mirror of
https://github.com/Oarcinae/FactorioScenarioMultiplayerSpawn.git
synced 2025-02-05 13:05:09 +02:00
Trying to polish the new regrowth and player reset features. Will require lots of testing.
This commit is contained in:
parent
01cf0fd922
commit
6df4bbd629
17
control.lua
17
control.lua
@ -234,11 +234,20 @@ end)
|
||||
|
||||
script.on_event(defines.events.on_player_left_game, function(event)
|
||||
ServerWriteFile("player_events", game.players[event.player_index].name .. " left the game." .. "\n")
|
||||
|
||||
local player = game.players[event.player_index]
|
||||
|
||||
-- If players leave early, say goodbye.
|
||||
if ((player.online_time < (global.ocfg.minimum_online_time * TICKS_PER_MINUTE)) and
|
||||
game.players[event.player_index]) then
|
||||
RemoveOrResetPlayer(game.players[event.player_index], true, true)
|
||||
if (player and (player.online_time < (global.ocfg.minimum_online_time * TICKS_PER_MINUTE))) then
|
||||
RemoveOrResetPlayer(player, true, true, true)
|
||||
SendBroadcastMsg(player.name .. "'s base was marked for immediate clean up because they left within "..global.ocfg.minimum_online_time.." minutes of joining.")
|
||||
|
||||
-- Otherwise check if they are on the removal list.
|
||||
else
|
||||
for _,p in pairs(global.ocore.player_removal_list) do
|
||||
if (p == player) then
|
||||
RemoveOrResetPlayer(player, true, false, false)
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
|
@ -30,6 +30,7 @@ function GameOptionsGuiClick(event)
|
||||
if (pIndex ~= 0) then
|
||||
local resetPlayer = event.element.parent.ban_players_dropdown.get_item(pIndex)
|
||||
if (game.players[resetPlayer]) then
|
||||
RemoveOrResetPlayer(player, false, true, true)
|
||||
SeparateSpawnsPlayerCreated(resetPlayer, true)
|
||||
log("Resetting " .. resetPlayer)
|
||||
end
|
||||
|
@ -9,7 +9,7 @@ OARC_STORE_MAP_CATEGORIES =
|
||||
{
|
||||
special_chests = "Special buildings for sharing or monitoring items and energy. This will convert the closest wooden chest (to you) within 16 tiles into a special building of your choice. Make sure to leave enough space! The combinators and accumulators can take up several tiles around them.",
|
||||
special_chunks = "Map features that can be built on the special empty chunks found on the map. You must be standing inside an empty special chunk to be able to build these. Each player can only build one of each type. [color=red]THESE FEATURES ARE PERMANENT AND CAN NOT BE REMOVED![/color]",
|
||||
special_buttons = "Special actions. Like teleporting home. (For now this is the only one...)",
|
||||
special_buttons = "Special actions. Like teleporting home. (For now this is the only one...)"
|
||||
}
|
||||
|
||||
-- N = number already purchased
|
||||
@ -87,6 +87,21 @@ OARC_STORE_MAP_FEATURES =
|
||||
["assembling-machine-1"] = {
|
||||
initial_cost = 10,
|
||||
text="Teleport home."},
|
||||
["crash-site-generator"] = {
|
||||
initial_cost = 5000,
|
||||
solo_force = true,
|
||||
text="DESTROY your base and restart. This allows you to choose a new spawn and will completely remove all your buildings and your force. All technology progress will be reset."
|
||||
},
|
||||
["crash-site-lab-broken"] = {
|
||||
initial_cost = 10000,
|
||||
solo_force = true,
|
||||
text="ABANDON your base and restart. This allows you to choose a new spawn and will move all your buildings to a neutral force. They will still be on the map and can be interacted with, but will not be owned by any player or player force. All radars will be destroyed to help trim map size."
|
||||
},
|
||||
["crash-site-chest-1"] = {
|
||||
initial_cost = 5000,
|
||||
main_force = true,
|
||||
text="Restart your player. This will kick you from the game and delete your player. Any buildings that you created or interacted with (last_user = you) will be destroyed."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -113,6 +128,14 @@ function CreateMapFeatureStoreTab(tab_container, player)
|
||||
{bottom_margin=5, maximal_width = 400, single_line = false})
|
||||
local flow = tab_container.add{name = category, type="flow", direction="horizontal"}
|
||||
for item_name,item in pairs(section) do
|
||||
|
||||
if (item.solo_force and (player.force ~= global.ocfg.main_force)) then
|
||||
goto SKIP_ITEM
|
||||
end
|
||||
if (item.main_force and (player.force == global.ocfg.main_force)) then
|
||||
goto SKIP_ITEM
|
||||
end
|
||||
|
||||
local count = OarcMapFeaturePlayerCountGet(player, category, item_name)
|
||||
local cost = OarcMapFeatureCostScaling(player, category, item_name)
|
||||
local color = "[color=green]"
|
||||
@ -135,6 +158,7 @@ function CreateMapFeatureStoreTab(tab_container, player)
|
||||
else
|
||||
btn.tooltip = item.text.." Cost: "..color..cost.."[/color] [item=coin]"
|
||||
end
|
||||
::SKIP_ITEM::
|
||||
end
|
||||
local line2 = tab_container.add{type="line", direction="horizontal"}
|
||||
line2.style.top_margin = 5
|
||||
@ -241,10 +265,19 @@ function OarcMapFeatureStoreButton(event)
|
||||
elseif (button.name == "centrifuge") then
|
||||
result = RequestSpawnSpecialChunk(player, SpawnAssemblyChunk, button.name)
|
||||
elseif (button.name == "rocket-silo") then
|
||||
result = RequestSpawnSpecialChunk(player, SpawnSiloChunk, button.name)
|
||||
result = RequestSpawnSpecialChunk(player, SpawnSiloChunk, button.name)
|
||||
elseif (button.name == "assembling-machine-1") then
|
||||
SendPlayerToSpawn(player)
|
||||
result = true
|
||||
elseif (button.name == "crash-site-generator") then
|
||||
DestroyForce(player)
|
||||
result = true
|
||||
elseif (button.name == "crash-site-lab-broken") then
|
||||
AbandonForce(player)
|
||||
result = true
|
||||
elseif (button.name == "crash-site-chest-1") then
|
||||
KickAndMarkPlayerForRemoval(player)
|
||||
result = true
|
||||
end
|
||||
|
||||
-- On success, we deduct money
|
||||
|
@ -381,9 +381,9 @@ end
|
||||
-- Set all forces to ceasefire
|
||||
function SetCeaseFireBetweenAllForces()
|
||||
for name,team in pairs(game.forces) do
|
||||
if name ~= "neutral" and name ~= "enemy" then
|
||||
if name ~= "neutral" and name ~= "enemy" and name ~= global.ocore.abandoned_force then
|
||||
for x,y in pairs(game.forces) do
|
||||
if x ~= "neutral" and x ~= "enemy" then
|
||||
if x ~= "neutral" and x ~= "enemy" and name ~= global.ocore.abandoned_force then
|
||||
team.set_cease_fire(x,true)
|
||||
end
|
||||
end
|
||||
@ -394,9 +394,9 @@ end
|
||||
-- Set all forces to friendly
|
||||
function SetFriendlyBetweenAllForces()
|
||||
for name,team in pairs(game.forces) do
|
||||
if name ~= "neutral" and name ~= "enemy" then
|
||||
if name ~= "neutral" and name ~= "enemy" and name ~= global.ocore.abandoned_force then
|
||||
for x,y in pairs(game.forces) do
|
||||
if x ~= "neutral" and x ~= "enemy" then
|
||||
if x ~= "neutral" and x ~= "enemy" and name ~= global.ocore.abandoned_force then
|
||||
team.set_friend(x,true)
|
||||
end
|
||||
end
|
||||
|
@ -318,6 +318,30 @@ function WorldEaterSingleStep()
|
||||
return -- Chunk isn't in our map so we don't care?
|
||||
end
|
||||
|
||||
-- Search for any abandoned radars and destroy them?
|
||||
local entities = game.surfaces[GAME_SURFACE_NAME].find_entities_filtered{area=next_chunk.area,
|
||||
force={global.ocore.abandoned_force},
|
||||
name="radar"}
|
||||
for k,v in pairs(entities) do
|
||||
v.die(nil)
|
||||
end
|
||||
|
||||
-- Search for any entities with _DESTROYED_ force and kill them.
|
||||
entities = game.surfaces[GAME_SURFACE_NAME].find_entities_filtered{area=next_chunk.area,
|
||||
force={global.ocore.destroyed_force}}
|
||||
for k,v in pairs(entities) do
|
||||
v.die(nil)
|
||||
end
|
||||
|
||||
-- Text for visual debugging.
|
||||
rendering.draw_text{text="WORLD EATER",
|
||||
surface=game.surfaces[GAME_SURFACE_NAME],
|
||||
target=GetCenterTilePosFromChunkPos(next_chunk),
|
||||
color={0.7,0.7,0.7,0.7},
|
||||
scale=1,
|
||||
font="compi",
|
||||
time_to_live=60*3}
|
||||
|
||||
-- If the chunk isn't marked permament, then check if we can remove it
|
||||
local c_timer = global.rg.map[next_chunk.x][next_chunk.y]
|
||||
if (c_timer == -1) then
|
||||
|
@ -93,6 +93,12 @@ function InitSpawnGlobalsAndForces()
|
||||
-- This is what any new player is assigned to when they join, even before they spawn.
|
||||
local main_force = CreateForce(global.ocfg.main_force)
|
||||
main_force.set_spawn_position({x=0,y=0}, GAME_SURFACE_NAME)
|
||||
|
||||
-- Special forces for when players with their own force want a reset.
|
||||
global.ocore.abandoned_force = "_ABANDONED_"
|
||||
global.ocore.destroyed_force = "_DESTROYED_"
|
||||
game.create_force(global.ocore.abandoned_force)
|
||||
game.create_force(global.ocore.destroyed_force)
|
||||
end
|
||||
|
||||
|
||||
@ -115,14 +121,11 @@ function SeparateSpawnsPlayerCreated(player_index, clear_inv)
|
||||
SetOarcGuiTabEnabled(player, OARC_SPAWN_CTRL_GUI_NAME, false)
|
||||
SwitchOarcGuiTab(player, OARC_GAME_OPTS_GUI_TAB_NAME)
|
||||
|
||||
-- If they are NOT a new player, reset them.
|
||||
if (player.force.name ~= "player") then
|
||||
RemoveOrResetPlayer(player, false, true)
|
||||
else
|
||||
-- If they are a new player, put them on the main force.
|
||||
if (player.force.name == "player") then
|
||||
player.force = global.ocfg.main_force
|
||||
end
|
||||
|
||||
|
||||
-- Reset counts for map feature usage for this player.
|
||||
OarcMapFeaturePlayerCreatedEvent(player)
|
||||
|
||||
@ -526,8 +529,45 @@ end
|
||||
|
||||
--]]
|
||||
|
||||
|
||||
function DestroyForce(player)
|
||||
local player_old_force = player.force
|
||||
|
||||
player.force = global.ocfg.main_force
|
||||
|
||||
if ((#player_old_force.players <= 1) and (player_old_force.name ~= global.ocfg.main_force)) then
|
||||
SendBroadcastMsg("Team " .. player_old_force.name .. " has been destroyed! All buildings will slowly be destroyed now.")
|
||||
log("DestroyForce - FORCE DESTROYED: " .. player_old_force.name)
|
||||
game.merge_forces(player_old_force, global.ocore.destroyed_force)
|
||||
end
|
||||
|
||||
RemoveOrResetPlayer(player, false, false, false)
|
||||
end
|
||||
|
||||
function AbandonForce(player)
|
||||
local player_old_force = player.force
|
||||
|
||||
player.force = global.ocfg.main_force
|
||||
|
||||
if ((#player_old_force.players <= 1) and (player_old_force.name ~= global.ocfg.main_force)) then
|
||||
SendBroadcastMsg("Team " .. player_old_force.name .. " has been abandoned!")
|
||||
log("AbandonForce - FORCE ABANDONED: " .. player_old_force.name)
|
||||
game.merge_forces(player_old_force, global.ocore.abandoned_force)
|
||||
end
|
||||
|
||||
RemoveOrResetPlayer(player, false, false, false)
|
||||
end
|
||||
|
||||
function KickAndMarkPlayerForRemoval(player)
|
||||
game.kick_player(player, "KickAndMarkPlayerForRemoval")
|
||||
if (not global.ocore.player_removal_list) then
|
||||
global.ocore.player_removal_list = {}
|
||||
end
|
||||
table.insert(global.ocore.player_removal_list, player)
|
||||
end
|
||||
|
||||
-- Call this if a player leaves the game early (or a player wants an early game reset)
|
||||
function RemoveOrResetPlayer(player, remove_player, remove_force)
|
||||
function RemoveOrResetPlayer(player, remove_player, remove_force, remove_base)
|
||||
if (not player) then
|
||||
log("ERROR - CleanupPlayer on NIL Player!")
|
||||
return
|
||||
@ -543,12 +583,11 @@ function RemoveOrResetPlayer(player, remove_player, remove_force)
|
||||
CleanupPlayerGlobals(player.name) -- Except global.ocore.uniqueSpawns
|
||||
|
||||
-- Clear their unique spawn (if they have one)
|
||||
UniqueSpawnCleanupRemove(player.name) -- Specifically global.ocore.uniqueSpawns
|
||||
UniqueSpawnCleanupRemove(player.name, remove_base) -- Specifically global.ocore.uniqueSpawns
|
||||
|
||||
-- Remove a force if this player created it and they are the only one on it
|
||||
if (remove_force) then
|
||||
if ((#player_old_force.players == 0) and (player_old_force.name ~= global.ocfg.main_force)) then
|
||||
SendBroadcastMsg("FORCE REMOVED?!")
|
||||
log("RemoveOrResetPlayer - FORCE REMOVED: " .. player_old_force.name)
|
||||
game.merge_forces(player_old_force, "neutral")
|
||||
end
|
||||
@ -560,7 +599,7 @@ function RemoveOrResetPlayer(player, remove_player, remove_force)
|
||||
end
|
||||
end
|
||||
|
||||
function UniqueSpawnCleanupRemove(playerName)
|
||||
function UniqueSpawnCleanupRemove(playerName, cleanup)
|
||||
if (global.ocore.uniqueSpawns[playerName] == nil) then return end -- Safety
|
||||
log("UniqueSpawnCleanupRemove - " .. playerName)
|
||||
|
||||
@ -576,7 +615,7 @@ function UniqueSpawnCleanupRemove(playerName)
|
||||
end
|
||||
|
||||
-- Unused Chunk Removal mod (aka regrowth)
|
||||
if (global.ocfg.enable_abandoned_base_removal and (not nearOtherSpawn) and global.ocfg.enable_regrowth) then
|
||||
if (cleanup and global.ocfg.enable_abandoned_base_removal and (not nearOtherSpawn) and global.ocfg.enable_regrowth) then
|
||||
|
||||
if (global.ocore.uniqueSpawns[playerName].vanilla) then
|
||||
log("Returning a vanilla spawn back to available.")
|
||||
@ -587,10 +626,6 @@ function UniqueSpawnCleanupRemove(playerName)
|
||||
|
||||
RegrowthMarkAreaForRemoval(spawnPos, math.ceil(global.ocfg.spawn_config.gen_settings.land_area_tiles/CHUNK_SIZE))
|
||||
TriggerCleanup()
|
||||
SendBroadcastMsg(playerName .. "'s base was marked for immediate clean up because they left within "..global.ocfg.minimum_online_time.." minutes of joining.")
|
||||
|
||||
else
|
||||
SendBroadcastMsg(playerName .. " base was abandoned because they left within "..global.ocfg.minimum_online_time.." minutes of joining.")
|
||||
end
|
||||
|
||||
global.ocore.uniqueSpawns[playerName] = nil
|
||||
@ -890,7 +925,7 @@ function CreateForce(force_name)
|
||||
-- Check if force already exists
|
||||
if (game.forces[force_name] ~= nil) then
|
||||
log("Force already exists!")
|
||||
return game.forces[global.ocfg.main_force]
|
||||
return CreateForce(force_name .. "_") -- Append a character to make the force name unique.
|
||||
|
||||
-- Create a new force
|
||||
elseif (TableLength(game.forces) < MAX_FORCES) then
|
||||
|
Loading…
x
Reference in New Issue
Block a user