1
0
mirror of https://github.com/Oarcinae/FactorioScenarioMultiplayerSpawn.git synced 2025-02-11 13:15:30 +02:00

Should fix a LOT of cases where player was used instead of player.character. Add broadcast for when player changes surfaces and platforms.

This commit is contained in:
Oarcinae 2024-10-27 19:50:52 -04:00
parent 388ada2b4f
commit 7ddc0c2135
8 changed files with 110 additions and 77 deletions

View File

@ -1,18 +1,23 @@
---------------------------------------------------------------------------------------------------
Version: 2.1.3
Date: ????
Date: 2024-10-27
Minor Features:
- Add GPS ping for when player clicks on someone's location in the player list.
- Players can now reset themselves if they want a different spawn. Available in the spawn controls tab of the custom GUI. This feature is enabled by default but can be disabled with a setting.
- New settings allow changing if player teams are friendly and/or have a cease fire. Exposed because friendly forces are problematic due to griefing. CooP is still the default setting.
- Add a broadcast message for when a player changes surfaces.
Changes:
- Change default spacing between fluid resource patches (like crude-oil) to be 6 instead of 4.
- Added config setting to control the spacing between fluid resource patches. (Not exposed in the GUI.)
- Set default starting items to be the same as Vanilla freeplay.
Bugfixes:
- Fixed logistics chest not shown in coin shop due to outdated item name.
- Fix crash when player dies and respawns on other surfaces.
- Fix allowing players to teleport home from anywhere if viewing their home surface remotely.
- Fixed a LOT of references to player where player.character should be used instead.
Info:
- Rename and re-arrange the custom GUI tabs. (Surface Config --> Surface Settings)
- Add several custom events to support future features and integration. These have lots of debug logging enabled currently, I'll disable these at a future date, for they are useful now to assist when issues come up with the new SA and 2.0 features.
---------------------------------------------------------------------------------------------------
Version: 2.1.2
Date: 2024-10-23

View File

@ -142,7 +142,7 @@ end)
---@field player_index integer
script.on_event("oarc-mod-on-player-reset", function(event)
log("Custom event oarc-mod-on-player-reset")
log(serpent.block(event))
log(serpent.block(event --[[@as OarcModOnPlayerResetEvent]]))
if (game.players[event.player_index]) then
log("Player is still valid: " .. game.players[event.player_index].name)
end
@ -152,7 +152,7 @@ end)
---@field player_index integer
script.on_event("oarc-mod-on-player-spawned", function(event)
log("Custom event oarc-mod-on-player-spawned")
log(serpent.block(event))
log(serpent.block(event --[[@as OarcModOnPlayerSpawnedEvent]]))
log("Player spawned: " .. game.players[event.player_index].name)
end)
@ -162,7 +162,7 @@ end)
---@field new_surface_name string
script.on_event("oarc-mod-character-surface-changed", function(event)
log("Custom event oarc-mod-character-surface-changed")
log(serpent.block(event))
log(serpent.block(event --[[@as OarcModCharacterSurfaceChangedEvent]]))
local player = game.players[event.player_index]
SeparateSpawnsPlayerChangedSurface(player, event.old_surface_name, event.new_surface_name)
@ -175,7 +175,7 @@ script.on_event(defines.events.script_raised_teleported, function(event)
local entity = event.entity
if entity.type == "character" and entity.player then
UpdatePlayerSurface(entity.player, entity.surface.name)
SeparateSpawnsUpdatePlayerSurface(entity.player, entity.surface.name)
end
end)
@ -284,70 +284,24 @@ end)
--If a player gets in or out of a vehicle, mark the area as safe so we don't delete the vehicle by accident.
--Only world eater will clean up these chunks over time if it is enabled.
script.on_event(defines.events.on_player_driving_changed_state, function (event)
if storage.ocfg.regrowth.enable_regrowth then
RegrowthMarkAreaSafeGivenTilePos(event.entity.surface.name, event.entity.position, 1, false)
local entity = event.entity
if storage.ocfg.regrowth.enable_regrowth and (entity ~= nil) then
RegrowthMarkAreaSafeGivenTilePos(entity.surface.name, entity.position, 1, false)
end
log("Player driving changed state")
log(serpent.block(event))
local player = game.players[event.player_index]
log("Player vehicle: " .. serpent.block(player.vehicle))
-- Track the surfaces whenever driving state changes.
if (event.entity ~= nil) then
UpdatePlayerSurface(player, entity.surface.name)
-- Track the surfaces whenever driving state changes. This triggers events for surface changes.
if (entity ~= nil) then
SeparateSpawnsUpdatePlayerSurface(player, entity.surface.name)
end
-- local entity = event.entity
-- if (entity ~= nil) and(entity.name == "cargo-pod") and
-- (entity.surface.name == "nauvis") and
-- (storage.player_surfaces[player.name] == "platform-1") then
-- log("Landing cargo pod on nauvis")
-- player.teleport({x=100,y=100})
-- end
-- --[[@type OarcPlayerSpawn]]
-- local respawn_info = storage.player_respawns[player.name][player.surface.name]
-- if (respawn_info == nil) then
-- log("ERROR: No respawn info for player: " .. player.name)
-- return
-- end
-- local respawn_surface_name = respawn_info.surface
-- local respawn_position = respawn_info.position
end)
---Updates the player's surface and raises an event if it changes.
---@param player LuaPlayer
---@param new_surface_name string
---@return nil
function UpdatePlayerSurface(player, new_surface_name)
if (storage.player_surfaces == nil) then
storage.player_surfaces = {}
end
local previous_surface_name = storage.player_surfaces[player.name]
if (previous_surface_name ~= new_surface_name) then
storage.player_surfaces[player.name] = new_surface_name
-- Raise event if previous surface isn't nil (avoids first spawn event)
if (previous_surface_name ~= nil) then
script.raise_event("oarc-mod-character-surface-changed", {
player_index=player.index,
old_surface_name=previous_surface_name,
new_surface_name=new_surface_name
})
end
end
end
----------------------------------------
-- On script_raised_built. This should help catch mods that
-- place items that don't count as player_built and robot_built.

View File

@ -61,7 +61,8 @@ function AddPlayerRow(table, player_name, online)
AddLabel(table, nil, player.force.name, my_label_style)
-- List home surface name or holding pen
if (player.surface.name == HOLDING_PEN_SURFACE_NAME) then
local character = player.character
if character and (character.surface.name == HOLDING_PEN_SURFACE_NAME) then
AddLabel(table, nil, {"oarc-player-waiting-to-spawn"}, my_label_style)
else
local spawn = FindPlayerHomeSpawn(player.name)

View File

@ -134,8 +134,21 @@ function CreateSetRespawnLocationButton(player, container)
AddSpacerLine(container)
AddLabel(container, nil, { "oarc-set-respawn-loc-header" }, "caption_label")
-- Check if player has a valid character
if (player.character == nil) then
AddLabel(container, nil, { "oarc-no-valid-player-character" }, my_warning_style)
return
end
-- Check if player is in a vehicle
if player.driving then
AddLabel(container, nil, { "oarc-player-character-in-vehicle" }, my_warning_style)
return
end
local surface_name = player.character.surface.name
--[[@type OarcPlayerSpawn]]
local respawn_info = storage.player_respawns[player.name][player.surface.name]
local respawn_info = storage.player_respawns[player.name][surface_name]
if (respawn_info == nil) then
AddLabel(container, nil, { "oarc-no-respawn-this-surface" }, my_warning_style)
@ -388,14 +401,26 @@ function SpawnCtrlTabGuiClick(event)
-- Sets a new respawn point and resets the cooldown.
if (tags.setting == "set_respawn_location") then
-- Check if the surface is blacklisted
local surface_name = player.surface.name
if IsSurfaceBlacklisted(surface_name) then
player.print("Can't set a respawn point on this surface!")
-- Check if player has a valid character
if (player.character == nil) then
player.print({ "oarc-no-valid-player-character" })
return
end
SetPlayerRespawn(player.name, surface_name, player.position, true)
-- Check if player is in a vehicle
if player.driving then
player.print({ "oarc-player-character-in-vehicle" })
return
end
-- Check if the surface is blacklisted
local surface_name = player.character.surface.name
if IsSurfaceBlacklisted(surface_name) then
player.print({"oarc-no-respawn-this-surface"})
return
end
SetPlayerRespawn(player.name, surface_name, player.character.position, true)
OarcGuiRefreshContent(player)
player.print({ "oarc-spawn-point-updated" })
@ -412,7 +437,17 @@ function SpawnCtrlTabGuiClick(event)
local surface_name = tags.surface --[[@as string]]
local position = tags.position --[[@as MapPosition]]
--TODO Verify player is still on the same surface, if they leave the GUI open, they can teleport back from any surface.
-- Check if player has a valid character
if (player.character == nil) then
player.print({ "oarc-no-valid-player-character" })
return
end
-- Check if player is in a vehicle
if player.driving then
player.print({ "oarc-player-character-in-vehicle" })
return
end
SafeTeleport(player, game.surfaces[surface_name], position)

View File

@ -406,7 +406,7 @@ end
---@param player LuaPlayer
---@return nil
function GivePlayerRespawnItems(player)
local surface_name = player.surface.name
local surface_name = player.character.surface.name
if (storage.ocfg.surfaces_config[surface_name] == nil) then
error("GivePlayerRespawnItems - Missing surface config! " .. surface_name)
return
@ -421,7 +421,7 @@ end
---@param player LuaPlayer
---@return nil
function GivePlayerStarterItems(player)
local surface_name = player.surface.name
local surface_name = player.character.surface.name
if (storage.ocfg.surfaces_config[surface_name] == nil) then
error("GivePlayerStarterItems - Missing surface config! " .. surface_name)
return
@ -436,7 +436,7 @@ end
---@param player LuaPlayer
---@return nil
function RemovePlayerStarterItems(player)
local surface_name = player.surface.name
local surface_name = player.character.surface.name
if (storage.ocfg.surfaces_config[surface_name]) ~= nil then
local startItems = storage.ocfg.surfaces_config[surface_name].starting_items.player_start_items
OarcsSaferRemove(player, startItems)

View File

@ -380,12 +380,13 @@ function RefreshPlayerArea()
player_index = GetNextConnectedPlayerIndex()
if (player_index and game.connected_players[player_index]) then
local player = game.connected_players[player_index]
local surface_name = player.surface.name
if (not player.character) then return end
local surface_name = player.character.surface.name
if (storage.rg[surface_name] == nil) or (not storage.rg[surface_name].active) then return end
RefreshArea(surface_name, player.position, REGROWTH_ACTIVE_AREA_AROUND_PLAYER, 0)
RefreshArea(surface_name, player.character.position, REGROWTH_ACTIVE_AREA_AROUND_PLAYER, 0)
end
end

View File

@ -207,10 +207,10 @@ end
---@return nil
function SeparateSpawnsPlayerRespawned(event)
local player = game.players[event.player_index]
local surface_name = player.surface.name
local surface_name = player.character.surface.name
-- It's possible if player is dead, and then resets, we don't want to do anything else.
if (player.surface.name == HOLDING_PEN_SURFACE_NAME) then return end
if (surface_name == HOLDING_PEN_SURFACE_NAME) then return end
-- If the mod isn't active on this surface, then ignore it.
local surface_config = storage.oarc_surfaces[surface_name]
@ -246,6 +246,15 @@ function SeparateSpawnsPlayerChangedSurface(player, previous_surface_name, new_s
if (previous_surface_name == nil) then return end
log("SeparateSpawnsPlayerChangedSurface from " .. previous_surface_name .. " to " .. new_surface_name)
-- TODO make sure this isn't too spammy?
local surface = game.surfaces[new_surface_name]
local platform = surface.platform
if (platform ~= nil) then
SendBroadcastMsg({ "oarc-player-on-platform", player.name, surface.platform.name })
else
SendBroadcastMsg({ "oarc-player-changed-surface", player.name, surface.name })
end
-- Check if player has been init'd yet. If not, then ignore it.
if (storage.player_respawns[player.name] == nil) then return end
@ -256,7 +265,6 @@ function SeparateSpawnsPlayerChangedSurface(player, previous_surface_name, new_s
return
end
-- If previous surface was a platform
-- local arriving_from_space = StringStartsWith(previous_surface_name, "platform-")
@ -282,7 +290,32 @@ function SeparateSpawnsPlayerChangedSurface(player, previous_surface_name, new_s
-- TODO: Need to figure out buddy spawns and other stuff still!
log("WARNING - THIS IS NOT FULLY IMPLEMENTED YET!!")
SecondarySpawn(player, player.surface)
SecondarySpawn(player, game.surfaces[new_surface_name])
end
---Updates the player's surface and raises an event if it changes.
---@param player LuaPlayer
---@param new_surface_name string
---@return nil
function SeparateSpawnsUpdatePlayerSurface(player, new_surface_name)
if (storage.player_surfaces == nil) then
storage.player_surfaces = {}
end
local previous_surface_name = storage.player_surfaces[player.name]
if (previous_surface_name ~= new_surface_name) then
storage.player_surfaces[player.name] = new_surface_name
-- Raise event if previous surface isn't nil (avoids first spawn event)
if (previous_surface_name ~= nil) then
script.raise_event("oarc-mod-character-surface-changed", {
player_index=player.index,
old_surface_name=previous_surface_name,
new_surface_name=new_surface_name
})
end
end
end
--[[
@ -503,7 +536,7 @@ function SendPlayerToNewSpawnAndCreateIt(delayed_spawn)
-- Chart the area.
ChartArea(player.force, delayed_spawn.position, math.ceil(storage.ocfg.spawn_general.spawn_radius_tiles / CHUNK_SIZE),
player.surface)
player.character.surface)
-- Remove waiting dialog
if (player.gui.screen.wait_for_spawn_dialog ~= nil) then

View File

@ -78,6 +78,8 @@ oarc-generating-spawn-please-wait=Generating your spawn now, please wait...
oarc-host-left-new-host=__1__ has left so __2__ now owns their base.
oarc-new-owner-msg=You have been given ownership of this base!
oarc-player-changed-surface=__1__ is now on __2__!
oarc-player-on-platform=__1__ is now on platform: __2__!
oarc-looking-for-buddy=__1__ is looking for a buddy.
@ -122,6 +124,8 @@ oarc-shared-spawn-full=Your base is full! No more players can join.
oarc-set-respawn-loc-header=Respawn Location
oarc-no-respawn-this-surface=You cannot set a custom respawn location on this surface.
oarc-no-valid-player-character=Coudn't find a valid character attached to the player!
oarc-player-character-in-vehicle=Player must not be in a vehicle to use this!
oarc-set-respawn-loc-info-surface-label=Current Surface Respawn: __1__ (x=__2__, y=__3__)
oarc-set-respawn-loc=Set Respawn Location
oarc-set-respawn-loc-tooltip=This will set your respawn point to your current location. There is a cooldown before you can change it again. You can only set this on supported surfaces.