Healing Shrine v1
3000
ID:
629
Family ID:
Author:
SirCoqaLot.
Rarity:
uncommon
Element:
astral
Attack Type:
Elemental
Attack Range:
1000
Attack CD:
1.5
Damage:
10109-10171
Status:
Approved

Description:

Basic tower that can't hold back its holy powers for long.
Grace
65% of the damage done by this tower will be revoked over 3 seconds. Does not affect immune targets.

Level Bonus:
 -0.8% of the damage healed. 
+1 second needed to heal at level 15 and 25
Download

Toggle Triggers

On Damage

ONDAMAGE_chance: 1.0 ONDAMAGE_chanceLevelAdd: 0.0
function onDamage takes Tower tower returns nothing
local Unit target = Event.getTarget()
local integer id = target.getUID()
local integer loopnr = tower.userInt
local integer healing = R2I(Event.damage*(0.65-tower.getLevel()*0.008))

if not target.isImmune() then
    set healing = R2I(healing/loopnr)
    loop
        exitwhen loopnr == 0
        call TriggerSleepAction(1.0)
        if target.getUID() == id then
            call SetUnitState(target.getUnit(),UNIT_STATE_LIFE,GetUnitState(target.getUnit(),UNIT_STATE_LIFE)+healing)
            call SFXAtUnit("Abilities\\Spells\\Human\\HolyBolt\\HolyBoltSpecialArt.mdl",target.getUnit())
            call tower.getOwner().displayFloatingTextX("+"+I2S(healing),target,0, 255, 0,255,0.05,0.0,2.0)
        endif
        set loopnr = loopnr - 1
    endloop
endif
endfunction

On Level Up

function onLevelUp takes Tower tower returns nothing
    local integer level = tower.getLevel()
    if level < 15 then
        set tower.userInt = 3
    elseif level < 25 then
        set tower.userInt = 4
    else 
        set tower.userInt = 5
    endif
endfunction

On Tower Creation

function onCreate takes Tower tower returns nothing
    local integer level = tower.getLevel()
    if level < 15 then
        set tower.userInt = 3
    elseif level < 25 then
        set tower.userInt = 4
    else 
        set tower.userInt = 5
    endif
endfunction
Citadel of Souls v1
3000
ID:
631
Family ID:
Author:
Natac
Rarity:
rare
Element:
darkness
Attack Type:
Decay
Attack Range:
800
Attack CD:
1.4
Damage:
1902-2052
Status:
Approved

Description:

The last place of all already fallen souls, seeking for their last revenge.
Revenge of Souls
This tower gains 18 permanent bonus damage and 3 experience every time a creep in 1000 range dies.

Level Bonus:
+0.9 damage per kill
Download

Toggle Triggers

Header

    globals
        //@import
        BuffType  natac_revengeOfSouls_Buff
    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 Tower Creation

function onCreate takes Tower tower returns nothing
    local Tower preceding = Event.getPrecedingTower()
    local real  soulBonus
    
    set tower.userInt   = 3
    set tower.userReal  = 18
    set tower.userReal2 = 0.9   
    
    if(preceding != 0 and preceding.getFamily() == tower.getFamily()) then
        set  soulBonus       = preceding.userReal3
        set  tower.userReal3 = soulBonus
        call tower.modifyProperty(MOD_DAMAGE_ADD, soulBonus)
    else
        set   tower.userReal3  = 0.0 //Damage bonus from souls
    endif
    
    
endfunction

Tower Aura

AURA_auraEffect: natac_revengeOfSouls_Buff AURA_power: 1 AURA_level: 1 AURA_auraRange: 1000 AURA_targetType: TARGET_TYPE_CREEPS AURA_levelAdd: 0 AURA_powerAdd: 0 AURA_targetSelf: false
Frozen Spirit v1
3000
ID:
647
Family ID:
Author:
Boekie
Rarity:
rare
Element:
ice
Attack Type:
Energy
Attack Range:
950
Attack CD:
2
Damage:
1013-1013
Status:
Approved

Description:

An icy spirit that lives in the north. It can invoke an ice nova.
Nova Storm
When this tower attacks there is a 25% chance to hit 3 creeps in 900 range around it with ice novas. A nova hits all creeps in 200 AoE dealing 2100 spelldamage at the centre, dropping off to 50% at the sides. Also slows by 12.5% for 4 seconds.

Level Bonus:
+105 spelldamage 
+0.5% chance 
+0.5% slow 
+1 nova at lvl 15 and 25
Download

Toggle Triggers

Header

    globals
    //@import  
    BuffType boekie_icySpirit_buff
    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 Attack

ONATTACK_chance: 0.25 ONATTACK_chanceLevelAdd: 0.005
function onAttack takes Tower tower returns nothing
    local integer level = tower.getLevel() 

    if tower.userInt != 0 then
        if level < 15 then
            set tower.userInt2 = 3 
        elseif level < 25 then
            set tower.userInt2 = 4
        else
            set tower.userInt2 = 5
        endif

        call PeriodicEvent(tower.userInt).enable() 
    endif 
endfunction

On Tower Creation

function onCreate takes Tower tower returns nothing
    set tower.userInt = 0 //Saves the periodic
    set tower.userInt2 = 0 //Saves the number of novas remaining to fire
endfunction

Periodic

PERIODIC_period: 0.1
function periodic takes Tower tower returns nothing
    local Iterate it
    local Unit target 
    local integer level = tower.getLevel()

    if tower.userInt2 > 0 then 
        set it = Iterate.overUnitsInRangeOfCaster(tower,TARGET_CREEPS,900) 
        set target = it.nextRandom()

        if target != 0 then
            call it.destroy()
            call tower.doSpellDamageAoEUnit(target,200,2100.0+(level*105.0),tower.calcSpellCritNoBonus(),0.5)
            call SFXOnUnit("Abilities\\Spells\\Undead\\FrostNova\\FrostNovaTarget.mdl",target.getUnit(),"origin")

            set it = Iterate.overUnitsInRangeOfUnit(tower,TARGET_CREEPS,target,200) 
            loop
                set target = it.next()
                exitwhen target == 0
                call boekie_icySpirit_buff.apply(tower,target,125+level*5)
            endloop 
        endif 

        set tower.userInt2 = tower.userInt2 - 1 
    else
        //Save the periodic event
        if tower.userInt == 0 then
            set tower.userInt = Event.getCurrentPeriodicEvent()
        endif
        call PeriodicEvent(tower.userInt).disable()
    endif 
endfunction
Garden of Eden v1
3000
ID:
652
Family ID:
Author:
Majildian
Rarity:
unique
Element:
nature
Attack Type:
Essence
Attack Range:
800
Attack CD:
1
Damage:
1885-1888
Status:
Approved

Description:

A natural wonder, once lost to the sands of time, has re-appeared harnessing a spiteful vengence.
Specials:
+50% dmg to nature
+50% dmg to orcs
+50% dmg to humanoids
Eden's Wrath
The garden uses half of the stored lifeforce to create a huge explosion, dealing [current spawn level x 15] spell damage in 1600 AoE for each lifeforce stored.

AC_TYPE_OFFENSIVE_IMMEDIATE
 0, 800 range, 10.0s cooldown
Essence of the Mortals
When the garden kills a nature, orc or human unit, its lifeforce is captured in the fountain. For each lifeforce stored in the fountain, the garden deals an additional [current spawn level x 2] spell damage on attack. Maximum of 5 stored lifeforce.

Level Bonus:
+1 maximum lifeforce
Download

Toggle Triggers

Autocast

caster_art: none AUTOCAST_cooldown: 10.0 AUTOCAST_numBuffsBeforeIdle: 0 AUTOCAST_isExtended: false AUTOCAST_autocastType: AC_TYPE_OFFENSIVE_IMMEDIATE AUTOCAST_manacost: 0 AUTOCAST_range: 800 AUTOCAST_buffType: 0 AUTOCAST_targetSelf: false AUTOCAST_targetType: 0 target_art: none AUTOCAST_autoRange: 800
private function onAutocast takes Tower tower returns nothing
    local real x = tower.getX()
    local real y = tower.getY()
    local Effect Boom
    local integer UID = tower.getUID()
    if tower.userInt > 0 then
        set Boom = Effect.createAnimatedScaled("Units\\NightElf\\Wisp\\WispExplode.mdl",x,y,0,0,8.0)
        call Boom.setAnimationSpeed(.6)
        call Boom.setLifetime(2.0)
        set Boom = Effect.createAnimatedScaled("Units\\NightElf\\Wisp\\WispExplode.mdl",x,y,0,0,8.0)
        call Boom.setAnimationSpeed(.7)
        call Boom.setLifetime(2.0)
        set Boom = Effect.createAnimatedScaled("Units\\NightElf\\Wisp\\WispExplode.mdl",x,y,0,0,8.0)
        call Boom.setAnimationSpeed(.8)
        call Boom.setLifetime(2.0)
        set Boom = Effect.createAnimatedScaled("Units\\NightElf\\Wisp\\WispExplode.mdl",x,y,0,0,8.0)
        call Boom.setAnimationSpeed(.9)
        call Boom.setLifetime(2.0)
        call TriggerSleepAction(0.5)
        if tower.getUID() == UID then
            call tower.doSpellDamagePBAoE(1600.0,tower.userInt*15*tower.userInt2,tower.calcSpellCritNoBonus(),0.0)
            set tower.userInt = R2I(tower.userInt*0.5)
        endif
    endif
endfunction

Header

    globals
        MultiboardValues lfValue
    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
        set lfValue=MultiboardValues.create(1)
        call lfValue.setKey(0,"Lifeforce Stored")  
    endfunction

On Attack

ONATTACK_chance: 1.0 ONATTACK_chanceLevelAdd: 0.0
function onAttack takes Tower tower returns nothing
    local Creep target = Event.getTarget()
    set tower.userInt2 = target.getSpawnLevel()
    call tower.doSpellDamage(target,tower.userInt*2*tower.userInt2,tower.calcSpellCritNoBonus())
endfunction

On Kill

function onKill takes Tower tower returns nothing
    local integer category = Creep(Event.getTarget()).getCategory()
    if tower.userInt < (tower.getLevel()+5) and (category == CATEGORY_NATURE or category == CATEGORY_ORC or category == CATEGORY_HUMANOID) then
        set tower.userInt = (tower.userInt+1)
        call SFXAtUnit("Objects\\Spawnmodels\\NightElf\\NEDeathMedium\\NEDeath.mdl",tower.getUnit())
    endif
endfunction

On Tower Creation

function onCreate takes Tower tower returns nothing
    set tower.userInt = 0
endfunction

On Tower Details

function onTowerDetails takes Tower tower returns MultiboardValues
    call lfValue.setValue(0,I2S(tower.userInt))
    return lfValue
endfunction
Fortified Sniper Nest v1
3000
ID:
665
Family ID:
Author:
cedi
Rarity:
uncommon
Element:
iron
Attack Type:
Physical
Attack Range:
1400
Attack CD:
2.5
Damage:
4252-4252
Status:
Approved

Description:

A long ranged tower which is good against bosses, but weak against mass creeps.
Specials:
-70% dmg to masses
-30% dmg to normals
+20% dmg to champions (+1.6%/lvl)
+50% dmg to bosses (+4%/lvl)
+20% dmg to air (+1.6%/lvl)
Rocket Strike
30% chance to fire a rocket towards the attacked unit. On impact it deals 4000 damage in a 180 AoE. Deals 125% damage to mass creeps.

Level Bonus:
+0.6% chance
+100 damage
Download

Toggle Triggers

Header

    globals
        //@import
        ProjectileType cedi_sniper_rocket
    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 Attack

ONATTACK_chance: 0.30 ONATTACK_chanceLevelAdd: 0.006
function onAttack takes Tower tower returns nothing
    set Projectile.createLinearInterpolationFromUnitToUnit(cedi_sniper_rocket,tower,40.0+tower.getLevel()*1.0, tower.calcSpellCritNoBonus(),tower,Event.getTarget(),0.25,true).userReal = 180.0
endfunction
Gryphon Rider v1
3050
ID:
157
Family ID:
Author:
cedi
Rarity:
unique
Element:
storm
Attack Type:
Energy
Attack Range:
900
Attack CD:
2
Damage:
5040-5050
Mana:
55
Mana regen:
2
Status:
Approved

Description:

WC2 wasn't enough.
Specials:
Attacks GROUND only
+8% damage/lvl
Hammer Fall
Summons a hammer which falls from the sky. The hammer deals 10000 spell damage to all units in 600 AoE and stuns them for 1 second. Each of the player's storm tower in 2500 range loses 10% attack damage for 6 seconds but increases the spell damage of the Hammer by 5%. Can gain a maximum of 100% bonus damage.

Level Bonus:
+0.2% damage from towers

AC_TYPE_OFFENSIVE_UNIT
 50, 900.0 range, 10.0s cooldown
Mystical Storm Hammer
Whenever this tower damages a creep, part of the damage is dealt as spell damage and the rest as attack damage. The amount of spell damage depends on the magic resistance of the target. The higher the resistance, the smaller ratio of spell damage dealt. Deals no spell damage against immune creeps and deals no physical damage against banished creeps. If this ability deals all the damage in one type, it will have 5% increased critchance.

Level Bonus:
+1.8% crit chance
Storm Bolt
When this tower attacks it launches a storm bolt towards the target unit. Upon collision, the bolt deals the towers attack damage to the target and creates a trail of 5 storm explosions. The explosions deal the tower's attack damage to every unit in 85 AOE. Each explosion deals 40% less damage than the previous one.

Level Bonus:
-1.2% damage reduction
Download

Toggle Triggers

Autocast

caster_art: AUTOCAST_cooldown: 10.0 AUTOCAST_numBuffsBeforeIdle: 0 AUTOCAST_isExtended: false AUTOCAST_autocastType: AC_TYPE_OFFENSIVE_UNIT AUTOCAST_manacost: 50 AUTOCAST_range: 900.0 AUTOCAST_buffType: 0 AUTOCAST_targetSelf: true AUTOCAST_targetType: 0 target_art: AUTOCAST_autoRange: 900.0
private function onAutocast takes Tower tower returns nothing
    local Projectile P = Projectile.createFromUnit( HR, tower, Event.getTarget(), 0.0, 1.0, 1.0 )
    local Iterate I = Iterate.overUnitsInRangeOfCaster( tower, TARGET_PLAYER_TOWERS, 2500.0 )
    local Tower U
    local real r = 1
    call P.setScale( 8 )
    set P.z = 1000.0
    set P.userReal = 10000.0
    
    loop
        set U = I.next()
        exitwhen U == 0
        if U.getElement() == Element.STORM then
            set r = r + ( 0.05 + 0.002 * tower.getLevel() )
            call BT.apply( tower, U, 0 )
        endif
        if r >= 2.0 then
            call I.destroy()
            exitwhen true
        endif
    endloop
    set P.userReal = P.userReal * r
endfunction

Header

    globals
        ProjectileType PT
        ProjectileType HR
        BuffType BT
    endglobals
        
    function DealDamage takes Tower T, Creep C, real dmg returns nothing
        local real spell = C.getProp_SpellDmgReceived()
        local real phys = C.getProp_AtkDmgReceived()
        local real r
        local real crit = 0.0
        
        //calc spell damage taken
        //Immune?
        if C.isImmune() then
            //0% spell damage
            set spell = 0
        endif
        
        //calc physical damage taken
        //Banished?
        if C.isBanished() then
            //0% physical damage
            set phys = 0
        else
            //armor
            set phys = phys * C.getCurrentArmorDamageReduction()
        endif
        
        //we don't want anything below zero!
        if spell < 0.00 then
            set spell = 0
        endif
        if phys < 0.00 then
            set phys = 0
        endif
        
        //Result are how much physical and spell damage the unit takes.
        //Probably adding these two wont result in 100% so we have to scale them
        set r = spell + phys
        if r <= 0 then
            //shit happened...
            return
        endif
        if r != 1.0 then
            set spell = spell / r
            set phys = phys / r
        endif
        
        //crit bonus?
        if phys == 1.0 or spell == 1.0 then
            set crit = 0.05 + 0.018 * T.getLevel()
        endif
        //Now we know what we need to know to deal damage
        call T.doSpellDamage( C, dmg * spell, T.calcSpellCrit(crit, 0.0) )
        call T.doAttackDamage( C, dmg * phys, T.calcAttackMulticrit(crit, 0, 0) )
    endfunction
    
    function LineDamage takes Tower T, real sx, real sy, real angle returns nothing
        local Iterate I
        local Creep C
        local integer i = 0
        local real distance = 128.0
        local real x
        local real y
        local Effect E
        local real dmg = T.getCurrentAttackDamageWithBonus()
        local integer UID = T.getUID()
        set angle = angle * bj_DEGTORAD
        loop
            exitwhen i >= 5 or T.getUID() != UID
            set x = sx + Cos( angle ) * ( distance * i )
            set y = sy + Sin( angle ) * ( distance * i )
            set I = Iterate.overUnitsInRange( T, TARGET_CREEPS, x, y, 85.0 )
            loop
                set C = I.next()
                exitwhen C == 0
                call DealDamage( T, C, dmg )
            endloop
            //Effect creation
            call Effect.createScaled( "Abilities\\Spells\\Human\\Thunderclap\\ThunderClapCaster.mdl", x, y, 0.00, 0.00, 0.5 ).setLifetime(1.5)
            call Effect.createColored( "Abilities\\Spells\\Other\\Monsoon\\MonsoonBoltTarget.mdl", x, y, 0.00, 0.00, 2.0, 0, 0, 0, 255 ).setLifetime(2.5)
            
            set dmg = dmg * ( 0.6 + 0.012 * T.getLevel() )
            set i = i + 1
            call TriggerSleepAction( 0.15 )
        endloop
    endfunction
    
    function hit takes Projectile P, Creep C returns nothing
        local Tower T = P.getCaster()
        if C != 0 then
            //hit
            call DealDamage( T, C, T.getCurrentAttackDamageWithBonus() )
        endif
        call LineDamage( T, P.x, P.y, P.direction )
    endfunction
    
    function impact takes Projectile P returns nothing
        local Tower T = P.getCaster()
        local Iterate I = Iterate.overUnitsInRange( T, TARGET_CREEPS, P.x, P.y, 600.0 )
        local Unit U
        
        loop
            set U = I.next()
            exitwhen U == 0
            call DealDamage( T, U, P.userReal )
            call cb_stun.applyOnlyTimed( T, U, 1.0 )
        endloop
    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 m = Modifier.create()
        call m.addModification( MOD_DAMAGE_ADD_PERC, -0.1, 0.0 )
        
        set PT = ProjectileType.createInterpolate( "Abilities\\Spells\\Human\\StormBolt\\StormBoltMissile.mdl", 1100.0 )
        call PT.setEventOnInterpolationFinished( hit )
        
        set HR = ProjectileType.create( "Abilities\\Spells\\Human\\StormBolt\\StormBoltMissile.mdl", 90.0, 0.0 )
        call HR.enablePhysics( 0, impact, -30, 0, 0.0 )
        
        set BT = BuffType.create( 6.0, 0.0, false )
        call BT.setBuffIcon( '@@0@@' )
        call BT.setBuffModifier( m )
    endfunction

On Attack

ONATTACK_chance: 1.0 ONATTACK_chanceLevelAdd: 0.0
function onAttack takes Tower tower returns nothing
    call Projectile.createLinearInterpolationFromUnitToUnit( PT, tower, 1.0, 1.0, tower, Event.getTarget(), 0.15, true )
endfunction

On Damage

ONDAMAGE_chance: 1.0 ONDAMAGE_chanceLevelAdd: 0.0
function onDamage takes Tower tower returns nothing
    set Event.damage = 0
endfunction
Queen of Light v1
3100
ID:
168
Family ID:
Author:
Boekie
Rarity:
rare
Element:
astral
Attack Type:
Magic
Attack Range:
1000
Attack CD:
1.5
Damage:
3389-3389
Mana:
30
Mana regen:
1.5
Status:
Approved

Description:

This tower is able to extract experience from creeps and energy from spells.
Specials:
+2 mana/lvl
Extract Experience
Casts a buff on a creep. Towers that damage this creep have a 33% chance to extract 2 experience. Buff lasts 10 seconds or until 10 extractions occur.

Level Bonus:
+0.1 experience
+1 extraction

AC_TYPE_OFFENSIVE_BUFF
 20, 1000 range, 5s cooldown
Channel Energy
Whenever this tower is hit by a friendly spell, the caster of that spell will be granted 2 experience and this tower will gain 20% bonus damage for 12 seconds. This effect stacks up to 15 times, but new stacks will not refresh the duration of olds ones.

Level Bonus:
+0.5% damage 
+0.1 seconds duration
Download

Toggle Triggers

Autocast

caster_art: AUTOCAST_cooldown: 5 AUTOCAST_numBuffsBeforeIdle: 3 AUTOCAST_isExtended: false AUTOCAST_autocastType: AC_TYPE_OFFENSIVE_BUFF AUTOCAST_manacost: 20 AUTOCAST_range: 1000 AUTOCAST_buffType: boekie_expGain_buff AUTOCAST_targetSelf: false AUTOCAST_targetType: TARGET_TYPE_CREEPS target_art: AUTOCAST_autoRange: 1000
private function onAutocast takes Tower tower returns nothing
    local integer level = tower.getLevel()
    set boekie_expGain_buff.apply(tower,Event.getTarget(),level*2 + 20).userInt = 10 + level
endfunction

Header

    globals
        //@import
        BuffType boekie_expGain_buff
        //@import
        BuffType boekie_lightSpeed_buff
    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 Spell Target

function onSpellTarget takes Tower tower returns nothing
    local Unit caster = Event.getTarget()
    local Buff b = tower.getBuffOfType(boekie_lightSpeed_buff)
    local integer twrLevel = tower.getLevel()
    local integer UID = tower.getUID()
    local integer bonusDmg = 40 + twrLevel //each point = 0.5% dmg bonus

    if caster.isATower() then
        call caster.addExp(2) 
        if b == 0 then
            set boekie_lightSpeed_buff.apply(tower, tower, bonusDmg).userInt = 1
        else
            if b.userInt >= 15 then
                return //already at max stacks. ABORT!
            endif
            set b.userInt = b.userInt + 1
            call b.setPower(b.getPower() + bonusDmg)
        endif
        call TriggerSleepAction(12 + 0.01 * twrLevel)
        if tower.getUID() == UID then //make sure tower still alive
            set b = tower.getBuffOfType(boekie_lightSpeed_buff)
            if b != 0 then //make sure buff hasn't been purged or something
                if b.userInt <= 1 then
                    call b.removeBuff()
                else
                    set b.userInt = b.userInt - 1
                    call b.setPower(b.getPower() - bonusDmg)
                endif
            endif
        endif
    endif
endfunction