//***************************************************************************************************
//* ========================
//* Nether Glaive ver.1.0a
//* ========================
//* Made by Shdow89
//*
//*
//* How to implement:
//* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
//* 1. Copy the spell "Nether Glaive" to your map.
//*
//* 2. Copy the unit "Glaive Dummy" to your map. Change it's model path to what you like.
//*
//* 3. Make a global variable of type hashtable, name it Hash, and copy "InitHashtable" trigger.
//*
//* 4, Make a global variable of type unit group and name it temp_group1.
//*
//* 5. Make a global variable of type unit and name it damager.
//*
//* 6. Copy the "Nether Glaive" trigger to your map, go down through constants,
//* hange the rawcodes, other data, and enjoy.
//*
//* Choosable/Effects:
//* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
//* Go down through constant function and change to what you like. Units affected are:
//* Enemy Units, Non-Structures and living. This can be change in function Filter_Action.
//*
//* Editor's Word:
//* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯
//* This is most advanced JASS spell I ever made. The code is really large, and I'm not
//* sure if I did everything right. It will remain BETA version, until I get some feedback
//* about code. Until then, you can check it out, use it, and tell me what you think.
//*
//* Spells Action:
//* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯
//* The casters throws a nether glaive at a targeted enemy unit. Glaive will deal damage
//* to unit it passes by unitl it reaches it's target. When it reaches the target it will
//* blast it with a few lightnings and return to the caster, again dealing damage to enemy
//* units it passes by.
//*
//* Credits:
//* ¯¯¯¯¯¯¯¯
//* TriggerHappy187 for help with groups, and amazing reviews.
//*
//*************************************************************************************************
constant function Glaive_Hit_SFX takes nothing returns string
return "Abilities\\Spells\\Other\\Stampede\\StampedeMissileDeath.mdl" // Special Effect for units hit by the glaive while moving
endfunction
constant function Glaive_Spin_SFX takes nothing returns string
return "Abilities\\Spells\\Other\\Charm\\CharmTarget.mdl" // Special Effect from which lightning is created.
endfunction
constant function Glaive_Lightning takes nothing returns string
return "AFOD" // The Finger of Death lightning code. This can be change to Chain Lig, Forl Lig, etc.
endfunction
constant function Nether_Glaive_ID takes nothing returns integer
return 'A002' // Nether Glaive rawcode. Change to yours if used.
endfunction
constant function Glaive_Dummy_ID takes nothing returns integer
return 'h000' // Glaive Dummy rawcode. Change to yours if used.
endfunction
constant function Dummy_Moving_Speed takes nothing returns real
return 30.0 // Glaive moving speed.
endfunction
constant function Moving_Damage takes integer i returns real
return 50.0*i // Damage dealt while moving. Currently: 50 * level of Nether Glaive
endfunction
constant function Spin_Damage takes integer pica returns real
return 25.0*pica // Damage dealt by the lightnings. Currently: 25 * level of nether glaive.
endfunction
constant function Spin_Times takes integer cvarak returns integer
return 2*cvarak // How many lightnings, special effects are spawned, and damaged the tarageted unit. Currently: 2 * level of nether glaive
endfunction
constant function Glaive_Coolison takes nothing returns real
return 100.0 // Area of effect for Glaive damage while moving.
endfunction
//====================================================================================================================
function Trig_Nether_Glaive_Conditions takes nothing returns boolean
return GetSpellAbilityId() == Nether_Glaive_ID()
endfunction
function Filter_Actions takes nothing returns boolean
local unit u = GetFilterUnit()
if IsUnitEnemy(u, GetOwningPlayer(udg_damager)) == true and IsUnitType(u, UNIT_TYPE_STRUCTURE) == false and (GetWidgetLife(u)>0.405) and IsUnitInGroup(u, udg_temp_group1) == false then
call UnitDamageTarget(udg_damager, u, Moving_Damage(GetUnitAbilityLevel(udg_damager, Nether_Glaive_ID())), true, false, ATTACK_TYPE_MAGIC, DAMAGE_TYPE_MAGIC, WEAPON_TYPE_WHOKNOWS)
call DestroyEffect(AddSpecialEffect(Glaive_Hit_SFX(), GetUnitX(u), GetUnitY(u)))
call GroupAddUnit(udg_temp_group1, u)
endif
set u = null
return false
endfunction
//====================================================================================================================================
//===========================Moving Glaive=====================================================================
function Glaive_Return takes nothing returns nothing
local timer rt = GetExpiredTimer()
local unit gl = LoadUnitHandle(udg_Hash, GetHandleId(rt), 2)
local unit ct = LoadUnitHandle(udg_Hash, GetHandleId(rt), 1)
local real x = GetUnitX(ct)
local real y = GetUnitY(ct)
local real x1 = GetUnitX(gl)
local real y1 = GetUnitY(gl)
local real dist = SquareRoot((x1 - x) * (x1 - x) + (y1 - y) * (y1 - y))
local real angle = Atan2(y - y1, x - x1)
local real newX = x1 + Dummy_Moving_Speed() * Cos(angle)
local real newY = y1 + Dummy_Moving_Speed() * Sin(angle)
set udg_damager = LoadUnitHandle(udg_Hash, GetHandleId(rt), 1)
if dist <= Dummy_Moving_Speed() then
call PauseTimer(rt)
call DestroyTimer(rt)
call RemoveUnit(gl)
call FlushChildHashtable(udg_Hash, GetHandleId(rt))
call GroupClear(udg_temp_group1)
set rt = null
set gl = null
set ct = null
else
call SetUnitPosition(gl, newX, newY)
set udg_temp_group1 = LoadGroupHandle(udg_Hash, GetHandleId(rt), 30)
call GroupEnumUnitsInRange(LoadGroupHandle(udg_Hash, StringHash("Global G"), 0), GetUnitX(gl), GetUnitY(gl), Glaive_Coolison(), Condition(function Filter_Actions))
call GroupClear(LoadGroupHandle(udg_Hash, StringHash("Global G"), 0))
call SaveGroupHandle(udg_Hash, GetHandleId(rt), 30, udg_temp_group1)
set ct = null
set gl = null
set rt = null
endif
endfunction
//=========================LIGHTNING AND NOVAS SPAWN===================================================================
function Spin_Attack takes nothing returns nothing
local timer spin = GetExpiredTimer()
local timer returner = null
local unit dmg = LoadUnitHandle(udg_Hash, GetHandleId(spin), 3)
local unit trg = LoadUnitHandle(udg_Hash, GetHandleId(spin), 1)
local unit glv = null
local integer count = LoadInteger (udg_Hash, GetHandleId(spin), 4)
local real angle1 = 360.0/Spin_Times(GetUnitAbilityLevel(dmg,Nether_Glaive_ID()))
local real effectX = GetUnitX(trg) + 300.0 * Cos((angle1*count) * bj_DEGTORAD)
local real effectY = GetUnitY(trg) + 300.0 * Sin((angle1*count) * bj_DEGTORAD)
local real angle = 0.0
local lightning l = LoadLightningHandle(udg_Hash, GetHandleId(spin), 6)
call DestroyLightning(l)
set l = null
if GetWidgetLife(trg)>0.405 and count != Spin_Times(GetUnitAbilityLevel(dmg,Nether_Glaive_ID())) then
call DestroyEffect(AddSpecialEffect(Glaive_Spin_SFX(), effectX, effectY))
set l = AddLightning(Glaive_Lightning(), true, effectX, effectY, GetUnitX(trg), GetUnitY(trg))
call UnitDamageTarget(dmg, trg, Spin_Damage(GetUnitAbilityLevel(dmg, Nether_Glaive_ID())), true, false, ATTACK_TYPE_MAGIC, DAMAGE_TYPE_MAGIC, WEAPON_TYPE_WHOKNOWS)
call SaveLightningHandle(udg_Hash, GetHandleId(spin), 6, l)
call SaveInteger(udg_Hash, GetHandleId(spin), 4, count + 1)
set l = null
set dmg = null
set trg = null
set spin = null
else
if GetWidgetLife(dmg)>0.408 then
call PauseTimer(spin)
call DestroyTimer(spin)
set angle = Atan2(GetUnitY(dmg) - GetUnitY(trg), GetUnitX(dmg) - GetUnitX(trg))
set glv = CreateUnit(GetOwningPlayer(dmg), Glaive_Dummy_ID(), GetUnitX(trg) + 20.0 * Cos(angle), GetUnitY(trg) + 20.0 * Sin(angle), angle)
set returner = CreateTimer()
call SaveUnitHandle (udg_Hash, GetHandleId(returner), 1, dmg)
call SaveUnitHandle (udg_Hash, GetHandleId(returner), 2, glv)
call SaveGroupHandle(udg_Hash, GetHandleId(returner), 30, CreateGroup())
call TimerStart(returner, 0.03, true, function Glaive_Return)
set spin = null
set dmg = null
set trg = null
set glv = null
else
call FlushChildHashtable(udg_Hash, GetHandleId(spin))
call PauseTimer(spin)
call DestroyTimer(spin)
set spin = null
set dmg = null
set trg = null
endif
endif
endfunction
//========================GLAIVE FIRST MOVE======================================================================================
function Glaive_Move takes nothing returns nothing
local timer mover = GetExpiredTimer()
local timer spin = null
local timer returner = null
local unit target = LoadUnitHandle(udg_Hash, GetHandleId(mover), 1)
local unit glaive = LoadUnitHandle(udg_Hash, GetHandleId(mover), 2)
local real x = GetUnitX(target)
local real y = GetUnitY(target)
local real x1 = GetUnitX(glaive)
local real y1 = GetUnitY(glaive)
local real dist = SquareRoot((x1 - x) * (x1 - x) + (y1 - y) * (y1 - y))
local real angle = Atan2(y - y1, x - x1)
local real newX = x1 + Dummy_Moving_Speed() * Cos(angle)
local real newY = y1 + Dummy_Moving_Speed() * Sin(angle)
set udg_damager = LoadUnitHandle(udg_Hash, GetHandleId(mover), 3)
//!!!!!!!Conditions for stopping the glaive, if target is dead, move it back to caster. If caster is dead, destroy it.
if dist <= Dummy_Moving_Speed() then
call PauseTimer(mover)
call DestroyTimer(mover)
set mover = null
call FlushChildHashtable(udg_Hash, GetHandleId(mover))
call RemoveUnit(glaive)
call GroupClear(udg_temp_group1)
if GetWidgetLife(target)>0.405 then
set spin = CreateTimer()
call SaveUnitHandle (udg_Hash, GetHandleId(spin), 1, target)
call SaveUnitHandle (udg_Hash, GetHandleId(spin), 2, glaive)
call SaveUnitHandle (udg_Hash, GetHandleId(spin), 3, udg_damager)
call SaveInteger (udg_Hash, GetHandleId(spin), 4, 0)
call TimerStart (spin, 0.3, true, function Spin_Attack)
set glaive = null
set target = null
set spin = null
else
if GetWidgetLife(udg_damager)>0.405 then
set returner = CreateTimer()
set glaive = null
set glaive = CreateUnit(GetOwningPlayer(udg_damager), Glaive_Dummy_ID(), GetUnitX(target) + 20.0 * Cos(angle), GetUnitY(target) + 20.0 * Sin(angle), angle)
call SaveUnitHandle (udg_Hash, GetHandleId(returner), 1, udg_damager)
call SaveUnitHandle (udg_Hash, GetHandleId(returner), 2, glaive)
call SaveGroupHandle (udg_Hash, GetHandleId(returner), 30, CreateGroup())
call TimerStart (returner, 0.03, true, function Glaive_Return)
set glaive = null
set target = null
set returner = null
else
set glaive = null
set target = null
endif
endif
else
call SetUnitPosition(glaive, newX, newY)
set udg_temp_group1 = LoadGroupHandle(udg_Hash, GetHandleId(mover), 30)
call GroupEnumUnitsInRange(LoadGroupHandle(udg_Hash, StringHash("Global G"), 0), GetUnitX(glaive), GetUnitY(glaive), Glaive_Coolison(), Condition(function Filter_Actions))
call SaveGroupHandle(udg_Hash, GetHandleId(mover), 30, udg_temp_group1)
call GroupClear(LoadGroupHandle(udg_Hash, StringHash("Global G"), 0))
set target = null
set mover = null
endif
endfunction
//=====================Preset action trigger==================================================================
function Trig_Nether_Glaive_Actions takes nothing returns nothing
local timer moving = CreateTimer()
local unit cast = GetTriggerUnit()
local unit target = GetSpellTargetUnit()
local real angle = Atan2(GetUnitY(cast) - GetUnitY(target), GetUnitX(cast) - GetUnitX(target))
local unit glaive = CreateUnit(GetOwningPlayer(cast), Glaive_Dummy_ID(), GetUnitX(cast) + 20.0 * Cos(angle), GetUnitY(cast) + 20.0 * Sin(angle), angle)
call SaveUnitHandle(udg_Hash, GetHandleId(moving), 1, target)
call SaveUnitHandle(udg_Hash, GetHandleId(moving), 2, glaive)
call SaveUnitHandle(udg_Hash, GetHandleId(moving), 3, cast)
call SaveGroupHandle(udg_Hash, GetHandleId(moving), 30, CreateGroup())
call TimerStart(moving, 0.03, true, function Glaive_Move)
set cast = null
set target = null
set glaive = null
set moving = null
endfunction
//=============INIT TRIGG===================================================================
function InitTrig_Nether_Glaive takes nothing returns nothing
local trigger trig = CreateTrigger()
local integer taki = 0
loop
call TriggerRegisterPlayerUnitEvent(trig, Player(taki), EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
set taki = taki + 1
exitwhen taki == 16
endloop
call TriggerAddCondition(trig, Condition(function Trig_Nether_Glaive_Conditions))
call TriggerAddAction(trig, function Trig_Nether_Glaive_Actions)
call Preload(Glaive_Hit_SFX())
call Preload(Glaive_Spin_SFX())
call PreloadStart()
endfunction