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

Widget convert to Unit

Status
Not open for further replies.
Level 14
Joined
Oct 19, 2014
Messages
187
Im sick of this,, Is there anyway to use widget for unit's arguments or anything that settable for unit.. Grrrrr...

I was dreaming for this grrr
JASS:
private function W2U takes widget u returns unit
    return u
endfunction

because I hook the native UnitDamageTarget but at the end,, it was fcking useless,, I was expecting that the target is still a unit.

JASS:
private function dt takes unit u1,widget u2,real r,boolean b1,boolean b2,attacktype a,damagetype d,weapontype w returns nothing
    if r>0 then
        set EventAttackType=a
        set EventCustomDamage=true
    endif
endfunction
hook UnitDamageTarget dt
 
Last edited:

Dr Super Good

Spell Reviewer
Level 63
Joined
Jan 18, 2005
Messages
27,191
Technically this requires new natives...

If the widget is not a unit, a value of null should be returned and there should be another function to test if the widget is a unit.

That said Illidan(Evil)X code probably does work. I just do not trust it since using hashtables to type cast back in the hashtable PTR used to be very crash prone.
 
Level 14
Joined
Oct 19, 2014
Messages
187
JASS:
        globals
            private group GroupW2U=CreateGroup()
        endglobals

        public function W2U takes widget w returns unit
            local real rdm=GetRandomReal(1.0,10.0)
            local real wbaselife=GetWidgetLife(w)
            local real ubaselife
            local boolean b
            local unit u
            loop
                call GroupEnumUnitsInRangeCounted(GroupW2U,GetWidgetX(w),GetWidgetY(w),0.01,null,1)
                set u=FirstOfGroup(GroupW2U)
                set b=u!=null
                if b then
                    set ubaselife=GetWidgetLife(u)
                    set b=(wbaselife-rdm)==(ubaselife-rdm)//In this part,, will make the specific searching.. because random real has a unique number,, it could be somelike this 5.2341235.. so that is it..
                endif
                exitwhen b
            endloop
            call GroupClear(GroupW2U)
            return u
        endfunction
how about this kind of converting?
 
Last edited:
Level 39
Joined
Feb 27, 2007
Messages
4,994
You're not truly 'converting' a widget to a unit. Instead you are asking where exactly a widget is and are getting the closest 1 unit to that coordinate location. It will work but it's 'not' a conversion. Can fail too if you're using SetUnitX() to move units directly on top of one another.
 
Level 14
Joined
Oct 19, 2014
Messages
187
You're not truly 'converting' a widget to a unit. Instead you are asking where exactly a widget is and are getting the closest 1 unit to that coordinate location. It will work but it's 'not' a conversion. Can fail too if you're using SetUnitX() to move units directly on top of one another.
Actaully it works,, yeah I know it is not convertion,, I just glitch everyhing,, so far,, it is working properly and no fail,, tested by BJDebugMsg hehehe

Since you talk about the coordinate of the unit,, I will add boolean for their coordinate if equal..
In that way maybe,, the search action will easy found the subject,, because X and Y is a real number..hmmm
And wider the search range,, and set the count about 1-5 or I will just use the GroupRange without counting..

And also comparing thier life cant actaully found the specific subject,, so I'll better use coordinate,, because using GroupRange will search unit by range,, even though how little the range is,, but their Coordinates is to deep..
Like,, X=-5542.2215862258.... Y=4582.005460445...

In this case,, I will on the collison of each unit seach by the action and relocate them through SetUnitPosition,, after that call they will automatically separate,, and their coordinate will change,, this may happen if we create unit in the same coordinate or if both unit has no collision,, but I must strict,, so next,, I will on the collision of each unit search and relocate them by using SetUnitPosition then check thier coordinate,, if one of them didnt change its coordinate then we found the subject :)
 
Last edited:
Dunno if you still need it, but to hang on, on your approach, but with handle id? something like
JASS:
globals
    group GroupW2U = CreateGroup()
endglobals

function W2U takes widget w returns unit
    local unit u
    local integer handleId = GetHandleId(w)
 
    call GroupEnumUnitsInRange(GroupW2U, GetWidgetX(w), GetWidgetY(w), 0, null)
    loop
        set u = FirstOfGroup(GroupW2U)

        // exit with "null" if group got empty
        // exit with correct unit if handleId was found
        exitwhen (u == null or GetHandleId(u) == handleId)
        call GroupRemoveUnit(GroupW2U, u)
    endloop

    return u
endfunction
 
Level 14
Joined
Oct 19, 2014
Messages
187
Dunno if you still need it, but to hang on, on your approach, but with handle id? something like
JASS:
globals
    group GroupW2U = CreateGroup()
endglobals

function W2U takes widget w returns unit
    local unit u
    local integer handleId = GetHandleId(w)
 
    call GroupEnumUnitsInRange(GroupW2U, GetWidgetX(w), GetWidgetY(w), 0, null)
    loop
        set u = FirstOfGroup(GroupW2U)

        // exit with "null" if group got empty
        // exit with correct unit if handleId was found
        exitwhen (u == null or GetHandleId(u) == handleId)
        call GroupRemoveUnit(GroupW2U, u)
    endloop

    return u
endfunction
Exactly bro,,why I didnt even think of that,, solved men hahahaha,,
Widget has a HandleId
 
Level 9
Joined
Jul 30, 2012
Messages
156
Don't try to reinvent the wheel. When typecast was first removed back in 1.24, they gave us hashtables to meet our needs. This:
JASS:
globals
    hashtable Hashtable = InitHashtable()
endglobals

function Widget2Unit takes widget w returns unit
    call SaveWidgetHandle(Hashtable, 0, 0, w)
    return LoadUnitHandle(Hashtable, 0, 0)
endfunction
is the correct and officially supported way of doing it. It should work in all versions of WC3, and if it doesn't, it's Blizzard's fault, not yours.

LoadUnitHandle will return null if the saved handle is not a valid unit. Just check for that and you'll be fine.
 
Level 9
Joined
Jul 20, 2018
Messages
176
Dunno if you still need it, but to hang on, on your approach, but with handle id? something like
A little updated version of this, must still work.
JASS:
globals
    unit W2Uunit = null
    integer W2Uhid = 0
endglobals

function W2Ufilter takes nothing returns boolean
    local unit u = GetFilterUnit()
    if W2Uhid == GetHandleId(u) then
        set W2Uunit = u
    endif
    set u = null
endfunction

function W2U takes widget w returns unit
    set W2Uunit = null
    set W2Uhid = GetHandleId(w)
    call GroupEnumUnitsInRange(bj_lastCreatedGroup, GetWidgetX(w), GetWidgetY(w), 0., Filter(function W2Ufilter))
    return W2Uunit
endfunction
 
Level 14
Joined
Oct 19, 2014
Messages
187
A little updated version of this, must still work.
JASS:
globals
    unit W2Uunit = null
    integer W2Uhid = 0
endglobals

function W2Ufilter takes nothing returns boolean
    local unit u = GetFilterUnit()
    if W2Uhid == GetHandleId(u) then
        set W2Uunit = u
    endif
    set u = null
endfunction

function W2U takes widget w returns unit
    set W2Uunit = null
    set W2Uhid = GetHandleId(w)
    call GroupEnumUnitsInRange(bj_lastCreatedGroup, GetWidgetX(w), GetWidgetY(w), 0., Filter(function W2Ufilter))
    return W2Uunit
endfunction
Good work bro,, very excellent rep+ why? You really take care of locals with handle and that was unit,, by your filter without calling its function the local unit can be nulled compare to use the local unit was being returned,, excellent bro thanks
 
Level 12
Joined
Feb 22, 2010
Messages
1,115
You really did a good job of getting rid of local unit variable. Previous version of the function was returning the found unit via a local unit variable and there was a reference leak because of this (similar to PolledWait). With your filter solution, local unit variable declared in filter function can be nulled inside that function (compared to local unit inside W2U function which can't be nulled).

Maybe in the next iteration you should completely remove local unit variable in filter function and just use GetFilterUnit.
 
Status
Not open for further replies.
Top