Add Tool Gui (#20)

* Update _file_loader.lua

* Create tool.lua

* Update trains.lua

* Update research.lua

* Fix use of created_entity in events

* Update trains.lua

* Update tool.lua

* Update research.lua

* Update research.lua

* Update tool.lua

* Update research.lua

* Update trains.lua

* Fix waterfill locale

* Fix bug with selection tools and remote view

* Fix tool GUI

* Update tool.lua

---------

Co-authored-by: Cooldude2606 <25043174+Cooldude2606@users.noreply.github.com>
This commit is contained in:
2024-12-29 02:29:51 +09:00
committed by GitHub
parent d489615542
commit 8c19d67450
7 changed files with 328 additions and 30 deletions

View File

@@ -56,6 +56,7 @@ return {
"modules.gui.research",
"modules.gui.module",
"modules.gui.landfill",
"modules.gui.tool",
"modules.gui.production",
"modules.gui.playerdata",
"modules.gui.surveillance",

View File

@@ -233,6 +233,7 @@ Roles.new_role("Member", "Mem")
"gui/warp-list/edit",
"gui/surveillance",
"gui/vlayer-edit",
"gui/tool",
"command/save-quickbar",
"command/vlayer-info",
"command/personal-logistic",

View File

@@ -31,9 +31,10 @@ Storage.register({
end)
--- Let a player select an area by providing a selection planner
-- @tparam LuaPlayer player The player to place into selection mode
-- @tparam string selection_name The name of the selection to start, used with on_selection
-- @tparam[opt=false] boolean single_use When true the selection will stop after first use
--- @param player LuaPlayer The player to place into selection mode
--- @param selection_name string The name of the selection to start, used with on_selection
--- @param single_use boolean? When true the selection will stop after first use
--- @param ... any Arguments to pass to the selection handler
function Selection.start(player, selection_name, single_use, ...)
if not player or not player.valid then return end
if selections[player.index] then
@@ -67,10 +68,15 @@ function Selection.start(player, selection_name, single_use, ...)
player.clear_cursor() -- Clear the current item
player.cursor_stack.set_stack(selection_tool)
-- This does not work for selection planners, will make a feature request for it
--player.cursor_stack_temporary = true
-- Make a slot to place the selection tool even if inventory is full
if not player.character then return end
player.character_inventory_slots_bonus = player.character_inventory_slots_bonus + 1
player.hand_location = { inventory = defines.inventory.character_main, slot = #player.get_main_inventory() }
local inventory = player.get_main_inventory()
if inventory then
player.hand_location = { inventory = inventory.index, slot = #inventory }
end
end
--- Stop a player selection by removing the selection planner
@@ -150,6 +156,16 @@ Event.add(defines.events.on_player_cursor_stack_changed, function(event)
if player.cursor_stack.is_selection_tool then return end
Selection.stop(player)
end)
--- Make sure the hand location exists when the player returns from remote view
Event.add(defines.events.on_player_controller_changed, function(event)
local player = game.players[event.player_index] --- @cast player -nil
local inventory = player.get_main_inventory()
if player.cursor_stack.is_selection_tool and inventory then
player.hand_location = { inventory = inventory.index, slot = #inventory }
end
end)
--- Stop selection after an event such as death or leaving the game
local function stop_after_event(event)
local player = game.players[event.player_index]

View File

@@ -0,0 +1,262 @@
--[[-- Gui Module - Tool
@gui Tool
@alias tool_container
]]
local ExpUtil = require("modules/exp_util")
local Gui = require("modules/exp_legacy/expcore/gui") --- @dep expcore.gui
local Roles = require("modules.exp_legacy.expcore.roles") --- @dep expcore.roles
local Event = require("modules/exp_legacy/utils/event") --- @dep utils.event
local Selection = require("modules/exp_legacy/modules/control/selection") --- @dep modules.control.selection
local addon_train = require("modules/exp_scenario/commands/trains")
local addon_research = require("modules/exp_scenario/commands/research")
local tool_container
local SelectionArtyArea = "ExpCommand_Artillery"
local SelectionWaterfillArea = "ExpCommand_Waterfill"
local style = {
label = {
width = 160
},
button = {
width = 80
}
}
--- Arty label
-- @element tool_gui_arty_l
local tool_gui_arty_l =
Gui.element{
type = "label",
name = "tool_arty_l",
caption = { "tool.artillery" },
tooltip = { "tool.artillery-tooltip" },
style = "heading_2_label"
}:style(
style.label
)
--- Arty button
-- @element tool_gui_arty_b
local tool_gui_arty_b =
Gui.element{
type = "button",
name = "tool_arty_b",
caption = { "tool.apply" }
}:style(
style.button
):on_click(function(player, _, _)
if Selection.is_selecting(player, SelectionArtyArea) then
Selection.stop(player)
else
Selection.start(player, SelectionArtyArea)
player.print{ "tool.entered-area-selection" }
end
end)
--- Waterfill label
-- @element tool_gui_waterfill_l
local tool_gui_waterfill_l =
Gui.element{
type = "label",
name = "tool_waterfill_l",
caption = { "tool.waterfill" },
tooltip = { "tool.waterfill-tooltip" },
style = "heading_2_label"
}:style(
style.label
)
--- Waterfill button
-- @element tool_gui_waterfill_b
local tool_gui_waterfill_b =
Gui.element{
type = "button",
name = "tool_waterfill_b",
caption = { "tool.apply" }
}:style(
style.button
):on_click(function(player, _, _)
if Selection.is_selecting(player, SelectionWaterfillArea) then
Selection.stop(player)
return player.print{ "exp-commands_waterfill.exit" }
elseif player.get_item_count("cliff-explosives") == 0 then
return player.print{ "exp-commands_waterfill.requires-explosives" }
else
Selection.start(player, SelectionWaterfillArea)
return player.print{ "exp-commands_waterfill.enter" }
end
end)
--- Train label
-- @element tool_gui_train_l
local tool_gui_train_l =
Gui.element{
type = "label",
name = "tool_train_l",
caption = { "tool.train" },
tooltip = { "tool.train-tooltip" },
style = "heading_2_label"
}:style(
style.label
)
--- Train button
-- @element tool_gui_train_b
local tool_gui_train_b =
Gui.element{
type = "button",
name = "tool_train_b",
caption = { "tool.apply" }
}:style(
style.button
):on_click(function(player, _, _)
addon_train.manual(player)
end)
--- Research label
-- @element tool_gui_research_l
local tool_gui_research_l =
Gui.element{
type = "label",
name = "tool_research_l",
caption = { "tool.research" },
tooltip = { "tool.research-tooltip" },
style = "heading_2_label"
}:style(
style.label
)
--- Research button
-- @element tool_gui_research_b
local tool_gui_research_b =
Gui.element{
type = "button",
name = "tool_research_b",
caption = { "tool.apply" }
}:style(
style.button
):on_click(function(player, _, _)
local enabled = addon_research.set_auto_research()
if enabled then
addon_research.res_queue(player.force, true)
end
local player_name = ExpUtil.format_player_name_locale(player)
game.print{ "exp-commands_research.auto-research", player_name, enabled }
end)
--- Spawn label
-- @element tool_gui_spawn_l
local tool_gui_spawn_l =
Gui.element{
type = "label",
name = "tool_spawn_l",
caption = { "tool.spawn" },
tooltip = { "tool.spawn-tooltip" },
style = "heading_2_label"
}:style(
style.label
)
--- Spawn button
-- @element tool_gui_spawn_b
local tool_gui_spawn_b =
Gui.element{
type = "button",
name = "tool_spawn_b",
caption = { "tool.apply" }
}:style(
style.button
):on_click(function(player, _, _)
if not player.character
or player.character.health <= 0
or not ExpUtil.teleport_player(player, game.surfaces.nauvis, { 0, 0 }, "dismount") then
return player.print{ "exp-commands_teleport.unavailable" }
end
end)
local function tool_perm(player)
local frame = Gui.get_left_element(player, tool_container)
local disp = frame.container["tool_st"].disp.table
local allowed
allowed = Roles.player_allowed(player, "command/artillery")
disp[tool_gui_arty_l.name].visible = allowed
disp[tool_gui_arty_b.name].visible = allowed
allowed = Roles.player_allowed(player, "command/waterfill")
disp[tool_gui_waterfill_l.name].visible = allowed
disp[tool_gui_waterfill_b.name].visible = allowed
allowed = Roles.player_allowed(player, "command/set-trains-to-automatic")
disp[tool_gui_train_l.name].visible = allowed
disp[tool_gui_train_b.name].visible = allowed
allowed = Roles.player_allowed(player, "command/set-auto-research")
disp[tool_gui_research_l.name].visible = allowed
disp[tool_gui_research_b.name].visible = allowed
allowed = Roles.player_allowed(player, "command/spawn")
disp[tool_gui_spawn_l.name].visible = allowed
disp[tool_gui_spawn_b.name].visible = allowed
end
--- A vertical flow containing all the tool
-- @element tool_set
local tool_set =
Gui.element(function(_, parent, name)
local tool_set = parent.add{ type = "flow", direction = "vertical", name = name }
local disp = Gui.scroll_table(tool_set, 240, 2, "disp")
tool_gui_arty_l(disp)
tool_gui_arty_b(disp)
tool_gui_waterfill_l(disp)
tool_gui_waterfill_b(disp)
tool_gui_train_l(disp)
tool_gui_train_b(disp)
tool_gui_research_l(disp)
tool_gui_research_b(disp)
tool_gui_spawn_l(disp)
tool_gui_spawn_b(disp)
return tool_set
end)
--- The main container for the tool gui
-- @element tool_container
tool_container =
Gui.element(function(definition, parent)
local player = Gui.get_player_from_element(parent)
local container = Gui.container(parent, definition.name, 240)
tool_set(container, "tool_st")
tool_perm(player)
return container.parent
end)
:static_name(Gui.unique_static_name)
:add_to_left_flow()
--- Button on the top flow used to toggle the tool container
-- @element toggle_left_element
Gui.left_toolbar_button("item/repair-pack", { "tool.main-tooltip" }, tool_container, function(player)
return Roles.player_allowed(player, "gui/tool")
end)
Event.add(Roles.events.on_role_assigned, function(event)
tool_perm(game.players[event.player_index])
end)
Event.add(Roles.events.on_role_unassigned, function(event)
tool_perm(game.players[event.player_index])
end)

View File

@@ -36,24 +36,34 @@ function module.res_queue(force, silent)
end
end
--- @param state boolean? use nil to toggle current state
--- @return boolean # New auto research state
function module.set_auto_research(state)
local new_state
if state == nil then
new_state = not research.res_queue_enable
else
new_state = state ~= false
end
research.res_queue_enable = new_state
return new_state
end
--- Sets the auto research state
Commands.new("set-auto-research", { "exp-commands_research.description" })
:optional("state", { "exp-commands_research.arg-state" }, Commands.types.boolean)
:add_aliases{ "auto-research" }
:register(function(player, state)
--- @cast state boolean?
if state == nil then
research.res_queue_enable = not research.res_queue_enable
else
research.res_queue_enable = state
end
local enabled = module.set_auto_research(state)
if research.res_queue_enable then
if enabled then
module.res_queue(player.force --[[@as LuaForce]], true)
end
local player_name = format_player_name(player)
game.print{ "exp-commands_research.auto-research", player_name, research.res_queue_enable }
game.print{ "exp-commands_research.auto-research", player_name, enabled }
end)
--- @param event EventData.on_research_finished

View File

@@ -4,9 +4,26 @@ Adds a command that set all train back to automatic
local Commands = require("modules/exp_commands")
local format_player_name = Commands.format_player_name_locale
local format_number = require("util").format_number
--- @class Command.Trains
local module = {}
function module.manual(player, surface, force)
local trains = game.train_manager.get_trains{
has_passenger = false,
is_manual = true,
surface = surface,
force = force,
}
for _, train in ipairs(trains) do
train.manual_mode = false
end
game.print{ "exp-commands_trains.response", format_player_name(player), format_number(#trains, false) }
end
--- Set all trains to automatic
Commands.new("set-trains-to-automatic", { "exp-commands_trains.description" })
:optional("surface", { "exp-commands_trains.arg-surface" }, Commands.types.surface)
@@ -14,16 +31,7 @@ Commands.new("set-trains-to-automatic", { "exp-commands_trains.description" })
:register(function(player, surface, force)
--- @cast surface LuaSurface?
--- @cast force LuaForce?
local trains = game.train_manager.get_trains{
has_passenger = false,
is_manual = true,
surface = surface,
force = force,
}
for _, train in ipairs(trains) do
train.manual_mode = false
end
game.print{ "exp-commands_trains.response", format_player_name(player), format_number(#trains, false) }
module.manual(player, surface, force)
end)
return module

View File

@@ -29,19 +29,19 @@ Selection.on_selection(SelectionName, function(event)
local surface = event.surface
if surface.planet and surface.planet ~= game.planets.nauvis then
player.print({ "exp-cods_waterfill.nauvis-only" }, Commands.print_settings.error)
player.print({ "exp-commands_waterfill.nauvis-only" }, Commands.print_settings.error)
return
end
local area_size = (area.right_bottom.x - area.left_top.x) * (area.right_bottom.y - area.left_top.y)
if area_size > 1000 then
player.print({ "exp-cods_waterfill.area-too-large", 1000, area_size }, Commands.print_settings.error)
player.print({ "exp-commands_waterfill.area-too-large", 1000, area_size }, Commands.print_settings.error)
return
end
local item_count = player.get_item_count("cliff-explosives")
if item_count < area_size then
player.print({ "exp-cods_waterfill.too-few-explosives", area_size, item_count }, Commands.print_settings.error)
player.print({ "exp-commands_waterfill.too-few-explosives", area_size, item_count }, Commands.print_settings.error)
return
end
@@ -62,8 +62,8 @@ Selection.on_selection(SelectionName, function(event)
player.remove_item{ name = "cliff-explosives", count = tile_count - remaining_tiles }
if remaining_tiles > 0 then
player.print({ "exp-cods_waterfill.part-complete", tile_count, remaining_tiles }, Commands.print_settings.default)
player.print({ "exp-commands_waterfill.part-complete", tile_count, remaining_tiles }, Commands.print_settings.default)
else
player.print({ "exp-cods_waterfill.complete", tile_count }, Commands.print_settings.default)
player.print({ "exp-commands_waterfill.complete", tile_count }, Commands.print_settings.default)
end
end)