HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

GetUnitUserData() is 100% safe?

12-10-2006, 07:37 PM#1
Themerion
Multiple times this nice little function has acted by responding '0' where I am sure that there ought to be a value. Are there any known bugs related to Custom Values? (such as they will not work under certain circumstances)
12-10-2006, 08:06 PM#2
moyack
This function has worked fine when I've made spells, but it is limited according with the usage in the script in my opinion.

I can say I've used it combined with the return bug to save information (The spell caster unit of one spell, to get the data in a call back function at ForGroup function, for instance)

I consider it is quite reliable.
12-10-2006, 08:21 PM#3
Themerion
One weird thing that I've noticed is that when I call it at an arbitrary time, it sometimes return 0. When I call it again, another time, it has the value it ought to have!

Can this by any chance be a WEU related problem?
12-10-2006, 08:59 PM#4
wyrmlord
I doubt it is a WEU problem, unless WEU modified the function's script (I doubt it did), it should work like it would in the regular editor.
12-10-2006, 09:36 PM#5
Captain Griffen
It works fine. There are no bugs in it. It is your script's problem.
12-10-2006, 10:09 PM#6
Vexorian
or the unit you are passing to GetUnitUserData is null or the wrong unit or a removed unit
12-11-2006, 03:16 PM#7
Themerion
Okay, then my problems ought to origin from this code. Can somebody help me to debug it?

You see, I'm writing scripts for another mapmaker. This script works flawlessly for me, but hardly at all for him ( he said that it worked ~5% of times ).

The script is supposed to make computer controlled units move after they've been targeted with the teleportation-ability. All computer controlled units get the custom value when they are created and when they enter certain regions.

The error must be in this code, as it can be run multiple times showing 0, but then on the n:th time it returns the value that it should do.

Collapse JASS:
//@version: rev2
//===========================================================================
constant function Staff_of_Teleportation_fix_SpellId takes nothing returns integer
    return 'AImt'
endfunction
constant function Staff_of_Teleportation_fix_delay takes nothing returns real
    return 1.2
endfunction
//===========================================================================
function Staff_of_Teleportation_fix takes nothing returns nothing
    local trigger trg=GetTriggeringTrigger()
    local unit t=GetAttachedUnit(trg,"t")
    local integer i=GetUnitUserData(t)
    local location loc

    call TriggerSleepAction(Staff_of_Teleportation_fix_delay())

    set loc=udg_AttackLocations[i]
    call IssuePointOrder(t,"attack",GetLocationX(loc),GetLocationY(loc))
    set loc=null

    set t=null
    call CleanAttachedVars(trg)
    call DestroyTrigger(trg)
    set trg=null
endfunction

function Staff_of_Teleportation_fix_Actions takes nothing returns nothing
    local unit u=GetSpellAbilityUnit()
    local unit t=GetSpellTargetUnit()
    local trigger trg=CreateTrigger()

// player 1 and player 7 are computer controlled players.
    if((GetOwningPlayer(t)==Player(0))!=(GetOwningPlayer(t)==Player(6))) then
        call AttachObject(trg,"t",t)
        call TriggerRegisterUnitEvent(trg,u,EVENT_UNIT_SPELL_ENDCAST)
        call TriggerAddAction(trg, function Staff_of_Teleportation_fix)
    endif
    set trg=null
    set t=null
    set u=null
endfunction

//===========================================================================
function Staff_of_Teleportation_fix_Conditions takes nothing returns boolean
    if(GetSpellAbilityId()==Staff_of_Teleportation_fix_SpellId()) then
        if(IsUnitType(GetSpellTargetUnit(), UNIT_TYPE_STRUCTURE)==false) then
            return true
        endif
    endif
    return false
endfunction

function InitTrig_Staff_of_Teleportation_fix takes nothing returns nothing
    set gg_trg_Staff_of_Teleportation_fix = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Staff_of_Teleportation_fix, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_Staff_of_Teleportation_fix, Condition( function Staff_of_Teleportation_fix_Conditions ) )
    call TriggerAddAction( gg_trg_Staff_of_Teleportation_fix, function Staff_of_Teleportation_fix_Actions )
endfunction
12-11-2006, 03:46 PM#8
Ryude
There are so many weird coding decisions I don't know where to start. I would like to know where GetUnitUserData() is being used?
12-11-2006, 04:57 PM#9
BertTheJasser
I agree to Ryude. Review your code, read the jass tut again. This burns in my eyes.
12-11-2006, 05:32 PM#10
Captain Griffen
That code is always going to return 0. You never set the unit user data.

How the heck can we debug what we cannot see?

That trigger also leaks if it isn't computer controlled.

Make sure you're getting the right unit.
12-11-2006, 07:18 PM#11
Themerion
A: My retaliations.
(skip to B if you don't care about reading my insolent replies)

Quote:
Originally Posted by BertTheJasser
I agree to Ryude. Review your code, read the jass tut again. This bourns in my eyes.

Quote:
Originally Posted by Ryude
There are so many weird coding decisions I don't know where to start. I would like to know where GetUnitUserData() is being used?

1. Ryude, if you don't even know how to find the "Search" function in your browser, then you should get a new browser or quit using computers.

2. Nice. Lot's of critique which won't help me at all. "This suck". Thanks. Now, if you told me WHY it might help even more. Just a hint.

Quote:
That code is always going to return 0. You never set the unit user data.

Quote:
Originally Posted by Themerion
The script is supposed to make computer controlled units move after they've been targeted with the teleportation-ability. All computer controlled units [b]get the custom value when they are created[/u] and when they enter certain regions.

You know... I posted text... before the script...

Sorry for being a bit rude, but I don't like people who treat me like a complete idiot only because:
My post count < 10^3

---

With weird coding descicions, you perhaps mean:

1. The use of headers ( constant functions ) is due to the owner of the map. He isn't a JASS:er and I want to make things wasy for him.

2. Yes, I know. I could've used "Stops Casting an Ability" in the first place instead of creating the trigger when "Starts the effect" is run. However, this ought to work just as good. If not, then tell me why, thanks.

---
B:

I thought you'd appreciate the entire code. Seems like I was wrong. Well then, here comes the vital part of it, commented;

Collapse JASS:
function Staff_of_Teleportation_fix takes nothing returns nothing
// The trigger "trg" has the event "a unit stops casting an ability"
// It is created when a unit "begins casting an ability"
    local trigger trg=GetTriggeringTrigger()
// The GetSpellAbilityTarget() is attached to trg
// The Spell ability target is a non-structure, computer controlled unit.
    local unit t=GetAttachedUnit(trg,"t")
// The unit's user data is pointing at an array index...
// The custom data is set when the units are created.
    local integer i=GetUnitUserData(t)
    local location loc

    call TriggerSleepAction(Staff_of_Teleportation_fix_delay())

// AttackLocations are where the units are heading.
    set loc=udg_AttackLocations[i]
    call IssuePointOrder(t,"attack",GetLocationX(loc),GetLocationY(loc))
    set loc=null

    set t=null
        call TriggerRemoveAction(trg,GetAttachedTriggerAction(trg,"ta"))
    call CleanAttachedVars(trg)
    call DestroyTrigger(trg)
    set trg=null
endfunction

I am certain that the units have the custom data when they have been created. I wrote the code like this, just to be sure:

Collapse JASS:
call SetUnitUserData(unit,value)
call IssuePointOrderLoc(unit,"attack",udg_AttackLocations[GetUnitUserData(unit)])
12-11-2006, 08:18 PM#12
Jazradel
People with 10^3 post counts won't treat like an idiot without reason. Thats how they've managed to get 10^3 posts.

Constant functions are absolutely standard.

Collapse JASS:
function Staff_of_Teleportation_fix_Conditions takes nothing returns boolean
    if(GetSpellAbilityId()==Staff_of_Teleportation_fix_SpellId()) then
        if(IsUnitType(GetSpellTargetUnit(), UNIT_TYPE_STRUCTURE)==false) then
            return true
        endif
    endif
    return false
endfunction
Is pretty wierd, for example. It would normally be written like this:
Collapse JASS:
function Staff_of_Teleportation_fix_Conditions takes nothing returns boolean
    return GetSpellAbilityId()==Staff_of_Teleportation_fix_SpellId() and IsUnitType(GetSpellTargetUnit(), UNIT_TYPE_STRUCTURE)==false
endfunction
Collapse JASS:
if((GetOwningPlayer(t)==Player(0))!=(GetOwningPlayer(t)==Player(6)))
Is a wierd line.

You need to redo your triggers, because I see no SetUnitData at any point.
12-11-2006, 08:20 PM#13
iNfraNe
what if value isnt set :) we still cant see the triggers dude, this isnt helping at all. People arent being rude to you cus you have low postcount but because you're asking for help when its impossible to see what you did wrong since you dont post the essential part of the trigger.
12-11-2006, 08:45 PM#14
Captain Griffen
You are not god. You get things wrong. We all get things wrong. You are not special. It may not have been set correctly.

In fact, some guy gave you great advice.

Quote:
Make sure you're getting the right unit.

You done that yet?
12-12-2006, 12:56 AM#15
Ryude
I never meant to be offensive. I have been in your boat before. But, the best way for anyone to learn is to attempt to review their own code because most of the time you're the only one who understands your own code.

That's the case with my PHP libraries. No one understands them but me.

Now, I see where GETUnitUserData() is, but I don't see SETUnitUserData().