HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

attaching units in StatusEvents by grim001

06-24-2009, 12:34 PM#1
Sinnergy
I'm posting it here, since its about attaching stuffs.

in StatusEvents, you can detect units that die, it is an event response that requires a function that follows its interface, and the function interface takes a unit u, u refers to the triggering unit (dying unit in my case)

in my spell, when the ability is learned, I created an OnDeathEvent response, now I want to attach the unit that learned the spell and use it on the function interface used by OnDeathEvent, but how? I need the spell to maintain its' MUI-ness.

The code:
Collapse JASS:
scope Spell3 initializer init

globals
    private constant integer spell = 'A020'
    private constant integer bap = 'B00M'
    private constant string mdl = "Abilities\\Spells\\Undead\\DeathCoil\\DeathCoilMissile.mdl"
    private constant string sfx = "Abilities\\Spells\\Undead\\DeathCoil\\DeathCoilSpecialArt.mdl"
endglobals

private struct dcollider extends xecollider
    unit c
    integer l
    method onUnitHit takes unit u returns nothing
        if u == .c then
            call SetWidgetLife(.c,GetWidgetLife(.c) + 15*.l)
            call DestroyEffect(AddSpecialEffectTarget(sfx,.c,"origin"))
            call .terminate()
        endif
    endmethod
    
    method loopControl takes nothing returns nothing
        if GetWidgetLife(.c) < 0.405 then
            call .terminate()
        endif
    endmethod
    
endstruct

private function con takes nothing returns boolean
    return GetLearnedSkill() == spell and GetUnitAbilityLevel(GetTriggerUnit(),spell) == 1
endfunction

private function deathDetect takes unit u returns nothing
//forget these lines, they aren't necessary
    local integer l = GetUnitAbilityLevel(d.c,spell)
    local dcollider xe
    local real x = GetUnitX(d.c)
    local real y = GetUnitY(d.c)
    local real tx
    local real ty
    local real a
    if GetUnitAbilityLevel(u,bap) > 0 then
        set tx = GetUnitX(u)
        set ty = GetUnitY(u)
        set a = Atan3(tx,ty,x,y)
        set xe = dcollider.create(tx,ty,a)
        set xe.fxpath = mdl
        set xe.z = 50
        set xe.collisionSize = 40
        set xe.speed = 650.0
        set xe.targetUnit = d.c
        set xe.angleSpeed = 3.0
        set xe.c = d.c
        set xe.l = l
    endif
endfunction

private function act takes nothing returns nothing
    call OnUnitDeath(deathDetect,true)
    //how to attach units?
endfunction

private function init takes nothing returns nothing
    local trigger t = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ(t,EVENT_PLAYER_HERO_SKILL)
    call TriggerAddAction(t,function act)
    call TriggerAddCondition(t, Condition(function con))
endfunction

endscope
06-24-2009, 01:37 PM#2
tamisrah
I'd suggest a different approach:
Setup the DeathEvent like an AnyUnitEvent and check in an if statement whether it is a unit affected by your spell. That unit could be marked by a buff, a dummy ability or some attachement, which would be done with a different system. e.g. -> AutoIndex + StructStack
06-24-2009, 03:38 PM#3
grim001
I don't know what you mean by "attach" here. When you attach, you much attach something to something else.

Examle: Attaching an integer to a unit...

If you can be more clear about what you want to do it'll help.
06-24-2009, 05:27 PM#4
Anitarf
Wait, if I understand this correctly (your explanation is very vague) you want the function to run, but only when a specific unit dies? If so, then register the function at map init, not when the unit learns the ability, then when the unit learns the ability add it to a global group. In the function that you registered, simply check if the unit that was passed to the function is in the group.
06-24-2009, 11:25 PM#5
Sinnergy
Quote:
Originally Posted by Anitarf
Wait, if I understand this correctly (your explanation is very vague) you want the function to run, but only when a specific unit dies? If so, then register the function at map init, not when the unit learns the ability, then when the unit learns the ability add it to a global group. In the function that you registered, simply check if the unit that was passed to the function is in the group.
yep, that's right, my problem is, when I attached the unit in a global variable, if another unit (with the same type) learns the spell, then the global variable will be replaced by the last unit learning the spell.

For the "attach the unit to the group" method, I haven't tried it before, and I really can't compare what's the difference between adding the unit to a global unit variable or adding the unit to a global group variable (maybe storing the units in some sort of unit pool?).

Lets say 2 units with the same type are added to the group, and when a unit dies with the aura buff, the response function runs, but what unit will I pick as the owner of the aura, since the two units has the same aura with the same buff?

Here's what I want for the spell: A passive ability that buffs nearby enemy units, if a buffed unit dies, some sort of death coil missile will run from the dying unit to the owner of the aura, healing the owner.

In my problem, I want to attach the learning unit to use it as the target of the death coil missiles and still maintaining its' MUI-ness.

Quote:
Originally Posted by grim001
I don't know what you mean by "attach" here. When you attach, you much attach something to something else.

Examle: Attaching an integer to a unit...

If you can be more clear about what you want to do it'll help.
attaching an integer to a unit is an example, but what unit will I use to attach the integer? since there are no units that will be passed to the function? the response function takes a unit u, which is used by the response function as the dying unit, but I can't find a way to attach something to that unit.
06-24-2009, 11:40 PM#6
Anitarf
Quote:
Originally Posted by Sinnergy
For the "attach the unit to the group" method, I haven't tried it before, and I really can't compare what's the difference between adding the unit to a global unit variable or adding the unit to a global group variable (maybe storing the units in some sort of unit pool?).
Yes, that's kind of the point of unit groups. As the name implies, it can store a group of units, not just one.
06-24-2009, 11:46 PM#7
grim001
You aren't using the word "attach" properly. Whenever you say "attach" you have to say what you're what you're attaching to what. Attachment is something that requires 2 pieces of data, and you are making one retrievable when you have the other. You seem to be using it as some generic verb, but in the context of how you're using it, it's totally meaningless.

Anyway, you can either use the unitgroup method Anitarf is recommending, or you can use a global boolean array. And why are you using unit indexing if you don't understand how to attach things to units with it?

Collapse JASS:
set SomeBooleanArray[GetUnitId(u)] = true
06-26-2009, 08:58 AM#8
Sinnergy
Ok I have made another code for the spell, I hope I am doing right.
Collapse JASS:
scope Spell3 initializer init

globals
    private constant integer spell = 'A020'
    private constant integer bap = 'B00M'
    private constant string mdl = "Abilities\\Spells\\Undead\\DeathCoil\\DeathCoilMissile.mdl"
    private constant string sfx = "Abilities\\Spells\\Undead\\DeathCoil\\DeathCoilSpecialArt.mdl"
    private boolean array myBool
    private group ADD
endglobals

private struct dcollider extends xecollider
    unit c
    integer l
    method onUnitHit takes unit u returns nothing
        if u == .c then
            call SetWidgetLife(.c,GetWidgetLife(.c) + 15*.l)
            call DestroyEffect(AddSpecialEffectTarget(sfx,.c,"origin"))
            call .terminate()
        endif
    endmethod
    
    method loopControl takes nothing returns nothing
        if GetWidgetLife(.c) < 0.405 then
            call .terminate()
        endif
    endmethod
    
endstruct

private function con takes nothing returns boolean
    return GetLearnedSkill() == spell and GetUnitAbilityLevel(GetTriggerUnit(),spell) == 1
endfunction

private function deathDetect takes unit u returns nothing
//forget these lines, they aren't necessary
    local unit c = FirstOfGroup(ADD)
    local integer l = GetUnitAbilityLevel(c,spell)
    local dcollider xe
    local real x = GetUnitX(c)
    local real y = GetUnitY(c)
    local real tx
    local real ty
    local real a
    if GetUnitAbilityLevel(u,bap) > 0 then
        set tx = GetUnitX(u)
        set ty = GetUnitY(u)
        set a = Atan3(tx,ty,x,y)
        set xe = dcollider.create(tx,ty,a)
        set xe.fxpath = mdl
        set xe.z = 50
        set xe.collisionSize = 40
        set xe.speed = 650.0
        set xe.targetUnit = c
        set xe.angleSpeed = 3.0
        set xe.c = c
        set xe.l = l
    endif
endfunction

private function act takes nothing returns nothing
    set myBool[GetUnitId(GetTriggerUnit())] = true
    call GroupAddUnit(ADD,GetTriggerUnit())
    call OnUnitDeath(deathDetect,myBool[GetUnitId(GetTriggerUnit())])
endfunction

private function init takes nothing returns nothing
    local trigger t = CreateTrigger()
    set ADD = CreateGroup()
    call TriggerRegisterAnyUnitEventBJ(t,EVENT_PLAYER_HERO_SKILL)
    call TriggerAddAction(t,function act)
    call TriggerAddCondition(t, Condition(function con))
endfunction

endscope
I am not familiar with storing the unit in a unit group and use the unit inside the global group as the unit source. Am I coding the spell right in means of using the learning unit as the source unit? If I am doing it wrong, what should I do to make this work and of course should maintain its MUI-ness?

By looking at the code, if my hero learns the skill, it will be added to the global unit group, and in the response function, the unit (first of group) is used as the source of the aura. What if another unit (enemy or allied or owned by me) with the same type learns the same ability? I pictured out that the "another" unit that learns the spell will be added in the group, which means only one of the 2 units inside the global group will be used as the source of aura, which ends up healing the second unit when a unit dies with the buff, even though the first unit owns the aura and the one which is the buff source.
06-26-2009, 05:44 PM#9
Feroc1ty
Quote:
Originally Posted by grim001
Whenever you say "attach" you have to say what you're what you're attaching to what.

what?
06-26-2009, 11:30 PM#10
Sinnergy
he said, "attach" means attaching an object to another object.
06-26-2009, 11:36 PM#11
grim001
Quote:
Originally Posted by Feroc1ty
what?

Ha ha.
06-27-2009, 11:41 AM#12
Sinnergy
For the code, it is now working, but didn't used StatusEvents, I used ABuff_Auras, since I already have ABuff_Aura inside my map.