• 🏆 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!
  • 🏆 Hive's 6th HD Modeling Contest: Mechanical is now open! Design and model a mechanical creature, mechanized animal, a futuristic robotic being, or anything else your imagination can tinker with! 📅 Submissions close on June 30, 2024. Don't miss this opportunity to let your creativity shine! Enter now and show us your mechanical masterpiece! 🔗 Click here to enter!

"SetHeroLevel" problem increasing a level of a hero above 20

Status
Not open for further replies.
Level 1
Joined
Jan 2, 2023
Messages
15
As the title implies I'm having a trouble increasing a hero level above 20.
The custom map I'm developing should have a fixed level for a spawned hero. That way his health pool, attack, speed, etc are easier to manage and is more eye-catchy. However, increasing the level above 35 doesn't work as expected. For example:
JASS:
    local integer index = 1
    local integer iloops = 10
    local integer ilevel = R2I( 60.0 * 1.5 )
    local unit ucaller = GetEnteringUnit()     // implies that the unit enters a region

        // set wanted level and slowly increment it over N iloops
        loop
            //exitwhen ( index > iloops ) or ( GetHeroLevel( ucaller ) >= ilevel )
            exitwhen ( GetHeroLevel( ucaller ) >= ilevel )
           
            // call SetHeroLevel( ucaller, index * ilevel / iloops, false )
            call TriggerSleepAction( 0.5 )
            set index = index + 1
        endloop

In the code above the index value is unbounded and may (possibly) reach 2^31 - 1. However the "SetHeroLevel" function doesn't even gradually increment the hero's level! In the current code example it will start from 35, then jump to 51 and stay there for a minute, until the hero level SUDDENLY reaches the "GameConstant -> Hero Maximum Level".
I tried using a direct "Grant XP" function with 100K as an increment, but it's too small of a value to reach, say, level 120. Using a bigger value to XP increments repeats the above problem: no effects at all for a minute, then jump to the maximum level.
Also, worth mentioning is that "Hero -> XP Gained -> Hero", "Hero -> XP Gained -> Normal", "Hero -> XP Required" are all set to custom values.

How would you deal with it and did you encounter that problem?
 
Last edited:

Uncle

Warcraft Moderator
Level 64
Joined
Aug 10, 2018
Messages
6,584
With your current formula, and assuming you wanted the SetHeroLevel() line to be uncommented, you will end up like this:
0 seconds -> Set level to 9 (90/10)
0.50 seconds -> Set level to 18 (180/10)
1.00 second -> Set level to 27 (270/10)

And that that pattern should continue on and on until you reach level 90.

I imagine the issue lies in either a bug with the more recent patches or the use of TriggerSleepAction() in a For Loop. If I were you I would rely on a Timer that runs once every 0.50 seconds instead of a For Loop with Waits, it will be far more precise and less prone to issues. There are many Jass timer systems that allow you to attach data to your newly created timers so you can do things like reference ucaller in the Callback function. You could also attach the timer to the unit, this way you can easily kill the timer if the unit leaves the region. This will prevent the issue of having multiple of these timers running per unit.
 
Last edited:
Level 1
Joined
Jan 2, 2023
Messages
15
Heh, apparently the issue is with the gameplay constant! "Hero XP Required - Previous Value Factor" which was set to 1.5, which is set to 1.0 by default.
According to the formula provided by thehelper.net:
EXP_REQ = (PREV_VAL * FACTOR_PREV_VAL) + (LEVEL_NEXT * FACTOR_LEVEL) + CONSTANT

Using a "Factor Previous Value" bigger than 1.0 will quickly exhaust the int32 limit, which is 2^31 - 1. Apparently, Blizzard SetHeroLevel native is not just setting/incrementing the current hero level. This native method adds experience required to reach the next level! So when you exhaust the 2^31 limit of experience, you will no longer be able to reach the next level (unless the logic bugs out and grants you the "Game Constant - Hero Maximum Level", skipping every level in between).
Just checked that using a script that would increment the hero level each second, while the FACTOR_PREV_VAL was set to 2.0, FACTOR_LEVEL to 0.0 and "XP Required Table" to 500. Unsurprisingly, after reaching level 22 (which is 500 * 2.0^22 = 2.097B...) the game would not let you level your hero any further and will immediately grant you "Hero Maximum Level" with 0/0 experience points. Case closed.

TLDR: To gradually reach the maximum hero level without problems, make sure that the "maximum hero level" requires less than (2^31) experience points.
 
Last edited:
Level 1
Joined
Jan 2, 2023
Messages
15
Using a bit of a wolframalpha calculator and the factors presented above (FACTOR_LEVEL set to 0), it's easy to procure a required value, like this:
( 500 * ( x ^ (100 - 1) ) ) < ( 2^31 ); x>1.0,
where 500 is a first and only "XP Required Table" value, 100 is the maximum hero level, x is the unknown FACTOR_PREV_VAL.
In this example x lies within a range of ( 1.0; 1.166809 ). Pick 1.16 and you're sure to reach level 99 without problems.

The above formula isn't the best one for obvious reasons (you would need to get like 100 XP to reach level 2). If you would instead set FACTOR_PREV_VAL to 1.0, FACTOR_LEVEL to 400.0 and REQUIRED_TABLE_VALUE to 400 then the following formula would suffice:
( ( x / 2) * ( 400 * ( x - 1 ) ) + 400 * ( x - 2 ) ),
where X is the level you wish to reach.
 
Last edited:
Status
Not open for further replies.
Top