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

[Snippet] Set unit range partial fix

Hello there, the native BlzSetUnitWeaponRealFieldBJ is bugged for setting the range (UNIT_WEAPON_RF_ATTACK_RANGE).
☼ Doesn't work for the weapon index 2
☼ For weapon index 1, will add the new range minus the difference between the base value of weapon 1 and 2

Also some getter/setter are based on index 0 and 1, as other are based on 1 and 2 which can be confusing.

For example, setting a peasant range to 100 will add 100 - (90-66) = 34 instead, so we go from 90 to 124. Setting it again to 100 will add 34 again and again.

This is a tiny snippet to fix this for at least 1.36 and for weapon index 1.

JASS:
// Getter is based on index 0 and 1
// Setter is based on index 1 and 2
// WHY BLIZZARD WHYYYYY
function SetUnitRange takes unit u, real newRange returns nothing
        call BlzSetUnitWeaponRealFieldBJ(u,UNIT_WEAPON_RF_ATTACK_RANGE,1,newRange-BlzGetUnitWeaponRealField(u,UNIT_WEAPON_RF_ATTACK_RANGE,0)+BlzGetUnitWeaponRealField(u,UNIT_WEAPON_RF_ATTACK_RANGE,1))
endfunction

No need to credit me in your map.
If someone has other solutions, even about similar cases, feel free to pursue this topic.
This snipped will be rendered useless once it is fixed, or broken in another way.
 

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,468
Interesting quirk, and wild that this is even required!

I would recommend changing the format of the function for the sake of not having it be a one-line blob. Something like this will allow mult-line formatting without having to create placeholder variables:

JASS:
function SetUnitAttackRange takes unit u, real newRange returns nothing
    call BlzSetUnitWeaponRealFieldBJ(/*
        */ u, /*
        */ UNIT_WEAPON_RF_ATTACK_RANGE, /*
        */ 1, /*
        */ newRange - BlzGetUnitWeaponRealField(/*
            */ u, /*
            */ UNIT_WEAPON_RF_ATTACK_RANGE, /*
            */ 0 /*
        */) + BlzGetUnitWeaponRealField(/*
        */ u, /*
        */ UNIT_WEAPON_RF_ATTACK_RANGE, /*
        */ 1 /*
        */)/*
    */)
endfunction

Or the more JASSy way, like this:

JASS:
function SetUnitAttackRange takes unit u, real newRange returns nothing
    local real attackRange0 = BlzGetUnitWeaponRealField(u, UNIT_WEAPON_RF_ATTACK_RANGE, 0)
    local real attackRange1 = BlzGetUnitWeaponRealField(u, UNIT_WEAPON_RF_ATTACK_RANGE, 1)
    call BlzSetUnitWeaponRealFieldBJ(u, UNIT_WEAPON_RF_ATTACK_RANGE, 1, newRange - attackRange0 + attackRange1)
endfunction
 

Cokemonkey11

Spell Reviewer
Level 29
Joined
May 9, 2006
Messages
3,537
Here is a wurst version

Wurst:
function unit.setAttackRange(real newRange)
    BlzSetUnitWeaponRealField(
        this,
        UNIT_WEAPON_RF_ATTACK_RANGE,
        1,
        newRange
        - BlzGetUnitWeaponRealField(this, UNIT_WEAPON_RF_ATTACK_RANGE, 0)
        + BlzGetUnitWeaponRealField(this, UNIT_WEAPON_RF_ATTACK_RANGE, 1)
    )
 
Top