2021-03-24 20:14:55 +01:00
--luacheck: ignore
2020-03-26 04:41:16 +01:00
local event = require 'utils.event'
local math_random = math.random
local math_floor = math.floor
global.biter_command = {}
global.biter_command . active_unit_groups = {}
2020-04-08 20:28:02 +02:00
global.biter_command . enabled = true
global.biter_command . whitelist = {}
2020-03-26 04:41:16 +01:00
global.biter_command . admin_mode = true --if only admins can see and use the panel
2020-07-27 11:07:32 +02:00
2020-03-26 04:41:16 +01:00
global.biter_command . teleporting = false --if teleporting is allowed for non-admins
2020-04-30 15:36:56 +02:00
global.biter_command . buildings = true ---if player can trigger building nests and worms
2020-03-26 04:41:16 +01:00
local worm_raffle = {
2021-03-24 16:46:00 +01:00
'small-worm-turret' ,
'small-worm-turret' ,
'medium-worm-turret' ,
'small-worm-turret' ,
'medium-worm-turret' ,
'medium-worm-turret' ,
'big-worm-turret' ,
'medium-worm-turret' ,
'big-worm-turret' ,
'big-worm-turret' ,
'behemoth-worm-turret' ,
'big-worm-turret' ,
'behemoth-worm-turret' ,
'behemoth-worm-turret' ,
'behemoth-worm-turret' ,
'big-worm-turret' ,
'behemoth-worm-turret'
2020-03-26 04:41:16 +01:00
}
local function shuffle ( tbl )
2021-03-24 16:46:00 +01:00
local size = # tbl
for i = size , 1 , - 1 do
local rand = math_random ( size )
tbl [ i ], tbl [ rand ] = tbl [ rand ], tbl [ i ]
end
return tbl
2020-03-26 04:41:16 +01:00
end
local function is_closer ( pos1 , pos2 , pos )
2021-03-24 16:46:00 +01:00
return (( pos1.x - pos.x ) ^ 2 + ( pos1.y - pos.y ) ^ 2 ) < (( pos2.x - pos.x ) ^ 2 + ( pos2.y - pos.y ) ^ 2 )
2020-03-26 04:41:16 +01:00
end
local function shuffle_distance ( tbl , position )
2021-03-24 16:46:00 +01:00
local size = # tbl
for i = size , 1 , - 1 do
local rand = math_random ( size )
if is_closer ( tbl [ i ]. position , tbl [ rand ]. position , position ) and i > rand then
tbl [ i ], tbl [ rand ] = tbl [ rand ], tbl [ i ]
end
end
return tbl
2020-03-26 04:41:16 +01:00
end
local function get_evo ( force )
2021-03-24 16:46:00 +01:00
local evo = math_floor ( game.forces [ 'enemy' ]. evolution_factor * 20 )
local nests = math_random ( 1 + evo , 2 + evo * 2 )
2020-03-26 04:41:16 +01:00
end
local function place_nest_near_unit_group ( group )
2021-03-24 16:46:00 +01:00
if not global.biter_command . buildings then
return false
end
if not group.members then
return false
end
if # group.members < 5 then
return false
end
local units = group.members
shuffle ( units )
for i = 1 , 5 , 1 do
if not units [ i ]. valid then
return false
end
end
local name = 'biter-spawner'
if math_random ( 1 , 3 ) == 1 then
name = 'spitter-spawner'
end
local position = group.surface . find_non_colliding_position ( name , group.position , 16 , 1 )
if not position then
return false
end
group.surface . create_entity ({ name = name , position = position , force = group.force })
group.surface . create_entity ({ name = 'blood-explosion-huge' , position = position })
for i = 1 , 5 , 1 do
units [ i ]. surface.create_entity ({ name = 'blood-explosion-huge' , position = units [ i ]. position })
units [ i ]. destroy ()
end
return true
2020-03-26 04:41:16 +01:00
end
local function build_worm ( group )
2021-03-24 16:46:00 +01:00
if not global.biter_command . buildings then
return false
end
if not group.members then
return false
end
if # group.members < 5 then
return false
end
local units = group.members
shuffle ( units )
for i = 1 , 5 , 1 do
if not units [ i ]. valid then
return false
end
end
local position = group.surface . find_non_colliding_position ( 'assembling-machine-1' , group.position , 8 , 1 )
local worm = worm_raffle [ math_random ( 1 + math_floor ( group.force . evolution_factor * 8 ), math_floor ( 1 + group.force . evolution_factor * 16 ))]
if not position then
return false
end
group.surface . create_entity ({ name = worm , position = position , force = group.force })
group.surface . create_entity ({ name = 'blood-explosion-huge' , position = position })
for i = 1 , 5 , 1 do
units [ i ]. surface.create_entity ({ name = 'blood-explosion-huge' , position = units [ i ]. position })
units [ i ]. destroy ()
end
return true
2020-03-26 04:41:16 +01:00
end
local function flying_text ( message , action , position , player )
2021-03-24 16:46:00 +01:00
local texts = {
{ 'roger' , 'acknowledged' , 'aye aye' , 'confirmed' , 'will do' },
{ 'negative' , 'no' , 'not really' , 'we are not your critters' , 'go away' },
{ 'fooood' , 'nom nom' , 'we hunger' , 'killllll' },
{ 'WTF' , 'we wanted ACTION' , 'why you hate us' , 'we were good soldiers' , 'go to hell' }
}
colors = {{ r = 0 , g = 220 , b = 0 }, { r = 220 , g = 0 , b = 0 }, { r = 0 , g = 100 , b = 220 }, { r = 200 , g = 200 , b = 0 }, { r = 255 , g = 255 , b = 255 }}
if message then
player.create_local_flying_text { text = message , position = position , color = colors [ 5 ]}
else
player.create_local_flying_text { text = texts [ action ][ math_random ( 1 , # texts [ action ])], position = position , color = colors [ action ]}
end
2020-03-26 04:41:16 +01:00
end
-----------commands-----------
local function move_to ( position , distraction )
2021-03-24 16:46:00 +01:00
local command = {
type = defines.command . go_to_location ,
destination = position ,
distraction = distraction ,
pathfind_flags = { allow_destroy_friendly_entities = true }
}
return command
2020-03-26 04:41:16 +01:00
end
-- local function attackmaincommand(target)
-- local wave_defense_table = WD.get_table()
-- if not wave_defense_table.target then return end
-- if not wave_defense_table.target.valid then return end
-- local command = {
-- type = defines.command.attack,
-- target = target,
-- distraction = defines.distraction.by_enemy,
-- }
-- return command
-- end
local function attackareacommand ( position )
2021-03-24 16:46:00 +01:00
local command = {
type = defines.command . attack_area ,
destination = position ,
radius = 25 ,
distraction = defines.distraction . by_enemy
}
return command
2020-03-26 04:41:16 +01:00
end
local function attackobstaclescommand ( surface , position )
2021-03-24 16:46:00 +01:00
local commands = {}
local obstacles = surface.find_entities_filtered { position = position , radius = 20 , type = { 'simple-entity' , 'tree' }, limit = 100 }
if obstacles then
shuffle ( obstacles )
shuffle_distance ( obstacles , position )
for i = 1 , # obstacles , 1 do
if obstacles [ i ]. valid then
commands [ # commands + 1 ] = {
type = defines.command . attack ,
target = obstacles [ i ],
distraction = defines.distraction . by_enemy
}
end
end
2020-03-26 04:41:16 +01:00
end
2021-03-24 16:46:00 +01:00
return commands
2020-03-26 04:41:16 +01:00
end
local function get_coords ( group , source_player )
2021-03-24 16:46:00 +01:00
local position
if source_player.gui . screen [ 'biter_panel' ] then
local x = tonumber ( source_player.gui . screen [ 'biter_panel' ][ 'coords' ][ 'coord_x' ]. text )
local y = tonumber ( source_player.gui . screen [ 'biter_panel' ][ 'coords' ][ 'coord_y' ]. text )
if x == nil or x == 'nil' then
x = group.position . x
source_player.gui . screen [ 'biter_panel' ][ 'coords' ][ 'coord_x' ]. text = group.position . x
end
if y == nil or y == 'nil' then
y = group.position . y
source_player.gui . screen [ 'biter_panel' ][ 'coords' ][ 'coord_y' ]. text = group.position . y
end
position = { x = x , y = y }
2020-03-26 04:41:16 +01:00
end
2021-03-24 16:46:00 +01:00
return position
2020-03-26 04:41:16 +01:00
end
-------button functions-------------
local function pan ( group , source_player )
2021-03-24 16:46:00 +01:00
source_player.open_map ( group.position , 0.5 )
2020-03-26 04:41:16 +01:00
end
local function teleport ( group , source_player )
2021-03-24 16:46:00 +01:00
if source_player.admin or global.biter_command . teleporting then
source_player.teleport ( group.position , group.surface )
else
flying_text ( 'Teleporting is disabled' , nil , source_player.position , source_player )
end
2020-03-26 04:41:16 +01:00
end
local function disband ( group , source_player )
2021-03-24 16:46:00 +01:00
flying_text ( nil , 4 , group.position , source_player )
group.destroy ()
2020-03-26 04:41:16 +01:00
end
local function movetome ( group , source_player )
2021-03-24 16:46:00 +01:00
group.set_command ( move_to ( source_player.position , defines.distraction . none ))
flying_text ( nil , 1 , group.position , source_player )
2020-03-26 04:41:16 +01:00
end
local function movetoposition ( group , source_player )
2021-03-24 16:46:00 +01:00
local position = get_coords ( group , source_player )
if position then
group.set_command ( move_to ( position , defines.distraction . none ))
flying_text ( nil , 1 , group.position , source_player )
else
flying_text ( nil , 2 , group.position , source_player )
end
2020-03-26 04:41:16 +01:00
end
local function patroltome ( group , source_player )
2021-03-24 16:46:00 +01:00
group.set_command ( move_to ( source_player.position , defines.distraction . by_enemy ))
flying_text ( nil , 1 , group.position , source_player )
2020-03-26 04:41:16 +01:00
end
local function patroltoposition ( group , source_player )
2021-03-24 16:46:00 +01:00
local position = get_coords ( group , source_player )
if position then
group.set_command ( move_to ( position , defines.distraction . by_enemy ))
flying_text ( nil , 1 , group.position , source_player )
else
flying_text ( nil , 2 , group.position , source_player )
end
2020-03-26 04:41:16 +01:00
end
local function settle ( group , source_player )
2021-03-24 16:46:00 +01:00
local success = place_nest_near_unit_group ( group )
if success then
flying_text ( nil , 1 , group.position , source_player )
else
flying_text ( nil , 2 , group.position , source_player )
source_player.print ( 'Settling new nest failed. Check if group has enough members(5+) and there is empty space (or nests are disabled).' )
end
2020-03-26 04:41:16 +01:00
end
local function siege ( group , source_player )
2021-03-24 16:46:00 +01:00
local success = build_worm ( group )
if success then
flying_text ( nil , 1 , group.position , source_player )
else
flying_text ( nil , 2 , group.position , source_player )
source_player.print ( 'Making worm failed. Check if group has enough members(5+) and there is empty space (or worms are disabled).' )
end
2020-03-26 04:41:16 +01:00
end
local function report ( group , source_player )
2021-03-24 16:46:00 +01:00
local status = group.state
local states = { 'gathering' , 'moving' , 'attacking distraction' , 'attacking target' , 'finished' , 'pathfinding' , 'wander in group' }
flying_text ( states [ status + 1 ], nil , group.position , source_player )
2020-03-26 04:41:16 +01:00
end
local function attackenemiesaround ( group , source_player )
2021-03-24 16:46:00 +01:00
flying_text ( nil , 3 , group.position , source_player )
group.set_command ( attackareacommand ( group.position ))
2020-03-26 04:41:16 +01:00
end
local function attackobstaclesaround ( group , source_player )
2021-03-24 16:46:00 +01:00
local commands = attackobstaclescommand ( group.surface , group.position )
if # commands > 1 then
group.set_command (
{
type = defines.command . compound ,
structure_type = defines.compound_command . return_last ,
commands = commands
}
)
flying_text ( nil , 3 , group.position , source_player )
else
source_player.print ( 'No obstacles found around unit group.' )
flying_text ( nil , 2 , group.position , source_player )
end
2020-03-26 04:41:16 +01:00
end
local function attackenemiesaroundme ( group , source_player )
2021-03-24 16:46:00 +01:00
group.set_command ( attackareacommand ( source_player.position ))
flying_text ( nil , 3 , group.position , source_player )
2020-03-26 04:41:16 +01:00
end
local function attackobstaclesaroundme ( group , source_player )
2021-03-24 16:46:00 +01:00
local commands = attackobstaclescommand ( source_player.surface , source_player.position )
if # commands > 1 then
group.set_command (
{
type = defines.command . compound ,
structure_type = defines.compound_command . return_last ,
commands = commands
}
)
flying_text ( nil , 3 , group.position , source_player )
else
source_player.print ( 'No obstacles found around player.' )
flying_text ( nil , 2 , group.position , source_player )
end
2020-03-26 04:41:16 +01:00
end
local function addunitsaroundme ( group , source_player )
2021-03-24 16:46:00 +01:00
local units = source_player.surface . find_entities_filtered { position = source_player.position , radius = 50 , type = 'unit' , force = group.force }
for i = 1 , # units , 1 do
group.add_member ( units [ i ])
end
2020-03-26 04:41:16 +01:00
end
local function addunits ( group , source_player )
2021-03-24 16:46:00 +01:00
local units = source_player.surface . find_entities_filtered { position = group.position , radius = 50 , type = 'unit' , force = group.force }
for i = 1 , # units , 1 do
group.add_member ( units [ i ])
end
2020-03-26 04:41:16 +01:00
end
local function forcemove ( group , source_player )
2021-03-24 16:46:00 +01:00
group.start_moving ()
flying_text ( nil , 1 , group.position , source_player )
2020-03-26 04:41:16 +01:00
end
local function creategroup ( source_player )
2021-03-24 16:46:00 +01:00
source_player.surface . create_unit_group { position = source_player.position , force = source_player.force }
flying_text ( 'Unit group created' , nil , source_player.position , source_player )
2020-03-26 04:41:16 +01:00
end
----------------------direction panel-----------------
local function set_directions ( changedx , changedy , source_player )
2021-03-24 16:46:00 +01:00
if source_player.gui . screen [ 'biter_panel' ] then
local x = tonumber ( source_player.gui . screen [ 'biter_panel' ][ 'coords' ][ 'coord_x' ]. text )
local y = tonumber ( source_player.gui . screen [ 'biter_panel' ][ 'coords' ][ 'coord_y' ]. text )
if x == nil or x == 'nil' then
x = 0
end
if y == nil or y == 'nil' then
y = 0
end
x = x + changedx
y = y + changedy
source_player.gui . screen [ 'biter_panel' ][ 'coords' ][ 'coord_x' ]. text = x
source_player.gui . screen [ 'biter_panel' ][ 'coords' ][ 'coord_y' ]. text = y
end
2020-03-26 04:41:16 +01:00
end
local function nw ( source_player )
2021-03-24 16:46:00 +01:00
set_directions ( - 25 , - 25 , source_player )
2020-03-26 04:41:16 +01:00
end
local function n ( source_player )
2021-03-24 16:46:00 +01:00
set_directions ( 0 , - 25 , source_player )
2020-03-26 04:41:16 +01:00
end
local function ne ( source_player )
2021-03-24 16:46:00 +01:00
set_directions ( 25 , - 25 , source_player )
2020-03-26 04:41:16 +01:00
end
local function w ( source_player )
2021-03-24 16:46:00 +01:00
set_directions ( - 25 , 0 , source_player )
2020-03-26 04:41:16 +01:00
end
local function e ( source_player )
2021-03-24 16:46:00 +01:00
set_directions ( 25 , 0 , source_player )
2020-03-26 04:41:16 +01:00
end
local function sw ( source_player )
2021-03-24 16:46:00 +01:00
set_directions ( - 25 , 25 , source_player )
2020-03-26 04:41:16 +01:00
end
local function s ( source_player )
2021-03-24 16:46:00 +01:00
set_directions ( 0 , 25 , source_player )
2020-03-26 04:41:16 +01:00
end
local function se ( source_player )
2021-03-24 16:46:00 +01:00
set_directions ( 25 , 25 , source_player )
2020-03-26 04:41:16 +01:00
end
local function center ( group , source_player )
2021-03-24 16:46:00 +01:00
if source_player.gui . screen [ 'biter_panel' ] then
source_player.gui . screen [ 'biter_panel' ][ 'coords' ][ 'coord_x' ]. text = group.position . x
source_player.gui . screen [ 'biter_panel' ][ 'coords' ][ 'coord_y' ]. text = group.position . y
end
2020-03-26 04:41:16 +01:00
end
----------------------------gui-----------------------
local function top_button ( player )
2021-03-24 16:46:00 +01:00
if player.gui . top [ 'biter_commands' ] then
if global.biter_command . enabled or global.biter_command . whitelist [ player.name ] == true then
player.gui . top [ 'biter_commands' ]. visible = true
return
else
--player.gui.top["biter_commands"].destroy()
player.gui . top [ 'biter_commands' ]. visible = false
return
end
2020-04-08 20:28:02 +02:00
end
2021-03-24 16:46:00 +01:00
if player.admin or not global.biter_command . admin_mode then
if global.biter_command . enabled or global.biter_command . whitelist [ player.name ] == true then
local button = player.gui . top.add ({ type = 'sprite-button' , name = 'biter_commands' , sprite = 'entity/medium-spitter' })
button.style . minimal_height = 38
button.style . minimal_width = 38
button.style . padding = - 2
end
2020-04-08 20:28:02 +02:00
end
2020-03-26 04:41:16 +01:00
end
local function show_info ( player )
2021-03-24 16:46:00 +01:00
if player.gui . screen [ 'biter_comm_info' ] then
player.gui . screen [ 'biter_comm_info' ]. destroy ()
return
end
local frame = player.gui . screen.add { type = 'frame' , name = 'biter_comm_info' , caption = 'Biter Commander needs halp' , direction = 'vertical' }
frame.location = { x = 350 , y = 45 }
frame.style . minimal_height = 300
frame.style . maximal_height = 300
frame.style . minimal_width = 330
frame.style . maximal_width = 630
frame.add ({ type = 'label' , caption = 'Create new group first, then add biters to it.' })
frame.add ({ type = 'label' , caption = 'You can use directionpad to navigate them, or do it in person.' })
frame.add ({ type = 'label' , caption = "If you input invalid coordinates, they get rewritten to current group's position." })
frame.add ({ type = 'label' , caption = 'You can operate only biters and create groups of your own force.' })
frame.add ({ type = 'label' , caption = "If group is stuck at gathering state, use 'force move' button." })
frame.add ({ type = 'label' , caption = 'Empty groups get autodeleted by game after a while.' })
frame.add ({ type = 'button' , name = 'close_info' , caption = 'Close' })
2020-03-26 04:41:16 +01:00
end
local function build_groups ( player )
2021-03-24 16:46:00 +01:00
local groups = {}
for _ , g in pairs ( global.biter_command . active_unit_groups ) do
if g.group . valid then
if player.admin and global.biter_command . admin_mode then
table.insert ( groups , tostring ( g.id ))
else
if player.force == g.group . force then
table.insert ( groups , tostring ( g.id ))
end
end
else
g = nil
2020-03-26 04:41:16 +01:00
end
2020-04-17 23:01:34 +02:00
end
2021-03-24 16:46:00 +01:00
table.insert ( groups , 'Select Group' )
return groups
2020-03-26 04:41:16 +01:00
end
local function biter_panel ( player )
2021-03-24 16:46:00 +01:00
if player.gui . screen [ 'biter_panel' ] then
player.gui . screen [ 'biter_panel' ]. destroy ()
return
end
2020-03-26 04:41:16 +01:00
2021-03-24 16:46:00 +01:00
local frame = player.gui . screen.add { type = 'frame' , caption = 'Biter Commander' , name = 'biter_panel' , direction = 'vertical' }
frame.location = { x = 5 , y = 45 }
frame.style . minimal_height = 680
frame.style . maximal_height = 680
frame.style . minimal_width = 330
frame.style . maximal_width = 330
2020-03-26 04:41:16 +01:00
2021-03-24 16:46:00 +01:00
local groups = build_groups ( player )
local selected_index = # groups
if global.panel_group_index then
if global.panel_group_index [ player.name ] then
if groups [ global.panel_group_index [ player.name ]] then
selected_index = global.paneld_group_index [ player.name ]
end
end
end
local t0 = frame.add ({ type = 'table' , name = 'top' , column_count = 3 })
local drop_down = t0.add ({ type = 'drop-down' , name = 'group_select' , items = groups , selected_index = selected_index })
drop_down.style . minimal_width = 150
drop_down.style . right_padding = 12
drop_down.style . left_padding = 12
t0.add ({ type = 'sprite-button' , name = 'info' , sprite = 'virtual-signal/signal-info' })
t0.add ({ type = 'sprite-button' , name = 'close_biters' , sprite = 'virtual-signal/signal-X' })
2020-03-26 04:41:16 +01:00
2021-03-24 16:46:00 +01:00
local l1 = frame.add ({ type = 'label' , caption = 'Camera' })
local t1 = frame.add ({ type = 'table' , name = 'camera' , column_count = 2 })
local l2 = frame.add ({ type = 'label' , caption = 'Movement' })
local t2 = frame.add ({ type = 'table' , name = 'movement' , column_count = 2 })
local l3 = frame.add ({ type = 'label' , caption = 'Build' })
local t3 = frame.add ({ type = 'table' , name = 'build' , column_count = 2 })
local l4 = frame.add ({ type = 'label' , caption = 'Attack' })
local t4 = frame.add ({ type = 'table' , name = 'attack' , column_count = 2 })
local l5 = frame.add ({ type = 'label' , caption = 'Group Management' })
local t5 = frame.add ({ type = 'table' , name = 'management' , column_count = 2 })
local line = frame.add { type = 'line' }
line.style . top_margin = 8
line.style . bottom_margin = 8
local t6 = frame.add ({ type = 'table' , name = 'directions' , column_count = 3 })
local buttons = {
t1.add ({ type = 'button' , caption = 'Pan to group' , name = 'pan' , tooltip = 'Moves camera to group position.' }),
t1.add ({ type = 'button' , caption = 'TP to group' , name = 'teleport' , tooltip = 'Teleports to group.' }),
t2.add ({ type = 'button' , caption = 'Move to me' , name = 'movetome' , tooltip = 'Gives group order to move to your position.' }),
t2.add ({ type = 'button' , caption = 'Move to position' , name = 'movetoposition' , tooltip = 'Sends group to position with coordinates entered below.' }),
t2.add ({ type = 'button' , caption = 'Patrol to me ' , name = 'patroltome' , tooltip = 'Gives group order to move to your position and engage any enemy during movement.' }),
t2.add (
{
type = 'button' ,
caption = 'Patrol to position' ,
name = 'patroltoposition' ,
tooltip = 'Sends group to position with coordinates entered below and engage any enemy during movement.'
}
),
t3.add ({ type = 'button' , caption = 'Settle nest' , name = 'settle' , tooltip = 'Group creates base. Costs 5 units.' }),
t3.add ({ type = 'button' , caption = 'Build worm' , name = 'siege' , tooltip = 'Group builds worm turret. Costs 5 units.' }),
t4.add ({ type = 'button' , caption = 'Attack area' , name = 'attackenemiesaround' , tooltip = 'Group attacks enemy things around self.' }),
t4.add ({ type = 'button' , caption = 'Attack obstacles' , name = 'attackobstaclesaround' , tooltip = 'Group attacks obstacles around self.' }),
t4.add ({ type = 'button' , caption = 'Attack my area' , name = 'attackenemiesaroundme' , tooltip = 'Group attacks enemy things around your position.' }),
t4.add ({ type = 'button' , caption = 'Attack my obstacles' , name = 'attackobstaclesaroundme' , tooltip = 'Group attacks obstacles around your position.' }),
t5.add ({ type = 'button' , caption = 'Report' , name = 'report' , tooltip = 'Reports group status.' }),
t5.add ({ type = 'button' , caption = 'Force Move' , name = 'forcemove' , tooltip = 'Makes group to start moving even if gathering is not done (unstuck).' }),
t5.add ({ type = 'button' , caption = 'Add units around me' , name = 'addunitsaroundme' , tooltip = 'Adds units around you to selected unit group.' }),
t5.add ({ type = 'button' , caption = 'Add units' , name = 'addunits' , tooltip = 'Adds units around group to it.' }),
t5.add ({ type = 'button' , caption = 'Create group' , name = 'creategroup' , tooltip = 'Creates new group on player position' }),
t5.add ({ type = 'button' , caption = 'Disband group' , name = 'disband' , tooltip = 'Disbands group.' })
}
local buttons2 = {
t6.add ({ type = 'button' , caption = '25 NW' , name = 'nw' , tooltip = 'Changes remote position' }),
t6.add ({ type = 'button' , caption = '25 N' , name = 'n' , tooltip = 'Changes remote position' }),
t6.add ({ type = 'button' , caption = '25 NE' , name = 'ne' , tooltip = 'Changes remote position' }),
t6.add ({ type = 'button' , caption = '25 W' , name = 'w' , tooltip = 'Changes remote position' }),
t6.add ({ type = 'button' , caption = 'Center' , name = 'center' , tooltip = 'Centers remote position to group' }),
t6.add ({ type = 'button' , caption = '25 E' , name = 'e' , tooltip = 'Changes remote position' }),
t6.add ({ type = 'button' , caption = '25 SW' , name = 'sw' , tooltip = 'Changes remote position' }),
t6.add ({ type = 'button' , caption = '25 S' , name = 's' , tooltip = 'Changes remote position' }),
t6.add ({ type = 'button' , caption = '25 SE' , name = 'se' , tooltip = 'Changes remote position' })
}
for _ , button in pairs ( buttons ) do
button.style . font = 'default-bold'
button.style . font_color = { r = 0.99 , g = 0.99 , b = 0.99 }
button.style . minimal_width = 150
end
for _ , button in pairs ( buttons2 ) do
button.style . font = 'default-bold'
button.style . font_color = { r = 0.99 , g = 0.99 , b = 0.99 }
button.style . minimal_width = 70
end
local t7 = frame.add ({ type = 'table' , name = 'coords' , column_count = 2 })
t7.add ({ type = 'label' , caption = 'X: ' })
t7.add ({ type = 'textfield' , name = 'coord_x' })
t7.add ({ type = 'label' , caption = 'Y: ' })
t7.add ({ type = 'textfield' , name = 'coord_y' })
2020-03-26 04:41:16 +01:00
end
local comm_functions = {
2021-03-24 16:46:00 +01:00
[ 'pan' ] = pan ,
[ 'teleport' ] = teleport ,
[ 'disband' ] = disband ,
[ 'movetome' ] = movetome ,
[ 'movetoposition' ] = movetoposition ,
[ 'patroltome' ] = patroltome ,
[ 'patroltoposition' ] = patroltoposition ,
[ 'settle' ] = settle ,
[ 'siege' ] = siege ,
[ 'report' ] = report ,
[ 'attackenemiesaround' ] = attackenemiesaround ,
[ 'attackobstaclesaround' ] = attackobstaclesaround ,
[ 'attackenemiesaroundme' ] = attackenemiesaroundme ,
[ 'attackobstaclesaroundme' ] = attackobstaclesaroundme ,
[ 'addunits' ] = addunits ,
[ 'addunitsaroundme' ] = addunitsaroundme ,
[ 'forcemove' ] = forcemove ,
[ 'center' ] = center
}
2020-03-26 04:41:16 +01:00
local comm_global_functions = {
2021-03-24 16:46:00 +01:00
[ 'creategroup' ] = creategroup ,
[ 'nw' ] = nw ,
[ 'n' ] = n ,
[ 'ne' ] = ne ,
[ 'w' ] = w ,
[ 'e' ] = e ,
[ 'sw' ] = sw ,
[ 's' ] = s ,
[ 'se' ] = se
}
2020-03-26 04:41:16 +01:00
local function refresh_groups ( player )
2021-03-24 16:46:00 +01:00
local groups = build_groups ( player )
player.gui . screen [ 'biter_panel' ][ 'top' ][ 'group_select' ]. items = groups
2020-03-26 04:41:16 +01:00
end
local function on_gui_click ( event )
2021-03-24 16:46:00 +01:00
if not event then
return
end
if not event.element then
return
end
if not event.element . valid then
return
end
local player = game.players [ event.element . player_index ]
if event.element . name == 'biter_commands' then --top button press
if global.biter_command . enabled or global.biter_command . whitelist [ player.name ] == true then
biter_panel ( player )
return
else
top_button ( player )
player.print ( 'Biter commander module is disabled.' )
return
end
2020-04-08 20:28:02 +02:00
else
2021-03-24 16:46:00 +01:00
if global.biter_command . enabled or global.biter_command . whitelist [ player.name ] == true then
top_button ( player )
end
2020-04-08 20:28:02 +02:00
end
2021-03-24 16:46:00 +01:00
if event.element . type ~= 'button' and event.element . type ~= 'sprite-button' then
return
2020-04-08 20:28:02 +02:00
end
2021-03-24 16:46:00 +01:00
--if event.frame.name ~= "biter_panel" then return end
local name = event.element . name
if name == 'close_biters' then
biter_panel ( player )
return
2020-03-26 04:41:16 +01:00
end
2021-03-24 16:46:00 +01:00
if name == 'info' then
show_info ( player )
return
end
if name == 'close_info' then
show_info ( player )
return
end
if comm_functions [ name ] then
local target_group_id = event.element . parent.parent [ 'top' ][ 'group_select' ]. items [ event.element . parent.parent [ 'top' ][ 'group_select' ]. selected_index ]
if not target_group_id then
return
end
if target_group_id == 'Select Group' then
player.print ( 'No target group selected.' , { r = 0.88 , g = 0.88 , b = 0.88 })
return
end
-- local index = index(tonumber(target_group_id))
-- if not index then
-- player.print("Selected group is no longer valid.", {r=0.88, g=0.88, b=0.88})
-- return
-- end
local group = global.biter_command . active_unit_groups [ tonumber ( target_group_id )]
if group and group.group . valid then
comm_functions [ name ]( group.group , player )
else
refresh_groups ( player )
end
return
2020-03-26 04:41:16 +01:00
end
2021-03-24 16:46:00 +01:00
if comm_global_functions [ name ] then
comm_global_functions [ name ]( player )
return
end
2020-03-26 04:41:16 +01:00
end
local function refresh_panel ()
2021-03-24 16:46:00 +01:00
for _ , player in pairs ( game.connected_players ) do
if player.gui . screen [ 'biter_panel' ] then
refresh_groups ( player )
end
end
2020-03-26 04:41:16 +01:00
end
local function on_player_joined_game ( event )
2021-03-24 16:46:00 +01:00
top_button ( game.players [ event.player_index ])
2020-03-26 04:41:16 +01:00
end
local function on_unit_group_created ( event )
2021-03-24 16:46:00 +01:00
if event and event.group and event.group . valid then
global.biter_command . active_unit_groups [ event.group . group_number ] = { id = event.group . group_number , group = event.group }
refresh_panel ()
end
2020-03-26 04:41:16 +01:00
end
local function on_unit_removed_from_group ( event )
2021-03-24 16:46:00 +01:00
if event and event.group and event.group . valid then
if # event.group . members == 1 then
global.biter_command . active_unit_groups [ event.group . group_number ] = nil
refresh_panel ()
end
2020-03-26 04:41:16 +01:00
end
end
event.add ( defines.events . on_unit_removed_from_group , on_unit_removed_from_group )
event.add ( defines.events . on_unit_group_created , on_unit_group_created )
event.add ( defines.events . on_player_joined_game , on_player_joined_game )
event.add ( defines.events . on_gui_click , on_gui_click )