1
0
mirror of https://github.com/ComfyFactory/ComfyFactorio.git synced 2025-03-29 21:47:08 +02:00
2024-10-29 14:11:14 +00:00

448 lines
14 KiB
Lua

---@diagnostic disable: inject-field
-- This file is part of thesixthroc's Pirate Ship softmod, licensed under GPLv3 and stored at https://github.com/ComfyFactory/ComfyFactorio and https://github.com/danielmartin0/ComfyFactorio-Pirates.
local Memory = require('maps.pirates.memory')
local Common = require('maps.pirates.common')
-- local CoreData = require 'maps.pirates.coredata'
-- local Utils = require 'maps.pirates.utils_local'
local Math = require('maps.pirates.math')
local _inspect = require('utils.inspect').inspect
local Crew = require('maps.pirates.crew')
-- local Progression = require 'maps.pirates.progression'
-- local Structures = require 'maps.pirates.structures.structures'
-- local Shop = require 'maps.pirates.shop.shop'
local Boats = require('maps.pirates.structures.boats.boats')
local Surfaces = require('maps.pirates.surfaces.surfaces')
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 = { 246, 230, 255 }
Public.sufficient_font_color = { 66, 220, 124 }
Public.insufficient_font_color = { 1, 0.62, 0.19 }
Public.achieved_font_color = { 227, 250, 192 }
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 }
Public.default_window_positions = {
minimap = { x = 10, y = 76 },
color = { x = 160, y = 76 },
info = { x = 160, y = 108 },
runs = { x = 234, y = 76 },
crew = { x = 364, y = 76 },
classes = { x = 442, y = 76 },
progress = { x = 520, y = 76 },
treasure = { x = 676, y = 76 },
}
function Public.new_window(player, name)
local global_memory = Memory.get_global_memory()
local gui_memory = global_memory.player_gui_memories[player.index]
local flow
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
flow.style = 'map_details_frame'
flow.style.minimal_width = 210
flow.style.natural_width = 210
flow.style.maximal_width = 420
flow.style.minimal_height = 80
flow.style.natural_height = 80
flow.style.maximal_height = 760
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
flow2 = flow1.add({
name = button_name .. '_frame',
type = 'frame',
})
flow2.style.height = 40
flow2.style.margin = 0
flow2.style.left_padding = -4
flow2.style.top_padding = -4
flow2.style.right_margin = -2
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
function Public.flow_add_floating_button(flow1, button_name)
local flow2, flow3
flow2 = flow1.add({
name = button_name .. '_flow_1',
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
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
return flow3
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.single_line = false
flow3 = flow2.add({
name = 'body',
type = 'flow',
direction = 'vertical',
})
flow3.style.left_margin = 5
flow3.style.right_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 = 'tabbed_pane_frame'
flow2.style.natural_width = 100
flow2.style.top_padding = -2
flow2.style.top_margin = -2
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',
})
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 = { 'pirates.gui_close_button' },
})
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
function Public.crew_overall_state_bools(player_index)
local global_memory = Memory.get_global_memory()
local memory = Memory.get_crew_memory()
--*** PLAYER STATUS ***--
local ret = {
adventuring = false,
created_crew = false,
proposing = false,
sloops_full = false,
crew_count_capped = false,
leaving = false,
proposal_can_launch = false,
}
if memory.crewstatus == Crew.enum.ADVENTURING then
for _, playerindex in pairs(memory.crewplayerindices) do
if player_index == playerindex then
ret.adventuring = 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
if global_memory.crew_memories[crewid].original_proposal.created_by_player == player_index then
ret.leaving = true
end
end
end
for _, proposal in pairs(global_memory.crewproposals) do
if proposal.created_by_player == player_index then
ret.proposing = true
if #global_memory.crew_active_ids >= Common.starting_ships_count then
ret.sloops_full = true
elseif #global_memory.crew_active_ids >= global_memory.active_crews_cap_in_memory then
ret.crew_count_capped = true
end
if not (ret.sloops_full or ret.crew_count_capped) then
ret.proposal_can_launch = true
end
end
if player_index == proposal.created_by_player then
ret.created_crew = true
end
end
end
return ret
end
function Public.player_and_crew_state_bools(player)
local memory = Memory.get_crew_memory()
local boat = memory.boat
-- 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, atsea_waiting_bool, atsea_victorious_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 = Common.validate_player_and_character(player)
and string.sub(player.character.surface.name, 9, 17) == 'Crowsnest'
in_hold_bool = Common.validate_player_and_character(player)
and string.sub(player.character.surface.name, 9, 12) == 'Hold'
in_cabin_bool = Common.validate_player_and_character(player)
and string.sub(player.character.surface.name, 9, 13) == 'Cabin'
onmap_bool = destination.surface_name
and (
Common.validate_player_and_character(player)
and player.character.surface.name == destination.surface_name
or (
boat
and 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 = boat and boat.state == Boats.enum_state.APPROACHING and onmap_bool
retreating_bool = boat and boat.state == Boats.enum_state.RETREATING and onmap_bool
-- approaching_bool = boat and boat.state == Boats.enum_state.APPROACHING
atsea_sailing_bool = boat and boat.state == Boats.enum_state.ATSEA_SAILING
atsea_waiting_bool = boat and boat.state == Boats.enum_state.ATSEA_WAITING_TO_SAIL
atsea_victorious_bool = boat and boat.state == Boats.enum_state.ATSEA_VICTORIOUS
landed_bool = boat and boat.state == Boats.enum_state.LANDED
quest_bool = (dynamic_data.quest_type ~= nil) and onmap_bool
charged_bool = dynamic_data.silo_is_charged
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.rocket_launched
cost_bool = destination.static_params.base_cost_to_undock
and not atsea_sailing_bool
and not atsea_waiting_bool
and not atsea_victorious_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 boat then
atsea_loading_bool = boat.state == Boats.enum_state.ATSEA_LOADING_MAP and memory.loading_ticks
character_on_deck_bool = Common.validate_player_and_character(player)
and player.character
and player.character.position
and player.character.surface.name
and player.character.surface.name == boat.surface_name
if character_on_deck_bool then
local BoatData = Boats.get_scope(boat).Data
on_deck_standing_near_loco_bool = Math.distance(
player.character.position,
Math.vector_sum(boat.position, BoatData.loco_pos)
) < 2.5
on_deck_standing_near_cabin_bool = Math.distance(
player.character.position,
Math.vector_sum(boat.position, BoatData.cabin_car)
) < 2.0
on_deck_standing_near_crowsnest_bool = Math.distance(
player.character.position,
Math.vector_sum(boat.position, BoatData.crowsnest_center)
) < 2.5
end
approaching_dock_bool = destination.type == Surfaces.enum.DOCK and boat.state == Boats.enum_state.APPROACHING
leaving_dock_bool = destination.type == Surfaces.enum.DOCK and 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,
atsea_waiting_bool = atsea_waiting_bool,
atsea_victorious_bool = atsea_victorious_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
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