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

Merge pull request #261 from danielmartin0/develop

PS milestone version
This commit is contained in:
Gerkiz 2022-05-08 23:28:00 +02:00 committed by GitHub
commit e2f7c5488d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
43 changed files with 1680 additions and 1063 deletions

View File

@ -1,25 +1,25 @@
[pirates]
softmod_info_header_before_version_number==== Pirate Ship v
softmod_info_header_after_version_number= ===
softmod_info_body_1=News and voice chat: getcomfy.eu/discord
softmod_info_body_1=News and chat: getcomfy.eu/discord
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. Doubloons 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 deciding when the boat leaves.\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. Each crew has a captain, who performs actions such as deciding when the boat leaves. Doubloons can be spent at various markets throughout the game.\n\nGame progression is significantly slowed 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= Very rarely (only observed once), the deck locomotive can disappear, and an admin needs to make a new one.
softmod_info_bugs_2=
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 doubloons.\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. (The time-based rate of evolution is proportional to nests too, but destroying a nest will immediately jump evolution by 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• The player who spent the longest as captain between leagues 0 and 1000 (exclusive) is written into the highscores table.\n• Logged-out players keep their items with them for a while — except 'important' items that are returned to the crew immediately.\n• Commands: /ccolor gives you a fun color. To manage your class, use /classinfo {classname}, /take {classname}, or /giveup. Captains also have /undock, /req, /officer, /plank.
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 doubloons.\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. (The time-based rate of evolution is proportional to nests too, but destroying a nest will immediately jump evolution by most of 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• The player who spent the longest as captain between leagues 0 and 1000 (exclusive) is written into the highscores table.\n• Logged-out players keep their items with them for a while — except 'important' items that are returned to the crew immediately.\n• Commands: /ccolor gives you a fun color. /classinfo {classname} gives the description of the named class. To manage your class, use /take {classname} or /giveup. Captains also have /undock, /req, /officer, /plank.
softmod_info_updates_1=Development
softmod_info_updates_2=Recent significant changes: Silo death is no longer a lose condition. Game made much easier for small crews. New islands and classes. The ship now shares power across each of its floors. Officers can now access chests in the captain's cabin directly.
softmod_info_updates_1=Recent changes
softmod_info_updates_2=v1.1.2.2.2\n- Some rebalancing of Nightmare difficulty\n\nv1.1.2.2.1\n- Downsides from some classes removed.\n- Small bugfixes\n\nv1.1.2.2.0\n- Coin requisitioning replaced by a 'tax' that takes only 10% of each player's coins.\n- Scaled up coin economy; rocket coin rewards now default to the second reward chest.\n- Deckhand nerfed.
softmod_info_credits_1=Credits
softmod_info_credits_2=Pirate Ship designed and coded by thesixthroc. Comfy codebase and help from Gerkiz, Hanakocz and Mew @ Comfy Industries (https://getcomfy.eu). Some island structure blueprints contributed by Mattisso.\n\nContact us via Discord: https://getcomfy.eu/discord\n\n"Those white gloves. I'll never forget them 'till the day I die." - Dr. John
softmod_info_credits_2=Pirate Ship designed and coded by thesixthroc. Comfy codebase and help from Gerkiz, Hanakocz and Mew @ Comfy Industries (https://getcomfy.eu). Some island structure blueprints contributed by Mattisso.\n\nthesixthroc is looking for coders to help implement planned features for this mod. Come chat with us: https://getcomfy.eu/discord\n\n"Those white gloves. I'll never forget them 'till the day I die." - Dr. John
softmod_info_credits_2_old=Softmod designed and written by thesixthroc. Comfy codebase help from Gerkiz, Hanakocz and Mew @ Comfy Industries (https://getcomfy.eu). Some island structure blueprints were contributed by Mattisso. Gold sprite by Clint Bellanger. Parrot sprites by @pixelthen.\n\n"Those white gloves. I'll never forget them 'till the day I die." - Dr. John
softmod_info_body_promote=by thesixthroc
@ -39,10 +39,14 @@ mode_tooltip=Mode.
auto_undock_tooltip=The maximum time to stay at this location.\n\nOnce this time is reached, the boat undocks automatically. The captain can choose to leave earlier by pressing this button.
atsea_loading_tooltip=The next destination is loading.
leave_anytime_tooltip=The captain chooses when to undock the ship.\n\nThey can undock by pressing this button.
resources_needed_tooltip_1=At the next destination, resources will be needed in order to undock early.\n\nFewer resources will be needed the longer you stay, eventually dropping to zero.
resources_needed_tooltip_0=At the next destination, these resources will be needed in order to undock.
resources_needed_tooltip_1=At the next destination, these resources will be needed in order to undock early.\n\nFewer resources will be needed the longer you stay, eventually dropping to zero.
resources_needed_tooltip_2=The captain can undock early by clicking this button, but only if enough resources have been stored in the captain's cabin.\n\nCost on arrival: __1__\nLeaving now will spend: __2__
resources_needed_tooltip_3=The captain can undock by clicking this button, but only if enough resources are stored in the captain's cabin.
resources_needed_tooltip_1_rocketvariant=At the next destination, these resources will be needed in order to undock early.\n\nFewer resources will be needed the longer you stay, eventually dropping to zero..\n\nThe silo represents a rocket launch.
resources_needed_tooltip_0_rocketvariant=At the next destination, these resources will be needed in order to undock.\n\nThe silo represents a rocket launch rather than a resource.
resources_needed_tooltip_1_rocketvariant=At the next destination, these resources will be needed in order to undock early.\n\nFewer resources will be needed the longer you stay, eventually dropping to zero.\n\nThe silo represents a rocket launch rather than a resource.
resources_needed_tooltip_2_rocketvariant=The captain can undock early by clicking this button, but only if enough resources have been stored in the captain's cabin.\n\nThe silo represents a rocket launch rather than a resource.\n\nnCost on arrival: __1__\nLeaving now will spend: __2__
resources_needed_tooltip_3_rocketvariant=The captain can undock by clicking this button, but only if enough resources are stored in the captain's cabin.\n\nThe silo represents a rocket launch rather than a resource.
fuel_tooltip=__1__ stored fuel.\n\nTo store more, send it to the captain's cabin. If the ship runs out of fuel, the crew loses.\n\n*Click* to open the Captain's Store, which only the captain and their officers are authorised to use.
fuel_tooltip=Stored fuel: __1__.\n\nTo store more, send it to the captain's cabin. If the ship runs out of fuel, the crew loses.

View File

@ -61,22 +61,21 @@ function Public.Tick_actions(tickinterval)
-- if destination.subtype and destination.subtype == Islands.enum.RED_DESERT then return end -- This was a hack to stop biter boats causing attacks, but, it has the even worse effect of stopping all floating_pollution gathering.
local minute_cycle = {-- even seconds only
[2] = Public.eat_up_fraction_of_all_pollution_wrapped,
[4] = Public.try_rogue_attack,
[6] = Public.poke_script_groups,
[16] = Public.try_main_attack,
[20] = Public.poke_script_groups,
-- [18] = Public.try_secondary_attack, --commenting out: less attacks per minute, but stronger. @TODO need to do more here
[24] = Public.tell_biters_near_silo_to_attack_it,
[28] = Public.eat_up_fraction_of_all_pollution_wrapped,
[30] = Public.try_secondary_attack,
[36] = Public.poke_script_groups,
[46] = Public.poke_script_groups,
[50] = Public.tell_biters_near_silo_to_attack_it,
[52] = Public.create_mail_delivery_biters,
[56] = Public.poke_script_groups,
[58] = Public.poke_inactive_scripted_biters,
local minute_cycle = {-- warning: use even seconds only
[2] = Public.tell_biters_near_silo_to_attack_it,
[4] = Public.poke_script_groups,
[6] = Public.try_main_attack,
[16] = Public.tell_biters_near_silo_to_attack_it,
[18] = Public.poke_script_groups,
[20] = Public.try_secondary_attack,
[32] = Public.tell_biters_near_silo_to_attack_it,
[34] = Public.poke_script_groups,
[36] = Public.try_rogue_attack,
[46] = Public.poke_inactive_scripted_biters,
[48] = Public.create_mail_delivery_biters,
}
if minute_cycle[(game.tick / 60) % 60] then
@ -124,87 +123,103 @@ function Public.eat_up_fraction_of_all_pollution(surface, fraction_of_global_pol
memory.floating_pollution = pollution_available
end
function Public.try_main_attack()
function Public.wave_size_rng() -- random variance in attack sizes
local wave_size_multiplier = 1
local memory = Memory.get_crew_memory()
if memory.overworldx > 0 then
if Math.random(2) == 1 then
-- log('attack aborted by chance')
return nil
end --variance in attack sizes
if Math.random(10) == 1 then wave_size_multiplier = 1.7 end --variance in attack sizes
if Math.random(70) == 1 then wave_size_multiplier = 3.2 end --variance in attack sizes
if Math.random(500) == 1 then wave_size_multiplier = 5 end --variance in attack sizes
local rng1 = Math.random(100)
if rng1 <= 65 then
wave_size_multiplier = 0
elseif memory.overworldx > 0 then
local rng2 = Math.random(1000)
if rng2 <= 900 then
wave_size_multiplier = 1
elseif rng2 <= 975 then
wave_size_multiplier = 1.5
elseif rng2 <= 985 then
wave_size_multiplier = 2
elseif rng2 <= 995 then
wave_size_multiplier = 2.5
else
wave_size_multiplier = 3
end
end
local group = Public.spawn_group_of_scripted_biters(2/3, 6, 180, wave_size_multiplier)
local target = Public.generate_main_attack_target()
if not group or not group.valid or not target or not target.valid then return end
return wave_size_multiplier
end
-- group.set_command(Public.attack_target(target))
function Public.try_main_attack()
Public.eat_up_fraction_of_all_pollution_wrapped()
Public.group_set_commands(group, Public.attack_target(target))
local wave_size_multiplier = Public.wave_size_rng()
-- if _DEBUG then game.print(game.tick .. string.format(": sending main attack of %s units from {%f,%f} to %s", #group.members, group.position.x, group.position.y, target.name)) end
if wave_size_multiplier == 0 then
log('Attacks: ' .. 'Aborted by chance.')
return nil
else
local group = Public.spawn_group_of_scripted_biters(2/3, 6, 180, wave_size_multiplier)
local target = Public.generate_main_attack_target()
if not group or not group.valid or not target or not target.valid then return end
-- group.set_command(Public.attack_target(target))
Public.group_set_commands(group, Public.attack_target(target))
-- if _DEBUG then game.print(game.tick .. string.format(": sending main attack of %s units from {%f,%f} to %s", #group.members, group.position.x, group.position.y, target.name)) end
end
end
function Public.try_secondary_attack()
local wave_size_multiplier = 1
local memory = Memory.get_crew_memory()
if memory.overworldx > 0 then
if Math.random(2) == 1 then
log('attack aborted by chance')
end --variance in attack sizes
if Math.random(10) == 1 then wave_size_multiplier = 1.7 end --variance in attack sizes
if Math.random(70) == 1 then wave_size_multiplier = 3.2 end --variance in attack sizes
if Math.random(500) == 1 then wave_size_multiplier = 5 end --variance in attack sizes
end
Public.eat_up_fraction_of_all_pollution_wrapped()
local surface = game.surfaces[Common.current_destination().surface_name]
local wave_size_multiplier = Public.wave_size_rng()
local group = Public.spawn_group_of_scripted_biters(2/3, 12, 180, wave_size_multiplier)
if not (group and group.valid) then return end
local target
if Math.random(2) == 1 then
target = Public.generate_main_attack_target()
if wave_size_multiplier == 0 then
log('Attacks: ' .. 'Aborted by chance.')
return nil
else
target = Public.generate_side_attack_target(surface, group.position)
local surface = game.surfaces[Common.current_destination().surface_name]
local group = Public.spawn_group_of_scripted_biters(2/3, 12, 180, wave_size_multiplier)
if not (group and group.valid) then return end
local target
if Math.random(2) == 1 then
target = Public.generate_main_attack_target()
else
target = Public.generate_side_attack_target(surface, group.position)
end
if not group or not group.valid or not target or not target.valid then log('target invalid') return end
-- group.set_command(Public.attack_target(target))
Public.group_set_commands(group, Public.attack_target(target))
-- if _DEBUG then game.print(game.tick .. string.format(": sending main attack of %s units from {%f,%f} to %s", #group.members, group.position.x, group.position.y, target.name)) end
end
if not group or not group.valid or not target or not target.valid then log('target invalid') return end
-- group.set_command(Public.attack_target(target))
Public.group_set_commands(group, Public.attack_target(target))
-- if _DEBUG then game.print(game.tick .. string.format(": sending main attack of %s units from {%f,%f} to %s", #group.members, group.position.x, group.position.y, target.name)) end
end
function Public.try_rogue_attack()
local wave_size_multiplier = 1
local memory = Memory.get_crew_memory()
if memory.overworldx > 0 then
if Math.random(2) == 1 then
log('attack aborted by chance')
end --variance in attack sizes
if Math.random(10) == 1 then wave_size_multiplier = 1.7 end --variance in attack sizes
if Math.random(70) == 1 then wave_size_multiplier = 3.2 end --variance in attack sizes
if Math.random(500) == 1 then wave_size_multiplier = 5 end --variance in attack sizes
Public.eat_up_fraction_of_all_pollution_wrapped()
local wave_size_multiplier = Public.wave_size_rng()
if wave_size_multiplier == 0 then
log('Attacks: ' .. 'Aborted by chance.')
return nil
else
local surface = game.surfaces[Common.current_destination().surface_name]
local group = Public.spawn_group_of_scripted_biters(1/2, 6, 180, wave_size_multiplier)
if not (group and group.valid) then return end
local target = Public.generate_side_attack_target(surface, group.position)
if not (target and target.valid) then return end
-- group.set_command(Public.attack_target(target))
Public.group_set_commands(group, Public.attack_target(target))
-- if _DEBUG then game.print(game.tick .. string.format(": sending rogue attack of %s units from {%f,%f} to %s", #group.members, group.position.x, group.position.y, target.name)) end
end
local surface = game.surfaces[Common.current_destination().surface_name]
local group = Public.spawn_group_of_scripted_biters(1/2, 6, 180, wave_size_multiplier)
if not (group and group.valid) then return end
local target = Public.generate_side_attack_target(surface, group.position)
if not (target and target.valid) then return end
-- group.set_command(Public.attack_target(target))
Public.group_set_commands(group, Public.attack_target(target))
-- if _DEBUG then game.print(game.tick .. string.format(": sending rogue attack of %s units from {%f,%f} to %s", #group.members, group.position.x, group.position.y, target.name)) end
end
@ -341,7 +356,7 @@ function Public.spawn_group_of_scripted_biters(fraction_of_floating_pollution, m
nearby_units_to_bring = {}
end
local new_units = Public.try_spawner_spend_fraction_of_available_pollution_on_biters(spawner.position, fraction_of_floating_pollution, minimum_avg_units, maximum_units, 1/wave_size_multiplier)
local new_units = Public.try_spawner_spend_fraction_of_available_pollution_on_biters(spawner.position, fraction_of_floating_pollution, minimum_avg_units, maximum_units, wave_size_multiplier)
if (new_units and nearby_units_to_bring and (#new_units + #nearby_units_to_bring) == 0) then return end
@ -359,7 +374,7 @@ function Public.spawn_group_of_scripted_biters(fraction_of_floating_pollution, m
end
function Public.try_spawner_spend_fraction_of_available_pollution_on_biters(spawnposition, fraction_of_floating_pollution, minimum_avg_units, maximum_units, unit_pollutioncost_multiplier, enforce_type)
function Public.try_spawner_spend_fraction_of_available_pollution_on_biters(spawnposition, fraction_of_floating_pollution, minimum_avg_units, maximum_units, wave_size_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 ''))
@ -381,7 +396,7 @@ function Public.try_spawner_spend_fraction_of_available_pollution_on_biters(spaw
local initialpollution = memory.floating_pollution
-- local initialbudget = budget
local base_pollution_cost_multiplier = 1
local map_pollution_cost_multiplier = 1
local destination = Common.current_destination()
if destination.dynamic_data and destination.dynamic_data.initial_spawner_count then
@ -398,40 +413,40 @@ 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 = initial_spawner_count/spawnerscount
map_pollution_cost_multiplier = initial_spawner_count/spawnerscount
if memory.overworldx == 0 then
base_pollution_cost_multiplier = Math.max(1, base_pollution_cost_multiplier)
map_pollution_cost_multiplier = Math.max(1, map_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
map_pollution_cost_multiplier = 1000000
end
end
end
if memory.overworldx == 0 then
-- less biters:
base_pollution_cost_multiplier = base_pollution_cost_multiplier * 2.30 --tuned to teach players to defend, but then to feel relaxing once they do
end
-- if memory.overworldx == 0 then
-- -- less biters:
-- base_pollution_cost_multiplier = base_pollution_cost_multiplier * 2.30 --tuned to teach players to defend, but then to feel relaxing once they do
-- end -- moved to scripted_biters_pollution_cost_multiplier
base_pollution_cost_multiplier = base_pollution_cost_multiplier * unit_pollutioncost_multiplier
local base_scripted_biters_pollution_cost_multiplier = Balance.scripted_biters_pollution_cost_multiplier()
base_pollution_cost_multiplier = base_pollution_cost_multiplier * Balance.scripted_biters_pollution_cost_multiplier()
map_pollution_cost_multiplier = map_pollution_cost_multiplier * base_scripted_biters_pollution_cost_multiplier
if destination.subtype and destination.subtype == IslandsCommon.enum.SWAMP then
base_pollution_cost_multiplier = base_pollution_cost_multiplier * 0.9 --biters 10% more aggressive
map_pollution_cost_multiplier = map_pollution_cost_multiplier * 0.95 --biters 5% more aggressive
end
-- if destination.subtype and destination.subtype == IslandsCommon.enum.MAZE then
-- base_pollution_cost_multiplier = base_pollution_cost_multiplier * 1.2 --biters 20% less aggressive
-- end
if budget >= minimum_avg_units * Common.averageUnitPollutionCost(evolution) * base_pollution_cost_multiplier then
if budget >= minimum_avg_units * Common.averageUnitPollutionCost(evolution) * map_pollution_cost_multiplier then
local function spawn(name2)
units_created_count = units_created_count + 1
local unittype_pollutioncost = CoreData.biterPollutionValues[name2] * base_pollution_cost_multiplier
local unit_pollutioncost = CoreData.biterPollutionValues[name2] * map_pollution_cost_multiplier / wave_size_multiplier
local p = surface.find_non_colliding_position(name2, spawnposition, 60, 1)
if not p then
@ -444,10 +459,10 @@ function Public.try_spawner_spend_fraction_of_available_pollution_on_biters(spaw
units_created[#units_created + 1] = biter
memory.scripted_biters[biter.unit_number] = {entity = biter, created_at = game.tick}
temp_floating_pollution = temp_floating_pollution - unittype_pollutioncost
budget = budget - unittype_pollutioncost
temp_floating_pollution = temp_floating_pollution - unit_pollutioncost
budget = budget - unit_pollutioncost
-- flow statistics should reflect the number of biters generated. Therefore it should mismatch the actual pollution spent, because it should miss all the factors that can vary:
game.pollution_statistics.on_flow(name2, - CoreData.biterPollutionValues[name2] * Balance.scripted_biters_pollution_cost_multiplier())
game.pollution_statistics.on_flow(name2, - CoreData.biterPollutionValues[name2])
return biter.unit_number
end
@ -455,10 +470,10 @@ function Public.try_spawner_spend_fraction_of_available_pollution_on_biters(spaw
local mixed = (Math.random(3) <= 2)
if mixed then
local whilesafety = 1000
local whilesafety = 5000
local next_name = enforce_type or Common.get_random_unit_type(evolution)
while units_created_count < maximum_units and budget >= CoreData.biterPollutionValues[next_name] * base_pollution_cost_multiplier and #memory.scripted_biters < CoreData.total_max_biters and whilesafety > 0 do
while units_created_count < maximum_units and budget >= CoreData.biterPollutionValues[next_name] * map_pollution_cost_multiplier and #memory.scripted_biters < CoreData.total_max_biters and whilesafety > 0 do
whilesafety = whilesafety - 1
spawn(next_name)
next_name = enforce_type or Common.get_random_unit_type(evolution)
@ -466,18 +481,20 @@ function Public.try_spawner_spend_fraction_of_available_pollution_on_biters(spaw
else
local name = enforce_type or Common.get_random_unit_type(evolution)
local whilesafety = 1000
while units_created_count < maximum_units and budget >= CoreData.biterPollutionValues[name] * base_pollution_cost_multiplier and #memory.scripted_biters < CoreData.total_max_biters and whilesafety > 0 do
local whilesafety = 5000
while units_created_count < maximum_units and budget >= CoreData.biterPollutionValues[name] * map_pollution_cost_multiplier and #memory.scripted_biters < CoreData.total_max_biters and whilesafety > 0 do
whilesafety = whilesafety - 1
spawn(name)
end
end
memory.floating_pollution = temp_floating_pollution
end
else
log('Attacks: ' .. 'Insufficient pollution for wave.')
end
if units_created_count > 0 then
log('Spent ' .. Math.floor(100 * (initialpollution - temp_floating_pollution) / initialpollution) .. '% of ' .. Math.ceil(initialpollution) .. ' pollution budget on biters, at ' .. Math.ceil(base_pollution_cost_multiplier*100)/100 .. 'x price.')
log('Attacks: ' .. 'Spent ' .. Math.floor(100 * (initialpollution - temp_floating_pollution) / initialpollution) .. '% of ' .. Math.ceil(initialpollution) .. ' pollution budget on biters, at ' .. Math.ceil(map_pollution_cost_multiplier/wave_size_multiplier*100)/100 .. 'x price.')
end
return units_created

View File

@ -28,23 +28,24 @@ Public.EEI_stages = { --multipliers
function Public.scripted_biters_pollution_cost_multiplier()
return 1.3 --tuned
return 1.45 / Math.sloped(Common.difficulty_scale(), 1/5) * (1 + 1.2 / ((1 + (Common.overworldx()/40))^(1.5+Common.difficulty_scale()))) -- the complicated factor just makes the early-game easier; in particular the first island, but on easier difficulties the next few islands as well
end
function Public.cost_to_leave_multiplier()
-- return Math.sloped(Common.difficulty(), 7/10) --should scale with difficulty similar to, but slightly slower than, passive fuel depletion rate --Edit: not sure about this?
-- return Math.sloped(Common.difficulty(), 9/10)
-- return Math.sloped(Common.difficulty_scale(), 7/10) --should scale with difficulty similar to, but slightly slower than, passive fuel depletion rate --Edit: not sure about this?
-- return Math.sloped(Common.difficulty_scale(), 9/10)
-- extra factor now that the cost scales with time:
return Math.sloped(Common.difficulty(), 8/10)
return Math.sloped(Common.difficulty_scale(), 8/10)
end
Public.rocket_launch_coin_reward = 5000
Public.rocket_launch_coin_reward = 6000
function Public.crew_scale()
local ret = Common.activecrewcount()/10
if ret == 0 then ret = 1/10 end --if all players are afk
if ret > 2.4 then ret = 2.4 end --we have to cap this because you need time to mine the ore... and big crews are a mess anyway. currently this value matches the 24 player cap
if ret > 2.4 then ret = 2.4 end --we have to cap this because you need time to mine the ore... and big crews are a mess anyway. currently this value matches the 24 player capacity setting
return ret
end
@ -70,7 +71,7 @@ function Public.silo_energy_needed_MJ()
local est_base_power = 2*Public.starting_boatEEIpower_production_MW() * (1 + 0.05 * (Common.overworldx()/40)^(5/3))
return est_secs * est_base_power
-- return est_secs * est_base_power * Math.sloped(Common.difficulty(), 1/3)
-- return est_secs * est_base_power * Math.sloped(Common.difficulty_scale(), 1/3)
end
function Public.silo_count()
@ -81,8 +82,8 @@ end
function Public.game_slowness_scale()
-- return 1 / Public.crew_scale()^(55/100) / Math.sloped(Common.difficulty(), 1/4) --changed crew_scale factor significantly to help smaller crews
return 1 / Public.crew_scale()^(50/100) / Math.sloped(Common.difficulty(), 1/4) --changed crew_scale factor significantly to help smaller crews
-- return 1 / Public.crew_scale()^(55/100) / Math.sloped(Common.difficulty_scale(), 1/4) --changed crew_scale factor significantly to help smaller crews
return 1 / Public.crew_scale()^(50/100) / Math.sloped(Common.difficulty_scale(), 1/4) --changed crew_scale factor significantly to help smaller crews
end
@ -94,12 +95,20 @@ function Public.max_time_on_island_formula() --always >0 --tuned
end
Public.rockets_needed_x = 40*21
function Public.max_time_on_island()
if Common.overworldx() == 0 or ((Common.overworldx()/40) > 20) then
local x = Common.overworldx()
if x == 0 or (x >= Public.rockets_needed_x) then
-- if Common.overworldx() == 0 or ((Common.overworldx()/40) > 20 and (Common.overworldx()/40) < 25) then
return -1
else
return Math.ceil(Public.max_time_on_island_formula())
if x == 40 then
return 1.1 * Math.ceil(Public.max_time_on_island_formula()) --it's important for this island to be chill, so that it's not such a shock to go here from the first chill island
else
return Math.ceil(Public.max_time_on_island_formula())
end
end
end
@ -116,7 +125,7 @@ function Public.fuel_depletion_rate_static()
local rate
if Common.overworldx() > 0 then
rate = 550 * (0 + (Common.overworldx()/40)^(9/10)) * Public.crew_scale()^(1/7) * Math.sloped(Common.difficulty(), 65/100) / T --most of the crewsize dependence is through T, i.e. the coal cost per island stays the same... but the extra player dependency accounts for the fact that even in compressed time, more players seem to get more resources per island
rate = 575 * (0 + (Common.overworldx()/40)^(9/10)) * Public.crew_scale()^(1/8) * Math.sloped(Common.difficulty_scale(), 65/100) / T --most of the crewsize dependence is through T, i.e. the coal cost per island stays the same... but the extra player dependency accounts for the fact that even in compressed time, more players seem to get more resources per island
else
rate = 0
end
@ -127,12 +136,12 @@ end
function Public.fuel_depletion_rate_sailing()
if (not Common.overworldx()) then return 0 end
return - 7.35 * (1 + 0.135 * (Common.overworldx()/40)^(100/100)) * Math.sloped(Common.difficulty(), 1/20) --shouldn't depend on difficulty much if at all, as available resources don't depend much on difficulty
return - 7.65 * (1 + 0.135 * (Common.overworldx()/40)^(100/100)) * Math.sloped(Common.difficulty_scale(), 1/20) --shouldn't depend on difficulty much if at all, as available resources don't depend much on difficulty
end
function Public.silo_total_pollution()
return (
365 * (Common.difficulty()^(1.2)) * Public.crew_scale()^(2/5) * (3.2 + 0.7 * (Common.overworldx()/40)^(1.6)) --shape of the curve with x is tuned
365 * (Common.difficulty_scale()^(1.2)) * Public.crew_scale()^(3/10) * (3.2 + 0.7 * (Common.overworldx()/40)^(1.6)) / Math.sloped(Common.difficulty_scale(), 1/5) --shape of the curve with x is tuned. Final factor of difficulty is to offset a change made to scripted_biters_pollution_cost_multiplier
)
end
@ -142,7 +151,11 @@ function Public.boat_passive_pollution_per_minute(time)
if (Common.overworldx()/40) > 25 then T = T * 0.9 end
if time then
if time >= 100/100 * T then --will still happen regularly, on islands without an auto-undock timer
if time >= 160/100 * T then
boost = 40
elseif time >= 130/100 * T then
boost = 30
elseif time >= 100/100 * T then --will still happen regularly, on islands without an auto-undock timer
boost = 20
elseif time >= 95/100 * T then
boost = 16
@ -162,8 +175,8 @@ function Public.boat_passive_pollution_per_minute(time)
end
return boost * (
2.73 * Common.difficulty() * (Common.overworldx()/40)^(1.8) * (Public.crew_scale())^(55/100)
) -- There is no _explicit_ T dependence, but it depends almost the same way on the crew_scale as T does.
2.73 * (Common.difficulty_scale()^(1.1)) * (Common.overworldx()/40)^(1.8) * (Public.crew_scale())^(55/100)-- There is no _explicit_ T dependence, but it depends almost the same way on the crew_scale as T does.
) / Math.sloped(Common.difficulty_scale(), 1/5) --Final factor of difficulty is to offset a change made to scripted_biters_pollution_cost_multiplier
end
@ -174,7 +187,7 @@ function Public.base_evolution_leagues(leagues)
if overworldx == 0 then
evo = 0
else
evo = (0.0201 * (overworldx/40)) * Math.sloped(Common.difficulty(), 1/5)
evo = (0.0201 * (overworldx/40)) * Math.sloped(Common.difficulty_scale(), 1/5)
if overworldx > 600 and overworldx < 1000 then
evo = evo + (0.0025 * (overworldx - 600)/40)
@ -235,22 +248,28 @@ function Public.evolution_per_nest_kill() --it's important to have evo go up wit
return 0
end
-- return 0.003 * Common.difficulty()
-- return 0.003 * Common.difficulty_scale()
end
function Public.evolution_per_full_silo_charge()
--too low and you always charge immediately, too high and you always charge late
-- return 0.05
-- observed x=2000 run, changed this to:
return 0.05 + 0.03 * Common.overworldx()/1000
-- return 0.05 + 0.03 * Common.overworldx()/1000
return 0.05 + 0.02 * Common.overworldx()/1000
end
function Public.bonus_damage_to_humans()
local ret = 0.025
local diff = Common.difficulty()
if diff <= 0.7 then ret = 0 end
if diff >= 1.3 then ret = 0.050 end
return ret
-- function Public.bonus_damage_to_humans()
-- local ret = 0.025
-- local diff = Common.difficulty_scale()
-- if diff <= 0.7 then ret = 0 end
-- if diff >= 1.3 then ret = 0.050 end
-- return ret
-- end
function Public.biter_timeofday_bonus_damage(darkness) -- a surface having min_brightness of 0.2 will cap this at 0.8
return 0.1 * darkness
end
@ -286,19 +305,19 @@ function Public.biter_base_density_scale()
end
function Public.launch_fuel_reward()
return Math.ceil(1000 * (1 + 0.13 * (Common.overworldx()/40)^(9/10)))
-- return Math.ceil(1000 * (1 + 0.1 * (Common.overworldx()/40)^(8/10)) / Math.sloped(Common.difficulty(), 1/4))
function Public.rocket_launch_fuel_reward()
return Math.ceil(1250 * (1 + 0.13 * (Common.overworldx()/40)^(9/10)) * Math.sloped(Common.difficulty_scale(), 1/3))
-- return Math.ceil(1000 * (1 + 0.1 * (Common.overworldx()/40)^(8/10)) / Math.sloped(Common.difficulty_scale(), 1/4))
end
function Public.quest_reward_multiplier()
return (0.4 + 0.08 * (Common.overworldx()/40)^(8/10)) * Math.sloped(Common.difficulty(), 1/3) * (Public.crew_scale())^(1/8)
return (0.4 + 0.08 * (Common.overworldx()/40)^(8/10)) * Math.sloped(Common.difficulty_scale(), 1/3) * (Public.crew_scale())^(1/8)
end
function Public.island_richness_avg_multiplier()
local ret
-- local base = 0.7 + 0.1 * (Common.overworldx()/40)^(7/10) --tuned tbh
local base = 0.73 + 0.110 * (Common.overworldx()/40)^(7/10) --tuned tbh
local base = 0.73 + 0.120 * (Common.overworldx()/40)^(65/100) --tuned tbh
ret = base * Math.sloped(Public.crew_scale(), 1/40) --we don't really have resources scaling by player count in this resource-constrained scenario, but we scale a little, to accommodate each player filling their inventory with useful tools. also, I would do higher than 1/40, but we go even slightly lower because we're applying this somewhat sooner than players actually get there.
@ -306,25 +325,28 @@ function Public.island_richness_avg_multiplier()
end
function Public.resource_quest_multiplier()
return (1.0 + 0.075 * (Common.overworldx()/40)^(8/10)) * Math.sloped(Common.difficulty(), 1/3) * (Public.crew_scale())^(1/8)
return (1.0 + 0.075 * (Common.overworldx()/40)^(8/10)) * Math.sloped(Common.difficulty_scale(), 1/5) * (Public.crew_scale())^(1/10)
end
function Public.apply_crew_buffs_per_x(force)
force.laboratory_productivity_bonus = Math.max(0, 7/100 * (Common.overworldx()/40) - (10*(Common.difficulty()) - 5)) --difficulty causes lab productivity boosts to start later
force.laboratory_productivity_bonus = Math.max(0, 7/100 * (Common.overworldx()/40) - (10*(Common.difficulty_scale()) - 5)) --difficulty causes lab productivity boosts to start later
end
function Public.class_cost()
return 8000
return 10000
-- return Math.ceil(10000 / (Public.crew_scale()*10/4)^(1/6))
end
Public.covered_first_appears_at = 40
Public.coin_sell_amount = 500
Public.starting_fuel = 4000
Public.silo_max_hp = 8000
Public.silo_max_hp = 5000
Public.silo_resistance_factor = 7
function Public.pistol_damage_multiplier() return 2.25 end --2.0 slightly too low, 2.5 causes players to yell at each other for not using pistol
@ -338,16 +360,20 @@ function Public.sandworm_evo_increase_per_spawn()
if _DEBUG then
return 1/100
else
return 1/100 * 1/8 * Math.sloped(Common.difficulty(), 3/5)
return 1/100 * 1/7 * Math.sloped(Common.difficulty_scale(), 3/5)
end
end
function Public.kraken_kill_reward()
return {{name = 'sulfuric-acid-barrel', count = 10}}
function Public.kraken_kill_reward_items()
return {{name = 'sulfuric-acid-barrel', count = 5}, {name = 'coin', count = 1000}}
end
function Public.kraken_kill_reward_fuel()
return 150
end
function Public.kraken_health()
return Math.ceil(3500 * Math.max(1, 1 + 0.08 * ((Common.overworldx()/40)^(13/10)-6)) * (Public.crew_scale()^(5/8)) * Math.sloped(Common.difficulty(), 3/4))
return Math.ceil(3500 * Math.max(1, 1 + 0.075 * (Common.overworldx()/40)^(13/10)) * (Public.crew_scale()^(4/8)) * Math.sloped(Common.difficulty_scale(), 3/4))
-- return Math.ceil(3500 * Math.max(1, 1 + 0.08 * ((Common.overworldx()/40)^(13/10)-6)) * (Public.crew_scale()^(5/8)) * Math.sloped(Common.difficulty_scale(), 3/4))
end
Public.kraken_regen_scale = 0.1 --starting off low
@ -390,7 +416,7 @@ function Public.barter_decay_parameter()
end
function Public.sandworm_speed()
return 6.4 * Math.sloped(Common.difficulty(), 1/5)
return 6.4 * Math.sloped(Common.difficulty_scale(), 1/5)
end
-- function Public.island_otherresources_prospect_decay_parameter()
@ -477,7 +503,7 @@ function Public.starting_items_crew_upstairs()
{['grenade'] = 3},
{['shotgun'] = 2, ['shotgun-shell'] = 36},
-- {['raw-fish'] = 5},
{['coin'] = 1000},
{['coin'] = 2000},
}
end
@ -487,11 +513,10 @@ function Public.starting_items_crew_downstairs()
{['underground-belt'] = 80},
{['splitter'] = Math.random(50,56)},
{['inserter'] = Math.random(120,140)},
{['storage-tank'] = 4},
{['storage-tank'] = 2},
{['medium-electric-pole'] = Math.random(15,21)},
{['coin'] = 2000},
{['solar-panel'] = 3},
{['accumulator'] = 1},
}
end
@ -499,7 +524,7 @@ end
function Public.covered_entry_price_scale()
return 0.85 * (1 + 0.033 * (Common.overworldx()/40 - 1)) * ((1 + Public.crew_scale())^(1/3)) * Math.sloped(Common.difficulty(), 1/2) --whilst resource scales tend to be held fixed with crew size, we account slightly for the fact that more players tend to handcraft more
return 0.85 * (1 + 0.033 * (Common.overworldx()/40 - 1)) * ((1 + Public.crew_scale())^(1/3)) * Math.sloped(Common.difficulty_scale(), 1/2) --whilst resource scales tend to be held fixed with crew size, we account slightly for the fact that more players tend to handcraft more
end
-- if the prices are too high, players will accidentally throw too much in when they can't do it
@ -519,7 +544,7 @@ Public.covered1_entry_price_data_raw = { --watch out that the raw_materials ches
{1, 0.1, 1, false, {
price = {name = 'assembling-machine-1', count = 80},
raw_materials = {{name = 'iron-plate', count = 1760}, {name = 'copper-plate', count = 360}}}, {}},
{1, 0, 0.15, false, {
{0.25, 0, 0.15, false, {
price = {name = 'burner-mining-drill', count = 150},
raw_materials = {{name = 'iron-plate', count = 1350}}}, {}},
{0.75, 0, 0.6, false, {
@ -531,7 +556,7 @@ Public.covered1_entry_price_data_raw = { --watch out that the raw_materials ches
{1, 0, 1, false, {
price = {name = 'firearm-magazine', count = 700},
raw_materials = {{name = 'iron-plate', count = 2800}}}, {}},
{1, 0, 1, false, {
{0.6, 0, 1, false, {
price = {name = 'constant-combinator', count = 276},
raw_materials = {{name = 'iron-plate', count = 552}, {name = 'copper-plate', count = 1518}}}, {}},
@ -577,7 +602,7 @@ function Public.covered1_entry_price()
-- local overworldx = memory.overworldx or 0
local game_completion_progress = Math.max(Math.min(Math.sloped(Common.difficulty(),1/2) * Common.game_completion_progress(), 1), 0)
local game_completion_progress = Math.max(Math.min(Math.sloped(Common.difficulty_scale(),1/2) * Common.game_completion_progress(), 1), 0)
local data = Public.covered1_entry_price_data()
local types, weights = {}, {}

View File

@ -2,7 +2,7 @@
local Memory = require 'maps.pirates.memory'
-- local Roles = require 'maps.pirates.roles.roles'
-- local Balance = require 'maps.pirates.balance'
-- local Common = require 'maps.pirates.common'
local Common = require 'maps.pirates.common'
-- local Utils = require 'maps.pirates.utils_local'
-- local Math = require 'maps.pirates.math'
-- local Loot = require 'maps.pirates.loot'
@ -44,19 +44,39 @@ Public.crowsnest_display_form = {
[enum.ROCKETS_FOR_SALE] = 'Unlock Rockets',
}
function Public.execute_upgade(upgrade_type)
-- WARNING: The dock market pulls from these values, but the Crowsnest caption pulls data from main_shop_data_1. So don't change one without the other
Public.market_offer_form = {
[enum.MORE_POWER] = {price = {{'coin', 7000}, {'coal', 500}}, offer = {type='nothing', effect_description='Upgrade the ship\'s passive power generators.'}},
[enum.EXTRA_HOLD] = {price = {{'coin', 7000}, {'coal', 500}}, offer = {type='nothing', effect_description='Purchase an extra hold.'}},
[enum.UNLOCK_MERCHANTS] = {price = {{'coin', 14000}, {'coal', 1000}}, offer = {type='nothing', effect_description='Unlock merchant ships on future islands.'}},
[enum.ROCKETS_FOR_SALE] = {price = {{'coin', 21000}, {'coal', 1000}}, offer = {type='nothing', effect_description='Unlock the sale of rockets at covered markets.'}},
}
function Public.execute_upgade(upgrade_type, player)
local memory = Memory.get_crew_memory()
local boat = memory.boat
if upgrade_type == enum.EXTRA_HOLD then
if player then
Common.notify_force(player.force,string.format('[font=heading-1]%s upgraded the ship\'s hold.[/font]', player.name))
end
Hold.add_another_hold_surface()
elseif upgrade_type == enum.MORE_POWER then
if player then
Common.notify_force(player.force, string.format('[font=heading-1]%s upgraded the ship\'s power.[/font]', player.name))
end
boat.EEI_stage = boat.EEI_stage + 1
Boats.update_EEIs(boat)
elseif upgrade_type == enum.UNLOCK_MERCHANTS then
if player then
Common.notify_force(player.force,string.format('[font=heading-1]%s unlocked merchant ships.[/font]', player.name))
end
memory.merchant_ships_unlocked = true
elseif upgrade_type == enum.ROCKETS_FOR_SALE then
if player then
Common.notify_force(player.force,string.format('[font=heading-1]%s unlocked the sale of rockets at covered-up markets.[/font]', player.name))
end
memory.rockets_for_sale = true
end

View File

@ -340,14 +340,14 @@ function(cmd)
end)
commands.add_command(
'req',
'is a captain command to take \'important\' items from the crew into your inventory.',
'tax',
'is a captain command to take a quarter of all coins, plus other game-critical items from the crew, into your inventory.',
function(cmd)
local param = tostring(cmd.parameter)
if check_captain(cmd) then
local player = game.players[cmd.player_index]
local memory = Memory.get_crew_memory()
Roles.captain_requisition(memory.playerindex_captain)
Roles.captain_tax(memory.playerindex_captain)
end
end)

View File

@ -1,5 +1,6 @@
local Math = require 'maps.pirates.math'
local Server = require 'utils.server'
local Utils = require 'maps.pirates.utils_local'
local CoreData = require 'maps.pirates.coredata'
local Memory = require 'maps.pirates.memory'
@ -48,7 +49,7 @@ Public.ban_from_rejoining_crew_ticks = 45 * 60 --to prevent observing map and re
Public.afk_time = 60 * 60 * 5
Public.afk_warning_time = 60 * 60 * 4.5
Public.logged_off_items_preserved_minutes = 5
Public.important_items = {'coin', 'uranium-235', 'uranium-238', 'fluid-wagon', 'coal', 'electric-engine-unit', 'flying-robot-frame', 'advanced-circuit', 'beacon', 'speed-module-3', 'speed-module-2', 'roboport', 'construction-robot'} --internal inventories of these will not be preserved
Public.logout_unprotected_items = {'coin', 'uranium-235', 'rail-signal', 'uranium-238', 'fluid-wagon', 'coal', 'electric-engine-unit', 'flying-robot-frame', 'advanced-circuit', 'beacon', 'speed-module-3', 'speed-module-2', 'roboport', 'construction-robot'} --internal inventories of these will not be preserved
-- Public.mainshop_rate_limit_ticks = 11
@ -68,7 +69,14 @@ function Public.oil_abstract_to_real(amount)
return Math.ceil(amount*3000)
end
function Public.difficulty() return Memory.get_crew_memory().difficulty end
function Public.difficulty_scale()
local memory = Memory.get_crew_memory()
if memory.overworldx > 0 then
return memory.difficulty
else
return 0.75
end
end
function Public.capacity() return Memory.get_crew_memory().capacity end
-- function Public.mode() return Memory.get_crew_memory().mode end
function Public.overworldx() return Memory.get_crew_memory().overworldx end
@ -150,6 +158,9 @@ end
function Public.parrot_speak(force, message)
force.print('Parrot: ' .. message, CoreData.colors.parrot)
local memory = Memory.get_crew_memory()
Server.to_discord_embed_raw('[' .. memory.name .. '] Parrot: ' .. message)
end
@ -229,16 +240,18 @@ function Public.raffle_from_processed_loot_data(processed_loot_data, how_many, g
for _ = 1, how_many do
local loot = Math.raffle(loot_types, loot_weights)
local low = Math.max(1, Math.ceil(loot.min_count))
local high = Math.max(1, Math.ceil(loot.max_count))
local _count = Math.random(low, high)
local lucky = Math.random(1, 220)
if lucky == 1 then --lucky
_count = _count * 3
elseif lucky <= 12 then
_count = _count * 2
end
ret[#ret + 1] = {name = loot.name, count = _count}
if loot then
local low = Math.max(1, Math.ceil(loot.min_count))
local high = Math.max(1, Math.ceil(loot.max_count))
local _count = Math.random(low, high)
local lucky = Math.random(1, 220)
if lucky == 1 then --lucky
_count = _count * 3
elseif lucky <= 12 then
_count = _count * 2
end
ret[#ret + 1] = {name = loot.name, count = _count}
end
end
return ret
@ -248,11 +261,12 @@ end
function Public.give(player, stacks, spill_position, spill_surface)
function Public.give(player, stacks, spill_position, spill_surface, flying_text_position)
-- stack elements of form {name = '', count = '', color = {r = , g = , b = }}
-- to just spill on the ground, pass player and nill and give a position and surface directly
spill_position = spill_position or player.position
spill_surface = spill_surface or player.surface
flying_text_position = flying_text_position or spill_position
local text1 = ''
local text2 = ''
@ -289,51 +303,60 @@ function Public.give(player, stacks, spill_position, spill_surface)
end
end
if itemcount > 0 then
if itemcount < 5 then
spill_surface.spill_item_stack(spill_position, {name = itemname, count = itemcount}, true)
else
local e = spill_surface.create_entity{name = 'item-on-ground', position = spill_position, stack = {name = itemname, count = itemcount}}
if e and e.valid then
e.to_be_looted = true
end
end
-- if itemcount < 5 then
-- spill_surface.spill_item_stack(spill_position, {name = itemname, count = itemcount}, true)
-- else
-- local e = spill_surface.create_entity{name = 'item-on-ground', position = spill_position, stack = {name = itemname, count = itemcount}}
-- if e and e.valid then
-- e.to_be_looted = true
-- end
-- end
spill_surface.spill_item_stack(spill_position, {name = itemname, count = itemcount}, true)
end
else
local e = spill_surface.create_entity{name = 'item-on-ground', position = spill_position, stack = {name = itemname, count = itemcount}}
if e and e.valid then
e.to_be_looted = true
end
-- local e = spill_surface.create_entity{name = 'item-on-ground', position = spill_position, stack = {name = itemname, count = itemcount}}
-- if e and e.valid then
-- e.to_be_looted = true
-- end
spill_surface.spill_item_stack(spill_position, {name = itemname, count = itemcount}, true)
end
end
text1 = text1 .. '[color=1,1,1]'
if itemcount_remember > 0 then
text1 = text1 .. '+'
text1 = text1 .. itemcount_remember .. '[/color] [item=' .. itemname .. ']'
if #stacks2 == 1 and itemname == 'coin' and itemcount_remember == 1 then --for a single coin, drop the '+'
text1 = text1 .. '[item=' .. itemname .. ']'
else
text1 = text1 .. '[color=1,1,1]'
text1 = text1 .. '+'
text1 = text1 .. itemcount_remember .. '[/color] [item=' .. itemname .. ']'
end
else
text1 = text1 .. '[color=1,1,1]'
text1 = text1 .. '-'
text1 = text1 .. -itemcount_remember .. '[/color] [item=' .. itemname .. ']'
end
-- count total of that item they have:
local new_total_count = 0
if player then
if player and not (#stacks2 == 1 and itemname == 'coin') then
-- count total of that item they have:
local new_total_count = 0
local cursor_stack = player.cursor_stack
if cursor_stack and cursor_stack.valid_for_read and cursor_stack.name == itemname and cursor_stack.count and cursor_stack.count > 0 then
new_total_count = new_total_count + cursor_stack.count
end
end
if inv and inv.get_item_count(itemname) and inv.get_item_count(itemname) > 0 then
new_total_count = new_total_count + inv.get_item_count(itemname)
end
if inv and inv.get_item_count(itemname) and inv.get_item_count(itemname) > 0 then
new_total_count = new_total_count + inv.get_item_count(itemname)
end
if #stacks2 > 1 then
text2 = text2 .. '[color=' .. flying_text_color.r .. ',' .. flying_text_color.g .. ',' .. flying_text_color.b .. ']' .. new_total_count .. '[/color]'
else
text2 = '[color=' .. flying_text_color.r .. ',' .. flying_text_color.g .. ',' .. flying_text_color.b .. '](' .. new_total_count .. ')[/color]'
end
if j < #stacks2 then
text2 = text2 .. ', '
if #stacks2 > 1 then
text2 = text2 .. '[color=' .. flying_text_color.r .. ',' .. flying_text_color.g .. ',' .. flying_text_color.b .. ']' .. new_total_count .. '[/color]'
else
text2 = '[color=' .. flying_text_color.r .. ',' .. flying_text_color.g .. ',' .. flying_text_color.b .. '](' .. new_total_count .. ')[/color]'
end
if j < #stacks2 then
text2 = text2 .. ', '
end
end
if j < #stacks2 then
@ -345,9 +368,9 @@ function Public.give(player, stacks, spill_position, spill_surface)
if #stacks2 > 1 then
text2 = '(' .. text2 .. ')'
end
Public.flying_text(spill_surface, spill_position, text1 .. ' [font=count-font]' .. text2 .. '[/font]')
Public.flying_text(spill_surface, flying_text_position, text1 .. ' [font=count-font]' .. text2 .. '[/font]')
else
Public.flying_text(spill_surface, spill_position, text1)
Public.flying_text(spill_surface, flying_text_position, text1)
end
end
@ -367,10 +390,10 @@ end
function Public.surplus_evo_biter_damage_modifier(surplus_evo)
return Math.floor(surplus_evo/2*1000)/1000 --is this floor needed?
end
function Public.surplus_evo_biter_health_fractional_modifier(surplus_evo)
return surplus_evo*3
-- return Math.floor(surplus_evo*3*1000)/1000
end
-- function Public.surplus_evo_biter_health_fractional_modifier(surplus_evo)
-- return surplus_evo*3
-- -- return Math.floor(surplus_evo*3*1000)/1000
-- end
function Public.set_biter_surplus_evo_modifiers()
local memory = Memory.get_crew_memory()
@ -629,12 +652,12 @@ function Public.spend_stored_resources(to_spend)
end
function Public.new_healthbar(text, target_entity, max_health, optional_id, health, size)
function Public.new_healthbar(text, target_entity, max_health, optional_id, health, size, extra_offset, location_override)
health = health or max_health
size = size or 0.5
text = text or false
local memory = Memory.get_crew_memory()
extra_offset = extra_offset or 0
location_override = location_override or Memory.get_crew_memory()
local render1 = rendering.draw_sprite(
{
@ -644,7 +667,7 @@ function Public.new_healthbar(text, target_entity, max_health, optional_id, heal
y_scale = size,
render_layer = 'light-effect',
target = target_entity,
target_offset = {0, -2.5},
target_offset = {0, -2.5 + extra_offset},
surface = target_entity.surface,
}
)
@ -653,36 +676,67 @@ function Public.new_healthbar(text, target_entity, max_health, optional_id, heal
render2 = rendering.draw_text(
{
color = {255, 255, 255},
scale = 2,
scale = 1.2 + size*2,
render_layer = 'light-effect',
target = target_entity,
target_offset = {0, -4},
target_offset = {0, -3.6 - size*0.6 + extra_offset},
surface = target_entity.surface,
alignment = 'center'
alignment = 'center',
}
)
end
local new_healthbar = {
health = max_health,
health = health,
max_health = max_health,
size = size,
extra_offset = extra_offset,
render1 = render1,
render2 = render2,
id = optional_id,
}
memory.healthbars[target_entity.unit_number] = new_healthbar
if not location_override.healthbars then location_override.healthbars = {} end
location_override.healthbars[target_entity.unit_number] = new_healthbar
Public.update_healthbar_rendering(new_healthbar, health)
return new_healthbar
end
function Public.entity_damage_healthbar(entity, damage)
local memory = Memory.get_crew_memory()
function Public.transfer_healthbar(old_unit_number, new_entity, location_override)
location_override = location_override or Memory.get_crew_memory()
if not location_override.healthbars then return end
local old_healthbar = location_override.healthbars[old_unit_number]
-- local new_unit_number = new_entity.unit_number
-- if new_surface_bool then
-- Public.new_healthbar(old_healthbar.render2, new_entity, old_healthbar.max_health, old_healthbar.id, old_healthbar.health, rendering.get_y_scale(old_healthbar.render1))
-- else
-- rendering.set_target(old_healthbar.render1, new_entity)
-- if old_healthbar.render2 then
-- rendering.set_target(old_healthbar.render2, new_entity)
-- end
-- memory.healthbars[new_unit_number] = old_healthbar
-- end
Public.new_healthbar(old_healthbar.render2, new_entity, old_healthbar.max_health, old_healthbar.id, old_healthbar.health, old_healthbar.size, old_healthbar.extra_offset, location_override)
if rendering.is_valid(old_healthbar.render1) then
rendering.destroy(old_healthbar.render1)
end
if rendering.is_valid(old_healthbar.render2) then
rendering.destroy(old_healthbar.render2)
end
location_override.healthbars[old_unit_number] = nil
end
function Public.entity_damage_healthbar(entity, damage, location_override)
location_override = location_override or Memory.get_crew_memory()
local unit_number = entity.unit_number
local healthbar = memory.healthbars[unit_number]
local healthbar = location_override.healthbars[unit_number]
if not healthbar then return 0 end
local new_health = healthbar.health - damage
@ -1172,7 +1226,7 @@ function Public.send_important_items_from_player_to_crew(player, all_items)
for iii = 1, #player_inv[ii], 1 do
-- local item_stack = player_inv[ii][iii] --don't do this as LuaItemStack is a reference!
if player_inv[ii] and player_inv[ii][iii].valid and player_inv[ii][iii].valid_for_read then
if all_items or (player_inv[ii][iii].name and Utils.contains(Public.important_items, player_inv[ii][iii].name)) then
if all_items or (player_inv[ii][iii].name and Utils.contains(Public.logout_unprotected_items, player_inv[ii][iii].name)) then
to_remove[#to_remove + 1] = player_inv[ii][iii]
any = true
-- else
@ -1197,7 +1251,7 @@ function Public.send_important_items_from_player_to_crew(player, all_items)
end
function Public.give_items_to_crew(items)
function Public.give_items_to_crew(items, prefer_alternate_chest)
local memory = Memory.get_crew_memory()
local boat = memory.boat
@ -1206,8 +1260,18 @@ function Public.give_items_to_crew(items)
if not surface_name then return end
local surface = game.surfaces[surface_name]
if not (surface and surface.valid) then return end
local chest = boat.output_chest
if not (chest and chest.valid) then return end
local chest, chest2
if prefer_alternate_chest then
chest = boat.backup_output_chest
if not (chest and chest.valid) then return end
chest2 = boat.output_chest
if not (chest2 and chest2.valid) then return end
else
chest = boat.output_chest
if not (chest and chest.valid) then return end
chest2 = boat.backup_output_chest
if not (chest2 and chest2.valid) then return end
end
local inventory = chest.get_inventory(defines.inventory.chest)
@ -1215,8 +1279,6 @@ function Public.give_items_to_crew(items)
if not (items.count and items.count>0) then return end
local inserted = inventory.insert(items)
if items.count - inserted > 0 then
local chest2 = boat.backup_output_chest
if not (chest2 and chest2.valid) then return end
local inventory2 = chest2.get_inventory(defines.inventory.chest)
local i2 = Utils.deepcopy(items)
if i2.name then
@ -1240,8 +1302,6 @@ function Public.give_items_to_crew(items)
if not (i.count and i.count>0) then return end
local inserted = inventory.insert(i)
if i.count - inserted > 0 then
local chest2 = boat.backup_output_chest
if not (chest2 and chest2.valid) then return end
local inventory2 = chest2.get_inventory(defines.inventory.chest)
local i2 = Utils.deepcopy(i)
i2.count = i.count - inserted

View File

@ -5,8 +5,8 @@ local _inspect = require 'utils.inspect'.inspect
local Public = {}
Public.scenario_id_name = 'pirates'
Public.version_string = '1.1.1.5.4'
Public.version_float = 1.1154
Public.version_string = '1.1.2.2.2'
Public.version_float = 1.1222
Public.blueprint_library_allowed = true
Public.blueprint_importing_allowed = true
@ -24,6 +24,7 @@ Public.colors = {
wood = {r=204, g=158, b=67},
stone = {r=230, g=220, b=190},
coin = {r=242, g=193, b=97},
oil = {r=181, g=107, b=91},
['raw-fish'] = {r=0, g=237, b=170},
['iron-plate'] = {r=170, g=180, b=190},
['iron-ore'] = {r=170, g=180, b=190},
@ -110,10 +111,10 @@ Public.difficulty_options = {
-- The difficulty values we currently offer
--For the value of Easy difficulty, we are pulled in two directions: We wish to make the game comfy to play for those who haven't played it, but we also wish to represent the game mechanics faithfully so that Normal is not a crazy distance away.
{value = 0.55, icon = 'item/firearm-magazine', text = 'Easy', associated_color = {r = 50, g = 255, b = 50}},
{value = 0.9, icon = 'item/piercing-rounds-magazine', text = 'Normal', associated_color = {r = 255, g = 255, b = 50}},
{value = 1.5, icon = 'item/uranium-rounds-magazine', text = 'Hard', associated_color = {r = 255, g = 50, b = 50}},
{value = 3, icon = 'item/atomic-bomb', text = 'Nightmare', associated_color = {r = 120, g = 35, b = 35}},
{value = 0.6, icon = 'item/firearm-magazine', text = 'Easy', associated_color = {r = 50, g = 255, b = 50}},
{value = 1.0, icon = 'item/piercing-rounds-magazine', text = 'Normal', associated_color = {r = 255, g = 255, b = 50}},
{value = 1.4, icon = 'item/uranium-rounds-magazine', text = 'Hard', associated_color = {r = 255, g = 50, b = 50}},
{value = 2.4, icon = 'item/atomic-bomb', text = 'Nightmare', associated_color = {r = 120, g = 35, b = 35}},
}
function Public.get_difficulty_name_from_value(difficulty_value)
-- Functions will reference this when given a difficulty value and want to present a difficulty name to the player; just make it consistent with the above

View File

@ -92,7 +92,7 @@ function Public.try_add_extra_time_at_sea(ticks)
if not memory.extra_time_at_sea then memory.extra_time_at_sea = 0 end
if memory.extra_time_at_sea > CoreData.max_extra_seconds_at_sea * 60 then return false end
if memory.extra_time_at_sea >= CoreData.max_extra_seconds_at_sea * 60 then return false end
-- if memory.boat and memory.boat.state and memory.boat.state == Boats.enum_state.ATSEA_LOADING_MAP then return false end
@ -713,6 +713,15 @@ function Public.initialise_crew(accepted_proposal)
memory.destinationsvisited_indices = {}
memory.stored_fuel = Balance.starting_fuel
memory.available_classes_pool = Classes.initial_class_pool()
memory.playtesting_stats = {
coins_gained_by_biters = 0,
coins_gained_by_nests_and_worms = 0,
coins_gained_by_trees_and_rocks = 0,
coins_gained_by_ore = 0,
coins_gained_by_rocket_launches = 0,
coins_gained_by_markets = 0,
coins_gained_by_krakens = 0,
}
memory.captain_accrued_time_data = {}
memory.max_players_recorded = 0
@ -745,6 +754,10 @@ function Public.initialise_crew(accepted_proposal)
memory.boat = global_memory.lobby_boats[new_id]
local boat = memory.boat
for _, e in pairs(memory.boat.cannons_temporary_reference or {}) do
Common.new_healthbar(true, e, 2000, nil, e.health, 0.3, -0.1, memory.boat)
end
boat.dockedposition = boat.position
boat.speed = 0
boat.cannonscount = 2
@ -846,13 +859,21 @@ function Public.reset_crew_and_enemy_force(id)
crew_force.technologies['inserter-capacity-bonus-1'].researched = true --needed to make stack inserters different to fast inserters
-- crew_force.technologies['inserter-capacity-bonus-2'].researched = true
--as prerequisites for uranium ammo and automation 3:
crew_force.technologies['speed-module'].researched = true
crew_force.technologies['tank'].researched = true
crew_force.recipes['speed-module'].enabled = false
crew_force.recipes['tank'].enabled = false
crew_force.recipes['cannon-shell'].enabled = false
crew_force.recipes['explosive-cannon-shell'].enabled = false
--@TRYING this out:
crew_force.technologies['coal-liquefaction'].enabled = true
crew_force.technologies['coal-liquefaction'].researched = true
crew_force.technologies['automobilism'].enabled = false
-- note: some of these are overwritten after tech researched!!!!!!! like pistol
-- note: many of these recipes are overwritten after tech researched!!!!!!! like pistol. check elsewhere in code
crew_force.recipes['pistol'].enabled = false
@ -935,8 +956,9 @@ function Public.reset_crew_and_enemy_force(id)
crew_force.technologies['stronger-explosives-5'].enabled = false
crew_force.technologies['stronger-explosives-6'].enabled = false
crew_force.technologies['stronger-explosives-7'].enabled = false
-- these require 2000 white sci each:
crew_force.technologies['artillery-shell-range-1'].enabled = false --infinite techs
-- crew_force.technologies['artillery-shell-speed-1'].enabled = false --infinite techs
crew_force.technologies['artillery-shell-speed-1'].enabled = false --infinite techs
crew_force.technologies['steel-axe'].enabled = false
@ -945,7 +967,8 @@ function Public.reset_crew_and_enemy_force(id)
crew_force.technologies['effect-transmission'].enabled = true
crew_force.technologies['gate'].enabled = false
-- exploit?:
crew_force.technologies['gate'].enabled = true
crew_force.technologies['productivity-module-2'].enabled = true
crew_force.technologies['productivity-module-3'].enabled = false

View File

@ -425,8 +425,8 @@ function Public.player_and_crew_state_bools(player)
atsea_sailing_bool = memory.boat and memory.boat.state == Boats.enum_state.ATSEA_SAILING
landed_bool = memory.boat and memory.boat.state == Boats.enum_state.LANDED
quest_bool = (dynamic_data.quest_type ~= nil) and onmap_bool
silo_bool = dynamic_data.rocketsilos and dynamic_data.rocketsilos[1] and dynamic_data.rocketsilos[1].valid and onmap_bool
charged_bool = dynamic_data.silocharged
silo_bool = dynamic_data.rocketsilos and onmap_bool and ((dynamic_data.rocketsilos[1] and dynamic_data.rocketsilos[1].valid) or charged_bool)
launched_bool = dynamic_data.rocketlaunched
cost_bool = destination.static_params.base_cost_to_undock and (not atsea_sailing_bool) and (not retreating_bool)

View File

@ -268,7 +268,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.tooltip = 'The player will be returned to the lobby and can\'t join your crew for a while. (or use /plank {player})'
flow3 = flow2.add({
name = 'line',
@ -296,7 +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 = 'Make this player an Officer.'
flow3.tooltip = 'Make this player an Officer. (or use /officer {player})'
flow3 = flow2.add({
name = 'unmake_officer',
@ -306,7 +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 = 'Remove this player as an Officer.'
flow3.tooltip = 'Remove this player as an Officer. (or use /officer {player})'
flow3 = flow2.add({
name = 'revoke_class',
@ -331,12 +331,12 @@ function Public.toggle_window(player)
flow3 = flow2.add({
name = 'capn_requisition',
type = 'button',
caption = 'Requisition Items',
caption = 'Tax Crew',
})
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 doubloons and uranium-235 from each non-officer.'
flow3.tooltip = 'For each non-officer in your crew, take a quarter of their doubloons (and other game-critical items). (or use /tax)'
flow2 = flow.add({
@ -587,7 +587,7 @@ function Public.click(event)
if eventname == 'capn_requisition' then
--double check:
if Roles.player_privilege_level(player) >= Roles.privilege_levels.CAPTAIN then
Roles.captain_requisition(memory.playerindex_captain)
Roles.captain_tax(memory.playerindex_captain)
end
return
end

View File

@ -79,7 +79,7 @@ function Public.full_update(player)
local types = {'leagues', 'kraken', 'time', 'silo', 'nests', 'sandwurms'}
local str = 'Local biter evolution\n\n'
local str = 'Local biter evolution: '
if memory.boat and memory.boat.state and (memory.boat.state == Boats.enum_state.ATSEA_SAILING or memory.boat.state == Boats.enum_state.ATSEA_LOADING_MAP) then
evolution_leagues = evo - (memory.kraken_evo or 0)
@ -106,34 +106,34 @@ function Public.full_update(player)
evolution_total = (evolution_leagues or 0) + (evolution_time or 0) + (evolution_nests or 0) + (evolution_silo or 0) + (evolution_sandwurms or 0)
end
str = str .. string.format('%.2f\n', evolution_total)
for _, type in ipairs(types) do
if type == 'leagues' then
if evolution_leagues then
str = str .. string.format('Leagues: %.2f\n', evolution_leagues)
str = str .. string.format('\nLeagues: %.2f', evolution_leagues)
end
elseif type == 'kraken' then
if evolution_kraken then
str = str .. string.format('Kraken: %.2f\n', evolution_kraken)
str = str .. string.format('\nKraken: %.2f', evolution_kraken)
end
elseif type == 'time' then
if evolution_time then
str = str .. string.format('Time: %.2f\n', evolution_time)
str = str .. string.format('\nTime: %.2f', evolution_time)
end
elseif type == 'silo' then
if evolution_silo then
str = str .. string.format('Silo: %.2f\n', evolution_silo)
str = str .. string.format('\nSilo: %.2f', evolution_silo)
end
elseif type == 'nests' then
if evolution_nests then
str = str .. string.format('Nests: %.2f\n', evolution_nests)
str = str .. string.format('\nNests: %.2f', evolution_nests)
end
elseif type == 'sandwurms' then
if evolution_sandwurms then
str = str .. string.format('Sandwurms: %.2f\n', evolution_sandwurms)
str = str .. string.format('\nSandwurms: %.2f', evolution_sandwurms)
end
end
end
str = str .. string.format('Total: %.2f', evolution_total)
button.number = evolution_total
button.tooltip = str

View File

@ -131,8 +131,21 @@ local function create_gui(player)
flow2 = GuiCommon.flow_add_floating_button(flow1, 'fuel_piratebutton')
-- flow2.style.right_padding = -100
flow2 = flow1.add({
name = 'fuel_flow',
type = 'frame',
})
flow2.style.minimal_width = 80
flow2.style.natural_width = 80
flow2.style.minimal_height = 40
flow2.style.maximal_height = 40
flow2.style.left_padding = 4
flow2.style.right_padding = 4
flow2.style.top_padding = 3
-- interactive version:
-- flow2 = GuiCommon.flow_add_floating_button(flow1, 'fuel_piratebutton')
flow3 = flow2.add({
name = 'fuel_label_0',
@ -575,11 +588,20 @@ function Public.process_etaframe_update(player, flow1, bools)
-- local caption
if bools.atsea_loading_bool then
flow2.etaframe_label_3.caption = 'Next escape cost:'
if bools.cost_includes_rocket_launch_bool then
tooltip = {'pirates.resources_needed_tooltip_1_rocketvariant'}
if memory.overworldx >= Balance.rockets_needed_x then --bools.eta_bool is not helpful yet
flow2.etaframe_label_3.caption = 'Next escape cost:'
if bools.cost_includes_rocket_launch_bool then
tooltip = {'pirates.resources_needed_tooltip_0_rocketvariant'}
else
tooltip = {'pirates.resources_needed_tooltip_0'}
end
else
tooltip = {'pirates.resources_needed_tooltip_1'}
flow2.etaframe_label_3.caption = 'Next escape cost:'
if bools.cost_includes_rocket_launch_bool then
tooltip = {'pirates.resources_needed_tooltip_1_rocketvariant'}
else
tooltip = {'pirates.resources_needed_tooltip_1'}
end
end
elseif (not bools.eta_bool) then
flow2.etaframe_label_3.visible = false
@ -755,7 +777,7 @@ function Public.process_siloframe_and_questframe_updates(flowsilo, flowquest, bo
local tooltip = ''
if quest_complete then
if quest_complete and quest_reward then
tooltip = 'This island\'s quest is complete, and this is the reward.'
flow1.quest_label_1.caption = 'Quest:'
flow1.quest_label_1.style.font_color = GuiCommon.achieved_font_color
@ -763,7 +785,7 @@ function Public.process_siloframe_and_questframe_updates(flowsilo, flowquest, bo
flow1.quest_label_3.visible = false
flow1.quest_label_4.visible = false
flow1.quest_label_2.caption = quest_reward.display_amount .. ' ' .. quest_reward.display_sprite
else
elseif quest_reward then
if quest_progress < quest_progressneeded then
flow1.quest_label_1.caption = 'Quest:'
flow1.quest_label_1.style.font_color = GuiCommon.bold_font_color
@ -820,7 +842,7 @@ function Public.process_siloframe_and_questframe_updates(flowsilo, flowquest, bo
end
elseif quest_type == Quest.enum.RESOURCECOUNT then
if tooltip == '' then tooltip = 'Quest: Item Production\n\nProduce a particular number of items for a bonus.' end
if tooltip == '' then tooltip = 'Quest: Item Production\n\nSimply produce a particular number of items for a bonus, anywhere on the map.' end
flow1.quest_label_2.caption = string.format('%s ', '[item=' .. quest_params.item .. ']')
@ -850,6 +872,13 @@ function Public.process_siloframe_and_questframe_updates(flowsilo, flowquest, bo
end
-- local function create_gui_2()
-- end
-- Event.add(defines.events.on_player_joined_game, create_gui_2)
function Public.update_gui(player)
local memory = Memory.get_crew_memory()
local destination = Common.current_destination()
@ -895,12 +924,16 @@ function Public.update_gui(player)
-- button.number = 3
-- end
flow1 = pirates_flow.fuel_piratebutton_flow_1
flow1 = pirates_flow.fuel_flow
-- flow1 = pirates_flow.fuel_piratebutton_flow_1
flow1.fuel_piratebutton.tooltip = {'pirates.fuel_tooltip', Math.floor(memory.stored_fuel or 0)}
local tooltip = {'pirates.fuel_tooltip', Math.floor(memory.stored_fuel or 0)}
flow1.tooltip = tooltip
-- flow1.fuel_piratebutton.tooltip = {'pirates.fuel_tooltip', Math.floor(memory.stored_fuel or 0)}
flow2 = flow1.fuel_piratebutton_flow_2
flow2 = flow1
-- flow2 = flow1.fuel_piratebutton_flow_2
flow2.fuel_label_1.caption = Utils.bignumber_abbrevform(memory.stored_fuel or 0) .. '[item=coal]'
flow2.fuel_label_2.caption = Utils.negative_rate_abbrevform(memory.fuel_depletion_rate_memoized or 0)
@ -910,6 +943,9 @@ function Public.update_gui(player)
g = GuiCommon.fuel_color_1.g * (1-color_scale) + GuiCommon.fuel_color_2.g * color_scale,
b = GuiCommon.fuel_color_1.b * (1-color_scale) + GuiCommon.fuel_color_2.b * color_scale,
}
flow2.fuel_label_0.tooltip = tooltip
flow2.fuel_label_1.tooltip = tooltip
flow2.fuel_label_2.tooltip = tooltip
flow1 = pirates_flow.progress_piratebutton_frame.progress_piratebutton
@ -929,7 +965,8 @@ function Public.update_gui(player)
--== Update Gui ==--
flow1 = pirates_flow.fuel_piratebutton_flow_1
flow1 = pirates_flow.fuel_flow
-- flow1 = pirates_flow.fuel_piratebutton_flow_1
if memory.crewstatus == nil then
flow1.visible = false

View File

@ -51,7 +51,8 @@ function Public.toggle_window(player)
flow2 = Public.flow_add_info_tab(flow, 'Updates')
Public.flow_add_info_sections(flow2, {'updates', 'bugs'})
Public.flow_add_info_sections(flow2, {'updates'})
-- Public.flow_add_info_sections(flow2, {'updates', 'bugs'})
flow2 = Public.flow_add_info_tab(flow, 'Tips')
@ -223,11 +224,11 @@ function Public.full_update(player)
if flow2.selected_tab_index == 1 then
flow2.style.height = 400
elseif flow2.selected_tab_index == 2 then
flow2.style.height = 330
flow2.style.height = 420
elseif flow2.selected_tab_index == 3 then
flow2.style.height = 660
flow2.style.height = 685
elseif flow2.selected_tab_index == 4 then
flow2.style.height = 330
flow2.style.height = 360
end
end

View File

@ -3,9 +3,9 @@
local Event = require 'utils.event'
local Global = require 'utils.global'
local Server = require 'utils.server'
local Gui = require 'utils.gui'
local Math = require 'maps.pirates.math'
local Token = require 'utils.token'
local Tabs = require 'utils.gui'
require 'utils.core'
local _inspect = require 'utils.inspect'.inspect
local SpamProtection = require 'utils.spam_protection'
@ -13,12 +13,14 @@ local SpamProtection = require 'utils.spam_protection'
local Utils = require 'maps.pirates.utils_local'
local CoreData = require 'maps.pirates.coredata'
local module_name = 'Highscore'
local module_name = Gui.uid_name()
-- local module_name = 'Highscore'
local score_dataset = 'highscores'
local score_key = 'pirate_ship_scores'
local score_key_debug = 'pirate_ship_scores_debug'
local score_key_modded = 'pirate_ship_scores_modded'
local Public = {}
local insert = table.insert
local this = {
@ -38,6 +40,8 @@ local function sort_list(method, column_name, score_list)
['ascending'] = function(a, b)
if column_name == 'completion_time' then
return (a[column_name] < b[column_name]) and not (a[column_name] == 0 and b[column_name] ~= 0)
elseif type(a[column_name]) == 'string' then
return a[column_name] > b[column_name]
else
return a[column_name] < b[column_name]
end
@ -45,6 +49,8 @@ local function sort_list(method, column_name, score_list)
['descending'] = function(a, b)
if column_name == 'completion_time' then
return (a[column_name] > b[column_name])
elseif type(a[column_name]) == 'string' then
return a[column_name] < b[column_name]
else
return a[column_name] > b[column_name]
end
@ -81,7 +87,7 @@ local function get_tables_of_scores_by_type(scores)
if score.leagues_travelled and score.leagues_travelled > 0 then
leagues_travelled[#leagues_travelled + 1] = score.leagues_travelled
end
if score.difficulty and score.difficulty >= 1.5 then
if score.difficulty and score.difficulty > 1 then
if score.completion_time and score.completion_time > 0 then
completion_times_hard[#completion_times_hard + 1] = score.completion_time
end
@ -89,7 +95,7 @@ local function get_tables_of_scores_by_type(scores)
leagues_travelled_hard[#leagues_travelled_hard + 1] = score.leagues_travelled
end
end
if score.difficulty and score.difficulty >= 3 then
if score.difficulty and score.difficulty > 2 then
if score.completion_time and score.completion_time > 0 then
completion_times_nightmare[#completion_times_nightmare + 1] = score.completion_time
end
@ -194,14 +200,14 @@ local function saved_scores_trim(scores)
if cutoffs.completion_times_cutoff and score.completion_time and score.completion_time < cutoffs.completion_times_cutoff then include = true
elseif cutoffs.completion_times_mediump_latestv_cutoff and score.completion_time and score.completion_time < cutoffs.completion_times_mediump_latestv_cutoff and score.version == cutoffs.latest_version and score.difficulty >= 1 then include = true
elseif cutoffs.completion_times_hard_cutoff and score.completion_time and score.completion_time < cutoffs.completion_times_hard_cutoff and score.difficulty >= 1.5 then include = true
elseif cutoffs.completion_times_nightmare_cutoff and score.completion_time and score.completion_time < cutoffs.completion_times_nightmare_cutoff and score.difficulty >=3 then include = true
elseif cutoffs.completion_times_hard_cutoff and score.completion_time and score.completion_time < cutoffs.completion_times_hard_cutoff and score.difficulty > 1 then include = true
elseif cutoffs.completion_times_nightmare_cutoff and score.completion_time and score.completion_time < cutoffs.completion_times_nightmare_cutoff and score.difficulty > 2 then include = true
elseif cutoffs.completion_times_latestv_cutoff and score.completion_time and score.completion_time < cutoffs.completion_times_latestv_cutoff and score.version == cutoffs.latest_version then include = true
elseif cutoffs.leagues_travelled_cutoff and score.leagues_travelled and score.leagues_travelled > cutoffs.leagues_travelled_cutoff then include = true
elseif cutoffs.leagues_travelled_mediump_latestv_cutoff and score.leagues_travelled and score.leagues_travelled > cutoffs.leagues_travelled_mediump_latestv_cutoff and score.version == cutoffs.latest_version and score.difficulty >= 1 then include = true
elseif cutoffs.leagues_travelled_hard_cutoff and score.leagues_travelled and score.leagues_travelled > cutoffs.leagues_travelled_hard_cutoff and score.difficulty >= 1.5 then include = true
elseif cutoffs.leagues_travelled_nightmare_cutoff and score.leagues_travelled and score.leagues_travelled > cutoffs.leagues_travelled_nightmare_cutoff and score.difficulty >= 3 then include = true
elseif cutoffs.leagues_travelled_hard_cutoff and score.leagues_travelled and score.leagues_travelled > cutoffs.leagues_travelled_hard_cutoff and score.difficulty > 1 then include = true
elseif cutoffs.leagues_travelled_nightmare_cutoff and score.leagues_travelled and score.leagues_travelled > cutoffs.leagues_travelled_nightmare_cutoff and score.difficulty > 2 then include = true
elseif cutoffs.leagues_travelled_latestv_cutoff and score.leagues_travelled and score.leagues_travelled > cutoffs.leagues_travelled_latestv_cutoff and score.version == cutoffs.latest_version then include = true
end
@ -398,7 +404,7 @@ local function score_gui(data)
-- Score headers
local headers = {
{name = '_name', caption = 'Crew'},
{name = '_captain_name', caption = 'Captain'},
{column = 'captain_name', name = '_captain_name', caption = 'Captain'},
{column = 'completion_time', name = '_completion_time', caption = 'Completion'},
{column = 'leagues_travelled', name = '_leagues_travelled', caption = 'Leagues'},
{column = 'version', name = '_version', caption = 'Version'},
@ -510,22 +516,18 @@ end
local score_gui_token = Token.register(score_gui)
local function on_gui_click(event)
if not event then
return
end
if not event.element then
return
end
if not event.element.valid then
local element = event.element
if not element or not element.valid then
return
end
local player = game.players[event.element.player_index]
local frame = Tabs.get_player_active_frame(player)
local player = game.get_player(element.player_index)
local frame = Gui.get_player_active_frame(player)
if not frame then
return
end
if frame.name ~= module_name then
if frame.name ~= 'Highscore' then
return
end
@ -538,6 +540,7 @@ local function on_gui_click(event)
-- Handles click on a score header
local element_to_column = {
['_captain_name'] = 'captain_name',
['_version'] = 'version',
['_completion_time'] = 'completion_time',
['_leagues_travelled'] = 'leagues_travelled',
@ -577,7 +580,7 @@ end
local function on_player_joined_game(event)
local player = game.players[event.player_index]
if player.index and this.sort_by and (not this.sort_by[player.index]) then
this.sort_by[player.index] = {{method = 'ascending', column = 'completion_time'}, {method = 'descending', column = 'leagues_travelled'}, {method = 'descending', column = 'version'}, {method = 'descending', column = 'difficulty'}}
this.sort_by[player.index] = {{method = 'ascending', column = 'completion_time'}, {method = 'descending', column = 'leagues_travelled'}, {method = 'descending', column = 'version'}, {method = 'descending', column = 'difficulty'}, {method = 'ascending', column = 'captain_name'}}
end
end
@ -607,8 +610,15 @@ Server.on_data_set_changed(
end
)
Gui.add_tab_to_gui({name = module_name, caption = 'Highscore', id = score_gui_token, admin = false, only_server_sided = true})
Tabs.add_tab_to_gui({name = module_name, id = score_gui_token, admin = false, only_server_sided = false})
Gui.on_click(
module_name,
function(event)
local player = event.player
Gui.reload_active_tab(player)
end
)
Event.on_init(on_init)
Event.add(defines.events.on_player_left_game, on_player_left_game)

View File

@ -39,7 +39,7 @@ local tick_tack_trap = require 'maps.pirates.locally_maintained_comfy_forks.tick
local Public = {}
function Public.silo_died()
function Public.silo_die()
local memory = Memory.get_crew_memory()
local destination = Common.current_destination()
local force = memory.force
@ -62,38 +62,38 @@ function Public.silo_died()
end
end
destination.dynamic_data.rocketsilos[1].destroy()
destination.dynamic_data.rocketsilos[1].die()
destination.dynamic_data.rocketsilos = nil
end
end
function Public.damage_silo(final_damage_amount)
if final_damage_amount == 0 then return end
local destination = Common.current_destination()
-- local memory = Memory.get_crew_memory()
-- function Public.damage_silo(final_damage_amount)
-- if final_damage_amount == 0 then return end
-- local destination = Common.current_destination()
-- -- local memory = Memory.get_crew_memory()
-- if we are doing the 'no damage' quest, then damage in the first 20 seconds after landing doesn't count:
if destination and destination.dynamic_data and destination.dynamic_data.quest_type == Quest.enum.NODAMAGE then
if not (destination.dynamic_data.timer and destination.dynamic_data.timeratlandingtime and destination.dynamic_data.timer > destination.dynamic_data.timeratlandingtime + 20) then return end
end
-- -- if we are doing the 'no damage' quest, then damage in the first 20 seconds after landing doesn't count:
-- if destination and destination.dynamic_data and destination.dynamic_data.quest_type == Quest.enum.NODAMAGE then
-- if not (destination.dynamic_data.timer and destination.dynamic_data.timeratlandingtime and destination.dynamic_data.timer > destination.dynamic_data.timeratlandingtime + 20) then return end
-- end
-- manual 'resistance:'
local final_damage_amount2 = Utils.deepcopy(final_damage_amount) / 5
-- -- manual 'resistance:'
-- local final_damage_amount2 = final_damage_amount / 4
destination.dynamic_data.rocketsilohp = Math.max(0, Math.floor(destination.dynamic_data.rocketsilohp - final_damage_amount2))
if destination.dynamic_data.rocketsilohp > destination.dynamic_data.rocketsilomaxhp then destination.dynamic_data.rocketsilohp = destination.dynamic_data.rocketsilomaxhp end
-- destination.dynamic_data.rocketsilohp = Math.max(0, Math.floor(destination.dynamic_data.rocketsilohp - final_damage_amount2))
-- if destination.dynamic_data.rocketsilohp > destination.dynamic_data.rocketsilomaxhp then destination.dynamic_data.rocketsilohp = destination.dynamic_data.rocketsilomaxhp end
if destination.dynamic_data.rocketsilohp <= 0 then
-- if destination.dynamic_data.rocketsilohp <= 0 and (not destination.dynamic_data.rocketlaunched) then
Public.silo_died()
rendering.destroy(destination.dynamic_data.rocketsilohptext)
else
rendering.set_text(destination.dynamic_data.rocketsilohptext, 'HP: ' .. destination.dynamic_data.rocketsilohp .. ' / ' .. destination.dynamic_data.rocketsilomaxhp)
end
-- if destination.dynamic_data.rocketsilohp < destination.dynamic_data.rocketsilomaxhp / 2 and final_damage_amount > 0 then
-- Upgrades.trigger_poison()
-- end
end
-- if destination.dynamic_data.rocketsilohp <= 0 then
-- -- if destination.dynamic_data.rocketsilohp <= 0 and (not destination.dynamic_data.rocketlaunched) then
-- Public.silo_die()
-- rendering.destroy(destination.dynamic_data.rocketsilohptext)
-- else
-- rendering.set_text(destination.dynamic_data.rocketsilohptext, 'HP: ' .. destination.dynamic_data.rocketsilohp .. ' / ' .. destination.dynamic_data.rocketsilomaxhp)
-- end
-- -- if destination.dynamic_data.rocketsilohp < destination.dynamic_data.rocketsilomaxhp / 2 and final_damage_amount > 0 then
-- -- Upgrades.trigger_poison()
-- -- end
-- end
local function biters_chew_stuff_faster(event)
@ -119,30 +119,46 @@ end
local function event_on_player_repaired_entity(event)
-- local function event_on_player_repaired_entity(event)
-- local entity = event.entity
-- if entity and entity.valid and entity.name and entity.name == 'artillery-turret' then
-- entity.health = entity.health - 2 --prevents repairing
-- end
-- --@TODO: somehow fix the fact that drones can repair the turret
-- end
local function protect_special_entities(event)
-- local memory = Memory.get_crew_memory()
local entity = event.entity
if entity and entity.valid and entity.name and entity.name == 'artillery-turret' then
entity.health = entity.health - 2 --prevents repairing
if event.cause and event.cause.valid and entity and entity.valid then
local surfacedata = Surfaces.SurfacesCommon.decode_surface_name(entity.surface.name)
-- local dest = Common.current_destination()
if surfacedata.type == Surfaces.enum.CROWSNEST or surfacedata.type == Surfaces.enum.LOBBY then
entity.health = entity.health + event.final_damage_amount
end
end
--@TODO: somehow fix the fact that drones can repair the turret
end
local function silo_damage(event)
local function damage_to_silo(event)
local memory = Memory.get_crew_memory()
local entity = event.entity
if event.cause and event.cause.valid and event.entity and event.entity.valid then
if event.entity.force.name == memory.force_name then
local surfacedata = Surfaces.SurfacesCommon.decode_surface_name(event.entity.surface.name)
local dest = Common.current_destination()
if surfacedata.type == Surfaces.enum.CROWSNEST or surfacedata.type == Surfaces.enum.LOBBY then
event.entity.health = event.entity.health + event.final_damage_amount
elseif dest.dynamic_data.rocketsilos and dest.dynamic_data.rocketsilos[1] and dest.dynamic_data.rocketsilos[1].valid and event.entity == Common.current_destination().dynamic_data.rocketsilos[1] then
event.entity.health = event.entity.health + event.final_damage_amount
if string.sub(event.cause.force.name, 1, 4) ~= 'crew' then
Public.damage_silo(event.original_damage_amount)
if event.cause and event.cause.valid and entity and entity.valid and entity.force.name == memory.force_name then
local destination = Common.current_destination()
if destination.dynamic_data.rocketsilos and destination.dynamic_data.rocketsilos[1] and destination.dynamic_data.rocketsilos[1].valid and entity == Common.current_destination().dynamic_data.rocketsilos[1] then
if string.sub(event.cause.force.name, 1, 4) ~= 'crew' then
if Common.entity_damage_healthbar(entity, event.original_damage_amount / Balance.silo_resistance_factor * (1 + Balance.biter_timeofday_bonus_damage(event.cause.surface.darkness))) <= 0 then
Public.silo_die()
else
destination.dynamic_data.rocketsilohp = memory.healthbars[entity.unit_number].health
end
else
entity.health = entity.prototype.max_health
end
end
end
@ -162,13 +178,13 @@ local function damage_to_enemyboat_spawners(event)
local damage = event.final_damage_amount
local adjusted_damage = damage
adjusted_damage = adjusted_damage / 3
adjusted_damage = adjusted_damage / 2.6
if event.cause.name == 'artillery-turret' then
adjusted_damage = adjusted_damage / 1.8
end
-- if event.cause.name == 'artillery-turret' then
-- adjusted_damage = adjusted_damage / 1
-- end
if Common.entity_damage_healthbar(event.entity, adjusted_damage) < 0 then
if Common.entity_damage_healthbar(event.entity, adjusted_damage) <= 0 then
event.entity.die()
end
end
@ -181,17 +197,22 @@ end
local function damage_to_artillery(event)
-- local memory = Memory.get_crew_memory()
if not (event.entity and event.entity.valid and event.entity.name and event.entity.name == 'artillery-turret') then return end
if not event.cause then return end
if not event.cause.valid then return end
if not event.cause.name then return end
if (event.cause.name == 'small-biter') or (event.cause.name == 'small-spitter') or (event.cause.name == 'medium-biter') or (event.cause.name == 'medium-spitter') or (event.cause.name == 'big-biter') or (event.cause.name == 'big-spitter') or (event.cause.name == 'behemoth-biter') or (event.cause.name == 'behemoth-spitter') then
if string.sub(event.cause.force.name, 1, 5) ~= 'enemy' then return end
-- remove resistances:
event.entity.health = event.entity.health + event.final_damage_amount - event.original_damage_amount
-- event.entity.health = event.entity.health + event.final_damage_amount - event.original_damage_amount
if Common.entity_damage_healthbar(event.entity, event.original_damage_amount / 1.5 * (1 + Balance.biter_timeofday_bonus_damage(event.cause.surface.darkness)), Memory.get_crew_memory().boat) <= 0 then
event.entity.die()
end
else
event.entity.health = event.entity.health + event.final_damage_amount --nothing else should damage it
event.entity.health = event.entity.prototype.max_health --nothing else should damage it
end
end
@ -233,7 +254,7 @@ local function damage_to_krakens(event)
adjusted_damage = adjusted_damage / 8 --laser turrets are in range
end
if Common.entity_damage_healthbar(event.entity, adjusted_damage) < 0 then
if Common.entity_damage_healthbar(event.entity, adjusted_damage) <= 0 then
Kraken.kraken_die(memory.healthbars[unit_number].id)
end
end
@ -244,13 +265,11 @@ end
local function damage_to_players_changes(event)
local memory = Memory.get_crew_memory()
if not (event.entity and event.entity.valid and event.entity.name and event.entity.name == 'character') then return end
if not event.cause then return end
if not event.cause.valid then return end
if not event.cause.name then return end
-- if not (event.cause.name == 'small-biter') or (event.cause.name == 'small-spitter') or (event.cause.name == 'medium-biter') or (event.cause.name == 'medium-spitter') or (event.cause.name == 'big-biter') or (event.cause.name == 'big-spitter') or (event.cause.name == 'behemoth-biter') or (event.cause.name == 'behemoth-spitter') then return end
-- if string.sub(event.cause.force.name, 1, 5) ~= 'enemy' then return end --Enemy Forces
local player_index = event.entity.player.index
local class = memory.classes_table and memory.classes_table[player_index]
@ -273,13 +292,17 @@ local function damage_to_players_changes(event)
if not (inv and inv.valid) then return end
local count = inv.get_item_count('iron-ore')
if count and count >= 3500 then
damage_multiplier = damage_multiplier * 0.14
damage_multiplier = damage_multiplier * 0.18
end
else
damage_multiplier = damage_multiplier * (1 + Balance.bonus_damage_to_humans())
-- else
-- damage_multiplier = damage_multiplier * (1 + Balance.bonus_damage_to_humans())
end
end
if string.sub(event.cause.force.name, 1, 5) == 'enemy' then
damage_multiplier = damage_multiplier * (1 + Balance.biter_timeofday_bonus_damage(event.cause.surface.darkness))
end --Enemy Forces
if damage_multiplier > 1 then
event.entity.health = event.entity.health - event.final_damage_amount * (damage_multiplier - 1)
@ -289,6 +312,28 @@ local function damage_to_players_changes(event)
end
local function other_enemy_damage_bonuses(event)
if not event.cause then return end
if not event.cause.valid then return end
if not event.cause.name then return end
if not event.cause.surface then return end
if not event.cause.surface.valid then return end
if event.damage_type.name == 'impact' then return end --avoid circularity
-- if not (event.cause.name == 'small-biter') or (event.cause.name == 'small-spitter') or (event.cause.name == 'medium-biter') or (event.cause.name == 'medium-spitter') or (event.cause.name == 'big-biter') or (event.cause.name == 'big-spitter') or (event.cause.name == 'behemoth-biter') or (event.cause.name == 'behemoth-spitter') then return end
if string.sub(event.cause.force.name, 1, 5) ~= 'enemy' then return end --Enemy Forces
local bonusDamage = event.final_damage_amount * Balance.biter_timeofday_bonus_damage(event.cause.surface.darkness)
if bonusDamage > 0 then
event.entity.damage(bonusDamage, event.cause.force, 'impact', event.cause)
end
end
local function damage_dealt_by_players_changes(event)
local memory = Memory.get_crew_memory()
@ -330,7 +375,7 @@ local function damage_dealt_by_players_changes(event)
elseif hatamoto then
extra_damage_to_deal = 50
end
elseif acid then --this hacky stuff is to implement repeated spillover splash damage, whilst getting around the fact that if ovekill damage takes something to zero health, we can't tell in that event how much double-overkill damage should be dealt by reading off its HP. it assumes that characters only deal acid damage via this function.
elseif acid then --this hacky stuff is to implement repeated spillover splash damage, whilst getting around the fact that if ovekill damage takes something to zero health, we can't tell in that event how much double-overkill damage should be dealt by reading off its HP. This code assumes that characters only deal acid damage via this function.
extra_damage_to_deal = event.original_damage_amount * big_number
end
elseif (not melee) and event.final_health > 0 then
@ -341,7 +386,7 @@ local function damage_dealt_by_players_changes(event)
if extra_damage_to_deal > 0 then
if event.entity.health >= extra_damage_to_deal then
event.entity.health = event.entity.health - extra_damage_to_deal
event.entity.damage(extra_damage_to_deal, character.force, 'impact', character) --using .damage rather than subtracting from health directly plays better with entities which use healthbars
else
local surplus = (extra_damage_to_deal - event.entity.health)*0.8
event.entity.die(character.force, character)
@ -361,7 +406,7 @@ local function damage_dealt_by_players_changes(event)
for _, p2 in pairs(nearby_players) do
if p2.player and p2.player.valid then
local p2_index = p2.player.index
if player_index ~= p2_index and memory.classes_table[p2_index] and memory.classes_table[p2_index] == Classes.enum.QUARTERMASTER then
if event.entity.valid and player_index ~= p2_index and memory.classes_table[p2_index] and memory.classes_table[p2_index] == Classes.enum.QUARTERMASTER then
event.entity.damage(0.1 * event.final_damage_amount, character.force, 'impact', character) --triggers this function again, but not physical this time
end
end
@ -372,7 +417,7 @@ local function damage_dealt_by_players_changes(event)
if character.shooting_state.state ~= defines.shooting.not_shooting then
local weapon = character.get_inventory(defines.inventory.character_guns)[character.selected_gun_index]
local ammo = character.get_inventory(defines.inventory.character_ammo)[character.selected_gun_index]
if weapon.valid_for_read and ammo.valid_for_read and weapon.name == 'pistol' and (ammo.name == 'firearm-magazine' or ammo.name == 'piercing-rounds-magazine' or ammo.name == 'uranium-rounds-magazine') then
if event.entity.valid and weapon.valid_for_read and ammo.valid_for_read and weapon.name == 'pistol' and (ammo.name == 'firearm-magazine' or ammo.name == 'piercing-rounds-magazine' or ammo.name == 'uranium-rounds-magazine') then
event.entity.damage(event.final_damage_amount * (Balance.pistol_damage_multiplier() - 1), character.force, 'impact', character) --triggers this function again, but not physical this time
end
end
@ -433,30 +478,31 @@ end
local function damage_to_enemies(event)
local memory = Memory.get_crew_memory()
-- functions like this need to be rewritten so they play nicely with healthbars:
-- local function damage_to_enemies(event)
-- local memory = Memory.get_crew_memory()
if not (event.entity and event.entity.valid and event.entity.force and event.entity.force.valid) then return end
-- if not (event.entity and event.entity.valid and event.entity.force and event.entity.force.valid) then return end
if not string.sub(event.entity.force.name, 1, 5) == 'enemy' then return end
local evo = memory.evolution_factor
-- if not string.sub(event.entity.force.name, 1, 5) == 'enemy' then return end
-- local evo = memory.evolution_factor
if evo and evo > 1 and event.final_health > 0 then --lethal damage needs to be unaffected, else they never die
-- if evo and evo > 1 and event.final_health > 0 then --lethal damage needs to be unaffected, else they never die
local surplus = evo - 1
-- local surplus = evo - 1
local damage_multiplier = 1/(1 + Common.surplus_evo_biter_health_fractional_modifier(surplus))
-- local damage_multiplier = 1/(1 + Common.surplus_evo_biter_health_fractional_modifier(surplus))
if damage_multiplier < 1 then
event.entity.health = event.entity.health + event.final_damage_amount * (1 - damage_multiplier)
end
end
-- if damage_multiplier < 1 then
-- event.entity.health = event.entity.health + event.final_damage_amount * (1 - damage_multiplier)
-- end
-- end
-- commented out as this is done elsewhere:
-- if event.damage_type.name == 'poison' then
-- event.entity.health = event.entity.health + event.final_damage_amount
-- end
end
-- -- commented out as this is done elsewhere:
-- -- if event.damage_type.name == 'poison' then
-- -- event.entity.health = event.entity.health + event.final_damage_amount
-- -- end
-- end
local function event_on_entity_damaged(event)
@ -472,22 +518,33 @@ local function event_on_entity_damaged(event)
-- local difficulty = memory.difficulty
if not event.entity.valid then return end
silo_damage(event)
if not event.entity.valid then return end -- need to call again, silo might be dead
damage_to_silo(event)
damage_to_krakens(event)
damage_to_enemyboat_spawners(event)
if event.entity and event.entity.valid and event.entity.name and event.entity.name == 'artillery-turret' then
damage_to_artillery(event)
end
protect_special_entities(event)
if not event.entity.valid then return end -- need to call again, healthbar'd object might have been killed by script, so we shouldn't proceed now
if not event.entity.health then return end
damage_to_players_changes(event)
if (event.entity and event.entity.valid and event.entity.name and event.entity.name == 'character') then
damage_to_players_changes(event)
else
other_enemy_damage_bonuses(event)
end
damage_to_enemyboat_spawners(event)
biters_chew_stuff_faster(event)
damage_to_artillery(event)
swamp_resist_poison(event)
maze_walls_resistance(event)
damage_to_krakens(event)
damage_dealt_by_players_changes(event)
damage_to_enemies(event)
-- damage_to_enemies(event)
end
@ -621,6 +678,8 @@ local function event_on_player_mined_entity(event)
return
end
local every_nth_tree_gives_coins = 6
if entity.type == 'tree' then
if not event.buffer then return end
local available = destination.dynamic_data.wood_remaining
@ -637,15 +696,21 @@ local function event_on_player_mined_entity(event)
local give = {}
if memory.classes_table and memory.classes_table[event.player_index] then
if memory.classes_table[event.player_index] == Classes.enum.LUMBERJACK then
if Math.random(7) == 1 then
give[#give + 1] = {name = 'coin', count = 15}
give[#give + 1] = {name = 'wood', count = 4}
if Math.random(every_nth_tree_gives_coins) == 1 then
local a = 20
give[#give + 1] = {name = 'coin', count = a}
memory.playtesting_stats.coins_gained_by_trees_and_rocks = memory.playtesting_stats.coins_gained_by_trees_and_rocks + a
end
elseif memory.classes_table[event.player_index] == Classes.enum.WOOD_LORD then
give[#give + 1] = {name = 'iron-ore', count = 2}
give[#give + 1] = {name = 'copper-ore', count = 2}
give[#give + 1] = {name = 'coal', count = 2}
if Math.random(7) == 1 then
give[#give + 1] = {name = 'coin', count = 15}
give[#give + 1] = {name = 'wood', count = 1}
give[#give + 1] = {name = 'iron-ore', count = 1}
give[#give + 1] = {name = 'copper-ore', count = 1}
give[#give + 1] = {name = 'coal', count = 1}
if Math.random(every_nth_tree_gives_coins) == 1 then
local a = 12
give[#give + 1] = {name = 'coin', count = a}
memory.playtesting_stats.coins_gained_by_trees_and_rocks = memory.playtesting_stats.coins_gained_by_trees_and_rocks + a
end
end
end
@ -663,21 +728,27 @@ local function event_on_player_mined_entity(event)
if memory.classes_table and memory.classes_table[event.player_index] and memory.classes_table[event.player_index] == Classes.enum.LUMBERJACK then
give[#give + 1] = {name = 'wood', count = amount + 3}
if Math.random(7) == 1 then
give[#give + 1] = {name = 'coin', count = 15}
if Math.random(every_nth_tree_gives_coins) == 1 then
local a = 12
give[#give + 1] = {name = 'coin', count = a}
memory.playtesting_stats.coins_gained_by_trees_and_rocks = memory.playtesting_stats.coins_gained_by_trees_and_rocks + a
end
elseif memory.classes_table and memory.classes_table[event.player_index] and memory.classes_table[event.player_index] == Classes.enum.WOOD_LORD then
give[#give + 1] = {name = 'wood', count = amount + 3}
give[#give + 1] = {name = 'iron-ore', count = 1}
give[#give + 1] = {name = 'copper-ore', count = 1}
give[#give + 1] = {name = 'coal', count = 1}
if Math.random(7) == 1 then
give[#give + 1] = {name = 'coin', count = 15}
if Math.random(every_nth_tree_gives_coins) == 1 then
local a = 12
give[#give + 1] = {name = 'coin', count = a}
memory.playtesting_stats.coins_gained_by_trees_and_rocks = memory.playtesting_stats.coins_gained_by_trees_and_rocks + a
end
else
give[#give + 1] = {name = 'wood', count = amount}
if Math.random(7) == 1 then --tuned
give[#give + 1] = {name = 'coin', count = 5}
if Math.random(every_nth_tree_gives_coins) == 1 then --tuned
local a = 5
give[#give + 1] = {name = 'coin', count = a}
memory.playtesting_stats.coins_gained_by_trees_and_rocks = memory.playtesting_stats.coins_gained_by_trees_and_rocks + a
end
end
@ -691,7 +762,7 @@ local function event_on_player_mined_entity(event)
if memory.classes_table and memory.classes_table[event.player_index] and memory.classes_table[event.player_index] == Classes.enum.MASTER_ANGLER then
Common.give(player, {{name = 'raw-fish', count = 4}, {name = 'coin', count = 8}}, entity.position)
Common.give(player, {{name = 'raw-fish', count = 4}, {name = 'coin', count = 10}}, entity.position)
elseif memory.classes_table and memory.classes_table[event.player_index] and memory.classes_table[event.player_index] == Classes.enum.DREDGER then
local to_give = {{name = 'raw-fish', count = 4}}
to_give[#to_give + 1] = Loot.dredger_loot()[1]
@ -709,14 +780,20 @@ local function event_on_player_mined_entity(event)
if memory.overworldx > 0 then
if memory.classes_table and memory.classes_table[event.player_index] and memory.classes_table[event.player_index] == Classes.enum.PROSPECTOR then
give[#give + 1] = {name = 'coin', count = 3}
local a = 3
give[#give + 1] = {name = 'coin', count = a}
memory.playtesting_stats.coins_gained_by_ore = memory.playtesting_stats.coins_gained_by_ore + a
give[#give + 1] = {name = entity.name, count = 6}
elseif memory.classes_table and memory.classes_table[event.player_index] and memory.classes_table[event.player_index] == Classes.enum.CHIEF_EXCAVATOR then
give[#give + 1] = {name = 'coin', count = 4}
local a = 4
give[#give + 1] = {name = 'coin', count = a}
memory.playtesting_stats.coins_gained_by_ore = memory.playtesting_stats.coins_gained_by_ore + a
give[#give + 1] = {name = entity.name, count = 12}
else
if memory.overworldx > 0 then
give[#give + 1] = {name = 'coin', count = 1}
local a = 1
give[#give + 1] = {name = 'coin', count = a}
memory.playtesting_stats.coins_gained_by_ore = memory.playtesting_stats.coins_gained_by_ore + a
end
give[#give + 1] = {name = entity.name, count = 2}
end
@ -747,25 +824,28 @@ local function event_on_player_mined_entity(event)
if memory.overworldx >= 0 then --used to be only later levels
if entity.name == 'rock-huge' then
c2[#c2 + 1] = {name = 'coin', count = 45, color = CoreData.colors.coin}
local a = 55
c2[#c2 + 1] = {name = 'coin', count = a, color = CoreData.colors.coin}
memory.playtesting_stats.coins_gained_by_trees_and_rocks = memory.playtesting_stats.coins_gained_by_trees_and_rocks + a
if Math.random(1, 35) == 1 then
c2[#c2 + 1] = {name = 'crude-oil-barrel', count = 1, color = CoreData.colors.oil}
end
else
c2[#c2 + 1] = {name = 'coin', count = 30, color = CoreData.colors.coin}
local a = 35
c2[#c2 + 1] = {name = 'coin', count = a, color = CoreData.colors.coin}
memory.playtesting_stats.coins_gained_by_trees_and_rocks = memory.playtesting_stats.coins_gained_by_trees_and_rocks + a
if Math.random(1, 35*3) == 1 then
c2[#c2 + 1] = {name = 'crude-oil-barrel', count = 1, color = CoreData.colors.oil}
end
end
end
for k, v in pairs(c) do
local color
if k == 'coal' then
color = CoreData.colors.coal
if k == 'coal' and #c2 <= 1 then --if oil, then no coal
c2[#c2 + 1] = {name = k, count = v, color = CoreData.colors.coal}
elseif k == 'stone' then
color = CoreData.colors.stone
c2[#c2 + 1] = {name = k, count = v, color = CoreData.colors.stone}
end
--old version:
-- local amount = Math.max(Math.min(available,Math.ceil(v * available/starting)),1)
local amount = v
c2[#c2 + 1] = {name = k, count = amount, color = color}
end
Common.give(player, c2, entity.position)
@ -800,52 +880,91 @@ local function base_kill_rewards(event)
local entity = event.entity
if not (entity and entity.valid) then return end
if not (event.force and event.force.valid) then return end
local entity_name = entity.name
-- no worm loot in the maze:
local maze = (destination and destination.subtype and destination.subtype == Islands.enum.MAZE)
if maze and not (entity.name == 'biter-spawner' or entity.name == 'spitter-spawner') then return end
local maze = (destination.subtype and destination.subtype == Islands.enum.MAZE)
if maze and not (entity_name == 'biter-spawner' or entity_name == 'spitter-spawner') then return end
local revenge_target
if event.cause and event.cause.valid and event.cause.name == 'character' then
revenge_target = event.cause
end
local iron_amount = 0
local coin_amount = 0
local iron_amount
local coin_amount
if memory.overworldx >= 0 then
if entity.name == 'small-worm-turret' then
iron_amount = 5
coin_amount = 40
elseif entity.name == 'medium-worm-turret' then
iron_amount = 20
coin_amount = 70
elseif entity.name == 'biter-spawner' or entity.name == 'spitter-spawner'
then
iron_amount = 30
coin_amount = 70
elseif entity.name == 'big-worm-turret'
then
iron_amount = 30
coin_amount = 100
elseif entity.name == 'behemoth-worm-turret'
then
iron_amount = 50
coin_amount = 200
if entity_name == 'small-worm-turret' then
iron_amount = 5
coin_amount = 60
memory.playtesting_stats.coins_gained_by_nests_and_worms = memory.playtesting_stats.coins_gained_by_nests_and_worms + coin_amount
elseif entity_name == 'medium-worm-turret' then
iron_amount = 20
coin_amount = 100
memory.playtesting_stats.coins_gained_by_nests_and_worms = memory.playtesting_stats.coins_gained_by_nests_and_worms + coin_amount
elseif entity_name == 'biter-spawner' or entity_name == 'spitter-spawner' then
iron_amount = 30
coin_amount = 100
memory.playtesting_stats.coins_gained_by_nests_and_worms = memory.playtesting_stats.coins_gained_by_nests_and_worms + coin_amount
elseif entity_name == 'big-worm-turret' then
iron_amount = 30
coin_amount = 160
memory.playtesting_stats.coins_gained_by_nests_and_worms = memory.playtesting_stats.coins_gained_by_nests_and_worms + coin_amount
elseif entity_name == 'behemoth-worm-turret' then
iron_amount = 50
coin_amount = 280
memory.playtesting_stats.coins_gained_by_nests_and_worms = memory.playtesting_stats.coins_gained_by_nests_and_worms + coin_amount
elseif memory.overworldx > 0 then --avoid coin farming on first island
if entity_name == 'small-biter' then
-- if Math.random(2) == 1 then
-- coin_amount = 1
-- end
coin_amount = 1
memory.playtesting_stats.coins_gained_by_biters = memory.playtesting_stats.coins_gained_by_biters + coin_amount
elseif entity_name == 'small-spitter' then
coin_amount = 1
memory.playtesting_stats.coins_gained_by_biters = memory.playtesting_stats.coins_gained_by_biters + coin_amount
elseif entity_name == 'medium-biter' then
coin_amount = 2
memory.playtesting_stats.coins_gained_by_biters = memory.playtesting_stats.coins_gained_by_biters + coin_amount
elseif entity_name == 'medium-spitter' then
coin_amount = 2
memory.playtesting_stats.coins_gained_by_biters = memory.playtesting_stats.coins_gained_by_biters + coin_amount
elseif entity_name == 'big-biter' then
coin_amount = 4
memory.playtesting_stats.coins_gained_by_biters = memory.playtesting_stats.coins_gained_by_biters + coin_amount
elseif entity_name == 'big-spitter' then
coin_amount = 4
memory.playtesting_stats.coins_gained_by_biters = memory.playtesting_stats.coins_gained_by_biters + coin_amount
elseif entity_name == 'behemoth-biter' then
coin_amount = 8
memory.playtesting_stats.coins_gained_by_biters = memory.playtesting_stats.coins_gained_by_biters + coin_amount
elseif entity_name == 'behemoth-spitter' then
coin_amount = 8
memory.playtesting_stats.coins_gained_by_biters = memory.playtesting_stats.coins_gained_by_biters + coin_amount
end
end
if iron_amount > 0 then
local stack = {{name = 'iron-plate', count = iron_amount}, {name = 'coin', count = coin_amount}}
if coin_amount then
local stack
if iron_amount then
stack = {{name = 'iron-plate', count = iron_amount}, {name = 'coin', count = coin_amount}}
else
stack = {{name = 'coin', count = coin_amount}}
end
if revenge_target then
Common.give(event.cause.player, stack)
Common.give(revenge_target.player, stack, revenge_target.player.position, entity.surface, entity.position)
else
Common.give(nil, stack, entity.position, entity.surface)
if event.cause and event.cause.valid and event.cause.position then
Common.give(nil, stack, event.cause.position, entity.surface, entity.position)
else
Common.give(nil, stack, entity.position, entity.surface)
end
end
end
if (entity.name == 'biter-spawner' or entity.name == 'spitter-spawner') and entity.position and entity.surface and entity.surface.valid then
if (entity_name == 'biter-spawner' or entity_name == 'spitter-spawner') and entity.position and entity.surface and entity.surface.valid then
--check if its a boat biter entity
local boat_spawner = false
if memory.enemyboats then
@ -859,7 +978,7 @@ local function base_kill_rewards(event)
end
if boat_spawner then
Ai.revenge_group(entity.surface, entity.position, revenge_target, 'biter', 0.3, 2)
elseif entity.name == 'biter-spawner' then
elseif entity_name == 'biter-spawner' then
Ai.revenge_group(entity.surface, entity.position, revenge_target, 'biter')
else
Ai.revenge_group(entity.surface, entity.position, revenge_target, 'spitter')
@ -1045,6 +1164,13 @@ local function event_on_research_finished(event)
p_force.recipes['slowdown-capsule'].enabled = false
p_force.recipes['nuclear-fuel'].enabled = false
-- p_force.recipes['rail'].enabled = false
p_force.recipes['speed-module'].enabled = false
p_force.recipes['tank'].enabled = false
p_force.recipes['cannon-shell'].enabled = false
p_force.recipes['explosive-cannon-shell'].enabled = false
-- and since we can't build tanks anyway, let's disable this for later:
p_force.recipes['uranium-cannon-shell'].enabled = false
p_force.recipes['explosive-uranium-cannon-shell'].enabled = false
end
local function event_on_player_joined_game(event)
@ -1477,11 +1603,14 @@ local function event_on_rocket_launched(event)
destination.dynamic_data.rocketlaunched = true
if memory.stored_fuel and destination.dynamic_data and destination.dynamic_data.rocketcoalreward then
memory.stored_fuel = memory.stored_fuel + destination.dynamic_data.rocketcoalreward
Common.give_items_to_crew{{name = 'coin', count = Balance.rocket_launch_coin_reward}}
local a = Balance.rocket_launch_coin_reward
Common.give_items_to_crew({{name = 'coin', count = a}}, true)
memory.playtesting_stats.coins_gained_by_rocket_launches = memory.playtesting_stats.coins_gained_by_rocket_launches + a
end
local force = memory.force
Common.notify_force_light(force,'Granted ' .. string.format('%.1fk', Balance.rocket_launch_coin_reward/1000) .. ' doubloons and ' .. string.format('%.1fk', destination.dynamic_data.rocketcoalreward/1000) .. ' fuel.')
Common.notify_force_light(force,'Granted: ' .. Math.floor(Balance.rocket_launch_coin_reward/100)/10 .. 'k [item=coin], ' .. Math.floor(destination.dynamic_data.rocketcoalreward/100)/10 .. 'k [item=coal].')
if destination.dynamic_data.quest_type == Quest.enum.TIME and (not destination.dynamic_data.quest_complete) then
destination.dynamic_data.quest_progressneeded = 1
@ -1512,7 +1641,7 @@ local function event_on_built_entity(event)
entity.time_to_live = entity.force.ghost_time_to_live
end
if memory.boat and memory.boat.surface_name and player.surface == game.surfaces[memory.boat.surface_name] and entity.position then
if memory.boat and memory.boat.surface_name and player.surface == game.surfaces[memory.boat.surface_name] and entity.valid and entity.position then
if (entity.type and (entity.type == 'underground-belt')) or (entity.name == 'entity-ghost' and entity.ghost_type and (entity.ghost_type == 'underground-belt')) then
if Boats.on_boat(memory.boat, entity.position) then
-- if (entity.type and (entity.type == 'underground-belt' or entity.type == 'pipe-to-ground')) or (entity.name == 'entity-ghost' and entity.ghost_type and (entity.ghost_type == 'underground-belt' or entity.ghost_type == 'pipe-to-ground')) then
@ -1651,7 +1780,7 @@ local event = require 'utils.event'
event.add(defines.events.on_built_entity, event_on_built_entity)
event.add(defines.events.on_entity_damaged, event_on_entity_damaged)
event.add(defines.events.on_entity_died, event_on_entity_died)
event.add(defines.events.on_player_repaired_entity, event_on_player_repaired_entity)
-- event.add(defines.events.on_player_repaired_entity, event_on_player_repaired_entity)
event.add(defines.events.on_player_joined_game, event_on_player_joined_game)
event.add(defines.events.on_pre_player_left_game, event_on_pre_player_left_game)
-- event.add(defines.events.on_player_left_game, event_on_player_left_game)

View File

@ -41,7 +41,7 @@ Public.buried_treasure_loot_data_raw = {
}
Public.chest_loot_data_raw = {
{80, 0, 1, false, 'coin', 250, 400},
{80, 0, 1, false, 'coin', 400, 700},
{30, 0, 1, false, 'rail-signal', 25, 110},
{1, 0.2, 1, false, 'electric-engine-unit', 1, 2},
{3, 0, 1, false, 'small-lamp', 4, 16},
@ -129,13 +129,15 @@ Public.chest_loot_data_raw = {
{2, 0.3, 1.2, true, 'combat-shotgun', 1, 1},
{5, 0.2, 1.8, true, 'cluster-grenade', 8, 16},
{0.04, 0.25, 1.75, true, 'modular-armor', 1, 1},
{0.01, 0.5, 1.5, true, 'power-armor', 1, 1},
{0.3, 0.1, 1, true, 'solar-panel-equipment', 1, 2},
{0.2, 0.1, 1, true, 'battery-equipment', 1, 1},
{0.16, 0.2, 1, true, 'energy-shield-equipment', 1, 2},
{0.08, 0.1, 1, true, 'night-vision-equipment', 1, 1},
{0.04, 0.5, 1.5, true, 'personal-laser-defense-equipment', 1, 1},
{0.04, 0.1, 1.9, true, 'modular-armor', 1, 1},
{0.01, 0.4, 1.6, true, 'power-armor', 1, 1},
{0.001, 0.6, 1.4, true, 'power-armor-mk2', 1, 1},
{0.6, 0.05, 2, true, 'solar-panel-equipment', 1, 2},
{0.4, 0.05, 2, true, 'battery-equipment', 1, 1},
{0.32, 0.05, 2, true, 'energy-shield-equipment', 1, 2},
{0.16, 0.05, 1.5, true, 'night-vision-equipment', 1, 1},
{0.12, 0.01, 1.8, true, 'personal-laser-defense-equipment', 1, 1},
{0.12, 0.01, 1.8, true, 'exoskeleton-equipment', 1, 1},
{8, -0.5, 0.5, true, 'automation-science-pack', 4, 24},
{8, -0.6, 0.6, true, 'logistic-science-pack', 4, 24},
@ -210,7 +212,7 @@ function Public.wooden_chest_loot()
local num = 1
return Public.chest_loot(num,
Math.max(0,Math.min(1, Math.sloped(Common.difficulty(),1/2) * Common.game_completion_progress())) --enforce 0 to 1
Math.max(0,Math.min(1, Math.sloped(Common.difficulty_scale(),1/2) * Common.game_completion_progress())) --enforce 0 to 1
)
end
@ -218,9 +220,9 @@ function Public.iron_chest_loot()
local num = 2
local loot = Public.chest_loot(num,
Math.max(0,Math.min(1, Math.sloped(Common.difficulty(),1/2) * (5/100 + Common.game_completion_progress()))) --enforce 0 to 1
Math.max(0,Math.min(1, Math.sloped(Common.difficulty_scale(),1/2) * (5/100 + Common.game_completion_progress()))) --enforce 0 to 1
) --reward higher difficulties with better loot
loot[#loot + 1] = {name = 'coin', count = Math.random(1,1500)}
loot[#loot + 1] = {name = 'coin', count = Math.random(500,1500)}
return loot
end
@ -229,7 +231,7 @@ function Public.covered_wooden_chest_loot()
local num = 2
local loot = Public.chest_loot(num,
Math.max(0,Math.min(1, Math.sloped(Common.difficulty(),1/2) * (10/100 + Common.game_completion_progress()))) --enforce 0 to 1
Math.max(0,Math.min(1, Math.sloped(Common.difficulty_scale(),1/2) * (10/100 + Common.game_completion_progress()))) --enforce 0 to 1
) --reward higher difficulties with better loot
return loot
@ -296,7 +298,7 @@ function Public.chest_loot(number_of_items, game_completion_progress)
end
function Public.buried_treasure_loot()
local ret = Common.raffle_from_processed_loot_data(Common.processed_loot_data(Public.buried_treasure_loot_data_raw), 1, Math.sloped(Common.difficulty(),1/2) * Common.game_completion_progress_capped())
local ret = Common.raffle_from_processed_loot_data(Common.processed_loot_data(Public.buried_treasure_loot_data_raw), 1, Math.sloped(Common.difficulty_scale(),1/2) * Common.game_completion_progress_capped())
if ret and ret[1] then return ret[1] end
end
@ -305,7 +307,7 @@ function Public.maze_camp_loot()
if Math.random(10) <= 7 then
return {Public.random_plates()}
else
return Common.raffle_from_processed_loot_data(Common.processed_loot_data(Public.chest_loot_data_raw), 1, Math.max(0,Math.min(1, Math.sloped(Common.difficulty(),1/2) * (15/100 + Common.game_completion_progress()))))
return Common.raffle_from_processed_loot_data(Common.processed_loot_data(Public.chest_loot_data_raw), 1, Math.max(0,Math.min(1, Math.sloped(Common.difficulty_scale(),1/2) * (15/100 + Common.game_completion_progress()))))
end
end
@ -321,7 +323,7 @@ Public.maze_lab_loot_data_raw = {
}
function Public.maze_lab_loot()
return Common.raffle_from_processed_loot_data(Common.processed_loot_data(Public.maze_lab_loot_data_raw), 1, Math.max(0,Math.min(1, Math.sloped(Common.difficulty(),1/2) * (Common.game_completion_progress()))))
return Common.raffle_from_processed_loot_data(Common.processed_loot_data(Public.maze_lab_loot_data_raw), 1, Math.max(0,Math.min(1, Math.sloped(Common.difficulty_scale(),1/2) * (Common.game_completion_progress()))))
end
Public.maze_treasure_data_raw = {
@ -346,7 +348,7 @@ Public.maze_treasure_data_raw = {
{2, 0, 1.5, true, 'production-science-pack', 20, 25},
{2, 0, 2, true, 'utility-science-pack', 7, 8},
{2, 0, 1.5, true, 'coin', 3000, 6500},
-- {2, 0, 1.5, true, 'coin', 4000, 6500},
{3, 0, 0.9, false, 'beacon', 1, 1},
{1, 0, 1, false, 'construction-robot', 30, 40},
@ -366,17 +368,17 @@ Public.maze_treasure_data_raw = {
{1, 0, 2, true, 'power-armor', 1, 1},
{0.1, 0, 2, true, 'power-armor-mk2', 1, 1},
{2, -1, 1, true, 'solar-panel-equipment', 3, 4},
{2, -1, 1, true, 'battery-equipment', 1, 1},
{1, 0, 2, true, 'battery-mk2-equipment', 1, 1},
{2, -1, 1, true, 'energy-shield-equipment', 1, 2},
{1, 0, 2, true, 'energy-shield-mk2-equipment', 1, 1},
{1, -1, 1, true, 'personal-roboport-equipment', 1, 1},
{0.5, 0, 2, true, 'personal-roboport-mk2-equipment', 1, 1},
{0.5, 0, 0.8, false, 'night-vision-equipment', 1, 1},
{1, 0, 1, false, 'personal-laser-defense-equipment', 1, 1},
{0.5, 0, 1, false, 'fusion-reactor-equipment', 1, 1},
{2, 0, 1, false, 'exoskeleton-equipment', 1, 1},
{4, -1, 1, true, 'solar-panel-equipment', 3, 4},
{4, -1, 1, true, 'battery-equipment', 1, 1},
{2, 0, 2, true, 'battery-mk2-equipment', 1, 1},
{4, -1, 1, true, 'energy-shield-equipment', 1, 2},
{2, 0, 2, true, 'energy-shield-mk2-equipment', 1, 1},
{2, -1, 1, true, 'personal-roboport-equipment', 1, 1},
{1, 0, 2, true, 'personal-roboport-mk2-equipment', 1, 1},
{1, 0, 0.8, false, 'night-vision-equipment', 1, 1},
{2, 0, 1, false, 'personal-laser-defense-equipment', 1, 1},
{1, 0, 1, false, 'fusion-reactor-equipment', 1, 1},
{4, 0, 1, false, 'exoskeleton-equipment', 1, 1},
{2, -0.7, 1.3, true, 'advanced-circuit', 40, 90},
@ -391,7 +393,7 @@ function Public.maze_treasure_loot()
if Math.random(5) == 1 then
return {Public.random_plates(8)}
else
return Common.raffle_from_processed_loot_data(Common.processed_loot_data(Public.maze_treasure_data_raw), 1, Math.max(0,Math.min(1, Math.sloped(Common.difficulty(),1/2) * (Common.game_completion_progress()))))
return Common.raffle_from_processed_loot_data(Common.processed_loot_data(Public.maze_treasure_data_raw), 1, Math.max(0,Math.min(1, Math.sloped(Common.difficulty_scale(),1/2) * (Common.game_completion_progress()))))
end
end

View File

@ -109,6 +109,8 @@ function Public.reset_crew_memory(id) --mostly serves as a dev reference of memo
memory.scripted_biters = nil
memory.scripted_unit_groups = nil
memory.floating_pollution = nil
memory.playtesting_stats = nil
end
function Public.fallthrough_crew_memory() --could make this a metatable, but metatables and factorio global seem not to play nicely

View File

@ -79,6 +79,12 @@ function Public.generate_destination_type_and_subtype(overworld_position)
if macro_x == 4 then
island_subtype_raffle = Utils.ordered_table_with_values_removed(island_subtype_raffle, Surfaces.Island.enum.STANDARD)
end
if macro_x == 11 then
island_subtype_raffle = Utils.ordered_table_with_values_removed(island_subtype_raffle, 'none') --make sure there's an island after kraken
end
if macro_x == 12 then
island_subtype_raffle = Utils.ordered_table_with_values_removed(island_subtype_raffle, 'none') --make sure there's another island after kraken
end
if macro_x == 18 then
island_subtype_raffle = Utils.ordered_table_with_values_removed(island_subtype_raffle, 'none') --flying-robot-frame cost is here, and we just make sure there's an island to see it
end
@ -109,7 +115,13 @@ function Public.generate_destination_type_and_subtype(overworld_position)
subtype = Surfaces.Island.enum.MAZE
elseif macro_x == 23 then --overwrite dock. rocket launch cost
type = Surfaces.enum.ISLAND
subtype = Surfaces.Island.enum.WALKWAYS
if macro_y == 0 then
subtype = Surfaces.Island.enum.RED_DESERT
elseif macro_y == -1 then
subtype = Surfaces.Island.enum.SWAMP
else
subtype = Surfaces.Island.enum.STANDARD_VARIANT
end
elseif macro_y == -1 and (((macro_x % 4) == 3 and macro_x ~= 15) or macro_x == 14) then --avoid x=15 because radioactive is there
type = Surfaces.enum.DOCK
elseif macro_x == 3 then
@ -134,7 +146,7 @@ function Public.generate_destination_type_and_subtype(overworld_position)
-- else
-- type = nil
-- end
elseif macro_x == 11 then --just after krakens, but dock is here too, so there's a choice
elseif macro_x == 12 and macro_y < 1 then
type = Surfaces.enum.ISLAND
subtype = Surfaces.Island.enum.SWAMP
elseif macro_x == 16 then
@ -147,7 +159,7 @@ function Public.generate_destination_type_and_subtype(overworld_position)
type = nil
elseif macro_x == 21 then --rocket launch cost
type = Surfaces.enum.ISLAND
subtype = Surfaces.Island.enum.SWAMP
subtype = Surfaces.Island.enum.WALKWAYS
elseif macro_x == 22 then --game length decrease, pending more content. also kinda fun to have to steer in realtime due to double space
type = nil
elseif macro_x == 24 then --rocket launch cost
@ -170,6 +182,8 @@ function Public.generate_destination_type_and_subtype(overworld_position)
end
end
-- an incomplete list of things that could break if the islands are rearranged: parrot tips are given on certain islands;
--== DEBUG override to test islands:
@ -605,6 +619,8 @@ function Public.check_for_destination_collisions()
local destination = Common.current_destination()
Surfaces.destination_on_collide(destination)
Public.cleanup_old_destination_data()
return true
end
end
@ -612,6 +628,15 @@ function Public.check_for_destination_collisions()
end
function Public.cleanup_old_destination_data() --we do actually access destinations behind us (during the cleanup process and for marooned players), so only fire this when safe
local memory = Memory.get_crew_memory()
for i, destination_data in pairs(memory.destinations) do
if destination_data.overworld_position.x < memory.overworldx then
memory.destinations[i] = nil
end
end
end
@ -626,10 +651,12 @@ function Public.try_overworld_move_v2(vector) --islands stay, crowsnest moves
Common.notify_force(memory.force, message, CoreData.colors.notify_victory)
end
Public.ensure_lane_generated_up_to(0, memory.overworldx + Crowsnest.Data.visibilitywidth)
Public.ensure_lane_generated_up_to(24, memory.overworldx + Crowsnest.Data.visibilitywidth)
Public.ensure_lane_generated_up_to(-24, memory.overworldx + Crowsnest.Data.visibilitywidth)
Public.overwrite_a_dock_upgrade()
if vector.x > 0 then
Public.ensure_lane_generated_up_to(0, memory.overworldx + Crowsnest.Data.visibilitywidth)
Public.ensure_lane_generated_up_to(24, memory.overworldx + Crowsnest.Data.visibilitywidth)
Public.ensure_lane_generated_up_to(-24, memory.overworldx + Crowsnest.Data.visibilitywidth)
Public.overwrite_a_dock_upgrade()
end
if not Public.is_position_free_to_move_to{x = memory.overworldx + vector.x, y = memory.overworldy+ vector.y} then
if _DEBUG then log(string.format('can\'t move by ' .. vector.x .. ', ' .. vector.y)) end
@ -647,7 +674,7 @@ function Public.try_overworld_move_v2(vector) --islands stay, crowsnest moves
local player_index = player.index
if memory.classes_table and memory.classes_table[player_index] and memory.classes_table[player_index] == Classes.enum.MERCHANT then
Common.flying_text_small(player.surface, player.position, '[color=0.97,0.9,0.2]+[/color]')
Common.give_items_to_crew{{name = 'coin', count = 40 * vector.x}}
Common.give_items_to_crew{{name = 'coin', count = 50 * vector.x}}
end
end
end

View File

@ -57,10 +57,11 @@ function Public.parrot_0()
local memory = Memory.get_crew_memory()
Common.parrot_speak(memory.force, 'We can wait here for as long as we like.')
end
-- function Public.parrot_80()
-- local memory = Memory.get_crew_memory()
-- Common.parrot_speak(memory.force, 'Let\'s build out the ship?')
-- end
function Public.parrot_80()
local memory = Memory.get_crew_memory()
-- Common.parrot_speak(memory.force, 'Let\'s build out the ship?')
Common.parrot_speak(memory.force, 'Did you know that biters deal more damage at night?')
end
function Public.parrot_boats_warning()
local memory = Memory.get_crew_memory()
Common.parrot_speak(memory.force, '200 leagues? I think we\'re being chased...')
@ -75,20 +76,20 @@ function Public.parrot_radioactive_tip_1()
end
function Public.parrot_radioactive_tip_2()
local memory = Memory.get_crew_memory()
Common.parrot_speak(memory.force, 'The biters don\'t care if we pollute here, but they evolve fast...')
Common.parrot_speak(memory.force, 'The biters don\'t care if we pollute here, but they evolve fast.')
end
function Public.parrot_maze_tip_1()
local memory = Memory.get_crew_memory()
Common.parrot_speak(memory.force, 'Something seems wrong with our minimap.')
end
function Public.parrot_800_tip()
local memory = Memory.get_crew_memory()
Common.parrot_speak(memory.force, 'The resources needed to leave will get a bit harder now...')
end
function Public.parrot_overstay_tip()
local memory = Memory.get_crew_memory()
Common.parrot_speak(memory.force, 'We\'ve been here quite a while! Check the evo...')
end
-- function Public.parrot_800_tip()
-- local memory = Memory.get_crew_memory()
-- Common.parrot_speak(memory.force, 'The resources needed to leave will get a bit harder now...')
-- end
-- function Public.parrot_overstay_tip()
-- local memory = Memory.get_crew_memory()
-- Common.parrot_speak(memory.force, 'We\'ve been here quite a while! Check the evo.')
-- end
-- function Public.parrot_say_tip()
-- local memory = Memory.get_crew_memory()
@ -100,6 +101,8 @@ end
-- if we're using custom sprites, we have access to this dynamic parrot that flies around:
-- function Public.parrot_tick()
-- local memory = Memory.get_crew_memory()

View File

@ -162,11 +162,11 @@ function Public.go_from_starting_dock_to_first_destination()
boat.EEI_stage = 1
Boats.update_EEIs(boat)
-- if Common.difficulty() == 1 then
-- if Common.difficulty_scale() == 1 then
-- Boats.upgrade_chests(boat, 'iron-chest')
-- Hold.upgrade_chests(1, 'iron-chest')
-- Crowsnest.upgrade_chests('iron-chest')
-- elseif Common.difficulty() > 1 then
-- elseif Common.difficulty_scale() > 1 then
-- Boats.upgrade_chests(boat, 'steel-chest')
-- Hold.upgrade_chests(1, 'steel-chest')
-- Crowsnest.upgrade_chests('steel-chest')
@ -462,7 +462,7 @@ function Public.try_retreat_from_island(player, manual) -- Assumes the cost can
end
else
if player and Common.validate_player(player) then
Common.notify_player_error(player.force, 'Undock error: Not enough resources stored in the captain\'s cabin.')
Common.notify_force_error(player.force, 'Undock error: Not enough resources stored in the captain\'s cabin.')
end
end
end
@ -538,7 +538,7 @@ function Public.go_from_currentdestination_to_sea()
if memory.overworldx == 0 and memory.boat then
local difficulty_name = CoreData.get_difficulty_name_from_value(Common.difficulty())
local difficulty_name = CoreData.get_difficulty_name_from_value(memory.difficulty)
if difficulty_name == CoreData.difficulty_options[#CoreData.difficulty_options].text then
Boats.upgrade_chests(boat, 'steel-chest')
Hold.upgrade_chests(1, 'steel-chest')

View File

@ -44,12 +44,16 @@ function Public.quest_reward()
ret = {name = 'iron-plate', count = Math.ceil(2000 * multiplier), display_sprite = '[item=iron-plate]', display_amount = string.format('%.1fk', 2 * multiplier), chat_name = '[item=iron-plate]'}
elseif rng <= 0.5 then
ret = {name = 'copper-plate', count = Math.ceil(2000 * multiplier), display_sprite = '[item=copper-plate]', display_amount = string.format('%.1fk', 2 * multiplier), chat_name = '[item=copper-plate]'}
elseif rng <= 0.6 then
ret = {name = 'steel-plate', count = Math.ceil(380 * multiplier), display_sprite = '[item=steel-plate]', display_amount = string.format('%.0f', 380 * multiplier), chat_name = '[item=steel-plate]'}
elseif rng <= 0.7 then
ret = {name = 'solid-fuel', count = Math.ceil(450 * multiplier), display_sprite = '[item=solid-fuel]', display_amount = string.format('%.0f', Math.ceil(450 * multiplier)), chat_name = '[item=solid-fuel]'}
elseif rng <= 0.9 then
ret = {name = 'coin', count = Math.ceil(6000 * (multiplier^(1/2))), display_sprite = '[item=coin]', display_amount = string.format('%.1fk', Math.ceil(6 * (multiplier^(1/2)))), chat_name = 'doubloons'}
else
ret = {name = 'raw-fish', count = Math.ceil(420 * (multiplier^(1/2))), display_sprite = '[item=raw-fish]', display_amount = string.format('%.1fk', 0.42 * (multiplier^(1/2))), chat_name = '[item=raw-fish]'}
elseif rng <= 0.85 then
ret = {name = 'piercing-rounds-magazine', count = Math.ceil(250 * multiplier), display_sprite = '[item=piercing-rounds-magazine]', display_amount = string.format('%.0f', Math.ceil(250 * multiplier)), chat_name = '[item=piercing-rounds-magazine]'}
elseif rng <= 0.94 then
ret = {name = 'solid-fuel', count = Math.ceil(450 * multiplier), display_sprite = '[item=solid-fuel]', display_amount = string.format('%.0f', Math.ceil(450 * multiplier)), chat_name = '[item=solid-fuel]'}
else
ret = {name = 'modular-armor', count = 1, display_sprite = '[item=modular-armor]', display_amount = '1', chat_name = '[item=modular-armor]'}
end
return ret
@ -65,16 +69,16 @@ function Public.initialise_random_quest()
if destination.destination_index == 2 then return end
local rng = Math.random(10)
if rng == 1 then
local rng = Math.random(100)
if rng <= 10 then
Public.initialise_nodamage_quest()
elseif rng <= 3 then
elseif rng <= 33 then
Public.initialise_worms_quest()
elseif rng <= 5 then
elseif rng <= 54 then
Public.initialise_time_quest()
elseif rng <= 7 then
elseif rng <= 74 then
Public.initialise_find_quest()
elseif rng <= 10 then
elseif rng <= 100 then
Public.initialise_resourcecount_quest()
-- Public.initialise_resourceflow_quest()
end
@ -173,7 +177,7 @@ function Public.initialise_resourcecount_quest()
destination.dynamic_data.quest_params.initial_count = force.item_production_statistics.get_flow_count{name = generated_production_quest.item, input = true, precision_index = defines.flow_precision_index.one_thousand_hours, count = true}
end
local progressneeded_before_rounding = generated_production_quest.base_rate * Balance.resource_quest_multiplier() * Common.difficulty()
local progressneeded_before_rounding = generated_production_quest.base_rate * Balance.resource_quest_multiplier() * Common.difficulty_scale()
destination.dynamic_data.quest_progressneeded = Math.ceil(progressneeded_before_rounding/10)*10
@ -200,10 +204,10 @@ function Public.initialise_worms_quest()
1 + 9 * Math.slopefromto(count, 0, 20) + 10 * Math.slopefromto(count, 20, 70)
)
if Common.difficulty() < 1 then needed = Math.max(1, needed - 3) end
if Common.difficulty() > 1 then needed = Math.max(1, needed + 2) end
if Common.difficulty_scale() < 1 then needed = Math.max(1, needed - 3) end
if Common.difficulty_scale() > 1 then needed = Math.max(1, needed + 2) end
local difficulty_name = CoreData.get_difficulty_name_from_value(Common.difficulty())
local difficulty_name = CoreData.get_difficulty_name_from_value(Common.difficulty_scale())
if difficulty_name == CoreData.difficulty_options[1].text then
needed = Math.max(1, needed - 3)
elseif difficulty_name ~= CoreData.difficulty_options[2].text then
@ -233,7 +237,7 @@ function Public.try_resolve_quest()
local force = memory.force
if not (force and force.valid) then return end
Common.notify_force_light(force,'Granted ' .. destination.dynamic_data.quest_reward.display_amount .. ' ' .. destination.dynamic_data.quest_reward.chat_name)
Common.notify_force_light(force,'Granted: ' .. destination.dynamic_data.quest_reward.display_amount .. ' ' .. destination.dynamic_data.quest_reward.chat_name)
local name = destination.dynamic_data.quest_reward.name
local count = destination.dynamic_data.quest_reward.count
@ -300,6 +304,9 @@ end
-- end
function Public.generate_flow_quest()
--@TODO: Ensure this function cannot return nil
--@TODO: This is related to a more general problem with raffles — how they handle game_completion being above 1. As of May '22, we cap game_completion at 1 before passing it to the raffle
local game_completion_progress = Common.game_completion_progress_capped()
local data = Public.flow_quest_data()
@ -332,21 +339,21 @@ end
Public.resourcecount_quest_data_raw = {
{1, 0, 1, false, 'iron-gear-wheel', 2400},
-- {1, 0, 1, false, 'electronic-circuit', 1400},
{1.2, 0, 1, false, 'transport-belt', 1600},
{1, 0, 1, false, 'repair-pack', 350},
{1.1, 0, 1, false, 'iron-gear-wheel', 2400},
{0.5, 0, 1, false, 'electronic-circuit', 1400},
{1.1, 0, 1, false, 'transport-belt', 1600},
{0.8, 0, 1, false, 'repair-pack', 350},
-- {0.1, 0, 1, false, 'red-wire', 500},
{0.5, 0, 1, false, 'empty-barrel', 200},
{0.3, 0, 0.2, false, 'underground-belt', 200},
{0.3, 0, 0.2, false, 'splitter', 150},
{0.4, 0.2, 1, false, 'fast-splitter', 60},
{0.4, 0.2, 1, false, 'fast-underground-belt', 75},
{0.5, 0.3, 1, false, 'big-electric-pole', 160},
{1.2, 0.61, 1, false, 'advanced-circuit', 350},
{0.4, 0, 1, false, 'empty-barrel', 200},
{0.7, 0, 0.5, false, 'underground-belt', 200},
{0.7, 0, 0.5, false, 'splitter', 150},
{0.35, 0.2, 1, false, 'fast-splitter', 60},
{0.35, 0.2, 1, false, 'fast-underground-belt', 75},
{0.7, 0.3, 1, false, 'big-electric-pole', 100},
{0.3, 0.61, 1, false, 'advanced-circuit', 350},
{1, 0, 1, false, 'shotgun-shell', 600},
{1.5, 0.9, 1, false, 'processing-unit', 40},
-- {0.3, 0.8, 1, false, 'electric-engine-unit', 1 * 6},
{1, 0.9, 1, false, 'processing-unit', 40},
{0.6, 0.8, 1, false, 'electric-engine-unit', 1 * 6},
}
function Public.resourcecount_quest_data()

View File

@ -73,18 +73,18 @@ Public.display_form = {
[enum.GOURMET] = 'Gourmet',
}
Public.explanation = {
[enum.DECKHAND] = 'They move faster and generate ore for the cabin whilst onboard above deck, but move slower offboard.',
[enum.DECKHAND] = 'They move faster and generate ore for the cabin whilst onboard above deck.',
[enum.FISHERMAN] = 'They fish at greater distance.',
[enum.SCOUT] = 'They are faster, but frail and deal less damage.',
[enum.SAMURAI] = 'They are tough, and *with no weapon equipped* fight well by melee, but poorly otherwise.',
[enum.MERCHANT] = 'They generate 40 doubloons per league.',
[enum.SHORESMAN] = 'They move slightly faster and generate ore for the cabin whilst offboard, but move slower onboard.',
[enum.BOATSWAIN] = 'They move faster and generate ore for the cabin whilst below deck, but move slower offboard.',
[enum.PROSPECTOR] = 'They find more resources when handmining ore.',
[enum.MERCHANT] = 'They generate 50 doubloons per league.',
[enum.SHORESMAN] = 'They move slightly faster and generate ore for the cabin whilst offboard.',
[enum.BOATSWAIN] = 'They move faster and generate ore for the cabin whilst below deck.',
[enum.PROSPECTOR] = 'They find more resources when handmining.',
[enum.LUMBERJACK] = 'They find more resources when chopping trees.',
[enum.MASTER_ANGLER] = 'They fish at much greater distance, and catch more.',
[enum.WOOD_LORD] = 'They find many more resources when chopping trees.',
[enum.CHIEF_EXCAVATOR] = 'They find many more resources when handmining ore.',
[enum.CHIEF_EXCAVATOR] = 'They find many more resources when handmining.',
[enum.HATAMOTO] = 'They are very tough, and *with no weapon equipped* fight well by melee, but poorly otherwise.',
[enum.IRON_LEG] = 'They are very resistant to damage when carrying 3500 iron ore.',
[enum.QUARTERMASTER] = 'They give nearby crewmates extra physical attack, and generate ore for the cabin for each one.',
@ -95,7 +95,7 @@ Public.explanation = {
Public.class_unlocks = {
[enum.FISHERMAN] = {enum.MASTER_ANGLER},
[enum.LUMBERJACK] = {enum.WOOD_LORD},
-- [enum.LUMBERJACK] = {enum.WOOD_LORD}, --not that interesting
-- [enum.PROSPECTOR] = {enum.CHIEF_EXCAVATOR}, --breaks the resource pressure in the game too strongly I think
[enum.SAMURAI] = {enum.HATAMOTO},
[enum.MASTER_ANGLER] = {enum.DREDGER},
@ -124,7 +124,7 @@ function Public.initial_class_pool()
enum.PROSPECTOR,
enum.LUMBERJACK,
enum.IRON_LEG,
enum.SMOLDERING,
-- enum.SMOLDERING,
enum.GOURMET,
}
end
@ -257,7 +257,7 @@ local function class_on_player_used_capsule(event)
elseif tile.name == CoreData.walkway_tile then
multiplier = 1
elseif tile.name == 'orange-refined-concrete' then
multiplier = 0.8
multiplier = 0.5
elseif tile.name == CoreData.enemy_landing_tile then
multiplier = 0.33
elseif tile.name == CoreData.static_boat_floor then

View File

@ -83,7 +83,7 @@ function Public.revoke_class(captain, player)
memory.spare_classes[#memory.spare_classes + 1] = memory.classes_table[player.index]
memory.classes_table[player.index] = nil
Common.notify_force_light(force, string.format('%s revoked %s from %s.', captain.name, Classes.display_form[memory.classes_table[player.index]]), player.name)
Common.notify_force_light(force, string.format('%s revoked %s from %s.', captain.name, Classes.display_form[memory.classes_table[player.index]], player.name))
end
end
@ -381,11 +381,11 @@ function Public.assign_captain_based_on_priorities(excluded_player_index)
end
function Public.captain_requisition(captain_index)
function Public.captain_tax(captain_index)
local memory = Memory.get_crew_memory()
local any_taken = false
local items_to_req = {'coin', 'uranium-235'}
local items_to_req = {'coin', 'rail-signal', 'uranium-235'}
local item_count_table = {}
for _, i in pairs(items_to_req) do
@ -406,6 +406,7 @@ function Public.captain_requisition(captain_index)
if inv and inv.valid then
for _, i in pairs(items_to_req) do
local amount = inv.get_item_count(i)
if i == 'coin' then amount = Math.floor(amount/10) end
if amount and amount > 0 then
inv.remove{name=i, count=amount}
captain_inv.insert{name=i, count=amount}
@ -435,7 +436,7 @@ function Public.captain_requisition(captain_index)
end
if any_taken then
local str = 'The captain requisitioned '
local str = 'The captain taxed '
local j = 1
for i = 1, #items_to_req do
local item = items_to_req[i]
@ -461,7 +462,7 @@ function Public.captain_requisition(captain_index)
str = str .. '.'
Common.notify_force(memory.force, str)
else
Common.notify_player_error(captain, 'No important items found in crewmates\' inventories or cursor stacks.')
Common.notify_player_error(captain, 'No coins or game-critical found in crewmates\' inventories or cursor stacks.')
end
end
end
@ -553,9 +554,9 @@ function Public.add_player_to_permission_group(player, group_override)
group.set_allows_action(defines.input_action.activate_paste, false)
group.set_allows_action(defines.input_action.upgrade, false)
group.set_allows_action(defines.input_action.grab_blueprint_record, false)
if not CoreData.blueprint_library_allowed then
group.set_allows_action(defines.input_action.open_blueprint_library_gui, false)
group.set_allows_action(defines.input_action.grab_blueprint_record, false)
end
if not CoreData.blueprint_importing_allowed then
group.set_allows_action(defines.input_action.import_blueprint_string, false)
@ -572,9 +573,9 @@ function Public.add_player_to_permission_group(player, group_override)
plebs_group.set_allows_action(defines.input_action.add_permission_group, false)
plebs_group.set_allows_action(defines.input_action.admin_action, false)
plebs_group.set_allows_action(defines.input_action.grab_blueprint_record, false)
if not CoreData.blueprint_library_allowed then
plebs_group.set_allows_action(defines.input_action.open_blueprint_library_gui, false)
plebs_group.set_allows_action(defines.input_action.grab_blueprint_record, false)
end
if not CoreData.blueprint_importing_allowed then
plebs_group.set_allows_action(defines.input_action.import_blueprint_string, false)

View File

@ -1,26 +1,30 @@
local Memory = require 'maps.pirates.memory'
-- local Roles = require 'maps.pirates.roles.roles'
local Balance = require 'maps.pirates.balance'
local Common = require 'maps.pirates.common'
-- local Balance = require 'maps.pirates.balance'
-- local Common = require 'maps.pirates.common'
-- local Utils = require 'maps.pirates.utils_local'
-- local Math = require 'maps.pirates.math'
-- local Loot = require 'maps.pirates.loot'
local _inspect = require 'utils.inspect'.inspect
local Upgrades = require 'maps.pirates.boat_upgrades'
-- local Hold = require 'maps.pirates.surfaces.hold'
local Crew = require 'maps.pirates.crew'
local Boats = require 'maps.pirates.structures.boats.boats'
local Dock = require 'maps.pirates.surfaces.dock'
-- local Crew = require 'maps.pirates.crew'
-- local Boats = require 'maps.pirates.structures.boats.boats'
-- local Dock = require 'maps.pirates.surfaces.dock'
local CustomEvents = require 'maps.pirates.custom_events'
local Public = {}
-- Note! This file is deprecated. It is replaced with a dedicated market at the dock and inside the captain's cabin. The exception is main_shop_data_1 as noted below, which is consulted for the Crowsnest caption. (Haven't had time to unify this yet.)
--== Warning: If something only costs fuel, then we need to check the player can't buy it whilst they're dead
-- WARNING: The Crowsnest caption pulls data from this data. But the actual dock market pulls from boat_upgrades.lua.
Public.main_shop_data_1 = {
repair_cannons = {
tooltip = 'Repair the cannons.',
@ -66,22 +70,22 @@ Public.main_shop_data_1 = {
[Upgrades.enum.MORE_POWER] = {
tooltip = 'Upgrade the ship\'s power.',
what_you_get_sprite_buttons = {['utility/status_working'] = false},
base_cost = {coins = 5000, fuel = 500},
base_cost = {coins = 7000, fuel = 500},
},
[Upgrades.enum.EXTRA_HOLD] = {
tooltip = 'Upgrade the ship\'s hold.',
what_you_get_sprite_buttons = {['item/steel-chest'] = false},
base_cost = {coins = 10000, fuel = 2000},
base_cost = {coins = 7000, fuel = 500},
},
[Upgrades.enum.UNLOCK_MERCHANTS] = {
tooltip = 'Unlock merchant ships.',
what_you_get_sprite_buttons = {['entity/market'] = false},
base_cost = {coins = 10000, fuel = 2000},
base_cost = {coins = 14000, fuel = 1000},
},
[Upgrades.enum.ROCKETS_FOR_SALE] = {
tooltip = 'Unlock rockets for sale at covered-up markets.',
what_you_get_sprite_buttons = {['item/rocket-launcher'] = false},
base_cost = {coins = 15000, fuel = 2000},
base_cost = {coins = 21000, fuel = 1000},
},
}
@ -142,192 +146,195 @@ function Public.initialise_captains_shop()
script.raise_event(CustomEvents.enum['update_crew_fuel_gui'], {})
end
function Public.main_shop_try_purchase(player, purchase_name)
local memory = Memory.get_crew_memory()
local destination = Common.current_destination()
local shop_data_1 = Public.main_shop_data_1
local shop_data_2 = Public.main_shop_data_2
local trade_data = shop_data_1[purchase_name] or shop_data_2[purchase_name]
if not trade_data then return end
-- function Public.main_shop_try_purchase(player, purchase_name)
-- local memory = Memory.get_crew_memory()
-- local destination = Common.current_destination()
-- local shop_data_1 = Public.main_shop_data_1
-- local shop_data_2 = Public.main_shop_data_2
-- 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
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 stored_fuel = memory.stored_fuel
-- 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 and inv.valid) then return end
-- local inv = player.get_inventory(defines.inventory.character_main)
-- if not (inv and inv.valid) then return end
local multiplier = Balance.main_shop_cost_multiplier()
-- local multiplier = Balance.main_shop_cost_multiplier()
-- local rate_limit_ok = not (memory.mainshop_rate_limit_ticker and memory.mainshop_rate_limit_ticker > 0)
local rate_limit_ok = true
local enough_fuel = true
local enough_iron_plates = true
local enough_coins = true
local enough_copper_plates = true
local coins_got
local iron_plates_got
local copper_plates_got
-- local able_to_buy_boats = memory.boat.state == Boats.enum_state.DOCKED --disabled for now
local able_to_buy_boats = false
-- local able_to_buy_boats = (memory.boat.state == Boats.enum_state.DOCKED or memory.boat.state == Boats.enum_state.APPROACHING) --problem with this if you buy whilst approaching, the original one no longer moves
-- -- local rate_limit_ok = not (memory.mainshop_rate_limit_ticker and memory.mainshop_rate_limit_ticker > 0)
-- local rate_limit_ok = true
-- local enough_fuel = true
-- local enough_iron_plates = true
-- local enough_coins = true
-- local enough_copper_plates = true
-- local coins_got
-- local iron_plates_got
-- local copper_plates_got
-- -- local able_to_buy_boats = memory.boat.state == Boats.enum_state.DOCKED --disabled for now
-- local able_to_buy_boats = false
-- -- local able_to_buy_boats = (memory.boat.state == Boats.enum_state.DOCKED or memory.boat.state == Boats.enum_state.APPROACHING) --problem with this if you buy whilst approaching, the original one no longer moves
for k, v in pairs(trade_data.base_cost) do
if k == 'fuel' then
enough_fuel = (stored_fuel >= v * multiplier)
elseif k == 'coins' then
coins_got = inv.get_item_count('coin')
enough_coins = coins_got >= v * multiplier
elseif k == 'iron_plates' then
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 = inv.get_item_count('copper-plate')
enough_copper_plates = copper_plates_got >= v * multiplier
end
end
-- for k, v in pairs(trade_data.base_cost) do
-- if k == 'fuel' then
-- enough_fuel = (stored_fuel >= v * multiplier)
-- elseif k == 'coins' then
-- coins_got = inv.get_item_count('coin')
-- enough_coins = coins_got >= v * multiplier
-- elseif k == 'iron_plates' then
-- 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 = inv.get_item_count('copper-plate')
-- enough_copper_plates = copper_plates_got >= v * multiplier
-- end
-- end
local can_buy = rate_limit_ok and enough_coins and enough_fuel and enough_iron_plates and enough_copper_plates
-- local can_buy = rate_limit_ok and enough_coins and enough_fuel and enough_iron_plates and enough_copper_plates
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
-- 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
-- -- @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
inv.remove{name="coin", count=v * multiplier}
elseif k == 'iron_plates' then
inv.remove{name="iron-plate", count=v * multiplier}
elseif k == 'copper_plates' then
inv.remove{name="copper-plate", count=v * multiplier}
end
end
-- 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
-- inv.remove{name="coin", count=v * multiplier}
-- elseif k == 'iron_plates' then
-- inv.remove{name="iron-plate", count=v * multiplier}
-- elseif k == 'copper_plates' then
-- inv.remove{name="copper-plate", count=v * multiplier}
-- end
-- end
local force = memory.force
if not (force and force.valid) then return end
-- local force = memory.force
-- if not (force and force.valid) then return end
local gotamount
if purchase_name == 'uranium_ore' then
gotamount = trade_data.what_you_get_sprite_buttons['item/uranium-238']
Common.give(player, {{name = 'uranium-238', count = gotamount}})
Common.notify_force_light(force,string.format('%s is buying green rocks...', player.name))
-- local gotamount
-- if purchase_name == 'uranium_ore' then
-- gotamount = trade_data.what_you_get_sprite_buttons['item/uranium-238']
-- Common.give(player, {{name = 'uranium-238', count = gotamount}})
-- Common.notify_force_light(force,string.format('%s is buying green rocks...', player.name))
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...', player.name))
else
Common.notify_player_error(player, string.format('Purchase error: Can\'t buy more time than this.', player.name))
-- refund:
memory.stored_fuel = memory.stored_fuel + trade_data.base_cost.fuel * multiplier
end
-- 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...', player.name))
-- else
-- Common.notify_player_error(player, string.format('Purchase error: Can\'t buy more time than this.', player.name))
-- -- refund:
-- memory.stored_fuel = memory.stored_fuel + trade_data.base_cost.fuel * multiplier
-- end
elseif purchase_name == 'rail_signal' then
gotamount = trade_data.what_you_get_sprite_buttons['item/rail-signal']
Common.give(player, {{name = 'rail-signal', count = gotamount}})
Common.notify_force_light(force,string.format('%s is buying signals...', player.name))
-- elseif purchase_name == 'rail_signal' then
-- gotamount = trade_data.what_you_get_sprite_buttons['item/rail-signal']
-- Common.give(player, {{name = 'rail-signal', count = gotamount}})
-- Common.notify_force_light(force,string.format('%s is buying signals...', player.name))
elseif purchase_name == 'artillery_shell' then
gotamount = trade_data.what_you_get_sprite_buttons['item/artillery-shell']
Common.give(player, {{name = 'artillery-shell', count = gotamount}})
Common.notify_force_light(force,string.format('%s is buying cannon shells...', player.name))
-- elseif purchase_name == 'artillery_shell' then
-- gotamount = trade_data.what_you_get_sprite_buttons['item/artillery-shell']
-- Common.give(player, {{name = 'artillery-shell', count = gotamount}})
-- Common.notify_force_light(force,string.format('%s is buying cannon shells...', player.name))
elseif purchase_name == 'artillery_remote' then
gotamount = trade_data.what_you_get_sprite_buttons['item/artillery-targeting-remote']
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 purchase_name == 'artillery_remote' then
-- gotamount = trade_data.what_you_get_sprite_buttons['item/artillery-targeting-remote']
-- 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 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(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 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(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 purchase_name == 'repair_cannons' then
-- heal all cannons:
local cannons = game.surfaces[destination.surface_name].find_entities_filtered({type = 'artillery-turret'})
for _, c in pairs(cannons) do
c.health = c.prototype.max_health
end
Common.notify_force(force,string.format('[font=heading-1]%s repaired the cannons.[/font]', player.name))
memory.mainshop_availability_bools[purchase_name] = false
-- elseif purchase_name == 'repair_cannons' then
-- -- heal all cannons:
-- local cannons = game.surfaces[destination.surface_name].find_entities_filtered({type = 'artillery-turret'})
-- for _, c in pairs(cannons) do
-- local unit_number = c.unit_number
elseif purchase_name == Upgrades.enum.MORE_POWER then
Upgrades.execute_upgade(Upgrades.enum.MORE_POWER)
Common.notify_force(force,string.format('[font=heading-1]%s upgraded the ship\'s power.[/font]', player.name))
memory.mainshop_availability_bools[purchase_name] = false
-- local healthbar = memory.healthbars[unit_number]
-- if _DEBUG then game.print(unit_number) end
-- if healthbar then
-- healthbar.health = healthbar.max_health
-- Public.update_healthbar_rendering(healthbar, healthbar.max_health)
-- end
-- end
-- Common.notify_force(force,string.format('[font=heading-1]%s repaired the cannons.[/font]', player.name))
-- memory.mainshop_availability_bools[purchase_name] = false
elseif purchase_name == Upgrades.enum.EXTRA_HOLD then
Upgrades.execute_upgade(Upgrades.enum.EXTRA_HOLD)
Common.notify_force(force,string.format('[font=heading-1]%s upgraded the ship\'s hold.[/font]', player.name))
memory.mainshop_availability_bools[purchase_name] = false
-- elseif purchase_name == Upgrades.enum.MORE_POWER then
-- Upgrades.execute_upgade(Upgrades.enum.MORE_POWER)
-- memory.mainshop_availability_bools[purchase_name] = false
elseif purchase_name == Upgrades.enum.UNLOCK_MERCHANTS then
Upgrades.execute_upgade(Upgrades.enum.UNLOCK_MERCHANTS)
Common.notify_force(force,string.format('[font=heading-1]%s unlocked merchant ships.[/font]', player.name))
memory.mainshop_availability_bools[purchase_name] = false
-- elseif purchase_name == Upgrades.enum.EXTRA_HOLD then
-- Upgrades.execute_upgade(Upgrades.enum.EXTRA_HOLD)
-- memory.mainshop_availability_bools[purchase_name] = false
elseif purchase_name == Upgrades.enum.ROCKETS_FOR_SALE then
Upgrades.execute_upgade(Upgrades.enum.ROCKETS_FOR_SALE)
Common.notify_force(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 purchase_name == Upgrades.enum.UNLOCK_MERCHANTS then
-- Upgrades.execute_upgade(Upgrades.enum.UNLOCK_MERCHANTS)
-- memory.mainshop_availability_bools[purchase_name] = false
elseif purchase_name == 'sell_iron' then
gotamount = trade_data.what_you_get_sprite_buttons['item/coal']
Common.give(player, {{name = 'fuel', count = gotamount}})
Common.notify_force_light(force,string.format('%s is selling iron...', player.name))
-- elseif purchase_name == Upgrades.enum.ROCKETS_FOR_SALE then
-- Upgrades.execute_upgade(Upgrades.enum.ROCKETS_FOR_SALE)
-- memory.mainshop_availability_bools[purchase_name] = false
elseif purchase_name == 'buy_iron' then
gotamount = trade_data.what_you_get_sprite_buttons['item/iron-plate']
Common.give_items_to_crew{{name = 'iron-plate', count = gotamount}}
Common.notify_force_light(force,string.format('%s is buying iron...', player.name))
-- elseif purchase_name == 'sell_iron' then
-- gotamount = trade_data.what_you_get_sprite_buttons['item/coal']
-- Common.give(player, {{name = 'fuel', count = gotamount}})
-- Common.notify_force_light(force,string.format('%s is selling iron...', player.name))
elseif purchase_name == 'buy_copper' then
gotamount = trade_data.what_you_get_sprite_buttons['item/copper-plate']
Common.give_items_to_crew{{name = 'copper-plate', count = gotamount}}
Common.notify_force_light(force,string.format('%s is buying copper...', player.name))
-- elseif purchase_name == 'buy_iron' then
-- gotamount = trade_data.what_you_get_sprite_buttons['item/iron-plate']
-- Common.give_items_to_crew{{name = 'iron-plate', count = gotamount}}
-- Common.notify_force_light(force,string.format('%s is buying iron...', player.name))
-- elseif name == 'buy_fast_loader' then
-- gotamount = trade_data.what_you_get_sprite_buttons['item/fast-loader']
-- Common.give(player, {{name = 'fast-loader', count = gotamount}})
-- Common.notify_force_light(force,string.format('%s bought a fast loader...', player.name))
-- elseif purchase_name == 'buy_copper' then
-- gotamount = trade_data.what_you_get_sprite_buttons['item/copper-plate']
-- Common.give_items_to_crew{{name = 'copper-plate', count = gotamount}}
-- Common.notify_force_light(force,string.format('%s is buying copper...', player.name))
elseif purchase_name == 'sell_copper' then
gotamount = trade_data.what_you_get_sprite_buttons['item/coal']
Common.give(player, {{name = 'fuel', count = gotamount}})
Common.notify_force_light(force,string.format('%s is selling copper...', player.name))
-- -- elseif name == 'buy_fast_loader' then
-- -- gotamount = trade_data.what_you_get_sprite_buttons['item/fast-loader']
-- -- Common.give(player, {{name = 'fast-loader', count = gotamount}})
-- -- Common.notify_force_light(force,string.format('%s bought a fast loader...', player.name))
end
-- elseif purchase_name == 'sell_copper' then
-- gotamount = trade_data.what_you_get_sprite_buttons['item/coal']
-- Common.give(player, {{name = 'fuel', count = gotamount}})
-- Common.notify_force_light(force,string.format('%s is selling copper...', player.name))
script.raise_event(CustomEvents.enum['update_crew_fuel_gui'], {})
-- end
-- memory.mainshop_rate_limit_ticker = Common.mainshop_rate_limit_ticks
else
-- play sound?
if rate_limit_ok == false then
Common.notify_player_error(player, 'Purchase error: Shop rate limit exceeded.')
end
if enough_fuel == false then
Common.notify_player_error(player, 'Purchase error: Not enough stored fuel.')
end
if enough_coins == false then
Common.notify_player_error(player, 'Purchase error: Not enough doubloons.')
end
if enough_iron_plates == false then
Common.notify_player_error(player, 'Purchase error: Not enough iron plates.')
end
if enough_copper_plates == false then
Common.notify_player_error(player, 'Purchase error: Not enough copper plates.')
end
-- script.raise_event(CustomEvents.enum['update_crew_fuel_gui'], {})
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, 'Purchase error: Not able to purchase ships right now.')
end
end
end
-- -- memory.mainshop_rate_limit_ticker = Common.mainshop_rate_limit_ticks
-- else
-- -- play sound?
-- if rate_limit_ok == false then
-- Common.notify_player_error(player, 'Purchase error: Shop rate limit exceeded.')
-- end
-- if enough_fuel == false then
-- Common.notify_player_error(player, 'Purchase error: Not enough stored fuel.')
-- end
-- if enough_coins == false then
-- Common.notify_player_error(player, 'Purchase error: Not enough doubloons.')
-- end
-- if enough_iron_plates == false then
-- Common.notify_player_error(player, 'Purchase error: Not enough iron plates.')
-- end
-- if enough_copper_plates == false then
-- Common.notify_player_error(player, 'Purchase error: 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, 'Purchase error: Not able to purchase ships right now.')
-- end
-- end
-- end
return Public

View File

@ -23,35 +23,35 @@ Public.enum = enum
Public.offers_loaders = {
{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}},
{price = {{'coin', 1800}}, offer = {type = 'give-item', item = 'loader', count = 1}},
{price = {{'coin', 3000}}, offer = {type = 'give-item', item = 'fast-loader', count = 1}},
{price = {{'coin', 4200}}, offer = {type = 'give-item', item = 'express-loader', count = 1}},
}
Public.offers_rockets = {
{price = {{'coin', 200}, {'electronic-circuit', 80}}, offer = {type = 'give-item', item = 'rocket-launcher', count = 1}},
{price = {{'coin', 1000}, {'explosives', 20}, {'electronic-circuit', 20}}, offer = {type = 'give-item', item = 'rocket', count = 20}},
{price = {{'coin', 250}, {'electronic-circuit', 80}}, offer = {type = 'give-item', item = 'rocket-launcher', count = 1}},
{price = {{'coin', 1200}, {'explosives', 20}, {'electronic-circuit', 20}}, offer = {type = 'give-item', item = 'rocket', count = 20}},
}
Public.offers_default = {
{price = {{'coin', 600}}, offer = {type = 'give-item', item = 'copper-plate', count = 150}},
{price = {{'coin', 600}}, offer = {type = 'give-item', item = 'iron-plate', count = 150}},
{price = {{'coin', 450}}, offer = {type = 'give-item', item = 'piercing-rounds-magazine', count = 14}},
{price = {{'coin', 700}}, offer = {type = 'give-item', item = 'heavy-armor', count = 1}},
{price = {{'coin', 400}}, offer = {type = 'give-item', item = 'grenade', count = 10}},
{price = {{'coin', 300}}, offer = {type = 'give-item', item = 'defender-capsule', count = 3}},
{price = {{'coin', 400}}, offer = {type = 'give-item', item = 'distractor-capsule', count = 3}},
{price = {{'coin', 500}}, offer = {type = 'give-item', item = 'slowdown-capsule', count = 5}},
{price = {{'coin', 500}}, offer = {type = 'give-item', item = 'poison-capsule', count = 5}},
{price = {{'coin', 500}}, offer = {type = 'give-item', item = 'gate', count = 10}},
{price = {{'coin', 100}}, offer = {type = 'give-item', item = 'storage-tank', count = 4}},
{price = {{'coin', 200}}, offer = {type = 'give-item', item = 'big-electric-pole', count = 8}},
{price = {{'coin', 200}}, offer = {type = 'give-item', item = 'steel-furnace', count = 4}},
{price = {{'coin', 300}}, offer = {type = 'give-item', item = 'stack-inserter', count = 3}},
{price = {{'coin', 750}}, offer = {type = 'give-item', item = 'piercing-shotgun-shell', count = 9}},
{price = {{'coin', 800}}, offer = {type = 'give-item', item = 'flamethrower', count = 1}},
{price = {{'coin', 1500}}, offer = {type = 'give-item', item = 'flamethrower-ammo', count = 4}},
{price = {{'coin', 1500}}, offer = {type = 'give-item', item = 'flying-robot-frame', count = 1}},
{price = {{'coin', 720}}, offer = {type = 'give-item', item = 'copper-plate', count = 150}},
{price = {{'coin', 720}}, offer = {type = 'give-item', item = 'iron-plate', count = 150}},
{price = {{'coin', 540}}, offer = {type = 'give-item', item = 'piercing-rounds-magazine', count = 14}},
{price = {{'coin', 840}}, offer = {type = 'give-item', item = 'heavy-armor', count = 1}},
{price = {{'coin', 480}}, offer = {type = 'give-item', item = 'grenade', count = 10}},
{price = {{'coin', 360}}, offer = {type = 'give-item', item = 'defender-capsule', count = 3}},
{price = {{'coin', 480}}, offer = {type = 'give-item', item = 'distractor-capsule', count = 3}},
{price = {{'coin', 600}}, offer = {type = 'give-item', item = 'slowdown-capsule', count = 5}},
{price = {{'coin', 600}}, offer = {type = 'give-item', item = 'poison-capsule', count = 5}},
{price = {{'coin', 720}}, offer = {type = 'give-item', item = 'gate', count = 10}},
{price = {{'coin', 120}}, offer = {type = 'give-item', item = 'storage-tank', count = 4}},
{price = {{'coin', 240}}, offer = {type = 'give-item', item = 'big-electric-pole', count = 8}},
{price = {{'coin', 240}}, offer = {type = 'give-item', item = 'steel-furnace', count = 4}},
{price = {{'coin', 360}}, offer = {type = 'give-item', item = 'stack-inserter', count = 3}},
{price = {{'coin', 900}}, offer = {type = 'give-item', item = 'piercing-shotgun-shell', count = 9}},
{price = {{'coin', 960}}, offer = {type = 'give-item', item = 'flamethrower', count = 1}},
{price = {{'coin', 1800}}, offer = {type = 'give-item', item = 'flamethrower-ammo', count = 5}},
{price = {{'coin', 1800}}, offer = {type = 'give-item', item = 'flying-robot-frame', count = 1}},
}

View File

@ -1,7 +1,7 @@
-- local Memory = require 'maps.pirates.memory'
-- local Roles = require 'maps.pirates.roles.roles'
local CoreData = require 'maps.pirates.coredata'
-- local CoreData = require 'maps.pirates.coredata'
local Classes = require 'maps.pirates.roles.classes'
-- local Crew = require 'maps.pirates.crew'
-- local Boats = require 'maps.pirates.structures.boats.boats'
@ -10,6 +10,7 @@ local Balance = require 'maps.pirates.balance'
local Common = require 'maps.pirates.common'
local Utils = require 'maps.pirates.utils_local'
local Math = require 'maps.pirates.math'
local Upgrades = require 'maps.pirates.boat_upgrades'
local _inspect = require 'utils.inspect'.inspect
-- local Upgrades = require 'maps.pirates.boat_upgrades'
@ -32,37 +33,39 @@ Public.market_barters = {
{price = {{'raw-fish', 50}}, offer = {type = 'give-item', item = 'copper-plate', count = 750}},
{price = {{'raw-fish', 50}}, offer = {type = 'give-item', item = 'steel-plate', count = 125}},
{price = {{'wood', 200}}, offer = {type = 'give-item', item = 'coin', count = 250}},
{price = {{'wood', 200}}, offer = {type = 'give-item', item = 'coin', count = 360}},
--TODO: add more complex trades
}
Public.market_permanent_offers = {
{price = {{'coin', 2400}}, offer = {type = 'give-item', item = 'iron-ore', count = 800}},
{price = {{'coin', 2400}}, offer = {type = 'give-item', item = 'copper-ore', count = 800}},
{price = {{'coin', 3000}}, offer = {type = 'give-item', item = 'crude-oil-barrel', count = 100}},
{price = {{'coin', 2500}}, offer = {type = 'give-item', item = 'fast-loader', count = 1}},
{price = {{'coin', 5000}}, offer = {type = 'give-item', item = 'beacon', count = 2}},
{price = {{'coin', 2800}}, offer = {type = 'give-item', item = 'speed-module-2', count = 2}},
{price = {{'pistol', 1}}, offer = {type = 'give-item', item = 'coin', count = Balance.coin_sell_amount}},
{price = {{'coin', 3600}}, offer = {type = 'give-item', item = 'iron-ore', count = 800}},
{price = {{'coin', 3600}}, offer = {type = 'give-item', item = 'copper-ore', count = 800}},
{price = {{'coin', 4200}}, offer = {type = 'give-item', item = 'crude-oil-barrel', count = 100}},
{price = {{'coin', 3600}}, offer = {type = 'give-item', item = 'fast-loader', count = 1}},
{price = {{'coin', 7200}}, offer = {type = 'give-item', item = 'beacon', count = 2}},
{price = {{'coin', 4200}}, offer = {type = 'give-item', item = 'speed-module-2', count = 2}},
{price = {{'coin', 28000}}, offer = {type = 'give-item', item = 'artillery-targeting-remote', count = 1}},
}
-- cheap but one-off
Public.market_sales = {
{price = {{'coin', 2000}}, offer = {type = 'give-item', item = 'coal', count = 900}},
{price = {{'coin', 2000}}, offer = {type = 'give-item', item = 'piercing-rounds-magazine', count = 75}},
{price = {{'coin', 2000}}, offer = {type = 'give-item', item = 'uranium-rounds-magazine', count = 30}},
{price = {{'coin', 2000}}, offer = {type = 'give-item', item = 'piercing-shotgun-shell', count = 50}},
{price = {{'coin', 2000}}, offer = {type = 'give-item', item = 'raw-fish', count = 300}},
{price = {{'coin', 2000}}, offer = {type = 'give-item', item = 'laser-turret', count = 1}},
{price = {{'coin', 2000}}, offer = {type = 'give-item', item = 'vehicle-machine-gun', count = 3}},
{price = {{'coin', 3000}}, offer = {type = 'give-item', item = 'modular-armor', count = 1}},
{price = {{'coin', 2000}}, offer = {type = 'give-item', item = 'distractor-capsule', count = 20}},
{price = {{'coin', 2000}}, offer = {type = 'give-item', item = 'poison-capsule', count = 20}},
{price = {{'coin', 2000}}, offer = {type = 'give-item', item = 'slowdown-capsule', count = 20}},
{price = {{'coin', 2000}}, offer = {type = 'give-item', item = 'coin', count = 4000}},
{price = {{'coin', 2000}}, offer = {type = 'give-item', item = 'roboport', count = 1}},
{price = {{'coin', 2000}}, offer = {type = 'give-item', item = 'construction-robot', count = 10}},
{price = {{'coin', 2000}}, offer = {type = 'give-item', item = 'logistic-chest-passive-provider', count = 2}},
{price = {{'coin', 2000}}, offer = {type = 'give-item', item = 'logistic-robot', count = 2}},
{price = {{'coin', 3000}}, offer = {type = 'give-item', item = 'coal', count = 900}},
{price = {{'coin', 3000}}, offer = {type = 'give-item', item = 'piercing-rounds-magazine', count = 75}},
{price = {{'coin', 3000}}, offer = {type = 'give-item', item = 'uranium-rounds-magazine', count = 30}},
{price = {{'coin', 3000}}, offer = {type = 'give-item', item = 'piercing-shotgun-shell', count = 50}},
{price = {{'coin', 3000}}, offer = {type = 'give-item', item = 'raw-fish', count = 300}},
{price = {{'coin', 3000}}, offer = {type = 'give-item', item = 'laser-turret', count = 1}},
{price = {{'coin', 3000}}, offer = {type = 'give-item', item = 'vehicle-machine-gun', count = 3}},
{price = {{'coin', 6000}}, offer = {type = 'give-item', item = 'modular-armor', count = 1}},
{price = {{'coin', 3000}}, offer = {type = 'give-item', item = 'distractor-capsule', count = 20}},
{price = {{'coin', 3000}}, offer = {type = 'give-item', item = 'poison-capsule', count = 20}},
{price = {{'coin', 3000}}, offer = {type = 'give-item', item = 'slowdown-capsule', count = 20}},
{price = {{'coin', 3000}}, offer = {type = 'give-item', item = 'coin', count = 6000}},
{price = {{'coin', 3000}}, offer = {type = 'give-item', item = 'roboport', count = 1}},
{price = {{'coin', 3000}}, offer = {type = 'give-item', item = 'construction-robot', count = 10}},
{price = {{'coin', 3000}}, offer = {type = 'give-item', item = 'logistic-chest-passive-provider', count = 2}},
{price = {{'coin', 3000}}, offer = {type = 'give-item', item = 'logistic-robot', count = 2}},
}
@ -108,13 +111,29 @@ Public.market_sales = {
function Public.create_dock_markets(surface, p)
-- local memory = Memory.get_crew_memory()
local destination = Common.current_destination()
if not (surface and p) then return end
local e
e = surface.create_entity{name = 'market', position = {x = p.x - 7, y = p.y}}
e = surface.create_entity{name = 'market', position = {x = p.x - 22, y = p.y - 1}, force = 'environment'}
if e and e.valid then
e.minable = false
e.rotatable = false
e.destructible = false
e.add_market_item{price = {{'repair-pack', 20}, {'coin', 1000}}, offer = {type = 'give-item', item = 'artillery-turret', count = 1}}
local upgrade_for_sale = Common.current_destination().static_params.upgrade_for_sale
if upgrade_for_sale then
e.add_market_item(Upgrades.market_offer_form[upgrade_for_sale])
end
destination.dynamic_data.dock_captains_market = e
end
e = surface.create_entity{name = 'market', position = {x = p.x - 7, y = p.y}, force = 'environment'}
if e and e.valid then
e.minable = false
e.rotatable = false
@ -125,7 +144,7 @@ function Public.create_dock_markets(surface, p)
end
end
e = surface.create_entity{name = 'market', position = {x = p.x, y = p.y - 1}}
e = surface.create_entity{name = 'market', position = {x = p.x, y = p.y - 1}, force = 'environment'}
if e and e.valid then
e.minable = false
e.rotatable = false
@ -147,23 +166,22 @@ function Public.create_dock_markets(surface, p)
end
-- new class offerings:
local destination = Common.current_destination()
if destination.static_params.class_for_sale then
e.add_market_item{price={{'coin', Balance.class_cost()}}, offer={type="nothing"}}
e.add_market_item{price={{'coin', Balance.class_cost()}}, offer={type="nothing", effect_description = 'Purchase the class ' .. Classes.display_form[destination.static_params.class_for_sale] .. '.'}}
destination.dynamic_data.market_class_offer_rendering = rendering.draw_text{
text = 'Class available: ' .. Classes.display_form[destination.static_params.class_for_sale],
surface = surface,
target = Utils.psum{e.position, {x = 0, y = -4}},
color = CoreData.colors.renderingtext_green,
scale = 2.5,
font = 'default-game',
alignment = 'center'
}
-- destination.dynamic_data.market_class_offer_rendering = rendering.draw_text{
-- text = 'Class available: ' .. Classes.display_form[destination.static_params.class_for_sale],
-- surface = surface,
-- target = Utils.psum{e.position, {x = 0, y = -4}},
-- color = CoreData.colors.renderingtext_green,
-- scale = 2.5,
-- font = 'default-game',
-- alignment = 'center'
-- }
end
end
e = surface.create_entity{name = 'market', position = {x = p.x + 7, y = p.y}}
e = surface.create_entity{name = 'market', position = {x = p.x + 7, y = p.y}, force = 'environment'}
if e and e.valid then
e.minable = false
e.rotatable = false

View File

@ -2,15 +2,17 @@
local Memory = require 'maps.pirates.memory'
-- local Roles = require 'maps.pirates.roles.roles'
local Classes = require 'maps.pirates.roles.classes'
-- local Crew = require 'maps.pirates.crew'
local Crew = require 'maps.pirates.crew'
-- local Boats = require 'maps.pirates.structures.boats.boats'
-- local Dock = require 'maps.pirates.surfaces.dock'
local Balance = require 'maps.pirates.balance'
local Common = require 'maps.pirates.common'
local Utils = require 'maps.pirates.utils_local'
local Roles = require 'maps.pirates.roles.roles'
local Math = require 'maps.pirates.math'
local _inspect = require 'utils.inspect'.inspect
local SurfacesCommon = require 'maps.pirates.surfaces.common'
local Upgrades = require 'maps.pirates.boat_upgrades'
-- local Upgrades = require 'maps.pirates.boat_upgrades'
local Public = {}
@ -21,14 +23,39 @@ Public.Minimarket = require 'maps.pirates.shop.dock'
function Public.event_on_market_item_purchased(event)
local player_index, market, offer_index, trade_count = event.player_index, event.market, event.offer_index, event.count
local player = game.players[player_index]
if not (market and market.valid and offer_index and Common.validate_player(player)) then return end
function Public.print_transaction(player, offer, price)
local s1 = ' traded away '
local s2 = ''
local s3 = offer.count .. ' ' .. offer.item
if offer.item == 'coin' then s1 = ' sold ' end
for i, p in pairs(price) do
local p2 = {name = p.name, amount = p.amount}
if p2.name == 'raw-fish' then p2.name = 'fish' end
if p2.name == 'coin' then
s1 = ' bought '
p2.name = 'doubloons'
end
if i > 1 then
if i == #price then
s2 = s2 .. ' and '
else
s2 = s2 .. ', '
end
end
s2 = s2 .. p2.amount .. ' ' .. p2.name
end
if s1 == ' sold ' or s1 == ' traded away ' then
Common.notify_force_light(player.force, player.name .. s1 .. s2 .. ' for ' .. s3 .. '.')
else
Common.notify_force_light(player.force, player.name .. s1 .. s3 .. ' for ' .. s2 .. '.')
end
end
local function purchaseData(market, player, offer_index)
--a proper rewriting of this function would directly check market entities against saved references to them in memory, but we haven't had time to rewrite it yet
local crew_id = tonumber(string.sub(player.force.name, -3, -1)) or nil
Memory.set_working_id(crew_id)
local memory = Memory.get_crew_memory()
local destination = Common.current_destination()
local alloffers = market.get_market_items()
@ -41,9 +68,6 @@ function Public.event_on_market_item_purchased(event)
offer_giveitem_count = this_offer.offer.count
end
local inv = player.get_inventory(defines.inventory.character_main)
-- check for BARTER vs STATIC vs ONE-OFF
-- One-off becomes unavailable after purchase, such as class purchase
-- Static doesn't decay
@ -56,144 +80,257 @@ function Public.event_on_market_item_purchased(event)
local special_purchase_bool = (offer_giveitem_name == 'rocket-launcher')
-- local special_purchase_bool = (offer_giveitem_name and (offer_giveitem_name == 'loader' or offer_giveitem_name == 'fast-loader' or offer_giveitem_name == 'express-loader' or offer_giveitem_name == 'rocket-launcher'))
if offer_type == 'nothing' then
local surface_name_decoded = SurfacesCommon.decode_surface_name(player.surface.name)
local type = surface_name_decoded.type
local in_captains_cabin = type and type == SurfacesCommon.enum.CABIN
local dock_upgrades_market = destination.dynamic_data.dock_captains_market and (destination.dynamic_data.dock_captains_market == market)
local permission_level_fail = (in_captains_cabin and Roles.player_privilege_level(player) < Roles.privilege_levels.OFFICER) or (dock_upgrades_market and Roles.player_privilege_level(player) < Roles.privilege_levels.OFFICER)
if in_captains_cabin then
decay_type = 'static'
elseif offer_type == 'nothing' or dock_upgrades_market then
decay_type = 'one-off'
elseif simple_efficiency_trade_bool or special_purchase_bool then
decay_type = 'static'
elseif dock_bool and purchase_bool and (offer_giveitem_name) and (offer_giveitem_name == 'stone' or offer_giveitem_name == 'iron-ore' or offer_giveitem_name == 'copper-ore' or offer_giveitem_name == 'crude-oil-barrel') then
decay_type = 'fast_decay'
elseif dock_bool and purchase_bool and (offer_giveitem_name) then
decay_type = 'one-off'
elseif simple_efficiency_trade_bool or special_purchase_bool then
decay_type = 'static'
elseif island_bool and (not (offer_giveitem_name and offer_giveitem_name == 'rocket')) then
decay_type = 'one-off'
else
decay_type = 'decay'
end
-- For everything but static, we want to disallow multi-purchases in this game, so refund any additional purchases:
if decay_type ~= 'static' and player and trade_count and trade_count > 1 then
return {
decay_type = decay_type,
price = price,
offer_type = offer_type,
offer_giveitem_name = offer_giveitem_name,
offer_giveitem_count = offer_giveitem_count,
dock_bool = dock_bool,
island_bool = island_bool,
purchase_bool = purchase_bool,
simple_efficiency_trade_bool = simple_efficiency_trade_bool,
special_purchase_bool = special_purchase_bool,
in_captains_cabin = in_captains_cabin,
dock_upgrades_market = dock_upgrades_market,
permission_level_fail = permission_level_fail,
}
end
function Public.event_on_market_item_purchased(event)
local player_index, market, offer_index, trade_count = event.player_index, event.market, event.offer_index, event.count
local player = game.players[player_index]
if not (market and market.valid and offer_index and Common.validate_player(player)) then return end
local crew_id = tonumber(string.sub(player.force.name, -3, -1)) or nil
Memory.set_working_id(crew_id)
local memory = Memory.get_crew_memory()
local destination = Common.current_destination()
local inv = player.get_inventory(defines.inventory.character_main)
local thisPurchaseData = purchaseData(market, player, offer_index)
local refunds = 0
-- Normally we want to disallow multi-purchases in this game (with the exception of static trades for items), so refund any additional purchases:
if (thisPurchaseData.decay_type ~= 'static' or thisPurchaseData.offer_type == 'nothing') and player and trade_count and trade_count > 1 then
inv = player.get_inventory(defines.inventory.character_main)
if not inv then return end
for _, p in pairs(price) do
for _, p in pairs(thisPurchaseData.price) do
inv.insert{name = p.name, count = p.amount * (trade_count - 1)}
end
if offer_type == 'give-item' then
inv.remove{name = offer_giveitem_name, count = offer_giveitem_count * (trade_count - 1)}
if thisPurchaseData.offer_type == 'give-item' then
inv.remove{name = thisPurchaseData.offer_giveitem_name, count = thisPurchaseData.offer_giveitem_count * (trade_count - 1)}
end
refunds = refunds + (trade_count - 1)
end
if thisPurchaseData.decay_type == 'one-off' then
local force = player.force
if thisPurchaseData.dock_upgrades_market then
if thisPurchaseData.offer_type == 'give-item' then
-- this is the dummy artillery purchase
inv.remove{name = thisPurchaseData.offer_giveitem_name, count = thisPurchaseData.offer_giveitem_count}
end
if thisPurchaseData.permission_level_fail then
Common.notify_player_error(player, string.format('Purchase error: You need to be a captain or officer to buy this.', player.name))
-- refund:
inv = player.get_inventory(defines.inventory.character_main)
if not inv then return end
for _, p in pairs(thisPurchaseData.price) do
inv.insert{name = p.name, count = p.amount}
end
refunds = refunds + 1
else
if thisPurchaseData.offer_type == 'give-item' then
-- heal all cannons:
local cannons = game.surfaces[destination.surface_name].find_entities_filtered({type = 'artillery-turret'})
for _, c in pairs(cannons) do
local unit_number = c.unit_number
local healthbar = memory.boat.healthbars[unit_number]
if healthbar then
healthbar.health = healthbar.max_health
Common.update_healthbar_rendering(healthbar, healthbar.max_health)
else
log('error: healthbar ' .. unit_number .. ' not found')
end
end
Common.notify_force(force,string.format('[font=heading-1]%s repaired the ship\'s cannons.[/font]', player.name))
market.remove_market_item(offer_index)
else
local upgrade_type = Common.current_destination().static_params.upgrade_for_sale
if upgrade_type then
Upgrades.execute_upgade(upgrade_type, player)
end
market.remove_market_item(offer_index)
end
end
else
if thisPurchaseData.offer_type == 'nothing' and destination.static_params.class_for_sale then
local class_for_sale = destination.static_params.class_for_sale
-- if not class_for_sale then return end
local required_class = Classes.class_purchase_requirement[class_for_sale]
local ok = true
-- check if they have the required class to buy it
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_force_error(force, string.format('Class purchase error: You need to be a %s to buy this.', Classes.display_form[required_class]))
end
end
if ok then
if required_class then
if force and force.valid then
Common.notify_force_light(force,string.format('%s upgraded their class from %s to %s. ([font=scenario-message-dialog]%s[/font])', player.name, Classes.display_form[required_class], Classes.display_form[class_for_sale], Classes.explanation[class_for_sale]))
end
else
-- check if they have a role already - renounce it if so
if memory.classes_table and memory.classes_table[player.index] then
Classes.try_renounce_class(player, false)
end
if force and force.valid then
Common.notify_force_light(force,string.format('%s bought the class %s. ([font=scenario-message-dialog]%s[/font])', player.name, Classes.display_form[class_for_sale], Classes.explanation[class_for_sale]))
end
end
memory.classes_table[player.index] = class_for_sale
memory.available_classes_pool = Utils.ordered_table_with_single_value_removed(memory.available_classes_pool, class_for_sale)
-- if destination.dynamic_data and destination.dynamic_data.market_class_offer_rendering then
-- rendering.destroy(destination.dynamic_data.market_class_offer_rendering)
-- end
market.remove_market_item(offer_index)
if Classes.class_unlocks[class_for_sale] then
for _, upgrade in pairs(Classes.class_unlocks[class_for_sale]) do
memory.available_classes_pool[#memory.available_classes_pool + 1] = upgrade
end
end
else
--refund
inv = player.get_inventory(defines.inventory.character_main)
if not inv then return end
for _, p in pairs(thisPurchaseData.price) do
inv.insert{name = p.name, count = p.amount}
end
refunds = refunds + 1
end
else
Common.notify_force_light(player.force, player.name .. ' bought ' .. thisPurchaseData.this_offer.offer.count .. ' ' .. thisPurchaseData.this_offer.offer.item .. ' for ' .. thisPurchaseData.price[1].amount .. ' ' .. thisPurchaseData.price[1].name .. '.')
market.remove_market_item(offer_index)
end
end
else
if thisPurchaseData.in_captains_cabin and thisPurchaseData.permission_level_fail then
Common.notify_player_error(player, string.format('Purchase error: You need to be a captain or officer to buy this.', player.name))
-- refund:
inv = player.get_inventory(defines.inventory.character_main)
if not inv then return end
for _, p in pairs(thisPurchaseData.price) do
inv.insert{name = p.name, count = p.amount}
end
if thisPurchaseData.offer_type == 'give-item' then
inv.remove{name = thisPurchaseData.offer_giveitem_name, count = thisPurchaseData.offer_giveitem_count}
end
refunds = refunds + 1
else
-- print:
if (thisPurchaseData.price and thisPurchaseData.price[1]) then
if not (thisPurchaseData.price[1].name and thisPurchaseData.price[1].name == 'burner-mining-drill') then --this one is too boring to announce
if thisPurchaseData.in_captains_cabin and thisPurchaseData.offer_type == 'nothing' then
local price_name = thisPurchaseData.price[1].name
Common.notify_force_light(player.force, player.name .. ' bought extra time at sea for ' .. thisPurchaseData.price[1].amount .. ' ' .. price_name .. '.')
else
Public.print_transaction(player, thisPurchaseData.this_offer.offer, thisPurchaseData.price)
end
end
end
if thisPurchaseData.in_captains_cabin and thisPurchaseData.offer_type == 'nothing' then
local success = Crew.try_add_extra_time_at_sea(60 * 60)
if not success then
Common.notify_player_error(player, string.format('Purchase error: Reached the maximum allowed loading time.', player.name))
-- refund:
inv = player.get_inventory(defines.inventory.character_main)
if not inv then return end
for _, p in pairs(thisPurchaseData.price) do
inv.insert{name = p.name, count = p.amount}
end
refunds = refunds + 1
end
else
if thisPurchaseData.decay_type == 'static' then
if not inv then return end
local flying_text_color = {r = 255, g = 255, b = 255}
local text1 = '[color=1,1,1]+' .. thisPurchaseData.this_offer.offer.count .. '[/color] [item=' .. thisPurchaseData.alloffers[offer_index].offer.item .. ']'
local text2 = '[color=' .. flying_text_color.r .. ',' .. flying_text_color.g .. ',' .. flying_text_color.b .. '](' .. inv.get_item_count(thisPurchaseData.alloffers[offer_index].offer.item) .. ')[/color]'
Common.flying_text(player.surface, player.position, text1 .. ' [font=count-font]' .. text2 .. '[/font]')
else
local decay_param = Balance.barter_decay_parameter()
if thisPurchaseData.decay_type == 'fast_decay' then decay_param = Balance.barter_decay_parameter()^3 end
if not inv then return end
local flying_text_color = {r = 255, g = 255, b = 255}
local text1 = '[color=1,1,1]+' .. thisPurchaseData.this_offer.offer.count .. '[/color] [item=' .. thisPurchaseData.alloffers[offer_index].offer.item .. ']'
local text2 = '[color=' .. flying_text_color.r .. ',' .. flying_text_color.g .. ',' .. flying_text_color.b .. '](' .. inv.get_item_count(thisPurchaseData.this_offer.offer.item) .. ')[/color]'
Common.flying_text(player.surface, player.position, text1 .. ' [font=count-font]' .. text2 .. '[/font]')
--update market trades:
thisPurchaseData.alloffers[offer_index].offer.count = Math.max(Math.floor(thisPurchaseData.alloffers[offer_index].offer.count * decay_param),1)
market.clear_market_items()
for _, offer in pairs(thisPurchaseData.alloffers) do
market.add_market_item(offer)
end
end
end
end
end
if decay_type == 'one-off' then
local force = player.force
if offer_type == 'nothing' and destination.static_params.class_for_sale then
local class_for_sale = destination.static_params.class_for_sale
-- if not class_for_sale then return end
local required_class = Classes.class_purchase_requirement[class_for_sale]
local ok = true
-- check if they have the required class to buy it
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_force_error(force, string.format('Class purchase error: You need to be a %s to buy this.', Classes.display_form[required_class]))
end
end
if ok then
if required_class then
if force and force.valid then
Common.notify_force_light(force,string.format('%s upgraded their class from %s to %s. ([font=scenario-message-dialog]%s[/font])', player.name, Classes.display_form[required_class], Classes.display_form[class_for_sale], Classes.explanation[class_for_sale]))
end
else
-- check if they have a role already - renounce it if so
if memory.classes_table and memory.classes_table[player.index] then
Classes.try_renounce_class(player, false)
end
if force and force.valid then
Common.notify_force_light(force,string.format('%s bought the class %s. ([font=scenario-message-dialog]%s[/font])', player.name, Classes.display_form[class_for_sale], Classes.explanation[class_for_sale]))
end
end
memory.classes_table[player.index] = class_for_sale
memory.available_classes_pool = Utils.ordered_table_with_single_value_removed(memory.available_classes_pool, class_for_sale)
if destination.dynamic_data and destination.dynamic_data.market_class_offer_rendering then
rendering.destroy(destination.dynamic_data.market_class_offer_rendering)
end
market.remove_market_item(offer_index)
if Classes.class_unlocks[class_for_sale] then
for _, upgrade in pairs(Classes.class_unlocks[class_for_sale]) do
memory.available_classes_pool[#memory.available_classes_pool + 1] = upgrade
end
end
else
--refund
inv = player.get_inventory(defines.inventory.character_main)
if not inv then return end
for _, p in pairs(price) do
inv.insert{name = p.name, count = p.amount}
end
end
else
Common.notify_force_light(player.force, player.name .. ' bought ' .. this_offer.offer.count .. ' ' .. this_offer.offer.item .. ' for ' .. price[1].amount .. ' ' .. price[1].name .. '.')
market.remove_market_item(offer_index)
end
else
-- print:
if (price and price[1]) then
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 .. ' traded away ' .. price[1].amount .. ' ' .. price[1].name .. ' and ' .. fish .. ' for ' .. this_offer.offer.count .. ' ' .. this_offer.offer.item .. '.')
else
if price[1].name == 'coin' then
Common.notify_force_light(player.force, player.name .. ' bought ' ..this_offer.offer.count .. ' ' .. this_offer.offer.item .. ' for ' .. price[1].amount .. ' ' .. price[1].name .. '.')
elseif this_offer.offer.item == 'coin' then
local sold_amount = price[1].amount
if sold_amount == 1 then sold_amount = 'a' end
Common.notify_force_light(player.force, player.name .. ' sold ' .. sold_amount .. ' ' .. price[1].name .. ' for ' .. this_offer.offer.count .. ' ' .. this_offer.offer.item .. '.')
else
Common.notify_force_light(player.force, player.name .. ' traded away ' .. price[1].amount .. ' ' .. price[1].name .. ' for ' .. this_offer.offer.count .. ' ' .. this_offer.offer.item .. '.')
end
end
end
end
if decay_type == 'static' then
if not inv then return end
local flying_text_color = {r = 255, g = 255, b = 255}
local text1 = '[color=1,1,1]+' .. this_offer.offer.count .. '[/color] [item=' .. alloffers[offer_index].offer.item .. ']'
local text2 = '[color=' .. flying_text_color.r .. ',' .. flying_text_color.g .. ',' .. flying_text_color.b .. '](' .. inv.get_item_count(alloffers[offer_index].offer.item) .. ')[/color]'
Common.flying_text(player.surface, player.position, text1 .. ' [font=count-font]' .. text2 .. '[/font]')
else
local decay_param = Balance.barter_decay_parameter()
if decay_type == 'fast_decay' then decay_param = Balance.barter_decay_parameter()^3 end
if not inv then return end
local flying_text_color = {r = 255, g = 255, b = 255}
local text1 = '[color=1,1,1]+' .. this_offer.offer.count .. '[/color] [item=' .. alloffers[offer_index].offer.item .. ']'
local text2 = '[color=' .. flying_text_color.r .. ',' .. flying_text_color.g .. ',' .. flying_text_color.b .. '](' .. inv.get_item_count(this_offer.offer.item) .. ')[/color]'
Common.flying_text(player.surface, player.position, text1 .. ' [font=count-font]' .. text2 .. '[/font]')
--update market trades:
alloffers[offer_index].offer.count = Math.max(Math.floor(alloffers[offer_index].offer.count * decay_param),1)
market.clear_market_items()
for _, offer in pairs(alloffers) do
market.add_market_item(offer)
end
end
if thisPurchaseData.this_offer.offer.item == 'coin' and refunds < trade_count then
memory.playtesting_stats.coins_gained_by_markets = memory.playtesting_stats.coins_gained_by_markets + thisPurchaseData.this_offer.offer.count
end
end

View File

@ -312,7 +312,8 @@ function Public.place_boat(boat, floor_tile, place_entities_bool, correct_tiles,
if e and e.valid then
e.minable = false
if p.y > 0 then e.direction = defines.direction.south end
-- boat.cannons[#boat.cannons + 1] = e
if not boat.cannons_temporary_reference then boat.cannons_temporary_reference = {} end
boat.cannons_temporary_reference[#boat.cannons_temporary_reference + 1] = e
end
local wall1,wall2,wall3 = surface.create_entity({name = 'stone-wall', position = {x = p2.x+1, y = p2.y}, force = boat.force_name, create_build_effect_smoke = false}),surface.create_entity({name = 'stone-wall', position = {x = p2.x, y = p2.y}, force = boat.force_name, create_build_effect_smoke = false}),surface.create_entity({name = 'stone-wall', position = {x = p2.x-1, y = p2.y}, force = boat.force_name, create_build_effect_smoke = false})
if wall1 and wall2 and wall3 and wall1.valid and wall2.valid and wall3.valid then
@ -694,6 +695,7 @@ end
local function process_entity_on_boat_unteleportable(memory, boat, newsurface, vector, players_just_offside, oldsurface_name, newsurface_name, e, name)
local un = e.unit_number
local p = e.position
local p2 = {x = p.x + vector.x, y = p.y + vector.y}
@ -709,6 +711,7 @@ local function process_entity_on_boat_unteleportable(memory, boat, newsurface, v
-- end
local ee = e.clone{position = p2, surface = newsurface, force = e.force, create_build_effect_smoke = false}
if ee and ee.valid then
e.destroy()
else
@ -723,6 +726,10 @@ local function process_entity_on_boat_unteleportable(memory, boat, newsurface, v
if ee and ee.valid then
if un and boat.healthbars and boat.healthbars[un] then
Common.transfer_healthbar(un, ee, boat) --for some reason I don't understand, if the old healthbars is contained within memory rather than boat, sometimes this function can't find them (observed during the initial ship launch)
end
if name == 'artillery-turret' then
-- if friendlyboat_bool then
-- if memory.enemyboatcannons then memory.enemyboatcannons[#memory.enemyboatcannons + 1] = ee end
@ -1000,8 +1007,8 @@ local function teleport_handle_wake_tiles(boat, dummyboat, newsurface_name, olds
for _, area in pairs(wakeareas) do
for _, p in pairs(Common.central_positions_within_area(area, adjustednewposition)) do
local t = old_water_tile
if static_params and static_params.deepwater_xposition and (p.x <= static_params.deepwater_xposition) then t = 'deepwater' end
if friendlyboat_bool and boat.state == enum_state.RETREATING and vector.x < 0 then
if static_params and static_params.deepwater_xposition and (p.x <= static_params.deepwater_xposition - 0.5) then t = 'deepwater' end
if friendlyboat_bool and boat.state == enum_state.RETREATING and vector.x < 0 then --in this case we need to place some landing tiles, as the cannon juts out
if (p.x >= boat.dockedposition.x + scope.Data.leftmost_gate_position) and (p.y <= scope.Data.upmost_gate_position or p.y >= scope.Data.downmost_gate_position) then t = CoreData.landing_tile end
end
newtiles[#newtiles + 1] = {name = t, position = {x = p.x, y = p.y}}

View File

@ -111,7 +111,7 @@ Public.areas_offleft = {
Public.entities = {
static = {
pos = { x = -34, y = 0},
bp_str = [[0eNqVmu1u2zAMRd/Fv93CJPWZVxmKoR9GF6B1iiTdVhR59yXtgA3Yrsn704B9QMlHEiXxfbh7ep1f9tvlOGzeh8Ny+3J13F097rcPl+efw6bUcXgbNppO47C93y2HYfPl/OL2cbl9urxyfHuZh82wPc7Pwzgst8+Xpx+73cO8XN1/mw/H4fLh8jCfWXK6GYd5OW6P2/mT8/Hw9nV5fb6b9+cX/k8Yh5fd4fzRbvkdlFznj6im63w6jf9gNIiZ1jEWxNg6JgUxuo7JQUxex5QgJq1jahBT1zEtiCnrmB7E9HWMTEFOczhhjx2RJWqyOCpL1GVxZJaozeLoLFGf1YsoarQ6I0OiTqszNiRqtXo+Rr02b0KMim2ORxo125y/plGzzfFIw7O08/s1arY5v1+jZpszOWrUbHOmR42abY6QGjXbnBlSo2Ynx2yLmp28xT5qdnKEtKjZ2RkiFjU7exFFzc7OELFwDuIMEStkhqaAU0mOAE5jewiBol7nut6yFPU6FwckLAg0LbFZdQIcIzkGOIntagQKW92dlkWtzs0BVRaEmtbIvi6A00lOBnuYie1qBIpaXWS9ZTlqdXG6KBsLQk1LZF83wMkkpwJOOL+uTkDh/Lo5oMb+fNS0qNbF1iMqUa+LOiBhQaBphZ2tBZ0XsNN1B5zwxjF7EUXFluSRompL8Uh0hg1JdIoNSXSOjUiVTrIhic6yIUnZsQvErOGJ2xOzRhUvyQmJnboFJH+VzbMFJH+10mMOkRpNQo3rtJUgpsb7DWJqQsuESEqTUOvCghePlGgSah1tOEiVG204SJVbpdcnROINR6ROr0+A1Cd6fUIkodcnRFJ6fUIko8cvIiV6fUKkzK5PSPFe6JkAxVTZBQrGxG4sBWybOruzlIzubiZ2n4JRwu5UMErZvQrqKZmMNgpGldhtBo4q0ygYFT2XN0SizwUrIjX2xAIH1WkVUFThi8ridlX4rrK4fSXsnlPh/Sm76ZSOSPQpIQ6KPifEUdEnhTgq+qwQR8VO6qqIxM7qKugCfGJP5mFQ4bvLPyrAqJQ+nYdRGY2CUSWyfEYNkdj0HJMKWUSDSZWso8GkRpbSYFInq2kgKXyPWV2SkDU1mKRkWQ0mGVlYg0mJLa3BqMwW12BUYctrMKqyBTYY1dgSG4zqbJENRIVvNtUdNOG7TXUNDd9umutV+ILTXK/Cd5zm/sHwLae5XoXvOc2XobJFNxjV2LIbjOps4Q1EZfrgBaPokxeMoo9eMIo+e8Eo+vAFozJbhINRhS3DwahKJ7MQ1dhSnE/UzfhZqr35q/B7HL7P+8PHJ9rOQ7JrTVZS13Y6/QLM+swl]],
bp_str = [[0eNqVmt1OG0EMhd9lrwPK2PObV6lQRWHVRiobREJbVPHuDVCVSu1Zn3MZKfnkmf3W8Xj8c/r09XG+f9gvp2n3czou1/cXp8PF54f97cvnH9Outs30NO0sP2+m/c1hOU67D+cv7j8v119fvnJ6up+n3bQ/zXfTZlqu714+fT8cbufl4ubLfDxNLz9cbuczKz1fbaZ5Oe1P+/mN8/rh6ePyePdpfjh/4f+EzXR/OJ5/dFh+B7W9LK9Rpcvy/Lz5B2MiZvt/jJOYtI7JJMbWMYXE+Dqmkpi8jmkkpqxjOomp65hBYto6Jm1JTg84rMcj4LAip8DkRKscuJxYmVNgc2J1ToHPiRXaIhCrtAWvRmKltuDlSKzWFnhkrNceeGSs2B54ZKzZHnhkrNkePH5jzfbg8RudqIPHb6zZHmRHY832ID8aa7YHCdJYsz0w21mzc/Rfz5qdA7OdNTsHZjtrdolArNkleEWcNbuU9frMWbNL8K55UyNCINbsUoOlDbH2dFA0bkWOAQ7rdWlBQKbuEIrI1YgQiPa6B0sr4l4XwKkiJwMObfUIAurqDqGIhhoRABVW6xrsdVGPig1w1LNiBRzW6pqCgLK6QyiiokaEQKzW1YKlNXGvB+B0kdMBh66v2zqoslZbD0Cs1dXXt6ia+sxQRK5GhEC01zlYmpqtE/irrmq6TqilwnqdchRSl0koJtbtVAJSY+VOLSKxdqcakUw9iECSqycRSMrqUQRZ0IpMQjFV9VQDSU091kAS3fMr0T4NmYTakHRZUoOYutzCBkVpVwuTBMrk7nJOQSFlOacgUpFjQqurcnZCMTU5OyGS3CaBJLlPgkhDbpRAktwpgSSTYwIWDJezE4opyzkFkYpMQqurcnZCJLUCT+D4NdQSPIED4ZBrcBRS2spVOEYltXzGKFMLaIySa3G062krV+MYJdfjDZHkgrwiUlMP0Tiorh6jMWrIKLRA+qbyXVCIkiuWgUhyydIRydXGFQ4qq60rjCoyCi6wyoJClJrTLSGSmtQN3n8PuVmMgqLvLt/bxRAl98LhAun7yz+CYpSru+6IlMWBFUxSc7oZIlVx+gXH1MQBGEzq4gwMJg1xDAaS6IvMGpKSOAyDSSaOw2CSiwMxmJTVkRiMKupQDEZVdSwGo5o6GINRXR2NwaihDsdAFH2zaeFLQ19uWugVfb3poVf0BaeHXtFXnB56RV9yeigDfc/psQxNHZbBqK6Oy2DUUAdmIIq+8PQwidJXnh7aXuTOC0a52g7CqKx2cTCqqMMzGFXV8RmMaurcC0Z1dfIFo4aMQtUefRH6Xve/oq42bwPku7/G0TfTt/nh+PoT6+dEMayVfP7T3p6//wu8Yvvb]],
-- bp_str = [[0eNqVmu1qG0EMRd9lfm/CSvPtVymhOMmSGpK1sTdtQ/C7104KLbR3pfvTYB804zMfGuk93D+/Tofjbl7C5j2c5u3hZtnfPB13j9fPP8Om1CG8hY2m8xB2D/v5FDZfLl/cPc3b5+tXlrfDFDZht0wvYQjz9uX66cd+/zjNNw/fptMSrj+cH6cLS853Q5jmZbfspk/Ox4e3r/Pry/10vHzh/4QhHPany4/28++g5DZ/RDXe5vN5+AejTsy4jolOTFzHJCdG1zHZicnrmOLEpHVMdWLqOqY5MWUd052Yvo6R0clpBsftsSGyeE0WQ2XxuiyGzOK1WQydxeuzWhF5jVZDafE6rZZGXqvV8sjrdbQ2RK/Y0fBIvWZH419Tr9nR8Ejdu7SxMarX7Gh4pF6zo7E5qtfsaGyP6jU7Gmar1+xomK1es5NhdvSanazD3mt2MoSMXrOzsUSi1+xsReQ1OxtLJLrvIMYSiYW8oSngVJIjgNPYGUIgr9e5ro8seb3OxQAJCwJDS+ytOgFOJDkRcBI71QjktrobI/NanZsBqiwIDa2Rc10Ap5OcDHKYkZ1qBPJaXWR9ZNlrdTGmKEcWhIaWyLlugJNJTgWcwh7VKKDKnrAI1Ng/Hw3Nq3WJ6xEVr9fFGFoRFgSGVtjdWtB7Abtdd8BxJ47ZisgrtiSL5FVbikWic0dIopNHSKKzR0SqdPoIScKmfZCk7NoFYlb3xm2JWb2Kl2SExG7dAi5/lb1nC7j81UqvOURqNAkNrtNWgpga7zeIqQktEyIpTUKjcwteLFKiSWh0tOHgqtxow8FVuVX6fEIk3nBE6vT5BEh9pM8nRBL6fEIkpc8nRIr0+kWkRJ9PiJTZ8wkp3gu9E6CYKntAwZjYxFJA2tTZzFIyqt2MbJ6CUfRbIEYpm6ugmZIx0kbBqBKbZuCoMo2CUdF7eUMk+l2wIlJjXyxwUJ1WAUXlLlQWc6rctcpizpWwOafC+imbdEpHJPqVEAdFvxPiqOiXQhwV/VaIo2I3dVVEYnd1FVQAH9mXeRiUu3b5RwUYldKv8zCqSKNgVIlsn9GISOz1HJMK2USDSZXso8GkRrbSYFInu2kgyV3HrCZJyJ4aTFKyrQaTItlYg0mJba3BqMw212BUYdtrMKqyDTYY1dgWG4zqbJMNRCU6FcUoOhfFKDoZxSg6G8WoxLbbYFRmM1uMKmzLDUZVtukGoxrbdoNRnW28gSh3xTOatrtrntG03V31TKbt7rpnMm13Vz6Tqai7+JnNheOuf2Y7qkpfZiGqsa04n6i74bNVe/NX4/cQvk/H08dPtF2WZNeaNMaWy/n8C9A5zAo=]],
},
inaccessible = {
@ -149,18 +149,24 @@ Public.deck_whitebelts_lrtp_order = {
{x = -52.5, y = -11.5, direction = defines.direction.north, type = 'input'},
{x = -51.5, y = -11.5, direction = defines.direction.north, type = 'input'},
{x = -50.5, y = -11.5, direction = defines.direction.north, type = 'input'},
{x = -49.5, y = -11.5, direction = defines.direction.north, type = 'input'},
{x = -18.5, y = -11.5, direction = defines.direction.south, type = 'input'},
{x = -17.5, y = -11.5, direction = defines.direction.south, type = 'input'},
{x = -16.5, y = -11.5, direction = defines.direction.south, type = 'input'},
{x = -15.5, y = -11.5, direction = defines.direction.south, type = 'input'},
{x = -52.5, y = -2.5, direction = defines.direction.south, type = 'output'},
{x = -51.5, y = -2.5, direction = defines.direction.south, type = 'output'},
{x = -50.5, y = -2.5, direction = defines.direction.south, type = 'output'},
{x = -49.5, y = -2.5, direction = defines.direction.south, type = 'output'},
{x = -52.5, y = 2.5, direction = defines.direction.north, type = 'input'},
{x = -51.5, y = 2.5, direction = defines.direction.north, type = 'input'},
{x = -50.5, y = 2.5, direction = defines.direction.north, type = 'input'},
{x = -49.5, y = 2.5, direction = defines.direction.north, type = 'input'},
{x = -52.5, y = 11.5, direction = defines.direction.south, type = 'output'},
{x = -51.5, y = 11.5, direction = defines.direction.south, type = 'output'},
{x = -50.5, y = 11.5, direction = defines.direction.south, type = 'output'},
{x = -49.5, y = 11.5, direction = defines.direction.south, type = 'output'},
{x = -18.5, y = 11.5, direction = defines.direction.south, type = 'output'},
{x = -17.5, y = 11.5, direction = defines.direction.south, type = 'output'},
{x = -16.5, y = 11.5, direction = defines.direction.south, type = 'output'},
{x = -15.5, y = 11.5, direction = defines.direction.south, type = 'output'},

View File

@ -16,69 +16,104 @@ Public.enum = enum
Public.Data = {}
Public.Data.width = 16
Public.Data.width = 18
Public.Data.height = 24
Public.Data.cabin_whitebelts_lrtp_order = {
{x = -7.5, y = -10.5, direction = defines.direction.north, type = 'input'},
{x = -6.5, y = -10.5, direction = defines.direction.north, type = 'input'},
{x = -5.5, y = -10.5, direction = defines.direction.north, type = 'input'},
{x = -4.5, y = -10.5, direction = defines.direction.north, type = 'input'},
{x = -3.5, y = -10.5, direction = defines.direction.north, type = 'input'},
{x = -7.5, y = 10.5, direction = defines.direction.south, type = 'output'},
{x = -6.5, y = 10.5, direction = defines.direction.south, type = 'output'},
{x = -5.5, y = 10.5, direction = defines.direction.south, type = 'output'},
{x = -4.5, y = 10.5, direction = defines.direction.south, type = 'output'},
{x = -3.5, y = 10.5, direction = defines.direction.south, type = 'output'},
}
Public.Data.car_pos = {x = 7, y = 0}
Public.Data.car_pos = {x = 9, y = 0}
Public.Data.static_entities_bp = [[0eNqlmt1u4jAQhd/F16HKOP4Lr1JVK1qsbiSaoCTstqp49yWwW9EtJ/FxLyPIx9g+4zP28K4ed4e475t2VOt3NbSb/WrsVs99s52eX9VaXKHe1FqbY6Gap64d1Pr+9MXmud3spq+Mb/uo1qoZ44sqVLt5mZ5+d902tqunn3EY1fRiu40T61gsvhpf930chtXYb9ph3/Xj6jHuriH6+FCo2I7N2MRLMOeHtx/t4eUx9qdfuR1GofbdcHqpa/+N7M6eh1be2eMU2H8YnYgp5zFVIqaax5hEjJ7H2ESMnce4RIyZx/hEjJ/HhESMm8fUiZh6HiNlIicscJJ1vCBkSVWyLEhZUrUsC2KWVDXLgpwlVc+yoERxZLYL4HiSowEnLG2IMNcQsWanCoB0yYLAXGkh56oCHHanNoBT0XOuF4gmm4jGamlitRCj+0LcdZvt6aMb+8MHqFDbpo9Plw9PhL9W3h3G/WEy668/41nVoHgDC0JTWZOyscDgS5LjAEeyxYKIOpuIxlplyw8R+RSxV6P+pEN9i2+zN1IUscuOGBF9cgp6MPKPDGxakIAV7yj+KuzPCX+LX9N8x/BNye5TNmefMsJuLyD5jGZBQB2mIvcXDziG5ATAsdm7CiLmZ1RI2QMMm18hI78M7UtoNuhCDSy4ZY2pBhy2ThN0+Mz3I4issqVzRi5qxxpSOzewy+KxyecYuzQhjq7OEYmu2JB+AqsfcGCwbMUm4AjjynwhIqTkC1GnCNFpVog6Q4iONRsB1bVj3UZAve/y7QYi8/1GTNJasYZzA5uwVoHeNNBi0ZaDptbzlwMgJk+7DqifPHs9IKCi8/n3AxCZf/qRpOOPt6wSc84WnjcdNCG06cBlp10HlFGedh1Q2IVvuA5CfsN1kkrnQLtOTu0cKnrV0YQYmgSWPVh22UH5E9irZY3aHD5bPxBJH1ogibcQMF81e2zRoFysWQfRoLardf5lPIqNVjwMjlY8jMmSjVMNrLumFY9AnmyeQlAg26cQVJMNVASSsiR7qJgkZBsVkzTZScWkimymYpIh26mYZNmGKkY5tqWKUZ5tqmJUYNuqGMV3C8+oh+Lyd4711f9KCvUr9sOlFghifK29FSuVK4/HPzs+Pbo=]]
Public.Data.market_position = {x = 4.5, y = 3.5}
Public.Data.operable_entities_bp = [[0eNqV1NtqxCAQBuB3mWtTVnP2VUopyWbYCskY1G0bFt+9MUthKW4a7xzw/xyN5gb9eMXZKHIgb2CpmzOns4tRQ6i/QfKKwQJSFJ6BOmuyIF/XiepC3RimuGVGkKAcTsCAuilUX1oPSNn5A62DEKQBg+XZv1FnOrKzNi7rcXwMC//GAMkpp/DexFYs73SdejSrHl+ewaztGtL0u6PTS7ntKQx8aOkPJFKhNu7kRx2+7xRHHbHvlEedfN+pkg+ax6E6GRJxqEmGijjUJkN5HOKn1I/2rCXOU6/RU0mkXoC7tL677Y3Kh58Fg080douIhhd1K+pC5HlTVt7/AARAZgM=]]
Public.Data.static_entities_bp = [[0eNqlmu9u2jAUxd8ln2HK9X/zKlM10RJ1kWiCkrAVVX33hVJtXcuJfcwnhEh+XF+fY8e596W63x+bw9B2U7V5qcZue1hP/fpxaHfn78/VRsKqOlUbZV5XVfvQd2O1+T5f2D522/35kul0aKpN1U7NU7Wquu3T+dvvvt813frhZzNO1fnGbtecWa+r5K3N82FoxnE9HvbtNDXDh9vV692qarqpndrmEsbbl9OP7vh0P1+5kesBrKpDP8439d37mOpv9m1Q8+frOaRPGJWJkWWMzsSoZYzJxOhljM3EmGWMy8TYZYzPxLhlTMjE+GVMzMSEZYzUmZyY4OTqWBJClmwlJ6QsuVqWhJglV82SkLPk6lkSgpZcRUtC0pKraUmIWgK5jCnAiSRHwHJYf1mcp2HbjYd+mNb3zX5hLQKRKaGJJkFUpPUQR5MclLN/Ot8OU7vfN8NpPR2HoVmS6Jy2ebfbtUPzcPnZXUNbVmcoRseCUNI8KTQDOKzwNeBEWl6yTNR1MRGMVfMWUAmiKjYVGrX+Qtz32938E9ynzf/6nV3w/pDXH6fD8fws+PVfTPa/+Bv+xZLGRll2JAfllt4tECiwIDQydrtw4Hm1JjkWcKTYc4ioiolorLrYxYhoiolo1LZ4+0YxumIiitEXr10oxkATbYLI7yruAzG5r1v29ADitEJywJxYxS4sCKRZEBqZIVeWADiW5HjAccXrCSL6YiIaayheT1CMsdhZ/rMP1LU3DHX+8wCg/n0eaDvwOOBYk4D0OvbcAZLqaI8gkGFBaGSsSQS9MXIkKAJOuTdgaOWbRMySciSlHAuk7Nl9A2XDs54AE+XpjQOBsk3hU0OjXQFJtC3AodmzthBwjPc3+ALFVu6LtyiTxvCsMa5g084ItDNAPgLrDDRXQbGTDg5rQbMgcHwMplw9KDZbrh6do57gWPXoEvV4dtJRPgILQnMV6VUMhBRremUFMUWhY0Ik2hvgmBBpb4CDS7zBGyi2G7xhc7wRaW/YAm9E2hsoH7Q30Fzx3rCoilfTKIdQbEVaAiLR7vCIpMtVDaMz5bLOOhRKbVldlxwLpWZf7+KU0BaBE0a/4cUo3iVofMK+5lWw2k2bJCJS+QteHJ0ur1VCpmGrlZDEljVw7lxJxfItsOSrTeFr4zhO2g04eWzFQ6FKu6LNIIgk5cV2yCyvDGImWyjHuaPNAGOiK+MYxdfG4fjY6rjSiBTIxjRMimRvGiTpmmxPwyQhO9QwSZFNapikyT41TDJkqxomsUs+Jjmy7w2TPNtohlGBbX7DqMg2m0FUdlFbko4xwjacYZRim+Awii5AXFB3q0v/7uZDI/Gq+tUM4+WZO4jxUXlrZt3W8/V/ACz9dUA=]]
Public.Data.operable_entities_bp = [[0eNqVkeFqwzAMhN9Fv51Ru8nS+lVKGWkjOkMiG0vZGkrefbZXRhljbX+Jg7vPJ/kCh2HCEB0J2AswdaESX52i67M+gzUrBXMa9aLAHT0x2F0yuhN1Q7bIHBAsOMERFFA3ZvXpfY9UHd+RBXKQekwsvai7UTyHiMwVh8GJYLyJm2WvAEmcOPyuUcT8RtN4SE6rfygsiMP1fQXBc8p4uq6kX1+aslSaS670C2MexLT/Y9ZPtmn/xtRPtimYdKhyVnvzvwo+MHJJmI2u261pm1qvm1XyfwG7QKjd]]
Public.Data.cabin_splitters = {
{x = -5, y = 9.5, direction = defines.direction.north, type = 0},
{x = -4, y = 8.5, direction = defines.direction.north, type = 0},
{x = -3, y = 7.5, direction = defines.direction.north, type = 0},
{x = -5, y = 7.5, direction = defines.direction.north, type = 1},
{x = -4, y = 6.5, direction = defines.direction.north, type = 1},
{x = -3, y = 5.5, direction = defines.direction.north, type = 1},
{x = -5, y = 5.5, direction = defines.direction.north, type = 2},
{x = -4, y = 4.5, direction = defines.direction.north, type = 2},
{x = -3, y = 3.5, direction = defines.direction.north, type = 2},
{x = -5, y = 3.5, direction = defines.direction.north, type = 3},
{x = -4, y = 2.5, direction = defines.direction.north, type = 3},
{x = -3, y = 1.5, direction = defines.direction.north, type = 3},
{x = -5, y = 1.5, direction = defines.direction.north, type = 4},
{x = -4, y = 0.5, direction = defines.direction.north, type = 4},
{x = -3, y = -0.5, direction = defines.direction.north, type = 4},
{x = -5, y = -0.5, direction = defines.direction.north, type = 5},
{x = -4, y = -1.5, direction = defines.direction.north, type = 5},
{x = -3, y = -2.5, direction = defines.direction.north, type = 5},
{x = -5, y = -2.5, direction = defines.direction.north, type = 6},
{x = -4, y = -3.5, direction = defines.direction.north, type = 6},
{x = -3, y = -4.5, direction = defines.direction.north, type = 6},
{x = -7, y = 9.5, direction = defines.direction.north, type = 0},
{x = -6, y = 8.5, direction = defines.direction.north, type = 0},
{x = -5, y = 7.5, direction = defines.direction.north, type = 0},
{x = -4, y = 6.5, direction = defines.direction.north, type = 0},
{x = -7, y = 7.5, direction = defines.direction.north, type = 1},
{x = -6, y = 6.5, direction = defines.direction.north, type = 1},
{x = -5, y = 5.5, direction = defines.direction.north, type = 1},
{x = -4, y = 4.5, direction = defines.direction.north, type = 1},
{x = -7, y = 5.5, direction = defines.direction.north, type = 2},
{x = -6, y = 4.5, direction = defines.direction.north, type = 2},
{x = -5, y = 3.5, direction = defines.direction.north, type = 2},
{x = -4, y = 2.5, direction = defines.direction.north, type = 2},
{x = -7, y = 3.5, direction = defines.direction.north, type = 3},
{x = -6, y = 2.5, direction = defines.direction.north, type = 3},
{x = -5, y = 1.5, direction = defines.direction.north, type = 3},
{x = -4, y = 0.5, direction = defines.direction.north, type = 3},
{x = -7, y = 1.5, direction = defines.direction.north, type = 4},
{x = -6, y = 0.5, direction = defines.direction.north, type = 4},
{x = -5, y = -0.5, direction = defines.direction.north, type = 4},
{x = -4, y = -1.5, direction = defines.direction.north, type = 4},
{x = -7, y = -0.5, direction = defines.direction.north, type = 5},
{x = -6, y = -1.5, direction = defines.direction.north, type = 5},
{x = -5, y = -2.5, direction = defines.direction.north, type = 5},
{x = -4, y = -3.5, direction = defines.direction.north, type = 5},
-- {x = -7, y = -2.5, direction = defines.direction.north, type = 6},
-- {x = -6, y = -3.5, direction = defines.direction.north, type = 6},
-- {x = -5, y = -4.5, direction = defines.direction.north, type = 6},
-- {x = -4, y = -5.5, direction = defines.direction.north, type = 6},
{x = -7, y = -2.5, direction = defines.direction.north, type = 7},
{x = -6, y = -3.5, direction = defines.direction.north, type = 7},
{x = -5, y = -4.5, direction = defines.direction.north, type = 7},
{x = -4, y = -5.5, direction = defines.direction.north, type = 7},
{x = -4, y = -8.5, direction = defines.direction.north, type = 7},
{x = -5, y = -9.5, direction = defines.direction.north, type = 7},
{x = -3, y = -7.5, direction = defines.direction.north, type = 8},
{x = 0.5, y = -7, direction = defines.direction.west, type = 8},
{x = -5, y = -7.5, direction = defines.direction.north, type = 7},
{x = -6, y = -8.5, direction = defines.direction.north, type = 7},
{x = -7, y = -9.5, direction = defines.direction.north, type = 7},
{x = -4, y = -6.5, direction = defines.direction.north, type = 8},
{x = -2, y = -6.5, direction = defines.direction.south, type = 9},
}
Public.Data.output_chest = {x = 3.5, y = -6.5}
Public.Data.backup_output_chest = {x = 3.5, y = -7.5}
Public.Data.output_chest = {x = -2.5, y = -9.5}
Public.Data.backup_output_chest = {x = -1.5, y = -9.5}
Public.Data.input_chests = {
{x = 0.5, y = 6.5},
{x = 0.5, y = 4.5},
{x = 0.5, y = 2.5},
{x = 0.5, y = 0.5},
{x = 0.5, y = -1.5},
{x = 0.5, y = -3.5},
{x = 0.5, y = -5.5},
{x = -0.5, y = 5.5},
{x = -0.5, y = 3.5},
{x = -0.5, y = 1.5},
{x = -0.5, y = -0.5},
{x = -0.5, y = -2.5},
{x = -0.5, y = -4.5},
-- {x = 0.5, y = -6.5},
}
Public.Data.surfacename_rendering_pos = {x = -0.5, y = -15}
Public.cabin_shop_data = {
{
price = {{'coin', 300}, {'coal', 25}},
offer = {type='give-item', item = 'artillery-shell', count = 5},
},
{
price = {{'coin', 1000}, {'electronic-circuit', 30}},
offer = {type='give-item', item = 'rail-signal', count = 100},
},
{
price = {{'coin', 2000}, {'stone-brick', 30}},
offer = {type='give-item', item = 'uranium-238', count = 10},
},
{
price = {{'coin', 25}},
offer = {type='nothing', effect_description='Relax at sea for an extra minute: Increase the next destination\'s loading time by 60 seconds.'},
},
}
function Public.get_cabin_surface_name()
local memory = Memory.get_crew_memory()
return SurfacesCommon.encode_surface_name(memory.id, 1, SurfacesCommon.enum.CABIN, enum.DEFAULT)
@ -142,6 +177,9 @@ function Public.create_cabin_surface()
elseif splitter.type == 8 then
priority = 'right'
filter = 'landfill'
elseif splitter.type == 9 then
priority = 'left'
filter = 'landfill'
end
local e = surface.create_entity({name = name, position = p, force = boat.force_name, create_build_effect_smoke = false, direction = splitter.direction})
if e and e.valid then
@ -197,7 +235,7 @@ function Public.create_cabin_surface()
e2.operable = false
end
end
local es2 = Common.build_from_blueprint(Public.Data.operable_entities_bp, surface, {x=4, y=0}, boat.force_name)
local es2 = Common.build_from_blueprint(Public.Data.operable_entities_bp, surface, {x=5, y=-4}, boat.force_name)
for _, e2 in pairs(es2) do
if e2 and e2.valid then
e2.destructible = false
@ -215,6 +253,16 @@ function Public.create_cabin_surface()
e.operable = false
end
e = surface.create_entity({name = 'market', position = Public.Data.market_position, force = boat.force_name, create_build_effect_smoke = false})
if e and e.valid then
e.destructible = false
e.minable = false
e.rotatable = false
for _, offer in pairs(Public.cabin_shop_data) do
e.add_market_item(offer)
end
end
rendering.draw_text{
text = 'Captain\'s Cabin',
surface = surface,
@ -234,12 +282,14 @@ function Public.connect_up_linked_belts_to_deck() --assumes both are in standard
if boat and boat.deck_whitebelts and #boat.deck_whitebelts > 0 and boat.cabin_whitebelts and #boat.cabin_whitebelts > 0 then
local connections = {
{1,7},
{2,8},
{3,9},
{4,10},
{5,11},
{6,12},
{1,9},
{2,10},
{3,11},
{4,12},
{5,13},
{6,14},
{7,15},
{8,16},
}
for _, c in pairs(connections) do

View File

@ -150,8 +150,8 @@ end
Public.Data.jetty_offset = {x = -20, y = -38}
Public.Data.jetty_bp = [[0eNqVmcFO4zAYhN/F5yBl5ncSJ6+y4lAgQpFKWrUBgVDenZZw4LC76nesNHVGHs/nxP5MD/vX8Xia5iUNn+k87453y+Hu+TQ9XX+/pyFylT7SkNu1StPjYT6n4c9FOD3Pu/1VsnwcxzSkaRlfUpXm3cv110X3eBqXMV3/ND+Nl3G03ldpmfbjNsDxcJ6W6TD/PKXeHhLr34b4lzojdXObWsiJkBMhJ0ZOjJwYOQnkJJCTQE4ycpKRk4ycNMhJg5w0yEmLnLTISYucdMhJh5x0yElBTgpyUpCTHjnpkZOekY1BVoyygpiFnIWgZaQVQ60Ya8VgK0ZbMdyK8VYMuGLEFUOuGHPFoCtGXTHsinFXDLxi5BVDrxh7xeArRl8x/IrxVwzAYgQ2I7AZgc0IbEZgMwIbvuvCl134tssIbEZgMwKbEdiMwGYENiOwGYHNCGxGYDMCmxHYjMDeGNkidYfUBakDynskzzWTB5NnJr81o4IyKiijgjIqLKPCMiosI7Zfm+3XZvu1tx21RmohtZE6kDojNZuTFqk7pC5sTqC8Z3PIws8s/czizzB/tgBuPoCrSSt+1EJqI3UgdUZqNictUndIXdicQHnP5pCFn1n6mcWfYf5sAdzcCqFWCLVCqBVCrRBqhVArhFoh1AqhVoi1QqwVYq0Qa4VYK9indLBP6WCf0mG0AoxWgNEKMFsBZivAbAWwE4ZgJwwBL9QCZRQoo0AZBcsoWEbBMoIXjfCm8X8HL/fVdoU9/LoQr9LbeDp/D+Ci3PXuGjWKtl7XLyUP5fs=]]
Public.Data.stone_bp_1_offset = {x = -5, y = -49}
Public.Data.stone_bp_1 = [[0eNqd2cFq4zAURuF30dqB/FeWZPtVShdpKjqiqW1st7QUv/skbRZDoYNPloEb2ToEog99uofTax6n0i+u+3Rzfxh3y7B7msrj5fO768xX7sN1aa1cOQ797Lq781x56g+ny8TyMWbXubLkF1e5/vBy+TQvQ593D1M5PrvL9/rHfF5J633llnLK32uMw1yWMvTX5+y/HrNffywyHpY/5zV+GRcbNzbut46LvbvYu4u9u25593rruLGtGtuqsa0a26rdstWwddyzMp6V8ayMZ2U8K+NvKRO3jtcsZM1C1ixkzULWLGTNQtYsZGAhAwsZWMjAQoafIc//PccpL/n34cDW3pwxsoyRZYwsY2QZI/s9RhYyspCJhUwsZGIhEwuZWMjEQiYWsmEhGxayYSEbFrJhIRsWsmEhWxayZSFbFrJlIVsWsmUhWxZS8PgueH4XPMCLnuD3rOZ1PsD57T0pKagpKCqoKiArrvMBzm/vCd0iCBdBuQjSRdAugni5zm/vCbUjyB1B7wiCR1A8guQRNI8gegTVI8geQfcIwkdQPoL0EbSPIH4E9SPIHwXYExJI0ECCCBJUkCCDBB0kCCFBCQlSSNBCghgS1JAghwQ9JAgiQREJkkjQRIIoElSRIIsEXSQII0EZCdJI0EaCOBLUkSCPBH1k0EcGfWTQRwZ9ZNBHBn1k0DsGvWPQOwa9Y/Qahd6j0IsUepPyX4/cV98XfN0/t4WVe8vT/LWCNapTaykoyMf9uv4FIKIUeQ==]]
Public.Data.stone_bp_1_offset = {x = -19, y = -49}
Public.Data.stone_bp_1 = [[0eNqd2t1q20AUxPF32WsZfGa0+nqVkgsnEamoIxtbKQ3B71470UUptOzfl4aT9c5wCPohf6TH/dt4PE3zkoaPdJ53x81y2Lycpufb519pcFul9zS0lypNT4f5nIZv17npZd7tbxPL+3FMQ5qW8TVVad693j6dl8M8bh5P09OPdPu7+Xm8nhSXhyot0378OuN4OE/LdJjX79l+fs328tchx93y/XrGP8aDjYuNu3Q82N2D3T3Y3eOeu9el42JRxaKKRRWLKhbVLKpZVLOoZlHNotYsas2i1ixqzaLWLGpmUTOLmlnUzKJmFrVhURsWtWFRG/hvCa5kwJ0MuJQBtzLgngVctICbFvmu+xfvWsBlC7htAdct6L41d+XNxfMt7KeF/bSwnxb208J+2rv6aYrnO9hnB/vsYJ8d7LODfXawzw722cM+e9hnD/vsYZ897LOHffasT0HPCIJGUDSCpFnnazif4Xx5n9BYgsgSVJYgs0SdFbDPgH1SyFHJUcpRy0HMrfMZzpf3CbUoyEVBLwqCUVCM63yG8+V9wud/wed/wed/wed/QZau8xnOl/cJPSLoEUGPCHpE0CPrfIbz5X1C7wh6R9A7gt4R9I6gd9b58j6hjwR9JOgjQR8J+kjQR4I+EvSRoI8EfSToI0EfCfpI0EeCPhL0kaCPBH0k6CNBHwn6yNBHhj4y9JGhjwx9ZOgjQx8Z+sjQR4Y+MvSRoY8MfWToI0MfGfrI0EeGPjJ92QV9ZOgj07dp9HUafZ9GX6hBHxn6yNBHhj4y9JGhjwx9ZOgjQx8ZesfQO4beMfSOoXcMPWLoEUOP+L8eeai+fjEy/PHzkyr9HE/nzxPURd32anMdztt8ufwGAFgVOg==]]
Public.Data.ground_bp_1_offset = {x = -122, y = -49}

View File

@ -38,7 +38,9 @@ Public[enum.INITIAL].Data.hold_whitebelts_lrtp_order = {
{x = -19.5, y = -21.5, direction = defines.direction.north, type = 'output'},
{x = -18.5, y = -21.5, direction = defines.direction.north, type = 'output'},
{x = -17.5, y = -21.5, direction = defines.direction.north, type = 'output'},
{x = -16.5, y = -21.5, direction = defines.direction.north, type = 'output'},
{x = 16.5, y = -21.5, direction = defines.direction.north, type = 'output'},
{x = 17.5, y = -21.5, direction = defines.direction.north, type = 'output'},
{x = 18.5, y = -21.5, direction = defines.direction.north, type = 'output'},
{x = 19.5, y = -21.5, direction = defines.direction.north, type = 'output'},
@ -55,7 +57,9 @@ Public[enum.INITIAL].Data.hold_whitebelts_lrtp_order = {
{x = -19.5, y = 21.5, direction = defines.direction.south, type = 'input'},
{x = -18.5, y = 21.5, direction = defines.direction.south, type = 'input'},
{x = -17.5, y = 21.5, direction = defines.direction.south, type = 'input'},
{x = -16.5, y = 21.5, direction = defines.direction.south, type = 'input'},
{x = 16.5, y = 21.5, direction = defines.direction.south, type = 'input'},
{x = 17.5, y = 21.5, direction = defines.direction.south, type = 'input'},
{x = 18.5, y = 21.5, direction = defines.direction.south, type = 'input'},
{x = 19.5, y = 21.5, direction = defines.direction.south, type = 'input'},
@ -149,6 +153,13 @@ function Public.create_hold_surface(nth)
end
end
Common.build_small_loco(surface, Public.Data.loco_offset, memory.force, {255, 106, 52})
-- We place obstacle boxes before the other static boxes, so that they are potentially one tile closer to the edge than they would be otherwise:
local items = subtype == enum.INITIAL and Balance.starting_items_crew_downstairs() or {}
Common.surface_place_random_obstacle_boxes(Public.get_hold_surface(nth), {x=0,y=0}, Public.Data.width, Public.Data.height, 'rocket-silo', {[1] = 0, [2] = 6, [3] = 5, [4] = 2}, items)
-- Public.hold_place_random_obstacle_boxes(nth, {[1] = 0, [2] = 9, [3] = 3, [4] = 1}, items)
local boxes = Common.build_from_blueprint(Public.Data.boxes_bp, surface, Public.Data.boxes_bp_offset, boat.force_name)
for _, e in pairs(boxes) do
if e and e.valid then
@ -158,12 +169,6 @@ function Public.create_hold_surface(nth)
end
end
Common.build_small_loco(surface, Public.Data.loco_offset, memory.force, {255, 106, 52})
local items = subtype == enum.INITIAL and Balance.starting_items_crew_downstairs() or {}
Common.surface_place_random_obstacle_boxes(Public.get_hold_surface(nth), {x=0,y=0}, Public.Data.width, Public.Data.height, 'rocket-silo', {[1] = 0, [2] = 5, [3] = 4, [4] = 2}, items)
-- Public.hold_place_random_obstacle_boxes(nth, {[1] = 0, [2] = 9, [3] = 3, [4] = 1}, items)
if not boat.downstairs_poles then boat.downstairs_poles = {} end
boat.downstairs_poles[nth] = {}
for i = 1, 2 do
@ -182,7 +187,7 @@ function Public.create_hold_surface(nth)
end
if subtype == enum.SECONDARY then
local difficulty_name = CoreData.get_difficulty_name_from_value(Common.difficulty())
local difficulty_name = CoreData.get_difficulty_name_from_value(memory.difficulty)
if difficulty_name == CoreData.difficulty_options[#CoreData.difficulty_options].text then
Public.upgrade_chests(nth, 'steel-chest')
elseif difficulty_name ~= CoreData.difficulty_options[1].text then
@ -270,12 +275,16 @@ function Public.connect_up_linked_belts_to_deck() --assumes both are in standard
{4,4},
{5,5},
{6,6},
{15,13},
{16,14},
{17,15},
{18,16},
{19,17},
{20,18},
{7,7},
{8,8},
{17,17},
{18,18},
{19,19},
{20,20},
{21,21},
{22,22},
{23,23},
{24,24},
}
for _, c in pairs(connections) do
@ -297,10 +306,10 @@ function Public.nth_hold_connect_linked_belts(nth) --assumes both are in standar
if nth % 2 == 0 then
if nth == 2 then
connections = {
{5,11},
{6,12},
{7,13},
{8,14},
{5,13},
{6,14},
{7,15},
{8,16},
}
for _, c in pairs(connections) do
local b1 = boat.hold_whitebelts[nth][c[1]]
@ -321,10 +330,10 @@ function Public.nth_hold_connect_linked_belts(nth) --assumes both are in standar
end
end
connections = {
{1,7},
{2,8},
{3,9},
{4,10},
{1,9},
{2,10},
{3,11},
{4,12},
}
for _, c in pairs(connections) do
local b1 = boat.hold_whitebelts[nth][c[1]]
@ -344,10 +353,10 @@ function Public.nth_hold_connect_linked_belts(nth) --assumes both are in standar
b1.connect_linked_belts(b2)
end
connections = {
{5,7},
{6,8},
{7,9},
{8,10},
{5,9},
{6,10},
{7,11},
{8,12},
}
for _, c in pairs(connections) do
local b1 = boat.hold_whitebelts[nth][c[1]]

View File

@ -114,10 +114,10 @@ function Public.chunk_structures(args)
local noises = Public.noises{p = p, noise_generator = args.noise_generator, static_params = args.static_params, seed = args.seed}
return {
placeable = noises.farness(p) > 0.35,
placeable = noises.farness(p) > 0.36,
spawners_indestructible = false,
-- spawners_indestructible = noises.farness(p) > 0.7,
density_perchunk = 10 * Math.slopefromto(noises.mood(p), 0.12, -0.18) * Math.slopefromto(noises.farness(p), 0.35, 1) * args.biter_base_density_scale,
density_perchunk = 9 * Math.slopefromto(noises.mood(p), 0.12, -0.18) * Math.slopefromto(noises.farness(p), 0.36, 1) * args.biter_base_density_scale,
}
end

View File

@ -27,7 +27,7 @@ function Public.silo_setup_position(x_fractional_offset, x_absolute_offset)
local surface = game.surfaces[destination.surface_name]
local boatposition = memory.boat.position
local island_center = destination.static_params.islandcenter_position
local difficulty_offset = (1 - Common.difficulty()) * 20 or 0
local difficulty_offset = (1 - Common.difficulty_scale()) * 20 or 0
local silo_count = Balance.silo_count()
@ -232,7 +232,7 @@ function Public.position_away_from_players_1(_, radius)
local tile = surface.get_tile(p2)
if tile and tile.valid and tile.name then
if not Utils.contains(CoreData.tiles_that_conflict_with_resource_layer, tile.name) then
if not Utils.contains(CoreData.tiles_that_conflict_with_resource_layer_extended, tile.name) then
local nearby_characters = surface.find_entities_filtered{position = p2, radius = radius, name = 'character'}
if (not nearby_characters) or (#nearby_characters == 0) then
p_ret = p2

View File

@ -32,23 +32,23 @@ Public['IslandsCommon'] = require 'maps.pirates.surfaces.islands.common'
local function render_silo_hp()
-- local memory = Memory.get_crew_memory()
local destination = Common.current_destination()
local surface = game.surfaces[destination.surface_name]
if not (destination.dynamic_data.rocketsilos and destination.dynamic_data.rocketsilos[1] and destination.dynamic_data.rocketsilos[1].valid) then return end
destination.dynamic_data.rocketsilohptext = rendering.draw_text{
text = 'HP: ' .. destination.dynamic_data.rocketsilohp .. ' / ' .. destination.dynamic_data.rocketsilomaxhp,
surface = surface,
target = destination.dynamic_data.rocketsilos[1],
target_offset = {0, 4.5},
color = {0, 255, 0},
scale = 1.20,
font = 'default-game',
alignment = 'center',
scale_with_zoom = true
}
end
-- local function render_silo_hp()
-- -- local memory = Memory.get_crew_memory()
-- local destination = Common.current_destination()
-- local surface = game.surfaces[destination.surface_name]
-- if not (destination.dynamic_data.rocketsilos and destination.dynamic_data.rocketsilos[1] and destination.dynamic_data.rocketsilos[1].valid) then return end
-- destination.dynamic_data.rocketsilohptext = rendering.draw_text{
-- text = 'HP: ' .. destination.dynamic_data.rocketsilohp .. ' / ' .. destination.dynamic_data.rocketsilomaxhp,
-- surface = surface,
-- target = destination.dynamic_data.rocketsilos[1],
-- target_offset = {0, 4.5},
-- color = {0, 255, 0},
-- scale = 1.20,
-- font = 'default-game',
-- alignment = 'center',
-- scale_with_zoom = true
-- }
-- end
function Public.spawn_treasure_maps(destination, points_to_avoid)
@ -328,6 +328,7 @@ function Public.spawn_silo_setup()
silo.operable = false
if i == 1 then
silo.auto_launch = true
Common.new_healthbar(true, silo, Balance.silo_max_hp, nil, Balance.silo_max_hp, 0.6, -2)
else
silo.destructible = false
end
@ -361,7 +362,7 @@ function Public.spawn_silo_setup()
Task.set_timeout_in_ticks(2, silo_chart_tag, {p_silo = p_silo, surface_name = destination.surface_name, crew_id = memory.id})
end
render_silo_hp()
-- render_silo_hp()
return p_silo
end
@ -381,8 +382,8 @@ function Public.spawn_enemy_boat(type)
local boat = {
state = Boats.enum_state.APPROACHING,
type = type,
speed = 4.5,
position = {x = - surface.map_gen_settings.width/2 + 17.5, y = (memory.boat.dockedposition or memory.boat.position).y + offsets[Math.random(4)]},
speed = 4,
position = {x = - surface.map_gen_settings.width/2 + 23.5, y = (memory.boat.dockedposition or memory.boat.position).y + offsets[Math.random(4)]},
force_name = memory.enemy_force_name,
surface_name = surface.name,
unit_group = nil,
@ -398,7 +399,7 @@ function Public.spawn_enemy_boat(type)
-- e.destructible = false
boat.spawner = e
Common.new_healthbar(false, e, 350, nil, 350, 0.3)
Common.new_healthbar(true, e, 900, nil, 900, 0.5)
end
return enemyboats[#enemyboats]

View File

@ -25,7 +25,7 @@ function Public.base_ores()
['iron-ore'] = 6.5,
['coal'] = 4.0,
['stone'] = 2.0,
['crude-oil'] = 25,
['crude-oil'] = 30,
}
end

View File

@ -139,12 +139,12 @@ local free_labyrinth_cell_raffle = {
maze_worms = 0.8,
small_abandoned_refinery = 0.05,
small_roboport_base = 0.05,
maze_belts_1 = 0.2,
maze_belts_2 = 0.2,
maze_belts_3 = 0.2,
maze_belts_4 = 0.2,
maze_belts_1 = 0.28,
maze_belts_2 = 0.28,
maze_belts_3 = 0.28,
maze_belts_4 = 0.28,
maze_mines = 0.1,
maze_treasure = 0.7,
maze_treasure = 0.74,
}
local function free_labyrinth_cell_type(args)

View File

@ -283,7 +283,7 @@ local function radioactive_tick()
local pollution = 0
local timer = destination.dynamic_data.timer
if timer and timer > 15 then
pollution = 4.9 * (6 * Common.difficulty()^(1.1) * (memory.overworldx/40)^(14/10) * (Balance.crew_scale())^(0.6)) / 3600 * tickinterval * (1 + (Common.difficulty()-1)*0.2 + 0.001 * timer)
pollution = 10.0 * (Common.difficulty_scale()^(1.1) * (memory.overworldx/40)^(18/10) * (Balance.crew_scale())^(0.55)) / 3600 * tickinterval * (1 + (Common.difficulty_scale()-1)*0.2 + 0.001 * timer)
end
if pollution > 0 then

View File

@ -336,7 +336,7 @@ function Public.underground_worms_ai()
worms[#worms] = nil
end
local max_worms = Math.ceil(45 * Math.sloped(Common.difficulty(), 1/2))
local max_worms = Math.ceil(45 * Math.sloped(Common.difficulty_scale(), 1/2))
-- spawn worms
if game.tick % 90 == 0 then

View File

@ -93,13 +93,26 @@ function Public.kraken_tick(crew_id, kraken_id, step, substep)
Common.update_healthbar_rendering(healthbar, new_health)
end
if substep % 4 == 0 then
local crewmembers = Common.crew_get_crew_members()
local crewmembers = Common.crew_get_crew_members()
local crewCount = #crewmembers
-- firing speed now depends on player count:
local firing_period
if crewCount <= 12 then
firing_period = 4
else
firing_period = 3
-- elseif crewCount <= 24 then
-- firing_period = 3
-- else
-- firing_period = 2
end
if substep % firing_period == 0 then
local p_can_fire_at = {}
for _, player in pairs(crewmembers) do
local p = player.position
if player.surface == surface then
-- if player.surface == surface and Public.on_boat(memory.boat, p) then
if player.surface == surface then -- and Public.on_boat(memory.boat, p)
p_can_fire_at[#p_can_fire_at + 1] = p
end
end
@ -243,7 +256,7 @@ function Public.kraken_move(kraken_id, new_p, new_frame)
kraken_data.spawner_entity.teleport(new_p_2.x - old_p_2.x, new_p_2.y - old_p_2.y)
else
kraken_data.spawner_entity = surface.create_entity{name = 'biter-spawner', position = new_p_2, force = memory.enemy_force_name}
Common.new_healthbar(true, kraken_data.spawner_entity, kraken_data.max_health, kraken_id)
Common.new_healthbar(true, kraken_data.spawner_entity, kraken_data.max_health, kraken_id, kraken_data.max_health, 0.8)
end
if old_frame then --cleanup old tiles
@ -282,12 +295,15 @@ function Public.kraken_die(kraken_id)
memory.active_sea_enemies.krakens[kraken_id] = nil
local reward = Balance.kraken_kill_reward()
Common.give_items_to_crew(reward)
local reward_items = Balance.kraken_kill_reward_items()
Common.give_items_to_crew(reward_items)
local force = memory.force
if not (force and force.valid) then return end
Common.notify_force_light(force,'Granted ' .. reward[1].count .. ' [item=sulfuric-acid-barrel]')
local reward_fuel = Balance.kraken_kill_reward_fuel()
memory.stored_fuel = memory.stored_fuel + reward_fuel
Common.notify_force_light(memory.force,'Granted: ' .. Math.floor(reward_items[2].count/100)/10 .. 'k [item=coin], ' .. reward_fuel .. ' [item=coal], ' .. reward_items[1].count .. ' [item=sulfuric-acid-barrel].')
memory.playtesting_stats.coins_gained_by_krakens = memory.playtesting_stats.coins_gained_by_krakens + reward_items[2].count
end
local event = require 'utils.event'

View File

@ -169,7 +169,7 @@ function Public.destination_on_collide(destination)
local playercount = Common.activecrewcount()
local max_evo
local difficulty_name = CoreData.get_difficulty_name_from_value(Common.difficulty())
local difficulty_name = CoreData.get_difficulty_name_from_value(Common.difficulty_scale())
if difficulty_name == CoreData.difficulty_options[1].text then
if memory.overworldx/40 < 20 then
max_evo = 0.9 - (20 - memory.overworldx/40) * 1/100
@ -200,7 +200,7 @@ function Public.destination_on_collide(destination)
-- scheduled_raft_raids[#scheduled_raft_raids + 1] = {timeinseconds = t, max_bonus_evolution = 0.52}
end
end
elseif memory.overworldx == 200 or _DEBUG then
elseif memory.overworldx == 200 then
local times
if playercount <= 2 then
times = {1, 5, 10, 15, 20}
@ -227,8 +227,8 @@ function Public.destination_on_collide(destination)
if memory.overworldx == 40*5 then
Parrot.parrot_boats_warning()
elseif memory.overworldx == 800 then
Parrot.parrot_800_tip()
-- elseif memory.overworldx == 800 then
-- Parrot.parrot_800_tip()
end
end
@ -238,7 +238,10 @@ function Public.destination_on_arrival(destination)
local memory = Memory.get_crew_memory()
-- game.map_settings.pollution.enemy_attack_pollution_consumption_modifier = Balance.defaultai_attack_pollution_consumption_modifier()
-- Event_functions.flamer_nerfs()
-- Event_functions.flamer_nerfs()
log('Playthrough stats:')
log(_inspect(memory.playtesting_stats))
memory.floating_pollution = 0
@ -249,12 +252,12 @@ function Public.destination_on_arrival(destination)
if destination.type == enum.ISLAND then
destination.dynamic_data.rocketsiloenergyneeded = Balance.silo_energy_needed_MJ() * 1000000
destination.dynamic_data.rocketcoalreward = Balance.launch_fuel_reward()
destination.dynamic_data.rocketcoalreward = Balance.rocket_launch_fuel_reward()
if destination.subtype == Islands.enum.RADIOACTIVE then
destination.dynamic_data.time_remaining = -1
elseif destination.subtype == Islands.enum.MAZE then --more time
destination.dynamic_data.time_remaining = Math.ceil(1.08 * Balance.max_time_on_island())
destination.dynamic_data.time_remaining = Math.ceil(1.05 * Balance.max_time_on_island())
else
destination.dynamic_data.time_remaining = Math.ceil(Balance.max_time_on_island())
end
@ -319,9 +322,9 @@ function Public.destination_on_arrival(destination)
if not (#memory.destinationsvisited_indices and #memory.destinationsvisited_indices == 1) then --don't need to notify for the first island
Server.to_discord_embed_raw((destination.static_params.discord_emoji or CoreData.comfy_emojis.wut) .. '[' .. memory.name .. '] Approaching ' .. name .. ', ' .. memory.overworldx .. ' leagues.')
end
if destination.static_params.name == 'Dock' then
message = message .. ' ' .. 'New trades are available in the Captain\'s Store.'
end
-- if destination.static_params.name == 'Dock' then
-- message = message .. ' ' .. 'New trades are available in the Captain\'s Store.'
-- end
Common.notify_force(memory.force, message)
if destination.type == enum.ISLAND then
@ -359,6 +362,8 @@ function Public.destination_on_departure(destination)
local memory = Memory.get_crew_memory()
-- local boat = memory.boat
-- need to put tips only where we know there are islands:
if memory.overworldx == 40*9 then
Parrot.parrot_kraken_warning()
end
@ -384,10 +389,12 @@ function Public.destination_on_crewboat_hits_shore(destination)
if destination.type == enum.ISLAND then
destination.dynamic_data.initial_spawner_count = Common.spawner_count(game.surfaces[destination.surface_name])
if memory.overworldx == 0 then
Parrot.parrot_0()
-- elseif memory.overworldx == 80 then
-- Parrot.parrot_80()
elseif memory.overworldx == 80 then
Parrot.parrot_80()
end
if destination.subtype == Islands.enum.RADIOACTIVE then
@ -412,12 +419,6 @@ function Public.destination_on_crewboat_hits_shore(destination)
ShopMerchants.generate_merchant_trades(destination.dynamic_data.merchant_market)
end
end
if destination and destination.surface_name and game.surfaces[destination.surface_name] and game.surfaces[destination.surface_name].valid and (not (destination.dynamic_data and destination.dynamic_data.initial_spawner_count)) then
--Note: This gives the wrong answer on the first island. Because the terrain hasn't finished generating yet.
destination.dynamic_data.initial_spawner_count = Common.spawner_count(game.surfaces[destination.surface_name])
end
end

View File

@ -286,7 +286,7 @@ function Public.periodic_free_resources(tickinterval)
Common.give_items_to_crew{{name = 'sulfuric-acid-barrel', count = count}}
local force = memory.force
if not (force and force.valid) then return end
Common.notify_force_light(force, 'Granted ' .. count .. ' [item=sulfuric-acid-barrel]')
Common.notify_force_light(force, 'Granted: ' .. count .. ' [item=sulfuric-acid-barrel]')
end
end
@ -622,7 +622,7 @@ function Public.place_cached_structures(tickinterval)
covered_data.market.rotatable = false
covered_data.market.destructible = false
covered_data.market.add_market_item{price={{'pistol', 1}}, offer={type = 'give-item', item = 'coin', count = 450}}
covered_data.market.add_market_item{price={{'pistol', 1}}, offer={type = 'give-item', item = 'coin', count = Balance.coin_sell_amount}}
covered_data.market.add_market_item{price={{'burner-mining-drill', 1}}, offer={type = 'give-item', item = 'iron-plate', count = 9}}
local how_many_coin_offers = 4
@ -633,17 +633,17 @@ function Public.place_cached_structures(tickinterval)
end
if destination.static_params.class_for_sale then
covered_data.market.add_market_item{price={{'coin', Balance.class_cost()}}, offer={type="nothing"}}
covered_data.market.add_market_item{price={{'coin', Balance.class_cost()}}, offer={type="nothing", effect_description = 'Purchase the class ' .. Classes.display_form[destination.static_params.class_for_sale] .. '.'}}
destination.dynamic_data.market_class_offer_rendering = rendering.draw_text{
text = 'Class available: ' .. Classes.display_form[destination.static_params.class_for_sale],
surface = surface,
target = Utils.psum{special.position, hardcoded_data.market, {x = 1, y = -3.9}},
color = CoreData.colors.renderingtext_green,
scale = 2.5,
font = 'default-game',
alignment = 'center'
}
-- destination.dynamic_data.market_class_offer_rendering = rendering.draw_text{
-- text = 'Class available: ' .. Classes.display_form[destination.static_params.class_for_sale],
-- surface = surface,
-- target = Utils.psum{special.position, hardcoded_data.market, {x = 1, y = -3.9}},
-- color = CoreData.colors.renderingtext_green,
-- scale = 2.5,
-- font = 'default-game',
-- alignment = 'center'
-- }
end
end
@ -678,7 +678,7 @@ function Public.place_cached_structures(tickinterval)
local inv = e.get_inventory(defines.inventory.chest)
local loot = Loot.covered_wooden_chest_loot()
if k==1 then loot[1] = {name = 'coin', count = 1500} end
if k==1 then loot[1] = {name = 'coin', count = 2000} end
for j = 1, #loot do
local l = loot[j]
inv.insert(l)
@ -1180,9 +1180,9 @@ function Public.silo_update(tickinterval)
memory.floating_pollution = memory.floating_pollution + pollution/2
game.surfaces[destination.surface_name].pollute(p, pollution/2)
if memory.overworldx >= 200 and dynamic_data.rocketsiloenergyconsumed >= 0.25 * dynamic_data.rocketsiloenergyneeded and (not dynamic_data.parrot_silo_warned) then
if memory.overworldx >= 80 and dynamic_data.rocketsiloenergyconsumed >= 0.25 * dynamic_data.rocketsiloenergyneeded and (not dynamic_data.parrot_silo_warned) then
dynamic_data.parrot_silo_warned = true
Common.parrot_speak(memory.force, 'Just a warning... the silo is attracting biters...')
Common.parrot_speak(memory.force, 'The silo is attracting biters...')
elseif dynamic_data.rocketsiloenergyconsumed >= dynamic_data.rocketsiloenergyneeded and (not (silo.rocket_parts == 100)) and (dynamic_data.silocharged == false) and (not memory.game_lost) then
-- silo.energy = 0
silo.rocket_parts = 100

View File

@ -122,9 +122,11 @@ function Public.update_character_properties(tickinterval)
-- health_boost = health_boost + 1300
-- end
-- end
if Common.is_captain(player) then
health_boost = health_boost + 50
end
-- Captain health boost:
-- if Common.is_captain(player) then
-- health_boost = health_boost + 50
-- end
character.character_health_bonus = health_boost
local speed_boost = Balance.base_extra_character_speed
@ -144,19 +146,13 @@ function Public.update_character_properties(tickinterval)
if class == Classes.enum.DECKHAND then
if on_ship_bool and (not hold_bool) then
speed_boost = speed_boost + 0.25
elseif (not on_ship_bool) then
speed_boost = speed_boost - 0.25
end
elseif class == Classes.enum.BOATSWAIN then
if hold_bool then
speed_boost = speed_boost + 0.25
elseif (not on_ship_bool) then
speed_boost = speed_boost - 0.25
end
elseif class == Classes.enum.SHORESMAN then
if on_ship_bool then
speed_boost = speed_boost - 0.25
else
if not on_ship_bool then
speed_boost = speed_boost + 0.07
end
end
@ -209,9 +205,9 @@ function Public.class_rewards_tick(tickinterval)
local hold_bool = surfacedata.type == Surfaces.enum.HOLD
if class == Classes.enum.DECKHAND and on_ship_bool and (not hold_bool) then
Classes.class_ore_grant(player, 4)
Classes.class_ore_grant(player, 2)
elseif class == Classes.enum.BOATSWAIN and hold_bool then
Classes.class_ore_grant(player, 6)
Classes.class_ore_grant(player, 4)
elseif class == Classes.enum.SHORESMAN and (not on_ship_bool) then
Classes.class_ore_grant(player, 2)
elseif class == Classes.enum.QUARTERMASTER then