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