Thief v1
585
ID:
110
Family ID:
Author:
i_mOck_death
Rarity:
uncommon
Element:
darkness
Attack Type:
Physical
Attack Range:
800
Attack CD:
1.5
Damage:
904-904
Status:
Approved

Description:

Trained in the shadows, the thief is an expert in finding gold.
Specials:
-10% dmg to undead (+0.4%/lvl)
+1% bounty collected/lvl
+7% item chance (+0.28%/lvl)
+7% item quality (+0.28%/lvl)
Steal
Every time the thief damages a creep there is a 10% chance he steals 2.7 gold.

Level Bonus:
+0.108 gold
+0.4% chance
Download

Toggle Triggers

Header

    globals
        //@import
        ProjectileType mOck_steal
        //@import
        MultiboardValues mOck_thief_multiboard
    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 ONDAMAGE_chanceLevelAdd: 0.004
function onDamage takes Tower tower returns nothing
    call Projectile.createLinearInterpolationFromUnitToUnit(mOck_steal,tower,0,0,Event.getTarget(),tower,0,true)
endfunction

On Tower Creation

function onCreate takes Tower tower returns nothing
    local Tower super = Event.getPrecedingTower()
    call AddUnitAnimationProperties(tower.getUnit(), "stand alternate", false)
    if super.getFamily() == tower.getFamily() then
        set tower.userReal = super.userReal
    else
        set tower.userReal = 0.0 
    endif
    set tower.userInt = 27
endfunction

On Tower Details

function onTowerDetails takes Tower tower returns MultiboardValues
    call mOck_thief_multiboard.setValue(0,I2S(R2I(tower.userReal)))
    return mOck_thief_multiboard
endfunction
Necromantic Statue v1
600
ID:
6
Family ID:
Author:
Boekie
Rarity:
uncommon
Element:
darkness
Attack Type:
Decay
Attack Range:
875
Attack CD:
1.6
Damage:
573-573
Mana:
30
Mana regen:
2
Status:
Approved

Description:

This statue is haunted by lost souls.
Soul Revenge
Hits 3 random creeps in 875 range, the first one suffers 400 spelldamage, the second one suffers 800 spelldamage and the third one suffers 1200 spelldamage.

Level Bonus:
+24/48/72 spelldamage

AC_TYPE_OFFENSIVE_IMMEDIATE
 20, 875 range, 1s cooldown
Download

Toggle Triggers

Autocast

caster_art: AUTOCAST_cooldown: 1 AUTOCAST_numBuffsBeforeIdle: 0 AUTOCAST_isExtended: false AUTOCAST_autocastType: AC_TYPE_OFFENSIVE_IMMEDIATE AUTOCAST_manacost: 20 AUTOCAST_range: 875 AUTOCAST_buffType: 0 AUTOCAST_targetSelf: false AUTOCAST_targetType: 0 target_art: Abilities\Spells\Undead\Curse\CurseTarget.mdl AUTOCAST_autoRange: 875
private function onAutocast takes Tower tower returns nothing
    local integer  lvl = tower.getLevel()
    local Iterate inRange = Iterate.overUnitsInRangeOfCaster(tower,TARGET_TYPE_CREEPS,875) //Can set this at the start.
    local Unit next //Used as next during the iterate and the unit to affect during the other loop.
    local integer indexCounter = 0
    local integer loopCounter = 3
    local integer counter = 1

    loop
        set next=inRange.next()
        exitwhen next==0
        set resultArray[indexCounter] = next
        set indexCounter = indexCounter+1
    endloop
   
    if(indexCounter > 0) then //Commented lines here are for setting the period to a low time when no creeps are around,
                              //remove them if you don't want this to happen. Also if these lines are used, the On Level
                              //Up code isn't needed.
        loop
            set loopCounter = loopCounter - 1
            set next = resultArray[GetRandomInt(0,indexCounter-1)]
            call tower.doSpellDamage(next,(400+lvl*24)*counter,tower.calcSpellCritNoBonus())
            call SFXAtUnit("Abilities\\Spells\\Items\\AIre\\AIreTarget.mdl",next.getUnit())
            set counter = counter + 1
            exitwhen loopCounter == 0
        endloop
    
    endif
    
endfunction

Header

    globals
    Unit array resultArray //Instead of numResults, use a resultArray so you only have to iterate once.
    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
Small Bug Nest v1
600
ID:
24
Family ID:
Author:
Majildian
Rarity:
uncommon
Element:
darkness
Attack Type:
Physical
Attack Range:
725
Attack CD:
1.5
Damage:
724-823
Status:
Approved

Description:

A small colony of bugs.
Swarm of Bugs
On kill, produces bugs that increase the base damage of this tower by 6. The damage gain decreases by 1 for every 12 productions, down to a minimum of 1.

Number of produced bugs is retained through upgrade and applied with the upgrade's values. Replacing a tower from a different family will produce bugs from 60% of its total kills.
Download

Toggle Triggers

On Kill

function onKill takes Tower tower returns nothing
    call tower.modifyProperty(MOD_DAMAGE_BASE,IMaxBJ(6 - tower.userInt/12,1))
    set tower.userInt = tower.userInt+1
endfunction

On Tower Creation

function onCreate takes Tower tower returns nothing
    local Tower prev = Event.getPrecedingTower()
    local integer N
    local integer mults
    if prev != 0 then
        if prev.getFamily() == tower.getFamily() then
            set tower.userInt  = prev.userInt
        else
            set tower.userInt  = R2I(prev.getKills()*0.6)
        endif
    
        //sadly, using inlined constants gives us things like 6-1 and 6+0.5 instead of 5 and 6.5
        set mults = tower.userInt /12 //full growth multiples in all kills
        if mults >= 6 then //mults until minimum of 1
            set mults = 6-1
        endif
        
        //Since the equation is linear:
        //[Average growth over N] * N + remaining growth * (total kills - N)
        set N = mults*12
        set N = R2I((6 + 0.5-mults/2.0)*N) + (tower.userInt-N)*(6-mults)
        call tower.modifyProperty(MOD_DAMAGE_BASE,N)
    else
        //if no predecessor, initialize with zeros
        set tower.userInt = 0 //counted kills
    endif
endfunction
Lunar Guardian v1
600
ID:
49
Family ID:
Author:
SirCoqaLot.
Rarity:
uncommon
Element:
astral
Attack Type:
Energy
Attack Range:
1200
Attack CD:
2
Damage:
262-282
Status:
Approved

Description:

The spirit of a watcher left to look over the ruins.
Lunar Grace
Smites a target creep dealing 500 spelldamage to it. There is a 12.5% chance to empower the smite with lunar energy dealing 500 additional spell damage, stunning the target for 0.3 seconds and making it receive 16% more damage from spells for 2.5 seconds.

Level Bonus:
+20 inital and chanced spelldamage 
+0.5% chance 
+200 initial damage at level 15 
+4% spelldamage received at level 15 
+0.1 seconds stun at level 25

AC_TYPE_OFFENSIVE_UNIT
 0, 1200 range, 2s cooldown
Download

Toggle Triggers

Autocast

caster_art: AUTOCAST_cooldown: 2 AUTOCAST_numBuffsBeforeIdle: 0 AUTOCAST_isExtended: true AUTOCAST_autocastType: AC_TYPE_OFFENSIVE_UNIT AUTOCAST_manacost: 0 AUTOCAST_range: 1200 AUTOCAST_buffType: 0 AUTOCAST_targetSelf: false AUTOCAST_targetType: 0 target_art: Abilities\Spells\Items\AIil\AIilTarget.mdl AUTOCAST_autoRange: 1200
private function onAutocast takes Tower tower returns nothing
local integer level = tower.getLevel()
local Unit target = Event.getTarget()
    if level < 15 then
        call tower.doSpellDamage(target,500+level*20,tower.calcSpellCritNoBonus())
    else
        call tower.doSpellDamage(target,700+level*20,tower.calcSpellCritNoBonus())
    endif
    
    if tower.calcChance(0.125 + level * 0.005) == true then
        call tower.doSpellDamage(target,500 + level * 20,tower.calcSpellCritNoBonus())
            if level < 25 then
                call cb_stun.applyOnlyTimed(tower,target,0.3)
            else
                call cb_stun.applyOnlyTimed(tower,target,0.4)
            endif
            if level < 15 then
                call sir_moonp_buff.applyAdvanced(tower,target,0,160,2.5)
            else
                call sir_moonp_buff.applyAdvanced(tower,target,0,200,2.5)
            endif
        endif
    
endfunction

Header

    globals
    //@import
    BuffType sir_moonp_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
Bone Shrine v1
600
ID:
91
Family ID:
Author:
SirCoqaLot.
Rarity:
uncommon
Element:
darkness
Attack Type:
Physical
Attack Range:
950
Attack CD:
2
Damage:
1155-1165
Status:
Approved

Description:

Lesser darkness tower that increases the damage of its target taken by darkness towers.
Empowering Darkness
On attack this tower increases the damage the target receives from other darkness towers by 2%. This effect stacks up to 10 times.

Level Bonus:
 +0.04% damage increased
Download

Toggle Triggers

Header

    globals
    //@export
    BuffType sir_bone_debuff
    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 sir_bone_debuff = BuffType.create(0,0,false)
    call sir_bone_debuff.setBuffIcon('@@0@@')
    endfunction

On Attack

ONATTACK_chance: 1.0 ONATTACK_chanceLevelAdd: 0.0
function onAttack takes Tower tower returns nothing
local integer bufflevel = Event.getTarget().getBuffOfType(sir_bone_debuff).getLevel()
    if bufflevel < 10 then
        call Event.getTarget().modifyProperty(MOD_DMG_FROM_DARKNESS,0.02+tower.getLevel()*(0.0004))
        call sir_bone_debuff.applyAdvanced(tower,Event.getTarget(),bufflevel+1,0,1000)
    endif
endfunction
Crystalized Tendrils v1
600
ID:
153
Family ID:
Author:
drol
Rarity:
common
Element:
ice
Attack Type:
Energy
Attack Range:
750
Attack CD:
0.75
Damage:
291-390
Status:
Approved

Description:

Can still grow even in the coldest places.
Frozen Thorn
Has a 15% chance to deal 750 additional spell damage each time it deals damage.

Level Bonus:
+30 spell damage
Download

Toggle Triggers

On Damage

ONDAMAGE_chance: 1.0 ONDAMAGE_chanceLevelAdd: 0.0
function onDamage takes Tower tower returns nothing
    if Event.isMainTarget() and tower.calcChance(0.15) and not Event.getTarget().isImmune() then
        call SFXAtUnit("Abilities\\Spells\\Undead\\FrostArmor\\FrostArmorDamage.mdl", Event.getTarget().getUnit())
        call tower.doSpellDamage(Event.getTarget(), 750 + 30 * tower.getLevel(), tower.calcSpellCritNoBonus())
    endif
endfunction
Undisturbed Crypt v1
600
ID:
165
Family ID:
Author:
eMoo
Rarity:
rare
Element:
darkness
Attack Type:
Decay
Attack Range:
1000
Attack CD:
1.95
Damage:
696-696
Status:
Approved

Description:

A combination of decaying body parts and the presence of an unfathomable evil create a pillar of darkness within this crypt to form a reliable attack and the ability to explode corpses.
Corpse Explosion
Explodes a corpse within 1000 range of the tower, causing enemies in 500 range of the corpse to take 5% more damage from darkness towers and move 5% slower for 8 seconds. 5 second cooldown. Doesn't affect Air.

Level Bonus:
+0.2% slow and damage taken
+0.25 seconds duration
Critical Mass
Has a 30% chance on attack to shoot an extra projectile. For each projectile after the initial one, there is a 30% chance to shoot an extra projectile. There is a maximum of 14 projectiles fired per attack.

Level Bonus:
 +0.3% initial chance
 +0.6% extra chance
Download

Toggle Triggers

Header

    globals
    //@export
    ProjectileType Top_Crypt_ball
    ProjectileType meat
    //@export
    EventTypeList Top_Corpse_explode
    Unit array targList
    BuffType Top_Corpse_buff
    endglobals

    
    function fire takes Unit tower returns nothing
        local unit tu = tower.getUnit()
        local unit u
        local real tx = GetUnitX(tu)
        local real ty = GetUnitY(tu)
        local real r1
        local real r2
        local integer num = 0
        local Unit U
        local Iterate it = Iterate.overCorpsesInRange(tower,tx,ty,1000)
        local Iterate it2
        local Projectile proj

            
        // loops through all the nearby corpses
        loop
            if num == 0 then
                set u = it.nextCorpse()
            else
                call it.destroy()
            endif
            
            exitwhen u == null or num > 0
            
            if IsUnitType(u,UNIT_TYPE_FLYING) == false then 
                    
                set num = 0
                    
                set it2 = Iterate.overUnitsInRange(tower,TARGET_CREEPS,GetUnitX(u),GetUnitY(u),500)
                loop
                    set U = it2.next()
                    exitwhen U == 0
                    set targList[num] = U
                    set num = num + 1
                endloop
            endif
        endloop
            
        // if corpse is an actual unit then it sets off the ability
        if u != null then
            call ShowUnit(u,false)
            set U = 4
            set tx = GetUnitX(u)
            set ty = GetUnitY(u)
            call DestroyEffect(AddSpecialEffect("Objects\\Spawnmodels\\Orc\\OrcLargeDeathExplode\\OrcLargeDeathExplode.mdl",tx,ty))
            
            call Effect.createScaled("Abilities\\Weapons\\MeatwagonMissile\\T_MeatwagonMissile.mdl",tx,ty,0,GetRandomReal(0,360),1.2).destroy()
            
            loop
                exitwhen 0 <= U
                set r1 = GetRandomReal(0.017,6.283)
                set r2 = GetRandomInt(200,500)
                set proj = Projectile.createLinearInterpolationFromPointToPoint(meat,tower,0,0,tx,ty,0,tx+r2*Cos(r1),ty+r2*Sin(r1),0,GetRandomReal(0.1,0.6))
                call proj.setScale(0.5)
                set U = U - 1
            endloop
            
            set U = 0
            loop
                exitwhen U >= num
                call Top_Corpse_buff.apply(tower, targList[U], tower.userInt)
                set U = U + 1
            endloop
        endif
        set tu = null
        set u = null
    endfunction
    
    function incDmg takes Unit tower returns nothing
        set tower.userInt = tower.userInt2+tower.userInt3*tower.getLevel()
    endfunction
    
    //@export
    function burstFire takes Tower tower, real chance, Creep target, real z returns nothing
        local integer numShots = 0
        local real x = tower.getX()
        local real y = tower.getY()
        local integer UID = target.getUID()
        local Projectile p
        loop
            set p = Projectile.createFromPointToUnit(Top_Crypt_ball,tower,1,1,x+GetRandomReal(-2*numShots,2*numShots),y+GetRandomReal(-2*numShots,2*numShots),z,target,true,false,false)
            call p.setScale(0.4)
            set p.speed = 500 + RMinBJ(numShots * 80,500)+numShots*20
            set p.accelerate = RMaxBJ(20 - numShots * 2,0)
            set numShots = numShots + 1
            exitwhen tower.calcChance(chance) == false or numShots >= 14 or target.getUID() != UID
        endloop
    endfunction
    
    function hit takes Projectile p, Unit creep returns nothing
        local Tower tower = p.getCaster()
        call tower.doAttackDamage(creep,tower.getCurrentAttackDamageWithBonus(),tower.calcAttackMulticrit(0, 0, 0))
    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()
        
        set Top_Crypt_ball = ProjectileType.create("Abilities\\Spells\\Undead\\OrbOfDeath\\AnnihilationMissile.mdl",5,500)
        call Top_Crypt_ball.enableHoming(ProjectileTargetEvent.hit,0)
        
        set meat = ProjectileType.createInterpolate("Abilities\\Weapons\\MeatwagonMissile\\T_MeatwagonMissile.mdl",400)
        
        set Top_Corpse_explode = EventTypeList.create()
        call Top_Corpse_explode.addPeriodicEvent(fire,5)
        call Top_Corpse_explode.addEventOnLevelUp(incDmg)
        
        set Top_Corpse_buff = BuffType.create(8, 0.25, false)
        call Top_Corpse_buff.setBuffIcon('@@0@@')
        call m.addModification(MOD_MOVESPEED, 0, -0.001)
        call m.addModification(MOD_DMG_FROM_DARKNESS, 0, 0.001)
        call Top_Corpse_buff.setBuffModifier(m)
    endfunction

On Attack

ONATTACK_chance: 0.3 ONATTACK_chanceLevelAdd: 0.003
function onAttack takes Tower tower returns nothing
    call burstFire(tower, 0.3+tower.getLevel()*0.006,Event.getTarget(),100)
endfunction

On Tower Creation

function onCreate takes Tower tower returns nothing
call tower.addEventList(Top_Corpse_explode)
set tower.userInt = 50 //This will be the base+level damage.
set tower.userInt2 = 50 //Base damage.
set tower.userInt3 = 2 //Level up damage.
endfunction