/*
Spell Name: Twin Wolves
Made by: mckill2009
REQUIRES:
- Jass New Gen Pack (JNGP) by Vexorian
- RegisterPlayerUnitEvent by Magtheridon96
- Table by Bribe
- SimError by Vexorian
- SummonedEscort by mckill2009
*/
scope TwinWolves
globals
private constant integer SPELL_ID = 'A002'
private constant integer WOLF_ID = 'n000'
private constant integer FOR_ALLY_SPELL_ID = 'A004' //rejuvenation
private constant integer FOR_ENEMY_SPELL_ID = 'A005' //chainlightning
private constant integer FOR_ALLY_OID = 852160 //this should match the FOR_ALLY_SPELL_ID
private constant integer FOR_ENEMY_OID = 852119 //this should match the FOR_ENEMY_SPELL_ID
private constant real AOE = 600.
private constant string SFX_APPEAR = "Abilities\\Spells\\Orc\\FeralSpirit\\feralspirittarget.mdl"
private constant real PERIOD = 1.0 //how fast the wolves will cast spells, affected by cooldowns
private constant real WOLF_LIFE = 60.
//===NON-CONFIGURABLE
private Table c
private unit FilterUnit
private unit TempUnit
endglobals
private function UnitAlive takes unit u returns boolean
return not IsUnitType(u, UNIT_TYPE_DEAD)
endfunction
private function UnitAllyInRange takes nothing returns boolean
set FilterUnit = GetFilterUnit()
return UnitAlive(FilterUnit) and not IsUnitEnemy(TempUnit, GetOwningPlayer(FilterUnit)) /*
*/ and not IsUnitType(FilterUnit, UNIT_TYPE_STRUCTURE) and not IsUnitType(FilterUnit, UNIT_TYPE_MECHANICAL) /*
*/ and not IsUnitType(FilterUnit, UNIT_TYPE_MAGIC_IMMUNE) and GetWidgetLife(FilterUnit) < GetUnitState(FilterUnit, UNIT_STATE_MAX_LIFE)
endfunction
private function UnitEnemyInRange takes nothing returns boolean
set FilterUnit = GetFilterUnit()
return UnitAlive(FilterUnit) and IsUnitEnemy(TempUnit, GetOwningPlayer(FilterUnit)) /*
*/ and not IsUnitType(FilterUnit, UNIT_TYPE_STRUCTURE) and not IsUnitType(FilterUnit, UNIT_TYPE_MECHANICAL) /*
*/ and not IsUnitType(FilterUnit, UNIT_TYPE_MAGIC_IMMUNE)
endfunction
struct TW
unit caster
unit healer
unit damager
real duration
private static integer index = 0
private static integer array indexAR
private static timer t = CreateTimer()
private static method periodic takes nothing returns nothing
local thistype this
local integer i = 0
local unit first
loop
set i = i+1
set this = indexAR[i]
if .duration > 0 and UnitAlive(.caster) then
set .duration = .duration - PERIOD
set TempUnit = .caster
if UnitAlive(.damager) then
set first = GetClosestUnitInRange(GetUnitX(.damager), GetUnitY(.damager), AOE, Filter(function UnitEnemyInRange))
if first!=null then
call IssueTargetOrderById(.damager, FOR_ENEMY_OID, first)
endif
endif
if UnitAlive(.healer) then
set first = GetClosestUnitInRange(GetUnitX(.healer), GetUnitY(.healer), AOE, Filter(function UnitAllyInRange))
if first!=null then
call IssueTargetOrderById(.healer, FOR_ALLY_OID, first)
endif
endif
else
call c.remove(GetHandleId(.caster))
call KillUnit(.damager)
call KillUnit(.healer)
set .caster = null
set .damager = null
set .healer = null
call .destroy()
set indexAR[i] = indexAR[index]
set indexAR[index] = this
set index = index - 1
set i = i-1
if index==0 then
call PauseTimer(t)
endif
endif
exitwhen i==index
endloop
set first = null
endmethod
private static method cast takes nothing returns nothing
local unit u
local integer level
local real facing
local real x
local real y
local thistype this
if GetSpellAbilityId()==SPELL_ID then
set u = GetTriggerUnit()
if c.has(GetHandleId(u)) then
call IssueImmediateOrder(u, "stop")
call SimError(GetTriggerPlayer(), "you cant use this spell yet")
else
set this = allocate()
set x = GetUnitX(u)
set y = GetUnitY(u)
set facing = GetUnitFacing(u)*0.017453333
set .caster = u
set level = GetUnitAbilityLevel(u, SPELL_ID)
//===Healer
set .healer = CreateUnit(GetTriggerPlayer(), WOLF_ID, x+150*Cos(facing+1.5708), y+150*Sin(facing+1.5708), GetUnitFacing(u))
call DestroyEffect(AddSpecialEffectTarget(SFX_APPEAR, .healer, "origin"))
call UnitAddAbility(.healer, FOR_ALLY_SPELL_ID)
call SetUnitAbilityLevel(.healer, FOR_ALLY_SPELL_ID, level)
call MakeUnitUnSelectable(.healer, 0)
call SE.summoned(.caster, .healer)
//===Damager
set .damager = CreateUnit(GetTriggerPlayer(), WOLF_ID, x+150*Cos(facing-1.5708), y+150*Sin(facing-1.5708), GetUnitFacing(u))
call DestroyEffect(AddSpecialEffectTarget(SFX_APPEAR, .damager, "origin"))
call UnitAddAbility(.damager, FOR_ENEMY_SPELL_ID)
call SetUnitAbilityLevel(.damager, FOR_ENEMY_SPELL_ID, level)
call MakeUnitUnSelectable(.damager, 0)
call SE.summoned(.caster, .damager)
set .duration = WOLF_LIFE
set c[GetHandleId(u)] = 0
if index==0 then
call TimerStart(t, PERIOD, true, function thistype.periodic)
endif
set index = index + 1
set indexAR[index] = this
endif
set u = null
endif
endmethod
private static method onInit takes nothing returns nothing
local unit u = CreateUnit(Player(15), WOLF_ID, 0,0,0)
call RegisterPlayerUnitEvent(EVENT_PLAYER_UNIT_SPELL_CAST, function thistype.cast)
set c = Table.create()
//Preloading
call UnitAddAbility(u, FOR_ENEMY_SPELL_ID)
call UnitAddAbility(u, FOR_ALLY_SPELL_ID)
call ShowUnit(u, false)
call RemoveUnit(u)
set u = null
endmethod
endstruct
endscope