Name | Type | is_array | initial_value |
//TESH.scrollpos=248
//TESH.alwaysfold=0
////////////////////////////////////////////////////////////////////
// Blight Curse V1.0 //
// Author: Hashjie //
// //
// //
// Credits: //
// - fireblasts //
// //
// for those of you wondering, I give fireblasts full permission //
// to upload this resource to the hive. he came up with the //
// original concept of the spell. //
// //
// //
// The spell works as followed: //
// Whenever a unit casts Blight Curse, all units within a //
// specified range of the target will get affected by a buff //
// that does damage over time. How much damage is done, how much //
// range it has, how much range it gains, the duration of the //
// spell, the number of units infected and the number of //
// infections gained per level are all configurable. Basically //
// this spell will infect units that come within range of the //
// unit it is casted on or are already in range. //
////////////////////////////////////////////////////////////////////
scope BlightCurse
globals
//--------------------------------------------------------------------------//
// CONFIGURATION //
//--------------------------------------------------------------------------//
// SPELL_ID: //
// The SPELL_ID is the raw code for the spell ability in the object editor. //
// To see rawcodes, press control+d inside the editor. //
//--------------------------------------------------------------------------//
constant integer SPELL_ID = 'A000'
//--------------------------------------------------------------------------//
// DUMMY_UNIT: //
// The DUMMY_UNIT is the raw code for the dumy unit that is used to cast the//
// blight dummy spell that adds the blight buff to the enemies. //
//--------------------------------------------------------------------------//
constant integer DUMMY_UNIT = 'h000'
//--------------------------------------------------------------------------//
// BUFF_ID: //
// The BUFF_ID is the rawcode of the buff that is applied to the infected //
// units. //
//--------------------------------------------------------------------------//
constant integer BUFF_ID = 'B000'
//--------------------------------------------------------------------------//
// EFFECT: //
// The EFFECT is the path to an effect that is created on the position of //
// the units that gets infected. //
//--------------------------------------------------------------------------//
constant string EFFECT = "Abilities\\Spells\\NightElf\\CorrosiveBreath\\ChimaeraAcidTargetArt.mdl"
//--------------------------------------------------------------------------//
// RANGE: //
// The RANGE is the initial range around the target where units can get //
// infected from. //
//--------------------------------------------------------------------------//
constant real RANGE = 300
//--------------------------------------------------------------------------//
// RANGE_PER_LEVEL: //
// The RANGE_PER_LEVEL indicates how much extra range is added each level //
// of the spell. //
//--------------------------------------------------------------------------//
constant real RANGE_PER_LEVEL = 50
//--------------------------------------------------------------------------//
// DAMAGE: //
// The DAMAGE is the amount of damage per second against the infected units.//
//--------------------------------------------------------------------------//
constant real DAMAGE = 20
//--------------------------------------------------------------------------//
// DURATION: //
// The DURATION is how long the spell lasts/untill the buff wears off. //
//--------------------------------------------------------------------------//
constant real DURATION = 10
//--------------------------------------------------------------------------//
// INFECTIONS: //
// The INFECTIONS is the inital amount of maximum infections the spell must //
// have. //
//--------------------------------------------------------------------------//
constant integer INFECTIONS = 5
//--------------------------------------------------------------------------//
// INFECTIONS_PER_LEVEL: //
// The INFECTIONS_PER_LEVEL is the amount of extra infections it can have //
// per level of the spell. //
//--------------------------------------------------------------------------//
constant integer INFECTIONS_PER_LEVEL = 1
//--------------------------------------------------------------------------//
// TIMEOUT: (WARNING) //
// Please leave this value as is and don't touch it. If you mess with this //
// value you will mess with the duration and interval of the spell. //
//--------------------------------------------------------------------------//
constant real TIMEOUT = 0.03125
endglobals
struct BlightCurse
private thistype next
private thistype prev
private static timer time = CreateTimer()
private integer tick1
private integer tick2
private integer level
private integer infections
private player owner
private unit caster
private unit target
private group targets
private group temp
private group swap
private boolean infected
private method destroy takes nothing returns nothing
local unit u
call this.deallocate()
set this.next.prev = this.prev
set this.prev.next = this.next
if this.next == 1 then
call PauseTimer(time)
endif
set this.caster = null
set this.target = null
set this.owner = null
loop
set u = FirstOfGroup(this.targets)
exitwhen u == null
call UnitRemoveAbility(u, BUFF_ID)
call GroupRemoveUnit(this.targets, u)
endloop
call DestroyGroup(this.targets)
call DestroyGroup(this.temp)
call DestroyGroup(this.swap)
endmethod
private static method periodic takes nothing returns nothing
local thistype this = thistype(0).next
local unit u
local unit dummy
local real unitX
local real unitY
loop
exitwhen this == 0
if this.tick2 == DURATION then
call this.destroy()
endif
set this.tick1 = this.tick1 + 1
if this.tick1 == 4 then
if not this.infected then
set unitX = GetUnitX(this.target)
set unitY = GetUnitY(this.target)
call GroupEnumUnitsInRange(this.temp, unitX, unitY, RANGE + (this.level * RANGE_PER_LEVEL), null)
loop
set u = FirstOfGroup(this.temp)
exitwhen u == null
if GetUnitTypeId(u) != DUMMY_UNIT and GetWidgetLife(u) > 0 and IsUnitEnemy(u, this.owner) then
if this.infections < (INFECTIONS + (this.level * INFECTIONS_PER_LEVEL)) then
if GetUnitAbilityLevel(u, BUFF_ID) == 0 then
set unitX = GetUnitX(u)
set unitY = GetUnitY(u)
call DestroyEffect(AddSpecialEffect(EFFECT, unitX, unitY))
set dummy = CreateUnit(this.owner, DUMMY_UNIT, unitX, unitY, 0)
call UnitApplyTimedLife(dummy, 'BTLF', 1)
call IssueTargetOrder(dummy, "soulburn", u)
call GroupAddUnit(this.targets, u)
set this.infections = this.infections + 1
endif
elseif this.infections == (INFECTIONS + (this.level * INFECTIONS_PER_LEVEL)) then
set this.infected = true
endif
endif
call GroupRemoveUnit(this.temp, u)
endloop
endif
endif
if this.tick1 == 32 then
loop
set u = FirstOfGroup(this.targets)
exitwhen u == null
if GetUnitAbilityLevel(u, BUFF_ID) > 0 then
call UnitDamageTarget(this.caster, u, DAMAGE, true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS)
endif
call GroupAddUnit(this.temp, u)
call GroupRemoveUnit(this.targets, u)
endloop
set this.swap = this.targets
set this.targets = this.temp
set this.temp = this.swap
set this.tick2 = this.tick2 + 1
set this.tick1 = 0
endif
set this = this.next
endloop
set u = null
set dummy = null
endmethod
private static method run takes nothing returns boolean
local thistype this
local unit u
local unit dummy
local real unitX
local real unitY
if GetSpellAbilityId() == SPELL_ID then
set this = thistype.allocate()
set this.next = 0
set this.prev = thistype(0).prev
set thistype(0).prev.next = this
set thistype(0).prev = this
if this.next == 0 then
call TimerStart(time, TIMEOUT, true, function thistype.periodic)
endif
set this.caster = GetTriggerUnit()
set this.target = GetSpellTargetUnit()
set this.owner = GetTriggerPlayer()
set this.level = GetUnitAbilityLevel(this.caster, SPELL_ID)
set this.tick1 = 0
set this.tick2 = 0
set this.temp = CreateGroup()
set this.targets = CreateGroup()
set this.infections = 0
set this.infected = false
set unitX = GetUnitX(this.target)
set unitY = GetUnitY(this.target)
call DestroyEffect(AddSpecialEffect(EFFECT, unitX, unitY))
set dummy = CreateUnit(this.owner, DUMMY_UNIT, unitX, unitY, 0)
call UnitApplyTimedLife(dummy, 'BTLF', 1)
call IssueTargetOrder(dummy, "soulburn", this.target)
call GroupAddUnit(this.targets, this.target)
set this.infections = this.infections + 1
call GroupEnumUnitsInRange(this.temp, unitX, unitY, RANGE + (this.level * RANGE_PER_LEVEL), null)
loop
set u = FirstOfGroup(this.temp)
exitwhen u == null
if GetUnitTypeId(u) != DUMMY_UNIT and GetWidgetLife(u) > 0 and IsUnitEnemy(u, this.owner) then
if this.infections < (INFECTIONS + (this.level * INFECTIONS_PER_LEVEL)) then
if GetUnitAbilityLevel(u, BUFF_ID) == 0 then
set unitX = GetUnitX(u)
set unitY = GetUnitY(u)
call DestroyEffect(AddSpecialEffect(EFFECT, unitX, unitY))
set dummy = CreateUnit(this.owner, DUMMY_UNIT, unitX, unitY, 0)
call UnitApplyTimedLife(dummy, 'BTLF', 1)
call IssueTargetOrder(dummy, "soulburn", u)
call GroupAddUnit(this.targets, u)
set this.infections = this.infections + 1
endif
elseif this.infections == (INFECTIONS + (this.level * INFECTIONS_PER_LEVEL)) then
set this.infected = true
endif
endif
call GroupRemoveUnit(this.temp, u)
endloop
endif
set u = null
set dummy = null
return false
endmethod
private static method onInit takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(t, Condition(function thistype.run))
set t = null
endmethod
endstruct
endscope