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

List of non-working object data constants

Status
Not open for further replies.
The thread specifically addresses which object data related constants cannot be modified, work, or are problematic in some cases in the most recent patches (Not including the World Editor). This is a list in progress, so it may not yet include all the dysfunctional constants.

  • (8/17/19) - Thread post
  • (8/17/19) - Added UNIT_IF_HIT_POINTS_REGENERATION_TYPE

Legend:

elements in nonFunctional tables -> Do not work, but do not crash the game.
elements in problematic tables -> Do work, but will crash at certain values.

Lua:
nonFunctional = {
    ABILITY_SF_NAME
}

Lua:
problematic = {
    UNIT_IF_DEFENSE_TYPE,  -- Suspected that values exceeding 7 will not behave as intended
                              -- Values 8 - 15 are just translated up by 8 (hides the armor icon)
                              -- Values 16 - 23 hide information (translated up)
                              -- Values 24, 26 display attribute icons (don't know why that happens).
                              -- Values including 25 and exceeding 26 will crash the game (most likely).
    UNIT_IF_INTELLIGENCE_PERMANENT,
    UNIT_IF_AGILITY_PERMANENT,
    UNIT_IF_STRENGTH_PERMANENT
                              -- They do not return the updated values when set via
                              -- BlzSetUnitIntegerField. (Only returns 1).
}
nonfunctional = {
    UNIT_IF_INTELLIGENCE_WITH_BONUS,
    UNIT_IF_AGILITY_WITH_BONUS,
    UNIT_IF_STRENGTH_WITH_BONUS,
    UNIT_IF_PRIMARY_ATTRIBUTE,
    UNIT_IF_HIT_POINTS_REGENERATION_TYPE
                              -- Even if the result is successful, this does not actually change
                              -- the regeneration type.
}

Lua:
nonFunctional = {
    UNIT_RF_TURN_RATE,
    UNIT_RF_MANA,
    UNIT_RF_MAXIMUM_PITCH_ANGLE_DEGREES,
    UNIT_RF_MAXIMUM_ROLL_ANGLE_DEGREES,
    UNIT_RF_SHADOW_IMAGE_WIDTH
    UNIT_RF_FLY_HEIGHT
    UNIT_RF_SHADOW_IMAGE_HEIGHT
    UNIT_RF_SPEED
                             -- Some of these may update in game time (They do not immediately
                                 return the assigned value from the setter, though this is mostly speculation).
}

Lua:
problematic = {
    UNIT_SF_NAME   -- Do not pass "" as a parameter (crashes the game)
                              -- Appears to modify proper name as well.
}

Lua:
nonFunctional = {

    UNIT_WEAPON_IF_ATTACK_DAMAGE_NUMBER_OF_DICE
    UNIT_WEAPON_IF_ATTACK_MAXIMUM_NUMBER_OF_TARGETS
    UNIT_WEAPON_IF_ATTACK_ATTACK_TYPE
    UNIT_WEAPON_IF_ATTACK_AREA_OF_EFFECT_TARGETS[/FONT]

    UNIT_WEAPON_IF_ATTACK_DAMAGE_BASE
    UNIT_WEAPON_IF_ATTACK_DAMAGE_SIDES_PER_DIE
    UNIT_WEAPON_IF_ATTACK_TARGETS_ALLOWED
    UNIT_WEAPON_IF_ATTACK_WEAPON_SOUND
        -- Virtually all fields do not work
}

Lua:
nonfunctional = {
    -- Virtually all fields do not work in wc3 1.31
}


Lua:
nonfunctional = {
    -- Virtually all fields do not work in 1.31
}
functional = {
    UNIT_WEAPON_BF_ATTACKS_ENABLED    -- Doesn't work as stated beforehand, but works on Reforged. Credit to J2Krauser for this finding.
}

Lua:
nonfunctional = {
    UNIT_WEAPON_SF_ATTACK_PROJECTILE_ART
                                           -- Cannot be modified for melee units.
                                           -- Does not appear to change the model even when
                                           -- applied.
}

If you want to test things out, you can use the following script (scripting language must be in Lua):
Lua:
ObjectEditorTypes = {
    --  Ability-related fields.
    IF = {exclude=true},
    RF = {exclude=true},
    SF = {exclude=true},
    BF = {exclude=true},
    ILF = {exclude=true},
    RLF = {exclude=true},
    SLF = {exclude=true},
    BLF = {exclude=true},

    --  Unit-related fields.
    UIF = {exclude=false},
    URF = {exclude=true},
    USF = {exclude=true},
    UBF = {exclude=true},
    UWIF = {exclude=true},
    UWRF = {exclude=true},
    UWSF = {exclude=true},
    UWBF = {exclude=true},
}
ObjectEditorTypes.initialized   = false
ObjectEditorTypes.doManipulate  = true
ObjectEditorTypes.breakpoint    = nil
ObjectEditorTypes.abilityIndex  = 3

function OnSelect(u)
    if not ObjectEditorTypes.initialized then
        for k, v in pairs(_G) do
            if k:sub(1, 7) == 'ABILITY' then
                local j = 9
                local i = j
                while true do
                    if k:sub(j, j) == '_' then break end
                    j = j + 1
                end
                local str = k:sub(i, j-1)
                if not ObjectEditorTypes[str].exclude then ObjectEditorTypes[str][k] = v end
            elseif k:sub(1, 4) == 'UNIT' then
                local usub = k:sub(6, 7)
                if usub == 'IF' or usub == 'RF' or usub == 'BF' or usub == 'SF' then
                    usub = 'U' .. usub
                    if not ObjectEditorTypes[usub].exclude then ObjectEditorTypes[usub][k] = v end
                else
                    usub = k:sub(6, 11)
                    if usub == 'WEAPON' then
usub = k:sub(13, 14)
                        if usub == 'IF' or usub == 'RF' or usub == 'BF' or usub == 'SF' then
                            usub = 'UW' .. usub
                            if not ObjectEditorTypes[usub].exclude then ObjectEditorTypes[usub][k] = v end
                        end
                    end
                end
            end
        end
        ObjectEditorTypes.initialized = true
    end
    local abil   = BlzGetUnitAbilityByIndex(u, ObjectEditorTypes.abilityIndex)
    if abil == nil then
        print('|cffffcc00Error:|r Ability index is nil.')
        return
    end
    local metaFactory = function(param)
        local f = function(str, strname, setter, getter, ...)
            if ObjectEditorTypes[str].exclude then return end
            local i             = 1
            local params        = table.pack(...)
            local paramcount    = #params
            local lastparam     = params[paramcount]
            local strs          = ""

            table.remove(params, n)

            for k1, v1 in pairs(ObjectEditorTypes[str]) do
                if ObjectEditorTypes.breakpoint ~= nil and i > ObjectEditorTypes.breakpoint then break end
                if k1 ~= 'exclude' then
                    if not ObjectEditorTypes.doManipulate then
                        print(strname .. ': Parameter [' .. tostring(i) .. '] ' .. tostring(k1) .. ' being read.')
                    else
                        local result = pcall(setter, param, v1, ...)
                        table.remove(params, paramcount)

                        local success, presult = pcall(getter, param, v1, table.unpack(params))
                        result = result and (presult == lastparam)
                        if not result then
                            print('|cffff2020' .. strname .. ':|r Parameter [' .. tostring(i) .. '] ' .. tostring(k1) .. ' cannot be modified.')
                            print('Expected: ' .. tostring(lastparam) .. '; Observed: ' .. tostring(presult))
                        else
                            print(strname .. ': Parameter [' .. tostring(i) .. '] ' .. tostring(k1) .. ' was successfully modified.')
                        end
                    end
                else
                    i = i - 1
                end
                i = i + 1
            end
        end
        return f
    end
    local abilFactory = metaFactory(abil)
    local unitFactory = metaFactory(u)

    abilFactory('IF', 'AbilityIntegerField', BlzSetAbilityIntegerField, BlzGetAbilityIntegerField, 0)
    abilFactory('RF', 'AbilityRealField', BlzSetAbilityRealField, BlzGetAbilityRealField, 0.)
    abilFactory('SF', 'AbilityStringField', BlzSetAbilityStringField, BlzGetAbilityStringField, "")
    abilFactory('BF', 'AbilityBooleanField', BlzSetAbilityBooleanField, BlzGetAbilityBooleanField, false)

    abilFactory('ILF', 'AbilityIntegerLevelField', BlzSetAbilityIntegerLevelField, BlzGetAbilityIntegerLevelField, 0, 0)
    abilFactory('RLF', 'AbilityRealLevelField', BlzSetAbilityRealLevelField, BlzGetAbilityRealLevelField, 0, 0.)
    abilFactory('SLF', 'AbilityStringLevelField', BlzSetAbilityStringLevelField, BlzGetAbilityStringLevelField, 0, "")
    abilFactory('BLF', 'AbilityBooleanLevelField', BlzSetAbilityBooleanLevelField, BlzGetAbilityBooleanLevelField, 0, false)

    unitFactory('UIF', 'UnitIntegerField', BlzSetUnitIntegerField, BlzGetUnitIntegerField, 6)
    unitFactory('URF', 'UnitRealField', BlzSetUnitRealField, BlzGetUnitRealField, 750.)
    unitFactory('USF', 'UnitStringField', BlzSetUnitStringField, BlzGetUnitStringField, "Horse")
    unitFactory('UBF', 'UnitBooleanField', BlzSetUnitBooleanField, BlzGetUnitBooleanField, true)

    unitFactory('UWIF', 'UnitWeaponIntegerField', BlzSetUnitWeaponIntegerField, BlzGetUnitWeaponIntegerField, 0, 500)
    unitFactory('UWRF', 'UnitWeaponRealField', BlzSetUnitWeaponRealField, BlzGetUnitWeaponRealField, 0, 750.)
    unitFactory('UWSF', 'UnitWeaponStringField', BlzSetUnitWeaponStringField, BlzGetUnitWeaponStringField, 0, "")
    unitFactory('UWBF', 'UnitWeaponBooleanField', BlzSetUnitWeaponBooleanField, BlzGetUnitWeaponBooleanField, 0, true)
end

State: WIP
 

Attachments

  • lua test (normal).w3x
    18.1 KB · Views: 220
Last edited:
ABILITY_RLF_DURATION_HERO and ABILITY_RLF_DURATION_NORMAL worked for me, I changed the Duration of a thunderbolt based on the distance between caster and target. Although in a disable System test, changing the fields for an ability with 0s base Duration did not enable the buff blinking: which Shows the buff would turn off soon.

ABILITY_RLF_CHANCE_TO_MISS_CRS does nehter work for reading nor writing. (Curse)
ABILITY_IF_LEVEL_SKIP_REQUIREMENT returns 0, didn't test writing.
 
Level 12
Joined
Jan 30, 2020
Messages
875
Very useful.

You should specify when the fields work in reading mode but not in writing mode.
The best example is UNIT_IF_PRIMARY_ATTRIBUTE that I currently use in my map to manage my custom attributes.

These kind of fields are still quite useful even if they don't allow changing the values.

Besides, this kind of issues seem to spread to some separate natives that don't use fields directly, like BlzSetAbilityTooltip and BlzSetAbilityExtendedTooltip that have issues changing the tooltips for hero abilities beyond level 3.
This is sad because we don't even have ability string fields for these.
 
I tested various abilitybooleanlevelfield in Warcraft 3 V1.31.1 and none did work.
Worse when used inside BlzSetAbilityBooleanLevelField it crashed the game.
After that I tried some things and had the idea that the game uses integers instead of booleans (as shown in raw data view). Therefore I tested to use the address of such a BLF in ConvertAbilityIntegerLevelField and used the values 0 for false and 1 for true. That way I was able to turn of/on the Never miss Flag of Critical Strike, "
JASS:
abilitybooleanlevelfield ABILITY_BLF_NEVER_MISS_OCR5  = ConvertAbilityBooleanLevelField('Ocr5') 
-> ConvertAbilityIntegerLevelField ('Ocr5')
BlzSetAbilityIntegerLevelField(whichAbility, ConvertAbilityIntegerLevelField ('Ocr5'), 0, 0)

Other BLF it worked for
"Healing Salve - Dispel/No Target", "Liquid Fire - allow Repair", "Inventory - drop/pick/use/drop death", "Devour - Count Ally Buff", "Cyclone - Dispelable", "Imaple - Invincible", "Hartskin - melee/ranged", "Teleport/Recall/Townportal clusterTeleport", "Attribute hide", "Spellbook - Shared Cooldown", "Channel - Disable others", "transmute - bounty", "Aura - is percent", "Windwalk start cooldown after expire", "windwalk backstab", "Death pact keep target alive", "Trueshot Aura- melee, ranged", "Reive dead invincible", "Select Hero - Show Target", "possess - invincible", "Carrion Beetles - Unsummon On death" & "Shadowmimic work during day", ...
 
Yes, "orc crit ignore evasion"-field behaves in V1.32.10 the same as in V1.31.1. BlzSetAbilityBooleanLevelField crashs the game and BlzSetAbilityIntegerLevelField enables/disables the behaviour.
My test lua code, udg_Unit is the current selected Unit.
Lua:
abiCode = FourCC("AOcr")
abi = BlzGetUnitAbility(udg_Unit, abiCode)
field = ConvertAbilityBooleanLevelField(FourCC("Ocr5"))
print(BlzGetAbilityBooleanLevelField(abi, field, 0))
BlzSetAbilityBooleanLevelField(abi, field, 0, false)
print(BlzGetAbilityBooleanLevelField(abi, field, 0))

abiCode = FourCC("AOcr")
abi = BlzGetUnitAbility(udg_Unit, abiCode)
field =  ConvertAbilityIntegerLevelField(FourCC("Ocr5"))
print(BlzGetAbilityIntegerLevelField(abi, field, 0))
BlzSetAbilityIntegerLevelField(abi, field, 0, 1)
print(BlzGetAbilityIntegerLevelField(abi, field, 0))
 
Level 5
Joined
Jul 31, 2020
Messages
103
Maybe this is a bit of a necro, but I accidentally stumbled upon this list. I noticed it says nothing in BlzSetUnitWeaponBooleanField works, however, I'm using UNIT_WEAPON_BF_ATTACKS_ENABLED both for detecting if an attack is enabled with the getter, and changing it with the setter. I just want to ask if you perhaps overlooked it, the list hasn't been updated and this one got fixed at some point, or maybe you found some bug with it (crashes the game infrequently or something). I've been using it for a while and never noticed any issues, but still would rather make sure.

Edit: Obviously the native is 0-indexed while the object editor is 1-indexed if maybe that caused confusion.
 
Maybe this is a bit of a necro, but I accidentally stumbled upon this list. I noticed it says nothing in BlzSetUnitWeaponBooleanField works, however, I'm using UNIT_WEAPON_BF_ATTACKS_ENABLED both for detecting if an attack is enabled with the getter, and changing it with the setter. I just want to ask if you perhaps overlooked it, the list hasn't been updated and this one got fixed at some point, or maybe you found some bug with it (crashes the game infrequently or something). I've been using it for a while and never noticed any issues, but still would rather make sure.

Edit: Obviously the native is 0-indexed while the object editor is 1-indexed if maybe that caused confusion.
Hmm, perhaps. After some testing, the native doesn't work in patch 1.31.1, but it does work in Reforged. I'll add that info to the list.
 
UNIT_WEAPON_RF_ATTACK_RANGE does work but with a caveat, the math is off. It like adds 100 to whatever value you supply it, so if you try to improve a unit's weapon range from 600 to 750, you'd need to supply the value 650.

Instead, I found getting the RealField and just adding directly to that is the simplest way. Also, the indexes start at 1 here.

JASS:
//Modified/created for Tasyen's Jui talent picker
//Add 150 range to a unit's first weapon
BlzSetUnitWeaponRealField(udg_Talent__Unit, UNIT_WEAPON_RF_ATTACK_RANGE, 1, BlzGetUnitWeaponRealField(udg_Talent__Unit, UNIT_WEAPON_RF_ATTACK_RANGE, 1) + 150)
 
Last edited:
Level 11
Joined
Jul 4, 2016
Messages
627
Tested both UNIT_BF_HIDE_MINIMAP_DISPLAY and UNIT_BF_HERO_HIDE_HERO_MINIMAP_DISPLAY, they do not appear to do anything at all.

EDIT: also tested ABILITY_ILF_ALTERNATE_FORM_UNIT_EMEU and ABILITY_SLF_NORMAL_FORM_UNIT_EME1 (which for some reason is a string field instead of integer) also do not work.

UNIT_WEAPON_IF_ATTACK_ATTACK_TYPE also works in the latest version.
 
Last edited:
Level 11
Joined
Jul 4, 2016
Messages
627
Apologies for the double post, but I had some further findings

ABILITY_RLF_CASTING_TIME does not work for channel. I suppose one could stimulate casting time by using ABILITY_RLF_FOLLOW_THROUGH_TIME which works.

ABILITY_SLF_CASTER and _EFFECT does not work. _TARGET works

When using ABILITY_RLF_CASTING_DELAY_SECONDS on channel, it reverts its target type back to its default type that is used in the editor.

ABILITY_IF_BUTTON_POSITION_NORMAL_Y and X do not work.

All the following works.

ABILITY_RLF_CAST_RANGE
ABILITY_RLF_AREA_OF_EFFECT
ABILITY_ILF_OPTIONS
 
Last edited:

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,464
UNIT_WEAPON_IF_ATTACK_ATTACK_TYPE also works in the latest version.
Ok this might just be huge then. Nestharus had a vision a long time ago for an “attack indexer” that would have set a unit’s base damage based on a struct integer. That obviously has a lot of problems, namely screwing up splash damage.

I will be running some tests later to see if you can still use attack types greater than 7 and if BlzGetEventAttackType will also return those. If so, we’ve solved Attack Indexing and I can add the final missing piece to DamageEngine.
 

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,464
Update - MUCH better discovery - UNIT_WEAPON_IF_ATTACK_WEAPON_SOUND works correctly with the newest patch!

Sadly, you cannot set either the attack type or weapon type to be out-of bounds, so the limit is 24 instances per unit, or 12 if you want to differentiate between attack 1 and attack 2 by setting the weapontype back to its original value on each DAMAGING event. I think ranged units will never have more than 1-2 attacks launched at the same time, so this doesn't sound like a bad approach.

Tracking the attack events this way will also ensure that splash damage correctly identifies the attacked unit (unless the order was "attack ground" in which case nothing like this will trigger I think).
 

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,464
I have created a working demo of this technique and uploaded it here if anyone is interested in testing it out:


The above synchronizes the event "unit is attacked" with "unit takes damage". The below marks my progress to try to find a way to detect when a unit actually launches a projectile (to little success).

Edit: And whoa!!!!!!!!!!!!!!!!!!!! I just tested
print(BlzGetUnitWeaponRealField(udg_AttackEventSource, UNIT_WEAPON_RF_ATTACK_DAMAGE_POINT, 0))
print(BlzGetUnitWeaponRealField(udg_AttackEventSource, UNIT_WEAPON_RF_ATTACK_DAMAGE_POINT, 1))

And they do indeed work correctly! This is it! Setting a timer to correspond with whatever the damage point on attack index 0 (1 in Object Editor) multiplied by the attack cooldown modifier (not sure how to get that yet). Should enable the launch attack event.



Uhh... unfortunately, there is no reasonable way to detect if there are any bonuses applied on the unit's attack speed. We're talking about indexing every single built-in attack speed modifier such as items, abilities, agility as well as any custom changes made via triggers. I tried comparing BlzGetUnitAttackCooldown to BlzGetUnitWeaponRealField(unit, UNIT_WEAPON_RF_ATTACK_BASE_COOLDOWN, 0), but they both return the exact same number (the base value set within the Object Editor).

The best solution I can come up with is to allow a public-facing "damage speed percentage per unit" to be set from outside of this system so that someone can tailor it for their specific map at specific points, depending on what abilities/units they know are in the map. And that's JUST if they even want to have this kind of detection.

Not only that, but I then have to find a way to detect if the attack was not interrupted prior to this. I'd have to use a series of different order events to see if the order had even been deployed. What a mess, right?

Another option is to bypass the need to KNOW what the damage point is by setting the following fields: BlzSetUnitWeaponRealField(unit, UNIT_WEAPON_RF_ATTACK_PROJECTILE_SPEED, 0, 999999) and BlzSetUnitWeaponStringField(udg_AttackEventSource, UNIT_WEAPON_SF_ATTACK_PROJECTILE_ART, 0, ""). The problems then become simplified to:

1) How to not aggro the attacked unit instantly (medium priority fix)
2) How to handle the actual projectile (critical fix)
3) Nullify damage with the original attack, but apply that original damage with the secondary attack
4) Make sure that the re-issued attack follows the same structure (doesn't miss if it hit, or still fires but misses if it was evaded)

1) Might be impossible. Even changing the player ownership on damage impact (DAMAGING event) will still wake up a sleeping creep. I have no idea if this is solvable. I've tried adjusting the attack type, damage type and weapon type, but this doesn't fix it either.
2) Can be solved with a projectile system. It MIGHT be able to be solved if I manually remove the attack cooldown, attack backswing point, attack damage point and re-issue the attack with the normal projectile speed. However, this is garbage when it comes to AoE as I would have to somehow re-map all of the corresponding damage that was dealt the first time back to those units.

Overall, I think that this event just might not be worth it, unless either:

A) Someone else finds a better solution to one/some of the problems above
B) Someone discovers an alternative to any of these
C) Blizzard adds the "missile launched" event

Further edit:

I've just thought of an idea where the attack is issued against a dummy unit at the location of the target, which would solve problem 1. Problem 3 therefore becomes obsolete, but AOE is still an issue. If the unit deals an AOE attack, I can set the AOE to be anything I need it to be in order to avoid aggroing an entire group on the first hit. The game will crash if a melee unit tries to attack with any of these set up, so it also needs to make sure that only units with AOE damage are taken into account.

I think the dummy solution, like all of these other solutions, are a bust and not worth the effort. In hindsight, it's probably easier just to go back to the first solution of using the attack damage point and expecting the user to manually assign any attack speed bonuses to it. The work Nestharus did here JASS/script.j at master · nestharus/JASS might fix the was-unit-attack-interrupted problem.
 
Last edited:

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,464
Ability real fields referencing poison attack speed/movement data have corruptions in their memory access points and lead to thread crashes.

For example, these two cannot be read without crashing the thread:

ABILITY_RLF_ATTACK_SPEED_FACTOR_POI2
ABILITY_RLF_MOVEMENT_SPEED_FACTOR_POI3

My test:

  • Actions
    • Custom script: ability = BlzGetUnitAbility(udg_AttackEventSource, FourCC("Aspo"))
    • Custom script: print (ability)
    • Custom script: print(BlzGetAbilityRealField(ability, ABILITY_RLF_ATTACK_SPEED_FACTOR_SPO3))
    • Custom script: print(BlzGetAbilityRealField(ability, ABILITY_RLF_MOVEMENT_SPEED_FACTOR_SPO2))
    • Custom script: print ("done...")
Only prints the ability's handle ID, but never either real value nor "done...".

The problem is that "attack speed" and "movement speed" in the Object editor are swapped with the values that the game engine thinks this data points to. It isn't enough to just swap them.

Slow poison:
ABILITY_RLF_ATTACK_SPEED_FACTOR_SPO3
ABILITY_RLF_MOVEMENT_SPEED_FACTOR_SPO2

Poison sting:
ABILITY_RLF_ATTACK_SPEED_FACTOR_POI2
ABILITY_RLF_MOVEMENT_SPEED_FACTOR_POI3

Poison arrows:
ABILITY_RLF_ATTACK_SPEED_FACTOR_POA3
ABILITY_RLF_MOVEMENT_SPEED_FACTOR_POA4
 
Level 5
Joined
Oct 16, 2022
Messages
15
UNIT_WEAPON_RF_ATTACK_RANGE does work but with a caveat, the math is off. It like adds 100 to whatever value you supply it, so if you try to improve a unit's weapon range from 600 to 750, you'd need to supply the value 650.

Instead, I found getting the RealField and just adding directly to that is the simplest way. Also, the indexes start at 1 here.
JASS:
//Modified/created for Tasyen's Jui talent picker
//Add 150 range to a unit's first weapon
BlzSetUnitWeaponRealField(udg_Talent__Unit, UNIT_WEAPON_RF_ATTACK_RANGE, 1, BlzGetUnitWeaponRealField(udg_Talent__Unit, UNIT_WEAPON_RF_ATTACK_RANGE, 1) + 150)

I am not sure if it has changed since but it behaves differently for me on many points (lua backend).

Setting the attack range is an incremental operation and may have an offset as you mentionned; Getting the range back should be done with index 0 instead of 1.

So, to set a unit attack range to a desired value i had to do the following
(in this case my unit had an offset of 100)

Lua:
-- weapon_index=0,1 to follow blizzard standard
function SetUnitAttackRange(unit, weapon_index, desired_range)
  local current_range = BlzGetUnitWeaponRealField(unit, UNIT_WEAPON_RF_ATTACK_RANGE, weapon_index) -- index is correct, returned range is correct.
  BlzSetUnitWeaponRealField(unit, UNIT_WEAPON_RF_ATTACK_RANGE, weapon_index + 1, desired_range - current_range + 100)
end

Hope it may help others, or someone correct me as why I have to do this.
 
Last edited:
Level 11
Joined
Jul 4, 2016
Messages
627
This works in 1.35
UNIT_WEAPON_IF_ATTACK_DAMAGE_BASE

These two following work in 1.35 but like the range function, they are incremental operations and 1-indexed
UNIT_WEAPON_IF_ATTACK_DAMAGE_NUMBER_OF_DICE
UNIT_WEAPON_IF_ATTACK_DAMAGE_SIDES_PER_DIE

EDIT: it has come to my attention that there are natives specifically used to modify the above, so this isn't too terribly useful anymore.
 
Last edited:
Status
Not open for further replies.
Top