diff --git a/locale/en/pirates.cfg b/locale/en/pirates.cfg index a3e7c3f0..4892d225 100644 --- a/locale/en/pirates.cfg +++ b/locale/en/pirates.cfg @@ -4,7 +4,7 @@ softmod_info_header_after_version_number= === softmod_info_body_1=Ahoy, pirate. softmod_info_game_description_1=Game Description -softmod_info_game_description_2=Set sail in this multiplayer scenario. Collect resources and fuel the ship in order to survive as many leagues as possible. The ship moves with code magic. To upgrade the ship, visit a dock. Each crew has a captain, who can perform actions such as making the boat leave early.\n\nGame progression is significantly slowed down the smaller the crew.\n\n[font=default-bold]Win condition:[/font] Travel 1000 leagues.\n[font=default-bold]Lose condition:[/font] The ship runs out of fuel, or a cannon is destroyed. +softmod_info_game_description_2=Set sail in this multiplayer scenario. Collect resources and fuel the ship in order to survive as many leagues as possible. The ship moves with code magic. Coins can be spent at docks and other markets, to upgrade players, upgrade the ship, and buy rare items. Each crew has a captain, who can perform actions such as making the boat leave early.\n\nGame progression is significantly slowed down the smaller the crew.\n\n[font=default-bold]Win condition:[/font] Travel 1000 leagues.\n[font=default-bold]Lose condition:[/font] The ship runs out of fuel, or a cannon is destroyed. softmod_info_bugs_1=Known issues softmod_info_bugs_2=• Circuit connections don't survive when the ship teleports between surfaces.\n• Concurrent runs are disabled until a bug gets fixed. @@ -13,10 +13,10 @@ softmod_info_new_players_1=For New Players softmod_info_new_players_2=Mine coal and other resources and bring them to the ship to keep things going, or try asking the captain for more specific tasks. softmod_info_tips_1=Features of the game that are hard to work out alone -softmod_info_tips_2=• You can steer the boat from the crow's nest by placing 100 rail signals in one of the blue boxes.\n• Resources granted to the ship appear in the captain's cabin.\n• Charging a silo launches a rocket. This causes pollution and evo, but gives a reward of fuel and coins.\n• Charging a silo drains power from everything else on its network.\n• The quantity of ore available on an island is independent of the order in which you break rocks.\n• Passive pollution ramps up over time on each island.\n• The strength of attacks is proportional to the number of remaining nests. (Technically the time-based rate of evolution is proportional to nests too, but destroying a nest will immediately jump evolution by roughly the amount it 'would have' made had it survived.)\n• Covered markets give back any plates spent to unlock them.\n• Lab productivity increases with each league.\n• Useful commands: /class, /ccolor, /inventory, /shout +softmod_info_tips_2=• Electric networks upstairs and downstairs and separate.\n• You can steer the boat from the crow's nest by placing 100 rail signals in one of the blue boxes.\n• Resources granted to the ship appear in the captain's cabin.\n• Charging a silo launches a rocket. This causes pollution and evo, but gives a reward of fuel and coins.\n• Charging a silo drains power from everything else on its network.\n• The quantity of ore available on an island is independent of the order in which you break rocks.\n• Passive pollution ramps up over time on each island.\n• The strength of attacks is proportional to the number of remaining nests. (Technically the time-based rate of evolution is proportional to nests too, but destroying a nest will immediately jump evolution by roughly the amount it 'would have' made had it survived.)\n• Covered markets give back any plates spent to unlock them.\n• Lab productivity increases with each league.\n• Useful commands: /class, /ccolor, /inventory, /shout softmod_info_updates_1=Development -softmod_info_updates_2=Pirate Ship 1.0.4 is currently stable. Recent significant changes: Fuel mechanic replaces gold. Silo death is no longer a lose condition. Game made much easier for small crews. New island type. New system of class availabilities. Samurai class finally fixed. +softmod_info_updates_2=Pirate Ship 1.0.4 is currently stable. Recent significant changes: Fuel mechanic replaces gold. Silo death is no longer a lose condition. Game made much easier for small crews. New island type. New system of class availabilities. Samurai class fixed. softmod_info_credits_1=Credits softmod_info_credits_2=Softmod designed and written by thesixthroc. Comfy codebase and help from Gerkiz, Hanakocz and Mew @ Comfy Industries (https://getcomfy.eu). Most island structure blueprints contributed by Mattisso.\n\nContact us via Discord, at https://getcomfy.eu.\n\n"Those white gloves. I'll never forget them 'till the day I die." - Dr. John diff --git a/maps/pirates/ai.lua b/maps/pirates/ai.lua index dee4ec3e..b79c264a 100644 --- a/maps/pirates/ai.lua +++ b/maps/pirates/ai.lua @@ -389,11 +389,12 @@ function Public.try_spawner_spend_fraction_of_available_pollution_on_biters(spaw local base_pollution_cost_multiplier = 1 local destination = Common.current_destination() - if destination.dynamic_data then - local spawnerscount = Common.spawner_count(surface) + if destination.dynamic_data and destination.dynamic_data.initial_spawner_count then local initial_spawner_count = destination.dynamic_data.initial_spawner_count - if initial_spawner_count and initial_spawner_count > 0 then + + if initial_spawner_count > 0 then + local spawnerscount = Common.spawner_count(surface) if spawnerscount > 0 then -- if Common.current_destination().subtype and Common.current_destination().subtype == Islands.enum.RADIOACTIVE then -- -- destroying spawners doesn't do quite as much here: @@ -403,7 +404,11 @@ function Public.try_spawner_spend_fraction_of_available_pollution_on_biters(spaw -- end -- base_pollution_cost_multiplier = (initial_spawner_count/spawnerscount)^(1/2) -- Now directly proportional: - base_pollution_cost_multiplier = Math.max(1, initial_spawner_count/spawnerscount) -- Can't be less than 1. (The first map not being fully loaded when you get there commonly means it records too few initial spawners, which this helps fix) + base_pollution_cost_multiplier = initial_spawner_count/spawnerscount + + if memory.overworldx == 0 then + base_pollution_cost_multiplier = Math.max(1, base_pollution_cost_multiplier) + end -- The first map not being fully loaded when you get there commonly means it records too few initial spawners, which this helps fix else base_pollution_cost_multiplier = 1000000 end diff --git a/maps/pirates/balance.lua b/maps/pirates/balance.lua index f267e6df..17d7cb18 100644 --- a/maps/pirates/balance.lua +++ b/maps/pirates/balance.lua @@ -87,8 +87,10 @@ function Public.max_time_on_island() end end +Public.expected_time_fraction = 3/5 + function Public.expected_time_on_island() --always >0 - return 3/5 * Public.max_time_on_island_formula() + return Public.expected_time_fraction * Public.max_time_on_island_formula() end function Public.fuel_depletion_rate_static() @@ -189,11 +191,11 @@ function Public.evolution_per_biter_base_kill() --it's important to have evo go local initial_spawner_count = destination.dynamic_data.initial_spawner_count local time = destination.dynamic_data.timer - local expected_time = Public.expected_time_on_island() - if time > expected_time then return 0 + local time_to_jump_to = Public.expected_time_on_island() * (1/Public.expected_time_fraction)^(1/2) + if time > time_to_jump_to then return 0 else -- evo it 'would have' contributed: - return 1/initial_spawner_count * Public.expected_time_evo() * (expected_time - time)/expected_time + return 1/initial_spawner_count * Public.expected_time_evo() * (time_to_jump_to - time)/time_to_jump_to end else return 0 diff --git a/maps/pirates/commands.lua b/maps/pirates/commands.lua index 797008a4..6c1d864b 100644 --- a/maps/pirates/commands.lua +++ b/maps/pirates/commands.lua @@ -69,7 +69,7 @@ function(cmd) if string then Common.notify_player_expected(player, 'Class definition for ' .. string) else - Common.notify_player_error(player, 'Class \'' .. param .. '\' not found.') + Common.notify_error(player, 'Class \'' .. param .. '\' not found.') end else Common.notify_player_expected(player, '/class {classname} returns the definition of the named class.') @@ -93,7 +93,7 @@ function(cmd) local message = '[color=' .. rgb.r .. ',' .. rgb.g .. ',' .. rgb.b .. ']' .. player.name .. '\'s color is now ' .. param .. '[/color] (via /ccolor).' Common.notify_game(message) else - Common.notify_player_error(player, 'Color \'' .. param .. '\' not found.') + Common.notify_error(player, 'Color \'' .. param .. '\' not found.') end else local color = PlayerColors.names[Math.random(#PlayerColors.names)] diff --git a/maps/pirates/common.lua b/maps/pirates/common.lua index a87355a5..2f205d4c 100644 --- a/maps/pirates/common.lua +++ b/maps/pirates/common.lua @@ -120,9 +120,9 @@ function Public.notify_lobby(message, color_override) game.forces['player'].print('>> ' .. message, color_override) end -function Public.notify_player_error(player, message, color_override) - color_override = color_override or CoreData.colors.notify_player_error - player.print('>> ' .. message, color_override) +function Public.notify_error(target, message, color_override) + color_override = color_override or CoreData.colors.notify_error + target.print('>> ' .. message, color_override) end function Public.notify_player_expected(player, message, color_override) diff --git a/maps/pirates/coredata.lua b/maps/pirates/coredata.lua index a94ae662..f8d4985d 100644 --- a/maps/pirates/coredata.lua +++ b/maps/pirates/coredata.lua @@ -5,8 +5,8 @@ local inspect = require 'utils.inspect'.inspect local Public = {} Public.scenario_id_name = 'pirates' -Public.version_string = '1.0.4.5' -Public.version_float = 1.045 +Public.version_string = '1.0.4.51' +Public.version_float = 1.0451 Public.blueprint_library_allowed = true Public.blueprint_importing_allowed = true @@ -29,7 +29,7 @@ Public.colors = { ['iron-ore'] = {r=170, g=180, b=190}, ['copper-plate'] = {r=219, g=149, b=96}, ['copper-ore'] = {r=219, g=149, b=96}, - notify_player_error = {r=196, g=196, b=196}, + notify_error = {r=196, g=196, b=196}, notify_player_expected = {r=255, g=231, b=46}, notify_game = {r=249, g=103, b=56}, notify_lobby = {r=249, g=153, b=56}, diff --git a/maps/pirates/from_comfy/autostash.lua b/maps/pirates/from_comfy/autostash.lua index 11a2a756..d1af9d14 100644 --- a/maps/pirates/from_comfy/autostash.lua +++ b/maps/pirates/from_comfy/autostash.lua @@ -431,16 +431,16 @@ local function auto_stash(player, event) local ctrl = event.control local shift = event.shift if not player.character then - Common.notify_player_error(player, 'It seems that you are not in the realm of the living.', print_color) + Common.notify_error(player, 'It seems that you are not in the realm of the living.', print_color) return end if not player.character.valid then - Common.notify_player_error(player, 'It seems that you are not in the realm of the living.', print_color) + Common.notify_error(player, 'It seems that you are not in the realm of the living.', print_color) return end local inventory = player.get_inventory(defines.inventory.character_main) if inventory.is_empty() then - Common.notify_player_error(player, 'Inventory is empty.', print_color) + Common.notify_error(player, 'Inventory is empty.', print_color) return end @@ -460,7 +460,7 @@ local function auto_stash(player, event) end if not chests or not chests[1] then - Common.notify_player_error(player, 'No valid nearby containers found.', print_color) + Common.notify_error(player, 'No valid nearby containers found.', print_color) return end local filtered_chests = {} diff --git a/maps/pirates/gui/gui.lua b/maps/pirates/gui/gui.lua index c4a62530..af01067e 100644 --- a/maps/pirates/gui/gui.lua +++ b/maps/pirates/gui/gui.lua @@ -1067,7 +1067,7 @@ local function on_gui_click(event) if Common.query_can_pay_cost_to_leave() then Progression.try_retreat_from_island() else - Common.notify_player_error(player, 'Not enough stored resources.') + Common.notify_error(player, 'Not enough stored resources.') end end else diff --git a/maps/pirates/gui/runs.lua b/maps/pirates/gui/runs.lua index 23be8192..8b6ab86a 100644 --- a/maps/pirates/gui/runs.lua +++ b/maps/pirates/gui/runs.lua @@ -656,7 +656,7 @@ function Public.click(event) return end else - Common.notify_player_error(player, 'The number of concurrent runs on the server is currently capped at ' .. global_memory.active_crews_cap .. '.') + Common.notify_error(player, 'The number of concurrent runs on the server is currently capped at ' .. global_memory.active_crews_cap .. '.') end end end diff --git a/maps/pirates/interface.lua b/maps/pirates/interface.lua index 4770dabb..a422c57e 100644 --- a/maps/pirates/interface.lua +++ b/maps/pirates/interface.lua @@ -1404,7 +1404,7 @@ local function event_on_built_entity(event) player.insert{name = entity.name, count = 1} end entity.destroy() - Common.notify_player_error(player, 'Undergrounds can\'t be built on the boat, due to conflicts with the boat movement code.') + Common.notify_error(player, 'Undergrounds can\'t be built on the boat, due to conflicts with the boat movement code.') return end end diff --git a/maps/pirates/overworld.lua b/maps/pirates/overworld.lua index c92679a9..18c9154b 100644 --- a/maps/pirates/overworld.lua +++ b/maps/pirates/overworld.lua @@ -275,6 +275,9 @@ function Public.generate_overworld_destination(p) cost_to_leave = Utils.deepcopy(base_cost_4) local delete = normal_costitems[Math.random(#normal_costitems)] cost_to_leave[delete] = nil + if Math.random(5) <= 2 then + cost_to_leave['launch_rocket'] = true + end end -- override: if subtype == Surfaces.Island.enum.RADIOACTIVE then diff --git a/maps/pirates/progression.lua b/maps/pirates/progression.lua index a6967007..0c5a1cb5 100644 --- a/maps/pirates/progression.lua +++ b/maps/pirates/progression.lua @@ -411,7 +411,7 @@ function Public.try_retreat_from_island() -- Assumes the cost can be paid local captain = game.players[captain_index] if captain and Common.validate_player(captain) and destination.dynamic_data.timeratlandingtime and destination.dynamic_data.timer < destination.dynamic_data.timeratlandingtime + 10 then - Common.notify_player_error(captain, 'Can\'t depart in the first 10 seconds.') + Common.notify_error(captain, 'Can\'t depart in the first 10 seconds.') else local cost = destination.static_params.cost_to_leave -- if cost and (not destination.dynamic_data.rocketlaunched) then diff --git a/maps/pirates/roles/roles.lua b/maps/pirates/roles/roles.lua index 5b6902af..8acca4e6 100644 --- a/maps/pirates/roles/roles.lua +++ b/maps/pirates/roles/roles.lua @@ -136,7 +136,7 @@ function Public.update_tags(player) if not (inv and inv.valid) then return end local count = inv.get_item_count('iron-ore') if count and count < 2500 then - local rgb = CoreData.colors.notify_player_error + local rgb = CoreData.colors.notify_error Common.flying_text(player.surface, player.position, '[color=' .. rgb.r .. ',' .. rgb.g .. ',' .. rgb.b .. ']missing iron ore[/color]') end end @@ -176,7 +176,7 @@ function Public.player_confirm_captainhood(player) local captain_index = memory.playerindex_captain if not (player.index == captain_index) then - Common.notify_player_error(player, 'You\'re not the captain.') + Common.notify_error(player, 'You\'re not the captain.') else if memory.captain_acceptance_timer then memory.captain_acceptance_timer = nil @@ -216,7 +216,7 @@ function Public.renounce_captainhood(player) local memory = Memory.get_crew_memory() if #Common.crew_get_crew_members() == 1 then - Common.notify_player_error(player, 'But you\'re the only crew member...') + Common.notify_error(player, 'But you\'re the only crew member...') else local force = memory.force diff --git a/maps/pirates/shop/shop.lua b/maps/pirates/shop/shop.lua index d5e44595..75258c91 100644 --- a/maps/pirates/shop/shop.lua +++ b/maps/pirates/shop/shop.lua @@ -219,7 +219,7 @@ function Public.main_shop_try_purchase(player, purchase_name) if success then Common.notify_force_light(force,string.format('%s is buying extra time at sea...', player.name)) else - Common.notify_player_error(player, string.format('Can\'t buy more time than this.', player.name)) + Common.notify_error(player, string.format('Can\'t buy more time than this.', player.name)) -- refund: memory.stored_fuel = memory.stored_fuel + trade_data.base_cost.fuel * multiplier end @@ -304,23 +304,23 @@ function Public.main_shop_try_purchase(player, purchase_name) else -- play sound? if rate_limit_ok == false then - Common.notify_player_error(player, 'Shop rate limit exceeded.') + Common.notify_error(player, 'Shop rate limit exceeded.') end if enough_fuel == false then - Common.notify_player_error(player, 'Not enough stored fuel.') + Common.notify_error(player, 'Not enough stored fuel.') end if enough_coins == false then - Common.notify_player_error(player, 'Not enough coins.') + Common.notify_error(player, 'Not enough coins.') end if enough_iron_plates == false then - Common.notify_player_error(player, 'Not enough iron plates.') + Common.notify_error(player, 'Not enough iron plates.') end if enough_copper_plates == false then - Common.notify_player_error(player, 'Not enough copper plates.') + Common.notify_error(player, 'Not enough copper plates.') end if (purchase_name == 'new_boat_cutter' or purchase_name == 'new_boat_sloop_with_hold' or purchase_name == 'new_boat_cutter_with_hold') and (not able_to_buy_boats) then - Common.notify_player_error(player, 'Not able to purchase ships right now.') + Common.notify_error(player, 'Not able to purchase ships right now.') end end end @@ -400,7 +400,7 @@ function Public.event_on_market_item_purchased(event) if required_class then if not (memory.classes_table and memory.classes_table[player.index] and memory.classes_table[player.index] == required_class) then ok = false - Common.notify_player_error(force,string.format('You need to be a %s to buy this.', Classes.display_form[required_class])) + Common.notify_error(force,string.format('You need to be a %s to buy this.', Classes.display_form[required_class])) end end diff --git a/maps/pirates/tick_functions.lua b/maps/pirates/tick_functions.lua index d1251166..5a9d727e 100644 --- a/maps/pirates/tick_functions.lua +++ b/maps/pirates/tick_functions.lua @@ -94,7 +94,7 @@ function Public.prevent_disembark(tickinterval) for _, player in pairs(game.connected_players) do if player.surface and player.surface.valid and boat.surface_name and player.surface.name == boat.surface_name and ps[player.index] and (not Boats.on_boat(boat, player.position)) and (not (player.controller_type == defines.controllers.spectator)) then - Common.notify_player_error(player, 'Now is no time to disembark.') + Common.notify_error(player, 'Now is no time to disembark.') -- player.teleport(memory.spawnpoint) local p = player.surface.find_non_colliding_position('character', memory.spawnpoint, 5, 0.1) if p then diff --git a/maps/pirates/tick_functions_classes.lua b/maps/pirates/tick_functions_classes.lua index 47b986b6..16240add 100644 --- a/maps/pirates/tick_functions_classes.lua +++ b/maps/pirates/tick_functions_classes.lua @@ -67,10 +67,10 @@ function Public.class_renderings(tickinterval) end end - for _, r in pairs(memory.quartermaster_renderings) do - if not processed_renderings[r] then + for k, r in pairs(memory.quartermaster_renderings) do + if not processed_renderings[k] then rendering.destroy(r) - memory.quartermaster_renderings[r] = nil + memory.quartermaster_renderings[k] = nil end end end @@ -177,12 +177,13 @@ function Public.class_rewards_tick(tickinterval) --assuming tickinterval = 6 seconds for now local memory = Memory.get_crew_memory() - if memory.boat and memory.boat.state ~= Structures.Boats.enum_state.ATSEA_LOADING_MAP then --it is possible to spend extra time here, so don't give out freebies + if not (memory.boat and memory.boat.state and memory.boat.state == Structures.Boats.enum_state.ATSEA_LOADING_MAP) then --it is possible to spend extra time here, so don't give out freebies local crew = Common.crew_get_crew_members() for _, player in pairs(crew) do if Common.validate_player_and_character(player) then local player_index = player.index + if memory.classes_table and memory.classes_table[player_index] then local class = memory.classes_table[player_index] if class == Classes.enum.DECKHAND or class == Classes.enum.SHORESMAN or class == Classes.enum.BOATSWAIN then @@ -202,13 +203,13 @@ function Public.class_rewards_tick(tickinterval) end if game.tick % (tickinterval*2) == 0 then - local nearby_players = player.surface.find_entities_filtered{position = player.position, radius = Common.quartermaster_range, type = {'character'}} + local nearby_players = player.surface.find_entities_filtered{position = player.position, radius = Common.quartermaster_range, name = 'character'} for _, p2 in pairs(nearby_players) do if p2.player and p2.player.valid then local p2_index = p2.player.index if p2_index ~= player_index and memory.classes_table[p2_index] and memory.classes_table[p2_index] == Classes.enum.QUARTERMASTER then - class_ore_grant(p2, 2) + class_ore_grant(p2, 1) end end end