library PsyKeeperHorror initializer OnInit
globals
//configurables
private constant integer ABILITY_RAW = 'A000'
// raw of the ability.
private constant real BaseDamage = 100
// base damage of the skill. before all changes.
private constant boolean MultiplyDamage = true
// asks if you want to multiply damage every level of ability.
private constant real MultiplyDamageBy = 2
// if boolean above is true, multiply by?
// math is:
//BaseDamage * (GetUnitAbilityLevel(caster, Horror) * MultiplyDamageBy)
private constant real BaseDamageAoe = 150
// how much does the spell damage per unit in aoe. (maximum)
private constant boolean MultiplyAoeDamage = true
private constant real MultiplyAoeDamageBy = 2
// same as damage, just aoedamage.
private constant real SpellReachedUnitsAoe = 150
// aoe that damages units withing.
// stun unit math from your words:
//The target then get's paused for [(Spell level * Target level) / 100] seconds, then it get’s unpaused.
// based by: Spell level * unit level / 100 = stun duration.
// Example: 1 * 1 / 100 = 0.01
// Example: 5 * 7 / 100 = 0.35 (thats what could happend. i reccomand lowering the math >.>
// level 5 spell * level 7 unit = abuse.
// Example: 10(spell level) * 20(unit level) = 1
// 1 second stun, when hero is level 20. and i guess your game has 45 levels,
// which ends up by:
// 10 * 45 / 100 = 4.5 seconds!
// thats enought to kill 5 units at that level.
private constant real DownBy = 100 // this represents the X * Y / ||DownBy||(100 atm).
// the 100 seconds, so basicly, if you increase, stun duration gets lowered, if you decrease, stun duration get increased.
// defaults - for damaging units -
private constant boolean ATTACK_DEFAULT = false
private constant boolean RANGED_DEFAULT = false
private constant attacktype ATTACK_TYPE_DEFAULT = ATTACK_TYPE_NORMAL
private constant damagetype DAMAGE_TYPE_DEFAULT = DAMAGE_TYPE_NORMAL
private constant weapontype WEAPON_TYPE_DEFAULT = WEAPON_TYPE_WHOKNOWS
private constant boolean ATTACK_DEFAULT_AOE = false
private constant boolean RANGED_DEFAULT_AOE = false
private constant attacktype ATTACK_TYPE_DEFAULT_AOE = ATTACK_TYPE_NORMAL
private constant damagetype DAMAGE_TYPE_DEFAULT_AOE = DAMAGE_TYPE_NORMAL
private constant weapontype WEAPON_TYPE_DEFAULT_AOE = WEAPON_TYPE_WHOKNOWS
//---------
private constant string StunModelPath = "Abilities\\Spells\\Human\\Thunderclap\\ThunderclapTarget.mdl"
// the path of the model to stun the hero, since i use a custom made stun.
private constant string StunModelAttachmentPoint = "overhead"
// attach the path above to the "overhead" of the human
// just like a regular stun effect.
//dont touch below
//------- Arrays
private unit array Caster
private unit array Target
private real array Duration
private real array aoedamage
private effect array stunEffect
//------- Non Arrays
private integer Count = 0
private integer Count2 = 0
//-------------------
endglobals
private function OnLoop takes nothing returns nothing
local integer c = 0
if Count != 0 then
loop
set c = c + 1
if Duration[c] >= 1 then
set Duration[c] = Duration[c] - 0.032
else
call PauseUnit(Target[c], false)
set Target[c] = null
set Duration[c] = 0
call DestroyEffect(stunEffect[c])
set stunEffect[c] = null
set Count2 = Count2 - 1
if Count2 == 0 then
set Count = 0
set Count2 = 0
endif
endif
exitwhen c == Count
endloop
endif
endfunction
private function UNIT_IS_ALIVE takes nothing returns boolean
return GetWidgetLife(GetFilterUnit()) > 0.405
endfunction
private function GroupCall takes nothing returns nothing
local unit t = GetEnumUnit()
local player p = GetOwningPlayer(Caster[Count])
if t != Target[Count] and IsUnitEnemy(t, p) then
call UnitDamageTarget(Caster[Count], t, aoedamage[Count], ATTACK_DEFAULT_AOE, RANGED_DEFAULT_AOE, ATTACK_TYPE_DEFAULT_AOE, DAMAGE_TYPE_DEFAULT_AOE, WEAPON_TYPE_DEFAULT_AOE)
endif
set p = null
set t = null
endfunction
private function OnCast takes nothing returns nothing
local real damage = 0
local group AoeG = CreateGroup()
local boolexpr UNIT_IS_ALIVE_BER = Condition(function UNIT_IS_ALIVE)
set Count = Count + 1
set Count2 = Count2 + 1
set Target[Count] = GetSpellTargetUnit()
set Caster[Count] = GetTriggerUnit()
if MultiplyDamage == true then
set damage = BaseDamage * (GetUnitAbilityLevel(Caster[Count], ABILITY_RAW) * MultiplyDamageBy)
else
set damage = BaseDamage
endif
if MultiplyAoeDamage == true then
set aoedamage[Count] = BaseDamageAoe * (GetUnitAbilityLevel(Caster[Count], ABILITY_RAW) * MultiplyAoeDamageBy)
else
set aoedamage[Count] = BaseDamageAoe
endif
set Duration[Count] = (GetUnitAbilityLevel(Caster[Count], ABILITY_RAW) * GetUnitLevel(Target[Count])) / DownBy
//dont touch below
call PauseUnit(Target[Count], true)
call ResetUnitAnimation(Target[Count])
call IssueImmediateOrder(Target[Count], "stop")
set stunEffect[Count] = AddSpecialEffectTarget(StunModelPath, Target[Count], StunModelAttachmentPoint)
call UnitDamageTarget(Caster[Count], Target[Count], damage, ATTACK_DEFAULT, RANGED_DEFAULT, ATTACK_TYPE_DEFAULT, DAMAGE_TYPE_DEFAULT, WEAPON_TYPE_DEFAULT)
call GroupEnumUnitsInRange(AoeG, GetUnitX(Target[Count]), GetUnitY(Target[Count]), SpellReachedUnitsAoe, UNIT_IS_ALIVE_BER)
call ForGroup(AoeG, function GroupCall)
call DestroyGroup(AoeG)
call DestroyBoolExpr(UNIT_IS_ALIVE_BER)
set Caster[Count] = null
//---------------------------------
endfunction
private function OnCond takes nothing returns boolean
return GetSpellAbilityId() == ABILITY_RAW
endfunction
private function OnInit takes nothing returns nothing
local trigger DM = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(DM, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(DM, Condition(function OnCond))
call TriggerAddAction(DM, function OnCast)
call TimerStart(CreateTimer(), 0.032, true, function OnLoop)
set DM = null
endfunction
endlibrary