- Joined
- Jan 9, 2005
- Messages
- 2,131
I'm trying to make an activateable/deactivateable spell that heals 3 units for 0.30 hit points every 0.03 seconds. I've managed to pull it off, but the spell is not MUI and bugs out when two units casts it. It drains mana until it reaches 0 or spell is deactivated. No two units can be healed by this spell at the same time.
This is what it looks like:
There are two suspected culprits to this issue:
1) loop within loops; the last time I tried having loops within an existing loop, the spell I was trying to make failed, so I've guessing a similar thing may be happening here.
2) 2D array: I used 2D array to identify what unit is being healed by what healer. Idk if I did it right though.
Any help anyone can give would be welcome.
This is what it looks like:
-
Reconstruction Beam OnActivate
-
Events
-
Unit - A unit Starts the effect of an ability
-
-
Conditions
-
Or - Any (Conditions) are true
-
Conditions
-
(Ability being cast) Equal to Reconstruction Beam ON
-
(Ability being cast) Equal to Reconstruction Beam OFF
-
-
-
-
Actions
-
Set ID_1 = (Custom value of (Triggering unit))
-
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
-
If - Conditions
-
(Ability being cast) Equal to Reconstruction Beam ON
-
-
Then - Actions
-
Set RecBeam_MaxTargets[ID_1] = 4
-
Set RecBeam_MaxDistance[ID_1] = 450.00
-
Unit Group - Add (Triggering unit) to RecBeam_Group
-
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
-
If - Conditions
-
(Reconstruction Beam OnLoop <gen> is on) Equal to False
-
-
Then - Actions
-
Trigger - Turn on Reconstruction Beam OnLoop <gen>
-
-
Else - Actions
-
-
Unit - Remove (Ability being cast) from (Triggering unit)
-
Unit - Add Reconstruction Beam OFF to (Triggering unit)
-
-
Else - Actions
-
Set RecBeam_RecBeamOff[ID_1] = True
-
Unit - Remove (Ability being cast) from (Triggering unit)
-
Unit - Add Reconstruction Beam ON to (Triggering unit)
-
-
-
-
JASS:
function Trig_Reconstruction_Beam_OnLoop_Actions takes nothing returns nothing
local unit MC = null
local unit u = null
local unit array ViableTargets
local integer id = 0
local integer UnitID = 0
local integer uIndex = 0
local integer LoopCount = 0
local integer RandomIndex = 0
local real x1 = 0.00
local real y1 = 0.00
local real z1 = 0.00
local real x2 = 0.00
local real y2 = 0.00
local real z2 = 0.00
local real dx = 0.00
local real dy = 0.00
//local real angle = 0.00
local real dist = 0.00
local real UnitLife = 0.00
local real HealAmount = 0.30
loop
set MC = FirstOfGroup(udg_RecBeam_Group)
exitwhen MC == null
set id = GetUnitUserData(MC)
call GroupRemoveUnit(udg_RecBeam_Group, MC)
if not udg_RecBeam_RecBeamOff[id] then
call GroupAddUnit(udg_RecBeam_GroupTemp, MC)
endif
set x1 = GetUnitX(MC)
set y1 = GetUnitY(MC)
set z1 = GetUnitFlyHeight(MC) + 30
loop // One MC can heal multiple units at the same time. This is what this loop is for.
set LoopCount = LoopCount + 1
exitwhen LoopCount >= udg_RecBeam_MaxTargets[id]
//set UnitID = id * udg_RecBeam_MaxTargets[id] + LoopCount
set UnitID = id * 4 + LoopCount
set x2 = GetUnitX(udg_RecBeam_CurrentTarget[UnitID])
set y2 = GetUnitY(udg_RecBeam_CurrentTarget[UnitID])
set z2 = GetUnitFlyHeight(udg_RecBeam_CurrentTarget[UnitID]) + 60
if udg_RecBeam_CurrentTarget[UnitID] == null then
call GroupEnumUnitsInRange(udg_RecBeam_EnumGroup, x1, y1, udg_RecBeam_MaxDistance[id], null)
if FirstOfGroup(udg_RecBeam_EnumGroup) != null then
loop // This loop filters out undesireable units. Alternatively, make a filter function somewhere to use with the GroupEnumUnitsInRange
set u = FirstOfGroup(udg_RecBeam_EnumGroup)
exitwhen u == null
call GroupRemoveUnit(udg_RecBeam_EnumGroup, u)
set uIndex = GetUnitUserData(u)
set UnitLife = GetUnitState(u, UNIT_STATE_MAX_LIFE)
if IsUnitAlly(u, GetOwningPlayer(MC)) and GetUnitState(u, UNIT_STATE_LIFE) < UnitLife and GetUnitState(u, UNIT_STATE_LIFE) > 0.00 /*
*/ and IsUnitType(u, UNIT_TYPE_MECHANICAL) and not IsUnitType(u, UNIT_TYPE_STRUCTURE) and u != MC and not udg_RecBeam_IsBeingHealed[uIndex] then
set RandomIndex = RandomIndex + 1
set ViableTargets[RandomIndex] = u
endif
endloop
if RandomIndex > 0 then // this picks a random unit within the viable pool of pre-selected units
set udg_RecBeam_CurrentTarget[UnitID] = ViableTargets[GetRandomInt(1, RandomIndex)]
set uIndex = GetUnitUserData(udg_RecBeam_CurrentTarget[UnitID])
set udg_RecBeam_IsBeingHealed[uIndex] = true
set udg_RecBeam_Caster[UnitID] = CreateUnit(GetOwningPlayer(MC), 'dumm', x1, y1, 0)
set udg_RecBeam_Mover[UnitID] = CreateUnit(GetOwningPlayer(MC), 'dumm', x2, y2, 0)
call PauseUnit(udg_RecBeam_Caster[UnitID], true)
call PauseUnit(udg_RecBeam_Mover[UnitID], true)
call UnitAddAbility(udg_RecBeam_Caster[UnitID], 'pbct')
call UnitAddAbility(udg_RecBeam_Mover[UnitID], 'pbct')
set udg_RecBeam_LightningFX[UnitID] = AddLightningEx("GRSB", true, x1, y2, z1, x2, y2, z2)
call SetLightningColor(udg_RecBeam_LightningFX[UnitID], 0.20, 0.20, 1.00, 1.00)
loop // this clears ViableTargets[RandomIndex]
exitwhen RandomIndex == 0
set ViableTargets[RandomIndex] = null
set RandomIndex = RandomIndex - 1
endloop
endif
endif
else
set dx = x2 - x1
set dy = y2 - y1
set dist = SquareRoot(dx*dx + dy*dy) // this is necessary to see if the unit has gone out of healing range
call SetUnitPosition(udg_RecBeam_Caster[UnitID], x1, y1)
call SetUnitFlyHeight(udg_RecBeam_Caster[UnitID], z1, 0.00)
call SetUnitPosition(udg_RecBeam_Mover[UnitID], x2, y2)
call SetUnitFlyHeight(udg_RecBeam_Mover[UnitID], z2, 0.00)
if udg_RecBeam_LightningFX[UnitID] != null then
call MoveLightningEx(udg_RecBeam_LightningFX[UnitID], true, x1, y1, z1, x2, y2, z2)
endif
set UnitLife = GetUnitState(udg_RecBeam_CurrentTarget[UnitID], UNIT_STATE_LIFE)
if UnitLife >= GetUnitState(udg_RecBeam_CurrentTarget[UnitID], UNIT_STATE_MAX_LIFE) or UnitLife <= 0.00 or dist > udg_RecBeam_MaxDistance[id] or udg_RecBeam_RecBeamOff[id] then
set uIndex = GetUnitUserData(udg_RecBeam_CurrentTarget[UnitID])
set udg_RecBeam_IsBeingHealed[uIndex] = false
set udg_RecBeam_CurrentTarget[UnitID] = null
//unpause the mover and caster and kill them
call PauseUnit(udg_RecBeam_Caster[UnitID], false)
call PauseUnit(udg_RecBeam_Mover[UnitID], false)
call UnitApplyTimedLife(udg_RecBeam_Mover[UnitID], 'BTLF', 0.01)
call UnitApplyTimedLife(udg_RecBeam_Caster[UnitID], 'BTLF', 0.01)
// if there is a lightning fx, destroy it. This is also a precaution as destroying a null lightning variable will crash the game. I think...
// replacing a non-null lightning with another one does crash the game for sure though.
if udg_RecBeam_LightningFX[UnitID] != null then
call DestroyLightning(udg_RecBeam_LightningFX[UnitID])
set udg_RecBeam_LightningFX[UnitID] = null
endif
else
call SetUnitState(udg_RecBeam_CurrentTarget[UnitID], UNIT_STATE_LIFE, UnitLife + HealAmount)
call SetUnitState(MC, UNIT_STATE_MANA, GetUnitState(MC, UNIT_STATE_MANA) - 0.06)
if GetUnitState(MC, UNIT_STATE_MANA) <= 0.1 then
//call IssueImmediateOrder(MC, "channel")
set udg_RecBeam_RecBeamOff[id] = true
call UnitRemoveAbility(MC, 'trbd')
call UnitAddAbility(MC, 'trba')
endif
endif
endif
endloop
endloop
if udg_RecBeam_RecBeamOff[id] == true then
set udg_RecBeam_RecBeamOff[id] = false
endif
loop
set MC = FirstOfGroup(udg_RecBeam_GroupTemp)
exitwhen MC == null
call GroupRemoveUnit(udg_RecBeam_GroupTemp, MC)
call GroupAddUnit(udg_RecBeam_Group, MC)
endloop
if FirstOfGroup(udg_RecBeam_Group) == null then
call DisableTrigger(GetTriggeringTrigger())
endif
endfunction
//===========================================================================
function InitTrig_Reconstruction_Beam_OnLoop takes nothing returns nothing
set gg_trg_Reconstruction_Beam_OnLoop = CreateTrigger( )
call DisableTrigger( gg_trg_Reconstruction_Beam_OnLoop )
call TriggerRegisterTimerEvent( gg_trg_Reconstruction_Beam_OnLoop, 0.03, true )
call TriggerAddAction( gg_trg_Reconstruction_Beam_OnLoop, function Trig_Reconstruction_Beam_OnLoop_Actions )
endfunction
There are two suspected culprits to this issue:
1) loop within loops; the last time I tried having loops within an existing loop, the spell I was trying to make failed, so I've guessing a similar thing may be happening here.
2) 2D array: I used 2D array to identify what unit is being healed by what healer. Idk if I did it right though.
Any help anyone can give would be welcome.
Attachments
Last edited: