- Joined
- Oct 16, 2008
- Messages
- 10,454
The code below works completely fine as as intended but for some unknown reason, after I cast it for a large amount of time my wc3 crashes.. I'm thinking there might be some leaks that I hadn't clean so maybe someone can see what leaks there still are or some other problems that may cause the fatal error. Thanks!
BTW, is it okay to have 2 scopes with the same set of private globals?
JASS:
///////////////////////////////////////////////////
// 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
private constant string WATER = "Objects\\Spawnmodels\\Naga\\NagaDeath\\NagaDeath.mdl" //The path to the explosion effect
private constant real AOE = 150 //The radius of the spell
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 constant real LIFTSPEED = 20 //The rate at which units get thrown up/down
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 boolean SE = false //If true, there will be an explosion effect
private 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.
//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()
endglobals
private struct AC
real x
real y
real distance
real facing
unit u
real height
effect wave
player owner
unit v
integer level
boolean direction = false
static method create takes real x, real y, player p, real facing, integer level returns AC
local AC dat = AC.allocate()
set Data[Total] = dat
set dat.x = x - RANGE*Cos(facing*bj_DEGTORAD)
set dat.y = y - RANGE*Sin(facing*bj_DEGTORAD)
set dat.u = CreateUnit(p, DUMMY, dat.x, dat.y, facing)
set dat.distance = RANGE
set dat.owner = p
set dat.level = level
set dat.facing = facing*bj_DEGTORAD
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, this.y - AOE, this.x + AOE, this.y + AOE)
//if TREE then
//call EnumDestructablesInRect(r, null, function Dest)
//endif
call DestroyEffect(this.wave)
call KillUnit(this.u)
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, 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.u, 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 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()
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 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]
if dat.direction then
set dat.height = dat.height - LIFTSPEED
call SetUnitPosition(dat.v,dat.x,dat.y)
call SetUnitFlyHeight(dat.v,dat.height,0)
else
set dat.height = dat.height + LIFTSPEED
call SetUnitPosition(dat.v,dat.x,dat.y)
call SetUnitFlyHeight(dat.v,dat.height,0)
if dat.height >= 600 then
set dat.direction = true
endif
endif
if dat.height == 0 then
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
function Aqua_Check takes nothing returns boolean
return GetSpellAbilityId() == SPELL
endfunction
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), GetUnitAbilityLevel(a, SPELL))
set i = i + 1
endloop
set a = null
endfunction
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
BTW, is it okay to have 2 scopes with the same set of private globals?