HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Referencing unit created with Couple?

11-24-2008, 01:01 AM#1
Monstah
Hello again. This time I want some help with the couple ability (as in Pick Up Archer and Mount Hippogryph).

I am trying to create a system in which "gold" (or rather, it's equivalent resource) is represented by "wisps". Among other difficulties I will tackle later (such as spending the wisps), I want the player to be able to group together wisps into larger wisps, which hold more gold (so they don't end up with an army of $1 coins). Think of it as changing ten $1s for one $10 (and vice-versa).

I made the custom abilities, and now I want to implement the gold value change. I am storing the ammount of gold via Unit Custom Value (when the gold wisps are created, the value is set to 1). I want these values to add when wisps group together.

What I got so far: I got the trigger to catch the ability being cast. "triggering unit" and "target of ability being cast" are the two units that fuse together, so I can add their custom values. How can I get the new unit, tho? "Spawned unit", "last created unit", "last replaced unit", "entering unit"... all these don't seem to work. Can I do it with custom scripting?

Collapse JASS:
function Trig_group_wisps_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A002'
endfunction

function Trig_group_wisps_Actions takes nothing returns nothing
    local unit a
    local unit b
    local unit c
    local integer gold_a
    local integer gold_b
    local integer gold_c

    set a = GetTriggerUnit()
    set b = GetSpellTargetUnit()
    set c = ?????
    set gold_a = GetUnitUserData(a)
    set gold_b = GetUnitUserData(b)
    set gold_c = gold_a + gold_b

    call SetUnitUserData( c, gold_c )
endfunction

//===========================================================================
function InitTrig_group_wisps takes nothing returns nothing
    set gg_trg_group_wisps = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_group_wisps, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_group_wisps, Condition( function Trig_group_wisps_Conditions ) )
    call TriggerAddAction( gg_trg_group_wisps, function Trig_group_wisps_Actions )
endfunction


Thank you.
11-24-2008, 02:26 AM#2
Zerzax
You could try using a group to find unit the unit that matches the condition you are looking for in a very tiny radius between the GetTriggerUnit() and GetSpellTargetUnit(). Here would be an example:

Collapse JASS:

function Trig_group_wisps_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A002'
endfunction

function Wisp_Morph_Filter takes nothing returns boolean
    return GetWidgetLife(GetFilterUnit()) > 0.405 and IsUnitTypeId(MORPHED_UNIT_ID)
endfunction

// 0.405 health is the official cutoff of a dead unit. We do not want a dead hippogryph! The second condition checks whether the unit the group has found in range matches the type of unit you want, namely the mounted hippogryph.

function Trig_group_wisps_Actions takes nothing returns nothing
    local unit a = GetTriggerUnit()
    local unit b = GetSpellTargetUnit()
    local unit c
    local group g = CreateGroup()
    local boolexpr morph_filter = Condition(function Wisp_Morph_Filter)
    // to prevent a memory leak, this filtering boolean expression is used with the filter function as a base
    local integer gold_a
    local integer gold_b
    local integer gold_c

    call GroupEnumUnitsInRange(g, GetUnitX(a), GetUnitY(a), 25.00, morph_filter)
    
    if FirstOfGroup(g) != null then
        set c=FirstOfGroup(g)
    endif 

    set gold_a = GetUnitUserData(a)
    set gold_b = GetUnitUserData(b)
    set gold_c = gold_a + gold_b

    call SetUnitUserData( c, gold_c )
    
   // The handles that we created need to be destroyed.

    call DestroyBoolExpr(morph_filter)
    call GroupClear(g)
    call DestroyGroup(g)

    // all handle variables ( unit, group, boolexpr to name a few, need to be nulled to prevent memory leaks )


    set a = null
    set b = null
    set morph_filter = null
    set c = null    
    set g = null

endfunction

//===========================================================================
function InitTrig_group_wisps takes nothing returns nothing
    set gg_trg_group_wisps = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_group_wisps, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_group_wisps, Condition( function Trig_group_wisps_Conditions ) )
    call TriggerAddAction( gg_trg_group_wisps, function Trig_group_wisps_Actions )
endfunction

I haven't compiled this nor tested it, so it might not work, but do you get the gist of it? The group will find the unit that you've just morphed by searching for units in this tiny radius. The new stuff I added might be confusing, but I went to lengths to ensure that there would be no memory leaks.
11-24-2008, 03:52 AM#3
xombie
I understand what you're trying to look for here, but honestly I think that you would be better off to trigger this so that each time the ability is put into effect, you kill off both wisps and create the new, bigger wisp.
11-24-2008, 07:50 AM#4
Tide-Arc Ephemera
Like what Xombie said. Kill both of them, create a new unit with the total custom value. Easier.
11-24-2008, 01:31 PM#5
Zerzax
Yeah that's the best way.
11-24-2008, 01:55 PM#6
tamisrah
Just for curiosity, is there a way to do so, like GetSummonedUnit() or something like that?
11-24-2008, 02:17 PM#7
Kyrbi0
Yes, I too would like to know if it's even possible. I've tried to make Couple work with 2 of the same unit (i.e. "2 ghouls --> Abomination" type merger, or "2 high Templar --> Archon" :P), but it never works right. Are triggers the only solution?
11-24-2008, 03:04 PM#8
Sooda
I think 'unit enters playable map area' should detect new unit (mounted unit).
11-24-2008, 03:57 PM#9
Monstah
Quote:
Originally Posted by Kyrbi0
Yes, I too would like to know if it's even possible. I've tried to make Couple work with 2 of the same unit (i.e. "2 ghouls --> Abomination" type merger, or "2 high Templar --> Archon" :P), but it never works right. Are triggers the only solution?
Mine is wisp + wisp = wisp. This part worked fine, which was funny, because since there's no trigger to control this yet (the custom point "mana" part), and no mana cost or cooldown, I could make a single wisp explode into a huge population.

Besides, I found out if you use "Mount Hippogryph" as your base ability, it doesn't work. You need to use "Pick up archer", because it is the hippogryph that moves towards the archer. Theres a boolean supposed to control that, but I think it didn't work. Not so sure now.

I suspect I could use the unit's mana to store that value (initial ammount = 1, regen = 0), but then there's the undesirable (maybe not?) mana maximum. Plus, I intend wisps to have other uses than just ordering money around. Maybe that does make it interesting to use mana instead of custom points...

Quote:
Originally Posted by tamisrah
Just for curiosity, is there a way to do so, like GetSummonedUnit() or something like that?

I think that's what GUI "event response - summoned unit" does, isn't it? Tried it, didn't work :(

Quote:
Originally Posted by Sooda
I think 'unit enters playable map area' should detect new unit (mounted unit).

That's an event, isn't it? My event is "unit begins effect of ability". Can I use them together?

Think I will try killing them and creating a new one. Sounds logical, plus I can get to order it to couple again (if possible). Will try that and report later.
11-24-2008, 08:03 PM#10
MaD[Lion]
this is a great great idea man... it allow good expansion of the income and stuff :P
11-25-2008, 01:11 AM#11
Monstah
It works like a charm! All I need now are cool visual and sould effects.

I wanted my wisps to have the Doodad - Fire Blue model, but it can't be selected. What's the easiest way to add the fire on top of the unit?

edit - attached map. Check it out! Thank you very much.
Attached Files
File type: w3xgold wisp test.w3x (19.4 KB)
11-25-2008, 01:50 AM#12
Kyrbi0
Try making a "dummy art attachment" ability out of something like Item - Armor Bonus (+1), removing all the "+ armor" parts, and then putting the effect you want in the "Art - Target". Then, of course, change "Art - Target Attachment Point 1" to wherever you want the attachment to attach, and change "Art - Target Attachments" to 1 (or however many attachments you attach).
11-25-2008, 10:19 AM#13
Anitarf
Quote:
Originally Posted by Monstah
How can I get the new unit, tho? "Spawned unit", "last created unit", "last replaced unit", "entering unit"... all these don't seem to work. Can I do it with custom scripting?
Just thought I'd clarify this, they don't work because they were made to work with other events, not the spell event you were using at the time.
11-25-2008, 12:06 PM#14
Monstah
Quote:
Originally Posted by Anitarf
Just thought I'd clarify this, they don't work because they were made to work with other events, not the spell event you were using at the time.

Though so, but gave it a try anyway.

Quote:
Originally Posted by Kyrbi0
Try making a "dummy art attachment" ability out of something like Item - Armor Bonus (+1), removing all the "+ armor" parts, and then putting the effect you want in the "Art - Target". Then, of course, change "Art - Target Attachment Point 1" to wherever you want the attachment to attach, and change "Art - Target Attachments" to 1 (or however many attachments you attach).

Will try, thanks ^^

And here's the script, in case you don't feel like downloading the map:

Collapse JASS:
function Trig_group_wisps_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A002'
endfunction

function Trig_group_wisps_Actions takes nothing returns nothing

    local unit a = GetTriggerUnit()
    local unit b = GetSpellTargetUnit()
    local unit c
    
    local location x = GetUnitLoc(a)
    local player p = GetOwningPlayer(a)
    local integer u = GetUnitTypeId(a)

    local real mana_a = GetUnitStateSwap(UNIT_STATE_MANA, a)
    local real mana_b = GetUnitStateSwap(UNIT_STATE_MANA, b)
    local real mana_c = mana_a + mana_b

    local real life_a = GetUnitStateSwap(UNIT_STATE_LIFE, a)
    local real life_b = GetUnitStateSwap(UNIT_STATE_LIFE, b)
    local real life_c = (life_a * mana_a + life_b * mana_b)/(mana_a + mana_b)

    call RemoveUnit( a )
    call RemoveUnit( b )

    set c = CreateUnitAtLoc( p, u, x, GetUnitFacing(a))

    call SetUnitManaBJ( c, mana_c )
    call SetUnitLifeBJ( c, life_c )
    call SelectUnitAddForPlayer( c, p )
    call IssueImmediateOrderBJ( c, "coupleinstant" )

    //call DisplayTextToForce( GetPlayersAll(), R2S(GetUnitStateSwap(UNIT_STATE_MANA, c)) )

    set a = null
    set b = null
    set c = null
    set x = null
    set p = null
endfunction

//===========================================================================
function InitTrig_group_wisps takes nothing returns nothing
    set gg_trg_group_wisps = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_group_wisps, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_group_wisps, Condition( function Trig_group_wisps_Conditions ) )
    call TriggerAddAction( gg_trg_group_wisps, function Trig_group_wisps_Actions )
endfunction

Collapse JASS:
function Trig_ungroup_wisps_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A001'
endfunction

function Trig_ungroup_wisps_Actions takes nothing returns nothing

    local unit a = GetTriggerUnit()
    local unit b
    local unit c

    local player p = GetOwningPlayer(a)
    local location x = GetUnitLoc(a)
    local integer u = GetUnitTypeId(a)
    
    local real mana_a =  GetUnitStateSwap(UNIT_STATE_MANA, a)
    local real mana_b
    local real mana_c

    local real life = GetUnitStateSwap(UNIT_STATE_LIFE, a)

    if (mana_a > 1 and life > .405) then

        set mana_b = mana_a/2
        set mana_c = mana_a - mana_b

        call RemoveUnit( a )
        
        set b = CreateUnitAtLoc( p, u, x, GetUnitFacing(a))
        set c = CreateUnitAtLoc( p, u, x, GetUnitFacing(a))
        
        call SetUnitManaBJ( b, mana_b )
        call SetUnitLifeBJ( b, life )
        
        call SetUnitManaBJ( c, mana_c )
        call SetUnitLifeBJ( c, life )

        call SelectUnitAddForPlayer( b, p )
        call SelectUnitAddForPlayer( c, p )
        
        //call DisplayTextToForce( GetPlayersAll(), R2S(GetUnitStateSwap(UNIT_STATE_MANA, b)) )
        //call DisplayTextToForce( GetPlayersAll(), R2S(GetUnitStateSwap(UNIT_STATE_MANA, c)) )
    else    
        call IssueImmediateOrderBJ( a, "stop" )
        //call DisplayTextToForce( GetPlayersAll(), R2S(GetUnitStateSwap(UNIT_STATE_MANA, !a)) )
    endif
    
    set a = null
    set b = null
    set c = null
    set x = null
    set p = null
endfunction

//===========================================================================
function InitTrig_ungroup_wisps takes nothing returns nothing
    set gg_trg_ungroup_wisps = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_ungroup_wisps, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_ungroup_wisps, Condition( function Trig_ungroup_wisps_Conditions ) )
    call TriggerAddAction( gg_trg_ungroup_wisps, function Trig_ungroup_wisps_Actions )
endfunction

Hmm, I made some slight alterations but my computer crashed without saving, but that's pretty much it.
11-25-2008, 12:13 PM#15
Kyrbi0
^Cool, thanks; I always prefer to copy/paste than to Download.

Glad I could (hopefully) help.