• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

[JASS] Problem with effect deletion

Status
Not open for further replies.
Level 3
Joined
Dec 28, 2007
Messages
46
Ok so here's the ability setup that I have:

One hero has two skills. One skill summons a fire bear unit. The other skill summons an ice bear unit. Both of these units have an ability for a 6 item inventory that wont let them use items, but will let them pick them up and hold them.

Im making two separate scripts for each summoned unit that stores the items in an array when they die and when the unit is next summoned, puts the items back into the inventory.

Here is my script so far:


JASS:
function Is_Storing takes nothing returns boolean
    return ( GetUnitTypeId(GetDyingUnit()) == 'n004' )
endfunction

function Is_Restoring takes nothing returns boolean
    return ( GetSpellAbilityId() == 'A00B' )
endfunction

function Trig_AG_Items_Frost_Actions takes nothing returns nothing
    local item array AG_Bear_Inventory
    local integer AG_Item_Index = 0 
    local location AG_Summoner_Index
    local location AG_Death_Pos
    local effect AG_Death_Effect
    local unit AG_Item_Recipient
    
    if ( Is_Storing() == true ) then
        loop
            exitwhen (AG_Item_Index == 6)
            call DisplayTextToForce( GetPlayersAll(), I2S(AG_Item_Index) ) //DEBUG OUTPUT
            set AG_Bear_Inventory[AG_Item_Index] = UnitItemInSlot(GetDyingUnit(), AG_Item_Index)
            set AG_Item_Index = (AG_Item_Index + 1)
        endloop
            set AG_Death_Pos = GetUnitLoc(GetDyingUnit())
            call AddSpecialEffectLoc("Abilities\\Spells\\Orc\\SpiritLink\\SpiritLinkZapTarget.mdl", AG_Death_Pos)
            set AG_Death_Effect = bj_lastCreatedEffect
            set AG_Death_Pos = null
            call RemoveLocation(AG_Death_Pos)
            call RemoveUnit(GetDyingUnit())
            call TriggerSleepAction(3)
            call DestroyEffect(AG_Death_Effect)
            set AG_Death_Effect = null           
        endif  
    
endfunction

//==== Init Trigger AG_Items_Frost ====
function InitTrig_AG_Items_Frost takes nothing returns nothing
    set gg_trg_AG_Items_Frost = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ(gg_trg_AG_Items_Frost, EVENT_PLAYER_UNIT_DEATH )
    call TriggerRegisterAnyUnitEventBJ(gg_trg_AG_Items_Frost, EVENT_PLAYER_UNIT_SPELL_CAST )
    call TriggerAddAction(gg_trg_AG_Items_Frost, function Trig_AG_Items_Frost_Actions)
endfunction



I need to know why the effect isnt being removed in the part:

JASS:
set AG_Death_Pos = GetUnitLoc(GetDyingUnit())
            call AddSpecialEffectLoc("Abilities\\Spells\\Orc\\SpiritLink\\SpiritLinkZapTarget.mdl", AG_Death_Pos)
            set AG_Death_Effect = bj_lastCreatedEffect
            set AG_Death_Pos = null
            call RemoveLocation(AG_Death_Pos)
            call RemoveUnit(GetDyingUnit())
            call TriggerSleepAction(3)
            call DestroyEffect(AG_Death_Effect)
            set AG_Death_Effect = null

Thanks for the help. :)
 
Level 20
Joined
Apr 22, 2007
Messages
1,960
Because bj_lastCreatedEffect only works with the BJ functions. In this case, you'd have to do:
JASS:
set AG_Death_Effect = AddSpecialEffectLoc("Abilities\\Spells\\Orc\\SpiritLink\\SpiritLinkZapTarget.mdl", AG_Death_Pos)
And remove the set AG_Death_Effect = bj_lastCreatedEffect line.

I haven't reviewed the rest of your code though, but just by quickly glancing, I'll have to tell you to:
  • Stop using locations. Use coordinates (reals) instead.
  • Use timers instead of TriggerSleepAction
  • Avoid BJ functions.
 
Level 3
Joined
Dec 28, 2007
Messages
46
Awesome. Thanks HINDY. I do avoid BJ Functions completely. I wasnt sure of the non-BJ function for getting last created special effect, so i looked inside the BJ Function and found that. :xxd:

As for the locations. If you delete/remove them do they still pose a leak problem?
 
Level 20
Joined
Apr 22, 2007
Messages
1,960
Yup. Locations are handles, and local handles leak if you don't null them at the end of a function. Remember to null all local handles at the end of a function (handles are every variable type in wc3 except integer,real,boolean,string,code.
 
Level 3
Joined
Dec 28, 2007
Messages
46
Also, does storing the items in that local array even do anything? Since the revival of the unit will be a separate instance of the same trigger, it wont be able to access the items will it?

**EDIT**
Found that the spell would not work as was with a local array variable. So I have to re-work it. I am going to store the items instead of in a variable, in dummy units with inventories. However I am having a problem.

What the scripts are supposed to do, is when the unit picks up the item, the script finds the item type, finds the owner of the unit as an index which points to one of the storage units which are in a global array. If the inventory of the dummy unit is full, the script knows the slot the item is in and is supposed to remove an item from the corresponding spot in the dummy unit. This ensures that the inventories of the two stay exactly the same.

The problem I am having is that for some reason the script isnt finding the slot correctly and it is removing items wrong. It is best seen in the actual map which I have made a testing-easy version of and attached. I would appreciate it if someone could take a look at it to see for themselves.

Here are the scripts. The first one creates the dummy units (one for each player) and assigns each unit to the global unit array. The second script is the actual item storage/inventory clone spell. right now im just trying to get the scripts to work right. I havnt gotten around to optimizing yet, so if possible help me get them working first.

thanks so much.



JASS:
//==============================================================================//
// Trigger:         AG Create Item Store                                        //
//                                                                              //
// Original Script: AlphaChicken                                                //
//                                                                              //
// !!REQS!!         Uses global variable:                                       //
//                  -AG_Store_Ownership  Unit Array(1) Empty                    //
//==============================================================================//


function Trig_AG_Create_Item_Store_Actions takes nothing returns nothing

    local integer AG_Loop_Index = 0
    local integer X_Coord = 2500
    local integer Y_Coord = -3000
    
    loop
        exitwhen (AG_Loop_Index == 12)
        set udg_AG_Store_Ownership[AG_Loop_Index] = (CreateUnit(Player(15), 'n006', X_Coord, Y_Coord, 270))
        set X_Coord = (X_Coord + 100)
        if (X_Coord == 2900) then
            set X_Coord = 2500
            set Y_Coord = (Y_Coord + 100)
        endif
        set AG_Loop_Index = (AG_Loop_Index + 1)
    endloop
    
    set AG_Loop_Index = 0
    set X_Coord = 2500
    set Y_Coord = -3000
    
endfunction

//==== Init Trigger AG_Create_Item_Store ====
function InitTrig_AG_Create_Item_Store takes nothing returns nothing
    set gg_trg_AG_Create_Item_Store = CreateTrigger()
    call TriggerAddAction(gg_trg_AG_Create_Item_Store, function Trig_AG_Create_Item_Store_Actions)
endfunction



JASS:
function Trig_AG_Store_Items_Conditions takes nothing returns boolean
    if ( GetUnitTypeId(GetTriggerUnit()) == 'n004' ) then
        return true
    endif    
    return false
endfunction

function Find_Player_No takes nothing returns integer
    local integer index = 0
    loop
        exitwhen (index == 12)
        if ( GetOwningPlayer(GetTriggerUnit()) == Player(index) ) then
            return index
        endif
        set index = (index + 1)
    endloop
    return 99
endfunction

function Find_Slot_No takes nothing returns integer
    local integer index = 0
    loop
        exitwhen (index == 6)
        if ( GetItemType(GetManipulatedItem()) == GetItemType(UnitItemInSlot(GetTriggerUnit(), index)) ) then
            return index
        endif
        set index = (index +1)
    endloop
    return 99
endfunction
        
    

function Trig_AG_Store_Items_Actions takes nothing returns nothing
    local integer AG_Picked_Up
    local integer Player_Number = Find_Player_No()
    local integer Slot_Number = Find_Slot_No()    
    set AG_Picked_Up = GetItemTypeId(GetManipulatedItem())
    call UnitRemoveItemFromSlot(udg_AG_Store_Ownership[Player_Number], Slot_Number)
    call UnitAddItemById(udg_AG_Store_Ownership[Player_Number], AG_Picked_Up)    
endfunction

//==== Init Trigger AG_Store_Items ====
function InitTrig_AG_Store_Items takes nothing returns nothing
    set gg_trg_AG_Store_Items = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ( gg_trg_AG_Store_Items, EVENT_PLAYER_UNIT_PICKUP_ITEM )
    call TriggerAddCondition( gg_trg_AG_Store_Items, Condition( function Trig_AG_Store_Items_Conditions ) )
    call TriggerAddAction(gg_trg_AG_Store_Items, function Trig_AG_Store_Items_Actions)
endfunction
 

Attachments

  • ItemRestoreTest.w3x
    25 KB · Views: 47
Status
Not open for further replies.
Top