• 🏆 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!
  • ✅ Time to vote for the top 3 models! The POLL for Hive's 6th HD Modeling Contest: Mechanical is now open! 📅 Poll close on July 16, 2024! 🔗 Cast your vote now!

[System] Bonus



Level 4
Jun 7, 2011
Why rewrite something that has already been done in the form of Earth-Fury's BonusMod and Jesus4Lyf's Status?

I'd use BonusMod over anything, simply because (in my opinion) it's the best and the most versatile system of this kind.

Also, the only thing your Lua framework does is limiting the availability of the systems that use it. You have no idea how many users would pass them up just because they wouldn't want to install all that nonsense. Object ID collisions are a very rare case and can be fixed with little-to-no effort.

Off-topic: I really appreciate your work, but sometimes, what you're doing is just irrational and senesless. I mean, look at all those variable names you're using in UnitIndexer, TimerQueue and even here (I'd actually like to see versions of UnitIndexer and TimerQueue with "normal" and descriptive variable names).

Fixing the map optimizer to work with stuff such as the boolean UnitAlive(unit) native would probably be easier and far more productive than coming up with your own forms of "optimization".
I mean, look at all those variable names you're using in UnitIndexer, TimerQueue and even here
But short variable names are 10x better than long ones :D (less load on the processor -> faster)

Honestly, I prefer Status, but others may prefer this, so all I have to say: Good Work :D

Thanks for inspiring to learn LUA a few weeks ago ^^

What I love about this is that it's literrally 20x shorter than Status :D
Level 31
Jul 10, 2007
It's not 20x shorter than status.... you forget the code generated by the Lua : P

Why rewrite something that has already been done in the form of Earth-Fury's BonusMod and Jesus4Lyf's Status?

Because I needed this system and I have high standards for what I use in my map ; P.

Off-topic: I really appreciate your work, but sometimes, what you're doing is just irrational and senesless. I mean, look at all those variable names you're using in UnitIndexer, TimerQueue and even here (I'd actually like to see versions of UnitIndexer and TimerQueue with "normal" and descriptive variable names).

I just name them short variable names that I can happen to read, which is easier for me than writing a new script optimizer that doesn't kill AI natives ; P

updated to
-> updated installation script to make bv boolean array debug only

updated to

-> added attack speed bonus
-> fixed % bonuses =P

updated to

-> added POWER+1 as -(2^POWER) to installation script for faster get bonus loop
-> made the vjass loops a little faster

struct tester extends array
    private static method display takes unit u returns nothing
        call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 60, "Bonus Armor: " + I2S(GetUnitBonus(u,BONUS_ARMOR)))
        call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 60, "Bonus Damage: " + I2S(GetUnitBonus(u,BONUS_DAMAGE)))
        call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 60, "Bonus Agility: " + I2S(GetUnitBonus(u,BONUS_AGILITY)))
        call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 60, "Bonus Strength: " + I2S(GetUnitBonus(u,BONUS_STRENGTH)))
        call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 60, "Bonus Intelligence: " + I2S(GetUnitBonus(u,BONUS_INTELLIGENCE)))
        call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 60, "Bonus Life: " + I2S(GetUnitBonus(u,BONUS_LIFE)))
        call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 60, "Bonus Life Regen: " + I2S(GetUnitBonus(u,BONUS_LIFE_REGEN)))
        call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 60, "Bonus Mana: " + I2S(GetUnitBonus(u,BONUS_MANA)))
        call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 60, "Bonus Mana Regen%: " + I2S(GetUnitBonus(u,BONUS_MANA_REGEN)))
        call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 60, "Bonus Attack Speed%: " + I2S(GetUnitBonus(u,BONUS_ATTACK_SPEED)))
        call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 60, "Bonus Sight: " + I2S(GetUnitBonus(u,BONUS_SIGHT)))
    private static method onInit takes nothing returns nothing
        local unit u = CreateUnit(Player(0), 'Hpal', WorldBounds.centerX, WorldBounds.centerY, 0)
        call SetUnitBonus(u,BONUS_ATTACK_SPEED,27)
        call SetUnitBonus(u,BONUS_SIGHT,-27)
        call display(u)

Honestly, I prefer Status, but others may prefer this, so all I have to say: Good Work :D

Status comes coupled with tons of other things... what if you only need the regular bonuses rather than all of the extra effects like stun? : )
Last edited:
Level 14
Nov 18, 2007
Oh, look, a quote just for you.
Earth-Fury said:
Few points...
  • Debug mode modifies the behaviour of the system.
  • Range checking is only done in debug mode, which requires users to range-check themselves to avoid horrible, horrible errors. Why the heck would you do that, instead of constraining the value and returning the actual applied value?
  • A single min/max range means excess abilities end up generated
  • The inability to easily disable individual bonus types leads to unused abilities.
  • The last two points mean that you're needlessly increasing map load time, and possibly quite substantially. Unless you manually remove abilities, or edit far too much code...
  • My version of bonus mod can handle custom bonuses not applied via abilities... at the cost of a single integer comparison per function.
  • You don't sanely handle bonus types which can only affect heroes...
  • You have a non-optional external dependency
  • The BONUS_MANA_REGEN constant is misleadingly named, with only a single "%" sign at the top to tell you it is percentage regen increase, as opposed to BONUS_LIFE_REGEN.
  • You completely lack any real form of documentation.


Your code is less functional and you should feel less functional.

Less function, less robust, and less optimal (Significantly, from a map loading time perspective) code. High standards... on opposite day.

What if you only need two types of ability-based bonuses?

Oh, right... Use BonusMod...


I quite honestly could optimize BonusMod slightly more. But why the hell would I invest effort in heavily optimizing something that will rape you horribly no matter what due to ability adding/removing overhead, and will never be called that often in spite of its actual performance characteristics?

I completely fail to see the point of this library, other than reinventing the wheel for the sake of it... If you're gonna reinvent the wheel, though... At least make it round, for fuck sakes.
Level 31
Jul 10, 2007
Oh, look, a quote just for you.

Yea, I knew about the single range thing. I am planning on doing a different power variable for each type of bonus for the next update =). Just been busy today, so I haven't gotten to it yet ^)^.

And for why I coded the system, I guess I can say it again. I need a Bonus system and none of the current systems do even decent object generation, so I refuse to use them ; ). Any systems that don't use getvarobject to generate objects are systems that I will never ever use =).

But yea, this'll prob be updated on the 10th or 11th with support for different ranges. It would change the max range and power variables into arrays, but that'd be the only dif on the vjass side ; ).

Another planned update is selecting which bonuses you want on the Lua side =), meaning you can pick specific bonuses to enable.

Also, the reason the loops are set up the way they are is because each ability has a range of values along the ability id array. You need both the power (second index) and the ability (first index) in order to loop through it. It's essentially a 2D array =). Yes, you could do ability*(POWER+2)+power and loop through just power, but that'd be stupid ; P.
Last edited:
Level 31
Jul 10, 2007

and this is around 653 lines long =), so Status is only around 3x bigger. But you need to remember that Status has a whole bunch of other stuff in it besides the bonuses =P.

Also, I think the vjass is as optimal as it can get for speed. Yea, I can do captain's looping thing, but that thing is really dependent upon how many globals are in the map >.>.

And here is a look at the new ini code with everything enabled
//! textmacro BONUS_DATA
private integer array bd
private integer array bp
private integer array pw
private integer array pm
constant integer BONUS_ARMOR=0
constant integer BONUS_DAMAGE=15
constant integer BONUS_AGILITY=33
constant integer BONUS_STRENGTH=49
constant integer BONUS_INTELLIGENCE=65
constant integer BONUS_LIFE=81
constant integer BONUS_LIFE_REGEN=103
constant integer BONUS_MANA=121
constant integer BONUS_MANA_REGEN=143
constant integer BONUS_SIGHT=154
constant integer BONUS_ATTACK_SPEED=167
private module I
private static method onInit takes nothing returns nothing
static if PRELOAD then
local unit u = CreateUnit(Player(14),'hpea',100000,100000,0)
call UnitAddAbility(u,'A!(@')
call UnitAddAbility(u,'A!([')
call UnitAddAbility(u,'A!(]')
call UnitAddAbility(u,'A!(^')
call UnitAddAbility(u,'A!(_')
call UnitAddAbility(u,'A!({')
call UnitAddAbility(u,'A!(|')
call UnitAddAbility(u,'A!(}')
call UnitAddAbility(u,'A!(~')
call UnitAddAbility(u,'A!)!')
call UnitAddAbility(u,'A!)"')
call UnitAddAbility(u,'A!)#')
call UnitAddAbility(u,'A!)$')
call UnitAddAbility(u,'A!)%')
call UnitAddAbility(u,'A!)&')
call UnitAddAbility(u,'A!)(')
call UnitAddAbility(u,'A!))')
call UnitAddAbility(u,'A!)*')
call UnitAddAbility(u,'A!)+')
call UnitAddAbility(u,'A!)-')
call UnitAddAbility(u,'A!).')
call UnitAddAbility(u,'A!):')
call UnitAddAbility(u,'A!);')
call UnitAddAbility(u,'A!)<')
call UnitAddAbility(u,'A!)=')
call UnitAddAbility(u,'A!)>')
call UnitAddAbility(u,'A!)?')
call UnitAddAbility(u,'A!)@')
call UnitAddAbility(u,'A!)[')
call UnitAddAbility(u,'A!)]')
call UnitAddAbility(u,'A!)^')
call UnitAddAbility(u,'A!)_')
call UnitAddAbility(u,'A!){')
call UnitAddAbility(u,'A!)|')
call UnitAddAbility(u,'A!)}')
call UnitAddAbility(u,'A!)~')
call UnitAddAbility(u,'A!*!')
call UnitAddAbility(u,'A!*"')
call UnitAddAbility(u,'A!*#')
call UnitAddAbility(u,'A!*$')
call UnitAddAbility(u,'A!*%')
call UnitAddAbility(u,'A!*&')
call UnitAddAbility(u,'A!*(')
call UnitAddAbility(u,'A!*)')
call UnitAddAbility(u,'A!**')
call UnitAddAbility(u,'A!*+')
call UnitAddAbility(u,'A!*-')
call UnitAddAbility(u,'A!*.')
call UnitAddAbility(u,'A!*:')
call UnitAddAbility(u,'A!*;')
call UnitAddAbility(u,'A!*<')
call UnitAddAbility(u,'A!*=')
call UnitAddAbility(u,'A!*>')
call UnitAddAbility(u,'A!*?')
call UnitAddAbility(u,'A!*@')
call UnitAddAbility(u,'A!*[')
call UnitAddAbility(u,'A!*]')
call UnitAddAbility(u,'A!*^')
call UnitAddAbility(u,'A!*_')
call UnitAddAbility(u,'A!*{')
call UnitAddAbility(u,'A!*|')
call UnitAddAbility(u,'A!*}')
call UnitAddAbility(u,'A!*~')
call UnitAddAbility(u,'A!+!')
call UnitAddAbility(u,'A!+"')
call UnitAddAbility(u,'A!+#')
call UnitAddAbility(u,'A!+$')
call UnitAddAbility(u,'A!+%')
call UnitAddAbility(u,'A!+&')
call UnitAddAbility(u,'A!+(')
call UnitAddAbility(u,'A!+)')
call UnitAddAbility(u,'A!+*')
call UnitAddAbility(u,'A!++')
call UnitAddAbility(u,'A!+-')
call UnitAddAbility(u,'A!+.')
call UnitAddAbility(u,'A!+:')
call UnitAddAbility(u,'A!+;')
call UnitAddAbility(u,'A!+<')
call UnitAddAbility(u,'A!+=')
call UnitAddAbility(u,'A!+>')
call UnitAddAbility(u,'A!+?')
call UnitAddAbility(u,'A!+@')
call UnitAddAbility(u,'A!+[')
call UnitAddAbility(u,'A!+]')
call UnitAddAbility(u,'A!+^')
call UnitAddAbility(u,'A!+_')
call UnitAddAbility(u,'A!+{')
call UnitAddAbility(u,'A!+|')
call UnitAddAbility(u,'A!+}')
call UnitAddAbility(u,'A!+~')
call UnitAddAbility(u,'A!-!')
call UnitAddAbility(u,'A!-"')
call UnitAddAbility(u,'A!-#')
call UnitAddAbility(u,'A!-$')
call UnitAddAbility(u,'A!-%')
call UnitAddAbility(u,'A!-&')
call UnitAddAbility(u,'A!-(')
call UnitAddAbility(u,'A!-)')
call UnitAddAbility(u,'A!-*')
call UnitAddAbility(u,'A!-+')
call UnitAddAbility(u,'A!--')
call UnitAddAbility(u,'A!-.')
call UnitAddAbility(u,'A!-:')
call UnitAddAbility(u,'A!-;')
call UnitAddAbility(u,'A!-<')
call UnitAddAbility(u,'A!-=')
call UnitAddAbility(u,'A!->')
call UnitAddAbility(u,'A!-?')
call UnitAddAbility(u,'A!-@')
call UnitAddAbility(u,'A!-[')
call UnitAddAbility(u,'A!-]')
call UnitAddAbility(u,'A!-^')
call UnitAddAbility(u,'A!-_')
call UnitAddAbility(u,'A!-{')
call UnitAddAbility(u,'A!-|')
call UnitAddAbility(u,'A!-}')
call UnitAddAbility(u,'A!-~')
call UnitAddAbility(u,'A!.!')
call UnitAddAbility(u,'A!."')
call UnitAddAbility(u,'A!.#')
call UnitAddAbility(u,'A!.$')
call UnitAddAbility(u,'A!.%')
call UnitAddAbility(u,'A!.&')
call UnitAddAbility(u,'A!.(')
call UnitAddAbility(u,'A!.)')
call UnitAddAbility(u,'A!.*')
call UnitAddAbility(u,'A!.+')
call UnitAddAbility(u,'A!.-')
call UnitAddAbility(u,'A!..')
call UnitAddAbility(u,'A!.:')
call UnitAddAbility(u,'A!.;')
call UnitAddAbility(u,'A!.<')
call UnitAddAbility(u,'A!.=')
call UnitAddAbility(u,'A!.>')
call UnitAddAbility(u,'A!.?')
call UnitAddAbility(u,'A!.@')
call UnitAddAbility(u,'A!.[')
call UnitAddAbility(u,'A!.]')
call UnitAddAbility(u,'A!.^')
call UnitAddAbility(u,'A!._')
call UnitAddAbility(u,'A!.{')
call UnitAddAbility(u,'A!.|')
call UnitAddAbility(u,'A!.}')
call UnitAddAbility(u,'A!.~')
call UnitAddAbility(u,'A!:!')
call UnitAddAbility(u,'A!:"')
call UnitAddAbility(u,'A!:#')
call UnitAddAbility(u,'A!:$')
call UnitAddAbility(u,'A!:%')
call UnitAddAbility(u,'A!:&')
call UnitAddAbility(u,'A!:(')
call UnitAddAbility(u,'A!:)')
call UnitAddAbility(u,'A!:*')
call UnitAddAbility(u,'A!:+')
call UnitAddAbility(u,'A!:-')
call UnitAddAbility(u,'A!:.')
call UnitAddAbility(u,'A!::')
call UnitAddAbility(u,'A!:;')
call UnitAddAbility(u,'A!:<')
call UnitAddAbility(u,'A!:=')
call UnitAddAbility(u,'A!:>')
call UnitAddAbility(u,'A!:?')
call UnitAddAbility(u,'A!:@')
call UnitAddAbility(u,'A!:[')
call UnitAddAbility(u,'A!:]')
call UnitAddAbility(u,'A!:^')
call UnitAddAbility(u,'A!:_')
call UnitAddAbility(u,'A!:{')
call UnitAddAbility(u,'A!:|')
call UnitAddAbility(u,'A!:}')
call UnitAddAbility(u,'A!:~')
call UnitAddAbility(u,'A!;!')
call UnitAddAbility(u,'A!;"')
call UnitAddAbility(u,'A!;#')
call UnitAddAbility(u,'A!;$')
call UnitAddAbility(u,'A!;%')
call UnitAddAbility(u,'A!;&')
call UnitAddAbility(u,'A!;(')
call RemoveUnit(u)
set u = null
set bd[0]='A!(@'
set bd[1]='A!(['
set bd[2]='A!(]'
set bd[3]='A!(^'
set bd[4]='A!(_'
set bd[5]='A!({'
set bd[6]='A!(|'
set bd[7]='A!(}'
set bd[8]='A!(~'
set bd[9]='A!)!'
set bd[10]='A!)"'
set bd[11]='A!)#'
set bd[12]='A!)$'
set bd[13]='A!)%'
set bd[14]='A!)&'
set bd[15]='A!)('
set bd[16]='A!))'
set bd[17]='A!)*'
set bd[18]='A!)+'
set bd[19]='A!)-'
set bd[20]='A!).'
set bd[21]='A!):'
set bd[22]='A!);'
set bd[23]='A!)<'
set bd[24]='A!)='
set bd[25]='A!)>'
set bd[26]='A!)?'
set bd[27]='A!)@'
set bd[28]='A!)['
set bd[29]='A!)]'
set bd[30]='A!)^'
set bd[31]='A!)_'
set bd[32]='A!){'
set bd[33]='A!)|'
set bd[34]='A!)}'
set bd[35]='A!)~'
set bd[36]='A!*!'
set bd[37]='A!*"'
set bd[38]='A!*#'
set bd[39]='A!*$'
set bd[40]='A!*%'
set bd[41]='A!*&'
set bd[42]='A!*('
set bd[43]='A!*)'
set bd[44]='A!**'
set bd[45]='A!*+'
set bd[46]='A!*-'
set bd[47]='A!*.'
set bd[48]='A!*:'
set bd[49]='A!*;'
set bd[50]='A!*<'
set bd[51]='A!*='
set bd[52]='A!*>'
set bd[53]='A!*?'
set bd[54]='A!*@'
set bd[55]='A!*['
set bd[56]='A!*]'
set bd[57]='A!*^'
set bd[58]='A!*_'
set bd[59]='A!*{'
set bd[60]='A!*|'
set bd[61]='A!*}'
set bd[62]='A!*~'
set bd[63]='A!+!'
set bd[64]='A!+"'
set bd[65]='A!+#'
set bd[66]='A!+$'
set bd[67]='A!+%'
set bd[68]='A!+&'
set bd[69]='A!+('
set bd[70]='A!+)'
set bd[71]='A!+*'
set bd[72]='A!++'
set bd[73]='A!+-'
set bd[74]='A!+.'
set bd[75]='A!+:'
set bd[76]='A!+;'
set bd[77]='A!+<'
set bd[78]='A!+='
set bd[79]='A!+>'
set bd[80]='A!+?'
set bd[81]='A!+@'
set bd[82]='A!+['
set bd[83]='A!+]'
set bd[84]='A!+^'
set bd[85]='A!+_'
set bd[86]='A!+{'
set bd[87]='A!+|'
set bd[88]='A!+}'
set bd[89]='A!+~'
set bd[90]='A!-!'
set bd[91]='A!-"'
set bd[92]='A!-#'
set bd[93]='A!-$'
set bd[94]='A!-%'
set bd[95]='A!-&'
set bd[96]='A!-('
set bd[97]='A!-)'
set bd[98]='A!-*'
set bd[99]='A!-+'
set bd[100]='A!--'
set bd[101]='A!-.'
set bd[102]='A!-:'
set bd[103]='A!-;'
set bd[104]='A!-<'
set bd[105]='A!-='
set bd[106]='A!->'
set bd[107]='A!-?'
set bd[108]='A!-@'
set bd[109]='A!-['
set bd[110]='A!-]'
set bd[111]='A!-^'
set bd[112]='A!-_'
set bd[113]='A!-{'
set bd[114]='A!-|'
set bd[115]='A!-}'
set bd[116]='A!-~'
set bd[117]='A!.!'
set bd[118]='A!."'
set bd[119]='A!.#'
set bd[120]='A!.$'
set bd[121]='A!.%'
set bd[122]='A!.&'
set bd[123]='A!.('
set bd[124]='A!.)'
set bd[125]='A!.*'
set bd[126]='A!.+'
set bd[127]='A!.-'
set bd[128]='A!..'
set bd[129]='A!.:'
set bd[130]='A!.;'
set bd[131]='A!.<'
set bd[132]='A!.='
set bd[133]='A!.>'
set bd[134]='A!.?'
set bd[135]='A!.@'
set bd[136]='A!.['
set bd[137]='A!.]'
set bd[138]='A!.^'
set bd[139]='A!._'
set bd[140]='A!.{'
set bd[141]='A!.|'
set bd[142]='A!.}'
set bd[143]='A!.~'
set bd[144]='A!:!'
set bd[145]='A!:"'
set bd[146]='A!:#'
set bd[147]='A!:$'
set bd[148]='A!:%'
set bd[149]='A!:&'
set bd[150]='A!:('
set bd[151]='A!:)'
set bd[152]='A!:*'
set bd[153]='A!:+'
set bd[154]='A!:-'
set bd[155]='A!:.'
set bd[156]='A!::'
set bd[157]='A!:;'
set bd[158]='A!:<'
set bd[159]='A!:='
set bd[160]='A!:>'
set bd[161]='A!:?'
set bd[162]='A!:@'
set bd[163]='A!:['
set bd[164]='A!:]'
set bd[165]='A!:^'
set bd[166]='A!:_'
set bd[167]='A!:{'
set bd[168]='A!:|'
set bd[169]='A!:}'
set bd[170]='A!:~'
set bd[171]='A!;!'
set bd[172]='A!;"'
set bd[173]='A!;#'
set bd[174]='A!;$'
set bd[175]='A!;%'
set bd[176]='A!;&'
set bd[177]='A!;('
set pm[0]=14
set pm[15]=17
set pm[33]=15
set pm[49]=15
set pm[65]=15
set pm[81]=21
set pm[103]=17
set pm[121]=21
set pm[143]=10
set pm[154]=12
set pm[167]=10
set bp[0]=8192
set bp[15]=65536
set bp[33]=16384
set bp[49]=16384
set bp[65]=16384
set bp[81]=1048576
set bp[103]=65536
set bp[121]=1048576
set bp[143]=512
set bp[154]=2048
set bp[167]=512
set pw[0]=1
set pw[1]=2
set pw[2]=4
set pw[3]=8
set pw[4]=16
set pw[5]=32
set pw[6]=64
set pw[7]=128
set pw[8]=256
set pw[9]=512
set pw[10]=1024
set pw[11]=2048
set pw[12]=4096
set pw[13]=8192
set pw[14]=-8192
set pw[15]=1
set pw[16]=2
set pw[17]=4
set pw[18]=8
set pw[19]=16
set pw[20]=32
set pw[21]=64
set pw[22]=128
set pw[23]=256
set pw[24]=512
set pw[25]=1024
set pw[26]=2048
set pw[27]=4096
set pw[28]=8192
set pw[29]=16384
set pw[30]=32768
set pw[31]=65536
set pw[32]=-65536
set pw[33]=1
set pw[34]=2
set pw[35]=4
set pw[36]=8
set pw[37]=16
set pw[38]=32
set pw[39]=64
set pw[40]=128
set pw[41]=256
set pw[42]=512
set pw[43]=1024
set pw[44]=2048
set pw[45]=4096
set pw[46]=8192
set pw[47]=16384
set pw[48]=-16384
set pw[49]=1
set pw[50]=2
set pw[51]=4
set pw[52]=8
set pw[53]=16
set pw[54]=32
set pw[55]=64
set pw[56]=128
set pw[57]=256
set pw[58]=512
set pw[59]=1024
set pw[60]=2048
set pw[61]=4096
set pw[62]=8192
set pw[63]=16384
set pw[64]=-16384
set pw[65]=1
set pw[66]=2
set pw[67]=4
set pw[68]=8
set pw[69]=16
set pw[70]=32
set pw[71]=64
set pw[72]=128
set pw[73]=256
set pw[74]=512
set pw[75]=1024
set pw[76]=2048
set pw[77]=4096
set pw[78]=8192
set pw[79]=16384
set pw[80]=-16384
set pw[81]=1
set pw[82]=2
set pw[83]=4
set pw[84]=8
set pw[85]=16
set pw[86]=32
set pw[87]=64
set pw[88]=128
set pw[89]=256
set pw[90]=512
set pw[91]=1024
set pw[92]=2048
set pw[93]=4096
set pw[94]=8192
set pw[95]=16384
set pw[96]=32768
set pw[97]=65536
set pw[98]=131072
set pw[99]=262144
set pw[100]=524288
set pw[101]=1048576
set pw[102]=-1048576
set pw[103]=1
set pw[104]=2
set pw[105]=4
set pw[106]=8
set pw[107]=16
set pw[108]=32
set pw[109]=64
set pw[110]=128
set pw[111]=256
set pw[112]=512
set pw[113]=1024
set pw[114]=2048
set pw[115]=4096
set pw[116]=8192
set pw[117]=16384
set pw[118]=32768
set pw[119]=65536
set pw[120]=-65536
set pw[121]=1
set pw[122]=2
set pw[123]=4
set pw[124]=8
set pw[125]=16
set pw[126]=32
set pw[127]=64
set pw[128]=128
set pw[129]=256
set pw[130]=512
set pw[131]=1024
set pw[132]=2048
set pw[133]=4096
set pw[134]=8192
set pw[135]=16384
set pw[136]=32768
set pw[137]=65536
set pw[138]=131072
set pw[139]=262144
set pw[140]=524288
set pw[141]=1048576
set pw[142]=-1048576
set pw[143]=1
set pw[144]=2
set pw[145]=4
set pw[146]=8
set pw[147]=16
set pw[148]=32
set pw[149]=64
set pw[150]=128
set pw[151]=256
set pw[152]=512
set pw[153]=-512
set pw[154]=1
set pw[155]=2
set pw[156]=4
set pw[157]=8
set pw[158]=16
set pw[159]=32
set pw[160]=64
set pw[161]=128
set pw[162]=256
set pw[163]=512
set pw[164]=1024
set pw[165]=2048
set pw[166]=-2048
set pw[167]=1
set pw[168]=2
set pw[169]=4
set pw[170]=8
set pw[171]=16
set pw[172]=32
set pw[173]=64
set pw[174]=128
set pw[175]=256
set pw[176]=512
set pw[177]=-512
private struct O extends array
implement I
//! endtextmacro
Last edited:
Level 31
Jul 10, 2007
Updated to

->made -ability bonus 2^(power+1) so that 1 less ability is needed for almost the same ranges of power +1
-----| -(2^(power+1) to 2^(power+1)-1

The ini script is now down to 554 lines with default settings and the amount of objects generated are now down to 167 with default settings =). In the previous version, it was 587 lines and 178 objects.
Level 31
Jul 10, 2007
If you could increase the mana regeneration bonus, I'd definitely trash "Status" and use this ^^ (After I go through all the trouble installing those LUA scripts :p

non % is impossible to increase. Status only does it through JASS w/ timers, which has a lot over overhead.

Resources that don't run off of abilities like this should just be their own little resources, like ManaRegenBonus resource and so on =).
As the API is exactly identical to BonusMod, here are some pros and cons of each I can think of.

Why to use BonusMod -
- Really easy to set up compared to the LUA library chain that this requires.
- It's the original

Why to use this -
- Safe LUA generation

Are there any other real advantages this has? I'm not talking about speed, I'm talking about functionality.
Level 31
Jul 10, 2007
It's pretty obvious which of the 2 scripts is better...

Are you going to give me that wc3c nonsense that the first script written is the best, regardless of how bad it is?

Really easy to set up compared to the LUA library chain that this requires.

Chain of lib scripts only need to be installed one time per computer and only take like 30 seconds to install for people who bother to do it. You should know that >.>.

It's the original

And how is that a pro exactly? That doesn't even make any sense. Does being the first automatically make the code the best, regardless of how bad it is? >.>. Listen to urself Bribe, ur starting to talk like the peeps at wc3c.

If that were the case, then technology in the world would be at a standstill because coal power would be the best since it was the first.
Listen to urself Bribe, ur starting to talk like the peeps at wc3c.

If that were the case, then technology in the world would be at a standstill because coal power would be the best since it was the first.

You so pwned him Nestharus :X

Here are the pros for this resource:
- Clean API
- Short script (relatively)
- Safe and fast LUA installation

For anyone using UnitIndexer, this is VERY useful.
UnitIndexer breaks AIDS, thus breaking Status (AIDS is required by it)
Without this, anyone using UnitIndexer couldn't use Status, so they would simply use AIDS as a result and deprecate UnitIndexer.

That's why Nestharus is recreating all these libraries.

I checked out BonusMod. Since they both have the same functionality (other than the fast implementation given to us by these awesome LUA scripts), they're tied, but this library is faster, so... It wins :p
Nah, I'm mostly recreating them as I personally need them =). I require a certain standard be met in a lib before I use it ^)^, and if it doesn't meet that standard by even a little, I just rewrite it so that it does and submit it for others to use =).

Next time, just use my excuse :p
It's better cause it makes people think you actually care ^)^
I was doing some thinking because you and I have been rewriting a lot of older concepts lately. It's a moral dilemma for me - someone else put tons of work into a project, finding bugs and of course coming up with the idea, then someone like you or me only finds a way to make it run faster... in many cases not even 50-100% faster, but something insignificant like 5-10%.

I get that a user leaves the scene or just absolutely doesn't care and the resource should live up to current standards. But at the very least credit should be supplied to the people who came up with the idea. Using a buggy +life ability trick to change the max life of a unit, or using the buggy undefend trick to detect when a unit dies/is removed... come on these things were found by other people, not you and not me.
Level 31
Jul 10, 2007
eh, for Undefend, I did do research into PurplePoot's and Griffen's work, but I also expanded that research a bit (how many times it fired and etc). king also mentioned how undefend was removed right before second fire for deindexing. For Bonus, that was my own work except for 1 tip given by Dr Super Good =).

Also, I don't personally care if someone improves one of my libs and submits it or w/e. You know me, I always push for the newest in and older out. I treat other people's work just like I treat my own. I don't care about credit or anything either =).

So yea, you are talking to the wrong guy about morals. I've been called a heartless machine before =P.

If someone took my research on combat in AdvDamageEvent and managed a better library using those techniques, I wouldn't mind at all. Ofc, if I saw improvements that could be done to their work, then I'd probably update my lib to use their techniques with improvements =P. At that point, it's whichever lib has the better API or that people are more willing to use (if they both turn out identical).

History lessons shouldn't be given in resources. All that should be in a resource is the API with documentation on how to use each method and possibly a tutorial if the resource merits that.

Sometimes in tutorials, I do go over history, like in my Save/Load tutorial, but that history doesn't belong in resources. People don't care about the history, they just want the resource >.>.

If you really want to write a historical document on how these techniques were discovered and who discovered them and how the various libraries came about, then go for it = ).

The fact of the matter is that this current Bonus lib is obviously better than the other one >.>. The code is also radically different. Most code for Bonus libs is Lua code. The entire design for the Lua portion is completely different from any design done with Bonus libs before. You can try to compare them or say they are similar, but the fact is that this Bonus lib has absolutely nothing to do with the others.

The design here is absolutely my own, from the loops in the functions to the structures in the background.

And let me also mention that giving Earth-Fury credit for my own design is stupid.

In UnitIndexer/UnitEvent, the code is also drastically different from other systems >.>.
Level 14
Nov 18, 2007
- Clean API [same as with EFs BonusMod]
- Short script (relatively) [and that makes this better in what way again?]
- Safe and fast LUA installation [BonusMod is about as easy to install, if not easier]
- Safe LUA generation [which noone ever needed or will ever need]

That leaves us with exactly 0 points in favour of this resource ... maybe half a point in the very unlikely event youll actually have to manually adjust 8 lines in BonusMod, like replacing a '(' with a '%'.

But wait, maybe theres even some unmentioned merits to EFs version.
Lets try this:
- actually safe
- extensible (easily)
- max life/mana is handled way better
- has a movement speed bonus
- its actually readable.
Level 31
Jul 10, 2007
Eh you forgot this >.>. Last time I checked, this was the only script with this config in it.
    *                                   POWER
    *   Power determines how big a bonus range can go. For example, a power of 15 would be
    *   -(2^16) to 2^(16-1), or -65536 to 65535.
    //! i powers[armor] = 12                      --bonus armor
    //! i powers[damage] = 15                     --bonus damage
    //! i powers[agility] = 13                    --bonus agility
    //! i powers[strength] = 13                   --bonus strength
    //! i powers[intelligence] = 13               --bonus intelligence
    //! i powers[life] = 19                       --bonus life
    //! i powers[liferegen] = 15                  --bonus life regen
    //! i powers[mana] = 19                       --bonus mana
    //! i powers[manaregen] = 8                   --bonus mana regen (%) (8 max?)
    //! i powers[sight] = 10                      --bonus sight range (10 max)
    //! i powers[attackspeed] = 8                 --bonus attack speed (%) (8 max)
    *                                   ENABLED
    *   Should the bonus be implemented into the system? By disabling a bonus, it will be
    *   be in the system at all. Abilities and constants won't be made.
    //! i enabled[armor] = true                   --bonus armor
    //! i enabled[damage] = true                  --bonus damage
    //! i enabled[agility] = true                 --bonus agility
    //! i enabled[strength] = true                --bonus strength
    //! i enabled[intelligence] = true            --bonus intelligence
    //! i enabled[life] = true                    --bonus life
    //! i enabled[liferegen] = true               --bonus life regen
    //! i enabled[mana] = true                    --bonus mana
    //! i enabled[manaregen] = true               --bonus mana regen (%)
    //! i enabled[sight] = true                   --bonus sight range
    //! i enabled[attackspeed] = true             --bonus attack speed (%)

Furthermore, I can argue that a library should only have the minimum amount required in it to run. Anything extra can be a separate library.

For example, movement speed can be an entirely separate resource since it doesn't deal with abilities.

Maximum hp/mana handling can be an entirely separate resource: function wrappers for this resource.

That is the reason they are not in here.

Also, because any non ability bonus is handled very differently from ability bonuses, I haven't made this extensible as it'd be a major efficiency loss.

Also, I personally think that this is a major point for a script that generates so many abilities-
Safe LUA generation [which noone ever needed or will ever need]
Not that your libraries were readable in the first place, so in the end it doesn't even matter.

I think time is better spent coming up with real ways to improve on things, come up with new ideas, etc. That's how creativity is maximized. From my experience, playing around in poop definitely is not conducive to creativity (figuratively speaking).
Level 31
Jul 10, 2007
Nothing is perfectly optimal! Believing that this resource is perfectly optimal will limit you, .. and it!

Well, there was one thing that could be improved (improved it just now). The not n at line 87. Excluding naming and (var names, func names, lib name, etc) and encapsulation (private vars have longer names), there's nothing else ;D.

Try seeing if you can find anything in the vJASS code that could possibly be faster another way =P.
Level 14
Nov 18, 2007
Furthermore, I can argue that a library should only have the minimum amount required in it to run. Anything extra can be a separate library.
And i wouldnt argue against that. Its just that BonusMod has extension libraries that supply a few bonuses which require other libraries, like max HP/Mana or movement speed.

Maximum hp/mana handling can be an entirely separate resource: function wrappers for this resource.
I wouldnt recommend doing that. Theres a reason BonusMod uses another library to supply that bonus. Its because that other library uses a certain trick that allows adding theoretically infinite HP/Mana (itll overflow eventually, but thats not the point).

Also, because any non ability bonus is handled very differently from ability bonuses, I haven't made this extensible as it'd be a major efficiency loss.
Its pointless to worry about this, how often do you think youll have to adjust a units bonuses? 32 times a second? Try once every 5 seconds.

Also, I personally think that this is a major point for a script that generates so many abilities-
As i mentioned before, its not as important as you think it is. Sure, in the event there actually is a collision, your libraries would have an advantage. Until then, theyre just overhead.
Do i need to mention that ive never had two public libraries collide using their default settings?
Level 10
May 27, 2009
well for me i still prefer bonusmod rather than this one, i like the easy to understand api for adding custom bonuses (since the custom bonuses here are implemented in lua, that makes me sick)

anyways improve readability D: or just some spaces between functions, my eyes are spinning xD

(please don't fight me)
Nest, do you allow me to make a demo (updated of course) of your Bonus using non-lua? :3

Do it. O_O

Can't do a non Lua version as there are too many abilities. That is never going to happen =). If you want to use this, suck it up and use Lua ; P.

I'd do the same thing if I was in your shoes, so who am I to judge :p
Level 7
Dec 3, 2006
I might end up using this; since BonusMod's lua script is apparently bugging with the cJASS parser? Has anyone else had this problem? I think it's cause of the ( inside the " " 's for the lua script or something like that.

I'd switch to this; but it'd be better if things like MovementBonus, and SetUnitMaxState libraries were made to work with this new structure somewhat.

Also a way to improve upon MovmentBonus from what i've heard -80% = no movement.
Last edited:
Level 31
Jul 10, 2007
Well, actually, I am planning to update this eventually. I have the new version of this 99% written, I just have to finish it ; |. I've been procrastinating the fine bits of code ; P.

The update features better Lua code, a good SetUnitMaxState, and I've decided to include MovementBonus % as SetUnitMoveSpeed doesn't achieve the same thing or show the bonuses on that =).
Level 6
Jun 20, 2011
Nes if it isn't much to ask, please add support for "raw damage" bonus using the item bonus damage ability, it would come in handy to know the current attack damage of a unit if it's fully coded up from 0.