- Reaction score
- 91
// needs a better name...
GUI/JASS/vJASS? vJASS
MUI? Yes
Lagless? Yes
Requires?
TimerUtils
LightLeaklessDamageDetect
PUI
Description:
Sends a coil of unholy energy that blasts an enemy unit and curses it with dark power, which causes the target to take amplified damage. Enemies that come close to the main affected unit will be affected by the curse. Bonus damage, duration and AoE increases per level.
Code:
Screenshots:
http://i42.tinypic.com/xlz0cg.gif
http://i39.tinypic.com/2qw04tj.gif
Read Me:

GUI/JASS/vJASS? vJASS
MUI? Yes
Lagless? Yes
Requires?
TimerUtils
LightLeaklessDamageDetect
PUI
Description:
Sends a coil of unholy energy that blasts an enemy unit and curses it with dark power, which causes the target to take amplified damage. Enemies that come close to the main affected unit will be affected by the curse. Bonus damage, duration and AoE increases per level.
Code:
JASS:
scope DeathCoil initializer Init
//! runtextmacro PUI_PROPERTY("private", "real", "AMPLIFY", "0.00")
//! runtextmacro PUI_PROPERTY("private", "integer", "TIME", "0")
//==============================================================================
// C O N F I G U R A T I O N M E N U
//==============================================================================
globals
// Raw code of the ability Death Coil.
private constant integer AID_RAW = 'A000'
// First special effect that is going to be attached on affected units.
private constant string SFX_ONE = "Abilities\\Spells\\Undead\\DeathandDecay\\DeathandDecayDamage.mdl"
// Attachment point of the first special effect.
private constant string AP_ONE = "hand right"
// Second special effect that is going to be attached on affected units.
private constant string SFX_TWO = "Abilities\\Spells\\Undead\\DeathandDecay\\DeathandDecayDamage.mdl"
// Attachment point of the second special effect.
private constant string AP_TWO = "hand left"
// Third special effect that is going to be attached on affected units.
private constant string SFX_THREE = "Abilities\\Spells\\NightElf\\Immolation\\ImmolationDamage.mdl"
// Attachment point of the third special effect.
private constant string AP_THREE = "chest"
// This is the frequency of detecting units around the unit affected by Death Coil.
private constant real ENUM_FREQUENCY = 0.33
// Period between attaching special effect on affected units.
private constant real SFX_PERIOD = 1.
private constant real MISSILE_SPEED = 950.
endglobals
private function DAMAGE takes unit cast returns real
return 75. * GetUnitAbilityLevel(cast, AID_RAW)
endfunction
// How much bonus damage should the spell deal.
private function AMPLIFIED_DAMAGE takes unit cast returns real
return GetUnitAbilityLevel(cast, AID_RAW) * 0.1 // 10%/20%/30%/40%
endfunction
// Area of effect of spreading the plague around a unit hit by Death Coil.
private function AMPLIFIED_AOE takes unit cast returns real
return 200.
endfunction
// Duration of the plague.
private function DURATION takes unit cast returns real
return I2R(8 + (GetUnitAbilityLevel(cast, AID_RAW) * 2))
endfunction
// Effect created when the missile hits its target.
private function EFFECT takes unit cast returns string
return "Abilities\\Spells\\Undead\\DeathCoil\\DeathCoilSpecialArt.mdl"
endfunction
// Attachment point of the special effect.
private function AP_EFFECT takes unit cast returns string
return "chest"
endfunction
//==============================================================================
// E N D O F C O N F I G U R A T I O N
//==============================================================================
globals
private group ENUM_GROUP = CreateGroup()
private group PLAGUED = CreateGroup()
private unit forFilter = null
endglobals
private struct Data
unit cast
unit targ
integer ticks
static method create takes unit cast, unit targ returns Data
local Data d = Data.allocate()
set d.cast = cast
set d.targ = targ
set d.ticks = R2I(DURATION(d.cast) / ENUM_FREQUENCY)
return d
endmethod
endstruct
private function GetEnemies takes nothing returns boolean
return IsUnitEnemy(GetFilterUnit(), GetOwningPlayer(forFilter)) and IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE) == false and GetWidgetLife(GetFilterUnit()) > 0.405
endfunction
private function GetPlaguedUnits takes nothing returns boolean
return AMPLIFY[GetFilterUnit()] > 0.00
endfunction
private function EffectHandler takes nothing returns nothing
local unit fir
call GroupClear(ENUM_GROUP)
call GroupEnumUnitsInRange(ENUM_GROUP, 0., 0., 999999., Condition(function GetPlaguedUnits))
loop
set fir = FirstOfGroup(ENUM_GROUP)
exitwhen fir == null
call DestroyEffect(AddSpecialEffectTarget(SFX_ONE, fir, AP_ONE))
call DestroyEffect(AddSpecialEffectTarget(SFX_TWO, fir, AP_TWO))
call DestroyEffect(AddSpecialEffectTarget(SFX_THREE, fir, AP_THREE))
call GroupRemoveUnit(ENUM_GROUP, fir)
endloop
endfunction
private function DurationHandler takes nothing returns nothing
local unit fir
call GroupClear(ENUM_GROUP)
call GroupEnumUnitsInRange(ENUM_GROUP, 0., 0., 999999., Condition(function GetPlaguedUnits))
loop
set fir = FirstOfGroup(ENUM_GROUP)
exitwhen fir == null
if TIME[fir] > 0 then
set TIME[fir] = TIME[fir] - 1
else
set AMPLIFY[fir] = 0.00
call GroupRemoveUnit(PLAGUED, fir)
endif
call GroupRemoveUnit(ENUM_GROUP, fir)
endloop
endfunction
private function OnDamage takes nothing returns boolean
local unit damager = GetEventDamageSource()
local unit damaged = GetTriggerUnit()
local real damage = GetEventDamage()
if AMPLIFY[damaged] > 0.00 then
call DisableDamageDetect()
call UnitDamageTarget(damager, damaged, damage * AMPLIFY[damaged], true, true, ATTACK_TYPE_MAGIC, DAMAGE_TYPE_MAGIC, null)
call EnableDamageDetect()
endif
set damager = null
set damaged = null
return false
endfunction
private function Conditions takes nothing returns boolean
return GetSpellAbilityId() == AID_RAW
endfunction
private function SpreadPlague takes nothing returns nothing
local timer tim = GetExpiredTimer()
local Data d = Data(GetTimerData(tim))
local unit fir
set forFilter = d.cast
call GroupClear(ENUM_GROUP)
call GroupEnumUnitsInRange(ENUM_GROUP, GetUnitX(d.targ), GetUnitY(d.targ), AMPLIFIED_AOE(d.cast), Condition(function GetEnemies))
loop
set fir = FirstOfGroup(ENUM_GROUP)
exitwhen fir == null
if not IsUnitInGroup(fir, PLAGUED) then
call GroupAddUnit(PLAGUED, fir)
if AMPLIFIED_DAMAGE(d.cast) > AMPLIFY[fir] then
set AMPLIFY[fir] = AMPLIFIED_DAMAGE(d.cast)
endif
set TIME[fir] = 2
endif
call GroupRemoveUnit(ENUM_GROUP, fir)
endloop
set d.ticks = d.ticks - 1
if d.ticks <= 0 then
call ReleaseTimer(tim)
call d.destroy()
endif
set tim = null
endfunction
private function Callback takes nothing returns nothing
local timer tim = GetExpiredTimer()
local Data d = Data(GetTimerData(tim))
call DisableDamageDetect()
call UnitDamageTarget(d.cast, d.targ, DAMAGE(d.cast), true, true, ATTACK_TYPE_MAGIC, DAMAGE_TYPE_MAGIC, null)
call EnableDamageDetect()
if AMPLIFIED_DAMAGE(d.cast) > AMPLIFY[d.targ] then
// Only the more powerful Death Coil will take effect.
set AMPLIFY[d.targ] = AMPLIFIED_DAMAGE(d.cast)
endif
set TIME[d.targ] = R2I(DURATION(d.cast))
if not IsUnitInGroup(d.targ, PLAGUED) then
call GroupAddUnit(PLAGUED, d.targ)
endif
call DestroyEffect(AddSpecialEffectTarget(EFFECT(d.cast), d.targ, AP_EFFECT(d.cast)))
call TimerStart(tim, ENUM_FREQUENCY, true, function SpreadPlague)
set tim = null
endfunction
private function Actions takes nothing returns nothing
local unit cast = GetTriggerUnit()
local unit targ = GetSpellTargetUnit()
local Data d = Data.create(cast, targ)
local real x = GetUnitX(cast) - GetUnitX(targ)
local real y = GetUnitY(cast) - GetUnitY(targ)
local timer tim = NewTimer()
set x = SquareRoot(x * x + y * y) / MISSILE_SPEED
call SetTimerData(tim, integer(d))
call TimerStart(tim, x, true, function Callback)
set cast = null
set targ = null
set tim = null
endfunction
private function Init takes nothing returns nothing
local trigger trig = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(trig, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(trig, Condition(function Conditions))
call TriggerAddAction(trig, function Actions)
call TimerStart(CreateTimer(), SFX_PERIOD, true, function EffectHandler)
call TimerStart(CreateTimer(), 1., true, function DurationHandler)
call AddOnDamageFunc(Condition(function OnDamage))
endfunction
endscope
Screenshots:
http://i42.tinypic.com/xlz0cg.gif
http://i39.tinypic.com/2qw04tj.gif
Read Me:
JASS:
Spell created by tyrande_ma3x. If you want to use it in your map, credits are not necessary but would be appreciated.
To implement:
- Copy the TimerUtils trigger in your map if you do not have it.
- Copy the PUI trigger in your map if you do not have it.
- Copy the LightLeaklesDamageDetect trigger in your map if you do not have it.
- Create a single-target spell based on whatever you like (or just copy the one in Object Editor and edit it)
- Copy the DeathCoil trigger and configure it if you want to change something.
Notes:
- The spell deals damage but that damage is not affected by the spell (it means it won't get amplified).
- If you cast Death Coil on some unit and that unit affects another unit, the second unit will not spread the disease.
- The duration of the disease is individual for every unit. If the main infected unit gets away from other units
they will be freed from the plague in two seconds.
- If you need another attachment system for this spell just contact me and I'll try to make it.
(this is in cases where you wouldn't want to implement a whole system just for one spell).
- Suggestions to improve this are welcome.
- If you would want another effect for this spell, feel free to edit the code
or tell me and I'll add it.
Attachments
-
38.1 KB Views: 168