1
0
mirror of https://github.com/ComfyFactory/ComfyFactorio.git synced 2024-12-26 22:56:43 +02:00

New class GUI window

Changes:
- Fixed crash that could happen if player clicked on crew window button with middle mouse button while in lobby
- Removed "Pro..." text from Progress window button
- Moved class related info from crew window to new class window
- Added scroll pane for crew window
This commit is contained in:
Piratux 2022-07-07 23:01:45 +03:00
parent 5e2200f897
commit f826660619
17 changed files with 600 additions and 315 deletions

View File

@ -279,12 +279,12 @@ class_purchase=__1__ bought the class __2__. ([font=scenario-message-dialog]__3_
class_upgrade=__1__ upgraded their class from __2__ to __3__ ([font=scenario-message-dialog]__4__[/font]).
class_take_spare=__1__ took the spare class __2__. ([font=scenario-message-dialog]__3__[/font])
class_give_spare=A spare __1__ class with given to __2__. ([font=scenario-message-dialog]__3__[/font])
class_give_up=__1__ gave up __2__.
class_becomes_spare=A __1__ class is now spare.
class_give_up_error_no_class=Class error: You don't have any class to give up.
class_revoke=__1__ revoked __2__ from __3__.
# class_take_spare=__1__ took the spare class __2__. ([font=scenario-message-dialog]__3__[/font])
# class_give_spare=A spare __1__ class with given to __2__. ([font=scenario-message-dialog]__3__[/font])
# class_give_up=__1__ gave up __2__.
# class_becomes_spare=A __1__ class is now spare.
# class_give_up_error_no_class=Class error: You don't have any class to give up.
# class_revoke=__1__ revoked __2__ from __3__.
class_purchase_error_prerequisite_class=Class purchase error: You need to be a __1__ to buy this.
roles_confirm_captain=__1__ accepted the role of captain.
@ -310,8 +310,8 @@ roles_notify_looking_for_captain=Looking for a suitable captain...
warn_nearly_afk_captain=Note: If you go idle as captain for too long, the role passes to another crewmember.
error_class_assign_redundant=Class error: You're already a __1__.
error_class_assign_unavailable_class=Class error: No spare class of that type is available.
# error_class_assign_redundant=Class error: You're already a __1__.
# error_class_assign_unavailable_class=Class error: No spare class of that type is available.
@ -405,17 +405,17 @@ gui_crew_window_buttons_join_crew=Join Crew
gui_crew_window_buttons_join_spectators=Spectate
gui_crew_window_buttons_join_spectators_tooltip=You won't be able to rejoin the crew for a short while after you do this.
gui_crew_window_crewmembers=Crew Members
gui_crew_window_crewmembers_give_up_class=Give Up Class
gui_crew_window_crewmembers_give_up_class_tooltip=Give Up Class
# gui_crew_window_crewmembers_give_up_class=Give Up Class
# gui_crew_window_crewmembers_give_up_class_tooltip=Give Up Class
gui_crew_window_crewmembers_resign_as_officer=Resign as Officer
gui_crew_window_crewmembers_resign_as_officer_tooltip=Give up the officer role.
gui_crew_window_spectators=Spectators
gui_crew_window_vote_for_difficulty=Vote for Difficulty
gui_crew_window_spare_classes=Spare Classes
gui_crew_window_assign_class_button=Give class: __1__
gui_crew_window_assign_class_button_tooltip=Give the selected player the class __1__.\n\n Class description: __2__
gui_crew_window_selfassign_class_button=Take class: __1__
gui_crew_window_selfassign_class_button_tooltip=Give yourself the spare class __1__.\n\n Class description: __2__
# gui_crew_window_spare_classes=Spare Classes
# gui_crew_window_assign_class_button=Give class: __1__
# gui_crew_window_assign_class_button_tooltip=Give the selected player the class __1__.\n\n Class description: __2__
# gui_crew_window_selfassign_class_button=Take class: __1__
# gui_crew_window_selfassign_class_button_tooltip=Give yourself the spare class __1__.\n\n Class description: __2__
gui_crew_window_captains_actions=Captain's Actions
gui_crew_window_captains_actions_disband_crew=Disband Crew
gui_crew_window_captains_actions_disband_crew_tooltip=End the run. You will be prompted again after clicking.
@ -431,8 +431,8 @@ gui_crew_window_captains_actions_make_officer=Make Officer
gui_crew_window_captains_actions_make_officer_tooltip=Make this player an Officer. (or use /officer {player})
gui_crew_window_captains_actions_unmake_officer=Unmake Officer
gui_crew_window_captains_actions_unmake_officer_tooltip=Remove this player as an Officer. (or use /officer {player})
gui_crew_window_captains_actions_revoke_class=Revoke Class
gui_crew_window_captains_actions_revoke_class_tooltip=Put this player's class back in the Spare Classes pool.
# gui_crew_window_captains_actions_revoke_class=Revoke Class
# gui_crew_window_captains_actions_revoke_class_tooltip=Put this player's class back in the Spare Classes pool.
gui_crew_window_captains_actions_summon_crew=Summon Crew to Ship
gui_crew_window_captains_actions_summon_crew_tooltip=Teleport crewmembers to the ship.
gui_crew_window_captains_actions_tax=Tax Crew
@ -443,6 +443,16 @@ gui_crew_window_crew_age=Age: __1__
gui_crew_window_crew_capacity_and_difficulty=__1__, Capacity __2__.
gui_crew_window_crew_count=Crew Members (__1__)
gui_classes=Classes
gui_classes_available_classes=Available classes
gui_classes_taken_by=Taken by
gui_classes_actions=Actions
gui_classes_take=Take
gui_classes_drop=Drop
gui_classes_take_enabled_tooltip=Equip the class to receive bonuses!
gui_classes_take_disabled_tooltip=This class is currently in use by someone
gui_classes_drop_tooltip=Unequip the class to allow someone else to take it
gui_evo_tooltip_1=Local Biter Evolution: __1__
gui_evo_tooltip_2=Leagues: __1__
gui_evo_tooltip_3=Kraken: __1__
@ -534,8 +544,13 @@ gui_questframe_nodamage=Island Quest: No Damage\n\nLaunch a rocket without the s
gui_crew_tooltip_1=Your Crew\n\nPerform crew actions, such as selecting a class if any are available.
gui_crew_tooltip_2=Your Crew\n\nYou're a free agent, so there's nothing to do here.
gui_classes_tooltip_1=Class panel\n\nShows list of unlocked classes and let's you take them.\nClasses will start to appear in the list as you unlock them.
gui_classes_tooltip_2=Class panel\n\nYou're a free agent, so there's nothing to do here.
gui_progress_tooltip=Progress: __1__ leagues.\n\nTravel __2__ leagues to win the game.
gui_close_button=Close
cmd_notify_set_max_crews=The maximum number of concurrent crews has been set to __1__.
cmd_error_not_admin=[ERROR] Only admins are allowed to run this command!

View File

@ -216,7 +216,14 @@ local function damage_to_artillery(event)
if not event.cause.name then return end
if (event.cause.name == 'small-biter') or (event.cause.name == 'small-spitter') or (event.cause.name == 'medium-biter') or (event.cause.name == 'medium-spitter') or (event.cause.name == 'big-biter') or (event.cause.name == 'big-spitter') or (event.cause.name == 'behemoth-biter') or (event.cause.name == 'behemoth-spitter') then
if (event.cause.name == 'small-biter')
or (event.cause.name == 'small-spitter')
or (event.cause.name == 'medium-biter')
or (event.cause.name == 'medium-spitter')
or (event.cause.name == 'big-biter')
or (event.cause.name == 'big-spitter')
or (event.cause.name == 'behemoth-biter')
or (event.cause.name == 'behemoth-spitter') then
if event.cause.force.name ~= memory.enemy_force_name then return end
-- play alert sound for all crew members
@ -1064,7 +1071,7 @@ local function event_on_entity_died(event)
local crew_id = Common.get_id_from_force_name(entity.force.name)
Memory.set_working_id(crew_id)
local memory = Memory.get_crew_memory()
if memory.id == 0 then return end
if not Common.is_id_valid(memory.id) then return end
base_kill_rewards(event)
@ -1228,9 +1235,9 @@ local function event_on_player_joined_game(event)
end
local crew_to_put_back_in = nil
for _, mem in pairs(global_memory.crew_memories) do
if mem.id and mem.crewstatus and mem.crewstatus == Crew.enum.ADVENTURING and mem.temporarily_logged_off_characters[player.index] then
crew_to_put_back_in = mem.id
for _, memory in pairs(global_memory.crew_memories) do
if Common.is_id_valid(memory.id) and memory.crewstatus and memory.crewstatus == Crew.enum.ADVENTURING and memory.temporarily_logged_off_characters[player.index] then
crew_to_put_back_in = memory.id
break
end
end
@ -1267,9 +1274,17 @@ local function event_on_player_joined_game(event)
-- Auto-join the oldest crew:
local ages = {}
for _, mem in pairs(global_memory.crew_memories) do
if mem.id and mem.crewstatus and mem.crewstatus == Crew.enum.ADVENTURING and mem.capacity and mem.crewplayerindices and #mem.crewplayerindices < mem.capacity and (not (mem.tempbanned_from_joining_data and mem.tempbanned_from_joining_data[player.index] and game.tick < mem.tempbanned_from_joining_data[player.index] + Common.ban_from_rejoining_crew_ticks)) then
ages[#ages+1] = {id = mem.id, age = mem.age, large = (mem.capacity >= Common.minimum_run_capacity_to_enforce_space_for)}
for _, memory in pairs(global_memory.crew_memories) do
if Common.is_id_valid(memory.id)
and memory.crewstatus
and memory.crewstatus == Crew.enum.ADVENTURING
and memory.capacity
and memory.crewplayerindices
and #memory.crewplayerindices < memory.capacity
and (not (memory.tempbanned_from_joining_data
and memory.tempbanned_from_joining_data[player.index]
and game.tick < memory.tempbanned_from_joining_data[player.index] + Common.ban_from_rejoining_crew_ticks)) then
ages[#ages+1] = {id = memory.id, age = memory.age, large = (memory.capacity >= Common.minimum_run_capacity_to_enforce_space_for)}
end
end
table.sort(
@ -1570,14 +1585,38 @@ function Public.event_on_chunk_generated(event)
if (p.x >= -width/2 and p.y >=-height/2 and p.x <= width/2 and p.y <= height/2) then
terrain_fn{p = Utils.psum{p, {1, terraingen_coordinates_offset}}, true_p = p, true_left_top = chunk_left_top, left_top = Utils.psum{chunk_left_top, {1, terraingen_coordinates_offset}}, noise_generator = noise_generator, static_params = static_params, tiles = tiles, entities = entities, decoratives = decoratives, specials = specials, seed = seed, other_map_generation_data = other_map_generation_data, iconized_generation = false}
terrain_fn{
p = Utils.psum{p, {1, terraingen_coordinates_offset}},
true_p = p,
true_left_top = chunk_left_top,
left_top = Utils.psum{chunk_left_top, {1, terraingen_coordinates_offset}},
noise_generator = noise_generator,
static_params = static_params,
tiles = tiles,
entities = entities,
decoratives = decoratives,
specials = specials,
seed = seed,
other_map_generation_data = other_map_generation_data,
iconized_generation = false
}
else
tiles[#tiles + 1] = {name = 'out-of-map', position = Utils.psum{p, {1, terraingen_coordinates_offset}}}
end
end
end
chunk_structures_fn{true_left_top = chunk_left_top, left_top = Utils.psum{chunk_left_top, {1, terraingen_coordinates_offset}}, noise_generator = noise_generator, static_params = static_params, specials = specials, entities = entities, seed = seed, other_map_generation_data = other_map_generation_data, biter_base_density_scale = Balance.biter_base_density_scale()}
chunk_structures_fn{
true_left_top = chunk_left_top,
left_top = Utils.psum{chunk_left_top, {1, terraingen_coordinates_offset}},
noise_generator = noise_generator,
static_params = static_params,
specials = specials,
entities = entities,
seed = seed,
other_map_generation_data = other_map_generation_data,
biter_base_density_scale = Balance.biter_base_density_scale()
}
local tiles_corrected = {}
for i = 1, #tiles do
@ -1810,7 +1849,7 @@ local remove_boost_movement_speed_on_respawn =
Memory.set_working_id(crew_id)
local memory = Memory.get_crew_memory()
if not (memory.id and memory.id > 0) then return end --check if crew disbanded
if not Common.is_id_valid(memory.id) then return end --check if crew disbanded
if memory.game_lost then return end
memory.speed_boost_characters[player.index] = nil
@ -1830,7 +1869,7 @@ local boost_movement_speed_on_respawn =
Memory.set_working_id(crew_id)
local memory = Memory.get_crew_memory()
if not (memory.id and memory.id > 0) then return end --check if crew disbanded
if not Common.is_id_valid(memory.id) then return end --check if crew disbanded
if memory.game_lost then return end
memory.speed_boost_characters[player.index] = true

View File

@ -1443,7 +1443,7 @@ end
function Public.update_alert_sound_frequency_tracker()
local memory = Memory.get_crew_memory()
if memory.seconds_until_alert_sound_can_be_played_again > 0 then
if memory.seconds_until_alert_sound_can_be_played_again and memory.seconds_until_alert_sound_can_be_played_again > 0 then
memory.seconds_until_alert_sound_can_be_played_again = memory.seconds_until_alert_sound_can_be_played_again - 1
memory.seconds_until_alert_sound_can_be_played_again = Math.max(0, memory.seconds_until_alert_sound_can_be_played_again)
end

View File

@ -156,6 +156,9 @@ commands.add_command(
function(cmd)
cmd_set_memory(cmd)
local memory = Memory.get_crew_memory()
if not Common.is_id_valid(memory.id) then return end
--local param = tostring(cmd.parameter)
if check_admin(cmd) then
--local player = game.players[cmd.player_index]
@ -173,6 +176,9 @@ commands.add_command(
function(cmd)
cmd_set_memory(cmd)
local memory = Memory.get_crew_memory()
if not Common.is_id_valid(memory.id) then return end
local param = tostring(cmd.parameter)
if check_admin(cmd) then
local player = game.players[cmd.player_index]
@ -190,6 +196,9 @@ commands.add_command(
function(cmd)
cmd_set_memory(cmd)
local memory = Memory.get_crew_memory()
if not Common.is_id_valid(memory.id) then return end
--local param = tostring(cmd.parameter)
if check_admin(cmd) then
Crew.summon_crew()
@ -201,6 +210,10 @@ commands.add_command(
{'pirates.cmd_explain_ok'},
function(cmd)
cmd_set_memory(cmd)
local memory = Memory.get_crew_memory()
if not Common.is_id_valid(memory.id) then return end
local player = game.players[cmd.player_index]
if not Common.validate_player(player) then return end
@ -249,7 +262,7 @@ function(cmd)
if not Common.validate_player(player) then return end
if param and param ~= 'nil' then
local string = Roles.get_class_print_string(param, true)
local string = Roles.get_class_print_string(param, true, true)
if string then
Common.notify_player_expected(player, {'', {'pirates.class_definition_for'}, ' ', string})
else
@ -265,6 +278,10 @@ commands.add_command(
{'pirates.cmd_explain_take'},
function(cmd)
cmd_set_memory(cmd)
local memory = Memory.get_crew_memory()
if not Common.is_id_valid(memory.id) then return end
local param = tostring(cmd.parameter)
local player = game.players[cmd.player_index]
if not Common.validate_player(player) then return end
@ -272,7 +289,7 @@ function(cmd)
if param and param ~= 'nil' then
for _, class in pairs(Classes.enum) do
if Classes.eng_form[class]:lower() == param:lower() then
Classes.assign_class(player.index, class, true)
Classes.assign_class(player.index, class)
return true
end
end
@ -289,11 +306,15 @@ commands.add_command(
{'pirates.cmd_explain_giveup'},
function(cmd)
cmd_set_memory(cmd)
local memory = Memory.get_crew_memory()
if not Common.is_id_valid(memory.id) then return end
--local param = tostring(cmd.parameter)
local player = game.players[cmd.player_index]
if not Common.validate_player(player) then return end
Classes.try_renounce_class(player, true)
Classes.assign_class(player.index, nil)
end)
commands.add_command(
@ -371,6 +392,9 @@ commands.add_command(
function(cmd)
cmd_set_memory(cmd)
local memory = Memory.get_crew_memory()
if not Common.is_id_valid(memory.id) then return end
local player = game.players[cmd.player_index]
local param = tostring(cmd.parameter)
if check_captain_or_admin(cmd) then
@ -387,6 +411,9 @@ commands.add_command(
{'pirates.cmd_explain_officer'},
function(cmd)
cmd_set_memory(cmd)
local memory = Memory.get_crew_memory()
if not Common.is_id_valid(memory.id) then return end
local player = game.players[cmd.player_index]
local param = tostring(cmd.parameter)
@ -409,6 +436,9 @@ commands.add_command(
{'pirates.cmd_explain_undock'},
function(cmd)
cmd_set_memory(cmd)
local memory = Memory.get_crew_memory()
if not Common.is_id_valid(memory.id) then return end
--local param = tostring(cmd.parameter)
if check_captain_or_admin(cmd) then
@ -427,6 +457,9 @@ commands.add_command(
{'pirates.cmd_explain_tax'},
function(cmd)
cmd_set_memory(cmd)
local memory = Memory.get_crew_memory()
if not Common.is_id_valid(memory.id) then return end
--local param = tostring(cmd.parameter)
if check_captain(cmd) then

View File

@ -112,7 +112,7 @@ end
function Public.activecrewcount()
local global_memory = Memory.get_global_memory()
local memory = Memory.get_crew_memory()
if memory.id == 0 then return 0 end
if not Public.is_id_valid(memory.id) then return 0 end
local count = 0
for _, id in pairs(memory.crewplayerindices) do
@ -815,7 +815,7 @@ end
function Public.crew_get_crew_members()
local memory = Memory.get_crew_memory()
if memory.id == 0 then return {} end
if not Public.is_id_valid(memory.id) then return {} end
local playerlist = {}
for _, id in pairs(memory.crewplayerindices) do
@ -828,7 +828,7 @@ end
function Public.crew_get_crew_members_and_spectators()
local memory = Memory.get_crew_memory()
if memory.id == 0 then return {} end
if not Public.is_id_valid(memory.id) then return {} end
local playerlist = {}
for _, id in pairs(memory.crewplayerindices) do
@ -848,7 +848,7 @@ end
function Public.crew_get_nonafk_crew_members()
local global_memory = Memory.get_global_memory()
local memory = Memory.get_crew_memory()
if memory.id == 0 then return {} end
if not Public.is_id_valid(memory.id) then return {} end
local playerlist = {}
for _, id in pairs(memory.crewplayerindices) do
@ -1510,4 +1510,12 @@ function Public.get_id_from_force_name(force_name)
return tonumber(string.sub(force_name, -3, -1)) or nil
end
function Public.is_id_valid(id)
if id and id ~= 0 then
return true
else
return false
end
end
return Public

View File

@ -734,6 +734,7 @@ function Public.initialise_crew(accepted_proposal)
memory.classes_table = {}
memory.officers_table = {}
memory.spare_classes = {}
memory.unlocked_classes = {}
memory.healthbars = {}
memory.overworld_krakens = {}
@ -1034,5 +1035,4 @@ function Public.reset_crew_and_enemy_force(id)
end
return Public

View File

@ -0,0 +1,251 @@
-- This file is part of thesixthroc's Pirate Ship softmod, licensed under GPLv3 and stored at https://github.com/danielmartin0/ComfyFactorio-Pirates.
local Memory = require 'maps.pirates.memory'
local Common = require 'maps.pirates.common'
local Classes = require 'maps.pirates.roles.classes'
local GuiCommon = require 'maps.pirates.gui.common'
local Public = {}
local window_name = 'classes'
local widths = {}
widths['available_classes'] = 150
widths['taken_by'] = 150
widths['action_buttons'] = 100
-- used to track whether new class entries should be added during "full_update"
local entry_count = 0
local function add_class_entry(player, class, taken_by_player_index, index)
if not player.gui.screen[window_name .. '_piratewindow'] then return end
local flow
flow = player.gui.screen[window_name .. '_piratewindow']
local class_list_panel_table = flow.scroll_pane.class_list_panel_table
-- Class label
local explanation = Classes.explanation_advanced(class, false)
local full_explanation
if Classes.class_purchase_requirement[class] then
full_explanation = {'pirates.class_explanation_upgraded_class', Classes.display_form(class), Classes.display_form(Classes.class_purchase_requirement[class]), explanation}
else
full_explanation = {'pirates.class_explanation', Classes.display_form(class), explanation}
end
local available_class_label = class_list_panel_table.add({
type = 'label',
caption = Classes.display_form(class),
tooltip = full_explanation,
})
available_class_label.style.minimal_width = widths['available_classes']
available_class_label.style.maximal_width = widths['available_classes']
-- Player label
local taken_by_player_name = taken_by_player_index and game.players[taken_by_player_index].name or ''
local taken_by_label = class_list_panel_table.add({
name = 'player_label' .. index,
type = 'label',
caption = taken_by_player_name,
})
taken_by_label.style.minimal_width = widths['taken_by']
taken_by_label.style.maximal_width = widths['taken_by']
-- Button
local button
if not taken_by_player_index then
button = class_list_panel_table.add({
name = 'button' .. index,
type = 'button',
caption = {'pirates.gui_classes_take'},
tooltip = {'pirates.gui_classes_take_enabled_tooltip'},
})
elseif taken_by_player_index == player.index then
button = class_list_panel_table.add({
name = 'button' .. index,
type = 'button',
caption = {'pirates.gui_classes_drop'},
tooltip = {'pirates.gui_classes_drop_tooltip'},
})
button.style.font_color = {r=1, g=0, b=0}
button.style.hovered_font_color = {r=1, g=0, b=0}
button.style.clicked_font_color = {r=1, g=0, b=0}
else
button = class_list_panel_table.add({
name = 'button' .. index,
type = 'button',
enabled = false, -- wanted to make "visble = false" instead, but table doesn't like that
caption = {'pirates.gui_classes_take'},
tooltip = {'pirates.gui_classes_take_disabled_tooltip'},
})
end
button.tags = {type = 'pirates_' .. window_name, index = index}
button.style.minimal_width = widths['action_buttons']
button.style.maximal_width = widths['action_buttons']
end
function Public.toggle_window(player)
local memory = Memory.get_crew_memory()
local flow, flow2, flow3, flow4
--*** OVERALL FLOW ***--
if player.gui.screen[window_name .. '_piratewindow'] then player.gui.screen[window_name .. '_piratewindow'].destroy() return end
if not Common.is_id_valid(memory.id) then return end
flow = GuiCommon.new_window(player, window_name)
flow.caption = {'pirates.gui_classes'}
flow.auto_center = true
flow.style.maximal_width = 500
flow2 = flow.add({
name = 'headers',
type = 'flow',
direction = 'horizontal',
})
flow3 = flow2.add({
name = 'available_classes',
type = 'label',
caption = {'pirates.gui_classes_available_classes'},
})
flow3.style.minimal_width = widths['available_classes']
flow3.style.maximal_width = widths['available_classes']
flow3.style.font = 'heading-2'
flow3.style.font_color = GuiCommon.section_header_font_color
flow3 = flow2.add({
name = 'taken_by',
type = 'label',
caption = {'pirates.gui_classes_taken_by'},
})
flow3.style.minimal_width = widths['taken_by']
flow3.style.maximal_width = widths['taken_by']
flow3.style.font = 'heading-2'
flow3.style.font_color = GuiCommon.section_header_font_color
flow3 = flow2.add({
name = 'action_buttons',
type = 'label',
caption = {'pirates.gui_classes_actions'},
})
flow3.style.minimal_width = widths['action_buttons']
flow3.style.maximal_width = widths['action_buttons']
flow3.style.font = 'heading-2'
flow3.style.font_color = GuiCommon.section_header_font_color
-- List management
local scroll_pane = flow.add {
type = 'scroll-pane',
name = 'scroll_pane',
direction = 'vertical',
horizontal_scroll_policy = 'never',
vertical_scroll_policy = 'auto'
}
scroll_pane.style.maximal_height = 500
scroll_pane.style.bottom_padding = 20
scroll_pane.add{
type = 'table',
name = 'class_list_panel_table',
column_count = 3
}
for i, class_entry in ipairs(memory.unlocked_classes) do
add_class_entry(player, class_entry.class, class_entry.taken_by, i)
end
entry_count = #memory.unlocked_classes
GuiCommon.flow_add_close_button(flow, window_name .. '_piratebutton')
end
function Public.full_update(player)
if not player.gui.screen[window_name .. '_piratewindow'] then return end
local flow = player.gui.screen[window_name .. '_piratewindow']
local memory = Memory.get_crew_memory()
--*** Overwrite contents ***--
local class_list_panel_table = flow.scroll_pane.class_list_panel_table
-- Currently assuming class list size never decreases
-- Update current content table
for i = 1, entry_count do
local label = class_list_panel_table['player_label' .. i]
local class_entry = memory.unlocked_classes[i]
label.caption = class_entry.taken_by and game.players[class_entry.taken_by].name or ''
local black = {r=0, g=0, b=0}
local red = {r=1, g=0, b=0}
local button = class_list_panel_table['button' .. i]
if not class_entry.taken_by then
button.caption = {'pirates.gui_classes_take'}
button.tooltip = {'pirates.gui_classes_take_enabled_tooltip'}
button.style.font_color = black
button.style.hovered_font_color = black
button.style.clicked_font_color = black
elseif class_entry.taken_by == player.index then
button.caption = {'pirates.gui_classes_drop'}
button.tooltip = {'pirates.gui_classes_drop_tooltip'}
button.style.font_color = red
button.style.hovered_font_color = red
button.style.clicked_font_color = red
else
button.caption = {'pirates.gui_classes_take'}
button.tooltip = {'pirates.gui_classes_take_disabled_tooltip'}
button.style.font_color = black
button.style.hovered_font_color = black
button.style.clicked_font_color = black
end
end
-- If new entries were added since last update, add them to GUI
if entry_count ~= #memory.unlocked_classes then
for i = entry_count + 1, #memory.unlocked_classes do
local class_entry = memory.unlocked_classes[i]
add_class_entry(player, class_entry.class, class_entry.taken_by, i)
end
entry_count = #memory.unlocked_classes
end
end
function Public.click(event)
local player = game.players[event.element.player_index]
if not player.gui.screen[window_name .. '_piratewindow'] then return end
local tags = event.element.tags
if not tags then return end
if tags.type ~= 'pirates_' .. window_name then return end
local memory = Memory.get_crew_memory()
if tags.index then
local button_is_take_class = (not memory.unlocked_classes[tags.index].taken_by) and true or false
if button_is_take_class then
local class_to_assign = memory.unlocked_classes[tags.index].class
Classes.assign_class(player.index, class_to_assign, tags.index)
return
else -- button is drop class
Classes.assign_class(player.index, nil, tags.index)
return
end
end
end
return Public

View File

@ -323,7 +323,7 @@ function Public.flow_add_close_button(flow, close_button_name)
flow4 = flow3.add({
type = 'button',
name = close_button_name,
caption = 'Close',
caption = {'pirates.gui_close_button'},
})
flow4.style = 'back_button'
flow4.style.minimal_width = 90

View File

@ -4,15 +4,8 @@
local Memory = require 'maps.pirates.memory'
local Common = require 'maps.pirates.common'
local Utils = require 'maps.pirates.utils_local'
-- local Math = require 'maps.pirates.math'
-- local Surfaces = require 'maps.pirates.surfaces.surfaces'
local Roles = require 'maps.pirates.roles.roles'
local Classes = require 'maps.pirates.roles.classes'
local Crew = require 'maps.pirates.crew'
-- local Progression = require 'maps.pirates.progression'
-- local Structures = require 'maps.pirates.structures.structures'
local _inspect = require 'utils.inspect'.inspect
-- local Boats = require 'maps.pirates.structures.boats.boats'
local GuiCommon = require 'maps.pirates.gui.common'
local CoreData = require 'maps.pirates.coredata'
local Server = require 'utils.server'
@ -25,13 +18,24 @@ local window_name = 'crew'
function Public.toggle_window(player)
local memory = Memory.get_crew_memory()
local flow, flow2, flow3, flow4
local window
--*** OVERALL FLOW ***--
if player.gui.screen[window_name .. '_piratewindow'] then player.gui.screen[window_name .. '_piratewindow'].destroy() return end
if not memory.id then return end
if not Common.is_id_valid(memory.id) then return end
flow = GuiCommon.new_window(player, window_name)
window = GuiCommon.new_window(player, window_name)
flow = window.add {
type = 'scroll-pane',
name = 'scroll_pane',
direction = 'vertical',
horizontal_scroll_policy = 'never',
vertical_scroll_policy = 'auto'
}
flow.style.maximal_height = 500
flow.style.bottom_padding = 20
--*** PARAMETERS OF RUN ***--
@ -126,16 +130,6 @@ function Public.toggle_window(player)
flow3.style.margin = 2
flow3.style.maximal_height = 350
flow3 = flow2.add({
name = 'class_renounce',
type = 'button',
caption = {'pirates.gui_crew_window_crewmembers_give_up_class'},
})
flow3.style.minimal_width = 95
flow3.style.font = 'default-bold'
flow3.style.font_color = {r=0.10, g=0.10, b=0.10}
flow3.tooltip = {'pirates.gui_crew_window_crewmembers_give_up_class_tooltip'}
flow3 = flow2.add({
name = 'officer_resign',
type = 'button',
@ -171,53 +165,6 @@ function Public.toggle_window(player)
flow3.style.font_color = {r=0.10, g=0.10, b=0.10}
end
--*** SPARE CLASSES ***--
flow2 = GuiCommon.flow_add_section(flow, 'spare_classes', {'pirates.gui_crew_window_spare_classes'})
flow3 = flow2.add({
name = 'list',
type = 'label',
})
flow3.style.left_margin = 5
flow3.style.top_margin = -3
flow3.style.bottom_margin = -3
flow3.style.single_line = false
flow3.style.maximal_width = 160
flow3.style.font = 'default-dropdown'
flow3 = flow2.add({
name = 'assign_flow',
type = 'flow',
direction = 'vertical',
})
flow3.style.top_margin = 3
for _, c in pairs(Classes.enum) do
flow4 = flow3.add({
name = 'assign_class_' .. c,
type = 'button',
caption = {'pirates.gui_crew_window_assign_class_button', Classes.display_form(c)},
})
flow4.style.minimal_width = 95
flow4.style.font = 'default-bold'
flow4.style.font_color = {r=0.10, g=0.10, b=0.10}
flow4.tooltip = {'pirates.gui_crew_window_assign_class_button_tooltip', Classes.display_form(c), Classes.explanation(c)}
-- flow4.tooltip = 'Give this class to the selected player.'
end
for _, c in pairs(Classes.enum) do
flow4 = flow3.add({
name = 'selfassign_class_' .. c,
type = 'button',
caption = {'pirates.gui_crew_window_selfassign_class_button', Classes.display_form(c)},
})
flow4.style.minimal_width = 95
flow4.style.font = 'default-bold'
flow4.style.font_color = {r=0.10, g=0.10, b=0.10}
flow4.tooltip = {'pirates.gui_crew_window_selfassign_class_button_tooltip', Classes.display_form(c), Classes.explanation(c)}
end
--*** CAPTAIN's ACTIONS ***--
flow2 = GuiCommon.flow_add_section(flow, 'captain', {'pirates.gui_crew_window_captains_actions'})
@ -310,16 +257,6 @@ function Public.toggle_window(player)
flow3.style.font_color = {r=0.10, g=0.10, b=0.10}
flow3.tooltip = {'pirates.gui_crew_window_captains_actions_unmake_officer_tooltip'}
flow3 = flow2.add({
name = 'revoke_class',
type = 'button',
caption = {'pirates.gui_crew_window_captains_actions_revoke_class'},
})
flow3.style.minimal_width = 95
flow3.style.font = 'default-bold'
flow3.style.font_color = {r=0.10, g=0.10, b=0.10}
flow3.tooltip = {'pirates.gui_crew_window_captains_actions_revoke_class_tooltip'}
flow3 = flow2.add({
name = 'capn_summon_crew',
type = 'button',
@ -353,9 +290,8 @@ function Public.toggle_window(player)
flow2.style.font = 'default'
flow2.caption = {'pirates.gui_crew_window_captains_actions_undock_tip'}
--
GuiCommon.flow_add_close_button(flow, window_name .. '_piratebutton')
GuiCommon.flow_add_close_button(window, window_name .. '_piratebutton')
end
@ -370,58 +306,22 @@ function Public.full_update(player)
if Public.regular_update then Public.regular_update(player) end
if not player.gui.screen[window_name .. '_piratewindow'] then return end
local flow = player.gui.screen[window_name .. '_piratewindow']
local window = player.gui.screen[window_name .. '_piratewindow']
local flow = window.scroll_pane
local memory = Memory.get_crew_memory()
local playercrew_status = GuiCommon.crew_overall_state_bools(player.index)
-- local destination = Common.current_destination()
--*** WHAT TO SHOW ***--
flow.difficulty_vote.visible = memory.overworldx and memory.overworldx == 0
flow.members.body.class_renounce.visible = memory.classes_table and memory.classes_table[player.index]
flow.members.body.officer_resign.visible = memory.officers_table and memory.officers_table[player.index]
flow.spare_classes.visible = memory.spare_classes and #memory.spare_classes > 0
local other_player_selected = flow.members.body.members_listbox.selected_index ~= 0 and tonumber(flow.members.body.members_listbox.get_item(flow.members.body.members_listbox.selected_index)[2]) ~= player.index
local any_class_button = false
for _, c in pairs(Classes.enum) do
if memory.spare_classes and Utils.contains(memory.spare_classes, c) and (not (player.controller_type == defines.controllers.spectator)) then
if Common.is_captain(player) and memory.crewplayerindices and #memory.crewplayerindices > 1 then
if other_player_selected and (not (memory.classes_table[tonumber(flow.members.body.members_listbox.get_item(flow.members.body.members_listbox.selected_index)[2])])) then
flow.spare_classes.body.assign_flow['selfassign_class_' .. c].visible = false
flow.spare_classes.body.assign_flow['assign_class_' .. c].visible = true
any_class_button = true
else
flow.spare_classes.body.assign_flow['assign_class_' .. c].visible = false
if (not memory.classes_table[player.index]) then
flow.spare_classes.body.assign_flow['selfassign_class_' .. c].visible = true
any_class_button = true
else
flow.spare_classes.body.assign_flow['selfassign_class_' .. c].visible = false
end
end
else
flow.spare_classes.body.assign_flow['assign_class_' .. c].visible = false
if (not memory.classes_table[player.index]) then
flow.spare_classes.body.assign_flow['selfassign_class_' .. c].visible = true
any_class_button = true
else
flow.spare_classes.body.assign_flow['selfassign_class_' .. c].visible = false
end
end
else
flow.spare_classes.body.assign_flow['assign_class_' .. c].visible = false
flow.spare_classes.body.assign_flow['selfassign_class_' .. c].visible = false
end
end
flow.spare_classes.body.assign_flow.visible = any_class_button
flow.captain.visible = Common.is_captain(player)
flow.undock_tip.visible = Common.is_captain(player)
@ -431,8 +331,6 @@ function Public.full_update(player)
flow.captain.body.make_officer.visible = other_player_selected and (not (memory.officers_table and memory.officers_table[tonumber(flow.members.body.members_listbox.get_item(flow.members.body.members_listbox.selected_index)[2])]))
flow.captain.body.unmake_officer.visible = other_player_selected and ((memory.officers_table and memory.officers_table[tonumber(flow.members.body.members_listbox.get_item(flow.members.body.members_listbox.selected_index)[2])]))
flow.captain.body.revoke_class.visible = other_player_selected and (memory.classes_table[tonumber(flow.members.body.members_listbox.get_item(flow.members.body.members_listbox.selected_index)[2])])
-- flow.captain.body.capn_undock_normal.visible = memory.boat and memory.boat.state and ((memory.boat.state == Boats.enum_state.LANDED) or (memory.boat.state == Boats.enum_state.APPROACHING) or (memory.boat.state == Boats.enum_state.DOCKED))
flow.captain.body.capn_summon_crew.visible = false
@ -467,27 +365,11 @@ function Public.full_update(player)
--== UPDATE CONTENT ==--
if memory.id then
flow.caption = memory.name
if Common.is_id_valid(memory.id) then
window.caption = memory.name
flow.crew_age.caption = {'pirates.gui_crew_window_crew_age', Utils.time_mediumform((memory.age or 0)/60)}
flow.crew_capacity_and_difficulty.caption = {'pirates.gui_crew_window_crew_capacity_and_difficulty', CoreData.difficulty_options[memory.difficulty_option].text, CoreData.capacity_options[memory.capacity_option].text3}
if flow.spare_classes.visible then
local str = {''}
for i, c in ipairs(memory.spare_classes) do
if i>1 then
str[#str+1] = {'', {'pirates.separator_1'}, Classes.display_form(c)} -- we need to do nesting here, because you can't contanenate more than 20 localised strings. Watch out!
--@TODO: In fact we should nest iteratively, as this still caps out around 19 classes.
else
str[#str+1] = {'', Classes.display_form(c)}
end
end
str[#str+1] = '.'
flow.spare_classes.body.list.caption = str
end
end
@ -563,18 +445,6 @@ function Public.click(event)
-- return
-- end
if string.sub(eventname, 1, 13) and string.sub(eventname, 1, 13) == 'assign_class_' then
local other_id = tonumber(flow.members.body.members_listbox.get_item(flow.members.body.members_listbox.selected_index)[2])
Classes.assign_class(other_id, string.sub(eventname, 14, -1))
return
end
if string.sub(eventname, 1, 17) and string.sub(eventname, 1, 17) == 'selfassign_class_' then
Classes.assign_class(player.index, string.sub(eventname, 18, -1), true)
return
end
if string.sub(eventname, 1, 18) and string.sub(eventname, 1, 18) == 'difficulty_option_' then
Crew.difficulty_vote(player.index, tonumber(string.sub(eventname, 19, -1)))
return
@ -597,11 +467,6 @@ function Public.click(event)
return
end
if eventname == 'class_renounce' then
Classes.try_renounce_class(player, true)
return
end
if eventname == 'capn_renounce' then
Roles.renounce_captainhood(player)
return
@ -653,12 +518,6 @@ function Public.click(event)
return
end
if eventname == 'revoke_class' then
local other_id = tonumber(flow.members.body.members_listbox.get_item(flow.members.body.members_listbox.selected_index)[2])
Roles.revoke_class(player, game.players[other_id])
return
end
if eventname == 'capn_plank' then
local other_id = tonumber(flow.members.body.members_listbox.get_item(flow.members.body.members_listbox.selected_index)[2])

View File

@ -9,6 +9,7 @@ local GuiEvo = require 'maps.pirates.gui.evo'
local GuiProgress = require 'maps.pirates.gui.progress'
local GuiRuns = require 'maps.pirates.gui.runs'
local GuiCrew = require 'maps.pirates.gui.crew'
local GuiClasses = require 'maps.pirates.gui.classes'
local GuiFuel = require 'maps.pirates.gui.fuel'
local GuiMinimap = require 'maps.pirates.gui.minimap'
local GuiInfo = require 'maps.pirates.gui.info'
@ -45,6 +46,7 @@ Public.enum = enum
Public.progress = require 'maps.pirates.gui.progress'
Public.runs = require 'maps.pirates.gui.runs'
Public.crew = require 'maps.pirates.gui.crew'
Public.classes = require 'maps.pirates.gui.classes'
Public.fuel = require 'maps.pirates.gui.fuel'
Public.minimap = require 'maps.pirates.gui.minimap'
Public.info = require 'maps.pirates.gui.info'
@ -101,6 +103,9 @@ local function create_gui(player)
flow2 = GuiCommon.flow_add_floating_sprite_button(flow1, 'crew_piratebutton')
flow2.sprite = 'utility/spawn_flag'
flow2 = GuiCommon.flow_add_floating_sprite_button(flow1, 'classes_piratebutton')
flow2.sprite = 'item/light-armor'
-- flow2 = GuiCommon.flow_add_floating_sprite_button(flow1, 'lives_piratebutton')
-- flow2.tooltip = 'Lives\n\nWhen a silo is destroyed before its rocket is launched, you lose a life.\n\nLosing all your lives is one way to lose the game.'
-- flow2.mouse_button_filter = {'middle'}
@ -902,7 +907,7 @@ function Public.update_gui(player)
flow1 = pirates_flow.crew_piratebutton_frame.crew_piratebutton
if memory.id and memory.id ~= 0 then
if Common.is_id_valid(memory.id) then
flow1.tooltip = {'pirates.gui_crew_tooltip_1'}
flow1.mouse_button_filter = {'left','right'}
else
@ -913,10 +918,24 @@ function Public.update_gui(player)
end
end
flow1 = pirates_flow.classes_piratebutton_frame.classes_piratebutton
if Common.is_id_valid(memory.id) then
flow1.tooltip = {'pirates.gui_classes_tooltip_1'}
flow1.mouse_button_filter = {'left','right'}
else
flow1.tooltip = {'pirates.gui_classes_tooltip_2'}
flow1.mouse_button_filter = {'middle'} --hack to avoid press visual
if player.gui.screen['classes_piratewindow'] then
player.gui.screen['classes_piratewindow'].destroy()
end
end
if GuiEvo.full_update then GuiEvo.full_update(player) end
if GuiProgress.regular_update then GuiProgress.regular_update(player) end --moved to event
if GuiRuns.full_update then GuiRuns.full_update(player) end
if GuiCrew.full_update then GuiCrew.full_update(player) end
if GuiClasses.full_update then GuiClasses.full_update(player) end
if GuiFuel.regular_update then GuiFuel.regular_update(player) end --moved to event
if GuiMinimap.full_update then GuiMinimap.full_update(player) end
if GuiInfo.full_update then GuiInfo.full_update(player) end
@ -961,7 +980,7 @@ function Public.update_gui(player)
flow1 = pirates_flow.progress_piratebutton_frame.progress_piratebutton
flow1.number = (memory.overworldx or 0)
flow1.caption = {'pirates.gui_progress_tooltip', memory.overworldx or 0, CoreData.victory_x}
flow1.tooltip = {'pirates.gui_progress_tooltip', memory.overworldx or 0, CoreData.victory_x}
-- pirates_flow.destination_piratebutton_frame.destination_piratebutton.number = memory.destinationsvisited_indices and #memory.destinationsvisited_indices or 0
@ -1201,6 +1220,7 @@ local function on_gui_click(event)
else
if GuiRuns.click then GuiRuns.click(event) end
if GuiCrew.click then GuiCrew.click(event) end
if GuiClasses.click then GuiClasses.click(event) end
if GuiFuel.click then GuiFuel.click(event) end
if GuiMinimap.click then GuiMinimap.click(event) end
if GuiInfo.click then GuiInfo.click(event) end

View File

@ -78,6 +78,8 @@ function Public.initialise_crew_memory(id) --mostly serves as a dev reference of
memory.boat = nil
memory.available_classes_pool = nil
-- Duplicating unlocked classes data for consistency reasons (this way, entries will remain in the same order when unlocked class data changes)
memory.unlocked_classes = nil
memory.seconds_until_alert_sound_can_be_played_again = 0
memory.crewplayerindices = nil

View File

@ -546,7 +546,7 @@ local parrot_set_sail_advice =
Memory.set_working_id(crew_id)
local memory = Memory.get_crew_memory()
if not (memory.id and memory.id > 0) then return end --check if crew disbanded
if not Common.is_id_valid(memory.id) then return end --check if crew disbanded
if memory.game_lost then return end
if memory.boat and memory.boat.state and memory.boat.state == Boats.enum_state.ATSEA_WAITING_TO_SAIL then

View File

@ -70,7 +70,7 @@ function Public.explanation(class)
return {'pirates.class_' .. class .. '_explanation'}
end
function Public.explanation_advanced(class)
function Public.explanation_advanced(class, add_is_class_obstainable)
local explanation = 'pirates.class_' .. class .. '_explanation_advanced'
local full_explanation
@ -124,7 +124,9 @@ function Public.explanation_advanced(class)
full_explanation = {'', {explanation}}
end
full_explanation[#full_explanation + 1] = Public.class_is_obtainable(class) and {'', ' ', {'pirates.class_obtainable'}} or {'', ' ', {'pirates.class_unobtainable'}}
if add_is_class_obstainable then
full_explanation[#full_explanation + 1] = Public.class_is_obtainable(class) and {'', ' ', {'pirates.class_obtainable'}} or {'', ' ', {'pirates.class_unobtainable'}}
end
return full_explanation
end
@ -204,59 +206,61 @@ function Public.class_is_obtainable(class)
return false
end
function Public.assign_class(player_index, class, self_assigned)
-- When "class" is nil, player drops equipped class
-- "class_entry_index" only relevant for GUI order consistency
function Public.assign_class(player_index, class, class_entry_index)
local memory = Memory.get_crew_memory()
local player = game.players[player_index]
if not memory.classes_table then memory.classes_table = {} end
if memory.classes_table[player_index] == class then
Common.notify_player_error(player, {'pirates.error_class_assign_redundant', Public.display_form(class)})
return false
end
if Utils.contains(memory.spare_classes, class) then -- verify that one is spare
if class then
if Utils.contains(memory.spare_classes, class) then
-- drop class
if memory.classes_table[player_index] then
memory.spare_classes[#memory.spare_classes + 1] = memory.classes_table[player_index]
memory.classes_table[player_index] = nil
Public.try_renounce_class(player, false)
memory.classes_table[player_index] = class
local force = memory.force
if force and force.valid then
if self_assigned then
Common.notify_force_light(force,{'pirates.class_take_spare', player.name, Public.display_form(memory.classes_table[player_index]), Public.explanation(memory.classes_table[player_index])})
else
Common.notify_force_light(force,{'pirates.class_give_spare', Public.display_form(memory.classes_table[player_index]), player.name, Public.explanation(memory.classes_table[player_index])})
end
end
memory.spare_classes = Utils.ordered_table_with_single_value_removed(memory.spare_classes, class)
return true
else
Common.notify_player_error(player, {'pirates.error_class_assign_unavailable_class'})
return false
end
end
function Public.try_renounce_class(player, whisper_failure_message, impersonal_bool)
local memory = Memory.get_crew_memory()
local force = memory.force
if force and force.valid and player and player.index then
if memory.classes_table and memory.classes_table[player.index] then
if force and force.valid then
if impersonal_bool then
Common.notify_force_light(force,{'pirates.class_becomes_spare', Public.display_form(memory.classes_table[player.index])})
else
Common.notify_force_light(force,{'pirates.class_give_up', player.name, Public.display_form(memory.classes_table[player.index])})
for _, class_entry in ipairs(memory.unlocked_classes) do
if class_entry.taken_by == player.index then
class_entry.taken_by = nil
break
end
end
end
memory.spare_classes[#memory.spare_classes + 1] = memory.classes_table[player.index]
memory.classes_table[player.index] = nil
elseif whisper_failure_message then
Common.notify_player_error(player, {'pirates.class_give_up_error_no_class'})
-- assign class
memory.classes_table[player_index] = class
memory.spare_classes = Utils.ordered_table_with_single_value_removed(memory.spare_classes, class)
if class_entry_index then
memory.unlocked_classes[class_entry_index].taken_by = player.index
else
for _, class_entry in ipairs(memory.unlocked_classes) do
if class_entry.class == class and (not class_entry.taken_by) then
class_entry.taken_by = player.index
break
end
end
end
end
else
-- drop class
if memory.classes_table[player_index] then
memory.spare_classes[#memory.spare_classes + 1] = memory.classes_table[player_index]
memory.classes_table[player_index] = nil
if class_entry_index then
memory.unlocked_classes[class_entry_index].taken_by = nil
else
for _, class_entry in ipairs(memory.unlocked_classes) do
if class_entry.taken_by == player.index then
class_entry.taken_by = nil
break
end
end
end
end
end
end
@ -380,6 +384,78 @@ function Public.lumberjack_bonus_items(give_table)
end
end
function Public.try_unlock_class(class_for_sale, player, force_unlock)
local memory = Memory.get_crew_memory()
local required_class = Public.class_purchase_requirement[class_for_sale]
if not (memory.classes_table and memory.spare_classes) then
return false
end
if required_class then
local chosen_class_assigned = false
for p_index, chosen_class in pairs(memory.classes_table) do
if chosen_class == required_class then
memory.classes_table[p_index] = class_for_sale
chosen_class_assigned = true
-- update GUI data
for _, class_entry in ipairs(memory.unlocked_classes) do
if class_entry.taken_by == player.index then
class_entry.class = class_for_sale
break
end
end
return true
end
end
if not chosen_class_assigned then
for i, spare_class in pairs(memory.spare_classes) do
if spare_class == required_class then
memory.spare_classes[i] = class_for_sale
-- update GUI data
for _, class_entry in ipairs(memory.unlocked_classes) do
if required_class == class_entry.class and (not class_entry.taken_by) then
class_entry.class = class_for_sale
break
end
end
return true
end
end
end
-- allows to unlock class even if pre-requisite is missing
if force_unlock then
memory.spare_classes[#memory.spare_classes + 1] = class_for_sale
-- update GUI data
memory.unlocked_classes[#memory.unlocked_classes + 1] = {class = class_for_sale}
end
else -- there is no required class
-- if player who unlocked class doesn't have one equipped, equip it for him
if not memory.classes_table[player.index] then
memory.classes_table[player.index] = class_for_sale
-- update GUI data
memory.unlocked_classes[#memory.unlocked_classes + 1] = {class = class_for_sale, taken_by = player.index}
else
memory.spare_classes[#memory.spare_classes + 1] = class_for_sale
-- update GUI data
memory.unlocked_classes[#memory.unlocked_classes + 1] = {class = class_for_sale}
end
return true
end
return false
end
local event = require 'utils.event'
event.add(defines.events.on_player_used_capsule, class_on_player_used_capsule)

View File

@ -74,17 +74,17 @@ function Public.unmake_officer(captain, player)
end
end
function Public.revoke_class(captain, player)
local memory = Memory.get_crew_memory()
local force = memory.force
-- function Public.revoke_class(captain, player)
-- local memory = Memory.get_crew_memory()
-- local force = memory.force
if force and force.valid and player.index and memory.classes_table[player.index] then
memory.spare_classes[#memory.spare_classes + 1] = memory.classes_table[player.index]
memory.classes_table[player.index] = nil
-- if force and force.valid and player.index and memory.classes_table[player.index] then
-- memory.spare_classes[#memory.spare_classes + 1] = memory.classes_table[player.index]
-- memory.classes_table[player.index] = nil
Common.notify_force_light(captain,{'pirates.class_revoke', captain.name, Classes.display_form(memory.classes_table[player.index]), player.name})
end
end
-- Common.notify_force_light(captain,{'pirates.class_revoke', captain.name, Classes.display_form(memory.classes_table[player.index]), player.name})
-- end
-- end
function Public.tag_text(player)
local memory = Memory.get_crew_memory()
@ -92,7 +92,7 @@ function Public.tag_text(player)
local str = ''
local tags = {}
if memory.id ~= 0 and Common.is_captain(player) then
if Common.is_id_valid(memory.id) and Common.is_captain(player) then
tags[#tags + 1] = 'Cap\'n'
elseif player.controller_type == defines.controllers.spectator then
tags[#tags + 1] = 'Spectating'
@ -131,13 +131,13 @@ end
-- return str
-- end
function Public.get_class_print_string(class, full)
function Public.get_class_print_string(class, full, add_is_class_obstainable)
for _, class2 in pairs(Classes.enum) do
if Classes.eng_form[class2]:lower() == class:lower() or class2 == class:lower() then
local explanation
if full then
explanation = Classes.explanation_advanced(class2)
explanation = Classes.explanation_advanced(class2, add_is_class_obstainable)
else
explanation = Classes.explanation(class2)
end
@ -164,7 +164,7 @@ end
function Public.player_privilege_level(player)
local memory = Memory.get_crew_memory()
if memory.id ~= 0 and Common.is_captain(player) then
if Common.is_id_valid(memory.id) and Common.is_captain(player) then
return Public.privilege_levels.CAPTAIN
elseif memory.officers_table and memory.officers_table[player.index] then
return Public.privilege_levels.OFFICER
@ -215,18 +215,31 @@ end
function Public.player_left_so_redestribute_roles(player)
-- local memory = Memory.get_crew_memory()
if player and player.index then
if Common.is_captain(player) then
Public.assign_captain_based_on_priorities()
end
if not (player and player.index) then return end
-- no need to do this, as long as officers get reset when the captainhood changes hands
-- if memory.officers_table and memory.officers_table[player.index] then
-- memory.officers_table[player.index] = nil
-- end
if Common.is_captain(player) then
Public.assign_captain_based_on_priorities()
end
Classes.try_renounce_class(player, false, true)
-- no need to do this, as long as officers get reset when the captainhood changes hands
-- if memory.officers_table and memory.officers_table[player.index] then
-- memory.officers_table[player.index] = nil
-- end
local memory = Memory.get_crew_memory()
-- free up the class
if memory.classes_table and memory.classes_table[player.index] then
memory.spare_classes[#memory.spare_classes + 1] = memory.classes_table[player.index]
memory.classes_table[player.index] = nil
for _, class_entry in ipairs(memory.unlocked_classes) do
if class_entry.taken_by == player.index then
class_entry.taken_by = nil
break
end
end
end
end
@ -274,7 +287,7 @@ function Public.confirm_captain_exists(player_to_make_captain_otherwise)
local memory = Memory.get_crew_memory()
-- Currently this catches an issue where a crew drops to zero players, and then someone else joins.
if (memory.id and memory.id > 0 and memory.crewstatus and memory.crewstatus == 'adventuring') and (not (memory.playerindex_captain and game.players[memory.playerindex_captain] and Common.validate_player(game.players[memory.playerindex_captain]))) then --fixme: enum hacked
if (Common.is_id_valid(memory.id) and memory.crewstatus and memory.crewstatus == 'adventuring') and (not (memory.playerindex_captain and game.players[memory.playerindex_captain] and Common.validate_player(game.players[memory.playerindex_captain]))) then --fixme: enum hacked
if player_to_make_captain_otherwise then
Public.make_captain(player_to_make_captain_otherwise)
-- game.print('Auto-reassigning captain.')

View File

@ -211,41 +211,7 @@ function Public.event_on_market_item_purchased(event)
-- if not class_for_sale then return end
local required_class = Classes.class_purchase_requirement[class_for_sale]
local ok = false
if memory.classes_table and memory.spare_classes then
if required_class then
local chosen_class_assigned = false
if required_class then
for p_index, chosen_class in pairs(memory.classes_table) do
if chosen_class == required_class then
memory.classes_table[p_index] = class_for_sale
chosen_class_assigned = true
ok = true
break
end
end
end
if not chosen_class_assigned then
for i, spare_class in pairs(memory.spare_classes) do
if spare_class == required_class then
memory.spare_classes[i] = class_for_sale
ok = true
break
end
end
end
else -- there is no required class
if not memory.classes_table[player.index] then
memory.classes_table[player.index] = class_for_sale
else
memory.spare_classes[#memory.spare_classes + 1] = class_for_sale
end
ok = true
end
end
local ok = Classes.try_unlock_class(class_for_sale, player)
if ok then
if force and force.valid then
@ -266,7 +232,7 @@ function Public.event_on_market_item_purchased(event)
memory.available_classes_pool[#memory.available_classes_pool + 1] = upgrade
end
end
else
else -- if this happens, I believe there is something wrong with code
if force and force.valid then
Common.notify_force_error(force, {'pirates.class_purchase_error_prerequisite_class', Classes.display_form(required_class)})
end
@ -278,6 +244,8 @@ function Public.event_on_market_item_purchased(event)
inv.insert{name = p.name, count = p.amount}
end
refunds = refunds + 1
log('Error purchasing class: ' .. class_for_sale)
end
else
Common.notify_force_light(player.force, {'pirates.market_event_buy', player.name, thisPurchaseData.offer_giveitem_count .. ' ' .. thisPurchaseData.offer_giveitem_name, thisPurchaseData.price[1].amount .. ' ' .. thisPurchaseData.price[1].name})

View File

@ -54,7 +54,7 @@ local swimming_biters_tick_token =
function Public.swimming_biters_tick(crew_id, kraken_id)
Memory.set_working_id(crew_id)
local memory = Memory.get_crew_memory()
if not (memory.id and memory.id > 0) then return end --check if crew disbanded
if not Common.is_id_valid(memory.id) then return end --check if crew disbanded
if memory.game_lost then return end
local kraken_data = memory.active_sea_enemies.krakens[kraken_id]
if not kraken_data then return end --check if kraken died
@ -87,7 +87,7 @@ end
function Public.kraken_tick(crew_id, kraken_id, step, substep)
Memory.set_working_id(crew_id)
local memory = Memory.get_crew_memory()
if not (memory.id and memory.id > 0) then return end --check if crew disbanded
if not Common.is_id_valid(memory.id) then return end --check if crew disbanded
if memory.game_lost then return end
local kraken_data = memory.active_sea_enemies.krakens[kraken_id]
if not kraken_data then return end --check if kraken died

View File

@ -338,16 +338,17 @@ function Public.destination_on_arrival(destination)
-- add special chunk structures(small mining base, etc.) to avoid list
local structures = destination.dynamic_data.structures_waiting_to_be_placed
for i = #structures, 1, -1 do
local structure = structures[i]
local special = structure.data
local position = special.position
local avoid_radius = math.sqrt(special.width * special.width + special.height * special.height) / 2 + 4
if structures then
for i = #structures, 1, -1 do
local structure = structures[i]
local special = structure.data
local position = special.position
local avoid_radius = math.sqrt(special.width * special.width + special.height * special.height) / 2 + 5
points_to_avoid[#points_to_avoid + 1] = {x = position.x, y = position.y, r = avoid_radius}
points_to_avoid[#points_to_avoid + 1] = {x = position.x, y = position.y, r = avoid_radius}
end
end
-- game.print('spawning silo')
if destination.subtype ~= Islands.enum.RADIOACTIVE then
local silo_position = Islands.spawn_silo_setup(points_to_avoid)