mirror of
https://github.com/peter-tanner/spidertron-squad-control.git
synced 2024-11-30 19:10:18 +08:00
243 lines
8.6 KiB
Lua
243 lines
8.6 KiB
Lua
--[[ 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 AlertPlayer(player, str)
|
|
local enabled = settings.get_player_settings(player)["spidertron-alerts"].value
|
|
if (enabled) then
|
|
player.print(str)
|
|
return true
|
|
else
|
|
return false
|
|
end
|
|
end
|
|
|
|
function SpidertronWaypointsCompatibility()
|
|
-- Compatability for Spidertron Waypoints
|
|
if remote.interfaces["SpidertronWaypoints"] then
|
|
SPIDERTRON_WAYPOINTS = true
|
|
-- local event_ids = remote.call("SpidertronWaypoints", "get_events")
|
|
-- local on_spidertron_given_new_destination = event_ids.on_spidertron_given_new_destination
|
|
-- script.on_event(on_spidertron_given_new_destination, function(event)
|
|
-- game.print("New destination")
|
|
-- Goto(global.spidercontrol_player_s[event.player_index].active, event.position)
|
|
-- end)
|
|
end
|
|
end
|
|
|
|
function GiveStack(player, stack)
|
|
if player.clear_cursor() and player.cursor_stack and player.cursor_stack.can_set_stack(stack) then
|
|
if player.get_main_inventory() then
|
|
local inv = player.get_main_inventory()
|
|
inv.remove("squad-spidertron-remote-sel")
|
|
inv.remove("squad-spidertron-remote")
|
|
end
|
|
player.cursor_stack.set_stack(stack)
|
|
return true
|
|
end
|
|
end
|
|
|
|
function Remove(table, indices)
|
|
local n = #table
|
|
for i = 1, #indices do
|
|
table[indices[i]] = nil
|
|
end
|
|
|
|
local tmp = {}
|
|
for i = 1, n do
|
|
if (table[i] ~= nil) then
|
|
tmp[#tmp+1] = table[i]
|
|
end
|
|
end
|
|
|
|
return tmp
|
|
end
|
|
|
|
function Goto(spiders, center)
|
|
local invalid = {}
|
|
for i = 1, #spiders do
|
|
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)
|
|
end
|
|
|
|
local function drawSprite(surface, target, scale, force, tint)
|
|
return rendering.draw_sprite({
|
|
sprite="item/squad-spidertron-link-tool",
|
|
target = target,
|
|
surface = (target.surface or surface),
|
|
x_scale = scale,
|
|
y_scale = scale,
|
|
only_in_alt_mode = true,
|
|
forces = {force},
|
|
tint = (tint or {r=1,g=1,b=1})
|
|
})
|
|
end
|
|
-- rendering.draw_sprite({sprite="item/squad-spidertron-link-tool", target = game.player.selected, surface = game.player.surface, only_in_alt_mode = true, forces = {game.player.force}, tint = {r=1,g=1,b=1}})
|
|
local function resetSprites(indices)
|
|
if indices then
|
|
for i = 1, #indices do
|
|
rendering.destroy(indices[i])
|
|
end
|
|
end
|
|
end
|
|
-- Original GotoPlayer function before waypoints compat.
|
|
function GotoPlayerUpdate(index, position)
|
|
local active = global.spidercontrol_player_s[index].active
|
|
local active_n = #active
|
|
local active_updated = Goto(active, position)
|
|
global.spidercontrol_player_s[index].active = active_updated
|
|
|
|
if (active_n > #active_updated) then
|
|
local str = "[img=utility/warning_icon] " .. (active_n - #active_updated) .. " units were destroyed or mined"
|
|
AlertPlayer(game.players[index], str)
|
|
end
|
|
end
|
|
|
|
local function GotoPlayerSW(index, position)
|
|
local active = global.spidercontrol_player_s[index].active
|
|
local player = game.players[index]
|
|
local linear = player.is_shortcut_toggled("spidertron-remote-waypoint")
|
|
local cyclic = player.is_shortcut_toggled("spidertron-remote-patrol")
|
|
if (cyclic) then
|
|
if player.is_shortcut_toggled("squad-spidertron-follow") then
|
|
return
|
|
end
|
|
active[1].spider.autopilot_destination = nil
|
|
local patrol = global.spidercontrol_spidertronwaypoints_patrol[index]
|
|
if (patrol) then
|
|
local start = rendering.get_target(patrol[1]).position
|
|
if (util.distance(position, start) < 5) then
|
|
for j = 1, #active do
|
|
if (active[j] and active[j].spider.valid) then
|
|
local waypoints = {}
|
|
for i = 1, #patrol do
|
|
local position = IJAdd(
|
|
rendering.get_target(patrol[i]).position,
|
|
active[j].delta
|
|
)
|
|
waypoints[#waypoints+1] = {position = position}
|
|
end
|
|
|
|
remote.call("SpidertronWaypoints", "assign_patrol", active[j].spider, waypoints)
|
|
end
|
|
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
|
|
else
|
|
patrol[#patrol+1] = drawSprite(player.surface, position, 1.5, player.force, {r=1.0,g=0.0,b=1.0})
|
|
end
|
|
else
|
|
patrol = {drawSprite(player.surface, position, 1.5, player.force, {r=1.0,g=1.0,b=1.0})}
|
|
end
|
|
global.spidercontrol_spidertronwaypoints_patrol[index] = patrol
|
|
elseif (linear) then
|
|
local active_updated = Goto(active, position)
|
|
for i = 1, #active_updated do
|
|
local position = IJAdd(position, active_updated[i].delta)
|
|
local waypoint = {{position = position}}
|
|
remote.call("SpidertronWaypoints", "assign_waypoints", active_updated[i].spider, waypoint)
|
|
end
|
|
|
|
resetSprites(global.spidercontrol_spidertronwaypoints_patrol[index])
|
|
global.spidercontrol_spidertronwaypoints_patrol[index] = nil
|
|
else
|
|
GotoPlayerUpdate(index, position)
|
|
|
|
resetSprites(global.spidercontrol_spidertronwaypoints_patrol[index])
|
|
global.spidercontrol_spidertronwaypoints_patrol[index] = nil
|
|
end
|
|
end
|
|
|
|
function GotoPlayer(index, position)
|
|
if SPIDERTRON_WAYPOINTS then
|
|
GotoPlayerSW(index, position)
|
|
else
|
|
GotoPlayerUpdate(index, position)
|
|
end
|
|
end
|
|
|
|
function GotoEntity(index)
|
|
local t = global.spidercontrol_linked_s[index]
|
|
local entity = t.target
|
|
local active = t.s
|
|
if entity.valid then
|
|
local active_n = #active
|
|
local pos = entity.position
|
|
|
|
local active_updated = Goto(active, pos)
|
|
|
|
global.spidercontrol_linked_s[index].s = active_updated
|
|
|
|
if (active_n > #active_updated) then
|
|
local str = {"", "[img=utility/warning_icon] " .. (active_n - #active_updated) .. " units were destroyed or mined near [gps="..pos.x..","..pos.y.."], linked to ", entity.localised_name}
|
|
game.forces[t.force].print(str)
|
|
end
|
|
|
|
if (#active_updated == 0) then
|
|
local str = {"", "[img=utility/warning_icon] Spidertron squad has been destroyed or unlinked from ", entity.localised_name, " near [gps="..pos.x..","..pos.y.."]"}
|
|
game.forces[t.force].print(str) -- using force comms because this could be the death of a spidertron, not only removal
|
|
end
|
|
else
|
|
local e = false
|
|
for i = 1, #active do
|
|
if (active[i].spider.valid) then
|
|
e = active[i].spider
|
|
end
|
|
end
|
|
if (e) then
|
|
local pos = e.position
|
|
game.forces[t.force].print("[img=utility/warning_icon] Target entity of spidertron squad has been destroyed or removed near [gps="..pos.x..","..pos.y.."]")
|
|
else
|
|
game.forces[t.force].print("[img=utility/warning_icon] Target entity of spidertron squad has been destroyed or removed")
|
|
end
|
|
|
|
global.spidercontrol_linked_s = Remove(global.spidercontrol_linked_s, {index})
|
|
end
|
|
end
|
|
|
|
function FirstValid(entities)
|
|
for i = 1, #entities do
|
|
if entities[i] and entities[i].valid then
|
|
return entities[i]
|
|
end
|
|
end
|
|
return false
|
|
end
|
|
|
|
-- local function squad_center(spidersquad)
|
|
-- local xbar=0
|
|
-- local ybar=0
|
|
-- local c=0
|
|
-- for i=1, #spidersquad do
|
|
-- c=c+1
|
|
-- local pos = spidersquad[i].position
|
|
-- xbar=xbar+pos.x
|
|
-- ybar=ybar+pos.y
|
|
-- end
|
|
-- return {xbar/c,ybar/c}
|
|
-- end
|
|
|
|
function Mean(list)
|
|
local sum = 0
|
|
for i=1, #list do
|
|
sum=sum+list[i]
|
|
end
|
|
return sum/#list
|
|
end |