1
0
mirror of https://github.com/ComfyFactory/ComfyFactorio.git synced 2025-01-04 00:15:45 +02:00

Player leaving/joining changes

Changes:
- Fixed an issue where player force wasn't properly set to default force, when player joined the game 2nd time after 5 minutes, which caused all sorts of issues (such as being able to take classes while staying in lobby, etc.)
- Player inventory when player leaves the crew (either to lobby or quite game) now remains in their character corpse.
- When player leaves and joins the game within 1 minute, he will spawn where he left.
This commit is contained in:
Piratux 2023-06-26 21:51:55 +03:00
parent e81c587a63
commit 254c43c081
7 changed files with 106 additions and 80 deletions

View File

@ -1437,22 +1437,26 @@ local function event_on_player_joined_game(event)
local crew_to_put_back_in = nil
for _, memory in pairs(global_memory.crew_memories) do
if Common.is_id_valid(memory.id) and memory.crewstatus == Crew.enum.ADVENTURING and memory.temporarily_logged_off_characters[player.index] then
if Common.is_id_valid(memory.id) and memory.crewstatus == Crew.enum.ADVENTURING and memory.temporarily_logged_off_player_data[player.index] then
crew_to_put_back_in = memory.id
break
end
end
if crew_to_put_back_in then
Crew.join_crew(player, crew_to_put_back_in, true)
log('INFO: ' .. player.name .. ' (crew ID: ' .. crew_to_put_back_in .. ') joined the game')
local memory = global_memory.crew_memories[crew_to_put_back_in]
Memory.set_working_id(crew_to_put_back_in)
Crew.join_crew(player, true)
local memory = Memory.get_crew_memory()
if (not memory.run_is_protected) and #memory.crewplayerindices <= 1 then
Roles.make_captain(player)
end
if _DEBUG then log('putting player back in their old crew') end
else
log('INFO: ' .. player.name .. ' (crew ID: NONE) joined the game')
if player.character and player.character.valid then
player.character.destroy()
end
@ -1475,6 +1479,8 @@ local function event_on_player_joined_game(event)
Common.notify_player_expected(player, {'pirates.player_join_game_info'})
player.force = Common.lobby_force_name
-- It was suggested to always spawn players in lobby, in hopes that they may want to create their crew increasing the popularity of scenario.
-- Auto-join the oldest crew:
@ -1505,7 +1511,7 @@ local function event_on_player_joined_game(event)
-- end
-- )
-- if ages[1] then
-- Crew.join_crew(player, ages[1].id)
-- Crew.join_crew(player)
-- local memory = global_memory.crew_memories[ages[1].id]
-- if (not memory.run_is_protected) and #memory.crewplayerindices <= 1 then
@ -1565,6 +1571,11 @@ local function event_on_pre_player_left_game(event)
local global_memory = Memory.get_global_memory()
-- figure out which crew this is about:
local crew_id = Common.get_id_from_force_name(player.force.name)
if crew_id then
log('INFO: ' .. player.name .. ' (crew ID: ' .. crew_id .. ') left the game')
else
log('INFO: ' .. player.name .. ' (crew ID: NONE) left the game')
end
for k, proposal in pairs(global_memory.crewproposals) do
if proposal and proposal.endorserindices then
@ -2082,7 +2093,7 @@ local function event_on_console_chat(event)
local memory = Memory.get_crew_memory()
-- NOTE: This check to see if player is in a crew is not reliable and can sometimes cause errors!
if player.force.name == 'player' then
if player.force.name == Common.lobby_force_name then
local other_force_indices = global_memory.crew_active_ids
for _, index in pairs(other_force_indices) do

View File

@ -262,34 +262,34 @@ function Public.prune_offline_characters_list(tickinterval)
if memory.game_lost then return end
for player_index, tick in pairs(memory.temporarily_logged_off_characters) do
if player_index and game.players[player_index] and game.players[player_index].connected then
memory.temporarily_logged_off_characters[player_index] = nil
if memory.temporarily_logged_off_characters_items[player_index] then
memory.temporarily_logged_off_characters_items[player_index].destroy()
end
memory.temporarily_logged_off_characters_items[player_index] = nil
for player_index, data in pairs(memory.temporarily_logged_off_player_data) do
if game.players[player_index] and game.players[player_index].connected then
-- memory.temporarily_logged_off_characters[player_index] = nil
-- if memory.temporarily_logged_off_characters_items[player_index] then
-- memory.temporarily_logged_off_characters_items[player_index].destroy()
-- end
-- memory.temporarily_logged_off_characters_items[player_index] = nil
memory.temporarily_logged_off_player_data[player_index] = nil
else
if player_index and tick < game.tick - 60 * 60 * Common.logged_off_items_preserved_minutes then
local any = false
local temp_inv = memory.temporarily_logged_off_characters_items[player_index]
if temp_inv then
for i = 1, #temp_inv, 1 do
if temp_inv[i] and temp_inv[i].valid and temp_inv[i].valid_for_read then
Common.give_items_to_crew(temp_inv[i])
any = true
end
end
if any then
Common.notify_force_light(memory.force, {'pirates.recover_offline_player_items'})
end
local tick = data.tick
if tick < game.tick - 60 * 60 * Common.temporarily_logged_off_player_data_preservation_minutes then
-- local any = false
-- local temp_inv = memory.temporarily_logged_off_characters_items[player_index]
-- if temp_inv then
-- for i = 1, #temp_inv, 1 do
-- if temp_inv[i] and temp_inv[i].valid and temp_inv[i].valid_for_read then
-- Common.give_items_to_crew(temp_inv[i])
-- any = true
-- end
-- end
temp_inv.destroy()
end
-- if any then
-- Common.notify_force_light(memory.force, {'pirates.recover_offline_player_items'})
-- end
-- temp_inv.destroy()
-- end
memory.temporarily_logged_off_characters[player_index] = nil
memory.temporarily_logged_off_characters_items[player_index] = nil
memory.temporarily_logged_off_player_data[player_index] = nil
end
end

View File

@ -63,9 +63,11 @@ Public.ban_from_rejoining_crew_ticks = 45 * 60 --to prevent observing map and re
Public.afk_time = 60 * 60 * 5
Public.afk_warning_time = 60 * 60 * 4.5
Public.logged_off_items_preserved_minutes = 1
Public.temporarily_logged_off_player_data_preservation_minutes = 1
Public.logout_unprotected_items = {'uranium-235', 'uranium-238', 'fluid-wagon', 'coal', 'electric-engine-unit', 'flying-robot-frame', 'advanced-circuit', 'beacon', 'speed-module-3', 'speed-module-2', 'roboport', 'construction-robot'} --internal inventories of these will not be preserved
Public.lobby_force_name = 'player'
-- Public.mainshop_rate_limit_ticks = 11
@ -138,7 +140,7 @@ end
function Public.notify_lobby(message, color_override)
color_override = color_override or CoreData.colors.notify_lobby
game.forces['player'].print({"", '>> ', message}, color_override)
game.forces[Public.lobby_force_name].print({"", '>> ', message}, color_override)
end
function Public.notify_force(force, message, color_override)

View File

@ -268,7 +268,7 @@ function Public.join_spectators(player, crewid)
player.set_controller{type = defines.controllers.spectator}
end
local c = surface.create_entity{name = 'character', position = surface.find_non_colliding_position('character', Common.lobby_spawnpoint, 32, 0.5) or Common.lobby_spawnpoint, force = 'player'}
local c = surface.create_entity{name = 'character', position = surface.find_non_colliding_position('character', Common.lobby_spawnpoint, 32, 0.5) or Common.lobby_spawnpoint, force = Common.lobby_force_name}
player.associate_character(c)
@ -333,14 +333,11 @@ function Public.leave_spectators(player, quiet)
if _DEBUG then memory.crew_disband_tick = game.tick + 30*60*60 end
end
player.force = 'player'
player.force = Common.lobby_force_name
end
function Public.join_crew(player, crewid, rejoin)
if not crewid then return end
Memory.set_working_id(crewid)
function Public.join_crew(player, rejoin)
local memory = Memory.get_crew_memory()
if not Common.validate_player(player) then return end
@ -369,7 +366,7 @@ function Public.join_crew(player, crewid, rejoin)
if spectating then
local chars = player.get_associated_characters()
for _, char in pairs(chars) do
char.destroy()
char.destroy()
end
player.teleport(surface.find_non_colliding_position('character', memory.spawnpoint, 32, 0.5) or memory.spawnpoint, surface)
@ -379,6 +376,11 @@ function Public.join_crew(player, crewid, rejoin)
memory.spectatorplayerindices = Utils.ordered_table_with_values_removed(memory.spectatorplayerindices, player.index)
else
if not (player.character and player.character.valid) then
player.set_controller{type = defines.controllers.god}
player.create_character()
end
Public.player_abandon_endorsements(player)
player.force = memory.force
@ -394,16 +396,17 @@ function Public.join_crew(player, crewid, rejoin)
-- If surface where player left the game still exists, place him there.
if rejoin_surface and rejoin_surface.valid then
-- Edge case: if player left the game while he was on the boat, it could be that boat position
-- changed when he left the game vs when he came back. In that case we do nothing.
if not rejoin_data.on_boat then
-- changed when he left the game vs when he came back.
if not (rejoin_data.on_boat and rejoin_data.on_island) then
player.teleport(rejoin_surface.find_non_colliding_position('character', rejoin_data.position, 32, 0.5) or memory.spawnpoint, rejoin_surface)
end
end
-- We shouldn't give back items when player was on island, but that island is gone.
if not (rejoin_data.on_island and (not (rejoin_surface and rejoin_surface.valid))) then
Common.give_back_items_to_temporarily_logged_off_player(player)
end
-- Left in case we decide to store player inventory in offline character instead of in the corpse.
-- if not (rejoin_data.on_island and (not (rejoin_surface and rejoin_surface.valid))) then
-- Common.give_back_items_to_temporarily_logged_off_player(player)
-- end
memory.temporarily_logged_off_player_data[player.index] = nil
end
@ -466,22 +469,24 @@ function Public.leave_crew(player, to_lobby, quiet)
-- @TODO: figure out why surface_name can be nil
-- When player remains in island when ship leaves, prevent him from getting items back
local save_items = true
if player.surface and
player.surface.valid and
memory.boat and
memory.boat.surface_name
then
if player_surface_type == Surfaces.enum.ISLAND and boat_surface_type == Surfaces.enum.SEA then
save_items = false
end
end
-- local save_items = true
-- if player.surface and
-- player.surface.valid and
-- memory.boat and
-- memory.boat.surface_name
-- then
-- if player_surface_type == Surfaces.enum.ISLAND and boat_surface_type == Surfaces.enum.SEA then
-- save_items = false
-- end
-- end
-- Code regarding item saving is left here if we decide it's better to store items in
-- logged off character as opposed to in the character corpse.
if to_lobby then
if save_items then
Common.send_important_items_from_player_to_crew(player, true)
end
char.die(memory.force_name)
-- if save_items then
-- Common.send_important_items_from_player_to_crew(player, true)
-- end
-- char.die(memory.force_name)
else
if not memory.temporarily_logged_off_player_data then memory.temporarily_logged_off_player_data = {} end
@ -489,15 +494,18 @@ function Public.leave_crew(player, to_lobby, quiet)
on_island = (player_surface_type == Surfaces.enum.ISLAND),
on_boat = (player_surface_type == boat_surface_type) and Boats.on_boat(memory.boat, player.character.position),
surface_name = player.surface.name,
position = player.character.position
position = player.character.position,
tick = game.tick
}
if save_items then
Common.temporarily_store_logged_off_character_items(player)
end
memory.temporarily_logged_off_characters[player.index] = game.tick
-- if save_items then
-- Common.temporarily_store_logged_off_character_items(player)
-- end
-- memory.temporarily_logged_off_characters[player.index] = game.tick
end
char.die(memory.force_name)
-- else
-- if not quiet then
-- -- local message = player.name .. ' left the crew.'
@ -509,7 +517,7 @@ function Public.leave_crew(player, to_lobby, quiet)
player.set_controller{type = defines.controllers.god}
player.teleport(surface.find_non_colliding_position('character', Common.lobby_spawnpoint, 32, 0.5) or Common.lobby_spawnpoint, surface)
player.force = 'player'
player.force = Common.lobby_force_name
player.create_character()
Event.raise(BottomFrame.events.bottom_quickbar_respawn_raise, {player_index = player.index})
end
@ -588,7 +596,7 @@ function Public.disband_crew(donotprint)
for _,player in pairs(players) do
if player.controller_type == defines.controllers.editor then player.toggle_map_editor() end
player.force = 'player'
player.force = Common.lobby_force_name
end
if (not donotprint) then
@ -774,8 +782,9 @@ function Public.initialise_crew(accepted_proposal)
memory.spectatorplayerindices = {}
memory.tempbanned_from_joining_data = {}
memory.destinations = {}
memory.temporarily_logged_off_characters = {}
memory.temporarily_logged_off_characters_items = {}
-- memory.temporarily_logged_off_characters = {}
-- memory.temporarily_logged_off_characters_items = {}
memory.temporarily_logged_off_player_data = {}
memory.class_renderings = {}
memory.class_auxiliary_data = {}
@ -820,8 +829,8 @@ function Public.initialise_crew(accepted_proposal)
memory.officers_table = {}
memory.classes_table = {} -- stores all unlocked untaken classes
memory.spare_classes = {} -- stores all unlocked taken classes
memory.classes_table = {} -- stores all unlocked taken classes
memory.spare_classes = {} -- stores all unlocked untaken classes
memory.recently_purchased_classes = {} -- stores recently unlocked classes to add it back to available class pool list later
memory.unlocked_classes = {} -- stores all unlocked classes just for GUI (to have consistent order)
memory.available_classes_pool = Classes.initial_class_pool() -- stores classes that can be randomly picked for unlocking
@ -909,8 +918,8 @@ function Public.reset_crew_and_enemy_force(id)
crew_force.set_friend('player', true)
game.forces['player'].set_friend(crew_force, true)
crew_force.set_friend(Common.lobby_force_name, true)
game.forces[Common.lobby_force_name].set_friend(crew_force, true)
crew_force.set_friend(ancient_friendly_force, true)
ancient_friendly_force.set_friend(crew_force, true)
enemy_force.set_friend(ancient_friendly_force, true)

View File

@ -512,7 +512,7 @@ function Public.click(event)
end
if eventname == 'spectator_join_crew' then
Crew.join_crew(player, memory.id)
Crew.join_crew(player)
if memory.run_is_protected and (not Roles.captain_exists()) then
Common.notify_player_expected(player, {'pirates.player_joins_protected_run_with_no_captain'})

View File

@ -696,7 +696,11 @@ function Public.click(event)
if eventname == 'join_spectators' then
local listbox = flow.ongoing_runs.body.ongoing_runs_listbox
Crew.join_spectators(player, tonumber(listbox.get_item(listbox.selected_index)[2]))
-- It was observed that "listbox.get_item(listbox.selected_index)" can produce "Index out of range error"
-- This is to prevent that error.
if listbox.selected_index >= 1 and listbox.selected_index <= #listbox.items then
Crew.join_spectators(player, tonumber(listbox.get_item(listbox.selected_index)[2]))
end
return
end
@ -713,12 +717,13 @@ function Public.click(event)
if listbox.selected_index >= 1 and listbox.selected_index <= #listbox.items then
local crewid = tonumber(listbox.get_item(listbox.selected_index)[2])
local memory = global_memory.crew_memories[crewid]
Memory.set_working_id(crewid)
local memory = Memory.get_crew_memory()
-- If run is private
if global_memory.crew_memories[crewid].run_is_private then
if global_memory.crew_memories[crewid].private_run_password == flow.ongoing_runs.body.password_namefield.text then
Crew.join_crew(player, crewid)
if memory.run_is_private then
if memory.private_run_password == flow.ongoing_runs.body.password_namefield.text then
Crew.join_crew(player)
flow.ongoing_runs.body.join_private_crew_info.visible = false
flow.ongoing_runs.body.password_namefield.visible = false
@ -730,7 +735,7 @@ function Public.click(event)
Common.notify_player_error(player, {'pirates.gui_join_private_run_error_wrong_password'})
end
else
Crew.join_crew(player, crewid)
Crew.join_crew(player)
if memory.run_is_protected and (not Roles.captain_exists()) then
Common.notify_player_expected(player, {'pirates.player_joins_protected_run_with_no_captain'})

View File

@ -86,8 +86,7 @@ function Public.initialise_crew_memory(id) --mostly serves as a dev reference of
memory.playerindex_captain = nil
memory.captain_accrued_time_data = nil
memory.max_players_recorded = nil
memory.temporarily_logged_off_characters = nil
memory.temporarily_logged_off_characters_items = nil
memory.temporarily_logged_off_player_data = nil
memory.speed_boost_characters = nil
@ -125,7 +124,7 @@ function Public.fallthrough_crew_memory() --could make this a metatable, but met
return {
id = 0,
difficulty = 1,
force_name = 'player',
force_name = 'player', -- should match Common.lobby_force_name
boat = {},
destinations = {},
spectatorplayerindices = {},