//TESH.scrollpos=337
//TESH.alwaysfold=0
function SaveLoad_InitialSetup takes nothing returns nothing
local integer i = 0
local integer j = 0
loop
set udg_SaveLoad_Compress[i + 48] = j
set udg_SaveLoad_Uncompress[i] = i + 48
set j = j + 1
set i = i + 1
exitwhen i >= 10
endloop
set i = 0
loop
set udg_SaveLoad_Compress[i + 97] = j
set udg_SaveLoad_Compress[i + 65] = j + 26
set udg_SaveLoad_Uncompress[i + 10] = i + 97
set udg_SaveLoad_Uncompress[i + 26 + 10] = i + 65
set j = j + 1
set i = i + 1
exitwhen i >= 26
endloop
endfunction
function SaveLoad_Id2CId takes integer n returns integer
local integer i = n / (256 * 256 * 256)
local integer r
set n = n - i * (256 * 256 * 256)
set r = udg_SaveLoad_Compress[i]
set i = n / (256 * 256)
set n = n - i * (256 * 256)
set r = r * 64 + udg_SaveLoad_Compress[i]
set i = n / 256
set r = r * 64 + udg_SaveLoad_Compress[i]
return r * 64 + udg_SaveLoad_Compress[n - i * 256]
endfunction
function SaveLoad_CId2Id takes integer n returns integer
local integer i = n / (64 * 64 * 64)
local integer r
set n = n - i * (64 * 64 * 64)
set r = udg_SaveLoad_Uncompress[i]
set i = n / (64 * 64)
set n = n - i * (64 * 64)
set r = r * 256 + udg_SaveLoad_Uncompress[i]
set i = n / 64
set r = r * 256 + udg_SaveLoad_Uncompress[i]
return r * 256 + udg_SaveLoad_Uncompress[n - i * 64]
endfunction
function SaveLoad_Unit2Integer takes unit u returns integer
local integer i = 0
local integer n = GetUnitTypeId(u)
if udg_SaveLoad_Initialized == false then
set udg_SaveLoad_Initialized = true
call SaveLoad_InitialSetup()
endif
loop
set i = i + 1
exitwhen i > udg_SaveLoad_Heroes_LastIndex
if udg_SaveLoad_Heroes[i] == n then
return i
endif
endloop
return SaveLoad_Id2CId(n)
endfunction
function SaveLoad_Integer2Unit takes integer i returns integer
if udg_SaveLoad_Initialized == false then
set udg_SaveLoad_Initialized = true
call SaveLoad_InitialSetup()
endif
if i <= udg_SaveLoad_Heroes_LastIndex then
return udg_SaveLoad_Heroes[i]
endif
return SaveLoad_CId2Id(i)
endfunction
function SaveLoad_Item2Integer takes item t returns integer
local integer i = 0
local integer n = GetItemTypeId(t)
if udg_SaveLoad_Initialized == false then
set udg_SaveLoad_Initialized = true
call SaveLoad_InitialSetup()
endif
loop
set i = i + 1
exitwhen i > udg_SaveLoad_Items_LastIndex
if udg_SaveLoad_Items[i] == n then
return i
endif
endloop
return SaveLoad_Id2CId(n)
endfunction
function SaveLoad_Integer2Item takes integer i returns integer
if udg_SaveLoad_Initialized == false then
set udg_SaveLoad_Initialized = true
call SaveLoad_InitialSetup()
endif
if i <= udg_SaveLoad_Items_LastIndex then
return udg_SaveLoad_Items[i]
endif
return SaveLoad_CId2Id(i)
endfunction
function SaveLoad_Ability2Integer takes integer a returns integer
local integer i = 0
if udg_SaveLoad_Initialized == false then
set udg_SaveLoad_Initialized = true
call SaveLoad_InitialSetup()
endif
loop
set i = i + 1
exitwhen i > udg_SaveLoad_Abilities_LastIndex
if udg_SaveLoad_Abilities[i] == a then
return i
endif
endloop
return SaveLoad_Id2CId(a)
endfunction
function SaveLoad_Integer2Ability takes integer i returns integer
if udg_SaveLoad_Initialized == false then
set udg_SaveLoad_Initialized = true
call SaveLoad_InitialSetup()
endif
if i <= udg_SaveLoad_Abilities_LastIndex then
return udg_SaveLoad_Abilities[i]
endif
return SaveLoad_CId2Id(i)
endfunction
function SaveLoad_Color takes string s returns string
local integer i = StringLength(s)
local string c
local string r = ""
loop
set i = i - 1
set c = SubString(s,i,i + 1)
if c == "0" or c == "1" or c == "2" or c == "3" or c == "4" or c == "5" or c == "6" or c == "7" or c == "8" or c == "9" then
set r = "|cffffcc00" + c + "|r" + r
elseif c == "-" then
set r = "|cffdddddd-|r" + r
else
set r = c + r
endif
exitwhen i <= 0
endloop
return r
endfunction
function SaveLoad_EncodeChar takes string n returns integer
local integer i = 0
local string s1 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
local string s2 = "abcdefghijklmnopqrstuvwxyz"
local string s3 = "0123456789"
loop
if SubString(s1,i,i + 1) == n then
return i
endif
if SubString(s2,i,i + 1) == n then
return i
endif
set i = i + 1
exitwhen i >= 26
endloop
set i = 0
loop
if SubString(s3,i,i + 1) == n then
return i
endif
set i = i + 1
exitwhen i >= 10
endloop
return 0
endfunction
function SaveLoad_EncodeVerify takes string buffer returns integer
local integer i = 0
local integer j = 0
local string name = GetPlayerName(GetTriggerPlayer())
if udg_SaveLoad_UsePlayername == true then
loop
set j = j + SaveLoad_EncodeChar(SubString(name,i,i + 1))
set i = i + 1
exitwhen i >= StringLength(name)
endloop
endif
set i = 0
loop
set j = j + SaveLoad_EncodeChar(SubString(buffer,i,i + 1))
set i = i + 1
exitwhen i >= StringLength(buffer)
endloop
return j
endfunction
function SaveLoad_EncodeValues takes nothing returns string
local integer i
local integer j
local integer k
local integer l
local integer m
local integer CodeLength = StringLength(udg_SaveLoad_Alphabet)
local integer array a
local string buffer = ""
local string c = ""
local integer skip = 0
local integer CONST = 1000000
local string abc = "0123456789"
set i = 0
loop
set i = i + 1
exitwhen i > udg_SaveCount
set buffer = buffer + I2S(udg_Save[i]) + "-"
endloop
set buffer = buffer + I2S(SaveLoad_EncodeVerify(buffer))
if udg_Save[1] == 0 then
set buffer = "-" + buffer
endif
set i = 0
loop
set a[i] = 0
set i = i + 1
exitwhen i >= 100
endloop
set m = 0
set i = 0
loop
set j = 0
loop
set a[j] = a[j] * 11
set j = j + 1
exitwhen j > m
endloop
set l = 0
set c = SubString(buffer,i,i + 1)
loop
exitwhen SubString(abc,l,l + 1) == c
set l = l + 1
exitwhen l > 9
endloop
set a[0] = a[0] + l
set j = 0
loop
set k = a[j] / CONST
set a[j] = a[j] - k * CONST
set a[j + 1] = a[j + 1] + k
set j = j + 1
exitwhen j > m
endloop
if k > 0 then
set m = m + 1
endif
set i = i + 1
exitwhen i >= StringLength(buffer)
endloop
set buffer = ""
loop
exitwhen m < 0
set j = m
loop
exitwhen j <= 0
set k = a[j] / CodeLength
set a[j - 1] = a[j - 1] + (a[j] - k * CodeLength) * CONST
set a[j] = k
set j = j - 1
endloop
set k = a[j] / CodeLength
set i = a[j] - k * CodeLength
set buffer = buffer + SubString(udg_SaveLoad_Alphabet,i,i + 1)
set a[j] = k
if a[m] == 0 then
set m = m - 1
endif
endloop
set i = StringLength(buffer)
set skip = 0
set c = ""
loop
set i = i - 1
set c = c + SubString(buffer,i,i + 1)
set skip = skip + 1
if skip == 4 and i > 0 then
set c = c + "-"
set skip = 0
endif
exitwhen i <= 0
endloop
return c
endfunction
function SaveLoad_DecodeValues takes string s returns boolean
local integer i
local integer j
local integer k
local integer l
local integer SaveCode = 0
local integer m
local integer array a
local string buffer = ""
local integer CodeLength = StringLength(udg_SaveLoad_Alphabet)
local integer skip = -1
local integer CONST = 1000000
local string abc = "0123456789-"
local string c
set i = 0
loop
set a[i] = 0
set i = i + 1
exitwhen i >= 100
endloop
set m = 0
set i = 0
loop
set j = 0
loop
set a[j] = a[j] * CodeLength
set j = j + 1
exitwhen j > m
endloop
set skip = skip + 1
if skip == 4 then
set skip = 0
set i = i + 1
endif
set l = CodeLength
set c = SubString(s,i,i + 1)
loop
set l = l - 1
exitwhen l < 1
exitwhen SubString(udg_SaveLoad_Alphabet,l,l + 1) == c
endloop
set a[0] = a[0] + l
set j = 0
loop
set k = a[j] / CONST
set a[j] = a[j] - k * CONST
set a[j + 1] = a[j + 1] + k
set j = j + 1
exitwhen j > m
endloop
if k > 0 then
set m = m + 1
endif
set i = i + 1
exitwhen i >= StringLength(s)
endloop
loop
exitwhen m < 0
set j = m
loop
exitwhen j <= 0
set k = a[j] / 11
set a[j - 1] = a[j - 1] + (a[j] - k * 11) * CONST
set a[j] = k
set j = j - 1
endloop
set k = a[j] / 11
set i = a[j] - k * 11
set buffer = SubString(abc,i,i + 1) + buffer
set a[j] = k
if a[m] == 0 then
set m = m - 1
endif
endloop
set i = 0
set j = 0
loop
loop
exitwhen i >= StringLength(buffer)
exitwhen i > 0 and SubString(buffer,i,i + 1) == "-" and SubString(buffer,i - 1,i) != "-"
set i = i + 1
endloop
if i < StringLength(buffer) then
set k = i
endif
set SaveCode = SaveCode + 1
set udg_Save[SaveCode] = S2I(SubString(buffer,j,i))
set j = i + 1
set i = i + 1
exitwhen i >= StringLength(buffer)
endloop
set j = SaveLoad_EncodeVerify(SubString(buffer,0,k))
set udg_SaveCount = SaveCode - 1
if j == udg_Save[SaveCode] then
return true
endif
return false
endfunction
function SaveLoad_Encode takes nothing returns string
if udg_SaveLoad_CaseSensitive == false then
set udg_SaveLoad_Alphabet = StringCase(udg_SaveLoad_Alphabet,true)
endif
return SaveLoad_Color(SaveLoad_EncodeValues())
endfunction
function SaveLoad_Decode takes string s returns boolean
if udg_SaveLoad_CaseSensitive == false then
set udg_SaveLoad_Alphabet = StringCase(udg_SaveLoad_Alphabet,true)
set s = StringCase(s,true)
endif
if SaveLoad_DecodeValues(s) then
call DisplayTextToPlayer(GetTriggerPlayer(),0,0,"Decoding sucessful")
return true
endif
call DisplayTextToPlayer(GetTriggerPlayer(),0,0,"Decoding failed")
return false
endfunction
//=============================================
function DebugError takes player ForPlayer, string msg returns nothing
local sound error=CreateSoundFromLabel("InterfaceError",false,false,false,10,10)
if (GetLocalPlayer() == ForPlayer) then
if (msg!="") and (msg!=null) then
call ClearTextMessages()
call DisplayTimedTextToPlayer(ForPlayer, 0.85, 0., 2.00, "|cffffcc00"+msg+"|r")
endif
call StartSound(error)
endif
call KillSoundWhenDone(error)
set error=null
endfunction
//=============================================
function Refresh takes unit u returns nothing
call SetUnitLifePercentBJ(u,100.0)
call SetUnitManaPercentBJ(u,100.0)
call UnitResetCooldown(u)
call SetHeroLevelBJ( u, ( GetHeroLevel(u) + 10 ), false )
endfunction
//====================================================
//Remove Location
function rl takes location l returns nothing
call RemoveLocation(l)
set l = null
endfunction
//=============================================
//Destroy Group
function dg takes group g returns nothing
call DestroyGroup(g)
set g = null
endfunction
//=============================================
//Destroy Effect
function de takes effect e returns nothing
call DestroyEffect(e)
set e = null
endfunction
Name | Type | is_array | initial_value |
A | integervar | No | |
AfterDamageEvent | real | No | |
AlreadyInScreen | boolean | Yes | |
AMSAmount | real | Yes | |
Angle | real | No | |
AOEDamageEvent | real | No | |
AOEString | string | No | |
B | integervar | No | |
bagUnitType | unitcode | No | |
bagZoneLoc | location | Yes | |
bagZoneRect | rect | Yes | |
C | integervar | No | |
cage | destructablecode | No | LOcg |
Camera_Distance | real | No | |
CamView | camerasetup | Yes | |
CleanedItem | item | Yes | |
ClearDamageEvent | trigger | No | |
Code | string | No | |
Conjurador | unit | No | |
ContadorResets | integer | Yes | |
CR_Angle | real | Yes | |
CR_Integer | integer | No | |
CR_Point | location | Yes | |
CR_Temp_Unit_Group | group | No | |
CR_Type | unitcode | Yes | |
Creep_Face_Ang | real | Yes | |
Creep_Loc | location | Yes | |
D | integervar | No | |
DAMAGE_FACTOR_BRACERS | real | No | |
DAMAGE_FACTOR_ELUNES | real | No | |
DAMAGE_FACTOR_ETHEREAL | real | No | |
DamageBlockingAbility | abilcode | No | |
DamageEvent | real | 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 | |
DamageEventType | integer | No | |
DamageModifierEvent | real | 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 | |
Deaths | integer | Yes | |
DialogRace | dialog | No | |
DialogRaceButton | button | Yes | |
DmgEvBracers | itemcode | No | |
DmgEvLife | real | No | |
DmgEvMana | real | No | |
DmgEvManaMult | real | No | |
DmgEvMSlvl | integer | 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 | |
Dummy | unit | No | |
Dummy_Unit_Wave | group | No | |
E | integervar | No | |
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 | |
EmptySlot | destructable | Yes | |
EnhancedDamageTarget | unit | No | |
Entregarcarta | trigger | No | |
F | integervar | No | |
FactorCleared | boolean | Yes | |
Gold | integer | No | |
Hero | integer | No | |
Heroes | unit | Yes | |
HeroIV | unit | Yes | |
HideDamageFrom | boolean | Yes | |
IconType | destructablecode | No | |
Ingredients | integer | No | |
Integer | integer | No | |
integer | integer | No | 1 |
InvCam | camerasetup | Yes | |
IsDamageSpell | boolean | No | |
ItemBoard | multiboard | Yes | |
ItemCleanupFlag | boolean | No | |
ItemCleanupTimer | timer | No | |
ItemHA1 | abilcode | Yes | |
ItemHA2 | abilcode | Yes | |
ItemHelmet | destructablecode | Yes | |
ItemHName | string | Yes | |
ItemHString | string | Yes | |
ItemInSelection | destructable | Yes | |
ItemRA1 | abilcode | Yes | |
ItemRA2 | abilcode | Yes | |
ItemRing | destructablecode | Yes | |
ItemRName | string | Yes | |
ItemRString | string | Yes | |
Items | itemcode | Yes | |
ItemShiA1 | abilcode | Yes | |
ItemShiA2 | abilcode | Yes | |
ItemShield | destructablecode | Yes | |
ItemShiName | string | Yes | |
ItemShiString | string | Yes | |
ItemShoA1 | abilcode | Yes | |
ItemShoA2 | abilcode | Yes | |
ItemShoulder | destructablecode | Yes | |
ItemShoulName | string | Yes | |
ItemShoulString | string | Yes | |
ItemsToClean | integer | No | |
ItemTA1 | abilcode | Yes | |
ItemTA2 | abilcode | Yes | |
ItemTName | string | Yes | |
ItemTorso | destructablecode | Yes | |
ItemTString | string | Yes | |
ItemTypeHelmet | itemcode | Yes | |
ItemTypeRing | itemcode | Yes | |
ItemTypeShield | itemcode | Yes | |
ItemTypeShoulder | itemcode | Yes | |
ItemTypeTorso | itemcode | Yes | |
ItemTypeWeapon | itemcode | Yes | |
ItemWA1 | abilcode | Yes | |
ItemWA2 | abilcode | Yes | |
ItemWeapon | destructablecode | Yes | |
ItemWName | string | Yes | |
ItemWString | string | Yes | |
Kill_Count | integer | Yes | |
KillingEnforcer | integer | No | 0 |
Kills | integer | No | |
KoboldCounter | integer | No | |
LastDamageHP | real | No | |
LastDmgPrevAmount | real | Yes | |
LastDmgPrevType | integer | Yes | |
LastDmgSource | unit | Yes | |
LastDmgTarget | unit | Yes | |
LastDmgValue | real | Yes | |
LastDmgWasSpell | boolean | Yes | |
LevelLumber | integer | No | |
Lobo | unitcode | Yes | n000 |
Loop | integervar | No | |
Mineral_Rock | itemcode | Yes | |
Mision_Completa | boolean | Yes | |
Mision_Descripcion | string | Yes | |
Mision_Ganado | string | Yes | |
Mision_Icono | string | Yes | |
Mision_Index | integer | No | |
Mision_Kills | integer | Yes | |
Mision_Mision | quest | Yes | |
Mision_NombreUni | string | Yes | |
Mision_OnOff | boolean | Yes | |
Mision_Player | player | Yes | |
Mision_RecibeInmediato | boolean | Yes | |
Mision_Recompensa_Cash | integer | Yes | |
Mision_Recompensa_Exp | integer | Yes | |
Mision_Recompensa_Items | itemcode | Yes | |
Mision_Recompensa_Madera | integer | Yes | |
Mision_Titulo | string | Yes | |
Mision_Total | integer | No | |
Mision_Unidad | unit | Yes | |
Mision_UnidadType | unitcode | Yes | |
Multi | multiboard | No | |
Murloc_Loc | location | No | |
NextDamageOverride | boolean | No | |
NextDamageType | integer | No | |
Occupied | boolean | Yes | |
OurQuest | string | Yes | notstarted |
OurQuest_Copy | string | Yes | notstarted |
PETDummy | unit | Yes | |
PETGroup | group | No | |
PETOwner | unit | No | |
PETOwnerLoc | location | No | |
Player | player | No | |
Player_Dificulty | integer | No | |
PlayerNumber | integer | No | |
PointsPlayer1 | integer | No | |
PointsPlayer2 | integer | No | |
PointsPlayer3 | integer | No | |
PointsPlayer4 | integer | No | |
PointsPlayer5 | integer | No | |
PointsPlayer6 | integer | No | |
Portaocidade | boolean | No | false |
Portaocidade_Copy | boolean | No | false |
Pos | location | Yes | |
Position | location | No | |
PotionsFilled | integer | Yes | |
Power_Slam_Ability_Level | integer | No | |
Power_Slam_Base_Chance | real | No | |
Power_Slam_Caster | unit | No | |
Power_Slam_Damage | real | No | |
Power_Slam_Damage_Multiplier | real | No | |
Power_Slam_Dummy_Ability | abilcode | No | |
Power_Slam_Location | location | No | |
Power_Slam_Owner | player | No | |
Power_Slam_Strength | integer | No | |
Power_Slam_Target | unit | No | |
Power_Slam_Total_Chance | real | No | |
PreviousLevel | integer | Yes | |
Random | integer | No | |
RecipeFactor | itemcode | Yes | |
Resets | integer | No | |
Roots_Point | location | No | |
Roots_Units | group | No | |
Save | integer | Yes | |
SaveCount | integer | No | |
SaveLoad_Abilities | abilcode | Yes | |
SaveLoad_Abilities_LastIndex | integer | No | |
SaveLoad_Alphabet | string | No | |
SaveLoad_CaseSensitive | boolean | No | |
SaveLoad_Compress | integer | Yes | |
SaveLoad_Heroes | unitcode | Yes | |
SaveLoad_Heroes_LastIndex | integer | No | |
SaveLoad_Initialized | boolean | No | |
SaveLoad_Items | itemcode | Yes | |
SaveLoad_Items_LastIndex | integer | No | |
SaveLoad_Uncompress | integer | Yes | |
SaveLoad_UsePlayername | boolean | No | |
Selection | group | Yes | |
SelectionCircle | destructable | Yes | |
SkillArea | group | No | |
SlotInt | integer | No | |
SlotsFilled | integer | Yes | |
SpellDamageAbility | abilcode | No | |
temp_cast_point | location | No | |
temp_group | group | No | |
temp_lightning | lightning | Yes | |
temp_point | location | No | |
Temp_Unit | unit | No | |
TempDes | destructable | No | |
TempGroup | group | No | |
TempInt | integer | No | |
TempItem | item | No | |
TempItemType | itemcode | No | |
TempPlayers | force | No | |
TempPoint | location | No | |
tempRect | rect | No | |
TempUnit | unit | No | |
tempUnit | unit | No | |
TempUnitType | unitcode | No | |
teste | quest | Yes | |
teste1 | questitem | Yes | |
UDex | integer | No | |
UDexGen | integer | No | |
UDexNext | integer | Yes | |
UDexPrev | integer | Yes | |
UDexRecycle | integer | No | |
UDexUnits | unit | Yes | |
UDexWasted | integer | No | |
UnitDamageRegistered | boolean | Yes | |
UnitGroup | group | No | |
UnitIndexerEnabled | boolean | No | |
UnitIndexEvent | real | No | |
UnitIndexLock | integer | Yes | |
UnitMoving | boolean | Yes | |
Validate | boolean | No | |
Victima | unit | No | |
Vis | fogmodifier | Yes | |
Visibility | rect | Yes | |
Wolf_ExtraDmg | integer | No | |
Wolf_HundDigit | integer | No | |
Wolf_Lvl | integer | No | |
Wolf_OnesDigit | integer | No | |
Wolf_Summoner | unit | No | |
Wolf_TensDigit | integer | No | |
Wolf_ThouDigit | integer | No | |
Wolf_Unit | unit | No |
//TESH.scrollpos=150
//TESH.alwaysfold=0
//===========================================================================
// 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