```
library ShieldSystem initializer OnInit requires /*
*/DamageEvent, /* http://www.wc3c.net/showthread.php?t=108009
*/ AutoIndex, /* http://www.wc3c.net/showthread.php?t=105643
*/ GroupUtils /* http://www.wc3c.net/showthread.php?t=104464
*/
//* ========================= Credits ==================================================*
//* Created by x-dardas *
//* Math (Equations) by Naitsirk *
//* Mui tested in garena, with Minimage *
//* Gotta credit Naitsirk again, for his help on all my systems =] *
//* ====================================================================================*
//* ========================= Introduction =============================================*
//* This system is used to create shields, like the 1 in the example. *
//* Those shields have a specific amount of life, *
//* And they take damage for the hero. *
//* When creating a shield, you also pick the damage reduction, *
//* Which reduces the damage by percents (1 - 100). *
//* This code also supports shield explosions on death. *
//* Which will cause your shield to explode for X% the damage it took *
//* In Total. (All hits togheter). *
//* ====================================================================================*
//* ========================= User Api =================================================*
//* local ShieldData shieldData = ShieldData.create(shieldWielder, string shielfSFX, *
//* real shieldMaxLife, real damageReduction, string ShieldAttachPoint) *
//* call createShield(shieldData) returns nothing *
//* call shieldData.isShieldAlive() returns boolean *
//* call shieldData.damage(real damage) returns nothing *
//* call shieldData.registerDamageEvent(ShieldTakesDamage (function interface) *
//* call shieldData.allowExplosion(real damageReduction, *
//* real explosionRange, boolexpr groupFilter) *
//* ====================================================================================*
function interface ShieldTakesDamage takes unit wielder, real shieldLifeLeft, real dealtDamage, real dealtDamageTotal returns nothing
struct ShieldData
public unit wielder
public string shieldSFX
public effect sEffect
public real shieldCurrentLife
public real shieldMaximumLife
public real damageReduction
public real currentDamage
public real damageHoldoff
public real explosionDamageReduction
public real explosionRadius
public boolexpr explosionBer
public group explosionGroup
public ShieldTakesDamage eventFunction
public static method create takes unit shieldWielder, string shieldSFX, real shieldMaxLife, real damageReduction, string shieldAttachPoint returns thistype
local thistype t = allocate()
set t.wielder = shieldWielder
set t.shieldSFX = shieldSFX
set t.shieldCurrentLife = shieldMaxLife
set t.shieldMaximumLife = shieldMaxLife
set t.damageReduction = damageReduction
set t.currentDamage = 0
set t.explosionRadius = 0
set t.sEffect = AddSpecialEffectTarget(t.shieldSFX, t.wielder, shieldAttachPoint)
set t.explosionGroup = NewGroup()
return t
endmethod
public method allowExplosion takes real explosionDamageReduction, real explosionRange, boolexpr groupFilter returns nothing
set this.explosionDamageReduction = damageReduction
set this.explosionRadius = explosionRange
set this.explosionBer = groupFilter
endmethod
public method registerDamageEvent takes ShieldTakesDamage func returns nothing
set eventFunction = func
endmethod
public method isShieldAlive takes nothing returns boolean
return .shieldCurrentLife > 0
endmethod
public method damage takes real damage returns nothing
local unit enemy = null
local real equation = 0
if isShieldAlive() then
set shieldCurrentLife = shieldCurrentLife - damage
set currentDamage = currentDamage + damage
call eventFunction.execute(wielder, shieldCurrentLife, damage, currentDamage)
if isShieldAlive() == false then
call DestroyEffect(sEffect)
//Explode It Here
call GroupEnumUnitsInArea(explosionGroup, GetUnitX(wielder), GetUnitY(wielder), explosionRadius, explosionBer)
//function GroupEnumUnitsInArea takes group whichGroup, real x, real y, real radius, boolexpr filter returns nothing
loop
set enemy = FirstOfGroup(explosionGroup)
exitwhen enemy == null
set equation = currentDamage * explosionDamageReduction / 100
call UnitDamageTarget(wielder, enemy, equation, false, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_NORMAL, null)
call GroupRemoveUnit(explosionGroup, enemy)
endloop
call ReleaseGroup(explosionGroup)
endif
endif
endmethod
endstruct
globals
public ShieldData array shieldData
endglobals
function createShield takes ShieldData data returns nothing
set shieldData[GetUnitId(data.wielder)] = data
endfunction
public function UnitUnderAttack takes unit damagedUnit, unit damageSource, real damage returns nothing
local integer count = 0
local real equation = 0
set count = GetUnitId(damagedUnit)
if shieldData[count].isShieldAlive() then
set equation = damage * shieldData[count].damageReduction / 100
call shieldData[count].damage(equation)
call SetWidgetLife(damagedUnit, GetWidgetLife(damagedUnit) + equation)
endif
endfunction
public function OnInit takes nothing returns nothing
call RegisterDamageResponse(UnitUnderAttack)
endfunction
endlibrary
```