mirror of
https://github.com/ComfyFactory/ComfyFactorio.git
synced 2025-01-08 00:39:30 +02:00
777 lines
28 KiB
Lua
777 lines
28 KiB
Lua
-- This file is part of thesixthroc's Pirate Ship softmod, licensed under GPLv3 and stored at https://github.com/danielmartin0/ComfyFactorio-Pirates.
|
|
|
|
local Public = {}
|
|
|
|
local Memory = require 'maps.pirates.memory'
|
|
local Math = require 'maps.pirates.math'
|
|
local Balance = require 'maps.pirates.balance'
|
|
local Common = require 'maps.pirates.common'
|
|
local CoreData = require 'maps.pirates.coredata'
|
|
local Utils = require 'maps.pirates.utils_local'
|
|
local _inspect = require 'utils.inspect'.inspect
|
|
-- local Server = require 'utils.server'
|
|
|
|
-- local Structures = require 'maps.pirates.structures.structures'
|
|
local Boats = require 'maps.pirates.structures.boats.boats'
|
|
local Surfaces = require 'maps.pirates.surfaces.surfaces'
|
|
local Crowsnest = require 'maps.pirates.surfaces.crowsnest'
|
|
local Dock = require 'maps.pirates.surfaces.dock'
|
|
-- local Islands = require 'maps.pirates.surfaces.islands.islands'
|
|
-- local Sea = require 'maps.pirates.surfaces.sea.sea'
|
|
local Crew = require 'maps.pirates.crew'
|
|
-- local Roles = require 'maps.pirates.roles.roles'
|
|
-- local Classes = require 'maps.pirates.roles.classes'
|
|
-- local Quest = require 'maps.pirates.quest'
|
|
-- local Parrot = require 'maps.pirates.parrot'
|
|
-- local Hold = require 'maps.pirates.surfaces.hold'
|
|
-- local Cabin = require 'maps.pirates.surfaces.cabin'
|
|
local Shop = require 'maps.pirates.shop.shop'
|
|
local Upgrades = require 'maps.pirates.boat_upgrades'
|
|
local Kraken = require 'maps.pirates.surfaces.sea.kraken'
|
|
local Highscore = require 'maps.pirates.highscore'
|
|
local CustomEvents = require 'maps.pirates.custom_events'
|
|
|
|
|
|
local infront_positions = {}
|
|
for x = -6, -3 do
|
|
for y = - 3, 3 do
|
|
infront_positions[#infront_positions + 1] = {x = x, y = y}
|
|
end
|
|
end
|
|
local interior_positions = {}
|
|
for x = 1, 14 do
|
|
for y = - 3, 3 do
|
|
interior_positions[#interior_positions + 1] = {x = x, y = y}
|
|
end
|
|
end
|
|
|
|
|
|
function Public.generate_destination_type_and_subtype(overworld_position)
|
|
local memory = Memory.get_crew_memory()
|
|
|
|
local macro_p = {x = overworld_position.x/40, y = overworld_position.y/24}
|
|
local macro_x = macro_p.x
|
|
local macro_y = macro_p.y
|
|
|
|
local type, subtype
|
|
|
|
local island_subtype_raffle = {'none', 'none', Surfaces.Island.enum.STANDARD, Surfaces.Island.enum.STANDARD_VARIANT, Surfaces.Island.enum.RED_DESERT, Surfaces.Island.enum.HORSESHOE}
|
|
|
|
if macro_x >= 6 then island_subtype_raffle[#island_subtype_raffle + 1] = Surfaces.Island.enum.WALKWAYS end
|
|
if macro_x >= 6 then island_subtype_raffle[#island_subtype_raffle + 1] = 'none' end
|
|
-- if macro_x >= 13 and macro_y == 1 then
|
|
-- island_subtype_raffle[#island_subtype_raffle + 1] = Surfaces.Island.enum.MAZE
|
|
-- island_subtype_raffle[#island_subtype_raffle + 1] = Surfaces.Island.enum.MAZE
|
|
-- end
|
|
if macro_x >= 21 then island_subtype_raffle[#island_subtype_raffle + 1] = Surfaces.Island.enum.SWAMP end
|
|
if macro_x >= 21 then island_subtype_raffle[#island_subtype_raffle + 1] = 'none' end
|
|
|
|
--avoid duplicate subtype twice in a row in the same lane
|
|
for _, d in pairs(memory.destinations) do
|
|
if d.subtype and d.overworld_position.x == macro_p.x - 40 and d.overworld_position.y == macro_p.y then
|
|
local new_island_subtype_raffle = Utils.ordered_table_with_values_removed(island_subtype_raffle, d.subtype)
|
|
-- if _DEBUG and #new_island_subtype_raffle ~= #island_subtype_raffle then
|
|
-- game.print('Removed ' .. d.subtype .. ' from raffle at ' .. p.x .. ',' .. p.y)
|
|
-- end
|
|
island_subtype_raffle = new_island_subtype_raffle
|
|
end
|
|
end
|
|
-- some other raffle removals for smoothness:
|
|
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
|
|
if macro_x == 19 then
|
|
island_subtype_raffle = Utils.ordered_table_with_values_removed(island_subtype_raffle, Surfaces.Island.enum.SWAMP)
|
|
end
|
|
|
|
if macro_x == 0 then
|
|
if macro_y == 0 then
|
|
type = Surfaces.enum.ISLAND
|
|
subtype = Surfaces.Island.enum.FIRST
|
|
elseif macro_y == -1 then
|
|
type = Surfaces.enum.DOCK
|
|
else
|
|
type = nil
|
|
end
|
|
elseif macro_x == 1 then
|
|
type = Surfaces.enum.ISLAND
|
|
subtype = Surfaces.Island.enum.HORSESHOE --map where you break rocks
|
|
elseif macro_x == 2 then
|
|
type = Surfaces.enum.ISLAND
|
|
subtype = Surfaces.Island.enum.STANDARD_VARIANT --aesthetically different to first map
|
|
elseif (macro_x > 25 and (macro_x - 22) % 20 == 0) then --we want this to overwrite dock, so putting it here.
|
|
type = Surfaces.enum.ISLAND
|
|
subtype = Surfaces.Island.enum.RADIOACTIVE
|
|
elseif (macro_x > 25 and (macro_x - 22) % 20 == 18) then --we want this to overwrite dock, so putting it here. should be even so rocket launch is forced
|
|
type = Surfaces.enum.ISLAND
|
|
subtype = Surfaces.Island.enum.MAZE
|
|
elseif macro_x == 23 then --overwrite dock. rocket launch cost
|
|
type = Surfaces.enum.ISLAND
|
|
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
|
|
type = nil
|
|
elseif macro_x == 5 then --biter boats appear. large island works well so players run off
|
|
type = Surfaces.enum.ISLAND
|
|
subtype = Surfaces.Island.enum.STANDARD
|
|
elseif macro_x == 6 then
|
|
type = Surfaces.enum.ISLAND
|
|
subtype = Surfaces.Island.enum.MAZE
|
|
elseif macro_x == 8 then --game length decrease, pending more content
|
|
type = nil
|
|
-- elseif macro_x == 9 then --just before krakens
|
|
-- type = Surfaces.enum.ISLAND
|
|
-- subtype = Surfaces.Island.enum.RED_DESERT
|
|
elseif macro_x == 10 then --krakens appear
|
|
type = nil
|
|
-- elseif macro_x == 11 then
|
|
-- if macro_y == -1 then
|
|
-- type = Surfaces.enum.ISLAND
|
|
-- subtype = Surfaces.Island.enum.MAZE
|
|
-- else
|
|
-- type = nil
|
|
-- end
|
|
elseif macro_x == 12 and macro_y < 1 then
|
|
type = Surfaces.enum.ISLAND
|
|
subtype = Surfaces.Island.enum.SWAMP
|
|
elseif macro_x == 16 then
|
|
type = Surfaces.enum.ISLAND
|
|
subtype = Surfaces.Island.enum.RADIOACTIVE
|
|
--electric engines needed at 20
|
|
-- elseif macro_x == 17 then --game length decrease, pending more content
|
|
-- type = nil
|
|
elseif macro_x == 20 then --game length decrease, pending more content
|
|
type = nil
|
|
elseif macro_x == 21 then --rocket launch cost
|
|
type = Surfaces.enum.ISLAND
|
|
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
|
|
type = Surfaces.enum.ISLAND
|
|
subtype = Surfaces.Island.enum.MAZE
|
|
elseif macro_x == 25 then
|
|
type = nil --finish line
|
|
else
|
|
type = Surfaces.enum.ISLAND
|
|
|
|
if #island_subtype_raffle > 0 then
|
|
subtype = island_subtype_raffle[Math.random(#island_subtype_raffle)]
|
|
else
|
|
subtype = 'none'
|
|
end
|
|
|
|
if subtype == 'none' then
|
|
type = nil
|
|
subtype = nil
|
|
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:
|
|
|
|
-- if _DEBUG and type == Surfaces.enum.ISLAND then
|
|
-- subtype = Surfaces.Island.enum.MAZE
|
|
-- -- subtype = nil
|
|
-- -- type = Surfaces.enum.DOCK
|
|
-- end
|
|
|
|
-- warning: the first map is unique in that it isn't all loaded by the time you arrive, which can cause issues. For example, structures might get placed after ore, thereby deleting the ore underneath them.
|
|
|
|
-- if _DEBUG and ((macro_p.x > 0 and macro_p.x < 25)) and type ~= Surfaces.enum.DOCK then
|
|
-- type = nil
|
|
-- subtype = nil
|
|
-- end
|
|
|
|
return {type = type, subtype = subtype}
|
|
end
|
|
|
|
|
|
function Public.generate_overworld_destination(p)
|
|
-- be careful when calling any Balance functions that depend on overworldx — they will be evaluated when the island is chosen, not on arrival
|
|
local memory = Memory.get_crew_memory()
|
|
|
|
local macro_p = {x = p.x/40, y = p.y/24}
|
|
|
|
local type_data = Public.generate_destination_type_and_subtype(p)
|
|
local type = type_data.type
|
|
local subtype = type_data.subtype
|
|
|
|
if type == Surfaces.enum.ISLAND then
|
|
|
|
local scope = Surfaces[Surfaces.enum.ISLAND][subtype]
|
|
|
|
local static_params = Utils.deepcopy(scope.Data.static_params_default)
|
|
local base_cost_to_undock
|
|
|
|
local normal_costitems = {'electronic-circuit', 'advanced-circuit'}
|
|
|
|
-- These need to scale up slightly slower than the static fuel depletion rate, so you're increasingly incentivised to leave:
|
|
local base_cost_1 = {
|
|
['electronic-circuit'] = Math.ceil(((macro_p.x-2)^(2/3))*120),
|
|
}
|
|
local base_cost_2 = {
|
|
['electronic-circuit'] = Math.ceil(((macro_p.x-2)^(2/3))*200),
|
|
['advanced-circuit'] = Math.ceil(((macro_p.x-14)^(2/3))*20),
|
|
-- the below got this response from a new player: "This feels... underwhelming."
|
|
-- ['electronic-circuit'] = Math.ceil(((macro_p.x-2)^(2/3))*120),
|
|
-- ['advanced-circuit'] = Math.ceil(((macro_p.x-14)^(2/3))*18),
|
|
}
|
|
local base_cost_2b = {
|
|
['electronic-circuit'] = Math.ceil(((macro_p.x-2)^(2/3))*200),
|
|
['flying-robot-frame'] = 3,
|
|
}
|
|
local base_cost_3 = {
|
|
['electronic-circuit'] = Math.ceil(((macro_p.x-2)^(2/3))*160),
|
|
['advanced-circuit'] = Math.ceil(((macro_p.x-14)^(2/3))*20),
|
|
['launch_rocket'] = true,
|
|
}
|
|
local base_cost_4 = {
|
|
['electronic-circuit'] = Math.ceil(((macro_p.x-2)^(2/3))*140),
|
|
['advanced-circuit'] = Math.ceil(((macro_p.x-14)^(2/3))*20),
|
|
['flying-robot-frame'] = Math.ceil(((macro_p.x-18)^(2/3))*15),
|
|
['launch_rocket'] = true,
|
|
}
|
|
local base_cost_5 = {
|
|
['electronic-circuit'] = Math.ceil(((macro_p.x-2)^(2/3))*140),
|
|
['advanced-circuit'] = Math.ceil(((macro_p.x-14)^(2/3))*20),
|
|
['flying-robot-frame'] = Math.ceil(((macro_p.x-18)^(2/3))*10),
|
|
-- ['electronic-circuit'] = Math.ceil(((macro_p.x-2)^(2/3))*100),
|
|
-- ['advanced-circuit'] = Math.ceil(((macro_p.x-14)^(2/3))*20),
|
|
-- ['flying-robot-frame'] = Math.ceil(((macro_p.x-18)^(2/3))*10),
|
|
}
|
|
-- if macro_p.x == 0 then
|
|
-- if _DEBUG then
|
|
-- base_cost_to_undock = {
|
|
-- ['electronic-circuit'] = 5,
|
|
-- ['engine-unit'] = 5,
|
|
-- ['advanced-circuit'] = 5,
|
|
-- ['flying-robot-frame'] = 5,
|
|
-- }
|
|
-- end
|
|
-- base_cost_to_undock = nil
|
|
-- elseif macro_p.x <= 6 then
|
|
if macro_p.x <= Common.first_cost_to_leave_macrox - 1 then
|
|
-- base_cost_to_undock = {['electronic-circuit'] = 5}
|
|
base_cost_to_undock = nil
|
|
elseif macro_p.x <= 9 then
|
|
base_cost_to_undock = base_cost_1
|
|
elseif macro_p.x <= 15 then
|
|
if macro_p.x % 3 > 0 then
|
|
base_cost_to_undock = base_cost_1
|
|
else
|
|
base_cost_to_undock = nil
|
|
end
|
|
elseif macro_p.x == 18 then --a super small amount of flying-robot-frame on a relatively early level so that they see they need lubricant
|
|
base_cost_to_undock = base_cost_2b
|
|
elseif macro_p.x <= 20 then
|
|
if macro_p.x % 3 > 0 then
|
|
base_cost_to_undock = base_cost_2
|
|
else
|
|
base_cost_to_undock = nil
|
|
end
|
|
-- after this point, mandatory
|
|
elseif macro_p.x <= 23 then
|
|
base_cost_to_undock = base_cost_3
|
|
elseif macro_p.x <= 24 then
|
|
base_cost_to_undock = base_cost_4
|
|
else
|
|
base_cost_to_undock = Utils.deepcopy(base_cost_5)
|
|
local delete = normal_costitems[Math.random(#normal_costitems)]
|
|
base_cost_to_undock[delete] = nil
|
|
if macro_p.x < 50 then
|
|
if macro_p.x % 2 == 0 then
|
|
base_cost_to_undock['launch_rocket'] = true
|
|
end
|
|
else --now we're just trying to kill you
|
|
base_cost_to_undock['launch_rocket'] = true
|
|
end
|
|
end
|
|
-- override:
|
|
if subtype == Surfaces.Island.enum.RADIOACTIVE then
|
|
base_cost_to_undock = {
|
|
['uranium-235'] = Math.ceil(Math.ceil(80 + (macro_p.x - 1))),
|
|
-- ['uranium-235'] = Math.ceil(Math.ceil(80 + (macro_p.x)/2)), --tried adding beacons instead of this
|
|
}
|
|
end
|
|
|
|
-- -- debug override:
|
|
-- if _DEBUG then
|
|
-- base_cost_to_undock = {
|
|
-- ['electronic-circuit'] = 200,
|
|
-- ['launch_rocket'] = true,
|
|
-- }
|
|
-- end
|
|
|
|
static_params.base_cost_to_undock = base_cost_to_undock -- Multiplication by Balance.cost_to_leave_multiplier() happens later, in destination_on_collide.
|
|
|
|
--scheduled raft raids moved to destination_on_arrival
|
|
|
|
local ores_multiplier = Balance.island_richness_avg_multiplier()
|
|
if macro_p.x == 0 then ores_multiplier = 0.9 end
|
|
|
|
local base_ores = scope.Data.base_ores()
|
|
|
|
local rngs = {}
|
|
local rngsum = 0
|
|
local rngcount = 0
|
|
for k, _ in pairs(base_ores) do
|
|
if k ~= 'coal' then
|
|
local rng = 2*Math.random()
|
|
-- local rng = 1 + ((2*Math.random() - 1)^3) --lower variances
|
|
rngs[k] = rng
|
|
rngsum = rngsum + rng
|
|
rngcount = rngcount + 1
|
|
end
|
|
end
|
|
|
|
local abstract_ore_amounts = {}
|
|
for k, v in pairs(base_ores) do
|
|
local rng = 1
|
|
if not (k == 'coal' or macro_p.x == 0) then
|
|
rng = rngs[k] / (rngsum/rngcount) --average of 1
|
|
end
|
|
abstract_ore_amounts[k] = ores_multiplier * v * rng
|
|
end
|
|
static_params.abstract_ore_amounts = abstract_ore_amounts
|
|
|
|
static_params.radius_squared_modifier = (2 + 2 * Math.random())
|
|
|
|
if macro_p.x == 0 then static_params.radius_squared_modifier = 1.75 end
|
|
|
|
static_params.discord_emoji = scope.Data.discord_emoji
|
|
|
|
local rng = 0.5 + 1 * Math.random()
|
|
static_params.starting_treasure_maps = Math.ceil((static_params.base_starting_treasure_maps or 0) * rng)
|
|
static_params.starting_wood = Math.ceil(static_params.base_starting_wood or 1000)
|
|
static_params.starting_rock_material = Math.ceil(static_params.base_starting_rock_material or 300) * Balance.island_richness_avg_multiplier()
|
|
|
|
rng = 0.5 + 1 * Math.random()
|
|
static_params.starting_treasure = Math.ceil((static_params.base_starting_treasure or 1000) * Balance.island_richness_avg_multiplier() * rng)
|
|
|
|
static_params.name = scope.Data.display_names[Math.random(#scope.Data.display_names)]
|
|
|
|
local dest = Surfaces.initialise_destination{
|
|
static_params = static_params,
|
|
type = type,
|
|
subtype = subtype,
|
|
overworld_position = p,
|
|
}
|
|
|
|
Crowsnest.draw_destination(dest)
|
|
|
|
elseif type == Surfaces.enum.DOCK then
|
|
|
|
local boat_for_sale_type
|
|
-- if macro_p.x == 3 then
|
|
-- boat_for_sale_type = Boats.enum.CUTTER
|
|
-- elseif macro_p.x == 7 or macro_p.x == 0 then
|
|
-- boat_for_sale_type = Boats.enum.SLOOP_WITH_HOLD
|
|
-- end
|
|
boat_for_sale_type = Boats.enum.SLOOP
|
|
|
|
local upgrade_for_sale
|
|
if macro_p.x == 0 then
|
|
upgrade_for_sale = nil
|
|
elseif macro_p.x == 3 then
|
|
upgrade_for_sale = Upgrades.enum.MORE_POWER
|
|
elseif macro_p.x == 7 then
|
|
upgrade_for_sale = Upgrades.enum.EXTRA_HOLD
|
|
elseif macro_p.x % 16 < 8 then
|
|
upgrade_for_sale = Upgrades.enum.MORE_POWER
|
|
else
|
|
upgrade_for_sale = Upgrades.enum.EXTRA_HOLD
|
|
end --upgrades like UNLOCK_MERCHANTS will slot themselves in when necessary, due to .overwrite_a_dock_upgrade()
|
|
-- one day it's worth making this system more readable
|
|
|
|
local static_params = Utils.deepcopy(Dock.Data.static_params_default)
|
|
static_params.upgrade_for_sale = upgrade_for_sale
|
|
static_params.boat_for_sale_type = boat_for_sale_type
|
|
|
|
static_params.name = Dock.Data.display_names[Math.random(#Dock.Data.display_names)]
|
|
|
|
local dest = Surfaces.initialise_destination{
|
|
static_params = static_params,
|
|
type = type,
|
|
subtype = subtype,
|
|
overworld_position = {x = p.x, y = -36},
|
|
-- overworld_position = {x = p.x, y = 36},
|
|
}
|
|
|
|
Crowsnest.draw_destination(dest)
|
|
|
|
-- renderings e.g. for docks
|
|
|
|
local surface = Crowsnest.get_crowsnest_surface()
|
|
local x = Crowsnest.platformrightmostedge + dest.overworld_position.x
|
|
local y = dest.overworld_position.y
|
|
if dest.static_params.upgrade_for_sale then
|
|
local display_form = {'', Upgrades.crowsnest_display_form[dest.static_params.upgrade_for_sale], ':'}
|
|
|
|
if not dest.dynamic_data.crowsnest_renderings then
|
|
dest.dynamic_data.crowsnest_renderings = {}
|
|
end
|
|
|
|
dest.dynamic_data.crowsnest_renderings.base_text_rendering = rendering.draw_text{
|
|
text = display_form,
|
|
surface = surface,
|
|
target = {x = x + 5.5, y = y + 2.5},
|
|
color = CoreData.colors.renderingtext_green,
|
|
scale = 7,
|
|
font = 'default-game',
|
|
alignment = 'right',
|
|
visible = false,
|
|
}
|
|
|
|
local i = 1
|
|
for price_name, price_count in pairs(Shop.Captains.main_shop_data_1[dest.static_params.upgrade_for_sale].base_cost) do
|
|
local sprite
|
|
if price_name == 'fuel' then
|
|
sprite = 'item/coal'
|
|
else
|
|
sprite = 'item/coin'
|
|
end
|
|
dest.dynamic_data.crowsnest_renderings[price_name] = {
|
|
text_rendering = rendering.draw_text{
|
|
text = Utils.bignumber_abbrevform2(price_count),
|
|
surface = surface,
|
|
target = {x = x + 6, y = y + 8.3 - i * 3.5},
|
|
color = CoreData.colors.renderingtext_green,
|
|
scale = 5.2,
|
|
font = 'default-game',
|
|
alignment = 'left',
|
|
visible = false,
|
|
},
|
|
sprite_rendering = rendering.draw_sprite{
|
|
sprite = sprite,
|
|
surface = surface,
|
|
target = {x = x + 14.1, y = y + 10.8 - i * 3.5},
|
|
x_scale = 4.5,
|
|
y_scale = 4.5,
|
|
visible = false,
|
|
}
|
|
}
|
|
i = i + 1
|
|
end
|
|
end
|
|
end
|
|
|
|
--== krakens ==--
|
|
|
|
local kraken_count = 0
|
|
local position_candidates
|
|
if type == nil then
|
|
kraken_count = Balance.krakens_per_free_slot(p.x)
|
|
position_candidates = interior_positions
|
|
elseif type ~= Surfaces.enum.DOCK then
|
|
kraken_count = Balance.krakens_per_slot()
|
|
position_candidates = infront_positions
|
|
end
|
|
|
|
-- override:
|
|
if macro_p.x < 10 then
|
|
kraken_count = 0
|
|
elseif macro_p.x == 10 then
|
|
kraken_count = 1
|
|
end
|
|
|
|
-- if _DEBUG then
|
|
-- kraken_count = 1
|
|
-- end
|
|
|
|
if position_candidates then
|
|
local positions_placed = {}
|
|
local whilesafety = 0
|
|
while whilesafety < 10 and (#positions_placed < Math.min(kraken_count, 10)) do
|
|
local p_chosen, p_kraken
|
|
local whilesafety2 = 0
|
|
while whilesafety2 < 50 and ((not p_kraken) or Utils.contains(positions_placed, p_chosen)) do
|
|
p_chosen = position_candidates[Math.random(#position_candidates)]
|
|
p_kraken = Utils.psum{p_chosen, p}
|
|
whilesafety2 = whilesafety2 + 1
|
|
end
|
|
Crowsnest.draw_kraken(p_kraken)
|
|
positions_placed[#positions_placed + 1] = p_kraken
|
|
memory.overworld_krakens[#memory.overworld_krakens + 1] = p_kraken
|
|
whilesafety = whilesafety + 1
|
|
end
|
|
-- game.print(#positions_placed .. ' krakens placed for' .. macro_p.x .. ', ' .. macro_p.y)
|
|
end
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
function Public.ensure_lane_generated_up_to(lane_yvalue, x)
|
|
-- make sure lane_yvalue=0 is painted first
|
|
local memory = Memory.get_crew_memory()
|
|
|
|
local highest_x = memory['greatest_overworldx_generated_for_' .. lane_yvalue] or -40
|
|
|
|
local whilesafety = 0
|
|
while whilesafety < 10 and highest_x < x do
|
|
whilesafety = whilesafety + 1
|
|
|
|
highest_x = highest_x + 32 + 7 + 1 -- should be at least maximum island size plus crowsnest platform size plus 1
|
|
|
|
if lane_yvalue == 0 then
|
|
Crowsnest.paint_water_between_overworld_positions(highest_x + 32 + 7 + 1, highest_x + 32 + 7 + 1 + 40)
|
|
-- a little hack that we're updating this here rather than Crowsnest, due to the dependency on Shop to avoid a loop... almost finished 1.0, so too late to figure out how to restructure things for now!
|
|
for _, dest in pairs(memory.destinations) do
|
|
if dest.static_params.upgrade_for_sale and dest.dynamic_data.crowsnest_renderings then
|
|
if rendering.is_valid(dest.dynamic_data.crowsnest_renderings.base_text_rendering) then
|
|
rendering.set_text(dest.dynamic_data.crowsnest_renderings.base_text_rendering, {'', Upgrades.crowsnest_display_form[dest.static_params.upgrade_for_sale], ':'})
|
|
end
|
|
for rendering_name, r in pairs(dest.dynamic_data.crowsnest_renderings) do
|
|
if type(r) == 'table' and r.text_rendering and rendering.is_valid(r.text_rendering) then
|
|
rendering.set_text(r.text_rendering, Utils.bignumber_abbrevform2(Shop.Captains.main_shop_data_1[dest.static_params.upgrade_for_sale].base_cost[rendering_name]))
|
|
end
|
|
end
|
|
end
|
|
end
|
|
Crowsnest.update_destination_renderings()
|
|
end
|
|
Public.generate_overworld_destination{x = highest_x, y = lane_yvalue}
|
|
end
|
|
|
|
memory['greatest_overworldx_generated_for_' .. lane_yvalue] = highest_x
|
|
end
|
|
|
|
|
|
|
|
|
|
function Public.is_position_free_to_move_to(p)
|
|
local memory = Memory.get_crew_memory()
|
|
|
|
local ret = true
|
|
|
|
for _, destination_data in pairs(memory.destinations) do
|
|
if p.x >= destination_data.overworld_position.x + 1 and
|
|
p.x <= destination_data.overworld_position.x + destination_data.iconized_map_width + Crowsnest.platformwidth - 1 and
|
|
p.y >= destination_data.overworld_position.y - destination_data.iconized_map_width/2 - Crowsnest.platformheight/2 + 1 and
|
|
p.y <= destination_data.overworld_position.y + destination_data.iconized_map_width/2 + Crowsnest.platformheight/2 - 1
|
|
then
|
|
ret = false
|
|
break
|
|
end
|
|
end
|
|
return ret
|
|
end
|
|
|
|
|
|
function Public.check_for_kraken_collisions()
|
|
local memory = Memory.get_crew_memory()
|
|
local krakens = memory.overworld_krakens
|
|
|
|
for i, k in ipairs(krakens) do
|
|
|
|
local relativex = Crowsnest.platformrightmostedge + k.x - memory.overworldx
|
|
local relativey = k.y - memory.overworldy
|
|
|
|
if (relativex <= 3.5 and relativex >= -3.5 and relativey >= -4 and relativey <= 4) then
|
|
Kraken.try_spawn_kraken()
|
|
memory.overworld_krakens = Utils.ordered_table_with_index_removed(krakens, i)
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
function Public.check_for_destination_collisions()
|
|
local memory = Memory.get_crew_memory()
|
|
|
|
-- if memory.overworldx > CoreData.victory_x - 10 then return end
|
|
-- to avoid crashing into the finish line...
|
|
|
|
for _, destination_data in pairs(memory.destinations) do
|
|
|
|
local relativex = Crowsnest.platformrightmostedge + destination_data.overworld_position.x - memory.overworldx
|
|
local relativey = destination_data.overworld_position.y - memory.overworldy
|
|
|
|
if (relativex == 4 and relativey + destination_data.iconized_map_height/2 >= -3.5 and relativey - destination_data.iconized_map_height/2 <= 3.5) then
|
|
--or (relativey - destination_data.iconized_map.height/2 == 5 and (relativex >= -3.5 or relativex <= 4.5)) or (relativey + destination_data.iconized_map.height/2 == -4 and (relativex >= -3.5 or relativex <= 4.5))
|
|
|
|
Surfaces.clean_up(Common.current_destination())
|
|
|
|
Surfaces.create_surface(destination_data)
|
|
|
|
local index = destination_data.destination_index
|
|
memory.loadingticks = 0
|
|
memory.mapbeingloadeddestination_index = index
|
|
memory.currentdestination_index = index
|
|
memory.boat.state = Boats.enum_state.ATSEA_LOADING_MAP
|
|
|
|
script.raise_event(CustomEvents.enum['update_crew_progress_gui'], {})
|
|
|
|
local destination = Common.current_destination()
|
|
Surfaces.destination_on_collide(destination)
|
|
|
|
Public.cleanup_old_destination_data()
|
|
|
|
return true
|
|
end
|
|
end
|
|
return false
|
|
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
|
|
|
|
|
|
|
|
|
|
function Public.try_overworld_move_v2(vector) --islands stay, crowsnest moves
|
|
local memory = Memory.get_crew_memory()
|
|
|
|
if memory.game_lost or (memory.victory_pause_until_tick and game.tick < memory.victory_pause_until_tick) then return end
|
|
|
|
if memory.victory_continue_message then
|
|
memory.victory_continue_message = false
|
|
Common.notify_force(memory.force, {'pirates.crew_continue_on_freeplay'}, CoreData.colors.notify_victory)
|
|
end
|
|
|
|
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
|
|
return false
|
|
else
|
|
|
|
Crowsnest.move_crowsnest(vector.x, vector.y)
|
|
|
|
if vector.x > 0 then
|
|
|
|
-- merchant is disabled
|
|
-- crew bonus resources per x:
|
|
-- local crew = Common.crew_get_crew_members()
|
|
-- for _, player in pairs(crew) do
|
|
-- if Common.validate_player_and_character(player) then
|
|
-- local player_index = player.index
|
|
-- if memory.classes_table and memory.classes_table[player_index] == 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 = 50 * vector.x}}
|
|
-- end
|
|
-- end
|
|
-- end
|
|
|
|
-- other freebies:
|
|
for i=1,vector.x do
|
|
Common.give_items_to_crew(Balance.periodic_free_resources_per_x())
|
|
end
|
|
|
|
Balance.apply_crew_buffs_per_league(memory.force, vector.x)
|
|
|
|
-- add some evo: (this will get reset upon arriving at a destination anyway, so this is just relevant for sea monsters and the like:)
|
|
local extra_evo = Balance.base_evolution_leagues(memory.overworldx) - Balance.base_evolution_leagues(memory.overworldx - vector.x)
|
|
Common.increment_evo(extra_evo)
|
|
end
|
|
|
|
if memory.overworldx >= CoreData.victory_x then
|
|
Crew.try_win()
|
|
end
|
|
|
|
if memory.overworldx % 40 == 0 then
|
|
local modal_captain = nil
|
|
local modal_captain_time = 0
|
|
for name, time in pairs(memory.captain_accrued_time_data) do
|
|
if time > modal_captain_time then
|
|
modal_captain_time = time
|
|
modal_captain = name
|
|
end
|
|
end
|
|
Highscore.write_score(memory.secs_id, memory.name, modal_captain, memory.completion_time or 0, memory.overworldx, CoreData.version_string, memory.difficulty, memory.max_players_recorded or 0)
|
|
end
|
|
|
|
return true
|
|
end
|
|
end
|
|
|
|
|
|
|
|
function Public.overwrite_a_dock_upgrade()
|
|
local memory = Memory.get_crew_memory()
|
|
|
|
if (memory.overworldx % (40*8)) == (40*4-1) then -- pick a point that _must_ be visited, i.e. right before a destination
|
|
if (memory.overworldx) == (40*4-1) then -- LEAVE A GAP at x=40*11, because we haven't developed an upgrade to put there yet
|
|
for _, dest in pairs(memory.destinations) do
|
|
if dest.type == Surfaces.enum.DOCK then
|
|
if dest.overworld_position.x == memory.overworldx + 1 + (40*7) then
|
|
dest.static_params.upgrade_for_sale = Upgrades.enum.MORE_POWER
|
|
end
|
|
end
|
|
end
|
|
else
|
|
local upgrade_to_overwrite_with
|
|
|
|
if not memory.dock_overwrite_variable then memory.dock_overwrite_variable = 1 end
|
|
|
|
local possible_overwrites = {}
|
|
if (not memory.merchant_ships_unlocked) then
|
|
possible_overwrites[#possible_overwrites + 1] = Upgrades.enum.UNLOCK_MERCHANTS
|
|
end
|
|
if (not memory.rockets_for_sale) then
|
|
possible_overwrites[#possible_overwrites + 1] = Upgrades.enum.ROCKETS_FOR_SALE
|
|
end
|
|
|
|
if #possible_overwrites > 0 then
|
|
if memory.dock_overwrite_variable > #possible_overwrites then memory.dock_overwrite_variable = 1 end
|
|
upgrade_to_overwrite_with = possible_overwrites[memory.dock_overwrite_variable]
|
|
|
|
-- bump the variable up, but only if the list hasn't reduced in length. use a second variable to track this:
|
|
if memory.dock_overwrite_variable_2 and memory.dock_overwrite_variable_2 == #possible_overwrites then
|
|
memory.dock_overwrite_variable = memory.dock_overwrite_variable + 1
|
|
end
|
|
memory.dock_overwrite_variable_2 = #possible_overwrites
|
|
end
|
|
|
|
if upgrade_to_overwrite_with then
|
|
for _, dest in pairs(memory.destinations) do
|
|
if dest.type == Surfaces.enum.DOCK then
|
|
if dest.overworld_position.x == memory.overworldx + 1 + (40*7) then
|
|
dest.static_params.upgrade_for_sale = upgrade_to_overwrite_with
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return Public |