//Garfield1337's Pathfinding system
//===================================================
//Credit This system to Garfield1337
function ItemHide takes nothing returns nothing
call SetItemVisible(GetEnumItem(),false)
endfunction
function ItemShow takes nothing returns nothing
call SetItemVisible(GetEnumItem(),true)
endfunction
function IsGarLocPathable takes location l returns boolean
local boolean b
local real dx
local real dy
if IsTerrainPathable(GetLocationX(l),GetLocationY(l),PATHING_TYPE_WALKABILITY) == true then
set b = false
else
call MoveRectToLoc(udg_DummyRect,l)
call EnumItemsInRect(udg_DummyRect,null,function ItemHide)
call SetItemVisible(udg_DummyItem,true)
call SetItemPosition(udg_DummyItem,GetLocationX(l),GetLocationY(l))
set dx = GetItemX(udg_DummyItem) - GetLocationX(l)
set dy = GetItemY(udg_DummyItem) - GetLocationY(l)
if SquareRoot(dx * dx + dy * dy) > 0.00 then
set b = false
else
set b = true
endif
call EnumItemsInRect(udg_DummyRect,null,function ItemShow)
call SetItemVisible(udg_DummyItem,false)
endif
return b
endfunction
// **********************
// ** VECTOR SYSTEM **
// **********************
// Original concept by iNfraNe
// Made by Anitarf
// Required global variables:
// vectorMaxIndex integer
// vectorUnusedAmount integer
// vectorUnusedIndex integer array
// vectorX real array
// vectorY real array
// vectorZ real array
// vectorTaken boolean aray
constant function BouncyPeriod takes nothing returns real
return 0.01
endfunction
constant function VectorGetX takes integer vector returns real
return udg_vectorX[vector]
endfunction
constant function VectorGetY takes integer vector returns real
return udg_vectorY[vector]
endfunction
constant function VectorGetZ takes integer vector returns real
return udg_vectorZ[vector]
endfunction
function VectorGetLength takes integer vector returns real
return SquareRoot(udg_vectorX[vector]*udg_vectorX[vector] + udg_vectorY[vector]*udg_vectorY[vector] + udg_vectorZ[vector]*udg_vectorZ[vector])
endfunction
function VectorSetX takes integer vector, real x returns boolean
if udg_vectorTaken[vector] then
set udg_vectorX[vector] = x
return true
endif
return false
endfunction
function VectorSetY takes integer vector, real y returns boolean
if udg_vectorTaken[vector] then
set udg_vectorY[vector] = y
return true
endif
return false
endfunction
function VectorSetZ takes integer vector, real z returns boolean
if udg_vectorTaken[vector] then
set udg_vectorZ[vector] = z
return true
endif
return false
endfunction
function VectorCreate takes real x, real y, real z returns integer
local integer i = 1
if udg_vectorUnusedAmount == 0 then
set udg_vectorMaxIndex = udg_vectorMaxIndex + 1
set i = udg_vectorMaxIndex
else
set i = udg_vectorUnusedIndex[udg_vectorUnusedAmount]
set udg_vectorUnusedAmount = udg_vectorUnusedAmount - 1
endif
set udg_vectorX[i] = x
set udg_vectorY[i] = y
set udg_vectorZ[i] = z
set udg_vectorTaken[i] = true
return i
endfunction
function VectorDestroy takes integer vector returns boolean
if not udg_vectorTaken[vector] then
return false
endif
set udg_vectorTaken[vector] = false
set udg_vectorUnusedAmount = udg_vectorUnusedAmount + 1
set udg_vectorUnusedIndex[udg_vectorUnusedAmount] = vector
return true
endfunction
function VectorSum takes integer augendV, integer addendV returns integer
if udg_vectorTaken[augendV] and udg_vectorTaken[addendV] then
return VectorCreate(udg_vectorX[augendV]+udg_vectorX[addendV], udg_vectorY[augendV]+udg_vectorY[addendV], udg_vectorZ[augendV]+udg_vectorZ[addendV])
endif
return 0
endfunction
function VectorAdd takes integer increasedV, integer addedV returns boolean
if udg_vectorTaken[increasedV] and udg_vectorTaken[addedV] then
set udg_vectorX[increasedV] = udg_vectorX[increasedV] + udg_vectorX[addedV]
set udg_vectorY[increasedV] = udg_vectorY[increasedV] + udg_vectorY[addedV]
set udg_vectorZ[increasedV] = udg_vectorZ[increasedV] + udg_vectorZ[addedV]
return true
endif
return false
endfunction
function VectorDifference takes integer minuendV, integer subtrahendV returns integer
if udg_vectorTaken[minuendV] and udg_vectorTaken[subtrahendV] then
return VectorCreate(udg_vectorX[minuendV]-udg_vectorX[subtrahendV], udg_vectorY[minuendV]-udg_vectorY[subtrahendV], udg_vectorZ[minuendV]-udg_vectorZ[subtrahendV])
endif
return 0
endfunction
function VectorSubtract takes integer decreasedV, integer subtractedV returns boolean
if udg_vectorTaken[decreasedV] and udg_vectorTaken[subtractedV] then
set udg_vectorX[decreasedV] = udg_vectorX[decreasedV] - udg_vectorX[subtractedV]
set udg_vectorY[decreasedV] = udg_vectorY[decreasedV] - udg_vectorY[subtractedV]
set udg_vectorZ[decreasedV] = udg_vectorZ[decreasedV] - udg_vectorZ[subtractedV]
return true
endif
return false
endfunction
function VectorAmplify takes integer vector1, real factor returns integer
if udg_vectorTaken[vector1] then
return VectorCreate(factor*udg_vectorX[vector1],factor*udg_vectorY[vector1],factor*udg_vectorZ[vector1])
endif
return 0
endfunction
function VectorScale takes integer vector1, real factor returns boolean
if udg_vectorTaken[vector1] then
set udg_vectorX[vector1] = udg_vectorX[vector1] * factor
set udg_vectorY[vector1] = udg_vectorY[vector1] * factor
set udg_vectorZ[vector1] = udg_vectorZ[vector1] * factor
return true
endif
return false
endfunction
function VectorProductScalar takes integer vector1, integer vector2 returns real
if udg_vectorTaken[vector1] and udg_vectorTaken[vector2] then
return udg_vectorX[vector1] * udg_vectorX[vector2] + udg_vectorY[vector1] * udg_vectorY[vector2] + udg_vectorZ[vector1] * udg_vectorZ[vector2]
endif
return 0.00
endfunction
function VectorProductVector takes integer vector1, integer vector2 returns integer
local real x = udg_vectorY[vector1]*udg_vectorZ[vector2] - udg_vectorZ[vector1]*udg_vectorY[vector2]
local real y = udg_vectorZ[vector1]*udg_vectorX[vector2] - udg_vectorX[vector1]*udg_vectorZ[vector2]
local real z = udg_vectorX[vector1]*udg_vectorY[vector2] - udg_vectorY[vector1]*udg_vectorX[vector2]
if udg_vectorTaken[vector1] and udg_vectorTaken[vector2] then
return VectorCreate(x,y,z)
endif
return 0
endfunction
function VectorProjectVector takes integer projectedV, integer directionV returns integer
local real r = VectorProductScalar(projectedV, directionV)
local real l = VectorProductScalar(directionV, directionV)
if l == 0.0 then
return 0
endif
if udg_vectorTaken[projectedV] and udg_vectorTaken[directionV] then
return VectorAmplify(directionV, r/l)
endif
return 0
endfunction
function VectorProjectPlane takes integer projectedV, integer planeNormalV returns integer
local integer vect = VectorProjectVector(projectedV, planeNormalV)
local integer vect2 = VectorDifference(projectedV, vect)
call VectorDestroy(vect)
return vect2
endfunction
function VectorSetLength takes integer vector1, real length returns boolean
local real l = VectorGetLength(vector1)
if l == 0 then
return false
endif
return VectorScale(vector1, (length/l))
endfunction
function VectorGetAngle takes integer vector1, integer vector2 returns real
local real l1 = VectorGetLength(vector1)
local real l2 = VectorGetLength(vector2)
if l1 == 0 or l2 == 0 then
return 0.0
endif
if udg_vectorTaken[vector1] and udg_vectorTaken[vector2] then
return Acos(VectorProductScalar(vector1, vector2)/(l1*l2))
endif
return 0.00
endfunction
function VectorGetAngleDeg takes integer vector1, integer vector2 returns real
return VectorGetAngle(vector1, vector2)*bj_RADTODEG
endfunction
function VectorRotate takes integer rotatedV, integer axisV, real angle returns integer
local integer locX
local integer locY
local integer locZ
local integer result
if udg_vectorTaken[rotatedV] and udg_vectorTaken[axisV] then
set locZ = VectorProjectVector(rotatedV, axisV)
if locZ == 0 then
return 0
endif
set locX = VectorDifference(rotatedV, locZ)
set locY = VectorProductVector(axisV, locX)
call VectorSetLength(locY, VectorGetLength(locX))
call VectorScale(locX, Cos(angle))
call VectorScale(locY, Sin(angle))
set result = VectorSum(locX, locY)
call VectorAdd(result, locZ)
call VectorDestroy(locX)
call VectorDestroy(locY)
call VectorDestroy(locZ)
return result
endif
return 0
endfunction
function VectorRotateDeg takes integer rotatedV, integer axisV, real angle returns integer
return VectorRotate(rotatedV, axisV, (angle*bj_DEGTORAD))
endfunction
function VectorGetTerrainPosition takes real x, real y returns integer
local location stupid = Location(x,y)
local real z = GetLocationZ(stupid)
call RemoveLocation(stupid)
set stupid = null
return VectorCreate(x,y,z)
endfunction
function VectorGetTerrainNormal takes real x, real y, real sampleRadius returns integer
local location stupid = Location(x,y)
local real array z
local integer xvect
local integer yvect
local integer normvect
call MoveLocation(stupid, x-sampleRadius, y)
set z[1]=GetLocationZ(stupid)
call MoveLocation(stupid, x+sampleRadius, y)
set z[2]=GetLocationZ(stupid)
call MoveLocation(stupid, x, y-sampleRadius)
set z[3]=GetLocationZ(stupid)
call MoveLocation(stupid, x, y+sampleRadius)
set z[4]=GetLocationZ(stupid)
call RemoveLocation(stupid)
set xvect = VectorCreate(2*sampleRadius, 0.0, z[2]-z[1])
set yvect = VectorCreate(0.00, 2*sampleRadius, z[4]-z[3])
set normvect = VectorProductVector(xvect, yvect)
call VectorDestroy(xvect)
call VectorDestroy(yvect)
set stupid = null
return normvect
endfunction
function IsPointInCylinder takes integer pointV, integer cylinderOriginV, integer cylinderHeightV, real cylinderRadius returns boolean
local integer array vectors
local boolean b = false
local real l = VectorGetLength(cylinderHeightV)
if udg_vectorTaken[pointV] and udg_vectorTaken[cylinderOriginV] and udg_vectorTaken[cylinderHeightV] and l > 0.0 then
set vectors[1]=VectorDifference(pointV, cylinderOriginV)
set vectors[2]=VectorDifference(vectors[1], cylinderHeightV)
set vectors[3]=VectorProjectPlane(vectors[1], cylinderHeightV)
if VectorProductScalar(vectors[1], cylinderHeightV)>=0 and VectorProductScalar(vectors[2], cylinderHeightV)<=0 and VectorProductScalar(vectors[3], vectors[3])<=cylinderRadius*cylinderRadius then
set b = true
endif
call VectorDestroy(vectors[1])
call VectorDestroy(vectors[2])
call VectorDestroy(vectors[3])
endif
return b
endfunction
function IsPointInCone takes integer pointV, integer coneOriginV, integer coneHeightV, real coneRadius returns boolean
local integer array vectors
local boolean b = false
local real r
local real l = VectorGetLength(coneHeightV)
if udg_vectorTaken[pointV] and udg_vectorTaken[coneOriginV] and udg_vectorTaken[coneHeightV] and l>0.0 then
set vectors[1]=VectorDifference(pointV, coneOriginV)
set vectors[2]=VectorDifference(vectors[1], coneHeightV)
set vectors[3]=VectorProjectVector(vectors[1], coneHeightV)
set vectors[4]=VectorDifference(vectors[1], vectors[3])
set r = 1.0-( VectorGetLength(vectors[3])/l )
if VectorProductScalar(vectors[1], coneHeightV)>=0 and VectorGetLength(vectors[4])<=(coneRadius*r) then
set b = true
endif
call VectorDestroy(vectors[1])
call VectorDestroy(vectors[2])
call VectorDestroy(vectors[3])
call VectorDestroy(vectors[4])
endif
return b
endfunction
function IsPointInSphere takes integer pointV, integer sphereOriginV, real sphereRadius returns boolean
local integer vectors
local boolean b = false
if udg_vectorTaken[pointV] and udg_vectorTaken[sphereOriginV] then
set vectors=VectorDifference(pointV, sphereOriginV)
if VectorProductScalar(vectors, vectors)<= sphereRadius*sphereRadius then
set b = true
endif
call VectorDestroy(vectors)
endif
return b
endfunction
Name | Type | is_array | initial_value |
AB_AnimationSpeed | real | No | |
AB_BombCount | real | No | |
AbominationGroup | group | No | |
AfterDamageEvent | real | No | |
allocatedAttacks | integer | No | |
allocCounter | integer | No | |
AMS_Units_Near | integer | No | |
AnimationSpeed | real | No | |
AnimFrame | real | No | |
AnimSpeed | real | No | |
AOEDamageEvent | real | No | |
ArtilleryGroup | group | No | |
ArtilleryTime | real | No | |
ATTACK_TYPE_UNIVERSAL | attacktype | No | |
AttackStart | boolean | No | |
B_Critical | real | Yes | |
B_Damage | real | Yes | |
B_DistanceT | real | Yes | |
B_Facing | real | Yes | |
B_MaxDistance | real | Yes | |
B_Piercing | integer | Yes | |
B_Speed | real | Yes | |
B_Strength | real | Yes | |
BE_AnimationSpeed | real | No | |
BE_AnimFrame | real | No | |
BE_BloatCount | real | No | |
BE_TempPoint | location | No | |
BE_TempSize | real | No | |
BE_TempUnit | unit | No | |
BloatAnimGroup | group | No | |
BloodExpSFX | string | Yes | |
BomberDistanceTraveled | real | No | |
BombingPoint | location | No | |
BombingPoint2 | location | No | |
BombingPoint3 | location | No | |
BombingPoint4 | location | No | |
BombingPoint5 | location | No | |
BombSpawn | boolean | No | |
BombX | real | No | |
BombY | real | No | |
BouncyBall | unit | No | |
BoxSpawn | boolean | No | |
BRACERS_SPELL_DAMAGE_REDUCTION | real | No | |
BulletCrit | real | No | |
BulletFacing | real | No | |
BulletFacing2 | real | No | |
BulletGroup | group | No | |
BulletPoint | location | No | |
BulletPoint2 | location | No | |
BulletPoint3 | location | No | |
BulletUnit | unit | No | |
BurnDamage | real | No | |
BurnDuration | real | No | |
BurnExtra | boolean | No | |
BurnGroup | group | No | |
BurrowGroup | group | No | |
BurrowRestriction | real | No | |
BurrowTimeFrame | real | No | |
Cam_int | integer | No | |
Cam_Reset | boolean | Yes | |
CarpetGroup | group | No | |
CE_Angle | real | Yes | |
CE_FacingSizeM | real | No | |
CE_FacingSizeR | real | No | |
CE_Group | group | No | |
CE_RangeB | real | No | |
CE_RangeM | real | No | |
CE_RangeR | real | No | |
CE_RelativeAngle | real | No | |
CE_RelativeAngle2 | real | No | |
CE_RelativeAngle2B | real | No | |
CE_RelativeAngleB | real | No | |
CE_RelativeAngleC | real | No | |
CE_Speed | real | Yes | |
CE_TempPoint | location | No | |
CE_TempUnit | unit | No | |
ChestAttachments | string | Yes | |
ClassAbility | abilcode | Yes | |
ClassColor | playercolor | Yes | |
ClassIcon | string | Yes | |
ClearDamageEvent | trigger | No | |
CODE | integer | No | |
CODERED_SPAWNED | boolean | No | |
CODEREDSPAWNTIME | integer | No | |
CollisionSize | real | Yes | |
Color1 | real | No | |
Color2 | real | No | |
Color3 | real | No | |
ComboStreak | integer | No | |
ComboTime | real | No | |
Copter_Value | integer | No | |
CopterGroup | group | No | |
CopterHeight | real | No | |
CR_Group | group | No | |
CR_PulseTimer | real | Yes | |
CR_ShardCount | real | No | |
CR_TempReal | real | No | |
CurrentHighScore | integer | No | |
CurrentUnitIndex | integer | No | |
CW_Color | real | No | |
CW_Group | group | No | |
CW_Timer | real | Yes | |
D_TempPoint | location | No | |
Damage | real | No | |
DAMAGE_FACTOR_BRACERS | real | No | |
DAMAGE_FACTOR_ELUNES | real | No | |
DAMAGE_FACTOR_ETHEREAL | real | No | |
DAMAGE_TYPE_DETECTOR | integer | No | |
DamageBlockingAbility | abilcode | No | |
DamageEvent | real | No | |
damageEvent | trigger | No | |
DamageEventAmount | real | No | |
DamageEventAOE | integer | No | |
DamageEventAOEGroup | group | No | |
DamageEventExplodesUnit | boolean | No | |
DamageEventLevel | integer | No | |
DamageEventOverride | boolean | No | |
DamageEventPrevAmt | real | No | |
DamageEventSource | unit | No | |
DamageEventsWasted | integer | No | |
DamageEventTarget | unit | No | |
DamageEventTrigger | trigger | No | |
damageEventTrigger | real | No | |
DamageEventType | integer | No | |
damageHandler | trigger | No | |
DamageModifierEvent | real | No | |
damageType | integer | No | |
DamageTypeBlocked | integer | No | |
DamageTypeCriticalStrike | integer | No | |
DamageTypeDOT | integer | No | |
DamageTypeExplosive | integer | No | |
DamageTypeHeal | integer | No | |
DamageTypeRanged | integer | No | |
DamageTypeReduced | integer | No | |
DamageTypeSpell | integer | No | |
DB_SummonPos | location | Yes | |
DebugMode | boolean | No | |
DeployableZombies | integer | No | |
DeployRemaining | integer | No | |
DevourerGroup | group | No | |
DevourerHeight | real | No | |
DevourerVelocity | real | No | |
DevourGroup | group | No | |
DevourTime | real | No | |
DialogClassButton | button | Yes | |
DialogMenuClassSelect | dialog | No | |
DialogMenuSummon | dialog | No | |
DialogModeSelectionMenu | dialog | No | |
DialogSummonList | button | Yes | |
DialogSurvivalMode | button | No | |
DialogVersusFFA | button | No | |
DialogVersusMode | button | No | |
DialogVersusPlayer | button | Yes | |
DialogVsPartnerSelectionMenu | dialog | No | |
DistanceT | real | No | |
DiverBurrowed | boolean | No | |
DiverDevourCD | real | No | |
DiveTime | real | No | |
DmgEvBracers | itemcode | No | |
DmgEvLife | real | No | |
DmgEvN | integer | No | |
DmgEvRecursionN | integer | No | |
DmgEvRunning | boolean | No | |
DmgEvStack | unit | Yes | |
DmgEvStarted | boolean | No | |
DmgEvTimer | timer | No | |
DmgEvTrig | trigger | No | |
DmgTypPrev | integer | No | |
DropTableInt | integer | No | |
DropTableTrueInt | integer | No | |
DummyItem | item | No | |
DummyRect | rect | No | |
DV_Height | real | Yes | |
DV_SFX | effect | Yes | |
DV_Velocity | real | Yes | |
EasyItem__ERRORSOUND | string | No | |
EasyItem__SPLIT | boolean | No | |
EasyItem__SPLITDROP | boolean | No | |
EasyItem__SPLITSIZE | integer | No | |
EasyItem__SPLITSTACK | boolean | No | |
EasyItem__SPLITSTACKDELAY | real | No | |
EasyItem__USEITEMLEVEL | boolean | No | |
EasyItem_integer | integervar | Yes | |
EasyItem_item | item | No | |
EasyItem_items | item | Yes | |
EasyItem_point | location | Yes | |
EasyItem_sound | sound | No | |
EasyItem_string | string | Yes | |
EasyItem_timer | timer | No | |
EasyItem_unit | unit | No | |
EasyItem_units | unit | Yes | |
EnhancedDamageTarget | unit | No | |
ETHEREAL_DAMAGE_FACTOR | real | No | |
FallingBombGroup | group | No | |
FallingBoxGroup | group | No | |
FallSound | sound | No | |
FallSpeed | real | No | |
FBG_Rocket_SFX | effect | Yes | |
FBG_RocketFallSpeed | real | Yes | |
FBG_RocketHeight | real | Yes | |
FogB | real | No | |
FogB_Max | real | No | |
FogG | real | No | |
FogG_Max | real | No | |
FogR | real | No | |
FogR_Max | real | No | |
Frag | integer | Yes | |
FragScore | real | No | |
FS_AnimationTime | real | No | |
FS_AnimSpeed | real | No | |
FS_CurrentHeight | real | No | |
FS_FlyAngle | real | No | |
FS_Group | group | No | |
FS_Height | real | No | |
FS_Speed | real | No | |
FS_Strength | real | No | |
FS_UnitFacingAngle | real | No | |
FSS_Angle | real | Yes | |
FSS_CurrentHeight | real | Yes | |
FSS_Height | real | Yes | |
FSS_Speed | real | Yes | |
FSS_Strength | real | Yes | |
FSS_TimeFrame | real | Yes | |
GameCamDist | real | No | |
GameEndCinematic | boolean | No | |
GameMode_Survival | boolean | No | |
GameMode_Versus | boolean | No | |
gCurrentH | real | No | |
gDistFactor | real | No | |
gKey | integer | No | |
gLife | real | No | |
GlobalHighScore | integer | No | |
GlobalHSName | string | No | |
GlobalHSVersion | string | No | |
gOwner | unit | No | |
GR_ShardCount | real | No | |
GreenGreenPot | itemcode | No | |
GreenPot | itemcode | No | |
GreenRedPot | itemcode | No | |
GrenadeGroup | group | No | |
gTempPoint1 | location | No | |
gTempPoint2 | location | No | |
gTempPoint3 | location | No | |
gTempPoint4 | location | No | |
gTempPoint5 | location | No | |
gTempReal | real | No | |
gX | real | No | |
gXCal1 | real | No | |
gXCal2 | real | No | |
gXCal3 | real | No | |
gY | real | No | |
gYCal1 | real | No | |
gYCal2 | real | No | |
gYCal3 | real | No | |
gZ | real | No | |
gZ2 | real | No | |
gZCal1 | real | No | |
h | hashtable | No | |
h1 | real | No | |
HandAttachments | string | Yes | |
HeadAttachments | string | Yes | |
HerbTempPoint | location | No | |
HerbTempPoint2 | location | No | |
HGAmmo | integer | Yes | |
HGAutoReload | real | Yes | |
HGAutoReloadTime | real | No | |
HGCooldown | real | Yes | |
HGCooldownTime | real | No | |
HGFireSound | sound | Yes | |
HGGroup | group | No | |
HGMaxBullet | integer | No | |
HGPlayerNumber | integer | No | |
HGRelativeAngle | real | No | |
HGReloadCooldownTime | real | No | |
HGSoundClipCount | integer | No | |
HGSoundFireSlow | sound | Yes | |
HGTempPoint | location | No | |
HGTempPoint2 | location | No | |
HGTempPoint3 | location | No | |
HGUnit | unit | No | |
HideDamageFrom | boolean | Yes | |
HitGroup | group | No | |
HitUnit | unit | No | |
HopperDist | real | No | |
INIT_Integer | integer | No | |
INIT_Integer2 | integer | No | |
INIT_ItemRarity | integer | Yes | |
INIT_ItemType | itemcode | Yes | |
INIT_ItemTypeCount | integer | No | |
IsDamageSpell | boolean | No | |
ItemDrop | itemcode | Yes | |
ITEMRARITY | integer | No | |
JetSpeed | real | No | |
JobItemInt | integer | Yes | |
JobString | string | Yes | |
JumpDown | boolean | No | |
JumpHeight | real | No | |
KEV_amount | real | No | |
Key | integer | No | |
Key2 | integer | No | |
LastDamageHP | real | No | |
LastDmgPrevAmount | real | Yes | |
LastDmgPrevType | integer | Yes | |
LastDmgSource | unit | Yes | |
LastDmgTarget | unit | Yes | |
LastDmgValue | real | Yes | |
LastDmgWasSpell | boolean | Yes | |
LastHopperDist | real | No | |
LB_Bool | boolean | No | |
LB_ChangeDirTime | real | Yes | |
LB_Group | group | No | |
LB_IsChangeDir | boolean | Yes | |
LB_OriFacing | real | Yes | |
LB_TempReal1 | real | No | |
LB_TempReal2 | real | No | |
LB_Unit | unit | No | |
LB_Unit2 | unit | No | |
LB_Unit3 | unit | No | |
LC_TempReal | real | No | |
LevelValue | integer | No | |
LivingPlayerUnit | group | No | |
LoopInteger1 | integer | No | |
LoopInteger2 | integer | No | |
MAX_CLASSES | integer | No | |
MAX_PLAYER_ZOMBIES | integer | No | |
MAX_SPAWN | integer | No | |
MAX_SUPPLY_TIMER | real | No | |
MAX_VERSUS_TIME | integer | No | |
MAX_ZOMB_TYPE | integer | No | |
MAXAMMO | integer | No | |
MAXCLIP | integer | No | |
MaxDist | real | No | |
MaxHandGunSound | integer | No | |
MaxHeight | real | No | |
MaxPoint | location | No | |
MC | unit | Yes | |
MC_Alive | boolean | Yes | |
MCFlag | boolean | No | |
MeleeGroup | group | No | |
MeleeTimer | real | No | |
MIN_CLASSES | integer | No | |
MINGOODSCORE | integer | No | |
MinPoint | location | No | |
ModeSelectionLeader | player | No | |
MolotovGroup | group | No | |
MolotovLife | real | No | |
MorphAnimGroup | group | No | |
MR_AnimationSpeed | real | No | |
MR_AnimFrame | real | No | |
MR_TempSize | real | No | |
MR_TempUnit | unit | No | |
NEWHSReached | boolean | No | |
NextBombDist | real | No | |
NextDamageOverride | boolean | No | |
NextDamageType | integer | No | |
NextSupplyPoint | location | No | |
NitrogenGroup | group | No | |
NoDamage | boolean | No | false |
order | integer | No | |
ParachuteOn | boolean | No | |
PeriodicInterval | real | No | |
PHYSICAL | integer | No | |
PickedUnitPoint | location | No | |
Pierce | integer | No | |
PlayerClass | integer | Yes | |
PlayerColor | string | Yes | |
PlayerCount | integer | No | |
PlayerName | string | Yes | |
PlayerPitch | real | Yes | |
PotItem | item | No | |
PotTargetItem | item | No | |
PreLoadComplete | boolean | No | false |
pureAmount | real | No | |
RandomAttachmentString | string | Yes | |
RandomInt | integer | No | |
RandomInt2 | integer | No | |
RandomInt3 | integer | No | |
RandomReal | real | No | |
RebuildCount | integer | No | |
RebuildItemType | itemcode | Yes | |
RedPot | itemcode | No | |
ReloadGroup | group | No | |
ReloadUnit | unit | No | |
RessUnit | unit | No | |
ResultingItem | itemcode | No | |
RG_BQueue | integer | Yes | |
RG_Combo | integer | Yes | |
RG_Group | group | No | |
RG_NextBullet | real | Yes | |
RG_Point | location | Yes | |
RG_Point2 | location | No | |
RG_Point3 | location | No | |
RG_SpecialEffect | effect | Yes | |
RG_Unit | unit | No | |
RLTempPoint | location | No | |
RocketX | real | No | |
RocketY | real | No | |
runAllocatedAttacks | trigger | No | |
SA_Group | group | No | |
SA_Time | real | Yes | |
Score | integer | Yes | |
ScoreMultiboard | multiboard | No | |
SET_MAX_LIFE | integer | No | |
SFXTempPoint | location | No | |
Size | real | No | |
SlotAvailable | boolean | Yes | |
SlowMoTime | real | No | |
SlowMotionDummy | unit | No | |
SlowMotionON | boolean | No | |
SmokeGroup | group | No | |
Speed | real | No | |
SPELL | integer | No | |
SPELL_DAMAGE_REDUCTION_ITEM | integer | No | |
SPELL_RESISTANCE_AUTO_DETECT | boolean | No | |
SpellDamageAbility | abilcode | No | |
STARTCLIP | integer | No | |
StartItem | itemcode | Yes | |
SupplyGenericAmount | integer | No | |
SupplyGenericCount | integer | No | |
SupplyItemsGeneric | itemcode | Yes | |
SupplyItemsRandom | itemcode | Yes | |
SupplyRandomAmount | integer | No | |
SupplyRandomCount | integer | No | |
SupplyTimer | real | No | |
SurvivalPlayerColor | playercolor | Yes | |
SV_MAX_PLAYER_ZOMBIES | integer | No | |
SV_MAX_SPAWN | integer | No | |
SwayFactor | real | No | |
SwayGroup | group | No | |
TargetUnit1 | unit | No | |
TargetUnit2 | unit | No | |
TeamString | string | Yes | |
TempAngle | real | No | |
TempBomberAngle | real | No | |
TempBomberHeight | real | No | |
TempBombUnit | unit | No | |
TempBoolean | boolean | No | |
TempBoxHeight | real | No | |
TempDarkDistance | real | No | |
TempDarkDistance2 | real | No | |
TempDarkTargetCount | integer | No | |
TempDistance | real | No | |
TempFloatingText | texttag | No | |
TempHopperUnitFollow | unit | No | |
TempInt | integer | No | |
TempItem | item | No | |
TempItemDropPoint | location | No | |
TempLCUnit | unit | No | |
TempMS | real | No | |
TempParachuteUnit | unit | No | |
TempParaVelocity | real | No | |
TempPickedUnit | unit | No | |
TempPoint | location | No | |
TempPoint2 | location | No | |
TempPoint3 | location | No | |
TempPoint4 | location | No | |
TempPoint5 | location | No | |
TempPoint6 | location | No | |
TempPoint7 | location | No | |
TempReal | real | No | |
TempReal10 | real | No | |
TempReal11 | real | No | |
TempReal13 | real | No | |
TempReal14 | real | No | |
TempReal2 | real | No | |
TempReal3 | real | No | |
TempReal4 | real | No | |
TempReal5 | real | No | |
TempReal6 | real | No | |
TempReal7 | real | No | |
TempReal8 | real | No | |
TempReal9 | real | No | |
TempRealHP | real | No | |
TempRealSize | real | No | |
TempReloadBar | unit | No | |
TempRocketHeight | real | No | |
TempRocketPoint | location | No | |
TempRocketPoint2 | location | No | |
TempRocketUnit | unit | No | |
TempRotDistance | real | No | |
TempSize | real | No | |
TempSound | sound | No | |
TempStartPoint | location | No | |
TempString | string | No | |
TempString2 | string | No | |
TempTrigUnit | unit | No | |
TempUnit | unit | No | |
TempVsScoreInt | integer | No | |
TempWallUnit | unit | No | |
TerrainPassable | boolean | No | |
TimeFrame | real | No | |
TornadoEffectedUnit | unit | No | |
totalAllocs | integer | No | |
TotalPlayer | integer | No | |
TotalScore | integer | No | |
TotalZombieInt | integer | Yes | |
TotalZombies | group | Yes | |
TRIGGER_CLEANUP_PERIOD | real | No | |
UDex | integer | No | |
UDexGen | integer | No | |
UDexNext | integer | Yes | |
UDexPrev | integer | Yes | |
UDexRecycle | integer | No | |
UDexUnits | unit | Yes | |
UDexWasted | integer | No | |
UI_TempUnit | unit | No | |
UNIT_MIN_LIFE | real | No | |
UnitDamageRegistered | boolean | Yes | |
UnitIndexerEnabled | boolean | No | |
UnitIndexEvent | real | No | |
UnitIndexLock | integer | Yes | |
UnitMoving | boolean | Yes | |
UnitPoint | integer | Yes | |
vectorMaxIndex | integer | No | |
vectors | integer | Yes | |
vectorTaken | boolean | Yes | |
vectorUnusedAmount | integer | No | |
vectorUnusedIndex | integer | Yes | |
vectorX | real | Yes | |
vectorY | real | Yes | |
vectorZ | real | Yes | |
Versus_Assist | integer | Yes | |
Versus_ComboStreak | integer | Yes | |
Versus_ComboTime | real | Yes | |
Versus_DeadCountDown | integer | Yes | |
Versus_DeadPlayerGroup | force | No | |
Versus_Death | integer | Yes | |
Versus_FFA | boolean | No | |
Versus_Kills | integer | Yes | |
VERSUS_MAX_PLAYER_ZOMBIES | integer | No | |
VERSUS_MAX_RESPAWNTIME | integer | No | |
VERSUS_MAX_SPAWN | integer | No | |
VERSUS_MAX_SUPPLY_TIMER | real | No | |
Versus_MCFlag | boolean | Yes | |
Versus_PlayerTeam | integer | Yes | |
Versus_Score | integer | Yes | |
VERSUS_STARTCLIP | integer | No | |
Versus_TeamScore | integer | Yes | |
Versus_TempPlayerInt | integer | No | |
Versus_TempWinner | integer | No | |
VersusTimeRemaining | integer | No | |
VS_StartItem | itemcode | Yes | |
WeaponRecoil | real | No | |
WormNear | boolean | No | |
WormUnit | unit | No | |
X | real | No | |
XInteger | integer | No | |
Y | real | No | |
ZD_Acceleration | real | Yes | |
ZD_Angle | real | Yes | |
ZD_AnimLoop | real | Yes | |
ZD_AnimSpeed | real | Yes | |
ZD_Group | group | No | |
ZD_Speed | real | Yes | |
ZD_TimeFrame | real | Yes | |
ZG_CommandUnit | unit | Yes | |
ZG_GrabberUnit | unit | Yes | |
ZG_GrabUnit | unit | Yes | |
ZG_Group | group | No | |
ZG_NextBite | real | Yes | |
ZG_X | real | Yes | |
ZG_Y | real | Yes | |
ZInteger | integer | No | |
Zombie_Hash | hashtable | No | |
ZombieInt | integer | No | |
ZombieName | string | Yes | |
ZombieType | unitcode | Yes |
//===========================================================================
// Damage Engine lets you detect, amplify, block or nullify damage. It even
// lets you detect if the damage was physical or from a spell. Just reference
// DamageEventAmount/Source/Target or the boolean IsDamageSpell, to get the
// necessary damage event data.
//
// - Detect damage: use the event "DamageEvent Equal to 1.00"
// - To change damage before it's dealt: use the event "DamageModifierEvent Equal to 1.00"
// - Detect damage after it was applied, use the event "AfterDamageEvent Equal to 1.00"
// - Detect spell damage: use the condition "IsDamageSpell Equal to True"
// - Detect zero-damage: use the event "DamageEvent Equal to 2.00" (an AfterDamageEvent will not fire for this)
//
// You can specify the DamageEventType before dealing triggered damage. To prevent an already-improbable error, I recommend running the trigger "ClearDamageEvent (Checking Conditions)" after dealing triggered damage from within a damage event:
// - Set NextDamageType = DamageTypeWhatever
// - Unit - Cause...
// - Trigger - Run ClearDamageEvent (Checking Conditions)
//
// You can modify the DamageEventAmount and the DamageEventType from a "DamageModifierEvent Equal to 1.00" trigger.
// - If the amount is modified to negative, it will count as a heal.
// - If the amount is set to 0, no damage will be dealt.
//
// If you need to reference the original in-game damage, use the variable "DamageEventPrevAmt".
//
//===========================================================================
// Programming note about "integer i" and "udg_DmgEvRecursionN": integer i
// ranges from -1 upwards. "udg_DmgEvRecursionN" ranges from 0 upwards.
// "integer i" is always 1 less than "udg_DmgEvRecursionN"
//
function DmgEvResetVars takes nothing returns nothing
local integer i = udg_DmgEvRecursionN - 2
set udg_DmgEvRecursionN = i + 1
if i >= 0 then
set udg_DamageEventPrevAmt = udg_LastDmgPrevAmount[i]
set udg_DamageEventAmount = udg_LastDmgValue[i]
set udg_DamageEventSource = udg_LastDmgSource[i]
set udg_DamageEventTarget = udg_LastDmgTarget[i]
set udg_IsDamageSpell = udg_LastDmgWasSpell[i]
set udg_DamageEventType = udg_LastDmgPrevType[i]
endif
endfunction
function CheckDamagedLifeEvent takes boolean clear returns nothing
if clear then
set udg_NextDamageOverride = false
set udg_NextDamageType = 0
endif
if udg_DmgEvTrig != null then
call DestroyTrigger(udg_DmgEvTrig)
set udg_DmgEvTrig = null
if udg_IsDamageSpell then
call SetWidgetLife(udg_DamageEventTarget, RMaxBJ(udg_LastDamageHP, 0.41))
if udg_LastDamageHP <= 0.405 then
if udg_DamageEventType < 0 then
call SetUnitExploded(udg_DamageEventTarget, true)
endif
//Kill the unit
call DisableTrigger(udg_DamageEventTrigger)
call UnitDamageTarget(udg_DamageEventSource, udg_DamageEventTarget, -999, false, false, null, DAMAGE_TYPE_UNIVERSAL, null)
call EnableTrigger(udg_DamageEventTrigger)
endif
elseif GetUnitAbilityLevel(udg_DamageEventTarget, udg_DamageBlockingAbility) > 0 then
call UnitRemoveAbility(udg_DamageEventTarget, udg_DamageBlockingAbility)
call SetWidgetLife(udg_DamageEventTarget, udg_LastDamageHP)
endif
if udg_DamageEventAmount != 0.00 and not udg_HideDamageFrom[GetUnitUserData(udg_DamageEventSource)] then
set udg_AfterDamageEvent = 0.00
set udg_AfterDamageEvent = 1.00
set udg_AfterDamageEvent = 0.00
endif
call DmgEvResetVars()
endif
endfunction
function DmgEvOnAOEEnd takes nothing returns nothing
if udg_DamageEventAOE > 1 then
set udg_AOEDamageEvent = 0.00
set udg_AOEDamageEvent = 1.00
set udg_AOEDamageEvent = 0.00
set udg_DamageEventAOE = 1
endif
set udg_DamageEventLevel = 1
set udg_EnhancedDamageTarget = null
call GroupClear(udg_DamageEventAOEGroup)
endfunction
function DmgEvOnExpire takes nothing returns nothing
set udg_DmgEvStarted = false
call CheckDamagedLifeEvent(true)
//Reset things so they don't perpetuate for AoE/Level target detection
call DmgEvOnAOEEnd()
set udg_DamageEventTarget = null
set udg_DamageEventSource = null
endfunction
function PreCheckDamagedLifeEvent takes nothing returns boolean
call CheckDamagedLifeEvent(true)
return false
endfunction
function OnUnitDamage takes nothing returns boolean
local boolean override = udg_DamageEventOverride
local integer i
local integer e = udg_DamageEventLevel
local integer a = udg_DamageEventAOE
local string s
local real prevAmount
local real life
local real prevLife
local unit u
local unit f
call CheckDamagedLifeEvent(false) //in case the unit state event failed and the 0.00 second timer hasn't yet expired
set i = udg_DmgEvRecursionN - 1 //Had to be moved here due to false recursion tracking
if i < 0 then
//Added 25 July 2017 to detect AOE damage or multiple single-target damage
set u = udg_DamageEventTarget
set f = udg_DamageEventSource
elseif i < 16 then
set udg_LastDmgPrevAmount[i]= udg_DamageEventPrevAmt
set udg_LastDmgValue[i] = udg_DamageEventAmount
set udg_LastDmgSource[i] = udg_DamageEventSource
set udg_LastDmgTarget[i] = udg_DamageEventTarget
set udg_LastDmgWasSpell[i] = udg_IsDamageSpell
set udg_LastDmgPrevType[i] = udg_DamageEventType
else
set s = "WARNING: Recursion error when dealing damage! Make sure when you deal damage from within a DamageEvent trigger, do it like this:\n\n"
set s = s + "Trigger - Turn off (This Trigger)\n"
set s = s + "Unit - Cause...\n"
set s = s + "Trigger - Turn on (This Trigger)"
//Delete the next couple of lines to disable the in-game recursion crash warnings
call ClearTextMessages()
call DisplayTimedTextToPlayer(GetLocalPlayer(), 0.00, 0.00, 999.00, s)
return false
endif
set udg_DmgEvRecursionN = i + 2
set prevAmount = GetEventDamage()
set udg_DamageEventTarget = GetTriggerUnit()
set udg_DamageEventSource = GetEventDamageSource()
set udg_DamageEventAmount = prevAmount
set udg_DamageEventType = udg_NextDamageType
set udg_NextDamageType = 0
set udg_DamageEventOverride = udg_NextDamageOverride
set udg_NextDamageOverride = false
if i < 0 then
//Added 25 July 2017 to detect AOE damage or multiple single-target damage
if udg_DamageEventType == 0 then
if f == udg_DamageEventSource then
//Source has damaged more than once
if IsUnitInGroup(udg_DamageEventTarget, udg_DamageEventAOEGroup) then
//Added 5 August 2017 to improve tracking of enhanced damage against, say, Pulverize
set udg_DamageEventLevel = udg_DamageEventLevel + 1
set udg_EnhancedDamageTarget = udg_DamageEventTarget
else
//Multiple targets hit by this source - flag as AOE
set udg_DamageEventAOE = udg_DamageEventAOE + 1
endif
else
//New damage source - unflag everything
set u = udg_DamageEventSource
set udg_DamageEventSource = f
call DmgEvOnAOEEnd()
set udg_DamageEventSource = u
endif
call GroupAddUnit(udg_DamageEventAOEGroup, udg_DamageEventTarget)
endif
if not udg_DmgEvStarted then
set udg_DmgEvStarted = true
call TimerStart(udg_DmgEvTimer, 0.00, false, function DmgEvOnExpire)
endif
endif
if prevAmount == 0.00 then
if not udg_HideDamageFrom[GetUnitUserData(udg_DamageEventSource)] then
set udg_DamageEventPrevAmt = 0.00
set udg_DamageEvent = 0.00
set udg_DamageEvent = 2.00
set udg_DamageEvent = 0.00
endif
call DmgEvResetVars()
else
set u = udg_DamageEventTarget
set udg_IsDamageSpell = prevAmount < 0.00
if udg_IsDamageSpell then
set prevAmount = -udg_DamageEventAmount
set life = 1.00
if IsUnitType(u, UNIT_TYPE_ETHEREAL) and not IsUnitType(u, UNIT_TYPE_HERO) then
set life = life*udg_DAMAGE_FACTOR_ETHEREAL //1.67
endif
if GetUnitAbilityLevel(u, 'Aegr') > 0 then
set life = life*udg_DAMAGE_FACTOR_ELUNES //0.80
endif
if udg_DmgEvBracers != 0 and IsUnitType(u, UNIT_TYPE_HERO) then
//Inline of UnitHasItemOfTypeBJ without the potential handle ID leak.
set i = 6
loop
set i = i - 1
if GetItemTypeId(UnitItemInSlot(u, i)) == udg_DmgEvBracers then
set life = life*udg_DAMAGE_FACTOR_BRACERS //0.67
exitwhen true
endif
exitwhen i == 0
endloop
endif
set udg_DamageEventAmount = prevAmount*life
endif
set udg_DamageEventPrevAmt = prevAmount
set udg_DamageModifierEvent = 0.00
if not udg_DamageEventOverride then
set udg_DamageModifierEvent = 1.00
if not udg_DamageEventOverride then
set udg_DamageModifierEvent = 2.00
set udg_DamageModifierEvent = 3.00
endif
endif
set udg_DamageEventOverride = override
if udg_DamageEventAmount > 0.00 then
set udg_DamageModifierEvent = 4.00
endif
set udg_DamageModifierEvent = 0.00
if not udg_HideDamageFrom[GetUnitUserData(udg_DamageEventSource)] then
set udg_DamageEvent = 0.00
set udg_DamageEvent = 1.00
set udg_DamageEvent = 0.00
endif
call CheckDamagedLifeEvent(true) //in case the unit state event failed from a recursive damage event
//All events have run and the damage amount is finalized.
set life = GetWidgetLife(u)
set udg_DmgEvTrig = CreateTrigger()
call TriggerAddCondition(udg_DmgEvTrig, Filter(function PreCheckDamagedLifeEvent))
if not udg_IsDamageSpell then
if udg_DamageEventAmount != prevAmount then
set life = life + prevAmount - udg_DamageEventAmount
if GetUnitState(u, UNIT_STATE_MAX_LIFE) < life then
set udg_LastDamageHP = life - prevAmount
call UnitAddAbility(u, udg_DamageBlockingAbility)
endif
call SetWidgetLife(u, RMaxBJ(life, 0.42))
endif
call TriggerRegisterUnitStateEvent(udg_DmgEvTrig, u, UNIT_STATE_LIFE, LESS_THAN, RMaxBJ(0.41, life - prevAmount/2.00))
else
set udg_LastDamageHP = GetUnitState(u, UNIT_STATE_MAX_LIFE)
set prevLife = life
if life + prevAmount*0.75 > udg_LastDamageHP then
set life = RMaxBJ(udg_LastDamageHP - prevAmount/2.00, 1.00)
call SetWidgetLife(u, life)
set life = (life + udg_LastDamageHP)/2.00
else
set life = life + prevAmount*0.50
endif
set udg_LastDamageHP = prevLife - (prevAmount - (prevAmount - udg_DamageEventAmount))
call TriggerRegisterUnitStateEvent(udg_DmgEvTrig, u, UNIT_STATE_LIFE, GREATER_THAN, life)
endif
endif
set u = null
set f = null
return false
endfunction
function CreateDmgEvTrg takes nothing returns nothing
set udg_DamageEventTrigger = CreateTrigger()
call TriggerAddCondition(udg_DamageEventTrigger, Filter(function OnUnitDamage))
endfunction
function SetupDmgEv takes nothing returns boolean
local integer i = udg_UDex
local unit u
if udg_UnitIndexEvent == 1.00 then
set u = udg_UDexUnits[i]
if GetUnitAbilityLevel(u, 'Aloc') == 0 and TriggerEvaluate(gg_trg_Damage_Engine_Config) then
set udg_UnitDamageRegistered[i] = true
call TriggerRegisterUnitEvent(udg_DamageEventTrigger, u, EVENT_UNIT_DAMAGED)
call UnitAddAbility(u, udg_SpellDamageAbility)
call UnitMakeAbilityPermanent(u, true, udg_SpellDamageAbility)
endif
set u = null
else
set udg_HideDamageFrom[i] = false
if udg_UnitDamageRegistered[i] then
set udg_UnitDamageRegistered[i] = false
set udg_DamageEventsWasted = udg_DamageEventsWasted + 1
if udg_DamageEventsWasted == 32 then //After 32 registered units have been removed...
set udg_DamageEventsWasted = 0
//Rebuild the mass EVENT_UNIT_DAMAGED trigger:
call DestroyTrigger(udg_DamageEventTrigger)
call CreateDmgEvTrg()
set i = udg_UDexNext[0]
loop
exitwhen i == 0
if udg_UnitDamageRegistered[i] then
call TriggerRegisterUnitEvent(udg_DamageEventTrigger, udg_UDexUnits[i], EVENT_UNIT_DAMAGED)
endif
set i = udg_UDexNext[i]
endloop
endif
endif
endif
return false
endfunction
//===========================================================================
function InitTrig_Damage_Engine takes nothing returns nothing
local unit u = CreateUnit(Player(bj_PLAYER_NEUTRAL_EXTRA), 'uloc', 0, 0, 0)
local integer i = bj_MAX_PLAYERS //Fixed in 3.8
//Create this trigger with UnitIndexEvents in order add and remove units
//as they are created or removed.
local trigger t = CreateTrigger()
call TriggerRegisterVariableEvent(t, "udg_UnitIndexEvent", EQUAL, 1.00)
call TriggerRegisterVariableEvent(t, "udg_UnitIndexEvent", EQUAL, 2.00)
call TriggerAddCondition(t, Filter(function SetupDmgEv))
set t = null
//Run the configuration trigger to set all configurables:
if gg_trg_Damage_Engine_Config == null then
//It's possible this InitTrig_ function ran first, in which case use ExecuteFunc.
call ExecuteFunc("Trig_Damage_Engine_Config_Actions")
else
call TriggerExecute(gg_trg_Damage_Engine_Config)
endif
//Create trigger for storing all EVENT_UNIT_DAMAGED events.
call CreateDmgEvTrg()
//Create GUI-friendly trigger for cleaning up after UnitDamageTarget.
set udg_ClearDamageEvent = CreateTrigger()
call TriggerAddCondition(udg_ClearDamageEvent, Filter(function PreCheckDamagedLifeEvent))
//Disable SpellDamageAbility for every player.
loop
set i = i - 1
call SetPlayerAbilityAvailable(Player(i), udg_SpellDamageAbility, false)
exitwhen i == 0
endloop
//Preload abilities.
call UnitAddAbility(u, udg_DamageBlockingAbility)
call UnitAddAbility(u, udg_SpellDamageAbility)
call RemoveUnit(u)
set u = null
endfunction
////////////////////////////////////////////////////////////////////////////////////
//
// Physical Damage Detection Engine GUI v 1.0.0.2
//  ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
// By looking_for_help aka eey
//
// This system is able to detect, modify and deal damage. It can differentiate
// between physical and spell damage, as well as block, reduce or increase the
// applied damage to a desired value. You can also allocate damage events from
// running damage events.
//
// This is the GUI version of the system, meaning that you can use this with the
// standard editor and basically without any knowledge of JASS.
//
////////////////////////////////////////////////////////////////////////////////////
//
// Implementation
//  ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
// 1. Create all variables that this system uses (compare the variable editor).
// You don't have to set them to specific values, they get initialized
// automatically by the system so just create them.
// 2. Copy this trigger to your map. You can then add damage handlers by using
// the event "value of real variable becomes equal to 1" with the variable
// damageEventTrigger. Compare the OnDamage trigger for an example usage.
// 3. Copy the two custom abilities to your map and make sure they have the
// correct ID. You can specify the ID in the function InitGlobalVariables
// above.
// 4. Go to the locust swarm ability and invert its damage return portion
// from (default) 0.75 to -0.75.
// 5. Remove the spell damage reduction ability from the spell damage reduction
// items you use (runed bracers). You can configure the resistance of this
// item in the InitGlobalVariables function, modifying the golbal variable
// BRACERS_SPELL_DAMAGE_REDUCTION.
//
////////////////////////////////////////////////////////////////////////////////////
//
// Important Notes
//  ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
// 1. Life Drain does not work with this system, so you should use a triggered
// version of this spell if you want to use it.
// 2. Same for Finger of Death, if you want to use this spell bug free with this
// system, you should use a triggered version of it.
// 3. If you use damage modifiers by setting the damage amount variable, you have
// to use GetUnitLife, GetUnitMaxLife and SetUnitLife instead of GetWidgetLife,
// GetUnitState for UNIT_STATE_MAX_LIFE and SetWidgetLife in your whole map to
// ensure there occure no bugs.
// 4. The boolean USE_SPELL_RESISTANCE_AUTO_DETECT is only neccessary set to true
// if you want to use a customized damage table with spell damage resistance
// above 100%. If this is not the case, it should be set to false, as the
// system is faster then and still works correct.
// 5. As already mentioned you can't use the spell reduction ability when using this
// system (runed bracers and elunes grace). If you want to use them, you can
// trigger them by using the damage modifiers. Runed bracers is already considered
// in this system, so you don't have to code it.
//
////////////////////////////////////////////////////////////////////////////////////
//
// System API
//  ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
// real damageEventTrigger
// - Use the event "value of real variable becomes equal to 1" to detect a damage
// event. In this event you can use the following API. Compare the OnDamage
// trigger for an example usage.
//
// unit target
// - In this global unit variable, the damaged unit is saved. Don't write any-
// thing into this variable, use it as readonly.
//
// unit source
// - In this global unit variable, the damage source is saved. Don't write any-
// thing into this variable, use it as readonly.
//
// real amount
// - In this global real variable, the amount of damage is saved. This amount
// can be modified by simply setting it to the desired amount that should be
// applied to the target. Set the amount to 0.0 to block the damage completly.
// Negative values will result in heal.
//
// integer damageType
// - In this global integer variable, the damage type of the current damage is
// saved. Use it to differentiate between physical, spell and code damage. The
// variable can takes the values PHYSICAL == 0, SPELL == 1 and CODE == 2. Don't
// write anything into this variable, use it as readonly.
//
// function GetUnitLife takes unit u returns real
// - Use this function instead of the GetWidgetLife native. It ensures that you
// get the correct health value, even when damage modifiers are applied. If
// you don't use damage modifiers at all, you don't need this function.
//
// function GetUnitMaxLife takes unit u returns real
// - Use this function instead of the GetUnitState(u, UNIT_STATE_MAX_LIFE) native.
// It will return the correct value, even when damage modifiers are applied. If
// you don't use damage modifiers at all, you don't need this function.
//
// function SetUnitLife takes unit u, real newLife returns nothing
// - Use this function instead of the SetWidgetLife(u, newLife) native if you use
// damage modifiers in your map. Same rules as for the GetUnitMaxLife and the
// GetUnitMaxLife functions.
//
// function AddDamageHandler takes code damageHandler returns nothing
// - Allows you to add a damage handler function to the system. This is not
// required for GUI users, only for vanilla JASS users. GUI users should
// use the real variable damageEventTrigger to add damage handlers to this
// system as explained above.
//
// function RemoveDamageHandler takes code damageHandler returns nothing
// - Allows you to remove a damage handler function from the system dynamic-
// ally. If you added the same handler function multiple times to the sys-
// tem, this function will remove all of these equal functions. This is not
// required for GUI users, only for vanilla JASS users.
//
//////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////
// Configurable globals
//////////////////////////////////////////////////////////////////////////////////
function InitGlobalVariables takes nothing returns nothing
// Put here the correct ability IDs
set udg_DAMAGE_TYPE_DETECTOR = 'A015'
set udg_SET_MAX_LIFE = 'A03C'
// Here you can configure some stuff, read the documentation for further info
set udg_SPELL_DAMAGE_REDUCTION_ITEM = 'brac'
set udg_SPELL_RESISTANCE_AUTO_DETECT = false
set udg_ETHEREAL_DAMAGE_FACTOR = 1.66
set udg_BRACERS_SPELL_DAMAGE_REDUCTION = 0.33
set udg_TRIGGER_CLEANUP_PERIOD = 60.0
endfunction
//////////////////////////////////////////////////////////////////////////////////
// End of configurable globals
//////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////
// User functions
//////////////////////////////////////////////////////////////////////////////////
function AddDamageHandler takes code func returns nothing
local integer id = GetHandleId(Condition(func))
local integer index = 0
// Loop to manage equal damage handlers
loop
exitwhen ( LoadTriggerConditionHandle(udg_h, id, index) == null )
set index = index + 1
endloop
// Store the desired damage handler function
call SaveTriggerConditionHandle(udg_h, id, index, TriggerAddCondition(udg_damageHandler, Filter(func)))
endfunction
function RemoveDamageHandler takes code func returns nothing
local integer id = GetHandleId(Condition(func))
local integer index = 0
// Loop through all equal damage handlers
loop
exitwhen ( LoadTriggerConditionHandle(udg_h, id, index) == null )
call TriggerRemoveCondition(udg_damageHandler, LoadTriggerConditionHandle(udg_h, id, index))
set index = index + 1
endloop
// Clean things up
call FlushChildHashtable(udg_h, id)
endfunction
function GetUnitLife takes unit u returns real
local boolean duringModification
local integer uId = GetHandleId(u)
local real health
local real storedHealth = LoadReal(udg_h, uId, 2)
local real storedDamage = LoadReal(udg_h, uId, 1)
// Check if the unit is being rescued from damage
set duringModification = GetUnitAbilityLevel(u, udg_SET_MAX_LIFE) > 0
if duringModification then
call UnitRemoveAbility(u, udg_SET_MAX_LIFE)
endif
// Get the correct health value of the unit
if storedHealth != 0.0 then
set health = storedHealth - storedDamage
else
set health = GetWidgetLife(u) - storedDamage
endif
// Restore the rescue ability and return
if duringModification then
call UnitAddAbility(u, udg_SET_MAX_LIFE)
endif
return health
endfunction
function GetUnitMaxLife takes unit u returns real
local real maxHealth
// Check if the unit is being rescued from damage
if GetUnitAbilityLevel(u, udg_SET_MAX_LIFE) > 0 then
call UnitRemoveAbility(u, udg_SET_MAX_LIFE)
set maxHealth = GetUnitState(u, UNIT_STATE_MAX_LIFE)
call UnitAddAbility(u, udg_SET_MAX_LIFE)
return maxHealth
endif
// If the unit isn't being rescued, use the standard native
return GetUnitState(u, UNIT_STATE_MAX_LIFE)
endfunction
function SetUnitLife takes unit u, real newLife returns nothing
local integer targetId
local integer oldTimerId
local real oldHealth
// Check if the unit is being rescued from damage
if GetUnitAbilityLevel(u, udg_SET_MAX_LIFE) > 0 then
call UnitRemoveAbility(u, udg_SET_MAX_LIFE)
call SetWidgetLife(u, newLife)
call UnitAddAbility(u, udg_SET_MAX_LIFE)
// Get the unit specific timer information
set targetId = GetHandleId(u)
set oldHealth = LoadReal(udg_h, targetId, 0)
// Update the unit specific timer information
if oldHealth != 0.0 then
set oldTimerId = LoadInteger(udg_h, targetId, 3)
call SaveReal(udg_h, targetId, 2, newLife)
call SaveReal(udg_h, targetId, 0, newLife)
call SaveReal(udg_h, oldTimerId, 4, newLife)
endif
return
endif
// If the unit isn't being rescued, use the standard native
call SetWidgetLife(u, newLife)
endfunction
function UnitDamageTargetEx takes unit localSource, unit localTarget, real localAmount, boolean attack, boolean ranged, attacktype localAttackType, damagetype localDamageType, weapontype localWeaponType returns boolean
// Avoid infinite loop due to recursion
if udg_damageType == udg_CODE then
return false
endif
// Avoid allocating attacks on units that are about to be killed
if ( localTarget == udg_DamageEventTarget and GetUnitLife(localTarget) - udg_DamageEventAmount < udg_UNIT_MIN_LIFE ) then
return false
endif
// Store all damage parameters determined by the user
set udg_allocatedAttacks = udg_allocatedAttacks + 1
call SaveUnitHandle(udg_h, udg_allocatedAttacks, 0, localSource)
call SaveUnitHandle(udg_h, udg_allocatedAttacks, 1, localTarget)
call SaveReal(udg_h, udg_allocatedAttacks, 2, localAmount)
call SaveBoolean(udg_h, udg_allocatedAttacks, 3, attack)
call SaveBoolean(udg_h, udg_allocatedAttacks, 4, ranged)
call SaveInteger(udg_h, udg_allocatedAttacks, 5, GetHandleId(localAttackType))
call SaveInteger(udg_h, udg_allocatedAttacks, 6, GetHandleId(localDamageType))
call SaveInteger(udg_h, udg_allocatedAttacks, 7, GetHandleId(localWeaponType))
// Return true if the damage was allocated
return true
endfunction
////////////////////////////////////////////////////////////////////////////////////
// Sub functions
////////////////////////////////////////////////////////////////////////////////////
function DealFixDamage takes unit source, unit target, real pureAmount returns nothing
local real MAX_DAMAGE = 1000000.0
local real beforeHitpoints
local real newHitpoints
// Ensure the amount is positive
if pureAmount < 0 then
set pureAmount = -pureAmount
endif
// Save the targets hitpoints
set beforeHitpoints = GetWidgetLife(target)
set newHitpoints = beforeHitpoints - pureAmount
// Apply the desired, fixed amount
if newHitpoints >= udg_UNIT_MIN_LIFE then
call SetUnitState(target, UNIT_STATE_LIFE, newHitpoints)
else
if ( IsUnitType(target, UNIT_TYPE_ETHEREAL) == false ) then
call SetWidgetLife(target, 1.0)
call UnitDamageTarget(source, target, MAX_DAMAGE, true, false, udg_ATTACK_TYPE_UNIVERSAL, DAMAGE_TYPE_UNIVERSAL, null)
else
call UnitRemoveAbility(target, udg_DAMAGE_TYPE_DETECTOR)
call SetWidgetLife(target, 1.0)
call UnitDamageTarget(source, target, MAX_DAMAGE, true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_UNIVERSAL, null)
endif
endif
endfunction
function GetUnitSpellResistance takes unit u returns real
local real originalHP
local real beforeHP
local real afterHP
local real resistance
local real DUMMY_DAMAGE = 100
local real DUMMY_FACTOR = 0.01
// Deal spell damage in order to get the units resistance
call UnitRemoveAbility(udg_DamageEventTarget, udg_DAMAGE_TYPE_DETECTOR)
set originalHP = GetWidgetLife(udg_DamageEventTarget)
call UnitAddAbility(udg_DamageEventTarget, udg_SET_MAX_LIFE)
call SetWidgetLife(udg_DamageEventTarget, 20000.0)
set beforeHP = GetWidgetLife(udg_DamageEventTarget)
call DisableTrigger(udg_damageEvent)
call UnitDamageTarget(udg_DamageEventSource, udg_DamageEventTarget, DUMMY_DAMAGE, true, false, null, DAMAGE_TYPE_UNIVERSAL, null)
call EnableTrigger(udg_damageEvent)
set afterHP = GetWidgetLife(udg_DamageEventTarget)
call UnitRemoveAbility(udg_DamageEventTarget, udg_SET_MAX_LIFE)
call SetWidgetLife(udg_DamageEventTarget, originalHP)
call UnitAddAbility(udg_DamageEventTarget, udg_DAMAGE_TYPE_DETECTOR)
call UnitMakeAbilityPermanent(udg_DamageEventTarget, true, udg_DAMAGE_TYPE_DETECTOR)
// Calculate this resistance
set resistance = DUMMY_FACTOR*(beforeHP - afterHP)
// If the resistance was greater than 100%, return it
if resistance > 1.0 then
return resistance
else
return 1.0
endif
endfunction
function UnitHasItemOfType takes unit u, integer itemId returns integer
local integer index = 0
local item indexItem
// Check if the target has a spell damage reducing item
loop
set indexItem = UnitItemInSlot(u, index)
if ( indexItem != null ) and ( GetItemTypeId(indexItem) == itemId ) then
return index + 1
endif
set index = index + 1
exitwhen index >= bj_MAX_INVENTORY
endloop
return 0
endfunction
////////////////////////////////////////////////////////////////////////////////////
// Damage Engine
////////////////////////////////////////////////////////////////////////////////////
function AfterDamage takes nothing returns nothing
local timer time = GetExpiredTimer()
local integer id = GetHandleId(time)
local unit localSource = LoadUnitHandle(udg_h, id, 0)
local unit localTarget = LoadUnitHandle(udg_h, id, 1)
local real pureAmount = LoadReal(udg_h, id, 2)
local real amount = LoadReal(udg_h, id, 3)
local real originalHealth = LoadReal(udg_h, id, 4)
// If the damage was modified, restore units health
if originalHealth != 0.0 then
call UnitRemoveAbility(localTarget, udg_SET_MAX_LIFE)
call SetWidgetLife(localTarget, originalHealth)
endif
// Apply the desired amount of damage
if amount > 0.0 then
call DisableTrigger(udg_damageEvent)
call DealFixDamage(localSource, localTarget, amount)
call EnableTrigger(udg_damageEvent)
else
call SetWidgetLife(localTarget, originalHealth - amount)
endif
// Clean things up
call FlushChildHashtable(udg_h, id)
call FlushChildHashtable(udg_h, GetHandleId(localTarget))
call DestroyTimer(time)
set time = null
set localSource = null
set localTarget = null
endfunction
function DamageEngine takes nothing returns nothing
local timer time
local integer id
local real health
local real rawAmount
local real originalHealth
local integer targetId
local integer oldTimerId
local real oldHealth
local real oldOriginalHealth
local real oldAmount
// Set damage variables
set udg_DamageEventSource = GetEventDamageSource()
set udg_DamageEventTarget = GetTriggerUnit()
set rawAmount = GetEventDamage()
// Determine the damage type
if udg_damageType == udg_CODE and rawAmount != 0.0 then
set udg_damageType = udg_CODE
elseif rawAmount > 0.0 then
set udg_damageType = udg_PHYSICAL
elseif rawAmount < 0.0 then
set udg_damageType = udg_SPELL
else
return
endif
// Correct the damage amount
if rawAmount < 0.0 then
set udg_DamageEventAmount = -rawAmount
else
set udg_DamageEventAmount = rawAmount
endif
// Register spell reduction above 100%
if udg_SPELL_RESISTANCE_AUTO_DETECT then
set udg_DamageEventAmount = GetUnitSpellResistance(udg_DamageEventTarget)*udg_DamageEventAmount
else
if ( IsUnitType(udg_DamageEventTarget, UNIT_TYPE_ETHEREAL) and IsUnitEnemy(udg_DamageEventTarget, GetOwningPlayer(udg_DamageEventSource)) and rawAmount < 0.0 ) then
set udg_DamageEventAmount = udg_ETHEREAL_DAMAGE_FACTOR*udg_DamageEventAmount
endif
endif
// Register spell damage reducing items like runed bracers
if ( IsUnitType(udg_DamageEventTarget, UNIT_TYPE_HERO) and UnitHasItemOfType(udg_DamageEventTarget, udg_SPELL_DAMAGE_REDUCTION_ITEM) > 0 ) and rawAmount < 0.0 then
set udg_DamageEventAmount = (1 - udg_BRACERS_SPELL_DAMAGE_REDUCTION)*udg_DamageEventAmount
endif
// Save health and damage variables
if udg_damageType != udg_CODE then
call UnitRemoveAbility(udg_DamageEventTarget, udg_SET_MAX_LIFE)
endif
set udg_pureAmount = udg_DamageEventAmount
set originalHealth = GetWidgetLife(udg_DamageEventTarget)
set oldTimerId = 0
// Call damage handlers
set udg_damageEventTrigger = 1.0
set udg_damageEventTrigger = 0.0
// If the damage was modified, apply the rescue ability
if udg_DamageEventAmount != udg_pureAmount then
call UnitAddAbility(udg_DamageEventTarget, udg_SET_MAX_LIFE)
call SetWidgetLife(udg_DamageEventTarget, GetWidgetLife(udg_DamageEventTarget) + udg_pureAmount)
endif
// Check if a previous timer didn't yet expire
set targetId = GetHandleId(udg_DamageEventTarget)
set oldHealth = LoadReal(udg_h, targetId, 0)
// If this is the case, update the timer information
if oldHealth != 0.0 then
set oldTimerId = LoadInteger(udg_h, targetId, 3)
set oldOriginalHealth = LoadReal(udg_h, targetId, 2)
set oldAmount = LoadReal(udg_h, targetId, 1)
set originalHealth = oldOriginalHealth - oldAmount
call SaveReal(udg_h, oldTimerId, 4, oldOriginalHealth)
endif
// Call after damage event if damage was spell, modified, code or parallel
if ( rawAmount < 0.0 or udg_pureAmount != udg_DamageEventAmount or oldTimerId != 0 or udg_allocatedAttacks > 0 ) then
set time = CreateTimer()
set id = GetHandleId(time)
// Save handles for after damage event
call SaveUnitHandle(udg_h, id, 0, udg_DamageEventSource)
call SaveUnitHandle(udg_h, id, 1, udg_DamageEventTarget)
call SaveReal(udg_h, id, 2, udg_pureAmount)
call SaveReal(udg_h, id, 3, udg_DamageEventAmount)
call SaveReal(udg_h, id, 4, originalHealth)
// Save this extra to manage parallel damage instances
call SaveReal(udg_h, targetId, 0, GetWidgetLife(udg_DamageEventTarget))
call SaveReal(udg_h, targetId, 1, udg_DamageEventAmount)
call SaveReal(udg_h, targetId, 2, originalHealth)
call SaveInteger(udg_h, targetId, 3, id)
// Avoid healing of negative spell damage
if rawAmount < 0.0 then
call DisableTrigger(udg_damageEvent)
call DealFixDamage(udg_DamageEventSource, udg_DamageEventTarget, -rawAmount)
if ( originalHealth - udg_DamageEventAmount < udg_UNIT_MIN_LIFE ) then
call UnitRemoveAbility(udg_DamageEventTarget, udg_SET_MAX_LIFE)
call DealFixDamage(udg_DamageEventSource, udg_DamageEventTarget, udg_DamageEventAmount)
endif
call EnableTrigger(udg_damageEvent)
endif
// Guarantee unit exploding
if originalHealth - udg_DamageEventAmount < udg_UNIT_MIN_LIFE then
if rawAmount > 0.0 then
call UnitRemoveAbility(udg_DamageEventTarget, udg_SET_MAX_LIFE)
call SetWidgetLife(udg_DamageEventTarget, udg_UNIT_MIN_LIFE)
endif
endif
// Start the after damage event
call TimerStart(time, 0.0, false, function AfterDamage)
endif
// Handle allocated attacks from UnitDamageTargetEx
if udg_totalAllocs == 0 then
set udg_totalAllocs = udg_allocatedAttacks
endif
if udg_allocatedAttacks > 0 then
set udg_allocatedAttacks = udg_allocatedAttacks - 1
set udg_allocCounter = udg_allocCounter + 1
call TriggerEvaluate(udg_runAllocatedAttacks)
endif
// Reset all required variables
set udg_damageType = -1
set udg_totalAllocs = 0
set udg_allocCounter = -1
endfunction
////////////////////////////////////////////////////////////////////////////////////
// Initialization
////////////////////////////////////////////////////////////////////////////////////
function RestoreTriggers takes nothing returns nothing
local unit enumUnit = GetEnumUnit()
// Re-register units that are alive
if GetWidgetLife(enumUnit) >= udg_UNIT_MIN_LIFE then
call TriggerRegisterUnitEvent(udg_damageEvent, enumUnit, EVENT_UNIT_DAMAGED)
endif
set enumUnit = null
endfunction
function ClearMemory_Actions takes nothing returns nothing
local group g = CreateGroup()
local code c = function DamageEngine
// Reset the damage event
call GroupEnumUnitsInRect(g, bj_mapInitialPlayableArea, null)
call ResetTrigger(udg_damageEvent)
call DestroyTrigger(udg_damageEvent)
set udg_damageEvent = null
// Rebuild it then
set udg_damageEvent = CreateTrigger()
call TriggerAddCondition(udg_damageEvent, Filter(c))
call ForGroup(g, function RestoreTriggers)
// Clean things up
call DestroyGroup(g)
set g = null
set c = null
endfunction
function MapInit takes nothing returns nothing
local unit enumUnit = GetEnumUnit()
// Register units on map initialization
call UnitAddAbility(enumUnit, udg_DAMAGE_TYPE_DETECTOR)
call UnitMakeAbilityPermanent(enumUnit, true, udg_DAMAGE_TYPE_DETECTOR)
call TriggerRegisterUnitEvent(udg_damageEvent, enumUnit, EVENT_UNIT_DAMAGED)
set enumUnit = null
endfunction
function UnitEntersMap takes nothing returns nothing
local unit triggerUnit = GetTriggerUnit()
// Register units that enter the map
if ( GetUnitAbilityLevel(triggerUnit, udg_DAMAGE_TYPE_DETECTOR) < 1 ) then
call UnitAddAbility(triggerUnit, udg_DAMAGE_TYPE_DETECTOR)
call UnitMakeAbilityPermanent(triggerUnit, true, udg_DAMAGE_TYPE_DETECTOR)
call TriggerRegisterUnitEvent(udg_damageEvent, triggerUnit, EVENT_UNIT_DAMAGED)
endif
set triggerUnit = null
endfunction
function RunAllocatedAttacks takes nothing returns nothing
local integer localAllocAttacks = udg_allocatedAttacks + 1
// Calculate the correct sequence of allocated attacks
set localAllocAttacks = localAllocAttacks - udg_totalAllocs + 1 + 2*udg_allocCounter
// Deal code damage if the unit isn't exploding
set udg_damageType = udg_CODE
if GetUnitLife(LoadUnitHandle(udg_h, localAllocAttacks, 1)) >= udg_UNIT_MIN_LIFE then
call UnitDamageTarget(LoadUnitHandle(udg_h, localAllocAttacks, 0), LoadUnitHandle(udg_h, localAllocAttacks, 1), LoadReal(udg_h, localAllocAttacks, 2), LoadBoolean(udg_h, localAllocAttacks, 3), LoadBoolean(udg_h, localAllocAttacks, 4), ConvertAttackType(LoadInteger(udg_h, localAllocAttacks, 5)), ConvertDamageType(LoadInteger(udg_h, localAllocAttacks, 6)), ConvertWeaponType(LoadInteger(udg_h, localAllocAttacks, 7)))
else
call FlushChildHashtable(udg_h, localAllocAttacks - 1)
endif
// Clean things up
call FlushChildHashtable(udg_h, localAllocAttacks)
endfunction
function InitTrig_DamageEven_Old takes nothing returns nothing
local group g = CreateGroup()
local region r = CreateRegion()
local trigger UnitEnters = CreateTrigger()
local trigger ClearMemory = CreateTrigger()
local code cDamageEngine = function DamageEngine
local code cUnitEnters = function UnitEntersMap
local code cClearMemory = function ClearMemory_Actions
local code cRunAllocatedAttacks = function RunAllocatedAttacks
// Initialize global variables
set udg_h = InitHashtable()
set udg_damageEvent = CreateTrigger()
set udg_damageHandler = CreateTrigger()
set udg_damageType = -1
set udg_allocatedAttacks = 0
set udg_runAllocatedAttacks = CreateTrigger()
// Initialize global configurable constants
call InitGlobalVariables()
// Initialize global fixed constants
set udg_PHYSICAL = 0
set udg_SPELL = 1
set udg_CODE = 2
set udg_UNIT_MIN_LIFE = 0.406
set udg_ATTACK_TYPE_UNIVERSAL = ConvertAttackType(7)
set udg_totalAllocs = 0
set udg_allocCounter = -1
set udg_damageEventTrigger = 0.0
// Register units on map initialization
call TriggerRegisterVariableEvent(udg_damageHandler, "damageEventTrigger", EQUAL, 1.0)
call TriggerAddCondition(udg_damageEvent, Filter(cDamageEngine))
call GroupEnumUnitsInRect(g, bj_mapInitialPlayableArea, null)
call ForGroup(g, function MapInit)
// Register units that enter the map
call RegionAddRect(r, bj_mapInitialPlayableArea)
call TriggerRegisterEnterRegion(UnitEnters, r, null)
call TriggerAddCondition(UnitEnters, Filter(cUnitEnters))
// Register trigger for allocated attacks
call TriggerAddCondition(udg_runAllocatedAttacks, Filter(cRunAllocatedAttacks))
// Clear memory leaks
call TriggerRegisterTimerEvent(ClearMemory, udg_TRIGGER_CLEANUP_PERIOD, true)
call TriggerAddCondition(ClearMemory, Filter(cClearMemory))
// Clean things up
call DestroyGroup(g)
set UnitEnters = null
set ClearMemory = null
set cDamageEngine = null
set cUnitEnters = null
set cClearMemory = null
set cRunAllocatedAttacks = null
set g = null
set r = null
endfunction