/*
Rift of Mana
by Adiktuz
Requires:
-> Nova by Adiktuz
-> SpellEffectEvent by Bribe
Description:
Creates a portal at the target point that connects to another dimension. The portal
causes energy disruptions around the area, damaging nearby enemies and saps away
their mana. If the mana of affected enemies drop below the threshold value,
minions are summoned from the portal. When the portal fully opens, a powerful
creature is summoned then the portal suddenly closes.
How to import:
1)Copy the Spell and Nova trigger folders to your map
2)Import the dummy.mdx and copy paste the dummy unit in case you don't have one
3)Configure to your liking
*/
library RiftOfMana initializer init requires Nova, SpellEffectEvent
//Configuration globals
globals
//Rawcode of the spell
private constant integer SPELL_ID = 'A000'
//Rawcode of the minion
private constant integer MINION_ID = 'h000'
//Rawcode of the final summon
private constant integer SUMMON_ID = 'h001'
//Path to the special effect that will be used as the "border" of the portal
private constant string FX_1 = "Abilities\\Spells\\Human\\Thunderclap\\ThunderClapCaster.mdl"
//Path to the special effect that will be used as the center of the portal
private constant string FX_2 = "Abilities\\Spells\\Orc\\Voodoo\\VoodooAura.mdl"
//Path to the special effect that will be created when the final summoning is done
private constant string FX_3 = "Abilities\\Spells\\Other\\Charm\\CharmTarget.mdl"
//Attacktype of the portal's damage
private constant attacktype AT = ATTACK_TYPE_MAGIC
//Damagetype of the portal's damage
private constant damagetype DT = DAMAGE_TYPE_MAGIC
//Can the portal hit enemies that has no mp value?
private constant boolean NO_MP_HIT = false
//Can the portal hit enemies that has zero mp?
private constant boolean ZERO_MP_HIT = false
//Do not edit this one
private constant key KEY
endglobals
//Configuration Functions
//Returns the radius of the portal, which is the distance of the center of the FX_1
//from the target point
private function GetRadius takes unit caster, integer level returns real
return level * 100.0
endfunction
//Returnss the number of effects created at the portal's border
//Remember that each border deals damage
private function GetNofFX1 takes unit caster, integer level returns real
return 12.0
endfunction
//Returns the delay in between the creation of each border
private function GetDelayBase takes unit caster, integer level returns real
return 0.12
endfunction
//Returns the height at which the border models are created
private function GetHeight takes unit caster, integer level returns real
return 10.0
endfunction
//Returns the height at which the portal model is created
private function GetPortalHeight takes unit caster, integer level returns real
return 30.0
endfunction
//Returns the aoe at which each border can deal damage
private function GetFAoe takes unit caster, integer level returns real
return GetHeroInt(caster,true) + 50.0*level
endfunction
//Returns the HP damage dealt by each border
private function GetHPDamage takes unit caster, integer level returns real
return GetHeroInt(caster,true)*0.1*level
endfunction
//Returns the MP damage dealt by each border
private function GetMPDamage takes unit caster, integer level returns real
return GetHeroInt(caster,true)*level*1.0
endfunction
//Returns the value of mana at which if the enemies hit by the border
//goes below, minions will be summoned
private function GetThreshold takes unit caster, integer level returns real
return 50.0*level
endfunction
//Returns the scale of the border models
private function GetScale takes unit caster, integer level returns real
return 1.0
endfunction
//Returns the scale of the portal model
private function GetPortalScale takes unit caster, integer level returns real
return 0.8 + 0.2*level
endfunction
//Returns the summon duration of the minions
private function GetMinionDuration takes unit caster, integer level returns real
return 5.0*level
endfunction
//Returns the summon duration of the final summon
private function GetSummonDuration takes unit caster, integer level returns real
return 20.0*level
endfunction
//Returns the number of border rotations
//Portal duration = Rotations*delaybase*NumberOfBorders
private function GetRotations takes unit caster, integer level returns integer
return 5*level
endfunction
//This function fires when the spell is used
private function Fire takes nothing returns nothing
local unit u = GetTriggerUnit()
local integer level = GetUnitAbilityLevel(u,SPELL_ID)
local integer i = 0
local integer i2 = 0
local integer rotations = GetRotations(u,level)
local real x = GetSpellTargetX()
local real y = GetSpellTargetY()
local real delaybase = GetDelayBase(u,level)
local real offset = GetRadius(u,level)
local real nfx1 = GetNofFX1(u,level)
local real angle = (360.0 / nfx1)*bj_DEGTORAD
local real faoe = GetFAoe(u,level)
local real scale = GetScale(u,level)
local real damage = GetHPDamage(u,level)
local real height = GetHeight(u,level)
local real delay2 = 0.0
loop
exitwhen i2 == rotations
loop
exitwhen i == nfx1
call NovaSystem.SimpleCreateDelay(u, x + Cos(angle*i)*offset, y + Sin(angle*i)*offset, delay2 + delaybase*i, 0.0, faoe, height,/*
*/ damage, scale, FX_1, AT, DT, SPELL_ID)
set i = i + 1
endloop
set i2 = i2 + 1
set delay2 = i2*delaybase*nfx1
set i = 0
endloop
call NovaSystem.create(u, x, y, 0.0, 0.0, GetPortalHeight(u,level), 1, 1, delaybase, delay2,0.0, /*
*/GetPortalScale(u,level), false, false, false, FX_2, AT, DT, false, KEY)
set u = null
endfunction
//function that is run when a unit is damaged by the rotating edge of the portal
//used Static ifs to minimize after-compilation if-then-elses
//I saved the initial mana and final mana in order to ensure that
//when the ZERO_MP_HIT is false, the ability will still fire
//at the case that the target's mana just became zero (meaning it has a non-zero value before hit)
private function OnDamage takes nothing returns nothing
local NovaSystem nova = NovaSystem.data
local integer level = GetUnitAbilityLevel(nova.caster,SPELL_ID)
local real mana = GetUnitState(nova.filter, UNIT_STATE_MANA)
local real manadamage = GetMPDamage(nova.caster,level)
local real mana2 = mana - manadamage
local real threshold = GetThreshold(nova.caster,level)
local unit u
call SetUnitState(nova.filter, UNIT_STATE_MANA, mana2)
static if NO_MP_HIT then
static if ZERO_MP_HIT then
if mana2 < threshold then
set u = CreateUnit(nova.owner,MINION_ID,GetUnitX(nova.filter),GetUnitY(nova.filter),0.0)
call UnitApplyTimedLife(u, 'BTLF', GetMinionDuration(nova.caster,level))
call SetUnitExploded(u,true)
endif
else
if mana2 < threshold and mana > 0.0 then
set u = CreateUnit(nova.owner,MINION_ID,GetUnitX(nova.filter),GetUnitY(nova.filter),0.0)
call UnitApplyTimedLife(u, 'BTLF', GetMinionDuration(nova.caster,level))
call SetUnitExploded(u,true)
endif
endif
else
if GetUnitState(nova.filter, UNIT_STATE_MAX_MANA) > 0.0 then
static if ZERO_MP_HIT then
if mana2 < threshold then
set u = CreateUnit(nova.owner,MINION_ID,GetUnitX(nova.filter),GetUnitY(nova.filter),0.0)
call UnitApplyTimedLife(u, 'BTLF', GetMinionDuration(nova.caster,level))
call SetUnitExploded(u,true)
endif
else
if mana2 < threshold and mana > 0.0 then
set u = CreateUnit(nova.owner,MINION_ID,GetUnitX(nova.filter),GetUnitY(nova.filter),0.0)
call UnitApplyTimedLife(u, 'BTLF', GetMinionDuration(nova.caster,level))
call SetUnitExploded(u,true)
endif
endif
endif
endif
set u = null
endfunction
//function that is run when the portal reaches the max number of rotations
private function OnFinish takes nothing returns nothing
local NovaSystem nova = NovaSystem.data
local unit u = CreateUnit(nova.owner,SUMMON_ID,nova.x,nova.y,0.0)
call UnitApplyTimedLife(u, 'BTLF', GetSummonDuration(nova.caster,GetUnitAbilityLevel(nova.caster,SPELL_ID)))
call SetUnitExploded(u,true)
call DestroyEffect(AddSpecialEffectTarget(FX_3,u,"origin"))
set u = null
endfunction
//init function of the library
//Registers the spellevent and the onDamage and onFinish nova events
private function init takes nothing returns nothing
call RegisterSpellEffectEvent(SPELL_ID, function Fire)
call NovaSystem.RegisterOnDamage(SPELL_ID, function OnDamage)
call NovaSystem.RegisterOnFinish(KEY, function OnFinish)
endfunction
endlibrary