//***********************************************************************************\\
//***********************************************************************************\\
// This spell is called: \\
// - D E S T R U T I V E S L A S H \\
// By: \\
// - Elphis - Nyuu \\
// Version: \\
// - v1.1 \\
// How to import: \\
// - Open this spell and copy Destructive Slash trigger, \\
// copy Destructive Slash, Destructive Slash \\
// ability, Destructive Slash buff, Dummy caster \\
// and change the rawcode \\
// (Ctrl + D to see the rawcode) if needed \\
// you may play with spell configuration below and have fun!\\
//***********************************************************************************\\
//***********************************************************************************\\
library DestructiveSlash
// S P E L L C O N F I G U R A T I O N \\
globals
//Spell rawcode, change if needed
private constant integer SPELL_ID = 'A000'
//Dummy spell rawcode, change if needed
private constant integer DSPELL_ID = 'A001'
//Spell buff rawcode, change if needed
private constant integer BUFF_ID = 'B000'
//Dummy rawcode, change if needed
private constant integer CASTER_DUMMY = 'e000'
//Spell periodic, decrease this value = fast ecxecution
private constant real PERIODIC = .031250000
//Caster speed animation, decrease this value = the caster play animation more slower
private constant real SPEED_ANIMATION = 1.
//Default scale of the caster when this spell end
private constant real DEFAULT_SCALE = 1.
//Max scale of the caster when spell running
private constant real MAX_SCALE = 4.
//Min scale of the caster increase per periodic
private constant real MIN_SCALE = 0.13
//Damage radius
private constant real DAMAGE_RADIUS = 200.
//Spell damage base
private constant real DAMAGE_BASE = 20.
//Min distance per loop integer (100. distance = 1 integer = 1 efect, 1000. distance = 10 integer = 10 effect)
private constant real MIN_DISTANCE = 100.
//Effect when the caster fire the ground
private constant real SWORD_DISTANCE = 200.
//***************************Damage Weapon Settings***************************
private constant attacktype AT = ATTACK_TYPE_HERO
private constant damagetype DT = DAMAGE_TYPE_FIRE
private constant weapontype WT = WEAPON_TYPE_AXE_MEDIUM_CHOP
//****************************************************************************
//Animation of the caster play when this spell is actived
private constant string ANIMATION = "slam"
//Effect of the spell when the caster fire the ground
private constant string EFFECT = "Objects\\Spawnmodels\\Other\\NeutralBuildingExplosion\\NeutralBuildingExplosion.mdl"
//Order id of the dummy spell
private constant string ORDER_ID = "doom"
// N O N - C O N F I G U R A T I O N \\
private constant timer TIMER = CreateTimer()
private constant group G = CreateGroup()
private integer M = -1
private integer array SM
private unit Dummy
//***********************************************************************************
endglobals
//*******************Damage Settings***********************************
/**/private constant function Damage takes integer lvl returns real
/**/ return DAMAGE_BASE*lvl
/**/endfunction
//*********************************************************************
//*******************Filter Function***********************************
/**/function filterFunc takes unit filterUnit,player playe returns boolean
/**/ //Assure a better death check//
/**/return not IsUnitType(filterUnit,UNIT_TYPE_DEAD) and /**/GetUnitTypeId(filterUnit) != 0/**/ and IsUnitEnemy(filterUnit,playe)
/**/endfunction
//********************************************************************
private struct DestructiveSlash
unit caster = null
unit dummy = null
boolean active = false
integer lvl
real scale = DEFAULT_SCALE
real dmg
real tx
real ty
real dec_scale = MIN_SCALE*2
static method onPeriodic takes nothing returns nothing
local integer i = 0
local integer ec
local real md
local real x
local real y
local real cx
local real cy
local real a
local real cos
local real sin
local integer distance
local unit f = null
local player p = null
local thistype this
loop
exitwhen i > M
set this = SM[i]
if scale < MAX_SCALE and not active then
set scale = scale + MIN_SCALE
else
if not active then
//Attention!: The code below just run once !
set active = true
set ec = 0
set a = Atan2(ty-GetUnitY(caster),tx-GetUnitX(caster))
set cos = Cos(a)
set sin = Sin(a)
set cx = GetUnitX(caster) + SWORD_DISTANCE * cos
set cy = GetUnitY(caster) + SWORD_DISTANCE * sin
set x = tx - cx
set y = ty - cy
set distance = R2I(SquareRoot(x*x+y*y))
set p = GetOwningPlayer(caster)
set md = 0.
loop
exitwhen ec > distance/MIN_DISTANCE
set x = cx + md * cos
set y = cy + md * sin
set md = md + MIN_DISTANCE
call DestroyEffect(AddSpecialEffect(EFFECT,x,y))
call GroupEnumUnitsInRange(G,x,y,DAMAGE_RADIUS,null)
call SetUnitAbilityLevel(Dummy,DSPELL_ID,lvl)
loop
set f = FirstOfGroup(G)
exitwhen f == null
if filterFunc(f,p) then
call UnitDamageTarget(caster,f,dmg,true,false,AT,DT,WT)
if GetUnitAbilityLevel(f,BUFF_ID) == 0 then
call SetUnitX(Dummy,GetUnitX(f))
call SetUnitY(Dummy,GetUnitY(f))
call IssueTargetOrder(Dummy,ORDER_ID,f)
endif
endif
call GroupRemoveUnit(G,f)
endloop
set ec = ec + 1
endloop
set p = null
elseif scale > DEFAULT_SCALE then
set scale = scale - dec_scale
else
call SetUnitTimeScale(caster,DEFAULT_SCALE)
set caster = null
set SM[i] = SM[M]
set SM[M] = -2
set M = M - 1
if M == -1 then
call PauseTimer(TIMER)
endif
endif
endif
call SetUnitScale(caster,scale,0.,0.)
set i = i + 1
endloop
endmethod
static method onCast takes nothing returns boolean
local thistype this
if GetSpellAbilityId() == SPELL_ID then
set this = allocate()
set M = M + 1
set SM[M] = this
set tx = GetSpellTargetX()
set ty = GetSpellTargetY()
set caster = GetTriggerUnit()
set lvl = GetUnitAbilityLevel(caster,SPELL_ID)
call SetUnitAnimation(caster,ANIMATION)
call SetUnitTimeScale(caster,SPEED_ANIMATION)
set dmg = Damage(lvl)
if M == 0 then
call TimerStart(TIMER,PERIODIC,true,function thistype.onPeriodic)
endif
endif
return false
endmethod
static method onInit takes nothing returns nothing
local trigger t = CreateTrigger()
local integer i = 0
loop
exitwhen i > 15
call TriggerRegisterPlayerUnitEvent(t,Player(i),EVENT_PLAYER_UNIT_SPELL_EFFECT,null)
set i = i + 1
endloop
call TriggerAddCondition(t,function thistype. onCast)
set Dummy = CreateUnit(Player(15),CASTER_DUMMY,0.,0.,0.)
endmethod
endstruct
endlibrary