Vol'jin the Witch Doctor v1
4600
|
ID: 114
Family ID:
Author: SirCoqaLot.
Rarity: unique
Element: astral
Attack Type: Elemental
Attack Range: 800
Attack CD: 2
Damage: 4756-4756
Mana: 40
Mana regen: 1.5
Status: Approved
|
Specials:
+3% attackspeed/lvl +8% damage/lvl
Maledict
Vol'jin jinxes all units in 800 range around him. Targets caught by the jinx are dealt 15% of the damage they received as spell damage after 8 seconds. Maledict stacks, with each stack adding 3.5% additional damage. If Maledict is purged it deals double damage. This ability is unaffected by Buff Duration. Level Bonus: +0.14% damage per stack AC_TYPE_OFFENSIVE_IMMEDIATE 30, 800 range, 5s cooldown
Serpent Ward
Vol'jin has an 18% chance on attack to summon 1 of 2 Serpent Wards to assist him. Each ward lasts 6 seconds modified by this tower's buff duration, deals 20% of Vol'jins attack damage and has Vol'jins current attackspeed at cast. Each Ward attacks a random target in 800 range and has a 35% chance to stack 'Maledict' on attack. Wards can not be resummoned and their duration cannot be refreshed. Level Bonus: +0.2% attackdamage +0.1 seconds duration +0.28% chance to summon a ward +1 maximum ward at level 15 and 25
Purify
Whenever Vol ' jin deals damage he purges all buffs and debuffs from his target, increasing his damage dealt on that attack by 12% for each purged effect. This ability has a 4 second cooldown. Level Bonus: -0.04 seconds cooldown +0.16% damage per purged effect |
Download
Toggle Triggers Autocast
AUTOCAST_cooldown: 5
AUTOCAST_autoRange: 800
AUTOCAST_manacost: 30
AUTOCAST_range: 800
AUTOCAST_targetType: 0
AUTOCAST_numBuffsBeforeIdle: 0
caster_art:
target_art:
AUTOCAST_autocastType: AC_TYPE_OFFENSIVE_IMMEDIATE
AUTOCAST_buffType: 0
AUTOCAST_isExtended: true
AUTOCAST_targetSelf: false
private function onAutocast takes Tower tower returns nothing
local Iterate it = Iterate.overUnitsInRangeOfUnit(tower,TARGET_CREEPS,tower,800)
local Unit u
loop
set u = it.next()
exitwhen u == 0
call ApplyMaledict(tower,u,true)
endloop
endfunction
Header globals
BuffType sir_voljin_debuff
ProjectileType sir_voljin_projectile
hashtable voljin_hashtable
// 0 = Ward 1
// 1 = Duration
// 2/3 = Position(x/y)
// 4 = Ward 2
// ...
endglobals
function damageEvent takes Buff b returns nothing
set b.userReal = b.userReal + Event.damage
endfunction
function expireEvent takes Buff b returns nothing
call b.getCaster().doSpellDamage(b.getBuffedUnit(),(0.15+(0.035+0.0014*b.getCaster().getLevel())*b.getLevel())*R2I(b.userReal),b.getCaster().calcSpellCritNoBonus())
endfunction
function purgeEvent takes Buff b returns nothing
call b.getCaster().doSpellDamage(b.getBuffedUnit(),(0.3+(0.07+0.0028*b.getCaster().getLevel())*b.getLevel())*R2I(b.userReal),b.getCaster().calcSpellCritNoBonus())
endfunction
function ApplyMaledict takes Tower caster, Unit target, boolean B returns nothing
local Buff b = target.getBuffOfType(sir_voljin_debuff)
local real duration = caster.getProp_BuffDuration()
if B == true and b == 0 then
set sir_voljin_debuff.applyAdvanced(caster, target,1, 0, 8.0/duration).userReal = 0.0
elseif (b != 0 and B == false and caster.calcChance(0.35)) or (b != 0 and B == true) then
call sir_voljin_debuff.applyAdvanced(caster, target, b.getLevel() + 1, 0, 8.0/duration)
endif
endfunction
function voljin_hit takes Projectile p, Unit hit returns nothing
local Tower tower = p.getCaster()
call tower.doAttackDamage(hit,tower.getCurrentAttackDamageWithBonus() * (0.2+tower.getLevel()*0.002),tower.calcAttackMulticrit(0,0,0))
call ApplyMaledict(tower,hit,false)
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 voljin_hashtable = InitHashtable()
set sir_voljin_debuff = BuffType.create(0,0,false)
call sir_voljin_debuff.setBuffIcon('@@0@@')
call sir_voljin_debuff.addEventOnDamaged(damageEvent,1,0)
call sir_voljin_debuff.setEventOnExpire(expireEvent)
call sir_voljin_debuff.setEventOnPurge(purgeEvent)
set sir_voljin_projectile=ProjectileType.create("Abilities\\Weapons\\SerpentWardMissile\\SerpentWardMissile.mdl",10.0,1200.0)
call sir_voljin_projectile.enableHoming(ProjectileTargetEvent.voljin_hit,0.0)
endfunction
On Attack
ONATTACK_chance: 0.18
ONATTACK_chanceLevelAdd: 0.0028
function onAttack takes Tower tower returns nothing
local integer level = tower.getLevel()
local unit towerUnit = tower.getUnit()
local real attackspeed = tower.getCurrentAttackspeed()
local PeriodicEvent periodicEvent = tower.userInt
local real towerUnitZ = GetUnitFlyHeight(towerUnit)
local integer counter = 0
local integer maxWards = 2
local Effect e
local real duration
local real x
local real y
if level == 25 then
set maxWards = 4
elseif level >= 15 then
set maxWards = 3
endif
loop
// Check whether all wards already exist, if not create one
if not HaveSavedInteger(voljin_hashtable, tower, counter) then
set x = LoadReal(voljin_hashtable, tower, counter + 2)
set y = LoadReal(voljin_hashtable, tower, counter + 3)
set e = Effect.createAnimated("units\\orc\\SerpentWard\\SerpentWard.mdl", x, y, towerUnitZ - 20, -(45.0 + 90.0 * (counter / 4)))
call e.setScale(0.4)
set duration = (6.0+tower.getLevel()*0.1) * tower.getProp_BuffDuration()
call SaveInteger(voljin_hashtable, tower, counter, e) // Save the effect
call SaveReal(voljin_hashtable, tower, counter + 1, duration) // Save the duration
set tower.userInt2 = tower.userInt2 + 1 // Save the amount of wards
// The first ward has been created => Start the Periodic Event
if tower.userInt2 == 1 then
call periodicEvent.enableAdvanced(attackspeed, false)
set tower.userReal = attackspeed // Save the periodic interval
endif
exitwhen true // Exit
endif
set counter = counter + 4 // Move to the next ward
exitwhen counter > (maxWards * 4 - 4)
endloop
set towerUnit = null
endfunction
On Damage
ONDAMAGE_chance: 1.0
ONDAMAGE_chanceLevelAdd: 0.0
function onDamage takes Tower tower returns nothing
local Unit creep = Event.getTarget()
local real damage = Event.damage
local integer numPurgedBuffs = 0
// Remove buffs (positive and negative buffs) and count them
if tower.userInt3 <= Game.getGameTime() then
set tower.userInt3 = Game.getGameTime()+100-tower.getLevel() // adding the cd
loop
exitwhen not (creep.purgeBuff(true) or creep.purgeBuff(false))
set numPurgedBuffs = numPurgedBuffs + 1
endloop
set damage = damage*(1+numPurgedBuffs*(0.12+tower.getLevel()*0.0016)) // 12% damage
set Event.damage = damage
if numPurgedBuffs != 0 then
call tower.getOwner().displaySmallFloatingText(I2S(R2I(damage)),tower,255,150,255,0)
endif
endif
endfunction
On Tower Creation function onCreate takes Tower tower returns nothing
local real towerX = tower.getX()
local real towerY = tower.getY()
set tower.userInt = 0 // Contains the Periodic Event
set tower.userInt2 = 0 // Stores the amount of wards
set tower.userReal = 0 // Stores the periodic interval
set tower.userInt3 = Game.getGameTime()-100 // stores the cooldown of purify
// Ward 1
call SaveReal(voljin_hashtable, tower, 2, towerX + 38)
call SaveReal(voljin_hashtable, tower, 3, towerY - 53)
// Ward 2
call SaveReal(voljin_hashtable, tower, 6, towerX - 43)
call SaveReal(voljin_hashtable, tower, 7, towerY - 45)
// Ward 3
call SaveReal(voljin_hashtable, tower, 10, towerX - 33)
call SaveReal(voljin_hashtable, tower, 11, towerY + 38)
// Ward 4
call SaveReal(voljin_hashtable, tower, 14, towerX + 35)
call SaveReal(voljin_hashtable, tower, 15, towerY + 38)
endfunction
On Tower Destruction function onDestruct takes Tower tower returns nothing
local integer counter = 0
loop
if HaveSavedInteger(voljin_hashtable, tower, counter) then
call Effect(LoadInteger(voljin_hashtable, tower, counter)).destroy()
endif
set counter = counter + 4
exitwhen counter > 12
endloop
call FlushChildHashtable(voljin_hashtable, tower)
endfunction
Periodic
PERIODIC_period: 0.1
function periodic takes Tower tower returns nothing
local Effect e
local Unit u
local Projectile p
local PeriodicEvent periodicEvent = tower.userInt
local Iterate it
local Unit array targets
local integer numTargets = 0
local integer counter = 0
local real duration
local real facing
local real x
local real y
// If it's the first time this event fires
if periodicEvent == 0 then
set tower.userInt = Event.getCurrentPeriodicEvent() // Save the event
call Event.getCurrentPeriodicEvent().disable() // Disable it
return
endif
// Get all targets in range
set it = Iterate.overUnitsInRangeOfCaster(tower,TARGET_CREEPS,800)
loop
set u = it.next()
exitwhen u == 0
set targets[numTargets] = u
set numTargets = numTargets + 1
endloop
loop
// Is there a ward ?
if HaveSavedInteger(voljin_hashtable, tower, counter) then
set e = LoadInteger(voljin_hashtable, tower, counter) // Load ward effect
set u = targets[GetRandomInt(0, numTargets - 1)] // Get a random target
set duration = LoadReal(voljin_hashtable, tower, counter + 1) - tower.userReal // Set duration to duration - periodic interval
if duration > 0 then // Is there duration remaining?
if u != 0 then // Is there are unit which can be attacked ?
// Load position
set x = LoadReal(voljin_hashtable, tower, counter + 2)
set y = LoadReal(voljin_hashtable, tower, counter + 3)
// Calculate the angle between the ward and the target
set facing = Atan2(GetUnitY(u.getUnit()) - y, GetUnitX(u.getUnit()) - x) * bj_RADTODEG
call e.setFacing(facing) // Set facing
call e.setAnimation("attack") // Play attack animation
// Shoot prohectile
set p = Projectile.createFromPointToUnit(sir_voljin_projectile, tower, 1.0, 1.0, x, y, 147.0, u, true, false, false)
call p.setScale(0.4)
call e.queueAnimation("stand") // Play the stand animation again
endif
// Save the remaining duration
call SaveReal(voljin_hashtable, tower, counter + 1, duration)
else // No more duration
// Remove the ward effect from the hashtable
call RemoveSavedInteger(voljin_hashtable, tower, counter)
call e.destroy() // Destroy the ward
set tower.userInt2 = tower.userInt2 - 1 // Decrease the ward counter
endif
endif
set counter = counter + 4 // Next ward
// Up to 4 wards with each taking 4 storage places in the hashtable starting at 0
// => 4 wards * 4 places - 4
exitwhen counter > (4 * 4 - 4)
endloop
// Disable the event
call periodicEvent.disable()
// Are there any wards?
if tower.userInt2 > 0 then
// Activate the event
set tower.userReal = tower.getCurrentAttackspeed()
call periodicEvent.enableAdvanced(tower.getCurrentAttackspeed() ,false)
endif
endfunction
|
Description: