1
0
mirror of https://github.com/Oarcinae/FactorioScenarioMultiplayerSpawn.git synced 2025-03-03 14:42:27 +02:00

Merge pull request #102 from Oarcinae/restricted_build

Restricted build & GUI rework
This commit is contained in:
Oarcinae 2019-08-11 21:37:19 -04:00 committed by GitHub
commit b15ab65123
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 829 additions and 998 deletions

View File

@ -2,12 +2,12 @@
-- Mar 2019
-- Oarc's Separated Spawn Scenario
--
--
-- I wanted to create a scenario that allows you to spawn in separate locations
-- From there, I ended up adding a bunch of other minor/major features
--
--
-- Credit:
-- Tags - Taken from WOGs scenario
-- Tags - Taken from WOGs scenario
-- Rocket Silo - Taken from Frontier as an idea
--
-- Feel free to re-use anything you want. It would be nice to give me credit
@ -30,7 +30,6 @@ require("lib/oarc_utils")
require("lib/frontier_silo")
require("lib/tag")
require("lib/game_opts")
require("lib/regrowth_map")
require("lib/player_list")
require("lib/rocket_launch")
require("lib/admin_commands")
@ -50,15 +49,18 @@ require("lib/oarc_global_cfg.lua")
require("lib/separate_spawns")
require("lib/separate_spawns_guis")
require("lib/oarc_gui_tabs")
-- Create a new surface so we can modify map settings at the start.
GAME_SURFACE_NAME="oarc"
--------------------------------------------------------------------------------
-- ALL EVENT HANLDERS ARE HERE IN ONE PLACE!
--------------------------------------------------------------------------------
----------------------------------------
-- On Init - only runs once the first
-- On Init - only runs once the first
-- time the game starts
----------------------------------------
script.on_init(function(event)
@ -72,9 +74,6 @@ script.on_init(function(event)
-- MUST be before other stuff, but after surface creation.
InitSpawnGlobalsAndForces()
-- Regardless of whether it's enabled or not, it's good to have this init.
OarcRegrowthInit()
-- Frontier Silo Area Generation
if (global.ocfg.frontier_rocket_silo) then
SpawnSilosAndGenerateSiloAreas()
@ -103,10 +102,6 @@ end)
----------------------------------------
script.on_event(defines.events.on_chunk_generated, function(event)
if global.ocfg.enable_regrowth then
OarcRegrowthChunkGenerate(event.area.left_top)
end
if global.ocfg.enable_undecorator then
UndecorateOnChunkGenerate(event)
end
@ -125,6 +120,10 @@ end)
-- Gui Click
----------------------------------------
script.on_event(defines.events.on_gui_click, function(event)
-- Don't interfere with other mod related stuff.
if (event.element.get_mod() ~= nil) then return end
if global.ocfg.enable_tags then
TagGuiClick(event)
end
@ -142,8 +141,9 @@ script.on_event(defines.events.on_gui_click, function(event)
BuddySpawnRequestMenuClick(event)
SharedSpawnJoinWaitMenuClick(event)
ClickOarcGuiButton(event)
GameOptionsGuiClick(event)
RocketGuiClick(event)
end)
script.on_event(defines.events.on_gui_checked_state_changed, function (event)
@ -151,47 +151,36 @@ script.on_event(defines.events.on_gui_checked_state_changed, function (event)
SpawnCtrlGuiOptionsSelect(event)
end)
script.on_event(defines.events.on_gui_selected_tab_changed, function (event)
TabChangeOarcGui(event)
end)
----------------------------------------
-- Player Events
----------------------------------------
script.on_event(defines.events.on_player_joined_game, function(event)
CreateGameOptionsGui(event)
PlayerJoinedMessages(event)
if global.ocfg.enable_player_list then
CreatePlayerListGui(event)
end
if global.ocfg.enable_tags then
CreateTagGui(event)
end
if global.satellite_sent then
CreateRocketGui(game.players[event.player_index])
end
ServerWriteFile("player_events", game.players[event.player_index].name .. " joined the game." .. "\n")
end)
script.on_event(defines.events.on_player_created, function(event)
local player = game.players[event.player_index]
-- Move the player to the game surface immediately.
-- May change this to Lobby in the future.
game.players[event.player_index].teleport({x=0,y=0}, GAME_SURFACE_NAME)
player.teleport({x=0,y=0}, GAME_SURFACE_NAME)
if global.ocfg.enable_long_reach then
GivePlayerLongReach(game.players[event.player_index])
GivePlayerLongReach(player)
end
SeparateSpawnsPlayerCreated(event.player_index)
InitOarcGuiTabs(player)
end)
script.on_event(defines.events.on_player_respawned, function(event)
SeparateSpawnsPlayerRespawned(event)
PlayerRespawnItems(event)
if global.ocfg.enable_long_reach then
@ -212,10 +201,6 @@ script.on_event(defines.events.on_built_entity, function(event)
Autofill(event)
end
if global.ocfg.enable_regrowth then
OarcRegrowthOffLimits(event.created_entity.position, 2)
end
if ENABLE_ANTI_GRIEFING then
SetItemBlueprintTimeToLive(event)
end
@ -223,6 +208,7 @@ script.on_event(defines.events.on_built_entity, function(event)
if global.ocfg.frontier_rocket_silo then
BuildSiloAttempt(event)
end
end)
@ -231,25 +217,16 @@ end)
-- place items that don't count as player_built and robot_built.
-- Specifically FARL.
----------------------------------------
script.on_event(defines.events.script_raised_built, function(event)
if global.ocfg.enable_regrowth then
OarcRegrowthOffLimits(event.entity.position, 2)
end
end)
-- script.on_event(defines.events.script_raised_built, function(event)
-- end)
----------------------------------------
-- On tick events. Stuff that needs to happen at regular intervals.
-- Delayed events, delayed spawns, regrowth logic...
-- Delayed events, delayed spawns, ...
----------------------------------------
script.on_event(defines.events.on_tick, function(event)
if global.ocfg.enable_regrowth then
OarcRegrowthOnTick()
end
if global.ocfg.enable_abandoned_base_removal then
OarcRegrowthForceRemovalOnTick()
end
DelayedSpawnOnTick()
@ -260,39 +237,19 @@ script.on_event(defines.events.on_tick, function(event)
end)
script.on_event(defines.events.on_sector_scanned, function (event)
if global.ocfg.enable_regrowth then
OarcRegrowthSectorScan(event)
end
end)
-- script.on_event(defines.events.on_sector_scanned, function (event)
-- end)
----------------------------------------
-- Refreshes regrowth timers around an active timer
-- Refresh areas where stuff is built, and mark any chunks with player
-- built stuff as permanent.
--
----------------------------------------
script.on_event(defines.events.on_robot_built_entity, function (event)
if global.ocfg.enable_regrowth then
OarcRegrowthOffLimits(event.created_entity.position, 2)
end
if global.ocfg.frontier_rocket_silo then
BuildSiloAttempt(event)
end
end)
-- I disabled this because it's too much overhead for too little gain!
-- script.on_event(defines.events.on_player_mined_entity, function(event)
-- if global.ocfg.enable_regrowth then
-- OarcRegrowthCheckChunkEmpty(event)
-- end
-- end)
-- script.on_event(defines.events.on_robot_mined_entity, function(event)
-- if global.ocfg.enable_regrowth then
-- OarcRegrowthCheckChunkEmpty(event)
-- end
-- end)
----------------------------------------
-- Shared chat, so you don't have to type /s
@ -314,13 +271,13 @@ end)
-- This is where you can permanently remove researched techs
----------------------------------------
script.on_event(defines.events.on_research_finished, function(event)
-- Never allows players to build rocket-silos in "frontier" mode.
if global.ocfg.frontier_rocket_silo and not global.ocfg.frontier_allow_build then
RemoveRecipe(event.research.force, "rocket-silo")
end
if global.ocfg.lock_goodies_rocket_launch and
if global.ocfg.lock_goodies_rocket_launch and
(not global.satellite_sent or not global.satellite_sent[event.research.force.name]) then
RemoveRecipe(event.research.force, "productivity-module-3")
RemoveRecipe(event.research.force, "speed-module-3")

View File

@ -1,7 +1,7 @@
-- example-config.lua (Rename this file to config.lua to use it)
-- Apr 2019
-- July 24 2019 (updated on)
-- Configuration Options
--
--
-- You should be able to leave most of the settings here as defaults.
-- The only thing you definitely want to change are the welcome messages.
@ -63,7 +63,7 @@ ENABLE_LONGREACH = true
ENABLE_AUTOFILL = true
-- Enable vanilla loaders
ENABLE_LOADERS = true
ENABLE_LOADERS = false
-- Enable Playerlist
ENABLE_PLAYER_LIST = true
@ -72,15 +72,8 @@ PLAYER_LIST_OFFLINE_PLAYERS = true -- List offline players as well.
-- Enable shared vision between teams (all teams are COOP regardless)
ENABLE_SHARED_TEAM_VISION = true
-- Enable map regrowth, see regrowth_map.lua for more info.
-- Eseentially clears up map area that was explored but not used every hour.
-- Helps reduce save file size.
ENABLE_REGROWTH = false
-- If you have regrowth enabled, this should also be enabled.
-- It removes bases for players that join and leave the game quickly.
-- This can also be used without enabling regrowth.
ENABLE_ABANDONED_BASE_REMOVAL = true
-- Only works if you have the Unused Chunk Removal mod installed.
ENABLE_ABANDONED_BASE_REMOVAL = false
-- Enable the new 0.17 research queue by default for all forces.
ENABLE_RESEARCH_QUEUE = true
@ -92,7 +85,7 @@ LOCK_GOODIES_UNTIL_ROCKET_LAUNCH = false
--------------------------------------------------------------------------------
-- MAP CONFIGURATION OPTIONS
-- In past versions I had a way to config map settings here to be used for cmd
-- line launching, but now you should just be using --map-gen-settings and
-- line launching, but now you should just be using --map-gen-settings and
-- --map-settings option since it works with --start-server-load-scenario
-- Read the README.md file for instructions.
--------------------------------------------------------------------------------
@ -107,10 +100,6 @@ LOCK_GOODIES_UNTIL_ROCKET_LAUNCH = false
-- If you're trying out the vanilla spawning, you might want to disable this.
OARC_MODIFIED_ENEMY_SPAWNING = true
--------------------------------------------------------------------------------
-- Spawn Options
--------------------------------------------------------------------------------
---------------------------------------
-- Starting Items
---------------------------------------
@ -147,7 +136,7 @@ PLAYER_RESPAWN_START_ITEMS = {
-- This is the radius, in chunks, that a spawn area is from any other generated
-- chunks. It ensures the spawn area isn't too near generated/explored/existing
-- area. The larger you make this, the further away players will spawn from
-- area. The larger you make this, the further away players will spawn from
-- generated map area (even if it is not visible on the map!).
CHECK_SPAWN_UNGENERATED_CHUNKS_RADIUS = 10
@ -187,7 +176,7 @@ OARC_CFG = {
-- Misc spawn related config.
gen_settings = {
-- THIS IS WHAT SETS THE SPAWN CIRCLE SIZE!
-- Create a circle of land area for the spawn
-- If you make this much bigger than a few chunks, good luck.
@ -262,35 +251,35 @@ OARC_CFG = {
-- If you are running with mods like bobs/angels, you'll want to customize this.
resource_tiles =
{
["iron-ore"] =
["iron-ore"] =
{
amount = 1500,
size = 16,
x_offset = -29,
y_offset = 16
},
["copper-ore"] =
["copper-ore"] =
{
amount = 1500,
size = 14,
x_offset = -28,
y_offset = -3
},
["stone"] =
["stone"] =
{
amount = 1000,
size = 12,
x_offset = -27,
y_offset = -34
},
["coal"] =
["coal"] =
{
amount = 1500,
size = 12,
x_offset = -27,
y_offset = -20
}--,
-- ["uranium-ore"] =
-- ["uranium-ore"] =
-- {
-- amount = 0,
-- size = 0,
@ -317,14 +306,14 @@ OARC_CFG = {
-- See https://github.com/Oarcinae/FactorioScenarioMultiplayerSpawn/issues/11#issuecomment-479724909
-- for full examples.
},
-- Special resource patches like oil
resource_patches =
{
["crude-oil"] =
["crude-oil"] =
{
num_patches = 2,
amount = 3000000,
amount = 900000,
x_offset_start = -3,
y_offset_start = 48,
x_offset_next = 6,
@ -421,3 +410,10 @@ ENABLE_ANTI_GRIEFING = true
-- Makes blueprint ghosts dissapear if they have been placed longer than this
GHOST_TIME_TO_LIVE = 0 * TICKS_PER_MINUTE -- set to 0 for infinite ghost life
--------------------------------------------------------------------------------
-- This turns on writing chat and certain events to specific files so that I can
-- use that for discord integration. I suggest you leave this off unless you
-- know what you are doing.
--------------------------------------------------------------------------------
ENABLE_SERVER_WRITE_FILES = false

View File

@ -11,13 +11,13 @@ require("lib/oarc_utils")
function SpawnSilosAndGenerateSiloAreas()
-- Special silo islands mode "boogaloo"
if (global.ocfg.silo_islands) then
local num_spawns = #global.vanillaSpawns
local new_spawn_list = {}
-- Pick out every OTHER vanilla spawn for the rocket silos.
for k,v in pairs(global.vanillaSpawns) do
if ((k <= num_spawns/2) and (k%2==1)) then
@ -96,15 +96,20 @@ local function CreateRocketSilo(surface, siloPosition, force)
-- Set tiles below the silo
tiles = {}
i = 1
for dx = -6,6 do
for dy = -6,6 do
if ((dx % 2 == 0) or (dx % 2 == 0)) then
tiles[i] = {name = "concrete", position = {siloPosition.x+dx, siloPosition.y+dy}}
for dx = -10,10 do
for dy = -10,10 do
if (game.active_mods["oarc-restricted-build"]) then
table.insert(tiles, {name = global.ocfg.locked_build_area_tile,
position = {siloPosition.x+dx, siloPosition.y+dy}})
else
tiles[i] = {name = "hazard-concrete-left", position = {siloPosition.x+dx, siloPosition.y+dy}}
if ((dx % 2 == 0) or (dx % 2 == 0)) then
table.insert(tiles, {name = "concrete",
position = {siloPosition.x+dx, siloPosition.y+dy}})
else
table.insert(tiles, {name = "hazard-concrete-left",
position = {siloPosition.x+dx, siloPosition.y+dy}})
end
end
i=i+1
end
end
surface.set_tiles(tiles, true)
@ -121,11 +126,14 @@ local function CreateRocketSilo(surface, siloPosition, force)
{position=siloPosition, text="Rocket Silo",
icon={type="item",name="rocket-silo"}})
-- Make silo safe from being removed by regrowth
-- if global.ocfg.enable_regrowth then
OarcRegrowthOffLimits(siloPosition, 5)
-- end
-- Make silo safe from being removed.
if (game.active_mods["unused-chunk-removal"]) then
remote.call("oarc_regrowth",
"area_offlimits_tilepos",
surface.index,
siloPosition,
5)
end
if ENABLE_SILO_BEACONS then
PhilipsBeacons(surface, siloPosition, game.forces[global.ocfg.main_force])
@ -133,13 +141,13 @@ local function CreateRocketSilo(surface, siloPosition, force)
if ENABLE_SILO_RADAR then
PhilipsRadar(surface, siloPosition, game.forces[global.ocfg.main_force])
end
end
-- Generates all rocket silos, should be called after the areas are generated
-- Includes a crop circle
function GenerateAllSilos(surface)
function GenerateAllSilos(surface)
-- Create each silo in the list
for idx,siloPos in pairs(global.siloPosition) do
CreateRocketSilo(surface, siloPos, global.ocfg.main_force)
@ -152,7 +160,13 @@ function BuildSiloAttempt(event)
-- Validation
if (event.created_entity == nil) then return end
if (event.created_entity.name ~= "rocket-silo") then return end
local e_name = event.created_entity.name
if (event.created_entity.name == "entity-ghost") then
e_name =event.created_entity.ghost_name
end
if (e_name ~= "rocket-silo") then return end
-- Check if it's in the right area.
local epos = event.created_entity.position
@ -167,7 +181,11 @@ function BuildSiloAttempt(event)
-- If we get here, means it wasn't in a valid position. Need to remove it.
if (event.created_entity.last_user ~= nil) then
FlyingText("Can't build silo here! Check the map!", epos, my_color_red, event.created_entity.surface)
event.created_entity.last_user.mine_entity(event.created_entity, true)
if (event.created_entity.name == "entity-ghost") then
event.created_entity.destroy()
else
event.created_entity.last_user.mine_entity(event.created_entity, true)
end
else
log("ERROR! Rocket-silo had no valid last user?!?!")
end
@ -183,7 +201,7 @@ function GenerateRocketSiloChunk(event)
local chunkAreaCenter = {x=chunkArea.left_top.x+(CHUNK_SIZE/2),
y=chunkArea.left_top.y+(CHUNK_SIZE/2)}
for idx,siloPos in pairs(global.siloPosition) do
local safeArea = {left_top=
{x=siloPos.x-(CHUNK_SIZE*4),
@ -191,7 +209,7 @@ function GenerateRocketSiloChunk(event)
right_bottom=
{x=siloPos.x+(CHUNK_SIZE*4),
y=siloPos.y+(CHUNK_SIZE*4)}}
-- Clear enemies directly next to the rocket
if CheckIfInArea(chunkAreaCenter,safeArea) then
@ -206,7 +224,7 @@ function GenerateRocketSiloChunk(event)
RemoveDecorationsArea(surface, chunkArea)
-- Create rocket silo
CreateCropOctagon(surface, siloPos, chunkArea, CHUNK_SIZE*2)
CreateCropOctagon(surface, siloPos, chunkArea, CHUNK_SIZE*2, "grass-1")
end
end
end
@ -344,7 +362,7 @@ function PhilipsBeacons(surface, siloPos, force)
end
function PhilipsRadar(surface, siloPos, force)
local radar = surface.create_entity{name = "solar-panel", position = {siloPos.x-43, siloPos.y+3}, force = force}
radar.destructible = false
local radar = surface.create_entity{name = "solar-panel", position = {siloPos.x-43, siloPos.y-3}, force = force}

View File

@ -7,136 +7,11 @@ require("config")
require("lib/oarc_utils")
require("lib/separate_spawns")
function CreateGameOptionsGui(event)
local player = game.players[event.player_index]
if mod_gui.get_button_flow(player).game_options == nil then
mod_gui.get_button_flow(player).add{name="game_options", type="button", caption="Info", style=mod_gui.button_style}
end
end
local function ExpandGameOptionsGui(player)
local frame = mod_gui.get_frame_flow(player)["game_options_panel"]
if (frame) then
frame.destroy()
else
local frame = mod_gui.get_frame_flow(player).add{type="frame",
name="game_options_panel",
caption="Server Info:",
direction="vertical"}
-- General Server Info:
AddLabel(frame, "info_1", global.ocfg.welcome_msg, my_longer_label_style)
AddLabel(frame, "info_2", global.ocfg.server_rules, my_longer_label_style)
AddLabel(frame, "info_3", global.ocfg.server_contact, my_longer_label_style)
AddSpacer(frame, "info_spacer1")
-- Enemy Settings:
local enemy_expansion_txt = "disabled"
if game.map_settings.enemy_expansion.enabled then enemy_expansion_txt = "enabled" end
local enemy_text="Server Run Time: " .. formattime_hours_mins(game.tick) .. "\n" ..
"Current Evolution: " .. string.format("%.4f", game.forces["enemy"].evolution_factor) .. "\n" ..
"Enemy evolution time factor: " .. game.map_settings.enemy_evolution.time_factor .. "\n" ..
"Enemy evolution pollution factor: " .. game.map_settings.enemy_evolution.pollution_factor .. "\n" ..
"Enemy evolution destroy factor: " .. game.map_settings.enemy_evolution.destroy_factor .. "\n" ..
"Enemy expansion is " .. enemy_expansion_txt
AddLabel(frame, "enemy_info", enemy_text, my_longer_label_style)
AddSpacer(frame, "enemy_info_spacer1")
-- Game Mode:
AddLabel(frame, "core_mod_en", "Core game mode (separate spawns) is enabled.", my_longer_label_style)
-- Soft Mods:
local soft_mods_string = "Oarc Core"
if (global.ocfg.enable_undecorator) then
soft_mods_string = soft_mods_string .. ", Undecorator"
end
if (global.ocfg.enable_tags) then
soft_mods_string = soft_mods_string .. ", Tags"
end
if (global.ocfg.enable_long_reach) then
soft_mods_string = soft_mods_string .. ", Long Reach"
end
if (global.ocfg.enable_autofill) then
soft_mods_string = soft_mods_string .. ", Auto Fill"
end
if (global.ocfg.enable_player_list) then
soft_mods_string = soft_mods_string .. ", Player List"
end
local game_info_str = "Soft Mods Enabled: " .. soft_mods_string
-- Spawn options:
if (global.ocfg.enable_separate_teams) then
game_info_str = game_info_str.."\n".."You are allowed to spawn on your own team (have your own research tree). All teams are friendly!"
end
if (global.ocfg.enable_vanilla_spawns) then
game_info_str = game_info_str.."\n".."You are spawned in a default style starting area."
else
game_info_str = game_info_str.."\n".."You are spawned with a fix set of starting resources."
if (global.ocfg.enable_buddy_spawn) then
game_info_str = game_info_str.."\n".."You can chose to spawn alongside a buddy if you spawn together at the same time."
end
end
if (global.ocfg.enable_shared_spawns) then
game_info_str = game_info_str.."\n".."Spawn hosts may choose to share their spawn and allow other players to join them."
end
if (global.ocfg.enable_separate_teams and global.ocfg.enable_shared_team_vision) then
game_info_str = game_info_str.."\n".."Everyone (all teams) have shared vision."
end
if (global.ocfg.frontier_rocket_silo) then
game_info_str = game_info_str.."\n".."Silos are only placeable in certain areas on the map!"
end
if (global.ocfg.enable_regrowth) then
game_info_str = game_info_str.."\n".."Old parts of the map will slowly be deleted over time (chunks without any player buildings)."
end
if (ENABLE_POWER_ARMOR_QUICK_START) then
game_info_str = game_info_str.."\n".."Power armor quick start enabled."
end
if (global.ocfg.lock_goodies_rocket_launch) then
game_info_str = game_info_str.."\n".."Artillery/Nukes/ArmorMK2 tech and Prod/Speed 3 module recipes are locked until you launch a rocket!"
end
AddLabel(frame, "game_info_label", game_info_str, my_longer_label_style)
if (global.ocfg.enable_abandoned_base_removal) then
AddLabel(frame, "leave_warning_msg", "If you leave within " .. global.ocfg.minimum_online_time .. " minutes of joining, your base and character will be deleted.", my_longer_label_style)
frame.leave_warning_msg.style.font_color=my_color_red
end
-- Ending Spacer
AddSpacer(frame, "end_spacer")
-- ADMIN CONTROLS
if (player.admin) then
player_list = {}
for _,player in pairs(game.connected_players) do
table.insert(player_list, player.name)
end
frame.add{name = "ban_players_dropdown",
type = "drop-down",
items = player_list}
frame.add{name="ban_player", type="button", caption="Ban Player"}
frame.add{name="restart_player", type="button", caption="Restart Player"}
-- AddLabel(frame, "restart_warning_msg", "You might CRASH the scenario by using Restart Player. Not 100% tested yet. Will not work if player has any center gui visible.", my_longer_label_style)
-- frame.restart_warning_msg.style.font_color=my_color_red
end
end
end
function GameOptionsGuiClick(event)
function GameOptionsGuiClick(event)
if not (event and event.element and event.element.valid) then return end
local player = game.players[event.element.player_index]
local name = event.element.name
if (name == "game_options") then
ExpandGameOptionsGui(player)
end
if (name == "ban_player") then
local pIndex = event.element.parent.ban_players_dropdown.selected_index
@ -161,3 +36,106 @@ function GameOptionsGuiClick(event)
end
end
end
-- Used by AddOarcGuiTab
function CreateGameOptionsTab(tab_container, player)
-- General Server Info:
AddLabel(tab_container, "info_1", global.ocfg.welcome_msg, my_longer_label_style)
AddLabel(tab_container, "info_2", global.ocfg.server_rules, my_longer_label_style)
AddLabel(tab_container, "info_3", global.ocfg.server_contact, my_longer_label_style)
AddSpacerLine(tab_container)
-- Enemy Settings:
local enemy_expansion_txt = "disabled"
if game.map_settings.enemy_expansion.enabled then enemy_expansion_txt = "enabled" end
local enemy_text="Server Run Time: " .. formattime_hours_mins(game.tick) .. "\n" ..
"Current Evolution: " .. string.format("%.4f", game.forces["enemy"].evolution_factor) .. "\n" ..
"Enemy evolution time factor: " .. game.map_settings.enemy_evolution.time_factor .. "\n" ..
"Enemy evolution pollution factor: " .. game.map_settings.enemy_evolution.pollution_factor .. "\n" ..
"Enemy evolution destroy factor: " .. game.map_settings.enemy_evolution.destroy_factor .. "\n" ..
"Enemy expansion is " .. enemy_expansion_txt
AddLabel(tab_container, "enemy_info", enemy_text, my_longer_label_style)
AddSpacerLine(tab_container)
-- Game Mode:
AddLabel(tab_container, "core_mod_en", "Core game mode (separate spawns) is enabled.", my_longer_label_style)
-- Soft Mods:
local soft_mods_string = "Oarc Core"
if (global.ocfg.enable_undecorator) then
soft_mods_string = soft_mods_string .. ", Undecorator"
end
if (global.ocfg.enable_tags) then
soft_mods_string = soft_mods_string .. ", Tags"
end
if (global.ocfg.enable_long_reach) then
soft_mods_string = soft_mods_string .. ", Long Reach"
end
if (global.ocfg.enable_autofill) then
soft_mods_string = soft_mods_string .. ", Auto Fill"
end
if (global.ocfg.enable_player_list) then
soft_mods_string = soft_mods_string .. ", Player List"
end
local game_info_str = "Soft Mods Enabled: " .. soft_mods_string
-- Spawn options:
if (global.ocfg.enable_separate_teams) then
game_info_str = game_info_str.."\n".."You are allowed to spawn on your own team (have your own research tree). All teams are friendly!"
end
if (global.ocfg.enable_vanilla_spawns) then
game_info_str = game_info_str.."\n".."You are spawned in a default style starting area."
else
game_info_str = game_info_str.."\n".."You are spawned with a fix set of starting resources."
if (global.ocfg.enable_buddy_spawn) then
game_info_str = game_info_str.."\n".."You can chose to spawn alongside a buddy if you spawn together at the same time."
end
end
if (global.ocfg.enable_shared_spawns) then
game_info_str = game_info_str.."\n".."Spawn hosts may choose to share their spawn and allow other players to join them."
end
if (global.ocfg.enable_separate_teams and global.ocfg.enable_shared_team_vision) then
game_info_str = game_info_str.."\n".."Everyone (all teams) have shared vision."
end
if (global.ocfg.frontier_rocket_silo) then
game_info_str = game_info_str.."\n".."Silos are only placeable in certain areas on the map!"
end
if (game.active_mods["unused-chunk-removal"]) then
game_info_str = game_info_str.."\n".."Old parts of the map will slowly be deleted over time (chunks without any player buildings)."
end
if (ENABLE_POWER_ARMOR_QUICK_START) then
game_info_str = game_info_str.."\n".."Power armor quick start enabled."
end
if (global.ocfg.lock_goodies_rocket_launch) then
game_info_str = game_info_str.."\n".."Artillery/Nukes/ArmorMK2 tech and Prod/Speed 3 module recipes are locked until you launch a rocket!"
end
AddLabel(tab_container, "game_info_label", game_info_str, my_longer_label_style)
if (global.ocfg.enable_abandoned_base_removal) then
AddLabel(tab_container, "leave_warning_msg", "If you leave within " .. global.ocfg.minimum_online_time .. " minutes of joining, your base and character will be deleted.", my_longer_label_style)
tab_container.leave_warning_msg.style.font_color=my_color_red
end
-- Ending Spacer
AddSpacerLine(tab_container)
-- ADMIN CONTROLS
if (player.admin) then
player_list = {}
for _,player in pairs(game.connected_players) do
table.insert(player_list, player.name)
end
tab_container.add{name = "ban_players_dropdown",
type = "drop-down",
items = player_list}
tab_container.add{name="ban_player", type="button", caption="Ban Player"}
tab_container.add{name="restart_player", type="button", caption="Restart Player"}
end
end

View File

@ -11,20 +11,16 @@
-- That's a LOT of settings.
function InitOarcConfig()
-- Short and sweet.
global.ocfg = {}
local is_mod = false
for name, version in pairs(game.active_mods) do
if (name == "oarc-mod") then
is_mod = true
log("Oarc MOD! Version: " .. version)
end
if (game.active_mods["clean-tutorial-grid"]) then
global.ocfg.locked_build_area_tile = "clean-tutorial-grid"
else
global.ocfg.locked_build_area_tile = "tutorial-grid"
end
-- SCENARIO VERSION
if (not is_mod) then
if (not game.active_mods["oarc-mod"]) then
global.ocfg.welcome_title = WELCOME_MSG_TITLE
global.ocfg.welcome_msg = WELCOME_MSG
global.ocfg.server_rules = SERVER_MSG
@ -42,10 +38,10 @@ function InitOarcConfig()
global.ocfg.enable_player_list = ENABLE_PLAYER_LIST
global.ocfg.list_offline_players = PLAYER_LIST_OFFLINE_PLAYERS
global.ocfg.enable_shared_team_vision = ENABLE_SHARED_TEAM_VISION
global.ocfg.enable_regrowth = ENABLE_REGROWTH
global.ocfg.enable_abandoned_base_removal = ENABLE_ABANDONED_BASE_REMOVAL
global.ocfg.enable_research_queue = ENABLE_RESEARCH_QUEUE
global.ocfg.lock_goodies_rocket_launch = LOCK_GOODIES_UNTIL_ROCKET_LAUNCH
global.ocfg.modified_enemy_spawning = OARC_MODIFIED_ENEMY_SPAWNING
global.ocfg.near_dist_start = NEAR_MIN_DIST
global.ocfg.near_dist_end = NEAR_MAX_DIST
@ -68,9 +64,13 @@ function InitOarcConfig()
global.ocfg.frontier_pos_table = SILO_POSITIONS
global.ocfg.frontier_silo_vision = ENABLE_SILO_VISION
global.ocfg.frontier_allow_build = ENABLE_SILO_PLAYER_BUILD
global.ocfg.enable_server_write_files = ENABLE_SERVER_WRITE_FILES
-- MOD VERSION
else
log("Oarc MOD! Version: " .. game.active_mods["oarc-mod"].version)
global.ocfg.welcome_title = settings.global["oarc-welcome-title"].value
global.ocfg.welcome_msg = settings.global["oarc-welcome-msg"].value
global.ocfg.server_rules = settings.global["oarc-server-rules"].value
@ -88,7 +88,6 @@ function InitOarcConfig()
global.ocfg.list_offline_players = settings.global["oarc-list-offline-players"].value
global.ocfg.enable_shared_team_vision = settings.global["oarc-enable-shared-team-vision"].value
global.ocfg.enable_regrowth = settings.global["oarc-enable-regrowth"].value
global.ocfg.enable_abandoned_base_removal = settings.global["oarc-enable-abandoned-base-removal"].value
global.ocfg.enable_research_queue = settings.global["oarc-enable-research-queue"].value
global.ocfg.lock_goodies_rocket_launch = false
global.ocfg.modified_enemy_spawning = settings.global["oarc-modified-enemy-spawning"].value
@ -131,35 +130,35 @@ function InitOarcConfig()
},
resource_tiles =
{
[settings.global["oarc-resource-1-name"].value] =
[settings.global["oarc-resource-1-name"].value] =
{
amount = settings.global["oarc-resource-1-amount"].value,
size = settings.global["oarc-resource-1-size"].value,
x_offset = -29,
y_offset = 16
},
[settings.global["oarc-resource-2-name"].value] =
[settings.global["oarc-resource-2-name"].value] =
{
amount = settings.global["oarc-resource-2-amount"].value,
size = settings.global["oarc-resource-2-size"].value,
x_offset = -28,
y_offset = -3
},
[settings.global["oarc-resource-3-name"].value] =
[settings.global["oarc-resource-3-name"].value] =
{
amount = settings.global["oarc-resource-3-amount"].value,
size = settings.global["oarc-resource-3-size"].value,
x_offset = -27,
y_offset = -34
},
[settings.global["oarc-resource-4-name"].value] =
[settings.global["oarc-resource-4-name"].value] =
{
amount = settings.global["oarc-resource-4-amount"].value,
size = settings.global["oarc-resource-4-size"].value,
x_offset = -27,
y_offset = -20
}
-- [settings.global["oarc-resource-5-name"].value] =
-- [settings.global["oarc-resource-5-name"].value] =
-- {
-- amount = settings.global["oarc-resource-5-amount"].value,
-- size = settings.global["oarc-resource-5-size"].value,
@ -169,7 +168,7 @@ function InitOarcConfig()
},
resource_patches =
{
[settings.global["oarc-resource-patch-1-name"].value] =
[settings.global["oarc-resource-patch-1-name"].value] =
{
num_patches = settings.global["oarc-resource-patch-1-count"].value,
amount = settings.global["oarc-resource-patch-1-amount"].value,

242
lib/oarc_gui_tabs.lua Normal file
View File

@ -0,0 +1,242 @@
-- oarc_gui_tabs.lua
--------------------------------------------------------------------------------
-- GUI Tab Handler
--------------------------------------------------------------------------------
-- NAME of the top level element (outer frame)
local OARC_GUI = "oarc_gui"
-- LIST of all implemented tabs and their content Functions
OARC_GAME_OPTS_GUI_TAB_NAME = "Server Info"
OARC_SPAWN_CTRL_GUI_NAME = "Spawn Controls"
OARC_PLAYER_LIST_GUI_TAB_NAME = "Players"
OARC_TAGS_GUI_TAB_NAME = "Name Tags"
OARC_ROCKETS_GUI_TAB_NAME = "Rockets"
local OARC_GUI_TAB_CONTENT_FUNCTIONS = {}
OARC_GUI_TAB_CONTENT_FUNCTIONS["Server Info"] = CreateGameOptionsTab
OARC_GUI_TAB_CONTENT_FUNCTIONS["Spawn Controls"] = CreateSpawnCtrlGuiTab
OARC_GUI_TAB_CONTENT_FUNCTIONS["Players"] = CreatePlayerListGuiTab
OARC_GUI_TAB_CONTENT_FUNCTIONS["Name Tags"] = CreateTagGuiTab
OARC_GUI_TAB_CONTENT_FUNCTIONS["Rockets"] = CreateRocketGuiTab
function InitOarcGuiTabs(player)
CreateOarcGuiButton(player)
-- Add general info tab
AddOarcGuiTab(player, OARC_GAME_OPTS_GUI_TAB_NAME)
SetOarcGuiTabEnabled(player, OARC_GAME_OPTS_GUI_TAB_NAME, true)
-- Spawn control tab, disabled by default
AddOarcGuiTab(player, OARC_SPAWN_CTRL_GUI_NAME)
-- If player list is enabled, create that
if global.ocfg.enable_player_list then
AddOarcGuiTab(player, OARC_PLAYER_LIST_GUI_TAB_NAME)
SetOarcGuiTabEnabled(player, OARC_PLAYER_LIST_GUI_TAB_NAME, true)
end
-- Player tags
if global.ocfg.enable_tags then
AddOarcGuiTab(player, OARC_TAGS_GUI_TAB_NAME)
SetOarcGuiTabEnabled(player, OARC_TAGS_GUI_TAB_NAME, true)
end
AddOarcGuiTab(player, OARC_ROCKETS_GUI_TAB_NAME)
end
function CreateOarcGuiButton(player)
if (mod_gui.get_button_flow(player).oarc_button == nil) then
local b = mod_gui.get_button_flow(player).add{name="oarc_button",
type="sprite-button",
sprite="utility/expand_dots",
style=mod_gui.button_style}
b.style.padding=2
b.style.width=20
end
end
function DoesOarcGuiExist(player)
return (mod_gui.get_frame_flow(player)[OARC_GUI] ~= nil)
end
function ToggleOarcGuiVisible(player)
local of = mod_gui.get_frame_flow(player)[OARC_GUI]
if (of ~= nil) then
of.visible = not of.visible
end
end
function GetOarcGuiTabsPane(player)
if (mod_gui.get_frame_flow(player)[OARC_GUI] == nil) then
return nil
else
return mod_gui.get_frame_flow(player)[OARC_GUI].oarc_if.oarc_tabs
end
end
function ClickOarcGuiButton(event)
if not (event and event.element and event.element.valid) then return end
local player = game.players[event.element.player_index]
local name = event.element.name
if (name ~= "oarc_button") then return end
if (not DoesOarcGuiExist(player)) then
CreateOarcGuiTabsPane(player)
else
ToggleOarcGuiVisible(player)
FakeTabChangeEventOarcGui(player)
end
end
function TabChangeOarcGui(event)
if (event.element.name ~= "oarc_tabs") then return end
local player = game.players[event.player_index]
local otabs = event.element
local selected_tab_name = otabs.tabs[otabs.selected_tab_index].tab.name
-- Clear all tab contents
for i,t in pairs(otabs.tabs) do
t.content.clear()
end
SetOarGuiTabContent(player, selected_tab_name)
end
function FakeTabChangeEventOarcGui(player)
local event = {}
event.element = GetOarcGuiTabsPane(player)
event.player_index = player.index
TabChangeOarcGui(event)
end
function CreateOarcGuiTabsPane(player)
if (mod_gui.get_frame_flow(player)[OARC_GUI] == nil) then
-- OUTER FRAME (TOP GUI ELEMENT)
local frame = mod_gui.get_frame_flow(player).add{
type = 'frame',
name = OARC_GUI,
direction = "vertical"}
frame.style.padding = 5
-- INNER FRAME
local inside_frame = frame.add{
type = "frame",
name = "oarc_if",
style = "inside_deep_frame",
direction = "vertical"
}
-- SUB HEADING w/ LABEL
local subhead = inside_frame.add{
type="frame",
name="sub_header",
style = "changelog_subheader_frame"}
AddLabel(subhead, "scen_info", "Scenario Info and Controls", "subheader_caption_label")
-- TABBED PANE
local oarc_tabs = inside_frame.add{
name="oarc_tabs",
type="tabbed-pane",
style="tabbed_pane"}
oarc_tabs.style.top_padding = 8
end
end
-- Function creates a new tab.
-- It adds whatever it wants to the provided scroll-pane.
-- content_function takes a content holder GUI and player
function AddOarcGuiTab(player, tab_name, content_function)
if (not DoesOarcGuiExist(player)) then
CreateOarcGuiTabsPane(player)
ToggleOarcGuiVisible(player)
end
-- Get the tabbed pane
local otabs = GetOarcGuiTabsPane(player)
-- Create new tab
local new_tab = otabs.add{
type="tab",
name=tab_name,
caption=tab_name}
-- Create inside frame for content
local tab_inside_frame = otabs.add{
type="frame",
name=tab_name.."_if",
style = "inside_deep_frame",
direction="vertical"}
tab_inside_frame.style.left_margin = 10
tab_inside_frame.style.right_margin = 10
tab_inside_frame.style.top_margin = 4
tab_inside_frame.style.bottom_margin = 4
tab_inside_frame.style.padding = 5
tab_inside_frame.style.horizontally_stretchable = true
-- tab_inside_frame.style.vertically_stretchable = true
-- tab_inside_frame.style.horizontally_squashable = true
-- tab_inside_frame.style.vertically_squashable = true
-- Add the whole thing to the tab now.
otabs.add_tab(new_tab, tab_inside_frame)
-- Disable all new tabs by default
new_tab.enabled = false
-- If no other tabs are selected, select the first one.
if (otabs.selected_tab_index == nil) then
otabs.selected_tab_index = 1
end
-- if (global.oarc_gui_tab_funcs == nil) then
-- global.oarc_gui_tab_funcs = {}
-- end
-- global.oarc_gui_tab_funcs[tab_name] = content_function
end
function SetOarGuiTabContent(player, tab_name)
if (not DoesOarcGuiExist(player)) then return end
local otabs = GetOarcGuiTabsPane(player)
for _,t in ipairs(otabs.tabs) do
if (t.tab.name == tab_name) then
t.content.clear()
OARC_GUI_TAB_CONTENT_FUNCTIONS[tab_name](t.content, player)
return
end
end
end
function SetOarcGuiTabEnabled(player, tab_name, enable)
if (not DoesOarcGuiExist(player)) then return end
local otabs = GetOarcGuiTabsPane(player)
for _,t in ipairs(otabs.tabs) do
if (t.tab.name == tab_name) then
t.tab.enabled = enable
return
end
end
end
function SwitchOarcGuiTab(player, tab_name)
if (not DoesOarcGuiExist(player)) then return end
local otabs = GetOarcGuiTabsPane(player)
for i,t in pairs(otabs.tabs) do
if (t.tab.name == tab_name) then
otabs.selected_tab_index = i
FakeTabChangeEventOarcGui(player)
return
end
end
end

View File

@ -19,6 +19,20 @@ my_label_style = {
top_padding = 0,
bottom_padding = 0
}
my_label_header_style = {
single_line = false,
font = "heading-1",
font_color = {r=1,g=1,b=1},
top_padding = 0,
bottom_padding = 0
}
my_label_header_grey_style = {
single_line = false,
font = "heading-1",
font_color = {r=0.6,g=0.6,b=0.6},
top_padding = 0,
bottom_padding = 0
}
my_note_style = {
-- minimal_width = 450,
single_line = false,
@ -37,7 +51,6 @@ my_warning_style = {
}
my_spacer_style = {
minimal_height = 10,
font_color = {r=0,g=0,b=0},
top_padding = 0,
bottom_padding = 0
}
@ -100,26 +113,25 @@ my_longer_warning_style = {
function ApplyStyle (guiIn, styleIn)
for k,v in pairs(styleIn) do
guiIn.style[k]=v
end
end
end
-- Shorter way to add a label with a style
function AddLabel(guiIn, name, message, style)
guiIn.add{name = name, type = "label",
local g = guiIn.add{name = name, type = "label",
caption=message}
ApplyStyle(guiIn[name], style)
if (type(style) == "table") then
ApplyStyle(g, style)
else
g.style = style
end
end
-- Shorter way to add a spacer
function AddSpacer(guiIn, name)
guiIn.add{name = name, type = "label",
caption=" "}
ApplyStyle(guiIn[name], my_spacer_style)
function AddSpacer(guiIn)
ApplyStyle(guiIn.add{type = "label", caption=" "}, my_spacer_style)
end
-- Shorter way to add a spacer with a decorative line
function AddSpacerLine(guiIn, name)
guiIn.add{name = name, type = "label",
caption="~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"}
ApplyStyle(guiIn[name], my_spacer_style)
function AddSpacerLine(guiIn)
ApplyStyle(guiIn.add{type = "line", direction="horizontal"}, my_spacer_style)
end

View File

@ -1,6 +1,6 @@
-- oarc_utils.lua
-- Nov 2016
--
--
-- My general purpose utility functions for factorio
-- Also contains some constants and gui styles
@ -95,7 +95,7 @@ function getDistance(posA, posB)
local xDist = posB.x - posA.x
local yDist = posB.y - posA.y
return math.sqrt( (xDist ^ 2) + (yDist ^ 2) )
return math.sqrt( (xDist ^ 2) + (yDist ^ 2) )
end
-- Given a table of positions, returns key for closest to given pos.
@ -154,7 +154,7 @@ function GiveQuickStartPowerArmor(player)
p_armor.put({name = "exoskeleton-equipment"})
p_armor.put({name = "battery-mk2-equipment"})
p_armor.put({name = "battery-mk2-equipment"})
p_armor.put({name = "personal-roboport-mk2-equipment"})
p_armor.put({name = "personal-roboport-mk2-equipment"})
p_armor.put({name = "personal-roboport-mk2-equipment"})
p_armor.put({name = "personal-roboport-mk2-equipment"})
p_armor.put({name = "battery-mk2-equipment"})
@ -245,7 +245,7 @@ end
-- Undecorator
function RemoveDecorationsArea(surface, area)
surface.destroy_decoratives(area)
surface.destroy_decoratives{area=area}
end
-- Remove fish
@ -266,7 +266,7 @@ end
-- Create a random direction vector to look in
function GetRandomVector()
local randVec = {x=0,y=0}
local randVec = {x=0,y=0}
while ((randVec.x == 0) and (randVec.y == 0)) do
randVec.x = math.random(-3,3)
randVec.y = math.random(-3,3)
@ -312,19 +312,19 @@ function FindMapEdge(directionVec, surface)
-- Keep checking chunks in the direction of the vector
while(true) do
-- Set some absolute limits.
if ((math.abs(chunkPos.x) > 1000) or (math.abs(chunkPos.y) > 1000)) then
break
-- If chunk is already generated, keep looking
elseif (surface.is_chunk_generated(chunkPos)) then
chunkPos.x = chunkPos.x + directionVec.x
chunkPos.y = chunkPos.y + directionVec.y
-- Found a possible ungenerated area
else
chunkPos.x = chunkPos.x + directionVec.x
chunkPos.y = chunkPos.y + directionVec.y
@ -364,17 +364,17 @@ function FindUngeneratedCoordinates(minDistChunks, maxDistChunks, surface)
if (tryCounter > maxTries) then
log("FindUngeneratedCoordinates - Max Tries Hit!")
break
-- Check that the distance is within the min,max specified
elseif ((distSqrd < minDistSqr) or (distSqrd > maxDistSqr)) then
-- Keep searching!
-- Check there are no generated chunks in a 10x10 area.
elseif IsChunkAreaUngenerated(chunkPos, CHECK_SPAWN_UNGENERATED_CHUNKS_RADIUS, surface) then
position.x = (chunkPos.x*CHUNK_SIZE) + (CHUNK_SIZE/2)
position.y = (chunkPos.y*CHUNK_SIZE) + (CHUNK_SIZE/2)
break -- SUCCESS
end
end
end
log("spawn: x=" .. position.x .. ", y=" .. position.y)
@ -430,9 +430,20 @@ function GetChunkPosFromTilePos(tile_pos)
return {x=math.floor(tile_pos.x/32), y=math.floor(tile_pos.y/32)}
end
-- Get the left_top
function GetChunkTopLeft(pos)
return {x=pos.x-(pos.x % 32), y=pos.y-(pos.y % 32)}
end
-- Get area given chunk
function GetAreaFromChunkPos(chunk_pos)
return {left_top={x=chunk_pos.x*32, y=chunk_pos.y*32},
right_bottom={x=chunk_pos.x*32+31, y=chunk_pos.y*32+31}}
end
-- Removes the entity type from the area given
function RemoveInArea(surface, area, type)
for key, entity in pairs(surface.find_entities_filtered({area=area, type= type})) do
for key, entity in pairs(surface.find_entities_filtered{area=area, type= type}) do
if entity.valid and entity and entity.position then
entity.destroy()
end
@ -442,7 +453,7 @@ end
-- Removes the entity type from the area given
-- Only if it is within given distance from given position.
function RemoveInCircle(surface, area, type, pos, dist)
for key, entity in pairs(surface.find_entities_filtered({area=area, type= type})) do
for key, entity in pairs(surface.find_entities_filtered{area=area, type= type}) do
if entity.valid and entity and entity.position then
if ((pos.x - entity.position.x)^2 + (pos.y - entity.position.y)^2 < dist^2) then
entity.destroy()
@ -453,7 +464,7 @@ end
-- Create another surface so that we can modify map settings and not have a screwy nauvis map.
function CreateGameSurface()
-- Get starting surface settings.
local nauvis_settings = game.surfaces["nauvis"].map_gen_settings
@ -467,7 +478,13 @@ function CreateGameSurface()
end
-- Create new game surface
game.create_surface(GAME_SURFACE_NAME, nauvis_settings)
local s = game.create_surface(GAME_SURFACE_NAME, nauvis_settings)
-- Add surface and safe areas
if (game.active_mods["unused-chunk-removal"]) then
remote.call("oarc_regrowth", "add_surface", s.index)
remote.call("oarc_regrowth", "area_offlimits_chunkpos", s.index, {x=0,y=0}, 10)
end
end
--------------------------------------------------------------------------------
@ -499,7 +516,7 @@ function DowngradeWormsInArea(surface, area, small_percent, medium_percent, big_
local worm_types = {"small-worm-turret", "medium-worm-turret", "big-worm-turret", "behemoth-worm-turret"}
for _, entity in pairs(surface.find_entities_filtered{area = area, name = worm_types}) do
-- Roll a number between 0-100
local rand_percent = math.random(0,100)
local worm_pos = entity.position
@ -510,7 +527,7 @@ function DowngradeWormsInArea(surface, area, small_percent, medium_percent, big_
if (not (worm_name == "small-worm-turret")) then
entity.destroy()
surface.create_entity{name = "small-worm-turret", position = worm_pos, force = game.forces.enemy}
end
end
-- ELSE If number is less than medium percent, change to small
elseif (rand_percent <= medium_percent) then
@ -560,7 +577,7 @@ function RemoveWormsInArea(surface, area, small, medium, big, behemoth)
if (behemoth) then
table.insert(worm_types, "behemoth-worm-turret")
end
-- Destroy
if (TableLength(worm_types) > 0) then
for _, entity in pairs(surface.find_entities_filtered{area = area, name = worm_types}) do
@ -578,7 +595,16 @@ function GivePlayerLongReach(player)
-- player.character.character_resource_reach_distance_bonus = RESOURCE_DIST_BONUS
end
-- General purpose cover an area in tiles.
function CoverAreaInTiles(surface, area, tile_name)
tiles = {}
for x = area.left_top.x,area.left_top.x+31 do
for y = area.left_top.y,area.left_top.y+31 do
table.insert(tiles, {name = tile_name, position = {x=x, y=y}})
end
end
surface.set_tiles(tiles, true)
end
--------------------------------------------------------------------------------
-- Anti-griefing Stuff & Gravestone (My own version)
@ -595,7 +621,7 @@ function SetForceGhostTimeToLive(force)
end
function SetItemBlueprintTimeToLive(event)
local type = event.created_entity.type
local type = event.created_entity.type
if type == "entity-ghost" or type == "tile-ghost" then
if GHOST_TIME_TO_LIVE ~= 0 then
event.created_entity.time_to_live = GHOST_TIME_TO_LIVE
@ -634,15 +660,15 @@ function DropGravestoneChests(player)
defines.inventory.character_ammo,
defines.inventory.character_vehicle,
defines.inventory.character_trash} do
local inv = player.get_inventory(id)
-- No idea how inv can be nil sometimes...?
-- No idea how inv can be nil sometimes...?
if (inv ~= nil) then
if ((#inv > 0) and not inv.is_empty()) then
for j = 1, #inv do
if inv[j].valid_for_read then
-- Create a chest when counter is reset
if (count == 0) then
grave = DropEmptySteelChest(player)
@ -684,12 +710,12 @@ function DropGravestoneChestFromCorpse(corpse)
local inv = corpse.get_inventory(defines.inventory.character_corpse)
-- No idea how inv can be nil sometimes...?
-- No idea how inv can be nil sometimes...?
if (inv ~= nil) then
if ((#inv > 0) and not inv.is_empty()) then
for j = 1, #inv do
if inv[j].valid_for_read then
-- Create a chest when counter is reset
if (count == 0) then
grave = DropEmptySteelChest(corpse)
@ -740,7 +766,7 @@ function TransferItems(srcInv, destEntity, itemStack)
if (not destEntity.can_insert(itemStack)) then
return -2
end
-- Insert items
local itemsRemoved = srcInv.remove(itemStack)
itemStack.count = itemsRemoved
@ -774,7 +800,7 @@ function AutofillTurret(player, turret)
-- Inserted ammo successfully
-- FlyingText("Inserted ammo x" .. ret, turret.position, my_color_red, player.surface)
elseif (ret == -1) then
FlyingText("Out of ammo!", turret.position, my_color_red, player.surface)
FlyingText("Out of ammo!", turret.position, my_color_red, player.surface)
elseif (ret == -2) then
FlyingText("Autofill ERROR! - Report this bug!", turret.position, my_color_red, player.surface)
end
@ -784,7 +810,7 @@ end
function AutoFillVehicle(player, vehicle)
local mainInv = player.get_main_inventory()
if (mainInv == nil) then return end
-- Attempt to transfer some fuel
if ((vehicle.name == "car") or (vehicle.name == "tank") or (vehicle.name == "locomotive")) then
TransferItemMultipleTypes(mainInv, vehicle, {"nuclear-fuel", "rocket-fuel", "solid-fuel", "coal", "wood"}, 50)
@ -806,7 +832,7 @@ end
--------------------------------------------------------------------------------
-- Enforce a circle of land, also adds trees in a ring around the area.
function CreateCropCircle(surface, centerPos, chunkArea, tileRadius)
function CreateCropCircle(surface, centerPos, chunkArea, tileRadius, fillTile)
local tileRadSqr = tileRadius^2
@ -820,13 +846,15 @@ function CreateCropCircle(surface, centerPos, chunkArea, tileRadius)
-- Fill in all unexpected water in a circle
if (distVar < tileRadSqr) then
if (surface.get_tile(i,j).collides_with("water-tile") or global.ocfg.spawn_config.gen_settings.force_grass) then
table.insert(dirtTiles, {name = "grass-1", position ={i,j}})
if (surface.get_tile(i,j).collides_with("water-tile") or
global.ocfg.spawn_config.gen_settings.force_grass or
(game.active_mods["oarc-restricted-build"])) then
table.insert(dirtTiles, {name = fillTile, position ={i,j}})
end
end
-- Create a circle of trees around the spawn point.
if ((distVar < tileRadSqr-200) and
if ((distVar < tileRadSqr-200) and
(distVar > tileRadSqr-400)) then
surface.create_entity({name="tree-02", amount=1, position={i, j}})
end
@ -839,7 +867,7 @@ end
-- COPIED FROM jvmguy!
-- Enforce a square of land, with a tree border
-- this is equivalent to the CreateCropCircle code
function CreateCropOctagon(surface, centerPos, chunkArea, tileRadius)
function CreateCropOctagon(surface, centerPos, chunkArea, tileRadius, fillTile)
local dirtTiles = {}
for i=chunkArea.left_top.x,chunkArea.right_bottom.x,1 do
@ -851,23 +879,25 @@ function CreateCropOctagon(surface, centerPos, chunkArea, tileRadius)
-- Fill in all unexpected water in a circle
if (distVar < tileRadius+2) then
if (surface.get_tile(i,j).collides_with("water-tile") or global.ocfg.spawn_config.gen_settings.force_grass) then
table.insert(dirtTiles, {name = "grass-1", position ={i,j}})
if (surface.get_tile(i,j).collides_with("water-tile") or
global.ocfg.spawn_config.gen_settings.force_grass or
(game.active_mods["oarc-restricted-build"])) then
table.insert(dirtTiles, {name = fillTile, position ={i,j}})
end
end
-- Create a tree ring
if ((distVar < tileRadius) and
if ((distVar < tileRadius) and
(distVar > tileRadius-2)) then
surface.create_entity({name="tree-01", amount=1, position={i, j}})
end
end
end
end
surface.set_tiles(dirtTiles)
end
-- Add a circle of water
function CreateMoat(surface, centerPos, chunkArea, tileRadius)
function CreateMoat(surface, centerPos, chunkArea, tileRadius, fillTile)
local tileRadSqr = tileRadius^2
@ -880,17 +910,17 @@ function CreateMoat(surface, centerPos, chunkArea, tileRadius)
local distVar = math.floor((centerPos.x - i)^2 + (centerPos.y - j)^2)
-- Create a circle of water
if ((distVar < tileRadSqr+(1500*global.ocfg.spawn_config.gen_settings.moat_size_modifier)) and
if ((distVar < tileRadSqr+(1500*global.ocfg.spawn_config.gen_settings.moat_size_modifier)) and
(distVar > tileRadSqr)) then
table.insert(waterTiles, {name = "water", position ={i,j}})
end
-- Enforce land inside the edges of the circle to make sure it's
-- a clean transition
if ((distVar <= tileRadSqr) and
(distVar > tileRadSqr-10000)) then
table.insert(waterTiles, {name = "grass-1", position ={i,j}})
end
-- if ((distVar <= tileRadSqr) and
-- (distVar > tileRadSqr-10000)) then
-- table.insert(waterTiles, {name = fillTile, position ={i,j}})
-- end
end
end
@ -904,7 +934,7 @@ function CreateWaterStrip(surface, leftPos, length)
table.insert(waterTiles, {name = "water", position={leftPos.x+i,leftPos.y}})
end
surface.set_tiles(waterTiles)
end
end
-- Function to generate a resource patch, of a certain size/amount at a pos.
function GenerateResourcePatch(surface, resourceName, diameter, pos, amount)

View File

@ -4,57 +4,43 @@
--------------------------------------------------------------------------------
-- Player List GUI - My own version
--------------------------------------------------------------------------------
function CreatePlayerListGui(event)
local player = game.players[event.player_index]
if mod_gui.get_button_flow(player).playerList == nil then
mod_gui.get_button_flow(player).add{name="playerList", type="button", caption="Player List", style=mod_gui.button_style}
end
end
function CreatePlayerListGuiTab(tab_container, player)
local scrollFrame = tab_container.add{type="scroll-pane",
name="playerList-panel",
direction = "vertical"}
ApplyStyle(scrollFrame, my_player_list_fixed_width_style)
scrollFrame.horizontal_scroll_policy = "never"
local function ExpandPlayerListGui(player)
local frame = mod_gui.get_frame_flow(player)["playerList-panel"]
if (frame) then
frame.destroy()
else
local frame = mod_gui.get_frame_flow(player).add{type="frame",
name="playerList-panel",
caption="Online:"}
local scrollFrame = frame.add{type="scroll-pane",
name="playerList-panel",
direction = "vertical"}
ApplyStyle(scrollFrame, my_player_list_fixed_width_style)
scrollFrame.horizontal_scroll_policy = "never"
for _,player in pairs(game.connected_players) do
local caption_str = player.name.." ["..player.force.name.."]".." ("..formattime_hours_mins(player.online_time)..")"
if (player.admin) then
AddLabel(scrollFrame, player.name.."_plist", caption_str, my_player_list_admin_style)
else
AddLabel(scrollFrame, player.name.."_plist", caption_str, my_player_list_style)
AddLabel(scrollFrame, "online_title_msg", "Online Players:", my_label_header_style)
for _,player in pairs(game.connected_players) do
local caption_str = player.name.." ["..player.force.name.."]".." ("..formattime_hours_mins(player.online_time)..")"
if (player.admin) then
AddLabel(scrollFrame, player.name.."_plist", caption_str, my_player_list_admin_style)
else
AddLabel(scrollFrame, player.name.."_plist", caption_str, my_player_list_style)
end
end
-- List offline players
if (global.ocfg.list_offline_players) then
AddSpacerLine(scrollFrame)
AddLabel(scrollFrame, "offline_title_msg", "Offline Players:", my_label_header_grey_style)
for _,player in pairs(game.players) do
if (not player.connected) then
local caption_str = player.name.." ["..player.force.name.."]".." ("..formattime_hours_mins(player.online_time)..")"
local text = scrollFrame.add{type="label", caption=caption_str, name=player.name.."_plist"}
ApplyStyle(text, my_player_list_offline_style)
end
end
-- List offline players
if (global.ocfg.list_offline_players) then
AddLabel(scrollFrame, "offline_title_msg", "Offline Players:", my_label_style)
for _,player in pairs(game.players) do
if (not player.connected) then
local caption_str = player.name.." ["..player.force.name.."]".." ("..formattime_hours_mins(player.online_time)..")"
local text = scrollFrame.add{type="label", caption=caption_str, name=player.name.."_plist"}
ApplyStyle(text, my_player_list_offline_style)
end
end
end
local spacer = scrollFrame.add{type="label", caption=" ", name="plist_spacer_plist"}
ApplyStyle(spacer, my_player_list_style_spacer)
end
end
function PlayerListGuiClick(event)
function PlayerListGuiClick(event)
if not (event and event.element and event.element.valid) then return end
local player = game.players[event.element.player_index]
local name = event.element.name
if (name == "playerList") then
ExpandPlayerListGui(player)
ExpandPlayerListGui(player)
end
end

View File

@ -1,366 +0,0 @@
-- regrowth_map.lua
-- July 2017
--
-- Code tracks all chunks generated and allows for deleting inactive chunks
-- Relies on some changes to RSO to provide random resource locations the next
-- time the land is regenerated. -- (THIS IS CURRENTLY NOT WORKING IN 0.16,
-- resources always how up in the same spot!)
--
-- Basic rules of regrowth:
-- 1. Area around player is safe for quite a large distance.
-- 2. Rocket silo won't be deleted. - PERMANENT
-- 3. Chunks with pollution won't be deleted.
-- 4. Chunks with railways won't be deleted.
-- 5. Anything within radar range won't be deleted, but radar MUST be active.
-- -- This works by refreshing all chunk timers within radar range using
-- the on_sector_scanned event.
-- 6. Chunks timeout after 1 hour-ish, configurable
-- 7. For now, oarc spawns are deletion safe as well, but only immediate area.
-- Generic Utility Includes
require("lib/oarc_utils")
require("config")
-- Default timeout of generated chunks
REGROWTH_TIMEOUT_TICKS = TICKS_PER_HOUR
-- We can't delete chunks regularly without causing lag.
-- So we should save them up to delete them.
REGROWTH_CLEANING_INTERVAL_TICKS = REGROWTH_TIMEOUT_TICKS
-- Not used right now.
-- It takes a radar 7 hours and 20 minutes to scan it's whole area completely
-- So I will bump the refresh time of blocks up by 8 hours
-- RADAR_COMPLETE_SCAN_TICKS = TICKS_PER_HOUR*8
-- Additional bonus time for certain things:
-- REFRESH_BONUS_RADAR = RADAR_COMPLETE_SCAN_TICKS
-- Init globals and set player join area to be off limits.
function OarcRegrowthInit()
global.chunk_regrow = {}
global.chunk_regrow.map = {}
global.chunk_regrow.removal_list = {}
global.chunk_regrow.player_refresh_index = 1
global.chunk_regrow.min_x = 0
global.chunk_regrow.max_x = 0
global.chunk_regrow.x_index = 0
global.chunk_regrow.min_y = 0
global.chunk_regrow.max_y = 0
global.chunk_regrow.y_index = 0
global.chunk_regrow.force_removal_flag = -1000
OarcRegrowthOffLimits({x=0,y=0}, 10)
end
function GetChunkTopLeft(pos)
return {x=pos.x-(pos.x % 32), y=pos.y-(pos.y % 32)}
end
function GetChunkCoordsFromPos(pos)
return {x=math.floor(pos.x/32), y=math.floor(pos.y/32)}
end
-- This complicated function checks that if a chunk
function CheckChunkEmpty(pos)
chunkPos = GetChunkCoordsFromPos(pos)
search_top_left = {x=chunkPos.x*32, y=chunkPos.y*32}
search_area = {search_top_left, {x=search_top_left.x+32,y=search_top_left.y+32}}
total = 0
for f,_ in pairs(game.forces) do
if f ~= "neutral" and f ~= "enemy" then
entities = game.surfaces[GAME_SURFACE_NAME].find_entities_filtered{area = search_area, force=f}
total = total + #entities
if (#entities > 0) then
for _,e in pairs(entities) do
if ((e.type == "player") or
(e.type == "car") or
(e.type == "logistic-robot") or
(e.type == "construction-robot")) then
total = total - 1
end
end
end
end
end
-- A destroyed entity is still found during the event check.
return (total == 1)
end
-- game.surfaces[GAME_SURFACE_NAME].find_entities_filtered{area = {game.player.position, {game.player.position.x+32, game.player.position-`32}}, type= "resource"}
-- If an entity is mined or destroyed, then check if the chunk
-- is empty. If it's empty, reset the refresh timer.
function OarcRegrowthCheckChunkEmpty(event)
if ((event.entity.force ~= nil) and (event.entity.force ~= "neutral") and (event.entity.force ~= "enemy")) then
if CheckChunkEmpty(event.entity.position) then
log("Resetting chunk timer."..event.entity.position.x.." "..event.entity.position.y)
OarcRegrowthForceRefreshChunk(event.entity.position, 0)
end
end
end
-- Adds new chunks to the global table to track them.
-- This should always be called first in the chunk generate sequence
-- (Compared to other RSO & Oarc related functions...)
function OarcRegrowthChunkGenerate(pos)
c_pos = GetChunkCoordsFromPos(pos)
-- If this is the first chunk in that row:
if (global.chunk_regrow.map[c_pos.x] == nil) then
global.chunk_regrow.map[c_pos.x] = {}
end
-- Confirm the chunk doesn't already have a value set:
if (global.chunk_regrow.map[c_pos.x][c_pos.y] == nil) then
global.chunk_regrow.map[c_pos.x][c_pos.y] = game.tick
end
-- Store min/max values for x/y dimensions:
if (c_pos.x < global.chunk_regrow.min_x) then
global.chunk_regrow.min_x = c_pos.x
end
if (c_pos.x > global.chunk_regrow.max_x) then
global.chunk_regrow.max_x = c_pos.x
end
if (c_pos.y < global.chunk_regrow.min_y) then
global.chunk_regrow.min_y = c_pos.y
end
if (c_pos.y > global.chunk_regrow.max_y) then
global.chunk_regrow.max_y = c_pos.y
end
end
-- Mark an area for immediate forced removal
function OarcRegrowthMarkForRemoval(pos, chunk_radius)
local c_pos = GetChunkCoordsFromPos(pos)
for i=-chunk_radius,chunk_radius do
for k=-chunk_radius,chunk_radius do
local x = c_pos.x+i
local y = c_pos.y+k
if (global.chunk_regrow.map[x] == nil) then
global.chunk_regrow.map[x] = {}
end
global.chunk_regrow.map[x][y] = nil
table.insert(global.chunk_regrow.removal_list, {pos={x=x,y=y},force=true})
end
end
end
-- Marks a chunk containing a position that won't ever be deleted.
function OarcRegrowthOffLimitsChunkPos(pos)
if (global.chunk_regrow.map[pos.x] == nil) then
global.chunk_regrow.map[pos.x] = {}
end
global.chunk_regrow.map[pos.x][pos.y] = -1
end
-- Marks a safe area around a position that won't ever be deleted.
function OarcRegrowthOffLimits(pos, chunk_radius)
local c_pos = GetChunkCoordsFromPos(pos)
for i=-chunk_radius,chunk_radius do
for j=-chunk_radius,chunk_radius do
OarcRegrowthOffLimitsChunkPos({x=c_pos.x+i,y=c_pos.y+j})
end
end
end
-- Refreshes timers on a chunk containing position
function OarcRegrowthRefreshChunk(pos, bonus_time)
local c_pos = GetChunkCoordsFromPos(pos)
if (global.chunk_regrow.map[c_pos.x] == nil) then
global.chunk_regrow.map[c_pos.x] = {}
end
if (global.chunk_regrow.map[c_pos.x][c_pos.y] ~= -1) then
global.chunk_regrow.map[c_pos.x][c_pos.y] = game.tick + bonus_time
end
end
-- Forcefully refreshes timers on a chunk containing position
-- Will overwrite -1 flag.
function OarcRegrowthForceRefreshChunk(pos, bonus_time)
local c_pos = GetChunkCoordsFromPos(pos)
if (global.chunk_regrow.map[c_pos.x] == nil) then
global.chunk_regrow.map[c_pos.x] = {}
end
global.chunk_regrow.map[c_pos.x][c_pos.y] = game.tick + bonus_time
end
-- Refreshes timers on all chunks around a certain area
function OarcRegrowthRefreshArea(pos, chunk_radius, bonus_time)
local c_pos = GetChunkCoordsFromPos(pos)
for i=-chunk_radius,chunk_radius do
for k=-chunk_radius,chunk_radius do
local x = c_pos.x+i
local y = c_pos.y+k
if (global.chunk_regrow.map[x] == nil) then
global.chunk_regrow.map[x] = {}
end
if (global.chunk_regrow.map[x][y] ~= -1) then
global.chunk_regrow.map[x][y] = game.tick + bonus_time
end
end
end
end
-- Refreshes timers on all chunks near an ACTIVE radar
function OarcRegrowthSectorScan(event)
OarcRegrowthRefreshArea(event.radar.position, 14, 0)
OarcRegrowthRefreshChunk(event.chunk_position, 0)
end
-- Refresh all chunks near a single player. Cyles through all connected players.
function OarcRegrowthRefreshPlayerArea()
global.chunk_regrow.player_refresh_index = global.chunk_regrow.player_refresh_index + 1
if (global.chunk_regrow.player_refresh_index > #game.connected_players) then
global.chunk_regrow.player_refresh_index = 1
end
if (game.connected_players[global.chunk_regrow.player_refresh_index]) then
OarcRegrowthRefreshArea(game.connected_players[global.chunk_regrow.player_refresh_index].position, 4, 0)
end
end
-- Check each chunk in the 2d array for a timeout value
function OarcRegrowthCheckArray()
-- Increment X
if (global.chunk_regrow.x_index > global.chunk_regrow.max_x) then
global.chunk_regrow.x_index = global.chunk_regrow.min_x
-- Increment Y
if (global.chunk_regrow.y_index > global.chunk_regrow.max_y) then
global.chunk_regrow.y_index = global.chunk_regrow.min_y
log("Finished checking regrowth array."..global.chunk_regrow.min_x.." "..global.chunk_regrow.max_x.." "..global.chunk_regrow.min_y.." "..global.chunk_regrow.max_y)
else
global.chunk_regrow.y_index = global.chunk_regrow.y_index + 1
end
else
global.chunk_regrow.x_index = global.chunk_regrow.x_index + 1
end
-- Check row exists, otherwise make one.
if (global.chunk_regrow.map[global.chunk_regrow.x_index] == nil) then
global.chunk_regrow.map[global.chunk_regrow.x_index] = {}
end
-- If the chunk has timed out, add it to the removal list
local c_timer = global.chunk_regrow.map[global.chunk_regrow.x_index][global.chunk_regrow.y_index]
if ((c_timer ~= nil) and (c_timer ~= -1) and ((c_timer+REGROWTH_TIMEOUT_TICKS) < game.tick)) then
-- Check chunk actually exists
if (game.surfaces[GAME_SURFACE_NAME].is_chunk_generated({x=(global.chunk_regrow.x_index),
y=(global.chunk_regrow.y_index)})) then
table.insert(global.chunk_regrow.removal_list, {pos={x=global.chunk_regrow.x_index,
y=global.chunk_regrow.y_index},
force=false})
global.chunk_regrow.map[global.chunk_regrow.x_index][global.chunk_regrow.y_index] = nil
end
end
end
-- Remove all chunks at same time to reduce impact to FPS/UPS
function OarcRegrowthRemoveAllChunks()
while (#global.chunk_regrow.removal_list > 0) do
local c_remove = table.remove(global.chunk_regrow.removal_list)
local c_pos = c_remove.pos
local c_timer = global.chunk_regrow.map[c_pos.x][c_pos.y]
if (game.surfaces[GAME_SURFACE_NAME] == nil) then
log("Error! game.surfaces[name] is nil?? WTF?")
return
end
-- Confirm chunk is still expired
if (c_timer == nil) then
-- If it is FORCE removal, then remove it regardless of pollution.
if (c_remove.force) then
game.surfaces[GAME_SURFACE_NAME].delete_chunk(c_pos)
global.chunk_regrow.map[c_pos.x][c_pos.y] = nil
-- If it is a normal timeout removal, don't do it if there is pollution in the chunk.
elseif (game.surfaces[GAME_SURFACE_NAME].get_pollution({c_pos.x*32,c_pos.y*32}) > 0) then
global.chunk_regrow.map[c_pos.x][c_pos.y] = game.tick
-- Else delete the chunk
else
game.surfaces[GAME_SURFACE_NAME].delete_chunk(c_pos)
global.chunk_regrow.map[c_pos.x][c_pos.y] = nil
end
else
-- log("Chunk no longer expired?")
end
end
end
-- This is the main work function, it checks a single chunk in the list
-- per tick. It works according to the rules listed in the header of this
-- file.
function OarcRegrowthOnTick()
-- Every half a second, refresh all chunks near a single player
-- Cyles through all players. Tick is offset by 2
if ((game.tick % (30)) == 2) then
OarcRegrowthRefreshPlayerArea()
end
-- Every tick, check a few points in the 2d array
-- According to /measured-command this shouldn't take more
-- than 0.1ms on average
for i=1,20 do
OarcRegrowthCheckArray()
end
-- Send a broadcast warning before it happens.
if ((game.tick % REGROWTH_CLEANING_INTERVAL_TICKS) == REGROWTH_CLEANING_INTERVAL_TICKS-601) then
if (#global.chunk_regrow.removal_list > 100) then
if (global.ocfg.enable_regrowth) then
SendBroadcastMsg("Map cleanup in 10 seconds... Unused and old map chunks will be deleted!")
else
SendBroadcastMsg("Map cleanup in 10 seconds. Cleaning up an abadoned base!")
end
end
end
-- Delete all listed chunks
if ((game.tick % REGROWTH_CLEANING_INTERVAL_TICKS) == REGROWTH_CLEANING_INTERVAL_TICKS-1) then
if (#global.chunk_regrow.removal_list > 100) then
OarcRegrowthRemoveAllChunks()
SendBroadcastMsg("Map cleanup done, sorry for your loss.")
end
end
end
-- This function removes any chunks flagged but on demand.
-- Controlled by the global.chunk_regrow.force_removal_flag
-- This function may be used outside of the normal regrowth modse.
function OarcRegrowthForceRemovalOnTick()
-- Catch force remove flag
if (game.tick == global.chunk_regrow.force_removal_flag+60) then
if (global.ocfg.enable_regrowth) then
SendBroadcastMsg("Map cleanup in 10 seconds... Unused and old map chunks will be deleted!")
else
SendBroadcastMsg("Map cleanup in 10 seconds. Cleaning up an abadoned base!")
end
end
if (game.tick == global.chunk_regrow.force_removal_flag+660) then
OarcRegrowthRemoveAllChunks()
if (global.ocfg.enable_regrowth) then
SendBroadcastMsg("Map cleanup done, sorry for your loss.")
else
SendBroadcastMsg("Abandoned base cleanup complete.")
end
end
end

View File

@ -12,7 +12,7 @@ require("config")
--------------------------------------------------------------------------------
function RocketLaunchEvent(event)
local force = event.rocket.force
-- Notify players on force if rocket was launched without sat.
if event.rocket.get_item_count("satellite") == 0 then
for index, player in pairs(force.players) do
@ -27,14 +27,14 @@ function RocketLaunchEvent(event)
SendBroadcastMsg("Team " .. event.rocket.force.name .. " was the first to launch a rocket!")
ServerWriteFile("rocket_events", "Team " .. event.rocket.force.name .. " was the first to launch a rocket!" .. "\n")
for name,player in pairs(game.connected_players) do
CreateRocketGui(player)
end
-- for name,player in pairs(game.connected_players) do
-- AddOarcGuiTab(player, "Rockets", CreateRocketGuiTab)
-- end
end
-- Track additional satellites launched by this force
if global.satellite_sent[force.name] then
global.satellite_sent[force.name] = global.satellite_sent[force.name] + 1
global.satellite_sent[force.name] = global.satellite_sent[force.name] + 1
SendBroadcastMsg("Team " .. event.rocket.force.name .. " launched another rocket. Total " .. global.satellite_sent[force.name])
ServerWriteFile("rocket_events", "Team " .. event.rocket.force.name .. " launched another rocket. Total " .. global.satellite_sent[force.name] .. "\n")
@ -52,43 +52,29 @@ function RocketLaunchEvent(event)
EnableTech(force, "artillery")
if (force.technologies["speed-module-3"].researched) then
AddRecipe(force, "speed-module-3")
end
if (force.technologies["productivity-module-3"].researched) then
AddRecipe(force, "productivity-module-3")
end
AddRecipe(force, "speed-module-3")
end
if (force.technologies["productivity-module-3"].researched) then
AddRecipe(force, "productivity-module-3")
end
end
end
end
function CreateRocketGuiTab(tab_container, player)
-- local frame = tab_container.add{type="frame", name="rocket-panel", caption="Satellites Launched:", direction = "vertical"}
function CreateRocketGui(player)
if mod_gui.get_button_flow(player)["rocket-score"] == nil then
mod_gui.get_button_flow(player).add{name="rocket-score", type="button", caption="Rockets", style=mod_gui.button_style}
end
end
AddLabel(tab_container, nil, "Satellites Launched:", my_label_header_style)
local function ExpandRocketGui(player)
local frame = player.gui.left["rocket-panel"]
if (frame) then
frame.destroy()
if (global.satellite_sent == nil) then
AddLabel(tab_container, nil, "No launches yet.", my_label_style)
else
local frame = player.gui.left.add{type="frame", name="rocket-panel", caption="Satellites Launched:", direction = "vertical"}
for force_name,sat_count in pairs(global.satellite_sent) do
frame.add{name="rc_"..force_name, type = "label",
caption="Team " .. force_name .. ": " .. tostring(sat_count)}
AddLabel(tab_container,
"rc_"..force_name,
"Team " .. force_name .. ": " .. tostring(sat_count),
my_label_style)
end
end
end
function RocketGuiClick(event)
if not (event and event.element and event.element.valid) then return end
local player = game.players[event.element.player_index]
local name = event.element.name
if (name == "rocket-score") then
ExpandRocketGui(player)
end
end

View File

@ -17,12 +17,16 @@ require("config")
function SeparateSpawnsPlayerCreated(player_index)
local player = game.players[player_index]
-- Make sure spawn control tab is disabled
SetOarcGuiTabEnabled(player, OARC_SPAWN_CTRL_GUI_NAME, false)
SwitchOarcGuiTab(player, OARC_GAME_OPTS_GUI_TAB_NAME)
-- This checks if they have just joined the server.
-- No assigned force yet.
if (player.force.name ~= "player") then
FindUnusedSpawns(player, false)
end
player.force = global.ocfg.main_force
DisplayWelcomeTextGui(player)
end
@ -41,7 +45,7 @@ end
function SeparateSpawnsGenerateChunk(event)
local surface = event.surface
local chunkArea = event.area
-- Modify enemies first.
if global.ocfg.modified_enemy_spawning then
DowngradeWormsDistanceBasedOnChunkGenerate(event)
@ -71,7 +75,7 @@ function FindUnusedSpawns(player, remove_player)
if (global.playerSpawns[player.name] ~= nil) then
global.playerSpawns[player.name] = nil
end
-- Remove them from the delayed spawn queue if they are in it
for i=#global.delayedSpawns,1,-1 do
delayedSpawn = global.delayedSpawns[i]
@ -89,7 +93,7 @@ function FindUnusedSpawns(player, remove_player)
-- Transfer or remove a shared spawn if player is owner
if (global.sharedSpawns[player.name] ~= nil) then
local teamMates = global.sharedSpawns[player.name].players
if (#teamMates >= 1) then
@ -114,7 +118,11 @@ function FindUnusedSpawns(player, remove_player)
end
end
if (global.ocfg.enable_abandoned_base_removal and not nearOtherSpawn) then
-- Unused Chunk Removal mod (aka regrowth)
if (global.ocfg.enable_abandoned_base_removal and
(not nearOtherSpawn) and
game.active_mods["unused-chunk-removal"]) then
if (global.uniqueSpawns[player.name].vanilla) then
log("Returning a vanilla spawn back to available.")
table.insert(global.vanillaSpawns, {x=spawnPos.x,y=spawnPos.y})
@ -123,9 +131,15 @@ function FindUnusedSpawns(player, remove_player)
global.uniqueSpawns[player.name] = nil
log("Removing base: " .. spawnPos.x .. "," .. spawnPos.y)
OarcRegrowthMarkForRemoval(spawnPos, CHECK_SPAWN_UNGENERATED_CHUNKS_RADIUS+5)
remote.call("oarc_regrowth",
"area_removal_tilepos",
game.surfaces[GAME_SURFACE_NAME].index,
spawnPos,
CHECK_SPAWN_UNGENERATED_CHUNKS_RADIUS)
remote.call("oarc_regrowth",
"trigger_immediate_cleanup")
SendBroadcastMsg(player.name .. "'s base was marked for immediate clean up because they left within "..global.ocfg.minimum_online_time.." minutes of joining.")
global.chunk_regrow.force_removal_flag = game.tick
else
-- table.insert(global.unusedSpawns, global.uniqueSpawns[player.name]) -- Not used/implemented right now.
@ -181,7 +195,7 @@ function SetupAndClearSpawnAreas(surface, chunkArea)
-- Make chunks near a spawn safe by removing enemies
if CheckIfInArea(chunkAreaCenter,safeArea) then
RemoveAliensInArea(surface, chunkArea)
-- Create a warning area with heavily reduced enemies
elseif CheckIfInArea(chunkAreaCenter,warningArea) then
ReduceAliensInArea(surface, chunkArea, global.ocfg.spawn_config.safe_area.warn_reduction)
@ -204,17 +218,22 @@ function SetupAndClearSpawnAreas(surface, chunkArea)
RemoveInCircle(surface, chunkArea, "tree", spawn.pos, global.ocfg.spawn_config.gen_settings.land_area_tiles)
RemoveInCircle(surface, chunkArea, "resource", spawn.pos, global.ocfg.spawn_config.gen_settings.land_area_tiles+5)
RemoveInCircle(surface, chunkArea, "cliff", spawn.pos, global.ocfg.spawn_config.gen_settings.land_area_tiles+5)
-- RemoveDecorationsArea(surface, chunkArea)
RemoveDecorationsArea(surface, chunkArea)
local fill_tile = "grass-1"
if (game.active_mods["oarc-restricted-build"]) then
fill_tile = global.ocfg.locked_build_area_tile
end
if (global.ocfg.spawn_config.gen_settings.tree_circle) then
CreateCropCircle(surface, spawn.pos, chunkArea, global.ocfg.spawn_config.gen_settings.land_area_tiles)
CreateCropCircle(surface, spawn.pos, chunkArea, global.ocfg.spawn_config.gen_settings.land_area_tiles, fill_tile)
end
if (global.ocfg.spawn_config.gen_settings.tree_octagon) then
CreateCropOctagon(surface, spawn.pos, chunkArea, global.ocfg.spawn_config.gen_settings.land_area_tiles)
CreateCropOctagon(surface, spawn.pos, chunkArea, global.ocfg.spawn_config.gen_settings.land_area_tiles, fill_tile)
end
if (global.ocfg.spawn_config.gen_settings.moat_choice_enabled) then
if (spawn.moat) then
CreateMoat(surface, spawn.pos, chunkArea, global.ocfg.spawn_config.gen_settings.land_area_tiles)
CreateMoat(surface, spawn.pos, chunkArea, global.ocfg.spawn_config.gen_settings.land_area_tiles, fill_tile)
end
end
end
@ -240,7 +259,7 @@ function GetClosestUniqueSpawn(pos)
end
if (closest_key == nil) then
log("GetClosestUniqueSpawn ERROR - None found?")
-- log("GetClosestUniqueSpawn ERROR - None found?")
return nil
end
@ -264,7 +283,7 @@ function ModifyEnemySpawnsNearPlayerStartingAreas(event)
local closest_spawn = GetClosestUniqueSpawn(enemy_pos)
if (closest_spawn == nil) then
log("GetClosestUniqueSpawn ERROR - None found?")
-- log("GetClosestUniqueSpawn ERROR - None found?")
return
end
@ -400,7 +419,7 @@ function GetOnlinePlayersAtSharedSpawn(ownerName)
end
for _,playerName in pairs(global.sharedSpawns[ownerName].players) do
if (playerName == player.name) then
count = count + 1
end
@ -436,7 +455,7 @@ end
-- Initializes the globals used to track the special spawn and player
-- status information
function InitSpawnGlobalsAndForces()
-- This contains each player's spawn point. Literally where they will respawn.
-- There is a way in game to change this under one of the little menu features I added.
if (global.playerSpawns == nil) then
@ -502,7 +521,6 @@ function InitSpawnGlobalsAndForces()
main_force.set_spawn_position({x=0,y=0}, GAME_SURFACE_NAME)
end
function DoesPlayerHaveCustomSpawn(player)
for name,spawnPos in pairs(global.playerSpawns) do
if (player.name == name) then
@ -518,7 +536,7 @@ function ChangePlayerSpawn(player, pos)
end
function QueuePlayerForDelayedSpawn(playerName, spawn, moatEnabled, vanillaSpawn)
-- If we get a valid spawn point, setup the area
if ((spawn.x ~= 0) or (spawn.y ~= 0)) then
global.uniqueSpawns[playerName] = {pos=spawn,moat=moatEnabled,vanilla=vanillaSpawn}
@ -532,7 +550,7 @@ function QueuePlayerForDelayedSpawn(playerName, spawn, moatEnabled, vanillaSpawn
DisplayPleaseWaitForSpawnDialog(game.players[playerName], delay_spawn_seconds)
else
else
log("THIS SHOULD NOT EVER HAPPEN! Spawn failed!")
SendBroadcastMsg("ERROR!! Failed to create spawn point for: " .. playerName)
end
@ -587,8 +605,8 @@ function SendPlayerToNewSpawnAndCreateIt(delayedSpawn)
-- Chart the area.
ChartArea(player.force, delayedSpawn.pos, math.ceil(global.ocfg.spawn_config.gen_settings.land_area_tiles/CHUNK_SIZE), player.surface)
if (player.gui.center.wait_for_spawn_dialog ~= nil) then
player.gui.center.wait_for_spawn_dialog.destroy()
if (player.gui.screen.wait_for_spawn_dialog ~= nil) then
player.gui.screen.wait_for_spawn_dialog.destroy()
end
end
@ -615,13 +633,13 @@ function SendPlayerToRandomSpawn(player)
break
end
counter = counter + 1
end
end
end
end
function CreateForce(force_name)
local newForce = nil
-- Check if force already exists
if (game.forces[force_name] ~= nil) then
log("Force already exists!")
@ -731,7 +749,7 @@ function FindUnusedVanillaSpawn(surface, target_distance)
local best_distance = nil
for k,v in pairs(global.vanillaSpawns) do
-- Check if chunks nearby are not generated.
local chunk_pos = GetChunkPosFromTilePos(v)
if IsChunkAreaUngenerated(chunk_pos, CHECK_SPAWN_UNGENERATED_CHUNKS_RADIUS+15, surface) then
@ -740,7 +758,7 @@ function FindUnusedVanillaSpawn(surface, target_distance)
if ((best_key == nil) or (best_distance == nil)) then
best_key = k
best_distance = math.abs(math.sqrt((v.x^2) + (v.y^2)) - target_distance)
-- Check if it is closer to target_distance than previous option.
else
local new_distance = math.abs(math.sqrt((v.x^2) + (v.y^2)) - target_distance)
@ -749,12 +767,12 @@ function FindUnusedVanillaSpawn(surface, target_distance)
best_distance = new_distance
end
end
-- If it's not a valid spawn anymore, let's remove it.
else
log("Removing vanilla spawn due to chunks generated: x=" .. v.x .. ",y=" .. v.y)
table.remove(global.vanillaSpawns, k)
end
end
end
local spawn_pos = {x=0,y=0}
@ -770,13 +788,13 @@ end
function ValidateVanillaSpawns(surface)
for k,v in pairs(global.vanillaSpawns) do
-- Check if chunks nearby are not generated.
local chunk_pos = GetChunkPosFromTilePos(v)
if not IsChunkAreaUngenerated(chunk_pos, CHECK_SPAWN_UNGENERATED_CHUNKS_RADIUS+15, surface) then
log("Removing vanilla spawn due to chunks generated: x=" .. v.x .. ",y=" .. v.y)
table.remove(global.vanillaSpawns, k)
end
end
end
end

View File

@ -26,15 +26,23 @@ local SPAWN_GUI_MAX_HEIGHT = 1000
-- A display gui message
-- Meant to be display the first time a player joins.
function DisplayWelcomeTextGui(player)
if (TableLength(player.gui.center.children) > 0) then
if ((player.gui.screen["welcome_msg"] ~= nil) or
(player.gui.screen["spawn_opts"] ~= nil) or
(player.gui.screen["shared_spawn_opts"] ~= nil) or
(player.gui.screen["join_shared_spawn_wait_menu"] ~= nil) or
(player.gui.screen["buddy_spawn_opts"] ~= nil) or
(player.gui.screen["buddy_wait_menu"] ~= nil) or
(player.gui.screen["buddy_request_menu"] ~= nil) or
(player.gui.screen["wait_for_spawn_dialog"] ~= nil)) then
log("DisplayWelcomeTextGui called while some other dialog is already displayed!")
return
return false
end
player.gui.center.add{name = "welcome_msg",
local wGui = player.gui.screen.add{name = "welcome_msg",
type = "frame",
direction = "vertical",
caption=global.ocfg.welcome_title}
local wGui = player.gui.center.welcome_msg
wGui.auto_center=true
wGui.style.maximal_width = SPAWN_GUI_MAX_WIDTH
wGui.style.maximal_height = SPAWN_GUI_MAX_HEIGHT
@ -42,14 +50,17 @@ function DisplayWelcomeTextGui(player)
-- Start with server message.
AddLabel(wGui, "server_msg_lbl1", global.ocfg.server_rules, my_label_style)
AddLabel(wGui, "contact_info_msg_lbl1", global.ocfg.server_contact, my_label_style)
AddSpacer(wGui, "server_msg_spacer1")
AddSpacer(wGui)
-- Informational message about the scenario
AddLabel(wGui, "scenario_info_msg_lbl1", SCENARIO_INFO_MSG, my_label_style)
AddSpacer(wGui, "scenario_info_msg_spacer1")
AddSpacer(wGui)
-- Warning about spawn creation time
AddLabel(wGui, "spawn_time_msg_lbl1", {"oarc-spawn-time-warning-msg"}, my_warning_style)
-- Confirm button
AddSpacerLine(wGui)
local button_flow = wGui.add{type = "flow"}
button_flow.style.horizontal_align = "right"
button_flow.style.horizontally_stretchable = true
@ -58,6 +69,7 @@ function DisplayWelcomeTextGui(player)
caption={"oarc-i-understand"},
style = "confirm_button"}
return true
end
@ -73,8 +85,8 @@ function WelcomeTextGuiClick(event)
end
if (buttonClicked == "welcome_okay_btn") then
if (player.gui.center.welcome_msg ~= nil) then
player.gui.center.welcome_msg.destroy()
if (player.gui.screen.welcome_msg ~= nil) then
player.gui.screen.welcome_msg.destroy()
end
DisplaySpawnOptions(player)
end
@ -88,18 +100,18 @@ function DisplaySpawnOptions(player)
return
end
if (player.gui.center.spawn_opts ~= nil) then
if (player.gui.screen.spawn_opts ~= nil) then
log("Tried to display spawn options when it was already displayed!")
return
end
player.gui.center.add{name = "spawn_opts",
player.gui.screen.add{name = "spawn_opts",
type = "frame",
direction = "vertical",
caption={"oarc-spawn-options"}}
local sGui = player.gui.center.spawn_opts
local sGui = player.gui.screen.spawn_opts
sGui.style.maximal_width = SPAWN_GUI_MAX_WIDTH
sGui.style.maximal_height = SPAWN_GUI_MAX_HEIGHT
sGui.auto_center=true
-- Warnings and explanations...
local warn_msg = {"oarc-click-info-btn-help"}
@ -265,11 +277,11 @@ function SpawnOptsGuiClick(event)
return
end
if (player.gui.center.spawn_opts == nil) then
if (player.gui.screen.spawn_opts == nil) then
return -- Gui event unrelated to this gui.
end
local pgcs = player.gui.center.spawn_opts
local pgcs = player.gui.screen.spawn_opts
local joinMainTeamRadio, joinOwnTeamRadio, moatChoice, vanillaChoice = false
@ -309,8 +321,8 @@ function SpawnOptsGuiClick(event)
ChangePlayerSpawn(player, player.force.get_spawn_position(GAME_SURFACE_NAME))
SendBroadcastMsg({"oarc-player-is-joining-main-force", player.name})
ChartArea(player.force, player.position, math.ceil(global.ocfg.spawn_config.gen_settings.land_area_tiles/CHUNK_SIZE), player.surface)
-- Create the button at the top left for setting respawn point and sharing base.
CreateSpawnCtrlGui(player)
-- Unlock spawn control gui tab
SetOarcGuiTabEnabled(player, OARC_SPAWN_CTRL_GUI_NAME, true)
elseif ((elemName == "isolated_spawn_near") or (elemName == "isolated_spawn_far")) then
@ -361,8 +373,8 @@ function SpawnOptsGuiClick(event)
SendBroadcastMsg({"oarc-player-is-joining-far", player.name})
end
-- Create the button at the top left for setting respawn point and sharing base.
CreateSpawnCtrlGui(player)
-- Unlock spawn control gui tab
SetOarcGuiTabEnabled(player, OARC_SPAWN_CTRL_GUI_NAME, true)
player.print({"oarc-please-wait"})
player.print({"", {"oarc-please-wait"}, "!"})
@ -388,12 +400,13 @@ end
-- Display the spawn options and explanation
function DisplaySharedSpawnOptions(player)
player.gui.center.add{name = "shared_spawn_opts",
player.gui.screen.add{name = "shared_spawn_opts",
type = "frame",
direction = "vertical",
caption={"oarc-avail-bases-join"}}
local shGuiFrame = player.gui.center.shared_spawn_opts
local shGuiFrame = player.gui.screen.shared_spawn_opts
shGuiFrame.auto_center = true
local shGui = shGuiFrame.add{type="scroll-pane", name="spawns_scroll_pane", caption=""}
ApplyStyle(shGui, my_fixed_width_style)
shGui.style.maximal_width = SPAWN_GUI_MAX_WIDTH
@ -445,8 +458,8 @@ function SharedSpwnOptsGuiClick(event)
-- Check for cancel button, return to spawn options
if (buttonClicked == "shared_spawn_cancel") then
DisplaySpawnOptions(player)
if (player.gui.center.shared_spawn_opts ~= nil) then
player.gui.center.shared_spawn_opts.destroy()
if (player.gui.screen.shared_spawn_opts ~= nil) then
player.gui.screen.shared_spawn_opts.destroy()
end
-- Else check for which spawn was selected
@ -464,8 +477,8 @@ function SharedSpwnOptsGuiClick(event)
table.insert(global.sharedSpawns[spawnName].joinQueue, player.name)
-- Clear the shared spawn options gui.
if (player.gui.center.shared_spawn_opts ~= nil) then
player.gui.center.shared_spawn_opts.destroy()
if (player.gui.screen.shared_spawn_opts ~= nil) then
player.gui.screen.shared_spawn_opts.destroy()
end
-- Display wait menu with cancel button.
@ -481,11 +494,11 @@ end
function DisplaySharedSpawnJoinWaitMenu(player)
player.gui.center.add{name = "join_shared_spawn_wait_menu",
local sGui = player.gui.screen.add{name = "join_shared_spawn_wait_menu",
type = "frame",
direction = "vertical",
caption={"oarc-waiting-for-spawn-owner"}}
local sGui = player.gui.center.join_shared_spawn_wait_menu
sGui.auto_center = true
sGui.style.maximal_width = SPAWN_GUI_MAX_WIDTH
sGui.style.maximal_height = SPAWN_GUI_MAX_HEIGHT
@ -509,13 +522,13 @@ function SharedSpawnJoinWaitMenuClick(event)
return
end
if (player.gui.center.join_shared_spawn_wait_menu == nil) then
if (player.gui.screen.join_shared_spawn_wait_menu == nil) then
return -- Gui event unrelated to this gui.
end
-- Check if player is cancelling the request.
if (elemName == "cancel_shared_spawn_wait_menu") then
player.gui.center.join_shared_spawn_wait_menu.destroy()
player.gui.screen.join_shared_spawn_wait_menu.destroy()
DisplaySpawnOptions(player)
-- Find and remove the player from the joinQueue they were in.
@ -535,14 +548,6 @@ function SharedSpawnJoinWaitMenuClick(event)
end
end
function CreateSpawnCtrlGui(player)
if player and (mod_gui.get_button_flow(player).spwn_ctrls == nil) then
mod_gui.get_button_flow(player).add{name="spwn_ctrls", type="button", caption={"oarc-spawn-ctrl"}, style=mod_gui.button_style}
end
end
local function IsSharedSpawnActive(player)
if ((global.sharedSpawns[player.name] == nil) or
(global.sharedSpawns[player.name].openAccess == false)) then
@ -570,70 +575,62 @@ function GetRandomSpawnPoint()
return {x=0,y=0}
end
-- This is a toggle function, it either shows or hides the spawn controls
function ExpandSpawnCtrlGui(player, tick)
local spwnCtrlPanel = mod_gui.get_frame_flow(player)["spwn_ctrl_panel"]
if (spwnCtrlPanel) then
spwnCtrlPanel.destroy()
else
local spwnCtrlPanel = mod_gui.get_frame_flow(player).add{type="frame",
name="spwn_ctrl_panel", caption={"oarc-spawn-controls"}}
local spwnCtrls = spwnCtrlPanel.add{type="scroll-pane",
name="spwn_ctrl_panel", caption=""}
ApplyStyle(spwnCtrls, my_fixed_width_style)
spwnCtrls.style.maximal_height = SPAWN_GUI_MAX_HEIGHT
spwnCtrls.horizontal_scroll_policy = "never"
function CreateSpawnCtrlGuiTab(tab_container, player)
local spwnCtrls = tab_container.add{
type="scroll-pane",
name="spwn_ctrl_panel",
caption=""}
ApplyStyle(spwnCtrls, my_fixed_width_style)
spwnCtrls.style.maximal_height = SPAWN_GUI_MAX_HEIGHT
spwnCtrls.horizontal_scroll_policy = "never"
if global.ocfg.enable_shared_spawns then
if (global.uniqueSpawns[player.name] ~= nil) then
-- This checkbox allows people to join your base when they first
-- start the game.
spwnCtrls.add{type="checkbox", name="accessToggle",
caption={"oarc-spawn-allow-joiners"},
state=IsSharedSpawnActive(player)}
ApplyStyle(spwnCtrls["accessToggle"], my_fixed_width_style)
end
end
-- Sets the player's custom spawn point to their current location
if ((tick - global.playerCooldowns[player.name].setRespawn) >
(global.ocfg.respawn_cooldown_min * TICKS_PER_MINUTE)) then
spwnCtrls.add{type="button", name="setRespawnLocation", caption={"oarc-set-respawn-loc"}}
spwnCtrls["setRespawnLocation"].style.font = "default-small-semibold"
else
AddLabel(spwnCtrls,"respawn_cooldown_note1",
{"oarc-set-respawn-loc-cooldown", formattime((global.ocfg.respawn_cooldown_min * TICKS_PER_MINUTE)-(tick - global.playerCooldowns[player.name].setRespawn))}, my_note_style)
end
AddLabel(spwnCtrls, "respawn_cooldown_note2", {"oarc-set-respawn-note"}, my_note_style)
-- Display a list of people in the join queue for your base.
if (global.ocfg.enable_shared_spawns and IsSharedSpawnActive(player)) then
if ((global.sharedSpawns[player.name].joinQueue ~= nil) and
(#global.sharedSpawns[player.name].joinQueue > 0)) then
AddLabel(spwnCtrls, "drop_down_msg_lbl1", {"oarc-select-player-join-queue"}, my_label_style)
spwnCtrls.add{name = "join_queue_dropdown",
type = "drop-down",
items = global.sharedSpawns[player.name].joinQueue}
spwnCtrls.add{name = "accept_player_request",
type = "button",
caption={"oarc-accept"}}
spwnCtrls.add{name = "reject_player_request",
type = "button",
caption={"oarc-reject"}}
else
AddLabel(spwnCtrls, "empty_join_queue_note1", {"oarc-no-player-join-reqs"}, my_note_style)
end
spwnCtrls.add{name = "join_queue_spacer", type = "label",
caption=" "}
if global.ocfg.enable_shared_spawns then
if (global.uniqueSpawns[player.name] ~= nil) then
-- This checkbox allows people to join your base when they first
-- start the game.
spwnCtrls.add{type="checkbox", name="accessToggle",
caption={"oarc-spawn-allow-joiners"},
state=IsSharedSpawnActive(player)}
ApplyStyle(spwnCtrls["accessToggle"], my_fixed_width_style)
end
end
end
-- Sets the player's custom spawn point to their current location
if ((game.tick - global.playerCooldowns[player.name].setRespawn) >
(global.ocfg.respawn_cooldown_min * TICKS_PER_MINUTE)) then
spwnCtrls.add{type="button", name="setRespawnLocation", caption={"oarc-set-respawn-loc"}}
spwnCtrls["setRespawnLocation"].style.font = "default-small-semibold"
else
AddLabel(spwnCtrls,"respawn_cooldown_note1",
{"oarc-set-respawn-loc-cooldown", formattime((global.ocfg.respawn_cooldown_min * TICKS_PER_MINUTE)-(game.tick - global.playerCooldowns[player.name].setRespawn))}, my_note_style)
end
AddLabel(spwnCtrls, "respawn_cooldown_note2", {"oarc-set-respawn-note"}, my_note_style)
-- Display a list of people in the join queue for your base.
if (global.ocfg.enable_shared_spawns and IsSharedSpawnActive(player)) then
if ((global.sharedSpawns[player.name].joinQueue ~= nil) and
(#global.sharedSpawns[player.name].joinQueue > 0)) then
AddLabel(spwnCtrls, "drop_down_msg_lbl1", {"oarc-select-player-join-queue"}, my_label_style)
spwnCtrls.add{name = "join_queue_dropdown",
type = "drop-down",
items = global.sharedSpawns[player.name].joinQueue}
spwnCtrls.add{name = "accept_player_request",
type = "button",
caption={"oarc-accept"}}
spwnCtrls.add{name = "reject_player_request",
type = "button",
caption={"oarc-reject"}}
else
AddLabel(spwnCtrls, "empty_join_queue_note1", {"oarc-no-player-join-reqs"}, my_note_style)
end
spwnCtrls.add{name = "join_queue_spacer", type = "label",
caption=" "}
end
end
function SpawnCtrlGuiOptionsSelect(event)
if not (event and event.element and event.element.valid) then return end
@ -664,6 +661,7 @@ function SpawnCtrlGuiOptionsSelect(event)
SendBroadcastMsg({"oarc-stop-shared-base", player.name})
end
end
FakeTabChangeEventOarcGui(player)
end
end
@ -678,10 +676,6 @@ function SpawnCtrlGuiClick(event)
return
end
if (elemName == "spwn_ctrls") then
ExpandSpawnCtrlGui(player, event.tick)
end
if (event.element.parent) then
if (event.element.parent.name ~= "spwn_ctrl_panel") then
return
@ -692,7 +686,7 @@ function SpawnCtrlGuiClick(event)
if (elemName == "setRespawnLocation") then
if DoesPlayerHaveCustomSpawn(player) then
ChangePlayerSpawn(player, player.position)
ExpandSpawnCtrlGui(player, event.tick)
FakeTabChangeEventOarcGui(player)
player.print({"oarc-spawn-point-updated"})
end
end
@ -703,7 +697,7 @@ function SpawnCtrlGuiClick(event)
if ((event.element.parent.join_queue_dropdown == nil) or
(event.element.parent.join_queue_dropdown.selected_index == 0)) then
player.print({"oarc-selected-player-not-wait"})
ExpandSpawnCtrlGui(player, event.tick)
FakeTabChangeEventOarcGui(player)
return
end
@ -713,18 +707,18 @@ function SpawnCtrlGuiClick(event)
if ((game.players[joinQueuePlayerChoice] == nil) or
(not game.players[joinQueuePlayerChoice].connected)) then
player.print({"oarc-selected-player-not-wait"})
ExpandSpawnCtrlGui(player, event.tick)
FakeTabChangeEventOarcGui(player)
return
end
if (elemName == "reject_player_request") then
player.print({"oarc-reject-joiner", joinQueuePlayerChoice})
SendMsg(joinQueuePlayerChoice, {"oarc-your-request-rejected"})
ExpandSpawnCtrlGui(player, event.tick)
FakeTabChangeEventOarcGui(player)
-- Close the waiting players menu
if (game.players[joinQueuePlayerChoice].gui.center.join_shared_spawn_wait_menu) then
game.players[joinQueuePlayerChoice].gui.center.join_shared_spawn_wait_menu.destroy()
if (game.players[joinQueuePlayerChoice].gui.screen.join_shared_spawn_wait_menu) then
game.players[joinQueuePlayerChoice].gui.screen.join_shared_spawn_wait_menu.destroy()
DisplaySpawnOptions(game.players[joinQueuePlayerChoice])
end
@ -751,8 +745,8 @@ function SpawnCtrlGuiClick(event)
SendBroadcastMsg({"oarc-player-joining-base", joinQueuePlayerChoice, player.name})
-- Close the waiting players menu
if (game.players[joinQueuePlayerChoice].gui.center.join_shared_spawn_wait_menu) then
game.players[joinQueuePlayerChoice].gui.center.join_shared_spawn_wait_menu.destroy()
if (game.players[joinQueuePlayerChoice].gui.screen.join_shared_spawn_wait_menu) then
game.players[joinQueuePlayerChoice].gui.screen.join_shared_spawn_wait_menu.destroy()
end
-- Spawn the player
@ -763,9 +757,8 @@ function SpawnCtrlGuiClick(event)
table.insert(global.sharedSpawns[player.name].players, joiningPlayer.name)
joiningPlayer.force = game.players[player.name].force
-- Create the button at the top left for setting respawn point and sharing base.
CreateSpawnCtrlGui(joiningPlayer)
ExpandSpawnCtrlGui(player, event.tick)
-- Unlock spawn control gui tab
SetOarcGuiTabEnabled(joiningPlayer, OARC_SPAWN_CTRL_GUI_NAME, true)
else
SendBroadcastMsg({"oarc-player-left-while-joining", joinQueuePlayerChoice})
end
@ -775,18 +768,24 @@ end
-- Display the buddy spawn menu
function DisplayBuddySpawnOptions(player)
player.gui.center.add{name = "buddy_spawn_opts",
local buddyGui = player.gui.screen.add{name = "buddy_spawn_opts",
type = "frame",
direction = "vertical",
caption={"oarc-buddy-spawn-options"}}
local buddyGui = player.gui.center.buddy_spawn_opts
buddyGui.auto_center = true
buddyGui.style.maximal_width = SPAWN_GUI_MAX_WIDTH
buddyGui.style.maximal_height = SPAWN_GUI_MAX_HEIGHT
-- Warnings and explanations...
AddLabel(buddyGui, "buddy_info_msg", {"oarc-buddy-spawn-instructions"}, my_label_style)
-- AddSpacerLine(buddyGui, "buddy_info_spacer")
AddSpacer(buddyGui)
-- The buddy spawning options.
local buddySpawnFlow = buddyGui.add{name = "spawn_buddy_flow",
type = "frame",
direction="vertical",
style = "bordered_frame"}
buddyList = {}
for _,buddyName in pairs(global.waitingBuddies) do
@ -795,20 +794,14 @@ function DisplayBuddySpawnOptions(player)
end
end
AddLabel(buddyGui, "drop_down_msg_lbl1", {"oarc-buddy-select-info"}, my_label_style)
buddyGui.add{name = "waiting_buddies_dropdown",
AddLabel(buddySpawnFlow, "drop_down_msg_lbl1", {"oarc-buddy-select-info"}, my_label_style)
buddySpawnFlow.add{name = "waiting_buddies_dropdown",
type = "drop-down",
items = buddyList}
buddyGui.add{name = "refresh_buddy_list",
buddySpawnFlow.add{name = "refresh_buddy_list",
type = "button",
caption={"oarc-buddy-refresh"}}
-- AddSpacerLine(buddyGui, "waiting_buddies_spacer")
-- The buddy spawning options.
local buddySpawnFlow = buddyGui.add{name = "spawn_buddy_flow",
type = "flow",
direction="vertical"}
-- AddSpacerLine(buddySpawnFlow)
-- Allow picking of teams
if (global.ocfg.enable_separate_teams) then
@ -832,7 +825,7 @@ function DisplayBuddySpawnOptions(player)
state=false}
end
AddSpacer(buddyGui, "buddy_options_spacer")
-- AddSpacerLine(buddySpawnFlow)
buddySpawnFlow.add{name = "buddy_spawn_request_near",
type = "button",
caption={"oarc-buddy-spawn-near"},
@ -841,18 +834,15 @@ function DisplayBuddySpawnOptions(player)
type = "button",
caption={"oarc-buddy-spawn-far"},
style = "confirm_button"}
AddSpacerLine(buddyGui, "buddy_spawn_spacer")
AddSpacer(buddyGui)
buddyGui.add{name = "buddy_spawn_cancel",
type = "button",
caption={"oarc-cancel-return-to-previous"},
style = "back_button"}
-- Some final notes
AddSpacerLine(buddyGui, "note_spacer1")
AddSpacerLine(buddyGui)
if (global.ocfg.max_players_shared_spawn > 0) then
AddLabel(buddyGui, "buddy_max_players_lbl1",
{"oarc-max-players-shared-spawn", global.ocfg.max_players_shared_spawn-1},
@ -875,17 +865,19 @@ function BuddySpawnOptsGuiClick(event)
return
end
if (player.gui.center.buddy_spawn_opts == nil) then
if (player.gui.screen.buddy_spawn_opts == nil) then
return -- Gui event unrelated to this gui.
end
local waiting_buddies_dropdown = player.gui.screen.buddy_spawn_opts.spawn_buddy_flow.waiting_buddies_dropdown
-- Just refresh the buddy list dropdown values only.
if (elemName == "refresh_buddy_list") then
player.gui.center.buddy_spawn_opts.waiting_buddies_dropdown.clear_items()
waiting_buddies_dropdown.clear_items()
for _,buddyName in pairs(global.waitingBuddies) do
if (player.name ~= buddyName) then
player.gui.center.buddy_spawn_opts.waiting_buddies_dropdown.add_item(buddyName)
waiting_buddies_dropdown.add_item(buddyName)
end
end
return
@ -893,7 +885,7 @@ function BuddySpawnOptsGuiClick(event)
-- Handle the cancel button to exit this menu
if (elemName == "buddy_spawn_cancel") then
player.gui.center.buddy_spawn_opts.destroy()
player.gui.screen.buddy_spawn_opts.destroy()
DisplaySpawnOptions(player)
-- Remove them from the buddy list when they cancel
@ -912,10 +904,10 @@ function BuddySpawnOptsGuiClick(event)
if ((elemName == "buddy_spawn_request_near") or
(elemName == "buddy_spawn_request_far")) then
local buddySpawnGui = player.gui.center.buddy_spawn_opts
local buddySpawnGui = player.gui.screen.buddy_spawn_opts.spawn_buddy_flow
local dropDownIndex = buddySpawnGui.waiting_buddies_dropdown.selected_index
if (dropDownIndex > 0) then
if ((dropDownIndex > 0) and (dropDownIndex <= #buddySpawnGui.waiting_buddies_dropdown.items)) then
buddyChoice = buddySpawnGui.waiting_buddies_dropdown.get_item(dropDownIndex)
else
player.print({"oarc-invalid-buddy"})
@ -933,22 +925,22 @@ function BuddySpawnOptsGuiClick(event)
end
if (not buddyIsStillWaiting) then
player.print({"oarc-buddy-not-avail"})
player.gui.center.buddy_spawn_opts.destroy()
player.gui.screen.buddy_spawn_opts.destroy()
DisplayBuddySpawnOptions(player)
return
end
if (global.ocfg.enable_separate_teams) then
joinMainTeamRadio = buddySpawnGui.spawn_buddy_flow.buddy_spawn_main_team_radio.state
joinOwnTeamRadio = buddySpawnGui.spawn_buddy_flow.buddy_spawn_new_team_radio.state
joinBuddyTeamRadio = buddySpawnGui.spawn_buddy_flow.buddy_spawn_buddy_team_radio.state
joinMainTeamRadio = buddySpawnGui.buddy_spawn_main_team_radio.state
joinOwnTeamRadio = buddySpawnGui.buddy_spawn_new_team_radio.state
joinBuddyTeamRadio = buddySpawnGui.buddy_spawn_buddy_team_radio.state
else
joinMainTeamRadio = true
joinOwnTeamRadio = false
joinBuddyTeamRadio = false
end
if (global.ocfg.spawn_config.gen_settings.moat_choice_enabled) then
moatChoice = buddySpawnGui.spawn_buddy_flow.buddy_spawn_moat_option_checkbox.state
moatChoice = buddySpawnGui.buddy_spawn_moat_option_checkbox.state
end
-- Save the chosen spawn options somewhere for later use.
@ -959,13 +951,13 @@ function BuddySpawnOptsGuiClick(event)
buddyChoice=buddyChoice,
distChoice=elemName}
player.gui.center.buddy_spawn_opts.destroy()
player.gui.screen.buddy_spawn_opts.destroy()
-- Display prompts to the players
DisplayBuddySpawnWaitMenu(player)
DisplayBuddySpawnRequestMenu(game.players[buddyChoice], player.name)
if (game.players[buddyChoice].gui.center.buddy_spawn_opts ~= nil) then
game.players[buddyChoice].gui.center.buddy_spawn_opts.destroy()
if (game.players[buddyChoice].gui.screen.buddy_spawn_opts ~= nil) then
game.players[buddyChoice].gui.screen.buddy_spawn_opts.destroy()
end
-- Remove them from the buddy list while they make up their minds.
@ -984,18 +976,18 @@ end
function DisplayBuddySpawnWaitMenu(player)
player.gui.center.add{name = "buddy_wait_menu",
local sGui = player.gui.screen.add{name = "buddy_wait_menu",
type = "frame",
direction = "vertical",
caption={"oarc-waiting-for-buddy"}}
local sGui = player.gui.center.buddy_wait_menu
sGui.auto_center = true
sGui.style.maximal_width = SPAWN_GUI_MAX_WIDTH
sGui.style.maximal_height = SPAWN_GUI_MAX_HEIGHT
-- Warnings and explanations...
AddLabel(sGui, "warning_lbl1", {"oarc-wait-buddy-select-yes"}, my_warning_style)
AddSpacer(sGui, "warning_spacer")
AddSpacer(sGui)
sGui.add{name = "cancel_buddy_wait_menu",
type = "button",
caption={"oarc-cancel-return-to-previous"}}
@ -1012,22 +1004,22 @@ function BuddySpawnWaitMenuClick(event)
return
end
if (player.gui.center.buddy_wait_menu == nil) then
if (player.gui.screen.buddy_wait_menu == nil) then
return -- Gui event unrelated to this gui.
end
-- Check if player is cancelling the request.
if (elemName == "cancel_buddy_wait_menu") then
player.gui.center.buddy_wait_menu.destroy()
player.gui.screen.buddy_wait_menu.destroy()
DisplaySpawnOptions(player)
local buddy = game.players[global.buddySpawnOptions[player.name].buddyChoice]
if (buddy.gui.center.buddy_request_menu ~= nil) then
buddy.gui.center.buddy_request_menu.destroy()
if (buddy.gui.screen.buddy_request_menu ~= nil) then
buddy.gui.screen.buddy_request_menu.destroy()
end
if (buddy.gui.center.buddy_spawn ~= nil) then
buddy.gui.center.buddy_spawn_opts.destroy()
if (buddy.gui.screen.buddy_spawn ~= nil) then
buddy.gui.screen.buddy_spawn_opts.destroy()
end
DisplaySpawnOptions(buddy)
@ -1042,11 +1034,11 @@ function DisplayBuddySpawnRequestMenu(player, requestingBuddyName)
return
end
player.gui.center.add{name = "buddy_request_menu",
local sGui = player.gui.screen.add{name = "buddy_request_menu",
type = "frame",
direction = "vertical",
caption="Buddy Request!"}
local sGui = player.gui.center.buddy_request_menu
sGui.auto_center = true
sGui.style.maximal_width = SPAWN_GUI_MAX_WIDTH
sGui.style.maximal_height = SPAWN_GUI_MAX_HEIGHT
@ -1078,7 +1070,7 @@ function DisplayBuddySpawnRequestMenu(player, requestingBuddyName)
local requestText = {"", requestingBuddyName, {"oarc-buddy-txt-would-like"}, teamText, {"oarc-buddy-txt-next-to-you"}, moatText, distText}
AddLabel(sGui, "note_lbl1", requestText, my_warning_style)
AddSpacer(sGui, "note_spacer1")
AddSpacer(sGui)
sGui.add{name = "accept_buddy_request",
@ -1102,7 +1094,7 @@ function BuddySpawnRequestMenuClick(event)
return
end
if (player.gui.center.buddy_request_menu == nil) then
if (player.gui.screen.buddy_request_menu == nil) then
return -- Gui event unrelated to this gui.
end
@ -1121,7 +1113,7 @@ function BuddySpawnRequestMenuClick(event)
player.print("Error! Invalid buddy info...")
log("Error! Invalid buddy info...")
player.gui.center.buddy_request_menu.destroy()
player.gui.screen.buddy_request_menu.destroy()
DisplaySpawnOptions(player)
end
else
@ -1131,11 +1123,11 @@ function BuddySpawnRequestMenuClick(event)
-- Handle player accepted
if (elemName == "accept_buddy_request") then
if (game.players[requesterName].gui.center.buddy_wait_menu ~= nil) then
game.players[requesterName].gui.center.buddy_wait_menu.destroy()
if (game.players[requesterName].gui.screen.buddy_wait_menu ~= nil) then
game.players[requesterName].gui.screen.buddy_wait_menu.destroy()
end
if (player.gui.center.buddy_request_menu ~= nil) then
player.gui.center.buddy_request_menu.destroy()
if (player.gui.screen.buddy_request_menu ~= nil) then
player.gui.screen.buddy_request_menu.destroy()
end
-- Create a new spawn point
@ -1180,9 +1172,9 @@ function BuddySpawnRequestMenuClick(event)
QueuePlayerForDelayedSpawn(requesterName, buddySpawn, requesterOptions.moatChoice, false)
SendBroadcastMsg(requesterName .. " and " .. player.name .. " are joining the game together!")
-- Create the button at the top left for setting respawn point and sharing base.
CreateSpawnCtrlGui(player)
CreateSpawnCtrlGui(game.players[requesterName])
-- Unlock spawn control gui tab
SetOarcGuiTabEnabled(player, OARC_SPAWN_CTRL_GUI_NAME, true)
SetOarcGuiTabEnabled(game.players[requesterName], OARC_SPAWN_CTRL_GUI_NAME, true)
player.print({"oarc-please-wait"})
player.print({"", {"oarc-please-wait"}, "!"})
@ -1196,16 +1188,16 @@ function BuddySpawnRequestMenuClick(event)
-- Check if player is cancelling the request.
if (elemName == "decline_buddy_request") then
player.gui.center.buddy_request_menu.destroy()
player.gui.screen.buddy_request_menu.destroy()
DisplaySpawnOptions(player)
local requesterBuddy = game.players[requesterName]
if (requesterBuddy.gui.center.buddy_wait_menu ~= nil) then
requesterBuddy.gui.center.buddy_wait_menu.destroy()
if (requesterBuddy.gui.screen.buddy_wait_menu ~= nil) then
requesterBuddy.gui.screen.buddy_wait_menu.destroy()
end
if (requesterBuddy.gui.center.buddy_spawn ~= nil) then
requesterBuddy.gui.center.buddy_spawn_opts.destroy()
if (requesterBuddy.gui.screen.buddy_spawn ~= nil) then
requesterBuddy.gui.screen.buddy_spawn_opts.destroy()
end
DisplaySpawnOptions(requesterBuddy)
@ -1216,11 +1208,11 @@ end
function DisplayPleaseWaitForSpawnDialog(player, delay_seconds)
player.gui.center.add{name = "wait_for_spawn_dialog",
local pleaseWaitGui = player.gui.screen.add{name = "wait_for_spawn_dialog",
type = "frame",
direction = "vertical",
caption={"oarc-spawn-wait"}}
local pleaseWaitGui = player.gui.center.wait_for_spawn_dialog
pleaseWaitGui.auto_center = true
pleaseWaitGui.style.maximal_width = SPAWN_GUI_MAX_WIDTH
pleaseWaitGui.style.maximal_height = SPAWN_GUI_MAX_HEIGHT

View File

@ -2,13 +2,6 @@
-- Apr 2017
-- Allows adding play tags
function CreateTagGui(event)
local player = game.players[event.player_index]
if mod_gui.get_button_flow(player).tag == nil then
mod_gui.get_button_flow(player).add{name="tag", type="button", caption="Tag", style=mod_gui.button_style}
end
end
-- Tag list
local roles = {
{display_name = "[Solo]"},
@ -26,38 +19,28 @@ local roles = {
{display_name = "[Rocket]"},
{display_name = "[AFK]"}}
local function ExpandTagGui(player)
local frame = mod_gui.get_frame_flow(player)["tag-panel"]
if (frame) then
frame.destroy()
else
local frame = mod_gui.get_frame_flow(player).add{type="frame", name="tag-panel", caption="What are you doing:", direction = "vertical"}
for _, role in pairs(roles) do
frame.add{type="button", caption=role.display_name, name=role.display_name}
end
if (player.admin) then
frame.add{type="button", caption="[Admin]", name="admin"}
frame.add{type="button", caption="[Moderator]", name="moderator"}
end
frame.add{type="button", caption="Clear", name="clear_btn"}
function CreateTagGuiTab(tab_container, player)
for i,role in ipairs(roles) do
tab_container.add{type="button", caption=role.display_name, name=role.display_name}
end
if (player.admin) then
tab_container.add{type="button", caption="[Admin]", name="admin"}
tab_container.add{type="button", caption="[Moderator]", name="moderator"}
end
tab_container.add{type="button", caption="Clear", name="clear_btn"}
end
function TagGuiClick(event)
function TagGuiClick(event)
if not (event and event.element and event.element.valid) then return end
local player = game.players[event.element.player_index]
local name = event.element.name
if (name == "tag") then
ExpandTagGui(player)
end
if (name == "clear_btn") then
if (name == "clear_btn") then
player.tag = ""
return
end
for _, role in pairs(roles) do
for i,role in ipairs(roles) do
if (name == role.display_name) then
player.tag = role.display_name
elseif (name == "admin") then