• 🏆 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!

how do they use it?

Status
Not open for further replies.

Chaosy

Tutorial Reviewer
Level 40
Joined
Jun 9, 2011
Messages
13,183
hey, have been thinking of it a few times but I can't seem to find it out.
I have seen systems that give bonus stat's example bonusmod or bonus those are not what made me ask this but they are known examples.

they use stuff like this
  • Set Bonus_Ability[0] = Item Armor Bonus (+1)
  • Set Bonus_Ability[1] = Item Armor Bonus (+2)
  • Set Bonus_Ability[2] = Item Armor Bonus (+4)
  • Set Bonus_Ability[3] = Item Armor Bonus (+8)
  • Set Bonus_Ability[4] = Item Armor Bonus (+16)
  • Set Bonus_Ability[5] = Item Armor Bonus (+32)
  • Set Bonus_Ability[6] = Item Armor Bonus (+64)
  • Set Bonus_Ability[7] = Item Armor Bonus (+128)
  • Set Bonus_Ability[8] = Item Armor Bonus (+256)
  • Set Bonus_Ability[9] = Item Armor Bonus (+512
and I want to know how do they use that? you certainly need some kind of calculation to make it fit but as said I can't think of a working way.

example if I want to add 7 armor should I add first 6 armor and then 1 armor? will those stack? and how do I calculate which ones to use
 
Level 37
Joined
Mar 6, 2006
Messages
9,240
Yes, they stack, and that is how it works.

99 bonus = 64+32+2+1

A "brute force" method is to first remove all the bonus abilities from the unit. Then you loop from 9 to 0.
if bonus[loopA] < armorToGive then
--add bonus[loopA] to unit
--set armorToGive = armorToGive - bonus[loopA]
endif

When you get that working, you can begin to think of ways to improve the method.
 
Yes, they stack, and that is how it works.

99 bonus = 64+32+2+1

A "brute force" method is to first remove all the bonus abilities from the unit. Then you loop from 9 to 0.
if bonus[loopA] < armorToGive then
--add bonus[loopA] to unit
--set armorToGive = armorToGive - bonus[loopA]
endif

When you get that working, you can begin to think of ways to improve the method.
That doesn't work for example with armor: 5


You'll have to work it the other way around

  • For each (Integer A) from 0 to 9, do (Actions)
    • Loop - Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • armorToGive Greater than or equal to (Integer((Power(2.00, (9.00 - (Real((Integer A))))))))
        • Then - Actions
          • Unit - Add (bonus[9-(Integer A)]) to Unit
          • Set armorToGive = armorToGive - (Power(2.00, (Real((9 - (Integer A))))))
        • Else - Actions

Edit:
Oh, didn't notice you said loop from 9 to 0.
Well it works then but I'd still directly use the powers of 2 in the comparison instead of manually writing them down into some index.
Also loops are assumed to have the end value higher than the start value.
 
Level 28
Joined
Jan 26, 2007
Messages
4,789
It works with binary. Since binary is just another base system, it means any number can be made with it.
With "amount" abilities, you can give any bonus between -2amount-1 and 2amount-1 - 1.
Because of that fact, it's a very cost-efficient concerning abilities/ability levels
(16 abilities is enough for all numbers between -32k and 32k, this is impossible for systems that use +1 bonus stat per ability level).

As others have said before me, you start with the highest number (like +512) and then go down all the way to +1 in the loop.
If the amount you want to give is higher than that power of 2, you give him the ability (see Maker's post for an example, +99 in that case).

I've re-created this system in GUI some time ago (with JASS for the loop).
  • Set Bonus_Int = Bonus_AbilityAmount
  • -------- Set the bonus stat to the correct amount --------
  • Custom script: loop
  • Set Bonus_Int = (Bonus_Int - 1)
  • Custom script: exitwhen udg_Bonus_Int <= 0 or udg_Bonus_Amount == 0
  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
    • If - Conditions
      • Bonus_Amount Greater than or equal to Bonus_PowersOf2[Bonus_Int]
    • Then - Actions
      • Unit - Add Bonus_Abilities[((Bonus_Type x Bonus_AbilityAmount) + Bonus_Int)] to Bonus_Unit
      • Set Bonus_Amount = (Bonus_Amount - Bonus_PowersOf2[Bonus_Int])
    • Else - Actions
      • Unit - Remove Bonus_Abilities[((Bonus_Type x Bonus_AbilityAmount) + Bonus_Int)] from Bonus_Unit
  • Custom script: endloop
"Bonus_Amount" is the amount of the bonus stat you're going to give (like +53 attack --> BonusAmount = +53).
"Bonus_Type" is the bonus type :p (in my case: 0 = damage, 1 = armor, ... )
"PowersOf2" is a variable that contains 1, 2, 4, 8, ... (you know, the powers of 2).
 
Level 37
Joined
Mar 6, 2006
Messages
9,240
Well it works then but I'd still directly use the powers of 2 in the comparison instead of manually writing them down into some index.
Also loops are assumed to have the end value higher than the start value.

Yes, in GUI you can't relly use default loops that have greater starting number than the end number, since internally the functions increment the looping integer.

In jass and coding in general you can loop whichever way you want, and is best for your system.

Ideally one would precalculate the values into arrays so there would be no repeated calculations.

I recommend to check out some approved bonus system, the best method can be found there.
 
Level 28
Joined
Jan 26, 2007
Messages
4,789
I went through apocalypses trigger and it seems to be 2 bugs. If I want to add 9 armor it adds 8,4,2,1= 15 and then the index is too high 1 x 9 + 1 = 10
That shouldn't be the case. At least, not if you decrease Bonus_Amount.

Example:
Bonus_Amount = 9

Loop
Bonus_Amount >= 8 --> add +8 armor
set Bonus_Amount = 1 ( = 9 - 8)
Bonus_Amount < 4 (skip)
Bonus_Amount < 2 (skip)
Bonus_Amount >= 1 --> add +1 armor
set Bonus_Amount = 0 (= 1 - 1)
endloop

I do want to note that my PowersOf2-variable might be confusing: PowersOf2[1] = 1 (as opposed to 2, because 21 = 2).

Here's the map (still had it in pastebin, just updated it to add a few comments).
 

Chaosy

Tutorial Reviewer
Level 40
Joined
Jun 9, 2011
Messages
13,183
I found out how to work with it and it worked fine when I tried it but it will only work once for me.
  • init
    • Events
      • Map initialization
    • Conditions
    • Actions
      • Set armor_bonus[1] = Item Armor Bonus (+1)
      • Set armor_bonus[2] = Item Armor Bonus (+2)
      • Set armor_bonus[3] = Item Armor Bonus (+4)
      • Set armor_bonus[4] = Item Armor Bonus (+8)
      • Set armor_bonus[5] = Item Armor Bonus (+16)
      • Set armor_bonus[6] = Item Armor Bonus (+32)
      • Set armor_bonus[7] = Item Armor Bonus (+64)
      • Set armor_bonus[8] = Item Armor Bonus (+128)
      • Set armor_bonus[9] = Item Armor Bonus (+256)
      • Set armor_bonus[10] = Item Armor Bonus (+512)
      • Set armor_value[1] = 1
      • Set armor_value[2] = 2
      • Set armor_value[3] = 4
      • Set armor_value[4] = 8
      • Set armor_value[5] = 16
      • Set armor_value[6] = 32
      • Set armor_value[7] = 64
      • Set armor_value[8] = 128
      • Set armor_value[9] = 256
      • Set armor_value[10] = 512
      • Set count = 10
  • system
    • Events
    • Conditions
    • Actions
      • Set temp_integer = count
      • Custom script: loop
      • Set temp_integer = (temp_integer - 1)
      • Custom script: exitwhen udg_temp_integer <= 0 or udg_ammout == 0
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • ammout Greater than or equal to armor_value[temp_integer]
        • Then - Actions
          • Set ammout = (ammout - armor_value[temp_integer])
          • Unit - Add armor_bonus[temp_integer] to target
        • Else - Actions
      • Custom script: endloop
 
Level 37
Joined
Mar 6, 2006
Messages
9,240
It is because you also need to remove the abilties that are not needed.

For example if you get +5 and +5 bonuses, your script adds 4 and 1. When you run it the second time, it tries to add 4 and 1. But the unit already has the abilities, so no additional bonus is gotten. You need to remove the 4 and 1, and add 8 and 2.
 
Level 28
Joined
Jan 26, 2007
Messages
4,789
so I just put the remove in the "else" part?
Yep, in case you've got any doubts:
ap0calypse said:
  • Set Bonus_Int = Bonus_AbilityAmount
  • -------- Set the bonus stat to the correct amount --------
  • Custom script: loop
  • Set Bonus_Int = (Bonus_Int - 1)
  • Custom script: exitwhen udg_Bonus_Int <= 0 or udg_Bonus_Amount == 0
  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
    • If - Conditions
      • Bonus_Amount Greater than or equal to Bonus_PowersOf2[Bonus_Int]
    • Then - Actions
      • Unit - Add Bonus_Abilities[((Bonus_Type x Bonus_AbilityAmount) + Bonus_Int)] to Bonus_Unit
      • Set Bonus_Amount = (Bonus_Amount - Bonus_PowersOf2[Bonus_Int])
    • Else - Actions
      • Unit - Remove Bonus_Abilities[((Bonus_Type x Bonus_AbilityAmount) + Bonus_Int)] from Bonus_Unit
  • Custom script: endloop
"Bonus_Amount" is the amount of the bonus stat you're going to give (like +53 attack --> BonusAmount = +53).
"Bonus_Type" is the bonus type :p (in my case: 0 = damage, 1 = armor, ... )
"PowersOf2" is a variable that contains 1, 2, 4, 8, ... (you know, the powers of 2).
 
Level 28
Joined
Jan 26, 2007
Messages
4,789
So your variable "ammout" (sic) determines how much armor you gain, right?
This is what you can do: loop from 1 to 10 and see if the ability level of armor_bonus[loop] is greater than 0 (this means he has that ability).
If so, set ammout = ammout + armor_value[loop].

Then you can set ammout = ammout + bonus and then "bonus" armor will be added to the current value.
 

Chaosy

Tutorial Reviewer
Level 40
Joined
Jun 9, 2011
Messages
13,183
Yes, that should work sadly it bugs for me again -.-. I tried 2 diferent methods before your and they got 10 + 10 = 14 for some reason and your way seems to bug atleast in my trigger.
  • system
    • Events
    • Conditions
    • Actions
      • Set temp_integer = count
      • Custom script: loop
      • Set temp_integer = (temp_integer - 1)
      • Custom script: exitwhen udg_temp_integer <= 0 or udg_ammout == 0
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Level of armor_bonus[temp_integer] for target) Greater than 0
        • Then - Actions
          • Set ammout = (ammout + armor_value[temp_integer])
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • ammout Greater than or equal to armor_value[temp_integer]
            • Then - Actions
              • Set ammout = (ammout - armor_value[temp_integer])
              • Unit - Add armor_bonus[temp_integer] to target
            • Else - Actions
              • Unit - Remove armor_bonus[temp_integer] from target
        • Else - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • ammout Greater than or equal to armor_value[temp_integer]
            • Then - Actions
              • Set ammout = (ammout - armor_value[temp_integer])
              • Unit - Add armor_bonus[temp_integer] to target
            • Else - Actions
              • Unit - Remove armor_bonus[temp_integer] from target
      • Custom script: endloop
 
Level 28
Joined
Jan 26, 2007
Messages
4,789
Oh, you should do it in 2 different loops though. Not the same one.
First you loop to set the amount correctly (if a unit has +10 armor, then ammout will be set to 10).
Then you need to increase that variable by the added bonus (let's say you want to add +4 armor, then ammout will be 10 + 4 = 14).

And only now can you do the loop where you actually add the bonuses.
 

Chaosy

Tutorial Reviewer
Level 40
Joined
Jun 9, 2011
Messages
13,183
ok, added the second loop but it still bugs but now 10 + 10 = 22

  • init
    • Events
      • Map initialization
    • Conditions
    • Actions
      • Set armor_bonus[1] = Item Armor Bonus (+1)
      • Set armor_bonus[2] = Item Armor Bonus (+2)
      • Set armor_bonus[3] = Item Armor Bonus (+4)
      • Set armor_bonus[4] = Item Armor Bonus (+8)
      • Set armor_bonus[5] = Item Armor Bonus (+16)
      • Set armor_bonus[6] = Item Armor Bonus (+32)
      • Set armor_bonus[7] = Item Armor Bonus (+64)
      • Set armor_bonus[8] = Item Armor Bonus (+128)
      • Set armor_bonus[9] = Item Armor Bonus (+256)
      • Set armor_bonus[10] = Item Armor Bonus (+512)
      • Set armor_value[1] = 1
      • Set armor_value[2] = 2
      • Set armor_value[3] = 4
      • Set armor_value[4] = 8
      • Set armor_value[5] = 16
      • Set armor_value[6] = 32
      • Set armor_value[7] = 64
      • Set armor_value[8] = 128
      • Set armor_value[9] = 256
      • Set armor_value[10] = 512
      • Set count = 10
  • system
    • Events
    • Conditions
    • Actions
      • For each (Integer A) from 1 to 10, do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Level of armor_bonus[(Integer A)] for target) Greater than 0
            • Then - Actions
              • Set ammout = (ammout + armor_value[(Integer A)])
            • Else - Actions
      • Set temp_integer = count
      • Custom script: loop
      • Set temp_integer = (temp_integer - 1)
      • Custom script: exitwhen udg_temp_integer <= 0 or udg_ammout == 0
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • ammout Greater than or equal to armor_value[temp_integer]
        • Then - Actions
          • Set ammout = (ammout - armor_value[temp_integer])
          • Unit - Add armor_bonus[temp_integer] to target
        • Else - Actions
          • Unit - Remove armor_bonus[temp_integer] from target
      • Custom script: endloop
  • demo
    • Events
      • Player - Player 1 (Red) skips a cinematic sequence
    • Conditions
    • Actions
      • Set target = Paladin 0000 <gen>
      • Set ammout = 10
      • Trigger - Run system <gen> (checking conditions)



EDIT: I tried setting a debug msg after the new value of "ammout" set.
first execute: no msg 10 armor added
second execute: msg 1 = 12 + msg 2 = 22
 
Level 19
Joined
Aug 8, 2007
Messages
2,765
why cant u just do...

temp int = armor to gain
temp int 2 = tempint (only initialization)
armor list = 1,2,4,8,...
armor abil list = +1 armor,...
loop (loopInt 10 to 1)
if temp int > loop[armor list] then
set temp int = temp int - armor list[loop]
add armor ability list[loop] to unit
endloop

your *trying* to do this but i dont follow you
 
Level 28
Joined
Jan 26, 2007
Messages
4,789
@Arhowk: "temp int2" is obsolete there, and I believe Chaosy got that part to work (setting the bonus).

Hmh, Chaosy: did you look at the map I linked before?
It contains a "GetUnitBonus"-function (in semi-GUI). It saves the current bonus of the unit in "Bonus_Amount" and you can then change Bonus_Amount to add (instead of set) the bonus stat.
There's an "Increase Armor"-trigger, which does what you want to do (I believe).
 
Status
Not open for further replies.
Top