Skip to content

Commit 6c91196

Browse files
committed
Fixed crash due to missing implied squad existence check
1 parent bc22ce2 commit 6c91196

File tree

3 files changed

+41
-31
lines changed

3 files changed

+41
-31
lines changed

Optional Features/#1. (Choose From This Folder First)/No Enemy Map Spots/gamedata/scripts/sim_squad_generic.script

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ local monster_num_by_resource = {
2323

2424
local math_random = math.random
2525
local math_ceil = math.ceil
26+
local table_remove = table.remove
2627

2728
class "sim_squad_generic"
2829

@@ -542,25 +543,27 @@ local function pave_way_off_smart(board, front, archive)
542543
local num_front = #front
543544
for i = 1, num_front do
544545
local front_smart = front[i]
546+
local front_smart_owner = front_smart.owner
545547
for neighbor_smart_id, neighbor_smart in pairs (board:get_nearest_smarts(front_smart.smart)) do
546-
if archive[neighbor_smart_id] == nil and sim_board.is_point_avail(neighbor_smart, front_smart.owner) then
548+
if front_smart_owner ~= "none" and archive[neighbor_smart_id] == nil and sim_board.is_point_avail(neighbor_smart, front_smart_owner) then
547549
archive[neighbor_smart_id] = true
548550
local neighbor_smart_owner = neighbor_smart.player_name
549551
local friends_at_neighbor
550-
if neighbor_smart_owner == "none" or game_relations.is_factions_enemies(front_smart.owner, neighbor_smart_owner) then
551-
friends_at_neighbor = board:get_smart_squad_quantity(neighbor_smart, board.players[front_smart.owner])
552-
elseif neighbor_smart_owner == front_smart.owner then
553-
friends_at_neighbor = board:get_smart_squad_quantity(neighbor_smart, board.players[front_smart.owner]) + board:get_smart_population(neighbor_smart)
552+
if neighbor_smart_owner == "none" or game_relations.is_factions_enemies(front_smart_owner, neighbor_smart_owner) then
553+
friends_at_neighbor = board:get_smart_squad_quantity(neighbor_smart, board.players[front_smart_owner])
554+
elseif neighbor_smart_owner == front_smart_owner then
555+
friends_at_neighbor = board:get_smart_squad_quantity(neighbor_smart, board.players[front_smart_owner]) + board:get_smart_population(neighbor_smart)
554556
end
555557
if friends_at_neighbor ~= nil then
556558
if friends_at_neighbor < neighbor_smart.squad_capacity then
557559
local step, step_target_id, step_target = front_smart, neighbor_smart_id, neighbor_smart
558560
local sim_avail_table = {}
559561
while step ~= nil do
560562
local step_squad = step.squad
561-
sim_avail_table[step.smart_id] = {step.smart, step.smart.sim_avail}
562-
-- dbglog("Booting squad '%s' from smart '%s' with population %d, friendly movers %d, and sim_avail [%s] to smart '%s' with population %d and friendly movers %d", step_squad.squad_id, smart_names.get_smart_terrain_name(step.smart), board:get_smart_population(step.smart), board:get_smart_squad_quantity(step.smart, board.players[step_squad.player_id]), tostring(step.smart.sim_avail), smart_names.get_smart_terrain_name(step_target), board:get_smart_population(step_target), board:get_smart_squad_quantity(step_target, board.players[step_squad.player_id]))
563-
step.smart.sim_avail = {{section = "false", infop_check = {}, infop_set = {}}} -- pseudo-hack to temporarily make the smart left by step_squad unavailable for unwanted visitors in case a race condition would otherwise send them there
563+
local step_smart = step.smart
564+
sim_avail_table[step.smart_id] = {step_smart, step_smart.sim_avail}
565+
-- dbglog("Booting squad '%s' from smart '%s' with population %d, friendly movers %d, and sim_avail [%s] to smart '%s' with population %d and friendly movers %d", step_squad.squad_id, smart_names.get_smart_terrain_name(step_smart), board:get_smart_population(step_smart), board:get_smart_squad_quantity(step_smart, board.players[step_squad.player_id]), tostring(step_smart.sim_avail), smart_names.get_smart_terrain_name(step_target), board:get_smart_population(step_target), board:get_smart_squad_quantity(step_target, board.players[step_squad.player_id]))
566+
step_smart.sim_avail = {{section = "false", infop_check = {}, infop_set = {}}} -- pseudo-hack to temporarily make the smart left by step_squad unavailable for unwanted visitors in case a race condition would otherwise send them there
564567
--[[
565568
-- TODO: Is this necessary? Maybe e.g. if step_squad is in combat when booted off their smart...
566569
-- Update: Nope. Combat manager unregistration is done in sim_attack_point:make() if necessary, and step_squad.current_action is guaranteed to be nil or sim_stay_point, which doesn't need finalization. TODO: Check: Also, not necessary to set current_action to nil from sim_stay_point.
@@ -574,7 +577,7 @@ local function pave_way_off_smart(board, front, archive)
574577
]]
575578
step_squad.current_action = sim_attack_point(step_squad, step_target_id, true)
576579
step_squad.current_action:make()
577-
step, step_target_id, step_target = step.prev, step.smart_id, step.smart
580+
step, step_target_id, step_target = step.prev, step.smart_id, step_smart
578581
end
579582
for k, smart_data in pairs (sim_avail_table) do
580583
-- dbglog("Reinstating sim_avail setting for smart '%s' to [%s]", smart_names.get_smart_terrain_name(smart_data[1]), tostring(smart_data[2]))
@@ -593,7 +596,7 @@ local function pave_way_off_smart(board, front, archive)
593596
end
594597
end
595598
for i = 1, num_front do
596-
table.remove(front, 1)
599+
table_remove(front, 1)
597600
end
598601
if #front == 0 then
599602
-- dbglog("Algorithm failed to unblock faction war!")

Optional Features/#2. (Choose From This Folder Last)/Show Only Ally Map Spots/gamedata/scripts/sim_squad_generic.script

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ local monster_num_by_resource = {
2323

2424
local math_random = math.random
2525
local math_ceil = math.ceil
26+
local string_sub = string.sub
27+
local table_remove = table.remove
2628

2729
class "sim_squad_generic"
2830

@@ -542,25 +544,27 @@ local function pave_way_off_smart(board, front, archive)
542544
local num_front = #front
543545
for i = 1, num_front do
544546
local front_smart = front[i]
547+
local front_smart_owner = front_smart.owner
545548
for neighbor_smart_id, neighbor_smart in pairs (board:get_nearest_smarts(front_smart.smart)) do
546-
if archive[neighbor_smart_id] == nil and sim_board.is_point_avail(neighbor_smart, front_smart.owner) then
549+
if front_smart_owner ~= "none" and archive[neighbor_smart_id] == nil and sim_board.is_point_avail(neighbor_smart, front_smart_owner) then
547550
archive[neighbor_smart_id] = true
548551
local neighbor_smart_owner = neighbor_smart.player_name
549552
local friends_at_neighbor
550-
if neighbor_smart_owner == "none" or game_relations.is_factions_enemies(front_smart.owner, neighbor_smart_owner) then
551-
friends_at_neighbor = board:get_smart_squad_quantity(neighbor_smart, board.players[front_smart.owner])
552-
elseif neighbor_smart_owner == front_smart.owner then
553-
friends_at_neighbor = board:get_smart_squad_quantity(neighbor_smart, board.players[front_smart.owner]) + board:get_smart_population(neighbor_smart)
553+
if neighbor_smart_owner == "none" or game_relations.is_factions_enemies(front_smart_owner, neighbor_smart_owner) then
554+
friends_at_neighbor = board:get_smart_squad_quantity(neighbor_smart, board.players[front_smart_owner])
555+
elseif neighbor_smart_owner == front_smart_owner then
556+
friends_at_neighbor = board:get_smart_squad_quantity(neighbor_smart, board.players[front_smart_owner]) + board:get_smart_population(neighbor_smart)
554557
end
555558
if friends_at_neighbor ~= nil then
556559
if friends_at_neighbor < neighbor_smart.squad_capacity then
557560
local step, step_target_id, step_target = front_smart, neighbor_smart_id, neighbor_smart
558561
local sim_avail_table = {}
559562
while step ~= nil do
560563
local step_squad = step.squad
561-
sim_avail_table[step.smart_id] = {step.smart, step.smart.sim_avail}
562-
-- dbglog("Booting squad '%s' from smart '%s' with population %d, friendly movers %d, and sim_avail [%s] to smart '%s' with population %d and friendly movers %d", step_squad.squad_id, smart_names.get_smart_terrain_name(step.smart), board:get_smart_population(step.smart), board:get_smart_squad_quantity(step.smart, board.players[step_squad.player_id]), tostring(step.smart.sim_avail), smart_names.get_smart_terrain_name(step_target), board:get_smart_population(step_target), board:get_smart_squad_quantity(step_target, board.players[step_squad.player_id]))
563-
step.smart.sim_avail = {{section = "false", infop_check = {}, infop_set = {}}} -- pseudo-hack to temporarily make the smart left by step_squad unavailable for unwanted visitors in case a race condition would otherwise send them there
564+
local step_smart = step.smart
565+
sim_avail_table[step.smart_id] = {step_smart, step_smart.sim_avail}
566+
-- dbglog("Booting squad '%s' from smart '%s' with population %d, friendly movers %d, and sim_avail [%s] to smart '%s' with population %d and friendly movers %d", step_squad.squad_id, smart_names.get_smart_terrain_name(step_smart), board:get_smart_population(step_smart), board:get_smart_squad_quantity(step_smart, board.players[step_squad.player_id]), tostring(step_smart.sim_avail), smart_names.get_smart_terrain_name(step_target), board:get_smart_population(step_target), board:get_smart_squad_quantity(step_target, board.players[step_squad.player_id]))
567+
step_smart.sim_avail = {{section = "false", infop_check = {}, infop_set = {}}} -- pseudo-hack to temporarily make the smart left by step_squad unavailable for unwanted visitors in case a race condition would otherwise send them there
564568
--[[
565569
-- TODO: Is this necessary? Maybe e.g. if step_squad is in combat when booted off their smart...
566570
-- Update: Nope. Combat manager unregistration is done in sim_attack_point:make() if necessary, and step_squad.current_action is guaranteed to be nil or sim_stay_point, which doesn't need finalization. TODO: Check: Also, not necessary to set current_action to nil from sim_stay_point.
@@ -574,7 +578,7 @@ local function pave_way_off_smart(board, front, archive)
574578
]]
575579
step_squad.current_action = sim_attack_point(step_squad, step_target_id, true)
576580
step_squad.current_action:make()
577-
step, step_target_id, step_target = step.prev, step.smart_id, step.smart
581+
step, step_target_id, step_target = step.prev, step.smart_id, step_smart
578582
end
579583
for k, smart_data in pairs (sim_avail_table) do
580584
-- dbglog("Reinstating sim_avail setting for smart '%s' to [%s]", smart_names.get_smart_terrain_name(smart_data[1]), tostring(smart_data[2]))
@@ -593,7 +597,7 @@ local function pave_way_off_smart(board, front, archive)
593597
end
594598
end
595599
for i = 1, num_front do
596-
table.remove(front, 1)
600+
table_remove(front, 1)
597601
end
598602
if #front == 0 then
599603
-- dbglog("Algorithm failed to unblock faction war!")
@@ -1314,7 +1318,7 @@ function sim_squad_generic:refresh()
13141318
return
13151319
end
13161320
local actor = db.actor
1317-
local actor_faction = string.sub(actor and actor:character_community() or alife():actor():community(), 7) -- actor faction always named 'actor_*', so to match '*', get sub-string from index 7
1321+
local actor_faction = string_sub(actor and actor:character_community() or alife():actor():community(), 7) -- actor faction always named 'actor_*', so to match '*', get sub-string from index 7
13181322
if self.player_id ~= actor_faction then
13191323
self:show_mini_only()
13201324
return

gamedata/scripts/sim_squad_generic.script

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ local monster_num_by_resource = {
2323

2424
local math_random = math.random
2525
local math_ceil = math.ceil
26+
local table_remove = table.remove
2627

2728
class "sim_squad_generic"
2829

@@ -544,25 +545,27 @@ local function pave_way_off_smart(board, front, archive)
544545
local num_front = #front
545546
for i = 1, num_front do
546547
local front_smart = front[i]
548+
local front_smart_owner = front_smart.owner
547549
for neighbor_smart_id, neighbor_smart in pairs (board:get_nearest_smarts(front_smart.smart)) do
548-
if archive[neighbor_smart_id] == nil and sim_board.is_point_avail(neighbor_smart, front_smart.owner) then
550+
if front_smart_owner ~= "none" and archive[neighbor_smart_id] == nil and sim_board.is_point_avail(neighbor_smart, front_smart_owner) then
549551
archive[neighbor_smart_id] = true
550552
local neighbor_smart_owner = neighbor_smart.player_name
551553
local friends_at_neighbor
552-
if neighbor_smart_owner == "none" or game_relations.is_factions_enemies(front_smart.owner, neighbor_smart_owner) then
553-
friends_at_neighbor = board:get_smart_squad_quantity(neighbor_smart, board.players[front_smart.owner])
554-
elseif neighbor_smart_owner == front_smart.owner then
555-
friends_at_neighbor = board:get_smart_squad_quantity(neighbor_smart, board.players[front_smart.owner]) + board:get_smart_population(neighbor_smart)
554+
if neighbor_smart_owner == "none" or game_relations.is_factions_enemies(front_smart_owner, neighbor_smart_owner) then
555+
friends_at_neighbor = board:get_smart_squad_quantity(neighbor_smart, board.players[front_smart_owner])
556+
elseif neighbor_smart_owner == front_smart_owner then
557+
friends_at_neighbor = board:get_smart_squad_quantity(neighbor_smart, board.players[front_smart_owner]) + board:get_smart_population(neighbor_smart)
556558
end
557559
if friends_at_neighbor ~= nil then
558560
if friends_at_neighbor < neighbor_smart.squad_capacity then
559561
local step, step_target_id, step_target = front_smart, neighbor_smart_id, neighbor_smart
560562
local sim_avail_table = {}
561563
while step ~= nil do
562564
local step_squad = step.squad
563-
sim_avail_table[step.smart_id] = {step.smart, step.smart.sim_avail}
564-
-- dbglog("Booting squad '%s' from smart '%s' with population %d, friendly movers %d, and sim_avail [%s] to smart '%s' with population %d and friendly movers %d", step_squad.squad_id, smart_names.get_smart_terrain_name(step.smart), board:get_smart_population(step.smart), board:get_smart_squad_quantity(step.smart, board.players[step_squad.player_id]), tostring(step.smart.sim_avail), smart_names.get_smart_terrain_name(step_target), board:get_smart_population(step_target), board:get_smart_squad_quantity(step_target, board.players[step_squad.player_id]))
565-
step.smart.sim_avail = {{section = "false", infop_check = {}, infop_set = {}}} -- pseudo-hack to temporarily make the smart left by step_squad unavailable for unwanted visitors in case a race condition would otherwise send them there
565+
local step_smart = step.smart
566+
sim_avail_table[step.smart_id] = {step_smart, step_smart.sim_avail}
567+
-- dbglog("Booting squad '%s' from smart '%s' with population %d, friendly movers %d, and sim_avail [%s] to smart '%s' with population %d and friendly movers %d", step_squad.squad_id, smart_names.get_smart_terrain_name(step_smart), board:get_smart_population(step_smart), board:get_smart_squad_quantity(step_smart, board.players[step_squad.player_id]), tostring(step_smart.sim_avail), smart_names.get_smart_terrain_name(step_target), board:get_smart_population(step_target), board:get_smart_squad_quantity(step_target, board.players[step_squad.player_id]))
568+
step_smart.sim_avail = {{section = "false", infop_check = {}, infop_set = {}}} -- pseudo-hack to temporarily make the smart left by step_squad unavailable for unwanted visitors in case a race condition would otherwise send them there
566569
--[[
567570
-- TODO: Is this necessary? Maybe e.g. if step_squad is in combat when booted off their smart...
568571
-- Update: Nope. Combat manager unregistration is done in sim_attack_point:make() if necessary, and step_squad.current_action is guaranteed to be nil or sim_stay_point, which doesn't need finalization. TODO: Check: Also, not necessary to set current_action to nil from sim_stay_point.
@@ -576,7 +579,7 @@ local function pave_way_off_smart(board, front, archive)
576579
]]
577580
step_squad.current_action = sim_attack_point(step_squad, step_target_id, true)
578581
step_squad.current_action:make()
579-
step, step_target_id, step_target = step.prev, step.smart_id, step.smart
582+
step, step_target_id, step_target = step.prev, step.smart_id, step_smart
580583
end
581584
for k, smart_data in pairs (sim_avail_table) do
582585
-- dbglog("Reinstating sim_avail setting for smart '%s' to [%s]", smart_names.get_smart_terrain_name(smart_data[1]), tostring(smart_data[2]))
@@ -595,7 +598,7 @@ local function pave_way_off_smart(board, front, archive)
595598
end
596599
end
597600
for i = 1, num_front do
598-
table.remove(front, 1)
601+
table_remove(front, 1)
599602
end
600603
if #front == 0 then
601604
-- dbglog("Algorithm failed to unblock faction war!")

0 commit comments

Comments
 (0)