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

[MemHack] Unit's structure

Status
Not open for further replies.
Level 19
Joined
Dec 12, 2010
Messages
2,069
Why do you need Cheat engine you asked? To find and to explore values. Today I'll show you what we found about unit's base structure.

Unit's structure
Normally you need to manipulate properties of units. It's most common task in mapmaker's work. Let's see what contains a "unit" as object.

Getting address
Using -cc I got the address of unit's structure, it started at E8811E4

Here and further Im using Cheat tables I uploaded before

unitstruct_1.png


So, most of fields are unknown or/and game-only required. Very first bytes are common for many widgets. It contains VTable link, UsedCounter, inner IDs and flags.

Very first 4 bytes is a link onto Vtable of unit's actions. There can be found functions which are called on damage event, on movement, etc etc.

unitstruct_2.png


We never needed to explore them, so they are pretty much unknown for now.

0x4 contains unknown value, probably counter of links onto this object.
0x8 completely unknown

0xC & 0x10 always keep object's unique handle, which is used by pretty much everything. Combining them with GetSomeAddressForAbility will give the address of structure start (E8811E4 in our case)
unitstruct_3.png


You will see unit's being stored in tables like this if needed. Game very rarely uses direct addresses.

Values up to 0x20 are unknown.

0x20 - main stack of various flags. It's rather hard to get what most of them means, yet I managed to find some
JASS:
    constant integer UNIT_HIDDEN                 = 0x1
    constant integer UNIT_LOCUST_NONSELECTABLE = 0x2
    constant integer UNIT_NONSELECTABLE = 0x4
    constant integer UNIT_INVULNERABLE             = 0x8
    constant integer UNIT_VISIBLED_TO_ALL         = 0x10
    constant integer UNIT_AUTOATTACK_DISABLED=0x10000000
1st one is obvious (same as ShowUnit (false) but doesn't include hardcoded projectile evasion and some other side-effects)
Second one provides locust-like properties - unit cannot be selected, no HP bar visible
Third disallows to point-target unit. It acts like non-unit, you can select it with ground-selection only, yet autoattack just fine. HP bar is visible.
Invulnerability speaks for itself
"Visibled to all" - unit's model being visible through fog of war, always, unless hidden. It doesn't reveal unit but only it's model, therefore no HP bar visible and unit counts as non-visible by any game mechanic.
Autoattack disabled seems to be part of peon's flags, never bothered to check it on non-DotA.

Rest flags have unknown purpose, you can make tests and find it out.

0x24 - portrait fon player color, 0-15. Can be independant of the owner. Probably also affects unit's colors as "Change colors" flag at SetUnitOwner native, but we don't know how to force game to re-draw unit.
0x28 - a link onto some unkonwn data table. It does contains some field (0xA0) with something looking like unit existant timer, but it can be async between clients. There's also unit color (0x148) and model scale (0xE8). Rest fields are also unknonw/non-obvious.

0x30 contains unit's ID. You can use "string" type of field to see it in CE, ingame you can use it as well as normal IDs, 'Hpal' for instance. Like
JASS:
local integer unitId=ReadRealMemory(unitaddress+0x30)

This address actually being scanned constantly, change unit's name and many stuff.
Normal UC76
unitstruct_4.png

uC76 (name been kept as they are case-insensitive)
unitstruct_5.png


0x54 looks like counter for stuns
0x58 is the owner of unit, 0-15
0x5C is the second flags of unit

Due to unit's complex structure they have more than 1 field for flags
JASS:
    //flag 0x4 causes fatal if any damage received
    //flag 0x40 stands for red flashing (on damage), but doesn't directly calls it
    constant integer UNIT_DEAD = 0x100
    //like dead hero, provides no vision, cant be selected, enemies doesn't flee when attacked by this flag
    constant integer UNIT_MINMAP_ICON_HIDE        = 0x80000
    constant integer UNIT_MINMAP_ICON_TAVERN    = 0x40000
    constant integer UNIT_MINMAP_ICON_GOLD        = 0x20000
    constant integer UNIT_MINMAP_SHAREVISIBLE    = 0x10000
    constant integer UNIT_STUNNED= 0x100000
    constant integer UNIT_INVISIBLED             = 0x1000000
    constant integer UNIT_HIDDEN_PANEL=0x4000000//same as 0x2000000, differences are unknown
    constant integer UNIT_HAS_FLYING_VISION= 0x20000000
    constant integer UNIT_ILLUSION=0x40000000
Note that UNIT_INVISIBLED flag actually makes unit invisible for any kind of targeting, even if he obviously visible. You can turn any unit into illusion as well, which will auto-apply it's properties.
Hidden panel is:
unitstruct_6.png


Rest flags have unknown purpose

0x88 and few values fill up whenver unit receives daamge, probably related to red flashing or something

0xB0 keeps unit's base regeneration but it doesn't actually affects it, purpose is unkonw
0xD4 - same as B0, but for mana regeneration

0xE0 contains total armor value. In case if modified it always change for white values and never for green. I mean if you have 2+10 armor it contains 12, if you change it to 15, you will end up with 5+10, not 2+13.
0xE4 stands for armor types.
JASS:
//armor types:
// 0 - Light; 1 - Medium; 2 - Heavy; 3 - Fortified; 4 - Normal; 5 - Hero; 6 - Divine; 7 - unarmored;
//rest seems to have Light properties

0xE8 counts sources of invulnerability. Whenever it's zero unit supposed to be vulnerable. It doesnt affect anything tho, you should check for 0x20 to contains 0x8 flag instead.

0x10C keeps amount of map cells unit can see. Max value is 14. Value stands still until day-night cycle starts (first night). Then it get updated every 1-2 seconds. If you disable day-night cycle you can manipulate this value once, else - you have to rewrite default values.

0x114 counts sources of active invisibility

0x120 & 0x124 are link onto fade time object which is used whenever any invisibility being used/active. I didn't explore this structure.

0x130 & 0x134 are link to invisibility main object. It contains info about unit's state - is he hightlighted by True sight of any of player.
unitstruct_7.png
unitstruct_8.png
unitstruct_9.png


0x24 counts flags of all players who have true sight vision over this unit
0x2C and following is counter of how many true sight sources is applied over this unit by this player
Following fields seems to be reserve, their purpose is unknown.

If you state there that player 10 has true sight vision over unit, then Player 10 and his allies will be able to hit this unit if he's invisible. Issue is, model isn't revealed, so they only can do it via autoattack.

unitstruct_A.png

Here tower (player 6) and dummy units of player 7 provides true sight vision over Banshee, which equals to 2^6+2^7 flags being enabled.

Here I stand next to 2 towers and the Throne, all of them have True sight, as well as dummy units nearby them. So it shown at counter:
unitstruct_B.png


0x13C & 0x140 are link to "detected" main object. It contains info about unit's state "hightlighted by True sight" of any of player.

unitstruct_C.png

By default this object is unexistant (-1 both fields), it only being generated if needed.
unitstruct_D.png
unitstruct_E.png


0x24 - flags of "unit visible to"
0x2C and following - counters
As invisibility, it's just a stack of flag and counters per player. Whenever Faeire Fire being applied over unit counter for player (which owns the caster) increase.

This flags are also used in ShareVision native. They doesn't affect counters, but only adds value to flag field.
Whenever player's flag is included to 0x24 he is able to see unit's model even if unit is invisible.

0x148 - "unit visible to" flags stack
0x14C - "shared vision to" flags stack

unitstruct_F.png


Faerie fire change all 4 values - it adds up +1 to all counters of true sight, and shares vision. To disable it you have to nullify unit's visibility flags, as well as 0x148 and 0x14C. You dont have to null counters.
These fields contains sum of player who is able to get vision over the unit. This ShareVision field (0x14C) is alliance-insensitive, means you can share vision to a single player instead of whole alliance. Game automatically adds up allies when native is used.

0x158 - counter of ethereal-provides abilities on unit
0x15C - counter of spell-immune providers
0x160 seems to be related with spell immune but purpose is unknown

0x18C unkonwn counter, game can crash if not 0
0x198 - counter of stuns unit affected by

0x19C & 0x1A0 - link at current order object
0x1A8 & 0x1AC - link at last given order object (shift-related, stun-related etc)
Stuns cause game to put "stunned" order as current unless it's already have 0x198 > 0. Then it push all given orders at "last given order" instead of "current order", effectively preventing unit from acting. In case if counter 0x198 is manually set to 1, it won't affect anything, unit will act as normal, but a real stuns won't effect it, 'cause counter is already >0 and it supposed to mean "stunned order already given". Beware of this issue (known as "fuck your disables" issue).

0x1B4 - counts amount of orders in queue
0x1B8 - somehow related to disabled abilities (Doom provides this)
0x1C0 - counter of "disable physical abilities", attack, suicide, etc
0x1C4 - seems to be 1 if unit is dead, else 0. If reincarnating still 1.
0x1D0 - global counter of silences applied over unit. Used to silence new learned/obtained abilities instead of periodic timers etc.
0x1DC & 0x1E0 - link onto last added ability (they are linked list overall)

0x1E8 - placeholder for attack ability address. Zero if unit has no attack
0x1EC - placeholder for movement ability address. Zero if unit immovable or base MS =0.
0x1F0 - placeholder for hero ability address. Zero if unit isn't a hero.
0x1F4 - placeholder for builder ability address (probably). Zero in all cases for dota, we have no builds whatsoever.
0x1F8 - placeholder for inventory ability address. Zero if unit has no inventory.

0x1FC - unknown, disregard "unit type" naming, it have nothing to do with it :D
0x200 - a flag/link onto something. If 1, unit will have ground vision even if he is flying or have flag Flying vision (above) as true. Negative side is - unit become immovable in terms of height (always keep ground level visually)

0x248 - unit type
JASS:
Here's table of possible values (decimal base)
  constant unittype UNIT_TYPE_GIANT             = ConvertUnitType(9)    1
  constant unittype UNIT_TYPE_SUMMONED          = ConvertUnitType(10)    2
  constant unittype UNIT_TYPE_UNDEAD            = ConvertUnitType(14)    4
  constant unittype UNIT_TYPE_MECHANICAL          = ConvertUnitType(15)    8
  constant unittype UNIT_TYPE_PEON            = ConvertUnitType(16)    16
  constant unittype UNIT_TYPE_SAPPER            = ConvertUnitType(17)    32
  constant unittype UNIT_TYPE_TOWNHALL          = ConvertUnitType(18)    64
  constant unittype UNIT_TYPE_ANCIENT           = ConvertUnitType(19)    128
  constant unittype UNIT_TYPE_TAUREN            = ConvertUnitType(20)    256
  constant unittype UNIT_TYPE_WARD= 512
  unkonwn unit type 1024
512 (ward) efficiently blocks command card, but doesn't prevent controlling unit.
unitstruct_A0.png

1024 have unknown purpose

0x280 - another flags of unit.
0x100 stands for "unit hp bar have to be shown", rest are unknown

0x284 - 0x2A4 - something related to unit's facing angle and/or position

0x2F8 - walk speed (for animation only)
0x2FC - run speed (for animation only)
0x300 - animation time scale

0x30C is the end of unit's structure.

There's many white spaces and we never aimed to explore all of them. Keep this journey by yourself.
Any help in terms of donations is highly appreciated.
 
Last edited:
Level 19
Joined
Dec 12, 2010
Messages
2,069
tl;dr, maybe later, but I noticed what you wrote about only white armor being affected - did you check if those are actually two separate fields (e.g. shorts) and only one is for armor?
lel
all data is 4 bytes, no exceptions. it may be filled byte-by-byte tho, but read always as 4 bytes. doubles only used at non-structures like video rendering and such
 
Level 19
Joined
Dec 12, 2010
Messages
2,069
torando's 0x20 is 0x64E (unknown 0x400, 0x200 & 0x40, + locust/unselectable/invul) and 0x5C is0x20001001 (0x2000000 is unknown, 0x1000 and 0x1 typical for units I saw). probably those special behavior provided by ability. like locust itself provides immunity from true sight, disregard normal detecting.
 
Level 19
Joined
Dec 12, 2010
Messages
2,069
Unit+0x25C
stands for the # of attached ubersplat which is movable along with the hero. issue is there's limits IDK why, didn't succeed with custom ones, only placing default works. Field is a number to uber inside UbsersplatData slk, numbers bigger than existing == fatal
 

Dr Super Good

Spell Reviewer
Level 63
Joined
Jan 18, 2005
Messages
27,191
Might be a good time to point out that this thread is technically illegal as it is actively encouraging reverse engineering the game without reasons such as compatibility or interoperation.

There is a big difference between documenting how mdx, blp or mpq files work with respect to the game and documenting/exploring the current build of WC3's memory structure for storing unit data.

Does Blizzard care? Probably they do as they have shut down similar in the past.
 
Status
Not open for further replies.
Top