• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

Custom stat system improvements

Status
Not open for further replies.
Level 10
Joined
Jun 6, 2007
Messages
392
Hello! I've been thinking about making a system, that allows modifying damage, armor, max hp, max mana etc. through triggers. First of all, is there such a system? I couldn't find one, but I'd rather not reinvent the wheel.

So far I have created a function, which adds (or removes) damage bonus. Other stats will be modified in a similar way (except mana/hp), so at this point I'd like to get some feedback. How could my code be improved? I realized that my variable naming could be better, but I couldn't think of more descriptive names. Also the code could probably be optimised. Here's my code:

JASS:
library ModifyStats initializer init
    globals
        private integer array damageAbilitiesPositive
        private integer array damageAbilitiesNegative
        
//#################
//# CONFIGURABLES #        
//#################

        //The number of levels each damage bonus ability has
        private constant integer LEVELS_PER_DAMAGE_ABILITY = 10
        //The number of damage bonus abilities. The real number is twice as big, because negative damage has its own abilities.
        private constant integer DAMAGE_ABILITY_COUNT = 2
        
        //There must be DAMAGE_ABILITY_COUNT abilities for positive and equal number of abilities for negative damage. Their bonus values must
        //be set so that the bonus of the first level is (LEVELS_PER_DAMAGE_ABILITY + 1)^N, where N is 0...DAMAGE_ABILITY_COUNT - 1. The bonuses of
        //other levels are lvl 1 bonus * level.
        //Example, LEVELS_PER_DAMAGE_ABILITY = 7, DAMAGE_ABILITY_COUNT = 4:
        
        //Damage ability | lvl 1 | lvl 2 | lvl 3 | lvl 4 | lvl 5 | lvl 6 | lvl 7
        //      1        |   1   |   2   |   3   |   4   |   5   |   6   |  7
        //      2        |   8   |   16  |   24  |   32  |   40  |   48  |  56
        //      3        |   64  |  128  |  192  |  256  |  320  |  384  |  448
        //      4        |  521  |  1024 |  1536 |  2048 |  2560 |  3072 |  3584
        //     -1        |  -1   |  -2   |  -3   |  -4   |  -5   |  -6   | -7
        //     -2        |  -8   |  -16  |  -24  |  -32  |  -40  |  -48  | -56
        //     -3        |  -64  | -128  | -192  | -256  | -320  | -384  | -448
        //     -4        | -521  | -1024 | -1536 | -2048 | -2560 | -3072 | -3584
        
        //Higher LEVELS_PER_DAMAGE_ABILITY reduces the number of abilities that have to be created, but for shorter loading time it's better
        //to have multiple abilities with few levels.
    endglobals
    
    //Set bonus abilities here
    private function init takes nothing returns nothing
        set damageAbilitiesPositive[0] = 'A04W'
        set damageAbilitiesNegative[0] = 'A04X'
        set damageAbilitiesPositive[1] = 'A04Y'
        set damageAbilitiesNegative[1] = 'A04Z'
    endfunction
    
//#####################
//# CONFIGURABLES END #        
//#####################
    
    function modifyDamage takes unit u, integer amount returns integer
        local integer currentBonus = 0
        local integer currAbil = 0
        local integer currLvl = 1
        local integer multiplier = 1
        local integer amountChange = 1
        local integer returnVal = 0
        local integer maxAmount = 0
        local integer pow = 0
        
        //CALCULATE CURRENT BONUS
        //Calculate positive bonus by checking every level of each damage ability
        loop
            exitwhen currAbil == DAMAGE_ABILITY_COUNT
            
            if (GetUnitAbilityLevel(u, damageAbilitiesPositive[currAbil]) == currLvl) then
                set currentBonus = currentBonus + amountChange
            endif
            
            //amountChange is the amount that current level of current ability adds to the damage bonus.
            //multiplier is the amount that damage bonus changes between the levels of current ability.
            set amountChange = amountChange + multiplier
            //Checking the last level, start checking next ability from level 1
            if (currLvl == LEVELS_PER_DAMAGE_ABILITY) then
                set currLvl = 1
                set currAbil = currAbil + 1
                set multiplier = amountChange
            else
                set currLvl = currLvl + 1
            endif
        endloop
        
        set amountChange = 1
        set multiplier = 1
        set currAbil = 0
        set currLvl = 1
        
        //Calculate negative bonus by checking every level of each damage ability
        loop
            exitwhen currAbil == DAMAGE_ABILITY_COUNT
            
            if (GetUnitAbilityLevel(u, damageAbilitiesNegative[currAbil]) == currLvl) then
                set currentBonus = currentBonus - amountChange
            endif
            //amountChange is the amount that current level of current ability adds to the damage bonus.
            //multiplier is the amount that damage bonus changes between the levels of current ability.
            set amountChange = amountChange + multiplier
            //Checking the last level, start checking next ability from level 1
            if (currLvl == LEVELS_PER_DAMAGE_ABILITY) then
                set currLvl = 1
                set currAbil = currAbil + 1
                set multiplier = amountChange
            else
                set currLvl = currLvl + 1
            endif
        endloop
        
        //CURRENT BONUS CALCULATED
        
        set pow = R2I(Pow(I2R(LEVELS_PER_DAMAGE_ABILITY + 1), I2R(DAMAGE_ABILITY_COUNT - 1)))
        set amountChange = pow
        set pow = pow * LEVELS_PER_DAMAGE_ABILITY
        
        //Calculate maximum amount. Maximum amount is achieved, when a unit has all bonus abilities at max level.
        loop
            exitwhen pow == 0
            set maxAmount = maxAmount + pow
            set pow = pow / (LEVELS_PER_DAMAGE_ABILITY + 1)
        endloop
        
        //If currentBonus + amount is not between -maxAmount and maxAmount, scale it.
        if (currentBonus + amount > maxAmount) then
            set returnVal = maxAmount - currentBonus
            set currentBonus = maxAmount
        elseif (currentBonus + amount < -maxAmount) then
            set returnVal = -maxAmount - currentBonus
            set currentBonus = -maxAmount
        else
            set returnVal = amount
            set currentBonus = currentBonus + amount            
        endif
        
        set currAbil = DAMAGE_ABILITY_COUNT - 1
        set currLvl = LEVELS_PER_DAMAGE_ABILITY
        
        //Total bonus is positive
        if (currentBonus > 0) then
            //currentBonus is the amount of damage, that still has to be added. For every level of each ability (starting from highest),
            //check if current bonus is bigger or equal to the bonus given by that ability on that level, and if it is, add that ability to a unit, set its level accordingly and
            //substract that amount from currentBonus.
            loop
                exitwhen currAbil < 0
                //If this is first time checking an ability, remove it.
                if (currLvl == LEVELS_PER_DAMAGE_ABILITY) then
                    call UnitRemoveAbility(u, damageAbilitiesPositive[currAbil])
                    call UnitRemoveAbility(u, damageAbilitiesNegative[currAbil])
                endif
                
                if (currentBonus >= amountChange * currLvl) then
                    call UnitAddAbility(u, damageAbilitiesPositive[currAbil])
                    call SetUnitAbilityLevel(u, damageAbilitiesPositive[currAbil], currLvl)
                    set currentBonus = currentBonus - amountChange * currLvl
                endif
                
                if (currLvl == 1) then
                    set currLvl = LEVELS_PER_DAMAGE_ABILITY
                    set currAbil = currAbil - 1
                    set amountChange = amountChange / LEVELS_PER_DAMAGE_ABILITY
                else
                    set currLvl = currLvl - 1
                endif
            endloop
        //Total bonus is negative
        else
            //currentBonus is the amount of damage, that still has to be added (in this case negative). For every level of each ability (starting from highest),
            //check if current bonus is less than or equal to the bonus given by that ability on that level, and if it is, add that ability to a unit, set its level accordingly and
            //add that amount to currentBonus.
            loop
                exitwhen currAbil < 0
                //If this is first time checking an ability, remove it.
                if (currLvl == LEVELS_PER_DAMAGE_ABILITY) then
                    call UnitRemoveAbility(u, damageAbilitiesPositive[currAbil])
                    call UnitRemoveAbility(u, damageAbilitiesNegative[currAbil])
                endif
                
                if (currentBonus <= -amountChange * currLvl) then
                    call UnitAddAbility(u, damageAbilitiesNegative[currAbil])
                    call SetUnitAbilityLevel(u, damageAbilitiesNegative[currAbil], currLvl)
                    set currentBonus = currentBonus + amountChange * currLvl
                endif
                
                if (currLvl == 1) then
                    set currLvl = LEVELS_PER_DAMAGE_ABILITY
                    set currAbil = currAbil - 1
                    set amountChange = amountChange / LEVELS_PER_DAMAGE_ABILITY
                else
                    set currLvl = currLvl - 1
                endif
            endloop
        endif
        
        //Return the amount of added damage
        return returnVal
    endfunction

endlibrary
 
Status
Not open for further replies.
Top