174 lines
6.5 KiB
Lua

require "template"
if not evogui.on_click then evogui.on_click = {} end
local sensor = ValueSensor.new("player_locations")
sensor.show_player_index = sensor:make_on_click_checkbox_handler("show_player_index")
sensor.show_position = sensor:make_on_click_checkbox_handler("show_position")
sensor.show_surface = sensor:make_on_click_checkbox_handler("show_surface")
sensor.show_direction = sensor:make_on_click_checkbox_handler("show_direction")
sensor.show_offline = sensor:make_on_click_checkbox_handler("show_offline")
function sensor:create_ui(owner)
if owner[self.name] == nil then
local root = owner.add{type="flow",
name=self.name,
direction="horizontal",
style="EvoGUI_cramped_flow_h"}
root.add{type="label", caption={self.format_key}}
root.add{type="table", name="player_list", column_count=1}
end
end
function sensor:settings_gui(player_index)
local player = game.players[player_index]
local sensor_settings = global.evogui[player.name].sensor_settings[self.name]
local root_name = self:settings_root_name()
local root = player.gui.center.add{type="frame",
name=root_name,
direction="vertical",
caption={"sensor.player_locations.settings.title"}}
root.add{type="checkbox", name="evogui_sensor_player_locations_checkbox_show_player_index",
caption={"sensor.player_locations.settings.show_player_index"},
state=sensor_settings.show_player_index}
root.add{type="checkbox", name="evogui_sensor_player_locations_checkbox_show_position",
caption={"sensor.player_locations.settings.show_position"},
state=sensor_settings.show_position}
root.add{type="checkbox", name="evogui_sensor_player_locations_checkbox_show_surface",
caption={"sensor.player_locations.settings.show_surface"},
state=sensor_settings.show_surface}
root.add{type="checkbox", name="evogui_sensor_player_locations_checkbox_show_direction",
caption={"sensor.player_locations.settings.show_direction"},
state=sensor_settings.show_direction}
root.add{type="checkbox", name="evogui_sensor_player_locations_checkbox_show_offline",
caption={"sensor.player_locations.settings.show_offline"},
state=sensor_settings.show_offline}
root.add{type="button", name="evogui_sensor_player_locations_close", caption={"settings_close"}}
end
local function directions(source, destination)
-- Directions to or from positionless things? Hrm.
if not source.position or not destination.position then return {"direction.unknown"} end
local delta_x = destination.position.x - source.position.x
local delta_y = destination.position.y - source.position.y
if math.abs(delta_x) < 2 and math.abs(delta_y) < 2 then return '' end
return evogui.get_octant_name{x=delta_x, y=delta_y}
end
local function get_online_time(player)
local minutes = math.floor(player.online_time / 3600)
local hours = math.floor(minutes / 60)
local days = math.floor(hours / 24)
local result = {""}
if days > 0 then
if days == 1 then
table.insert(result, {"sensor.player_locations.single_day_fragment"})
else
table.insert(result, {"sensor.player_locations.multi_day_fragment", tostring(days)})
end
table.insert(result, ' ')
end
table.insert(result, string.format("%d:%02d", hours % 24, minutes % 60))
return result
end
function sensor:update_ui(owner)
local player = game.players[owner.player_index]
local sensor_settings = global.evogui[player.name].sensor_settings[self.name]
local gui_list = owner[self.name].player_list
for _, p in pairs(game.players) do
local player_name = p.name
if not player_name or player_name == '' then
-- fallback to "Local Player" if this is singleplayer
if #game.players == 1 then
player_name = "sensor.player_locations.local_player"
else
if gui_list.error == nil then
gui_list.add{type="label", name="error", caption={"sensor.player_locations.err_no_name"}}
end
break
end
end
if gui_list.error ~= nil then gui_list.error.destroy() end
if p.connected == false and not sensor_settings.show_offline then
if gui_list[player_name] and gui_list[player_name].valid then
gui_list[player_name].destroy()
end
goto next_player
end
if gui_list[player_name] == nil then
gui_list.add{type="label", name=player_name}
end
local direction = '?'
local current_player = game.players[owner.player_index]
if p == current_player then
direction = ''
elseif current_player then
direction = directions(current_player, p)
end
local desc = {''}
if sensor_settings.show_player_index then
table.insert(desc, string.format('(%d) ', p.index))
end
if player_name == "sensor.player_locations.local_player" then
table.insert(desc, {player_name})
else
table.insert(desc, player_name)
end
table.insert(desc, ' ')
if p.connected then
table.insert(desc, {"sensor.player_locations.online_fragment", get_online_time(p)})
else
table.insert(desc, {"sensor.player_locations.offline_fragment", get_online_time(p)})
end
if sensor_settings.show_position or sensor_settings.show_surface then
table.insert(desc, ' (')
if sensor_settings.show_position then
table.insert(desc, string.format('@%d, %d', math.floor(p.position.x), math.floor(p.position.y)))
end
if sensor_settings.show_surface then
if sensor_settings.show_position then
table.insert(desc, ' ')
end
table.insert(desc, {"sensor.player_locations.surface_fragment", p.surface.name})
end
table.insert(desc, ')')
end
if sensor_settings.show_direction then
table.insert(desc, ' ')
table.insert(desc, direction)
end
gui_list[player_name].caption = desc
::next_player::
end
end
ValueSensor.register(sensor)