- Joined
- May 31, 2019
- Messages
- 150
Hi. I've noticed a reproducible crash in my Zerg Campaign. I've been able to get it to occur consistently in Chapter Four, if the player expands to the center of the map, where Maiev starts.
After fiddling with it, the source seems to be my modified Blizzard.j, in the function called SC_Larva_Pull
This function is only ever called by SC_Larva_Create, which determines where the larva will go relative to its parent hatchery before calling the above function to actually place it.
Normally, the Hatchery/Larva mechanic works 100% of the time without any issues. I ran a test map that auto-builds >100 hatcheries all over the place just to make sure there was no limit I was hitting somewhere, and no crash or other problem occurred.
I've only been able to experience a crash in Ch.4 of the Zerg Campaign, when expanding to that center gold mine, regardless of how many other hatcheries were on the map. After commenting out various lines of the above functions to narrow it down, I've found that commenting out the lines
So my guess is there's something the game doesn't like about Larvae being placed at certain positions, but alas I'm totally stumped about what it could be. So I'm just writing this thread in case someone wants to try to tinker with it. It's baffling to me, but probably some peoples' gameplay experience has been negatively impacted by it, so it would be nice to get to the bottom of this if possible.
EDIT: Looks like this is solved, or at least I have not experienced the crash since making the changes in the follow-up post.
JASS:
// LARVA - PULL FROM REPOSITORY
//===========================================================================
function SC_Larva_Pull takes integer playerId, integer hatcheryId, real x, real y returns nothing
local boolean hiddenLarvaExists = CountUnitsInGroup(sc_array_larva_playerHiddenGrp[playerId]) > 0
local player thisPlayer = Player(playerId)
local unit thisLarva = null
local boolean debugThis = false
if hiddenLarvaExists then
set thisLarva = FirstOfGroup(sc_array_larva_playerHiddenGrp[playerId])
// In the GUI version, there as a check here for if the larva is alive... not sure it's needed?
call SetUnitPosition(thisLarva, x, y)
call ShowUnit(thisLarva, true)
call SetUnitFacingTimed(thisLarva, GetRandomReal(0, 360), 0)
//call SetUnitAnimation(thisLarva, "stand")
call SetUnitAnimation(thisLarva, "birth")
call QueueUnitAnimation(thisLarva, "stand")
call GroupRemoveUnit(sc_array_larva_playerHiddenGrp[playerId], thisLarva)
if debugThis then
call DisplayTextToPlayer(Player(playerId), 0, 0, "Larva pulled from repo")
endif
else
// Existing larva not found, create a new one
set thisLarva = CreateUnit(Player(playerId), sc_ZERG_LARVA, x, y, GetRandomReal(0, 360))
if debugThis then
call DisplayTextToPlayer(Player(playerId), 0, 0, "Larva created since repo was empty")
endif
endif
if sc_array_larva_hatcheryGrp[hatcheryId] == null then
set sc_array_larva_hatcheryGrp[hatcheryId] = CreateGroup()
endif
if sc_array_larva_playerGrp[playerId] == null then
set sc_array_larva_playerGrp[playerId] = CreateGroup()
endif
call GroupAddUnit(sc_array_larva_hatcheryGrp[hatcheryId], thisLarva)
call GroupAddUnit(sc_array_larva_playerGrp[playerId], thisLarva)
call UnitRemoveAbility(thisLarva, sc_ABIL_RALLY)
call SetUnitLifePercentBJ(thisLarva, 100)
call SetUnitUserData(thisLarva, hatcheryId)
// Fail-safe in case for whatever reason the larva belongs to the wrong player
if GetOwningPlayer(thisLarva) != thisPlayer then
call SetUnitOwner(thisLarva, thisPlayer, true)
endif
// Clear leak
set thisPlayer = null
set thisLarva = null
endfunction
This function is only ever called by SC_Larva_Create, which determines where the larva will go relative to its parent hatchery before calling the above function to actually place it.
JASS:
// LARVA - CREATE
//===========================================================================
function SC_Larva_Create takes integer hatcheryId returns nothing
local integer playerId = 0
local integer larvaCount = CountUnitsInGroup(sc_array_larva_hatcheryGrp[hatcheryId])
local real hatcheryX = 0.00
local real hatcheryY = 0.00
local real larvaAngle = 0.00
local real larvaX = 0.00
local real larvaY = 0.00
local boolean debugThis = false
if debugThis then
//call DisplayTextToPlayer(Player(playerId), 0, 0, "Hatchery #" + I2S(hatcheryId) + " currently has " + I2S(larvaCount) + " larva.")
endif
if larvaCount >= sc_INT_HATCHERY_MAX_LARVA then
return
endif
set playerId = GetPlayerId(GetOwningPlayer(bribe_UDexUnits[hatcheryId]))
set hatcheryX = GetUnitX(bribe_UDexUnits[hatcheryId])
set hatcheryY = GetUnitY(bribe_UDexUnits[hatcheryId])
set larvaAngle = GetRandomReal(sc_REAL_LARVA_SPAWN_ANGLE_MIN, sc_REAL_LARVA_SPAWN_ANGLE_MAX)
set larvaX = PolarProjectionX(hatcheryX, sc_REAL_LARVA_SPAWN_DISTANCE, larvaAngle)
set larvaY = PolarProjectionY(hatcheryY, sc_REAL_LARVA_SPAWN_DISTANCE, larvaAngle)
if debugThis then
//call DisplayTextToPlayer(Player(playerId), 0, 0, "Hatchery #" + I2S(hatcheryId) + " is pulling a new larva.")
endif
call SC_Larva_Pull(playerId, hatcheryId, larvaX, larvaY)
if debugThis then
//call DisplayTextToPlayer(Player(playerId), 0, 0, "Hatchery #" + I2S(hatcheryId) + " currently has " + I2S(larvaCount) + " larva.")
endif
endfunction
Normally, the Hatchery/Larva mechanic works 100% of the time without any issues. I ran a test map that auto-builds >100 hatcheries all over the place just to make sure there was no limit I was hitting somewhere, and no crash or other problem occurred.
call SetUnitPosition(thisLarva, x, y)
and set thisLarva = CreateUnit(Player(playerId), sc_ZERG_LARVA, x, y, GetRandomReal(0, 360))
from SC_Larva_Pull()
prevents the crash, but of course also disables Larvae.So my guess is there's something the game doesn't like about Larvae being placed at certain positions
EDIT: Looks like this is solved, or at least I have not experienced the crash since making the changes in the follow-up post.
Last edited: