library GlaiveOfDestruction uses RegisterPlayerUnitEvent ,SpellEffectEvent, Tt, UnitIndexer, StunSystem, TerrainPathability
//************************************************************************
//Credits To:
//Magtheridon96, Bribe, iAyanami, Nestharus, Rising_Dusk
//************************************************************************
globals
//==================
private constant integer DUM_CODE = 'h000' //raw code of the dummy
private constant integer ABIL_CODE = 'A000' //raw code of the Spell
//===================
private constant real DUM_SCALE = 3.3 //Size of the Glaive
private constant real SPEED = 800. //Speed of the Glaive
private constant real HEIGHT = 150. //height of the Glaive
private constant real COL_SIZE = 250. // collision size of the Glaive
private constant real STUN_DUR = 3. // stun duration
private constant string SFX = "Objects\\Spawnmodels\\Human\\HumanBlood\\BloodElfSpellThiefBlood.mdl"
private constant string ATTACH = "origin"
//===================
private constant attacktype ATK = ATTACK_TYPE_NORMAL // attack type
private constant damagetype DMG = DAMAGE_TYPE_MAGIC // damage type
//===================
private constant player NEUTRAL_PASSIVE = Player(PLAYER_NEUTRAL_PASSIVE)
private group G = CreateGroup()
endglobals
//*******************************************************
//CONFIGURABLES
//********************************************************
//distance
private constant function GetDistance takes integer level returns real
return 1400.
endfunction
//Glaives AoE
private constant function GetAoE takes integer level returns real
return 250.
endfunction
//damage
private constant function GetDamage takes integer level returns real
return 75. * level
endfunction
//Prevents the Glaive from damaging dead units/mechanical units/structures/destructibles/allies/etc.
private constant function GetFilter takes unit caster, unit target returns boolean
return /*
*/ not IsUnitType(target, UNIT_TYPE_DEAD) and /* // target is alive
*/ IsUnitEnemy(target, GetOwningPlayer(caster)) and /* // target is an enemy of caster
*/ not IsUnitType(target, UNIT_TYPE_STRUCTURE) and /* // target is not a structure
*/ not IsUnitType(target, UNIT_TYPE_MECHANICAL) // target is not mechanic
endfunction
//***************************************************
//STRUCT
//****************************************************
private struct Main extends array
private group g
private unit u
private player owner
private unit dummy
private real aoe
private real damage
private real distance
private real sin
private real cos
private static integer array store
private static constant real TIMEOUT = 0.031260000
private static constant real MAX_SPEED = SPEED * TIMEOUT
implement CTTC
local unit u
local real x
local real y
implement CTTCExpire
set x = GetUnitX(this.dummy) + this.cos
set y = GetUnitY(this.dummy) + this.sin
//Pathability
if IsTerrainWalkable(x, y) then
call SetUnitX(this.dummy, x)
call SetUnitY(this.dummy, y)
else
set this.distance = 0
endif
set this.distance = this.distance - MAX_SPEED
call GroupEnumUnitsInRange(G, x, y, this.aoe + COL_SIZE, null)
loop
set u = FirstOfGroup(G)
exitwhen u == null
call GroupRemoveUnit(G, u)
if not IsUnitInGroup(u, this.g) and GetFilter(this.u, u) and IsUnitInRangeXY(u, x, y, this.aoe+COL_SIZE) then
call GroupAddUnit(this.g, u)
call UnitDamageTarget(this.u, u, this.damage, true, false, ATK, DMG, null)
call Stun.apply(u, STUN_DUR, false)
call DestroyEffect(AddSpecialEffectTarget(SFX,u,ATTACH))
endif
endloop
if this.distance <= 0 then
if thistype.store[GetUnitId(this.u)] == this then
set thistype.store[GetUnitId(this.u)] = 0
endif
call GroupClear(this.g)
call DestroyGroup(this.g)
call KillUnit(this.dummy)
set this.g = null
call this.destroy()
endif
implement CTTCEnd
private static method onCast takes nothing returns boolean
local thistype this = thistype.create()
local integer level
local real a
set this.g = CreateGroup()
set this.u = GetTriggerUnit()
set this.owner = GetTriggerPlayer()
set a = Atan2(GetSpellTargetY() - GetUnitY(this.u), GetSpellTargetX() - GetUnitX(this.u))
set this.dummy = CreateUnit(this.owner, DUM_CODE, GetUnitX(this.u), GetUnitY(this.u), a * bj_RADTODEG)
set level = GetUnitAbilityLevel(this.u, ABIL_CODE)
set this.aoe = GetAoE
set this.damage = GetDamage(level)
set this.distance = GetDistance(level)
set this.sin = MAX_SPEED * Sin(a)
set this.cos = MAX_SPEED * Cos(a)
set thistype.store[GetUnitId(this.u)] = this
call SetUnitScale(this.dummy, DUM_SCALE, 0, 0)
call SetUnitFlyHeight(this.dummy, HEIGHT, 0)
return false
endmethod
//**********************************
//SPELL EVENT
//**********************************
private static method onInit takes nothing returns nothing
call RegisterSpellEffectEvent(ABIL_CODE, function thistype.onCast)
endmethod
endstruct
endlibrary