library Rupture requires CTL
globals
// Rawcode of the Rupture ability
private constant integer RUPTURE_RAWCODE = 'A000'
// Rawcode of the Rupture buff
private constant integer RUPTURE_BUFF_RAWCODE = 'B000'
// Period in that the extra damage will be done
private constant real PERIOD = 0.25
// Special effect (blood)
private constant string SPECIAL_EFFECT = "Objects\\Spawnmodels\\Human\\HumanBlood\\BloodElfSpellThiefBlood.mdl"
// Special effect attachment
private constant string ATTACHMENT_POINT = "chest"
// Rupture initial damage
private constant real INITIAL_DAMAGE = 150.
// Rupture attack type
private constant attacktype ATTACK_TYPE = ATTACK_TYPE_NORMAL
// Rupture damage type (universal = "pure")
private constant damagetype DAMAGE_TYPE = DAMAGE_TYPE_UNIVERSAL
// Do you want preload the special effect?
private constant boolean PRELOAD = true
endglobals
// Returns the distance covered by the target
// a_x and a_y represents the actual position of the target
// x and y represents the position of the unit in the beggining of the timer
// Remember, the x and y variables are updated every time when timer expires
private function getDistance takes real x, real y, real a_x, real a_y returns real
return SquareRoot((a_x - x) * (a_x - x) + (a_y - y) * (a_y - y))
endfunction
// Returns the initial damage
private function getInitialDamage takes integer level returns real
return INITIAL_DAMAGE + (level * 50)
endfunction
// Returns the damage by the distance covered by the target
private function getDamage takes real distance, integer level returns real
return (distance * (20 * level)) / 100
endfunction
// Returns the affected units
private function affectedUnit takes unit target returns boolean
return true
endfunction
private keyword Init
private struct Spell extends array
// Caster
unit caster
// Rupture level
integer level
// Target
unit target
// a = actual (actual x of the target)
real a_x
// actual y
real a_y
// x of target
real x
// y of target
real y
// period, represents the period
// that the extra damage will be done (default: 0.25)
real period
implement CTL
// Distance covered by the target
local real distance
implement CTLExpire
// If the target still has the Rupture buff and is not dead...
if 0 < GetUnitAbilityLevel(this.target, RUPTURE_BUFF_RAWCODE) and not(IsUnitType(this.target, UNIT_TYPE_DEAD)) then
// If the PERIOD seconds was pass...
if PERIOD < this.period then
// Reset period to 0
set this.period = 0.
// Actual X and Y of the target
set this.a_x = GetUnitX(this.target)
set this.a_y = GetUnitY(this.target)
set distance = getDistance(this.x, this.y, this.a_x, this.a_y)
// Make the extra damage only if distance is greater than 0
// but less than 1300
if 0 < distance and distance < 1300 then
call DestroyEffect(AddSpecialEffectTarget(SPECIAL_EFFECT, this.target, ATTACHMENT_POINT))
call UnitDamageTarget(this.caster, this.target, getDamage(distance, this.level), false, false, ATTACK_TYPE, DAMAGE_TYPE, null)
endif
// Refreshing the coordenates of the target
set this.x = this.a_x
set this.y = this.a_y
else
// If the PERIOD seconds was not pass, add
// the period of the CTL timer (library)
set this.period = this.period + 0.031250000
endif
else
set this.caster = null
set this.target = null
call this.destroy()
endif
implement CTLNull
implement CTLEnd
private static method run takes nothing returns boolean
local thistype this
// If the ability being cast is the Rupture and the target can be affected
// (units that can be affected can be changed in the affectedUnit function)
if GetSpellAbilityId() == RUPTURE_RAWCODE and affectedUnit(GetSpellTargetUnit()) then
set this = thistype.create()
set this.caster = GetTriggerUnit()
set this.target = GetSpellTargetUnit()
set this.level = GetUnitAbilityLevel(this.caster,RUPTURE_RAWCODE)
set this.x = GetUnitX(this.target)
set this.y = GetUnitY(this.target)
// Make the initial damage
call UnitDamageTarget(this.caster, this.target, getInitialDamage(this.level), false, false, ATTACK_TYPE, DAMAGE_TYPE, null)
endif
return false
endmethod
implement Init
endstruct
private module Init
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))
// Preload the special effect...
static if PRELOAD then
call Preload(SPECIAL_EFFECT)
endif
set t = null
endmethod
endmodule
endlibrary