- Joined
- Sep 25, 2005
- Messages
- 71
Well, more experimentation, more problems. This time I was trying follow instructions to create abilities that are pretty much instanced in individual structs and methods. I think I screwed up to be honest.
The spell in question is supposed to make a cone of lightning balls, linked by lightning effects. The balls are supposed to do damage when they connect with an enemy and have large enough collision that even at full distance, the "beams" appear to do damage as well.
Multiple instances of this spell being cast cause the game to outright crash. Single casts work fine. I also tried to set a sort of GroupEnum loop (to deal damage) inside the "move" loop that iterates through each "ball" and moves each lightning, but that somehow just completely stopped whatever was going on and one ball would just wander off, forever moving against the border of the map.
For reference, the loop I was trying:
The "SetBoundedX/Y" functions are literally just functions meant to keep it within playable map area.
If someone has a solution or improvements/optimizations to this, feel free to peep at me.
The spell in question is supposed to make a cone of lightning balls, linked by lightning effects. The balls are supposed to do damage when they connect with an enemy and have large enough collision that even at full distance, the "beams" appear to do damage as well.
Multiple instances of this spell being cast cause the game to outright crash. Single casts work fine. I also tried to set a sort of GroupEnum loop (to deal damage) inside the "move" loop that iterates through each "ball" and moves each lightning, but that somehow just completely stopped whatever was going on and one ball would just wander off, forever moving against the border of the map.
For reference, the loop I was trying:
JASS:
loop
exitwhen enemy == null
set enemy = FirstOfGroup(LightningConeEnumGroup)
if IsUnitEnemy(enemy, GetOwningPlayer(localLightningCone.caster)) == true and IsUnitAliveBJ(enemy) == true then
call UnitDamageTarget(GetTriggerUnit(), enemy, 125., true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_FIRE, null)
endif
call GroupRemoveUnit(LightningConeEnumGroup, enemy)
endloop
The "SetBoundedX/Y" functions are literally just functions meant to keep it within playable map area.
JASS:
globals
timer LightningConeTimer = CreateTimer()
real LightningConeInterval = .012
real LightningConeSpeed = 12
integer LightningConeInstances = 0
group LightningConeEnumGroup = CreateGroup()
LightningConeData array LightningConeArray
endglobals
struct LightningConeData
unit caster
unit array balls[6]
player casterOwner
lightning array beams[5]
real distance
real maxDist
static method LightningConeExecution takes nothing returns nothing
local integer i = 0
local integer ballcount = 0
local unit enemy
local LightningConeData localLightningCone
loop
exitwhen i >= LightningConeInstances
set localLightningCone = LightningConeArray[i]
if localLightningCone.distance < localLightningCone.maxDist then
loop
exitwhen ballcount == 6
call MoveUnit(localLightningCone.balls[ballcount], LightningConeSpeed, GetUnitFacing(localLightningCone.balls[ballcount]))
if ballcount != 0 then
call MoveLightning(localLightningCone.beams[ballcount], true, GetUnitX(localLightningCone.balls[ballcount-1]), GetUnitY(localLightningCone.balls[ballcount-1]), GetUnitX(localLightningCone.balls[ballcount]), GetUnitY(localLightningCone.balls[ballcount]))
endif
set ballcount = ballcount + 1
endloop
set localLightningCone.distance = localLightningCone.distance + LightningConeSpeed
endif
if localLightningCone.distance >= localLightningCone.maxDist then
set LightningConeInstances = LightningConeInstances - 1
set LightningConeArray[i] = LightningConeArray[LightningConeInstances]
call localLightningCone.destroy()
endif
set i = i + 1
endloop
if LightningConeInstances == 0 then
call PauseTimer(LightningConeTimer)
endif
endmethod
static method create takes unit whichUnit, real speed, real range returns LightningConeData
local integer i = 0
local real facing = GetUnitFacing(whichUnit) + 30.
local LightningConeData data = LightningConeData.allocate()
set data.caster = whichUnit
set data.casterOwner = GetOwningPlayer(data.caster)
set data.distance = speed
set data.maxDist = range
loop
exitwhen i == 6
set data.balls[i] = CreateUnit(data.casterOwner, 'o002', GetUnitX(data.caster), GetUnitY(data.caster), (facing - (10 * i)))
if i != 0 then
set data.beams[i] = AddLightning("FORK", true, GetUnitX(data.balls[i-1]), GetUnitY(data.balls[i-1]), GetUnitX(data.balls[i]), GetUnitY(data.balls[i]))
endif
set i = i + 1
endloop
if LightningConeInstances <= 0 then
call TimerStart(LightningConeTimer, LightningConeInterval, true, function LightningConeData.LightningConeExecution)
endif
set LightningConeArray[LightningConeInstances] = data
set LightningConeInstances = LightningConeInstances + 1
return data
endmethod
method onDestroy takes nothing returns nothing
local integer i = 0
loop
exitwhen i == 6
call KillUnit(.balls[i])
set i = i + 1
endloop
set i = 0
loop
exitwhen i == 6
call DestroyLightning(.beams[i])
set i = i + 1
endloop
endmethod
endstruct
function LightningCone takes nothing returns nothing
local integer i = 0
local LightningConeData localLightningCone = LightningConeData.create(GetTriggerUnit(), 25., 900.)
endfunction
//====================================/ Condition /====================================================
function checkLightningCone takes nothing returns boolean
if GetSpellAbilityId() == 'A006' then
call LightningCone()
endif
return false
endfunction
//======================================/ Init /========================================================
function InitTrig_Lightning_Cone takes nothing returns nothing
local trigger localTrigVar = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(localTrigVar, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition( localTrigVar, Condition(function checkLightningCone))
set localTrigVar = null
endfunction
If someone has a solution or improvements/optimizations to this, feel free to peep at me.