• 🏆 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 Check, please!

Status
Not open for further replies.
Level 5
Joined
Sep 19, 2006
Messages
152
Just wanted you pros to take a gander over the following trigger and alert me to any inefficiencies. Thanks!

JASS:
function CreepsItemCreator 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 CreepsDeath_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_unitD         = GetUnitUserData (trig_unit)
    local integer trig_unitE
    local itempool I
    local integer C
    local integer P
    local integer P_CWu


//  Determine Killing Player

    if kill_unitQ == 0 or kill_unitQ == 14 then
        if trig_unitD > 3999 then
            call GroupRemoveUnit (udg_TrollGroup [trig_unitD], trig_unit)
        elseif trig_unitD == 80 then
            call GroupRemoveUnit (udg_CaveGroup, trig_unit)
        elseif trig_unitD == 100 then
            call GroupRemoveUnit (udg_EliteGroup, trig_unit)
        endif
        set trig_unit = null
        set kill_unit = null
        return
    elseif kill_unitQ == 15 then
        set P = 1
        loop
            exitwhen P == 12
            if kill_unit == udg_PlayerMerc  or kill_unit == udg_PlayerCompan  then
                set kill_unitQ = P
                set P = 12
            else
                set P = P + 1
            endif
        endloop
    endif


//  Scoring and Gold

    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
        if trig_unitD > 3999 then
            call GroupRemoveUnit (udg_TrollGroup [trig_unitD], trig_unit)
        elseif trig_unitD == 80 then
            call GroupRemoveUnit (udg_CaveGroup, trig_unit)
        elseif trig_unitD == 100 then
            call GroupRemoveUnit (udg_EliteGroup, trig_unit)
        endif
        set trig_unit = null
        set kill_unit = null
        return
    endif


//  Create Items

    set C = 0
    if trig_unitD > 3999 then
        call GroupRemoveUnit (udg_TrollGroup [trig_unitD], trig_unit)
        set P_CWu = udg_PlayerItemUsed_CrstWater [kill_unitQ]
        if P_CWu > 0 then
            set udg_PlayerItemUsed_CrstWater [kill_unitQ] = P_CWu - 1
            call CreepsItemCreator (trig_unit, trig_unitE, udg_PlayerChance_ItemBoost [kill_unitQ])
        elseif udg_RealArray [kill_unitQ + 100] > GetRandomReal (0.00, 99.00) then
            call CreepsItemCreator (trig_unit, trig_unitE, udg_PlayerChance_ItemBoost [kill_unitQ])
        endif
    elseif trig_unitD == 80 then
        call GroupRemoveUnit (udg_CaveGroup, trig_unit)
        set P_CWu = udg_PlayerItemUsed_CrstWater [kill_unitQ]
        if P_CWu > 0 then
            set udg_PlayerItemUsed_CrstWater [kill_unitQ] = P_CWu - 1
            call CreepsItemCreator (trig_unit, trig_unitE, udg_PlayerChance_ItemBoost [kill_unitQ])
        elseif udg_RealArray [kill_unitQ + 100] > GetRandomReal (0.00, 99.00) then
            call CreepsItemCreator (trig_unit, trig_unitE, udg_PlayerChance_ItemBoost [kill_unitQ])
        endif
    elseif trig_unitD == 100 then
        call GroupRemoveUnit (udg_EliteGroup, trig_unit)
        call RemoveUnit (trig_unit)
        if GetRandomInt (1, 2500) < trig_unitE and udg_UniqueIsAvail == true then
            set udg_UniqueIsAvail = false
            set I = CreateItemPool ()
            call ItemPoolAddItemType (I, 'sehr', 1)  //  Crimson Cape of Evading
            call ItemPoolAddItemType (I, 'gold', 1)  //  The Death Knell
            call ItemPoolAddItemType (I, 'shhn', 1)  //  Pegasus Plate
            call ItemPoolAddItemType (I, 'glsk', 1)  //  Pharaoh Band
            call ItemPoolAddItemType (I, 'shea', 1)  //  Phoenix Gloves
            call ItemPoolAddItemType (I, 'ratf', 1)  //  Ring of Perception
            call ItemPoolAddItemType (I, 'spsh', 1)  //  Ring of Sevens
            call ItemPoolAddItemType (I, 'ratf', 1)  //  Ring Of Perception
            call ItemPoolAddItemType (I, 'infs', 1)  //  Scroll of Barkskin
            call ItemPoolAddItemType (I, 'ledg', 1)  //  Scroll of Perfect Harmony
            call ItemPoolAddItemType (I, 'rdis', 1)  //  Scroll of Serenity
            call ItemPoolAddItemType (I, 'pmna', 1)  //  Stone Idol
            call ItemPoolAddItemType (I, 'fwss', 1)  //  Vivacio
            call PlaceRandomItem (I, GetUnitX (trig_unit), GetUnitY (trig_unit))
            call DestroyItemPool (I)
            set I = null
        endif
        set C = GetRandomInt (0, 3) + GetRandomInt (1, 4)
        loop
            exitwhen C == 0
            call CreepsItemCreator (trig_unit, trig_unitE, udg_PlayerChance_ItemBoost [kill_unitQ])
            set C = C - 1
        endloop
    endif
    set trig_unit = null
    set kill_unit = null
endfunction

function InitTrig_CreepsDeath takes nothing returns nothing
    set gg_trg_CreepsDeath = CreateTrigger ()
    call TriggerRegisterPlayerUnitEvent (gg_trg_CreepsDeath, Player (12), EVENT_PLAYER_UNIT_DEATH, null)
    call TriggerAddAction (gg_trg_CreepsDeath, function CreepsDeath_Action01)
endfunction
 
Level 17
Joined
Nov 13, 2006
Messages
1,814
why useing unit indexer fr make difference between units?
JASS:
if trig_unitD > 3999 then
u can use a global array for that, example unit_bla[custom value of unit] = x

JASS:
 if udg_PlayerTypeIsHuman [kill_unitQ] == false then
also for false things do this
JASS:
 if not udg_PlayerTypeIsHuman [kill_unitQ] then
but easier check the controller

JASS:
 if drop_itemJ == 'mgtk' or drop_itemJ == 'srrc' or drop_itemJ == 'mcri' or drop_itemJ == 'sres'

just question because this way easier, why dont make a item type array or integer array and store there every item type what u dont want then just check with loop

or simple make a function like this
JASS:
function IsRestrictedItem takes integer itType returns boolean
return itType == 'mgtk' or itType == 'srrc' or itType == 'mcri' or itType == 'sres'
endfunction

this way isnt faster, but more readable :)

JASS:
GetRandomInt (0, 3) + GetRandomInt (1, 4)

i dont udnerstand why use 2 instead this

JASS:
GetRandomInt (1, 7)

dont use ==true because useless

JASS:
if udg_UniqueIsAvail then
 
Level 5
Joined
Sep 19, 2006
Messages
152
1. why useing unit indexer fr make difference between units?
JASS:
if trig_unitD > 3999 then
u can use a global array for that, example unit_bla[custom value of unit] = x


JASS:
 if drop_itemJ == 'mgtk' or drop_itemJ == 'srrc' or drop_itemJ == 'mcri' or drop_itemJ == 'sres'

2. just question because this way easier, why dont make a item type array or integer array and store there every item type what u dont want then just check with loop

or simple make a function like this
JASS:
function IsRestrictedItem takes integer itType returns boolean
return itType == 'mgtk' or itType == 'srrc' or itType == 'mcri' or itType == 'sres'
endfunction

this way isnt faster, but more readable :)


JASS:
GetRandomInt (0, 3) + GetRandomInt (1, 4)

3. i dont udnerstand why use 2 instead this

JASS:
GetRandomInt (1, 7)


Thank you for your response. To reply to some of your points:
1. Can you provide me an example of what you mean here?
2. Is it more efficient to use an entirely separate function to determine if the item is of type A, B, etc.?
3. I use (0-3) + (1, 4) because those values are more likely to return a number somewhere in the middle. (1-7) has an equal chance of returning any one of the 7 possible numbers.
 
Level 17
Joined
Nov 13, 2006
Messages
1,814
Thank you for your response. To reply to some of your points:
1. Can you provide me an example of what you mean here?
2. Is it more efficient to use an entirely separate function to determine if the item is of type A, B, etc.?
3. I use (0-3) + (1, 4) because those values are more likely to return a number somewhere in the middle. (1-7) has an equal chance of returning any one of the 7 possible numbers.


1. First, you use custom value of categorize the creeps, right?
ok if u need here a dynamic value then u can do this:
instead add to troll group ur troll u can store to unit array where u picked the units into trollgroup.
set udg_Trolls[GetUnitUserData(u)] = u

then here just check if
JASS:
local unit u = GetDyingUnit()
if udg_Trolls[GetUnitUserData(u)] = u then
//do this
elseif udg_Elits[GetUnitUserData(u)] = u then
//do this
endif

if in troll group only trolls exist (so unit types) then use point value in object editor and that is the fastest way and still u can use the indexer for something else
Point Value is fixed thing and pretty similiar the usage like custom value so

JASS:
        if GetUnitPointValue(unit) < 2000 then

if u use custom value, so userdata, that no problem, but u can keep it for normal unit indexer

2 its more readable, ok depend how much time u use this function, if u use with very short interval (0.01-0.03) then maybe the long if more efficient but if no, then u dont see too much different in speed but far more readable this trigger :)
 
Level 5
Joined
Sep 19, 2006
Messages
152
I've enclosed the related trigger. Maybe this will shed some light on things:

JASS:
function EliteMonsterCreator takes unit creep_unit, integer PointsTotal returns nothing
    local integer PointsPossible
    local integer PointsCurrent


    set udg_NumberOfElites = udg_NumberOfElites + 1
    call SetUnitUserData (creep_unit, 100)
    call SetUnitColor (creep_unit, PLAYER_COLOR_RED)
    call SetUnitVertexColor (creep_unit, 150, 150, 150, 255)
    call SetUnitScale (creep_unit, 1.40, 1.40, 1.40)
    call GroupAddUnit (udg_EliteGroup, creep_unit)


//  Elite Monster Resistances

    if PointsTotal > 4 then
        set PointsPossible = 4
    else
        set PointsPossible = PointsTotal
    endif
    set PointsCurrent = GetRandomInt (0, PointsPossible)
    set PointsTotal = PointsTotal - PointsCurrent
    call UnitAddAbility (creep_unit, udg_EliteMonsterStat [PointsCurrent])


//  Elite Monster Damage

    if PointsTotal > 5 then
        set PointsPossible = 5
    else
        set PointsPossible = PointsTotal
    endif
    set PointsCurrent = GetRandomInt (5, PointsPossible + 5)
    call UnitAddAbility (creep_unit, udg_EliteMonsterStat [PointsCurrent])


//  Elite Monster Life

    if PointsTotal > 8 then
        set PointsPossible = 8
    else
        set PointsPossible = PointsTotal
    endif
    set PointsCurrent = GetRandomInt (11, PointsPossible + 11)
    call UnitAddAbility (creep_unit, udg_EliteMonsterStat [PointsCurrent])


//  Elite Ability

    if GetRandomInt (1, 4) == 4 then
        call UnitAddAbility (creep_unit, 'A084')
        if GetRandomInt (1, 4) == 4 then
            call UnitAddAbility (creep_unit, 'A084')
        endif
    endif
    if GetRandomInt (1, 10) == 10 then
        call UnitAddAbility (creep_unit, 'Apig')
    endif
endfunction

function CaveCounter takes nothing returns nothing
    set udg_CaveMonsterCount = udg_CaveMonsterCount +1
endfunction

function EliteCounter takes nothing returns nothing
    set udg_EliteMonsterCount = udg_EliteMonsterCount +1
endfunction

function TrollCounter takes nothing returns nothing
    set udg_TrollMonsterCount = udg_TrollMonsterCount +1
endfunction

function CreepsCreation_Action01 takes nothing returns nothing
    local integer n_LQual            = udg_LevelQualifier
    local integer n_LQualX25         = n_LQual * 25
    local integer n_CaveCount
    local integer n_HutNumb          = udg_HutNumber
    local integer n_HutNumb_max      = n_HutNumb + 2
    local integer n_MonsterCap       = udg_MonsterQuantity
    local integer n_EliteCount
    local integer n_TrollCount
    local unit creep_spawn
    local real creep_spawnX
    local real creep_spawnY
    local unit creep_unit
    local integer creep_unitE
    local integer R


//  Determine Number of Elite Monsters

    set udg_EliteMonsterCount = 0
    call ForGroup (udg_EliteGroup, function EliteCounter)
    set n_EliteCount = udg_EliteMonsterCount


//  Create Monsters (Cave)

    set udg_CaveMonsterCount = 0
    call ForGroup (udg_CaveGroup, function CaveCounter)
    set n_CaveCount = udg_CaveMonsterCount
    if n_CaveCount < 40 then
        set R = (GetRandomInt (0, n_LQualX25) / 5) + 200
        set creep_unit = CreateUnit (Player (12), udg_Monster [R], GetRandomReal (-3500.00, 5000.00), GetRandomReal (-11500.00, -10000.00), 0.00)
        call RemoveGuardPosition (creep_unit)

//      ** Create Elite Monster (Cave) **
        if GetRandomInt (1, 30) == 30 then
            set creep_unitE = GetUnitLevel (creep_unit)
            if creep_unitE > 24 and n_EliteCount < 5 then
                call EliteMonsterCreator (creep_unit, creep_unitE / 5)
            endif
        else
            call GroupAddUnit (udg_CaveGroup, creep_unit)
            call SetUnitUserData (creep_unit, 80)
            call SetUnitVertexColor (creep_unit, 150, 150, 150, 255)
        endif
    endif


//  Create Monsters (Troll)

    loop
        exitwhen n_HutNumb == n_HutNumb_max
        set udg_TrollMonsterCount = 0
        call ForGroup (udg_TrollGroup [n_HutNumb], function TrollCounter)
        set n_TrollCount = udg_TrollMonsterCount
        if n_TrollCount < n_MonsterCap then
            set creep_spawn = udg_TrollHut [n_HutNumb]
            set creep_spawnX = GetUnitX (creep_spawn)
            set creep_spawnY = GetUnitY (creep_spawn)
            loop
                exitwhen n_TrollCount == n_MonsterCap
                set R = GetRandomInt (0, n_LQualX25) / 5
                set creep_unit = CreateUnit (Player (12), udg_Monster [R], creep_spawnX, creep_spawnY, 0.00)
                call SetUnitUserData (creep_unit, n_HutNumb)
                call RemoveGuardPosition (creep_unit)
                call SetUnitVertexColor (creep_unit, 150, 150, 150, 255)
                call GroupAddUnit (udg_TrollGroup [n_HutNumb], creep_unit)
                set n_TrollCount = n_TrollCount + 1
            endloop

//          ** Create Elite Monster (Troll) **
            if GetRandomInt (1, 50) == 50 then
                set creep_unitE = GetUnitLevel (creep_unit)
                if GetUnitLevel (creep_unit) > 24 and n_EliteCount < 5 then
                    call EliteMonsterCreator (creep_unit, creep_unitE / 5)
                endif
            endif
        endif
        if n_HutNumb == 4080 then
            set n_HutNumb = 4001
            set n_HutNumb_max = 4001
        else
            set n_HutNumb = n_HutNumb + 1
        endif
    endloop
    set udg_HutNumber = n_HutNumb

    set creep_unit = null
    set creep_spawn = null
endfunction

function InitTrig_CreepsCreation takes nothing returns nothing
    set gg_trg_CreepsCreation = CreateTrigger ()
    call TriggerAddAction (gg_trg_CreepsCreation, function CreepsCreation_Action01)
endfunction
 
Level 17
Joined
Nov 13, 2006
Messages
1,814
i really no iddea why u use custom value, its huge waste...

JASS:
 call SetUnitUserData (creep_unit, n_HutNumb)

do this

JASS:
  set udg_variable[GetUnitUserData(creep_unit)] = n_HutNumb

its similiar easy to use just u can use custom value for unit indexer since alot usefull thing based on normal unit indexing...

if u use unit group array
JASS:
 call GroupAddUnit (udg_TrollGroup [n_HutNumb], creep_unit)
then be sure every group is created because its not created automatically (so u must CreateGroup() manually for each index)

whatever, unit group still slower than unit array with linked list because need more function call (example absolute dont need to count unit in linked list "group" because its store directly to integer), but maybe more easy to u the unit group, just i told not too hard to make a system where u dont need forloop functions and u can handle units directly

JASS:
    if GetRandomInt (1, 4) == 4 then
        call UnitAddAbility (creep_unit, 'A084')
        if GetRandomInt (1, 4) == 4 then
            call UnitAddAbility (creep_unit, 'A084')
        endif
    endif
why u do same thing 2x?

overall i dont understand why u mix the unit group and ~~something what look like linked list.

use 1 or another but both?
 
Level 5
Joined
Sep 19, 2006
Messages
152
1. i really no iddea why u use custom value, its huge waste...

JASS:
 call SetUnitUserData (creep_unit, n_HutNumb)

JASS:
    if GetRandomInt (1, 4) == 4 then
        call UnitAddAbility (creep_unit, 'A084')
        if GetRandomInt (1, 4) == 4 then
            call UnitAddAbility (creep_unit, 'A084')
        endif
    endif
2. why u do same thing 2x?

overall i dont understand why u mix the unit group and ~~something what look like linked list.

use 1 or another but both?

1. I use the custom data so I can determine to which group the dying unit belonged. This way, that unit can be removed from that group and replaced when new monsters are generated.

2. I use that function twice to give a 1/16 chance of adding 'A084' (+25% attack rate) twice.
 
Level 17
Joined
Nov 13, 2006
Messages
1,814
1. I use the custom data so I can determine to which group the dying unit belonged. This way, that unit can be removed from that group and replaced when new monsters are generated.

2. I use that function twice to give a 1/16 chance of adding 'A084' (+25% attack rate) twice.

1, seems u dont understand totally, variable aray excelent replacement to u, work exactly same way than ur custom value, only difference if u use a normal unit indexer like bribe unit indexer + variable array then u can do easily alot thing.

atm u use custom value only for determine 1 thing, but with normal unit indexer + variables u can determine everything what u want, not only 1 thing, also alot thing use normal unit indexer what make conflict with your trigger :p

2. u can make more level to ability and set level instead add same ability again :p
like level 1: 25% attack speed, level 2: 50%, lv3 etc etc etc :p
 
Level 5
Joined
Sep 19, 2006
Messages
152
seems u dont understand totally, variable aray excelent replacement to u, work exactly same way than ur custom value, only difference if u use a normal unit indexer like bribe unit indexer + variable array then u can do easily alot thing.

atm u use custom value only for determine 1 thing, but with normal unit indexer + variables u can determine everything what u want, not only 1 thing, also alot thing use normal unit indexer what make conflict with your trigger :p

You're right: I don't totally understand. In fact, I don't really know what you mean by "bribe unit indexer" or "normal unit indexer." Perhaps someone else can chime in and clear up my misunderstanding...

P.S. I'm guessing that English is not your native language?
 
Level 17
Joined
Nov 13, 2006
Messages
1,814
i talk about this, but overall every damage detection system or alot thing use indexer, and that screw up if somebody set manually the custom value.

http://www.hiveworkshop.com/forums/...prev=search=gui%20damage%20engine&d=list&r=20

so overall have alot option how can u do your system without setting the custom values and i advice try dont modify the unit custom value and use a indexer or hashtable for this :p
 
Level 5
Joined
Sep 19, 2006
Messages
152
I'm sure shadowvzs knows what he's (or she's) talking about, but I can't seem to understand it. Can someone else give explaining it to me a shot?
 
Level 17
Joined
Nov 13, 2006
Messages
1,814
I'm sure shadowvzs knows what he's (or she's) talking about, but I can't seem to understand it. Can someone else give explaining it to me a shot?

i talk about have systems when do this automatically:

lets say ur map starting with 0 unit

then u create 1 unit, indexer automatically set custom value to 1
when u create another unit his custom value = 2 without u set the custom values.

so every unit get a unique custom value, its mean dont have 2 unit on map what same custom value, this is a unique identifier to each unit.

u could ask what happen if custom value is allways higher with 1 and u create alot unit?

simple when a unit die and decayed then his custom value is recycled
example:
u have 5 unit on map

1 peon: indexer give to him custom value = 1
1 peasont: indexer give to him custom value = 2
1 (another) peon: indexer give to him custom value = 3
1 (another) peon: indexer give to him custom value = 4

lets say 2 peon who got custom value 3 die, when he decayed and u create another unit, lets say paladin then paladin get his custom value and this will be now the order

1 peon: indexer give to him custom value = 1
1 peasont: indexer give to him custom value = 2
1 paladin: indexer give to him custom value = 3
1 (another) peon: indexer give to him custom value = 4

this is how unit indexer work, but u dont must do nothing exclude copy indexer to ur map and any other job indexer do alone :)

so when u use indexer then every unit on your map have a custom value, each unit have different custom value so u can attach easily data to 1 unit.

lets say you have 3 paladin on your map

1 paladin with 25 custom value
another 1 paladin with 26 custom value
another 1 paladin with 27 custom value

lets say u want give +25 damage to 2nd paladin when he attack, how can u do it?
simple make a variable where index is the unit custom value, so it is 26 in our case

so out variable name is a real, and its a array, name BonusDamage.

simple set BonusDamage[custom value of your paladin]= 25
so set BonusDamage[26]= 25

when a unit attack then do this

attacker deal damage to attacked unit, damage amount = BonusDamage[custom value of attacker unit]

since u dont setted only to your paladin the bonus damage then others unit deal 0 bonus

so its look like this
JASS:
                    call UnitDamageTarget(GetAttackerUnit(), GetAttackedUnit(), udg_BonusDamage[getUnitUserData(GetAttackerUnit())], true, false, ATTACK_TYPE_HERO, DAMAGE_TYPE_NORMAL, null)

acctually similiar thing is the GetHandleId( your unit ), difference this custom value could be used like a array index, but handleid is longer.

useing arrays fastest way if u want store something (i hope others can agree with this)

coz of this alot system based on custom values (so UnitUserData), example gui damage engine where u can modify damn easily the damage as u want, really with really simple way.

also with custom values u can skip the useing hashtable in few case, then your code could be shorter with array, more readable and faster (but i am not sure u feel the speed difference just u can thing to if u do something with less function call, and do it directly then it is faster)
 
Level 5
Joined
Sep 19, 2006
Messages
152
Wow, thank you for all that typing! Please allow me a day or two (when my time allows) to look over and digest what you've written.
 
Status
Not open for further replies.
Top