/***************************************************************
Healing Arcs v1.5
by mckill2009
****************************************************************
REQUIRED LIBRARIES:
- SpellEffectEvent by Bribe
- Table by Bribe
- DamageEvent by looking_for_help
****************************************************************/
library HealingArcs initializer Init uses SpellEffectEvent, Table, DamageEvent
globals
/***********************************************************
* RAW CODES: Press CTRL+D view and change raw codes from
* object editor accordingly
************************************************************/
private constant integer SPELL_ID = 'A000' //unit target spell to ally
private constant integer DUMMY_ID = 'h000' //unit who cast the healing arc
private constant integer BOLT_SPELL_ID = 'A001' //firebolt ID with arc
private constant integer BOLT_ORDER_ID = 852231 //firebolt order ID, must match with BOLT_SPELL_ID
/***********************************************************
* CONFIGURABLE GLOBALS
************************************************************/
private constant string HEAL_SFX = "Abilities\\Spells\\Human\\HolyBolt\\HolyBoltSpecialArt.mdl"
private constant string DAMAGE_SFX = "Abilities\\Spells\\Undead\\DeathCoil\\DeathCoilSpecialArt.mdl"
private constant string HEAL_ATTACHMENT = "overhead"
private constant string DAMAGE_ATTACHMENT = "chest"
private constant player NEUTRAL_PASSIVE = Player(15)
private constant attacktype ATK = ATTACK_TYPE_CHAOS
private constant damagetype DMG = DAMAGE_TYPE_DEATH
/***********************************************************
* NON-CONFIGURABLE GLOBALS
************************************************************/
private group g = CreateGroup()
private unit dummy
private player owner
private integer uID
private Table heal
endglobals
/***********************************************************
* CONFIGURABLE FUNCTIONS
************************************************************/
//Area of effect when searching allies to heal
private function GetAoE takes integer level returns real
return 200. * level + 300 //500, 700, 900, 1100, 1300
endfunction
//Targets only 1 enemy
private function GetDamageAmount takes integer level returns real
return 25. * level + 25 //50, 75, 100, 125, 150
endfunction
//Heals the main ally target
private function GetHealAmount takes integer level returns real
return 50. * level + 50 //100, 150, 200, 250, 300
endfunction
//Heal Amount of the allies nearby
private function GetHealAmountArc takes integer level returns real
return 50. * level + 50 //100, 150, 200, 250, 300
endfunction
private function UnitFilter takes unit u returns boolean
return not (IsUnitType(u, UNIT_TYPE_STRUCTURE) or IsUnitType(u, UNIT_TYPE_MECHANICAL))
endfunction
/***********************************************************
* NON-CONFIGURABLE FUNCTIONS
************************************************************/
private function UnitAlive takes unit u returns boolean
return not (IsUnitType(u, UNIT_TYPE_DEAD) or GetUnitTypeId(u)==0 or u==null)
endfunction
private function IsAllyUnitDamaged takes unit u returns boolean
return GetWidgetLife(u) < GetUnitState(u, UNIT_STATE_MAX_LIFE)
endfunction
private function ArcLands takes nothing returns nothing
if PDDS.source==dummy then
if UnitFilter(PDDS.target) then
set uID = GetHandleId(PDDS.target)
set owner = heal.player[uID]
if IsUnitEnemy(PDDS.target, owner) then
call UnitDamageTarget(dummy, PDDS.target, GetDamageAmount(heal[uID]), false, false, ATK, DMG, null)
call DestroyEffect(AddSpecialEffectTarget(DAMAGE_SFX, PDDS.target, DAMAGE_ATTACHMENT))
else
call SetWidgetLife(PDDS.target, GetWidgetLife(PDDS.target) + heal.real[uID])
call DestroyEffect(AddSpecialEffectTarget(HEAL_SFX, PDDS.target, HEAL_ATTACHMENT))
endif
endif
set heal.player[uID] = null
call heal.remove(uID)
endif
endfunction
private function Cast takes nothing returns nothing
local unit first
local unit u = GetSpellTargetUnit()
local real x = GetUnitX(u)
local real y = GetUnitY(u)
local integer level = GetUnitAbilityLevel(GetTriggerUnit(), SPELL_ID)
local real healAmt = GetHealAmount(level)
local real healAmtArc = GetHealAmountArc(level)
call SetUnitX(dummy, x)
call SetUnitY(dummy, y)
call SetUnitOwner(dummy, GetTriggerPlayer(), false)
call SetUnitFlyHeight(dummy, GetUnitFlyHeight(u), 0)
if IsUnitEnemy(u, GetTriggerPlayer()) then
call UnitDamageTarget(GetTriggerUnit(), u, GetDamageAmount(level), false, false, ATK, DMG, null)
call DestroyEffect(AddSpecialEffectTarget(DAMAGE_SFX, u, DAMAGE_ATTACHMENT))
else
call SetWidgetLife(u, GetWidgetLife(u) + healAmt)
call DestroyEffect(AddSpecialEffectTarget(HEAL_SFX, u, HEAL_ATTACHMENT))
endif
call GroupEnumUnitsInRange(g, x, y, GetAoE(level), null)
loop
set first = FirstOfGroup(g)
exitwhen first==null
if UnitAlive(first) and first!=u then
if (IsAllyUnitDamaged(first) or IsUnitEnemy(first, GetTriggerPlayer())) and UnitFilter(first) then
set uID = GetHandleId(first)
set heal[uID] = level
set heal.real[uID] = healAmtArc
set heal.player[uID] = GetTriggerPlayer()
call IssueTargetOrderById(dummy, BOLT_ORDER_ID, first)
endif
endif
call GroupRemoveUnit(g, first)
endloop
call SetUnitOwner(dummy, NEUTRAL_PASSIVE, false)
set u = null
endfunction
private function OnDeath takes nothing returns nothing
if heal.has(GetHandleId(GetTriggerUnit())) then
set heal.player[GetHandleId(GetTriggerUnit())] = null
call heal.remove(GetHandleId(GetTriggerUnit()))
endif
endfunction
private function Init takes nothing returns nothing
call RegisterPlayerUnitEvent(EVENT_PLAYER_UNIT_DEATH, function OnDeath)
call RegisterSpellEffectEvent(SPELL_ID, function Cast)
set dummy = CreateUnit(NEUTRAL_PASSIVE, DUMMY_ID, 0,0,0)
call UnitRemoveAbility(dummy, 'Amov')
call UnitAddAbility(dummy, BOLT_SPELL_ID)
call AddDamageHandler(function ArcLands)
set heal = Table.create()
endfunction
endlibrary