2021-10-13 10:21:53 +02:00
local Memory = require ' maps.pirates.memory '
local Common = require ' maps.pirates.common '
local CoreData = require ' maps.pirates.coredata '
2022-03-19 23:20:55 +02:00
-- local Utils = require 'maps.pirates.utils_local'
2021-10-13 10:21:53 +02:00
local Math = require ' maps.pirates.math '
2022-03-19 23:20:55 +02:00
local _inspect = require ' utils.inspect ' . inspect
2021-10-13 10:21:53 +02:00
local Crew = require ' maps.pirates.crew '
2022-03-19 23:20:55 +02:00
-- local Progression = require 'maps.pirates.progression'
-- local Structures = require 'maps.pirates.structures.structures'
2021-10-13 10:21:53 +02:00
local Shop = require ' maps.pirates.shop.shop '
2022-03-19 23:20:55 +02:00
local Boats = require ' maps.pirates.structures.boats.boats '
local Surfaces = require ' maps.pirates.surfaces.surfaces '
2021-10-13 10:21:53 +02:00
local Public = { }
Public.bold_font_color = { 255 , 230 , 192 }
Public.default_font_color = { 1 , 1 , 1 }
Public.section_header_font_color = { r = 0.40 , g = 0.80 , b = 0.60 }
Public.subsection_header_font_color = { 229 , 255 , 242 }
Public.friendly_font_color = { 240 , 200 , 255 }
Public.sufficient_font_color = { 66 , 220 , 124 }
Public.insufficient_font_color = { 1 , 0.62 , 0.19 }
2022-03-09 01:36:03 +02:00
Public.achieved_font_color = { 227 , 250 , 192 }
2021-10-13 10:21:53 +02:00
2022-02-27 01:33:19 +02:00
Public.fuel_color_1 = { r = 255 , g = 255 , b = 255 }
Public.fuel_color_2 = { r = 255 , g = 0 , b = 60 }
Public.rage_font_color_1 = { r = 1 , g = 1 , b = 1 }
Public.rage_font_color_2 = { r = 1 , g = 0.5 , b = 0.1 }
Public.rage_font_color_3 = { r = 1 , g = 0.1 , b = 0.05 }
2021-10-13 10:21:53 +02:00
Public.default_window_positions = {
runs = { x = 10 , y = 48 } ,
crew = { x = 40 , y = 48 } ,
progress = { x = 250 , y = 48 } ,
2022-02-24 21:39:03 +02:00
fuel = { x = 468 , y = 48 } ,
2021-10-13 10:21:53 +02:00
minimap = { x = 10 , y = 48 } ,
2022-02-25 02:01:28 +02:00
color = { x = 160 , y = 96 } ,
2021-10-13 10:21:53 +02:00
}
function Public . new_window ( player , name )
local global_memory = Memory.get_global_memory ( )
local gui_memory = global_memory.player_gui_memories [ player.index ]
2022-03-19 23:20:55 +02:00
local flow
2021-10-13 10:21:53 +02:00
flow = player.gui . screen.add {
type = ' frame ' ,
name = name .. ' _piratewindow ' ,
direction = ' vertical '
}
if gui_memory and gui_memory [ name ] and gui_memory [ name ] . position then
flow.location = gui_memory [ name ] . position
else
flow.location = Public.default_window_positions [ name ]
end
2022-03-19 23:20:55 +02:00
2021-10-13 10:21:53 +02:00
flow.style = ' map_details_frame '
flow.style . minimal_width = 210
flow.style . natural_width = 210
flow.style . maximal_width = 270
flow.style . minimal_height = 80
flow.style . natural_height = 80
2022-03-09 01:36:03 +02:00
flow.style . maximal_height = 700
2021-10-13 10:21:53 +02:00
flow.style . padding = 10
return flow
end
function Public . update_gui_memory ( player , namespace , key , value )
local global_memory = Memory.get_global_memory ( )
if not global_memory.player_gui_memories [ player.index ] then
global_memory.player_gui_memories [ player.index ] = { }
end
local gui_memory = global_memory.player_gui_memories [ player.index ]
if not gui_memory [ namespace ] then
gui_memory [ namespace ] = { }
end
gui_memory [ namespace ] [ key ] = value
end
function Public . flow_add_floating_sprite_button ( flow1 , button_name , width )
width = width or 40
local flow2 , flow3
2022-03-19 23:20:55 +02:00
2021-10-13 10:21:53 +02:00
flow2 = flow1.add ( {
name = button_name .. ' _frame ' ,
type = ' frame ' ,
} )
flow2.style . height = 40
flow2.style . margin = 0
2022-02-24 21:39:03 +02:00
flow2.style . left_padding = - 4
flow2.style . top_padding = - 4
flow2.style . right_margin = - 2
2021-10-13 10:21:53 +02:00
flow2.style . width = width
flow3 = flow2.add ( {
name = button_name ,
type = ' sprite-button ' ,
} )
flow3.style . height = 40
flow3.style . width = width
-- flow3.style.padding = -4
return flow3
end
2022-03-13 03:44:32 +02:00
2022-02-24 21:39:03 +02:00
function Public . flow_add_floating_button ( flow1 , button_name )
local flow2 , flow3
2022-03-19 23:20:55 +02:00
2022-02-24 21:39:03 +02:00
flow2 = flow1.add ( {
2022-02-27 01:33:19 +02:00
name = button_name .. ' _flow_1 ' ,
2022-02-24 21:39:03 +02:00
type = ' flow ' ,
direction = ' vertical ' ,
} )
flow2.style . height = 40
-- flow2.style.left_padding = 4
-- flow2.style.top_padding = 0
-- flow2.style.right_margin = -2
flow2.style . natural_width = 40
flow3 = flow2.add ( {
name = button_name ,
type = ' button ' ,
} )
flow3.style = ' dark_rounded_button '
-- flow3.style.minimal_width = 60
-- flow3.style.natural_width = 60
flow3.style . minimal_height = 40
flow3.style . maximal_height = 40
flow3.style . left_padding = 10
flow3.style . right_padding = 4
flow3.style . top_padding = 3
-- flow3.style.padding = -4
flow3.style . natural_width = 40
flow3.style . horizontally_stretchable = true
2022-02-27 01:33:19 +02:00
flow3 = flow2.add ( {
name = button_name .. ' _flow_2 ' ,
type = ' flow ' ,
} )
flow3.style . natural_width = 20
flow3.style . top_margin = - 37
flow3.style . left_margin = 10
flow3.style . right_margin = 9
flow3.ignored_by_interaction = true
2022-02-24 21:39:03 +02:00
return flow3
end
2021-10-13 10:21:53 +02:00
function Public . flow_add_shop_item ( flow , name )
2022-03-19 23:20:55 +02:00
local flow2 , flow3
2021-10-13 10:21:53 +02:00
2022-03-07 20:41:42 +02:00
local shop_data_1 = Shop.Captains . main_shop_data_1
local shop_data_2 = Shop.Captains . main_shop_data_2
2021-10-13 10:21:53 +02:00
local trade_data = shop_data_1 [ name ] or shop_data_2 [ name ]
if not trade_data then return end
2022-03-19 23:20:55 +02:00
2021-10-13 10:21:53 +02:00
flow2 = flow.add ( {
name = name ,
type = ' flow ' ,
direction = ' horizontal ' ,
} )
flow2.style . top_margin = 3
flow2.style . horizontal_align = ' center '
flow2.style . vertical_align = ' center '
flow2.tooltip = trade_data.tooltip
2022-03-19 23:20:55 +02:00
2021-10-13 10:21:53 +02:00
for k , v in pairs ( trade_data.what_you_get_sprite_buttons ) do
flow3 = flow2.add ( {
type = ' sprite-button ' ,
name = k ,
sprite = k ,
enabled = false ,
} )
flow3.style . minimal_height = 40
flow3.style . maximal_height = 40
if v == false then
flow3.number = nil
else
flow3.number = v
end
flow3.tooltip = trade_data.tooltip
end
flow3 = flow2.add ( {
type = ' label ' ,
name = ' for ' ,
caption = ' for '
} )
flow3.style . font = ' default-large '
flow3.style . font_color = Public.default_font_color
flow3.tooltip = trade_data.tooltip
2022-03-19 23:20:55 +02:00
for k , _ in pairs ( trade_data.base_cost ) do
2021-10-13 10:21:53 +02:00
flow3 = flow2.add ( {
name = ' cost_ ' .. k ,
type = ' sprite-button ' ,
enabled = false ,
} )
flow3.style . minimal_height = 40
flow3.style . maximal_height = 40
flow3.tooltip = trade_data.tooltip
2022-02-24 21:39:03 +02:00
if k == ' fuel ' then
flow3.sprite = ' item/coal '
elseif k == ' coins ' then
flow3.sprite = ' item/coin '
2021-10-13 10:21:53 +02:00
elseif k == ' iron_plates ' then
flow3.sprite = ' item/iron-plate '
elseif k == ' copper_plates ' then
flow3.sprite = ' item/copper-plate '
end
end
2022-03-19 23:20:55 +02:00
2021-10-13 10:21:53 +02:00
flow3 = flow2.add ( {
name = ' spacing ' ,
type = ' flow ' ,
direction = ' horizontal ' ,
} )
flow3.style . horizontally_stretchable = true
flow3 = flow2.add ( {
type = ' sprite-button ' ,
name = ' buy_button ' ,
caption = ' Buy '
} )
flow3.style . font = ' default-large '
flow3.style . font_color = Public.default_font_color
flow3.style . height = 32
flow3.style . width = 50
flow3.style . padding = 0
flow3.style . margin = 0
return flow2
end
function Public . flow_add_section ( flow , name , caption )
local flow2 , flow3
flow2 = flow.add ( {
name = name ,
type = ' flow ' ,
direction = ' vertical ' ,
} )
flow2.style . bottom_margin = 5
flow3 = flow2.add ( {
type = ' label ' ,
name = ' header ' ,
caption = caption
} )
flow3.style . font = ' heading-2 '
flow3.style . font_color = Public.section_header_font_color
flow3.style . maximal_width = 300
-- flow3.style.maximal_width = 220
-- flow3.style.single_line = false
flow3 = flow2.add ( {
name = ' body ' ,
type = ' flow ' ,
direction = ' vertical ' ,
} )
flow3.style . left_margin = 5
return flow3
end
function Public . flow_add_subpanel ( flow , name )
local flow2
flow2 = flow.add ( {
name = name ,
type = ' frame ' ,
direction = ' vertical ' ,
} )
flow2.style = ' subpanel_frame '
flow2.style . natural_width = 100
flow2.style . top_padding = - 2
flow2.style . top_margin = - 8
return flow2
end
function Public . flow_add_close_button ( flow , close_button_name )
local flow2 , flow3 , flow4
flow2 = flow.add ( {
name = ' close_button_flow ' ,
type = ' flow ' ,
direction = ' vertical ' ,
} )
flow2.style . top_margin = - 3
flow2.style . bottom_margin = - 3
flow3 = flow2.add { type = " flow " , name = ' hflow ' , direction = " horizontal " }
flow3.style . vertical_align = ' center '
flow4 = flow3.add { type = " flow " , name = ' spacing ' , direction = " horizontal " }
flow4.style . horizontally_stretchable = true
flow4 = flow3.add ( {
type = ' button ' ,
name = close_button_name ,
caption = ' Close ' ,
} )
flow4.style = ' back_button '
flow4.style . minimal_width = 90
flow4.style . font = ' default-bold '
flow4.style . height = 28
flow4.style . horizontal_align = ' center '
return flow3
end
2022-03-19 23:20:55 +02:00
function Public . crew_overall_state_bools ( player_index )
2021-10-13 10:21:53 +02:00
local global_memory = Memory.get_global_memory ( )
local memory = Memory.get_crew_memory ( )
--*** PLAYER STATUS ***--
2022-03-19 23:20:55 +02:00
2021-10-13 10:21:53 +02:00
local ret = {
adventuring = false ,
spectating = false ,
endorsing = false ,
proposing = false ,
sloops_full = false ,
needs_more_capacity = false ,
2022-03-11 00:11:51 +02:00
crew_count_capped = false ,
2021-10-13 10:21:53 +02:00
needs_more_endorsers = false ,
leaving = false ,
2022-03-11 00:11:51 +02:00
proposal_can_launch = false ,
2021-10-13 10:21:53 +02:00
}
if memory.crewstatus == Crew.enum . ADVENTURING then
for _ , playerindex in pairs ( memory.crewplayerindices ) do
if player_index == playerindex then ret.adventuring = true end
end
for _ , playerindex in pairs ( memory.spectatorplayerindices ) do
if player_index == playerindex then ret.spectating = true end
end
end
if memory.crewstatus == nil then
for _ , crewid in pairs ( global_memory.crew_active_ids ) do
if global_memory.crew_memories [ crewid ] . crewstatus == Crew.enum . LEAVING_INITIAL_DOCK then
for _ , endorser_index in pairs ( global_memory.crew_memories [ crewid ] . original_proposal.endorserindices ) do
if endorser_index == player_index then ret.leaving = true end
end
end
end
for _ , proposal in pairs ( global_memory.crewproposals ) do
if # proposal.endorserindices > 0 and proposal.endorserindices [ 1 ] == player_index then
ret.proposing = true
if # global_memory.crew_active_ids >= 3 then
ret.sloops_full = true
2022-03-11 00:11:51 +02:00
elseif # global_memory.crew_active_ids >= global_memory.active_crews_cap then
ret.crew_count_capped = true
elseif global_memory.active_crews_cap > 1 and # global_memory.crew_active_ids == ( global_memory.active_crews_cap - 1 ) and not ( ( global_memory.crew_memories [ 1 ] and global_memory.crew_memories [ 1 ] . capacity >= Common.minimum_run_capacity_to_enforce_space_for ) or ( global_memory.crew_memories [ 2 ] and global_memory.crew_memories [ 2 ] . capacity >= Common.minimum_run_capacity_to_enforce_space_for ) or ( global_memory.crew_memories [ 3 ] and global_memory.crew_memories [ 3 ] . capacity >= Common.minimum_run_capacity_to_enforce_space_for ) ) and not ( CoreData.capacity_options [ proposal.capacity_option ] . value >= Common.minimum_run_capacity_to_enforce_space_for ) then
ret.needs_more_capacity = true
elseif proposal.endorserindices and # global_memory.crew_active_ids > 0 and # proposal.endorserindices < Math.min ( 4 , Math.ceil ( ( # game.connected_players or 0 ) / 5 ) ) then
ret.needs_more_endorsers = true
end
if ( not ( ret.sloops_full or ret.needs_more_capacity or ret.needs_more_endorsers or ret.crew_count_capped ) ) then
ret.proposal_can_launch = true
2021-10-13 10:21:53 +02:00
end
end
for _ , i in pairs ( proposal.endorserindices ) do
if player_index == i then ret.endorsing = true end
end
end
end
return ret
end
2022-03-19 23:20:55 +02:00
function Public . player_and_crew_state_bools ( player )
local memory = Memory.get_crew_memory ( )
-- if memory.player_and_crew_state_bools_memoized and memory.player_and_crew_state_bools_memoized.tick > game.tick - 30 then -- auto-memoize and only update every half-second
-- return memory.player_and_crew_state_bools_memoized.ret
-- else
local destination = Common.current_destination ( )
local dynamic_data = destination.dynamic_data --assumes this always exists
local in_crowsnest_bool , in_hold_bool , in_cabin_bool , onmap_bool , eta_bool , approaching_bool , retreating_bool , atsea_sailing_bool , landed_bool , quest_bool , silo_bool , charged_bool , launched_bool , captain_bool , atsea_loading_bool , character_on_deck_bool , on_deck_standing_near_loco_bool , on_deck_standing_near_cabin_bool , on_deck_standing_near_crowsnest_bool , cost_bool , cost_includes_rocket_launch_bool , approaching_dock_bool , leaving_dock_bool , leave_anytime_bool
captain_bool = Common.is_captain ( player )
in_crowsnest_bool = string.sub ( player.surface . name , 9 , 17 ) == ' Crowsnest '
in_hold_bool = string.sub ( player.surface . name , 9 , 12 ) == ' Hold '
in_cabin_bool = string.sub ( player.surface . name , 9 , 13 ) == ' Cabin '
onmap_bool = destination.surface_name and ( player.surface . name == destination.surface_name or (
memory.boat and memory.boat . surface_name == destination.surface_name and ( in_crowsnest_bool or in_hold_bool or in_cabin_bool )
) )
if destination then
eta_bool = dynamic_data.time_remaining and dynamic_data.time_remaining > 0 and onmap_bool
approaching_bool = memory.boat and memory.boat . state == Boats.enum_state . APPROACHING and onmap_bool
retreating_bool = memory.boat and memory.boat . state == Boats.enum_state . RETREATING and onmap_bool
-- approaching_bool = memory.boat and memory.boat.state == Boats.enum_state.APPROACHING
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
charged_bool = dynamic_data.silocharged
2022-04-30 00:48:34 +02:00
silo_bool = dynamic_data.rocketsilos and onmap_bool and ( ( dynamic_data.rocketsilos [ 1 ] and dynamic_data.rocketsilos [ 1 ] . valid ) or charged_bool )
2022-03-19 23:20:55 +02:00
launched_bool = dynamic_data.rocketlaunched
cost_bool = destination.static_params . base_cost_to_undock and ( not atsea_sailing_bool ) and ( not retreating_bool )
cost_includes_rocket_launch_bool = cost_bool and destination.static_params . base_cost_to_undock [ ' launch_rocket ' ]
leave_anytime_bool = ( landed_bool and not ( eta_bool or cost_bool ) )
end
if memory.boat then
atsea_loading_bool = memory.boat . state == Boats.enum_state . ATSEA_LOADING_MAP and memory.loadingticks
character_on_deck_bool = player.character and player.character . position and player.surface . name and player.surface . name == memory.boat . surface_name
if character_on_deck_bool then
local BoatData = Boats.get_scope ( memory.boat ) . Data
2022-05-14 00:35:12 +02:00
on_deck_standing_near_loco_bool = Math.distance ( player.character . position , Math.vector_sum ( memory.boat . position , BoatData.loco_pos ) ) < 2.5
2022-03-19 23:20:55 +02:00
2022-05-14 00:35:12 +02:00
on_deck_standing_near_cabin_bool = Math.distance ( player.character . position , Math.vector_sum ( memory.boat . position , BoatData.cabin_car ) ) < 2.0
2022-03-19 23:20:55 +02:00
2022-05-14 00:35:12 +02:00
on_deck_standing_near_crowsnest_bool = Math.distance ( player.character . position , Math.vector_sum ( memory.boat . position , BoatData.crowsnest_center ) ) < 2.5
2022-03-19 23:20:55 +02:00
end
approaching_dock_bool = destination.type == Surfaces.enum . DOCK and memory.boat . state == Boats.enum_state . APPROACHING
leaving_dock_bool = destination.type == Surfaces.enum . DOCK and memory.boat . state == Boats.enum_state . LEAVING_DOCK
end
local ret = {
in_crowsnest_bool = in_crowsnest_bool ,
in_hold_bool = in_hold_bool ,
in_cabin_bool = in_cabin_bool ,
-- onmap_bool = onmap_bool,
eta_bool = eta_bool ,
approaching_bool = approaching_bool ,
retreating_bool = retreating_bool ,
atsea_sailing_bool = atsea_sailing_bool ,
-- landed_bool = landed_bool,
quest_bool = quest_bool ,
silo_bool = silo_bool ,
charged_bool = charged_bool ,
launched_bool = launched_bool ,
captain_bool = captain_bool ,
atsea_loading_bool = atsea_loading_bool ,
-- character_on_deck_bool = character_on_deck_bool,
on_deck_standing_near_loco_bool = on_deck_standing_near_loco_bool ,
on_deck_standing_near_cabin_bool = on_deck_standing_near_cabin_bool ,
on_deck_standing_near_crowsnest_bool = on_deck_standing_near_crowsnest_bool ,
cost_bool = cost_bool ,
cost_includes_rocket_launch_bool = cost_includes_rocket_launch_bool ,
approaching_dock_bool = approaching_dock_bool ,
leaving_dock_bool = leaving_dock_bool ,
leave_anytime_bool = leave_anytime_bool
}
-- memory.player_and_crew_state_bools_memoized = {ret = ret, tick = game.tick}
return ret
-- end
end
2021-10-13 10:21:53 +02:00
function Public . update_listbox ( listbox , table )
-- pass a table of strings of the form {'locale', unique_id, ...}
-- remove any that shouldn't be there
local marked_for_removal = { }
for index , item in pairs ( listbox.items ) do
local exists = false
for _ , i in pairs ( table ) do
if tostring ( i [ 2 ] ) == item [ 2 ] then
exists = true
end
end
if exists == false then
marked_for_removal [ # marked_for_removal + 1 ] = index
end
end
for i = # marked_for_removal , 1 , - 1 do
listbox.remove_item ( marked_for_removal [ i ] )
end
local indexalreadyat
for _ , i in pairs ( table ) do
local contained = false
for index , item in pairs ( listbox.items ) do
if tostring ( i [ 2 ] ) == item [ 2 ] then
contained = true
indexalreadyat = index
end
end
if contained then
listbox.set_item ( indexalreadyat , i )
else
listbox.add_item ( i )
end
end
end
return Public