Dimensional Flux Collector v1
3500
|
ID: 306
Family ID:
Author: cedi
Rarity: unique
Element: storm
Status: Approved
|
Dimensional Link
Creates a link between this tower and the target tower. This tower will now monitor any spell damage dealt by the linked tower to creeps within 2000 range of this tower. If the linked tower is sold, replaced or upgraded the link will dissolve.
AC_TYPE_NOAC_PLAYER_TOWER 0, 800 range, 1s cooldown
Dimensional Distortion Field - Aura
Each second this tower attacks a creep within 800 range, dealing 25% of the linked tower's spell damage per second as energy damage to the target creep. This tower can only attack if a link exists for at least 10 seconds. Benefits from attackspeed bonuses. Level Bonus: +1% of spell dps as damage |
Download
Toggle Triggers Autocast
caster_art:
AUTOCAST_cooldown: 1
AUTOCAST_numBuffsBeforeIdle: 0
AUTOCAST_isExtended: false
AUTOCAST_autocastType: AC_TYPE_NOAC_PLAYER_TOWER
AUTOCAST_manacost: 0
AUTOCAST_range: 800
AUTOCAST_buffType: 0
AUTOCAST_targetSelf: false
AUTOCAST_targetType: TARGET_TYPE_PLAYER_TOWERS
target_art:
AUTOCAST_autoRange: 800
private function onAutocast takes Tower tower returns nothing
local Tower T
local Buff B
set B = Event.getTarget().getBuffOfType( LINK )
if B != 0 then
//Target is linked to another one of these towers.
//Destroy that link
call B.removeBuff()
endif
//It should be impossible for this to create a double free as this can only be true if the
//linked tower and the target aren't the same. Else the buff is destroyed before this
//-> tower.userInt3 == 0 (buff cleanup)
if tower.userInt3 != 0 then
//already linked! Cancel first!
set T = tower.userInt3
set B = T.getBuffOfType( LINK )
call B.removeBuff()
//Reset dps //Done in the buff's oncleanup, to make sure link is broken in case of selling / up
//set tower.userReal = 0.0
//set tower.userInt2 = 1
endif
set tower.userInt3 = Event.getTarget()
call LINK.apply( tower, Event.getTarget(), 0 )
endfunction
Header globals
BuffType BT
BuffType LINK
MultiboardValues MB
ProjectileType PT
constant real AURA_RANGE = 2000.00
hashtable TABLE = InitHashtable()
endglobals
function AddToTheList takes Tower T, Buff B returns nothing
local integer i = LoadInteger( TABLE, B, 0 ) + 1
call SaveInteger( TABLE, B, i, T )
call SaveInteger( TABLE, B, 0, i )
//In range -> count
set T.userInt = T.userInt + 1
endfunction
function IsInTheList takes Tower T, Buff B returns integer
local integer i = LoadInteger( TABLE, B, 0 )
loop
if LoadInteger( TABLE, B, i ) == T then
return i
endif
set i = i - 1
exitwhen i <= 0
endloop
return 0
endfunction
function RemoveFromTheList takes Tower T, Buff B returns nothing
local integer fullcount = LoadInteger( TABLE, B, 0 )
local integer pos = IsInTheList( T, B )
if pos == 0 then
//Tower not in the list
return
endif
if fullcount == pos then
//Last element
else
//Sorting!
call SaveInteger( TABLE, B, pos, LoadInteger( TABLE, B, fullcount ) )
endif
//cleanup
call RemoveSavedInteger( TABLE, B, fullcount )
//Save new total
call SaveInteger( TABLE, B, 0, fullcount - 1 )
//No longer in range -> don't count
set T.userInt = T.userInt - 1
endfunction
function LinkCreate takes Buff B returns nothing
local Tower T = B.getCaster().userInt3
local Tower C = B.getCaster()
local Lightning l = Lightning.createFromPointToUnit( "DRAM", C.getX(), C.getY(), C.getZ() + 220, T )
set B.userInt = l
endfunction
function LinkEnd takes Buff B returns nothing
local Tower tower = B.getCaster()
local Lightning l = B.userInt
//Cleanup sfx
call l.destroy()
//Reset dps
set tower.userReal = 0.0
set tower.userInt2 = 1
//clear Link value
set tower.userInt3 = 0
endfunction
function BuffCheck takes Buff B returns nothing
local unit c = B.getBuffedUnit().getUnit()
local integer i = LoadInteger( TABLE, B, 0 )
local Tower T
if i <= 0 then
//can happen, as the aura range != checking range.
set c = null
return
endif
loop
set T = LoadInteger( TABLE, B, i )
if not IsUnitInRange( c, T.getUnit(), AURA_RANGE ) then
//Unit is no longer in range of this tower. Remove the tower from the list
//Sorting and this shouldn't cause problems, as all sortet items are already
//checked.
call RemoveFromTheList( T, B )
endif
set i = i - 1
exitwhen i <= 0
endloop
set c = null
endfunction
function BuffCreate takes Buff B returns nothing
//local Tower T = B.getCaster()
//set T.userInt = T.userInt + 1
//Save the origin
call SaveInteger( TABLE, B, 0, 0 )
//call SaveInteger( TABLE, B, 1, T )
endfunction
//Remove all items from the list
function BuffEnd takes Buff B returns nothing
local integer i = LoadInteger( TABLE, B, 0 )
local Tower T
loop
set T = LoadInteger( TABLE, B, i )
call RemoveFromTheList( T, B )
set i = i - 1
exitwhen i <= 0
endloop
endfunction
function BuffTrigger takes Buff B returns nothing
local Buff trig = Event.getTarget().getBuffOfType( LINK )
local Tower T
if Event.isSpellDamage() and trig != 0 then //Spelldamage and attacking tower == linked tower
set T = trig.getCaster() //the linker
if IsInTheList( T, B ) != 0 then
//Only add the damage if the linker is on the list == in range
set T.userReal = T.userReal + Event.damage //add damage to the linker
endif
endif
endfunction
function ProjHit takes Projectile P, Unit U returns nothing
local Tower T = P.getCaster()
call T.doCustomAttackDamage( U, T.userReal / T.userInt2 * ( 0.25 + T.getLevel() * 0.01 ), T.calcAttackMulticrit( 0, 0, 0 ), AttackType.ENERGY )
endfunction
//Do not remove or rename this function!
//Put your initialization tasks here, this function will be called on map init
private function init takes nothing returns nothing
set BT = BuffType.createAuraEffectType( false )
call BT.addEventOnCreate( BuffCreate )
call BT.addEventOnCleanup( BuffEnd )
call BT.addPeriodicEvent( BuffCheck, 1.0 )
call BT.addEventOnDamaged( BuffTrigger, 1.0, 0.0 )
call BT.setBuffIcon( '@@0@@' )
set LINK = BuffType.create( -1, 0.0, true )
call LINK.addEventOnCreate( LinkCreate )
call LINK.addEventOnCleanup( LinkEnd )
call LINK.setBuffIcon( '@@1@@' )
set MB = MultiboardValues.create( 1 )
call MB.setKey( 0, "DPS" )
set PT = ProjectileType.createInterpolate( "Abilities\\Spells\\Undead\\OrbOfDeath\\OrbOfDeathMissile.mdl", 1000.0 )
call PT.setEventOnInterpolationFinished( ProjHit )
endfunction
On Tower Creation function onCreate takes Tower tower returns nothing
set tower.userReal = 0.0 //overall damage
set tower.userReal2 = 0.0 //active?
set tower.userInt = 0 //buffed creeps
set tower.userInt2 = 1 //time
set tower.userInt3 = 0 //Link Target
endfunction
On Tower Destruction function onDestruct takes Tower tower returns nothing
local Tower targ
//Remove link on destroy of this tower
if tower.userInt3 != 0 then
//Target is linked
set targ = tower.userInt3
call targ.getBuffOfType( LINK ).removeBuff()
endif
endfunction
On Tower Details
goldcost: 0
function onTowerDetails takes Tower tower returns MultiboardValues
call MB.setValue( 0, formatFloat( tower.userReal / tower.userInt2 * ( 0.15 + tower.getLevel() * 0.006 ), 0 ) )
return MB
endfunction
On Unit Comes In Range
UNITINRANGE_targetType: TARGET_TYPE_CREEPS
UNITINRANGE_range: 2000
function onUnitInRange takes Tower tower returns nothing
//Okay, new creep just came in range of this tower's aura - 1 (to make sure it has the buff)
//So let's add it to the TABLE, as long as it isn't already added.
local Creep C = Event.getTarget()
local Buff B = C.getBuffOfType( BT )
if B != 0 then
//Buffed unit entered
if IsInTheList( tower, B ) == 0 then
//Not in the list
call AddToTheList( tower, B )
endif
endif
endfunction
Periodic
PERIODIC_period: 1.0
function periodic takes Tower tower returns nothing
local Iterate I
local Unit U
if tower.userInt3 == 0 then
//NOT LINKED! Do nothing!
return
endif
if tower.userReal <= 0.0 then
//No dmg to deal! Do nothing!
return
endif
if tower.userInt > 0 then //at least one unit in range
set tower.userInt2 = tower.userInt2 + 1
set tower.userReal2 = 1
//Outsourced
//At least 10 seconds connected? (counting starts at 1, so 10 seconds are 11)
//if tower.userInt2 <= 10 then
// return
//endif
//ATTACK
//set I = Iterate.overUnitsInRangeOfCaster( tower, TARGET_CREEPS, 800.00 )
//set U = I.nextRandom()
//if U != 0 then
//Target Found. Launch Projectile.
// call Projectile.createBezierInterpolationFromPointToUnit( PT, tower, 1.0, 1.0, tower.getX(), tower.getY(), tower.getZ(), U, 0.35, 0.0, 0.0, true )
// call I.destroy()
//endif
else
//No unit in range, check if there was one in range during last tick
if tower.userReal2 > 0 then
set tower.userReal2 = -1
set tower.userInt2 = tower.userInt2 + 1
endif
endif
endfunction
Periodic
PERIODIC_period: 1.0
function periodic takes Tower tower returns nothing
local Iterate I
local Unit U
call Event.getCurrentPeriodicEvent().enableAdvanced( tower.getCurrentAttackspeed(), true )
if tower.userInt3 == 0 then
//NOT LINKED! Do nothing!
return
endif
if tower.userReal <= 0.0 then
//No dmg to deal! Do nothing!
return
endif
if tower.userInt > 0 then //at least one unit in range
//set tower.userInt2 = tower.userInt2 + 1
//set tower.userReal2 = 1
//Outsourced
//At least 10 seconds connected? (counting starts at 1, so 10 seconds are 11)
if tower.userInt2 <= 10 then
return
endif
//ATTACK
set I = Iterate.overUnitsInRangeOfCaster( tower, TARGET_CREEPS, 800.00 )
set U = I.nextRandom()
if U != 0 then
//Target Found. Launch Projectile.
call Projectile.createBezierInterpolationFromPointToUnit( PT, tower, 1.0, 1.0, tower.getX(), tower.getY(), tower.getZ(), U, 0.35, 0.0, 0.0, true )
call I.destroy()
endif
else
//No unit in range, check if there was one in range during last tick
//if tower.userReal2 > 0 then
// set tower.userReal2 = -1
// set tower.userInt2 = tower.userInt2 + 1
//endif
endif
endfunction
Tower Aura
AURA_auraEffect: BT
AURA_power: 0
AURA_level: 0
AURA_auraRange: 2150.00
AURA_targetType: TARGET_TYPE_CREEPS
AURA_levelAdd: 1
AURA_powerAdd: 1
AURA_targetSelf: false
|
Description: