Добавлены все обновления от сообщества, вплоть до #148
This commit is contained in:
76
Teleporters/script/script_util.lua
Normal file
76
Teleporters/script/script_util.lua
Normal file
@@ -0,0 +1,76 @@
|
||||
local util = require("util")
|
||||
|
||||
local deregister_gui_internal
|
||||
deregister_gui_internal = function(gui_element, data)
|
||||
data[gui_element.index] = nil
|
||||
for k, child in pairs (gui_element.children) do
|
||||
deregister_gui_internal(child, data)
|
||||
end
|
||||
end
|
||||
|
||||
util.deregister_gui = function(gui_element, data)
|
||||
local player_data = data[gui_element.player_index]
|
||||
if not player_data then return end
|
||||
deregister_gui_internal(gui_element, player_data)
|
||||
end
|
||||
|
||||
util.register_gui = function(data, gui_element, param)
|
||||
local player_data = data[gui_element.player_index]
|
||||
if not player_data then
|
||||
data[gui_element.player_index] = {}
|
||||
player_data = data[gui_element.player_index]
|
||||
end
|
||||
player_data[gui_element.index] = param
|
||||
end
|
||||
|
||||
util.gui_action_handler = function(event, data, functions)
|
||||
error("don't actually use me")
|
||||
if not data then error("Gui action handler data is nil") end
|
||||
if not functions then error("Gui action handler functions is nil") end
|
||||
local element = event.element
|
||||
if not (element and element.valid) then return end
|
||||
local player_data = data[event.player_index]
|
||||
if not player_data then return end
|
||||
local action = player_data[element.index]
|
||||
if action then
|
||||
functions[action.type](event, action)
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
util.center = function(area)
|
||||
return {x = (area.left_top.x + area.right_bottom.x) / 2, y = (area.left_top.y + area.right_bottom.y) / 2}
|
||||
end
|
||||
|
||||
util.distance = function(p1, p2)
|
||||
return (((p1.x - p2.x) ^ 2) + ((p1.y - p2.y) ^ 2)) ^ 0.5
|
||||
end
|
||||
|
||||
util.radius = function(area)
|
||||
return util.distance(area.right_bottom, area.left_top) / 2
|
||||
end
|
||||
|
||||
util.clear_item = function(entity, item_name)
|
||||
if not (entity and entity.valid and item_name) then return end
|
||||
entity.remove_item{name = item_name, count = entity.get_item_count(item_name)}
|
||||
end
|
||||
|
||||
util.copy = util.table.deepcopy
|
||||
|
||||
util.first_key = function(map)
|
||||
local k, v = next(map)
|
||||
return k
|
||||
end
|
||||
|
||||
util.first_value = function(map)
|
||||
local k, v = next(map)
|
||||
return v
|
||||
end
|
||||
|
||||
util.angle = function(position_1, position_2)
|
||||
local d_x = (position_2[1] or position_2.x) - (position_1[1] or position_1.x)
|
||||
local d_y = (position_2[2] or position_2.y) - (position_1[2] or position_1.y)
|
||||
return math.atan2(d_y, d_x)
|
||||
end
|
||||
|
||||
return util
|
||||
812
Teleporters/script/teleporters.lua
Normal file
812
Teleporters/script/teleporters.lua
Normal file
@@ -0,0 +1,812 @@
|
||||
local util = require("script/script_util")
|
||||
local names = require("shared")
|
||||
local teleporter_name = names.entities.teleporter
|
||||
local teleporter_sticker = names.entities.teleporter_sticker
|
||||
|
||||
local data =
|
||||
{
|
||||
networks = {},
|
||||
rename_frames = {},
|
||||
button_actions = {},
|
||||
teleporter_map = {},
|
||||
teleporter_frames = {},
|
||||
player_linked_teleporter = {},
|
||||
to_be_removed = {},
|
||||
tag_map = {},
|
||||
search_boxes = {},
|
||||
recent = {}
|
||||
}
|
||||
|
||||
local preview_size = 256
|
||||
|
||||
local debug_print = false
|
||||
local print = function(string)
|
||||
if not debug_print then return end
|
||||
game.print(string)
|
||||
log(string)
|
||||
end
|
||||
|
||||
local create_flash = function(surface, position)
|
||||
surface.create_entity{name = "teleporter-explosion", position = position}
|
||||
for k = 1, 3 do
|
||||
surface.create_entity{name = "teleporter-explosion-no-sound", position = position}
|
||||
end
|
||||
end
|
||||
|
||||
local clear_gui = function(frame)
|
||||
if not (frame and frame.valid) then return end
|
||||
util.deregister_gui(frame, data.button_actions)
|
||||
frame.clear()
|
||||
end
|
||||
|
||||
local close_gui = function(frame)
|
||||
if not (frame and frame.valid) then return end
|
||||
util.deregister_gui(frame, data.button_actions)
|
||||
frame.destroy()
|
||||
end
|
||||
|
||||
local get_rename_frame = function(player)
|
||||
local frame = data.rename_frames[player.index]
|
||||
if frame and frame.valid then return frame end
|
||||
data.rename_frames[player.index] = nil
|
||||
end
|
||||
|
||||
local get_teleporter_frame = function(player)
|
||||
local frame = data.teleporter_frames[player.index]
|
||||
if frame and frame.valid then return frame end
|
||||
data.teleporter_frames[player.index] = nil
|
||||
end
|
||||
|
||||
local make_rename_frame = function(player, caption)
|
||||
|
||||
local teleporter_frame = get_teleporter_frame(player)
|
||||
if teleporter_frame then
|
||||
teleporter_frame.ignored_by_interaction = true
|
||||
end
|
||||
|
||||
player.opened = nil
|
||||
|
||||
local force = player.force
|
||||
local teleporters = data.networks[force.name]
|
||||
local param = teleporters[caption]
|
||||
local text = param.flying_text
|
||||
local gui = player.gui.screen
|
||||
local frame = gui.add{type = "frame", caption = {"gui-train-rename.title", caption}, direction = "horizontal"}
|
||||
frame.auto_center = true
|
||||
player.opened = frame
|
||||
data.rename_frames[player.index] = frame
|
||||
|
||||
|
||||
|
||||
local textfield = frame.add{type = "textfield", text = caption}
|
||||
textfield.style.horizontally_stretchable = true
|
||||
textfield.focus()
|
||||
textfield.select_all()
|
||||
util.register_gui(data.button_actions, textfield, {type = "confirm_rename_textfield", textfield = textfield, flying_text = text, tag = param.tag})
|
||||
|
||||
local confirm = frame.add{type = "sprite-button", sprite = "utility/enter", style = "tool_button", tooltip = {"gui-train-rename.perform-change"}}
|
||||
util.register_gui(data.button_actions, confirm, {type = "confirm_rename_button", textfield = textfield, flying_text = text, tag = param.tag})
|
||||
|
||||
end
|
||||
|
||||
local get_force_color = function(force)
|
||||
local player = force.connected_players[1]
|
||||
if player and player.valid then
|
||||
return player.chat_color
|
||||
end
|
||||
return {r = 1, b = 1, g = 1}
|
||||
end
|
||||
|
||||
local add_recent = function(player, teleporter)
|
||||
local recent = data.recent[player.name]
|
||||
if not recent then
|
||||
recent = {}
|
||||
data.recent[player.name] = recent
|
||||
end
|
||||
recent[teleporter.unit_number] = game.tick
|
||||
if table_size(recent) >= 9 then
|
||||
local min = math.huge
|
||||
local index
|
||||
for k, tick in pairs (recent) do
|
||||
if tick < min then
|
||||
min = tick
|
||||
index = k
|
||||
end
|
||||
end
|
||||
if index then recent[index] = nil end
|
||||
end
|
||||
end
|
||||
|
||||
local unlink_teleporter = function(player)
|
||||
if player.character then player.character.active = true end
|
||||
close_gui(get_teleporter_frame(player))
|
||||
local source = data.player_linked_teleporter[player.index]
|
||||
if source and source.valid then
|
||||
source.active = true
|
||||
add_recent(player, source)
|
||||
end
|
||||
data.player_linked_teleporter[player.index] = nil
|
||||
end
|
||||
|
||||
local clear_teleporter_data = function(teleporter_data)
|
||||
local flying_text = teleporter_data.flying_text
|
||||
if flying_text and flying_text.valid then
|
||||
flying_text.destroy()
|
||||
end
|
||||
local map_tag = teleporter_data.tag
|
||||
if map_tag and map_tag.valid then
|
||||
data.tag_map[map_tag.tag_number] = nil
|
||||
map_tag.destroy()
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local get_sort_function = function()
|
||||
return
|
||||
function(t, a, b) return a < b end
|
||||
end
|
||||
|
||||
local make_teleporter_gui = function(player, source)
|
||||
|
||||
local location
|
||||
local teleporter_frame = get_teleporter_frame(player)
|
||||
if teleporter_frame then
|
||||
location = teleporter_frame.location
|
||||
data.teleporter_frames[player.index] = nil
|
||||
print("Frame already exists")
|
||||
close_gui(teleporter_frame)
|
||||
player.opened = nil
|
||||
end
|
||||
|
||||
print("Making new frame")
|
||||
|
||||
if not (source and source.valid and not data.to_be_removed[source.unit_number]) then
|
||||
unlink_teleporter(player)
|
||||
return
|
||||
end
|
||||
|
||||
local force = source.force
|
||||
local network = data.networks[force.name]
|
||||
if not network then return end
|
||||
|
||||
local gui = player.gui.screen
|
||||
local frame = gui.add{type = "frame", direction = "vertical", ignored_by_interaction = false}
|
||||
if location then
|
||||
frame.location = location
|
||||
else
|
||||
frame.auto_center = true
|
||||
end
|
||||
|
||||
player.opened = frame
|
||||
data.teleporter_frames[player.index] = frame
|
||||
frame.ignored_by_interaction = false
|
||||
local title_flow = frame.add{type = "flow", direction = "horizontal"}
|
||||
title_flow.style.vertical_align = "center"
|
||||
local title = title_flow.add{type = "label", style = "heading_1_label"}
|
||||
title.drag_target = frame
|
||||
local rename_button = title_flow.add{type = "sprite-button", sprite = "utility/rename_icon_small_white", style = "frame_action_button", visible = source.force == player.force}
|
||||
local pusher = title_flow.add{type = "empty-widget", direction = "horizontal", style = "draggable_space_header"}
|
||||
pusher.style.horizontally_stretchable = true
|
||||
pusher.style.vertically_stretchable = true
|
||||
pusher.drag_target = frame
|
||||
local search_box = title_flow.add{type = "textfield", visible = false}
|
||||
local search_button = title_flow.add{type = "sprite-button", style = "frame_action_button", sprite = "utility/search_white", tooltip = {"gui.search-with-focus", {"search"}}}
|
||||
util.register_gui(data.button_actions, search_button, {type = "search_button", box = search_box})
|
||||
data.search_boxes[player.index] = search_box
|
||||
local inner = frame.add{type = "frame", style = "inside_deep_frame"}
|
||||
local scroll = inner.add{type = "scroll-pane", direction = "vertical"}
|
||||
scroll.style.maximal_height = (player.display_resolution.height / player.display_scale) * 0.8
|
||||
local column_count = ((player.display_resolution.width / player.display_scale) * 0.6) / preview_size
|
||||
local holding_table = scroll.add{type = "table", column_count = column_count}
|
||||
util.register_gui(data.button_actions, search_box, {type = "search_text_changed", parent = holding_table})
|
||||
holding_table.style.horizontal_spacing = 2
|
||||
holding_table.style.vertical_spacing = 2
|
||||
local any = false
|
||||
--print(table_size(network))
|
||||
|
||||
local recent = data.recent[player.name] or {}
|
||||
|
||||
local sorted = {}
|
||||
local i = 1
|
||||
for name, teleporter in pairs (network) do
|
||||
if teleporter.teleporter.valid then
|
||||
sorted[i] = {name = name, teleporter = teleporter, unit_number = teleporter.teleporter.unit_number}
|
||||
i = i + 1
|
||||
else
|
||||
clear_teleporter_data(teleporter)
|
||||
end
|
||||
end
|
||||
|
||||
table.sort(sorted, function(a, b)
|
||||
if recent[a.unit_number] and recent[b.unit_number] then
|
||||
return recent[a.unit_number] > recent[b.unit_number]
|
||||
end
|
||||
|
||||
if recent[a.unit_number] then
|
||||
return true
|
||||
end
|
||||
|
||||
if recent[b.unit_number] then
|
||||
return false
|
||||
end
|
||||
|
||||
return a.name:lower() < b.name:lower()
|
||||
end)
|
||||
|
||||
local sorted_network = {}
|
||||
for k, sorted_data in pairs (sorted) do
|
||||
sorted_network[sorted_data.name] = sorted_data.teleporter
|
||||
end
|
||||
|
||||
local chart = player.force.chart
|
||||
for name, teleporter in pairs(sorted_network) do
|
||||
local teleporter_entity = teleporter.teleporter
|
||||
if not (teleporter_entity.valid) then
|
||||
clear_teleporter_data(teleporter)
|
||||
elseif teleporter_entity == source then
|
||||
title.caption = name
|
||||
util.register_gui(data.button_actions, rename_button, {type = "rename_button", caption = name})
|
||||
else
|
||||
local position = teleporter_entity.position
|
||||
local area = {{position.x - preview_size / 2, position.y - preview_size / 2}, {position.x + preview_size / 2, position.y + preview_size / 2}}
|
||||
chart(teleporter_entity.surface, area)
|
||||
local button = holding_table.add{type = "button", name = "_"..name}
|
||||
button.style.height = preview_size + 32 + 8
|
||||
button.style.width = preview_size + 8
|
||||
button.style.left_padding = 0
|
||||
button.style.right_padding = 0
|
||||
local inner_flow = button.add{type = "flow", direction = "vertical", ignored_by_interaction = true}
|
||||
inner_flow.style.vertically_stretchable = true
|
||||
inner_flow.style.horizontally_stretchable = true
|
||||
inner_flow.style.horizontal_align = "center"
|
||||
local map = inner_flow.add
|
||||
{
|
||||
type = "minimap",
|
||||
surface_index = teleporter_entity.surface.index,
|
||||
zoom = 1,
|
||||
force = teleporter_entity.force.name,
|
||||
position = position,
|
||||
}
|
||||
map.ignored_by_interaction = true
|
||||
map.style.height = preview_size
|
||||
map.style.width = preview_size
|
||||
map.style.horizontally_stretchable = true
|
||||
map.style.vertically_stretchable = true
|
||||
local caption = name
|
||||
if recent[teleporter_entity.unit_number] then
|
||||
caption = "[img=quantity-time] "..name
|
||||
end
|
||||
local label = inner_flow.add{type = "label", caption = caption}
|
||||
label.style.horizontally_stretchable = true
|
||||
label.style.font = "default-dialog-button"
|
||||
label.style.font_color = {}
|
||||
label.style.horizontally_stretchable = true
|
||||
label.style.maximal_width = preview_size
|
||||
util.register_gui(data.button_actions, button, {type = "teleport_button", param = teleporter})
|
||||
any = true
|
||||
end
|
||||
end
|
||||
if not any then
|
||||
holding_table.add{type = "label", caption = {"no-teleporters"}}
|
||||
end
|
||||
end
|
||||
|
||||
function spairs(t, order)
|
||||
-- collect the keys
|
||||
local keys = {}
|
||||
for k in pairs(t) do keys[#keys+1] = k end
|
||||
|
||||
-- if order function given, sort by it by passing the table and keys a, b,
|
||||
-- otherwise just sort the keys
|
||||
if order then
|
||||
table.sort(keys, function(a,b) return order(t, a, b) end)
|
||||
else
|
||||
table.sort(keys)
|
||||
end
|
||||
|
||||
-- return the iterator function
|
||||
local i = 0
|
||||
return function()
|
||||
i = i + 1
|
||||
if keys[i] then
|
||||
return keys[i], t[keys[i]]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local refresh_teleporter_frames = function()
|
||||
local players = game.players
|
||||
for player_index, source in pairs (data.player_linked_teleporter) do
|
||||
local player = players[player_index]
|
||||
local frame = get_teleporter_frame(player)
|
||||
if frame then
|
||||
print("Refreshing frame")
|
||||
make_teleporter_gui(player, source)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local check_player_linked_teleporter = function(player)
|
||||
print("Checking player linked teleporter")
|
||||
local source = data.player_linked_teleporter[player.index]
|
||||
if source and source.valid then
|
||||
print("Linked teleporter exists...")
|
||||
make_teleporter_gui(player, source)
|
||||
else
|
||||
print("Unlinnkgin")
|
||||
unlink_teleporter(player)
|
||||
end
|
||||
end
|
||||
|
||||
local resync_teleporter = function(name, teleporter_data)
|
||||
local teleporter = teleporter_data.teleporter
|
||||
if not (teleporter and teleporter.valid) then
|
||||
return
|
||||
end
|
||||
local force = teleporter.force
|
||||
local surface = teleporter.surface
|
||||
local color = get_force_color(force)
|
||||
|
||||
clear_teleporter_data(teleporter_data)
|
||||
|
||||
local flying_text = teleporter.surface.create_entity
|
||||
{
|
||||
name = "teleporter-flying-text",
|
||||
text = name,
|
||||
position = {teleporter.position.x, teleporter.position.y - 2},
|
||||
force = force,
|
||||
color = color
|
||||
}
|
||||
flying_text.active = false
|
||||
teleporter_data.flying_text = flying_text
|
||||
|
||||
data.adding_tag = true
|
||||
local map_tag = force.add_chart_tag(surface,
|
||||
{
|
||||
icon = {type = "item", name = teleporter_name},
|
||||
position = teleporter.position,
|
||||
text = name
|
||||
})
|
||||
data.adding_tag = false
|
||||
|
||||
if map_tag then
|
||||
teleporter_data.tag = map_tag
|
||||
data.tag_map[map_tag.tag_number] = teleporter_data
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
local is_name_available = function(force, name)
|
||||
local network = data.networks[force.name]
|
||||
return not network[name]
|
||||
end
|
||||
|
||||
local rename_teleporter = function(force, old_name, new_name)
|
||||
if old_name == new_name then
|
||||
refresh_teleporter_frames()
|
||||
return
|
||||
end
|
||||
local network = data.networks[force.name]
|
||||
local teleporter_data = network[old_name]
|
||||
network[new_name] = teleporter_data
|
||||
network[old_name] = nil
|
||||
resync_teleporter(new_name, teleporter_data)
|
||||
refresh_teleporter_frames()
|
||||
end
|
||||
|
||||
local gui_actions =
|
||||
{
|
||||
rename_button = function(event, param)
|
||||
make_rename_frame(game.get_player(event.player_index), param.caption)
|
||||
end,
|
||||
cancel_rename = function(event, param)
|
||||
local player = game.get_player(event.player_index)
|
||||
close_gui(get_rename_frame(player))
|
||||
|
||||
print("On cancel rename linked check")
|
||||
check_player_linked_teleporter(player)
|
||||
end,
|
||||
confirm_rename_button = function(event, param)
|
||||
if event.name ~= defines.events.on_gui_click then return end
|
||||
local flying_text = param.flying_text
|
||||
if not (flying_text and flying_text.valid) then return end
|
||||
local player = game.players[event.player_index]
|
||||
if not (player and player.valid) then return end
|
||||
local old_name = flying_text.text
|
||||
local new_name = param.textfield.text
|
||||
|
||||
if new_name ~= old_name and not is_name_available(player.force, new_name) then
|
||||
player.print({"name-already-taken"})
|
||||
return
|
||||
end
|
||||
|
||||
close_gui(get_rename_frame(player))
|
||||
rename_teleporter(player.force, old_name, new_name)
|
||||
|
||||
print("On rename linked check")
|
||||
--check_player_linked_teleporter(player)
|
||||
end,
|
||||
confirm_rename_textfield = function(event, param)
|
||||
if event.name ~= defines.events.on_gui_confirmed then return end
|
||||
local flying_text = param.flying_text
|
||||
if not (flying_text and flying_text.valid) then return end
|
||||
local player = game.players[event.player_index]
|
||||
if not (player and player.valid) then return end
|
||||
local old_name = flying_text.text
|
||||
local new_name = param.textfield.text
|
||||
|
||||
if new_name ~= old_name and not is_name_available(player.force, new_name) then
|
||||
player.print({"name-already-taken"})
|
||||
return
|
||||
end
|
||||
|
||||
close_gui(get_rename_frame(player))
|
||||
rename_teleporter(player.force, old_name, new_name)
|
||||
|
||||
print("On rename linked check")
|
||||
--check_player_linked_teleporter(player)
|
||||
end,
|
||||
teleport_button = function(event, param)
|
||||
local teleport_param = param.param
|
||||
if not teleport_param then return end
|
||||
local destination = teleport_param.teleporter
|
||||
if not (destination and destination.valid) then return end
|
||||
destination.timeout = destination.prototype.timeout
|
||||
local destination_surface = destination.surface
|
||||
local destination_position = destination.position
|
||||
local player = game.players[event.player_index]
|
||||
if not (player and player.valid) then return end
|
||||
create_flash(destination_surface, destination_position)
|
||||
create_flash(player.surface, player.position)
|
||||
--This teleport doesn't check collisions. If someone complains, make it check 'can_place' and if false find a positions etc....
|
||||
player.teleport(destination_position, destination_surface)
|
||||
unlink_teleporter(player)
|
||||
add_recent(player, destination)
|
||||
end,
|
||||
|
||||
search_text_changed = function(event, param)
|
||||
local box = event.element
|
||||
local search = box.text
|
||||
local parent = param.parent
|
||||
for k, child in pairs (parent.children) do
|
||||
child.visible = child.name:lower():find(search:lower(), 1, true)
|
||||
end
|
||||
end,
|
||||
search_button = function(event, param)
|
||||
param.box.visible = not param.box.visible
|
||||
if param.box.visible then param.box.focus() end
|
||||
end
|
||||
}
|
||||
|
||||
local get_network = function(force)
|
||||
local name = force.name
|
||||
local network = data.networks[name]
|
||||
if network then return network end
|
||||
data.networks[name] = {}
|
||||
return data.networks[name]
|
||||
end
|
||||
|
||||
local on_built_entity = function(event)
|
||||
local entity = event.created_entity or event.entity or event.destination
|
||||
if not (entity and entity.valid) then return end
|
||||
if entity.name ~= teleporter_name then return end
|
||||
local surface = entity.surface
|
||||
local force = entity.force
|
||||
local name = "Teleporter ".. entity.unit_number
|
||||
local network = get_network(force)
|
||||
local teleporter_data = {teleporter = entity, flying_text = text, tag = tag}
|
||||
network[name] = teleporter_data
|
||||
data.teleporter_map[entity.unit_number] = teleporter_data
|
||||
resync_teleporter(name, teleporter_data)
|
||||
refresh_teleporter_frames()
|
||||
end
|
||||
|
||||
local on_teleporter_removed = function(entity)
|
||||
if not (entity and entity.valid) then return end
|
||||
if entity.name ~= teleporter_name then return end
|
||||
local force = entity.force
|
||||
local teleporter_data = data.teleporter_map[entity.unit_number]
|
||||
if not teleporter_data then return end
|
||||
local caption = teleporter_data.flying_text.text
|
||||
local network = get_network(force)
|
||||
network[caption] = nil
|
||||
clear_teleporter_data(teleporter_data)
|
||||
data.teleporter_map[entity.unit_number] = nil
|
||||
|
||||
data.to_be_removed[entity.unit_number] = true
|
||||
refresh_teleporter_frames()
|
||||
data.to_be_removed[entity.unit_number] = nil
|
||||
end
|
||||
|
||||
local teleporter_triggered = function(entity, character)
|
||||
if not (entity and entity.valid and entity.name == teleporter_name) then return error("HEOK") end
|
||||
if character.type ~= "character" then return end
|
||||
local force = entity.force
|
||||
local surface = entity.surface
|
||||
local position = entity.position
|
||||
local param = data.teleporter_map[entity.unit_number]
|
||||
local player = character.player
|
||||
if not player then return end
|
||||
player.teleport(entity.position)
|
||||
entity.active = false
|
||||
entity.timeout = entity.prototype.timeout
|
||||
character.active = false
|
||||
data.player_linked_teleporter[player.index] = entity
|
||||
make_teleporter_gui(player, entity)
|
||||
end
|
||||
|
||||
local on_entity_removed = function(event)
|
||||
local entity = event.entity
|
||||
if not (entity and entity.valid) then return end
|
||||
on_teleporter_removed(entity)
|
||||
end
|
||||
|
||||
|
||||
local on_entity_died = function(event)
|
||||
on_teleporter_removed(event.entity)
|
||||
end
|
||||
|
||||
local on_player_mined_entity = function(event)
|
||||
on_teleporter_removed(event.entity)
|
||||
end
|
||||
|
||||
local on_robot_mined_entity = function(event)
|
||||
on_teleporter_removed(event.entity)
|
||||
end
|
||||
|
||||
local on_gui_action = function(event)
|
||||
local element = event.element
|
||||
if not (element and element.valid) then return end
|
||||
local player_data = data.button_actions[event.player_index]
|
||||
if not player_data then return end
|
||||
local action = player_data[element.index]
|
||||
if action then
|
||||
gui_actions[action.type](event, action)
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local on_gui_closed = function(event)
|
||||
--print("CLOSED "..event.tick)
|
||||
local element = event.element
|
||||
if not element then return end
|
||||
|
||||
local player = game.get_player(event.player_index)
|
||||
|
||||
local rename_frame = get_rename_frame(player)
|
||||
if rename_frame and rename_frame == element then
|
||||
close_gui(rename_frame)
|
||||
print("Closed rename frame, checking player linked")
|
||||
check_player_linked_teleporter(player)
|
||||
return
|
||||
end
|
||||
|
||||
local teleporter_frame = get_teleporter_frame(player)
|
||||
if teleporter_frame and teleporter_frame == element and not teleporter_frame.ignored_by_interaction then
|
||||
close_gui(teleporter_frame)
|
||||
unlink_teleporter(player)
|
||||
print("Frame unlinked")
|
||||
return
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
local on_player_removed = function(event)
|
||||
local player = game.get_player(event.player_index)
|
||||
close_gui(get_rename_frame(player))
|
||||
unlink_teleporter(player)
|
||||
end
|
||||
|
||||
local resync_all_teleporters = function()
|
||||
for force, network in pairs (data.networks) do
|
||||
for name, teleporter_data in pairs (network) do
|
||||
resync_teleporter(name, teleporter_data)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local on_chart_tag_modified = function(event)
|
||||
local force = event.force
|
||||
local tag = event.tag
|
||||
if not (force and force.valid and tag and tag.valid) then return end
|
||||
local teleporter_data = data.tag_map[tag.tag_number]
|
||||
if not teleporter_data then
|
||||
--Nothing to do with us...
|
||||
return
|
||||
end
|
||||
local player = event.player_index and game.get_player(event.player_index)
|
||||
|
||||
local old_name = event.old_text
|
||||
local new_name = tag.text
|
||||
if tag.icon and tag.icon.name ~= teleporter_name then
|
||||
--They're trying to modify the icon! Straight to JAIL!
|
||||
if player and player.valid then player.print({"cant-change-icon"}) end
|
||||
tag.icon = {type = "item", name = teleporter_name}
|
||||
end
|
||||
if new_name == old_name then
|
||||
return
|
||||
end
|
||||
if new_name == "" or not is_name_available(force, new_name) then
|
||||
if player and player.valid then
|
||||
player.print({"name-already-taken"})
|
||||
end
|
||||
tag.text = old_name
|
||||
return
|
||||
end
|
||||
rename_teleporter(force, old_name, new_name)
|
||||
end
|
||||
|
||||
local on_chart_tag_removed = function(event)
|
||||
local force = event.force
|
||||
local tag = event.tag
|
||||
if not (force and force.valid and tag and tag.valid) then return end
|
||||
local teleporter_data = data.tag_map[tag.tag_number]
|
||||
if not teleporter_data then
|
||||
--Nothing to do with us...
|
||||
return
|
||||
end
|
||||
local name = tag.text
|
||||
resync_teleporter(name, teleporter_data)
|
||||
end
|
||||
|
||||
local on_chart_tag_added = function(event)
|
||||
if data.adding_tag then return end
|
||||
local tag = event.tag
|
||||
if not (tag and tag.valid) then
|
||||
return
|
||||
end
|
||||
local icon = tag.icon
|
||||
if icon and icon.type == "item" and icon.name == teleporter_name then
|
||||
--Trying to add a fake teleporter tag! JAIL!
|
||||
local player = event.player_index and game.get_player(event.player_index)
|
||||
if player and player.valid then player.print({"cant-add-tag"}) end
|
||||
tag.destroy()
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
local toggle_search = function(player)
|
||||
local box = data.search_boxes[player.index]
|
||||
if not (box and box.valid) then return end
|
||||
box.visible = true
|
||||
box.focus()
|
||||
end
|
||||
|
||||
local on_search_focused = function(event)
|
||||
local player = game.get_player(event.player_index)
|
||||
toggle_search(player)
|
||||
end
|
||||
|
||||
local on_player_display_resolution_changed = function(event)
|
||||
local player = game.get_player(event.player_index)
|
||||
check_player_linked_teleporter(player)
|
||||
end
|
||||
|
||||
local on_player_display_scale_changed = function(event)
|
||||
local player = game.get_player(event.player_index)
|
||||
check_player_linked_teleporter(player)
|
||||
end
|
||||
|
||||
local on_trigger_created_entity = function(event)
|
||||
local entity = event.entity
|
||||
if not (entity and entity.valid) then return end
|
||||
if entity.name ~= teleporter_sticker then return end
|
||||
local source = event.source
|
||||
if not (source and source.valid) then return end
|
||||
local stuck_to = entity.sticked_to
|
||||
if not (stuck_to and stuck_to.valid) then return end
|
||||
teleporter_triggered(source, stuck_to)
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
local on_rocket_launched = function(event)
|
||||
local rocket = event.rocket
|
||||
if not (rocket and rocket.valid) then return end
|
||||
|
||||
local count = rocket.get_item_count(teleporter_name)
|
||||
if count == 0 then return end
|
||||
|
||||
local rand = math.random
|
||||
local rando = function(i)
|
||||
return rand() * (i or 5)
|
||||
end
|
||||
|
||||
local rando_autoplace = function(i)
|
||||
return
|
||||
{
|
||||
frequency = rando(i),
|
||||
richness = rando(i),
|
||||
size = rando(i)
|
||||
}
|
||||
end
|
||||
|
||||
local settings = rocket.surface.map_gen_settings
|
||||
|
||||
for name, autoplace in pairs(settings.autoplace_controls) do
|
||||
settings.autoplace_controls[name] = rando_autoplace(rando(2))
|
||||
end
|
||||
|
||||
settings.cliff_settings =
|
||||
{
|
||||
cliff_elevation_0 = rando(20),
|
||||
cliff_elevation_interval = rando(80),
|
||||
name = "cliff",
|
||||
richness = 1
|
||||
}
|
||||
|
||||
settings.seed = math.floor(rando(2 ^ 32))
|
||||
settings.terrain_segmentation = rando(3)
|
||||
settings.water = rando(3)
|
||||
settings.starting_area = rando(3)
|
||||
|
||||
local new_surface = game.create_surface("teleporter_surface"..game.tick..settings.seed, settings)
|
||||
|
||||
new_surface.create_entity{name = teleporter_name, position = {0, 0}, force = rocket.force, raise_built = true}
|
||||
|
||||
end
|
||||
|
||||
local teleporters = {}
|
||||
|
||||
teleporters.events =
|
||||
{
|
||||
[defines.events.on_built_entity] = on_built_entity,
|
||||
[defines.events.on_robot_built_entity] = on_built_entity,
|
||||
[defines.events.script_raised_built] = on_built_entity,
|
||||
[defines.events.script_raised_revive] = on_built_entity,
|
||||
[defines.events.on_entity_cloned] = on_built_entity,
|
||||
|
||||
[defines.events.on_entity_died] = on_entity_removed,
|
||||
[defines.events.on_player_mined_entity] = on_entity_removed,
|
||||
[defines.events.on_robot_mined_entity] = on_entity_removed,
|
||||
[defines.events.script_raised_destroy] = on_entity_removed,
|
||||
|
||||
[defines.events.on_gui_click] = on_gui_action,
|
||||
[defines.events.on_gui_text_changed] = on_gui_action,
|
||||
[defines.events.on_gui_confirmed] = on_gui_action,
|
||||
[defines.events.on_gui_closed] = on_gui_closed,
|
||||
[require("shared").hotkeys.focus_search] = on_search_focused,
|
||||
[defines.events.on_player_display_resolution_changed] = on_player_display_resolution_changed,
|
||||
[defines.events.on_player_display_scale_changed] = on_player_display_scale_changed,
|
||||
|
||||
[defines.events.on_player_died] = on_player_removed,
|
||||
[defines.events.on_player_left_game] = on_player_removed,
|
||||
[defines.events.on_player_changed_force] = on_player_removed,
|
||||
|
||||
[defines.events.on_chart_tag_modified] = on_chart_tag_modified,
|
||||
[defines.events.on_chart_tag_removed] = on_chart_tag_removed,
|
||||
[defines.events.on_chart_tag_added] = on_chart_tag_added,
|
||||
|
||||
[defines.events.on_trigger_created_entity] = on_trigger_created_entity,
|
||||
[defines.events.on_rocket_launched] = on_rocket_launched
|
||||
|
||||
}
|
||||
|
||||
teleporters.on_init = function()
|
||||
global.teleporters = global.teleporters or data
|
||||
end
|
||||
|
||||
teleporters.on_load = function()
|
||||
data = global.teleporters
|
||||
end
|
||||
|
||||
teleporters.on_configuration_changed = function()
|
||||
-- 0.1.2 migration...
|
||||
data.player_linked_teleporter = data.player_linked_teleporter or {}
|
||||
data.rename_frames = data.rename_frames or data.frames or {}
|
||||
data.to_be_removed = data.to_be_removed or {}
|
||||
|
||||
--0.1.5...
|
||||
data.teleporter_map = data.teleporter_map or data.map or {}
|
||||
data.tag_map = data.tag_map or {}
|
||||
resync_all_teleporters()
|
||||
|
||||
--0.1.7...
|
||||
data.search_boxes = data.search_boxes or {}
|
||||
|
||||
data.recent = data.recent or {}
|
||||
end
|
||||
|
||||
return teleporters
|
||||
Reference in New Issue
Block a user