//*************************************************************************************
//*************************************************************************************
//*************************************************************************************
//*************************************************************************************
// S C Y T H E D E A T H
// - Spell Create By:
// + Elphis
//*************************************************************************************
library ScytheDeath /*
*/ requires /*
// -*/ DelFX /* http://www.hiveworkshop.com/forums/spells-569/delfx-delayed-effects-1-4-2-a-116064/?prev=search%3DDel%2520Effect%26d%3Dlist%26r%3D20%26c%3D112
// -*/ TimerUtils /* http://www.wc3c.net/showthread.php?t=101322
// -*/ SpellEffectEvent /* http://www.hiveworkshop.com/forums/jass-resources-412/snippet-spelleffectevent-187193/
// -*/ xebasic /* http://www.wc3c.net/showthread.php?t=101150
// -*/ xedamage /* http://www.wc3c.net/showthread.php?t=101150
// -*/ DashDamage /* Dash Damage Library (Inside map)
// -*/ Table /* http://www.wc3c.net/showthread.php?t=101246 */
//*************************************************************************************
// - Spell Information:
// - Use the supreme power release 22/24/26/28 blade fly to the selected location
// when the scythe move, it slash all enemies in 150 range deals 20/40/60/80
// damage, when scythe accumulate to the selected location
// it will create explosions around 300 range deals 50/100/150/200 damage.
//*************************************************************************************
// - Installation:
// - Import/copy the required libraries and Scythe Death code to your map
// - Import/copy the custom ability and unit to your map and change the SPELL_ID if needed
// - You may view the raw ID of the objects by pressing CTRL+D in the object editor
// - You may play with the configurables below
//*************************************************************************************
globals
//=================================Configuration=================================//
//Scythe Model
private constant string SCYTHE_MODEL = "Abilities\\Weapons\\GargoyleMissile\\GargoyleMissile.mdl"
//Effect when scythe accumulate to the point
private constant string SCYTHE_EFFECT = "Abilities\\Spells\\Other\\Incinerate\\FireLordDeathExplode.mdl"
//Scythe Attachment
private constant string SCYTHE_ATTACH = "origin"
//Scythe Create Angle
private constant real SCYTHE_ANGLE = 90.
//Scythe life
private constant real SCYTHE_LIFE = 1.5
//Damage slash intevar
private constant real DAMAGE_INTEVAR = 0.1
//Scythe create between
private constant real SCYTHE_BETWEEN = 0.05
//Skythe size
private constant real SCYTHE_SIZE = 2.
//Rawcode of spell, change if needed
private constant integer SPELL_ID = 'A000'
//Periodic of spell, increase if laggy
private constant real PERIODIC = 0.031250000
//Count of the Scythe
private constant integer TOTAL_SCYTHE_BASE = 20
//Scythe moving speed
private constant real SCYTHE_SPEED = 35.
//Allow scythe damage to tree
private constant boolean DAMAGE_TREE = true
// ==DAMAGE SETTINGS==
//Radius slash enemies
private constant real DAMAGE_RADIUS = 150.
//Radius when scythe accumulate to the point
private constant real SCYTHE_MIN_RANGE = 100.
//Damage radius when scythe accumulate to the point
private constant real ACCUMULATE_RADIUS = 300.
//Distance between scythe create
private constant real SCYTHE_DISTANCE = 500.
//Damage of Scythe when it slash enemies
private constant real DAMAGE_SLASH_BASE = 20.
//Damage of Scythe when it accumulate to the point
private constant real DAMAGE_BASE = 50.
// =ATTACK DAMAGE WEAPON TYPE SETTINGHS=
private constant attacktype ATTACKTYPE = ATTACK_TYPE_HERO
private constant damagetype DAMAGETYPE = DAMAGE_TYPE_COLD
private constant weapontype WEAPONTYPE = WEAPON_TYPE_METAL_HEAVY_BASH
//================================================================================//
endglobals
//
private struct DeathScythe
//unit
unit caster
//integer
integer count
integer maxcount
//player
player p
//boolean
boolean between = false
//real
real intevar = 0.
real cxl
real cyl
real cxr
real cyr
real al
real ar
real tx
real ty
real f
//xedamage and Table
xedamage xed
Table tab
//--------------
static method onDamage takes unit u,boolean accumulate returns real
local real d
if accumulate then
set d = DAMAGE_SLASH_BASE * GetUnitAbilityLevel(u,SPELL_ID) // Damage when scythe slash enemies
else
set d = DAMAGE_BASE * GetUnitAbilityLevel(u,SPELL_ID) // Damage when scythe accumulate to the point
endif
return d
endmethod
//
static method onCount takes unit u returns integer
return TOTAL_SCYTHE_BASE+GetUnitAbilityLevel(u,SPELL_ID)*2 //Count scythe
endmethod
//
static method onPeriodic takes nothing returns nothing
local timer t = GetExpiredTimer()
local thistype this = GetTimerData(t)
//
//This key check dummy dead or not and use it for destroy data when done
local boolean k
//------------------
local integer co = 0
//
//Begin create scythe//
if count < maxcount then
if intevar < SCYTHE_BETWEEN then
set intevar = intevar + PERIODIC
else
set intevar = 0.
set count = count + 1
//
if between then
set between = false
//Calling Scythe
set tab.unit[count] = CreateUnit(p,XE_DUMMY_UNITID,cxl,cyl,al)
call DashDamage.add(al,DAMAGE_RADIUS,tab.unit[count],SCYTHE_SPEED,onDamage(caster,false),ATTACKTYPE,DAMAGETYPE,WEAPONTYPE,SCYTHE_LIFE,DAMAGE_INTEVAR)
else
set between = true
//Calling Scythe
set tab.unit[count] = CreateUnit(p,XE_DUMMY_UNITID,cxr,cyr,ar)
call DashDamage.add(ar,DAMAGE_RADIUS,tab.unit[count],SCYTHE_SPEED,onDamage(caster,false),ATTACKTYPE,DAMAGETYPE,WEAPONTYPE,SCYTHE_LIFE,DAMAGE_INTEVAR)
endif
//I use boolean because if not use this, it will spam effect and damage
set tab.boolean[count] = true
call SetUnitScale(tab.unit[count],SCYTHE_SIZE,0.,0.)
call CreateDelayedEffectTarget(SCYTHE_MODEL,tab.unit[count],SCYTHE_ATTACH,0.,SCYTHE_LIFE-0.01) //Safe remove effect
endif
else
set k = false
endif
//
loop
exitwhen co > count
if not IsUnitType(tab.unit[co],UNIT_TYPE_DEAD) and GetUnitTypeId(tab.unit[co]) != 0 then
set k = true
if IsUnitInRangeXY(tab.unit[co],tx,ty,SCYTHE_MIN_RANGE) and tab.boolean[co] then
//I use boolean because if not use this, it will spam effect and damage
set tab.boolean[co] = false
call DestroyEffect(AddSpecialEffect(SCYTHE_EFFECT,tx,ty))
//This line deals damage to enmies unit
call xed.damageAOE(caster,tx,ty,ACCUMULATE_RADIUS,onDamage(caster,true))
endif
endif
//
set co = co + 1
endloop
//
if not k then
//Recycle and Clean data
call ReleaseTimer(t)
loop
exitwhen co > count
call RemoveUnit(tab.unit[co])
set tab.unit[co] = null
set co = co + 1
endloop
set caster = null
set p = null
call tab.destroy()
call xed.destroy()
call destroy()
endif
//
set t = null
//
endmethod
//
static method onCast takes nothing returns nothing
local thistype this = allocate()
//Begin Get Data
set caster = GetTriggerUnit()
set p = GetTriggerPlayer()
//Set Count of Scythe
set count = 0
set maxcount = onCount(caster)
//Don't touch this
set f = GetUnitFacing(caster)
//
set tab = Table.create()
//Get xy left
set cxl = GetWidgetX(caster) + SCYTHE_DISTANCE * Cos((f+SCYTHE_ANGLE)*0.01747)
set cyl = GetWidgetY(caster) + SCYTHE_DISTANCE * Sin((f+SCYTHE_ANGLE)*0.01747)
//Get xy right
set cxr = GetWidgetX(caster) + SCYTHE_DISTANCE * Cos((f-SCYTHE_ANGLE)*0.01747)
set cyr = GetWidgetY(caster) + SCYTHE_DISTANCE * Sin((f-SCYTHE_ANGLE)*0.01747)
//Get Spell Target Location
set tx = GetSpellTargetX()
set ty = GetSpellTargetY()
//Get angle
set al = 57.29582 * Atan2(ty - cyl, tx - cxl)
set ar = 57.29582 * Atan2(ty - cyr, tx - cxr)
//Xe damage installing
set xed = xedamage.create()
set xed.dtype = DAMAGETYPE
set xed.atype = ATTACKTYPE
set xed.wtype = WEAPONTYPE
set xed.exception = UNIT_TYPE_STRUCTURE
set xed.damageEnemies = true
set xed.damageTrees = DAMAGE_TREE
//Calling Timer
call TimerStart(NewTimerEx(this),PERIODIC,true,function thistype.onPeriodic)
endmethod
//
static method onInit takes nothing returns nothing
call RegisterSpellEffectEvent(SPELL_ID,function thistype.onCast)
endmethod
//
endstruct
endlibrary
[/HIDDEN]