1
0
mirror of https://github.com/ComfyFactory/ComfyFactorio.git synced 2025-02-03 13:12:11 +02:00

v1.0.3.8.2

This commit is contained in:
danielmartin0 2022-02-27 16:42:25 +00:00
parent 57713f55aa
commit 27ba3e5dff
38 changed files with 452 additions and 268 deletions

BIN
.DS_Store vendored

Binary file not shown.

View File

@ -1,7 +1,7 @@
[pirates]
softmod_info_header_before_version_number==== Pirate Ship v
softmod_info_header_after_version_number= ===
softmod_info_body_1=Ahoy, pirate. If you're not in a crew — click 'Play'.
softmod_info_body_1=Ahoy, pirate.
softmod_info_game_description_1=Game Description
softmod_info_game_description_2=Set sail. 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.
@ -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=• Resources granted to the ship appear in the captain's cabin.\n• Charging a silo launches a rocket. This causes pollution and evo, but each launch gives a reward of fuel and coins.\n• Charging a silo drains power from everything else on its network.\n• Once a silo has launched a rocket, biters will ignore it.\n• You can steer the boat from the crow's nest by placing 100 rail signals in one of the blue boxes.\n• Lab productivity increases with each league.\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• At Abandoned Labs, biters don't care if you emit pollution. They only care how long you stay.\n• To launch a second parallel run, you need a fifth of the server's pirates to endorse it.
softmod_info_tips_2=• Resources granted to the ship appear in the captain's cabin.\n• Charging a silo launches a rocket. This causes pollution and evo, but each launch gives a reward of fuel and coins.\n• Charging a silo drains power from everything else on its network.\n• Once a silo has launched a rocket, biters will ignore it.\n• You can steer the boat from the crow's nest by placing 100 rail signals in one of the blue boxes.\n• Lab productivity increases with each league.\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• At Abandoned Labs, biters don't care if you emit pollution. They only care how long you stay.\n• To launch a second parallel run, you need a fifth of the server's pirates to endorse it.\n• Help commands: /class
softmod_info_updates_1=Development
softmod_info_updates_2=Pirate Ship 1.0.3 is currently in testing! The gameplay is reworked to center around a fuel mechanic. This should make for a clear central objective. Please play and help us tune the gameplay. \n\nRecent significant changes: Fuel mechanic replaces gold. Silo death is no longer a lose condition. Additional silos can appear to deconstrain power input. Weakened chest+furnace resistance to biters. Dock trades revamped.
softmod_info_updates_2=Pirate Ship 1.0.3 is currently in testing! The gameplay is reworked to center around a fuel mechanic. This should make for a clear central objective. Please play and help us tune the gameplay. \n\nRecent significant changes: Fuel mechanic replaces gold. Silo death is no longer a lose condition. Additional silos can appear to deconstrain power input. Weakened chest/furnace/pipe resistance to biters. Dock trades revamped.
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\n"Those white gloves. I'll never forget them 'till the day I die." - Dr. John
@ -42,4 +42,4 @@ leave_anytime_tooltip=The captain chooses when to undock the ship.\n\nThey can u
resources_needed_tooltip_1=At the next destination, these resources will be needed in order to undock early.
resources_needed_tooltip_2=The captain can undock early, but only if enough resources have been stored in the captain's cabin.
resources_needed_tooltip_3=The captain can only undock if enough resources are stored in the captain's cabin.
fuel_tooltip=__1__ stored fuel. If the ship runs out of fuel, you lose.\n\nClick to open the main store, which only the captain and their officers are authorised to use.
fuel_tooltip=__1__ stored fuel. If the ship runs out of fuel, you lose.\n\nClick to open the Captain's Store, which only the captain and their officers are authorised to use.

BIN
maps/.DS_Store vendored

Binary file not shown.

BIN
maps/pirates/.DS_Store vendored

Binary file not shown.

View File

@ -343,6 +343,8 @@ end
function Public.try_spawner_spend_fraction_of_available_pollution_on_biters(spawner, fraction_of_floating_pollution, minimum_avg_units, maximum_units, unit_pollutioncost_multiplier, enforce_type)
maximum_units = maximum_units or 256
log('ai spawning attempt params: ' .. (fraction_of_floating_pollution or '') .. ' ' .. (minimum_avg_units or '') .. ' ' .. (maximum_units or '') .. ' ' .. (unit_pollutioncost_multiplier or '') .. ' ' .. (enforce_type or ''))
local memory = Memory.get_crew_memory()
local surface = spawner.surface
@ -356,6 +358,8 @@ function Public.try_spawner_spend_fraction_of_available_pollution_on_biters(spaw
local temp_floating_pollution = memory.floating_pollution
local budget = fraction_of_floating_pollution * temp_floating_pollution
local initialpollution = memory.floating_pollution
local initialbudget = budget
local base_pollution_cost_multiplier = 1
@ -413,7 +417,7 @@ function Public.try_spawner_spend_fraction_of_available_pollution_on_biters(spaw
return biter.unit_number
end
local mixed = (Math.random(2) == 1)
local mixed = (Math.random(3) <= 2)
if mixed then
local whilesafety = 1000
@ -436,6 +440,11 @@ function Public.try_spawner_spend_fraction_of_available_pollution_on_biters(spaw
memory.floating_pollution = temp_floating_pollution
end
if units_created_count > 0 then
--@TEMP: Logging attack spending
log('Spent ' .. 100 * (initialpollution - temp_floating_pollution) / initialpollution .. '% of ' .. (initialpollution - temp_floating_pollution) .. ' pollution budget on biters, at ' .. base_pollution_cost_multiplier .. 'x price.')
end
return units_created
end

View File

@ -100,13 +100,13 @@ function Public.fuel_depletion_rate_static()
local T = Public.expected_time_on_island()
return - 1100 * (Common.overworldx()/40)^(7/10) * Public.onthefly_scaling_with_players_rule()^(1/3) * Math.sloped(Common.difficulty(), 2/3) / T --the extra player dependency accounts for the fact that even in compressed time, more players get more resources...
return - 1300 * (Common.overworldx()/40)^(7/10) * Public.onthefly_scaling_with_players_rule()^(1/3) * Math.sloped(Common.difficulty(), 3/4) / T --the extra player dependency accounts for the fact that even in compressed time, more players get more resources...
end
function Public.fuel_depletion_rate_sailing()
if (not Common.overworldx()) then return 0 end
return - 10 * (1 + 0.5 * (Common.overworldx()/40)^(6/10))
return - 10 * (1 + 0.5 * (Common.overworldx()/40)^(5/10))
end
function Public.boat_passive_pollution_per_minute(time)
@ -187,11 +187,10 @@ function Public.evolution_per_full_silo_charge()
end
function Public.bonus_damage_to_humans()
local ret = 0.15
local ret = 0.125
local diff = Common.difficulty()
if diff <= 0.7 then ret = 0.1 end
if diff >= 1.3 then ret = 0.2 end
if diff >= 2.5 then ret = 0.3 end
if diff >= 1.3 then ret = 0.15 end
return ret
end
@ -229,19 +228,19 @@ end
function Public.launch_fuel_reward()
return Math.ceil(1000 * (1 + 0.5 * Common.overworldx()/400) / Math.sloped(Common.difficulty(), 1/4))
return Math.ceil(1000 * (1 + 0.1 * (Common.overworldx()/40)^(8/10)) / Math.sloped(Common.difficulty(), 1/4))
end
function Public.quest_reward_multiplier()
return (0.4 + 0.08 * Common.overworldx()/40) * Math.sloped(Common.difficulty(), 1/3) * (Public.onthefly_scaling_with_players_rule())^(1/4)
return (0.4 + 0.08 * (Common.overworldx()/40)^(8/10)) * Math.sloped(Common.difficulty(), 1/3) * (Public.onthefly_scaling_with_players_rule())^(1/4)
end
function Public.island_richness_avg_multiplier()
return (0.75 + 0.07 * Common.overworldx()/40)
return 0.7 + 0.1 * (Common.overworldx()/40)^(7/10)
end
function Public.resource_quest_multiplier()
return (1.0 + 0.075 * (Common.overworldx()/40)^(1)) * Math.sloped(Common.difficulty(), 1/3) * (Public.onthefly_scaling_with_players_rule())^(1/4)
return (1.0 + 0.075 * (Common.overworldx()/40)^(8/10)) * Math.sloped(Common.difficulty(), 1/3) * (Public.onthefly_scaling_with_players_rule())^(1/4)
end
@ -250,7 +249,7 @@ function Public.apply_crew_buffs_per_x(force)
end
function Public.class_cost()
return 8000
return 9000
-- return Math.ceil(10000 / (Common.activecrewcount()/4)^(1/6))
end

View File

@ -36,7 +36,7 @@ local GUIcolor = require 'maps.pirates.gui.color'
commands.add_command(
'ok',
'ok',
'Used to accept captainhood.',
function(cmd)
local player = game.players[cmd.player_index]
if not Common.validate_player(player) then return end
@ -46,6 +46,36 @@ function(cmd)
Roles.try_accept_captainhood(player)
end)
-- Disabled for information-flow reasons:
-- 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(
'class',
'/class [classname] returns the definition of the named class.',
function(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)
if string then
Common.notify_player_expected(player, 'Class definition for ' .. string)
else
Common.notify_player_error(player, 'Class \'' .. param .. '\' not found.')
end
else
Common.notify_player_expected(player, '/class {classname} returns the definition of the named class.')
end
end)
commands.add_command(
'ccolor',
'ccolor is an extension to the built-in /color command, with more colors.',
@ -60,9 +90,10 @@ function(cmd)
local rgb = PlayerColors.colors[param]
player.color = rgb
player.chat_color = rgb
game.print(player.name .. '\'s color is now ' .. param .. ' (via /ccolor).', rgb)
local message = '[color=' .. rgb.r .. ',' .. rgb.g .. ',' .. rgb.b .. ']' .. player.name .. '\'s color is now ' .. param .. '[/color] (via /ccolor).'
Common.notify_game(message)
else
player.print('Color not found.')
Common.notify_player_error(player, 'Color \'' .. param .. '\' not found.')
end
else
local color = PlayerColors.names[Math.random(#PlayerColors.names)]
@ -70,7 +101,8 @@ function(cmd)
if not rgb then return end
player.color = rgb
player.chat_color = rgb
game.print(player.name .. '\'s color was randomized to ' .. color .. ' (via /ccolor).', rgb)
local message = '[color=' .. rgb.r .. ',' .. rgb.g .. ',' .. rgb.b .. ']' .. player.name .. '\'s color was randomized to ' .. color .. '[/color] (via /ccolor).'
Common.notify_game(message)
-- disabled due to lag:
-- GUIcolor.toggle_window(player)
end

View File

@ -114,8 +114,13 @@ function Public.notify_lobby(message, color_override)
game.forces['player'].print('>> ' .. message, color_override)
end
function Public.notify_player(player, message, color_override)
color_override = color_override or CoreData.colors.notify_player
function Public.notify_player_error(player, message, color_override)
color_override = color_override or CoreData.colors.notify_player_error
player.print('>> ' .. message, color_override)
end
function Public.notify_player_expected(player, message, color_override)
color_override = color_override or CoreData.colors.notify_player_expected
player.print('>> ' .. message, color_override)
end
@ -739,15 +744,15 @@ function Public.averageUnitPollutionCost(evolution)
sum_biters = sum_biters + 400 * (1 - f3)
local sum_spitters = 0
local f1 = Math.slopefromto(1 - 1/0.15*(evolution - 0.25), 0, 1)
local f2 = Math.slopefromto(1 - 1/0.3*(evolution - 0.4), 0, 1)
local f3 = Math.slopefromto(1 - 0.85/0.5*(evolution - 0.5), 0, 1)
local f4 = Math.slopefromto(1 - 0.4/0.1*(evolution - 0.9), 0, 1)
sum_spitters = sum_spitters + 4 * f1
sum_spitters = sum_spitters + 4 * (f2 - f1)
sum_spitters = sum_spitters + 12 * (f3 - f2)
sum_spitters = sum_spitters + 30 * (f4 - f3)
sum_spitters = sum_spitters + 200 * (1 - f4)
local g1 = Math.slopefromto(1 - 1/0.15*(evolution - 0.25), 0, 1)
local g2 = Math.slopefromto(1 - 1/0.3*(evolution - 0.4), 0, 1)
local g3 = Math.slopefromto(1 - 0.85/0.5*(evolution - 0.5), 0, 1)
local g4 = Math.slopefromto(1 - 0.4/0.1*(evolution - 0.9), 0, 1)
sum_spitters = sum_spitters + 4 * g1
sum_spitters = sum_spitters + 4 * (g2 - g1)
sum_spitters = sum_spitters + 12 * (g3 - g2)
sum_spitters = sum_spitters + 30 * (g4 - g3)
sum_spitters = sum_spitters + 200 * (1 - g4)
return (5 * sum_biters + sum_spitters)/6
end
@ -882,8 +887,8 @@ function Public.init_game_settings(technology_price_multiplier)
game.map_settings.enemy_expansion.enabled = true
-- faster expansion:
game.map_settings.enemy_expansion.min_expansion_cooldown = 1.2 * 3600
game.map_settings.enemy_expansion.max_expansion_cooldown = 20 * 3600
game.map_settings.enemy_expansion.min_expansion_cooldown = 4 * 3600
game.map_settings.enemy_expansion.max_expansion_cooldown = 30 * 3600
game.map_settings.enemy_expansion.settler_group_max_size = 24
game.map_settings.enemy_expansion.settler_group_min_size = 6
-- maybe should be 3.5 if possible:

View File

@ -5,8 +5,8 @@ local inspect = require 'utils.inspect'.inspect
local Public = {}
Public.scenario_id_name = 'pirates'
Public.version_string = '1.0.3.7'
Public.version_float = 1.037
Public.version_string = '1.0.3.8.2'
Public.version_float = 1.0382
Public.victory_x = 1000
@ -23,7 +23,8 @@ 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 = {r=255, g=231, b=46},
notify_player_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},
notify_force = {r=249, g=153, b=56},
@ -62,7 +63,7 @@ Public.edgemost_tile_names = {'sand-1'}
Public.tiles_that_conflict_with_resource_layer = {'water', 'deepwater', 'water-green', 'deepwater-green', 'water-shallow', 'water-mud', 'out-of-map'}
Public.tiles_that_conflict_with_resource_layer_extended = {'water', 'deepwater', 'water-green', 'deepwater-green', 'water-shallow', 'water-mud', 'out-of-map', 'red-refined-concrete', 'brown-refined-concrete'}
Public.tiles_that_conflict_with_resource_layer_extended = {'water', 'deepwater', 'water-green', 'deepwater-green', 'water-shallow', 'water-mud', 'out-of-map', 'red-refined-concrete', 'brown-refined-concrete', 'orange-refined-concrete'}
Public.noworm_tile_names = {'red-refined-concrete', 'purple-refined-concrete', 'green-refined-concrete', 'orange-refined-concrete', 'brown-refined-concrete', 'lab-dark-2', 'sand-1', 'red-desert-3'}

View File

@ -613,7 +613,8 @@ function Public.initialise_crew(accepted_proposal)
local message = '[' .. accepted_proposal.name .. '] Launched.'
Common.notify_game(message)
Server.to_discord_embed_raw(CoreData.comfy_emojis.pogkot .. message .. ' Difficulty: ' .. CoreData.difficulty_options[memory.difficulty_option].text .. ', Capacity: ' .. CoreData.capacity_options[memory.capacity_option].text3 .. '.')
-- Server.to_discord_embed_raw(CoreData.comfy_emojis.pogkot .. message .. ' Difficulty: ' .. CoreData.difficulty_options[memory.difficulty_option].text .. ', Capacity: ' .. CoreData.capacity_options[memory.capacity_option].text3 .. '.')
Server.to_discord_embed_raw(CoreData.comfy_emojis.pogkot .. message .. ' Capacity: ' .. CoreData.capacity_options[memory.capacity_option].text3 .. '.')
game.surfaces[CoreData.lobby_surface_name].play_sound{path='utility/new_objective', volume_modifier=0.75}
memory.boat = global_memory.lobby_boats[new_id]

View File

@ -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(player, 'It seems that you are not in the realm of the living.', print_color)
Common.notify_player_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(player, 'It seems that you are not in the realm of the living.', print_color)
Common.notify_player_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(player, 'Inventory is empty.', print_color)
Common.notify_player_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(player, 'No valid nearby containers found.', print_color)
Common.notify_player_error(player, 'No valid nearby containers found.', print_color)
return
end
local filtered_chests = {}

View File

@ -75,6 +75,7 @@ function Public.toggle_window(player)
flow3.style.minimal_width = 95
flow3.style.font = 'default-bold'
flow3.style.font_color = {r=0.10, g=0.10, b=0.10}
flow3.tooltip = 'Return to the lobby.'
flow3 = flow2.add({
name = 'leave_spectators',
@ -102,6 +103,7 @@ function Public.toggle_window(player)
flow3.style.minimal_width = 95
flow3.style.font = 'default-bold'
flow3.style.font_color = {r=0.10, g=0.10, b=0.10}
flow3.tooltip = 'You won\t be able to rejoin the crew for a short while after you do this.'
--*** MEMBERS AND SPECTATORS ***--
@ -122,6 +124,17 @@ function Public.toggle_window(player)
flow3.style.minimal_width = 95
flow3.style.font = 'default-bold'
flow3.style.font_color = {r=0.10, g=0.10, b=0.10}
flow3.tooltip = 'Give up this class. The class will then be available for other crewmembers to take.'
flow3 = flow2.add({
name = 'officer_resign',
type = 'button',
caption = 'Resign as Officer',
})
flow3.style.minimal_width = 95
flow3.style.font = 'default-bold'
flow3.style.font_color = {r=0.10, g=0.10, b=0.10}
flow3.tooltip = 'Give up the officer role.'
flow2 = GuiCommon.flow_add_section(flow, 'spectators', 'Spectators')
@ -178,6 +191,7 @@ function Public.toggle_window(player)
flow4.style.minimal_width = 95
flow4.style.font = 'default-bold'
flow4.style.font_color = {r=0.10, g=0.10, b=0.10}
flow4.tooltip = 'Give this class to the selected player.'
end
for _, c in ipairs(Classes.Class_List) do
@ -189,6 +203,7 @@ function Public.toggle_window(player)
flow4.style.minimal_width = 95
flow4.style.font = 'default-bold'
flow4.style.font_color = {r=0.10, g=0.10, b=0.10}
flow4.tooltip = 'Take the spare class for yourself.'
end
--*** CAPTAIN's ACTIONS ***--
@ -203,15 +218,17 @@ function Public.toggle_window(player)
flow3.style.minimal_width = 95
flow3.style.font = 'default-bold'
flow3.style.font_color = {r=0.10, g=0.10, b=0.10}
flow3.tooltip = 'End the run. You will be prompted again after clicking.'
flow3 = flow2.add({
name = 'capn_disband_are_you_sure',
type = 'button',
caption = 'Are you sure?',
caption = 'ARE YOU SURE?',
})
flow3.style.minimal_width = 95
flow3.style.font = 'default-bold'
flow3.style.font_color = {r=0.10, g=0.10, b=0.10}
flow3.tooltip = 'Click to disband the crew.'
flow3 = flow2.add({
name = 'capn_renounce',
@ -221,6 +238,7 @@ function Public.toggle_window(player)
flow3.style.minimal_width = 95
flow3.style.font = 'default-bold'
flow3.style.font_color = {r=0.10, g=0.10, b=0.10}
flow3.tooltip = 'You will no longer be captain, and the role will be passed around until a crewmember takes it.'
flow3 = flow2.add({
name = 'capn_pass',
@ -230,6 +248,7 @@ function Public.toggle_window(player)
flow3.style.minimal_width = 95
flow3.style.font = 'default-bold'
flow3.style.font_color = {r=0.10, g=0.10, b=0.10}
flow3.tooltip = 'Make the selected crewmember into the Captain.'
flow3 = flow2.add({
name = 'capn_plank',
@ -239,6 +258,7 @@ function Public.toggle_window(player)
flow3.style.minimal_width = 95
flow3.style.font = 'default-bold'
flow3.style.font_color = {r=0.10, g=0.10, b=0.10}
flow3.tooltip = 'The player will be returned to the lobby and can\'t join your crew for a while.'
flow3 = flow2.add({
name = 'line',
@ -266,6 +286,7 @@ function Public.toggle_window(player)
flow3.style.minimal_width = 95
flow3.style.font = 'default-bold'
flow3.style.font_color = {r=0.10, g=0.10, b=0.10}
flow3.tooltip = 'Make this player an Officer.'
flow3 = flow2.add({
name = 'unmake_officer',
@ -275,6 +296,7 @@ function Public.toggle_window(player)
flow3.style.minimal_width = 95
flow3.style.font = 'default-bold'
flow3.style.font_color = {r=0.10, g=0.10, b=0.10}
flow3.tooltip = 'Remove this player as an Officer.'
flow3 = flow2.add({
name = 'capn_summon_crew',
@ -284,6 +306,7 @@ function Public.toggle_window(player)
flow3.style.minimal_width = 95
flow3.style.font = 'default-bold'
flow3.style.font_color = {r=0.10, g=0.10, b=0.10}
flow3.tooltip = 'Teleport crewmembers to the ship.'
flow3 = flow2.add({
name = 'capn_take_coins',
@ -293,6 +316,7 @@ function Public.toggle_window(player)
flow3.style.minimal_width = 95
flow3.style.font = 'default-bold'
flow3.style.font_color = {r=0.10, g=0.10, b=0.10}
flow3.tooltip = 'Take coins from each crewmembers.'
flow2 = flow.add({
@ -332,6 +356,8 @@ function Public.update(player)
flow.members.body.class_renounce.visible = memory.classes_table and memory.classes_table[player.index]
flow.members.body.officer_resign.visible = memory.officers_table and memory.officers_table[player.index]
flow.spare_classes.visible = memory.spare_classes and #memory.spare_classes > 0
local other_player_selected = flow.members.body.members_listbox.selected_index ~= 0 and tonumber(flow.members.body.members_listbox.get_item(flow.members.body.members_listbox.selected_index)[2]) ~= player.index
@ -369,8 +395,9 @@ function Public.update(player)
end
flow.spare_classes.body.assign_flow.visible = any_class_button
flow.captain.visible = (memory.playerindex_captain and player.index == memory.playerindex_captain)
flow.undock_tip.visible = (memory.playerindex_captain and player.index == memory.playerindex_captain)
flow.captain.body.capn_pass.visible = other_player_selected
flow.captain.body.capn_plank.visible = flow.captain.body.capn_pass.visible
@ -558,6 +585,11 @@ function Public.click(event)
return
end
if eventname == 'officer_resign' then
Roles.resign_as_officer(player)
return
end
if eventname == 'capn_disband_crew' then
--double check:
if Roles.player_privilege_level(player) >= Roles.privilege_levels.CAPTAIN then
@ -602,7 +634,7 @@ function Public.click(event)
if eventname == 'capn_plank' then
local other_id = tonumber(flow.members.body.members_listbox.get_item(flow.members.body.members_listbox.selected_index)[2])
local message = "%s has planked %s!"
local message = "%s planked %s!"
Server.to_discord_embed_raw(CoreData.comfy_emojis.monkas .. message)
Common.notify_force(player.force, string.format(message, player.name, game.players[other_id].name))

View File

@ -403,11 +403,24 @@ local function create_gui(player)
--== SCREEN STUFF
flow1 = player.gui.screen
-- spontaneous inside view of the hold:
flow1 =
player.gui.screen.add(
{
type = 'camera',
name = 'pirates_spontaneous_camera',
position = {x=0,y=0},
}
)
flow1.visible = false
flow1.style.margin = 8
-- flow2.style.minimal_height = 64
-- flow2.style.minimal_width = 64
-- flow2.style.maximal_height = 640
-- flow2.style.maximal_width = 640
-- flow2 = flow1.add({
-- flow2 = player.gui.screen.add({
-- name = 'pirates_undock_shortcut_button',
-- type = 'sprite-button',
-- enabled = false,
@ -424,26 +437,6 @@ local function create_gui(player)
-- flow2.style.top_padding = 3
-- flow2.style.font = 'default-large-semibold'
-- flow2.style.font_color = GuiCommon.default_font_color
-- ComfyPanel.screen_to_bypass('pirates_undock_shortcut_button')
-- spontaneous inside view of the hold:
flow2 =
flow1.add(
{
type = 'camera',
name = 'pirates_spontaneous_camera',
position = {x=0,y=0},
}
)
flow2.visible = false
flow2.style.margin = 8
ComfyPanel.screen_to_bypass('pirates_spontaneous_camera')
-- flow2.style.minimal_height = 64
-- flow2.style.minimal_width = 64
-- flow2.style.maximal_height = 640
-- flow2.style.maximal_width = 640
end
@ -805,7 +798,7 @@ function Public.update_gui(player)
flow1.silo_progressbar.value = consumed/needed
local tooltip = string.format('Rocket silo charge\n\nCharge the silo to launch a rocket, gaining both gold and coins.\n\nCurrent charge: %.1f', consumed / 1000000000) .. '/' .. Math.floor(needed / 100000000)/10 .. ' GJ'
local tooltip = string.format('Rocket silo charge\n\nCharge the silo to launch a rocket, gaining both coins and fuel.\n\nCurrent charge: %.1f', consumed / 1000000000) .. '/' .. Math.floor(needed / 100000000)/10 .. ' GJ'
flow1.tooltip = tooltip
flow1.silo_label_1.tooltip = tooltip
flow1.silo_label_2.tooltip = tooltip
@ -958,6 +951,19 @@ function Public.update_gui(player)
flow1 = player.gui.screen.pirates_spontaneous_camera
if not flow1 then --comfy panel might possibly destroy this, so this puts it back
flow1 =
player.gui.screen.add(
{
type = 'camera',
name = 'pirates_spontaneous_camera',
position = {x=0,y=0},
}
)
flow1.visible = false
flow1.style.margin = 8
end
if flow1 then
flow1.visible = false
flow1.location = {x = 8, y = 48}
@ -1023,7 +1029,7 @@ local function on_gui_click(event)
if Common.query_sufficient_resources_to_leave() then
Progression.try_retreat_from_island()
else
Common.notify_player(player, 'Not enough stored resources.')
Common.notify_player_error(player, 'Not enough stored resources.')
end
end
else

View File

@ -198,7 +198,7 @@ function Public.update(player)
if flow2.selected_tab_index == 1 then
flow2.style.height = 400
elseif flow2.selected_tab_index == 2 then
flow2.style.height = 320
flow2.style.height = 420
elseif flow2.selected_tab_index == 3 then
flow2.style.height = 610
elseif flow2.selected_tab_index == 4 then

View File

@ -656,7 +656,7 @@ function Public.click(event)
return
end
else
Common.notify_player(player, 'The number of concurrent runs on the server is currently capped at ' .. global_memory.active_crews_cap .. '.')
Common.notify_player_error(player, 'The number of concurrent runs on the server is currently capped at ' .. global_memory.active_crews_cap .. '.')
end
end
end

View File

@ -27,7 +27,7 @@ function Public.toggle_window(player)
if player.gui.screen[window_name .. '_piratewindow'] then player.gui.screen[window_name .. '_piratewindow'].destroy() return end
flow = GuiCommon.new_window(player, window_name)
flow.caption = 'Main Store'
flow.caption = 'Captain\'s Store'
flow2 = flow.add({
@ -173,7 +173,7 @@ function Public.click(event)
local memory = Memory.get_crew_memory()
if eventname == 'buy_button' then
Shop.main_shop_try_purchase(event.element.parent.name)
Shop.main_shop_try_purchase(player, event.element.parent.name)
end
end

View File

@ -98,10 +98,12 @@ local function biters_chew_stuff_faster(event)
if (event.entity.force.index == 3 or event.entity.force.name == 'environment') then
event.entity.health = event.entity.health - event.final_damage_amount * 5
elseif event.entity.name == 'pipe' then
event.entity.health = event.entity.health - event.final_damage_amount * 0.5
elseif event.entity.name == 'stone-furnace' then
event.entity.health = event.entity.health - event.final_damage_amount * 0.75
event.entity.health = event.entity.health - event.final_damage_amount * 0.5
elseif event.entity.name == 'wooden-chest' or event.entity.name == 'stone-chest' or event.entity.name == 'steel-chest' then
event.entity.health = event.entity.health - event.final_damage_amount * 0.75
event.entity.health = event.entity.health - event.final_damage_amount * 0.5
end
end
@ -1183,7 +1185,7 @@ local function event_on_built_entity(event)
player.insert{name = entity.name, count = 1}
end
entity.destroy()
Common.notify_player(player, 'Undergrounds can\'t be built on the boat, due to conflicts with the boat movement code.')
Common.notify_player_error(player, 'Undergrounds can\'t be built on the boat, due to conflicts with the boat movement code.')
return
end
end
@ -1262,7 +1264,8 @@ local function event_on_player_used_capsule(event)
if memory.classes_table and memory.classes_table[player_index] then
local class = memory.classes_table[player_index]
if class == Classes.enum.SAMURAI then
player.entity.health = player.entity.health + 20
-- vanilla heal is 80HP
player.character.health = player.character.health + 160
end
end
end
@ -1282,12 +1285,12 @@ local remove_boost_movement_speed_on_respawn =
local memory = Memory.get_crew_memory()
if not (memory.id and memory.id > 0) then return end --check if crew disbanded
if memory.game_lost then return end
memory.speed_boost_characters[player.index] = false
memory.speed_boost_characters[player.index] = nil
-- their color was strobing, so reset it to their chat color:
-- their color was strobing, so now reset it to their chat color:
player.color = player.chat_color
Common.notify_player(player, 'Respawn speed bonus removed.')
Common.notify_player_expected(player, 'Respawn speed bonus removed.')
end
)
@ -1311,7 +1314,7 @@ local boost_movement_speed_on_respawn =
memory.speed_boost_characters[player.index] = true
Task.set_timeout_in_ticks(1050, remove_boost_movement_speed_on_respawn, {player = player, crew_id = crew_id})
Common.notify_player(player, 'Respawn speed bonus applied.')
Common.notify_player_expected(player, 'Respawn speed bonus applied.')
end
)

View File

@ -150,8 +150,8 @@ local function crew_tick()
TickFunctions.quest_progress_tick(5)
end
if tick % 10 == 0 then
TickFunctions.strobe_player_colors(10)
if tick % 5 == 0 then
TickFunctions.strobe_player_colors(5)
end
if tick % 10 == 0 then

File diff suppressed because one or more lines are too long

View File

@ -63,7 +63,7 @@ function Public.try_ore_spawn(surface, realp, source_name, density_bonus)
local density = (density_bonus + 17 + 4 * Math.random()) -- not too big, and not too much variation; it makes players have to stay longer
local radius_squared = (destination.static_params and destination.static_params.radius_squared_modifier or 1) * (9 + 39 * Math.slopefromto(Common.ore_abstract_to_real(choices[choice]), 800, 20000)) * (0.6 + Math.random())
local radius_squared = (destination.static_params and destination.static_params.radius_squared_modifier or 1) * (11 + 45 * Math.slopefromto(Common.ore_abstract_to_real(choices[choice]), 800, 20000)) * (0.6 + Math.random()) --tuned
if source_name == 'rock-huge' then
radius_squared = radius_squared * 1.5
@ -168,49 +168,32 @@ function Public.draw_noisy_ore_patch(surface, position, name, budget, radius_squ
end
end
--@FIXME: Hardcode positions instead, ordered by distance from origin
local spiral_layer = 0
local outwards_spiral_x = 0
local outwards_spiral_y = 0
local whilesafety = 0
while whilesafety < 10000 and spiral_layer < radius * 2 do
whilesafety = whilesafety + 1
local distance_to_center = Math.sqrt(outwards_spiral_x^2 + outwards_spiral_y^2)
for _, p in ipairs(Math.points_in_m20t20_squared_sorted_by_distance_to_origin) do
local x, y = p[1], p[2]
local distance_to_center = Math.sqrt(x^2 + y^2)
local noise
if distance_to_center > 0 then
noise = 0.99 * simplex_noise((position.x + outwards_spiral_x/distance_to_center) * 1/3, (position.y + outwards_spiral_y/distance_to_center) * 1/3, seed) * simplex_noise((position.x + outwards_spiral_x/distance_to_center) * 1/9, (position.y + outwards_spiral_y/distance_to_center) * 1/9, seed+100)
else
noise = 0.99 * simplex_noise((position.x) * 1/3, (position.y) * 1/3, seed) * simplex_noise((position.x) * 1/9, (position.y) * 1/9, seed+100)
if flat then
noise = 0.99 * simplex_noise((position.x + x) * 1/3, (position.y + y) * 1/3, seed) * simplex_noise((position.x + x) * 1/9, (position.y + y) * 1/9, seed+100)
else --put noise on the unit circle
if distance_to_center > 0 then
noise = 0.99 * simplex_noise((position.x + x/distance_to_center) * 1/3, (position.y + y/distance_to_center) * 1/3, seed) * simplex_noise((position.x + x/distance_to_center) * 1/9, (position.y + y/distance_to_center) * 1/9, seed+100)
else
noise = 0.99 * simplex_noise((position.x) * 1/3, (position.y) * 1/3, seed) * simplex_noise((position.x) * 1/9, (position.y) * 1/9, seed+100)
end
end
local radius_noisy = radius * (1 + noise)
if distance_to_center < radius_noisy then
local strength
if flat then
-- if noise > -0.5 then strength = 1 else strength = 0 end
-- its hard to make it both noncircular and flat in per-tile count
strength = 1
else
strength = (3/2) * (1 - (distance_to_center/radius_noisy)^2)
end
try_draw_at_relative_position(outwards_spiral_x, outwards_spiral_y, strength)
end
if outwards_spiral_x == 0 and outwards_spiral_y >= spiral_layer then
outwards_spiral_x = outwards_spiral_x + 1
spiral_layer = spiral_layer + 1
elseif outwards_spiral_x > 0 and outwards_spiral_y > 0 then
outwards_spiral_x = outwards_spiral_x + 1
outwards_spiral_y = outwards_spiral_y - 1
elseif outwards_spiral_x > 0 and outwards_spiral_y <= 0 then
outwards_spiral_x = outwards_spiral_x - 1
outwards_spiral_y = outwards_spiral_y - 1
elseif outwards_spiral_x <= 0 and outwards_spiral_y < 0 then
outwards_spiral_x = outwards_spiral_x - 1
outwards_spiral_y = outwards_spiral_y + 1
elseif outwards_spiral_x < 0 and outwards_spiral_y >= 0 then
outwards_spiral_x = outwards_spiral_x + 1
outwards_spiral_y = outwards_spiral_y + 1
try_draw_at_relative_position(x, y, strength)
end
if amountplaced >= budget then break end
end
return amountplaced

View File

@ -67,7 +67,7 @@ function Public.generate_overworld_destination(p)
if _DEBUG then
-- Edit these to force a type/subtype in debug:
subtype = Surfaces.Island.enum.RED_DESERT
-- subtype = Surfaces.Island.enum.RED_DESERT
-- type = Surfaces.enum.ISLAND
-- subtype = nil
end
@ -139,6 +139,8 @@ function Public.generate_overworld_destination(p)
local playercount = Common.activecrewcount()
local max_evo = 0.85
if Common.difficulty() < 1 then max_evo = 0.72 end
if Common.difficulty() > 1 then max_evo = 0.90 end
if macrop.x > 4 then
scheduled_raft_raids = {}
local times = {600, 360, 215, 210, 120, 30, 10, 5}
@ -330,26 +332,52 @@ function Public.generate_overworld_destination(p)
local y = dest.overworld_position.y
if dest.static_params.upgrade_for_sale then
local display_form = Upgrades.crowsnest_display_form[dest.static_params.upgrade_for_sale]
local price = Shop.main_shop_data_1[dest.static_params.upgrade_for_sale].base_cost.fuel
dest.dynamic_data.crowsnest_rendering_1 = rendering.draw_text{
text = display_form .. ': ' .. price,
if not dest.dynamic_data.crowsnest_renderings then
dest.dynamic_data.crowsnest_renderings = {}
end
dest.dynamic_data.crowsnest_renderings.base_text_rendering = rendering.draw_text{
text = display_form .. ':',
surface = surface,
target = {x = x + 4, y = y - 4.55},
target = {x = x, y = y - 7.05},
color = CoreData.colors.renderingtext_green,
scale = 7,
font = 'default-game',
alignment = 'right',
visible = false,
}
--@TODO add coin cost here as well
dest.dynamic_data.crowsnest_rendering_2 = rendering.draw_sprite{
sprite = 'item/coal',
surface = surface,
target = {x = x + 7, y = y - 1.75},
x_scale = 6,
y_scale = 6,
visible = false,
}
local i = 1
for price_name, price_count in pairs(Shop.main_shop_data_1[dest.static_params.upgrade_for_sale].base_cost) do
local sprite
if price_name == 'fuel' then
sprite = 'item/coal'
else
sprite = 'item/coin'
end
dest.dynamic_data.crowsnest_renderings[price_name] = {
text_rendering = rendering.draw_text{
text = Utils.bignumber_abbrevform(price_count),
surface = surface,
target = {x = x + 0.5, y = y - 1.25 - i * 3.5},
color = CoreData.colors.renderingtext_green,
scale = 5.2,
font = 'default-game',
alignment = 'left',
visible = false,
},
sprite_rendering = rendering.draw_sprite{
sprite = sprite,
surface = surface,
target = {x = x + 8.6, y = y + 1.25 - i * 3.5},
x_scale = 4.5,
y_scale = 4.5,
visible = false,
}
}
i = i + 1
end
end
end
@ -410,13 +438,13 @@ function Public.ensure_lane_generated_up_to(lane_yvalue, x)
if lane_yvalue == 0 then
Crowsnest.paint_water_between_overworld_positions(highest_x + 32 + 7 + 1, highest_x + 32 + 7 + 1 + 40)
-- a little hack that we're updating this here rather than Crowsnest, due to the dependency on Shop to avoid a loop... almost finished 1.0, so too late to need to figure out how to restructure things!
-- a little hack that we're updating this here rather than Crowsnest, due to the dependency on Shop to avoid a loop... almost finished 1.0, so too late to figure out how to restructure things for now!
for _, dest in pairs(memory.destinations) do
if dest.static_params.upgrade_for_sale then
if dest.dynamic_data.crowsnest_rendering_1 and rendering.is_valid(dest.dynamic_data.crowsnest_rendering_1) then
local display_form = Upgrades.crowsnest_display_form[dest.static_params.upgrade_for_sale]
local price = Shop.main_shop_data_1[dest.static_params.upgrade_for_sale].base_cost.fuel
rendering.set_text(dest.dynamic_data.crowsnest_rendering_1, display_form .. ': ' .. price)
for rendering_name, r in pairs(dest.dynamic_data.crowsnest_renderings) do
if type(r) == 'table' and r.text_rendering and rendering.is_valid(r.text_rendering) then
rendering.set_text(r.text_rendering, Utils.bignumber_abbrevform(Shop.main_shop_data_1[dest.static_params.upgrade_for_sale].base_cost[rendering_name]))
end
end
end
end

View File

@ -37,8 +37,10 @@ function Public.fuel_depletion_rate()
local memory = Memory.get_crew_memory()
local state = memory.boat.state
if state == Boats.enum_state.ATSEA_SAILING or state == Boats.enum_state.APPROACHING or state == Boats.enum_state.LEAVING_DOCK then
if state == Boats.enum_state.ATSEA_SAILING or state == Boats.enum_state.APPROACHING then
return Balance.fuel_depletion_rate_sailing()
elseif state == Boats.enum_state.LEAVING_DOCK then
return Balance.fuel_depletion_rate_sailing() * 2
elseif state == Boats.enum_state.RETREATING then
return Balance.fuel_depletion_rate_sailing() / 10
elseif state == Boats.enum_state.LANDED then
@ -411,7 +413,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(captain, 'Can\'t depart in the first 10 seconds.')
Common.notify_player_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

View File

@ -37,6 +37,7 @@ function Public.make_officer(captain, player)
local message = (captain.name .. ' made ' .. player.name .. ' an officer.')
Common.notify_force(force, message)
Public.update_privileges(player)
end
function Public.unmake_officer(captain, player)
@ -49,6 +50,7 @@ function Public.unmake_officer(captain, player)
local message = (captain.name .. ' unmade ' .. player.name .. ' an officer.')
Common.notify_force(force, message)
Public.update_privileges(player)
end
function Public.tag_text(player)
@ -81,6 +83,28 @@ function Public.tag_text(player)
return str
end
function Public.get_classes_print_string()
local str = 'Current class Descriptions:'
for i, class in ipairs(Classes.Class_List) do
str = str .. '\n' .. Classes.display_form[class] .. ': ' .. Classes.explanation[class] .. ''
end
return str
end
function Public.get_class_print_string(class)
for _, class2 in ipairs(Classes.Class_List) do
if Classes.display_form[class2]:lower() == class:lower() then
return Classes.display_form[class2] .. ': ' .. Classes.explanation[class2] .. ''
end
end
return nil
end
function Public.update_tags(player)
local str = Public.tag_text(player)
@ -104,7 +128,7 @@ function Public.try_accept_captainhood(player)
local captain_index = memory.playerindex_captain
if not (player.index == captain_index) then
Common.notify_player(player, 'You\'re not the captain.')
Common.notify_player_error(player, 'You\'re not the captain.')
else
if memory.captain_acceptance_timer then
memory.captain_acceptance_timer = nil
@ -116,7 +140,7 @@ function Public.try_accept_captainhood(player)
Server.to_discord_embed_raw(CoreData.comfy_emojis.derp .. '[' .. memory.name .. '] ' .. message)
end
else
Common.notify_player(player, 'You\'re not temporary, so you don\'t need to accept.')
Common.notify_player_expected(player, 'You\'re not temporary, so you don\'t need to accept.')
end
end
end
@ -143,7 +167,7 @@ function Public.renounce_captainhood(player)
local memory = Memory.get_crew_memory()
if #Common.crew_get_crew_members() == 1 then
Common.notify_player(player, 'But you\'re the only crew member...')
Common.notify_player_error(player, 'But you\'re the only crew member...')
else
local force = game.forces[memory.force_name]
@ -158,6 +182,21 @@ function Public.renounce_captainhood(player)
end
end
function Public.resign_as_officer(player)
local memory = Memory.get_crew_memory()
local force = game.forces[memory.force_name]
if memory.officers_table and memory.officers_table[player.index] then
memory.officers_table[player.index] = nil
local message = (player.name .. ' resigns as an officer.')
Common.notify_force(force, message)
Server.to_discord_embed_raw(CoreData.comfy_emojis.ree1 .. '[' .. memory.name .. '] ' .. message)
else
log('Error: player tried to resign as officer despite not being one.')
end
end
function Public.assign_class(player_index, class, self_assigned)
local memory = Memory.get_crew_memory()
@ -208,11 +247,16 @@ function Public.make_captain(player)
local global_memory = Memory.get_global_memory()
local memory = Memory.get_crew_memory()
if memory.playerindex_captain then
Public.update_privileges(game.players[memory.playerindex_captain])
end
memory.playerindex_captain = player.index
global_memory.playerindex_to_priority[player.index] = nil
memory.captain_acceptance_timer = nil
Public.reset_officers()
Public.update_privileges(player)
end
function Public.pass_captainhood(player, player_to_pass_to)
@ -322,10 +366,7 @@ end
function Public.captain_requisition_coins(captain_index)
local memory = Memory.get_crew_memory()
local print = true
if print then
Common.notify_force(game.forces[memory.force_name], 'Coins requisitioned by captain.')
end
local total = 0
local crew_members = memory.crewplayerindices
local captain = game.players[captain_index]
@ -343,10 +384,24 @@ function Public.captain_requisition_coins(captain_index)
if coin_amount and coin_amount > 0 then
inv.remove{name='coin', count=coin_amount}
captain_inv.insert{name='coin', count=coin_amount}
total = total + coin_amount
end
local cursor_stack = player.cursor_stack
if cursor_stack.valid_for_read and cursor_stack.name == 'coin' then
local cursor_stack_count = cursor_stack.count
if cursor_stack_count > 0 then
cursor_stack.count = 0
captain_inv.insert{name='coin', count = cursor_stack_count}
total = total + cursor_stack_count
end
end
end
end
end
if total > 0 then
Common.notify_force(game.forces[memory.force_name], 'The captain requisitions ' .. total .. ' coins.')
end
end

View File

@ -23,15 +23,15 @@ Public.enum = enum
Public.offers_loaders = {
{price = {{'coin', 1000}}, offer = {type = 'give-item', item = 'loader', count = 1}},
{price = {{'coin', 2000}}, offer = {type = 'give-item', item = 'fast-loader', count = 1}},
{price = {{'coin', 3000}}, offer = {type = 'give-item', item = 'express-loader', count = 1}},
{price = {{'coin', 1500}}, offer = {type = 'give-item', item = 'loader', count = 1}},
{price = {{'coin', 2500}}, offer = {type = 'give-item', item = 'fast-loader', count = 1}},
{price = {{'coin', 3500}}, offer = {type = 'give-item', item = 'express-loader', count = 1}},
}
Public.offers_default = {
{price = {{'coin', 2000}}, offer = {type = 'give-item', item = 'copper-plate', count = 150}},
{price = {{'coin', 2000}}, offer = {type = 'give-item', item = 'iron-plate', count = 150}},
{price = {{'coin', 1000}}, offer = {type = 'give-item', item = 'gun-turret', count = 1}},
{price = {{'coin', 2000}}, offer = {type = 'give-item', item = 'copper-plate', count = 200}},
{price = {{'coin', 2000}}, offer = {type = 'give-item', item = 'iron-plate', count = 200}},
{price = {{'coin', 800}}, offer = {type = 'give-item', item = 'gun-turret', count = 1}},
{price = {{'coin', 1250}}, offer = {type = 'give-item', item = 'defender-capsule', count = 1}},
}

View File

@ -39,7 +39,7 @@ Public.market_permanent_offers = {
{price = {{'coin', 4000}}, offer = {type = 'give-item', item = 'iron-ore', count = 750}},
{price = {{'coin', 4000}}, offer = {type = 'give-item', item = 'copper-ore', count = 750}},
{price = {{'coin', 4000}}, offer = {type = 'give-item', item = 'stone', count = 750}},
{price = {{'coin', 4000}}, offer = {type = 'give-item', item = 'crude-oil-barrel', count = 750}},
{price = {{'coin', 4000}}, offer = {type = 'give-item', item = 'crude-oil-barrel', count = 150}},
}
-- cheap but one-off

View File

@ -130,20 +130,22 @@ function Public.initialise_main_shop()
}
end
function Public.main_shop_try_purchase(name)
function Public.main_shop_try_purchase(player, purchase_name)
local memory = Memory.get_crew_memory()
local shop_data_1 = Public.main_shop_data_1
local shop_data_2 = Public.main_shop_data_2
local trade_data = shop_data_1[name] or shop_data_2[name]
local trade_data = shop_data_1[purchase_name] or shop_data_2[purchase_name]
if not trade_data then return end
local stored_fuel = memory.stored_fuel
local captain_index = memory.playerindex_captain
if not (stored_fuel and captain_index) then return end
local captain = game.players[captain_index]
if not Common.validate_player_and_character(captain) then return end
local captain_inv = captain.get_inventory(defines.inventory.character_main)
if not captain_inv then return end
if not stored_fuel then return end
-- local captain_index = memory.playerindex_captain
-- if not (stored_fuel and captain_index) then return end
-- local captain = game.players[captain_index]
if not Common.validate_player_and_character(player) then return end
local inv = player.get_inventory(defines.inventory.character_main)
if not inv then return end
local multiplier = Balance.main_shop_cost_multiplier()
@ -165,34 +167,33 @@ function Public.main_shop_try_purchase(name)
if k == 'fuel' then
enough_fuel = (stored_fuel >= v * multiplier)
elseif k == 'coins' then
coins_got = captain_inv.get_item_count('coin')
coins_got = inv.get_item_count('coin')
enough_coins = coins_got >= v * multiplier
elseif k == 'iron_plates' then
iron_plates_got = captain_inv.get_item_count('iron-plate')
iron_plates_got = inv.get_item_count('iron-plate')
enough_iron_plates = iron_plates_got >= v * multiplier
elseif k == 'copper_plates' then
copper_plates_got = captain_inv.get_item_count('copper-plate')
copper_plates_got = inv.get_item_count('copper-plate')
enough_copper_plates = copper_plates_got >= v * multiplier
end
end
can_buy = rate_limit_ok and enough_coins and enough_fuel and enough_iron_plates and enough_copper_plates
if name == 'new_boat_sloop_with_hold' or name == 'new_boat_cutter_with_hold' or name == 'new_boat_cutter' then can_buy = can_buy and able_to_buy_boats end
-- potential TODO: prevent the captain from buying things whilst marooned?
if purchase_name == 'new_boat_sloop_with_hold' or purchase_name == 'new_boat_cutter_with_hold' or purchase_name == 'new_boat_cutter' then can_buy = can_buy and able_to_buy_boats end
-- @TODO: prevent people from buying things whilst marooned
if can_buy then
for k, v in pairs(trade_data.base_cost) do
if k == 'fuel' then
memory.stored_fuel = memory.stored_fuel - v * multiplier
elseif k == 'coins' then
captain_inv.remove{name="coin", count=v * multiplier}
inv.remove{name="coin", count=v * multiplier}
elseif k == 'iron_plates' then
captain_inv.remove{name="iron-plate", count=v * multiplier}
inv.remove{name="iron-plate", count=v * multiplier}
elseif k == 'copper_plates' then
captain_inv.remove{name="copper-plate", count=v * multiplier}
inv.remove{name="copper-plate", count=v * multiplier}
end
end
@ -200,84 +201,84 @@ function Public.main_shop_try_purchase(name)
if not (force and force.valid) then return end
local gotamount
if name == 'uranium_ore' then
if purchase_name == 'uranium_ore' then
gotamount = trade_data.what_you_get_sprite_buttons['item/uranium-238']
Common.give(captain, {{name = 'uranium-238', count = gotamount}})
Common.notify_force_light(force,string.format('%s is buying green rocks...', captain.name))
Common.give(player, {{name = 'uranium-238', count = gotamount}})
Common.notify_force_light(force,string.format('%s is buying green rocks...', player.name))
elseif name == 'extra_time' then
elseif purchase_name == 'extra_time' then
local success = Crew.try_add_extra_time_at_sea(60 * 60)
if success then
Common.notify_force_light(force,string.format('%s is buying extra time at sea...', captain.name))
Common.notify_force_light(force,string.format('%s is buying extra time at sea...', player.name))
else
Common.notify_player(captain, string.format('Can\'t buy more time than this.', captain.name))
Common.notify_player_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
elseif name == 'rail_signal' then
elseif purchase_name == 'rail_signal' then
gotamount = trade_data.what_you_get_sprite_buttons['item/rail-signal']
Common.give(captain, {{name = 'rail-signal', count = gotamount}})
Common.notify_force_light(force,string.format('%s is buying signals...', captain.name))
Common.give(player, {{name = 'rail-signal', count = gotamount}})
Common.notify_force_light(force,string.format('%s is buying signals...', player.name))
elseif name == 'artillery_shell' then
elseif purchase_name == 'artillery_shell' then
gotamount = trade_data.what_you_get_sprite_buttons['item/artillery-shell']
Common.give(captain, {{name = 'artillery-shell', count = gotamount}})
Common.notify_force_light(force,string.format('%s is buying cannon shells...', captain.name))
Common.give(player, {{name = 'artillery-shell', count = gotamount}})
Common.notify_force_light(force,string.format('%s is buying cannon shells...', player.name))
elseif name == 'artillery_remote' then
elseif purchase_name == 'artillery_remote' then
gotamount = trade_data.what_you_get_sprite_buttons['item/artillery-targeting-remote']
Common.give(captain, {{name = 'artillery-targeting-remote', count = gotamount}})
Common.notify_force_light(force,string.format('%s is buying an artillery targeting remote...', captain.name))
Common.give(player, {{name = 'artillery-targeting-remote', count = gotamount}})
Common.notify_force_light(force,string.format('%s is buying an artillery targeting remote...', player.name))
elseif name == 'new_boat_cutter' or name == 'new_boat_cutter_with_hold' or name == 'new_boat_sloop_with_hold' then
elseif purchase_name == 'new_boat_cutter' or purchase_name == 'new_boat_cutter_with_hold' or purchase_name == 'new_boat_sloop_with_hold' then
Dock.execute_boat_purchase()
Common.notify_force_light(force,string.format('[font=heading-1]%s bought a %s.[/font]', captain.name, Boats[Common.current_destination().static_params.boat_for_sale_type].Data.display_name))
Common.notify_force_light(force,string.format('[font=heading-1]%s bought a %s.[/font]', player.name, Boats[Common.current_destination().static_params.boat_for_sale_type].Data.display_name))
elseif name == Upgrades.enum.MORE_POWER then
elseif purchase_name == Upgrades.enum.MORE_POWER then
Upgrades.execute_upgade(Upgrades.enum.MORE_POWER)
Common.notify_force_light(force,string.format('[font=heading-1]%s upgraded the ship\'s power.[/font]', captain.name))
memory.mainshop_availability_bools[name] = false
Common.notify_force_light(force,string.format('[font=heading-1]%s upgraded the ship\'s power.[/font]', player.name))
memory.mainshop_availability_bools[purchase_name] = false
elseif name == Upgrades.enum.EXTRA_HOLD then
elseif purchase_name == Upgrades.enum.EXTRA_HOLD then
Upgrades.execute_upgade(Upgrades.enum.EXTRA_HOLD)
Common.notify_force_light(force,string.format('[font=heading-1]%s upgraded the ship\'s hold.[/font]', captain.name))
memory.mainshop_availability_bools[name] = false
Common.notify_force_light(force,string.format('[font=heading-1]%s upgraded the ship\'s hold.[/font]', player.name))
memory.mainshop_availability_bools[purchase_name] = false
elseif name == Upgrades.enum.UNLOCK_MERCHANTS then
elseif purchase_name == Upgrades.enum.UNLOCK_MERCHANTS then
Upgrades.execute_upgade(Upgrades.enum.UNLOCK_MERCHANTS)
Common.notify_force_light(force,string.format('[font=heading-1]%s unlocked merchant ships.[/font]', captain.name))
memory.mainshop_availability_bools[name] = false
Common.notify_force_light(force,string.format('[font=heading-1]%s unlocked merchant ships.[/font]', player.name))
memory.mainshop_availability_bools[purchase_name] = false
elseif name == Upgrades.enum.ROCKETS_FOR_SALE then
elseif purchase_name == Upgrades.enum.ROCKETS_FOR_SALE then
Upgrades.execute_upgade(Upgrades.enum.ROCKETS_FOR_SALE)
Common.notify_force_light(force,string.format('[font=heading-1]%s unlocked the sale of rockets at covered-up markets.[/font]', captain.name))
memory.mainshop_availability_bools[name] = false
Common.notify_force_light(force,string.format('[font=heading-1]%s unlocked the sale of rockets at covered-up markets.[/font]', player.name))
memory.mainshop_availability_bools[purchase_name] = false
elseif name == 'sell_iron' then
elseif purchase_name == 'sell_iron' then
gotamount = trade_data.what_you_get_sprite_buttons['item/coal']
Common.give(captain, {{name = 'fuel', count = gotamount}})
Common.notify_force_light(force,string.format('%s is selling iron...', captain.name))
Common.give(player, {{name = 'fuel', count = gotamount}})
Common.notify_force_light(force,string.format('%s is selling iron...', player.name))
elseif name == 'buy_iron' then
elseif purchase_name == 'buy_iron' then
gotamount = trade_data.what_you_get_sprite_buttons['item/iron-plate']
Common.give_reward_items{{name = 'iron-plate', count = gotamount}}
Common.notify_force_light(force,string.format('%s is buying iron...', captain.name))
Common.notify_force_light(force,string.format('%s is buying iron...', player.name))
elseif name == 'buy_copper' then
elseif purchase_name == 'buy_copper' then
gotamount = trade_data.what_you_get_sprite_buttons['item/copper-plate']
Common.give_reward_items{{name = 'copper-plate', count = gotamount}}
Common.notify_force_light(force,string.format('%s is buying copper...', captain.name))
Common.notify_force_light(force,string.format('%s is buying copper...', player.name))
-- elseif name == 'buy_fast_loader' then
-- gotamount = trade_data.what_you_get_sprite_buttons['item/fast-loader']
-- Common.give(captain, {{name = 'fast-loader', count = gotamount}})
-- Common.notify_force_light(force,string.format('%s bought a fast loader...', captain.name))
-- Common.give(player, {{name = 'fast-loader', count = gotamount}})
-- Common.notify_force_light(force,string.format('%s bought a fast loader...', player.name))
elseif name == 'sell_copper' then
elseif purchase_name == 'sell_copper' then
gotamount = trade_data.what_you_get_sprite_buttons['item/coal']
Common.give(captain, {{name = 'fuel', count = gotamount}})
Common.notify_force_light(force,string.format('%s is selling copper...', captain.name))
Common.give(player, {{name = 'fuel', count = gotamount}})
Common.notify_force_light(force,string.format('%s is selling copper...', player.name))
end
@ -286,23 +287,23 @@ function Public.main_shop_try_purchase(name)
else
-- play sound?
if rate_limit_ok == false then
Common.notify_player(captain, 'Shop rate limit exceeded.')
Common.notify_player_error(player, 'Shop rate limit exceeded.')
end
if enough_fuel == false then
Common.notify_player(captain, 'Not enough stored fuel.')
Common.notify_player_error(player, 'Not enough stored fuel.')
end
if enough_coins == false then
Common.notify_player(captain, 'Not enough coins.')
Common.notify_player_error(player, 'Not enough coins.')
end
if enough_iron_plates == false then
Common.notify_player(captain, 'Not enough iron plates.')
Common.notify_player_error(player, 'Not enough iron plates.')
end
if enough_copper_plates == false then
Common.notify_player(captain, 'Not enough copper plates.')
Common.notify_player_error(player, 'Not enough copper plates.')
end
if (name == 'new_boat_cutter' or name == 'new_boat_sloop_with_hold' or name == 'new_boat_cutter_with_hold') and (not able_to_buy_boats) then
Common.notify_player(captain, 'Not able to purchase ships right now.')
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.')
end
end
end
@ -390,13 +391,14 @@ function Public.event_on_market_item_purchased(event)
else
-- print:
if (price and price[1]) then
-- if (price and price[1] and price[1].name and ((price[1].name ~= 'coin' and price[1].name ~= 'pistol') or price[2])) then
if price[2] then
local fish = price[2].name
if fish == 'raw-fish' then fish = 'fish' end
Common.notify_force_light(player.force, player.name .. ' is trading away ' .. price[1].amount .. ' ' .. price[1].name .. ' and ' .. fish .. ' for ' .. this_offer.offer.count .. ' ' .. this_offer.offer.item .. '...')
else
Common.notify_force_light(player.force, player.name .. ' is trading away ' .. price[1].amount .. ' ' .. price[1].name .. ' for ' .. this_offer.offer.count .. ' ' .. this_offer.offer.item .. '...')
if not (price[1].name and price[1].name == 'burner-mining-drill') then --this one is too boring to announce
if price[2] then
local fish = price[2].name
if fish == 'raw-fish' then fish = 'fish' end
Common.notify_force_light(player.force, player.name .. ' is trading away ' .. price[1].amount .. ' ' .. price[1].name .. ' and ' .. fish .. ' for ' .. this_offer.offer.count .. ' ' .. this_offer.offer.item .. '...')
else
Common.notify_force_light(player.force, player.name .. ' is trading away ' .. price[1].amount .. ' ' .. price[1].name .. ' for ' .. this_offer.offer.count .. ' ' .. this_offer.offer.item .. '...')
end
end
end

View File

@ -249,11 +249,11 @@ function Public.terrain(args)
else
args.tiles[#args.tiles + 1] = {name = CoreData.static_boat_floor, position = args.p}
end
return
return nil
end
function Public.chunk_structures(args)
return
return nil
end
return Public

View File

@ -124,15 +124,37 @@ end
function Public.update_destination_renderings()
local memory = Memory.get_crew_memory()
for _, dest in pairs(memory.destinations) do
local r1 = dest.dynamic_data.crowsnest_rendering_1
local r2 = dest.dynamic_data.crowsnest_rendering_2
if r1 and rendering.is_valid(r1) and r2 and rendering.is_valid(r2) then
if dest.dynamic_data.crowsnest_renderings then
if dest.overworld_position.x <= memory.overworldx+Public.Data.chartingdistance and dest.overworld_position.x >= memory.overworldx-Public.Data.chartingdistance then
rendering.set_visible(r1, true)
rendering.set_visible(r2, true)
for _, r in pairs(dest.dynamic_data.crowsnest_renderings) do
if type(r) == 'table' then
if rendering.is_valid(r.text_rendering) then
rendering.set_visible(r.text_rendering, true)
end
if rendering.is_valid(r.sprite_rendering) then
rendering.set_visible(r.sprite_rendering, true)
end
else
if rendering.is_valid(r) then
rendering.set_visible(r, true)
end
end
end
else
rendering.set_visible(r1, false)
rendering.set_visible(r2, false)
for _, r in pairs(dest.dynamic_data.crowsnest_renderings) do
if type(r) == 'table' then
if rendering.is_valid(r.text_rendering) then
rendering.set_visible(r.text_rendering, false)
end
if rendering.is_valid(r.sprite_rendering) then
rendering.set_visible(r.sprite_rendering, false)
end
else
if rendering.is_valid(r) then
rendering.set_visible(r, false)
end
end
end
end
end
end
@ -312,7 +334,7 @@ function Public.crowsnest_surface_delayed_init()
local force = game.forces[memory.force_name]
if _DEBUG and (not (surface and surface.valid)) then
game.print('debug issue: crowsnest_surface_delayed_init called when crowsnest surface wasn\'t valid...')
game.print('debug issue: crowsnest_surface_delayed_init called when crowsnest surface wasn\'t valid. This happens due to a difficult-to-handle race condition in concurrent delayed events in the /go shortcut. Firing event again...')
Task.set_timeout_in_ticks(5, crowsnest_delayed, {})
return
end

View File

@ -143,7 +143,7 @@ function Public.terrain(args)
end
function Public.chunk_structures(args)
return
return nil
end
Public.Data.jetty_offset = {x = -40, y = -6}

View File

@ -390,11 +390,11 @@ function Public.terrain(args)
else
args.tiles[#args.tiles + 1] = {name = CoreData.static_boat_floor, position = args.p}
end
return
return nil
end
function Public.chunk_structures(args)
return
return nil
end
return Public

View File

@ -23,7 +23,7 @@ Public.static_params_default = {
function Public.base_ores()
return {
['copper-ore'] = 2.0,
['iron-ore'] = 4.2,
['iron-ore'] = 4.1,
['coal'] = 1.8,
['stone'] = 0.4,
}

View File

@ -101,7 +101,7 @@ function Public.terrain(args)
if noises.height(p) > 0.18 and noises.mood(p) > 0.2 then
if noises.forest_abs(p) < 0.2 and noises.rock_abs(p) > 1.8 then
args.entities[#args.entities + 1] = {name = 'coal', position = args.p, amount = 10}
args.entities[#args.entities + 1] = {name = 'coal', position = args.p, amount = 8}
end
end
end

View File

@ -103,7 +103,7 @@ function Public.terrain(args)
if noises.height(p) > 0.18 and noises.mood(p) > 0.6 then
if noises.forest_abs(p) < 0.2 and noises.rock_abs(p) > 1.5 then
args.entities[#args.entities + 1] = {name = 'coal', position = args.p, amount = 10}
args.entities[#args.entities + 1] = {name = 'coal', position = args.p, amount = 8}
end
end
end

View File

@ -107,7 +107,7 @@ function Public.terrain(args)
if noises.height(p) > 0.18 and noises.mood(p) > 0.3 then
if noises.forest_abs(p) < 0.2 and noises.rock_abs(p) > 1.5 then
args.entities[#args.entities + 1] = {name = 'coal', position = args.p, amount = 10}
args.entities[#args.entities + 1] = {name = 'coal', position = args.p, amount = 8}
end
end
end

View File

@ -281,7 +281,7 @@ function Public.destination_on_arrival(destination)
Server.to_discord_embed_raw((destination.static_params.discord_emoji or CoreData.comfy_emojis.wut) .. '[' .. memory.name .. '] ' .. message)
end
if destination.static_params.name == 'Dock' then
message = message .. ' ' .. 'A special trade is available for the captain in the Main Store.'
message = message .. ' ' .. 'A special offer is available in the Captain\'s Store.'
end
Common.notify_force(game.forces[memory.force_name], message)

View File

@ -37,7 +37,7 @@ function Public.strobe_player_colors(tickinterval)
local strobing_players = memory.speed_boost_characters
if strobing_players and #strobing_players > 0 then
local col = Utils.rgb_from_hsv((game.tick*6) % 360, 1, 1)
local col = Utils.rgb_from_hsv((game.tick*6) % 360, 0.7, 0.9)
for index, val in pairs(strobing_players) do
if val then
local player = game.players[index]
@ -92,7 +92,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)) then
Common.notify_player(player, 'Now is no time to disembark.')
Common.notify_player_error(player, 'Now is no time to disembark.')
player.teleport(memory.spawnpoint)
end
end
@ -195,7 +195,7 @@ function Public.captain_warn_afk(tickinterval)
if memory.playerindex_captain then
for _, player in pairs(game.connected_players) do
if player.index == memory.playerindex_captain and #Common.crew_get_nonafk_crew_members() > 1 and player.afk_time >= Common.afk_time - 20*60 - 60 - tickinterval and player.afk_time < Common.afk_time - 20*60 then
Common.notify_player(player, 'Note: If you go idle as captain for too long, the role passes to another crewmember.')
Common.notify_player_expected(player, 'Note: If you go idle as captain for too long, the role passes to another crewmember.')
player.play_sound{path = 'utility/scenario_message'}
end
end
@ -458,15 +458,16 @@ function Public.place_cached_structures(tickinterval)
covered_data.market.destructible = false
-- @TODO: Add trades here
covered_data.market.add_market_item{price={{'coin', Balance.class_cost()}}, offer={type="nothing"}}
covered_data.market.add_market_item{price={{'pistol', 1}}, offer={type = 'give-item', item = 'coin', count = 500}}
covered_data.market.add_market_item{price={{'burner-mining-drill', 1}}, offer={type = 'give-item', item = 'iron-plate', count = 9}}
local coin_offers = ShopCovered.market_generate_coin_offers(2)
local coin_offers = ShopCovered.market_generate_coin_offers(4)
for _, o in pairs(coin_offers) do
covered_data.market.add_market_item(o)
end
covered_data.market.add_market_item{price={{'coin', Balance.class_cost()}}, offer={type="nothing"}}
destination.dynamic_data.market_class_offer_rendering = rendering.draw_text{
text = 'Class available: ' .. Classes.display_form[destination.static_params.class_for_sale],
surface = surface,

View File

@ -56,14 +56,15 @@ function Public.update_character_properties(tickinterval)
end
local health_boost = 0
-- base health is 250
if memory.classes_table and memory.classes_table[player_index] then
local class = memory.classes_table[player_index]
if class == Classes.enum.SAMURAI then
health_boost = health_boost + 225
health_boost = health_boost + 500
end
end
if memory.playerindex_captain and memory.playerindex_captain == player_index then
health_boost = health_boost + 25
health_boost = health_boost + 50
end
character.character_health_bonus = health_boost
@ -74,7 +75,7 @@ function Public.update_character_properties(tickinterval)
if memory.classes_table and memory.classes_table[player_index] then
local class = memory.classes_table[player_index]
if class == Classes.enum.SCOUT then
speed_boost = speed_boost + 0.4
speed_boost = speed_boost + 0.3
elseif class == Classes.enum.DECKHAND or class == Classes.enum.BOATSWAIN or class == Classes.enum.SHORESMAN then
local surfacedata = Surfaces.SurfacesCommon.decode_surface_name(player.surface.name)
local type = surfacedata.type

View File

@ -20,31 +20,31 @@ function Public.rgb_from_hsv(h, s, v)
local x = c * (1 - Math.abs(((h/60) % 2) - 1))
local m = v - c
if h < 60 then
r=c
g=x
b=0
r=c+m
g=x+m
b=m
elseif h < 120 then
r=x
g=c
b=0
r=x+m
g=c+m
b=m
elseif h < 180 then
r=0
g=c
b=x
r=m
g=c+m
b=x+m
elseif h < 240 then
r=0
g=x
b=c
r=m
g=x+m
b=c+m
elseif h < 300 then
r=x
g=0
b=c
r=x+m
g=m
b=c+m
else
r=c
g=0
b=x
r=c+m
g=m
b=x+m
end
return {r = r, g = g, b = b}
return {r = 255*r, g = 255*g, b = 255*b}
end
function Public.stable_sort(list, comp) --sorts but preserves ordering of equals