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

Get unit model path

Status
Not open for further replies.
Level 3
Joined
May 10, 2007
Messages
36
Being naive, I'd like to ask if there's any function to get the model path of a unit without defining it first, like there is for spells and effects if I'm not mistaken.
 
Level 13
Joined
May 10, 2009
Messages
868
As far as I know, no. Though you can use the GetAbilityEffectById function in order to get these fields from a unit: "Art - Special" (when unit explodes), "Combat - Attack 1/2 - Projectile Art", and "Art - Target".

JASS:
native GetAbilityEffectById takes integer abilityId, effecttype t, integer index returns string

//

EFFECT_TYPE_MISSILE
EFFECT_TYPE_SPECIAL
EFFECT_TYPE_TARGET // EDIT: Added this one

//

function NoName takes nothing returns nothing
    // hmpr = Priest
    call BJDebugMsg(GetAbilityEffectById('hmpr', EFFECT_TYPE_SPECIAL, 0)) // Art - Special
    call BJDebugMsg(GetAbilityEffectById('hmpr', EFFECT_TYPE_MISSILE, 0)) // Combat - Attack 1 - Projectile Art
    call BJDebugMsg(GetAbilityEffectById('hmpr', EFFECT_TYPE_MISSILE, 1)) // Combat - Attack 2 - Projectile Art
    call BJDebugMsg(GetAbilityEffectById('hmpr', EFFECT_TYPE_TARGET,  0)) // Art - Target | EDIT: Added
    // By default, priests don't have anything in their "Art - Target" field.
endfunction

Untitled-3.png

Note that when a unit does not have their "attack 2 - projectile art" defined, the function returns the path from the first one. If the first one is not defined, but the second one is, it returns null for the first one.
In this case, priest does not have his second "projectile art" defined by default, so it returned the first projectile instead.

EDIT: I forgot that units have the "Target" field in the object editor; "Art - Target".
 
Last edited:
Level 13
Joined
Nov 7, 2014
Messages
571
DracoL1ch has a SetUnitModel function (among other things) which can be repurposed to return a unit's model path:

JASS:
globals
    integer pUnitUIDefAddr = GameDLL + 0xAB58F0 // for game version 1.26
endglobals

function get_unit_type_model takes integer unit_type_id returns string
    local integer FirstDataDefEntry = Memory[pUnitUIDefAddr/4]
    local integer CurrentDefAddr = Memory[FirstDataDefEntry/4 + 2] + 0x10
    local integer FirstDefAddr = CurrentDefAddr
    local integer CurrentDefId = 0

    local boolean is_neg
    local integer i
    local integer p
    local string chars = " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~"
    local string result = ""
    local integer b1
    local integer b2
    local integer b3
    local integer b4

    if FirstDataDefEntry == 0 then
        call BJDebugMsg("FirstDataDefEntry == 0")
        return ""
    endif

    loop
        set CurrentDefId = Memory[CurrentDefAddr/4+2]

        exitwhen CurrentDefId == unit_type_id

        set CurrentDefAddr = Memory[CurrentDefAddr/4]
        if CurrentDefAddr == 0 or CurrentDefAddr == FirstDefAddr then
            call BJDebugMsg("CurrentDefAddr == 0 or CurrentDefAddr == FirstDefAddr")
            return ""
        endif
    endloop

    if CurrentDefAddr == 0 then
        call BJDebugMsg("CurrentDefAddr == 0")
        return ""
    endif

    set p = CurrentDefAddr - 0x0C + 0x30
    set p = Memory[p/4]

    // I don't know how else to turn a c-string into a jass string =)...
    //
    loop
        set i = Memory[p/4]

        set is_neg = false
        if i < 0 then
            set is_neg = true
            set i = i + 0x80000000
        endif
        set b1 = i - i / 0x100 * 0x100
        set i = i / 0x100
        set b2 = i - i / 0x100 * 0x100
        set i = i / 0x100
        set b3 = i - i / 0x100 * 0x100
        set i = i / 0x100
        set b4 = i
        if is_neg then
            set b4 = b4 + 0x80
        endif

        exitwhen b1 == 0

        set result = result + SubString(chars, b1 - 0x20, b1 - 0x1F)

        exitwhen b2 == 0

        set result = result + SubString(chars, b2 - 0x20, b2 - 0x1F)

        exitwhen b3 == 0

        set result = result + SubString(chars, b3 - 0x20, b3 - 0x1F)

        exitwhen b4 == 0

        set result = result + SubString(chars, b4 - 0x20, b4 - 0x1F)

        set p = p + 0x04
    endloop

    return result
endfunction

...

call BJDebugMsg(get_unit_type_model('hfoo')) // units\human\Footman\Footman.mdx
 
Level 3
Joined
May 10, 2007
Messages
36
That looks like it took you some time! It is much appreciated, thank you both for for your help. I'll get right back to it. :infl_thumbs_up:
 
Status
Not open for further replies.
Top