scope ReversalStance
globals
private constant integer AID = 'A000' //Rawcode of the reversal stance ability
private constant integer OID = 852600 //Order ID while reversal stance is active
private constant real DISTANCE = 1500. //Distance the shockwave travels
private constant real MISSILE_COLLISION = 200. //Collision radius of the shockwave
private constant real MISSILE_FX_SCALE = 4.0 //Scale of the shockwave model
private constant string COUNTER_FX_PATH = "Abilities\\Spells\\Human\\Defend\\DefendCaster.mdl" //Effect to play when an attack is countered
private constant string MISSILE_FX_PATH = "Abilities\\Weapons\\GargoyleMissile\\GargoyleMissile.mdl" //Shockwave model
private constant string ANIMATION = "attack slam" //Animation to play when an attack is countered
private constant boolean SINGLE_COUNTER = true //Should the stance stop after countering an attack?
private constant boolean FACE_ATTACKER = true //Should the caster turn to face the attacker when the counter occurs?
private constant real ANIM_DURATION = 2.0 //Duration to play the counter animation
endglobals
private struct Missile extends Missiles
private timer timer
private unit caster
private boolean animresetphase
private static method CounterCondition takes nothing returns boolean
//Adjust your counter condition here. Freel free to modify
if not udg_IsDamageAttack or GetUnitAbilityLevel(udg_DamageEventTarget, AID) == 0 or GetUnitCurrentOrder(udg_DamageEventTarget)!=OID then
return false
endif
if IsUnitPaused(udg_DamageEventTarget) then
return false
endif
return IsUnitType(udg_DamageEventSource,UNIT_TYPE_HERO)
endmethod
private static method DamageFormula takes nothing returns real
return udg_DamageEventAmount * 3 //configure your damage formula here
endmethod
method onFinish takes nothing returns boolean
return true
endmethod
method onHit takes unit hit returns boolean
if not IsUnitType(hit,UNIT_TYPE_STRUCTURE) and hit != .source and IsUnitEnemy(hit, .owner) and not BlzIsUnitInvulnerable(hit) and UnitAlive(hit) then
call UnitDamageTarget(.source, hit, damage, true, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_UNIVERSAL, null)
endif
return false
endmethod
private static method onTimerExpire takes nothing returns nothing
local thistype this = GetTimerData(GetExpiredTimer())
if not animresetphase then
set animresetphase = true
call BlzUnitDisableAbility(caster,AID,false,false)
call SetUnitAnimation(caster,ANIMATION)
call TimerStart(timer, ANIM_DURATION, false, function thistype.onTimerExpire)
else
call ResetUnitAnimation(caster)
call ReleaseTimer(timer)
call deallocate()
set caster = null
set timer = null
endif
endmethod
static method CounterAction takes nothing returns nothing
local unit c = udg_DamageEventTarget
local unit t = udg_DamageEventSource
local real x = GetUnitX(c)
local real y = GetUnitY(c)
local real z = GetUnitFlyHeight(c) + 50
local real angle = AngleBetweenPointsReal(GetUnitX(c),GetUnitY(c),GetUnitX(t),GetUnitY(t))
local real tx = x + DISTANCE * Cos(angle * bj_DEGTORAD)
local real ty = y + DISTANCE * Sin(angle * bj_DEGTORAD)
local thistype this = thistype.create(x, y, z, tx, ty, z)
set animresetphase = false
set source = c
set model = MISSILE_FX_PATH
set speed = 2000
set arc = 10
set collision = MISSILE_COLLISION
set owner = GetOwningPlayer(c)
set scale= MISSILE_FX_SCALE
set damage=DamageFormula()
call launch()
call DestroyEffect(AddSpecialEffectTarget(COUNTER_FX_PATH,c,"origin"))
if BlzGetUnitAbilityCooldownRemaining(c,AID) <= 0 then
call BlzStartUnitAbilityCooldown(c, AID, BlzGetUnitAbilityCooldown(c,AID,GetUnitAbilityLevel(c,AID)-1))
endif
static if FACE_ATTACKER then
call SetUnitFacing(c,angle)
endif
static if SINGLE_COUNTER then
set .caster = c
call BlzUnitDisableAbility(c,AID,true,false)
set timer = NewTimerEx(this)
call TimerStart(timer, 0.125, false, function thistype.onTimerExpire)
endif
set udg_DamageEventAmount = 0.0
set udg_DamageEventWeaponT=udg_WEAPON_TYPE_NONE
set udg_DamageEventArmorT=udg_ARMOR_TYPE_NONE
set c = null
set t = null
endmethod
private static method onInit takes nothing returns nothing
local trigger t= CreateTrigger()
call TriggerRegisterVariableEvent(t, "udg_PreDamageEvent", EQUAL, 1.00)
call TriggerAddCondition(t,Condition(function thistype.CounterCondition))
call TriggerAddAction(t,function thistype.CounterAction)
set t=null
endmethod
endstruct
endscope