//! runtextmacro Folder("TempestStrike")
//! runtextmacro Struct("CriticalAttacks")
static real array CRITICAL_INCREMENT
static Buff DUMMY_BUFF
static constant real DURATION = 5.
real criticalAdd
static method Event_BuffLose takes nothing returns nothing
local Unit target = UNIT.Event.GetTrigger()
local thistype this = target
local real criticalAdd = this.criticalAdd
call target.CriticalChance.Bonus.Subtract(criticalAdd)
endmethod
static method Event_BuffGain takes nothing returns nothing
local integer level = BUFF.Event.GetLevel()
local Unit target = UNIT.Event.GetTrigger()
local real criticalAdd = CRITICAL_INCREMENT[level]
local thistype this = target
set this.criticalAdd = criticalAdd
call target.CriticalChance.Bonus.Add(criticalAdd)
endmethod
static method Start takes integer level, Unit target returns nothing
call target.Buffs.Timed.Start(thistype.DUMMY_BUFF, level, thistype.DURATION)
endmethod
static method Init takes nothing returns nothing
//! runtextmacro Buff_Create("/", "DUMMY_BUFF", "CrA", "Tempest Strike", "5", "true", "ReplaceableTextures\\CommandButtons\\BTNCleavingAttack.blp", "Does a lot of critical strikes.")
call thistype.DUMMY_BUFF.Event.Add(Event.Create(UNIT.Buffs.Events.Gain.DUMMY_EVENT_TYPE, EventPriority.SPELLS, function thistype.Event_BuffGain))
call thistype.DUMMY_BUFF.Event.Add(Event.Create(UNIT.Buffs.Events.Lose.DUMMY_EVENT_TYPE, EventPriority.SPELLS, function thistype.Event_BuffLose))
call thistype.DUMMY_BUFF.SetLostOnDeath(true)
call thistype.DUMMY_BUFF.SetLostOnDispel(true)
call thistype.DUMMY_BUFF.TargetEffects.Add("Abilities\\Spells\\Orc\\TrollBerserk\\HeadhunterWEAPONSLeft.mdl", AttachPoint.WEAPON_LEFT, EffectLevel.LOW)
call thistype.DUMMY_BUFF.TargetEffects.Add("Abilities\\Spells\\Orc\\TrollBerserk\\HeadhunterWEAPONSRight.mdl", AttachPoint.WEAPON_RIGHT, EffectLevel.LOW)
set CRITICAL_INCREMENT[1] = 40.
set CRITICAL_INCREMENT[2] = 60.
set CRITICAL_INCREMENT[3] = 80.
set CRITICAL_INCREMENT[4] = 100.
set CRITICAL_INCREMENT[5] = 120.
endmethod
endstruct
//! runtextmacro Struct("Refresh")
static Event CAST_EVENT
static method Event_CooldownEnding takes nothing returns nothing
call UNIT.Event.GetTrigger().Event.Remove(CAST_EVENT)
endmethod
static method Event_Cast takes nothing returns nothing
if (SPELL.Event.GetTrigger() == TempestStrike.THIS_SPELL) then
return
endif
call UNIT.Event.GetTrigger().Abilities.Refresh(TempestStrike.THIS_SPELL)
endmethod
static method Event_CooldownStart takes nothing returns nothing
call UNIT.Event.GetTrigger().Event.Add(CAST_EVENT)
endmethod
static method Init takes nothing returns nothing
set CAST_EVENT = Event.Create(UNIT.Abilities.Events.Effect.DUMMY_EVENT_TYPE, EventPriority.SPELLS, function thistype.Event_Cast)
call TempestStrike.THIS_SPELL.Event.Add(Event.Create(UNIT.Abilities.Cooldown.ENDING_EVENT_TYPE, EventPriority.SPELLS, function thistype.Event_CooldownEnding))
call TempestStrike.THIS_SPELL.Event.Add(Event.Create(UNIT.Abilities.Cooldown.START_EVENT_TYPE, EventPriority.SPELLS, function thistype.Event_CooldownStart))
endmethod
endstruct
endscope
//! runtextmacro BaseStruct("TempestStrike", "TEMPEST_STRIKE")
static constant real AREA_RANGE = 90.
static real array DAMAGE
static Buff DUMMY_BUFF
static constant real DURATION = 0.5
static Group ENUM_GROUP
static constant real LENGTH = 500.
static constant real SPEED_END = 100.
static constant string TARGET_EFFECT_ATTACH_POINT = AttachPoint.CHEST
static constant string TARGET_EFFECT_PATH = "Abilities\\Spells\\Other\\Stampede\\StampedeMissileDeath.mdl"
static BoolExpr TARGET_FILTER
static constant real UPDATE_TIME = FRAME_UPDATE_TIME
static Spell THIS_SPELL
real damage
integer level
Group targetGroup
Timer updateTimer
//! runtextmacro LinkToStruct("TempestStrike", "CriticalAttacks")
//! runtextmacro LinkToStruct("TempestStrike", "Refresh")
static method Event_BuffLose takes nothing returns nothing
local Unit target = UNIT.Event.GetTrigger()
local thistype this = target
local integer level = this.level
local Group targetGroup = this.targetGroup
local Timer updateTimer = this.updateTimer
local boolean useBuff = (targetGroup.GetFirst() != NULL)
call targetGroup.Destroy()
call updateTimer.Destroy()
call target.Animation.Queue(UNIT.Animation.STAND)
call target.Ghost.Subtract()
call target.Stun.Subtract(UNIT.Stun.NONE_BUFF)
if (useBuff) then
call thistype(NULL).CriticalAttacks.Start(level, target)
endif
endmethod
static method Conditions takes nothing returns boolean
local Unit filterUnit = UNIT.Event.Native.GetFilter()
if (Group.TEMP.ContainsUnit(filterUnit)) then
return false
endif
if (filterUnit.Classes.Contains(UnitClass.DEAD)) then
return false
endif
if (filterUnit.IsAllyOf(User.TEMP)) then
return false
endif
return true
endmethod
static method Update takes nothing returns nothing
local real damage
local Unit target
local thistype this = Timer.GetExpired().GetData()
local Unit caster = this
local Group targetGroup = this.targetGroup
set Group.TEMP = targetGroup
set User.TEMP = caster.Owner.Get()
call ENUM_GROUP.EnumUnits.InRange.WithCollision.Do(caster.Position.X.Get(), caster.Position.Y.Get(), AREA_RANGE, TARGET_FILTER)
set target = ENUM_GROUP.FetchFirst()
if (target != NULL) then
set damage = this.damage
set targetGroup = this.targetGroup
loop
call target.Effects.Create(TARGET_EFFECT_PATH, TARGET_EFFECT_ATTACH_POINT, EffectLevel.NORMAL)
call targetGroup.AddUnit(target)
call caster.DamageUnitBySpell(target, damage, false, true)
set target = ENUM_GROUP.FetchFirst()
exitwhen (target == NULL)
endloop
endif
endmethod
static method Event_BuffGain takes nothing returns nothing
local integer level = BUFF.Event.GetLevel()
local Unit target = UNIT.Event.GetTrigger()
local real targetX = SPOT.Event.GetTargetX()
local real targetY = SPOT.Event.GetTargetY()
local Timer updateTimer = Timer.Create()
local thistype this = target
set this.damage = DAMAGE[level]
set this.level = level
set this.targetGroup = Group.Create()
set this.updateTimer = updateTimer
call updateTimer.SetData(this)
call target.Ghost.Add()
call target.Position.Timed.Accelerated.AddSpeedDirection(2. * LENGTH / DURATION - SPEED_END, 2. / DURATION * (SPEED_END - LENGTH / DURATION), Math.AtanByDeltas(targetY - target.Position.Y.Get(), targetX - target.Position.X.Get()), DURATION)
call target.Stun.Add(UNIT.Stun.NONE_BUFF)
call updateTimer.Start(UPDATE_TIME, true, function thistype.Update)
endmethod
static method Event_SpellEffect takes nothing returns nothing
call UNIT.Event.GetTrigger().Buffs.Timed.Start(thistype.DUMMY_BUFF, SPELL.Event.GetLevel(), thistype.DURATION)
endmethod
static method Init takes nothing returns nothing
set thistype.DUMMY_BUFF = Buff.CreateHidden("Tempest Strike")
call thistype.DUMMY_BUFF.Event.Add(Event.Create(UNIT.Buffs.Events.Gain.DUMMY_EVENT_TYPE, EventPriority.SPELLS, function thistype.Event_BuffGain))
call thistype.DUMMY_BUFF.Event.Add(Event.Create(UNIT.Buffs.Events.Lose.DUMMY_EVENT_TYPE, EventPriority.SPELLS, function thistype.Event_BuffLose))
call thistype.DUMMY_BUFF.TargetEffects.Add("Abilities\\Weapons\\PhoenixMissile\\Phoenix_Missile_mini.mdl", AttachPoint.ORIGIN, EffectLevel.NORMAL)
//! runtextmacro Spell_Create("/", "THIS_SPELL", "ATeS", "Tempest Strike", "HERO_FIRST")
//! runtextmacro Spell_SetAnimation("/", "spell")
//! runtextmacro Spell_SetCooldown5("/", "7.", "7.", "7.", "7.", "7.")
//! runtextmacro Spell_SetIcon("/", "ReplaceableTextures\\CommandButtons\\BTNCleavingAttack.blp")
//! runtextmacro Spell_SetManaCost5("/", "60", "70", "80", "90", "100")
//! runtextmacro Spell_SetOrder("/", "evileye")
//! runtextmacro Spell_SetRange("/", "99999.")
//! runtextmacro Spell_SetResearchRaw("/", "Te")
//! runtextmacro Spell_SetResearchUberTooltipLv("/", "1", "Slices through a distance to reach the target location. Encountering units will be damaged and if at least one unit is hit, Smokealot will gain a critical value buff. The cast of any other ability lifts the cooldown of 'Tempest Strike'.")
//! runtextmacro Spell_SetResearchUberTooltipLv("/", "2", "Slices through a distance to reach the target location. Encountering units will be damaged and if at least one unit is hit, Smokealot will gain a critical value buff. The cast of any other ability lifts the cooldown of 'Tempest Strike'.|n|nNext Level:|nCritical value increment: 40 --> 60|nDamage: 30 --> 60|nMana cost: 60 --> 70.")
//! runtextmacro Spell_SetResearchUberTooltipLv("/", "3", "Slices through a distance to reach the target location. Encountering units will be damaged and if at least one unit is hit, Smokealot will gain a critical value buff. The cast of any other ability lifts the cooldown of 'Tempest Strike'.|n|nNext Level:|nCritical value increment: 60 --> 80|nDamage: 60 --> 90|nMana cost: 70 --> 80.")
//! runtextmacro Spell_SetResearchUberTooltipLv("/", "4", "Slices through a distance to reach the target location. Encountering units will be damaged and if at least one unit is hit, Smokealot will gain a critical value buff. The cast of any other ability lifts the cooldown of 'Tempest Strike'.|n|nNext Level:|nCritical value increment: 80 --> 100|nDamage: 90 --> 120|nMana cost: 80 --> 90.")
//! runtextmacro Spell_SetResearchUberTooltipLv("/", "5", "Slices through a distance to reach the target location. Encountering units will be damaged and if at least one unit is hit, Smokealot will gain a critical value buff. The cast of any other ability lifts the cooldown of 'Tempest Strike'.|n|nNext Level:|nCritical value increment: 100 --> 120|nDamage: 120 --> 150|nMana cost: 90 --> 100.")
//! runtextmacro Spell_SetTargetType("/", "POINT")
//! runtextmacro Spell_SetUberTooltipLv("/", "1", "Slices through a distance of 500 to reach the target location. Encountering units will be damaged by 30 and if at least one unit is hit, Smokealot will gain a 40 critical value buff. The cast of any other ability lifts the cooldown of 'Tempest Strike'.|nLasts 5 seconds.")
//! runtextmacro Spell_SetUberTooltipLv("/", "2", "Slices through a distance of 500 to reach the target location. Encountering units will be damaged by 60 and if at least one unit is hit, Smokealot will gain a 60 critical value buff. The cast of any other ability lifts the cooldown of 'Tempest Strike'.|nLasts 5 seconds.")
//! runtextmacro Spell_SetUberTooltipLv("/", "3", "Slices through a distance of 500 to reach the target location. Encountering units will be damaged by 90 and if at least one unit is hit, Smokealot will gain a 80 critical value buff. The cast of any other ability lifts the cooldown of 'Tempest Strike'.|nLasts 5 seconds.")
//! runtextmacro Spell_SetUberTooltipLv("/", "4", "Slices through a distance of 500 to reach the target location. Encountering units will be damaged by 120 and if at least one unit is hit, Smokealot will gain a 100 critical value buff. The cast of any other ability lifts the cooldown of 'Tempest Strike'.|nLasts 5 seconds.")
//! runtextmacro Spell_SetUberTooltipLv("/", "5", "Slices through a distance of 500 to reach the target location. Encountering units will be damaged by 150 and if at least one unit is hit, Smokealot will gain a 120 critical value buff. The cast of any other ability lifts the cooldown of 'Tempest Strike'.|nLasts 5 seconds.")
//! runtextmacro Spell_Finalize("/")
set DAMAGE[1] = 30.
set DAMAGE[2] = 60.
set DAMAGE[3] = 90.
set DAMAGE[4] = 120.
set DAMAGE[5] = 150.
set ENUM_GROUP = Group.Create()
set TARGET_FILTER = BoolExpr.GetFromFunction(function thistype.Conditions)
call THIS_SPELL.Event.Add(Event.Create(UNIT.Abilities.Events.Effect.DUMMY_EVENT_TYPE, EventPriority.SPELLS, function thistype.Event_SpellEffect))
call thistype(NULL).CriticalAttacks.Init()
call thistype(NULL).Refresh.Init()
endmethod
endstruct