Plagued Crypt v1
2500
ID:
645
Family ID:
Author:
cedi
Rarity:
unique
Element:
darkness
Attack Type:
Decay
Attack Range:
1150
Attack CD:
3
Damage:
3899-3916
Status:
Approved

Description:

The Plague Bringer is a siege engine mounted ontop of corrupted crypts using the corpses of the fallen as ammunition.
Specials:
Attacks GROUND only
Splash attack:
   25 AoE: 100% damage
   50 AoE: 40% damage
   150 AoE: 25% damage
Plague
When a creep is damaged by this tower it will become infected with a plague. This plague deals 750 damage per second and lasts 5 seconds. Every 1.5 seconds the plague can spread to a creep in 250 range around the infected creep. If an infected creep is infected again by the plague the duration will refresh and the damage is increased by 375.

Level Bonus:
+30 damage
+0.2 seconds duration
+15 damage per rebuff
Army of the Damned
Every 3 seconds, if there is a corpse within 1150 range this tower will extract its soul, increasing its attack speed and damage by 5% and Plague's rate of spread by 10%. This buff lasts 20 seconds and stacks, but new stacks will not refresh the duration of old ones.

Level Bonus:
+0.4 seconds duration
Download

Toggle Triggers

Header

    globals
        BuffType BT
        BuffType cedi_armyOfDamned
        MultiboardValues MB
    endglobals
    
    function periodicDamage takes Buff B returns nothing
        local Unit T = B.getBuffedUnit()
        local Unit C = B.getCaster()
        local integer level = C.getLevel()
        call C.doSpellDamage( T, (750.00 + level * 30.00) + (( 375.00 + 15.00 * level) * B.userInt ), C.calcSpellCritNoBonus() )
    endfunction
    
    function periodicSpread takes Buff B returns nothing
        local Tower C = B.getCaster()
        local Unit T = B.getBuffedUnit()
        local Unit U
        local integer level = C.getLevel()
        local Iterate I
        //spread
        if B.userInt2 == 1 then
            set I = Iterate.overUnitsInRangeOfUnit( C, TARGET_CREEPS, T, 250.00 )
            loop
                set U = I.nextRandom()
                exitwhen U == 0
                if U != T then
                    call BT.apply(C, U, level)
                    call I.destroy()
                    exitwhen true
                endif
            endloop
        else
            set B.userInt2 = 1
        endif
        
        set B = C.getBuffOfType( cedi_armyOfDamned )
        if B == 0 then
            call Event.getCurrentPeriodicEvent().enableAdvanced(1.5, false )
        else
            //call Event.getCurrentPeriodicEvent().enableAdvanced(1.5 * Pow( 0.9, B.getLevel()), false )  //this decreases time between spreads by 10%
            call Event.getCurrentPeriodicEvent().enableAdvanced(1.5 * Pow( 1.1, -B.getLevel()), false ) //this increases rate of spreading by 10%   (there is a difference)
        endif
    endfunction
    
    function refresh takes Buff B returns nothing
        set B.userInt = B.userInt + 1
    endfunction
        
    function onCreate takes Buff B returns nothing
        set B.userInt = 0      // Damage increase multiplier
        set B.userInt2 = 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 BT = BuffType.create( 5.00, 0.2, false )
        call BT.setBuffIcon( '@@0@@' )
        call BT.addPeriodicEvent( periodicDamage, 1 )
        call BT.addPeriodicEvent( periodicSpread, 0.01 )    //the periodic gets set in the periodic handling event
        call BT.setEventOnRefresh( refresh )
        call BT.setEventOnUpgrade( refresh )
        call BT.addEventOnCreate( onCreate)
        
        call m.addModification( MOD_ATTACKSPEED, 0.0, 0.05 )
        call m.addModification( MOD_DAMAGE_BASE_PERC, 0.0, 0.05 )
        set cedi_armyOfDamned = BuffType.create( -1, 0, true )
        call cedi_armyOfDamned.setBuffIcon( '@@1@@' )
        call cedi_armyOfDamned.setBuffModifier( m )
        
        set MB = MultiboardValues.create( 2 )
        call MB.setKey( 0, "Souls Extracted" )
        call MB.setKey( 1, "Infection Rate" )
    endfunction

On Damage

ONDAMAGE_chance: 1.0 ONDAMAGE_chanceLevelAdd: 0.0
function onDamage takes Tower tower returns nothing
    call BT.apply(tower, Event.getTarget(), tower.getLevel())
endfunction

On Tower Details

function onTowerDetails takes Tower tower returns MultiboardValues
    call MB.setValue( 0, I2S( tower.getBuffOfType( cedi_armyOfDamned ).getLevel() ) )
    call MB.setValue( 1, formatFloat( 1.5 * Pow( 1.1, -tower.getBuffOfType( cedi_armyOfDamned ).getLevel() ), 2 ) )
    return MB
endfunction

Periodic

PERIODIC_period: 3.0
function periodic takes Tower tower returns nothing
   local Iterate I = Iterate.overCorpsesInRange( tower, tower.getX(), tower.getY(), 1150.00 )
   local unit u = I.nextCorpse()
   local Buff B = tower.getBuffOfType(cedi_armyOfDamned)
   local integer UID
   if u != null then
      call I.destroy()
      call DestroyEffect( AddSpecialEffect("Abilities\\Spells\\Undead\\RaiseSkeletonWarrior\\RaiseSkeleton.mdl", GetUnitX(u), GetUnitY(u)))
      call RemoveUnit(u)
      set u = null
       
      if B != 0 then
         set B = cedi_armyOfDamned.apply(tower, tower, B.getLevel() + 1)
      else
         set B = cedi_armyOfDamned.apply(tower, tower, 1)      
      endif
       
      set UID = B.getUID()

      call TriggerSleepAction((20 + 0.4 * tower.getLevel()) * tower.getProp_BuffDuration())

      if B.getUID() == UID then
         call B.setLevel(B.getLevel()-1)
         if B.getLevel() == 0 then
            call B.removeBuff()
         endif
      endif
   endif
endfunction