-- removes all data about surface connections; connection owners won't be notified function ClearAllSurfaceConnections() global.ConnectedSurfaces = {} end -- returns the string "number1|number2" in consistent order: the smaller number is always placed first local function sorted_pair(number1, number2) return (number1 < number2) and (number1..'|'..number2) or (number2..'|'..number1) end -- removes the surface connection between the given entities from global.SurfaceConnections. Does nothing if the connection doesn't exist. function DisconnectSurfaces(entity1, entity2) -- ensure received data is valid and usable if not( entity1 and entity1.valid and entity1.surface and entity1.surface.index and game.surfaces[entity1.surface.index] ) then if debug_log then log("(DisconnectSurfaces) Recieved entity1 was invalid.") end return end if not( entity2 and entity2.valid and entity2.surface and entity2.surface.index and game.surfaces[entity2.surface.index] ) then if debug_log then log("(DisconnectSurfaces) Recieved entity2 was invalid.") end return end local surface_pair_key = sorted_pair(entity1.surface.index, entity2.surface.index) local surface_connections = global.ConnectedSurfaces[surface_pair_key] if surface_connections then local entity_pair_key = sorted_pair(entity1.unit_number, entity2.unit_number) if debug_log then log("removing surface connection for entities "..entity_pair_key.." between surfaces "..surface_pair_key) end surface_connections[entity_pair_key] = nil end end -- adds a surface connection between the given entities; the network_id will be used in delivery processing to discard providers that don't match the surface connection's network_id function ConnectSurfaces(entity1, entity2, network_id) -- ensure received data is valid and usable if not( entity1 and entity1.valid and entity1.surface and entity1.surface.index and game.surfaces[entity1.surface.index] ) then if debug_log then log("(ConnectSurfaces) Recieved entity1 was invalid.") end return end if not( entity2 and entity2.valid and entity2.surface and entity2.surface.index and game.surfaces[entity2.surface.index] ) then if debug_log then log("(ConnectSurfaces) Recieved entity2 was invalid.") end return end if not( network_id and tonumber(network_id, 10) ) then if debug_log then log("(ConnectSurfaces) Recieved network_id was no valid integer.") end return end if entity1.surface == entity2.surface then if debug_log then log(format("(ConnectSurfaces) Entities [%d] and [%d] are on the same surface %s [%d].", entity1.unit_number, entity2.unit_number, entity1.surface.name, entity1.surface.index)) end return end local surface_pair_key = sorted_pair(entity1.surface.index, entity2.surface.index) local surface_connections = Get_Or_Create(global.ConnectedSurfaces, surface_pair_key) local entity_pair_key = sorted_pair(entity1.unit_number, entity2.unit_number) if debug_log then log(format("(ConnectSurfaces) Creating surface connection between [%d] on %s [%d] and [%d] on %s [%d].", entity1.unit_number, entity1.surface.name, entity1.surface.index, entity2.unit_number, entity2.surface.name, entity2.surface.index)) end surface_connections[entity_pair_key] = { -- enforce a consistent order for repeated calls with the same two entities entity1 = entity1.unit_number <= entity2.unit_number and entity1 or entity2, entity2 = entity1.unit_number > entity2.unit_number and entity1 or entity2, network_id = network_id, } end -- remove entity references when deleting surfaces function OnSurfaceRemoved(event) -- stop references local surfaceID = event.surface_index log(format("Removing LTN stops and surface connections on surface [%d].", surfaceID) ) local surface = game.surfaces[surfaceID] if surface then local train_stops = surface.find_entities_filtered{type = "train-stop"} for _, entity in pairs(train_stops) do if ltn_stop_entity_names[entity.name] then RemoveStop(entity.unit_number) end end end -- surface connections; surface_index will either be the first half of the key or the second local first_surface = "^"..surfaceID.."|" local second_surface = "|"..surfaceID.."$" for surface_pair_key, _ in pairs(global.ConnectedSurfaces) do if string.find(surface_pair_key, first_surface) or string.find(surface_pair_key, second_surface) then global.ConnectedSurfaces[surface_pair_key] = nil end end end