// i'd like to thank hvo-busterkomo because i learned a lot from his fireball spell
// i'd like to thank Flame_phoenix because i learned a lot from his vjass tutorial
//thanks to Thanathos for helping me out
scope UnholyP initializer Init
//*************************************************************************************************************
//****Configuration. You can set these values to fit your needs.****
globals
private constant integer SPELL_ID = 'A000' //rawcode of the Unholy Presence ability
private constant integer BUFF_ID = 'B000' //rawcode of the Unholy Presence buff
private constant string TARGET_FX = "Abilities\\Weapons\\IllidanMissile\\IllidanMissile.mdl" //Special effect attached to the origin of enemy units
private constant string TARGET_ATTACH_FX = "origin" //attachement point for the effect
private constant real INTERVAL = 0.20 //This is the interval of the spell. .20 means units get damaged every .20 seconds, 2: every 2 seconds, etc.
private constant real STRENGTH = 0.05 //Set this to a value for how much you will heal (in %) off of Strength each second. 0 means you dont want to heal from Strength
private constant boolean STRENGTH_BONUSES = true //true means include bonuses for Strength
private constant real INTELLIGENCE = 0.00 //Set this to a value for how much you will heal (in %) off of Intelligence each second. 0 means you dont want to heal from intel
private constant boolean INTELLIGENCE_BONUSES = false //true means include bonuses for intelligence
private constant real AGILITY = 0.00 //Set this to a value for how much you will heal( in %) off of Agility each second. 0 means you dont want to heal from intel
private constant boolean AGILITY_BONUSES = false //true means include bonuses for agility
private constant attacktype AT = ATTACK_TYPE_NORMAL //attack type
private constant damagetype DT = DAMAGE_TYPE_FIRE //damage type
private constant weapontype WT = WEAPON_TYPE_WHOKNOWS //weapon type
endglobals
private constant function Damage takes integer level returns real
return (level * 5. + 100.) * INTERVAL //does 100 damage + (level of the ability x 5) divided by the interval
endfunction
private constant function AoE takes integer level returns real
return level * 5. + 350. // the AOE is 350 + (level of the ability x 5)
endfunction
private constant function Heal takes integer attribute returns real
return attribute * INTERVAL //takes attribute(s) you want of the triggering unit and multiplies it by 0.05 and divides it by the interval.
endfunction
//****End of configuration*************************************************************************************
//*************************************************************************************************************
//Don't touch this stuff unless you know what you're doing
private struct UnholyP
unit u
integer level
real attribute
endstruct
globals
private boolexpr filter
private constant group Group = CreateGroup()
private constant timer Tim = CreateTimer()
private integer total = 0
private player UnholyPOwner
private UnholyP array queue
endglobals
private function Timer takes nothing returns nothing
local integer i = 0
local UnholyP data
local unit f
local real damage
loop
exitwhen i >= total
set data = queue[i]
set UnholyPOwner = GetOwningPlayer(data.u)
call GroupClear(Group)//Clears the global group.
if (GetUnitAbilityLevel(data.u, BUFF_ID) > 0) then //Checks if the triggering unit has the buff (this means the spell can be dispelled)
call GroupEnumUnitsInRange(Group, GetUnitX(data.u), GetUnitY(data.u), AoE(data.level), filter)//Groups all nearby units.
set damage = Damage(data.level)
loop
set f = FirstOfGroup(Group) //first unit selected in range
exitwhen f == null
call DestroyEffect(AddSpecialEffectTarget(TARGET_FX, f, TARGET_ATTACH_FX)) // creates the effect at the origin of the enemy unit
call UnitDamageTarget(data.u, f, damage, true, false, AT, DT, WT)//Damages the enemy.
call SetWidgetLife(data.u, GetWidgetLife(data.u) + Heal(R2I(data.attribute))) //heals the triggering unit for 5% of its strength
call GroupRemoveUnit(Group, f)//Removes the first selected unit from the group
endloop
else
call data.destroy()
set total = total - 1
set queue[i] = queue[total]
set i = i - 1
endif
set i = i + 1
endloop
if total == 0 then
call PauseTimer(Tim)
endif
endfunction
private function Conditions takes nothing returns boolean
return GetSpellAbilityId() == SPELL_ID//Checks if the spell being used is this one
endfunction
private function UnholyP_Filter takes nothing returns boolean
return GetUnitState(GetFilterUnit(), UNIT_STATE_LIFE) > 0. and IsUnitEnemy(GetFilterUnit(), UnholyPOwner) and (IsUnitType(GetFilterUnit(), UNIT_TYPE_MAGIC_IMMUNE) == false)//Chooses which units are affected.
// Is the unit alive? Is the unit an enemy to the caster? Is the unit immune to spells?
endfunction
private function Actions takes nothing returns nothing
local UnholyP data = UnholyP.create()
set data.u = GetTriggerUnit() // stores the triggering unit into a struct
set data.level = GetUnitAbilityLevel(data.u, SPELL_ID)//Stores the level of the ability in a struct.
//thanks to -JonNny :D
set data.attribute = GetHeroStr(data.u, STRENGTH_BONUSES) * STRENGTH + GetHeroInt(data.u, INTELLIGENCE_BONUSES) * INTELLIGENCE + GetHeroAgi(data.u, AGILITY_BONUSES) * AGILITY
if total == 0 then
call TimerStart(Tim, INTERVAL, true, function Timer)
endif
set queue[total] = data
set total = total + 1
endfunction
private constant function AntiLeak takes nothing returns boolean
return true
endfunction
private function Init takes nothing returns nothing
local trigger trig = CreateTrigger()//Creates the trigger.
local filterfunc f = Filter(function AntiLeak)
local integer i = 0
loop
call TriggerRegisterPlayerUnitEvent(trig, Player(i),EVENT_PLAYER_UNIT_SPELL_EFFECT, f) // registers the event for each player who casts the spell
set i = i + 1
exitwhen i == bj_MAX_PLAYER_SLOTS
endloop
call TriggerAddCondition(trig, Condition(function Conditions))//Adds the condition.
call TriggerAddAction(trig, function Actions)//Adds the action.
call Preload(TARGET_FX)//Preloads the effect, preventing it from lagging the first time it's cast.
set filter = Filter(function UnholyP_Filter)//Stores a global boolexp. Much faster than creating and destroying one all the time.
call DestroyFilter(f)
set trig = null
set f = null
endfunction
endscope