Add spidertron gui to save/load squad configs.

This commit is contained in:
Peter 2020-11-28 22:31:57 +08:00
parent 3840ea92cc
commit 6677ac9b29
16 changed files with 393 additions and 40 deletions

View File

@ -53,10 +53,10 @@ Date: 2020-11-28
Features:
- NOTE: BETA RELEASE - USE AT YOUR OWN RISK!
- Update mod to Factorio 1.1
- Completely refactor code
- Attempt at Spidertron Waypoints compatibility
- 0NOTICE: THIS VERSION IS A WORK IN PROGRESS - CHANGELOG IS NOT FINAL
- 1NOTICE: THIS VERSION IS A WORK IN PROGRESS - CHANGELOG IS NOT FINAL
- Completely refactor code to be cleaner
- Spidertron Waypoints mod compatibility
- Added menu/gui to save and load squad configurations
- Spidertron link tool (Link squads to an entity)
- 2NOTICE: THIS VERSION IS A WORK IN PROGRESS - CHANGELOG IS NOT FINAL
- 3NOTICE: THIS VERSION IS A WORK IN PROGRESS - CHANGELOG IS NOT FINAL
- 4NOTICE: THIS VERSION IS A WORK IN PROGRESS - CHANGELOG IS NOT FINAL

View File

@ -14,7 +14,7 @@ require("control.debug")
-- REMEMBER TO COMMENT DEBUG OUT IN RELEASE!!
-- REMEMBER TO COMMENT DEBUG OUT IN RELEASE!!
-- REMEMBER TO COMMENT DEBUG OUT IN RELEASE!!
require("control.gui")
require("control.init")
require("control.remote")
require("control.give_remote")
@ -41,14 +41,22 @@ script.on_event("squad-spidertron-link-tool", function(event)
GiveLinkTool(event.player_index)
end)
script.on_event("squad-spidertron-list", function(event)
ToggleGuiList(event.player_index)
end)
script.on_event(defines.events.on_lua_shortcut, function (event)
local name = event.prototype_name
if name == "squad-spidertron-follow" then
if name == "squad-spidertron-remote" then
GiveStack(game.players[event.player_index], {name = "squad-spidertron-remote-sel", count = 1})
elseif name == "squad-spidertron-follow" then
local index = event.player_index
-- squad_leader_state(index)
SpiderbotFollow(game.players[index])
elseif name == "squad-spidertron-link-tool" then
GiveLinkTool(event.player_index)
elseif name == "squad-spidertron-list" then
ToggleGuiList(event.player_index)
end
end)
@ -56,6 +64,11 @@ script.on_nth_tick(settings.global["spidertron-follow-update-interval"].value, f
UpdateFollow()
UpdateFollowEntity()
end)
script.on_nth_tick(60, function(event)
for _, player in pairs(game.players) do
UpdateGuiList(player)
end
end)
-- script.on_event(defines.events.on_spider_command_completed, function (event)

View File

@ -1,4 +1,10 @@
--[[ Copyright (c) 2020 npc_strider
* For direct use of code or graphics, credit is appreciated. See LICENSE.txt for more information.
* This mod may contain modified code sourced from base/core Factorio
*
* control/2dvec.lua
* 2d vectors stuff. Some are specific to this mod
--]]
function IJMean(vectors)
local sumx = 0

View File

@ -1,9 +1,16 @@
--[[ Copyright (c) 2020 npc_strider
* For direct use of code or graphics, credit is appreciated. See LICENSE.txt for more information.
* This mod may contain modified code sourced from base/core Factorio
*
* control/debug.lua
* REMEMBER TO DISABLE THIS MODULE IN RELEASE!!!
--]]
commands.add_command(
"dvars",
"debug: dump spider control vars",
function (cmd)
-- game.print(serpent.block(global.spidercontrol_player_s[cmd.player_index]))
game.print(serpent.block(global.spidercontrol_linked_s))
end
)
-- commands.add_command(
-- "dvars",
-- "debug: dump spider control vars",
-- function (cmd)
-- -- game.print(serpent.block(global.spidercontrol_player_s[cmd.player_index]))
-- game.print(serpent.block(global.spidercontrol_linked_s))
-- end
-- )

View File

@ -1,3 +1,10 @@
--[[ Copyright (c) 2020 npc_strider
* For direct use of code or graphics, credit is appreciated. See LICENSE.txt for more information.
* This mod may contain modified code sourced from base/core Factorio
*
* control/entity_follow.lua
* Runs periodically to designate commands for each linked squad to move to the target entity's position.
--]]
require("control.2dvec")

View File

@ -1,3 +1,10 @@
--[[ Copyright (c) 2020 npc_strider
* For direct use of code or graphics, credit is appreciated. See LICENSE.txt for more information.
* This mod may contain modified code sourced from base/core Factorio
*
* control/functions.lua
* General/commonly used/important functions.
--]]
function SpidertronWaypointsCompatibility()
-- Compatability for Spidertron Waypoints
@ -42,12 +49,14 @@ end
function Goto(spiders, center)
local invalid = {}
for i = 1, #spiders do
local spider = spiders[i].spider
local d = spiders[i].delta
if spider.valid then
spider.autopilot_destination = IJAdd(center, d)
else
invalid[#invalid+1] = i
if spiders[i] then
local spider = spiders[i].spider
local d = spiders[i].delta
if spider.valid then
spider.autopilot_destination = IJAdd(center, d)
else
invalid[#invalid+1] = i
end
end
end
return Remove(spiders, invalid) -- We return an updated spider list (Remove any invalid spiders)
@ -111,6 +120,7 @@ local function GotoPlayerSW(index, position)
end
resetSprites(patrol)
global.spidercontrol_player_s[index].active = {}
UpdateGuiList(player)
GiveStack(player, {name="squad-spidertron-remote-sel",count=1})
player.set_shortcut_toggled("spidertron-remote-patrol", false)
patrol = nil

View File

@ -1,3 +1,11 @@
--[[ Copyright (c) 2020 npc_strider
* For direct use of code or graphics, credit is appreciated. See LICENSE.txt for more information.
* This mod may contain modified code sourced from base/core Factorio
*
* control/give_remote.lua
* Gives the various remotes (link tool, unlink tool, squad remote, selection tool) to the player.
--]]
require("control.functions")
function GiveLinkTool(index)

222
control/gui.lua Normal file
View File

@ -0,0 +1,222 @@
--[[ Copyright (c) 2020 npc_strider
* For direct use of code or graphics, credit is appreciated. See LICENSE.txt for more information.
* This mod may contain modified code sourced from base/core Factorio
*
* control/gui.lua
* I fucking hate gui code!
--]]
local mod_gui = require("mod-gui")
local function get_frame_flow_(player, direction)
local gui = player.gui[direction] -- Left in mod-gui implementation (hardcoded.)
local frame_flow = gui.mod_gui_frame_flow
if not frame_flow then
frame_flow = gui.add{type = "flow", name = "mod_gui_frame_flow", direction = "horizontal", style = "mod_gui_spacing_horizontal_flow"}
end
return frame_flow
end -- Adopted from 'mod-gui'
local function getOrigin(s)
for i = 1, #s do
local spider = s[i].spider
if (spider.valid) then
return util.positiontostr(IJSub(spider.position, s[i].delta))
end
end
return "_invalid_" -- This should never occur
end
local function destroyRenameGui(frame_flow)
if (frame_flow["squad-spidertron-list-frame"]) then
return frame_flow["squad-spidertron-list-frame"].destroy()
end
end
local function renameGui(num, frame_flow, index)
local frame = frame_flow.add({
type = "frame",
name = "squad-spidertron-list-frame",
direction = "vertical",
caption = {"gui-map-editor-force-data-editor.edit-modifier-category", {"gui-mod-info.name"}},
style = mod_gui.frame_style
})
local inner = frame.add{type = "frame", name = "inner", style = "inside_deep_frame"}
inner.add({type = "textfield", name = "textfield", text = global.spidercontrol_player_s[index].inactive[num].name})
inner.add({type = "sprite-button", name = "rename-accept-"..num, sprite = "utility/check_mark_white", style = "tool_button_green"})
end
local function guiTable(parent, player)
local table = parent.add({
type = "table",
name = "table",
column_count = 7,
style = "removed_content_table"
})
for i = 2, 7 do
table.style.column_alignments[i] = "center"
end
local t = global.spidercontrol_player_s[player.index].active
table.add({type = "label", caption = {"gui-mod-info.name"}})
table.add({type = "label", caption = {"gui-map-editor-script-editor.current-positions"}})
table.add({type = "label", caption = "ID"})
table.add({type = "label", caption = "#"})
table.add({type = "label", caption = {"gui.save"}})
table.add({type = "empty-widget"})
table.add({type = "label", caption = {"gui-mod-info.delete"}})
table.add({type = "label", caption = "ACTIVE"})
table.add({type = "label", caption = getOrigin(t)})
table.add({type = "label", caption = "ACTIVE"})
table.add({type = "label", caption = #t})
table.add({type = "sprite-button", name = "save-active-to-list", sprite = "utility/reassign", style = "tool_button_green"})
table.add({type = "empty-widget"})
table.add({type = "sprite-button", name = "delete-active", sprite = "utility/trash", style = "tool_button_red"})
-- local frame = game.player.gui.top.add({type = "frame", style = "outer_frame"})
-- local frame = frame.add({type = "frame", caption = "Change active squad", style = "inner_frame_in_outer_frame"})
-- local table = frame.add({type="table", column_count = 3, style = "removed_content_table"})
-- Headers
table.add({type = "label", caption = {"gui-mod-info.name"}})
table.add({type = "label", caption = "Saved Position"})
table.add({type = "label", caption = "ID"})
table.add({type = "label", caption = "#"})
table.add({type = "label", caption = {"gui.load"}})
table.add({type = "label", caption = {"gui-map-editor-force-data-editor.edit-modifier-category", {"gui-mod-info.name"}}})
table.add({type = "label", caption = {"gui-mod-info.delete"}})
local t = global.spidercontrol_player_s[player.index].inactive
for i = 1, #t do
table.add({type = "label", caption = t[i].name})
table.add({type = "label", caption = t[i].position})
table.add({type = "label", caption = i})
table.add({type = "label", caption = #t[i].s})
table.add({type = "sprite-button", name = "make-active-"..i, sprite = "utility/upgrade_blueprint", style = "tool_button_green"})
table.add({type = "sprite-button", name = "rename-inactive-"..i, sprite = "utility/rename_icon_small_white", style = "tool_button_blue"})
table.add({type = "sprite-button", name = "delete-inactive-"..i, sprite = "utility/trash", style = "tool_button_red"})
end
end
local function gui(player)
local frame_flow = mod_gui.get_frame_flow(player)
frame_flow.style.left_padding = 4
frame_flow.style.top_padding = 4
local frame = frame_flow.add({
type = "frame",
name = "squad-spidertron-list-frame",
direction = "vertical",
caption = {"", {"gui.save"}, " ", {"and"}, " ", {"gui.load"}},
style = mod_gui.frame_style
})
local inner = frame.add{type = "frame", name = "inner", style = "inside_deep_frame"}
local scroll = inner.add{type = "scroll-pane", name = "scroll", direction = "vertical"}
guiTable(scroll, player)
end
function UpdateGuiList(player)
local gui_frame = mod_gui.get_frame_flow(player)
if (gui_frame["squad-spidertron-list-frame"]) then
local parent = gui_frame["squad-spidertron-list-frame"].inner.scroll
parent.table.destroy()
guiTable(parent, player)
end
end
function ToggleGuiList(index)
local player = game.players[index]
local gui_frame = mod_gui.get_frame_flow(player)
if (gui_frame["squad-spidertron-list-frame"]) then
gui_frame["squad-spidertron-list-frame"].destroy()
else
gui(player)
end
end
commands.add_command("ssc_gui", "Create gui", function(cmd)
gui(game.players[cmd.player_index])
end)
script.on_event(defines.events.on_gui_click, function(event)
local gui = event.element
local index = event.player_index
local player = game.players[index]
local limit = 20
if not (player and player.valid and gui and gui.valid) then
return
end
local name = gui.name
if (name == "save-active-to-list") then
local s = global.spidercontrol_player_s[index]
if (#s.active > 0) then
if (#s.inactive < limit) then
global.spidercontrol_player_s[index].inactive[#s.inactive+1] = {
name = game.tick,
position = getOrigin(s.active),
s = table.deepcopy(s.active)
}
UpdateGuiList(player)
destroyRenameGui(get_frame_flow_(player, "center"))
else
player.print("You have too many saved templates! Remove some before adding more. Maximum amount is "..limit)
end
end
elseif (name == "delete-active") then
global.spidercontrol_player_s[index].active = {}
local cursor_stack = player.cursor_stack
if (cursor_stack and cursor_stack.valid_for_read and cursor_stack.name == "squad-spidertron-remote") then
player.clear_cursor()
end
UpdateGuiList(player)
else
local num = tonumber(string.match(name, '[0-9]+'))
if num == nil then
return
end
if name == "make-active-"..num then -- string.match(name, 'make[-]active[-][0-9]+') then
destroyRenameGui(get_frame_flow_(player, "center"))
local s = global.spidercontrol_player_s[index].inactive[num].s
local spiders = {}
for i = 1, #s do
spiders[#spiders+1] = s[i].spider
end
SpiderDeSelect(spiders, player.force.index)
global.spidercontrol_player_s[index].active = s
global.spidercontrol_player_s[index].inactive[num].position = getOrigin(global.spidercontrol_player_s[index].inactive[num].s)
UpdateGuiList(player)
elseif name == "delete-inactive-"..num then -- string.match(name, 'delete[-]inactive[-][0-9]+') then
destroyRenameGui(get_frame_flow_(player, "center"))
global.spidercontrol_player_s[index].inactive = Remove(global.spidercontrol_player_s[index].inactive, {num})
UpdateGuiList(player)
elseif name == "rename-inactive-"..num then -- string.match(name, 'rename[-]inactive[-][0-9]+') then
local frame_flow = get_frame_flow_(player, "center")
destroyRenameGui(frame_flow)
UpdateGuiList(player)
renameGui(num, frame_flow, index)
elseif name == "rename-accept-"..num then
local frame_flow = get_frame_flow_(player, "center")
if (frame_flow["squad-spidertron-list-frame"]) then
local str = frame_flow["squad-spidertron-list-frame"].inner.textfield.text
if global.spidercontrol_player_s[index].inactive[num] then
global.spidercontrol_player_s[index].inactive[num].name = str
UpdateGuiList(player)
end
frame_flow["squad-spidertron-list-frame"].destroy()
end
end
end
end)
script.on_event(defines.events.on_gui_text_changed, function(event)
local elem = event.element
if string.match(elem.name, "inactive[-]name[-][0-9]+") then
local num = tonumber(string.match(elem.name, '[0-9]+'))
global.spidercontrol_player_s[event.player_index].inactive[num].name = event.text
end
end)

View File

@ -1,17 +1,35 @@
--[[ Copyright (c) 2020 npc_strider
* For direct use of code or graphics, credit is appreciated. See LICENSE.txt for more information.
* This mod may contain modified code sourced from base/core Factorio
*
* control/init.lua
* Runs when installed/config changes. Incorporate intermod compatibility here.
--]]
local function initialize()
if global.spidercontrol_spidersquad == nil then
game.print("Create tables for spidertron control mod")
function Initialize()
game.print("Create tables for spidertron control mod")
if global.spidercontrol_linked_s == nil then
global.spidercontrol_linked_s = {}
end
if global.spidercontrol_player_s == nil then
global.spidercontrol_player_s = {}
global.spidercontrol_spidertronwaypoints_patrol = {}
for _, player in pairs(game.players) do
global.spidercontrol_player_s[player.index] = {active = {}, inactive = {}} -- Some future-proofing here
end
end
if global.spidercontrol_spidertronwaypoints_patrol == nil then
global.spidercontrol_spidertronwaypoints_patrol = {}
end
SpidertronWaypointsCompatibility()
end
script.on_init(initialize)
script.on_configuration_changed(initialize)
-- commands.add_command("spiderbot_initialize_variables", "debug: ensure that all global tables are not nil (should not happen in a normal game)", initialize)
script.on_init(Initialize)
script.on_configuration_changed(Initialize)
-- commands.add_command("spiderbot_Initialize_variables", "debug: ensure that all global tables are not nil (should not happen in a normal game)", Initialize)
script.on_event(defines.events.on_player_created, function (event)
if global.spidercontrol_player_s == nil then
Initialize()
end
global.spidercontrol_player_s[event.player_index] = {active = {}, inactive = {}}
end)

View File

@ -1,3 +1,10 @@
--[[ Copyright (c) 2020 npc_strider
* For direct use of code or graphics, credit is appreciated. See LICENSE.txt for more information.
* This mod may contain modified code sourced from base/core Factorio
*
* control/player_follow.lua
* Stuff here runs periodically to move the player's active squad to their position in follow mode. Also incorporate some comaptibility with spidertron waypoints.
--]]
local function spidertronWaypointsOverride(s)
if SPIDERTRON_WAYPOINTS then

View File

@ -1,6 +1,14 @@
--[[ Copyright (c) 2020 npc_strider
* For direct use of code or graphics, credit is appreciated. See LICENSE.txt for more information.
* This mod may contain modified code sourced from base/core Factorio
*
* control/player_man_designate.lua
* Stuff happens here when a player calls a squad to a position.
--]]
require("control.functions")
local function moveTo(player, index, position)
local function moveTo(index, position)
game.players[index].set_shortcut_toggled("squad-spidertron-follow", false)
GotoPlayer(index, position)
end
@ -64,6 +72,7 @@ local function link(index, vehicle)
global.spidercontrol_player_s[index].active = {} -- We're taking away player control of this squad!
-- Probably should print the squad ID, the target entity id and other information
GiveStack(player, {name="squad-spidertron-unlink-tool",count=1})
UpdateGuiList(player)
end
vehicle.autopilot_destination = vehicle.position -- Just to look better
end
@ -77,7 +86,7 @@ script.on_event(defines.events.on_player_used_spider_remote, function(event)
if cursor_stack.valid_for_read and event.success then
local cname = cursor_stack.name
if cname == "squad-spidertron-remote" then
moveTo(player, index, event.position)
moveTo(index, event.position)
elseif cname == "spidertron-remote" then -- WARNING: We're only overriding for the player's spidertron if it's the vanilla spidertron remote. Does not cover modded remotes!
local vehicle = event.vehicle
local position = event.position

View File

@ -1,3 +1,10 @@
--[[ Copyright (c) 2020 npc_strider
* For direct use of code or graphics, credit is appreciated. See LICENSE.txt for more information.
* This mod may contain modified code sourced from base/core Factorio
*
* control/player_select.lua
* Handles selection tools for link and squad select.
--]]
require("control.functions")
require("control.2dvec")
@ -40,7 +47,7 @@ local function unitNumbers(entities)
return ids
end
local function spiderDeSelect(spiders, force)
function SpiderDeSelect(spiders, force)
local ids = unitNumbers(spiders)
local t = global.spidercontrol_linked_s
local rem_t = {} --This part is really bad - I think it's O(N^3) worst case?
@ -97,18 +104,17 @@ end
local function spiderSelect(spiders, index)
local player = game.players[index]
local force = player.force.index
local mean = IJMeanEntity(spiders)
global.spidercontrol_player_s[index].active = {}
spiderDeSelect(spiders, force) -- TO prevent double-linking (linking the same spider to 2 or more entities)
SpiderDeSelect(spiders, player.force.index) -- TO prevent double-linking (linking the same spider to 2 or more entities)
if SPIDERTRON_WAYPOINTS then
for i = 1, #spiders do
remote.call("SpidertronWaypoints", "clear_waypoints", spiders[i].unit_number)
spiders[i].autopilot_destination = nil
end
end
-- spiderDeSelectPlayers(spiders, force) -- Y'know what, not sure if i can be arsed to deselect player squads...
-- spiderDeSelectPlayers(spiders, player.force.index) -- Y'know what, not sure if i can be arsed to deselect player squads...
for i=1, #spiders do
table.insert(global.spidercontrol_player_s[index].active, {
@ -130,8 +136,10 @@ local function areaSelection(event)
if #spiders > 0 then
if item == "squad-spidertron-remote-sel" then
spiderSelect(spiders, index)
UpdateGuiList(game.players[index])
elseif item == "squad-spidertron-unlink-tool" then
spiderDeSelect(spiders, spiders[1].force.index)
SpiderDeSelect(spiders, spiders[1].force.index)
UpdateGuiList(game.players[index])
end
end
end

View File

@ -1,2 +1,9 @@
-- Just need to claim this interface name.
--[[ Copyright (c) 2020 npc_strider
* For direct use of code or graphics, credit is appreciated. See LICENSE.txt for more information.
* This mod may contain modified code sourced from base/core Factorio
*
* control/remote.lua
* Just need to claim this interface name.
--]]
remote.add_interface("SpiderControl", {})

View File

@ -2,7 +2,7 @@
"name": "Spider_Control",
"version": "0.5.0",
"factorio_version": "1.1",
"title": "Spidertron squad control",
"title": "Spidertron squad control [BETA RELEASE]",
"author": "npc_strider(morley376)",
"contact": "",
"homepage": "http://steamcommunity.com/id/morley376",

View File

@ -0,0 +1,18 @@
Initialize()
game.print("WARNING: Only player-links are being migrated - Spidertron entity-links are NOT being migrated! (As they were only implemented in the experimental 0.4.0 mod release)")
local player_squads = global.spidercontrol_spidersquad
if player_squads then
for i, t in pairs(player_squads) do
local newsquad = {}
for j, s in pairs(t.spiders) do
newsquad[#newsquad+1] = {
spider = s.spider_entity,
delta = {x=s.d[1],y=s.d[2]}
}
end
global.spidercontrol_player_s[i].active = newsquad
end
end

View File

@ -71,11 +71,10 @@ local shortcut_remote = {
type = "shortcut",
name = "squad-spidertron-remote",
order = "a[squad-spidertron-remote]",
action = "spawn-item",
action = "lua",
localised_name = "Spidertron squad remote",
associated_control_input = "squad-spidertron-remote",
technology_to_unlock = "spidertron",
item_to_spawn = "squad-spidertron-remote-sel",
style = "red",
icon =
{
@ -118,6 +117,13 @@ shortcut_link.localised_name = "Link spidertrons to entity"
shortcut_link.associated_control_input = "squad-spidertron-link-tool"
shortcut_link.style = "green"
local shortcut_list = util.table.deepcopy(shortcut_remote)
shortcut_list.name = "squad-spidertron-list"
shortcut_list.action = "lua"
shortcut_list.localised_name = "Manage saved spidertrons"
shortcut_list.associated_control_input = "squad-spidertron-list"
shortcut_list.style = nil
------------------------------------------------------------------------
-- CUSTOM INPUT
------------------------------------------------------------------------
@ -145,6 +151,11 @@ input_link.name = "squad-spidertron-link-tool"
input_link.localised_name = "Link spidertron squad to entity"
input_link.key_sequence = "ALT + Z"
local input_list = util.table.deepcopy(input_remote)
input_list.name = "squad-spidertron-list"
input_list.localised_name = "Manage saved spidertrons"
input_list.key_sequence = "ALT + V"
------------------------------------------------------------------------
-- EXTEND
------------------------------------------------------------------------
@ -154,6 +165,7 @@ data:extend(
shortcut_remote,
shortcut_follow,
shortcut_link,
shortcut_list,
item_remote_sel,
item_unlink_sel,
@ -196,5 +208,6 @@ data:extend(
input_remote,
input_follow,
input_switch_modes,
input_link
input_link,
input_list
})