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
|
Death Knight v1
3500
|
ID: 317
Family ID:
Author: DaveMatthews
Rarity: unique
Element: darkness
Attack Type: Decay
Attack Range: 875
Attack CD: 1.1
Damage: 2659-2659
Mana: 50
Mana regen: 0
Status: Approved
|
Description: Feeds on souls to unleash his full power.
Specials:
+2 mana/lvl
Will of the Undying
The death knight decreases the base attack damage of all towers in 200 range by 10% and loses 50% of his remaining mana to increase his base damage by 15% for each tower affected for 5 seconds. Only towers that cost at least 1300 gold are affected by this spell. Level Bonus: +0.2% damage absorbed AC_TYPE_OFFENSIVE_IMMEDIATE 50, 900 range, 10s cooldown
Insatiable Hunger
On each attack, the death knight deals 0.25% bonus damage for each mana point he's currently missing and replenishes 1% of his maximum mana. He replenishes 5% of his maximum mana for each unit he kills. Level Bonus: +0.01% damage per mana point
Withering Presence
Whenever a unit comes in 900 range of the death knight, it has a 15% chance to have its health regeneration reduced by 50% and to lose 5% of its current health every second for 4 seconds. Units affected by this spell grant 50% less experience and bounty on death. Level Bonus: +0.4% chance +1% health regen reduction -1% experience and bounty reduction |
Download
Toggle Triggers Autocast
caster_art: Abilities\Spells\Other\HowlOfTerror\HowlCaster.mdl
AUTOCAST_cooldown: 10
AUTOCAST_numBuffsBeforeIdle: 0
AUTOCAST_isExtended: false
AUTOCAST_autocastType: AC_TYPE_OFFENSIVE_IMMEDIATE
AUTOCAST_manacost: 50
AUTOCAST_range: 900
AUTOCAST_buffType: 0
AUTOCAST_targetSelf: false
AUTOCAST_targetType: 0
target_art:
AUTOCAST_autoRange: 900
private function onAutocast takes Tower tower returns nothing
local integer numTowers = 0
local integer level = tower.getLevel()
local Tower u
local Iterate it = Iterate.overUnitsInRangeOfCaster(tower, TARGET_TOWERS, 200)
local unit towerUnit = tower.getUnit()
local real mana = GetUnitState(towerUnit, UNIT_STATE_MANA)
call SetUnitState(towerUnit , UNIT_STATE_MANA, mana/2)
loop
set u = it.next()
exitwhen u == 0
if u != tower and u.getGoldcost() >= 1300 then
set numTowers = numTowers + 1
call dave_will_negative.apply(tower, u, (50 + level))
endif
endloop
if numTowers > 0 then
call dave_will_positive.apply(tower, tower, (75 + level) * numTowers)
endif
set towerUnit = null
endfunction
Header globals
BuffType dave_will_positive
BuffType dave_will_negative
BuffType dave_withering
endglobals
function OnWithering takes Buff b returns nothing
local Unit buffed = b.getBuffedUnit()
local Unit caster = b.getCaster()
local unit u = buffed.getUnit()
local real hp = GetWidgetLife(u)
local real damage = hp * 0.05
call SetWidgetLife(u, hp - damage)
set u = null
endfunction
private function init takes nothing returns nothing
local Modifier m = Modifier.create()
local Modifier n = Modifier.create()
local Modifier o = Modifier.create()
set dave_will_positive = BuffType.create(5.0,0.0,true)
call dave_will_positive.setBuffModifier(m)
call m.addModification(MOD_DAMAGE_BASE_PERC,0.0,0.002)
call dave_will_positive.setBuffIcon( '@@0@@' )
set dave_will_negative = BuffType.create(5.0,0,false)
call dave_will_negative.setBuffModifier(n)
call n.addModification(MOD_DAMAGE_BASE_PERC,-0.0,-0.002)
call dave_will_negative.setBuffIcon( '@@1@@' )
set dave_withering = BuffType.create(4.0,0,false)
call dave_withering.setBuffModifier(o)
call o.addModification(MOD_HP_REGEN_PERC,-0.5,-0.1)
call o.addModification(MOD_EXP_GRANTED,-0.5,0.01)
call o.addModification(MOD_BOUNTY_GRANTED,-0.5,0.01)
call dave_withering.addPeriodicEvent(EventHandler.OnWithering,1)
call dave_withering.setBuffIcon( '@@2@@' )
endfunction
On Damage
ONDAMAGE_chance: 1.0
ONDAMAGE_chanceLevelAdd: 0.0
function onDamage takes Tower tower returns nothing
local unit towerUnit = tower.getUnit()
local integer level = tower.getLevel()
local real mana = GetUnitState(towerUnit,UNIT_STATE_MANA)
local real maxMana = GetUnitState(towerUnit,UNIT_STATE_MAX_MANA)
call SetUnitState(towerUnit , UNIT_STATE_MANA, mana+(maxMana*0.01))
set Event.damage = Event.damage+(Event.damage*((maxMana-mana)*(0.0025+0.0001*level)))
set towerUnit = null
endfunction
On Kill function onKill takes Tower tower returns nothing
local unit towerUnit = tower.getUnit()
local real mana = GetUnitState(towerUnit, UNIT_STATE_MANA)
local real maxMana = GetUnitState(towerUnit,UNIT_STATE_MAX_MANA)
call SetUnitState(towerUnit , UNIT_STATE_MANA, mana+(maxMana*0.05))
set towerUnit = null
endfunction
On Unit Comes In Range
UNITINRANGE_targetType: TARGET_TYPE_CREEPS
UNITINRANGE_range: 900
function onUnitInRange takes Tower tower returns nothing
local integer level = tower.getLevel()
if tower.calcChance(0.15+level*0.004) then
call dave_withering.apply(tower,Event.getTarget(),level)
endif
endfunction
|
Drake Whisperer v2
3500
|
ID: 426
Family ID:
Author: Ely
Rarity: unique
Element: astral
Attack Type: Elemental
Attack Range: 1000
Attack CD: 1.9
Damage: 3109-3138
Status: Approved
|
Description: Unleashes mighty drakes against his enemies.
Specials:
+15% dmg to air (+0.4%/lvl)
Versatile
Every time this tower deals spell damage through its abilities, it increases its dps by 1.5% of the spell damage dealt. Lasts 2.5 seconds and stacks. Maximum bonus of [200 x (current wave)]. Level Bonus: +0.04% damage
Unleash
On attack, the Drake Whisperer has a 12.5% chance to unleash a bronze drake towards its target, dealing 1250 spell damage to a random creep in front of itself in 600 range every 0.2 seconds. Lasts 2 seconds. Level Bonus: +40 spell damage +0.3% chance
Feed the Drakes
Every 1.5 seconds, the Drake Whisperer feeds a nearby corpse to one of his drakes and unleashes it to a random target in 1000 range. If there is no target, the drake will attack on the next feeding, with a maximum of 5 fed drakes. Each corpse has a 15% chance to feed 2 drakes. The Blue Drake deals 6000 spell damage in 125 AoE and slows by 25% for 3 seconds. The Red Drake deals 200% of the tower's attack damage and stuns for 3 seconds. The Green Drake deals 5000 spell damage and spreads Versatile's current dps bonus to towers in 175 range for 2.5 seconds. Level Bonus: +0.4% double feed chance Blue Drake : +150 spell damage Red Drake : +8% damage Green Drake : +0.04 seconds duration |
Download
Toggle Triggers Header globals
BuffType versatileBuff
BuffType blueDrakeBuff
ProjectileType blueDrake
ProjectileType redDrake
ProjectileType greenDrake
ProjectileType bronzeDrake
ProjectileType bronzeDrakeAttack
constant integer BLUE = 0
constant integer GREEN = 1
constant integer RED = 2
// Drakeling status
constant integer IDLE = 0
constant integer ATTACKING = 1
constant integer COMING_BACK = 2
endglobals
struct Vec3
real x
real y
real z
endstruct
struct Drakelings
Projectile array d[3]
Vec3 array startPos[3]
endstruct
function allDrakesBusy takes Drakelings d returns boolean
return d.d[0].userInt != IDLE and d.d[1].userInt != IDLE and d.d[2].userInt != IDLE
endfunction
function launchDrakeling takes Tower t, integer which, Unit u returns nothing
local Drakelings d = t.userInt2
set d.d[which].speed = 600
call d.d[which].startBezierInterpolationToUnit(u, 0.15, 0.15, 0.17, true)
set d.d[which].userInt = ATTACKING
set t.userInt = t.userInt - 1
endfunction
function launchRandomDrakeling takes Tower t, Unit u returns nothing
local integer i = GetRandomInt(0, 2)
local Drakelings d = t.userInt2
loop
if d.d[i].userInt == IDLE then
call launchDrakeling(t, i, u)
return
endif
set i = ModuloInteger(i + 1, 3)
endloop
endfunction
function feeding takes Tower tower returns nothing
local Iterate it = Iterate.overUnitsInRangeOfCaster(tower, TARGET_TYPE_CREEPS, 1000)
local Unit u
local integer random
local Projectile p
local Drakelings d = tower.userInt2
local Effect e
local Iterate itCorpse
local unit corpse
local integer maxFedDrakes static constant = 5
// userInt = number of fed drakes, 5 max
if tower.userInt < maxFedDrakes then
set itCorpse = Iterate.overCorpsesInRange(tower, tower.getX(), tower.getY(), 1000)
set corpse = itCorpse.nextCorpse()
if corpse != null then
call ShowUnit(corpse, false)
set e = Effect.createScaled("Objects\\Spawnmodels\\Human\\HumanBlood\\HumanBloodFootman.mdl", tower.getX()+10, tower.getY(), tower.getZ() - 120, 0, 0.15)
call e.setLifetime(0.8)
if tower.calcChance(15/100.0 + (0.4/100.0)*tower.getLevel()) then
set tower.userInt = tower.userInt + 2
else
set tower.userInt = tower.userInt + 1
endif
if tower.userInt > maxFedDrakes then
set tower.userInt = maxFedDrakes
endif
set corpse = null
call itCorpse.destroy()
endif
endif
loop
if tower.userInt <= 0 or allDrakesBusy(d) then
call it.destroy()
return
endif
set u = it.nextRandom()
exitwhen u == 0
// Only red drakes deal physical, so unleash only them vs immune
if u.isImmune() then
if d.d[RED].userInt == IDLE then
call launchDrakeling(tower, RED, u)
endif
else
call launchRandomDrakeling(tower, u)
endif
endloop
endfunction
function refreshBuff takes Tower tower, real damage returns nothing
local Buff b = tower.getBuffOfType(versatileBuff)
local real powerup
local real maxDamage = 200*tower.getOwner().getTeam().getLevel()
if damage <= 0 then
return
endif
set powerup = damage*(1.5/100.0 + (0.04/100.0)*tower.getLevel())
if b != 0 then
set powerup = b.getPower() + powerup
if powerup > maxDamage then
set powerup = maxDamage
endif
call b.setPower(R2I(powerup))
call b.refreshDuration()
else
if powerup > maxDamage then
set powerup = maxDamage
endif
call versatileBuff.applyCustomPower(tower, tower, 1, R2I(powerup))
endif
endfunction
function spreadBuff takes Tower tower returns nothing
local Iterate it
local Buff b = tower.getBuffOfType(versatileBuff)
local Tower target
if b == 0 then
return
endif
set it = Iterate.overUnitsInRangeOfCaster(tower, TARGET_TYPE_TOWERS, 175)
loop
set target = it.next()
exitwhen target == 0
if target.getUnitType() != tower.getUnitType() then
call versatileBuff.applyAdvanced(tower, target, 1, b.getPower(), 2.5 + 0.04*tower.getLevel())
endif
endloop
endfunction
function blueDrakeHit takes Projectile p, Unit target returns nothing
local Tower tower = p.getCaster()
local real damage = tower.getOverallDamage()
local Iterate it
local Unit u
local Effect e
set it = Iterate.overUnitsInRange(tower, TARGET_TYPE_CREEPS, p.x, p.y, 125)
if it.count() == 0 then
call it.destroy()
return
endif
set e = Effect.createScaled("Abilities\\Spells\\Undead\\FrostNova\\FrostNovaTarget.mdl", p.x, p.y, p.z, 0, 0.2)
call e.setLifetime(2.0)
loop
set u = it.next()
exitwhen u == 0
call blueDrakeBuff.apply(tower, u, 1)
call tower.doSpellDamage(u, 6000 + 150*tower.getLevel(), tower.calcSpellCritNoBonus())
endloop
set damage = tower.getOverallDamage() - damage
call refreshBuff(tower, damage)
endfunction
function greenDrakeHit takes Projectile p, Unit target returns nothing
local Tower tower = p.getCaster()
local real damage = tower.getOverallDamage()
if target == 0 then
call spreadBuff(tower)
return
endif
call tower.doSpellDamage(target, 5000, tower.calcSpellCritNoBonus())
set damage = tower.getOverallDamage() - damage
call refreshBuff(tower, damage)
call spreadBuff(tower)
endfunction
function redDrakeHit takes Projectile p, Unit target returns nothing
local Tower tower = p.getCaster()
if target == 0 then
return
endif
call cb_stun.applyOnlyTimed(tower, target, 3)
call tower.doAttackDamage(target, tower.getCurrentAttackDamageWithBonus()*(200/100.0 + (8/100.0)*tower.getLevel()), tower.calcAttackCritNoBonus())
endfunction
function sendDrakelingHome takes Projectile p returns nothing
local Drakelings d = p.getCaster().userInt2
local integer which = p.userInt2
set d.d[which].speed = 600
call d.d[which].startBezierInterpolationToPoint(d.startPos[which].x, d.startPos[which].y, d.startPos[which].z, 0.15, 0.15, 0.17)
set d.d[which].userInt = COMING_BACK
endfunction
function onDrakelingEndInterpol takes Projectile p, Unit target returns nothing
local integer which = p.userInt2
call p.avertDestruction()
if p.userInt == COMING_BACK then
// Will be used to reset the drake, otherwise the code in Projectile messes with our position right after this event handler
call p.enablePeriodic(1)
set p.remainingLifetime = 999999
return
endif
if which == RED then
call redDrakeHit(p, target)
elseif which == BLUE then
call blueDrakeHit(p, target)
else
call greenDrakeHit(p, target)
endif
call sendDrakelingHome(p)
endfunction
function bronzeDrakeTick takes Projectile p returns nothing
local Tower tower = p.getCaster()
local Iterate it
local Unit u
local Projectile atkProj
local real startX
local real startY
local real angleDiff
if p.getAge() > 2 then
call p.color(255, 255, 255, 255 - R2I(((p.getAge() - 2) / (3 - 2))*255))
return
endif
set it = Iterate.overUnitsInRange(tower, TARGET_TYPE_CREEPS, p.x, p.y, 600)
loop
set u = it.nextRandom()
exitwhen u == 0
if not u.isImmune() then
// Test if the target is in a 90° cone in front of the drake
set angleDiff = Atan2(u.getY() - p.y, u.getX() - p.x)*bj_RADTODEG - p.direction
if angleDiff <= -310 or angleDiff >= 310 or (angleDiff >= -50 and angleDiff <= 50) then
set startX = p.x + Cos(p.direction*bj_DEGTORAD) * 100
set startY = p.y + Sin(p.direction*bj_DEGTORAD) * 100
set atkProj = Projectile.createLinearInterpolationFromPointToUnit(bronzeDrakeAttack, tower, 0, 0, startX, startY, p.z + 20, u, 0.30, true)
call atkProj.setScale(0.55)
call it.destroy()
return
endif
endif
endloop
endfunction
function onBronzeDrakeHit takes Projectile p, Unit target returns nothing
local Tower tower = p.getCaster()
local real damage = tower.getOverallDamage()
if target == 0 then
return
endif
call tower.doSpellDamage(target, 1250 + 40*tower.getLevel(), tower.calcSpellCritNoBonus())
set damage = tower.getOverallDamage() - damage
call refreshBuff(tower, damage)
endfunction
// Hackish way of resetting the projectile and making it still, facing the tower
function resetPosition takes Projectile p returns nothing
local Tower t = p.getCaster()
local Drakelings d = t.userInt2
local integer which = p.userInt2
local real finalX
local real finalY
call p.disablePeriodic()
set p.x = d.startPos[which].x
set p.y = d.startPos[which].y
set p.z = d.startPos[which].z
set p.speed = 0
set p.userInt = IDLE
set finalX = p.x + (t.getX() - p.x)*10
set finalY = p.y + (t.getY() - p.y)*10
call p.aimAtPoint(finalX, finalY, p.z, false, false)
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
local Modifier versatileModifier = Modifier.create()
local Modifier blueDrakeModifier = Modifier.create()
call versatileModifier.addModification(MOD_DPS_ADD, 0.00, 1.00)
set versatileBuff = BuffType.create(2.5, 0.00, true)
call versatileBuff.setBuffModifier(versatileModifier)
call versatileBuff.setBuffIcon('@@0@@')
call blueDrakeModifier.addModification(MOD_MOVESPEED, -1*(25/100.0), 0)
set blueDrakeBuff = BuffType.create(3, 0.00, true)
call blueDrakeBuff.setBuffModifier(blueDrakeModifier)
call blueDrakeBuff.setBuffIcon('@@1@@')
set blueDrake = ProjectileType.create("Units\\Creeps\\AzureDragon\\AzureDragon.mdl", 999999, 0)
call blueDrake.disableExplodeOnHit()
call blueDrake.disableExplodeOnExpiration()
call blueDrake.setEventOnInterpolationFinished(onDrakelingEndInterpol)
call blueDrake.enablePeriodic(resetPosition, 0.1)
set redDrake = ProjectileType.create("Units\\Creeps\\RedDragon\\RedDragon.mdl", 999999, 0)
call redDrake.disableExplodeOnHit()
call redDrake.disableExplodeOnExpiration()
call redDrake.setEventOnInterpolationFinished(onDrakelingEndInterpol)
call redDrake.enablePeriodic(resetPosition, 0.1)
set greenDrake = ProjectileType.create("Units\\Creeps\\GreenDragon\\GreenDragon.mdl", 999999, 0)
call greenDrake.disableExplodeOnHit()
call greenDrake.disableExplodeOnExpiration()
call greenDrake.setEventOnInterpolationFinished(onDrakelingEndInterpol)
call greenDrake.enablePeriodic(resetPosition, 0.1)
set bronzeDrake = ProjectileType.create("Units\\creeps\\BronzeDragon\\BronzeDragon.mdl", 3, 350.0)
call bronzeDrake.disableExplodeOnHit()
call bronzeDrake.disableExplodeOnExpiration()
call bronzeDrake.enablePeriodic(bronzeDrakeTick, 0.2)
set bronzeDrakeAttack = ProjectileType.create("Abilities\\Weapons\\FireBallMissile\\FireBallMissile.mdl", 2.5, 900.0)
call bronzeDrakeAttack.setEventOnInterpolationFinished(onBronzeDrakeHit)
endfunction
On Attack
ONATTACK_chance: 0.125
ONATTACK_chanceLevelAdd: 0.003
function onAttack takes Tower tower returns nothing
local integer i = GetRandomInt(0, 1)
local Projectile p
local Unit u = Event.getTarget()
local real finalX = tower.getX() + (u.getX() - tower.getX())*6
local real finalY = tower.getY() + (u.getY() - tower.getY())*6
set p = Projectile.createFromUnitToPoint(bronzeDrake, tower, 0, 0, tower, finalX, finalY, tower.getZ(), true, false)
call p.setScale(0.60)
endfunction
On Tower Creation function onCreate takes Tower tower returns nothing
local Drakelings d = Drakelings.create()
set d.d[0] = Projectile.create(blueDrake, tower, 0, 0, tower.getX() + 36, tower.getY() - 30, tower.getZ() - 30, 120)
set d.d[1] = Projectile.create(greenDrake, tower, 0, 0, tower.getX() - 50, tower.getY() - 13, tower.getZ() - 30, 10)
set d.d[2] = Projectile.create(redDrake, tower, 0, 0, tower.getX() + 27, tower.getY() + 59, tower.getZ() - 30, 250)
call d.d[0].disablePeriodic()
call d.d[1].disablePeriodic()
call d.d[2].disablePeriodic()
set d.d[0].userInt = IDLE
set d.d[1].userInt = IDLE
set d.d[2].userInt = IDLE
set d.d[0].userInt2 = 0
set d.d[1].userInt2 = 1
set d.d[2].userInt2 = 2
set d.startPos[0] = Vec3.create()
set d.startPos[0].x = tower.getX() + 36
set d.startPos[0].y = tower.getY() - 30
set d.startPos[0].z = tower.getZ() - 30
set d.startPos[1] = Vec3.create()
set d.startPos[1].x = tower.getX() - 50
set d.startPos[1].y = tower.getY() - 13
set d.startPos[1].z = tower.getZ() - 30
set d.startPos[2] = Vec3.create()
set d.startPos[2].x = tower.getX() + 27
set d.startPos[2].y = tower.getY() + 59
set d.startPos[2].z = tower.getZ() - 30
call d.d[0].setScale(0.25)
call d.d[1].setScale(0.25)
call d.d[2].setScale(0.25)
set tower.userInt = 0
set tower.userInt2 = d
endfunction
On Tower Destruction function onDestruct takes Tower tower returns nothing
local Drakelings d = tower.userInt2
local integer i = 0
loop
call d.d[i].destroy()
call d.startPos[i].destroy()
set i = i + 1
exitwhen i == 3
endloop
call d.destroy()
endfunction
Periodic
PERIODIC_period: 1.5
function periodic takes Tower tower returns nothing
call feeding(tower)
endfunction
|
Ancient Jungle Stalker v1
3500
|
ID: 550
Family ID:
Author: Boekie
Rarity: rare
Element: nature
Attack Type: Physical
Attack Range: 850
Attack CD: 1.1
Damage: 2021-2120
Status: Approved
|
Description: This tower becomes enraged when it kills a unit and also gets stronger with every critical hit.
Specials:
20% crit chance (+0.5%/lvl)
Feral Aggression
On every critical hit this tower gains +0.4% bonus damage. This bonus is permanent and has a maximum of 250% bonus damage.
Bloodthirst
Whenever this tower kills a unit it becomes enraged, gaining +150% attackspeed for 5 seconds. Cannot retrigger while active! Level Bonus: +0.05 sec duration +1% attackspeed |
Download
Toggle Triggers Header globals
//@import
BuffType boekie_rage_buff
//@import
MultiboardValues boekie_jungle_stalker_values
endglobals
//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
endfunction
On Damage
ONDAMAGE_chance: 1.0
ONDAMAGE_chanceLevelAdd: 0.0
function onDamage takes Tower tower returns nothing
local real damageBonus
if Event.isAttackDamageCritical() and tower.userReal <= 2.5 then
set tower.userReal = tower.userReal + 0.004
call tower.modifyProperty(MOD_DAMAGE_ADD_PERC, 0.004)
endif
endfunction
On Kill function onKill takes Tower tower returns nothing
local integer lvl = tower.getLevel()
if tower.getBuffOfType(boekie_rage_buff) == 0 then
call boekie_rage_buff.applyCustomTimed(tower, tower, 50+lvl, 5.0+0.05*lvl)
endif
endfunction
On Tower Creation function onCreate takes Tower tower returns nothing
local Tower preceding = Event.getPrecedingTower()
local real damageBonus
if(preceding.getFamily() == tower.getFamily()) then
set damageBonus = preceding.userReal
set tower.userReal = damageBonus
call tower.modifyProperty(MOD_DAMAGE_ADD_PERC, damageBonus)
else
set tower.userReal = 0.0 //Damage bonus
endif
endfunction
On Tower Details function onTowerDetails takes Tower tower returns MultiboardValues
call boekie_jungle_stalker_values.setValue(0, formatPercent(tower.userReal, 1))
return boekie_jungle_stalker_values
endfunction
|
Glaive Master v1
3600
|
ID: 435
Family ID:
Author: Ashbringer
Rarity: unique
Element: iron
Attack Type: Physical
Attack Range: 1000
Attack CD: 1.4
Damage: 1855-1855
Status: Approved
|
Description: Eviscerate them all, make them bleed.
Specials:
Bounce attack:
2 targets
Glaivesaw:
Create a Glaivesaw at the target location. Glaivesaws deal 50% of attack damage as Lacerate damage to enemies within 150 range per second. Limit 3. Level Bonus: +1% damage
Glaive Storm
Hits have a 5% chance to throw an additional glaive at the target, dealing 50% of attack damage as Lacerate damage before returning to the tower. When the glaive returns, it bounces to a new random target within attack range. Maximum of 20 hits. Level Bonus: +0.2% chance +2% damage
Bounder
Attacks have a 15% chance to throw a glaive at one of your Glaivesaws. The glaive will bounce to another Glaivesaw, dealing 250% of attack damage as Lacerate damage to enemies it passes through. Level Bonus: +0.6% chance +6% damage
Lacerate
This tower's attacks and abilities deal Lacerate damage. 50% of Lacerate damage is dealt immediately as Physical damage. 100% of the remaining damage is dealt as Decay damage over 5 seconds. If this effect is reapplied, any remaining damage will be added to the new duration. Damage over time is based on the target's movement speed, with faster movement increasing the damage dealt. Level Bonus: +1% damage over time |
Download
Toggle Triggers Header globals
BuffType ashbringer_lacerate_buff
ProjectileType ashbringer_storm_missile
ProjectileType ashbringer_bounder_missile
endglobals
struct Machinations
integer max
Effect array e[3]
boolean array b[3]
real array x[3]
real array y[3]
integer array c[3]
endstruct
function ashbringer_machinations_setup takes Tower tower returns nothing
local Machinations ma = Machinations.create()
local integer count = 0
set tower.userInt = 0
set tower.userReal2 = I2R(tower.getUID())
set ma.max = 3 + 1
loop
set ma.e[count] = 0
set ma.b[count] = false
set ma.c[count] = 3 + 1
set count = count + 1
exitwhen count==3
endloop
set tower.userInt3 = ma
endfunction
function ashbringer_lacerate_damage takes Tower tower, Creep target, real damage, real crit returns nothing
local Buff b
local real damage_stack
local real dot_inc = 1.0 + (tower.getLevel() * 0.01)
local real dot_damage = damage * crit
call tower.doAttackDamage(target, damage * 0.5, crit)
set b = target.getBuffOfType(ashbringer_lacerate_buff)
if b != 0 then
set damage_stack = b.userReal + (dot_damage * 0.5 * dot_inc)
set ashbringer_lacerate_buff.apply(tower, target, 0).userReal = damage_stack
else
set ashbringer_lacerate_buff.apply(tower, target, 0).userReal = (dot_damage * 0.5 * dot_inc)
endif
endfunction
function ashbringer_lacerate_dot takes Buff b returns nothing
local Tower tower = b.getCaster()
local Creep target = b.getBuffedUnit()
local real remaining = b.getRemainingDuration()
local real damage = b.userReal / remaining
local real damage_tick = damage
local real movement_relative = GetUnitMoveSpeed(target.getUnit()) / 261
if target.isStunned() then
set damage_tick = 0
else
if remaining<1 then
set damage = b.userReal
set damage_tick = damage
endif
endif
if damage_tick>0 then
set b.userReal = b.userReal - damage
call tower.doCustomAttackDamage(target, damage_tick, 1.0, AttackType.DECAY)
endif
endfunction
function ashbringer_bounder_throw takes Tower tower returns nothing
local Machinations ma = tower.userInt3
local real damage = tower.getCurrentAttackDamageWithBonus() * (2.5 + (tower.getLevel() * 0.06))
local integer random = GetRandomInt(0, ma.max)
local integer bounces = 1
local Projectile p
if ma.max!=(3+1) then
set p = Projectile.createLinearInterpolationFromPointToPoint(ashbringer_bounder_missile, tower, 0, 0, tower.getX(), tower.getY(), 110, ma.x[random], ma.y[random], 0, 0)
set p.userInt = random
set p.userInt2 = bounces
set p.userReal = damage
endif
endfunction
function ashbringer_bounder_bounce takes Projectile p, Creep target returns nothing
local Tower tower = p.getCaster()
local Machinations ma = tower.userInt3
local Projectile n
local integer closest = ma.c[p.userInt]
if p.userInt2>0 and closest!=(3+1) then
call p.avertDestruction()
call p.startLinearInterpolationToPoint(ma.x[closest], ma.y[closest], 0, 0)
set p.userInt = closest
set p.userInt2 = p.userInt2-1
endif
endfunction
function ashbringer_bounder_hit takes Projectile p, Unit target returns nothing
local Tower tower = p.getCaster()
call ashbringer_lacerate_damage(tower, target, p.userReal, tower.calcAttackMulticrit(0,0,0))
endfunction
function ashbringer_storm_throw takes Tower tower, Creep target returns nothing
local real damage = tower.getCurrentAttackDamageWithBonus() * (0.5 + (tower.getLevel() * 0.02))
local Projectile p
set p = Projectile.createBezierInterpolationFromUnitToUnit(ashbringer_storm_missile, tower, 1, 1, tower, target, 0, 0.3, 0.17, true)
set p.userInt = 1
set p.userInt2 = 20
set p.userReal = damage
set p.userReal2 = tower.getX()
set p.userReal3 = tower.getY()
endfunction
function ashbringer_storm_bounce takes Projectile p, Creep target returns nothing
local Tower tower = p.getCaster()
local Iterate i
if p.userInt==1 then
call p.avertDestruction()
call ashbringer_lacerate_damage(tower, target, p.userReal, tower.calcAttackMulticrit(0,0,0))
call p.startBezierInterpolationToPoint(p.userReal2, p.userReal3, 100, 0, 0.3, 0.17)
set p.userInt = 0
elseif p.userInt2>0 then
set i = Iterate.overUnitsInRange(tower, TARGET_TYPE_CREEPS, p.userReal2, p.userReal3, 1000)
set target = i.nextRandom()
if target!=0 then
call p.avertDestruction()
call p.startBezierInterpolationToUnit(target, 0, 0.3, 0.17, true)
set p.userInt = 1
set p.userInt2 = p.userInt2 - 1
call i.destroy()
endif
endif
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 ashbringer_lacerate_buff = BuffType.create(5, 0, false)
call ashbringer_lacerate_buff.setBuffIcon('@@1@@')
call ashbringer_lacerate_buff.addPeriodicEvent(ashbringer_lacerate_dot, 1.0)
set ashbringer_storm_missile = ProjectileType.createInterpolate("Abilities\\Weapons\\SentinelMissile\\SentinelMissile.mdl", 900)
call ashbringer_storm_missile.setEventOnInterpolationFinished(ProjectileTargetEvent.ashbringer_storm_bounce)
set ashbringer_bounder_missile = ProjectileType.createInterpolate("Abilities\\Weapons\\GlaiveMissile\\GlaiveMissile.mdl", 2000)
call ashbringer_bounder_missile.enableCollision(ProjectileTargetEvent.ashbringer_bounder_hit, 100, TARGET_TYPE_CREEPS, false)
call ashbringer_bounder_missile.setEventOnInterpolationFinished(ProjectileTargetEvent.ashbringer_bounder_bounce)
endfunction
On Attack
ONATTACK_chance: 1.0
ONATTACK_chanceLevelAdd: 0.0
function onAttack takes Tower tower returns nothing
local real bounder_chance = 0.15 + (tower.getLevel() * 0.006)
if tower.calcChance(bounder_chance) then
call ashbringer_bounder_throw(tower)
endif
endfunction
On Damage
ONDAMAGE_chance: 1.0
ONDAMAGE_chanceLevelAdd: 0
function onDamage takes Tower tower returns nothing
local Creep target = Event.getTarget()
local real storm_chance = 0.05 + (tower.getLevel() * 0.002)
call ashbringer_lacerate_damage(tower, target, tower.getCurrentAttackDamageWithBonus(), tower.calcAttackMulticrit(0,0,0))
set Event.damage = 0
if tower.calcChance(storm_chance) then
call ashbringer_storm_throw(tower, target)
endif
endfunction
On Spell Cast function onSpellCast takes Tower tower returns nothing
local Machinations ma = tower.userInt3
local real target_x = GetSpellTargetX()
local real target_y = GetSpellTargetY()
local real dist1
local real dist2 = 0
local integer subcount
local integer max_mach = 3
local integer count = 0
local integer sel = max_mach + 1
local integer closest
loop
if ma.b[count]==false then
set ma.b[count] = true
set ma.e[count] = Effect.createAnimatedScaled("Abilities\\Weapons\\BloodElfSpellThiefMISSILE\\BloodElfSpellThiefMISSILE.mdl", target_x+20, target_y, 40.0, 0.0, 1.45)
call ma.e[count].setAnimationSpeed(2.0)
call ma.e[count].setScale(2.0)
set ma.x[count] = target_x
set ma.y[count] = target_y
if count==0 then
set ma.c[count] = sel
elseif count==1 then
set ma.c[count-1] = 1
set ma.c[count] = 0
else
set ma.c[count] = sel
endif
set ma.max = count
set sel = count
set count = max_mach
else
endif
set count = count + 1
exitwhen count>=max_mach
endloop
if sel>max_mach then
set count = 0
call ma.e[0].destroy()
loop
if count<(max_mach-1) then
set ma.b[count] = ma.b[count+1]
set ma.e[count] = ma.e[count+1]
set ma.x[count] = ma.x[count+1]
set ma.y[count] = ma.y[count+1]
set ma.c[count] = sel
endif
set count = count + 1
exitwhen count==max_mach
endloop
set ma.b[max_mach-1] = true
set ma.e[max_mach-1] = Effect.createAnimatedScaled("Abilities\\Weapons\\BloodElfSpellThiefMISSILE\\BloodElfSpellThiefMISSILE.mdl", target_x+20, target_y, 40.0, 0.0, 1.45)
call ma.e[max_mach-1].setAnimationSpeed(2.0)
call ma.e[max_mach-1].setScale(2.0)
set ma.x[max_mach-1] = target_x
set ma.y[max_mach-1] = target_y
set ma.c[max_mach-1] = sel
set sel = 0
endif
if ma.max>1 then
set count = 0
loop
if ma.b[count]==true then
set subcount = 0
set closest = max_mach + 1
set dist2 = 0
loop
if ma.b[subcount]==true and count!=subcount then
set dist1 = SquareRoot(((ma.x[subcount]-ma.x[count]) * (ma.x[subcount]-ma.x[count])) + ((ma.y[subcount]-ma.y[count]) * (ma.y[subcount]-ma.y[count])))
if dist2==0 then
set dist2 = dist1
endif
if dist1<=dist2 and dist1>=50 then
set dist2 = dist1
set closest = subcount
endif
endif
set subcount = subcount + 1
exitwhen subcount==max_mach
endloop
set ma.c[count] = closest
endif
set count = count + 1
exitwhen count==max_mach
endloop
endif
set tower.userInt3 = ma
endfunction
On Tower Creation function onCreate takes Tower tower returns nothing
call ashbringer_machinations_setup(tower)
endfunction
On Tower Destruction function onDestruct takes Tower tower returns nothing
local Machinations ma = tower.userInt3
local integer max_mach = 3
local integer count = max_mach
loop
set count = count - 1
if ma.b[count] == true then
call ma.e[count].destroy()
endif
exitwhen count==0
endloop
endfunction
Periodic
PERIODIC_period: 1.0
function periodic takes Tower tower returns nothing
local Machinations ma = tower.userInt3
local Iterate i
local integer count = 0
local integer max_mach = 3
local real damage = tower.getCurrentAttackDamageWithBonus() * (0.5 + (tower.getLevel() * 0.01))
local Creep next
loop
if ma.b[count] == true then
set i = Iterate.overUnitsInRange(tower, TARGET_TYPE_CREEPS, ma.x[count], ma.y[count], 150)
set next = i.next()
loop
exitwhen next == 0
call Effect.createSimpleOnUnit("Abilities\\Spells\\Other\\Stampede\\StampedeMissileDeath.mdl", next, "origin").setLifetime(2.0)
call ashbringer_lacerate_damage(tower, next, damage, tower.calcAttackMulticrit(0,0,0))
set next = i.next()
endloop
//call i.destroy()
endif
set count = count + 1
exitwhen count==max_mach
endloop
endfunction
|
Ebonfrost Crystal v1
3600
|
ID: 437
Family ID:
Author: Ashbringer
Rarity: unique
Element: ice
Attack Type: Elemental
Attack Range: 1000
Attack CD: 1.6
Damage: 1960-1960
Mana: 400
Mana regen: 0
Status: Approved
|
Description: A pristine crystal atop a pillar of black frost.
Shattering Barrage
Spends all mana to encase the target in ice, stunning it and increasing damage taken by 100% for up to [mana / 150] seconds. All icicles are then fired at the target. Duration is reduced by 75% on Bosses, to a minimum of 2 seconds. Level Bonus: -1 mana divisor AC_TYPE_OFFENSIVE_UNIT 300, 1000 range, 30s cooldown
Icicles
Attacks have a 15% chance and Icy Bombardments have a 5% chance to create an icicle on hit, which is stored and waits to be fired. Stored icicles passively increase attack damage by 5% and mana regen by 0.5 mana per second each. Maximum of 5 icicles. At maximum icicles, any more icicles created are instantly fired at the target. Each icicle deals 3000 Frostburn damage on hit and permanently increases the damage dealt by future icicles by this tower by 2%. Level Bonus: +0.4% chance on attack +0.1% chance on Icy Bombardment +80 damage +1 max icicle every 5 levels
Icy Bombardment
Attacks have a 15% chance to fire a projectile at a random point within 150 range of the attacked creep that deals 25% of current attack damage as Frostburn damage in 200 AoE splash. Each additional projectile has a 30% chance to fire another, up to a maximum of 4 per attack. Level Bonus: +0.4% initial chance +0.4% additional chance +0.6% damage
Frostburn
This tower's attacks and abilities deal Frostburn damage. 50% of the damage is dealt immediately as attack damage. 100% of the remaining damage is dealt as spell damage over 5 seconds. If this effect is reapplied, any remaining damage will be added to the new duration. Level Bonus: +1% damage over time |
Download
Toggle Triggers Autocast
AUTOCAST_cooldown: 30
AUTOCAST_autoRange: 750
AUTOCAST_manacost: 300
AUTOCAST_range: 1000
AUTOCAST_targetType: 0
AUTOCAST_numBuffsBeforeIdle: 0
caster_art:
target_art:
AUTOCAST_autocastType: AC_TYPE_OFFENSIVE_UNIT
AUTOCAST_buffType: 0
AUTOCAST_isExtended: true
AUTOCAST_targetSelf: false
private function onAutocast takes Tower tower returns nothing
local Creep target = Event.getTarget()
local real towermana = GetUnitState( tower.getUnit(), UNIT_STATE_MANA)
local real duration = towermana / (150 - tower.getLevel())
if target.getSize()==SIZE_BOSS then
set duration = duration * 0.25
if duration<2.0 then
set duration = 2.0
endif
endif
call ashbringer_shatter_buff.applyCustomTimed(tower, target, tower.getLevel(), duration)
call tower.subtractMana(towermana, true)
endfunction
Header globals
BuffType ashbringer_frostburn_buff
BuffType ashbringer_shatter_buff
ProjectileType ashbringer_breath_missile
BuffType ashbringer_icicle_buff
ProjectileType ashbringer_icicle_prop
ProjectileType ashbringer_icicle_missile
endglobals
struct Icicles
Projectile array p[10]
Effect array e[10]
boolean array t[10]
real array x[10]
real array y[10]
endstruct
function ashbringer_icicles_setup takes Tower tower returns nothing
local Icicles ic = Icicles.create()
local integer count = 0
set tower.userInt = 0
set tower.userInt2 = 5 //starting max
set tower.userReal = 0
set tower.userReal2 = I2R(tower.getUID())
loop
set ic.e[count] = 0
set ic.t[count] = false
set count = count + 1
exitwhen count==10
endloop
set tower.userInt3 = ic
endfunction
function ashbringer_icicle_fire takes Tower tower, Creep target returns nothing
call Projectile.createFromPointToUnit(ashbringer_icicle_missile, tower, 0, 0, tower.getX(), tower.getY(), 200, target, true, false, false).setScale(0.7)
set tower.userReal = tower.userReal + 1
endfunction
function ashbringer_icicle_store takes Tower tower returns nothing
local integer num = tower.userInt
local real tower_x
local real tower_y
local real angle
local real target_x
local real target_y
local Projectile p
local Icicles ic = tower.userInt3
//safeguard against remnant icicles, find open icicle slot
if ic.t[num]==true then
set num = 0
loop
set num = num + 1
exitwhen num==tower.userInt2 or ic.t[num-1]!=true
endloop
endif
if num<tower.userInt2 then
set angle = 360 / tower.userInt2 * num
set tower_x = tower.getX()
set tower_y = tower.getY()
set target_x = tower_x + 100 * Cos(Deg2Rad(angle))
set target_y = tower_y + 100 * Sin(Deg2Rad(angle))
set p = Projectile.createLinearInterpolationFromPointToPoint(ashbringer_icicle_prop, tower, 1.0, 0.0, tower_x, tower_y, 200, target_x, target_y, 200, 0.0)
call p.setScale(0.7)
set p.userReal = target_x
set p.userReal2 = target_y
set p.userReal3 = angle
set p.userInt = num
set ic.p[num] = p
set ic.x[num] = p.userReal
set ic.y[num] = p.userReal2
set ic.t[num] = true
set tower.userInt = tower.userInt + 1
call ashbringer_icicle_buff.apply(tower, tower, tower.userInt)
endif
endfunction
function ashbringer_icicle_effect takes Projectile p, Unit target returns nothing
local Tower tower = p.getCaster()
local Icicles ic = tower.userInt3
if ic.e[p.userInt]!=0 then
call ic.e[p.userInt].destroy()
endif
if ic.t[p.userInt]==true and tower.getUID()!=0 and tower.getUID()==R2I(tower.userReal2) then
set ic.e[p.userInt] = Effect.createScaled("Abilities\\Spells\\Other\\FrostBolt\\FrostBoltMissile.mdl", p.userReal, p.userReal2, 200, p.userReal3, 0.7)
call ic.e[p.userInt].noDeathAnimation()
endif
endfunction
function ashbringer_icicle_create takes Tower tower, Creep target returns nothing
if tower.userInt<tower.userInt2 then
call ashbringer_icicle_store(tower) //stores the icicle
else
call ashbringer_icicle_fire(tower, target) //fires on immediately
endif
endfunction
function ashbringer_frostburn_damage takes Tower tower, Creep target, real damage returns nothing
local Buff b
local real damage_stack
local real dot_inc = 1.0 + (tower.getLevel() * 0.01)
local integer limit = 25 + tower.getLevel()
call tower.doAttackDamage(target, damage * 0.5, tower.calcAttackMulticrit(0, 0, 0))
set b = target.getBuffOfType(ashbringer_frostburn_buff)
if b != 0 then
set damage_stack = b.userReal + (damage * 0.5 * dot_inc)
set ashbringer_frostburn_buff.apply(tower, target, 0).userReal = damage_stack
else
set ashbringer_frostburn_buff.apply(tower, target, 0).userReal = (damage * 0.5 * dot_inc)
endif
endfunction
function ashbringer_frostburn_dot takes Buff b returns nothing
local Tower tower = b.getCaster()
local Creep target = b.getBuffedUnit()
local real remaining = b.getRemainingDuration()
local real damage_tick = b.userReal / remaining
if remaining<1 then
set damage_tick = b.userReal
endif
if damage_tick>0 then
set b.userReal = b.userReal - damage_tick
call tower.doSpellDamage(target, damage_tick, tower.calcSpellCritNoBonus())
endif
endfunction
public function ashbringer_icicle_hit takes Projectile p, Creep target returns nothing
local Tower tower = p.getCaster()
call ashbringer_frostburn_damage(tower, target, (3000 + (tower.getLevel() * 80)) * (1.0 + (tower.userReal * 0.02)))
endfunction
public function ashbringer_icicle_fireall takes Tower tower, Creep target returns nothing
local Icicles ic = tower.userInt3
local integer count = tower.userInt2
local Projectile icicle
local Buff b
set tower.userInt = tower.userInt2 //set to max so any created during this time are fired instantly
loop
set count = count - 1
if ic.t[count]==true then
set icicle = Projectile.createFromPointToUnit(ashbringer_icicle_missile, tower, 0, 0, ic.x[count], ic.y[count], 200, target, true, false, false)
set icicle.speed = 1400 - (count * 70)
call icicle.setScale(0.7)
set tower.userReal = tower.userReal + 1
set ic.t[count] = false
endif
call ic.p[count].destroy()
if ic.e[count]!=0 then
call ic.e[count].destroy()
endif
set ic.p[count] = 0
set ic.e[count] = 0
exitwhen count==0
endloop
set tower.userInt = 0
set b = tower.getBuffOfType(ashbringer_icicle_buff)
if b != 0 then
call b.removeBuff()
endif
endfunction
function ashbringer_breath_barrage takes Tower tower, real chance, Creep target returns nothing
local integer shots = 0
local real target_x = target.getX()
local real target_y = target.getY()
local integer UID = target.getUID()
local Projectile p
local real random_angle
local real random_distance
local real launch_x
local real launch_y
loop
set random_angle = GetRandomReal(0, 360)
set random_distance = GetRandomReal(0, 150)
set launch_x = target_x + random_distance * Cos(Deg2Rad(random_angle))
set launch_y = target_y + random_distance * Sin(Deg2Rad(random_angle))
set p = Projectile.createLinearInterpolationFromPointToPoint(ashbringer_breath_missile, tower, 0, 0, tower.getX(), tower.getY(), 200, launch_x, launch_y, 0, 0.2)
set p.userReal = launch_x
set p.userReal2 = launch_y
set shots = shots + 1
exitwhen tower.calcChance(chance) == false or shots>=4
endloop
endfunction
function ashbringer_breath_hit takes Projectile p returns nothing
local Tower tower = p.getCaster()
local Iterate i = Iterate.overUnitsInRange(tower, TARGET_TYPE_CREEPS, p.userReal, p.userReal2, 200)
local Creep next = i.next()
local real damage = tower.getCurrentAttackDamageWithBonus() * (0.25 + (tower.getLevel() * 0.006))
local real icicle_chance = 0.05 + (tower.getLevel() * 0.001)
loop
exitwhen next == 0
call ashbringer_frostburn_damage(tower, next, damage)
if tower.calcChance(icicle_chance) then
call ashbringer_icicle_create(tower, next)
endif
set next = i.next()
endloop
endfunction
function ashbringer_shatter_oncreate takes Buff b returns nothing
local Tower tower = b.getCaster()
local Creep target = b.getBuffedUnit()
call cb_stun.applyOnlyTimed(tower, target, b.getRemainingDuration())
call ashbringer_icicle_fireall(tower, target)
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
local Modifier ashbringer_icicle_modifier = Modifier.create()
local Modifier ashbringer_shatter_modifier = Modifier.create()
set ashbringer_frostburn_buff = BuffType.create(5, 0, false)
call ashbringer_frostburn_buff.setBuffIcon('@@0@@')
call ashbringer_frostburn_buff.addPeriodicEvent(ashbringer_frostburn_dot, 1.0)
set ashbringer_shatter_buff = BuffType.create(5, 0, false)
call ashbringer_shatter_buff.setBuffIcon('@@1@@')
call ashbringer_shatter_modifier.addModification(MOD_ATK_DAMAGE_RECEIVED, 0, 1.0)
call ashbringer_shatter_modifier.addModification(MOD_SPELL_DAMAGE_RECEIVED, 0, 1.0)
call ashbringer_shatter_buff.setBuffModifier(ashbringer_shatter_modifier)
call ashbringer_shatter_buff.addEventOnCreate(ashbringer_shatter_oncreate)
set ashbringer_icicle_buff = BuffType.create(-1.0, 0, true)
call ashbringer_icicle_buff.setBuffIcon('@@2@@')
call ashbringer_icicle_modifier.addModification(MOD_DAMAGE_ADD_PERC, 0.0, 0.05)
call ashbringer_icicle_modifier.addModification(MOD_MANA_REGEN, 0.0, 0.5)
call ashbringer_icicle_buff.setBuffModifier(ashbringer_icicle_modifier)
set ashbringer_breath_missile = ProjectileType.create("Abilities\\Weapons\\FrostWyrmMissile\\FrostWyrmMissile.mdl", 5, 1650)
call ashbringer_breath_missile.setEventOnCleanup(ProjectileEvent.ashbringer_breath_hit)
set ashbringer_icicle_prop = ProjectileType.createInterpolate("Abilities\\Spells\\Other\\FrostBolt\\FrostBoltMissile.mdl", 200)
call ashbringer_icicle_prop.setEventOnInterpolationFinished(ashbringer_icicle_effect)
call ashbringer_icicle_prop.disableExplodeOnExpiration()
set ashbringer_icicle_missile = ProjectileType.create("Abilities\\Spells\\Other\\FrostBolt\\FrostBoltMissile.mdl", 5, 1400)
call ashbringer_icicle_missile.enableHoming(ProjectileTargetEvent.ashbringer_icicle_hit, 0)
endfunction
On Attack
ONATTACK_chance: 0.15
ONATTACK_chanceLevelAdd: 0.004
function onAttack takes Tower tower returns nothing
call ashbringer_breath_barrage(tower, 0.3 + (tower.getLevel() * 0.004), Event.getTarget())
endfunction
On Damage
ONDAMAGE_chance: 1.0
ONDAMAGE_chanceLevelAdd: 0.0
function onDamage takes Tower tower returns nothing
local Creep target = Event.getTarget()
local real damage = Event.damage
local real icicle_chance = 0.15 + (tower.getLevel() * 0.004)
call ashbringer_frostburn_damage(tower, target, damage)
set Event.damage = 0
if tower.calcChance(icicle_chance) then
call ashbringer_icicle_create(tower, Event.getTarget())
endif
endfunction
On Level Up function onLevelUp takes Tower tower returns nothing
local integer prev_max = tower.userInt2
local Icicles ic = tower.userInt3
local Buff b
local integer count = 0
set tower.userInt2 = 5 + (tower.getLevel() / 5)
//cleanup ones over the limit on delevel
if tower.userInt2<prev_max then
set count = tower.userInt2
loop
if ic.t[count]==true then
call ic.p[count].destroy()
if ic.e[count]!=0 then
call ic.e[count].destroy()
endif
set ic.t[count] = false
endif
set count = count + 1
exitwhen count==10
endloop
endif
endfunction
On Tower Creation function onCreate takes Tower tower returns nothing
call ashbringer_icicles_setup(tower)
endfunction
On Tower Destruction function onDestruct takes Tower tower returns nothing
local Icicles ic = tower.userInt3
local integer count = 0
local Buff b
loop
if ic.t[count]==true then
call ic.p[count].destroy()
if ic.e[count]!=0 then
call ic.e[count].destroy()
endif
set ic.t[count] = false
endif
set count = count + 1
exitwhen count==10
endloop
call ic.destroy()
set b = tower.getBuffOfType(ashbringer_icicle_buff)
if b != 0 then
call b.removeBuff()
endif
endfunction
|
Living Volcano v1
3600
|
ID: 468
Family ID:
Author: Kricz
Rarity: unique
Element: fire
Attack Type: Decay
Attack Range: 1100
Attack CD: 1.8
Damage: 1771-1771
Status: Approved
|
Description: An ancient volcano that has lived for thousands of years. The heat radiating from its lava can be felt from kilometers away.
Specials:
+45% dmg to nature (+2%/lvl) +7.5% damage/lvl +1.5% spell damage/lvl
Heat Stroke
Whenever a creep dies while under the effect of Heat Aura, there is a 40% chance that it will explode, dealing 4500 damage in 300 AoE. Level Bonus: +100 damage
Lava Attack
Has a 25% chance on attack to throw a burning lava ball towards the target's location, dealing 3500 damage to creeps in 300 AoE. Level Bonus: +5 AoE +100 damage
Heat Aura - Aura
Burns every enemy in 700 range, making them lose 3% of their current life every second. |
Download
Toggle Triggers Header globals
ProjectileType Kricz_LV_M
BuffType Kricz_LV_HA
endglobals
function ragingHeatDamage takes Buff b returns nothing
local Creep creep = b.getBuffedUnit()
local Tower tower = b.getCaster()
local unit u = creep.getUnit()
local real life = GetWidgetLife(u)
local real dmg = life * 0.03 * tower.getDamageToCategory(creep.getCategory())
//Gex meant it is okay so...
if life < 2. then
call tower.killInstantly(creep)
else
call SetWidgetLife(u, life - dmg)
endif
set u = null
endfunction
function heatStroke takes Buff b returns nothing
local Tower tower = b.getCaster()
local Creep creep = b.getBuffedUnit()
if tower.calcChance(0.4) then
call SFXAtUnit("Abilities\\Spells\\Other\\Incinerate\\FireLordDeathExplode.mdl",creep.getUnit())
call tower.doSpellDamageAoEUnit(creep, 300, 4500 + tower.getLevel() * 100, tower.calcSpellCritNoBonus(), 0.33)
endif
endfunction
function LavaAttackMissileEnd takes Projectile p returns nothing
local Unit c = p.getCaster()
call DestroyEffect(AddSpecialEffect("Objects\\Spawnmodels\\Other\\NeutralBuildingExplosion\\NeutralBuildingExplosion.mdl", p.x, p.y))
call c.doSpellDamageAoE(p.x, p.y, p.userReal, p.userReal2, c.calcSpellCritNoBonus(), 0.25)
endfunction
private function init takes nothing returns nothing
local Modifier HAM = Modifier.create()
set Kricz_LV_M = ProjectileType.create("Abilities\\Weapons\\BallsOfFireMissile\\BallsOfFireMissile.mdl", 1.5, 650)
call Kricz_LV_M.setEventOnCleanup(ProjectileEvent.LavaAttackMissileEnd)
set Kricz_LV_HA = BuffType.createAuraEffectType(false)
call Kricz_LV_HA.setBuffModifier(HAM)
call Kricz_LV_HA.addPeriodicEvent(EventHandler.ragingHeatDamage, 1.0)
call Kricz_LV_HA.addEventOnDeath(EventHandler.heatStroke)
call Kricz_LV_HA.setStackingGroup("KRICZ_LV_DMG_AURA")
call Kricz_LV_HA.setBuffIcon('@@0@@')
endfunction
On Attack
ONATTACK_chance: 0.25
ONATTACK_chanceLevelAdd: 0.0
function onAttack takes Tower tower returns nothing
local Unit u = Event.getTarget()
local integer lvl = tower.getLevel()
local real AoE = 300 + 5 * lvl
local real dmg = 3500. + lvl * 100
local Projectile p
set p = Projectile.createLinearInterpolationFromUnitToPoint(Kricz_LV_M, tower, 1., tower.calcSpellCritNoBonus(), tower, u.getX(), u.getY(), 0., 0.45)
set p.userReal = AoE
set p.userReal2 = dmg
endfunction
Tower Aura
AURA_auraEffect: Kricz_LV_HA
AURA_power: 1
AURA_level: 0
AURA_auraRange: 700
AURA_targetType: TARGET_TYPE_CREEPS
AURA_levelAdd: 1
AURA_powerAdd: 1
AURA_targetSelf: false
|
Description: