2022-06-01 20:50:36 +02:00
-- This file is part of thesixthroc's Pirate Ship softmod, licensed under GPLv3 and stored at https://github.com/danielmartin0/ComfyFactorio-Pirates.
2021-10-13 10:21:53 +02:00
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 '
2022-10-02 23:37:54 +02:00
-- local _inspect = require 'utils.inspect'.inspect
2022-03-19 23:20:55 +02:00
-- local Server = require 'utils.server'
2021-10-13 10:21:53 +02:00
2022-03-19 23:20:55 +02:00
-- local Structures = require 'maps.pirates.structures.structures'
2021-10-13 10:21:53 +02:00
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 '
2022-10-02 23:37:54 +02:00
local Islands = require ' maps.pirates.surfaces.islands.islands '
2022-03-19 23:20:55 +02:00
-- local Sea = require 'maps.pirates.surfaces.sea.sea'
2021-10-13 10:21:53 +02:00
local Crew = require ' maps.pirates.crew '
2022-03-19 23:20:55 +02:00
-- local Roles = require 'maps.pirates.roles.roles'
2022-07-28 19:28:27 +02:00
-- local Classes = require 'maps.pirates.roles.classes'
2022-03-19 23:20:55 +02:00
-- 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'
2021-10-13 10:21:53 +02:00
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 '
2022-03-13 03:44:32 +02:00
local CustomEvents = require ' maps.pirates.custom_events '
2022-10-10 21:03:51 +02:00
local IslandEnum = require ' maps.pirates.surfaces.islands.island_enum '
2021-10-13 10:21:53 +02:00
2022-07-30 15:02:24 +02:00
local NIL = ' none '
local DOCK = ' dock '
2022-10-10 21:03:51 +02:00
local FIRST = IslandEnum.enum . FIRST
local RED_DESERT = IslandEnum.enum . RED_DESERT
local SWAMP = IslandEnum.enum . SWAMP
local STANDARD = IslandEnum.enum . STANDARD
local WALKWAYS = IslandEnum.enum . WALKWAYS
local MAZE = IslandEnum.enum . MAZE
local RADIOACTIVE = IslandEnum.enum . RADIOACTIVE
local HORSESHOE = IslandEnum.enum . HORSESHOE
local STANDARD_VARIANT = IslandEnum.enum . STANDARD_VARIANT
local CAVE = IslandEnum.enum . CAVE
2022-07-30 15:02:24 +02:00
2022-10-04 20:28:35 +02:00
local A = { STANDARD_VARIANT , RED_DESERT , HORSESHOE , WALKWAYS }
2022-10-02 23:37:54 +02:00
local B = { NIL , NIL , NIL , STANDARD , STANDARD_VARIANT , RED_DESERT , HORSESHOE , WALKWAYS , CAVE }
2022-10-04 20:28:35 +02:00
local C = { STANDARD , STANDARD_VARIANT , RED_DESERT , HORSESHOE , WALKWAYS }
2022-10-02 23:37:54 +02:00
local D = { NIL , NIL , NIL , STANDARD , STANDARD_VARIANT , RED_DESERT , HORSESHOE , WALKWAYS , SWAMP , CAVE }
2022-07-30 15:02:24 +02:00
local destinationScheme = {
[ 0 ] = { DOCK , FIRST , NIL } ,
[ 1 ] = { HORSESHOE , HORSESHOE , HORSESHOE } , --map where you break rocks
[ 2 ] = { STANDARD_VARIANT , STANDARD_VARIANT , STANDARD_VARIANT } , --aesthetically different to previous map
[ 3 ] = { DOCK , NIL , NIL } ,
2022-07-31 22:13:14 +02:00
[ 4 ] = { A , A , NIL } ,
2022-07-30 15:02:24 +02:00
[ 5 ] = { STANDARD , STANDARD , STANDARD } , --biter boats appear. large island works well so players run off
[ 6 ] = { MAZE , MAZE , MAZE } ,
[ 7 ] = { DOCK , B , B } ,
[ 8 ] = { NIL , NIL , NIL } ,
[ 9 ] = { B , B , B } ,
[ 10 ] = { NIL , NIL , NIL } ,
[ 11 ] = { DOCK , B , B } ,
[ 12 ] = { SWAMP , SWAMP , C } , --gotta steer if you don't want to do swamp
[ 13 ] = { B , B , B } ,
[ 14 ] = { B , B , B } ,
[ 15 ] = { DOCK , B , B } ,
[ 16 ] = { RADIOACTIVE , RADIOACTIVE , RADIOACTIVE } ,
[ 17 ] = { B , B , B } ,
[ 18 ] = { C , C , C } , --first showing of robot frame cost
[ 19 ] = { DOCK , B , B } ,
2022-07-31 11:23:59 +02:00
[ 20 ] = { WALKWAYS , WALKWAYS , WALKWAYS } , --rocket launch cost begins
[ 21 ] = { SWAMP , RED_DESERT , STANDARD_VARIANT } , -- uniquely, this has a rocket launch cost, but still has an auto-undock timer
[ 22 ] = { NIL , NIL , NIL } ,
2022-07-30 15:02:24 +02:00
[ 23 ] = { C , C , C } ,
[ 24 ] = { MAZE , MAZE , MAZE } , -- current 'boss map'
[ 25 ] = { NIL , NIL , NIL } ,
}
2021-10-13 10:21:53 +02:00
2022-07-30 15:02:24 +02:00
function Public . generate_destination_type_and_subtype ( overworld_position )
2022-03-19 23:20:55 +02:00
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
2021-10-13 10:21:53 +02:00
2022-07-30 15:02:24 +02:00
local type2 , subtype
2021-10-13 10:21:53 +02:00
2022-07-30 15:02:24 +02:00
if destinationScheme [ macro_x ] then
subtype = destinationScheme [ macro_x ] [ macro_y + 2 ]
else
if ( macro_x - 22 ) % 20 == 0 then
subtype = RADIOACTIVE
elseif ( macro_x - 22 ) % 20 == 18 then
subtype = MAZE
elseif macro_y == - 1 and ( macro_x % 4 ) == 3 then
subtype = DOCK
else
subtype = D
2022-03-05 02:11:11 +02:00
end
end
2022-07-30 15:02:24 +02:00
if type ( subtype ) == ' table ' then
if destinationScheme [ macro_x - 1 ] then
local previous = destinationScheme [ macro_x - 1 ] [ macro_y + 2 ]
if previous and type ( previous ) ~= ' table ' and previous ~= NIL and previous ~= DOCK then
subtype = Utils.deepcopy ( subtype )
subtype = Utils.ordered_table_with_values_removed ( subtype , previous ) --avoid duplicate subtype twice in a row in the same lane
end
end
subtype = subtype [ Math.random ( # subtype ) ]
2022-03-14 14:44:30 +02:00
end
2022-07-30 15:02:24 +02:00
if subtype == NIL then
type2 = nil
subtype = nil
elseif subtype == DOCK then
type2 = Surfaces.enum . DOCK
subtype = nil
else
type2 = Surfaces.enum . ISLAND
2022-03-11 12:40:55 +02:00
end
2022-10-04 20:28:35 +02:00
return { type = type2 , subtype = subtype }
2022-11-18 22:18:16 +02:00
-- return {type = Surfaces.enum.ISLAND, subtype = IslandEnum.enum.CAVE}
2022-07-30 15:02:24 +02:00
end
function Public . generate_destination_base_cost_to_undock ( p , subtype )
local macro_p = { x = p.x / 40 , y = p.y / 24 }
local base_cost_to_undock
local normal_costitems = { ' electronic-circuit ' , ' advanced-circuit ' }
-- local special_costitems = {'rocket-fuel', 'flying-robot-frame'}
-- 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 ) ,
2022-11-13 23:21:02 +02:00
[ ' flying-robot-frame ' ] = 5 ,
2022-07-30 15:02:24 +02:00
}
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 ) ) * 25 ) ,
[ ' 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 ) ,
-- ['rocket-fuel'] = 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
2021-10-13 10:21:53 +02:00
else
2022-07-30 15:02:24 +02:00
base_cost_to_undock = nil
2021-10-13 10:21:53 +02:00
end
2022-07-30 15:02:24 +02:00
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
2022-07-31 11:23:59 +02:00
elseif macro_p.x <= 19 then
2022-07-30 15:02:24 +02:00
if macro_p.x % 3 == 0 then
base_cost_to_undock = nil
2022-05-05 10:55:48 +02:00
else
2022-07-30 15:02:24 +02:00
base_cost_to_undock = base_cost_2
2022-05-05 10:55:48 +02:00
end
2022-07-31 11:23:59 +02:00
-- after this point, mandatory to pay. except for 21
elseif macro_p.x == 21 then
2022-07-30 15:02:24 +02:00
base_cost_to_undock = base_cost_2
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
2021-10-13 10:21:53 +02:00
else
2022-07-30 15:02:24 +02:00
base_cost_to_undock = Utils.deepcopy ( base_cost_5 )
local delete = normal_costitems [ Math.random ( # normal_costitems ) ]
base_cost_to_undock [ delete ] = nil
-- local delete2 = special_costitems[Math.random(#special_costitems)]
-- base_cost_to_undock[delete2] = 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
2021-10-13 10:21:53 +02:00
end
end
2023-01-12 18:58:53 +02:00
2022-07-30 15:02:24 +02:00
-- override:
2022-10-10 21:03:51 +02:00
if subtype == IslandEnum.enum . RADIOACTIVE then
2022-07-30 15:02:24 +02:00
base_cost_to_undock = {
2023-02-04 17:14:48 +02:00
[ ' uranium-235 ' ] = Math.ceil ( Math.ceil ( 65 + 2 * ( macro_p.x - 1 ) ) ) , -- people now have access to uranium tech and can make it on ship
-- ['uranium-235'] = Math.ceil(Math.ceil(80 + (macro_p.x - 1))),
2022-07-30 15:02:24 +02:00
-- ['uranium-235'] = Math.ceil(Math.ceil(80 + (macro_p.x)/2)), --tried adding beacons instead of this
}
2023-02-03 23:24:11 +02:00
elseif subtype == IslandEnum.enum . RED_DESERT or subtype == IslandEnum.enum . CAVE then
2023-01-12 18:58:53 +02:00
if base_cost_to_undock and base_cost_to_undock [ ' launch_rocket ' ] == true then
2023-02-19 15:05:34 +02:00
base_cost_to_undock [ ' launch_rocket ' ] = nil
2023-01-12 18:58:53 +02:00
end
2022-07-30 15:02:24 +02:00
end
-- -- debug override:
-- if _DEBUG then
-- base_cost_to_undock = {
-- ['electronic-circuit'] = 200,
-- ['launch_rocket'] = true,
-- }
-- end
2021-10-13 10:21:53 +02:00
2022-07-30 15:02:24 +02:00
return base_cost_to_undock -- Multiplication by Balance.cost_to_leave_multiplier() happens later, in destination_on_collide.
end
2022-05-06 14:00:57 +02:00
2022-03-04 19:57:58 +02:00
2022-03-20 13:41:23 +02:00
2022-03-04 19:57:58 +02:00
2021-10-13 10:21:53 +02:00
2022-07-30 15:02:24 +02:00
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
2022-03-19 23:20:55 +02:00
end
2022-07-30 15:02:24 +02:00
2022-03-19 23:20:55 +02:00
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
2021-10-13 10:21:53 +02:00
if type == Surfaces.enum . ISLAND then
local scope = Surfaces [ Surfaces.enum . ISLAND ] [ subtype ]
local static_params = Utils.deepcopy ( scope.Data . static_params_default )
2022-03-17 03:40:18 +02:00
2022-07-30 15:02:24 +02:00
static_params.base_cost_to_undock = Public.generate_destination_base_cost_to_undock ( p , subtype ) -- Multiplication by Balance.cost_to_leave_multiplier() happens later, in destination_on_collide.
2023-01-29 15:02:06 +02:00
static_params.undock_cost_decreases = true
if Balance.need_resources_to_undock ( p.x ) == true or subtype == IslandEnum.enum . RADIOACTIVE then
static_params.undock_cost_decreases = false
end
2021-10-13 10:21:53 +02:00
2021-10-14 11:23:34 +02:00
--scheduled raft raids moved to destination_on_arrival
2021-10-13 10:21:53 +02:00
2023-02-19 18:57:38 +02:00
local ores_multiplier = Balance.island_richness_avg_multiplier ( p.x )
2022-03-19 23:20:55 +02:00
2021-10-13 10:21:53 +02:00
local base_ores = scope.Data . base_ores ( )
local rngs = { }
local rngsum = 0
local rngcount = 0
for k , _ in pairs ( base_ores ) do
2022-02-24 21:39:03 +02:00
if k ~= ' coal ' then
2023-02-19 18:57:38 +02:00
-- It's preferred to create variance with different island types, rather than this, as it's important to have low variance in early islands for easier balance and predictable early gameplay.
-- Here we increase "rng" element on later islands as that's when "rng" shouldn't matter too much once players got solid start.
local rng
if p.x <= 400 then
rng = Math.random_float_in_range ( 0.8 , 1.2 )
else
rng = Math.random_float_in_range ( 0.5 , 1.5 )
end
2023-02-19 15:05:34 +02:00
-- local rng = 2*Math.random() -- such huge variance hard to reason and balance around, considering resources aren't equally worth.
2022-02-24 21:39:03 +02:00
-- local rng = 1 + ((2*Math.random() - 1)^3) --lower variances
2023-02-19 18:57:38 +02:00
2022-02-24 21:39:03 +02:00
rngs [ k ] = rng
rngsum = rngsum + rng
rngcount = rngcount + 1
end
2021-10-13 10:21:53 +02:00
end
local abstract_ore_amounts = { }
for k , v in pairs ( base_ores ) do
2022-02-24 21:39:03 +02:00
local rng = 1
2022-03-19 23:20:55 +02:00
if not ( k == ' coal ' or macro_p.x == 0 ) then
2022-02-24 21:39:03 +02:00
rng = rngs [ k ] / ( rngsum / rngcount ) --average of 1
end
2021-10-13 10:21:53 +02:00
abstract_ore_amounts [ k ] = ores_multiplier * v * rng
end
static_params.abstract_ore_amounts = abstract_ore_amounts
2022-03-13 03:44:32 +02:00
static_params.radius_squared_modifier = ( 2 + 2 * Math.random ( ) )
2021-10-13 10:21:53 +02:00
2022-03-19 23:20:55 +02:00
if macro_p.x == 0 then static_params.radius_squared_modifier = 1.75 end
2021-10-13 10:21:53 +02:00
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 )
2023-01-29 23:01:48 +02:00
static_params.starting_wood = static_params.base_starting_wood or 1000
2023-02-19 18:57:38 +02:00
static_params.starting_wood = Math.ceil ( static_params.starting_wood * Balance.island_richness_avg_multiplier ( p.x ) )
static_params.starting_rock_material = Math.ceil ( static_params.base_starting_rock_material or 300 ) * Balance.island_richness_avg_multiplier ( p.x )
2022-03-19 23:20:55 +02:00
2021-10-13 10:21:53 +02:00
rng = 0.5 + 1 * Math.random ( )
2023-02-19 18:57:38 +02:00
static_params.starting_treasure = Math.ceil ( ( static_params.base_starting_treasure or 1000 ) * Balance.island_richness_avg_multiplier ( p.x ) * rng )
2021-10-13 10:21:53 +02:00
static_params.name = scope.Data . display_names [ Math.random ( # scope.Data . display_names ) ]
2022-03-19 23:20:55 +02:00
2021-10-13 10:21:53 +02:00
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
2022-03-19 23:20:55 +02:00
-- if macro_p.x == 3 then
2021-10-13 10:21:53 +02:00
-- boat_for_sale_type = Boats.enum.CUTTER
2022-03-19 23:20:55 +02:00
-- elseif macro_p.x == 7 or macro_p.x == 0 then
2021-10-13 10:21:53 +02:00
-- boat_for_sale_type = Boats.enum.SLOOP_WITH_HOLD
-- end
boat_for_sale_type = Boats.enum . SLOOP
2022-10-23 14:16:39 +02:00
local upgrade_for_sale = nil
-- These upgrades have been made to be exclusive purchase at captain's cabin
-- 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
2022-10-30 23:25:30 +02:00
-- end --upgrades like UNLOCK_MERCHANTS will slot themselves in when necessary, due to .overwrite_a_dock_upgrade() (not anymore)
2022-02-28 18:36:46 +02:00
-- one day it's worth making this system more readable
2021-10-13 10:21:53 +02:00
2023-02-04 19:39:07 +02:00
-- NOTE: When DOCK frequency changes, this needs to change too (kinda bad design, but whatever)
-- NOTE: I couldn't manage to make upgrade overwriting to work so I made it here
2022-10-30 23:25:30 +02:00
-- TODO: Perhaps always have something special to sell (or remove the upgrade market if it has no offers?)
2022-11-19 23:28:37 +02:00
if macro_p.x % 16 == 15 and ( not memory.rockets_for_sale ) then
2022-10-30 23:25:30 +02:00
upgrade_for_sale = Upgrades.enum . ROCKETS_FOR_SALE
2022-11-19 23:28:37 +02:00
elseif macro_p.x % 16 == 3 and macro_p.x > 16 and ( not memory.merchant_ships_unlocked ) then
2022-10-30 23:25:30 +02:00
upgrade_for_sale = Upgrades.enum . UNLOCK_MERCHANTS
elseif ( macro_p.x % 8 ) == 3 then
upgrade_for_sale = Upgrades.enum . UPGRADE_CANNONS
end
2021-10-13 10:21:53 +02:00
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 ,
2022-03-04 19:57:58 +02:00
overworld_position = { x = p.x , y = - 36 } ,
-- overworld_position = {x = p.x, y = 36},
2021-10-13 10:21:53 +02:00
}
Crowsnest.draw_destination ( dest )
-- renderings e.g. for docks
2022-03-19 23:20:55 +02:00
2021-10-13 10:21:53 +02:00
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
2022-06-01 20:50:36 +02:00
local display_form = { ' ' , Upgrades.crowsnest_display_form [ dest.static_params . upgrade_for_sale ] , ' : ' }
2022-02-27 18:42:25 +02:00
if not dest.dynamic_data . crowsnest_renderings then
dest.dynamic_data . crowsnest_renderings = { }
end
2022-03-19 23:20:55 +02:00
2022-02-27 18:42:25 +02:00
dest.dynamic_data . crowsnest_renderings.base_text_rendering = rendering.draw_text {
2022-06-01 20:50:36 +02:00
text = display_form ,
2021-10-13 10:21:53 +02:00
surface = surface ,
2022-03-04 19:57:58 +02:00
target = { x = x + 5.5 , y = y + 2.5 } ,
2021-10-13 10:21:53 +02:00
color = CoreData.colors . renderingtext_green ,
scale = 7 ,
font = ' default-game ' ,
alignment = ' right ' ,
visible = false ,
}
2022-02-27 18:42:25 +02:00
local i = 1
2022-03-07 20:41:42 +02:00
for price_name , price_count in pairs ( Shop.Captains . main_shop_data_1 [ dest.static_params . upgrade_for_sale ] . base_cost ) do
2022-02-27 18:42:25 +02:00
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 {
2022-02-28 18:36:46 +02:00
text = Utils.bignumber_abbrevform2 ( price_count ) ,
2022-02-27 18:42:25 +02:00
surface = surface ,
2022-03-04 19:57:58 +02:00
target = { x = x + 6 , y = y + 8.3 - i * 3.5 } ,
2022-02-27 18:42:25 +02:00
color = CoreData.colors . renderingtext_green ,
scale = 5.2 ,
font = ' default-game ' ,
alignment = ' left ' ,
visible = false ,
} ,
sprite_rendering = rendering.draw_sprite {
sprite = sprite ,
surface = surface ,
2022-03-04 19:57:58 +02:00
target = { x = x + 14.1 , y = y + 10.8 - i * 3.5 } ,
2022-02-27 18:42:25 +02:00
x_scale = 4.5 ,
y_scale = 4.5 ,
visible = false ,
}
}
i = i + 1
end
2021-10-13 10:21:53 +02:00
end
end
--== krakens ==--
local kraken_count = 0
local position_candidates
if type == nil then
2022-03-09 01:36:03 +02:00
kraken_count = Balance.krakens_per_free_slot ( p.x )
2021-10-13 10:21:53 +02:00
position_candidates = interior_positions
elseif type ~= Surfaces.enum . DOCK then
2022-03-19 23:20:55 +02:00
kraken_count = Balance.krakens_per_slot ( )
2021-10-13 10:21:53 +02:00
position_candidates = infront_positions
end
-- override:
2022-03-19 23:20:55 +02:00
if macro_p.x < 10 then
2021-10-13 10:21:53 +02:00
kraken_count = 0
2022-03-19 23:20:55 +02:00
elseif macro_p.x == 10 then
2021-10-13 10:21:53 +02:00
kraken_count = 1
2022-07-31 11:23:59 +02:00
elseif macro_p.x == 22 then
2022-07-31 14:08:22 +02:00
kraken_count = 2
2021-10-13 10:21:53 +02:00
end
2022-03-19 23:20:55 +02:00
-- if _DEBUG then
2022-03-17 03:40:18 +02:00
-- kraken_count = 1
2022-03-19 23:20:55 +02:00
-- end
2022-03-04 19:57:58 +02:00
2021-10-13 10:21:53 +02:00
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
2022-03-19 23:20:55 +02:00
-- game.print(#positions_placed .. ' krakens placed for' .. macro_p.x .. ', ' .. macro_p.y)
2021-10-13 10:21:53 +02:00
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 )
2022-02-27 18:42:25 +02:00
-- 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!
2021-10-13 10:21:53 +02:00
for _ , dest in pairs ( memory.destinations ) do
2022-02-27 20:47:53 +02:00
if dest.static_params . upgrade_for_sale and dest.dynamic_data . crowsnest_renderings then
2022-02-28 18:36:46 +02:00
if rendering.is_valid ( dest.dynamic_data . crowsnest_renderings.base_text_rendering ) then
2022-06-01 20:50:36 +02:00
rendering.set_text ( dest.dynamic_data . crowsnest_renderings.base_text_rendering , { ' ' , Upgrades.crowsnest_display_form [ dest.static_params . upgrade_for_sale ] , ' : ' } )
2022-02-28 18:36:46 +02:00
end
2022-02-27 18:42:25 +02:00
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
2022-03-07 20:41:42 +02:00
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 ] ) )
2022-02-27 18:42:25 +02:00
end
2021-10-13 10:21:53 +02:00
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
2022-07-16 20:46:23 +02:00
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
2021-10-13 10:21:53 +02:00
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))
2022-03-19 23:20:55 +02:00
2021-10-14 11:23:34 +02:00
Surfaces.clean_up ( Common.current_destination ( ) )
2021-10-13 10:21:53 +02:00
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
2022-03-13 03:44:32 +02:00
script.raise_event ( CustomEvents.enum [ ' update_crew_progress_gui ' ] , { } )
2021-10-13 10:21:53 +02:00
local destination = Common.current_destination ( )
2021-10-14 11:23:34 +02:00
Surfaces.destination_on_collide ( destination )
2021-10-13 10:21:53 +02:00
2022-05-05 10:55:48 +02:00
Public.cleanup_old_destination_data ( )
2021-10-13 10:21:53 +02:00
return true
end
end
return false
end
2022-05-05 10:55:48 +02:00
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
2022-10-10 21:03:51 +02:00
Islands [ IslandEnum.enum . CAVE ] . cleanup_cave_surface ( memory.destinations [ i ] )
2022-10-02 23:37:54 +02:00
2022-05-05 10:55:48 +02:00
memory.destinations [ i ] = nil
end
end
end
2021-10-13 10:21:53 +02:00
function Public . try_overworld_move_v2 ( vector ) --islands stay, crowsnest moves
local memory = Memory.get_crew_memory ( )
2022-07-30 15:02:24 +02:00
-- if memory.game_lost or (memory.victory_pause_until_tick and game.tick < memory.victory_pause_until_tick) then return end
2021-10-13 10:21:53 +02:00
2022-07-30 15:02:24 +02:00
-- 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
2021-10-13 10:21:53 +02:00
2022-05-05 11:14:22 +02:00
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 )
2022-10-30 23:25:30 +02:00
-- Public.overwrite_a_dock_upgrade()
2022-05-05 11:14:22 +02:00
end
2021-10-13 10:21:53 +02:00
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 )
2022-03-19 23:20:55 +02:00
2021-10-13 10:21:53 +02:00
if vector.x > 0 then
2022-07-28 12:28:38 +02:00
-- merchant is disabled
2021-10-13 10:21:53 +02:00
-- crew bonus resources per x:
2022-07-28 12:28:38 +02:00
-- 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
2021-10-13 10:21:53 +02:00
-- other freebies:
2023-01-29 23:01:48 +02:00
-- for i=1,vector.x do
-- Common.give_items_to_crew(Balance.periodic_free_resources_per_x())
-- end
2022-06-02 18:49:05 +02:00
2023-01-29 23:01:48 +02:00
-- Makes game hard to balance around this when productivity bonus is not constant.
-- Balance.apply_crew_buffs_per_league(memory.force, vector.x)
2021-10-13 10:21:53 +02:00
2022-03-17 03:40:18 +02:00
-- 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 )
2021-10-13 10:21:53 +02:00
end
2022-03-01 23:59:48 +02:00
if memory.overworldx >= CoreData.victory_x then
Crew.try_win ( )
2021-10-13 10:21:53 +02:00
end
if memory.overworldx % 40 == 0 then
local modal_captain = nil
local modal_captain_time = 0
2021-10-13 15:56:49 +02:00
for name , time in pairs ( memory.captain_accrued_time_data ) do
2021-10-13 10:21:53 +02:00
if time > modal_captain_time then
modal_captain_time = time
2021-10-13 15:56:49 +02:00
modal_captain = name
2021-10-13 10:21:53 +02:00
end
end
2022-05-29 13:36:27 +02:00
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 )
2021-10-13 10:21:53 +02:00
end
return true
end
end
2022-10-30 23:25:30 +02:00
-- UNUSED
2021-10-13 10:21:53 +02:00
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
2022-10-30 23:25:30 +02:00
-- POWER upgrade is disabled at docks
-- 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
2021-10-13 10:21:53 +02:00
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 ]
2022-03-19 23:20:55 +02:00
2021-10-13 10:21:53 +02:00
-- 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
2022-03-19 23:20:55 +02:00
2021-10-13 10:21:53 +02:00
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
2022-10-30 23:25:30 +02:00
-- end
2021-10-13 10:21:53 +02:00
end
end
return Public