//***************************************************************************************************************
//* *
//* Death Carrier (vJASSified). *
//* By Moyack. *
//* V.2.0. *
//* *
//***************************************************************************************************************
// Made for the spell contest No 13 (for the bad luck maybe??)
// Requires TimerUtils (http://www.wc3c.net/showthread.php?t=101322) by Vexorian.
library DeathCarrier initializer init requires TimerUtils
// Configuration part...
globals
private constant integer SpellID = 'A000' // Sets the ability Rawcode
private constant real TIMEOUT = 0.5 // Sets the timer frequency
private constant attacktype ATTACK = ATTACK_TYPE_SIEGE // Sets the type of attack that deals the spell
private constant damagetype DAMAGE = DAMAGE_TYPE_NORMAL // Sets the type of damage that deals the spell
endglobals
private constant function Damage takes integer lvl returns real
return 100. + 70. * (lvl - 1)
endfunction
private constant function AOE takes integer lvl returns real
return 500. // I left it in this way so it can be configurable to a variable area
endfunction
private constant function Jumps takes integer lvl returns integer
return 5 // sets the number of times the maks jumps on units before explode
endfunction
// end configuration part...
private function GetEnemies takes nothing returns boolean
return GetUnitState(GetFilterUnit(), UNIT_STATE_LIFE) > 0.405 and IsUnitEnemy(GetFilterUnit(), GetOwningPlayer(bj_groupRandomCurrentPick))
endfunction
private struct data
group g
unit c
integer counter = 0
private method onDestroy takes nothing returns nothing
call GroupClear(.g)
set .c = null
endmethod
private static method PickRandomUnit takes nothing returns nothing
set bj_groupRandomConsidered = bj_groupRandomConsidered + 1
if GetWidgetLife(GetEnumUnit()) > 0.405 and GetRandomInt(1,bj_groupRandomConsidered) == 1 then
set bj_groupRandomCurrentPick = GetEnumUnit()
endif
endmethod
static method effect takes nothing returns nothing
local data d = thistype( GetTimerData(GetExpiredTimer()) )
local real x
local real y
set bj_groupRandomConsidered = 0
set bj_groupRandomCurrentPick = null
call ForGroup(d.g, function thistype.PickRandomUnit)
if bj_groupRandomCurrentPick == null then
call d.destroy()
call ReleaseTimer(GetExpiredTimer())
return
endif
call DestroyEffect(AddSpellEffectTargetById(SpellID, EFFECT_TYPE_SPECIAL, bj_groupRandomCurrentPick, "overhead"))
set d.counter = d.counter + 1
if d.counter > Jumps(GetUnitAbilityLevel(d.c, SpellID)) then
set x = GetUnitX(bj_groupRandomCurrentPick)
set y = GetUnitY(bj_groupRandomCurrentPick)
call DestroyEffect(AddSpecialEffect(GetAbilityEffectById(SpellID, EFFECT_TYPE_SPECIAL, 1), x, y))
// at this point, d.g is not needed, so I'll use to do the final task :P
set bj_groupRandomCurrentPick = d.c
call GroupEnumUnitsInRange(d.g, x, y, 0.5 * AOE(GetUnitAbilityLevel(d.c, SpellID)), Condition(function GetEnemies))
loop
set bj_groupRandomCurrentPick = FirstOfGroup(d.g)
exitwhen bj_groupRandomCurrentPick == null
call UnitDamageTarget(d.c, bj_groupRandomCurrentPick, Damage(GetUnitAbilityLevel(d.c, SpellID)), true, true, ATTACK, DAMAGE, WEAPON_TYPE_ROCK_HEAVY_BASH)
call DestroyEffect(AddSpecialEffectTarget(GetAbilityEffectById(SpellID, EFFECT_TYPE_SPECIAL, 2), bj_groupRandomCurrentPick, "chest"))
call GroupRemoveUnit(d.g, bj_groupRandomCurrentPick)
endloop
call d.destroy()
call ReleaseTimer(GetExpiredTimer())
else
call UnitDamageTarget(d.c, bj_groupRandomCurrentPick, GetRandomReal(0, Damage(GetUnitAbilityLevel(d.c, SpellID))), true, false, ATTACK, DAMAGE, WEAPON_TYPE_ROCK_HEAVY_BASH)
endif
endmethod
static method Start takes unit c, real x, real y returns nothing
local data d = data.allocate()
local timer t = NewTimer()
if d.g == null then
set d.g = CreateGroup()
endif
set d.c = c
set bj_groupRandomCurrentPick = c
call GroupEnumUnitsInRange(d.g, x, y, AOE(GetUnitAbilityLevel(c, SpellID)), Condition(function GetEnemies))
call SetTimerData(t, integer(d))
call TimerStart(t, TIMEOUT, true, function data.effect)
set t = null
endmethod
endstruct
private function Conditions takes nothing returns boolean
if GetSpellAbilityId() == SpellID then
call data.Start(GetTriggerUnit(), GetSpellTargetX(), GetSpellTargetY())
endif
return false
endfunction
//===========================================================================
private function init takes nothing returns nothing
local trigger t = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition( t, Condition( function Conditions ) )
set t = null
endfunction
endlibrary