From 7ec25774750f60eeb41bd32e9f5b8f4fb8ab1eb1 Mon Sep 17 00:00:00 2001 From: danielmartin0 Date: Thu, 5 Feb 2026 15:33:30 +0000 Subject: [PATCH 1/6] 1.9.0 --- changelog.txt | 103 ++ info.json | 2 +- maps/pirates/api_events.lua | 97 +- maps/pirates/commands.lua | 2288 ++++++++++++++++++----------------- 4 files changed, 1342 insertions(+), 1148 deletions(-) create mode 100644 changelog.txt diff --git a/changelog.txt b/changelog.txt new file mode 100644 index 000000000..26feb057c --- /dev/null +++ b/changelog.txt @@ -0,0 +1,103 @@ +--------------------------------------------------------------------------------------------------- +Version: 1.9.1 +Date: ???? + Changes: +--------------------------------------------------------------------------------------------------- +Version: 1.9.0 +Date: 2026-02-05 + Changes: + - Singleplayer games now launch the player on a ship automatically. +--------------------------------------------------------------------------------------------------- +Version: 1.8.19 +Date: 2026-01-26 + Changes: + - Players leaving crews and without leaving the server now immediately send their items to the captain's cabin rather than doing so on a timer. +--------------------------------------------------------------------------------------------------- +Version: 1.8.18 +Date: 2026-01-19 + Bugfixes: + - Fixed that the most recent version enabled debug mode. +--------------------------------------------------------------------------------------------------- +Version: 1.8.17 +Date: 2026-01-18 + Bugfixes: + - Fixed a bug in which player permissions could be set incorrectly if there were two or more crews on the server. + Changes: + - Empty crews now autodisband after 72 hours rather than 96. +--------------------------------------------------------------------------------------------------- +Version: 1.8.16 +Date: 2025-05-30 + Bugfixes: + - It is no longer impossible to use the centrifuges on newly generated uranium islands. + - The Compilatron quest no longer appears on the cave island since the Compilatron entity was removed in 2.0. + - Tweaked some autoplace settings code. +--------------------------------------------------------------------------------------------------- +Version: 1.8.15 +Date: 2025-05-06 + Info: + - Updated the changelog for clarity. +--------------------------------------------------------------------------------------------------- +Version: 1.8.13 +Date: 2025-05-05 + Bugfixes: + - Fixed that biters would not attack unless the player attacks first. This will not apply to the current islands in a given save, but is fixed for future islands. +--------------------------------------------------------------------------------------------------- +Version: 1.8.12 +Date: 2025-04-19 + Changes: + - Default difficulty changed from 'Easy' to 'Normal'. +--------------------------------------------------------------------------------------------------- +Version: 1.8.11 +Date: 2025-04-19 + Changes: + - Fixed that research effects were not always properly applied. +--------------------------------------------------------------------------------------------------- +Version: 1.8.10 +Date: 2025-04-12 + Changes: + - New thumbnail. +--------------------------------------------------------------------------------------------------- +Version: 1.8.9 +Date: 2025-04-12 + Changes: + - New thumbnail. +--------------------------------------------------------------------------------------------------- +Version: 1.8.7 +Date: 2025-04-12 + Changes: + - Rebased on Comfy. +--------------------------------------------------------------------------------------------------- +Version: 1.8.6 +Date: 2025-03-02 + Changes: + - Marked as incompatible with Space Age and Quality. +--------------------------------------------------------------------------------------------------- +Version: 1.8.5 +Date: 2025-02-28 + Changes: + - Fixed crash in api_on_tick when attempting to equalise fluid storages. +--------------------------------------------------------------------------------------------------- +Version: 1.8.4 +Date: 2025-02-25 + Changes: + - Fix turbo transport belts being teleported rather than cloned when the boat moves. +--------------------------------------------------------------------------------------------------- +Version: 1.8.3 +Date: 2025-02-25 + Changes: + - Fixed certain damage upgrades not being applied correctly. +--------------------------------------------------------------------------------------------------- +Version: 1.8.2 +Date: 2025-02-23 + Changes: + - Fixed crash on 'An interface already exists under with name: space_finish_script'. +--------------------------------------------------------------------------------------------------- +Version: 1.8.1 +Date: 2025-01-13 + Info: + - Description updated. +--------------------------------------------------------------------------------------------------- +Version: 1.8.0 +Date: 2025-01-13 + Changes: + - This mod no longer functions as a scenario. Pre-existing 'scenario' saves are not compatible with 1.8.0. \ No newline at end of file diff --git a/info.json b/info.json index 9e26dfeeb..0967ef424 100644 --- a/info.json +++ b/info.json @@ -1 +1 @@ -{} \ No newline at end of file +{} diff --git a/maps/pirates/api_events.lua b/maps/pirates/api_events.lua index 143b6df2f..0939ac7d1 100644 --- a/maps/pirates/api_events.lua +++ b/maps/pirates/api_events.lua @@ -12,7 +12,9 @@ local Ai = require("maps.pirates.ai") -- local Structures = require 'maps.pirates.structures.structures' local Boats = require("maps.pirates.structures.boats.boats") local Surfaces = require("maps.pirates.surfaces.surfaces") --- local Progression = require 'maps.pirates.progression' +local Progression = require("maps.pirates.progression") +local Overworld = require("maps.pirates.overworld") +local Crowsnest = require("maps.pirates.surfaces.crowsnest") local IslandEnum = require("maps.pirates.surfaces.islands.island_enum") local Roles = require("maps.pirates.roles.roles") local Permissions = require("maps.pirates.permissions") @@ -38,6 +40,80 @@ local Server = require("utils.server") local GuiWelcome = require("maps.pirates.gui.welcome") local tick_tack_trap = require("utils.functions.tick_tack_trap") +-- Token callbacks for singleplayer auto-go functionality +local singleplayer_go_2 = Token.register(function(data) + Memory.set_working_id(data.id) + local memory = Memory.get_crew_memory() + memory.loading_ticks = 0 + Progression.go_from_starting_dock_to_first_destination() +end) + +local singleplayer_go_1 = Token.register(function(data) + Memory.set_working_id(data.id) + local memory = Memory.get_crew_memory() + Overworld.ensure_lane_generated_up_to(0, Crowsnest.Data.visibilitywidth) + Overworld.ensure_lane_generated_up_to(24, Crowsnest.Data.visibilitywidth) + Overworld.ensure_lane_generated_up_to(-24, Crowsnest.Data.visibilitywidth) + + for i = 1, #memory.destinations do + if memory.destinations[i].overworld_position.x == 0 then + memory.map_being_loaded_destination_index = i + break + end + end + + memory.currentdestination_index = memory.map_being_loaded_destination_index + Surfaces.create_surface(Common.current_destination()) + Task.set_timeout_in_ticks(60, singleplayer_go_2, { id = data.id }) +end) + +-- Delayed callback that performs the actual auto-go after lobby boats are ready +local singleplayer_auto_go_delayed +singleplayer_auto_go_delayed = Token.register(function(data) + local global_memory = Memory.get_global_memory() + + -- Check if lobby boats are ready (they're created at tick 2) + if not global_memory.lobby_boats or not global_memory.lobby_boats[1] then + -- Boats not ready yet, retry in a few ticks + Task.set_timeout_in_ticks(5, singleplayer_auto_go_delayed, data) + return + end + + local player = game.players[data.player_index] + if not player or not player.valid then + return + end + + local proposal = { + capacity_option = 3, + difficulty_option = 4, + name = player.name .. (string.sub(player.name, -1) == "s" and "' Ship" or "'s Ship"), + created_by_player = player.index, + run_is_protected = false, + run_is_private = false, + } + + Crew.initialise_crew(proposal, player.position) + Crew.initialise_crowsnest() + + local memory = Memory.get_crew_memory() + local boat = Utils.deepcopy(Surfaces.Lobby.StartingBoats[memory.id]) + + for _, p in pairs(game.connected_players) do + p.teleport({ x = -30, y = boat.position.y }, game.surfaces[boat.surface_name]) + end + + Progression.set_off_from_starting_dock() + memory.boat.speed = 1 -- Small initial speed to start movement + Task.set_timeout_in_ticks(120, singleplayer_go_1, { id = memory.id }) +end) + +-- Schedule auto-go for singleplayer games (equivalent to /go command) +local function schedule_singleplayer_auto_go(player) + -- Delay execution to ensure lobby boats are ready (they're created at tick 2) + Task.set_timeout_in_ticks(5, singleplayer_auto_go_delayed, { player_index = player.index }) +end + local Public = {} function Public.silo_die() @@ -1784,14 +1860,25 @@ local function event_on_player_joined_game(event) Common.ensure_chunks_at(surface, spawnpoint, 5) end - Common.notify_player_expected(player, { "pirates.welcome_main_chat" }) - - if not _DEBUG then - GuiWelcome.show_welcome_window(player) + -- In singleplayer, automatically start the game on first join instead of showing the welcome message + local should_auto_go = false + if not global_memory.singleplayer_auto_go_checked then + global_memory.singleplayer_auto_go_checked = true + should_auto_go = not game.is_multiplayer() end player.force = Common.lobby_force_name + if should_auto_go then + schedule_singleplayer_auto_go(player) + else + Common.notify_player_expected(player, { "pirates.welcome_main_chat" }) + + if not _DEBUG then + GuiWelcome.show_welcome_window(player) + end + end + -- NOTE: It was suggested to always spawn players in lobby, in hopes that they may want to create their crew increasing the popularity of scenario. Hence the following code is disabled. -- WARNING: If re-enabling autojoin, make sure it respects private/protected runs. diff --git a/maps/pirates/commands.lua b/maps/pirates/commands.lua index 70c986589..0ed8325ba 100644 --- a/maps/pirates/commands.lua +++ b/maps/pirates/commands.lua @@ -1,1142 +1,1146 @@ --- This file is part of thesixthroc's Pirate Ship softmod, licensed under GPLv3 and stored at https://github.com/ComfyFactory/ComfyFactorio and https://github.com/danielmartin0/ComfyFactorio-Pirates. - ---luacheck: ignore ---luacheck ignores because mass requires is a code templating choice... - -local Color = require("utils.color_presets") -local Server = require("utils.server") -local Math = require("maps.pirates.math") -local Ai = require("maps.pirates.ai") -local Memory = require("maps.pirates.memory") -local Common = require("maps.pirates.common") -local CoreData = require("maps.pirates.coredata") -local PlayerColors = require("maps.pirates.player_colors") -local Utils = require("maps.pirates.utils_local") -local Crew = require("maps.pirates.crew") -local Roles = require("maps.pirates.roles.roles") -local Boats = require("maps.pirates.structures.boats.boats") -local Surfaces = require("maps.pirates.surfaces.surfaces") -local Overworld = require("maps.pirates.overworld") -local Islands = require("maps.pirates.surfaces.islands.islands") -local Progression = require("maps.pirates.progression") -local Crowsnest = require("maps.pirates.surfaces.crowsnest") -local PiratesApiEvents = require("maps.pirates.api_events") -local Upgrades = require("maps.pirates.shop.boat_upgrades") -local Effects = require("maps.pirates.effects") -local Kraken = require("maps.pirates.surfaces.sea.kraken") -local _inspect = require("utils.inspect").inspect -local simplex_noise = require("utils.math.simplex_noise").d2 -local Token = require("utils.token") -local Task = require("utils.task") -local Highscore = require("maps.pirates.highscore") -local Permissions = require("maps.pirates.permissions") -local Classes = require("maps.pirates.roles.classes") -local Gui = require("maps.pirates.gui.gui") --- local Session = require 'utils.datastore.session_data' - --- *** *** -- ---*** HELPERS ***-- --- *** *** -- - -local function cmd_set_memory(cmd) - local player = game.players[cmd.player_index] - local crew_id = Common.get_id_from_force_name(player.force.name) - Memory.set_working_id(crew_id) -end - -local function check_admin(cmd) - local player = game.players[cmd.player_index] - --local trusted = Session.get_trusted_table() - local p - if player then - if player ~= nil then - p = player.print - --@temporary - if player.name == "Piratux" or player.name == "thesixthroc" then - return true - end - if not player.admin then - p({ "pirates.cmd_error_not_admin" }, { color = Color.fail }) - return false - end - else - p = log - end - end - return true -end - -local function check_captain(cmd) - local player = game.players[cmd.player_index] - local p - if player then - if player ~= nil then - p = player.print - if not Common.validate_player(player) then - return - end - if not (Permissions.player_privilege_level(player) >= Permissions.privilege_levels.CAPTAIN) then - p({ "pirates.cmd_error_not_captain" }, { color = Color.fail }) - return false - end - else - p = log - end - end - return true -end - -local function check_captain_or_admin(cmd) - local player = game.players[cmd.player_index] - local p - if player then - if player ~= nil then - p = player.print - if not Common.validate_player(player) then - return - end - if - not (player.admin or Permissions.player_privilege_level(player) >= Permissions.privilege_levels.CAPTAIN) - then - p({ "pirates.cmd_error_not_captain" }, { color = Color.fail }) - return false - end - else - p = log - end - end - return true -end - -local function check_creator_of_crew(cmd) - local player = game.players[cmd.player_index] - local p - if player then - if player ~= nil then - p = player.print - - cmd_set_memory(cmd) - - local memory = Memory.get_crew_memory() - if not Common.is_id_valid(memory.id) then - return - end - - local creator = memory.original_proposal.created_by_player - - if creator ~= player.index then - Common.notify_player_error(player, { "pirates.cmd_error_not_creator_of_crew" }) - return false - end - end - end -end - --- @UNUSED --- local function check_trusted(cmd) --- local Session = require 'utils.datastore.session_data' --- local player = game.players[cmd.player_index] --- local trusted = Session.get_trusted_table() --- local p --- if player then --- if player ~= nil then --- p = player.print --- if not (trusted[player.name] or player.admin) then --- p('[ERROR] Only admins and trusted weebs are allowed to run this command!', {color=Color.fail}) --- return false --- end --- else --- p = log --- end --- end --- return true --- end - --- *** *** -- ---*** PUBLIC COMMANDS ***-- --- *** *** -- - -commands.add_command("ok", { "pirates.cmd_explain_ok" }, function(cmd) - cmd_set_memory(cmd) - - local memory = Memory.get_crew_memory() - if not Common.is_id_valid(memory.id) then - return - end - - local player = game.players[cmd.player_index] - if not Common.validate_player(player) then - return - end - - --local memory = Memory.get_crew_memory() - Roles.player_confirm_captainhood(player) -end) - --- Disabled, better to find these out through gameplay: --- commands.add_command( --- 'classes', --- 'Prints the available classes in the game.', --- function(cmd) --- local player = game.players[cmd.player_index] --- if not Common.validate_player(player) then return end --- player.print('[color=gray]' .. Roles.get_classes_print_string() .. '[/color]') --- end) - -commands.add_command("classinfo", { "pirates.cmd_explain_classinfo" }, function(cmd) - cmd_set_memory(cmd) - local param = tostring(cmd.parameter) - local player = game.players[cmd.player_index] - if not Common.validate_player(player) then - return - end - - if param and param ~= "nil" then - local string = Roles.get_class_print_string(param, true) - if string then - Common.notify_player_expected(player, { "", { "pirates.class_definition_for" }, " ", string }) - else - Common.notify_player_error(player, { "pirates.cmd_error_invalid_class_name", param }) - end - else - Common.notify_player_expected(player, { "", "/classinfo ", { "pirates.cmd_explain_classinfo" } }) - end -end) - -commands.add_command("ccolor", { "pirates.cmd_explain_ccolor" }, function(cmd) - local param = tostring(cmd.parameter) - local player_index = cmd.player_index - if player_index then - local player = game.players[player_index] - if player and player.valid then - if cmd.parameter then - if PlayerColors.colors[param] then - local rgb = PlayerColors.colors[param] - player.color = rgb - player.chat_color = rgb - local message = { - "", - "[color=" .. rgb.r .. "," .. rgb.g .. "," .. rgb.b .. "]", - { "pirates.choose_chat_color", player.name, param }, - "[/color] (via /ccolor).", - } - -- local message = '[color=' .. rgb.r .. ',' .. rgb.g .. ',' .. rgb.b .. ']' .. player.name .. ' chose the color ' .. param .. '[/color] (via /ccolor).' - Common.notify_game(message) - else - Common.notify_player_error(player, { "pirates.cmd_error_color_not_found", param }) - end - else - local color = PlayerColors.bright_color_names[Math.random(#PlayerColors.bright_color_names)] - local rgb = PlayerColors.colors[color] - if not rgb then - return - end - player.color = rgb - player.chat_color = rgb - local message = { - "", - "[color=" .. rgb.r .. "," .. rgb.g .. "," .. rgb.b .. "]", - { "pirates.randomize_chat_color", player.name, color }, - "[/color] (via /ccolor).", - } --'randomly became' was amusing, but let's not - -- local message = '[color=' .. rgb.r .. ',' .. rgb.g .. ',' .. rgb.b .. ']' .. player.name .. '\'s color randomized to ' .. color .. '[/color] (via /ccolor).' --'randomly became' was amusing, but let's not - Common.notify_game(message) - -- disabled due to lag: - -- GUIcolor.toggle_window(player) - end - end - end -end) - -commands.add_command("fixpower", { "pirates.cmd_explain_fixpower" }, function(cmd) - cmd_set_memory(cmd) - - local memory = Memory.get_crew_memory() - if not Common.is_id_valid(memory.id) then - return - end - - Boats.force_reconnect_boat_poles() -end) - --- *** *** -- ---*** CAPTAIN COMMANDS ***-- --- *** *** -- - -commands.add_command("plank", { "pirates.cmd_explain_plank" }, function(cmd) - cmd_set_memory(cmd) - - local memory = Memory.get_crew_memory() - if not Common.is_id_valid(memory.id) then - return - end - - local player = game.players[cmd.player_index] - local param = tostring(cmd.parameter) - if check_captain_or_admin(cmd) then - if param and game.players[param] and game.players[param].index then - Crew.plank(player, game.players[param]) - else - Common.notify_player_error(player, { "pirates.cmd_error_invalid_player_name", param }) - end - end -end) - -commands.add_command("officer", { "pirates.cmd_explain_officer" }, function(cmd) - cmd_set_memory(cmd) - - local memory = Memory.get_crew_memory() - if not Common.is_id_valid(memory.id) then - return - end - - local player = game.players[cmd.player_index] - local param = tostring(cmd.parameter) - if check_captain_or_admin(cmd) then - if param and game.players[param] and game.players[param].index then - if Common.is_officer(game.players[param].index) then - Roles.unmake_officer(player, game.players[param]) - else - Roles.make_officer(player, game.players[param]) - end - else - Common.notify_player_error(player, { "pirates.cmd_error_invalid_player_name", param }) - end - end -end) - -commands.add_command("tax", { "pirates.cmd_explain_tax" }, function(cmd) - cmd_set_memory(cmd) - - local memory = Memory.get_crew_memory() - if not Common.is_id_valid(memory.id) then - return - end - - --local param = tostring(cmd.parameter) - if check_captain(cmd) then - --local player = game.players[cmd.player_index] - Roles.captain_tax(memory.playerindex_captain) - end -end) - --- Try undock from an island or dock -commands.add_command("undock", { "pirates.cmd_explain_undock" }, function(cmd) - cmd_set_memory(cmd) - - local memory = Memory.get_crew_memory() - if not Common.is_id_valid(memory.id) then - return - end - - --local param = tostring(cmd.parameter) - if check_captain_or_admin(cmd) then - local player = game.players[cmd.player_index] - if memory.boat.state == Boats.enum_state.DOCKED then - Progression.undock_from_dock(true) - elseif memory.boat.state == Boats.enum_state.LANDED then - Progression.try_retreat_from_island(player, true) - end - end -end) - -commands.add_command("clear_north_tanks", { "pirates.cmd_explain_clear_north_tanks" }, function(cmd) - cmd_set_memory(cmd) - - local memory = Memory.get_crew_memory() - if not Common.is_id_valid(memory.id) then - return - end - - if check_captain_or_admin(cmd) then - Boats.clear_fluid_from_ship_tanks(1) - end -end) - -commands.add_command("clear_south_tanks", { "pirates.cmd_explain_clear_south_tanks" }, function(cmd) - cmd_set_memory(cmd) - - local memory = Memory.get_crew_memory() - if not Common.is_id_valid(memory.id) then - return - end - - if check_captain(cmd) then - Boats.clear_fluid_from_ship_tanks(2) - end -end) - --- *** *** -- ---*** CREATOR OF CREW COMMANDS ***-- --- *** *** -- - -commands.add_command("reset_password", { "pirates.cmd_explain_set_private_run_password" }, function(cmd) - cmd_set_memory(cmd) - - local memory = Memory.get_crew_memory() - if not Common.is_id_valid(memory.id) then - return - end - - local param = tostring(cmd.parameter) - if check_creator_of_crew(cmd) then - local player = game.players[cmd.player_index] - - if not memory.private_run_password then - Common.notify_player_error(player, { "pirates.cmd_error_no_existing_password" }) - return false - end - - memory.private_run_password = param - Common.notify_player_expected(player, { "pirates.cmd_notify_set_private_run_password", memory.name, param }) - end -end) - --- *** *** -- ---*** ADMIN COMMANDS ***-- --- *** *** -- - -commands.add_command("set_max_crews", { "pirates.cmd_explain_set_max_crews" }, function(cmd) - local param = tostring(cmd.parameter) - if check_admin(cmd) then - local player = game.players[cmd.player_index] - local global_memory = Memory.get_global_memory() - - if tonumber(param) then - global_memory.active_crews_cap_in_memory = tonumber(param) - Common.notify_player_expected(player, { "pirates.cmd_notify_set_max_crews", param }) - end - end -end) - -commands.add_command("setcaptain", { "pirates.cmd_explain_setcaptain" }, function(cmd) - cmd_set_memory(cmd) - - local memory = Memory.get_crew_memory() - if not Common.is_id_valid(memory.id) then - return - end - - local param = tostring(cmd.parameter) - if check_admin(cmd) then - local player = game.players[cmd.player_index] - if param and game.players[param] and game.players[param].index then - Roles.make_captain(game.players[param]) - else - Common.notify_player_error(player, { "pirates.cmd_error_invalid_player_name", param }) - end - end -end) - -commands.add_command("summoncrew", { "pirates.cmd_explain_summoncrew" }, function(cmd) - cmd_set_memory(cmd) - - local memory = Memory.get_crew_memory() - if not Common.is_id_valid(memory.id) then - return - end - - --local param = tostring(cmd.parameter) - if check_admin(cmd) then - Crew.summon_crew() - end -end) - --- Force undock from an island or dock -commands.add_command("ret", { "pirates.cmd_explain_dev" }, function(cmd) - cmd_set_memory(cmd) - - local memory = Memory.get_crew_memory() - if not Common.is_id_valid(memory.id) then - return - end - - -- local param = tostring(cmd.parameter) - if check_admin(cmd) then - if memory.boat.state == Boats.enum_state.DOCKED then - Progression.undock_from_dock(true) - elseif memory.boat.state == Boats.enum_state.LANDED then - Progression.retreat_from_island(true) - end - end -end) - -commands.add_command("dump_highscores", { "pirates.cmd_explain_dev" }, function(cmd) - cmd_set_memory(cmd) - - if check_admin(cmd) then - local player = game.players[cmd.player_index] - if not Common.validate_player(player) then - return - end - Highscore.dump_highscores() - player.print("Highscores dumped.") - end -end) - -commands.add_command("setevo", { "pirates.cmd_explain_dev" }, function(cmd) - cmd_set_memory(cmd) - - local param = tostring(cmd.parameter) - if check_admin(cmd) then - local player = game.players[cmd.player_index] - Common.set_evo(tonumber(param)) - end -end) - -commands.add_command("modi", { "pirates.cmd_explain_dev" }, function(cmd) - cmd_set_memory(cmd) - - local param = tostring(cmd.parameter) - if check_admin(cmd) then - local player = game.players[cmd.player_index] - local memory = Memory.get_crew_memory() - local surface = game.surfaces[Common.current_destination().surface_name] - local entities = surface.find_entities_filtered({ position = player.position, radius = 500 }) - for _, e in pairs(entities) do - if e and e.valid then - -- e.force = memory.force - e.minable = true - e.destructible = true - e.rotatable = true - end - end - player.print("nearby entities made modifiable") - end -end) - -commands.add_command("night", "night", function(cmd) - if check_admin(cmd) then - local player = game.players[cmd.player_index] - local surface = player.surface - surface.daytime = 0.5 - end -end) - -commands.add_command("overwrite_scores_specific", { "pirates.cmd_explain_dev" }, function(cmd) - cmd_set_memory(cmd) - - if check_admin(cmd) then - local player = game.players[cmd.player_index] - if not Common.validate_player(player) then - return - end - local memory = Memory.get_crew_memory() - if Highscore.overwrite_scores_specific() then - player.print("Highscores overwritten.") - end - end -end) - --- Unlock a class -commands.add_command("unlock", { "pirates.cmd_explain_dev" }, function(cmd) - cmd_set_memory(cmd) - local param = tostring(cmd.parameter) - if check_admin(cmd) then - local memory = Memory.get_crew_memory() - if not Common.is_id_valid(memory.id) then - return - end - local player = game.players[cmd.player_index] - if not Classes.try_unlock_class(param, player, true) then - Common.notify_player_error(player, { "pirates.cmd_error_invalid_class_name", param }) - end - end -end) - --- Remove all classes -commands.add_command("remove_classes", { "pirates.cmd_explain_dev" }, function(cmd) - cmd_set_memory(cmd) - local param = tostring(cmd.parameter) - if check_admin(cmd) then - local memory = Memory.get_crew_memory() - if not Common.is_id_valid(memory.id) then - return - end - - if not Gui.classes then - return - end - - memory.classes_table = {} - memory.spare_classes = {} - memory.recently_purchased_classes = {} - memory.unlocked_classes = {} - memory.available_classes_pool = Classes.initial_class_pool() - memory.class_entry_count = 0 - - local players = Common.crew_get_crew_members() - - for _, player in pairs(players) do - Gui.classes.full_update(player, true) - end - end -end) - --- *** *** -- ---*** DEVELOPER COMMANDS ***-- --- *** *** -- - -if _DEBUG then - local go_2 = Token.register(function(data) - Memory.set_working_id(data.id) - local memory = Memory.get_crew_memory() - - memory.loading_ticks = 0 - - -- local surface = game.surfaces[Common.current_destination().surface_name] - -- surface.request_to_generate_chunks({x = 0, y = 0}, 10) - -- surface.force_generate_chunk_requests() - Progression.go_from_starting_dock_to_first_destination() - end) - local go_1 = Token.register(function(data) - Memory.set_working_id(data.id) - local memory = Memory.get_crew_memory() - Overworld.ensure_lane_generated_up_to(0, Crowsnest.Data.visibilitywidth) - Overworld.ensure_lane_generated_up_to(24, Crowsnest.Data.visibilitywidth) - Overworld.ensure_lane_generated_up_to(-24, Crowsnest.Data.visibilitywidth) - - for i = 1, #memory.destinations do - if memory.destinations[i].overworld_position.x == 0 then - memory.map_being_loaded_destination_index = i - break - end - end - - memory.currentdestination_index = memory.map_being_loaded_destination_index - Surfaces.create_surface(Common.current_destination()) - Task.set_timeout_in_ticks(60, go_2, { id = data.id }) - end) - - -- Move overworld boat right by a lot (you can jump over islands that way to skip them) - commands.add_command("jump", { "pirates.cmd_explain_dev" }, function(cmd) - cmd_set_memory(cmd) - - local param = tostring(cmd.parameter) - if check_admin(cmd) then - local player = game.players[cmd.player_index] - Overworld.try_overworld_move_v2({ x = 40, y = 0 }) - end - end) - - -- Move overworld boat up - commands.add_command("advu", { "pirates.cmd_explain_dev" }, function(cmd) - cmd_set_memory(cmd) - - local param = tostring(cmd.parameter) - if check_admin(cmd) then - local player = game.players[cmd.player_index] - Overworld.try_overworld_move_v2({ x = 0, y = -24 }) - end - end) - - -- Move overworld boat down - commands.add_command("advd", { "pirates.cmd_explain_dev" }, function(cmd) - cmd_set_memory(cmd) - - local param = tostring(cmd.parameter) - if check_admin(cmd) then - local player = game.players[cmd.player_index] - Overworld.try_overworld_move_v2({ x = 0, y = 24 }) - end - end) - - -- Teleport player to available boat in lobby, automatically start journey and arrive at sea faster - commands.add_command("go", { "pirates.cmd_explain_dev" }, function(cmd) - cmd_set_memory(cmd) - local param = tostring(cmd.parameter) - if check_admin(cmd) then - local player = game.players[cmd.player_index] - -- Doesn't completely prevent server from crashing when used twice at lobby, but at least saves from crashing when boat leaves lobby - if not Common.get_id_from_force_name(player.character.force.name) then - local proposal = { - capacity_option = 3, - difficulty_option = 4, - name = "AdminRun", - created_by_player = cmd.player_index, - run_is_protected = false, - run_is_private = false, - } - - Crew.initialise_crew(proposal, player.position) - Crew.initialise_crowsnest() --contains a Task - - local memory = Memory.get_crew_memory() - local boat = Utils.deepcopy(Surfaces.Lobby.StartingBoats[memory.id]) - - for _, p in pairs(game.connected_players) do - p.teleport({ x = -30, y = boat.position.y }, game.surfaces[boat.surface_name]) - end - - Progression.set_off_from_starting_dock() - - -- local memory = Memory.get_crew_memory() - -- local boat = Utils.deepcopy(Surfaces.Lobby.StartingBoats[memory.id]) - -- memory.boat = boat - -- boat.dockedposition = boat.position - -- boat.decksteeringchests = {} - -- boat.crows_nest_steering_chests = {} - - Task.set_timeout_in_ticks(120, go_1, { id = memory.id }) - else - game.print("Can't use this command when run has already launched") - end - end - end) - - commands.add_command("chnk", { "pirates.cmd_explain_dev" }, function(cmd) - cmd_set_memory(cmd) - - local param = tostring(cmd.parameter) - if check_admin(cmd) then - local player = game.players[cmd.player_index] - local memory = Memory.get_crew_memory() - - for i = 0, 13 do - for j = 0, 13 do - PiratesApiEvents.event_on_chunk_generated({ - surface = player.surface, - area = { left_top = { x = -7 * 32 + i * 32, y = -7 * 32 + j * 32 } }, - }) - end - end - game.print("chunks generated") - end - end) - - commands.add_command("spd", { "pirates.cmd_explain_dev" }, function(cmd) - cmd_set_memory(cmd) - - local param = tostring(cmd.parameter) - if check_admin(cmd) then - local player = game.players[cmd.player_index] - local memory = Memory.get_crew_memory() - memory.boat.speed = 60 - end - end) - - commands.add_command("stp", { "pirates.cmd_explain_dev" }, function(cmd) - cmd_set_memory(cmd) - - local param = tostring(cmd.parameter) - if check_admin(cmd) then - local player = game.players[cmd.player_index] - local memory = Memory.get_crew_memory() - memory.boat.speed = 0 - end - end) - - commands.add_command("rms", { "pirates.cmd_explain_dev" }, function(cmd) - local param = tostring(cmd.parameter) - if check_admin(cmd) then - local player = game.players[cmd.player_index] - local rms = 0 - local n = 100000 - local seed = Math.random(n ^ 2) - for i = 1, n do - local noise = simplex_noise(i, 7.11, seed) - rms = rms + noise ^ 2 - end - rms = rms / n - game.print(rms) - end - end) - - commands.add_command("pro", { "pirates.cmd_explain_dev" }, function(cmd) - local param = tostring(cmd.parameter) - if check_admin(cmd) then - local player = game.players[cmd.player_index] - local global_memory = Memory.get_global_memory() - - local proposal = { - capacity_option = 3, - difficulty_option = 2, - -- mode_option = 'left', - name = "TestRun", - created_by_player = cmd.player_index, - } - - global_memory.crewproposals[#global_memory.crewproposals + 1] = proposal - end - end) - - -- Leave island, or dock immediately - commands.add_command("lev", { "pirates.cmd_explain_dev" }, function(cmd) - cmd_set_memory(cmd) - local param = tostring(cmd.parameter) - if check_admin(cmd) then - local player = game.players[cmd.player_index] - local memory = Memory.get_crew_memory() - Progression.go_from_currentdestination_to_sea() - end - end) - - -- Add another hold - commands.add_command("hld", { "pirates.cmd_explain_dev" }, function(cmd) - cmd_set_memory(cmd) - local param = tostring(cmd.parameter) - if check_admin(cmd) then - local player = game.players[cmd.player_index] - local memory = Memory.get_crew_memory() - Upgrades.execute_upgade(Upgrades.enum.EXTRA_HOLD) - end - end) - - -- Upgrade power generators - commands.add_command("pwr", { "pirates.cmd_explain_dev" }, function(cmd) - cmd_set_memory(cmd) - local param = tostring(cmd.parameter) - if check_admin(cmd) then - local player = game.players[cmd.player_index] - local memory = Memory.get_crew_memory() - Upgrades.execute_upgade(Upgrades.enum.MORE_POWER) - end - end) - - commands.add_command("score", { "pirates.cmd_explain_dev" }, function(cmd) - cmd_set_memory(cmd) - - local param = tostring(cmd.parameter) - if check_admin(cmd) then - local player = game.players[cmd.player_index] - local memory = Memory.get_crew_memory() - - game.print("faking a highscore...") - Highscore.write_score(memory.secs_id, "fakers", 0, 40, CoreData.version_string, 1, 1) - end - end) - - commands.add_command("scrget", { "pirates.cmd_explain_dev" }, function(cmd) - local param = tostring(cmd.parameter) - if check_admin(cmd) then - local player = game.players[cmd.player_index] - game.print("running Highscore.load_in_scores()") - Highscore.load_in_scores() - end - end) - - commands.add_command("tim", { "pirates.cmd_explain_dev" }, function(cmd) - cmd_set_memory(cmd) - local param = tostring(cmd.parameter) - if check_admin(cmd) then - local player = game.players[cmd.player_index] - local memory = Memory.get_crew_memory() - Common.current_destination().dynamic_data.timer = 88 - game.print("time set to 88 seconds") - end - end) - - -- Add 20000 coal fuel to ship - commands.add_command("gld", { "pirates.cmd_explain_dev" }, function(cmd) - cmd_set_memory(cmd) - local param = tostring(cmd.parameter) - if check_admin(cmd) then - local player = game.players[cmd.player_index] - local memory = Memory.get_crew_memory() - memory.stored_fuel = memory.stored_fuel + 20000 - end - end) - - commands.add_command("rad", { "pirates.cmd_explain_dev" }, function(cmd) - cmd_set_memory(cmd) - local param = tostring(cmd.parameter) - if check_admin(cmd) then - local destination = Common.current_destination() - Islands.spawn_enemy_boat(Boats.enum.RAFT) - local boat = destination.dynamic_data.enemyboats[1] - Ai.spawn_boat_biters(boat, 0.89, Boats.get_scope(boat).Data.capacity, Boats.get_scope(boat).Data.width) - game.print("enemy boat spawned") - end - end) - - commands.add_command("rad2", { "pirates.cmd_explain_dev" }, function(cmd) - cmd_set_memory(cmd) - local param = tostring(cmd.parameter) - if check_admin(cmd) then - local destination = Common.current_destination() - Islands.spawn_enemy_boat(Boats.enum.RAFTLARGE) - local boat = destination.dynamic_data.enemyboats[1] - Ai.spawn_boat_biters(boat, 0.89, Boats.get_scope(boat).Data.capacity, Boats.get_scope(boat).Data.width) - game.print("large enemy boat spawned") - end - end) - - -- Spawns kraken if at sea - commands.add_command("krk", { "pirates.cmd_explain_dev" }, function(cmd) - cmd_set_memory(cmd) - local param = tostring(cmd.parameter) - if check_admin(cmd) then - local player = game.players[cmd.player_index] - local memory = Memory.get_crew_memory() - Kraken.try_spawn_kraken() - end - end) - - -- Sets game speed to 0.25 - commands.add_command("1/4", { "pirates.cmd_explain_dev" }, function(cmd) - local param = tostring(cmd.parameter) - if check_admin(cmd) then - local player = game.players[cmd.player_index] - game.speed = 0.25 - end - end) - - -- Sets game speed to 0.5 - commands.add_command("1/2", { "pirates.cmd_explain_dev" }, function(cmd) - local param = tostring(cmd.parameter) - if check_admin(cmd) then - local player = game.players[cmd.player_index] - game.speed = 0.5 - end - end) - - -- Sets game speed to 1 - commands.add_command("1", { "pirates.cmd_explain_dev" }, function(cmd) - local param = tostring(cmd.parameter) - if check_admin(cmd) then - local player = game.players[cmd.player_index] - game.speed = 1 - end - end) - - -- Sets game speed to 2 - commands.add_command("2", { "pirates.cmd_explain_dev" }, function(cmd) - local param = tostring(cmd.parameter) - if check_admin(cmd) then - local player = game.players[cmd.player_index] - game.speed = 2 - end - end) - - -- Sets game speed to 4 - commands.add_command("4", { "pirates.cmd_explain_dev" }, function(cmd) - local param = tostring(cmd.parameter) - if check_admin(cmd) then - local player = game.players[cmd.player_index] - game.speed = 4 - end - end) - - -- Sets game speed to 8 - commands.add_command("8", { "pirates.cmd_explain_dev" }, function(cmd) - local param = tostring(cmd.parameter) - if check_admin(cmd) then - local player = game.players[cmd.player_index] - game.speed = 8 - end - end) - - -- Sets game speed to 16 - commands.add_command("16", { "pirates.cmd_explain_dev" }, function(cmd) - local param = tostring(cmd.parameter) - if check_admin(cmd) then - local player = game.players[cmd.player_index] - game.speed = 16 - end - end) - - -- Sets game speed to 32 - commands.add_command("32", { "pirates.cmd_explain_dev" }, function(cmd) - local param = tostring(cmd.parameter) - if check_admin(cmd) then - local player = game.players[cmd.player_index] - game.speed = 32 - end - end) - - -- Sets game speed to 64 - commands.add_command("64", { "pirates.cmd_explain_dev" }, function(cmd) - local param = tostring(cmd.parameter) - if check_admin(cmd) then - local player = game.players[cmd.player_index] - game.speed = 64 - end - end) - - commands.add_command("ef1", { "pirates.cmd_explain_dev" }, function(cmd) - cmd_set_memory(cmd) - - local param = tostring(cmd.parameter) - if check_admin(cmd) then - local player = game.players[cmd.player_index] - local memory = Memory.get_crew_memory() - local surface = game.surfaces[Common.current_destination().surface_name] - Effects.worm_movement_effect(surface, { x = -45, y = 0 }, false, true) - end - end) - - commands.add_command("ef2", { "pirates.cmd_explain_dev" }, function(cmd) - cmd_set_memory(cmd) - - local param = tostring(cmd.parameter) - if check_admin(cmd) then - local player = game.players[cmd.player_index] - local memory = Memory.get_crew_memory() - local surface = game.surfaces[Common.current_destination().surface_name] - Effects.worm_movement_effect(surface, { x = -45, y = 0 }, false, false) - end - end) - - commands.add_command("ef3", { "pirates.cmd_explain_dev" }, function(cmd) - cmd_set_memory(cmd) - - local param = tostring(cmd.parameter) - if check_admin(cmd) then - local player = game.players[cmd.player_index] - local memory = Memory.get_crew_memory() - local surface = game.surfaces[Common.current_destination().surface_name] - Effects.worm_movement_effect(surface, { x = -45, y = 0 }, true, false) - end - end) - - commands.add_command("ef4", { "pirates.cmd_explain_dev" }, function(cmd) - cmd_set_memory(cmd) - - local param = tostring(cmd.parameter) - if check_admin(cmd) then - local player = game.players[cmd.player_index] - local memory = Memory.get_crew_memory() - local surface = game.surfaces[Common.current_destination().surface_name] - Effects.worm_emerge_effect(surface, { x = -45, y = 0 }) - end - end) - - commands.add_command("ef5", { "pirates.cmd_explain_dev" }, function(cmd) - cmd_set_memory(cmd) - - local param = tostring(cmd.parameter) - if check_admin(cmd) then - local player = game.players[cmd.player_index] - local memory = Memory.get_crew_memory() - local surface = game.surfaces[Common.current_destination().surface_name] - Effects.biters_emerge(surface, { x = -30, y = 0 }) - end - end) - - commands.add_command("emoji", { "pirates.cmd_explain_dev" }, function(cmd) - local param = tostring(cmd.parameter) - if check_admin(cmd) then - local player = game.players[cmd.player_index] - Server.to_discord_embed_raw(CoreData.comfy_emojis.despair) - end - end) - - -- Spawn friendly gun turrets with ammo to defend your ship - commands.add_command("def", { "pirates.cmd_explain_dev" }, function(cmd) - cmd_set_memory(cmd) - local param = tostring(cmd.parameter) - if check_admin(cmd) then - local player = game.players[cmd.player_index] - local memory = Memory.get_crew_memory() - if not Common.is_id_valid(memory.id) then - return - end - - local boat = memory.boat - local scope = Boats.get_scope(boat) - local surface = game.surfaces[boat.surface_name] - if not surface then - return - end - - if scope.Data.cannons then - for i = -2, 2 do - local p1 = scope.Data.cannons[1] - local p2 = { x = boat.position.x + p1.x + i * 2, y = boat.position.y + p1.y - 4 } - local e = surface.create_entity({ - name = "gun-turret", - position = p2, - force = boat.force_name, - create_build_effect_smoke = false, - }) - if e and e.valid then - e.insert({ name = "uranium-rounds-magazine", count = 200 }) - end - end - for i = -2, 2 do - local p1 = scope.Data.cannons[2] - local p2 = { x = boat.position.x + p1.x + i * 2, y = boat.position.y + p1.y + 3 } - local e = surface.create_entity({ - name = "gun-turret", - position = p2, - force = boat.force_name, - create_build_effect_smoke = false, - }) - if e and e.valid then - e.insert({ name = "uranium-rounds-magazine", count = 200 }) - end - end - end - end - end) - - -- Spawn friendly gun turrets with ammo around you - commands.add_command("atk", { "pirates.cmd_explain_dev" }, function(cmd) - cmd_set_memory(cmd) - local param = tostring(cmd.parameter) - if check_admin(cmd) then - local player = game.players[cmd.player_index] - local memory = Memory.get_crew_memory() - if not Common.is_id_valid(memory.id) then - return - end - local boat = memory.boat - - local p = player.character.position - local turret_positions = { - { x = p.x - 2, y = p.y - 2 }, - { x = p.x - 2, y = p.y + 2 }, - { x = p.x + 2, y = p.y - 2 }, - { x = p.x + 2, y = p.y + 2 }, - } - - for _, pos in pairs(turret_positions) do - local e = player.surface.create_entity({ - name = "gun-turret", - position = pos, - force = boat.force_name, - create_build_effect_smoke = false, - }) - if e and e.valid then - e.insert({ name = "uranium-rounds-magazine", count = 200 }) - end - end - end - end) - - -- Give advanced starter kit to make exploration easier - commands.add_command("kit", { "pirates.cmd_explain_dev" }, function(cmd) - if check_admin(cmd) then - local player = game.players[cmd.player_index] - - player.insert({ name = "substation", count = 50 }) - player.insert({ name = "solar-panel", count = 50 }) - player.insert({ name = "vehicle-machine-gun", count = 1 }) - player.insert({ name = "uranium-rounds-magazine", count = 200 }) - player.insert({ name = "raw-fish", count = 100 }) - player.insert({ name = "coin", count = 50000 }) - player.insert({ name = "cluster-grenade", count = 100 }) - player.insert({ name = "steel-chest", count = 50 }) - player.insert({ name = "express-loader", count = 50 }) - player.insert({ name = "burner-inserter", count = 50 }) - player.insert({ name = "accumulator", count = 50 }) - end - end) - - -- Fills the inventory - commands.add_command("fill", { "pirates.cmd_explain_dev" }, function(cmd) - if check_admin(cmd) then - local player = game.players[cmd.player_index] - - player.insert({ name = "power-armor-mk2", count = 1 }) - player.insert({ name = "iron-plate", count = 10000 }) - end - end) - - commands.add_command("buff", "buffs all damage by 10%", function(cmd) - if check_admin(cmd) then - local player = game.players[cmd.player_index] - Crew.buff_all_damage(0.1) - end - end) -end +-- This file is part of thesixthroc's Pirate Ship softmod, licensed under GPLv3 and stored at https://github.com/ComfyFactory/ComfyFactorio and https://github.com/danielmartin0/ComfyFactorio-Pirates. + +--luacheck: ignore +--luacheck ignores because mass requires is a code templating choice... + +local Color = require("utils.color_presets") +local Server = require("utils.server") +local Math = require("maps.pirates.math") +local Ai = require("maps.pirates.ai") +local Memory = require("maps.pirates.memory") +local Common = require("maps.pirates.common") +local CoreData = require("maps.pirates.coredata") +local PlayerColors = require("maps.pirates.player_colors") +local Utils = require("maps.pirates.utils_local") +local Crew = require("maps.pirates.crew") +local Roles = require("maps.pirates.roles.roles") +local Boats = require("maps.pirates.structures.boats.boats") +local Surfaces = require("maps.pirates.surfaces.surfaces") +local Overworld = require("maps.pirates.overworld") +local Islands = require("maps.pirates.surfaces.islands.islands") +local Progression = require("maps.pirates.progression") +local Crowsnest = require("maps.pirates.surfaces.crowsnest") +local PiratesApiEvents = require("maps.pirates.api_events") +local Upgrades = require("maps.pirates.shop.boat_upgrades") +local Effects = require("maps.pirates.effects") +local Kraken = require("maps.pirates.surfaces.sea.kraken") +local _inspect = require("utils.inspect").inspect +local simplex_noise = require("utils.math.simplex_noise").d2 +local Token = require("utils.token") +local Task = require("utils.task") +local Highscore = require("maps.pirates.highscore") +local Permissions = require("maps.pirates.permissions") +local Classes = require("maps.pirates.roles.classes") +local Gui = require("maps.pirates.gui.gui") +-- local Session = require 'utils.datastore.session_data' + +-- *** *** -- +--*** HELPERS ***-- +-- *** *** -- + +local function cmd_set_memory(cmd) + local player = game.players[cmd.player_index] + local crew_id = Common.get_id_from_force_name(player.force.name) + Memory.set_working_id(crew_id) +end + +local function check_admin(cmd) + local player = game.players[cmd.player_index] + --local trusted = Session.get_trusted_table() + local p + if player then + if player ~= nil then + p = player.print + --@temporary + if player.name == "Piratux" or player.name == "thesixthroc" then + return true + end + if not player.admin then + p({ "pirates.cmd_error_not_admin" }, { color = Color.fail }) + return false + end + else + p = log + end + end + return true +end + +local function check_captain(cmd) + local player = game.players[cmd.player_index] + local p + if player then + if player ~= nil then + p = player.print + if not Common.validate_player(player) then + return + end + if not (Permissions.player_privilege_level(player) >= Permissions.privilege_levels.CAPTAIN) then + p({ "pirates.cmd_error_not_captain" }, { color = Color.fail }) + return false + end + else + p = log + end + end + return true +end + +local function check_captain_or_admin(cmd) + local player = game.players[cmd.player_index] + local p + if player then + if player ~= nil then + p = player.print + if not Common.validate_player(player) then + return + end + if + not (player.admin or Permissions.player_privilege_level(player) >= Permissions.privilege_levels.CAPTAIN) + then + p({ "pirates.cmd_error_not_captain" }, { color = Color.fail }) + return false + end + else + p = log + end + end + return true +end + +local function check_creator_of_crew(cmd) + local player = game.players[cmd.player_index] + local p + if player then + if player ~= nil then + p = player.print + + cmd_set_memory(cmd) + + local memory = Memory.get_crew_memory() + if not Common.is_id_valid(memory.id) then + return + end + + local creator = memory.original_proposal.created_by_player + + if creator ~= player.index then + Common.notify_player_error(player, { "pirates.cmd_error_not_creator_of_crew" }) + return false + end + end + end +end + +-- @UNUSED +-- local function check_trusted(cmd) +-- local Session = require 'utils.datastore.session_data' +-- local player = game.players[cmd.player_index] +-- local trusted = Session.get_trusted_table() +-- local p +-- if player then +-- if player ~= nil then +-- p = player.print +-- if not (trusted[player.name] or player.admin) then +-- p('[ERROR] Only admins and trusted weebs are allowed to run this command!', {color=Color.fail}) +-- return false +-- end +-- else +-- p = log +-- end +-- end +-- return true +-- end + +-- *** *** -- +--*** PUBLIC COMMANDS ***-- +-- *** *** -- + +commands.add_command("ok", { "pirates.cmd_explain_ok" }, function(cmd) + cmd_set_memory(cmd) + + local memory = Memory.get_crew_memory() + if not Common.is_id_valid(memory.id) then + return + end + + local player = game.players[cmd.player_index] + if not Common.validate_player(player) then + return + end + + --local memory = Memory.get_crew_memory() + Roles.player_confirm_captainhood(player) +end) + +-- Disabled, better to find these out through gameplay: +-- commands.add_command( +-- 'classes', +-- 'Prints the available classes in the game.', +-- function(cmd) +-- local player = game.players[cmd.player_index] +-- if not Common.validate_player(player) then return end +-- player.print('[color=gray]' .. Roles.get_classes_print_string() .. '[/color]') +-- end) + +commands.add_command("classinfo", { "pirates.cmd_explain_classinfo" }, function(cmd) + cmd_set_memory(cmd) + local param = tostring(cmd.parameter) + local player = game.players[cmd.player_index] + if not Common.validate_player(player) then + return + end + + if param and param ~= "nil" then + local string = Roles.get_class_print_string(param, true) + if string then + Common.notify_player_expected(player, { "", { "pirates.class_definition_for" }, " ", string }) + else + Common.notify_player_error(player, { "pirates.cmd_error_invalid_class_name", param }) + end + else + Common.notify_player_expected(player, { "", "/classinfo ", { "pirates.cmd_explain_classinfo" } }) + end +end) + +commands.add_command("ccolor", { "pirates.cmd_explain_ccolor" }, function(cmd) + local param = tostring(cmd.parameter) + local player_index = cmd.player_index + if player_index then + local player = game.players[player_index] + if player and player.valid then + if cmd.parameter then + if PlayerColors.colors[param] then + local rgb = PlayerColors.colors[param] + player.color = rgb + player.chat_color = rgb + local message = { + "", + "[color=" .. rgb.r .. "," .. rgb.g .. "," .. rgb.b .. "]", + { "pirates.choose_chat_color", player.name, param }, + "[/color] (via /ccolor).", + } + -- local message = '[color=' .. rgb.r .. ',' .. rgb.g .. ',' .. rgb.b .. ']' .. player.name .. ' chose the color ' .. param .. '[/color] (via /ccolor).' + Common.notify_game(message) + else + Common.notify_player_error(player, { "pirates.cmd_error_color_not_found", param }) + end + else + local color = PlayerColors.bright_color_names[Math.random(#PlayerColors.bright_color_names)] + local rgb = PlayerColors.colors[color] + if not rgb then + return + end + player.color = rgb + player.chat_color = rgb + local message = { + "", + "[color=" .. rgb.r .. "," .. rgb.g .. "," .. rgb.b .. "]", + { "pirates.randomize_chat_color", player.name, color }, + "[/color] (via /ccolor).", + } --'randomly became' was amusing, but let's not + -- local message = '[color=' .. rgb.r .. ',' .. rgb.g .. ',' .. rgb.b .. ']' .. player.name .. '\'s color randomized to ' .. color .. '[/color] (via /ccolor).' --'randomly became' was amusing, but let's not + Common.notify_game(message) + -- disabled due to lag: + -- GUIcolor.toggle_window(player) + end + end + end +end) + +commands.add_command("fixpower", { "pirates.cmd_explain_fixpower" }, function(cmd) + cmd_set_memory(cmd) + + local memory = Memory.get_crew_memory() + if not Common.is_id_valid(memory.id) then + return + end + + Boats.force_reconnect_boat_poles() +end) + +-- *** *** -- +--*** CAPTAIN COMMANDS ***-- +-- *** *** -- + +commands.add_command("plank", { "pirates.cmd_explain_plank" }, function(cmd) + cmd_set_memory(cmd) + + local memory = Memory.get_crew_memory() + if not Common.is_id_valid(memory.id) then + return + end + + local player = game.players[cmd.player_index] + local param = tostring(cmd.parameter) + if check_captain_or_admin(cmd) then + if param and game.players[param] and game.players[param].index then + Crew.plank(player, game.players[param]) + else + Common.notify_player_error(player, { "pirates.cmd_error_invalid_player_name", param }) + end + end +end) + +commands.add_command("officer", { "pirates.cmd_explain_officer" }, function(cmd) + cmd_set_memory(cmd) + + local memory = Memory.get_crew_memory() + if not Common.is_id_valid(memory.id) then + return + end + + local player = game.players[cmd.player_index] + local param = tostring(cmd.parameter) + if check_captain_or_admin(cmd) then + if param and game.players[param] and game.players[param].index then + if Common.is_officer(game.players[param].index) then + Roles.unmake_officer(player, game.players[param]) + else + Roles.make_officer(player, game.players[param]) + end + else + Common.notify_player_error(player, { "pirates.cmd_error_invalid_player_name", param }) + end + end +end) + +commands.add_command("tax", { "pirates.cmd_explain_tax" }, function(cmd) + cmd_set_memory(cmd) + + local memory = Memory.get_crew_memory() + if not Common.is_id_valid(memory.id) then + return + end + + --local param = tostring(cmd.parameter) + if check_captain(cmd) then + --local player = game.players[cmd.player_index] + Roles.captain_tax(memory.playerindex_captain) + end +end) + +-- Try undock from an island or dock +commands.add_command("undock", { "pirates.cmd_explain_undock" }, function(cmd) + cmd_set_memory(cmd) + + local memory = Memory.get_crew_memory() + if not Common.is_id_valid(memory.id) then + return + end + + --local param = tostring(cmd.parameter) + if check_captain_or_admin(cmd) then + local player = game.players[cmd.player_index] + if memory.boat.state == Boats.enum_state.DOCKED then + Progression.undock_from_dock(true) + elseif memory.boat.state == Boats.enum_state.LANDED then + Progression.try_retreat_from_island(player, true) + end + end +end) + +commands.add_command("clear_north_tanks", { "pirates.cmd_explain_clear_north_tanks" }, function(cmd) + cmd_set_memory(cmd) + + local memory = Memory.get_crew_memory() + if not Common.is_id_valid(memory.id) then + return + end + + if check_captain_or_admin(cmd) then + Boats.clear_fluid_from_ship_tanks(1) + end +end) + +commands.add_command("clear_south_tanks", { "pirates.cmd_explain_clear_south_tanks" }, function(cmd) + cmd_set_memory(cmd) + + local memory = Memory.get_crew_memory() + if not Common.is_id_valid(memory.id) then + return + end + + if check_captain(cmd) then + Boats.clear_fluid_from_ship_tanks(2) + end +end) + +-- *** *** -- +--*** CREATOR OF CREW COMMANDS ***-- +-- *** *** -- + +commands.add_command("reset_password", { "pirates.cmd_explain_set_private_run_password" }, function(cmd) + cmd_set_memory(cmd) + + local memory = Memory.get_crew_memory() + if not Common.is_id_valid(memory.id) then + return + end + + local param = tostring(cmd.parameter) + if check_creator_of_crew(cmd) then + local player = game.players[cmd.player_index] + + if not memory.private_run_password then + Common.notify_player_error(player, { "pirates.cmd_error_no_existing_password" }) + return false + end + + memory.private_run_password = param + Common.notify_player_expected(player, { "pirates.cmd_notify_set_private_run_password", memory.name, param }) + end +end) + +-- *** *** -- +--*** ADMIN COMMANDS ***-- +-- *** *** -- + +commands.add_command("set_max_crews", { "pirates.cmd_explain_set_max_crews" }, function(cmd) + local param = tostring(cmd.parameter) + if check_admin(cmd) then + local player = game.players[cmd.player_index] + local global_memory = Memory.get_global_memory() + + if tonumber(param) then + global_memory.active_crews_cap_in_memory = tonumber(param) + Common.notify_player_expected(player, { "pirates.cmd_notify_set_max_crews", param }) + end + end +end) + +commands.add_command("setcaptain", { "pirates.cmd_explain_setcaptain" }, function(cmd) + cmd_set_memory(cmd) + + local memory = Memory.get_crew_memory() + if not Common.is_id_valid(memory.id) then + return + end + + local param = tostring(cmd.parameter) + if check_admin(cmd) then + local player = game.players[cmd.player_index] + if param and game.players[param] and game.players[param].index then + Roles.make_captain(game.players[param]) + else + Common.notify_player_error(player, { "pirates.cmd_error_invalid_player_name", param }) + end + end +end) + +commands.add_command("summoncrew", { "pirates.cmd_explain_summoncrew" }, function(cmd) + cmd_set_memory(cmd) + + local memory = Memory.get_crew_memory() + if not Common.is_id_valid(memory.id) then + return + end + + --local param = tostring(cmd.parameter) + if check_admin(cmd) then + Crew.summon_crew() + end +end) + +-- Force undock from an island or dock +commands.add_command("ret", { "pirates.cmd_explain_dev" }, function(cmd) + cmd_set_memory(cmd) + + local memory = Memory.get_crew_memory() + if not Common.is_id_valid(memory.id) then + return + end + + -- local param = tostring(cmd.parameter) + if check_admin(cmd) then + if memory.boat.state == Boats.enum_state.DOCKED then + Progression.undock_from_dock(true) + elseif memory.boat.state == Boats.enum_state.LANDED then + Progression.retreat_from_island(true) + end + end +end) + +commands.add_command("dump_highscores", { "pirates.cmd_explain_dev" }, function(cmd) + cmd_set_memory(cmd) + + if check_admin(cmd) then + local player = game.players[cmd.player_index] + if not Common.validate_player(player) then + return + end + Highscore.dump_highscores() + player.print("Highscores dumped.") + end +end) + +commands.add_command("setevo", { "pirates.cmd_explain_dev" }, function(cmd) + cmd_set_memory(cmd) + + local param = tostring(cmd.parameter) + if check_admin(cmd) then + local player = game.players[cmd.player_index] + Common.set_evo(tonumber(param)) + end +end) + +commands.add_command("modi", { "pirates.cmd_explain_dev" }, function(cmd) + cmd_set_memory(cmd) + + local param = tostring(cmd.parameter) + if check_admin(cmd) then + local player = game.players[cmd.player_index] + local memory = Memory.get_crew_memory() + local surface = game.surfaces[Common.current_destination().surface_name] + local entities = surface.find_entities_filtered({ position = player.position, radius = 500 }) + for _, e in pairs(entities) do + if e and e.valid then + -- e.force = memory.force + e.minable = true + e.destructible = true + e.rotatable = true + end + end + player.print("nearby entities made modifiable") + end +end) + +commands.add_command("night", "night", function(cmd) + if check_admin(cmd) then + local player = game.players[cmd.player_index] + local surface = player.surface + surface.daytime = 0.5 + end +end) + +commands.add_command("overwrite_scores_specific", { "pirates.cmd_explain_dev" }, function(cmd) + cmd_set_memory(cmd) + + if check_admin(cmd) then + local player = game.players[cmd.player_index] + if not Common.validate_player(player) then + return + end + local memory = Memory.get_crew_memory() + if Highscore.overwrite_scores_specific() then + player.print("Highscores overwritten.") + end + end +end) + +-- Unlock a class +commands.add_command("unlock", { "pirates.cmd_explain_dev" }, function(cmd) + cmd_set_memory(cmd) + local param = tostring(cmd.parameter) + if check_admin(cmd) then + local memory = Memory.get_crew_memory() + if not Common.is_id_valid(memory.id) then + return + end + local player = game.players[cmd.player_index] + if not Classes.try_unlock_class(param, player, true) then + Common.notify_player_error(player, { "pirates.cmd_error_invalid_class_name", param }) + end + end +end) + +-- Remove all classes +commands.add_command("remove_classes", { "pirates.cmd_explain_dev" }, function(cmd) + cmd_set_memory(cmd) + local param = tostring(cmd.parameter) + if check_admin(cmd) then + local memory = Memory.get_crew_memory() + if not Common.is_id_valid(memory.id) then + return + end + + if not Gui.classes then + return + end + + memory.classes_table = {} + memory.spare_classes = {} + memory.recently_purchased_classes = {} + memory.unlocked_classes = {} + memory.available_classes_pool = Classes.initial_class_pool() + memory.class_entry_count = 0 + + local players = Common.crew_get_crew_members() + + for _, player in pairs(players) do + Gui.classes.full_update(player, true) + end + end +end) + +-- *** *** -- +--*** GO COMMAND LOGIC (also used by singleplayer auto-go in api_events.lua) ***-- +-- *** *** -- + +-- Token registrations for the /go command workflow +local go_2 = Token.register(function(data) + Memory.set_working_id(data.id) + local memory = Memory.get_crew_memory() + + memory.loading_ticks = 0 + + -- local surface = game.surfaces[Common.current_destination().surface_name] + -- surface.request_to_generate_chunks({x = 0, y = 0}, 10) + -- surface.force_generate_chunk_requests() + Progression.go_from_starting_dock_to_first_destination() +end) +local go_1 = Token.register(function(data) + Memory.set_working_id(data.id) + local memory = Memory.get_crew_memory() + Overworld.ensure_lane_generated_up_to(0, Crowsnest.Data.visibilitywidth) + Overworld.ensure_lane_generated_up_to(24, Crowsnest.Data.visibilitywidth) + Overworld.ensure_lane_generated_up_to(-24, Crowsnest.Data.visibilitywidth) + + for i = 1, #memory.destinations do + if memory.destinations[i].overworld_position.x == 0 then + memory.map_being_loaded_destination_index = i + break + end + end + + memory.currentdestination_index = memory.map_being_loaded_destination_index + Surfaces.create_surface(Common.current_destination()) + Task.set_timeout_in_ticks(60, go_2, { id = data.id }) +end) + +-- Execute the /go command logic for a player. Returns true on success, false if already in a crew. +local function execute_go(player) + if Common.get_id_from_force_name(player.character.force.name) then + return false -- Already in a crew + end + + local proposal = { + capacity_option = 3, + difficulty_option = 4, + name = "SingleplayerRun", + created_by_player = player.index, + run_is_protected = false, + run_is_private = false, + } + + Crew.initialise_crew(proposal, player.position) + Crew.initialise_crowsnest() -- contains a Task + + local memory = Memory.get_crew_memory() + local boat = Utils.deepcopy(Surfaces.Lobby.StartingBoats[memory.id]) + + for _, p in pairs(game.connected_players) do + p.teleport({ x = -30, y = boat.position.y }, game.surfaces[boat.surface_name]) + end + + Progression.set_off_from_starting_dock() + Task.set_timeout_in_ticks(120, go_1, { id = memory.id }) + + return true +end + +-- *** *** -- +--*** DEVELOPER COMMANDS ***-- +-- *** *** -- + +if _DEBUG then + -- Move overworld boat right by a lot (you can jump over islands that way to skip them) + commands.add_command("jump", { "pirates.cmd_explain_dev" }, function(cmd) + cmd_set_memory(cmd) + + local param = tostring(cmd.parameter) + if check_admin(cmd) then + local player = game.players[cmd.player_index] + Overworld.try_overworld_move_v2({ x = 40, y = 0 }) + end + end) + + -- Move overworld boat up + commands.add_command("advu", { "pirates.cmd_explain_dev" }, function(cmd) + cmd_set_memory(cmd) + + local param = tostring(cmd.parameter) + if check_admin(cmd) then + local player = game.players[cmd.player_index] + Overworld.try_overworld_move_v2({ x = 0, y = -24 }) + end + end) + + -- Move overworld boat down + commands.add_command("advd", { "pirates.cmd_explain_dev" }, function(cmd) + cmd_set_memory(cmd) + + local param = tostring(cmd.parameter) + if check_admin(cmd) then + local player = game.players[cmd.player_index] + Overworld.try_overworld_move_v2({ x = 0, y = 24 }) + end + end) + + -- Teleport player to available boat in lobby, automatically start journey and arrive at sea faster + commands.add_command("go", { "pirates.cmd_explain_dev" }, function(cmd) + cmd_set_memory(cmd) + if check_admin(cmd) then + local player = game.players[cmd.player_index] + if not execute_go(player) then + game.print("Can't use this command when run has already launched") + end + end + end) + + commands.add_command("chnk", { "pirates.cmd_explain_dev" }, function(cmd) + cmd_set_memory(cmd) + + local param = tostring(cmd.parameter) + if check_admin(cmd) then + local player = game.players[cmd.player_index] + local memory = Memory.get_crew_memory() + + for i = 0, 13 do + for j = 0, 13 do + PiratesApiEvents.event_on_chunk_generated({ + surface = player.surface, + area = { left_top = { x = -7 * 32 + i * 32, y = -7 * 32 + j * 32 } }, + }) + end + end + game.print("chunks generated") + end + end) + + commands.add_command("spd", { "pirates.cmd_explain_dev" }, function(cmd) + cmd_set_memory(cmd) + + local param = tostring(cmd.parameter) + if check_admin(cmd) then + local player = game.players[cmd.player_index] + local memory = Memory.get_crew_memory() + memory.boat.speed = 60 + end + end) + + commands.add_command("stp", { "pirates.cmd_explain_dev" }, function(cmd) + cmd_set_memory(cmd) + + local param = tostring(cmd.parameter) + if check_admin(cmd) then + local player = game.players[cmd.player_index] + local memory = Memory.get_crew_memory() + memory.boat.speed = 0 + end + end) + + commands.add_command("rms", { "pirates.cmd_explain_dev" }, function(cmd) + local param = tostring(cmd.parameter) + if check_admin(cmd) then + local player = game.players[cmd.player_index] + local rms = 0 + local n = 100000 + local seed = Math.random(n ^ 2) + for i = 1, n do + local noise = simplex_noise(i, 7.11, seed) + rms = rms + noise ^ 2 + end + rms = rms / n + game.print(rms) + end + end) + + commands.add_command("pro", { "pirates.cmd_explain_dev" }, function(cmd) + local param = tostring(cmd.parameter) + if check_admin(cmd) then + local player = game.players[cmd.player_index] + local global_memory = Memory.get_global_memory() + + local proposal = { + capacity_option = 3, + difficulty_option = 2, + -- mode_option = 'left', + name = "TestRun", + created_by_player = cmd.player_index, + } + + global_memory.crewproposals[#global_memory.crewproposals + 1] = proposal + end + end) + + -- Leave island, or dock immediately + commands.add_command("lev", { "pirates.cmd_explain_dev" }, function(cmd) + cmd_set_memory(cmd) + local param = tostring(cmd.parameter) + if check_admin(cmd) then + local player = game.players[cmd.player_index] + local memory = Memory.get_crew_memory() + Progression.go_from_currentdestination_to_sea() + end + end) + + -- Add another hold + commands.add_command("hld", { "pirates.cmd_explain_dev" }, function(cmd) + cmd_set_memory(cmd) + local param = tostring(cmd.parameter) + if check_admin(cmd) then + local player = game.players[cmd.player_index] + local memory = Memory.get_crew_memory() + Upgrades.execute_upgade(Upgrades.enum.EXTRA_HOLD) + end + end) + + -- Upgrade power generators + commands.add_command("pwr", { "pirates.cmd_explain_dev" }, function(cmd) + cmd_set_memory(cmd) + local param = tostring(cmd.parameter) + if check_admin(cmd) then + local player = game.players[cmd.player_index] + local memory = Memory.get_crew_memory() + Upgrades.execute_upgade(Upgrades.enum.MORE_POWER) + end + end) + + commands.add_command("score", { "pirates.cmd_explain_dev" }, function(cmd) + cmd_set_memory(cmd) + + local param = tostring(cmd.parameter) + if check_admin(cmd) then + local player = game.players[cmd.player_index] + local memory = Memory.get_crew_memory() + + game.print("faking a highscore...") + Highscore.write_score(memory.secs_id, "fakers", 0, 40, CoreData.version_string, 1, 1) + end + end) + + commands.add_command("scrget", { "pirates.cmd_explain_dev" }, function(cmd) + local param = tostring(cmd.parameter) + if check_admin(cmd) then + local player = game.players[cmd.player_index] + game.print("running Highscore.load_in_scores()") + Highscore.load_in_scores() + end + end) + + commands.add_command("tim", { "pirates.cmd_explain_dev" }, function(cmd) + cmd_set_memory(cmd) + local param = tostring(cmd.parameter) + if check_admin(cmd) then + local player = game.players[cmd.player_index] + local memory = Memory.get_crew_memory() + Common.current_destination().dynamic_data.timer = 88 + game.print("time set to 88 seconds") + end + end) + + -- Add 20000 coal fuel to ship + commands.add_command("gld", { "pirates.cmd_explain_dev" }, function(cmd) + cmd_set_memory(cmd) + local param = tostring(cmd.parameter) + if check_admin(cmd) then + local player = game.players[cmd.player_index] + local memory = Memory.get_crew_memory() + memory.stored_fuel = memory.stored_fuel + 20000 + end + end) + + commands.add_command("rad", { "pirates.cmd_explain_dev" }, function(cmd) + cmd_set_memory(cmd) + local param = tostring(cmd.parameter) + if check_admin(cmd) then + local destination = Common.current_destination() + Islands.spawn_enemy_boat(Boats.enum.RAFT) + local boat = destination.dynamic_data.enemyboats[1] + Ai.spawn_boat_biters(boat, 0.89, Boats.get_scope(boat).Data.capacity, Boats.get_scope(boat).Data.width) + game.print("enemy boat spawned") + end + end) + + commands.add_command("rad2", { "pirates.cmd_explain_dev" }, function(cmd) + cmd_set_memory(cmd) + local param = tostring(cmd.parameter) + if check_admin(cmd) then + local destination = Common.current_destination() + Islands.spawn_enemy_boat(Boats.enum.RAFTLARGE) + local boat = destination.dynamic_data.enemyboats[1] + Ai.spawn_boat_biters(boat, 0.89, Boats.get_scope(boat).Data.capacity, Boats.get_scope(boat).Data.width) + game.print("large enemy boat spawned") + end + end) + + -- Spawns kraken if at sea + commands.add_command("krk", { "pirates.cmd_explain_dev" }, function(cmd) + cmd_set_memory(cmd) + local param = tostring(cmd.parameter) + if check_admin(cmd) then + local player = game.players[cmd.player_index] + local memory = Memory.get_crew_memory() + Kraken.try_spawn_kraken() + end + end) + + -- Sets game speed to 0.25 + commands.add_command("1/4", { "pirates.cmd_explain_dev" }, function(cmd) + local param = tostring(cmd.parameter) + if check_admin(cmd) then + local player = game.players[cmd.player_index] + game.speed = 0.25 + end + end) + + -- Sets game speed to 0.5 + commands.add_command("1/2", { "pirates.cmd_explain_dev" }, function(cmd) + local param = tostring(cmd.parameter) + if check_admin(cmd) then + local player = game.players[cmd.player_index] + game.speed = 0.5 + end + end) + + -- Sets game speed to 1 + commands.add_command("1", { "pirates.cmd_explain_dev" }, function(cmd) + local param = tostring(cmd.parameter) + if check_admin(cmd) then + local player = game.players[cmd.player_index] + game.speed = 1 + end + end) + + -- Sets game speed to 2 + commands.add_command("2", { "pirates.cmd_explain_dev" }, function(cmd) + local param = tostring(cmd.parameter) + if check_admin(cmd) then + local player = game.players[cmd.player_index] + game.speed = 2 + end + end) + + -- Sets game speed to 4 + commands.add_command("4", { "pirates.cmd_explain_dev" }, function(cmd) + local param = tostring(cmd.parameter) + if check_admin(cmd) then + local player = game.players[cmd.player_index] + game.speed = 4 + end + end) + + -- Sets game speed to 8 + commands.add_command("8", { "pirates.cmd_explain_dev" }, function(cmd) + local param = tostring(cmd.parameter) + if check_admin(cmd) then + local player = game.players[cmd.player_index] + game.speed = 8 + end + end) + + -- Sets game speed to 16 + commands.add_command("16", { "pirates.cmd_explain_dev" }, function(cmd) + local param = tostring(cmd.parameter) + if check_admin(cmd) then + local player = game.players[cmd.player_index] + game.speed = 16 + end + end) + + -- Sets game speed to 32 + commands.add_command("32", { "pirates.cmd_explain_dev" }, function(cmd) + local param = tostring(cmd.parameter) + if check_admin(cmd) then + local player = game.players[cmd.player_index] + game.speed = 32 + end + end) + + -- Sets game speed to 64 + commands.add_command("64", { "pirates.cmd_explain_dev" }, function(cmd) + local param = tostring(cmd.parameter) + if check_admin(cmd) then + local player = game.players[cmd.player_index] + game.speed = 64 + end + end) + + commands.add_command("ef1", { "pirates.cmd_explain_dev" }, function(cmd) + cmd_set_memory(cmd) + + local param = tostring(cmd.parameter) + if check_admin(cmd) then + local player = game.players[cmd.player_index] + local memory = Memory.get_crew_memory() + local surface = game.surfaces[Common.current_destination().surface_name] + Effects.worm_movement_effect(surface, { x = -45, y = 0 }, false, true) + end + end) + + commands.add_command("ef2", { "pirates.cmd_explain_dev" }, function(cmd) + cmd_set_memory(cmd) + + local param = tostring(cmd.parameter) + if check_admin(cmd) then + local player = game.players[cmd.player_index] + local memory = Memory.get_crew_memory() + local surface = game.surfaces[Common.current_destination().surface_name] + Effects.worm_movement_effect(surface, { x = -45, y = 0 }, false, false) + end + end) + + commands.add_command("ef3", { "pirates.cmd_explain_dev" }, function(cmd) + cmd_set_memory(cmd) + + local param = tostring(cmd.parameter) + if check_admin(cmd) then + local player = game.players[cmd.player_index] + local memory = Memory.get_crew_memory() + local surface = game.surfaces[Common.current_destination().surface_name] + Effects.worm_movement_effect(surface, { x = -45, y = 0 }, true, false) + end + end) + + commands.add_command("ef4", { "pirates.cmd_explain_dev" }, function(cmd) + cmd_set_memory(cmd) + + local param = tostring(cmd.parameter) + if check_admin(cmd) then + local player = game.players[cmd.player_index] + local memory = Memory.get_crew_memory() + local surface = game.surfaces[Common.current_destination().surface_name] + Effects.worm_emerge_effect(surface, { x = -45, y = 0 }) + end + end) + + commands.add_command("ef5", { "pirates.cmd_explain_dev" }, function(cmd) + cmd_set_memory(cmd) + + local param = tostring(cmd.parameter) + if check_admin(cmd) then + local player = game.players[cmd.player_index] + local memory = Memory.get_crew_memory() + local surface = game.surfaces[Common.current_destination().surface_name] + Effects.biters_emerge(surface, { x = -30, y = 0 }) + end + end) + + commands.add_command("emoji", { "pirates.cmd_explain_dev" }, function(cmd) + local param = tostring(cmd.parameter) + if check_admin(cmd) then + local player = game.players[cmd.player_index] + Server.to_discord_embed_raw(CoreData.comfy_emojis.despair) + end + end) + + -- Spawn friendly gun turrets with ammo to defend your ship + commands.add_command("def", { "pirates.cmd_explain_dev" }, function(cmd) + cmd_set_memory(cmd) + local param = tostring(cmd.parameter) + if check_admin(cmd) then + local player = game.players[cmd.player_index] + local memory = Memory.get_crew_memory() + if not Common.is_id_valid(memory.id) then + return + end + + local boat = memory.boat + local scope = Boats.get_scope(boat) + local surface = game.surfaces[boat.surface_name] + if not surface then + return + end + + if scope.Data.cannons then + for i = -2, 2 do + local p1 = scope.Data.cannons[1] + local p2 = { x = boat.position.x + p1.x + i * 2, y = boat.position.y + p1.y - 4 } + local e = surface.create_entity({ + name = "gun-turret", + position = p2, + force = boat.force_name, + create_build_effect_smoke = false, + }) + if e and e.valid then + e.insert({ name = "uranium-rounds-magazine", count = 200 }) + end + end + for i = -2, 2 do + local p1 = scope.Data.cannons[2] + local p2 = { x = boat.position.x + p1.x + i * 2, y = boat.position.y + p1.y + 3 } + local e = surface.create_entity({ + name = "gun-turret", + position = p2, + force = boat.force_name, + create_build_effect_smoke = false, + }) + if e and e.valid then + e.insert({ name = "uranium-rounds-magazine", count = 200 }) + end + end + end + end + end) + + -- Spawn friendly gun turrets with ammo around you + commands.add_command("atk", { "pirates.cmd_explain_dev" }, function(cmd) + cmd_set_memory(cmd) + local param = tostring(cmd.parameter) + if check_admin(cmd) then + local player = game.players[cmd.player_index] + local memory = Memory.get_crew_memory() + if not Common.is_id_valid(memory.id) then + return + end + local boat = memory.boat + + local p = player.character.position + local turret_positions = { + { x = p.x - 2, y = p.y - 2 }, + { x = p.x - 2, y = p.y + 2 }, + { x = p.x + 2, y = p.y - 2 }, + { x = p.x + 2, y = p.y + 2 }, + } + + for _, pos in pairs(turret_positions) do + local e = player.surface.create_entity({ + name = "gun-turret", + position = pos, + force = boat.force_name, + create_build_effect_smoke = false, + }) + if e and e.valid then + e.insert({ name = "uranium-rounds-magazine", count = 200 }) + end + end + end + end) + + -- Give advanced starter kit to make exploration easier + commands.add_command("kit", { "pirates.cmd_explain_dev" }, function(cmd) + if check_admin(cmd) then + local player = game.players[cmd.player_index] + + player.insert({ name = "substation", count = 50 }) + player.insert({ name = "solar-panel", count = 50 }) + player.insert({ name = "vehicle-machine-gun", count = 1 }) + player.insert({ name = "uranium-rounds-magazine", count = 200 }) + player.insert({ name = "raw-fish", count = 100 }) + player.insert({ name = "coin", count = 50000 }) + player.insert({ name = "cluster-grenade", count = 100 }) + player.insert({ name = "steel-chest", count = 50 }) + player.insert({ name = "express-loader", count = 50 }) + player.insert({ name = "burner-inserter", count = 50 }) + player.insert({ name = "accumulator", count = 50 }) + end + end) + + -- Fills the inventory + commands.add_command("fill", { "pirates.cmd_explain_dev" }, function(cmd) + if check_admin(cmd) then + local player = game.players[cmd.player_index] + + player.insert({ name = "power-armor-mk2", count = 1 }) + player.insert({ name = "iron-plate", count = 10000 }) + end + end) + + commands.add_command("buff", "buffs all damage by 10%", function(cmd) + if check_admin(cmd) then + local player = game.players[cmd.player_index] + Crew.buff_all_damage(0.1) + end + end) +end From 444fdf124a8422cfec6a0b2263e9af7672e813f1 Mon Sep 17 00:00:00 2001 From: danielmartin0 Date: Thu, 5 Feb 2026 17:08:40 +0000 Subject: [PATCH 2/6] disable speed2/3 and automation3 --- maps/pirates/crew.lua | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/maps/pirates/crew.lua b/maps/pirates/crew.lua index e287f8b67..433334deb 100644 --- a/maps/pirates/crew.lua +++ b/maps/pirates/crew.lua @@ -1052,12 +1052,12 @@ function Public.reset_crew_and_enemy_force(id) -- crew_force.technologies['productivity-module-3'].enabled = false -- crew_force.technologies['speed-module'].enabled = true - -- crew_force.technologies['speed-module-2'].enabled = false - -- crew_force.technologies['speed-module-3'].enabled = false + crew_force.technologies['speed-module-2'].enabled = false + crew_force.technologies['speed-module-3'].enabled = false -- crew_force.technologies['efficiency-module'].enabled = true -- crew_force.technologies['efficiency-module-2'].enabled = false -- crew_force.technologies['efficiency-module-3'].enabled = false - -- crew_force.technologies['automation-3'].enabled = false + crew_force.technologies['automation-3'].enabled = false -- crew_force.technologies['rocket-silo'].enabled = false --Probably need to disable this tech if we're playing on space age -- crew_force.technologies['space-scienkce-pack'].enabled = false -- crew_force.technologies['mining-productivity-3'].enabled = false @@ -1128,6 +1128,7 @@ function Public.disable_recipes(crew_force) crew_force.recipes['speed-module-2'].enabled = false crew_force.recipes['speed-module-3'].enabled = false + crew_force.recipes['assembling-machine-3'].enabled = false end return Public From 52b8e6932da2b30d67c92bbdd791b2e57597ac26 Mon Sep 17 00:00:00 2001 From: danielmartin0 Date: Sun, 22 Feb 2026 20:29:12 +0000 Subject: [PATCH 3/6] Update changelog.txt --- changelog.txt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/changelog.txt b/changelog.txt index 26feb057c..425f744da 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,7 +1,8 @@ --------------------------------------------------------------------------------------------------- Version: 1.9.1 -Date: ???? - Changes: +Date: 2026-02-22 + Balancing: + - Speed modules T2+3 and Assembling machines T3 can no longer be researched, leaving them as valuable loot. --------------------------------------------------------------------------------------------------- Version: 1.9.0 Date: 2026-02-05 From 082c87edb733aa4327d60aa9ee342ec7cfdbab3f Mon Sep 17 00:00:00 2001 From: danielmartin0 Date: Sun, 22 Feb 2026 20:40:35 +0000 Subject: [PATCH 4/6] Delete changelog.txt --- changelog.txt | 104 -------------------------------------------------- 1 file changed, 104 deletions(-) delete mode 100644 changelog.txt diff --git a/changelog.txt b/changelog.txt deleted file mode 100644 index 425f744da..000000000 --- a/changelog.txt +++ /dev/null @@ -1,104 +0,0 @@ ---------------------------------------------------------------------------------------------------- -Version: 1.9.1 -Date: 2026-02-22 - Balancing: - - Speed modules T2+3 and Assembling machines T3 can no longer be researched, leaving them as valuable loot. ---------------------------------------------------------------------------------------------------- -Version: 1.9.0 -Date: 2026-02-05 - Changes: - - Singleplayer games now launch the player on a ship automatically. ---------------------------------------------------------------------------------------------------- -Version: 1.8.19 -Date: 2026-01-26 - Changes: - - Players leaving crews and without leaving the server now immediately send their items to the captain's cabin rather than doing so on a timer. ---------------------------------------------------------------------------------------------------- -Version: 1.8.18 -Date: 2026-01-19 - Bugfixes: - - Fixed that the most recent version enabled debug mode. ---------------------------------------------------------------------------------------------------- -Version: 1.8.17 -Date: 2026-01-18 - Bugfixes: - - Fixed a bug in which player permissions could be set incorrectly if there were two or more crews on the server. - Changes: - - Empty crews now autodisband after 72 hours rather than 96. ---------------------------------------------------------------------------------------------------- -Version: 1.8.16 -Date: 2025-05-30 - Bugfixes: - - It is no longer impossible to use the centrifuges on newly generated uranium islands. - - The Compilatron quest no longer appears on the cave island since the Compilatron entity was removed in 2.0. - - Tweaked some autoplace settings code. ---------------------------------------------------------------------------------------------------- -Version: 1.8.15 -Date: 2025-05-06 - Info: - - Updated the changelog for clarity. ---------------------------------------------------------------------------------------------------- -Version: 1.8.13 -Date: 2025-05-05 - Bugfixes: - - Fixed that biters would not attack unless the player attacks first. This will not apply to the current islands in a given save, but is fixed for future islands. ---------------------------------------------------------------------------------------------------- -Version: 1.8.12 -Date: 2025-04-19 - Changes: - - Default difficulty changed from 'Easy' to 'Normal'. ---------------------------------------------------------------------------------------------------- -Version: 1.8.11 -Date: 2025-04-19 - Changes: - - Fixed that research effects were not always properly applied. ---------------------------------------------------------------------------------------------------- -Version: 1.8.10 -Date: 2025-04-12 - Changes: - - New thumbnail. ---------------------------------------------------------------------------------------------------- -Version: 1.8.9 -Date: 2025-04-12 - Changes: - - New thumbnail. ---------------------------------------------------------------------------------------------------- -Version: 1.8.7 -Date: 2025-04-12 - Changes: - - Rebased on Comfy. ---------------------------------------------------------------------------------------------------- -Version: 1.8.6 -Date: 2025-03-02 - Changes: - - Marked as incompatible with Space Age and Quality. ---------------------------------------------------------------------------------------------------- -Version: 1.8.5 -Date: 2025-02-28 - Changes: - - Fixed crash in api_on_tick when attempting to equalise fluid storages. ---------------------------------------------------------------------------------------------------- -Version: 1.8.4 -Date: 2025-02-25 - Changes: - - Fix turbo transport belts being teleported rather than cloned when the boat moves. ---------------------------------------------------------------------------------------------------- -Version: 1.8.3 -Date: 2025-02-25 - Changes: - - Fixed certain damage upgrades not being applied correctly. ---------------------------------------------------------------------------------------------------- -Version: 1.8.2 -Date: 2025-02-23 - Changes: - - Fixed crash on 'An interface already exists under with name: space_finish_script'. ---------------------------------------------------------------------------------------------------- -Version: 1.8.1 -Date: 2025-01-13 - Info: - - Description updated. ---------------------------------------------------------------------------------------------------- -Version: 1.8.0 -Date: 2025-01-13 - Changes: - - This mod no longer functions as a scenario. Pre-existing 'scenario' saves are not compatible with 1.8.0. \ No newline at end of file From 6bc334c15c5b2bb4453f4fb99bda4e23ba0c77d7 Mon Sep 17 00:00:00 2001 From: danielmartin0 Date: Mon, 23 Feb 2026 10:31:34 +0000 Subject: [PATCH 5/6] Revert "1.9.0" This reverts commit 7ec25774750f60eeb41bd32e9f5b8f4fb8ab1eb1. --- info.json | 2 +- maps/pirates/api_events.lua | 97 +- maps/pirates/commands.lua | 2288 +++++++++++++++++------------------ 3 files changed, 1148 insertions(+), 1239 deletions(-) diff --git a/info.json b/info.json index 0967ef424..9e26dfeeb 100644 --- a/info.json +++ b/info.json @@ -1 +1 @@ -{} +{} \ No newline at end of file diff --git a/maps/pirates/api_events.lua b/maps/pirates/api_events.lua index 0939ac7d1..143b6df2f 100644 --- a/maps/pirates/api_events.lua +++ b/maps/pirates/api_events.lua @@ -12,9 +12,7 @@ local Ai = require("maps.pirates.ai") -- local Structures = require 'maps.pirates.structures.structures' local Boats = require("maps.pirates.structures.boats.boats") local Surfaces = require("maps.pirates.surfaces.surfaces") -local Progression = require("maps.pirates.progression") -local Overworld = require("maps.pirates.overworld") -local Crowsnest = require("maps.pirates.surfaces.crowsnest") +-- local Progression = require 'maps.pirates.progression' local IslandEnum = require("maps.pirates.surfaces.islands.island_enum") local Roles = require("maps.pirates.roles.roles") local Permissions = require("maps.pirates.permissions") @@ -40,80 +38,6 @@ local Server = require("utils.server") local GuiWelcome = require("maps.pirates.gui.welcome") local tick_tack_trap = require("utils.functions.tick_tack_trap") --- Token callbacks for singleplayer auto-go functionality -local singleplayer_go_2 = Token.register(function(data) - Memory.set_working_id(data.id) - local memory = Memory.get_crew_memory() - memory.loading_ticks = 0 - Progression.go_from_starting_dock_to_first_destination() -end) - -local singleplayer_go_1 = Token.register(function(data) - Memory.set_working_id(data.id) - local memory = Memory.get_crew_memory() - Overworld.ensure_lane_generated_up_to(0, Crowsnest.Data.visibilitywidth) - Overworld.ensure_lane_generated_up_to(24, Crowsnest.Data.visibilitywidth) - Overworld.ensure_lane_generated_up_to(-24, Crowsnest.Data.visibilitywidth) - - for i = 1, #memory.destinations do - if memory.destinations[i].overworld_position.x == 0 then - memory.map_being_loaded_destination_index = i - break - end - end - - memory.currentdestination_index = memory.map_being_loaded_destination_index - Surfaces.create_surface(Common.current_destination()) - Task.set_timeout_in_ticks(60, singleplayer_go_2, { id = data.id }) -end) - --- Delayed callback that performs the actual auto-go after lobby boats are ready -local singleplayer_auto_go_delayed -singleplayer_auto_go_delayed = Token.register(function(data) - local global_memory = Memory.get_global_memory() - - -- Check if lobby boats are ready (they're created at tick 2) - if not global_memory.lobby_boats or not global_memory.lobby_boats[1] then - -- Boats not ready yet, retry in a few ticks - Task.set_timeout_in_ticks(5, singleplayer_auto_go_delayed, data) - return - end - - local player = game.players[data.player_index] - if not player or not player.valid then - return - end - - local proposal = { - capacity_option = 3, - difficulty_option = 4, - name = player.name .. (string.sub(player.name, -1) == "s" and "' Ship" or "'s Ship"), - created_by_player = player.index, - run_is_protected = false, - run_is_private = false, - } - - Crew.initialise_crew(proposal, player.position) - Crew.initialise_crowsnest() - - local memory = Memory.get_crew_memory() - local boat = Utils.deepcopy(Surfaces.Lobby.StartingBoats[memory.id]) - - for _, p in pairs(game.connected_players) do - p.teleport({ x = -30, y = boat.position.y }, game.surfaces[boat.surface_name]) - end - - Progression.set_off_from_starting_dock() - memory.boat.speed = 1 -- Small initial speed to start movement - Task.set_timeout_in_ticks(120, singleplayer_go_1, { id = memory.id }) -end) - --- Schedule auto-go for singleplayer games (equivalent to /go command) -local function schedule_singleplayer_auto_go(player) - -- Delay execution to ensure lobby boats are ready (they're created at tick 2) - Task.set_timeout_in_ticks(5, singleplayer_auto_go_delayed, { player_index = player.index }) -end - local Public = {} function Public.silo_die() @@ -1860,25 +1784,14 @@ local function event_on_player_joined_game(event) Common.ensure_chunks_at(surface, spawnpoint, 5) end - -- In singleplayer, automatically start the game on first join instead of showing the welcome message - local should_auto_go = false - if not global_memory.singleplayer_auto_go_checked then - global_memory.singleplayer_auto_go_checked = true - should_auto_go = not game.is_multiplayer() + Common.notify_player_expected(player, { "pirates.welcome_main_chat" }) + + if not _DEBUG then + GuiWelcome.show_welcome_window(player) end player.force = Common.lobby_force_name - if should_auto_go then - schedule_singleplayer_auto_go(player) - else - Common.notify_player_expected(player, { "pirates.welcome_main_chat" }) - - if not _DEBUG then - GuiWelcome.show_welcome_window(player) - end - end - -- NOTE: It was suggested to always spawn players in lobby, in hopes that they may want to create their crew increasing the popularity of scenario. Hence the following code is disabled. -- WARNING: If re-enabling autojoin, make sure it respects private/protected runs. diff --git a/maps/pirates/commands.lua b/maps/pirates/commands.lua index 0ed8325ba..70c986589 100644 --- a/maps/pirates/commands.lua +++ b/maps/pirates/commands.lua @@ -1,1146 +1,1142 @@ --- This file is part of thesixthroc's Pirate Ship softmod, licensed under GPLv3 and stored at https://github.com/ComfyFactory/ComfyFactorio and https://github.com/danielmartin0/ComfyFactorio-Pirates. - ---luacheck: ignore ---luacheck ignores because mass requires is a code templating choice... - -local Color = require("utils.color_presets") -local Server = require("utils.server") -local Math = require("maps.pirates.math") -local Ai = require("maps.pirates.ai") -local Memory = require("maps.pirates.memory") -local Common = require("maps.pirates.common") -local CoreData = require("maps.pirates.coredata") -local PlayerColors = require("maps.pirates.player_colors") -local Utils = require("maps.pirates.utils_local") -local Crew = require("maps.pirates.crew") -local Roles = require("maps.pirates.roles.roles") -local Boats = require("maps.pirates.structures.boats.boats") -local Surfaces = require("maps.pirates.surfaces.surfaces") -local Overworld = require("maps.pirates.overworld") -local Islands = require("maps.pirates.surfaces.islands.islands") -local Progression = require("maps.pirates.progression") -local Crowsnest = require("maps.pirates.surfaces.crowsnest") -local PiratesApiEvents = require("maps.pirates.api_events") -local Upgrades = require("maps.pirates.shop.boat_upgrades") -local Effects = require("maps.pirates.effects") -local Kraken = require("maps.pirates.surfaces.sea.kraken") -local _inspect = require("utils.inspect").inspect -local simplex_noise = require("utils.math.simplex_noise").d2 -local Token = require("utils.token") -local Task = require("utils.task") -local Highscore = require("maps.pirates.highscore") -local Permissions = require("maps.pirates.permissions") -local Classes = require("maps.pirates.roles.classes") -local Gui = require("maps.pirates.gui.gui") --- local Session = require 'utils.datastore.session_data' - --- *** *** -- ---*** HELPERS ***-- --- *** *** -- - -local function cmd_set_memory(cmd) - local player = game.players[cmd.player_index] - local crew_id = Common.get_id_from_force_name(player.force.name) - Memory.set_working_id(crew_id) -end - -local function check_admin(cmd) - local player = game.players[cmd.player_index] - --local trusted = Session.get_trusted_table() - local p - if player then - if player ~= nil then - p = player.print - --@temporary - if player.name == "Piratux" or player.name == "thesixthroc" then - return true - end - if not player.admin then - p({ "pirates.cmd_error_not_admin" }, { color = Color.fail }) - return false - end - else - p = log - end - end - return true -end - -local function check_captain(cmd) - local player = game.players[cmd.player_index] - local p - if player then - if player ~= nil then - p = player.print - if not Common.validate_player(player) then - return - end - if not (Permissions.player_privilege_level(player) >= Permissions.privilege_levels.CAPTAIN) then - p({ "pirates.cmd_error_not_captain" }, { color = Color.fail }) - return false - end - else - p = log - end - end - return true -end - -local function check_captain_or_admin(cmd) - local player = game.players[cmd.player_index] - local p - if player then - if player ~= nil then - p = player.print - if not Common.validate_player(player) then - return - end - if - not (player.admin or Permissions.player_privilege_level(player) >= Permissions.privilege_levels.CAPTAIN) - then - p({ "pirates.cmd_error_not_captain" }, { color = Color.fail }) - return false - end - else - p = log - end - end - return true -end - -local function check_creator_of_crew(cmd) - local player = game.players[cmd.player_index] - local p - if player then - if player ~= nil then - p = player.print - - cmd_set_memory(cmd) - - local memory = Memory.get_crew_memory() - if not Common.is_id_valid(memory.id) then - return - end - - local creator = memory.original_proposal.created_by_player - - if creator ~= player.index then - Common.notify_player_error(player, { "pirates.cmd_error_not_creator_of_crew" }) - return false - end - end - end -end - --- @UNUSED --- local function check_trusted(cmd) --- local Session = require 'utils.datastore.session_data' --- local player = game.players[cmd.player_index] --- local trusted = Session.get_trusted_table() --- local p --- if player then --- if player ~= nil then --- p = player.print --- if not (trusted[player.name] or player.admin) then --- p('[ERROR] Only admins and trusted weebs are allowed to run this command!', {color=Color.fail}) --- return false --- end --- else --- p = log --- end --- end --- return true --- end - --- *** *** -- ---*** PUBLIC COMMANDS ***-- --- *** *** -- - -commands.add_command("ok", { "pirates.cmd_explain_ok" }, function(cmd) - cmd_set_memory(cmd) - - local memory = Memory.get_crew_memory() - if not Common.is_id_valid(memory.id) then - return - end - - local player = game.players[cmd.player_index] - if not Common.validate_player(player) then - return - end - - --local memory = Memory.get_crew_memory() - Roles.player_confirm_captainhood(player) -end) - --- Disabled, better to find these out through gameplay: --- commands.add_command( --- 'classes', --- 'Prints the available classes in the game.', --- function(cmd) --- local player = game.players[cmd.player_index] --- if not Common.validate_player(player) then return end --- player.print('[color=gray]' .. Roles.get_classes_print_string() .. '[/color]') --- end) - -commands.add_command("classinfo", { "pirates.cmd_explain_classinfo" }, function(cmd) - cmd_set_memory(cmd) - local param = tostring(cmd.parameter) - local player = game.players[cmd.player_index] - if not Common.validate_player(player) then - return - end - - if param and param ~= "nil" then - local string = Roles.get_class_print_string(param, true) - if string then - Common.notify_player_expected(player, { "", { "pirates.class_definition_for" }, " ", string }) - else - Common.notify_player_error(player, { "pirates.cmd_error_invalid_class_name", param }) - end - else - Common.notify_player_expected(player, { "", "/classinfo ", { "pirates.cmd_explain_classinfo" } }) - end -end) - -commands.add_command("ccolor", { "pirates.cmd_explain_ccolor" }, function(cmd) - local param = tostring(cmd.parameter) - local player_index = cmd.player_index - if player_index then - local player = game.players[player_index] - if player and player.valid then - if cmd.parameter then - if PlayerColors.colors[param] then - local rgb = PlayerColors.colors[param] - player.color = rgb - player.chat_color = rgb - local message = { - "", - "[color=" .. rgb.r .. "," .. rgb.g .. "," .. rgb.b .. "]", - { "pirates.choose_chat_color", player.name, param }, - "[/color] (via /ccolor).", - } - -- local message = '[color=' .. rgb.r .. ',' .. rgb.g .. ',' .. rgb.b .. ']' .. player.name .. ' chose the color ' .. param .. '[/color] (via /ccolor).' - Common.notify_game(message) - else - Common.notify_player_error(player, { "pirates.cmd_error_color_not_found", param }) - end - else - local color = PlayerColors.bright_color_names[Math.random(#PlayerColors.bright_color_names)] - local rgb = PlayerColors.colors[color] - if not rgb then - return - end - player.color = rgb - player.chat_color = rgb - local message = { - "", - "[color=" .. rgb.r .. "," .. rgb.g .. "," .. rgb.b .. "]", - { "pirates.randomize_chat_color", player.name, color }, - "[/color] (via /ccolor).", - } --'randomly became' was amusing, but let's not - -- local message = '[color=' .. rgb.r .. ',' .. rgb.g .. ',' .. rgb.b .. ']' .. player.name .. '\'s color randomized to ' .. color .. '[/color] (via /ccolor).' --'randomly became' was amusing, but let's not - Common.notify_game(message) - -- disabled due to lag: - -- GUIcolor.toggle_window(player) - end - end - end -end) - -commands.add_command("fixpower", { "pirates.cmd_explain_fixpower" }, function(cmd) - cmd_set_memory(cmd) - - local memory = Memory.get_crew_memory() - if not Common.is_id_valid(memory.id) then - return - end - - Boats.force_reconnect_boat_poles() -end) - --- *** *** -- ---*** CAPTAIN COMMANDS ***-- --- *** *** -- - -commands.add_command("plank", { "pirates.cmd_explain_plank" }, function(cmd) - cmd_set_memory(cmd) - - local memory = Memory.get_crew_memory() - if not Common.is_id_valid(memory.id) then - return - end - - local player = game.players[cmd.player_index] - local param = tostring(cmd.parameter) - if check_captain_or_admin(cmd) then - if param and game.players[param] and game.players[param].index then - Crew.plank(player, game.players[param]) - else - Common.notify_player_error(player, { "pirates.cmd_error_invalid_player_name", param }) - end - end -end) - -commands.add_command("officer", { "pirates.cmd_explain_officer" }, function(cmd) - cmd_set_memory(cmd) - - local memory = Memory.get_crew_memory() - if not Common.is_id_valid(memory.id) then - return - end - - local player = game.players[cmd.player_index] - local param = tostring(cmd.parameter) - if check_captain_or_admin(cmd) then - if param and game.players[param] and game.players[param].index then - if Common.is_officer(game.players[param].index) then - Roles.unmake_officer(player, game.players[param]) - else - Roles.make_officer(player, game.players[param]) - end - else - Common.notify_player_error(player, { "pirates.cmd_error_invalid_player_name", param }) - end - end -end) - -commands.add_command("tax", { "pirates.cmd_explain_tax" }, function(cmd) - cmd_set_memory(cmd) - - local memory = Memory.get_crew_memory() - if not Common.is_id_valid(memory.id) then - return - end - - --local param = tostring(cmd.parameter) - if check_captain(cmd) then - --local player = game.players[cmd.player_index] - Roles.captain_tax(memory.playerindex_captain) - end -end) - --- Try undock from an island or dock -commands.add_command("undock", { "pirates.cmd_explain_undock" }, function(cmd) - cmd_set_memory(cmd) - - local memory = Memory.get_crew_memory() - if not Common.is_id_valid(memory.id) then - return - end - - --local param = tostring(cmd.parameter) - if check_captain_or_admin(cmd) then - local player = game.players[cmd.player_index] - if memory.boat.state == Boats.enum_state.DOCKED then - Progression.undock_from_dock(true) - elseif memory.boat.state == Boats.enum_state.LANDED then - Progression.try_retreat_from_island(player, true) - end - end -end) - -commands.add_command("clear_north_tanks", { "pirates.cmd_explain_clear_north_tanks" }, function(cmd) - cmd_set_memory(cmd) - - local memory = Memory.get_crew_memory() - if not Common.is_id_valid(memory.id) then - return - end - - if check_captain_or_admin(cmd) then - Boats.clear_fluid_from_ship_tanks(1) - end -end) - -commands.add_command("clear_south_tanks", { "pirates.cmd_explain_clear_south_tanks" }, function(cmd) - cmd_set_memory(cmd) - - local memory = Memory.get_crew_memory() - if not Common.is_id_valid(memory.id) then - return - end - - if check_captain(cmd) then - Boats.clear_fluid_from_ship_tanks(2) - end -end) - --- *** *** -- ---*** CREATOR OF CREW COMMANDS ***-- --- *** *** -- - -commands.add_command("reset_password", { "pirates.cmd_explain_set_private_run_password" }, function(cmd) - cmd_set_memory(cmd) - - local memory = Memory.get_crew_memory() - if not Common.is_id_valid(memory.id) then - return - end - - local param = tostring(cmd.parameter) - if check_creator_of_crew(cmd) then - local player = game.players[cmd.player_index] - - if not memory.private_run_password then - Common.notify_player_error(player, { "pirates.cmd_error_no_existing_password" }) - return false - end - - memory.private_run_password = param - Common.notify_player_expected(player, { "pirates.cmd_notify_set_private_run_password", memory.name, param }) - end -end) - --- *** *** -- ---*** ADMIN COMMANDS ***-- --- *** *** -- - -commands.add_command("set_max_crews", { "pirates.cmd_explain_set_max_crews" }, function(cmd) - local param = tostring(cmd.parameter) - if check_admin(cmd) then - local player = game.players[cmd.player_index] - local global_memory = Memory.get_global_memory() - - if tonumber(param) then - global_memory.active_crews_cap_in_memory = tonumber(param) - Common.notify_player_expected(player, { "pirates.cmd_notify_set_max_crews", param }) - end - end -end) - -commands.add_command("setcaptain", { "pirates.cmd_explain_setcaptain" }, function(cmd) - cmd_set_memory(cmd) - - local memory = Memory.get_crew_memory() - if not Common.is_id_valid(memory.id) then - return - end - - local param = tostring(cmd.parameter) - if check_admin(cmd) then - local player = game.players[cmd.player_index] - if param and game.players[param] and game.players[param].index then - Roles.make_captain(game.players[param]) - else - Common.notify_player_error(player, { "pirates.cmd_error_invalid_player_name", param }) - end - end -end) - -commands.add_command("summoncrew", { "pirates.cmd_explain_summoncrew" }, function(cmd) - cmd_set_memory(cmd) - - local memory = Memory.get_crew_memory() - if not Common.is_id_valid(memory.id) then - return - end - - --local param = tostring(cmd.parameter) - if check_admin(cmd) then - Crew.summon_crew() - end -end) - --- Force undock from an island or dock -commands.add_command("ret", { "pirates.cmd_explain_dev" }, function(cmd) - cmd_set_memory(cmd) - - local memory = Memory.get_crew_memory() - if not Common.is_id_valid(memory.id) then - return - end - - -- local param = tostring(cmd.parameter) - if check_admin(cmd) then - if memory.boat.state == Boats.enum_state.DOCKED then - Progression.undock_from_dock(true) - elseif memory.boat.state == Boats.enum_state.LANDED then - Progression.retreat_from_island(true) - end - end -end) - -commands.add_command("dump_highscores", { "pirates.cmd_explain_dev" }, function(cmd) - cmd_set_memory(cmd) - - if check_admin(cmd) then - local player = game.players[cmd.player_index] - if not Common.validate_player(player) then - return - end - Highscore.dump_highscores() - player.print("Highscores dumped.") - end -end) - -commands.add_command("setevo", { "pirates.cmd_explain_dev" }, function(cmd) - cmd_set_memory(cmd) - - local param = tostring(cmd.parameter) - if check_admin(cmd) then - local player = game.players[cmd.player_index] - Common.set_evo(tonumber(param)) - end -end) - -commands.add_command("modi", { "pirates.cmd_explain_dev" }, function(cmd) - cmd_set_memory(cmd) - - local param = tostring(cmd.parameter) - if check_admin(cmd) then - local player = game.players[cmd.player_index] - local memory = Memory.get_crew_memory() - local surface = game.surfaces[Common.current_destination().surface_name] - local entities = surface.find_entities_filtered({ position = player.position, radius = 500 }) - for _, e in pairs(entities) do - if e and e.valid then - -- e.force = memory.force - e.minable = true - e.destructible = true - e.rotatable = true - end - end - player.print("nearby entities made modifiable") - end -end) - -commands.add_command("night", "night", function(cmd) - if check_admin(cmd) then - local player = game.players[cmd.player_index] - local surface = player.surface - surface.daytime = 0.5 - end -end) - -commands.add_command("overwrite_scores_specific", { "pirates.cmd_explain_dev" }, function(cmd) - cmd_set_memory(cmd) - - if check_admin(cmd) then - local player = game.players[cmd.player_index] - if not Common.validate_player(player) then - return - end - local memory = Memory.get_crew_memory() - if Highscore.overwrite_scores_specific() then - player.print("Highscores overwritten.") - end - end -end) - --- Unlock a class -commands.add_command("unlock", { "pirates.cmd_explain_dev" }, function(cmd) - cmd_set_memory(cmd) - local param = tostring(cmd.parameter) - if check_admin(cmd) then - local memory = Memory.get_crew_memory() - if not Common.is_id_valid(memory.id) then - return - end - local player = game.players[cmd.player_index] - if not Classes.try_unlock_class(param, player, true) then - Common.notify_player_error(player, { "pirates.cmd_error_invalid_class_name", param }) - end - end -end) - --- Remove all classes -commands.add_command("remove_classes", { "pirates.cmd_explain_dev" }, function(cmd) - cmd_set_memory(cmd) - local param = tostring(cmd.parameter) - if check_admin(cmd) then - local memory = Memory.get_crew_memory() - if not Common.is_id_valid(memory.id) then - return - end - - if not Gui.classes then - return - end - - memory.classes_table = {} - memory.spare_classes = {} - memory.recently_purchased_classes = {} - memory.unlocked_classes = {} - memory.available_classes_pool = Classes.initial_class_pool() - memory.class_entry_count = 0 - - local players = Common.crew_get_crew_members() - - for _, player in pairs(players) do - Gui.classes.full_update(player, true) - end - end -end) - --- *** *** -- ---*** GO COMMAND LOGIC (also used by singleplayer auto-go in api_events.lua) ***-- --- *** *** -- - --- Token registrations for the /go command workflow -local go_2 = Token.register(function(data) - Memory.set_working_id(data.id) - local memory = Memory.get_crew_memory() - - memory.loading_ticks = 0 - - -- local surface = game.surfaces[Common.current_destination().surface_name] - -- surface.request_to_generate_chunks({x = 0, y = 0}, 10) - -- surface.force_generate_chunk_requests() - Progression.go_from_starting_dock_to_first_destination() -end) -local go_1 = Token.register(function(data) - Memory.set_working_id(data.id) - local memory = Memory.get_crew_memory() - Overworld.ensure_lane_generated_up_to(0, Crowsnest.Data.visibilitywidth) - Overworld.ensure_lane_generated_up_to(24, Crowsnest.Data.visibilitywidth) - Overworld.ensure_lane_generated_up_to(-24, Crowsnest.Data.visibilitywidth) - - for i = 1, #memory.destinations do - if memory.destinations[i].overworld_position.x == 0 then - memory.map_being_loaded_destination_index = i - break - end - end - - memory.currentdestination_index = memory.map_being_loaded_destination_index - Surfaces.create_surface(Common.current_destination()) - Task.set_timeout_in_ticks(60, go_2, { id = data.id }) -end) - --- Execute the /go command logic for a player. Returns true on success, false if already in a crew. -local function execute_go(player) - if Common.get_id_from_force_name(player.character.force.name) then - return false -- Already in a crew - end - - local proposal = { - capacity_option = 3, - difficulty_option = 4, - name = "SingleplayerRun", - created_by_player = player.index, - run_is_protected = false, - run_is_private = false, - } - - Crew.initialise_crew(proposal, player.position) - Crew.initialise_crowsnest() -- contains a Task - - local memory = Memory.get_crew_memory() - local boat = Utils.deepcopy(Surfaces.Lobby.StartingBoats[memory.id]) - - for _, p in pairs(game.connected_players) do - p.teleport({ x = -30, y = boat.position.y }, game.surfaces[boat.surface_name]) - end - - Progression.set_off_from_starting_dock() - Task.set_timeout_in_ticks(120, go_1, { id = memory.id }) - - return true -end - --- *** *** -- ---*** DEVELOPER COMMANDS ***-- --- *** *** -- - -if _DEBUG then - -- Move overworld boat right by a lot (you can jump over islands that way to skip them) - commands.add_command("jump", { "pirates.cmd_explain_dev" }, function(cmd) - cmd_set_memory(cmd) - - local param = tostring(cmd.parameter) - if check_admin(cmd) then - local player = game.players[cmd.player_index] - Overworld.try_overworld_move_v2({ x = 40, y = 0 }) - end - end) - - -- Move overworld boat up - commands.add_command("advu", { "pirates.cmd_explain_dev" }, function(cmd) - cmd_set_memory(cmd) - - local param = tostring(cmd.parameter) - if check_admin(cmd) then - local player = game.players[cmd.player_index] - Overworld.try_overworld_move_v2({ x = 0, y = -24 }) - end - end) - - -- Move overworld boat down - commands.add_command("advd", { "pirates.cmd_explain_dev" }, function(cmd) - cmd_set_memory(cmd) - - local param = tostring(cmd.parameter) - if check_admin(cmd) then - local player = game.players[cmd.player_index] - Overworld.try_overworld_move_v2({ x = 0, y = 24 }) - end - end) - - -- Teleport player to available boat in lobby, automatically start journey and arrive at sea faster - commands.add_command("go", { "pirates.cmd_explain_dev" }, function(cmd) - cmd_set_memory(cmd) - if check_admin(cmd) then - local player = game.players[cmd.player_index] - if not execute_go(player) then - game.print("Can't use this command when run has already launched") - end - end - end) - - commands.add_command("chnk", { "pirates.cmd_explain_dev" }, function(cmd) - cmd_set_memory(cmd) - - local param = tostring(cmd.parameter) - if check_admin(cmd) then - local player = game.players[cmd.player_index] - local memory = Memory.get_crew_memory() - - for i = 0, 13 do - for j = 0, 13 do - PiratesApiEvents.event_on_chunk_generated({ - surface = player.surface, - area = { left_top = { x = -7 * 32 + i * 32, y = -7 * 32 + j * 32 } }, - }) - end - end - game.print("chunks generated") - end - end) - - commands.add_command("spd", { "pirates.cmd_explain_dev" }, function(cmd) - cmd_set_memory(cmd) - - local param = tostring(cmd.parameter) - if check_admin(cmd) then - local player = game.players[cmd.player_index] - local memory = Memory.get_crew_memory() - memory.boat.speed = 60 - end - end) - - commands.add_command("stp", { "pirates.cmd_explain_dev" }, function(cmd) - cmd_set_memory(cmd) - - local param = tostring(cmd.parameter) - if check_admin(cmd) then - local player = game.players[cmd.player_index] - local memory = Memory.get_crew_memory() - memory.boat.speed = 0 - end - end) - - commands.add_command("rms", { "pirates.cmd_explain_dev" }, function(cmd) - local param = tostring(cmd.parameter) - if check_admin(cmd) then - local player = game.players[cmd.player_index] - local rms = 0 - local n = 100000 - local seed = Math.random(n ^ 2) - for i = 1, n do - local noise = simplex_noise(i, 7.11, seed) - rms = rms + noise ^ 2 - end - rms = rms / n - game.print(rms) - end - end) - - commands.add_command("pro", { "pirates.cmd_explain_dev" }, function(cmd) - local param = tostring(cmd.parameter) - if check_admin(cmd) then - local player = game.players[cmd.player_index] - local global_memory = Memory.get_global_memory() - - local proposal = { - capacity_option = 3, - difficulty_option = 2, - -- mode_option = 'left', - name = "TestRun", - created_by_player = cmd.player_index, - } - - global_memory.crewproposals[#global_memory.crewproposals + 1] = proposal - end - end) - - -- Leave island, or dock immediately - commands.add_command("lev", { "pirates.cmd_explain_dev" }, function(cmd) - cmd_set_memory(cmd) - local param = tostring(cmd.parameter) - if check_admin(cmd) then - local player = game.players[cmd.player_index] - local memory = Memory.get_crew_memory() - Progression.go_from_currentdestination_to_sea() - end - end) - - -- Add another hold - commands.add_command("hld", { "pirates.cmd_explain_dev" }, function(cmd) - cmd_set_memory(cmd) - local param = tostring(cmd.parameter) - if check_admin(cmd) then - local player = game.players[cmd.player_index] - local memory = Memory.get_crew_memory() - Upgrades.execute_upgade(Upgrades.enum.EXTRA_HOLD) - end - end) - - -- Upgrade power generators - commands.add_command("pwr", { "pirates.cmd_explain_dev" }, function(cmd) - cmd_set_memory(cmd) - local param = tostring(cmd.parameter) - if check_admin(cmd) then - local player = game.players[cmd.player_index] - local memory = Memory.get_crew_memory() - Upgrades.execute_upgade(Upgrades.enum.MORE_POWER) - end - end) - - commands.add_command("score", { "pirates.cmd_explain_dev" }, function(cmd) - cmd_set_memory(cmd) - - local param = tostring(cmd.parameter) - if check_admin(cmd) then - local player = game.players[cmd.player_index] - local memory = Memory.get_crew_memory() - - game.print("faking a highscore...") - Highscore.write_score(memory.secs_id, "fakers", 0, 40, CoreData.version_string, 1, 1) - end - end) - - commands.add_command("scrget", { "pirates.cmd_explain_dev" }, function(cmd) - local param = tostring(cmd.parameter) - if check_admin(cmd) then - local player = game.players[cmd.player_index] - game.print("running Highscore.load_in_scores()") - Highscore.load_in_scores() - end - end) - - commands.add_command("tim", { "pirates.cmd_explain_dev" }, function(cmd) - cmd_set_memory(cmd) - local param = tostring(cmd.parameter) - if check_admin(cmd) then - local player = game.players[cmd.player_index] - local memory = Memory.get_crew_memory() - Common.current_destination().dynamic_data.timer = 88 - game.print("time set to 88 seconds") - end - end) - - -- Add 20000 coal fuel to ship - commands.add_command("gld", { "pirates.cmd_explain_dev" }, function(cmd) - cmd_set_memory(cmd) - local param = tostring(cmd.parameter) - if check_admin(cmd) then - local player = game.players[cmd.player_index] - local memory = Memory.get_crew_memory() - memory.stored_fuel = memory.stored_fuel + 20000 - end - end) - - commands.add_command("rad", { "pirates.cmd_explain_dev" }, function(cmd) - cmd_set_memory(cmd) - local param = tostring(cmd.parameter) - if check_admin(cmd) then - local destination = Common.current_destination() - Islands.spawn_enemy_boat(Boats.enum.RAFT) - local boat = destination.dynamic_data.enemyboats[1] - Ai.spawn_boat_biters(boat, 0.89, Boats.get_scope(boat).Data.capacity, Boats.get_scope(boat).Data.width) - game.print("enemy boat spawned") - end - end) - - commands.add_command("rad2", { "pirates.cmd_explain_dev" }, function(cmd) - cmd_set_memory(cmd) - local param = tostring(cmd.parameter) - if check_admin(cmd) then - local destination = Common.current_destination() - Islands.spawn_enemy_boat(Boats.enum.RAFTLARGE) - local boat = destination.dynamic_data.enemyboats[1] - Ai.spawn_boat_biters(boat, 0.89, Boats.get_scope(boat).Data.capacity, Boats.get_scope(boat).Data.width) - game.print("large enemy boat spawned") - end - end) - - -- Spawns kraken if at sea - commands.add_command("krk", { "pirates.cmd_explain_dev" }, function(cmd) - cmd_set_memory(cmd) - local param = tostring(cmd.parameter) - if check_admin(cmd) then - local player = game.players[cmd.player_index] - local memory = Memory.get_crew_memory() - Kraken.try_spawn_kraken() - end - end) - - -- Sets game speed to 0.25 - commands.add_command("1/4", { "pirates.cmd_explain_dev" }, function(cmd) - local param = tostring(cmd.parameter) - if check_admin(cmd) then - local player = game.players[cmd.player_index] - game.speed = 0.25 - end - end) - - -- Sets game speed to 0.5 - commands.add_command("1/2", { "pirates.cmd_explain_dev" }, function(cmd) - local param = tostring(cmd.parameter) - if check_admin(cmd) then - local player = game.players[cmd.player_index] - game.speed = 0.5 - end - end) - - -- Sets game speed to 1 - commands.add_command("1", { "pirates.cmd_explain_dev" }, function(cmd) - local param = tostring(cmd.parameter) - if check_admin(cmd) then - local player = game.players[cmd.player_index] - game.speed = 1 - end - end) - - -- Sets game speed to 2 - commands.add_command("2", { "pirates.cmd_explain_dev" }, function(cmd) - local param = tostring(cmd.parameter) - if check_admin(cmd) then - local player = game.players[cmd.player_index] - game.speed = 2 - end - end) - - -- Sets game speed to 4 - commands.add_command("4", { "pirates.cmd_explain_dev" }, function(cmd) - local param = tostring(cmd.parameter) - if check_admin(cmd) then - local player = game.players[cmd.player_index] - game.speed = 4 - end - end) - - -- Sets game speed to 8 - commands.add_command("8", { "pirates.cmd_explain_dev" }, function(cmd) - local param = tostring(cmd.parameter) - if check_admin(cmd) then - local player = game.players[cmd.player_index] - game.speed = 8 - end - end) - - -- Sets game speed to 16 - commands.add_command("16", { "pirates.cmd_explain_dev" }, function(cmd) - local param = tostring(cmd.parameter) - if check_admin(cmd) then - local player = game.players[cmd.player_index] - game.speed = 16 - end - end) - - -- Sets game speed to 32 - commands.add_command("32", { "pirates.cmd_explain_dev" }, function(cmd) - local param = tostring(cmd.parameter) - if check_admin(cmd) then - local player = game.players[cmd.player_index] - game.speed = 32 - end - end) - - -- Sets game speed to 64 - commands.add_command("64", { "pirates.cmd_explain_dev" }, function(cmd) - local param = tostring(cmd.parameter) - if check_admin(cmd) then - local player = game.players[cmd.player_index] - game.speed = 64 - end - end) - - commands.add_command("ef1", { "pirates.cmd_explain_dev" }, function(cmd) - cmd_set_memory(cmd) - - local param = tostring(cmd.parameter) - if check_admin(cmd) then - local player = game.players[cmd.player_index] - local memory = Memory.get_crew_memory() - local surface = game.surfaces[Common.current_destination().surface_name] - Effects.worm_movement_effect(surface, { x = -45, y = 0 }, false, true) - end - end) - - commands.add_command("ef2", { "pirates.cmd_explain_dev" }, function(cmd) - cmd_set_memory(cmd) - - local param = tostring(cmd.parameter) - if check_admin(cmd) then - local player = game.players[cmd.player_index] - local memory = Memory.get_crew_memory() - local surface = game.surfaces[Common.current_destination().surface_name] - Effects.worm_movement_effect(surface, { x = -45, y = 0 }, false, false) - end - end) - - commands.add_command("ef3", { "pirates.cmd_explain_dev" }, function(cmd) - cmd_set_memory(cmd) - - local param = tostring(cmd.parameter) - if check_admin(cmd) then - local player = game.players[cmd.player_index] - local memory = Memory.get_crew_memory() - local surface = game.surfaces[Common.current_destination().surface_name] - Effects.worm_movement_effect(surface, { x = -45, y = 0 }, true, false) - end - end) - - commands.add_command("ef4", { "pirates.cmd_explain_dev" }, function(cmd) - cmd_set_memory(cmd) - - local param = tostring(cmd.parameter) - if check_admin(cmd) then - local player = game.players[cmd.player_index] - local memory = Memory.get_crew_memory() - local surface = game.surfaces[Common.current_destination().surface_name] - Effects.worm_emerge_effect(surface, { x = -45, y = 0 }) - end - end) - - commands.add_command("ef5", { "pirates.cmd_explain_dev" }, function(cmd) - cmd_set_memory(cmd) - - local param = tostring(cmd.parameter) - if check_admin(cmd) then - local player = game.players[cmd.player_index] - local memory = Memory.get_crew_memory() - local surface = game.surfaces[Common.current_destination().surface_name] - Effects.biters_emerge(surface, { x = -30, y = 0 }) - end - end) - - commands.add_command("emoji", { "pirates.cmd_explain_dev" }, function(cmd) - local param = tostring(cmd.parameter) - if check_admin(cmd) then - local player = game.players[cmd.player_index] - Server.to_discord_embed_raw(CoreData.comfy_emojis.despair) - end - end) - - -- Spawn friendly gun turrets with ammo to defend your ship - commands.add_command("def", { "pirates.cmd_explain_dev" }, function(cmd) - cmd_set_memory(cmd) - local param = tostring(cmd.parameter) - if check_admin(cmd) then - local player = game.players[cmd.player_index] - local memory = Memory.get_crew_memory() - if not Common.is_id_valid(memory.id) then - return - end - - local boat = memory.boat - local scope = Boats.get_scope(boat) - local surface = game.surfaces[boat.surface_name] - if not surface then - return - end - - if scope.Data.cannons then - for i = -2, 2 do - local p1 = scope.Data.cannons[1] - local p2 = { x = boat.position.x + p1.x + i * 2, y = boat.position.y + p1.y - 4 } - local e = surface.create_entity({ - name = "gun-turret", - position = p2, - force = boat.force_name, - create_build_effect_smoke = false, - }) - if e and e.valid then - e.insert({ name = "uranium-rounds-magazine", count = 200 }) - end - end - for i = -2, 2 do - local p1 = scope.Data.cannons[2] - local p2 = { x = boat.position.x + p1.x + i * 2, y = boat.position.y + p1.y + 3 } - local e = surface.create_entity({ - name = "gun-turret", - position = p2, - force = boat.force_name, - create_build_effect_smoke = false, - }) - if e and e.valid then - e.insert({ name = "uranium-rounds-magazine", count = 200 }) - end - end - end - end - end) - - -- Spawn friendly gun turrets with ammo around you - commands.add_command("atk", { "pirates.cmd_explain_dev" }, function(cmd) - cmd_set_memory(cmd) - local param = tostring(cmd.parameter) - if check_admin(cmd) then - local player = game.players[cmd.player_index] - local memory = Memory.get_crew_memory() - if not Common.is_id_valid(memory.id) then - return - end - local boat = memory.boat - - local p = player.character.position - local turret_positions = { - { x = p.x - 2, y = p.y - 2 }, - { x = p.x - 2, y = p.y + 2 }, - { x = p.x + 2, y = p.y - 2 }, - { x = p.x + 2, y = p.y + 2 }, - } - - for _, pos in pairs(turret_positions) do - local e = player.surface.create_entity({ - name = "gun-turret", - position = pos, - force = boat.force_name, - create_build_effect_smoke = false, - }) - if e and e.valid then - e.insert({ name = "uranium-rounds-magazine", count = 200 }) - end - end - end - end) - - -- Give advanced starter kit to make exploration easier - commands.add_command("kit", { "pirates.cmd_explain_dev" }, function(cmd) - if check_admin(cmd) then - local player = game.players[cmd.player_index] - - player.insert({ name = "substation", count = 50 }) - player.insert({ name = "solar-panel", count = 50 }) - player.insert({ name = "vehicle-machine-gun", count = 1 }) - player.insert({ name = "uranium-rounds-magazine", count = 200 }) - player.insert({ name = "raw-fish", count = 100 }) - player.insert({ name = "coin", count = 50000 }) - player.insert({ name = "cluster-grenade", count = 100 }) - player.insert({ name = "steel-chest", count = 50 }) - player.insert({ name = "express-loader", count = 50 }) - player.insert({ name = "burner-inserter", count = 50 }) - player.insert({ name = "accumulator", count = 50 }) - end - end) - - -- Fills the inventory - commands.add_command("fill", { "pirates.cmd_explain_dev" }, function(cmd) - if check_admin(cmd) then - local player = game.players[cmd.player_index] - - player.insert({ name = "power-armor-mk2", count = 1 }) - player.insert({ name = "iron-plate", count = 10000 }) - end - end) - - commands.add_command("buff", "buffs all damage by 10%", function(cmd) - if check_admin(cmd) then - local player = game.players[cmd.player_index] - Crew.buff_all_damage(0.1) - end - end) -end +-- This file is part of thesixthroc's Pirate Ship softmod, licensed under GPLv3 and stored at https://github.com/ComfyFactory/ComfyFactorio and https://github.com/danielmartin0/ComfyFactorio-Pirates. + +--luacheck: ignore +--luacheck ignores because mass requires is a code templating choice... + +local Color = require("utils.color_presets") +local Server = require("utils.server") +local Math = require("maps.pirates.math") +local Ai = require("maps.pirates.ai") +local Memory = require("maps.pirates.memory") +local Common = require("maps.pirates.common") +local CoreData = require("maps.pirates.coredata") +local PlayerColors = require("maps.pirates.player_colors") +local Utils = require("maps.pirates.utils_local") +local Crew = require("maps.pirates.crew") +local Roles = require("maps.pirates.roles.roles") +local Boats = require("maps.pirates.structures.boats.boats") +local Surfaces = require("maps.pirates.surfaces.surfaces") +local Overworld = require("maps.pirates.overworld") +local Islands = require("maps.pirates.surfaces.islands.islands") +local Progression = require("maps.pirates.progression") +local Crowsnest = require("maps.pirates.surfaces.crowsnest") +local PiratesApiEvents = require("maps.pirates.api_events") +local Upgrades = require("maps.pirates.shop.boat_upgrades") +local Effects = require("maps.pirates.effects") +local Kraken = require("maps.pirates.surfaces.sea.kraken") +local _inspect = require("utils.inspect").inspect +local simplex_noise = require("utils.math.simplex_noise").d2 +local Token = require("utils.token") +local Task = require("utils.task") +local Highscore = require("maps.pirates.highscore") +local Permissions = require("maps.pirates.permissions") +local Classes = require("maps.pirates.roles.classes") +local Gui = require("maps.pirates.gui.gui") +-- local Session = require 'utils.datastore.session_data' + +-- *** *** -- +--*** HELPERS ***-- +-- *** *** -- + +local function cmd_set_memory(cmd) + local player = game.players[cmd.player_index] + local crew_id = Common.get_id_from_force_name(player.force.name) + Memory.set_working_id(crew_id) +end + +local function check_admin(cmd) + local player = game.players[cmd.player_index] + --local trusted = Session.get_trusted_table() + local p + if player then + if player ~= nil then + p = player.print + --@temporary + if player.name == "Piratux" or player.name == "thesixthroc" then + return true + end + if not player.admin then + p({ "pirates.cmd_error_not_admin" }, { color = Color.fail }) + return false + end + else + p = log + end + end + return true +end + +local function check_captain(cmd) + local player = game.players[cmd.player_index] + local p + if player then + if player ~= nil then + p = player.print + if not Common.validate_player(player) then + return + end + if not (Permissions.player_privilege_level(player) >= Permissions.privilege_levels.CAPTAIN) then + p({ "pirates.cmd_error_not_captain" }, { color = Color.fail }) + return false + end + else + p = log + end + end + return true +end + +local function check_captain_or_admin(cmd) + local player = game.players[cmd.player_index] + local p + if player then + if player ~= nil then + p = player.print + if not Common.validate_player(player) then + return + end + if + not (player.admin or Permissions.player_privilege_level(player) >= Permissions.privilege_levels.CAPTAIN) + then + p({ "pirates.cmd_error_not_captain" }, { color = Color.fail }) + return false + end + else + p = log + end + end + return true +end + +local function check_creator_of_crew(cmd) + local player = game.players[cmd.player_index] + local p + if player then + if player ~= nil then + p = player.print + + cmd_set_memory(cmd) + + local memory = Memory.get_crew_memory() + if not Common.is_id_valid(memory.id) then + return + end + + local creator = memory.original_proposal.created_by_player + + if creator ~= player.index then + Common.notify_player_error(player, { "pirates.cmd_error_not_creator_of_crew" }) + return false + end + end + end +end + +-- @UNUSED +-- local function check_trusted(cmd) +-- local Session = require 'utils.datastore.session_data' +-- local player = game.players[cmd.player_index] +-- local trusted = Session.get_trusted_table() +-- local p +-- if player then +-- if player ~= nil then +-- p = player.print +-- if not (trusted[player.name] or player.admin) then +-- p('[ERROR] Only admins and trusted weebs are allowed to run this command!', {color=Color.fail}) +-- return false +-- end +-- else +-- p = log +-- end +-- end +-- return true +-- end + +-- *** *** -- +--*** PUBLIC COMMANDS ***-- +-- *** *** -- + +commands.add_command("ok", { "pirates.cmd_explain_ok" }, function(cmd) + cmd_set_memory(cmd) + + local memory = Memory.get_crew_memory() + if not Common.is_id_valid(memory.id) then + return + end + + local player = game.players[cmd.player_index] + if not Common.validate_player(player) then + return + end + + --local memory = Memory.get_crew_memory() + Roles.player_confirm_captainhood(player) +end) + +-- Disabled, better to find these out through gameplay: +-- commands.add_command( +-- 'classes', +-- 'Prints the available classes in the game.', +-- function(cmd) +-- local player = game.players[cmd.player_index] +-- if not Common.validate_player(player) then return end +-- player.print('[color=gray]' .. Roles.get_classes_print_string() .. '[/color]') +-- end) + +commands.add_command("classinfo", { "pirates.cmd_explain_classinfo" }, function(cmd) + cmd_set_memory(cmd) + local param = tostring(cmd.parameter) + local player = game.players[cmd.player_index] + if not Common.validate_player(player) then + return + end + + if param and param ~= "nil" then + local string = Roles.get_class_print_string(param, true) + if string then + Common.notify_player_expected(player, { "", { "pirates.class_definition_for" }, " ", string }) + else + Common.notify_player_error(player, { "pirates.cmd_error_invalid_class_name", param }) + end + else + Common.notify_player_expected(player, { "", "/classinfo ", { "pirates.cmd_explain_classinfo" } }) + end +end) + +commands.add_command("ccolor", { "pirates.cmd_explain_ccolor" }, function(cmd) + local param = tostring(cmd.parameter) + local player_index = cmd.player_index + if player_index then + local player = game.players[player_index] + if player and player.valid then + if cmd.parameter then + if PlayerColors.colors[param] then + local rgb = PlayerColors.colors[param] + player.color = rgb + player.chat_color = rgb + local message = { + "", + "[color=" .. rgb.r .. "," .. rgb.g .. "," .. rgb.b .. "]", + { "pirates.choose_chat_color", player.name, param }, + "[/color] (via /ccolor).", + } + -- local message = '[color=' .. rgb.r .. ',' .. rgb.g .. ',' .. rgb.b .. ']' .. player.name .. ' chose the color ' .. param .. '[/color] (via /ccolor).' + Common.notify_game(message) + else + Common.notify_player_error(player, { "pirates.cmd_error_color_not_found", param }) + end + else + local color = PlayerColors.bright_color_names[Math.random(#PlayerColors.bright_color_names)] + local rgb = PlayerColors.colors[color] + if not rgb then + return + end + player.color = rgb + player.chat_color = rgb + local message = { + "", + "[color=" .. rgb.r .. "," .. rgb.g .. "," .. rgb.b .. "]", + { "pirates.randomize_chat_color", player.name, color }, + "[/color] (via /ccolor).", + } --'randomly became' was amusing, but let's not + -- local message = '[color=' .. rgb.r .. ',' .. rgb.g .. ',' .. rgb.b .. ']' .. player.name .. '\'s color randomized to ' .. color .. '[/color] (via /ccolor).' --'randomly became' was amusing, but let's not + Common.notify_game(message) + -- disabled due to lag: + -- GUIcolor.toggle_window(player) + end + end + end +end) + +commands.add_command("fixpower", { "pirates.cmd_explain_fixpower" }, function(cmd) + cmd_set_memory(cmd) + + local memory = Memory.get_crew_memory() + if not Common.is_id_valid(memory.id) then + return + end + + Boats.force_reconnect_boat_poles() +end) + +-- *** *** -- +--*** CAPTAIN COMMANDS ***-- +-- *** *** -- + +commands.add_command("plank", { "pirates.cmd_explain_plank" }, function(cmd) + cmd_set_memory(cmd) + + local memory = Memory.get_crew_memory() + if not Common.is_id_valid(memory.id) then + return + end + + local player = game.players[cmd.player_index] + local param = tostring(cmd.parameter) + if check_captain_or_admin(cmd) then + if param and game.players[param] and game.players[param].index then + Crew.plank(player, game.players[param]) + else + Common.notify_player_error(player, { "pirates.cmd_error_invalid_player_name", param }) + end + end +end) + +commands.add_command("officer", { "pirates.cmd_explain_officer" }, function(cmd) + cmd_set_memory(cmd) + + local memory = Memory.get_crew_memory() + if not Common.is_id_valid(memory.id) then + return + end + + local player = game.players[cmd.player_index] + local param = tostring(cmd.parameter) + if check_captain_or_admin(cmd) then + if param and game.players[param] and game.players[param].index then + if Common.is_officer(game.players[param].index) then + Roles.unmake_officer(player, game.players[param]) + else + Roles.make_officer(player, game.players[param]) + end + else + Common.notify_player_error(player, { "pirates.cmd_error_invalid_player_name", param }) + end + end +end) + +commands.add_command("tax", { "pirates.cmd_explain_tax" }, function(cmd) + cmd_set_memory(cmd) + + local memory = Memory.get_crew_memory() + if not Common.is_id_valid(memory.id) then + return + end + + --local param = tostring(cmd.parameter) + if check_captain(cmd) then + --local player = game.players[cmd.player_index] + Roles.captain_tax(memory.playerindex_captain) + end +end) + +-- Try undock from an island or dock +commands.add_command("undock", { "pirates.cmd_explain_undock" }, function(cmd) + cmd_set_memory(cmd) + + local memory = Memory.get_crew_memory() + if not Common.is_id_valid(memory.id) then + return + end + + --local param = tostring(cmd.parameter) + if check_captain_or_admin(cmd) then + local player = game.players[cmd.player_index] + if memory.boat.state == Boats.enum_state.DOCKED then + Progression.undock_from_dock(true) + elseif memory.boat.state == Boats.enum_state.LANDED then + Progression.try_retreat_from_island(player, true) + end + end +end) + +commands.add_command("clear_north_tanks", { "pirates.cmd_explain_clear_north_tanks" }, function(cmd) + cmd_set_memory(cmd) + + local memory = Memory.get_crew_memory() + if not Common.is_id_valid(memory.id) then + return + end + + if check_captain_or_admin(cmd) then + Boats.clear_fluid_from_ship_tanks(1) + end +end) + +commands.add_command("clear_south_tanks", { "pirates.cmd_explain_clear_south_tanks" }, function(cmd) + cmd_set_memory(cmd) + + local memory = Memory.get_crew_memory() + if not Common.is_id_valid(memory.id) then + return + end + + if check_captain(cmd) then + Boats.clear_fluid_from_ship_tanks(2) + end +end) + +-- *** *** -- +--*** CREATOR OF CREW COMMANDS ***-- +-- *** *** -- + +commands.add_command("reset_password", { "pirates.cmd_explain_set_private_run_password" }, function(cmd) + cmd_set_memory(cmd) + + local memory = Memory.get_crew_memory() + if not Common.is_id_valid(memory.id) then + return + end + + local param = tostring(cmd.parameter) + if check_creator_of_crew(cmd) then + local player = game.players[cmd.player_index] + + if not memory.private_run_password then + Common.notify_player_error(player, { "pirates.cmd_error_no_existing_password" }) + return false + end + + memory.private_run_password = param + Common.notify_player_expected(player, { "pirates.cmd_notify_set_private_run_password", memory.name, param }) + end +end) + +-- *** *** -- +--*** ADMIN COMMANDS ***-- +-- *** *** -- + +commands.add_command("set_max_crews", { "pirates.cmd_explain_set_max_crews" }, function(cmd) + local param = tostring(cmd.parameter) + if check_admin(cmd) then + local player = game.players[cmd.player_index] + local global_memory = Memory.get_global_memory() + + if tonumber(param) then + global_memory.active_crews_cap_in_memory = tonumber(param) + Common.notify_player_expected(player, { "pirates.cmd_notify_set_max_crews", param }) + end + end +end) + +commands.add_command("setcaptain", { "pirates.cmd_explain_setcaptain" }, function(cmd) + cmd_set_memory(cmd) + + local memory = Memory.get_crew_memory() + if not Common.is_id_valid(memory.id) then + return + end + + local param = tostring(cmd.parameter) + if check_admin(cmd) then + local player = game.players[cmd.player_index] + if param and game.players[param] and game.players[param].index then + Roles.make_captain(game.players[param]) + else + Common.notify_player_error(player, { "pirates.cmd_error_invalid_player_name", param }) + end + end +end) + +commands.add_command("summoncrew", { "pirates.cmd_explain_summoncrew" }, function(cmd) + cmd_set_memory(cmd) + + local memory = Memory.get_crew_memory() + if not Common.is_id_valid(memory.id) then + return + end + + --local param = tostring(cmd.parameter) + if check_admin(cmd) then + Crew.summon_crew() + end +end) + +-- Force undock from an island or dock +commands.add_command("ret", { "pirates.cmd_explain_dev" }, function(cmd) + cmd_set_memory(cmd) + + local memory = Memory.get_crew_memory() + if not Common.is_id_valid(memory.id) then + return + end + + -- local param = tostring(cmd.parameter) + if check_admin(cmd) then + if memory.boat.state == Boats.enum_state.DOCKED then + Progression.undock_from_dock(true) + elseif memory.boat.state == Boats.enum_state.LANDED then + Progression.retreat_from_island(true) + end + end +end) + +commands.add_command("dump_highscores", { "pirates.cmd_explain_dev" }, function(cmd) + cmd_set_memory(cmd) + + if check_admin(cmd) then + local player = game.players[cmd.player_index] + if not Common.validate_player(player) then + return + end + Highscore.dump_highscores() + player.print("Highscores dumped.") + end +end) + +commands.add_command("setevo", { "pirates.cmd_explain_dev" }, function(cmd) + cmd_set_memory(cmd) + + local param = tostring(cmd.parameter) + if check_admin(cmd) then + local player = game.players[cmd.player_index] + Common.set_evo(tonumber(param)) + end +end) + +commands.add_command("modi", { "pirates.cmd_explain_dev" }, function(cmd) + cmd_set_memory(cmd) + + local param = tostring(cmd.parameter) + if check_admin(cmd) then + local player = game.players[cmd.player_index] + local memory = Memory.get_crew_memory() + local surface = game.surfaces[Common.current_destination().surface_name] + local entities = surface.find_entities_filtered({ position = player.position, radius = 500 }) + for _, e in pairs(entities) do + if e and e.valid then + -- e.force = memory.force + e.minable = true + e.destructible = true + e.rotatable = true + end + end + player.print("nearby entities made modifiable") + end +end) + +commands.add_command("night", "night", function(cmd) + if check_admin(cmd) then + local player = game.players[cmd.player_index] + local surface = player.surface + surface.daytime = 0.5 + end +end) + +commands.add_command("overwrite_scores_specific", { "pirates.cmd_explain_dev" }, function(cmd) + cmd_set_memory(cmd) + + if check_admin(cmd) then + local player = game.players[cmd.player_index] + if not Common.validate_player(player) then + return + end + local memory = Memory.get_crew_memory() + if Highscore.overwrite_scores_specific() then + player.print("Highscores overwritten.") + end + end +end) + +-- Unlock a class +commands.add_command("unlock", { "pirates.cmd_explain_dev" }, function(cmd) + cmd_set_memory(cmd) + local param = tostring(cmd.parameter) + if check_admin(cmd) then + local memory = Memory.get_crew_memory() + if not Common.is_id_valid(memory.id) then + return + end + local player = game.players[cmd.player_index] + if not Classes.try_unlock_class(param, player, true) then + Common.notify_player_error(player, { "pirates.cmd_error_invalid_class_name", param }) + end + end +end) + +-- Remove all classes +commands.add_command("remove_classes", { "pirates.cmd_explain_dev" }, function(cmd) + cmd_set_memory(cmd) + local param = tostring(cmd.parameter) + if check_admin(cmd) then + local memory = Memory.get_crew_memory() + if not Common.is_id_valid(memory.id) then + return + end + + if not Gui.classes then + return + end + + memory.classes_table = {} + memory.spare_classes = {} + memory.recently_purchased_classes = {} + memory.unlocked_classes = {} + memory.available_classes_pool = Classes.initial_class_pool() + memory.class_entry_count = 0 + + local players = Common.crew_get_crew_members() + + for _, player in pairs(players) do + Gui.classes.full_update(player, true) + end + end +end) + +-- *** *** -- +--*** DEVELOPER COMMANDS ***-- +-- *** *** -- + +if _DEBUG then + local go_2 = Token.register(function(data) + Memory.set_working_id(data.id) + local memory = Memory.get_crew_memory() + + memory.loading_ticks = 0 + + -- local surface = game.surfaces[Common.current_destination().surface_name] + -- surface.request_to_generate_chunks({x = 0, y = 0}, 10) + -- surface.force_generate_chunk_requests() + Progression.go_from_starting_dock_to_first_destination() + end) + local go_1 = Token.register(function(data) + Memory.set_working_id(data.id) + local memory = Memory.get_crew_memory() + Overworld.ensure_lane_generated_up_to(0, Crowsnest.Data.visibilitywidth) + Overworld.ensure_lane_generated_up_to(24, Crowsnest.Data.visibilitywidth) + Overworld.ensure_lane_generated_up_to(-24, Crowsnest.Data.visibilitywidth) + + for i = 1, #memory.destinations do + if memory.destinations[i].overworld_position.x == 0 then + memory.map_being_loaded_destination_index = i + break + end + end + + memory.currentdestination_index = memory.map_being_loaded_destination_index + Surfaces.create_surface(Common.current_destination()) + Task.set_timeout_in_ticks(60, go_2, { id = data.id }) + end) + + -- Move overworld boat right by a lot (you can jump over islands that way to skip them) + commands.add_command("jump", { "pirates.cmd_explain_dev" }, function(cmd) + cmd_set_memory(cmd) + + local param = tostring(cmd.parameter) + if check_admin(cmd) then + local player = game.players[cmd.player_index] + Overworld.try_overworld_move_v2({ x = 40, y = 0 }) + end + end) + + -- Move overworld boat up + commands.add_command("advu", { "pirates.cmd_explain_dev" }, function(cmd) + cmd_set_memory(cmd) + + local param = tostring(cmd.parameter) + if check_admin(cmd) then + local player = game.players[cmd.player_index] + Overworld.try_overworld_move_v2({ x = 0, y = -24 }) + end + end) + + -- Move overworld boat down + commands.add_command("advd", { "pirates.cmd_explain_dev" }, function(cmd) + cmd_set_memory(cmd) + + local param = tostring(cmd.parameter) + if check_admin(cmd) then + local player = game.players[cmd.player_index] + Overworld.try_overworld_move_v2({ x = 0, y = 24 }) + end + end) + + -- Teleport player to available boat in lobby, automatically start journey and arrive at sea faster + commands.add_command("go", { "pirates.cmd_explain_dev" }, function(cmd) + cmd_set_memory(cmd) + local param = tostring(cmd.parameter) + if check_admin(cmd) then + local player = game.players[cmd.player_index] + -- Doesn't completely prevent server from crashing when used twice at lobby, but at least saves from crashing when boat leaves lobby + if not Common.get_id_from_force_name(player.character.force.name) then + local proposal = { + capacity_option = 3, + difficulty_option = 4, + name = "AdminRun", + created_by_player = cmd.player_index, + run_is_protected = false, + run_is_private = false, + } + + Crew.initialise_crew(proposal, player.position) + Crew.initialise_crowsnest() --contains a Task + + local memory = Memory.get_crew_memory() + local boat = Utils.deepcopy(Surfaces.Lobby.StartingBoats[memory.id]) + + for _, p in pairs(game.connected_players) do + p.teleport({ x = -30, y = boat.position.y }, game.surfaces[boat.surface_name]) + end + + Progression.set_off_from_starting_dock() + + -- local memory = Memory.get_crew_memory() + -- local boat = Utils.deepcopy(Surfaces.Lobby.StartingBoats[memory.id]) + -- memory.boat = boat + -- boat.dockedposition = boat.position + -- boat.decksteeringchests = {} + -- boat.crows_nest_steering_chests = {} + + Task.set_timeout_in_ticks(120, go_1, { id = memory.id }) + else + game.print("Can't use this command when run has already launched") + end + end + end) + + commands.add_command("chnk", { "pirates.cmd_explain_dev" }, function(cmd) + cmd_set_memory(cmd) + + local param = tostring(cmd.parameter) + if check_admin(cmd) then + local player = game.players[cmd.player_index] + local memory = Memory.get_crew_memory() + + for i = 0, 13 do + for j = 0, 13 do + PiratesApiEvents.event_on_chunk_generated({ + surface = player.surface, + area = { left_top = { x = -7 * 32 + i * 32, y = -7 * 32 + j * 32 } }, + }) + end + end + game.print("chunks generated") + end + end) + + commands.add_command("spd", { "pirates.cmd_explain_dev" }, function(cmd) + cmd_set_memory(cmd) + + local param = tostring(cmd.parameter) + if check_admin(cmd) then + local player = game.players[cmd.player_index] + local memory = Memory.get_crew_memory() + memory.boat.speed = 60 + end + end) + + commands.add_command("stp", { "pirates.cmd_explain_dev" }, function(cmd) + cmd_set_memory(cmd) + + local param = tostring(cmd.parameter) + if check_admin(cmd) then + local player = game.players[cmd.player_index] + local memory = Memory.get_crew_memory() + memory.boat.speed = 0 + end + end) + + commands.add_command("rms", { "pirates.cmd_explain_dev" }, function(cmd) + local param = tostring(cmd.parameter) + if check_admin(cmd) then + local player = game.players[cmd.player_index] + local rms = 0 + local n = 100000 + local seed = Math.random(n ^ 2) + for i = 1, n do + local noise = simplex_noise(i, 7.11, seed) + rms = rms + noise ^ 2 + end + rms = rms / n + game.print(rms) + end + end) + + commands.add_command("pro", { "pirates.cmd_explain_dev" }, function(cmd) + local param = tostring(cmd.parameter) + if check_admin(cmd) then + local player = game.players[cmd.player_index] + local global_memory = Memory.get_global_memory() + + local proposal = { + capacity_option = 3, + difficulty_option = 2, + -- mode_option = 'left', + name = "TestRun", + created_by_player = cmd.player_index, + } + + global_memory.crewproposals[#global_memory.crewproposals + 1] = proposal + end + end) + + -- Leave island, or dock immediately + commands.add_command("lev", { "pirates.cmd_explain_dev" }, function(cmd) + cmd_set_memory(cmd) + local param = tostring(cmd.parameter) + if check_admin(cmd) then + local player = game.players[cmd.player_index] + local memory = Memory.get_crew_memory() + Progression.go_from_currentdestination_to_sea() + end + end) + + -- Add another hold + commands.add_command("hld", { "pirates.cmd_explain_dev" }, function(cmd) + cmd_set_memory(cmd) + local param = tostring(cmd.parameter) + if check_admin(cmd) then + local player = game.players[cmd.player_index] + local memory = Memory.get_crew_memory() + Upgrades.execute_upgade(Upgrades.enum.EXTRA_HOLD) + end + end) + + -- Upgrade power generators + commands.add_command("pwr", { "pirates.cmd_explain_dev" }, function(cmd) + cmd_set_memory(cmd) + local param = tostring(cmd.parameter) + if check_admin(cmd) then + local player = game.players[cmd.player_index] + local memory = Memory.get_crew_memory() + Upgrades.execute_upgade(Upgrades.enum.MORE_POWER) + end + end) + + commands.add_command("score", { "pirates.cmd_explain_dev" }, function(cmd) + cmd_set_memory(cmd) + + local param = tostring(cmd.parameter) + if check_admin(cmd) then + local player = game.players[cmd.player_index] + local memory = Memory.get_crew_memory() + + game.print("faking a highscore...") + Highscore.write_score(memory.secs_id, "fakers", 0, 40, CoreData.version_string, 1, 1) + end + end) + + commands.add_command("scrget", { "pirates.cmd_explain_dev" }, function(cmd) + local param = tostring(cmd.parameter) + if check_admin(cmd) then + local player = game.players[cmd.player_index] + game.print("running Highscore.load_in_scores()") + Highscore.load_in_scores() + end + end) + + commands.add_command("tim", { "pirates.cmd_explain_dev" }, function(cmd) + cmd_set_memory(cmd) + local param = tostring(cmd.parameter) + if check_admin(cmd) then + local player = game.players[cmd.player_index] + local memory = Memory.get_crew_memory() + Common.current_destination().dynamic_data.timer = 88 + game.print("time set to 88 seconds") + end + end) + + -- Add 20000 coal fuel to ship + commands.add_command("gld", { "pirates.cmd_explain_dev" }, function(cmd) + cmd_set_memory(cmd) + local param = tostring(cmd.parameter) + if check_admin(cmd) then + local player = game.players[cmd.player_index] + local memory = Memory.get_crew_memory() + memory.stored_fuel = memory.stored_fuel + 20000 + end + end) + + commands.add_command("rad", { "pirates.cmd_explain_dev" }, function(cmd) + cmd_set_memory(cmd) + local param = tostring(cmd.parameter) + if check_admin(cmd) then + local destination = Common.current_destination() + Islands.spawn_enemy_boat(Boats.enum.RAFT) + local boat = destination.dynamic_data.enemyboats[1] + Ai.spawn_boat_biters(boat, 0.89, Boats.get_scope(boat).Data.capacity, Boats.get_scope(boat).Data.width) + game.print("enemy boat spawned") + end + end) + + commands.add_command("rad2", { "pirates.cmd_explain_dev" }, function(cmd) + cmd_set_memory(cmd) + local param = tostring(cmd.parameter) + if check_admin(cmd) then + local destination = Common.current_destination() + Islands.spawn_enemy_boat(Boats.enum.RAFTLARGE) + local boat = destination.dynamic_data.enemyboats[1] + Ai.spawn_boat_biters(boat, 0.89, Boats.get_scope(boat).Data.capacity, Boats.get_scope(boat).Data.width) + game.print("large enemy boat spawned") + end + end) + + -- Spawns kraken if at sea + commands.add_command("krk", { "pirates.cmd_explain_dev" }, function(cmd) + cmd_set_memory(cmd) + local param = tostring(cmd.parameter) + if check_admin(cmd) then + local player = game.players[cmd.player_index] + local memory = Memory.get_crew_memory() + Kraken.try_spawn_kraken() + end + end) + + -- Sets game speed to 0.25 + commands.add_command("1/4", { "pirates.cmd_explain_dev" }, function(cmd) + local param = tostring(cmd.parameter) + if check_admin(cmd) then + local player = game.players[cmd.player_index] + game.speed = 0.25 + end + end) + + -- Sets game speed to 0.5 + commands.add_command("1/2", { "pirates.cmd_explain_dev" }, function(cmd) + local param = tostring(cmd.parameter) + if check_admin(cmd) then + local player = game.players[cmd.player_index] + game.speed = 0.5 + end + end) + + -- Sets game speed to 1 + commands.add_command("1", { "pirates.cmd_explain_dev" }, function(cmd) + local param = tostring(cmd.parameter) + if check_admin(cmd) then + local player = game.players[cmd.player_index] + game.speed = 1 + end + end) + + -- Sets game speed to 2 + commands.add_command("2", { "pirates.cmd_explain_dev" }, function(cmd) + local param = tostring(cmd.parameter) + if check_admin(cmd) then + local player = game.players[cmd.player_index] + game.speed = 2 + end + end) + + -- Sets game speed to 4 + commands.add_command("4", { "pirates.cmd_explain_dev" }, function(cmd) + local param = tostring(cmd.parameter) + if check_admin(cmd) then + local player = game.players[cmd.player_index] + game.speed = 4 + end + end) + + -- Sets game speed to 8 + commands.add_command("8", { "pirates.cmd_explain_dev" }, function(cmd) + local param = tostring(cmd.parameter) + if check_admin(cmd) then + local player = game.players[cmd.player_index] + game.speed = 8 + end + end) + + -- Sets game speed to 16 + commands.add_command("16", { "pirates.cmd_explain_dev" }, function(cmd) + local param = tostring(cmd.parameter) + if check_admin(cmd) then + local player = game.players[cmd.player_index] + game.speed = 16 + end + end) + + -- Sets game speed to 32 + commands.add_command("32", { "pirates.cmd_explain_dev" }, function(cmd) + local param = tostring(cmd.parameter) + if check_admin(cmd) then + local player = game.players[cmd.player_index] + game.speed = 32 + end + end) + + -- Sets game speed to 64 + commands.add_command("64", { "pirates.cmd_explain_dev" }, function(cmd) + local param = tostring(cmd.parameter) + if check_admin(cmd) then + local player = game.players[cmd.player_index] + game.speed = 64 + end + end) + + commands.add_command("ef1", { "pirates.cmd_explain_dev" }, function(cmd) + cmd_set_memory(cmd) + + local param = tostring(cmd.parameter) + if check_admin(cmd) then + local player = game.players[cmd.player_index] + local memory = Memory.get_crew_memory() + local surface = game.surfaces[Common.current_destination().surface_name] + Effects.worm_movement_effect(surface, { x = -45, y = 0 }, false, true) + end + end) + + commands.add_command("ef2", { "pirates.cmd_explain_dev" }, function(cmd) + cmd_set_memory(cmd) + + local param = tostring(cmd.parameter) + if check_admin(cmd) then + local player = game.players[cmd.player_index] + local memory = Memory.get_crew_memory() + local surface = game.surfaces[Common.current_destination().surface_name] + Effects.worm_movement_effect(surface, { x = -45, y = 0 }, false, false) + end + end) + + commands.add_command("ef3", { "pirates.cmd_explain_dev" }, function(cmd) + cmd_set_memory(cmd) + + local param = tostring(cmd.parameter) + if check_admin(cmd) then + local player = game.players[cmd.player_index] + local memory = Memory.get_crew_memory() + local surface = game.surfaces[Common.current_destination().surface_name] + Effects.worm_movement_effect(surface, { x = -45, y = 0 }, true, false) + end + end) + + commands.add_command("ef4", { "pirates.cmd_explain_dev" }, function(cmd) + cmd_set_memory(cmd) + + local param = tostring(cmd.parameter) + if check_admin(cmd) then + local player = game.players[cmd.player_index] + local memory = Memory.get_crew_memory() + local surface = game.surfaces[Common.current_destination().surface_name] + Effects.worm_emerge_effect(surface, { x = -45, y = 0 }) + end + end) + + commands.add_command("ef5", { "pirates.cmd_explain_dev" }, function(cmd) + cmd_set_memory(cmd) + + local param = tostring(cmd.parameter) + if check_admin(cmd) then + local player = game.players[cmd.player_index] + local memory = Memory.get_crew_memory() + local surface = game.surfaces[Common.current_destination().surface_name] + Effects.biters_emerge(surface, { x = -30, y = 0 }) + end + end) + + commands.add_command("emoji", { "pirates.cmd_explain_dev" }, function(cmd) + local param = tostring(cmd.parameter) + if check_admin(cmd) then + local player = game.players[cmd.player_index] + Server.to_discord_embed_raw(CoreData.comfy_emojis.despair) + end + end) + + -- Spawn friendly gun turrets with ammo to defend your ship + commands.add_command("def", { "pirates.cmd_explain_dev" }, function(cmd) + cmd_set_memory(cmd) + local param = tostring(cmd.parameter) + if check_admin(cmd) then + local player = game.players[cmd.player_index] + local memory = Memory.get_crew_memory() + if not Common.is_id_valid(memory.id) then + return + end + + local boat = memory.boat + local scope = Boats.get_scope(boat) + local surface = game.surfaces[boat.surface_name] + if not surface then + return + end + + if scope.Data.cannons then + for i = -2, 2 do + local p1 = scope.Data.cannons[1] + local p2 = { x = boat.position.x + p1.x + i * 2, y = boat.position.y + p1.y - 4 } + local e = surface.create_entity({ + name = "gun-turret", + position = p2, + force = boat.force_name, + create_build_effect_smoke = false, + }) + if e and e.valid then + e.insert({ name = "uranium-rounds-magazine", count = 200 }) + end + end + for i = -2, 2 do + local p1 = scope.Data.cannons[2] + local p2 = { x = boat.position.x + p1.x + i * 2, y = boat.position.y + p1.y + 3 } + local e = surface.create_entity({ + name = "gun-turret", + position = p2, + force = boat.force_name, + create_build_effect_smoke = false, + }) + if e and e.valid then + e.insert({ name = "uranium-rounds-magazine", count = 200 }) + end + end + end + end + end) + + -- Spawn friendly gun turrets with ammo around you + commands.add_command("atk", { "pirates.cmd_explain_dev" }, function(cmd) + cmd_set_memory(cmd) + local param = tostring(cmd.parameter) + if check_admin(cmd) then + local player = game.players[cmd.player_index] + local memory = Memory.get_crew_memory() + if not Common.is_id_valid(memory.id) then + return + end + local boat = memory.boat + + local p = player.character.position + local turret_positions = { + { x = p.x - 2, y = p.y - 2 }, + { x = p.x - 2, y = p.y + 2 }, + { x = p.x + 2, y = p.y - 2 }, + { x = p.x + 2, y = p.y + 2 }, + } + + for _, pos in pairs(turret_positions) do + local e = player.surface.create_entity({ + name = "gun-turret", + position = pos, + force = boat.force_name, + create_build_effect_smoke = false, + }) + if e and e.valid then + e.insert({ name = "uranium-rounds-magazine", count = 200 }) + end + end + end + end) + + -- Give advanced starter kit to make exploration easier + commands.add_command("kit", { "pirates.cmd_explain_dev" }, function(cmd) + if check_admin(cmd) then + local player = game.players[cmd.player_index] + + player.insert({ name = "substation", count = 50 }) + player.insert({ name = "solar-panel", count = 50 }) + player.insert({ name = "vehicle-machine-gun", count = 1 }) + player.insert({ name = "uranium-rounds-magazine", count = 200 }) + player.insert({ name = "raw-fish", count = 100 }) + player.insert({ name = "coin", count = 50000 }) + player.insert({ name = "cluster-grenade", count = 100 }) + player.insert({ name = "steel-chest", count = 50 }) + player.insert({ name = "express-loader", count = 50 }) + player.insert({ name = "burner-inserter", count = 50 }) + player.insert({ name = "accumulator", count = 50 }) + end + end) + + -- Fills the inventory + commands.add_command("fill", { "pirates.cmd_explain_dev" }, function(cmd) + if check_admin(cmd) then + local player = game.players[cmd.player_index] + + player.insert({ name = "power-armor-mk2", count = 1 }) + player.insert({ name = "iron-plate", count = 10000 }) + end + end) + + commands.add_command("buff", "buffs all damage by 10%", function(cmd) + if check_admin(cmd) then + local player = game.players[cmd.player_index] + Crew.buff_all_damage(0.1) + end + end) +end From 92bd1e33a998b8d158d5da3bc8717dd17c9b1662 Mon Sep 17 00:00:00 2001 From: danielmartin0 Date: Mon, 23 Feb 2026 15:17:04 +0000 Subject: [PATCH 6/6] hotfix to use PlayerModifiers.update_single_modifier --- maps/pirates/roles/tick_functions.lua | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/maps/pirates/roles/tick_functions.lua b/maps/pirates/roles/tick_functions.lua index 8b98ffc96..a1c26d091 100644 --- a/maps/pirates/roles/tick_functions.lua +++ b/maps/pirates/roles/tick_functions.lua @@ -11,6 +11,7 @@ local Common = require('maps.pirates.common') local CoreData = require('maps.pirates.coredata') local Math = require('maps.pirates.math') local _inspect = require('utils.inspect').inspect +local PlayerModifiers = require('utils.player_modifiers') local Public = {} @@ -314,13 +315,13 @@ function Public.update_character_properties(tick_interval) -- end if class == Classes.enum.FISHERMAN then - character.character_reach_distance_bonus = Balance.fisherman_reach_bonus + PlayerModifiers.update_single_modifier(player, 'character_reach_distance_bonus', 'pirates', Balance.fisherman_reach_bonus) elseif class == Classes.enum.MASTER_ANGLER then - character.character_reach_distance_bonus = Balance.master_angler_reach_bonus + PlayerModifiers.update_single_modifier(player, 'character_reach_distance_bonus', 'pirates', Balance.master_angler_reach_bonus) elseif class == Classes.enum.DREDGER then - character.character_reach_distance_bonus = Balance.dredger_reach_bonus + PlayerModifiers.update_single_modifier(player, 'character_reach_distance_bonus', 'pirates', Balance.dredger_reach_bonus) else - character.character_reach_distance_bonus = 0 + PlayerModifiers.update_single_modifier(player, 'character_reach_distance_bonus', 'pirates', 0) end if class == Classes.enum.SCOUT then @@ -357,7 +358,7 @@ function Public.update_character_properties(tick_interval) end end - character.character_running_speed_modifier = speed_boost - 1 + PlayerModifiers.update_single_modifier(player, 'character_running_speed_modifier', 'pirates', speed_boost - 1) -- If they're a SAMURAI or HATAMOTO, and have a weapon equipped, unequip it: if class == Classes.enum.SAMURAI or class == Classes.enum.HATAMOTO then