Name | Type | is_array | initial_value |
//TESH.scrollpos=0
//TESH.alwaysfold=0
scope CruelEvasion initializer Init
//Cruel Evasion by The_Witcher
//
// requires my Stun System
//
// the unit has a chance to evade an attack, blink behind the attacker, hit him critical and stun him.
//
// The SETUP part
globals
// The rawcode of your ability
private constant integer AbiID = 'A000'
// The effect created at the target loc
private constant string BlinkTargetSFX = "Abilities\\Spells\\NightElf\\Blink\\BlinkTarget.mdl"
// The effect created at the caster loc
private constant string BlinkCasterSFX = "Abilities\\Spells\\NightElf\\Blink\\BlinkCaster.mdl"
// If ranged is false only attacks from nearer then 200 will fire the effect
private boolean ranged = true
endglobals
private function GetEvasionPercentage takes integer level returns real
return 0.2 * level //20% on level 1, 40% on level 2, 60% on level 3,...
endfunction
private function GetDamage takes integer level returns real
return 100 + 50 * I2R(level) //150 on level 1, 200 level 2, 250 level 3,...
endfunction
private function GetStunTime takes integer level returns real
return 1 + 1 * I2R(level) //2sec on level 1, 3sec level 2, 4sec level 3,...
endfunction
// END OF SETUP PART
private function DistanceBetweenUnits takes unit a, unit b returns real
local real dx = GetUnitX(b) - GetUnitX(a)
local real dy = GetUnitY(b) - GetUnitY(a)
return SquareRoot(dx * dx + dy * dy)
endfunction
private function check takes nothing returns boolean
local unit a = GetTriggerUnit()
local unit b = GetAttacker()
local integer lvl = GetUnitAbilityLevel(a,AbiID)
local real time = GetStunTime(lvl)
local real p = GetEvasionPercentage(lvl)
local real dmg = GetDamage(lvl)
local real x = GetUnitX(b) + 100 * Cos((GetUnitFacing(b)-180) *bj_DEGTORAD)
local real y = GetUnitY(b) + 100 * Sin((GetUnitFacing(b)-180) *bj_DEGTORAD)
local real rp = GetRandomReal(0,1)
local boolean bool = DistanceBetweenUnits(a,b) < 200
if ranged then
set bool = true
endif
if lvl > 0 and rp > (1-p) and bool then
call DestroyEffect(AddSpecialEffect(BlinkCasterSFX,GetUnitX(a),GetUnitY(a)))
call DestroyEffect(AddSpecialEffect(BlinkTargetSFX,x,y))
call SetUnitPosition(a,x,y)
call SetUnitFacing(a,GetUnitFacing(b))
call StunUnit(b,time)
call UnitDamageTarget(a,b,dmg,true,false,ATTACK_TYPE_NORMAL,DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS)
call SetUnitAnimation(a,"attack")
endif
set a = null
set b = null
return false
endfunction
private function Init takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_ATTACKED )
call TriggerAddCondition(t,Condition(function check))
endfunction
endscope
//TESH.scrollpos=0
//TESH.alwaysfold=0
library StunSystem
//Setup
globals
// this is the special effect created on a stunned unit
private string sfx = "Abilities\\Spells\\Human\\Thunderclap\\ThunderclapTarget.mdl"
// this is the attachement point for sfx
private string AttachPoint = "overhead"
endglobals
//End of setup
private struct data
unit u
real t
effect sfx
endstruct
globals
private data array StunnedUnits
private integer total=0
private timer tim = CreateTimer()
endglobals
private function Stun takes nothing returns nothing
local integer i = 0
local data dat
loop
exitwhen i >= total
set dat = StunnedUnits[i]
if dat.t <= 0 or IsUnitType(dat.u,UNIT_TYPE_DEAD) then
call DestroyEffect(dat.sfx)
set total = total-1
set StunnedUnits[i] = StunnedUnits[total]
call dat.destroy()
set i = i - 1
else
set dat.t = dat.t - 0.01
call SetUnitPosition(dat.u,GetUnitX(dat.u),GetUnitY(dat.u))
endif
set i = i + 1
endloop
if total == 0 then
call PauseTimer(tim)
endif
endfunction
function StunUnit takes unit u,real time returns nothing
local data dat = data.create()
set dat.t = time
set dat.u = u
set dat.sfx = AddSpecialEffectTarget(sfx,u,AttachPoint)
if total == 0 then
call TimerStart(tim,0.01,true,function Stun)
endif
set StunnedUnits[total]=dat
set total = total + 1
endfunction
endlibrary