• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

Best way to regulate Max HP and MP

Status
Not open for further replies.
Level 9
Joined
Apr 23, 2011
Messages
460
Hello, I'm currently wondering what the most efficient way to control HP and MP maximums is. I'm currently looking at a set of spells that increase/decrease the stats in ranks. I.E. Max Health. The first spell each rank reduces by 1 each level until level 49. At 50, a new spell reduces by 50, and the remainder pours into the 1st spell. After 50 at 99 it becomes spell 3 which increments by 100, and doing something like that. But is there a better way to do this?
 
Level 17
Joined
Nov 13, 2006
Messages
1,814
Hello, I'm currently wondering what the most efficient way to control HP and MP maximums is. I'm currently looking at a set of spells that increase/decrease the stats in ranks. I.E. Max Health. The first spell each rank reduces by 1 each level until level 49. At 50, a new spell reduces by 50, and the remainder pours into the 1st spell. After 50 at 99 it becomes spell 3 which increments by 100, and doing something like that. But is there a better way to do this?

see around in spell section, alot map exist a function, who want increase every time with only a fix lil amount then tome solution good too but for anything else most of people do 1 or more hp ability add it to unit change level and remove it
 
Level 9
Joined
Apr 23, 2011
Messages
460
The system I am talking about would do something like this.
Say the value to increase by is 132. You would get 132 > 100, so we use spell 3 one time, using a while x > 100 (where x = 132) add +100 HP spell, x -= 100, and then check 50. x > 50 is false so we go to 1. x > 0 is true 32 times, so we add +32 (because 1 would iterate only 31 times) and subtract 1.

Is this the most efficient way?
 
Level 17
Joined
Jul 17, 2011
Messages
1,863
you might need to create an entire list of spells where each will give an even or odd bonus
they can be
spell[1] = +1
spell[2] = + 5
spell[3] = +10
spell[4] = +20
spell[5] = +50
spell[6] = +100
.....
if you need to add 132
its gonna be spell[6] + spell[4] + spell[3] + spell[1] + spell[1]

thats how i would do it :thumbs_up:
 
Level 17
Joined
Nov 13, 2006
Messages
1,814
you might need to create an entire list of spells where each will give an even or odd bonus
they can be
spell[1] = +1
spell[2] = + 5
spell[3] = +10
spell[4] = +20
spell[5] = +50
spell[6] = +100
.....
if you need to add 132
its gonna be spell[6] + spell[4] + spell[3] + spell[1] + spell[1]

thats how i would do it :thumbs_up:
then better to use the power of 2.

1
2
4
8
16
32
64
128
etc

so for 132 need 128+4

but anyway i use only 1 ability, just lv10 for this

'A003' - hp ability
'A004' - mana ability
because this function handle both


JASS:
function AddHPMP takes boolean HP, integer v, unit u returns nothing
    local integer a
    local integer s
    local integer i
    local integer l
    local integer cv
    local integer mv

    if HP then
        set a = 'A003'
    else
        set a = 'A004'
    endif

    if ( v >= 0 ) then
        set s = 1
        set cv = v
    else
        set s = 5
        set cv = v * - 1
    endif
    set mv = cv - ( cv / 1000 ) * 1000
    set l = cv / 1000
    set i = 1
    loop
        exitwhen i > l
        call UnitAddAbility( u, a )
        call SetUnitAbilityLevel( u, a, ( 4 + s ) )
        call UnitRemoveAbility( u, a )
        set i = i + 1
    endloop
    set cv = mv
    set mv = cv - ( cv / 100 ) * 100
    set l = cv / 100
    set cv = mv
    set i = 1
    loop
        exitwhen i > l
        call UnitAddAbility( u, a )
        call SetUnitAbilityLevel( u, a, ( 3 + s ) )
        call UnitRemoveAbility( u, a )
        set i = i + 1
    endloop
    set mv = cv - ( cv / 10 ) * 10
    set l = cv / 10
    set cv = mv
    set i = 1
    loop
        exitwhen i > l
        call UnitAddAbility( u, a )
        call SetUnitAbilityLevel( u, a, ( 2 + s ) )
        call UnitRemoveAbility( u, a )
        set i = i + 1
    endloop
    set i = 1
    loop
        exitwhen i > cv
        call UnitAddAbility( u , a )
        call SetUnitAbilityLevel( u, a, ( 1 + s ) )
        call UnitRemoveAbility( u, a )
        set i = i + 1
    endloop
    set u = null
endfunction

this is the posted one by Doomlord in spellsection where he use more ability for this

JASS:
// HP bonus

function CSS_LifeBonus takes unit u returns nothing
    local integer array lifeBonus
    local integer i = 16
    local integer max = CSS_Powers(17)
    local integer life = LoadInteger(udg_CSS_Hashtable, GetHandleId(u), 1)

    set lifeBonus[0] = 'ZxE0'
    set lifeBonus[1] = 'ZxE1'
    set lifeBonus[2] = 'ZxE2'
    set lifeBonus[3] = 'ZxE3'
    set lifeBonus[4] = 'ZxE4'
    set lifeBonus[5] = 'ZxE5'
    set lifeBonus[6] = 'ZxE6'
    set lifeBonus[7] = 'ZxE7'
    set lifeBonus[8] = 'ZxE8'
    set lifeBonus[9] = 'ZxE9'
    set lifeBonus[10] = 'ZxEa'
    set lifeBonus[11] = 'ZxEb'
    set lifeBonus[12] = 'ZxEc'
    set lifeBonus[13] = 'ZxEd'
    set lifeBonus[14] = 'ZxEe'
    set lifeBonus[15] = 'ZxEf'
    set lifeBonus[16] = 'ZxEg'
    set lifeBonus[18] = 'ZxEh'

    if life < 0 then
        set life = max + life
    else
        call UnitRemoveAbility(u, lifeBonus[18])
    endif

    loop
        if life >= CSS_Powers(i) then
            call UnitAddAbility(u, lifeBonus[i])
            call UnitMakeAbilityPermanent(u, true, lifeBonus[i])
            set life = life - CSS_Powers(i)
        else
            call UnitRemoveAbility(u, lifeBonus[i])
        endif
        
        set i = i - 1
        exitwhen i < 0
    endloop

    if LoadInteger(udg_CSS_Hashtable, GetHandleId(u), 2) < 0 then
        call UnitAddAbility(u, lifeBonus[18])
        call UnitMakeAbilityPermanent(u, true, lifeBonus[18])
    endif
endfunction

// API

function CSS_AddLife takes unit u, integer life returns nothing
    local integer max = CSS_Powers(17) - 1
    local integer min = -CSS_Powers(17)
    local integer i = LoadInteger(udg_CSS_Hashtable, GetHandleId(u), 1)

    if life > max or life < min then
        call BJDebugMsg("Value too high or too low")
        return
    elseif life + GetUnitState(u, UNIT_STATE_MAX_LIFE) <= 0 then
        call BJDebugMsg("Unit's current max life is lower than the negative bonus amount. Unable to subtract.")
        return
    endif

    if i >= max or i <= min then
        call BJDebugMsg("Current value at maximum or minimum - Life")
        return
    endif

    call SaveInteger(udg_CSS_Hashtable, GetHandleId(u), 1, i + life)
    call CSS_LifeBonus(u)
endfunction

// HP bonus - End
 
Level 17
Joined
Nov 13, 2006
Messages
1,814
lv 10 enough for make it add/remove: 1/10/100/1000 hp, what sometimes need less adding somtimes more than the 2nd example but anyway, i dont got any problem with lagg or something with lv10 ability, really smoothly, after 10k hp adding at once time maybe inefficient but i guess most of people dont use that much hp exlcude if it is for dds
 
Level 26
Joined
Aug 18, 2009
Messages
4,097
Initialization-wise it is bad to have many abilities/levels but faster is of course when you do not need to calculate and stack the bonuses too much.

I would guess the best option would be to have mass abilities for each individual bonus but have those objects in slk shape, because those are far cheaper and are completely loaded on map init.
 
Level 17
Joined
Nov 13, 2006
Messages
1,814
Initialization-wise it is bad to have many abilities/levels but faster is of course when you do not need to calculate and stack the bonuses too much.

I would guess the best option would be to have mass abilities for each individual bonus but have those objects in slk shape, because those are far cheaper and are completely loaded on map init.

i guess have alot beginner people who dont know how it work (like me) :D
 
Not only beginners :p
There is no gain in using .slk files instead of the editor, apart from an excellent map loading time optimization (which can be get with the widgetizer for the biggest part), the choice of the objects' ID (which can be get with the JNGP) and the access to some obscure object editor features (such as the internal units' name and the "minCool" field).

WaterKnight said:
Initialization-wise it is bad to have many abilities/levels but faster is of course when you do not need to calculate and stack the bonuses too much.

I would guess the best option would be to have mass abilities for each individual bonus but have those objects in slk shape, because those are far cheaper and are completely loaded on map init.
I guess you talk about having abilities in the format 'AL01', 'AL02', 'AL03'... so you can just use 'AL00'+some_integer in the script. It would be wise, yes, but as I said, it can be done with the JNGP.
 
Level 26
Joined
Aug 18, 2009
Messages
4,097
Does not have to be in that format if you list it in an array. But if you wanted to add a bonus of 99 e.g., you would not have to assemble it of different numbers then, only a single add ability/set level/remove, which renders the execution very fast.

The excellent map loading time optimization is worth a lot :D, especially when testing. Widgetizer is very slow, so I cannot run it on every save.
 
Level 9
Joined
Apr 23, 2011
Messages
460
I don't see high values really. The Flat HP integration is really going to top out its bonuses at 2000 for 1 item. If anything I need a system that can sustain multiple uses of HP gain so that say you have 3 items that give HP. After you buy the second one, it needs to be adding it to the total. I assume doom's system does that?

However, I will need it for MP as well, and that will be more strenuous. The system will have to be subtracting AND adding, as I intend to use it for Flat MP Gain, and Flat MP loss, to regulate mana on certain heroes using the "rage system" and "energy system".
 
Level 9
Joined
Apr 23, 2011
Messages
460
Map development doesn't start until March 16th, I'm just gathering information and compiling my concepts together. The entirety of the system is to regulate the Hp in moderately low ranges. The average end game champion will have 50k hp, and that's with STR giving HP as well. But with my custom resource systems (rage and energy), i need to stop them from gaining mana from items. But that's all code snippets to add to a bigger system.
 
Level 17
Joined
Nov 13, 2006
Messages
1,814
Map development doesn't start until March 16th, I'm just gathering information and compiling my concepts together. The entirety of the system is to regulate the Hp in moderately low ranges. The average end game champion will have 50k hp, and that's with STR giving HP as well. But with my custom resource systems (rage and energy), i need to stop them from gaining mana from items. But that's all code snippets to add to a bigger system.

if u use above 10k hp then css system way better with more ability and with power of 2, just dont forget preload the abilities too
 
Level 28
Joined
Jan 26, 2007
Messages
4,789
Perhaps you could have a look at this BonusMod system, which is in GUI (which you might prefer).
There are actually 2 systems in that: BonusMod (which handles all unit stats, such as armor, damage, attributes, sight, attack speed and so on) and SetUnitMaxState, which handles the maxmimum HP/Mana of a unit.
It's the SetUnitMaxState that you would need for this.

Edit: I strongly recommend you to not use abilities with over 50 ability levels, as it makes the loading go slower and creates a lag spike when such a unit is created.
 
Use this:
JASS:
//////////////////////////////////////////////////////////////////////////////////////////
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@     SetUnitMaxState
//@=======================================================================================
//@ Credits:
//@---------------------------------------------------------------------------------------
//@     Written by:
//@         Earth-Fury
//@     Based on the work of:
//@         Blade.dk
//@
//@ If you use this system, please credit all of the people mentioned above in your map.
//@=======================================================================================
//@ SetUnitMaxState Readme
//@---------------------------------------------------------------------------------------
//@
//@ SetUnitMaxState() is a function origionally written by Blade.dk. It takes advantage of
//@ a bug which was introduced in one of the patches: Bonus life and mana abilitys will
//@ only ever add the bonus ammount for level 1. However, when removed, they will remove
//@ the ammount they should have added at their current level. This allows you to change a
//@ units maximum life and mana, without adding a perminent ability to the unit.
//@
//@---------------------------------------------------------------------------------------
//@ Adding SetUnitMaxState to your map:
//@ 
//@ Simply copy this library in to a trigger which has been converted to custom text.
//@ After that, you must copy over the abilitys. This is made easy by the ObjectMerger in
//@ JASS NewGen. Distributed with this system are //! external calls to the ObjectMerger.
//@ Simply copy both of them in to your map, save your map, close and reopen your map in
//@ the editor, and remove the external calls. (Or otherwise disable them. Removing the !
//@ after the // works.)
//@
//@---------------------------------------------------------------------------------------
//@ Using SetUnitMaxState:
//@
//@ nothing SetUnitMaxState(unit <target>, unitstate <state>, real <new value>)
//@
//@     This function changes <target>'s unitstate <state> to be eqal to <new value>. Note
//@ that the only valid unitstates this function will use are UNIT_STATE_MAX_MAN and
//@ UNIT_STATE_MAX_LIFE. Use SetUnitState() to change other unitstates.
//@
//@ nothing AddUnitMaxState(unit <target>, unitstate <state>, real <add value>)
//@
//@     This function adds <add value> to <target>'s <state> unitstate. <add value> can be
//@ less than 0, making this function reduce the specified unitstate. This function will
//@ only work with the unitstates UNIT_STATE_MAX_LIFE and UNIT_STATE_MAX_MANA.
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//////////////////////////////////////////////////////////////////////////////////////////
library SetUnitMaxState initializer Initialize
globals
//========================================================================================
// Configuration
//========================================================================================

    // The rawcode of the life ability:
    private constant integer MAX_STATE_LIFE_ABILITY = 'Zx01'
    
    // The rawcode of the mana ability:
    private constant integer MAX_STATE_MANA_ABILITY = 'Zx00'
    
    // The maximum power of two the abilitys use:
    private constant integer MAX_STATE_MAX_POWER = 8
endglobals

//========================================================================================
// System Code
//----------------------------------------------------------------------------------------
// Do not edit below this line unless you wish to change the way the system works.
//========================================================================================

globals
    private integer array PowersOf2
endglobals

function SetUnitMaxState takes unit u, unitstate state, real newValue returns nothing
    local integer stateAbility
    local integer newVal = R2I(newValue)
    local integer i = MAX_STATE_MAX_POWER
    local integer offset
    
    if state == UNIT_STATE_MAX_LIFE then
        set stateAbility = MAX_STATE_LIFE_ABILITY
    elseif state == UNIT_STATE_MAX_MANA then
        set stateAbility = MAX_STATE_MANA_ABILITY
    else
        debug call BJDebugMsg("SetUnitMaxState Error: Invalid unitstate")
        return
    endif
    
    set newVal = newVal - R2I(GetUnitState(u, state))
    
    if newVal > 0 then
        set offset = MAX_STATE_MAX_POWER + 3
    elseif newVal < 0 then
        set offset = 2
        set newVal = -newVal
    else
        return
    endif
    
    loop
        exitwhen newVal == 0 or i < 0
        if newVal >= PowersOf2[i] then
            call UnitAddAbility(u, stateAbility)
            call SetUnitAbilityLevel(u, stateAbility, offset + i)
            call UnitRemoveAbility(u, stateAbility)
            set newVal = newVal - PowersOf2[i]
        else
            set i = i - 1
        endif
    endloop
endfunction

function AddUnitMaxState takes unit u, unitstate state, real addValue returns nothing
    call SetUnitMaxState(u, state, GetUnitState(u, state) + addValue)
endfunction

private function Initialize takes nothing returns nothing
    local integer i = 1
    
    set PowersOf2[0] = 1
    loop
        set PowersOf2[i] = PowersOf2[i - 1] * 2
        set i = i + 1
        exitwhen i == MAX_STATE_MAX_POWER + 3
    endloop
endfunction
endlibrary
 
Status
Not open for further replies.
Top