[Snippet] Set unit range partial fix & Set unit AoE Small fix

Hello there, the native BlzSetUnitWeaponRealField (and BJ too) 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 BlzSetUnitWeaponRealField(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
 
// Setting small AoE range for a unit also sets its attack cooldown and the range at index 1...
// Why ? I don't know. Here's a fix.
// Must test with the other types of AoE and indexes
function SetUnitAoESmall takes unit u, integer index, real newAoE returns nothing
    local real r=BlzGetUnitAttackCooldown(u,index)
    local real r2=BlzGetUnitWeaponRealField(u,UNIT_WEAPON_RF_ATTACK_RANGE,0)
    call BlzSetUnitWeaponRealField(u,UNIT_WEAPON_RF_ATTACK_AREA_OF_EFFECT_SMALL_DAMAGE,index,newAoE)
    call BlzSetUnitAttackCooldown(u,r,index)
    call SetUnitRange(u,r2)
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 snippet will be rendered useless once it is fixed, or broken in another way.
 
Last edited:
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
 
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)
    )
 
Code:
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

can you explain why you subtract weapon 0 range from weapon1 range?

@Cokemonkey11

 
Top