Ayanami
칼리
- Reaction score
- 288
Introduction
Made another spellpack, because, why not?
Requirements
- JNGP
- AIDS
- Damage
- GroupUtils
- GTrigger
- Table
- Timer32
The spells:
Details
- The spells are vJASS
- They should be leak-less and lag-less
- It is MUI, meaning can be cast many times at the same instance
Implementation
Spells
Eagle Eye
Description:
Utilizing the shadows within the hero, the hero temporarily has sharper vision. This allows the hero to deal armor shattering blows for the duration. Any damage received from the hero during this duration will result in an armor penalty to the target for 5 seconds. The amount of armor shattered is dependant to the damage dealt. Maximum of 15 armor penalty.
Level 1 - 0.4% of damage as armor penalty. Buff lasts 8 seconds.
Level 2 - 0.6% of damage as armor penalty. Buff lasts 9 seconds.
Level 3 - 0.8% of damage as armor penalty. Buff lasts 10 seconds.
Level 4 - 1.0% of damage as armor penalty. Buff lasts 11 seconds.
Cast Range: Self
Target Type: Instant
Cooldown: 22 seconds
Screenshot:
Code:
Heartbreaker
Description:
Fires a bolt that pierces through the soul of the target, dealing damage. A shadow curse is also applied to the target and nearby enemy units. The curse takes effect after 3 seconds, which then enemies are stunned based on the damage taken. Enemies are immediately stunned if the maximum damage taken is reached.
Level 1 - 50 damage. 100 curse damage limit, 1 second stun limit.
Level 2 - 100 damage. 200 curse damage limit, 2 seconds stun limit.
Level 3 - 150 damage. 300 curse damage limit, 3 seconds stun limit.
Level 4 - 200 damage. 400 curse damage limit, 4 seconds stun limit.
Cast Range: 600
Target Type: Unit
Cooldown: 16 seconds
Screenshot:
Code:
Bolt Sequence
Description:
Fires a series of arrows at all enemies within the area, dealing physical damage. Every wave of arrows are released at 0.5 seconds intervals. Channels for 3 seconds.
Level 1 - 35 damage.
Level 2 - 50 damage.
Level 3 - 65 damage.
Level 4 - 80 damage.
Cast Range: 400
Target Type: Unit Area (400)
Cooldown: 20/19/18/17 seconds
Channeling
Screenshot:
Code:
Credits
Changelogs
Feedback will be appreciated.
Made another spellpack, because, why not?
Requirements
- JNGP
- AIDS
- Damage
- GroupUtils
- GTrigger
- Table
- Timer32
The spells:
- Eagle Eye [Active]
- Heartbreaker [Active]
- Bolt Sequence [Active]
Details
- The spells are vJASS
- They should be leak-less and lag-less
- It is MUI, meaning can be cast many times at the same instance
Implementation
JASS:
//==============================================================================
// SHADOW STING SPELLPACK v1.3
// BY Ayanami
//==============================================================================
//==============================================================================
// REQUIREMENTS
//==============================================================================
// - JNGP
// - AIDS
// - Damage
// * Event
// - GroupUtils
// - GTrigger
// - Timer32
// - Table
//==============================================================================
//==============================================================================
// IMPLEMENTATION
//==============================================================================
// 1) Copy the whole "Required Systems" Trigger folder
// 2) Save the map, it will take a bit longer than usual
// 3) Close the map and re-open it, then disable or delete the trigger "Objects"
// 4) Go to the Import Manager and export all resources, then import into map
// 5) Copy all 3 abilities under "Night Elf - Heroes"
// 6) Copy the whole "Shadow Sting Spellpack" Trigger folder
//==============================================================================
Spells
Eagle Eye
Description:
Utilizing the shadows within the hero, the hero temporarily has sharper vision. This allows the hero to deal armor shattering blows for the duration. Any damage received from the hero during this duration will result in an armor penalty to the target for 5 seconds. The amount of armor shattered is dependant to the damage dealt. Maximum of 15 armor penalty.
Level 1 - 0.4% of damage as armor penalty. Buff lasts 8 seconds.
Level 2 - 0.6% of damage as armor penalty. Buff lasts 9 seconds.
Level 3 - 0.8% of damage as armor penalty. Buff lasts 10 seconds.
Level 4 - 1.0% of damage as armor penalty. Buff lasts 11 seconds.
Cast Range: Self
Target Type: Instant
Cooldown: 22 seconds
Screenshot:
Code:
JASS:
library EagleEye uses AIDS, Damage, GT
globals
private integer array ARMORID
endglobals
//===========================================================================
// CONFIGURABLES
//===========================================================================
globals
private constant integer ABILID = 039;ABEE039; // raw code of ability "Eagle Eye"
private constant integer DUMABILID = 039;AEE0039; // raw code of ability "Eagle Eye (Buff)"
private constant integer BUFFID = 039;BEE0039; // raw code of buff "Eagle Eye"
private constant integer PRELOADID = 039;prel039; // raw code of unit "Preloader"
private constant string FX = "Abilities\\Spells\\Items\\SpellShieldAmulet\\SpellShieldCaster.mdl" // effect on target when damaged
private constant string FX_AT = "chest" // attachment point of FX
private constant real PERIOD = 0.10 // timer update frequency for buff checking
endglobals
private function SetUp takes nothing returns nothing
set ARMORID[0] = 039;dEE0039; // raw code of ability "Eagle Eye (Armor - -1's)"
set ARMORID[1] = 039;dEE1039; // raw code of ability "Eagle Eye (Armor - -10's)"
set ARMORID[2] = 039;dEE2039; // raw code of ability "Eagle Eye (Armor - -100's)"
set ARMORID[3] = 039;dEE3039; // raw code of ability "Eagle Eye (Armor - -1000's)"
set ARMORID[4] = 039;dEE4039; // raw code of ability "Eagle Eye (Armor - -10000's)"
endfunction
// duration of buff on caster
private constant function GetDuration takes integer level returns real
return 7. + level
endfunction
// duration of armor penalty
private constant function GetTargetDuration takes integer level returns real
return 5.
endfunction
// percentage of damage taken as armor penalty, where 1.00 = 100%
private constant function GetArmorPenalty takes integer level returns real
return 0.002 + (0.002 * level)
endfunction
// maximum armor penalty (supports up to 99999 armor reduction)
private constant function GetMaxPenalty takes integer level returns integer
return 15
endfunction
//===========================================================================
// END CONFIGURABLES
//===========================================================================
private struct Data
thistype next
thistype prev
unit u
real dur
static timer linkTimer = CreateTimer()
static integer linkCount = 0
static integer array store
private static method iterate takes nothing returns nothing
local thistype this = thistype(0)
loop
set this = this.next
exitwhen this == 0
if this.dur <= 0 then
set this.next.prev = this.prev
set this.prev.next = this.next
set linkCount = linkCount - 1
if linkCount == 0 then
call PauseTimer(linkTimer)
endif
call UnitRemoveAbility(this.u, DUMABILID)
call UnitRemoveAbility(this.u, BUFFID)
set store[GetUnitId(this.u)] = 0
call this.deallocate()
else
set this.dur = this.dur - PERIOD
endif
endloop
endmethod
private static method onCast takes nothing returns boolean
local thistype this
local unit u = GetTriggerUnit()
local integer id = GetUnitId(u)
if store[id] > 0 then
set this = store[id]
else
set this = thistype.allocate()
set thistype(0).next.prev = this
set this.next = thistype(0).next
set thistype(0).next = this
set this.prev = thistype(0)
if linkCount == 0 then
call TimerStart(linkTimer, PERIOD, true, function thistype.iterate)
endif
set linkCount = linkCount + 1
set this.u = GetTriggerUnit()
call UnitAddAbility(this.u, DUMABILID)
endif
set this.dur = GetDuration(GetUnitAbilityLevel(this.u, ABILID))
set u = null
return false
endmethod
private static method onInit takes nothing returns nothing
local trigger t = CreateTrigger()
call GT_RegisterStartsEffectEvent(t, ABILID)
call TriggerAddCondition(t, Condition(function thistype.onCast))
set t = null
endmethod
endstruct
private struct Damage
thistype next
thistype prev
unit u
real amount
real dur
static timer linkTimer = CreateTimer()
static integer linkCount = 0
static integer array store
private static method iterate takes nothing returns nothing
local thistype this = thistype(0)
local integer i
loop
set this = this.next
exitwhen this == 0
if this.dur <= 0 then
set this.next.prev = this.prev
set this.prev.next = this.next
set linkCount = linkCount - 1
if linkCount == 0 then
call PauseTimer(linkTimer)
endif
set i = 0
loop
exitwhen i > 4
call SetUnitAbilityLevel(this.u, ARMORID<i>, 1)
set i = i + 1
endloop
set store[GetUnitId(this.u)] = 0
call this.deallocate()
else
set this.dur = this.dur - PERIOD
endif
endloop
endmethod
private static method onDamage takes nothing returns boolean
local thistype this
local unit u = GetEventDamageSource()
local integer level
local integer id
local integer max
local integer value
local integer factor
local integer i
if GetUnitAbilityLevel(u, DUMABILID) == 1 then
set level = GetUnitAbilityLevel(u, ABILID)
set id = GetUnitId(GetTriggerUnit())
set max = GetMaxPenalty(level)
if store[id] > 0 then
set this = store[id]
set this.amount = this.amount + (GetEventDamage() * GetArmorPenalty(level))
else
set this = thistype.allocate()
set thistype(0).next.prev = this
set this.next = thistype(0).next
set thistype(0).next = this
set this.prev = thistype(0)
if linkCount == 0 then
call TimerStart(linkTimer, PERIOD, true, function thistype.iterate)
endif
set linkCount = linkCount + 1
set this.u = GetTriggerUnit()
set this.amount = GetEventDamage() * GetArmorPenalty(level)
set store[id] = this
endif
set this.dur = GetTargetDuration(level)
if this.amount > max then
set this.amount = max
endif
call DestroyEffect(AddSpecialEffectTarget(FX, this.u, FX_AT))
set value = R2I(this.amount)
set factor = 10000
set i = 4
loop
exitwhen i < 0
if GetUnitAbilityLevel(this.u, ARMORID<i>) == 0 then
call UnitAddAbility(this.u, ARMORID<i>)
endif
set level = value / factor
call SetUnitAbilityLevel(this.u, ARMORID<i>, level + 1)
set value = value - (level * factor)
set factor = factor / 10
set i = i - 1
endloop
endif
set u = null
return false
endmethod
private static method onInit takes nothing returns nothing
local trigger t = CreateTrigger()
local unit u = CreateUnit(Player(13), PRELOADID, 0, 0, 0)
local integer i = 4
call Damage_RegisterEvent(t)
call TriggerAddCondition(t, Condition(function thistype.onDamage))
call SetUp()
call UnitAddAbility(u, DUMABILID)
loop
exitwhen i < 0
call UnitAddAbility(u, ARMORID<i>)
set i = i - 1
endloop
call RemoveUnit(u)
set t = null
set u = null
endmethod
endstruct
endlibrary
</i></i></i></i></i>
Heartbreaker
Description:
Fires a bolt that pierces through the soul of the target, dealing damage. A shadow curse is also applied to the target and nearby enemy units. The curse takes effect after 3 seconds, which then enemies are stunned based on the damage taken. Enemies are immediately stunned if the maximum damage taken is reached.
Level 1 - 50 damage. 100 curse damage limit, 1 second stun limit.
Level 2 - 100 damage. 200 curse damage limit, 2 seconds stun limit.
Level 3 - 150 damage. 300 curse damage limit, 3 seconds stun limit.
Level 4 - 200 damage. 400 curse damage limit, 4 seconds stun limit.
Cast Range: 600
Target Type: Unit
Cooldown: 16 seconds
Screenshot:
Code:
JASS:
library Heartbreaker uses Damage, GroupUtils, T32, Table
constant native UnitAlive takes unit id returns boolean
//===========================================================================
// CONFIGURABLES
//===========================================================================
globals
private constant integer ABILID = 039;ABHe039; // raw code of ability "Heartbreaker"
private constant integer DUM_ABILID_1 = 039;AHe0039; // raw code of ability "Heartbreaker (Stun)"
private constant integer DUM_ABILID_2 = 039;AHe1039; // raw code of ability "Heartbreaker (Buff)"
private constant integer BUFFID_1 = 039;BHe0039; // raw code of buff "Heartbreaker (Stun)"
private constant integer BUFFID_2 = 039;BHe1039; // raw code of buff "Heartbreaker (Buff)"
private constant integer DUMMYID = 039;dHEA039; // raw code of unit "Heartbreaker Dummy"
private constant integer CASTERID = 039;cAST039; // raw code of unit "Caster Dummy"
private constant integer PRELOADID = 039;prel039; // raw code of unit "Preloader"
private constant string FX = "Abilities\\Spells\\Undead\\AnimateDead\\AnimateDeadTarget.mdl" // effect used upon being stunned
private constant string FX_AT = "origin" // attachment point of FX
private constant string PROJ_FX = "Objects\\Spawnmodels\\Undead\\UndeadDissipate\\UndeadDissipate.mdl" // effect used upon projectile impact
private constant boolean SHOWTEXT = true // true if floating text (displaying stun duration) is displayed
private constant string COLOR = "|cffff0000" // color code for floating text
private constant real FLOAT_ANGLE = bj_PI / 2 // floating angle of the floating text (radians)
private constant real SPEED = 1000.0 // distance traveled by projectile per second
private constant real TRUESPEED = SPEED * T32_PERIOD // distance per interval
private constant real COL_SIZE = 50. // collision size of projectile
private constant real PERIOD = 0.1 // timer update frequency for stun
private constant attacktype ATK = ATTACK_TYPE_NORMAL // attack type of damage
private constant damagetype DMG = DAMAGE_TYPE_MAGIC // damage type of damage
endglobals
// damage dealt
private constant function GetDamage takes integer level returns real
return 50. * level
endfunction
// damage limit for curse
private constant function GetDamageLimit takes integer level returns real
return 100. * level
endfunction
// stun limit for curse
private constant function GetStunLimit takes integer level returns real
return 1. * level
endfunction
// delay time before curse takes effect
private constant function GetDelayTime takes integer level returns real
return 3.
endfunction
// curse area of effect
private constant function GetArea takes integer level returns real
return 400.
endfunction
// target filter
private constant function GetFilter takes unit c, unit u returns boolean
return /*
*/ UnitAlive(u) /* // target is alive
*/ and IsUnitEnemy(u, GetOwningPlayer(c)) /* // target is an enemy
*/ and not IsUnitType(u, UNIT_TYPE_STRUCTURE) /* // target is not a structure
*/
endfunction
//===========================================================================
// END CONFIGURABLES
//===========================================================================
globals
private constant real TRUE_COL_SIZE = COL_SIZE * COL_SIZE
endglobals
private struct Curse
thistype next
thistype prev
unit u
unit tar
trigger trig
integer level
real damage
real damagelimit
real dur
static unit castDummy
static Table table
static timer linkTimer = CreateTimer()
static integer linkCount = 0
private static method iterate takes nothing returns nothing
local thistype this = thistype(0)
loop
set this = this.next
exitwhen this == 0
if this.dur <= 0 or not UnitAlive(this.tar) then
set this.next.prev = this.prev
set this.prev.next = this.next
set linkCount = linkCount - 1
if linkCount == 0 then
call PauseTimer(linkTimer)
endif
call UnitRemoveAbility(this.tar, BUFFID_1)
call this.deallocate()
else
if GetUnitAbilityLevel(this.tar, BUFFID_1) == 0 then
call IssueTargetOrder(castDummy, "firebolt", this.tar)
endif
set this.dur = this.dur - PERIOD
endif
endloop
endmethod
private method periodic takes nothing returns nothing
local boolean b = UnitAlive(this.tar)
local integer id
static if SHOWTEXT then
local texttag t
local integer digitone
local integer digittwo
endif
if this.dur <= 0 or this.damage >= this.damagelimit or not b then
if b and this.damage > 0 then
if this.damage > this.damagelimit then
set this.damage = this.damagelimit
endif
set this.dur = (this.damage / this.damagelimit) * GetStunLimit(this.level)
static if SHOWTEXT then
set digitone = R2I(this.dur)
set digittwo = R2I((this.dur - digitone) * 10)
set t = CreateTextTag()
call SetTextTagText(t, COLOR + I2S(digitone) + "." + I2S(digittwo) + "!|r", 0.0253)
call SetTextTagPosUnit(t, this.tar, 0)
call SetTextTagColor(t, 255, 255, 255, 255)
call SetTextTagVelocity(t, 0.0355 * Cos(FLOAT_ANGLE), 0.0355 * Sin(FLOAT_ANGLE))
call SetTextTagPermanent(t, false)
call SetTextTagLifespan(t, 2.50)
endif
call IssueTargetOrder(castDummy, "firebolt", this.tar)
call DestroyEffect(AddSpecialEffectTarget(FX, this.tar, FX_AT))
set thistype(0).next.prev = this
set this.next = thistype(0).next
set thistype(0).next = this
set this.prev = thistype(0)
if linkCount == 0 then
call TimerStart(linkTimer, PERIOD, true, function thistype.iterate)
endif
set linkCount = linkCount + 1
endif
call UnitRemoveAbility(this.tar, DUM_ABILID_2)
call UnitRemoveAbility(this.tar, BUFFID_2)
call table.remove(GetHandleId(this.trig))
call DestroyTrigger(this.trig)
call this.stopPeriodic()
if not b then
call this.deallocate()
endif
else
set this.dur = this.dur - T32_PERIOD
endif
static if SHOWTEXT then
set t = null
endif
endmethod
implement T32x
private static method onDamage takes nothing returns boolean
local thistype this = table[GetHandleId(GetTriggeringTrigger())]
if this.tar == GetTriggerUnit() then
set this.damage = this.damage + GetEventDamage()
endif
return false
endmethod
public static method create takes unit u, unit tar, integer level returns thistype
local thistype this = thistype.allocate()
set this.u = u
set this.tar = tar
set this.trig = CreateTrigger()
set this.level = level
set this.damage = 0
set this.damagelimit = GetDamageLimit(this.level)
set this.dur = GetDelayTime(this.level)
call UnitAddAbility(this.tar, DUM_ABILID_2)
call Damage_RegisterEvent(this.trig)
call TriggerAddCondition(this.trig, Condition(function thistype.onDamage))
set table[GetHandleId(this.trig)] = this
call this.startPeriodic()
return this
endmethod
private static method onInit takes nothing returns nothing
set table = Table.create()
set castDummy = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE), CASTERID, 0, 0, 0)
call UnitAddAbility(castDummy, DUM_ABILID_1)
endmethod
endstruct
private struct Data
unit u
unit tar
unit dummy
integer level
static thistype tempData
private static method filterFunc takes nothing returns boolean
local thistype this = tempData
local unit u = GetFilterUnit()
if GetFilter(this.u, u) then
call Curse.create(this.u, u, this.level)
endif
set u = null
return false
endmethod
private method periodic takes nothing returns nothing
local real x = GetUnitX(this.dummy)
local real y = GetUnitY(this.dummy)
local real dx = GetUnitX(this.tar) - x
local real dy = GetUnitY(this.tar) - y
local real a
if dx * dx + dy * dy <= TRUE_COL_SIZE then
call DestroyEffect(AddSpecialEffect(PROJ_FX, x, y))
call UnitDamageTargetEx(this.u, this.tar, GetDamage(this.level), true, false, ATK, DMG, null)
set tempData = this
call GroupEnumUnitsInArea(ENUM_GROUP, dx + x, dy + y, GetArea(this.level), Filter(function thistype.filterFunc))
call KillUnit(this.dummy)
call this.stopPeriodic()
call this.deallocate()
else
set a = Atan2(dy, dx)
call SetUnitX(this.dummy, x + TRUESPEED * Cos(a))
call SetUnitY(this.dummy, y + TRUESPEED * Sin(a))
call SetUnitFacing(this.dummy, a * bj_RADTODEG)
endif
endmethod
implement T32x
private static method onCast takes nothing returns boolean
local thistype this
local real x
local real y
set this = thistype.allocate()
set this.u = GetTriggerUnit()
set this.tar = GetSpellTargetUnit()
set x = GetUnitX(this.u)
set y = GetUnitY(this.u)
set this.dummy = CreateUnit(GetOwningPlayer(this.u), DUMMYID, x, y, Atan2(GetUnitY(this.tar) - y, GetUnitX(this.tar) - x) * bj_RADTODEG)
set this.level = GetUnitAbilityLevel(this.u, ABILID)
call this.startPeriodic()
return false
endmethod
private static method onInit takes nothing returns nothing
local trigger t = CreateTrigger()
local unit u
call GT_RegisterStartsEffectEvent(t, ABILID)
call TriggerAddCondition(t, Condition(function thistype.onCast))
// preload
set u = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE), CASTERID, 0, 0, 0)
call UnitAddAbility(u, DUM_ABILID_1)
call UnitAddAbility(u, DUM_ABILID_2)
call RemoveUnit(u)
call RemoveUnit(CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE), DUMMYID, 0, 0, 0))
set t = null
set u = null
endmethod
endstruct
endlibrary
Bolt Sequence
Description:
Fires a series of arrows at all enemies within the area, dealing physical damage. Every wave of arrows are released at 0.5 seconds intervals. Channels for 3 seconds.
Level 1 - 35 damage.
Level 2 - 50 damage.
Level 3 - 65 damage.
Level 4 - 80 damage.
Cast Range: 400
Target Type: Unit Area (400)
Cooldown: 20/19/18/17 seconds
Channeling
Screenshot:
Code:
JASS:
library BoltSequence uses Damage, GroupUtils, T32
constant native UnitAlive takes unit id returns boolean
//===========================================================================
// CONFIGURABLES
//===========================================================================
globals
private constant integer ABILID = 039;ABBS039; // raw code of ability "Bolt Sequence"
private constant string ORDERID = "blight" // order ID of "Bolt Sequence"
private constant integer DUMMYID = 039;dBOL039; // raw code of unit "Bolt Sequence Dummy"
private constant real ANIMTIME = 1.334 // this value is the attack animation time of the model
private constant real COLLISION = 50.0 // collision check for arrow impact
private constant real TRUECOL = COLLISION * COLLISION // square of COLLISION
private constant real SPEED = 1000.0 // distance traveled by projectile per second
private constant real TRUESPEED = SPEED * T32_PERIOD // distance per interval
private constant attacktype ATK = ATTACK_TYPE_CHAOS // attack type of damage
private constant damagetype DMG = DAMAGE_TYPE_NORMAL // damage type of damage
endglobals
// area of effect
private constant function GetArea takes integer level returns real
return 400.
endfunction
// damage per wave
private constant function GetDamage takes integer level returns real
return 15. * level + 20.
endfunction
// interval per wave
private constant function GetWaves takes integer level returns real
return 0.5
endfunction
// target filter
private constant function GetFilter takes unit c, unit u returns boolean
return /*
*/ UnitAlive(u) /* // target is alive
*/ and IsUnitEnemy(u, GetOwningPlayer(c)) /* // target is an enemy
*/ and not IsUnitType(u, UNIT_TYPE_STRUCTURE) /* // target is not a structure
*/
endfunction
//===========================================================================
// END CONFIGURABLES
//===========================================================================
private struct Projectile
unit u
unit tar
unit dummy
real damage
private method periodic takes nothing returns nothing
local real x = GetUnitX(this.dummy)
local real y = GetUnitY(this.dummy)
local real dx = GetUnitX(this.tar) - x
local real dy = GetUnitY(this.tar) - y
local real a
if dx * dx + dy * dy <= TRUECOL then
call UnitDamageTargetEx(this.u, this.tar, this.damage, true, false, ATK, DMG, null)
call KillUnit(this.dummy)
call this.stopPeriodic()
call this.deallocate()
else
set a = Atan2(dy, dx)
call SetUnitX(this.dummy, x + TRUESPEED * Cos(a))
call SetUnitY(this.dummy, y + TRUESPEED * Sin(a))
call SetUnitFacing(this.dummy, a * bj_RADTODEG)
endif
endmethod
implement T32x
static method create takes unit u, unit tar, real damage returns thistype
local thistype this = thistype.allocate()
local real x = GetUnitX(u)
local real y = GetUnitY(u)
set this.u = u
set this.tar = tar
set this.dummy = CreateUnit(GetOwningPlayer(this.u), DUMMYID, x, y, Atan2(GetUnitY(tar) - y, GetUnitX(tar) - x) * bj_RADTODEG)
set this.damage = damage
call this.startPeriodic()
return this
endmethod
endstruct
private struct Data
unit u
real area
real damage
real interval
real count
real x
real y
static thistype tempData
private static method filterFunc takes nothing returns boolean
local thistype this = tempData
local unit u = GetFilterUnit()
if GetFilter(this.u, u) then
call Projectile.create(this.u, u, this.damage)
endif
set u = null
return false
endmethod
private method periodic takes nothing returns nothing
if this.count <= 0 then
set tempData = this
call GroupEnumUnitsInArea(ENUM_GROUP, this.x, this.y, this.area, Filter(function thistype.filterFunc))
set this.count = this.interval - T32_PERIOD
else
set this.count = this.count - T32_PERIOD
endif
if GetUnitCurrentOrder(this.u) != OrderId(ORDERID) then
call SetUnitTimeScale(this.u, 1.)
call this.stopPeriodic()
call this.deallocate()
endif
endmethod
implement T32x
private static method onCast takes nothing returns boolean
local thistype this
local integer level
set this = thistype.allocate()
set this.u = GetTriggerUnit()
set level = GetUnitAbilityLevel(this.u, ABILID)
set this.area = GetArea(level)
set this.damage = GetDamage(level)
set this.interval = GetWaves(level)
set this.count = this.interval
set this.x = GetSpellTargetX()
set this.y = GetSpellTargetY()
set tempData = this
call GroupEnumUnitsInArea(ENUM_GROUP, this.x, this.y, this.area, Filter(function thistype.filterFunc))
call SetUnitTimeScale(this.u, ANIMTIME / this.interval)
call this.startPeriodic()
return false
endmethod
private static method onInit takes nothing returns nothing
local trigger t = CreateTrigger()
call GT_RegisterStartsEffectEvent(t, ABILID)
call TriggerAddCondition(t, Condition(function thistype.onCast))
//preload
call RemoveUnit(CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE), DUMMYID, 0, 0, 0))
set t = null
endmethod
endstruct
endlibrary
Credits
Code:
[B]Jesus4Lyf[/B]
- [URL=http://www.thehelper.net/forums/showthread.php/130752-Advanced-Indexing-Data-Storage]AIDS[/URL]
- [URL=http://www.thehelper.net/forums/showthread.php/131287-Damage]Damage[/URL]
- [URL=http://www.thehelper.net/forums/showthread.php/123288-GTrigger-Event-System]GTrigger[/URL]
- [URL="http://www.thehelper.net/forums/showthread.php/132538-Timer32?highlight=Timer32"]Timer32[/URL]
[B]Rising_Dusk[/B] - [URL=http://www.wc3c.net/showthread.php?t=104464]GroupUtils[/URL]
[B]Bribe[/B] - [URL=http://www.hiveworkshop.com/forums/jass-functions-413/snippet-new-table-188084/]Table[/URL]
[B]JetFangInferno[/B] - [URL="http://www.hiveworkshop.com/forums/models-530/brilliance-50443/?prev=search%3DGrudge%26d%3Dlist%26r%3D20"]Eagle Eye Model[/URL]
[B]Granado Espada[/B] - [URL="http://ge.hanbiton.com/Home/Home.aspx"]Skill Icons[/URL]
Changelogs
Code:
[B]Version 1.0[/B]
- Initial release
[B]Version 1.1[/B]
- Rewrote the triggers using Timer32 and TimerUtils instead of KeyTimers2
- Optimized code
[B]Version 1.2[/B]
- Removed use of TimerUtils
- Optimized code
[B]Version 1.3[/B]
- Optimized code
Feedback will be appreciated.