You've already forked ComfyFactorio
mirror of
https://github.com/ComfyFactory/ComfyFactorio.git
synced 2026-06-13 21:54:39 +02:00
1468 lines
39 KiB
Lua
1468 lines
39 KiB
Lua
local Gui = require 'utils.gui'
|
|
local Event = require 'utils.event'
|
|
local Global = require 'utils.global'
|
|
local Color = require 'utils.color_presets'
|
|
local SessionData = require 'utils.datastore.session_data'
|
|
local Task = require 'utils.task'
|
|
local Token = require 'utils.token'
|
|
local Utils = require 'utils.utils'
|
|
|
|
local warp_entities =
|
|
{
|
|
{ 'small-lamp', -3, -2 },
|
|
{ 'small-lamp', -3, 2 },
|
|
{ 'small-lamp', 3, -2 },
|
|
{ 'small-lamp', 3, 2 },
|
|
{ 'small-lamp', -2, -3 },
|
|
{ 'small-lamp', 2, -3 },
|
|
{ 'small-lamp', -2, 3 },
|
|
{ 'small-lamp', 2, 3 },
|
|
{ 'small-electric-pole', -3, -3 },
|
|
{ 'small-electric-pole', 3, 3 },
|
|
{ 'small-electric-pole', -3, 3 },
|
|
{ 'small-electric-pole', 3, -3 }
|
|
}
|
|
local warp_tiles =
|
|
{
|
|
{ -3, -2 },
|
|
{ -3, -1 },
|
|
{ -3, 0 },
|
|
{ -3, 1 },
|
|
{ -3, 2 },
|
|
{ 3, -2 },
|
|
{ 3, -1 },
|
|
{ 3, 0 },
|
|
{ 3, 1 },
|
|
{ 3, 2 },
|
|
{ -2, -3 },
|
|
{ -1, -3 },
|
|
{ 0, -3 },
|
|
{ 1, -3 },
|
|
{ 2, -3 },
|
|
{ -2, 3 },
|
|
{ -1, 3 },
|
|
{ 0, 3 },
|
|
{ 1, 3 },
|
|
{ 2, 3 }
|
|
}
|
|
|
|
local radius = 4
|
|
local warp_tile = 'tutorial-grid'
|
|
local warp_item = 'discharge-defense-equipment'
|
|
local global_offset = { x = 0, y = 0 }
|
|
|
|
local main_button_name = Gui.uid_name()
|
|
local main_frame_name = Gui.uid_name()
|
|
local create_warp_button_name = Gui.uid_name()
|
|
local confirmed_button_name = Gui.uid_name()
|
|
local edit_warp_func_name = Gui.uid_name()
|
|
local create_warp_func_name = Gui.uid_name()
|
|
local create_warp_is_shared = Gui.uid_name()
|
|
local edit_warp_button_name = Gui.uid_name()
|
|
local remove_warp_button_name = Gui.uid_name()
|
|
local close_main_frame_name = Gui.uid_name()
|
|
local cancel_button_name = Gui.uid_name()
|
|
local show_only_player_warps = Gui.uid_name()
|
|
local warp_icon_name = Gui.uid_name()
|
|
local click_to_view_on_map_name = Gui.uid_name()
|
|
|
|
local this =
|
|
{
|
|
warps = {},
|
|
player_settings = {},
|
|
surface_name = 'nauvis'
|
|
}
|
|
|
|
Global.register(
|
|
this,
|
|
function (tbl)
|
|
this = tbl
|
|
end
|
|
)
|
|
|
|
local Public = {}
|
|
|
|
local function validate_player(player)
|
|
if not player then
|
|
return false
|
|
end
|
|
if not player.valid then
|
|
return false
|
|
end
|
|
if not player.character then
|
|
return false
|
|
end
|
|
if not player.connected then
|
|
return false
|
|
end
|
|
if not game.players[player.name] then
|
|
return false
|
|
end
|
|
return true
|
|
end
|
|
|
|
local function validate_data(new, player, p)
|
|
if new == '' or new == 'Spawn' or new == 'Name:' or new == 'Warp name:' then
|
|
player.print('[Warp] Warp name is not valid.', Color.fail)
|
|
return false
|
|
end
|
|
|
|
if string.find(new:lower(), 'spawn') or string.find(new:lower(), 'warp') or string.find(new:lower(), 'name') then
|
|
player.print('[Warp] Warp name is not valid.', Color.fail)
|
|
return false
|
|
end
|
|
|
|
if string.len(new) > 30 then
|
|
player.print('[Warp] Warp name is too long!', Color.fail)
|
|
return false
|
|
end
|
|
|
|
if string.len(new) < 6 then
|
|
p.frame.new_name.text = ''
|
|
player.print('[Warp] Warp name is too short!', Color.fail)
|
|
return false
|
|
end
|
|
return true
|
|
end
|
|
|
|
local function get_player_data(player)
|
|
if not this.player_settings[player.index] then
|
|
this.player_settings[player.index] =
|
|
{
|
|
creating = false,
|
|
editing = false,
|
|
removing = false,
|
|
frame = nil,
|
|
spam = 100,
|
|
only_my_warps = false
|
|
}
|
|
end
|
|
return this.player_settings[player.index]
|
|
end
|
|
|
|
function Public.get_warp_by_name(name)
|
|
for _, data in pairs(this.warps) do
|
|
if name == data.name then
|
|
return data
|
|
end
|
|
end
|
|
return false
|
|
end
|
|
|
|
function Public.remove_warp_by_name(name)
|
|
for index, data in pairs(this.warps) do
|
|
if name == data.name then
|
|
this.warps[index] = nil
|
|
end
|
|
end
|
|
return false
|
|
end
|
|
|
|
function Public.remove_player(index)
|
|
for _, data in pairs(this.warps) do
|
|
if data.created_by == index then
|
|
Public.remove_warp_point(data.index)
|
|
end
|
|
end
|
|
end
|
|
|
|
function Public.remove_warp_point(index)
|
|
local warp = Public.get_warp_by_name(index)
|
|
if not warp then
|
|
return
|
|
end
|
|
local surface_index = warp.surface
|
|
local surface = game.get_surface(surface_index)
|
|
if warp.name == 'Spawn' then
|
|
return
|
|
end
|
|
|
|
|
|
local shared = warp.shared
|
|
|
|
if warp.entities then
|
|
for _, entity in pairs(warp.entities) do
|
|
entity.destroy()
|
|
end
|
|
end
|
|
|
|
if warp.old_tiles then
|
|
surface.set_tiles(warp.old_tiles, true, false)
|
|
end
|
|
|
|
if warp.tag then
|
|
warp.tag.destroy()
|
|
end
|
|
Public.remove_warp_by_name(index)
|
|
return shared
|
|
end
|
|
|
|
function Public.make_warp_point(player, position, surface, icon, force, name, shared)
|
|
if Public.get_warp_by_name(name) then
|
|
return
|
|
end
|
|
|
|
local offset = { x = math.floor(position.x), y = math.floor(position.y) }
|
|
local old_tiles = {}
|
|
local base_tiles = {}
|
|
local tiles = {}
|
|
local entities = {}
|
|
|
|
local _shared = shared or false
|
|
|
|
if not string.find(surface.name, 'platform') then
|
|
-- makes the base template to make the warp point
|
|
for x = -radius - 2, radius + 2 do
|
|
for y = -radius - 2, radius + 2 do
|
|
if x ^ 2 + y ^ 2 < radius ^ 2 then
|
|
local old_tile = surface.get_tile({ x + offset.x, y + offset.y })
|
|
if old_tile and (old_tile.name ~= warp_tile) then
|
|
old_tiles[#old_tiles + 1] = { name = old_tile.name, position = old_tile.position }
|
|
end
|
|
base_tiles[#base_tiles + 1] = { name = warp_tile, position = { x + offset.x, y + offset.y } }
|
|
end
|
|
end
|
|
end
|
|
surface.set_tiles(base_tiles)
|
|
|
|
|
|
-- adds the patterns and entities
|
|
for _, p in pairs(warp_tiles) do
|
|
local old_tile = surface.get_tile({ p[1] + offset.x + global_offset.x, p[2] + offset.y + global_offset.y })
|
|
if old_tile and (old_tile.name ~= warp_tile) then
|
|
old_tiles[#old_tiles + 1] = { name = old_tile.name, position = old_tile.position }
|
|
end
|
|
tiles[#tiles + 1] =
|
|
{
|
|
name = warp_tile,
|
|
position = { p[1] + offset.x + global_offset.x, p[2] + offset.y + global_offset.y }
|
|
}
|
|
end
|
|
|
|
surface.set_tiles(tiles)
|
|
for _, e in pairs(warp_entities) do
|
|
local entity =
|
|
surface.create_entity
|
|
{
|
|
name = e[1],
|
|
position = { e[2] + offset.x + global_offset.x, e[3] + offset.y + global_offset.y },
|
|
force = 'neutral'
|
|
}
|
|
entity.destructible = false
|
|
entity.health = 0
|
|
entity.minable = false
|
|
entity.rotatable = false
|
|
entities[#entities + 1] = entity
|
|
end
|
|
end
|
|
|
|
local tag =
|
|
force.add_chart_tag(
|
|
surface,
|
|
{
|
|
position = { offset.x + 0.5, offset.y + 0.5 },
|
|
text = 'Warp: ' .. name,
|
|
icon = { type = icon.type, name = icon.name }
|
|
}
|
|
)
|
|
if not tag then
|
|
return
|
|
end
|
|
|
|
local created_by = player.index
|
|
|
|
local index = #this.warps + 1
|
|
this.warps[index] =
|
|
{
|
|
tag = tag,
|
|
position = tag.position,
|
|
surface = surface.index,
|
|
icon = icon,
|
|
name = name,
|
|
index = index,
|
|
old_tiles = old_tiles,
|
|
created_by = created_by,
|
|
entities = entities,
|
|
shared = _shared
|
|
}
|
|
return true
|
|
end
|
|
|
|
function Public.edit_warp_point(surface, icon, force, old_name, new_name, shared)
|
|
local warp = Public.get_warp_by_name(old_name)
|
|
if not warp then
|
|
return
|
|
end
|
|
|
|
local old_tag = warp.tag
|
|
if not old_tag then
|
|
old_tag = warp
|
|
end
|
|
|
|
local tag =
|
|
force.add_chart_tag(
|
|
surface,
|
|
{
|
|
position = { old_tag.position.x + 0.5, old_tag.position.y + 0.5 },
|
|
text = 'Warp: ' .. new_name,
|
|
icon = { type = icon.type, name = icon.name }
|
|
}
|
|
)
|
|
|
|
local new_icon = icon
|
|
|
|
if warp.tag then
|
|
warp.tag.destroy()
|
|
end
|
|
|
|
warp.tag = tag
|
|
warp.icon = new_icon
|
|
warp.name = new_name
|
|
warp.shared = shared
|
|
|
|
return true
|
|
end
|
|
|
|
function Public.make_tag(name, pos, shared)
|
|
local get_surface = this.surface_name
|
|
local surface = game.surfaces[get_surface]
|
|
local data = {}
|
|
if data.forces then
|
|
data.forces = nil
|
|
end
|
|
for _, v in pairs(game.forces) do
|
|
data.forces = v
|
|
end
|
|
local created_by = 'script'
|
|
local v =
|
|
data.forces.add_chart_tag(
|
|
surface,
|
|
{
|
|
position = pos,
|
|
text = 'Warp: ' .. name,
|
|
icon = { type = 'item', name = warp_item }
|
|
}
|
|
)
|
|
|
|
local index = #this.warps + 1
|
|
this.warps[index] =
|
|
{
|
|
tag = v,
|
|
position = pos,
|
|
name = name,
|
|
index = index,
|
|
icon = { type = 'item', name = warp_item },
|
|
surface = surface.index,
|
|
created_by = created_by,
|
|
shared = shared
|
|
}
|
|
return data
|
|
end
|
|
|
|
function Public.create_warp_button(player)
|
|
if not SessionData.allowed(player, 'show-warp') then
|
|
if Gui.get_button_flow(player)[main_button_name] then
|
|
Gui.get_button_flow(player)[main_button_name].destroy()
|
|
end
|
|
return
|
|
end
|
|
if Gui.get_button_flow(player)[main_button_name] then
|
|
return
|
|
end
|
|
local button = Gui.get_button_flow(player).add
|
|
{
|
|
type = 'sprite-button',
|
|
sprite = 'item/discharge-defense-equipment',
|
|
name = main_button_name,
|
|
tooltip = 'Warp to places!',
|
|
style = Gui.button_style
|
|
}
|
|
if button then
|
|
button.style.font_color = { 165, 165, 165 }
|
|
button.style.font = 'default-semibold'
|
|
button.style.minimal_height = 36
|
|
button.style.maximal_height = 36
|
|
button.style.minimal_width = 40
|
|
button.style.padding = -2
|
|
end
|
|
end
|
|
|
|
local function draw_create_warp(parent, player)
|
|
local position = player.position
|
|
local posx = position.x
|
|
local posy = position.y
|
|
local dist2 = 100 ^ 2
|
|
local p = get_player_data(player)
|
|
if not SessionData.allowed(player, 'always-warp') then
|
|
for _, warp in pairs(this.warps) do
|
|
local pos = warp.position
|
|
if (posx - pos.x) ^ 2 + (posy - pos.y) ^ 2 < dist2 then
|
|
player.print('[Warp] Too close to another warp: ' .. warp.name, Color.fail)
|
|
p.creating = false
|
|
return
|
|
end
|
|
end
|
|
end
|
|
|
|
local x =
|
|
parent.add
|
|
{
|
|
type = 'table',
|
|
name = 'wp_table',
|
|
column_count = 4
|
|
}
|
|
|
|
local elem =
|
|
x.add
|
|
{
|
|
name = warp_icon_name,
|
|
type = 'choose-elem-button',
|
|
elem_type = 'signal',
|
|
signal = { type = 'item', name = warp_item },
|
|
tooltip = 'Choose the tag-icon'
|
|
}
|
|
local elem_style = elem.style
|
|
elem_style.height = 32
|
|
elem_style.width = 32
|
|
|
|
local textfield =
|
|
x.add
|
|
{
|
|
type = 'textfield',
|
|
name = 'wp_text',
|
|
text = 'Warp name:',
|
|
numeric = false,
|
|
allow_decimal = false,
|
|
allow_negative = false
|
|
}
|
|
p.shared = true
|
|
textfield.style.minimal_width = 100
|
|
textfield.style.maximal_width = 150
|
|
textfield.style.height = 24
|
|
p.frame = { new_name = textfield }
|
|
|
|
local _flow =
|
|
x.add
|
|
{
|
|
type = 'flow'
|
|
}
|
|
_flow.style.horizontal_align = 'right'
|
|
_flow.style.horizontally_stretchable = true
|
|
|
|
local checkbox =
|
|
_flow.add
|
|
{
|
|
type = 'checkbox',
|
|
name = create_warp_is_shared,
|
|
tooltip = 'Do you want to share this warp?',
|
|
state = true
|
|
}
|
|
checkbox.style.top_margin = 5
|
|
|
|
local btn =
|
|
_flow.add
|
|
{
|
|
type = 'sprite-button',
|
|
name = create_warp_func_name,
|
|
tooltip = 'Creates a new warp point.',
|
|
sprite = 'utility/confirm_slot',
|
|
style = 'shortcut_bar_button_green'
|
|
}
|
|
btn.style.height = 23
|
|
btn.style.width = 23
|
|
btn.style.padding = -2
|
|
end
|
|
|
|
local function draw_edit_warp(parent, player)
|
|
local p = get_player_data(player)
|
|
local data = Public.get_warp_by_name(p.edit_warp_name)
|
|
if not data then
|
|
return
|
|
end
|
|
|
|
local x =
|
|
parent.add
|
|
{
|
|
type = 'table',
|
|
name = 'wp_table',
|
|
column_count = 4
|
|
}
|
|
|
|
p.icon = data.icon
|
|
|
|
local elem =
|
|
x.add
|
|
{
|
|
name = warp_icon_name,
|
|
type = 'choose-elem-button',
|
|
elem_type = 'signal',
|
|
signal = { type = data.icon.type, name = data.icon.name },
|
|
tooltip = 'Choose the tag-icon'
|
|
}
|
|
local elem_style = elem.style
|
|
elem_style.height = 32
|
|
elem_style.width = 32
|
|
|
|
local textfield =
|
|
x.add
|
|
{
|
|
type = 'textfield',
|
|
name = 'wp_text',
|
|
text = data.name,
|
|
numeric = false,
|
|
allow_decimal = false,
|
|
allow_negative = false
|
|
}
|
|
textfield.focus()
|
|
p.shared = true
|
|
textfield.style.minimal_width = 80
|
|
textfield.style.maximal_width = 150
|
|
textfield.style.height = 24
|
|
p.frame = { new_name = textfield }
|
|
|
|
local _flow =
|
|
x.add
|
|
{
|
|
type = 'flow'
|
|
}
|
|
_flow.style.horizontal_align = 'right'
|
|
_flow.style.horizontally_stretchable = true
|
|
|
|
local checkbox =
|
|
_flow.add
|
|
{
|
|
type = 'checkbox',
|
|
name = create_warp_is_shared,
|
|
tooltip = 'Do you want to share this warp?',
|
|
state = data.shared
|
|
}
|
|
checkbox.style.top_margin = 5
|
|
|
|
local cancel_btn =
|
|
_flow.add
|
|
{
|
|
type = 'sprite-button',
|
|
name = cancel_button_name,
|
|
tooltip = 'Cancel editing',
|
|
style = 'shortcut_bar_button_blue',
|
|
sprite = 'utility/reset'
|
|
}
|
|
cancel_btn.style.height = 23
|
|
cancel_btn.style.width = 23
|
|
cancel_btn.style.padding = -2
|
|
|
|
local edit_btn =
|
|
_flow.add
|
|
{
|
|
type = 'sprite-button',
|
|
name = edit_warp_func_name,
|
|
tooltip = 'Edit the current warp point.',
|
|
sprite = 'utility/confirm_slot',
|
|
style = 'shortcut_bar_button_green'
|
|
}
|
|
edit_btn.style.height = 23
|
|
edit_btn.style.width = 23
|
|
edit_btn.style.padding = -2
|
|
end
|
|
|
|
local function draw_remove_warp(parent, player)
|
|
parent.clear()
|
|
if player.admin or SessionData.allowed(player, 'remove-warp') then
|
|
local btn =
|
|
parent.add
|
|
{
|
|
type = 'sprite-button',
|
|
name = confirmed_button_name,
|
|
tooltip = 'Do you really want to remove: ' .. parent.name,
|
|
style = 'shortcut_bar_button_red',
|
|
sprite = 'utility/confirm_slot'
|
|
}
|
|
btn.style.height = 23
|
|
btn.style.width = 23
|
|
btn.style.padding = -2
|
|
else
|
|
local btn =
|
|
parent.add
|
|
{
|
|
type = 'sprite-button',
|
|
name = confirmed_button_name,
|
|
enabled = 'false',
|
|
tooltip = 'You have not grown accustomed to this technology yet',
|
|
style = 'shortcut_bar_button_red',
|
|
sprite = 'utility/confirm_slot'
|
|
}
|
|
btn.style.height = 23
|
|
btn.style.width = 23
|
|
btn.style.padding = -2
|
|
end
|
|
local btn =
|
|
parent.add
|
|
{
|
|
type = 'sprite-button',
|
|
name = cancel_button_name,
|
|
tooltip = 'Cancel deletion of: ' .. parent.name,
|
|
style = 'shortcut_bar_button_blue',
|
|
sprite = 'utility/reset'
|
|
}
|
|
btn.style.height = 23
|
|
btn.style.width = 23
|
|
btn.style.padding = -2
|
|
end
|
|
|
|
local warp_icon_button
|
|
|
|
local function draw_player_warp_only(player, p, frame_tbl, sub_table, name, warp, e)
|
|
if not warp.tag or not warp.tag.valid then
|
|
local surface = game.get_surface(warp.surface)
|
|
for _, v in pairs(game.forces) do
|
|
v.add_chart_tag(
|
|
surface,
|
|
{
|
|
position = warp.position,
|
|
text = 'Warp: ' .. name,
|
|
icon = { type = 'item', name = warp_item }
|
|
}
|
|
)
|
|
end
|
|
end
|
|
local flow =
|
|
frame_tbl.add
|
|
{
|
|
type = 'flow',
|
|
caption = warp.name
|
|
}
|
|
warp_icon_button(flow, warp)
|
|
|
|
local created_by_player_name
|
|
|
|
local created_by_player = game.get_player(warp.created_by)
|
|
if not created_by_player or not created_by_player.valid then
|
|
created_by_player_name = warp.created_by
|
|
else
|
|
created_by_player_name = created_by_player.name
|
|
end
|
|
|
|
local subflow =
|
|
frame_tbl.add
|
|
{
|
|
type = 'flow'
|
|
}
|
|
subflow.style.horizontal_align = 'left'
|
|
subflow.style.horizontally_stretchable = true
|
|
|
|
local info_label_tooltip = 'Click to view on map'
|
|
|
|
if player.admin then
|
|
info_label_tooltip = 'Created by: ' ..
|
|
created_by_player_name .. '\nShared: ' .. tostring(warp.shared) .. '\nClick to view on map'
|
|
end
|
|
|
|
subflow.add
|
|
{
|
|
type = 'label',
|
|
caption = name,
|
|
name = click_to_view_on_map_name,
|
|
style = 'caption_label',
|
|
tooltip = info_label_tooltip
|
|
}
|
|
|
|
local _flows3 = frame_tbl.add { type = 'flow' }
|
|
_flows3.style.horizontal_align = 'right'
|
|
_flows3.style.horizontally_stretchable = true
|
|
|
|
local bottom_warp_flow = frame_tbl.add { type = 'flow', name = name }
|
|
|
|
if bottom_warp_flow.name ~= 'Spawn' and (warp.created_by == player.index or SessionData.allowed(player, 'warp-override')) then
|
|
local tooltip
|
|
if warp.created_by == player.index then
|
|
tooltip = 'Edit warp: ' .. bottom_warp_flow.name
|
|
else
|
|
tooltip = 'Edit warp created by: ' .. created_by_player_name .. ' with name: ' .. bottom_warp_flow.name
|
|
end
|
|
local edit_warp_button =
|
|
bottom_warp_flow.add
|
|
{
|
|
type = 'sprite-button',
|
|
name = edit_warp_button_name,
|
|
tooltip = tooltip,
|
|
style = Gui.button_style,
|
|
sprite = Gui.settings_white_icon,
|
|
hovered_sprite = Gui.settings_black_icon,
|
|
clicked_sprite = Gui.settings_black_icon
|
|
}
|
|
edit_warp_button.style.padding = -2
|
|
edit_warp_button.style.height = 23
|
|
edit_warp_button.style.width = 23
|
|
|
|
local remove_warp_flow =
|
|
bottom_warp_flow.add
|
|
{
|
|
type = 'sprite-button',
|
|
name = remove_warp_button_name,
|
|
tooltip = 'Removes warp: ' .. bottom_warp_flow.name,
|
|
style = Gui.button_style,
|
|
sprite = 'utility/trash'
|
|
}
|
|
remove_warp_flow.style.padding = -2
|
|
remove_warp_flow.style.height = 23
|
|
remove_warp_flow.style.width = 23
|
|
end
|
|
|
|
if p.editing then
|
|
draw_edit_warp(sub_table, player)
|
|
p.editing = false
|
|
end
|
|
|
|
if p.creating then
|
|
draw_create_warp(sub_table, player)
|
|
p.creating = false
|
|
end
|
|
|
|
if p.removing then
|
|
if bottom_warp_flow.name == e then
|
|
draw_remove_warp(bottom_warp_flow, player)
|
|
p.removing = false
|
|
end
|
|
end
|
|
end
|
|
|
|
local function draw_main_frame(player, left, are_you_sure)
|
|
local e = are_you_sure
|
|
local p = get_player_data(player)
|
|
|
|
local frame = Gui.add_main_frame(left, main_frame_name, 'Warps', 'Warp to places!')
|
|
|
|
local tbl = frame.add { type = 'table', column_count = 1 }
|
|
|
|
local _flows1 = tbl.add { type = 'flow' }
|
|
_flows1.style.horizontally_stretchable = true
|
|
|
|
local warp_list =
|
|
_flows1.add
|
|
{
|
|
type = 'scroll-pane',
|
|
direction = 'vertical',
|
|
horizontal_scroll_policy = 'never',
|
|
vertical_scroll_policy = 'auto',
|
|
style = 'scroll_pane_under_subheader'
|
|
}
|
|
local scroll_style = warp_list.style
|
|
scroll_style.padding = { 1, 3 }
|
|
scroll_style.maximal_height = 200
|
|
scroll_style.minimal_height = 200
|
|
scroll_style.horizontally_stretchable = true
|
|
|
|
local frame_tbl = warp_list.add { type = 'table', column_count = 4 }
|
|
|
|
local sub_table = warp_list.add { type = 'table', column_count = 4 }
|
|
sub_table.style.cell_padding = 4
|
|
|
|
for _, warp in pairs(this.warps) do
|
|
if p.edit_warp_name then
|
|
if (warp.created_by == 'script') then
|
|
draw_player_warp_only(player, p, frame_tbl, sub_table, warp.name, warp, e)
|
|
end
|
|
else
|
|
if p.only_my_warps then
|
|
if (warp.created_by == player.index or warp.created_by == 'script') then
|
|
draw_player_warp_only(player, p, frame_tbl, sub_table, warp.name, warp, e)
|
|
end
|
|
else
|
|
if (warp.created_by == player.index and not warp.shared) then
|
|
draw_player_warp_only(player, p, frame_tbl, sub_table, warp.name, warp, e)
|
|
elseif warp.shared == true then
|
|
draw_player_warp_only(player, p, frame_tbl, sub_table, warp.name, warp, e)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
local bottom_flow = frame.add { type = 'flow', direction = 'horizontal' }
|
|
|
|
bottom_flow.add
|
|
{
|
|
type = 'checkbox',
|
|
state = p.only_my_warps,
|
|
name = show_only_player_warps,
|
|
caption = 'Show only my warps.'
|
|
}
|
|
|
|
local bottom_bottom_flow = frame.add { type = 'flow', direction = 'horizontal' }
|
|
|
|
local left_flow = bottom_bottom_flow.add { type = 'flow' }
|
|
left_flow.style.horizontal_align = 'left'
|
|
left_flow.style.horizontally_stretchable = true
|
|
|
|
local close_button = left_flow.add { type = 'button', name = close_main_frame_name, caption = 'Close' }
|
|
Gui.apply_button_style(close_button)
|
|
|
|
local button_flow = left_flow.add { type = 'flow' }
|
|
button_flow.style.horizontal_align = 'right'
|
|
button_flow.style.horizontally_stretchable = true
|
|
|
|
if SessionData.allowed(player, 'create-warp') or player.admin then
|
|
local button = button_flow.add { type = 'button', name = create_warp_button_name, caption = 'Create Warp' }
|
|
Gui.apply_button_style(button)
|
|
else
|
|
local button =
|
|
button_flow.add
|
|
{
|
|
type = 'button',
|
|
name = create_warp_button_name,
|
|
caption = 'Create Warp.',
|
|
enabled = false,
|
|
tooltip = 'You have not grown accustomed to this technology yet.'
|
|
}
|
|
Gui.apply_button_style(button)
|
|
end
|
|
end
|
|
|
|
function Public.toggle(player)
|
|
local gui = player.gui
|
|
local left = gui.left
|
|
local main_frame = left[main_frame_name]
|
|
|
|
if not validate_player(player) then
|
|
return
|
|
end
|
|
|
|
if main_frame and main_frame.valid then
|
|
Gui.clear_all_left_frames(player)
|
|
else
|
|
Gui.clear_all_active_frames(player)
|
|
draw_main_frame(player, left)
|
|
end
|
|
end
|
|
|
|
function Public.refresh_gui_player(player, are_you_sure, close)
|
|
local e = are_you_sure
|
|
local gui = player.gui
|
|
local left = gui.left
|
|
local main_frame = left[main_frame_name]
|
|
|
|
if not validate_player(player) then
|
|
return
|
|
end
|
|
|
|
if main_frame then
|
|
Public.close_gui_player(main_frame)
|
|
if not close then
|
|
draw_main_frame(player, left, e)
|
|
end
|
|
end
|
|
end
|
|
|
|
function Public.close_gui_player(frame)
|
|
if frame and frame.valid then
|
|
frame.destroy()
|
|
end
|
|
end
|
|
|
|
function Public.is_spam(p, player)
|
|
if p.spam > game.tick then
|
|
player.print(
|
|
'[Warp] Please wait ' ..
|
|
math.ceil((p.spam - game.tick) / 60) .. ' seconds before trying to warp or add warps again.', Color.warning)
|
|
return true
|
|
end
|
|
return false
|
|
end
|
|
|
|
function Public.clear_player_table(player)
|
|
local p = get_player_data(player)
|
|
if p.removing == true then
|
|
p.removing = false
|
|
end
|
|
if p.creating == true then
|
|
p.creating = false
|
|
end
|
|
|
|
p.edit_warp_name = nil
|
|
|
|
if p.frame then
|
|
p.frame = nil
|
|
end
|
|
if p.icon then
|
|
p.icon = nil
|
|
end
|
|
if p.shared then
|
|
p.shared = nil
|
|
end
|
|
end
|
|
|
|
function Public.refresh_gui()
|
|
for _, player in pairs(game.connected_players) do
|
|
local gui = player.gui
|
|
local left = gui.left
|
|
|
|
if not validate_player(player) then
|
|
return
|
|
end
|
|
|
|
local main_frame = left[main_frame_name]
|
|
|
|
if not player.connected then
|
|
Public.close_gui_player(main_frame)
|
|
return
|
|
end
|
|
|
|
if main_frame then
|
|
Public.close_gui_player(main_frame)
|
|
draw_main_frame(player, left)
|
|
end
|
|
end
|
|
end
|
|
|
|
local function on_player_joined_game(event)
|
|
local player = game.get_player(event.player_index)
|
|
|
|
if not validate_player(player) then
|
|
return
|
|
end
|
|
|
|
get_player_data(player)
|
|
|
|
Public.create_warp_button(player)
|
|
end
|
|
|
|
local function on_player_left_game(event)
|
|
local player = game.get_player(event.player_index)
|
|
|
|
if not validate_player(player) then
|
|
return
|
|
end
|
|
|
|
Gui.clear_all_left_frames(player)
|
|
end
|
|
|
|
local function on_player_died(event)
|
|
local player = game.get_player(event.player_index)
|
|
|
|
if not validate_player(player) then
|
|
return
|
|
end
|
|
|
|
local p = player.gui.left[main_frame_name]
|
|
|
|
if not p then
|
|
return
|
|
end
|
|
|
|
Public.close_gui_player(p)
|
|
end
|
|
|
|
|
|
Gui.on_click(
|
|
main_button_name,
|
|
function (event)
|
|
local element = event.element
|
|
if not element then
|
|
return
|
|
end
|
|
local player = Gui.get_player_from_element(element)
|
|
if not validate_player(player) then
|
|
return
|
|
end
|
|
|
|
Public.clear_player_table(player)
|
|
Public.toggle(player)
|
|
end
|
|
)
|
|
|
|
Gui.on_click(
|
|
close_main_frame_name,
|
|
function (event)
|
|
local player = game.get_player(event.player_index)
|
|
|
|
if not validate_player(player) then
|
|
return
|
|
end
|
|
|
|
Public.clear_player_table(player)
|
|
Public.toggle(player)
|
|
end
|
|
)
|
|
|
|
Gui.on_click(
|
|
edit_warp_button_name,
|
|
function (event)
|
|
local player = game.get_player(event.player_index)
|
|
|
|
if not validate_player(player) then
|
|
return
|
|
end
|
|
|
|
local element = event.element
|
|
local p = get_player_data(player)
|
|
|
|
Public.clear_player_table(player)
|
|
|
|
if p.editing == false then
|
|
p.edit_warp_name = element.parent.name
|
|
p.editing = true
|
|
end
|
|
|
|
Public.refresh_gui_player(player)
|
|
end
|
|
)
|
|
|
|
Gui.on_click(
|
|
click_to_view_on_map_name,
|
|
function (event)
|
|
local player = game.get_player(event.player_index)
|
|
|
|
if not validate_player(player) then
|
|
return
|
|
end
|
|
|
|
local element = event.element
|
|
|
|
Public.clear_player_table(player)
|
|
|
|
local warp_name = element.caption
|
|
local warp = Public.get_warp_by_name(warp_name)
|
|
if not warp then
|
|
return
|
|
end
|
|
|
|
local position = warp.position
|
|
player.zoom_to_world(position, 1.5)
|
|
|
|
Public.refresh_gui_player(player)
|
|
end
|
|
)
|
|
|
|
Gui.on_click(
|
|
remove_warp_button_name,
|
|
function (event)
|
|
local player = game.get_player(event.player_index)
|
|
|
|
if not validate_player(player) then
|
|
return
|
|
end
|
|
|
|
local are_you_sure = event.element.parent.name
|
|
|
|
local p = get_player_data(player)
|
|
|
|
if not p then
|
|
return
|
|
end
|
|
|
|
if not p.removing == true then
|
|
p.removing = true
|
|
Public.refresh_gui_player(player, are_you_sure)
|
|
end
|
|
end
|
|
)
|
|
|
|
Gui.on_click(
|
|
create_warp_is_shared,
|
|
function (event)
|
|
local player = game.get_player(event.player_index)
|
|
|
|
if not validate_player(player) then
|
|
return
|
|
end
|
|
|
|
local p = get_player_data(player)
|
|
|
|
if not p then
|
|
return
|
|
end
|
|
|
|
p.shared = event.element.state
|
|
end
|
|
)
|
|
|
|
Gui.on_click(
|
|
show_only_player_warps,
|
|
function (event)
|
|
local player = game.get_player(event.player_index)
|
|
|
|
if not validate_player(player) then
|
|
return
|
|
end
|
|
|
|
local p = get_player_data(player)
|
|
|
|
if not p then
|
|
return
|
|
end
|
|
|
|
Public.clear_player_table(player)
|
|
p.only_my_warps = event.element.state
|
|
Public.refresh_gui_player(player)
|
|
end
|
|
)
|
|
|
|
Gui.on_click(
|
|
cancel_button_name,
|
|
function (event)
|
|
local player = game.get_player(event.player_index)
|
|
|
|
if not validate_player(player) then
|
|
return
|
|
end
|
|
|
|
Public.clear_player_table(player)
|
|
Public.refresh_gui_player(player)
|
|
end
|
|
)
|
|
|
|
Gui.on_click(
|
|
confirmed_button_name,
|
|
function (event)
|
|
local player = game.get_player(event.player_index)
|
|
local element = event.element
|
|
if not element or not element.valid then
|
|
return
|
|
end
|
|
|
|
if not validate_player(player) then
|
|
return
|
|
end
|
|
|
|
local p = get_player_data(player)
|
|
|
|
if not p then
|
|
return
|
|
end
|
|
|
|
local shared = Public.remove_warp_point(element.parent.name)
|
|
if shared then
|
|
game.print('[Warp] ' .. player.name .. ' removed warp: ' .. element.parent.name, Color.warning)
|
|
else
|
|
player.print('[Warp] Removed warp: ' .. element.parent.name, Color.warning)
|
|
end
|
|
Public.refresh_gui()
|
|
Public.clear_player_table(player)
|
|
end
|
|
)
|
|
|
|
Gui.on_click(
|
|
create_warp_button_name,
|
|
function (event)
|
|
local player = game.get_player(event.player_index)
|
|
|
|
if not validate_player(player) then
|
|
return
|
|
end
|
|
|
|
local p = get_player_data(player)
|
|
|
|
Public.clear_player_table(player)
|
|
|
|
if p.creating == false then
|
|
p.creating = true
|
|
end
|
|
|
|
Public.refresh_gui_player(player)
|
|
end
|
|
)
|
|
|
|
local set_remote_controller_token =
|
|
Token.register(
|
|
function (data)
|
|
local player_index = data.player_index
|
|
local player = game.get_player(player_index)
|
|
if player and player.valid then
|
|
player.set_controller({ type = defines.controllers.remote })
|
|
player.enter_space_platform(player.surface.platform)
|
|
end
|
|
end,
|
|
99999
|
|
)
|
|
|
|
warp_icon_button =
|
|
Gui.new_frame(
|
|
function (event_trigger, parent, warp)
|
|
local warp_position = warp.position
|
|
-- Draw the element
|
|
local sprite = warp.icon.type .. '/' .. warp.icon.name
|
|
if warp.icon.type == 'virtual' then
|
|
sprite = 'virtual-signal/' .. warp.icon.name
|
|
end
|
|
|
|
return parent.add
|
|
{
|
|
name = event_trigger,
|
|
type = 'sprite-button',
|
|
sprite = sprite,
|
|
tooltip = 'Go to: x:' .. warp_position.x .. ' y: ' .. warp_position.y,
|
|
style = 'slot_button'
|
|
}
|
|
end
|
|
):add_style(Gui.Styles[32]):on_click(
|
|
function (player, element, event)
|
|
local p = get_player_data(player)
|
|
|
|
if not p then
|
|
return
|
|
end
|
|
|
|
element = element.parent.caption
|
|
|
|
local warp
|
|
|
|
local position
|
|
|
|
if not SessionData.allowed(player, 'always-warp') then
|
|
if Public.is_spam(p, player) then
|
|
return
|
|
end
|
|
|
|
warp = Public.get_warp_by_name(element)
|
|
if not warp then
|
|
return
|
|
end
|
|
|
|
position = player.position
|
|
|
|
local area =
|
|
{
|
|
left_top = { x = position.x - 5, y = position.y - 5 },
|
|
right_bottom = { x = position.x + 5, y = position.y + 5 }
|
|
}
|
|
|
|
if not Utils.contains_positions(this.warps, area) then
|
|
player.print('[Warp] You are not standing on a warp platform.', Color.warning)
|
|
return
|
|
end
|
|
|
|
if (warp.position.x - position.x) ^ 2 + (warp.position.y - position.y) ^ 2 < 1024 then
|
|
player.print('[Warp] Destination is near source warp: ' .. element, Color.fail)
|
|
return
|
|
end
|
|
else
|
|
warp = Public.get_warp_by_name(element)
|
|
if not warp then
|
|
return
|
|
end
|
|
end
|
|
|
|
if player.vehicle then
|
|
player.vehicle.set_driver(nil)
|
|
end
|
|
if player.vehicle then
|
|
player.vehicle.set_passenger(nil)
|
|
end
|
|
if player.vehicle then
|
|
return
|
|
end
|
|
|
|
local surface = game.get_surface(warp.surface)
|
|
|
|
local button = event.button -- int
|
|
if button == defines.mouse_button_type.right then
|
|
Task.set_timeout_in_ticks(5, set_remote_controller_token, { player_index = player.index })
|
|
p.char = player.character
|
|
elseif button == defines.mouse_button_type.left then
|
|
if not player.character then
|
|
player.set_controller({ type = defines.controllers.character, character = p.char })
|
|
end
|
|
end
|
|
|
|
local non_col = surface.find_non_colliding_position('character', warp.position, 32, 1)
|
|
if non_col then
|
|
player.teleport(non_col, surface)
|
|
player.print('[Warp] Warped you over to: ' .. element, Color.success)
|
|
player.play_sound { path = 'utility/armor_insert', volume_modifier = 1 }
|
|
p.spam = game.tick + 900
|
|
end
|
|
|
|
Public.clear_player_table(player)
|
|
|
|
Public.refresh_gui_player(player, nil, true)
|
|
end
|
|
)
|
|
|
|
Gui.on_click(
|
|
create_warp_func_name,
|
|
function (event)
|
|
local player = game.get_player(event.player_index)
|
|
|
|
if not validate_player(player) then
|
|
return
|
|
end
|
|
|
|
local p = get_player_data(player)
|
|
|
|
local position = player.position
|
|
if not SessionData.allowed(player, 'always-warp') then
|
|
if Public.is_spam(p, player) then
|
|
return
|
|
end
|
|
|
|
local area =
|
|
{
|
|
left_top = { x = position.x - 100, y = position.y - 100 },
|
|
right_bottom = { x = position.x + 100, y = position.y + 100 }
|
|
}
|
|
|
|
if Utils.contains_positions(this.warps, area) then
|
|
player.print('[Warp] You are too close to another warp!', Color.warning)
|
|
return
|
|
end
|
|
end
|
|
|
|
local offset = { x = math.floor(position.x), y = math.floor(position.y) }
|
|
local i = 0
|
|
if not player.surface.name:find('platform') then
|
|
for x = -radius - 2, radius + 2 do
|
|
for y = -radius - 2, radius + 2 do
|
|
if x ^ 2 + y ^ 2 < radius ^ 2 then
|
|
local check_entities =
|
|
player.surface.find_entities_filtered
|
|
{
|
|
area = { { x + offset.x - 1, y + offset.y - 1 }, { x + offset.x, y + offset.y } }
|
|
}
|
|
if check_entities then
|
|
for _, entity in pairs(check_entities) do
|
|
if entity.name ~= 'character' then
|
|
i = i + 1
|
|
end
|
|
end
|
|
if i >= 1 then
|
|
player.print('[Warp] There are entities nearby and warp cannot be created.', Color.warning)
|
|
return
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
local shared = p.shared
|
|
local icon = p.icon
|
|
if not icon then
|
|
icon = { type = 'item', name = warp_item }
|
|
end
|
|
|
|
local new = p.frame.new_name.text
|
|
|
|
if not validate_data(new, player, p) then
|
|
return
|
|
end
|
|
|
|
local player_position = player.position
|
|
p.spam = game.tick + 900
|
|
Public.make_warp_point(player, player_position, player.surface, icon, player.force, new, shared)
|
|
|
|
if p.shared == true then
|
|
game.print('[Warp] ' .. player.name .. ' created warp: ' .. new, Color.success)
|
|
elseif p.shared == false then
|
|
player.print('[Warp] You created warp: ' .. new, Color.success)
|
|
end
|
|
Public.clear_player_table(player)
|
|
Public.refresh_gui()
|
|
end
|
|
)
|
|
|
|
Gui.on_click(
|
|
edit_warp_func_name,
|
|
function (event)
|
|
local player = game.get_player(event.player_index)
|
|
|
|
if not validate_player(player) then
|
|
return
|
|
end
|
|
|
|
local p = get_player_data(player)
|
|
|
|
local shared = p.shared
|
|
local icon = p.icon
|
|
if not icon then
|
|
icon = { type = p.icon.type, name = p.icon.name }
|
|
end
|
|
|
|
local new = p.frame.new_name.text
|
|
|
|
if not validate_data(new, player, p) then
|
|
return
|
|
end
|
|
|
|
p.spam = game.tick + 900
|
|
Public.edit_warp_point(player.surface, icon, player.force, p.edit_warp_name, new, shared)
|
|
|
|
if p.shared == true then
|
|
game.print('[Warp] ' .. player.name .. ' edited warp: ' .. new, Color.success)
|
|
elseif p.shared == false then
|
|
player.print('[Warp] You edited warp: ' .. new, Color.success)
|
|
end
|
|
Public.clear_player_table(player)
|
|
Public.refresh_gui()
|
|
end
|
|
)
|
|
|
|
Gui.on_elem_changed(
|
|
warp_icon_name,
|
|
function (event)
|
|
local player = game.get_player(event.player_index)
|
|
|
|
if not validate_player(player) then
|
|
return
|
|
end
|
|
|
|
local element = event.element
|
|
|
|
if not (element and element.valid) then
|
|
return
|
|
end
|
|
|
|
local p = get_player_data(player)
|
|
if not element.elem_value then
|
|
return
|
|
end
|
|
|
|
p.icon = { type = element.elem_value.type or 'item', name = element.elem_value.name }
|
|
end
|
|
)
|
|
|
|
local reassign_warp_button =
|
|
Token.register(
|
|
function (data)
|
|
local player_index = data.player_index
|
|
local player = game.get_player(player_index)
|
|
if player and player.valid then
|
|
Public.create_warp_button(player)
|
|
end
|
|
end
|
|
)
|
|
|
|
|
|
|
|
Event.add(
|
|
defines.events.on_tick,
|
|
function ()
|
|
if game.tick == 50 then
|
|
Public.make_tag('Spawn', { x = 0, y = 0 }, true)
|
|
end
|
|
end
|
|
)
|
|
|
|
Event.add(defines.events.on_player_died, on_player_died)
|
|
Event.add(defines.events.on_player_created, on_player_joined_game)
|
|
Event.add(defines.events.on_player_left_game, on_player_left_game)
|
|
Event.add(
|
|
ServerCommands.events.on_role_change,
|
|
function (event)
|
|
Task.set_timeout_in_ticks(10, reassign_warp_button, { player_index = event.player_index })
|
|
end
|
|
)
|
|
|
|
Event.add(
|
|
defines.events.on_player_removed,
|
|
function (event)
|
|
Public.remove_player(event.player_index)
|
|
end
|
|
)
|
|
|
|
--- Sets surface name for warp system to use
|
|
---@param name string
|
|
function Public.set_surface_name(name)
|
|
this.surface_name = name or 'nauvis'
|
|
end
|
|
|
|
return Public
|