Wand of Mana Zap v1
700
lvl: 27
ID:
166
Author:
drol
Rarity:
rare
Status:
Approved

Description:

'Then there was like this massive purple zap, and all my mana was gone!' - a creep
Mana Zap
The carrier's attacks zap away 8 mana from their target. Amount zapped is adjusted by attack speed and range.

Level Bonus:
+0.6 mana
Download

Toggle Triggers

On Damage

ONDAMAGE_chance: 1.0 goldcost: 700 ONDAMAGE_chanceLevelAdd: 0.0
function onDamage takes Item itm returns nothing
    local Tower tower = itm.getCarrier()
    local Creep creep = Event.getTarget()

    local Lightning l
    if Event.isMainTarget() then
        if creep.subtractMana((8 + 0.6 * tower.getLevel() * tower.getBaseAttackspeed()) * (55 / Pow(tower.getRange(), 0.6)), true) > 0. then
            set l = Lightning.createFromUnitToUnit("MFPB",tower,creep)
            call l.setColor(100,0,255,255)
            call l.setLifetime(0.1)
            call SFXOnUnit("Abilities\\Spells\\Human\\Feedback\\ArcaneTowerAttack.mdl", creep.getUnit(), "origin")
        endif
    endif
endfunction
Monocle v1
704
lvl: 39
ID:
243
Author:
Guennter
Rarity:
uncommon
Status:
Approved

Description:

Slow down and concentrate on searching items.
Specials:
-7.5% attackspeed (-0.7%/lvl)
+25% item chance
+25% item quality
Download
Ball Lightning v2
718
lvl: 27
ID:
255
Author:
axllow
Rarity:
rare
Status:
Approved

Description:

It's a hot potato.
Specials:
+150% attackspeed
Ball Lightning
Every 3 seconds this item jumps to another tower. If no other tower in  1500 range has an empty slot, this item will fly to stash.
Download

Toggle Triggers

Header

goldcost: 0
                globals
        ProjectileType BallLightning
    endglobals
    
    private function BallLightningJump takes Projectile Ball returns nothing
        local Tower tower = Ball.getCaster()
        local Iterate towersInRange
        local Item itm = Ball.userInt
        local Tower targetTower = Ball.userInt2
        local Tower towerInRange
        
        if not itm.pickup(targetTower) then
            set towersInRange = Iterate.overUnitsInRangeOfCaster(tower, TARGET_TYPE_PLAYER_TOWERS, 1500.00)
            loop
                set towerInRange = towersInRange.nextRandom()
                exitwhen towerInRange == 0
                if towerInRange != tower and towerInRange != targetTower and towerInRange.countFreeSlots() > 0 then
                    exitwhen true
                endif
            endloop
            
            if towerInRange != 0 then
                set Ball = Projectile.createBezierInterpolationFromUnitToUnit(BallLightning, tower, 0, 0, targetTower, towerInRange, 1.2, 0.0, 0.5, false)
                set Ball.userInt = itm
                set Ball.userInt2 = towerInRange
                call towersInRange.destroy()
            else
                call SetItemVisible(itm.getItem(), true)
                call itm.flyToStash(0.0)
            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 BallLightning = ProjectileType.createInterpolate("Abilities\\Weapons\\FarseerMissile\\FarseerMissile.mdl", 300)
        call BallLightning.setEventOnCleanup(BallLightningJump)

    endfunction
        

Periodic

PERIODIC_period: 3.0 goldcost: -20800
function periodic takes Item itm returns nothing
            
    local Tower tower = itm.getCarrier()
    local Projectile Ball
    local Iterate towersInRange = Iterate.overUnitsInRangeOfCaster(tower, TARGET_TYPE_PLAYER_TOWERS, 1500.00)
    local Tower towerInRange

    call itm.drop()

    loop
        set towerInRange = towersInRange.nextRandom()
        if towerInRange != tower and towerInRange.countFreeSlots() > 0 then
            call SetItemVisible(itm.getItem(), false)
            set Ball = Projectile.createBezierInterpolationFromUnitToUnit(BallLightning, tower, 0, 0, tower, towerInRange, 1.2, 0.0, 0.5, false)
            set Ball.userInt = itm
            set Ball.userInt2 = towerInRange
            exitwhen true
        endif
        exitwhen towerInRange == 0
    endloop

    if towerInRange != 0 then
        call towersInRange.destroy()
    else
        call itm.flyToStash(0.0)
    endif

        
endfunction
Pirate Map v1
729
lvl: 54
ID:
38
Author:
Boekie
Rarity:
common
Status:
Approved

Description:

This map has an x on it, maybe a treasure is located there?
Specials:
+30% bounty collected
+10% item chance
Download
Ogre Battle Axe v1
749
lvl: 42
ID:
263
Author:
Boekie
Rarity:
uncommon
Status:
Approved

Description:

Makes the tower a real threat to humankind.
Specials:
Specials:
+25% dmg to humanoids (+1%/lvl)
+5% crit chance
Download
Mindleecher v1
750
lvl: 29
ID:
206
Author:
Majildian
Rarity:
rare
Status:
Approved

Description:

A powerful item normally used to transfer knowledge from old wizards to young ones, this one has been corrupted so that it works on anything.
Siphon Knowledge
Removes a flat 15 to 60 exp from a random tower in range and gives it to the caster.

AC_TYPE_ALWAYS_IMMEDIATE
30s cooldown
Download

Toggle Triggers

Autocast

caster_art: AUTOCAST_cooldown: 30 AUTOCAST_numBuffsBeforeIdle: 0 goldcost: 750 AUTOCAST_isExtended: false AUTOCAST_autocastType: AC_TYPE_ALWAYS_IMMEDIATE AUTOCAST_manacost: 0 AUTOCAST_range: 450 AUTOCAST_buffType: 0 AUTOCAST_targetSelf: false AUTOCAST_targetType: 0 target_art: AUTOCAST_autoRange: 0
    local Tower tower = itm.getCarrier()
    local Iterate it = Iterate.overUnitsInRangeOfCaster(tower,TARGET_TOWERS,450)
    local Unit next

    loop
        set next = it.nextRandom()
        exitwhen next == 0
        exitwhen next != tower and next.getExp() > 0
    endloop

    if next != 0 then
        call it.destroy()        
        call tower.addExpFlat(next.removeExpFlat(I2R(GetRandomInt(15,60))))
        call SFXOnUnit("Abilities\\Spells\\Undead\\AnimateDead\\AnimateDeadTarget.mdl", next.getUnit(), "head")
        call SFXOnUnit("Abilities\\Spells\\Undead\\DeathCoil\\DeathCoilSpecialArt.mdl", tower.getUnit(), "head")
    endif
Chrono Jumper v1
770
lvl: 20
ID:
140
Author:
axllow
Rarity:
unique
Status:
Approved

Description:

Space-teleport device. Use it carefully.
Chrono Jump
Tower makes a leap through space to a target free location for 10 seconds, then returns to its original position. Increases attackspeed by 10% for the duration.

AC_TYPE_NOAC_POINT
30s cooldown
Download

Toggle Triggers

Autocast

caster_art: AUTOCAST_cooldown: 30 AUTOCAST_numBuffsBeforeIdle: 0 goldcost: 770 AUTOCAST_isExtended: true AUTOCAST_autocastType: AC_TYPE_NOAC_POINT AUTOCAST_manacost: 0 AUTOCAST_range: 1500 AUTOCAST_buffType: 0 AUTOCAST_targetSelf: false AUTOCAST_targetType: 0 target_art: AUTOCAST_autoRange: 1500
    local Tower tower = itm.getCarrier()
    local unit twrUnit = tower.getUnit()
    local integer unitID = GetUnitTypeId(twrUnit)
    local unit FX = tower.effects
    local Playor pl = tower.getOwner()
    local real fromX = GetUnitX(tower.getUnit())
    local real fromY = GetUnitY(tower.getUnit())
    local real toX = fromX + R2I(GetSpellTargetX() - tower.getX() + 32)/64*64
    local real toY = fromY + R2I(GetSpellTargetY() - tower.getY() + 32)/64*64
    local unit ill
    local unit array dummy
    local integer numEffects = 0
    local Buff b = tower.getBuffOfType(Chrono_Jumper_buff)
    local TowerType tt = tower.getUnitType()
    local ListElement l
    local real turnfix = 16.0
    local Effect ef
    local Tele tele        
    local boolean fail = true
    local real sx
    local real sy
    local integer sn = 1
    local real sd
    
    if isTowerAUnit(twrUnit) then
        if toX < fromX then
            set toX = toX - 64.0
        endif
        if toY < fromY then
            set toY = toY - 64.0
        endif
    else
        set turnfix = 0.0
        if fromX > toX then
            set toX = toX - 64.0
        endif
        if fromY > toY then
            set toY = toY - 64.0
        endif
    endif
    
    if isPointBuildableForPlayer(pl, toX-turnfix, toY-turnfix) then
        set fail = false
    else    //If target point is not buildable, check nearby (radially, up to ~288 range away)
        loop
            set sd = 0
            loop
                exitwhen not fail or sd >= 360
                set sx = R2I(toX-turnfix + sn*32 * Sin(sd))/64*64 
                set sy = R2I(toY-turnfix + sn*32 * Cos(sd))/64*64 
                if isPointBuildableForPlayer(pl, sx, sy) then
                    set toX = sx
                    set toY = sy
                    set fail = false
                endif
                set sd = sd + 45/sn     //32 distance: 8 positions checked, 64 distance: 16 positions checked, 96 distance: 24 positions checked, etc.
                                        //note that isPointBuildableForPlayer actually checks for 5 positions, 1 in middle and 4 in the cardinal directions
            endloop
            exitwhen not fail or sn == 8   // 8x32 search radius
            set sn = sn + 1
        endloop
    endif
            
    if fail then
        call tower.getOwner().displaySmallFloatingText("FAIL!", tower, 255, 150, 0, 30)
    else
        //Teleport
        call SFXAtUnit("Abilities\\Spells\\Human\\MassTeleport\\MassTeleportCaster.mdl",twrUnit)
        call SetUnitPosition(twrUnit,toX,toY)
        call tower.setPos(toX,toY) 
        call SFXAtUnit("Abilities\\Spells\\Human\\MassTeleport\\MassTeleportTarget.mdl",twrUnit)
        loop
            exitwhen FX == null
            call SetUnitX(FX, toX + GetUnitX(FX) - fromX)
            call SetUnitY(FX, toY + GetUnitY(FX) - fromY)
            set FX = LoadUnitHandle(tower.effectTable,tower,GetHandleId(FX))
        endloop
        //Leave illusion behind
        if b == 0 then
            set ill = CreateUnit(pl.getThePlayer(),unitID,fromX,fromY,0)
            call ShowUnit(ill, false)
            call SetUnitX(ill,fromX)
            call SetUnitY(ill,fromY)
            set ef = Effect.createAnimated(unitID,fromX,fromY,GetUnitFlyHeight(twrUnit),GetUnitFacing(twrUnit))
            call ef.setColor(150,150,255,100)
            call ef.noDeathAnimation()
            set tele = Tele.create(fromX, fromY, toX, toY, turnfix, ef, ill)
            if tt.effects != 0 then
                set l = tt.effects.getFirst()
                loop
                    exitwhen l == 0
                    set FX = TowerFXType(l.getContent()).createFX(ill)
                    call SetUnitVertexColor(FX,150,150,255,100)
                    call SetUnitX(FX,GetUnitX(FX) - turnfix)
                    call SetUnitY(FX,GetUnitY(FX) - turnfix)
                    set tele.dummy[tele.numEffects] = FX
                    set tele.numEffects = tele.numEffects + 1
                    set l = l.next
                endloop
            endif
            call block(false,fromX,fromY,turnfix)
            set Chrono_Jumper_buff.apply(tower,tower,0).userInt = tele
        else
            call Chrono_Jumper_buff.apply(tower,tower,0)
        endif
    endif
    set twrUnit = null
    set FX = null
    set ill = null

Header

goldcost: 0
    globals
        BuffType Chrono_Jumper_buff 
    endglobals    
    
    struct Tele
        real fromX
        real fromY
        real toX
        real toY
        real turnfix
        Effect ef
        integer numEffects = 0
        unit array dummy[100]
        unit ill
    
        static method create takes real fromX, real fromY, real toX, real toY, real turnfix, Effect ef, unit ill returns Tele
            local Tele t = Tele.allocate()
            set t.fromX = fromX
            set t.fromY = fromY
            set t.toX = toX
            set t.toY = toY
            set t.turnfix = turnfix
            set t.ef = ef
            set t.ill = ill
            return t
        endmethod
        
        private method onDestroy takes nothing returns nothing
            call .ef.destroy()
            call RemoveUnit(.ill)
            set .ill = null
            loop
                set .numEffects = .numEffects - 1
                exitwhen .numEffects < 0
                call RemoveUnit(.dummy[.numEffects])
                set .dummy[.numEffects] = null
            endloop
        endmethod
    endstruct
    
    function block takes boolean bl, real fromX, real fromY, real turnfix returns nothing
        local integer i = 0
        local integer j = 0
        loop
            loop
                call SetTerrainPathable(fromX - 48 - turnfix + j,fromY + 48 - turnfix - i,PATHING_TYPE_BUILDABILITY,bl)
                set j = j + 16
                exitwhen j > 96 - turnfix
            endloop
            set j = 0
            set i = i + 16
            exitwhen i > 96
        endloop
    endfunction
    
    function chrono_jumper_onCleanup takes Buff b returns nothing
        local Tele tele = b.userInt
        local Tower tower = b.getBuffedUnit()
        local unit twrUnit = tower.getUnit()
        local unit FX = tower.effects
        call block(true,tele.fromX,tele.fromY,tele.turnfix)
        call SFXAtUnit("Abilities\\Spells\\Human\\MassTeleport\\MassTeleportCaster.mdl",twrUnit)
        loop
            exitwhen FX == null
            call SetUnitX(FX, tele.fromX + GetUnitX(FX) - tele.toX)
            call SetUnitY(FX, tele.fromY + GetUnitY(FX) - tele.toY)
            set FX = LoadUnitHandle(tower.effectTable,tower,GetHandleId(FX))
        endloop
        call SetUnitPosition(twrUnit,tele.fromX,tele.fromY)
        call tower.setPos(tele.fromX,tele.fromY)
        call SFXAtUnit("Abilities\\Spells\\Human\\MassTeleport\\MassTeleportTarget.mdl",twrUnit)
        call tele.destroy()
        set twrUnit = null
    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_ATTACKSPEED,0.1,0.0) 
        set Chrono_Jumper_buff = BuffType.create(10,0,true)
        call Chrono_Jumper_buff.setBuffModifier(m)
        call Chrono_Jumper_buff.setBuffIcon('@@0@@')
        call Chrono_Jumper_buff.addEventOnCleanup(chrono_jumper_onCleanup)
    endfunction