spidertron-squad-control/control/functions.lua

243 lines
8.6 KiB
Lua
Raw Normal View History

--[[ 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.
--]]
2020-11-29 13:36:20 +08:00
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
2020-11-29 13:36:20 +08:00
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.
2020-11-29 13:36:20 +08:00
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
2020-11-29 13:36:20 +08:00
if (active_n > #active_updated) then
2020-11-29 13:36:20 +08:00
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
2020-11-29 13:36:20 +08:00
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
2020-11-29 13:36:20 +08:00
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
2020-11-29 13:36:20 +08:00
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
2020-11-29 13:36:20 +08:00
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
2020-11-29 13:36:20 +08:00
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
2020-11-29 13:36:20 +08:00
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
2020-11-29 13:36:20 +08:00
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
2020-11-29 13:36:20 +08:00
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