Skip to content

damian-pastorini/reldens-modifiers

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

77 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Reldens - GitHub - Release

Reldens - Modifiers

About

This package provides a modifiers system originally created for the Reldens project, but designed to be used anywhere.

The package includes:

  • Modifier: Apply and revert value modifications to object properties with conditions and limits
  • Condition: Define conditions that must be met before applying modifiers
  • Calculator: Handle mathematical operations (increase, decrease, multiply, divide, percentages, set values)
  • PropertyManager: Access and modify deep object properties using path notation
  • Constants: Pre-defined operation types, comparison operators, and state constants

Installation

npm install @reldens/modifiers

Quick Start

const { Modifier, ModifierConst } = require('@reldens/modifiers');

// Create a player object
let player = {
    health: 100,
    maxHealth: 150,
    attack: 50
};

// Create a modifier to increase attack by 20
let attackBoost = new Modifier({
    key: 'attack-boost',
    propertyKey: 'attack',
    operation: ModifierConst.OPS.INC,
    value: 20
});

// Apply the modifier
attackBoost.apply(player);
console.log(player.attack); // 70

// Revert the modifier
attackBoost.revert(player);
console.log(player.attack); // 50

Detailed Usage Examples

Modifier Class

The Modifier class is the core component for applying value changes to object properties.

Basic Operations

const { Modifier, ModifierConst } = require('@reldens/modifiers');

let character = {
    strength: 100,
    intelligence: 80,
    gold: 500
};

// Increase (INC)
let strengthBonus = new Modifier({
    key: 'str-bonus',
    propertyKey: 'strength',
    operation: ModifierConst.OPS.INC,
    value: 25
});
strengthBonus.apply(character);
console.log(character.strength); // 125

// Decrease (DEC)
let goldCost = new Modifier({
    key: 'shop-cost',
    propertyKey: 'gold',
    operation: ModifierConst.OPS.DEC,
    value: 150
});
goldCost.apply(character);
console.log(character.gold); // 350

// Multiply (MUL)
let criticalHit = new Modifier({
    key: 'crit-damage',
    propertyKey: 'strength',
    operation: ModifierConst.OPS.MUL,
    value: 2
});
criticalHit.apply(character);
console.log(character.strength); // 250

// Divide (DIV)
let weakness = new Modifier({
    key: 'weakness-debuff',
    propertyKey: 'strength',
    operation: ModifierConst.OPS.DIV,
    value: 2
});
weakness.apply(character);
console.log(character.strength); // 125

Percentage Operations

let stats = { damage: 200, defense: 100 };

// Increase by percentage (INC_P)
let damageIncrease = new Modifier({
    key: 'damage-boost',
    propertyKey: 'damage',
    operation: ModifierConst.OPS.INC_P,
    value: 50 // 50% increase
});
damageIncrease.apply(stats);
console.log(stats.damage); // 300 (200 + 50% of 200)

// Decrease by percentage (DEC_P)
let armorPiercing = new Modifier({
    key: 'armor-pierce',
    propertyKey: 'defense',
    operation: ModifierConst.OPS.DEC_P,
    value: 25 // 25% reduction
});
armorPiercing.apply(stats);
console.log(stats.defense); // 75 (100 - 25% of 100)

Set Operations

let player = { level: 1, status: 'normal' };

// Set numeric value (SET)
let levelUp = new Modifier({
    key: 'level-up',
    propertyKey: 'level',
    operation: ModifierConst.OPS.SET,
    value: 10
});
levelUp.apply(player);
console.log(player.level); // 10

// Set string value (SET with string type)
let statusEffect = new Modifier({
    key: 'poison-status',
    propertyKey: 'status',
    operation: ModifierConst.OPS.SET,
    type: ModifierConst.TYPES.STRING,
    value: 'poisoned'
});
statusEffect.apply(player);
console.log(player.status); // 'poisoned'

Value Limits

let character = { health: 50, maxHealth: 100 };

// Modifier with min/max limits
let healing = new Modifier({
    key: 'healing-potion',
    propertyKey: 'health',
    operation: ModifierConst.OPS.INC,
    value: 80,
    minValue: 0,
    maxValue: 100
});
healing.apply(character);
console.log(character.health); // 100 (capped at maxValue)

// Using property-based limits
let manaRestore = new Modifier({
    key: 'mana-potion',
    propertyKey: 'mana',
    operation: ModifierConst.OPS.INC,
    value: 50,
    maxProperty: 'maxMana' // Use maxMana property as limit
});

Deep Property Access

let character = {
    stats: {
        combat: {
            attack: 100,
            defense: 80
        },
        magic: {
            power: 60
        }
    }
};

// Modify nested property using path notation
let magicBoost = new Modifier({
    key: 'magic-boost',
    propertyKey: 'stats/magic/power',
    operation: ModifierConst.OPS.INC,
    value: 25
});
magicBoost.apply(character);
console.log(character.stats.magic.power); // 85

Condition Class

Conditions allow you to control when modifiers should be applied.

Basic Conditions

const { Condition, ModifierConst } = require('@reldens/modifiers');

let player = { level: 15, health: 80, maxHealth: 100 };

// Create conditions
let levelCondition = new Condition({
    key: 'min-level',
    propertyKey: 'level',
    conditional: ModifierConst.COMPARE.GE, // Greater or equal
    value: 10
});

let healthCondition = new Condition({
    key: 'low-health',
    propertyKey: 'health',
    conditional: ModifierConst.COMPARE.LT, // Less than
    value: 90
});

// Test conditions
console.log(levelCondition.isValidOn(player)); // true (15 >= 10)
console.log(healthCondition.isValidOn(player)); // true (80 < 90)

Available Comparison Operators

// All available comparison operators
let conditions = {
    equals: ModifierConst.COMPARE.EQ,        // ===
    notEquals: ModifierConst.COMPARE.NE,     // !==
    lessThan: ModifierConst.COMPARE.LT,      // <
    greaterThan: ModifierConst.COMPARE.GT,   // >
    lessOrEqual: ModifierConst.COMPARE.LE,   // <=
    greaterOrEqual: ModifierConst.COMPARE.GE // >=
};

Modifiers with Conditions

let player = { level: 5, experience: 1200, strength: 50 };

// Create condition
let experienceCondition = new Condition({
    key: 'exp-check',
    propertyKey: 'experience',
    conditional: ModifierConst.COMPARE.GE,
    value: 1000
});

// Create modifier with condition
let experienceBonus = new Modifier({
    key: 'exp-strength-bonus',
    propertyKey: 'strength',
    operation: ModifierConst.OPS.INC,
    value: 10,
    conditions: [experienceCondition]
});

// This will apply because experience >= 1000
experienceBonus.apply(player);
console.log(player.strength); // 60

// Change experience and test again
player.experience = 500;
let newBonus = new Modifier({
    key: 'another-bonus',
    propertyKey: 'strength',
    operation: ModifierConst.OPS.INC,
    value: 20,
    conditions: [experienceCondition]
});

// This won't apply because experience < 1000
newBonus.apply(player);
console.log(player.strength); // Still 60

PropertyManager Class

The PropertyManager handles deep property access using path notation.

const { PropertyManager } = require('@reldens/modifiers');

let propertyManager = new PropertyManager();

let gameObject = {
    player: {
        inventory: {
            weapons: {
                sword: { damage: 50, durability: 100 }
            }
        }
    }
};

// Get deep property value
let swordDamage = propertyManager.getPropertyValue(gameObject, 'player/inventory/weapons/sword/damage');
console.log(swordDamage); // 50

// Set deep property value
propertyManager.setOwnerProperty(gameObject, 'player/inventory/weapons/sword/damage', 65);
console.log(gameObject.player.inventory.weapons.sword.damage); // 65

Calculator Class

The Calculator class handles mathematical operations and can be used independently.

const { Calculator, ModifierConst } = require('@reldens/modifiers');

let calculator = new Calculator();

// Basic operations
console.log(calculator.calculateNewValue(100, ModifierConst.OPS.INC, 25, false)); // 125
console.log(calculator.calculateNewValue(100, ModifierConst.OPS.DEC, 30, false)); // 70
console.log(calculator.calculateNewValue(50, ModifierConst.OPS.MUL, 3, false)); // 150
console.log(calculator.calculateNewValue(60, ModifierConst.OPS.DIV, 2, false)); // 30

// Percentage operations
console.log(calculator.calculateNewValue(200, ModifierConst.OPS.INC_P, 50, false)); // 300
console.log(calculator.calculateNewValue(100, ModifierConst.OPS.DEC_P, 25, false)); // 75

// Revert operations (using revert = true)
console.log(calculator.calculateNewValue(125, ModifierConst.OPS.INC, 25, true)); // 100
console.log(calculator.calculateNewValue(70, ModifierConst.OPS.DEC, 30, true)); // 100

Real-World Examples

RPG Character System

const { Modifier, Condition, ModifierConst } = require('@reldens/modifiers');

// Character data
let character = {
    level: 20,
    class: 'warrior',
    stats: {
        strength: 100,
        agility: 60,
        intelligence: 40
    },
    equipment: {
        weapon: null,
        armor: null
    }
};

// Equipment modifiers
let magicSword = new Modifier({
    key: 'magic-sword',
    propertyKey: 'stats/strength',
    operation: ModifierConst.OPS.INC,
    value: 35
});

let agilityBoots = new Modifier({
    key: 'agility-boots',
    propertyKey: 'stats/agility',
    operation: ModifierConst.OPS.INC_P,
    value: 25 // 25% increase
});

// Class-specific bonuses with conditions
let warriorCondition = new Condition({
    key: 'warrior-class',
    propertyKey: 'class',
    conditional: ModifierConst.COMPARE.EQ,
    type: ModifierConst.TYPES.STRING,
    value: 'warrior'
});

let classBonus = new Modifier({
    key: 'warrior-strength-bonus',
    propertyKey: 'stats/strength',
    operation: ModifierConst.OPS.INC_P,
    value: 20,
    conditions: [warriorCondition]
});

// Apply equipment
magicSword.apply(character);
agilityBoots.apply(character);
classBonus.apply(character);

console.log('Final stats:', character.stats);
// strength: 162 (100 + 35 + 20% of 135)
// agility: 75 (60 + 25% of 60)
// intelligence: 40 (unchanged)

Temporary Buff System

// Buff system with time limits and conditions
let player = { health: 200, maxHealth: 300, mana: 50 };

// Health condition for mana regeneration
let lowManaCondition = new Condition({
    key: 'low-mana',
    propertyKey: 'mana',
    conditional: ModifierConst.COMPARE.LT,
    value: 100
});

// Conditional mana regeneration
let manaRegen = new Modifier({
    key: 'mana-regen-buff',
    propertyKey: 'mana',
    operation: ModifierConst.OPS.INC,
    value: 25,
    maxProperty: 'maxMana',
    conditions: [lowManaCondition]
});

// Apply buff (will work because mana < 100)
manaRegen.apply(player);
console.log(player.mana); // 75

// Try to apply again (still works because mana < 100)
manaRegen.apply(player);
console.log(player.mana); // 100

// Try once more (won't work because mana >= 100)
let player2 = { ...player };
manaRegen.apply(player2);
console.log(player2.mana); // Still 100 (condition not met)

Constants Reference

Operations (ModifierConst.OPS)

  • INC (1): Increase value
  • DEC (2): Decrease value
  • DIV (3): Divide value
  • MUL (4): Multiply value
  • INC_P (5): Increase by percentage
  • DEC_P (6): Decrease by percentage
  • SET (7): Set absolute value
  • METHOD (8): Call custom method
  • SET_N (9): Set value (alternative)

Comparison Operators (ModifierConst.COMPARE)

  • EQ: Equal to (===)
  • NE: Not equal to (!==)
  • LT: Less than (<)
  • GT: Greater than (>)
  • LE: Less than or equal (<=)
  • GE: Greater than or equal (>=)

Data Types (ModifierConst.TYPES)

  • INT: Integer type
  • STRING: String type

Modifier States

  • MOD_MISSING_KEY: Missing key parameter
  • MOD_MISSING_PROPERTY_KEY: Missing propertyKey parameter
  • MOD_MISSING_OPERATION: Missing operation parameter
  • MOD_MISSING_VALUE: Missing value parameter
  • MOD_READY: Modifier ready to apply
  • MOD_APPLIED: Modifier successfully applied
  • MOD_REVERTED: Modifier successfully reverted
  • MOD_UNDEFINED_TARGET: No target object specified
  • MOD_INVALID_CONDITIONS: Conditions not met
  • MOD_MISSING_CONDITION_INSTANCE: Invalid condition instance
  • MOD_MODIFIER_ERROR: General modifier error

Advanced Features

Base Property Operations

Use different properties for calculation and application:

let character = {
    currentHealth: 50,
    baseHealth: 100,
    maxHealth: 120
};

// Calculate from baseHealth but apply to currentHealth
let healing = new Modifier({
    key: 'healing-spell',
    propertyKey: 'currentHealth',
    basePropertyKey: 'baseHealth',
    operation: ModifierConst.OPS.INC_P,
    value: 30 // 30% of baseHealth
});

// Use baseHealth for calculation, apply to currentHealth
healing.apply(character, true, false);
console.log(character.currentHealth); // 80 (50 + 30% of 100)

Custom Method Operations

class CustomModifier extends Modifier
{
    customCalculation(modifier, currentValue)
    {
        // Custom logic here
        return Math.floor(currentValue * 1.5) + 10;
    }
}

let customMod = new CustomModifier({
    key: 'custom-boost',
    propertyKey: 'attack',
    operation: ModifierConst.OPS.METHOD,
    value: 'customCalculation'
});

Error Handling

The package includes comprehensive error handling and state management:

let invalidModifier = new Modifier({
    // Missing required parameters
    key: 'invalid'
});

console.log(invalidModifier.state); // Will show error state code

Need something specific?

Request a feature here: https://www.reldens.com/features-request

Documentation

https://www.reldens.com/documentation/modifiers


About

Reldens - Modifiers

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors