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

Merge pull request #215 from Oarcinae/148-feature-request-let-players-re-roll-their-spawn-area-unlimited

Player can now self reset (enabled by default).
This commit is contained in:
Oarcinae 2024-10-24 09:56:07 -04:00 committed by GitHub
commit fae51e1ad3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 142 additions and 8 deletions

View File

@ -3,6 +3,7 @@ Version: 2.1.3
Date: ????
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.
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.)

View File

@ -395,6 +395,9 @@ OCFG = {
-- Enable the coin shop GUI for players to buy items with coins.
enable_coin_shop = false,
-- Allow players to reset themselves in the spawn controls
enable_player_self_reset = true,
},
-- This is a separate feature that is part of the mod that helps keep the map size down. Not required but useful.
@ -597,6 +600,7 @@ OCFG = {
---@field enable_shared_power boolean Enable shared power between bases. Creates a special power pole for cross surface connections.
---@field enable_shared_chest boolean Enables a single shared chest using the native linked-chest entity in factorio.
---@field enable_coin_shop boolean Enable the coin shop GUI for players to buy items with coins.
---@field enable_player_self_reset boolean Allow players to reset themselves in the spawn controls
---@class OarcConfigRegrowth
---@field enable_regrowth boolean Cleans up unused chunks periodically. Helps keep map size down.

View File

@ -83,6 +83,7 @@ OCFG_KEYS =
["coin_generation_SUBHEADER"] = {mod_key = "" , ocfg_keys = {""}, type = "subheader", text = "Coin Generation"},
["coin_generation.enabled"] = {mod_key = "" , ocfg_keys = {"coin_generation", "enabled"}, type = "boolean", caption = "Coin Generation", tooltip = "Enemies drop coins when killed."},
["coin_generation.auto_decon_coins"] = {mod_key = "" , ocfg_keys = {"coin_generation", "auto_decon_coins"}, type = "boolean", caption = "Auto Decon Coins", tooltip = "Automatically marks coins dropped by enemies for deconstruction so robots will pick them up."},
["gameplayer.enable_player_self_reset"] = {mod_key = "" , ocfg_keys = {"gameplay", "enable_player_self_reset"}, type = "boolean", caption = "Player Self Reset", tooltip = "Allow players to reset themselves in the spawn controls."}
}
---Easy reverse lookup for mod settings keys.

View File

@ -136,7 +136,6 @@ function ServerInfoTabGuiClick(event)
log("Resetting " .. resetPlayer)
RemoveOrResetPlayer(game.players[resetPlayer], false)
SeparateSpawnsInitPlayer(resetPlayer --[[@as string]])
else
SendMsg(player.name, {"oarc-player-none-selected"})
return

View File

@ -1,5 +1,8 @@
-- Spawn control tab in the Oarc GUI, for things like sharing your base with others.
local RESET_GUI_MAX_WIDTH = 500
local RESET_GUI_MAX_HEIGHT = 1000
---Provides the content of the spawn control tab in the Oarc GUI.
---@param tab_container LuaGuiElement
---@param player LuaPlayer
@ -13,6 +16,11 @@ function CreateSpawnControlsTab(tab_container, player)
spwnCtrls.style.maximal_height = GENERIC_GUI_MAX_HEIGHT
spwnCtrls.style.padding = 5
-- Don't show anything WHILE they are still generating a spawn:
if PlayerHasDelayedSpawn(player.name--[[@as string]]) then
AddLabel(spwnCtrls, nil, { "oarc-spawn-controls-disabled-delayed" }, my_warning_style)
return
end
CreatePrimarySpawnInfo(player, spwnCtrls)
CreateSecondarySpawnInfo(player, spwnCtrls)
@ -22,6 +30,8 @@ function CreateSpawnControlsTab(tab_container, player)
CreateSharedSpawnControls(player, spwnCtrls)
CreateJoinQueueControls(player, spwnCtrls)
end
CreatePlayerResetControls(spwnCtrls)
end
---Display some general info about the player's home base (different from respawn point).
@ -51,8 +61,6 @@ function CreatePrimarySpawnInfo(player, container)
dragger.style.horizontally_stretchable = true
CreateGPSButton(horizontal_flow, primary_spawn.surface_name, primary_spawn.position)
AddSpacerLine(container)
end
---Display some general info about the player's secondary spawn points.
@ -63,6 +71,7 @@ function CreateSecondarySpawnInfo(player, container)
local secondary_spawns = FindSecondaryUniqueSpawns(player.name)
if (secondary_spawns == nil) or (table_size(secondary_spawns) == 0) then return end
AddSpacerLine(container)
AddLabel(container, nil, { "oarc-secondary-spawn-info-header" }, "caption_label")
AddLabel(container, nil, { "oarc-secondary-spawn-info-note" }, my_label_style)
@ -83,8 +92,6 @@ function CreateSecondarySpawnInfo(player, container)
CreateGPSButton(horizontal_flow, secondary_spawn.surface_name, secondary_spawn.position)
end
AddSpacerLine(container)
end
---Display the shared spawn controls
@ -95,6 +102,7 @@ function CreateSharedSpawnControls(player, container)
local primary_spawn = FindPrimaryUniqueSpawn(player.name)
if (primary_spawn == nil) then return end
AddSpacerLine(container)
AddLabel(container, nil, { "oarc-shared-spawn-controls" }, "caption_label")
local shared_spawn_open = IsSharedSpawnOpen(primary_spawn.surface_name, player.name)
@ -122,6 +130,8 @@ end
---@param container LuaGuiElement
---@return nil
function CreateSetRespawnLocationButton(player, container)
AddSpacerLine(container)
AddLabel(container, nil, { "oarc-set-respawn-loc-header" }, "caption_label")
--[[@type OarcPlayerSpawn]]
@ -178,7 +188,6 @@ function CreateSetRespawnLocationButton(player, container)
(game.tick - storage.player_cooldowns[player.name].setRespawn)) }, my_note_style)
end
AddLabel(container, nil, { "oarc-set-respawn-note" }, my_label_style)
AddSpacerLine(container)
end
---Display a list of people in the join queue for a shared spawn.
@ -257,6 +266,83 @@ function CreateGPSButton(container, surface_name, position)
gps_button.style.height = 28
end
---Create the GUI controls for self-resetting the player.
---@param container LuaGuiElement
---@return nil
function CreatePlayerResetControls(container)
if not storage.ocfg.gameplay.enable_player_self_reset then return end
AddSpacerLine(container)
AddLabel(container, nil, { "oarc-player-reset-header" }, "caption_label")
AddLabel(container, nil, { "oarc-player-reset-note" }, my_longer_label_style)
local horizontal_flow = container.add { type = "flow", direction = "horizontal" }
local dragger = horizontal_flow.add {
type = "empty-widget",
style = "draggable_space_header"
}
dragger.style.horizontally_stretchable = true
local reset_button = horizontal_flow.add {
type = "button",
tags = { action = "oarc_spawn_ctrl_tab", setting = "player_reset" },
caption = { "oarc-player-reset" },
tooltip = { "oarc-player-reset-tooltip" },
style = "red_button"
}
reset_button.style.font = "default-small-semibold"
end
---Display a confirmation GUI for the player to reset themselves.
---@param player LuaPlayer
---@return nil
function DisplayPlayerResetConfirmationGUI(player)
local self_reset_gui = player.gui.screen.add {
name = "self_reset_confirm",
type = "frame",
direction = "vertical",
caption = { "oarc-player-reset" }
}
self_reset_gui.auto_center = true
self_reset_gui.style.maximal_width = RESET_GUI_MAX_WIDTH
self_reset_gui.style.maximal_height = RESET_GUI_MAX_HEIGHT
self_reset_gui.style.padding = 5
local self_reset_gui_if = self_reset_gui.add {
type = "frame",
style = "inside_shallow_frame_with_padding",
direction = "vertical"
}
AddLabel(self_reset_gui_if, nil, { "oarc-player-reset-are-you-sure" }, my_warning_style)
AddSpacer(self_reset_gui_if)
local horizontal_flow = self_reset_gui_if.add { type = "flow", direction = "horizontal" }
horizontal_flow.style.horizontally_stretchable = true
local cancel_button = horizontal_flow.add {
type = "button",
tags = { action = "oarc_spawn_ctrl_tab", setting = "player_reset_cancel" },
caption = { "oarc-cancel-button-caption" },
style = "back_button"
}
local dragger = horizontal_flow.add {
type = "empty-widget",
style = "draggable_space_header"
}
dragger.style.horizontally_stretchable = true
local reset_button = horizontal_flow.add {
type = "button",
tags = { action = "oarc_spawn_ctrl_tab", setting = "player_reset_confirm" },
caption = { "oarc-confirm-button-caption" },
tooltip = { "oarc-player-reset" },
style = "confirm_button"
}
end
---Handle the gui checkboxes & radio buttons of the spawn control tab in the Oarc GUI.
---@param event EventData.on_gui_checked_state_changed
---@return nil
@ -330,6 +416,23 @@ function SpawnCtrlTabGuiClick(event)
SafeTeleport(player, game.surfaces[surface_name], position)
-- Self reset the player
elseif (tags.setting == "player_reset") then
DisplayPlayerResetConfirmationGUI(player)
-- Cancel the self reset
elseif (tags.setting == "player_reset_cancel") then
if (player.gui.screen.self_reset_confirm) then
player.gui.screen.self_reset_confirm.destroy()
end
-- Confirm the self reset
elseif (tags.setting == "player_reset_confirm") then
if (player.gui.screen.self_reset_confirm) then
player.gui.screen.self_reset_confirm.destroy()
end
RemoveOrResetPlayer(player, false)
-- Accept or reject pending player join requests to a shared base
elseif ((tags.setting == "accept_player_request") or (tags.setting == "reject_player_request")) then

View File

@ -782,8 +782,16 @@ function RemoveOrResetPlayer(player, remove_player)
end
-- Remove the character completely
if (remove_player) then
if (remove_player and not player.connected) then
game.remove_offline_players({ player })
-- Otherwise, make sure to re-init them!
else
if (remove_player) then
log("ERROR! RemoveOrResetPlayer - Player not removed as they are still connected: " .. player.name)
end
SeparateSpawnsInitPlayer(player.index --[[@as string]])
SendBroadcastMsg({"oarc-player-was-reset-notify", player.name})
end
-- Refresh the shared spawn spawn gui for all players
@ -866,11 +874,15 @@ function UniqueSpawnCleanupRemove(player_name)
end
end
-- TODO: Possibly limit this based on playtime? If player is on for a long time then don't remove it?
-- Use regrowth mod to cleanup the area.
local spawn_position = primary_spawn.position
if (storage.ocfg.regrowth.enable_abandoned_base_cleanup and (not nearOtherSpawn)) then
log("Removing base: " .. spawn_position.x .. "," .. spawn_position.y .. " on surface: " .. primary_spawn.surface_name)
RegrowthMarkAreaForRemoval(primary_spawn.surface_name, spawn_position, math.ceil(total_spawn_width / CHUNK_SIZE) + 1) -- +1 to match the spawn generation requested area
-- Clear an area around the spawn that SHOULD not include any other bases.
local clear_radius = storage.ocfg.gameplay.minimum_distance_to_existing_chunks - 2 -- Bring in a bit for safety.
RegrowthMarkAreaForRemoval(primary_spawn.surface_name, spawn_position, clear_radius)
TriggerCleanup()
end

View File

@ -84,6 +84,7 @@ oarc-looking-for-buddy=__1__ is looking for a buddy.
oarc-avail-bases-join=Available Bases to Join:
oarc-spawn-spots-remaining=__1__ (__2__ spots remaining)
oarc-cancel-button-caption=Cancel
oarc-confirm-button-caption=Confirm
oarc-return-to-previous-tooltip=Return to the previous menu.
oarc-player-requesting-join-you=__1__ is requesting to join your base!
oarc-waiting-for-spawn-owner=Waiting for spawn owner to respond...
@ -106,6 +107,13 @@ oarc-secondary-spawn-info-surface-label=Secondary: __1__ (x=__2__, y=__3__)
oarc-spawn-info-location-button=Show Map Location
oarc-spawn-info-location-button-tooltip=Click to show the location on the map.
oarc-player-reset-header=Player Reset
oarc-player-reset-note=This will let you [color=red][font=default-bold]RESET[/font][/color] your player and choose new spawn options. If you created your own spawn, it will be [color=red][font=default-bold]DELETED[/font][/color] or transferred to someone else if they joined. If you are in a shared base, you will be [color=red][font=default-bold]REMOVED[/font][/color] from it. You [color=red][font=default-bold]CAN NOT UNDO[/font][/color] this.
oarc-player-reset=RESET
oarc-player-reset-tooltip=There is a confirmation dialog after clicking this button. Be careful!
oarc-spawn-controls-disabled-delayed=Spawn is still generating! Refresh this tab after you have been sent to the new spawn.
oarc-player-reset-are-you-sure=Are you sure you want to reset?
oarc-player-was-reset-notify=__1__ was reset!
oarc-spawn-gps-location=Location:
oarc-shared-spawn-controls=Shared Spawn Controls

View File

@ -8,3 +8,9 @@ for surface_name, surface_config in pairs(storage.ocfg.surfaces_config) do
end
end
end
--Add setting for letting players reset themselves.
if storage.ocfg.gameplay.enable_player_self_reset == nil then
storage.ocfg.gameplay.enable_player_self_reset = true
log("Updating gameplay config with new 'enable_player_self_reset' setting.")
end