Array
(
[scriptVersion] => 7
[oeValues] => Array
(
[auto] => Array
(
)
[Art] => ReplaceableTextures\CommandButtons\BTNDragonHawk.blp
[turnRate] => 1
[dmgplus1] => 3108
[bldtm] => 1
[goldcost] => 3500
[sides1] => 30
[acquire] => 1000
[upgrades] => Array
(
)
[Upgrade] => Array
(
)
[Name] => Drake Whisperer
[weapTp1] => missile
[MissileHoming] => 1
[file] => units\human\BloodElfDragonHawk\BloodElfDragonHawk.mdl
[Missileart] => Abilities\Weapons\DragonHawkMissile\DragonHawkMissile.mdl
[Missilespeed] => 1300
[dice1] => 1
[RngBuff1] => 250
[modelScale] => 0.6
[rangeN1] => 1000
[atkType1] => pierce
[cool1] => 1.9
[Ubertip] => Unleashes mighty drakes against his enemies.
[abilList] => Array
(
)
[moveHeight] => 120
[buildingShadow] => Array
(
)
[targs1] => Array
(
)
[weapsOn] => 1
)
[settings] => Array
(
[balanceTip] => |cffFFFF00+15% |rdmg to air (|cffFFFF00+0.4%|r/lvl)
[abil_factor] => 0.4
[author] => Ely
[alpha] => 255
[authorDisplay] => Ely
[version] => 1.0
[element] => astral
[rarity] => unique
)
[effects] => Array
(
[0] => Array
(
[x] => 1.03415
[y] => 10.5561
[z] => 0
[scale] => 0.25
[rot] => 5.40134
[file] => Doodads\Barrens\Rocks\Crator\Crator0.mdl
[red] => 255
[green] => 255
[blue] => 255
[alpha] => 255
[pitch] => 0
[advanced] => false
[animation] => Array
(
)
[aniSpeed] => 50
)
[1] => Array
(
[x] => -5.66618
[y] => -34.6128
[z] => 0
[scale] => 0.25
[rot] => 4.52489
[file] => Doodads\Ruins\Rocks\CliffRubble_Double\CliffRubble_Double0.mdl
[red] => 255
[green] => 255
[blue] => 255
[alpha] => 255
[pitch] => 0
[advanced] => false
[animation] => Array
(
)
[aniSpeed] => 50
)
[2] => Array
(
[x] => -44.7844
[y] => 32.8657
[z] => 0
[scale] => 0.25
[rot] => 2.49406
[file] => Doodads\Ruins\Rocks\CliffRubble_Double\CliffRubble_Double0.mdl
[red] => 255
[green] => 255
[blue] => 255
[alpha] => 255
[pitch] => 0
[advanced] => false
[animation] => Array
(
)
[aniSpeed] => 50
)
[3] => Array
(
[x] => 46.7131
[y] => 13.954
[z] => 0
[scale] => 0.25
[rot] => 0.103301
[file] => Doodads\Ruins\Rocks\CliffRubble_Double\CliffRubble_Double0.mdl
[red] => 255
[green] => 255
[blue] => 255
[alpha] => 255
[pitch] => 0
[advanced] => false
[animation] => Array
(
)
[aniSpeed] => 50
)
[4] => Array
(
[x] => 37.4723
[y] => -31.1867
[z] => 0
[scale] => 0.25
[rot] => 5.39073
[file] => Doodads\Cityscape\Structures\City_ColumnSingle\City_ColumnSingle.mdl
[red] => 255
[green] => 255
[blue] => 255
[alpha] => 255
[pitch] => 0
[advanced] => false
[animation] => Array
(
)
[aniSpeed] => 50
)
[5] => Array
(
[x] => -46.1935
[y] => -13.3162
[z] => 0
[scale] => 0.25
[rot] => 0.253359
[file] => Doodads\Cityscape\Structures\City_ColumnSingle\City_ColumnSingle.mdl
[red] => 255
[green] => 255
[blue] => 255
[alpha] => 255
[pitch] => 0
[advanced] => false
[animation] => Array
(
)
[aniSpeed] => 50
)
[6] => Array
(
[x] => 28.3314
[y] => 56.9645
[z] => 0
[scale] => 0.25
[rot] => 1.10688
[file] => Doodads\Cityscape\Structures\City_ColumnSingle\City_ColumnSingle.mdl
[red] => 255
[green] => 255
[blue] => 255
[alpha] => 255
[pitch] => 0
[advanced] => false
[animation] => Array
(
)
[aniSpeed] => 50
)
[7] => Array
(
[x] => 36.5976
[y] => -36.0901
[z] => 89.6
[scale] => 0.4
[rot] => 0.994838
[file] => Doodads\Cinematic\GlowingRunes\GlowingRunes4.mdl
[red] => 255
[green] => 255
[blue] => 255
[alpha] => 255
[pitch] => 0
[advanced] => false
[animation] => Array
(
)
[aniSpeed] => 50
)
[8] => Array
(
[x] => -46.7586
[y] => -15.9918
[z] => 83.2
[scale] => 0.4
[rot] => 5.2709
[file] => Doodads\Cinematic\GlowingRunes\GlowingRunes6.mdl
[red] => 255
[green] => 255
[blue] => 255
[alpha] => 255
[pitch] => 0
[advanced] => false
[animation] => Array
(
)
[aniSpeed] => 50
)
[9] => Array
(
[x] => 27.6061
[y] => 58.1451
[z] => 83.2
[scale] => 0.4
[rot] => 2.04204
[file] => Doodads\Cinematic\GlowingRunes\GlowingRunes0.mdl
[red] => 255
[green] => 255
[blue] => 255
[alpha] => 255
[pitch] => 0
[advanced] => false
[animation] => Array
(
)
[aniSpeed] => 50
)
)
[dmgTable] => Array
(
[0] => Array
(
[id] => MOD_DMG_TO_AIR
[base] => 0.15
[add] => 0.004
)
)
[triggers] => Array
(
[0] => Array
(
[name] => On Attack
[code] => 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)
[values] => Array
(
[visible] => true
[icon] => ReplaceableTextures\CommandButtons\BTNBronzeDragon.blp
[name] => Unleash
[short_explain] => The Drake Whisperer has a chance on attack to unleash a bronze drake towards the attacked target. The drake periodically deals spell damage to a random creep in front of itself.
[ONATTACK_chance] => 0.125
[ONATTACK_chanceLevelAdd] => 0.003
[long_explain] => On attack, the Drake Whisperer has a |cffFFFF8012.5%|r chance to unleash a bronze drake towards its target, dealing |cffFFFF801250|r spell damage to a random creep in front of itself in |cffFFFF80600|r range every |cffFFFF800.2|r seconds. Lasts |cffFFFF802|r seconds.|n|n|cffFF8000Level Bonus:|r|n|cffFFFF80+40|r spell damage|n|cffFFFF80+0.3%|r chance
)
)
[1] => Array
(
[name] => Header
[code] => 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.getFamily() != tower.getFamily() 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('@@1@@')
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('@@0@@')
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
[values] => Array
(
[visible] => true
[icon] => ReplaceableTextures\CommandButtons\BTNDragonHawk.blp
[name] => Versatile
[short_explain] => Every time this tower deals spell damage through its abilities, it increases its dps temporarily. This ability stacks.
[long_explain] => Every time this tower deals spell damage through its abilities, it increases its dps by |cffFFFF801.5%|r of the spell damage dealt. Lasts |cffFFFF802.5|r seconds and stacks. Maximum bonus of |cffFFFF80[200 x (current wave)]|r.|n|n|cffFF8000Level Bonus:|r|n|cffFFFF80+0.04%|r damage
)
)
[2] => Array
(
[name] => On Tower Destruction
[code] => 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()
[values] => Array
(
[visible] => false
[icon] =>
[name] =>
[short_explain] =>
[long_explain] =>
)
)
[3] => Array
(
[name] => Periodic
[code] => call feeding(tower)
[values] => Array
(
[visible] => true
[PERIODIC_period] => 1.5
[icon] => ReplaceableTextures\CommandButtons\BTNGreenDragon.blp
[name] => Feed the Drakes
[short_explain] => The Drake Whisperer periodically feeds a nearby corpse to one of his drakes and then unleashes the drake to either deal spell damage and slow, deal attack damage and stun or deal spell damage and apply Versatile to towers in 175 range.
[long_explain] => Every |cffFFFF801.5|r seconds, the Drake Whisperer feeds a nearby corpse to one of his drakes and unleashes it to a random target in |cffFFFF801000|r range. If there is no target, the drake will attack on the next feeding, with a maximum of |cffFFFF805|r fed drakes. Each corpse has a |cffFFFF8015%|r chance to feed |cffFFFF802|r drakes.|n|nThe |c006969FFBlue|r Drake deals |cffFFFF806000|r spell damage in |cffFFFF80125|r AoE and slows by |cffFFFF8025%|r for |cffFFFF803|r seconds.|nThe |c00FF0000Red|r Drake deals |cffFFFF80200%|r of the tower's attack damage and stuns for |cffFFFF803|r seconds.|nThe |c0096FF96Green|r Drake deals |cffFFFF805000|r spell damage and spreads |cffFFFF80Versatile|r's current dps bonus to towers in |cffFFFF80175|r range for |cffFFFF802.5|r seconds.|n|n|cffFF8000Level Bonus:|r|n|cffFFFF80+0.4%|r double feed chance|n|c006969FFBlue|r Drake : |cffFFFF80+150|r spell damage|n|c00FF0000Red|r Drake : |cffFFFF80+8%|r damage|n|c0096FF96Green|r Drake : |cffFFFF80+0.04|r seconds duration
)
)
[4] => Array
(
[name] => On Tower Creation
[code] => 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
[values] => Array
(
[visible] => false
[icon] =>
[name] =>
[short_explain] =>
[long_explain] =>
)
)
)
[abilities] => Array
(
)
[buffs] => Array
(
[0] => Array
(
[id] => @@0@@
[derivedFrom] => Bapl
[oeValues] => Array
(
[Targetattach] => Array
(
)
[Buffubertip] => This unit is slowed by a blue drake.
[TargetArt] => Abilities\Spells\Other\BreathOfFrost\BreathOfFrostTarget.mdl
[Bufftip] => Blue Drake
[Buffart] => ReplaceableTextures\CommandButtons\BTNAzureDragon.blp
)
)
[1] => Array
(
[id] => @@1@@
[derivedFrom] => Bapl
[oeValues] => Array
(
[Targetattach] => overhead
[Buffubertip] => This tower has increased dps.
[TargetArt] => Abilities\Spells\Human\InnerFire\InnerFireTarget.mdl
[Bufftip] => Versatile
[Buffart] => ReplaceableTextures\CommandButtons\BTNDragonHawk.blp
)
)
)
[units] => Array
(
)
[references] => Array
(
)
)