1
0
mirror of https://github.com/ComfyFactory/ComfyFactorio.git synced 2025-01-08 00:39:30 +02:00
ComfyFactorio/modules/team_teleport.lua
2019-06-07 11:18:08 +02:00

230 lines
9.1 KiB
Lua

local event = require 'utils.event'
local function teleport_player(surface, source_player, position)
local materializing_characters = source_player.surface.find_entities_filtered({
name = "character",
area = {{position.x - 1, position.y - 1},{position.x + 1, position.y + 1}},
force = "neutral"
})
for _, e in pairs(materializing_characters) do
if e.valid then e.destroy() end
end
if not source_player.character then return end
surface.create_entity({name = "character-corpse", position = source_player.position, force = source_player.force.name})
source_player.teleport(position, surface)
if source_player.character.health < 25 then source_player.character.health = 250 end
global.team_teleport_delay[source_player.name] = game.tick + 18000
end
local function fix_player_position(source_player, original_position)
if not source_player.character then return end
if source_player.position.x == original_position.x and source_player.position.y == original_position.y then return end
source_player.teleport(original_position, source_player.surface)
end
local function teleport_effects(surface, position)
local x = position.x + (4 - (math.random(1,80) * 0.1))
surface.create_entity({
name = "railgun-beam",
position = {x = position.x, y = position.y},
target = {x = x, y = position.y - math.random(6,13)}
})
for y = 0, 1, 1 do
surface.create_entity({
name = "water-splash",
position = {x = position.x, y = position.y + y},
})
end
if math.random(1,40) == 1 then surface.create_entity({name = "explosion", position = {x = position.x + (3 - (math.random(1,60) * 0.1)), y = position.y + (3 - (math.random(1,60) * 0.1))}}) end
if math.random(1,32) == 1 then surface.create_entity({name = "blood-explosion-huge", position = position}) end
if math.random(1,16) == 1 then surface.create_entity({name = "blood-explosion-big", position = position}) end
if math.random(1,8) == 1 then surface.create_entity({name = "blood-explosion-small", position = position}) end
end
local function sync_health_and_direction(player, materializing_character)
if not player.character then return end
if not player.character.valid then return end
if not materializing_character then return end
if not materializing_character.valid then return end
materializing_character.health = materializing_character.health + 2
materializing_character.direction = player.character.direction
if player.character.health < 3 then player.character.health = 1 return end
if player.character.health == 250 then player.character.damage(2, "player") return end
if math.random(1,64) == 1 then player.character.damage(2, "player") return end
player.character.health = player.character.health - 2
end
local function teleport(source_player, target_player)
source_player.teleport({x = math.floor(source_player.position.x), y = math.floor(source_player.position.y)})
local target_position = target_player.surface.find_non_colliding_position("character", target_player.position, 128, 1)
if not target_position then target_position = {x = target_player.position.x, y = target_player.position.y} end
local materializing_character = target_player.surface.create_entity({name = "character", position = target_position, force = "neutral", direction = source_player.character.direction})
materializing_character.destructible = false
materializing_character.color = source_player.color
materializing_character.damage(1, "player")
materializing_character.health = 1
local a = 20
for t = 0, 780, 1 do
if not global.on_tick_schedule[game.tick + t] then global.on_tick_schedule[game.tick + t] = {} end
if t % a == 0 then
global.on_tick_schedule[game.tick + t][#global.on_tick_schedule[game.tick + t] + 1] = {
func = teleport_effects,
args = {source_player.surface, {x = source_player.position.x, y = source_player.position.y}}
}
global.on_tick_schedule[game.tick + t][#global.on_tick_schedule[game.tick + t] + 1] = {
func = teleport_effects,
args = {source_player.surface, target_position}
}
global.on_tick_schedule[game.tick + t][#global.on_tick_schedule[game.tick + t] + 1] = {
func = sync_health_and_direction,
args = {source_player, materializing_character}
}
a = a - 0.5
if a < 5 then a = 5 end
end
if t % 2 == 0 then
global.on_tick_schedule[game.tick + t][#global.on_tick_schedule[game.tick + t] + 1] = {
func = fix_player_position,
args = {source_player, {x = source_player.position.x, y = source_player.position.y}}
}
end
if t == 780 then
global.on_tick_schedule[game.tick + t][#global.on_tick_schedule[game.tick + t] + 1] = {
func = teleport_player,
args = {target_player.surface, source_player, target_position}
}
end
end
end
local function get_sorted_player_table(requesting_player)
local t = {}
for _, player in pairs(game.connected_players) do
if player.name ~= requesting_player.name and player.force == requesting_player.force then
local distance = math.ceil(math.sqrt((player.position.x - requesting_player.position.x)^2 + (player.position.y - requesting_player.position.y)^2) * 10) * 0.1
table.insert(t, {name = player.name, distance = distance})
end
end
for i = 1, #t, 1 do
for i2 = 1, #t, 1 do
if t[i].distance > t[i2].distance then
local k = t[i]
t[i] = t[i2]
t[i2] = k
end
end
end
return t
end
local function create_gui_toggle_button(player)
if player.gui.top["team_teleport_button"] then return end
local b = player.gui.top.add({type = "sprite-button", name = "team_teleport_button", caption = "TP", tooltip = "Teleport to a Team Member"})
b.style.font_color = {r = 0.55, g = 0.22, b = 0.77}
b.style.font = "heading-1"
b.style.minimal_height = 38
b.style.minimal_width = 38
b.style.top_padding = 2
b.style.left_padding = 4
b.style.right_padding = 4
b.style.bottom_padding = 2
end
local function create_teleport_gui(player)
if player.gui.center["team_teleport"] then player.gui.center["team_teleport"].destroy() end
local frame = player.gui.center.add({type = "frame", name = "team_teleport", caption = "<< Teleport to player >>"})
frame.style.font_color = {r = 0.55, g = 0.22, b = 0.77}
frame.style.font = "heading-1"
local scroll_pane = frame.add({ type = "scroll-pane", name = "scroll_pane", direction = "vertical", horizontal_scroll_policy = "never", vertical_scroll_policy = "auto"})
scroll_pane.style.maximal_height = 320
scroll_pane.style.minimal_height = 320
local t = scroll_pane.add({type = "table", column_count = 3, name = "team_teleport_table"})
local player_table = get_sorted_player_table(player)
for _, k in pairs(player_table) do
local l = t.add({type = "button", name = k.name, caption = k.name})
l.style.font_color = {r = game.players[k.name].color.r * 0.5, g = game.players[k.name].color.g * 0.5, b = game.players[k.name].color.b * 0.5}
l.style.font = "heading-2"
l.style.minimal_width = 120
local l = t.add({type = "label", caption = " Distance: "})
l.style.font = "heading-2"
local l = t.add({type = "label", caption = tostring(k.distance)})
l.style.font_color = {r = 0.66, g = 0.66, b = 0.99}
l.style.font = "heading-2"
l.style.minimal_width = 100
end
end
local function on_gui_click(event)
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.player_index]
local name = event.element.name
if name == "team_teleport_button" then
if player.gui.center["team_teleport"] then
player.gui.center["team_teleport"].destroy()
return
else
create_teleport_gui(player)
return
end
end
if not game.players[name] then return end
if event.element.parent.name ~= "team_teleport_table" then return end
if not player.character then return end
if not game.players[name].character then return end
if player.character.driving then return end
if game.tick - global.team_teleport_delay[player.name] < 0 then
local recovery_time = math.ceil(math.abs(game.tick - global.team_teleport_delay[player.name]) / 3600)
if recovery_time == 1 then
player.print("You need one more minute to recover from the last teleport.")
else
player.print("You are not capable of handling another teleport yet, you need " .. tostring(recovery_time) .. " more minutes to recover.")
end
return
end
global.team_teleport_delay[player.name] = game.tick + 900
teleport(player, game.players[name])
player.gui.center["team_teleport"].destroy()
end
local function refresh_gui()
for _, p in pairs(game.connected_players) do
if p.gui.center["team_teleport"] then
p.gui.center["team_teleport"].destroy()
create_teleport_gui(p)
end
end
end
local function on_player_joined_game(event)
local player = game.players[event.player_index]
if not global.team_teleport_delay then global.team_teleport_delay = {} end
if not global.team_teleport_delay[player.name] then global.team_teleport_delay[player.name] = 0 end
create_gui_toggle_button(player)
refresh_gui()
end
local function on_player_left_game(event)
refresh_gui()
end
event.add(defines.events.on_gui_click, on_gui_click)
event.add(defines.events.on_player_joined_game, on_player_joined_game)
event.add(defines.events.on_player_left_game, on_player_left_game)