2020-11-28 22:31:57 +08:00
--[[ 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-28 01:37:34 +08:00
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
2020-11-28 01:37:34 +08:00
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 " )
2020-11-28 01:37:34 +08:00
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
2020-11-28 22:31:57 +08:00
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
2020-11-28 01:37:34 +08:00
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 )
2020-11-28 01:37:34 +08:00
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
2020-11-28 01:37:34 +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 )
2020-11-28 01:37:34 +08:00
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
2020-11-28 01:37:34 +08:00
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 )
2020-11-28 01:37:34 +08:00
end
end
resetSprites ( patrol )
global.spidercontrol_player_s [ index ] . active = { }
2020-11-28 22:31:57 +08:00
UpdateGuiList ( player )
2020-11-28 01:37:34 +08:00
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 )
2020-11-28 01:37:34 +08:00
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 )
2020-11-28 01:37:34 +08:00
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 }
2020-11-28 01:37:34 +08:00
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 .. " ] " }
2020-11-28 01:37:34 +08:00
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 .. " ] " )
2020-11-28 01:37:34 +08:00
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 " )
2020-11-28 01:37:34 +08:00
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