//***********************************************************************************************************
//***********************************************************************************************************
//***********************************************************************************************************
//***********************************************************************************************************
//***********************************************************************************************************
// M A N A W A V E
// By: Elphis
// - Spell Information:
// - Calls forth a wave of energy that heals a target, if target belong to ally,
// it will bounces to all nearby friendlies around 700 AOE, each bounces heals 100 mana.
// But if the target belong to enemy, it will bounces to all nearby ememies around 700 AOE and
// destroy 100 on the target, every time it bounces to enemy, each wave, mana desrtoy will decreasing by 20.
// - Installation:
// - Import/copy Healing Mana 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
//***********************************************************************************************************
//***********************************************************************************************************
//***********************************************************************************************************
//***********************************************************************************************************
//***********************************************************************************************************
//***********************************************************************************************************
library ManaWave
//**********************************CONFIGURABLE**********************************
globals
//Spell rawcode
private constant integer SPELL_ID = 'A000'
//Spell period
private constant real PERIODIC = .031250000
//Area of effect
private constant real AOE = 700.
//Heal mana time intevar
private constant real HEAL_INTEVAR = 0.1
//Mana heal count
private constant real MANA_HEAL_BASE = 100.
//Mana destroy decrease every it link from enemy
private constant real MANA_DESTROY_DECREASE = 20.
//Lightning color fade timed
private constant real LIGHTNING_FADE_INTEVAR = 0.02
//***********LIGHTNING COLOR***********//
private constant real LIGHTNING_COLOR_RED = 0.5
private constant real LIGHTNING_COLOR_GREEN = 0.2
private constant real LIGHTNING_COLOR_BLUE = 1.
//***************************************
//Allies buff count
private constant integer ALLIES_COUNT_BASE = 5
//Lightning model
private constant string LIGHTNING_MODEL = "MFPB"
//Effect when no unit in area of effect
private constant string MODEL_EMPTY = "Abilities\\Spells\\Human\\DispelMagic\\DispelMagicTarget.mdl"
//Effect when buff allies
private constant string BUFF_EFFECT = "Abilities\\Spells\\Other\\Drain\\ManaDrainTarget.mdl"
//Effect when buff enemies
private constant string BUFF_EFFECT_ENEMY = "Abilities\\Spells\\Other\\Drain\\ManaDrainCaster.mdl"
//Effect linked of the lightning
private constant string EFFECT_LINKED = "Abilities\\Spells\\Demon\\DarkPortal\\DarkPortalTarget.mdl"
//Point attachment
private constant string ATTACH_POINT = "origin"
//Point linked attachment
private constant string ATTACH_POINT_LINKED = "origin"
//***********Non-Configurable***********//
private integer MUI = -1
private integer Plugin_MUI = -1
private constant group G = CreateGroup()
private constant integer array Struct_Data
private constant integer array Plugin_Struct_Data
private constant timer TIMER = CreateTimer()
private constant timer TIMER_2 = CreateTimer()
private constant location LOC = Location(0.,0.)
//***************************************
endglobals
//**********************************END OF CONFIGURABLE**********************************//
//**********************************DO NOT MODIFY ANYTHING BELOW**********************************//
private struct ManaWave
unit caster
unit last_unit
real intevar = 0.
real mana
boolean destroy_mana
group g = CreateGroup()
static method onPeriodic takes nothing returns nothing
local thistype this
local integer i = 0
local unit r
loop
exitwhen i > MUI
set this = Struct_Data[i]
if intevar < HEAL_INTEVAR then
set intevar = intevar + PERIODIC
else
set intevar = 0.
set r = GroupPickRandomUnit(g)
if r != null then
call GroupRemoveUnit(g,r)
call ManaWave_ManaWavePlugin.add(LIGHTNING_MODEL,r,last_unit,mana,destroy_mana)
if destroy_mana then
set mana = mana - MANA_DESTROY_DECREASE
endif
set last_unit = r
else
set Struct_Data[i] = Struct_Data[MUI]
set Struct_Data[MUI] = -2
set MUI = MUI - 1
if MUI == -1 then
call PauseTimer(TIMER)
endif
call DestroyGroup(g)
set g = null
set caster = null
set last_unit = null
call destroy()
endif
endif
set i = i + 1
endloop
endmethod
static method onCast takes nothing returns boolean
local thistype this
local unit f = GetSpellTargetUnit()
local unit ct = GetTriggerUnit()
local player owner = GetTriggerPlayer()
local integer lvl
local integer count
local integer total_unit = 0
local boolean destroy_mn = IsUnitEnemy(f,owner)
//Checking unit around the target....
call GroupEnumUnitsInRange(G,GetUnitX(f),GetUnitY(f),AOE,null)
loop
set f = FirstOfGroup(G)
exitwhen f == null
if f != ct and GetUnitState(f,UNIT_STATE_MAX_MANA) > 0. and not IsUnitType(f,UNIT_TYPE_DEAD) then
if IsUnitEnemy(f,owner) == destroy_mn then
set total_unit = 1
exitwhen true
endif
endif
call GroupRemoveUnit(G,f)
endloop
//Checking conditions before run this spell....
if total_unit == 0 then
call DestroyEffect(AddSpecialEffect(MODEL_EMPTY,GetUnitX(ct),GetUnitY(ct)))
set ct = null
set f = null
return false
endif
set this = allocate()
set total_unit = 0
set MUI = MUI + 1
set Struct_Data[MUI] = this
set caster = ct
set last_unit = GetSpellTargetUnit()
set lvl = GetUnitAbilityLevel(caster,SPELL_ID)
set mana = MANA_HEAL_BASE*lvl
set count = ALLIES_COUNT_BASE+lvl
set destroy_mana = destroy_mn
call GroupEnumUnitsInRange(G,GetUnitX(f),GetUnitY(f),AOE,null)
loop
set f = FirstOfGroup(G)
exitwhen f == null
if f != caster and GetUnitState(f,UNIT_STATE_MAX_MANA) > 0. and not IsUnitType(f,UNIT_TYPE_DEAD) then
if IsUnitEnemy(f,owner) == destroy_mana then
call GroupAddUnit(g,f)
endif
set total_unit = total_unit + 1
endif
call GroupRemoveUnit(G,f)
endloop
set count = total_unit - count
set f = GroupPickRandomUnit(g)
if f != null then
call ManaWave_ManaWavePlugin.add(LIGHTNING_MODEL,last_unit,caster,mana,destroy_mana)
call GroupRemoveUnit(g,last_unit)
loop
exitwhen count < 0
set f = GroupPickRandomUnit(g)
call GroupRemoveUnit(g,f)
set count = count - 1
endloop
endif
if MUI == 0 then
call TimerStart(TIMER,PERIODIC,true,function thistype.onPeriodic)
endif
set owner= null
set ct = null
set f = null
return false
endmethod
static method onInit takes nothing returns nothing
local integer i = 0
local trigger t = CreateTrigger()
//
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 t = null
endmethod
endstruct
public struct ManaWavePlugin
private unit plugin_unit
private unit plugin_caster
private real plugin_color
private real plugin_mana
private real plugin_intevar
private real plugin_fade = 1.
private effect plugin_effect
private lightning plugin_lightning
private boolean plugin_destroy
static method onPeriodic takes nothing returns nothing
local thistype this
local integer i = 0
local real zc
local real zu
local real xc
local real yc
local real xu
local real yu
loop
exitwhen i > Plugin_MUI
set this = Plugin_Struct_Data[i]
set xc = GetUnitX(plugin_caster)
set yc = GetUnitY(plugin_caster)
set zu = GetUnitX(plugin_unit)
set yu = GetUnitY(plugin_unit)
call MoveLocation(LOC,xc,yc)
set zc = GetLocationZ(LOC)+GetUnitFlyHeight(plugin_caster)
call MoveLocation(LOC,xu,yu)
set zc = GetLocationZ(LOC)+GetUnitFlyHeight(plugin_unit)
call MoveLightningEx(plugin_lightning,true,xc,yc,zc,zu,yu,zu)
if plugin_fade > 0. then
set plugin_fade = plugin_fade - LIGHTNING_FADE_INTEVAR
call SetLightningColor(plugin_lightning,LIGHTNING_COLOR_RED,LIGHTNING_COLOR_GREEN,LIGHTNING_COLOR_BLUE,plugin_fade)
if not plugin_destroy then
call SetUnitState(plugin_unit,UNIT_STATE_MANA,GetUnitState(plugin_unit,UNIT_STATE_MANA)+plugin_intevar)
else
call SetUnitState(plugin_unit,UNIT_STATE_MANA,GetUnitState(plugin_unit,UNIT_STATE_MANA)-plugin_intevar)
endif
else
set Plugin_Struct_Data[i] = Plugin_Struct_Data[Plugin_MUI]
set Plugin_Struct_Data[Plugin_MUI] = -2
set Plugin_MUI = Plugin_MUI - 1
if Plugin_MUI == -1 then
call PauseTimer(TIMER_2)
endif
call DestroyEffect(plugin_effect)
call DestroyLightning(plugin_lightning)
set plugin_effect = null
set plugin_lightning = null
set plugin_unit = null
set plugin_caster = null
call destroy()
endif
set i = i + 1
endloop
endmethod
static method add takes string lmodel,unit u,unit caster,real mana,boolean destroy returns nothing
local thistype this = allocate()
set Plugin_MUI = Plugin_MUI + 1
set Plugin_Struct_Data[Plugin_MUI] = this
set plugin_lightning = AddLightningEx(lmodel,true,GetUnitX(caster),GetUnitY(caster),GetUnitFlyHeight(caster),GetUnitX(u),GetUnitY(u),GetUnitFlyHeight(u))
call SetLightningColor(plugin_lightning,LIGHTNING_COLOR_RED,LIGHTNING_COLOR_GREEN,LIGHTNING_COLOR_BLUE,1.)
set plugin_unit = u
set plugin_caster = caster
set plugin_mana = mana
set plugin_intevar = plugin_mana*LIGHTNING_FADE_INTEVAR
set plugin_destroy = destroy
call DestroyEffect(AddSpecialEffectTarget(EFFECT_LINKED,u,ATTACH_POINT_LINKED))
if plugin_destroy then
set plugin_effect = AddSpecialEffectTarget(BUFF_EFFECT_ENEMY,u,ATTACH_POINT)
else
set plugin_effect = AddSpecialEffectTarget(BUFF_EFFECT,u,ATTACH_POINT)
endif
if Plugin_MUI == 0 then
call TimerStart(TIMER_2,PERIODIC,true,function thistype.onPeriodic)
endif
endmethod
endstruct
endlibrary