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

[JASS] Trigger Double-check

Status
Not open for further replies.
Level 5
Joined
Sep 19, 2006
Messages
152
Just wanted an extra set of eyes over this trigger, for the purposes of efficiency and leakage. One point to consider however: the undead units have a negative regeneration in daylight and therefore die (thus the != null condition).

JASS:
function CreepsDeathUndead_Condition01 takes nothing returns boolean
    return GetKillingUnit () != null
endfunction

function UndeadItemCreator takes unit trig_unit, integer trig_unitE, integer P_CIB returns nothing
    local item drop_item
    local integer drop_itemE
    local integer drop_itemJ


    if GetRandomInt (1, 10) > P_CIB then
        set drop_itemE = GetRandomInt (0, trig_unitE / 8)
    elseif GetRandomInt (1, 50) > P_CIB then
        set drop_itemE = GetRandomInt (0, trig_unitE / 8) + 1
    else
        set drop_itemE = GetRandomInt (0, trig_unitE / 8) + 2
    endif
    if drop_itemE > 9 then
        set drop_itemE = GetRandomInt (2, 9)
    endif

    set drop_item = CreateItem (ChooseRandomItem (drop_itemE), GetUnitX (trig_unit), GetUnitY (trig_unit))
    set drop_itemJ = GetItemTypeId (drop_item)
    if drop_itemJ == 'mgtk' or drop_itemJ == 'srrc' or drop_itemJ == 'mcri' or drop_itemJ == 'sres' then
        call SetItemInvulnerable (drop_item, true)
        call SetItemUserData (drop_item, 200)
    endif
    call DestroyEffect (AddSpecialEffectTarget ("Abilities\\Weapons\\PhoenixMissile\\Phoenix_Missile_mini.mdl", drop_item, "origin"))
    set drop_item = null
endfunction

function CreepsDeathUndead_Action01 takes nothing returns nothing
    local unit kill_unit         = GetKillingUnit ()
    local integer kill_unitQ     = GetPlayerId (GetOwningPlayer (kill_unit))
    local unit trig_unit         = GetDyingUnit ()
    local integer trig_unitE     = GetUnitLevel (trig_unit)
    local integer q
    local integer P_CWu
    local item drop_item
    local itempool I


//  Determine Killing Player

    if kill_unitQ == 15 then
        set q = 1
        loop
            exitwhen q == 12
            if kill_unit == udg_PlayerMerc [q] then
                set kill_unitQ = q
                set q = 12
            elseif kill_unit == udg_PlayerFamiliar [q] then
                set kill_unitQ = q
                set q = 12
            else
                set q = q + 1
            endif
        endloop
        if kill_unitQ == 15 then
            set trig_unit = null
            set kill_unit = null
            return
        endif
    endif


//  Scoring and Gold

    set udg_PlayerKills [kill_unitQ] = udg_PlayerKills [kill_unitQ] + 1
    set udg_PlayerKillsLevels [kill_unitQ] = udg_PlayerKillsLevels [kill_unitQ] + trig_unitE


//  Filter Computer Hero

    if udg_PlayerTypeIsHuman [kill_unitQ] == false then
        set trig_unit = null
        set kill_unit = null
        return
    endif


//  Create Items (Undead-specific)

    set P_CWu = udg_PlayerItemUsed_CrstWater [kill_unitQ]
    if P_CWu > 0 then
        set udg_PlayerItemUsed_CrstWater [kill_unitQ] = P_CWu - 1
        call UndeadItemCreator (trig_unit, trig_unitE, udg_PlayerChanceItemBoost [kill_unitQ])
    elseif udg_RealArray [kill_unitQ + 100] + udg_RealArray [kill_unitQ + 160] > GetRandomReal (0.00, 99.00) then
        call UndeadItemCreator (trig_unit, trig_unitE, udg_PlayerChanceItemBoost [kill_unitQ])
    elseif GetRandomInt (1, 35) == 1 then
        set I = CreateItemPool ()
        if GetRandomInt (1, 10) == 1 then
            call ItemPoolAddItemType (I, 'I05J', 1)  //  Bone Powder
            call ItemPoolAddItemType (I, 'I05F', 1)  //  Crypt Wand
            call ItemPoolAddItemType (I, 'I05E', 1)  //  Grave Wand
            call ItemPoolAddItemType (I, 'I05D', 1)  //  Tomb Relic
            call ItemPoolAddItemType (I, 'I05N', 1)  //  Vial of Evolution
            set drop_item = PlaceRandomItem (I, GetUnitX (trig_unit), GetUnitY (trig_unit))
        else
            call ItemPoolAddItemType (I, 'I05M', 4)  //  Black Zombie Hide
            call ItemPoolAddItemType (I, 'I05R', 4)  //  Carrion Bird Wing
            call ItemPoolAddItemType (I, 'I05Q', 4)  //  Grey Zombie Hide
            call ItemPoolAddItemType (I, 'I05O', 2)  //  Mossy Skull
            call ItemPoolAddItemType (I, 'I05G', 4)  //  Rotted Limb
            call ItemPoolAddItemType (I, 'I05S', 4)  //  Skull
            call ItemPoolAddItemType (I, 'I05P', 5)  //  Slime
            call ItemPoolAddItemType (I, 'I05K', 1)  //  Specter Soul
            call ItemPoolAddItemType (I, 'I05I', 1)  //  Wraith Soul
            call ItemPoolAddItemType (I, 'I05H', 4)  //  Yellow Zombie Hide
            call ItemPoolAddItemType (I, 'I05T', 2)  //  Zombie Heart
            set drop_item = PlaceRandomItem (I, GetUnitX (trig_unit), GetUnitY (trig_unit))
            call SetItemUserData (drop_item, 210)
        endif
        call DestroyEffect (AddSpecialEffectTarget ("Abilities\\Weapons\\PhoenixMissile\\Phoenix_Missile_mini.mdl", drop_item, "origin"))
        call DestroyItemPool (I)
        set I = null
        set drop_item = null
    endif
    set trig_unit = null
    set kill_unit = null
endfunction

function InitTrig_CreepsDeathUndead takes nothing returns nothing
    set gg_trg_CreepsDeathUndead = CreateTrigger ()
    call TriggerRegisterPlayerUnitEvent (gg_trg_CreepsDeathUndead, Player (14), EVENT_PLAYER_UNIT_DEATH, null)
    call TriggerAddCondition (gg_trg_CreepsDeathUndead, Condition (function CreepsDeathUndead_Condition01))
    call TriggerAddAction (gg_trg_CreepsDeathUndead, function CreepsDeathUndead_Action01)
endfunction
 

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,468
It's a pretty nice coding style you have.

For efficiency the most important thing you could change is drag the actions into the conditions block, since you don't use any TriggerSleepActions within the script you could spare yourself the weight of using trigger actions which are only useful for allowing TriggerSleepActions, at a relatively high performance penalty compared to the alternative (doing it all from one thread).

You could also get away with 2 global item pools which never get destroyed, since you are not modifying the pool contents dynamically this would be an efficiency perk.

ItemUserData is OK if you are making a map, because you know whether or not it won't conflict with other systems. If this were a standalone snippet apart from a larger map then it won't be safe to use ItemUserData.
 
Level 5
Joined
Sep 19, 2006
Messages
152
It's a pretty nice coding style you have.

For efficiency the most important thing you could change is drag the actions into the conditions block.

You could also get away with 2 global item pools which never get destroyed.


Thank you for your response. However, I am a bit unclear about your suggestions.

First, if I moved the Actions into the Conditions block, would I then begin that block with something like the following?
JASS:
local unit kill_unit = GetKillingUnit ()
// (other locals -- not yet assigned)

If killing_unit == null then
    return
else
// (set other locals)
endif

Second, I'm not sure how to create a global item pool, other than to use an integer array for the different item codes. Is there another method of which I am unaware?
 
Level 5
Joined
Sep 19, 2006
Messages
152
You just make an item pool variable in variable editor, set it from the inittrig function, and for the condition and action thing just make one function call another

Hmmm, I don't see either an "item pool" or an "item group" in the variable editor. Can you provide me an example?
 
Level 5
Joined
Sep 19, 2006
Messages
152
Here is the revised trigger (although I'm still a little unclear about the "move everything into the Conditions part" thing).

JASS:
function CreepsDeathUndead_Condition01 takes nothing returns boolean
    return GetKillingUnit () != null
endfunction

function UndeadItemCreator takes unit trig_unit, integer trig_unitE, integer P_CIB returns nothing
    local item drop_item
    local integer drop_itemE
    local integer drop_itemJ


    if GetRandomInt (1, 10) > P_CIB then
        set drop_itemE = GetRandomInt (0, trig_unitE / 8)
    elseif GetRandomInt (1, 50) > P_CIB then
        set drop_itemE = GetRandomInt (0, trig_unitE / 8) + 1
    else
        set drop_itemE = GetRandomInt (0, trig_unitE / 8) + 2
    endif
    if drop_itemE > 9 then
        set drop_itemE = GetRandomInt (2, 9)
    endif

    set drop_item = CreateItem (ChooseRandomItem (drop_itemE), GetUnitX (trig_unit), GetUnitY (trig_unit))
    set drop_itemJ = GetItemTypeId (drop_item)
    if drop_itemJ == 'mgtk' or drop_itemJ == 'srrc' or drop_itemJ == 'mcri' or drop_itemJ == 'sres' then
        call SetItemInvulnerable (drop_item, true)
        call SetItemUserData (drop_item, 200)
    endif
    call DestroyEffect (AddSpecialEffectTarget ("Abilities\\Weapons\\PhoenixMissile\\Phoenix_Missile_mini.mdl", drop_item, "origin"))
    set drop_item = null
endfunction

function CreepsDeathUndead_Action01 takes nothing returns nothing
    local unit kill_unit         = GetKillingUnit ()
    local integer kill_unitQ     = GetPlayerId (GetOwningPlayer (kill_unit))
    local unit trig_unit         = GetDyingUnit ()
    local integer trig_unitE     = GetUnitLevel (trig_unit)
    local integer q
    local integer P_CWu
    local item drop_item
    local integer R

//  Determine Killing Player

    if kill_unitQ == 15 then
        set q = 1
        loop
            exitwhen q == 12
            if kill_unit == udg_PlayerMerc [q] or kill_unit == udg_PlayerCompan [q] then
                set kill_unitQ = q
                set q = 12
            else
                set q = q + 1
            endif
        endloop
    endif
    if kill_unitQ > 11 then
        set trig_unit = null
        set kill_unit = null
        return
    endif


//  Scoring and Gold

    set udg_PlayerKills [kill_unitQ] = udg_PlayerKills [kill_unitQ] + 1
    set udg_PlayerKillsLevels [kill_unitQ] = udg_PlayerKillsLevels [kill_unitQ] + trig_unitE


//  Filter Computer Hero

    if udg_PlayerTypeIsHuman [kill_unitQ] == false then
        set trig_unit = null
        set kill_unit = null
        return
    endif


//  Create Items (Undead-specific)

    set P_CWu = udg_PlayerItemUsed_CrstWater [kill_unitQ]
    if P_CWu > 0 then
        set udg_PlayerItemUsed_CrstWater [kill_unitQ] = P_CWu - 1
        call UndeadItemCreator (trig_unit, trig_unitE, udg_PlayerChance_ItemBoost [kill_unitQ])
    elseif udg_RealArray [kill_unitQ + 100] + udg_RealArray [kill_unitQ + 160] > GetRandomReal (0.00, 99.00) then
        call UndeadItemCreator (trig_unit, trig_unitE, udg_PlayerChance_ItemBoost [kill_unitQ])
    elseif GetRandomInt (1, 35) == 1 then
        set R = GetRandomInt (1, 16)
        set drop_item = CreateItem (udg_UndeadDropItem [R], GetUnitX (trig_unit), GetUnitY (trig_unit))
        call DestroyEffect (AddSpecialEffectTarget ("Abilities\\Weapons\\PhoenixMissile\\Phoenix_Missile_mini.mdl", drop_item, "origin"))
        if R > 5 then
            call SetItemUserData (drop_item, 210)
        endif
        set drop_item = null
    endif
    set trig_unit = null
    set kill_unit = null
endfunction

function InitTrig_CreepsDeathUndead takes nothing returns nothing
    set gg_trg_CreepsDeathUndead = CreateTrigger ()
    call TriggerRegisterPlayerUnitEvent (gg_trg_CreepsDeathUndead, Player (14), EVENT_PLAYER_UNIT_DEATH, null)
    call TriggerAddCondition (gg_trg_CreepsDeathUndead, Condition (function CreepsDeathUndead_Condition01))
    call TriggerAddAction (gg_trg_CreepsDeathUndead, function CreepsDeathUndead_Action01)
endfunction
 
Level 5
Joined
Sep 19, 2006
Messages
152
All good?

JASS:
function UndeadItemCreator takes unit trig_unit, integer trig_unitE, integer P_CIB returns nothing
    local item drop_item
    local integer drop_itemE
    local integer drop_itemJ


    if GetRandomInt (1, 10) > P_CIB then
        set drop_itemE = GetRandomInt (0, trig_unitE / 8)
    elseif GetRandomInt (1, 50) > P_CIB then
        set drop_itemE = GetRandomInt (0, trig_unitE / 8) + 1
    else
        set drop_itemE = GetRandomInt (0, trig_unitE / 8) + 2
    endif
    if drop_itemE > 9 then
        set drop_itemE = GetRandomInt (2, 9)
    endif

    set drop_item = CreateItem (ChooseRandomItem (drop_itemE), GetUnitX (trig_unit), GetUnitY (trig_unit))
    set drop_itemJ = GetItemTypeId (drop_item)
    if drop_itemJ == 'mgtk' or drop_itemJ == 'srrc' or drop_itemJ == 'mcri' or drop_itemJ == 'sres' then
        call SetItemInvulnerable (drop_item, true)
        call SetItemUserData (drop_item, 200)
    endif
    call DestroyEffect (AddSpecialEffectTarget ("Abilities\\Weapons\\PhoenixMissile\\Phoenix_Missile_mini.mdl", drop_item, "origin"))
    set drop_item = null
endfunction

function CreepsDeathUndead_Condition01 takes nothing returns boolean
    local unit kill_unit         = GetKillingUnit ()
    local integer kill_unitQ
    local unit trig_unit
    local integer trig_unitE
    local integer q
    local integer P_CWu
    local item drop_item
    local integer R


    if kill_unit == null then
        return false
    else
        set kill_unitQ = GetPlayerId (GetOwningPlayer (kill_unit))
    endif


//  Determine Killing Player

    if kill_unitQ == 15 then
        set q = 1
        loop
            exitwhen q == 12
            if kill_unit == udg_PlayerMerc [q] or kill_unit == udg_PlayerCompan [q] then
                set kill_unitQ = q
                set q = 12
            else
                set q = q + 1
            endif
        endloop
    endif
    if kill_unitQ > 11 then
        set kill_unit = null
        return false
    endif


//  Scoring and Gold

    set trig_unit = GetDyingUnit ()
    set trig_unitE = GetUnitLevel (trig_unit)
    set udg_PlayerKills [kill_unitQ] = udg_PlayerKills [kill_unitQ] + 1
    set udg_PlayerKillsLevels [kill_unitQ] = udg_PlayerKillsLevels [kill_unitQ] + trig_unitE


//  Filter Computer Hero

    if udg_PlayerTypeIsHuman [kill_unitQ] == false then
        set trig_unit = null
        set kill_unit = null
        return false
    endif


//  Create Items (Undead-specific)

    set P_CWu = udg_PlayerItemUsed_CrstWater [kill_unitQ]
    if P_CWu > 0 then
        set udg_PlayerItemUsed_CrstWater [kill_unitQ] = P_CWu - 1
        call UndeadItemCreator (trig_unit, trig_unitE, udg_PlayerChance_ItemBoost [kill_unitQ])
    elseif udg_RealArray [kill_unitQ + 100] + udg_RealArray [kill_unitQ + 160] > GetRandomReal (0.00, 99.00) then
        call UndeadItemCreator (trig_unit, trig_unitE, udg_PlayerChance_ItemBoost [kill_unitQ])
    elseif GetRandomInt (1, 35) == 1 then
        set R = GetRandomInt (1, 16)
        set drop_item = CreateItem (udg_UndeadDropItem [R], GetUnitX (trig_unit), GetUnitY (trig_unit))
        call DestroyEffect (AddSpecialEffectTarget ("Abilities\\Weapons\\PhoenixMissile\\Phoenix_Missile_mini.mdl", drop_item, "origin"))
        if R > 5 then
            call SetItemUserData (drop_item, 210)
        endif
        set drop_item = null
    endif
    set trig_unit = null
    set kill_unit = null
    return false
endfunction

function InitTrig_CreepsDeathUndead takes nothing returns nothing
    set gg_trg_CreepsDeathUndead = CreateTrigger ()
    call TriggerRegisterPlayerUnitEvent (gg_trg_CreepsDeathUndead, Player (14), EVENT_PLAYER_UNIT_DEATH, null)
    call TriggerAddCondition (gg_trg_CreepsDeathUndead, Condition (function CreepsDeathUndead_Condition01))
endfunction
 
Status
Not open for further replies.
Top