Flare
Stops copies me!
- Reaction score
- 662
Seeing as I was bored, and felt the need to poke around with some new stuff (so the AIDS and Damage usage is questionable, and Event is only there for Damage )... I present to you, Corruption!
Corruption
Inflicts an agonising curse on the target, causing them to take damage over time and amplifying all damage dealt by the caster to the target. Deals 20/25/30 damage per second for 5/7/9 seconds, amplifies damage by 10/15/20%.
Visually, the spell is fairly simple - no (really) big fancy SFX, no really weird mechanics
Technical details:
Requires NewGen WE and WC3 TFT v1.24 (or above)
Coded in vJASS
Code: (I can have silly ASCII art too! )
Yes, I know there's the potential for A LOT of hashtables to be created, but I couldn't think of any other way to allow association between one caster and multiple targets.
Screenshot:
So... comments, criticism, etc?
Changelog:
Corruption
Inflicts an agonising curse on the target, causing them to take damage over time and amplifying all damage dealt by the caster to the target. Deals 20/25/30 damage per second for 5/7/9 seconds, amplifies damage by 10/15/20%.
Visually, the spell is fairly simple - no (really) big fancy SFX, no really weird mechanics
Technical details:
Requires NewGen WE and WC3 TFT v1.24 (or above)
Coded in vJASS
Code: (I can have silly ASCII art too! )
JASS:
// ______ __ _
// / ____/___ ____________ ______ / /_(_)___ ____
// / / / __ \/ ___/ ___/ / / / __ \/ __/ / __ \/ __ \
// / /___/ /_/ / / / / / /_/ / /_/ / /_/ / /_/ / / / /
// \____/\____/_/ /_/ \__,_/ .___/\__/_/\____/_/ /_/
// /_/
//Corruption, by Flare
//Requires: NewGen World Editor
// Warcraft 3: The Frozen Throne v1.23b (or above)
// Advanced Indexing & Data Storage (AIDS), by Jesus4Lyf
// TimerUtils, by Vexorian
// Event, by Jesus4Lyf
// Damage, by Jesus4Lyf
// Corruption [spell] - 'A000'
scope Corruption initializer Init
//CONFIGURABLE PROPERTIES
globals
private constant integer SPELL_ID = 039;A000039;
private constant real TICK = 1.
private constant string DEBUFF_SFX = "Abilities\\Spells\\Undead\\Curse\\CurseTarget.mdl"
private constant string DOT_TICK_SFX = "Abilities\\Weapons\\AvengerMissile\\AvengerMissile.mdl"
private constant string DAMAGE_AMP_SFX = "Abilities\\Spells\\Undead\\DeathCoil\\DeathCoilSpecialArt.mdl"
private constant string DEBUFF_ATTACH_PT = "overhead"
private constant string PROC_ATTACH_PT = "chest"
private constant attacktype AT = ATTACK_TYPE_MAGIC
private constant damagetype DT = DAMAGE_TYPE_NORMAL
private constant weapontype WT = WEAPON_TYPE_WHOKNOWS
endglobals
private function GetDuration takes unit u returns real
return 3. + GetUnitAbilityLevel (u, SPELL_ID) * 2.
endfunction
private function GetDamageMultiplier takes unit u returns real
return 0.05 + GetUnitAbilityLevel (u, SPELL_ID) * 0.05
endfunction
private function GetTickDamage takes unit u returns real
return 15. + GetUnitAbilityLevel (u, SPELL_ID) * 5.
endfunction
//END OF CONFIGURABLE PROPERTIES
private struct CasterData extends array
//!runtextmacro AIDS ()
//Target is parent key, caster is child key
hashtable ht
endstruct
private struct TargetData
unit caster
unit target
boolean dotdamage
real multiplier
real tickdamage
real dur
effect fx
endstruct
private function TimerFunc takes nothing returns nothing
local timer t = GetExpiredTimer ()
local TargetData a = GetTimerData (t)
local CasterData b
set a.dur = a.dur - TICK
if a.dur <= 0 or IsUnitType (a.target, UNIT_TYPE_DEAD) == true then
call ReleaseTimer (t)
set b = CasterData[GetUnitIndex (a.caster)]
call FlushChildHashtable (b.ht, GetHandleId (a.target))
call DestroyEffect (a.fx)
call a.destroy ()
else
set a.dotdamage = true
call UnitDamageTarget (a.caster, a.target, a.tickdamage, false, true, AT, DT, WT)
call DestroyEffect (AddSpecialEffectTarget (DOT_TICK_SFX, a.target, PROC_ATTACH_PT))
set a.dotdamage = false
endif
endfunction
private function DamageTriggerFunc takes nothing returns boolean
local unit dmger
local unit dmged
local real dmg = GetEventDamage ()
local trigger t
local integer id1
local integer id2
local CasterData a
local TargetData b
if dmg > 0 then
set t = GetTriggeringTrigger ()
set dmged = GetTriggerUnit ()
set id1 = GetHandleId (dmged)
set dmger = GetEventDamageSource ()
set id2 = GetHandleId (dmger)
set a = CasterData[GetUnitIndex (dmger)]
if HaveSavedInteger (a.ht, id1, id2) then
set b = LoadInteger (a.ht, id1, id2)
if b.dotdamage == false then
call DisableTrigger (t)
call UnitDamageTarget (dmger, dmged, dmg * b.multiplier, false, true, AT, DT, WT)
call DestroyEffect (AddSpecialEffectTarget (DAMAGE_AMP_SFX, dmged, PROC_ATTACH_PT))
call EnableTrigger (t)
endif
endif
set dmger = null
set dmged = null
set t = null
endif
return false
endfunction
private function SpellTriggerFunc takes nothing returns boolean
local unit cast
local unit targ
local integer cid
local integer tid
local CasterData a
local TargetData b
local timer t
if GetSpellAbilityId () == SPELL_ID then
set cast = GetTriggerUnit ()
set cid = GetHandleId (cast)
set targ = GetSpellTargetUnit ()
set tid = GetHandleId (targ)
set a = CasterData[GetUnitIndex (cast)]
if a.ht == null then
set a.ht = InitHashtable ()
endif
if HaveSavedInteger (a.ht, tid, cid) then
set b = LoadInteger (a.ht, tid, cid)
set b.dur = GetDuration (b.caster)
set b.multiplier = GetDamageMultiplier (b.caster)
set b.dotdamage = false
set b.tickdamage = GetTickDamage (b.caster)
else
set b = TargetData.create ()
set b.fx = AddSpecialEffectTarget (DEBUFF_SFX, targ, DEBUFF_ATTACH_PT)
set b.caster = cast
set b.target = targ
set b.tickdamage = GetTickDamage (b.caster)
set b.multiplier = GetDamageMultiplier (b.caster)
set b.dur = GetDuration (cast)
set b.dotdamage = false
call SaveInteger (a.ht, tid, cid, b)
set t = NewTimer ()
call SetTimerData (t, b)
call TimerStart (t, TICK, true, function TimerFunc)
endif
set cast = null
set targ = null
endif
return false
endfunction
private function Init takes nothing returns nothing
local trigger t = CreateTrigger ()
call TriggerRegisterAnyUnitEventBJ (t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition (t, Condition (function SpellTriggerFunc))
set t = CreateTrigger ()
call Damage_RegisterEvent (t)
call TriggerAddCondition (t, Condition (function DamageTriggerFunc))
endfunction
endscope
Yes, I know there's the potential for A LOT of hashtables to be created, but I couldn't think of any other way to allow association between one caster and multiple targets.
Screenshot:
So... comments, criticism, etc?
Changelog:
Code:
v1 - Initial release
v1.1 - Local handles nulled
v1.2 - Duration and spell stats now update on refresh