///////////////////////////////////////////////////
// Aqua Crush
// by: Adiktuz
///////////////////////////////////////////////////
scope AquaCrush initializer Aqua_Init
//configurables
globals
private constant integer FLY = 'Amrf' //Rawcode of Medivh's raven form
private constant integer DUMMY = 'h001' //Rawcode of the dummy unit(horizontal)
private constant integer SPELL = 'A001' //Rawcode of the spell
private constant real DAMAGE = .833 //Explosion damage per level (multiply this value by 12)
private constant real DAMAGER = 4.17 //Impact damage per level (multiply this by 12)
private constant real HEIGHT = 600 //The maximum height that units will be thrown up to
private constant string WAVE = "Abilities\\Spells\\Other\\CrushingWave\\CrushingWaveMissile.mdl" //The path to the wave effect
//Note: Using WATER and SPLASH can cause a little lag on some PCs
private boolean SE = false //If true, there will be an explosion effect
private boolean SPE = false //If true, there will be a splashdown effect
private constant string WATER = "Objects\\Spawnmodels\\Naga\\NagaDeath\\NagaDeath.mdl" //The path to the explosion effect
private constant string SPLASH = "Objects\\Spawnmodels\\Naga\\NagaDeath\\NagaDeath.mdl" //The path to the splashdown effect
private constant real AOE = 100 //The base radius of the spell
private constant real AOE_B = 50 //The bonus radius of the spell per level
private constant real RANGE = 500 //The distance of the waves from the target point
private constant real SPEED = 20 //The rate at which the waves move
private attacktype ATYPE = ATTACK_TYPE_MAGIC //The attack type of the spell
private damagetype DTYPE = DAMAGE_TYPE_COLD //The damage type of the spell
private constant boolean TREE = true //If set to true, the explosion will also destroy destructibles: if you use the normal bridges make them invulnerable or the spell will also destroy them.
private constant boolean FLYING = false //If set to true, flying units will also get lifted
//End of configurables
private integer array Data
private integer array Datax
private integer Total = 0
private integer Totalx = 0
private timer t = CreateTimer()
private timer tx = CreateTimer()
private group Temp = CreateGroup()
private constant real ACCELERATION = 3 //The increase in rate at which units get thrown up/down
endglobals
private struct AC
real x
real y
real distance
real facing
unit u
real height
effect wave
player owner
unit v
real time
integer level
boolean direction = false
static method create takes real x, real y, player p, real facing, integer level, unit caster returns AC
local AC dat = AC.allocate()
set Data[Total] = dat
set dat.x = x - RANGE*Cos(facing)
set dat.y = y - RANGE*Sin(facing)
set dat.u = CreateUnit(p, DUMMY, dat.x, dat.y, facing*bj_RADTODEG)
set dat.distance = RANGE
set dat.owner = p
set dat.level = level
set dat.facing = facing
set dat.v = caster
set dat.wave = AddSpecialEffectTarget(WAVE, dat.u, "chest")
if Total == 0 then
call TimerStart(t, .03, true, function AC.move)
endif
set Total = Total + 1
set p = null
return dat
endmethod
method onDestroy takes nothing returns nothing
local rect r = Rect(this.x - AOE - AOE_B*this.level, this.y - AOE - AOE_B*this.level, this.x + AOE + AOE_B*this.level, this.y + AOE + AOE_B*this.level)
if TREE then
call EnumDestructablesInRect(r, null, function Dest)
endif
call DestroyEffect(this.wave)
set this.u = null
set this.wave = null
set this.owner = null
set this.v = null
call RemoveRect(r)
set r = null
endmethod
static method move takes nothing returns nothing
local AC dat
local integer i = 0
local unit u
local unit x
loop
exitwhen i == Total
set dat = Data[i]
set dat.x = dat.x + SPEED*Cos(dat.facing)
set dat.y = dat.y + SPEED*Sin(dat.facing)
call SetUnitPosition(dat.u, dat.x, dat.y)
set dat.distance = dat.distance - SPEED
if dat.distance == 0 then
call GroupEnumUnitsInRange(Temp, dat.x, dat.y, AOE + AOE_B*dat.level, null)
loop
set u = FirstOfGroup(Temp)
exitwhen u == null
if (IsPlayerEnemy(GetOwningPlayer(u), dat.owner) and GetWidgetLife(u) > .405) then
call AC.LiftStart(u,dat.v, dat.level)
call UnitDamageTarget(dat.u,u, dat.level*DAMAGE, false, false, ATYPE, DTYPE, WEAPON_TYPE_WHOKNOWS)
endif
call GroupRemoveUnit(Temp, u)
endloop
if SE then
call DestroyEffect(AddSpecialEffectTarget(WATER, dat.u, "origin"))
endif
call UnitApplyTimedLife(dat.u, 'BTLF', 1.00)
call dat.destroy()
set Total = Total - 1
set Data[i] = Data[Total]
set i = i - 1
endif
set i = i + 1
endloop
if Total == 0 then
call PauseTimer(t)
endif
set x = null
set u = null
endmethod
static method LiftStart takes unit u,unit x, integer level returns nothing
local AC dat = AC.allocate()
if FLYING then
set dat.x = GetUnitX(u)
set dat.y = GetUnitY(u)
call UnitAddAbility(u, FLY)
call UnitRemoveAbility(u, FLY)
call SetUnitFlyHeight(u, 10.00, 0)
set dat.v = u
set dat.u = x
set dat.level = level
set dat.time = 0
else
if IsUnitType(u, UNIT_TYPE_FLYING) == false then
set dat.x = GetUnitX(u)
set dat.y = GetUnitY(u)
call UnitAddAbility(u, FLY)
call UnitRemoveAbility(u, FLY)
call SetUnitFlyHeight(u, 10.00, 0)
set dat.v = u
set dat.u = x
set dat.level = level
set dat.time = 0
else
set dat.v = null
set dat.u = null
set dat.direction = true
endif
endif
set Datax[Totalx] = dat
if Totalx == 0 then
call TimerStart(tx, .03, true, function AC.Lift)
endif
set Totalx = Totalx + 1
set u = null
set x = null
endmethod
static method Lift takes nothing returns nothing
local AC dat
local integer i = 0
loop
exitwhen i == Totalx
set dat = Datax[i]
set dat.time = dat.time + 1
if dat.direction then
set dat.height = dat.height - ACCELERATION*dat.time
call SetUnitPosition(dat.v,dat.x,dat.y)
call SetUnitFlyHeight(dat.v,dat.height,0)
else
set dat.height = dat.height + ACCELERATION*(20.00 - dat.time)
call SetUnitPosition(dat.v,dat.x,dat.y)
call SetUnitFlyHeight(dat.v,dat.height,0)
if dat.height >= 600 then
set dat.direction = true
set dat.time = 0
endif
endif
if dat.height <= 0 then
if SPE then
call DestroyEffect(AddSpecialEffect(SPLASH, GetUnitX(dat.v), GetUnitY(dat.v)))
endif
call UnitDamageTarget(dat.u,dat.v, dat.level*DAMAGER, false, false, ATYPE, DTYPE, WEAPON_TYPE_WHOKNOWS)
set dat.u = null
set dat.v = null
call dat.destroy()
set Totalx = Totalx - 1
set Datax[i] = Datax[Totalx]
set i = i - 1
endif
set i = i + 1
endloop
if Totalx == 0 then
call PauseTimer(tx)
endif
endmethod
endstruct
private function Aqua_Check takes nothing returns boolean
return GetSpellAbilityId() == SPELL
endfunction
private function Aqua_Start takes nothing returns nothing
local integer i = 0
local unit a = GetTriggerUnit()
local real x = GetSpellTargetX()
local real y = GetSpellTargetY()
loop
exitwhen i == 12
call AC.create(x,y,GetOwningPlayer(a), i*30*.017453292, GetUnitAbilityLevel(a, SPELL), a)
set i = i + 1
endloop
set a = null
endfunction
private function Aqua_Init takes nothing returns nothing
local trigger Aqua = CreateTrigger( )
call TriggerAddAction( Aqua, function Aqua_Start )
call TriggerAddCondition(Aqua, function Aqua_Check)
call TriggerRegisterAnyUnitEventBJ(Aqua, EVENT_PLAYER_UNIT_SPELL_EFFECT)
endfunction
endscope