Healing Altar v1
1900
ID:
628
Family ID:
Author:
SirCoqaLot.
Rarity:
uncommon
Element:
astral
Attack Type:
Elemental
Attack Range:
1000
Attack CD:
1.5
Damage:
5554-5616
Status:
Approved

Description:

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

Level Bonus:
 -0.68% 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.6-tower.getLevel()*0.0068))

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
Large Bug Nest v1
1950
ID:
26
Family ID:
Author:
Majildian
Rarity:
uncommon
Element:
darkness
Attack Type:
Physical
Attack Range:
725
Attack CD:
1.5
Damage:
2464-2563
Status:
Approved

Description:

A large colony of bugs.
Swarm of Bugs
On kill, produces bugs that increase the base damage of this tower by 20. The damage gain decreases by 1 for every 8 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(20 - tower.userInt/8,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 /8 //full growth multiples in all kills
        if mults >= 20 then //mults until minimum of 1
            set mults = 20-1
        endif
        
        //Since the equation is linear:
        //[Average growth over N] * N + remaining growth * (total kills - N)
        set N = mults*8
        set N = R2I((20 + 0.5-mults/2.0)*N) + (tower.userInt-N)*(20-mults)
        call tower.modifyProperty(MOD_DAMAGE_BASE,N)
    else
        //if no predecessor, initialize with zeros
        set tower.userInt = 0 //counted kills
    endif
endfunction
Xeno Research Facility v1
1984
ID:
158
Family ID:
Author:
Palandu
Rarity:
unique
Element:
iron
Attack Type:
Physical
Attack Range:
1200
Attack CD:
1.8
Damage:
1812-1812
Status:
Approved

Description:

Empowers you against the alien menace. Model credits: SirCoqaLot plus mOck and MasterCassim.
Sample Collection
Has a 25% chance to collect a tissue sample from a damaged creep. Once researched, it will provide a 5% bonus vs the race of that creep, through the Xeno Vulnerability Research aura. Maximum bonus per race is 25%. Whenever a different race is attacked, half of the research bonuses against all other races are lost.

Level Bonus:
+1% chance to collect sample
+1% maximum bonus per race
Xeno Vulnerability Research - Aura
Improves damage vs various creep races for all towers in 280 range. Improvement amount depends on the Sample Collection. Research results are published every 6 seconds and whenever a different race is attacked. Stops working in the Bonus Level.

Note: For this tower, research overrides any and all other race modifications. So the race bonuses of this tower reflect the bonuses given by this aura.
Download

Toggle Triggers

Header

    globals
        BuffType xeno_dummyAura
        BuffType xeno_undead
        BuffType xeno_magic
        BuffType xeno_nature
        BuffType xeno_orc
        BuffType xeno_humanoid
        
        hashtable xeno_raceBonusTable = InitHashtable()
    endglobals
    
    //halving and setting of all modifiers on base tower
    function xeno_ManageBonuses takes Tower tower, boolean isTypeChange, integer uid, integer currentCategory, integer currentBonus returns nothing
        local real currentRaceBonus
        local real idealBonus
        if isTypeChange then
            call SaveInteger(xeno_raceBonusTable, uid, CATEGORY_UNDEAD, LoadInteger(xeno_raceBonusTable, uid, CATEGORY_UNDEAD)/2)
            call SaveInteger(xeno_raceBonusTable, uid, CATEGORY_MAGIC, LoadInteger(xeno_raceBonusTable, uid, CATEGORY_MAGIC)/2)
            call SaveInteger(xeno_raceBonusTable, uid, CATEGORY_NATURE, LoadInteger(xeno_raceBonusTable, uid, CATEGORY_NATURE)/2)
            call SaveInteger(xeno_raceBonusTable, uid, CATEGORY_ORC, LoadInteger(xeno_raceBonusTable, uid, CATEGORY_ORC)/2)
            call SaveInteger(xeno_raceBonusTable, uid, CATEGORY_HUMANOID, LoadInteger(xeno_raceBonusTable, uid, CATEGORY_HUMANOID)/2)
            //now restore the correct one :P
            call SaveInteger(xeno_raceBonusTable, uid, currentCategory, currentBonus)
        endif
        
        //now set the correct race bonuses for this tower
        set idealBonus = 1.0 + (I2R(LoadInteger(xeno_raceBonusTable, uid, CATEGORY_UNDEAD))/1000)
        set currentRaceBonus = tower.getDamageToCategory(CATEGORY_UNDEAD)
        if idealBonus != currentRaceBonus then
            call tower.modifyProperty(MOD_DMG_TO_UNDEAD, idealBonus - currentRaceBonus) //add the delta
        endif
        
        set idealBonus = 1.0 + (I2R(LoadInteger(xeno_raceBonusTable, uid, CATEGORY_MAGIC))/1000)
        set currentRaceBonus = tower.getDamageToCategory(CATEGORY_MAGIC)
        if idealBonus != currentRaceBonus then
            call tower.modifyProperty(MOD_DMG_TO_MAGIC, idealBonus - currentRaceBonus) //add the delta
        endif
        
        set idealBonus = 1.0 + (I2R(LoadInteger(xeno_raceBonusTable, uid, CATEGORY_NATURE))/1000)
        set currentRaceBonus = tower.getDamageToCategory(CATEGORY_NATURE)
        if idealBonus != currentRaceBonus then
            call tower.modifyProperty(MOD_DMG_TO_NATURE, idealBonus - currentRaceBonus) //add the delta
        endif
        
        set idealBonus = 1.0 + (I2R(LoadInteger(xeno_raceBonusTable, uid, CATEGORY_ORC))/1000)
        set currentRaceBonus = tower.getDamageToCategory(CATEGORY_ORC)
        if idealBonus != currentRaceBonus then
            call tower.modifyProperty(MOD_DMG_TO_ORC, idealBonus - currentRaceBonus) //add the delta
        endif
        
        set idealBonus = 1.0 + (I2R(LoadInteger(xeno_raceBonusTable, uid, CATEGORY_HUMANOID))/1000)
        set currentRaceBonus = tower.getDamageToCategory(CATEGORY_HUMANOID)
        if idealBonus != currentRaceBonus then
            call tower.modifyProperty(MOD_DMG_TO_HUMANOID, idealBonus - currentRaceBonus) //add the delta
        endif
    endfunction
    
    //this is where all the magic or rather research happens :P
    function xeno_BuffTowers takes Tower tower, boolean isTypeChange returns nothing
        local BuffType selectedBuff
        local integer powerLevel
        local integer uid = tower.getUID()
        local Iterate towersInAura
        local Unit nextTower
        
        set powerLevel = LoadInteger(xeno_raceBonusTable, uid, tower.userInt)
        set tower.userInt2 = tower.userInt  //save the race type of new buff
        
        if tower.userInt == CATEGORY_UNDEAD then
            set selectedBuff = xeno_undead
            if (isTypeChange and powerLevel > 0) or tower.userReal3 > 0 then
                call tower.getOwner().displaySmallFloatingText("Undead Research Published", tower, 50, 50, 50, 0)
            endif
        elseif tower.userInt == CATEGORY_MAGIC then
            set selectedBuff = xeno_magic
            if (isTypeChange and powerLevel > 0) or tower.userReal3 > 0 then
                call tower.getOwner().displaySmallFloatingText("Magic Research Published", tower, 0, 155, 0, 0)
            endif
        elseif tower.userInt == CATEGORY_NATURE then
            set selectedBuff = xeno_nature
            if (isTypeChange and powerLevel > 0) or tower.userReal3 > 0 then
                call tower.getOwner().displaySmallFloatingText("Nature Research Published", tower, 0, 155, 0, 0)
            endif
        elseif tower.userInt == CATEGORY_ORC then
            set selectedBuff = xeno_orc
            if (isTypeChange and powerLevel > 0) or tower.userReal3 > 0 then
                call tower.getOwner().displaySmallFloatingText("Orc Research Published", tower, 155, 0, 155, 0)
            endif
        elseif tower.userInt == CATEGORY_HUMANOID then
            set selectedBuff = xeno_humanoid
            if (isTypeChange and powerLevel > 0) or tower.userReal3 > 0 then
                call tower.getOwner().displaySmallFloatingText("Humanoid Research Published", tower, 0, 155, 155, 0)
            endif
        else
            //Probs a champ wave. Exit early.
            return
        endif
        
        set tower.userReal3 = -101           //reset the message display flag
        
        call xeno_ManageBonuses(tower, isTypeChange, uid, tower.userInt, powerLevel)
        
        //re-apply buffs / refresh aura
        if powerLevel > 0 then
            set towersInAura = Iterate.overUnitsInRangeOfCaster(tower, TARGET_TOWERS, 315.0) //larger AoE needed as aura centre seems to be diff + collision problems
            loop
                set nextTower = towersInAura.next()
                exitwhen nextTower == 0
                if nextTower.getBuffOfType(xeno_dummyAura) != 0 and nextTower.getUID() != uid then //do not buff self
                    call selectedBuff.applyAdvanced(tower, nextTower, powerLevel, powerLevel, (6.5 / tower.getProp_BuffDuration())) //always 8.5 secs
                endif
            endloop
        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
        local Modifier m
        
        set xeno_undead = BuffType.create(1, 0, true)
        set m = Modifier.create()
        call m.addModification(MOD_DMG_TO_UNDEAD, 0.0, 0.001)
        call xeno_undead.setBuffModifier(m)
        
        set xeno_magic = BuffType.create(1, 0, true)
        set m = Modifier.create()
        call m.addModification(MOD_DMG_TO_MAGIC, 0.0, 0.001)
        call xeno_magic.setBuffModifier(m)
        
        set xeno_nature = BuffType.create(1, 0, true)
        set m = Modifier.create()
        call m.addModification(MOD_DMG_TO_NATURE, 0.0, 0.001)
        call xeno_nature.setBuffModifier(m)
        
        set xeno_orc = BuffType.create(1, 0, true)
        set m = Modifier.create()
        call m.addModification(MOD_DMG_TO_ORC, 0.0, 0.001)
        call xeno_orc.setBuffModifier(m)
        
        set xeno_humanoid = BuffType.create(1, 0, true)
        set m = Modifier.create()
        call m.addModification(MOD_DMG_TO_HUMANOID, 0.0, 0.001)
        call xeno_humanoid.setBuffModifier(m)
        
        set xeno_dummyAura = BuffType.createAuraEffectType(true)
        call xeno_dummyAura.setBuffIcon('@@0@@')
    endfunction

On Attack

ONATTACK_chance: 1.0 ONATTACK_chanceLevelAdd: 0.0
function onAttack takes Tower tower returns nothing
    local Creep enemy

    if tower.userReal < 0 then
        return
    endif
    
    set enemy = Event.getTarget()
    
    if enemy.getSpawnLevel() > Game.getMaxLevel() then
        set tower.userReal = -101 //off switch
        set tower.userInt3 = 0
    endif

    set tower.userInt = enemy.getCategory()    //setting the last attacked type
    
    if tower.userInt != tower.userInt2 then    //last attacked is diff from the prev. last attacked, halve bonuses and change buffs
        call xeno_BuffTowers(tower, true)
    endif
endfunction

On Damage

ONDAMAGE_chance: 0.25 ONDAMAGE_chanceLevelAdd: 0.01
function onDamage takes Tower tower returns nothing
    local Creep enemy
    local integer i
    local integer index
    local integer uid
    
    if tower.userReal < 0 then
        return
    endif

    if not Event.isMainTarget() or Event.isSpellDamage() then
        return
    endif
    
    set uid = tower.getUID()
    set enemy = Event.getTarget()
    
    set index = enemy.getCategory()     //can technically use the onattack userInt....

    set i = LoadInteger(xeno_raceBonusTable, uid, index)
    
    if i < tower.userInt3 then
        call tower.getOwner().displaySmallFloatingText("Sample Collected", enemy, 200, 200, 200, 40.0)
        set i = IMinBJ(tower.userInt3, i + 50)
        call SaveInteger(xeno_raceBonusTable, uid, index, i)
        set tower.userReal3 = 101                        //flag to show the research message
    endif
endfunction

On Level Up

function onLevelUp takes Tower tower returns nothing
    set tower.userInt3 = 250 + tower.getLevel()*10   //bonus limit
endfunction

On Tower Creation

function onCreate takes Tower tower returns nothing
    local integer uid = tower.getUID()
    set tower.userInt = CATEGORY_OTHERS               //which creep type i attacked - that's the type i'll buff next
    set tower.userInt2 = CATEGORY_OTHERS              //memory of prev. attacked creep type
    set tower.userInt3 = 250                          //bonus limit
    set tower.userReal = 101                          //on-off switch. Tower should not work in bonus level. +ve = tower is on
    set tower.userReal3 = -101                        //flag to show the research message. +ve = message is on.
    call SaveInteger(xeno_raceBonusTable, uid, CATEGORY_UNDEAD, 0)  //undead
    call SaveInteger(xeno_raceBonusTable, uid, CATEGORY_MAGIC, 0)  //magic
    call SaveInteger(xeno_raceBonusTable, uid, CATEGORY_NATURE, 0)  //nature
    call SaveInteger(xeno_raceBonusTable, uid, CATEGORY_ORC, 0)  //orc
    call SaveInteger(xeno_raceBonusTable, uid, CATEGORY_HUMANOID, 0)  //humanoid
    call SaveInteger(xeno_raceBonusTable, uid, CATEGORY_OTHERS, 0) //just to prevent a hashkey error
endfunction

On Tower Destruction

function onDestruct takes Tower tower returns nothing
    call FlushChildHashtable(xeno_raceBonusTable, tower.getUID())
endfunction

Periodic

PERIODIC_period: 6
function periodic takes Tower tower returns nothing
    if tower.userReal > 0 then
        call xeno_BuffTowers(tower, tower.userInt != tower.userInt2)
    endif
endfunction

Tower Aura

AURA_auraEffect: xeno_dummyAura AURA_power: 1 AURA_level: 1 AURA_auraRange: 280.0 AURA_targetType: TARGET_TYPE_TOWERS AURA_levelAdd: 1 AURA_powerAdd: 1 AURA_targetSelf: true
Cloudy Temple of Absorption v1
2000
ID:
38
Family ID:
Author:
Natac
Rarity:
unique
Element:
storm
Attack Type:
Energy
Attack Range:
900
Attack CD:
1.4
Damage:
1659-1659
Mana:
10000
Mana regen:
0.01
Status:
Approved

Description:

An ancient building, storing the power of storms.
Specials:
+500 mana/lvl
Cloudy Thunderstorm
Summons a cloudy thunderstorm, which strikes random creeps in 1000 range every 0.4 seconds with lightning. Each strike deals [Current Mana x 0.5] spell damage and costs mana based on the target's size and the damage dealt. The storm ends when this tower's mana falls below 1000, or no creep comes within range for 4 seconds.
This ability will activate automatically when this tower's mana reaches a set threshold, as determined by the 'Adjust Autocast Threshold' ability. The autocast cannot be disabled.

Level Bonus:
+0.02 damage per current mana

AC_TYPE_NOAC_IMMEDIATE
 1000, 0 range, 0.01s cooldown
Adjust Autocast Threshold
Use this ability to adjust the percentual mana required for Cloudy Thunderstorm's autocast.

AC_TYPE_NOAC_IMMEDIATE
 0, 0 range, 0.01s cooldown
Cloud of Absorption - Aura
Creates a lightning ball if a creep in 1000 range is killed with more damage than needed. The lighting ball absorbs the redundant damage and transfers it to this temple. Every 1 damage absorbed grants 1 mana.

Level Bonus:
+0.05 mana per absorbed damage
Download

Toggle Triggers

Autocast

AUTOCAST_cooldown: 0.01 AUTOCAST_autoRange: 0 AUTOCAST_manacost: 1000 AUTOCAST_range: 0 AUTOCAST_targetType: 0 AUTOCAST_numBuffsBeforeIdle: 0 caster_art: target_art: AUTOCAST_autocastType: AC_TYPE_NOAC_IMMEDIATE AUTOCAST_buffType: 0 AUTOCAST_isExtended: false AUTOCAST_targetSelf: false
private function onAutocast takes Tower tower returns nothing
    call SetUnitState(tower.getUnit(), UNIT_STATE_MANA, GetUnitState(tower.getUnit(), UNIT_STATE_MANA) + 1000.0)
    if tower.userInt != 0 then
        call enableStorm(tower)
    endif
endfunction

Autocast

AUTOCAST_cooldown: 0.01 AUTOCAST_autoRange: 0 AUTOCAST_manacost: 0 AUTOCAST_range: 0 AUTOCAST_targetType: 0 AUTOCAST_numBuffsBeforeIdle: 0 caster_art: target_art: AUTOCAST_autocastType: AC_TYPE_NOAC_IMMEDIATE AUTOCAST_buffType: 0 AUTOCAST_isExtended: false AUTOCAST_targetSelf: false
private function onAutocast takes Tower tower returns nothing
    if tower.userReal >= 1.0 then
        set tower.userReal = 0.0
    endif
    set tower.userReal = tower.userReal + 0.1
    
    call tower.getOwner().displaySmallFloatingText(formatPercent(tower.userReal, 0), tower, 155, 155, 255, 40.0)
endfunction

Header

    globals
        // --- Aura ---
        BuffType        natac_obsorption_BuffType
        ProjectileType  natac_obsorption_ProjectileType
        
        // --- Storm ---
        BuffType        natac_stormTarget_BuffType
        integer array   natac_stormManaReductionValues
        
        // --- MB ---
        MultiboardValues MB
    endglobals
    
    // --- Storm Buff Handling ---
    
    function storm_onDamaged takes Buff b returns nothing
        local Tower caster = b.getCaster()
        local Creep buffed = b.getBuffedUnit()
        local unit bufUnit = buffed.getUnit()
        local real dmgTaken= RMinBJ(Event.damage, GetUnitState(bufUnit, UNIT_STATE_LIFE)) // Calculate how much damage is really dealt
        local integer size = buffed.getSize()
        
        // Remove mana from the tower according to the damage taken and the size of the creep
        call caster.subtractMana(dmgTaken * 0.1 * natac_stormManaReductionValues[size] * (dmgTaken/GetUnitState(bufUnit, UNIT_STATE_MAX_LIFE)), true)
        call b.removeBuff()
        set bufUnit = null
    endfunction
    
    // Enables the storm. This function is needed, cause the storm can be enabled by two events:
    // a) Tower reaches max mana per mana ball
    // b) Creep comes in range of tower when tower's mana has satisfied threshold
    function enableStorm takes Tower tower returns nothing
        if(tower.userInt3 == 0) then
            call PeriodicEvent(tower.userInt).enable()
            set tower.userInt3 = Effect.create("Abilities\\Spells\\Human\\CloudOfFog\\CloudOfFog.mdl", tower.getX(), tower.getY(), 150.0, 0.0)
        endif
    endfunction
    
    
    //--- Aura Buff + Projectile Handling ---
    //If a creep with the auras buff is killed, a projectile spawns
    
    // Reaction of a natac_obsorption_AuraBuffType on Damage
    function aura_onDamagedSpawnManaBall takes Buff b returns nothing
        local real damage = Event.damage
        local Unit target = b.getBuffedUnit()
        local real life  = GetUnitState(target.getUnit(), UNIT_STATE_LIFE)
        local Unit caster
        local Projectile manaBall
        
        // Only spawn the ball if
        // a) the unit will die
        // b) the unit isnt hit by the storm spell
        if damage > life and target.getBuffOfType(natac_stormTarget_BuffType) == 0 then
            set caster = b.getCaster() 
            set manaBall = Projectile.createFromPointToUnit(natac_obsorption_ProjectileType, caster, 0.0, 0.0, target.getX(), target.getY(), 0.0, caster, true, false, false)
            set manaBall.userReal = damage - life
        endif
    endfunction
    
    // Reaction of a natac_obsorption_ProjectileType if it reaches the tower
    function aura_reachTower takes Projectile p, Unit tower returns nothing
        local real grantedMana
        local real maxMana
        local real currentMana
        
        if(tower != 0) then
            set maxMana = GetUnitState(tower.getUnit(), UNIT_STATE_MAX_MANA)
            set currentMana = GetUnitState(tower.getUnit(), UNIT_STATE_MANA)
            set grantedMana = p.userReal * (1 + tower.getLevel()*0.05)
            
            // Add mana
            if(grantedMana > 0) then
                call tower.addMana(grantedMana)
            endif
            call tower.getOwner().displaySmallFloatingText("+"+I2S(R2I(RMinBJ(maxMana - currentMana, grantedMana))), tower, 0, 0, 255, 40)
            
            // If Mana is filled, enable storm
            if tower.userInt != 0 and (currentMana + grantedMana >= maxMana) then
                call enableStorm(tower)
            endif
        endif
    endfunction
    
    // --- Init Function ---
    
    //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
        // --- Aura ---
        set  natac_obsorption_BuffType = BuffType.createAuraEffectType(false)
        call natac_obsorption_BuffType.setBuffIcon('@@1@@')
        call natac_obsorption_BuffType.addEventOnDamaged(EventHandler.aura_onDamagedSpawnManaBall, 1.0, 0.0)
        
        set  natac_obsorption_ProjectileType = ProjectileType.createRanged("Abilities\\Weapons\\FarseerMissile\\FarseerMissile.mdl", 1000+100, 500)
        call natac_obsorption_ProjectileType.enableHoming(aura_reachTower, 0.0)
        
        // --- Storm ---
        set  natac_stormTarget_BuffType = BuffType.create(-1.0, 0.0, false)
        call natac_stormTarget_BuffType.addEventOnDamaged(EventHandler.storm_onDamaged, 1.0, 0.0)
        set  natac_stormManaReductionValues[SIZE_CHALLENGE] = 130
        set  natac_stormManaReductionValues[SIZE_BOSS] = 100
        set  natac_stormManaReductionValues[SIZE_CHAMPION] = 20
        set  natac_stormManaReductionValues[SIZE_NORMAL] = 10
        set  natac_stormManaReductionValues[SIZE_AIR] = 20
        set  natac_stormManaReductionValues[SIZE_MASS] = 5
        set  natac_stormManaReductionValues[SIZE_MASS_CHALLENGE] = 13
        
        // --- MB ---
        set MB = MultiboardValues.create(1)
        call MB.setKey(0, "Mana required")
    endfunction

On Tower Creation

function onCreate takes Tower tower returns nothing
    set tower.userInt  = 0 // Stores the periodic event. Init with 0
    set tower.userInt2 = 0 // Stores the number of effectless periodic events. Is used for the timeout. 
    set tower.userInt3 = 0 // Stores the effect, shown during the storm
    
    set tower.userReal = 1.0 //Percentage required to trigger the storm
endfunction

On Tower Destruction

function onDestruct takes Tower tower returns nothing
    if tower.userInt3 != 0 then
        call Effect(tower.userInt3).destroy()
    endif
endfunction

On Tower Details

function onTowerDetails takes Tower tower returns MultiboardValues
    call MB.setValue(0, formatPercent(tower.userReal, 0))
    return MB
endfunction

On Unit Comes In Range

UNITINRANGE_targetType: TARGET_TYPE_CREEPS UNITINRANGE_range: 1000
function onUnitInRange takes Tower tower returns nothing
    local unit towerUnit = tower.getUnit()
    
    // Enable the storm if the tower is ready and a non-immune creep comes in range
    if tower.userInt != 0 and not Event.getTarget().isImmune() then
        if GetUnitState(towerUnit, UNIT_STATE_MANA) >= (tower.userReal * GetUnitState(towerUnit, UNIT_STATE_MAX_MANA)) then
            call enableStorm(tower)
        endif
    endif
    set towerUnit = null
endfunction

Periodic

PERIODIC_period: 0.4
function periodic takes Tower tower returns nothing
    local unit towerUnit = tower.getUnit()
    local real mana = GetUnitState(towerUnit, UNIT_STATE_MANA)
    local PeriodicEvent storm  
    local Iterate it
    local Unit target
  
    // The next strike will be realeased, if
    // a) The storm is enabled AND
    // b) The tower has still some mana AND
    // c) No timeout is reached
    if tower.userInt != 0 and mana > 1000.0 and tower.userInt2 < 10 then
        // -> Release next strike
        
        // Set the local values
        set it = Iterate.overUnitsInRangeOfCaster(tower, TARGET_CREEPS, 1000)
        set target = it.nextRandom()
        
        if(target != 0) then
            call it.destroy()
            // Do full available damage and apply buff,
            set tower.userInt2 = 0 // Reset timeout-counter
            call natac_stormTarget_BuffType.apply(tower, target, 1)
            call tower.doSpellDamage(target, GetUnitState(towerUnit, UNIT_STATE_MANA) * (0.5+tower.getLevel()*0.02), tower.calcSpellCritNoBonus())
            call SFXAtUnit("Abilities\\Spells\\Other\\Monsoon\\MonsoonBoltTarget.mdl", target.getUnit())
        else
            // Increase timeout counter
            set tower.userInt2 = tower.userInt2 + 1 
        endif
    else
        // -> Disable Storm
        set storm = Event.getCurrentPeriodicEvent() 
        set tower.userInt = storm
        call storm.disable()
        
        if tower.userInt3 != 0 then
            call Effect(tower.userInt3).destroy()
            set tower.userInt3 = 0
        endif
        
        set tower.userInt2 = 0 //reset timeout counter
    endif
    set towerUnit = null
endfunction

Tower Aura

AURA_powerAdd: 1 AURA_auraEffect: natac_obsorption_BuffType AURA_levelAdd: 1 AURA_power: 1 AURA_targetType: TARGET_TYPE_CREEPS AURA_targetSelf: false AURA_level: 1 AURA_auraRange: 1000
Champion of Light v1
2000
ID:
85
Family ID:
Author:
i_mOck_death
Rarity:
rare
Element:
astral
Attack Type:
Elemental
Attack Range:
900
Attack CD:
1
Damage:
751-751
Status:
Approved

Description:

Rare Astral tower with a chance on each attack to create a wave of light that damages enemies.
Ain Soph Aur
This tower has a 23% chance on every attack to create a shockwave of light that starts at the targeted creep and travels 500 units behind that creep dealing 2000 spell damage to all creeps in its path.

Level Bonus:
+0.7% chance
+100 damage
Aura of Light - Aura
Towers in 300 range deal 20% more damage to undead creeps.

Level Bonus:
+0.8% damage
Download

Toggle Triggers

Header

    globals
        Cast Swave
        //@import
        BuffType mOck_Warrioroflight
    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 Swave = Cast.create('@@0@@', "carrionswarm", 1)
    endfunction

On Attack

ONATTACK_chance: .23 ONATTACK_chanceLevelAdd: 0.007
function onAttack takes Tower tower returns nothing
local unit creep = Event.getTarget().getUnit()
local integer level = tower.getLevel()
local real facing = GetUnitFacing(creep) - 180
local real x = GetUnitX(creep) + (50) * Cos(facing * bj_DEGTORAD)
local real y = GetUnitY(creep) + (50) * Sin(facing * bj_DEGTORAD)
call Effect.createSimple("Abilities\\Spells\\Human\\HolyBolt\\HolyBoltSpecialArt.mdl",GetUnitX(creep),GetUnitY(creep)).destroy()
call Swave.pointCastFromUnitOnPoint(tower,Event.getTarget(),x, y,1.0+(.05*level), tower.calcSpellCritNoBonus())

set creep = null
endfunction

Tower Aura

AURA_auraEffect: mOck_Warrioroflight AURA_power: 200 AURA_level: 200 AURA_auraRange: 300 AURA_targetType: TARGET_TYPE_TOWERS AURA_levelAdd: 8 AURA_powerAdd: 8 AURA_targetSelf: true
Polar Ivy v1
2000
ID:
155
Family ID:
Author:
drol
Rarity:
common
Element:
ice
Attack Type:
Energy
Attack Range:
750
Attack CD:
0.75
Damage:
1020-1244
Status:
Approved

Description:

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

Level Bonus:
+100 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(), 2500 + 100 * tower.getLevel(), tower.calcSpellCritNoBonus())
    endif
endfunction
Void Drake v1
2000
ID:
196
Family ID:
Author:
Chronos
Rarity:
rare
Element:
darkness
Attack Type:
Essence
Attack Range:
1000
Attack CD:
1.35
Damage:
3633-3965
Status:
Approved

Description:

Selfish creature, harbringer of the void.
Specials:
-50% exp gain (-6%/lvl)
+4% attackspeed/lvl
+12% damage/lvl
Silence
Units damaged by this tower are silenced for 1.25 seconds. Bosses are silenced only for 1/3 of the normal duration.

Level Bonus:
+0.07 seconds duration
Void
Every second, this unit loses 1% of its experience. This tower will not lose levels in this way. Replacing a tower with this tower will reset the experience to 0 unless the replaced tower is of this tower's family. When this tower is upgraded or replaced to Void Dragon, it loses experience equal to 50% of its current experience. 

Level Bonus:
+0.02% periodical experience lost
+1% upgrade experience lost
Download

Toggle Triggers

Header

    globals
        //@export
        real array Chronos_voidLevelExp
    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
    local integer i = 1
    local real f = 1.0
    loop //calculate exp needed for levels
        exitwhen i > 25 
        set Chronos_voidLevelExp[i] = Chronos_voidLevelExp[i-1] + Game.EXP_BASE_VALUE * f 
        set i = i + 1 
        set f = f * Game.EXP_LEVEL_FACTOR 
    endloop 
    endfunction

On Damage

ONDAMAGE_chance: 1 ONDAMAGE_chanceLevelAdd: 0
function onDamage takes Tower tower returns nothing
    local real silenceDuration = 1.25 + 0.07 * tower.getLevel()
    local Unit creep = Event.getTarget()
    if creep.getSize() == SIZE_BOSS then
        set silenceDuration = silenceDuration / 3
    endif
    call cb_silence.applyOnlyTimed(tower, Event.getTarget(), silenceDuration)
endfunction

On Tower Creation

function onCreate takes Tower tower returns nothing
    if Event.getPrecedingTower().getFamily() != tower.getFamily() then
        call tower.removeExpFlat(tower.getExp())
    endif
endfunction

Periodic

PERIODIC_period: 1
function periodic takes Tower tower returns nothing
    local integer level = tower.getLevel()
    local real exp = tower.getExp()
    local real expRemoved = exp * (0.01+0.0002*level)
    if expRemoved >= (exp - Chronos_voidLevelExp[level]) then
        set expRemoved = (exp - Chronos_voidLevelExp[level]) - 0.01
    endif
    if (expRemoved) >= 0.1 and level != 25 then
        call tower.removeExpFlat(expRemoved)
    endif
endfunction