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

[vJASS] For some reason this formula doesn't work:S

Status
Not open for further replies.
Level 19
Joined
Oct 12, 2007
Messages
1,821
Hey there.

In the ORPG I'm working on players can increase their mana regeneration with a custom stat. This stat is called 'Wisdom'.
With some math I made 2 formula's to calculate the mana regeneration bonus a unit should get from a specific amount of Wisdom, however the higher the level of the unit, the more Wisdom he will need for the same amount of mana regeneration increasement.

If the unit is under level 11 then he will use this formula:
Bonus (in %) = (( Wisdom / (1+(HeroLevel*0.13)))*4) / 100

If the unit is above level 10 then he will use this formula:
Bonus (in %) = (Wisdom / (16*(HeroLevel - 6)/150)) / 100


I'm using a binair system in my map that adds this mana regeneration with the help of this function: call UnitModifyManaRegenPercent(Unit,Amount)
If the amount is negative it will (obviously) reduce the mana regeneration of that unit.

Now for some reason I can't get this to work in my map.
This is what I've got to test:

JASS:
scope MapInit initializer Init

function Wisdom takes nothing returns nothing
    local integer i = GetPlayerId(GetTriggerPlayer())
    local unit u = PlayerHero[i]
    local integer int = S2I(SubString(GetEventPlayerChatString(),8,StringLength(GetEventPlayerChatString())))

///PlayerEnergyReg[] is a real, PlayerWisdom[] is an integer///    
        call UnitModifyManaRegenPercent(u,-PlayerEnergyReg[i]) ///Setting the reg to 0
        set PlayerWisdom[i] = int
        if GetHeroLevel(u) < 11 then
            set PlayerEnergyReg[i] = ((PlayerWisdom[i]/(1+(GetHeroLevel(u)*0.13)))*4)/100
        else
            set PlayerEnergyReg[i] = (PlayerWisdom[i]/(16*(GetHeroLevel(u)-6)/150))/100
        endif
        call UnitModifyManaRegenPercent(u,PlayerEnergyReg[i]) ///Should set the reg to a value, but currently it looks like it stays at 0
endfunction

function Init takes nothing returns nothing
    local trigger Trig
    local integer i = 0
    
    loop
    exitwhen i > GetPlayers()
     
    set Trig = CreateTrigger()
    call TriggerRegisterPlayerChatEvent(Trig,Player(i),"-Wisdom ", false)
    call TriggerAddAction(Trig,function Wisdom)
   
    
    endloop

    set Trig = null
endfunction

endscope
 
Level 5
Joined
Jun 16, 2004
Messages
108
The level < 11 calculation should work, if it is not you might need to double check other things. Maybe that UnitModifyManaRegenPercent is not working.

The level >= 11 condition likely will fail, though. In order for it to actually return any value > 0 it probably needs a hero level >= 16, and a wisdom value >= 100. Assuming my calculations are correct, if the hero level is not >= 16 then the thread will simply crash, and if wisdom is not >= 100 then the value will be 0. The reason for this being that despite PlayerEnergyReg being a real, the calculation on the right of it (for the >= 11 condition) is entirely made up of integer operations.

Integers of course cannot store a decimal value. So when you do something with say hero level 15, the operation becomes (16 * (15 - 6) / 150) which is 144/150 = 0; to which you enter a division by zero next with wisdom / 0. The fix for this is simple, just affix a dot to your numbers when you want them to be treated as reals, thus using real arithmetic rather than integer arithmetic. You can also use I2R, but simply multiplying an integer by 1. achieves the same casting effect if you want it to be explicitly shown.

An operation using an integer and a real will implicitly cast the integer to a real, also. So 1 / 2. would return 0.5 for example, 1. / 2 would return 0.5, but 1 / 2 would return 0.

The reason the < 11 calculation should work, if the explanation above does not make it clear, is because the first thing that occurs is (GetHeroLevel(u)*0.13), which implicitly converts the integer value returned by GetHeroLevel to a real, then the operation itself returns a real, and it then serves to implicitly cast every other integer to a real as the operations go on.
 
Level 19
Joined
Oct 12, 2007
Messages
1,821
Alright thanks for that, I'll fix that.
However that won't explain why my tests didn't result into any mana regeneration being added.
I set my hero level to 30, and gave him 500 Wisdom with the chat command. In my excel sheet I saw that should give 195.31% bonus mana reg, so this should make PlayerEnergyReg to 195. But for some reason the hero doesn't receive this bonus. hmm.
Should I maybe add the stat system I'm using for this as a requirement at the first line of this trigger?
 
Level 5
Joined
Jun 16, 2004
Messages
108
JASS:
loop
    exitwhen i > GetPlayers()
     
    set Trig = CreateTrigger()
    call TriggerRegisterPlayerChatEvent(Trig,Player(i),"-Wisdom ", false)
    call TriggerAddAction(Trig,function Wisdom)
   
    
    endloop

Looks like you do not ever increment i, so you might be registering the trigger for only the first player again and again. So if you were not testing as player(0) that may be the cause.

Trying to add the stat system as a requirement should not be necessary, you would be getting errors on save if it was not considered beforehand. When I said to check if that function was working, I figured you could just call it arbitrarily on a specific unit in a situation you know it should not fail (to verify that it actually works). You could also try throwing a BJDebugMsg in there to verify that your calculation is working and that the trigger actually gets that far.
 
Level 19
Joined
Oct 12, 2007
Messages
1,821
Ah yeah thanks for pointing out that mistake, however I tried it as Player(0) so it wouldn't matter.
However I found the problem with a Debugmsg now! I'm not a math genius so I never tried the formula's out outside excel and apperantly the /100 in the end shouldn't have been there. Because when I want a value of 250 for PlayerEnergyReg I currently get 2.5. Which means when I tried to add a 100% bonus to regeneration I ended up giving myself a 1% bonus, that's why I never noticed the difference.;-)
 
Status
Not open for further replies.
Top