From f574bccd15a232bf9c83ec2434ea831bb1b8eb93 Mon Sep 17 00:00:00 2001 From: npc-strider Date: Mon, 17 Aug 2020 00:04:50 +0800 Subject: [PATCH] 0.3.0: Add toggle between command/selecting mode, eliminate drifting of squad and fix follow bug --- changelog.txt | 10 ++ control.lua | 217 ++++++++++++++++------------ info.json | 2 +- migrations/Spider_Control_0.3.0.lua | 6 + shortcuts.lua | 8 +- 5 files changed, 148 insertions(+), 95 deletions(-) create mode 100644 migrations/Spider_Control_0.3.0.lua diff --git a/changelog.txt b/changelog.txt index 9e3ac9f..9cb9a01 100644 --- a/changelog.txt +++ b/changelog.txt @@ -15,3 +15,13 @@ Version: 0.2.0 Date: 2020-08-15 Features: - Adds follow mode for your squad to follow you either on foot or in a vehicle + +--------------------------------------------------------------------------------------------------- +Version: 0.3.0 +Date: 2020-08-16 + Features: + - Squads stay aligned, based on original formation when selected + - RMB now switches between commanding and selecting mode + Bugfixes: + - Fixed "wobble" or "dance" when in follow mode while in a spidertron that is in the squad that is being asked to follow + - Fixed squad drifting diff --git a/control.lua b/control.lua index a2a8582..497e03a 100644 --- a/control.lua +++ b/control.lua @@ -6,34 +6,14 @@ * Spiderbot. --]] -local function spiderbot_select(event) - local index = event.player_index - local spiders = event.entities - if event.item == "squad-spidertron-remote-sel" and #spiders > 0 then - global.spidercontrol_spidersquad[index] = spiders - local player = game.players[index] - local stack = { - name="squad-spidertron-remote", - count=1 - } - -- game.print(spiders[1]) - if player.cursor_stack.can_set_stack(stack) then - player.cursor_stack.set_stack(stack) - player.cursor_stack.connected_entity=spiders[1] +local function give_tool(player, stack) + if player.clean_cursor() and player.cursor_stack.can_set_stack(stack) then + if player.get_main_inventory() then + player.get_main_inventory().remove("squad-spidertron-remote-sel") + player.get_main_inventory().remove("squad-spidertron-remote") end - end -end - -local function validate_spiders(index) - local c=0 - for i, spider in pairs(global.spidercontrol_spidersquad[index]) do - if not spider.valid then - global.spidercontrol_spidersquad[index][i] = nil - c=c+1 - end - end - if c > 0 then - game.players[index].print(c .. " units were destroyed since the last position command was sent") + player.cursor_stack.set_stack(stack) + return true end end @@ -43,26 +23,57 @@ local function squad_center(spidersquad) local c=0 for _, spider in pairs(spidersquad) do c=c+1 - xbar=xbar+spider.position.x - ybar=ybar+spider.position.y + local pos = spider.position + xbar=xbar+pos.x + ybar=ybar+pos.y end - xbar=xbar/c - ybar=ybar/c - return {xbar,ybar} + return {xbar/c,ybar/c} end -local function spiderbot_designate(index, position_) - validate_spiders(index) - local spidersquad = global.spidercontrol_spidersquad[index] +local function spiderbot_select(event) + local index = event.player_index + local spiders = event.entities + if event.item == "squad-spidertron-remote-sel" and #spiders > 0 then + local center = squad_center(spiders) + global.spidercontrol_spidersquad[index] = {spiders={}} -- some future proofing here + for _, spider in pairs(spiders) do + local pos = spider.position + table.insert(global.spidercontrol_spidersquad[index].spiders, { + spider_entity=spider, + d={pos.x-center[1],pos.y-center[2]} -- dx and dy + }) + end + local player = game.players[index] + if give_tool(player, {name="squad-spidertron-remote",count=1}) then + player.cursor_stack.connected_entity=spiders[1] + end + end +end - local posbar = squad_center(spidersquad) +local function validate_spiders(index) + local c=0 + if global.spidercontrol_spidersquad[index] then + for i, spider_ in pairs(global.spidercontrol_spidersquad[index].spiders) do + if not spider_.spider_entity.valid then + global.spidercontrol_spidersquad[index].spiders[i] = nil + c=c+1 + end + end + if c > 0 then + game.players[index].print(c .. " units were destroyed or mined since the last position command was sent") + end + return true + end +end - local dx=position_.x-posbar[1] - local dy=position_.y-posbar[2] - - for _, spider in pairs(spidersquad) do - local position = spider.position - spider.autopilot_destination = {position.x+dx, position.y+dy} +local function spiderbot_designate(index, position) + if validate_spiders(index) then + local spidersquad = global.spidercontrol_spidersquad[index].spiders + for _, spider_ in pairs(spidersquad) do + local spider = spider_.spider_entity + local d = spider_.d + spider.autopilot_destination = {position.x+d[1], position.y+d[2]} + end end end @@ -106,72 +117,92 @@ script.on_event(defines.events.on_lua_shortcut, function (event) end end) -script.on_event("squad-spidertron-remote", function(event) - local player = game.players[event.player_index] - local stack = {name="squad-spidertron-remote-sel",count=1} - if player.clean_cursor() and player.cursor_stack.can_set_stack(stack) then - if player.get_main_inventory() then - player.get_main_inventory().remove("squad-spidertron-remote-sel") - player.get_main_inventory().remove("squad-spidertron-remote") - end +script.on_event(defines.events.on_player_created, function (event) + global.spidercontrol_spidersquad[event.player_index] = {} +end) - player.cursor_stack.set_stack(stack) - end +script.on_event("squad-spidertron-remote", function(event) + give_tool(game.players[event.player_index], {name="squad-spidertron-remote-sel",count=1}) end) script.on_event("squad-spidertron-follow", function(event) spiderbot_follow(game.players[event.player_index]) end) +script.on_event("squad-spidertron-switch-modes", function(event) + local player = game.players[event.player_index] + local cursor_stack = player.cursor_stack + if cursor_stack.valid_for_read then + if cursor_stack.name == "squad-spidertron-remote" then + give_tool(player, {name="squad-spidertron-remote-sel",count=1}) + elseif cursor_stack.name == "squad-spidertron-remote-sel" then + local e = global.spidercontrol_spidersquad[event.player_index] + if e.spiders and e.spiders[1].spider_entity.valid and give_tool(player, {name="squad-spidertron-remote",count=1}) then + player.cursor_stack.connected_entity=e.spiders[1].spider_entity + end + end + end +end) + + local mov_offset = settings.global["spidertron-follow-prediction-distance"].value --This is so the player stays within the spider squad when moving local mov_offset_diagonal = math.sqrt(mov_offset^2/2) +local function pos_offset(position,dir) + local def_dir = defines.direction + local pos_x = position.x + local pos_y = position.y + + if dir == def_dir.north then + pos_y = pos_y - mov_offset + elseif dir == def_dir.northeast then + -- game.print("ne") + pos_x = pos_x + mov_offset_diagonal + pos_y = pos_y - mov_offset_diagonal + elseif dir == def_dir.east then + -- game.print("e") + pos_x = pos_x + mov_offset + elseif dir == def_dir.southeast then + -- game.print("se") + pos_x = pos_x + mov_offset_diagonal + pos_y = pos_y + mov_offset_diagonal + elseif dir == def_dir.south then + -- game.print("s") + pos_y = pos_y + mov_offset + elseif dir == def_dir.southwest then + -- game.print("sw") + pos_x = pos_x - mov_offset_diagonal + pos_y = pos_y + mov_offset_diagonal + elseif dir == def_dir.west then + -- game.print("w") + pos_x = pos_x - mov_offset + else -- northwest + -- game.print("nw") + pos_x = pos_x - mov_offset_diagonal + pos_y = pos_y - mov_offset_diagonal + end + + return {x=pos_x, y=pos_y} +end + local update_interval = settings.global["spidertron-follow-update-interval"].value -script.on_nth_tick(update_interval, function (event) +script.on_nth_tick(update_interval, function(event) for _, player in pairs(game.players) do - if player.is_shortcut_toggled("squad-spidertron-follow") and global.spidercontrol_spidersquad[player.index] then + if player.is_shortcut_toggled("squad-spidertron-follow") then local index = player.index - local pos = player.position - local pos_x = pos.x - local pos_y = pos.y - if player.walking_state.walking then - local dir = player.walking_state.direction - local def_dir = defines.direction - if dir == def_dir.north then - pos_y = pos_y - mov_offset - elseif dir == def_dir.northeast then - -- game.print("ne") - pos_x = pos_x + mov_offset_diagonal - pos_y = pos_y - mov_offset_diagonal - elseif dir == def_dir.east then - -- game.print("e") - pos_x = pos_x + mov_offset - elseif dir == def_dir.southeast then - -- game.print("se") - pos_x = pos_x + mov_offset_diagonal - pos_y = pos_y + mov_offset_diagonal - elseif dir == def_dir.south then - -- game.print("s") - pos_y = pos_y + mov_offset - elseif dir == def_dir.southwest then - -- game.print("sw") - pos_x = pos_x - mov_offset_diagonal - pos_y = pos_y + mov_offset_diagonal - elseif dir == def_dir.west then - -- game.print("w") - pos_x = pos_x - mov_offset - else -- northwest - -- game.print("nw") - pos_x = pos_x - mov_offset_diagonal - pos_y = pos_y - mov_offset_diagonal + if global.spidercontrol_spidersquad[index].spiders[1] then + local pos = player.position + if player.walking_state.walking then + local dir = player.walking_state.direction + pos = pos_offset(pos,dir) end - end - spiderbot_designate(index, {x=pos_x, y=pos_y}) - if player.vehicle then - local vehicle = player.vehicle - if vehicle.type == "spider-vehicle" then - vehicle.autopilot_destination = squad_center(global.spidercontrol_spidersquad[index]) + spiderbot_designate(index, pos) + if player.vehicle then + local vehicle = player.vehicle + if vehicle.type == "spider-vehicle" then + vehicle.autopilot_destination = pos + end end end end diff --git a/info.json b/info.json index 551d9b5..26ae2bb 100644 --- a/info.json +++ b/info.json @@ -1,6 +1,6 @@ { "name": "Spider_Control", - "version": "0.2.0", + "version": "0.3.0", "factorio_version": "1.0", "title": "Spidertron squad control", "author": "npc_strider(morley376)", diff --git a/migrations/Spider_Control_0.3.0.lua b/migrations/Spider_Control_0.3.0.lua new file mode 100644 index 0000000..df5cb21 --- /dev/null +++ b/migrations/Spider_Control_0.3.0.lua @@ -0,0 +1,6 @@ +if global.spidercontrol_spidersquad ~= nil then + for i,_ in pairs(global.spidercontrol_spidersquad) do + global.spidercontrol_spidersquad[i] = {spiders={}} + end + game.print("Spider control 0.3.0 migration: Reset squads") +end \ No newline at end of file diff --git a/shortcuts.lua b/shortcuts.lua index 2a05541..2ccc4b2 100644 --- a/shortcuts.lua +++ b/shortcuts.lua @@ -65,6 +65,11 @@ input_follow.name = "squad-spidertron-follow" input_follow.localised_name = "Follow player" input_follow.key_sequence = "ALT + C" +local input_switch_modes = util.table.deepcopy(input_remote) +input_switch_modes.name = "squad-spidertron-switch-modes" +input_switch_modes.localised_name = "Switch modes (between selecting and commanding)" +input_switch_modes.key_sequence = "mouse-button-2" + data:extend( { shortcut_remote, @@ -111,5 +116,6 @@ data:extend( }, input_remote, - input_follow + input_follow, + input_switch_modes })