1
0
mirror of https://github.com/ComfyFactory/ComfyFactorio.git synced 2025-09-16 09:06:21 +02:00

Comfypanel WIP

This commit is contained in:
MewMew
2019-10-20 11:48:14 +02:00
parent bfbbd0ab10
commit e076d3e5f1
6 changed files with 1088 additions and 11 deletions

View File

@@ -6,6 +6,7 @@
local event = require 'utils.event'
local session = require 'utils.session_data'
--[[
local function create_admin_button(player)
if player.gui.top["admin_button"] then return end
local b = player.gui.top.add({type = "button", caption = "Admin", name = "admin_button", tooltip = "Use your powers wisely"})
@@ -36,6 +37,7 @@ local function on_player_demoted(event)
if player.gui.top["admin_button"] then player.gui.top["admin_button"].destroy() end
if player.gui.left["admin_panel"] then player.gui.left["admin_panel"].destroy() end
end
]]
local function on_marked_for_deconstruction(event)
local tracker = session.get_session_table()
@@ -251,8 +253,8 @@ event.add(defines.events.on_gui_opened, on_gui_opened)
event.add(defines.events.on_marked_for_deconstruction, on_marked_for_deconstruction)
event.add(defines.events.on_player_ammo_inventory_changed, on_player_ammo_inventory_changed)
event.add(defines.events.on_player_built_tile, on_player_built_tile)
event.add(defines.events.on_player_demoted, on_player_demoted)
event.add(defines.events.on_player_joined_game, on_player_joined_game)
--event.add(defines.events.on_player_demoted, on_player_demoted)
--event.add(defines.events.on_player_joined_game, on_player_joined_game)
event.add(defines.events.on_pre_player_mined_item, on_pre_player_mined_item)
event.add(defines.events.on_player_promoted, on_player_promoted)
--event.add(defines.events.on_player_promoted, on_player_promoted)
event.add(defines.events.on_player_used_capsule, on_player_used_capsule)

375
comfy_panel/admin.lua Normal file
View File

@@ -0,0 +1,375 @@
--antigrief things made by mewmew
local event = require 'utils.event'
local function admin_only_message(str)
for _, player in pairs(game.connected_players) do
if player.admin == true then
player.print("Admins-only-message: " .. str, {r=0.88, g=0.88, b=0.88})
end
end
end
local jail_messages = {
"You´re done bud!",
"Busted!"
}
local function jail(player, source_player)
local permission_group = game.permissions.get_group("prisoner")
if not permission_group then
permission_group = game.permissions.create_group("prisoner")
for action_name, _ in pairs(defines.input_action) do
permission_group.set_allows_action(defines.input_action[action_name], false)
end
permission_group.set_allows_action(defines.input_action.write_to_console, true)
permission_group.set_allows_action(defines.input_action.gui_click, true)
permission_group.set_allows_action(defines.input_action.gui_selection_state_changed, true)
end
permission_group.add_player(player.name)
game.print(player.name .. " has been jailed. " .. jail_messages[math.random(1, #jail_messages)], { r=0.98, g=0.66, b=0.22})
admin_only_message(player.name .. " was jailed by " .. source_player.name)
end
local freedom_messages = {
"Yaay!",
"Welcome back!"
}
local function free(player, source_player)
local permission_group = game.permissions.get_group("Default")
permission_group.add_player(player.name)
game.print(player.name .. " was set free from jail. " .. freedom_messages[math.random(1, #freedom_messages)], { r=0.98, g=0.66, b=0.22})
admin_only_message(source_player.name .. " set " .. player.name .. " free from jail")
end
local bring_player_messages = {
"Come here my friend!",
"Papers, please.",
"What are you up to?"
}
local function bring_player(player, source_player)
if player.driving == true then
source_player.print("Target player is in a vehicle, teleport not available.", { r=0.88, g=0.88, b=0.88})
return
end
local pos = source_player.surface.find_non_colliding_position("character", source_player.position, 50, 1)
if pos then
player.teleport(pos, source_player.surface)
game.print(player.name .. " has been teleported to " .. source_player.name .. ". " .. bring_player_messages[math.random(1, #bring_player_messages)], { r=0.98, g=0.66, b=0.22})
end
end
local go_to_player_messages = {
"Papers, please.",
"What are you up to?"
}
local function go_to_player(player, source_player)
local pos = player.surface.find_non_colliding_position("character", player.position, 50, 1)
if pos then
source_player.teleport(pos, player.surface)
game.print(source_player.name .. " is visiting " .. player.name .. ". " .. go_to_player_messages[math.random(1, #go_to_player_messages)], { r=0.98, g=0.66, b=0.22})
end
end
local function spank(player, source_player)
if player.character then
if player.character.health > 1 then player.character.damage(1, "player") end
player.character.health = player.character.health - 5
player.surface.create_entity({name = "water-splash", position = player.position})
game.print(source_player.name .. " spanked " .. player.name, { r=0.98, g=0.66, b=0.22})
end
end
local damage_messages = {
" recieved a love letter from ",
" recieved a strange package from "
}
local function damage(player, source_player)
if player.character then
if player.character.health > 1 then player.character.damage(1, "player") end
player.character.health = player.character.health - 125
player.surface.create_entity({name = "big-explosion", position = player.position})
game.print(player.name .. damage_messages[math.random(1, #damage_messages)] .. source_player.name, { r=0.98, g=0.66, b=0.22})
end
end
local kill_messages = {
" did not obey the law.",
" should not have triggered the admins.",
" did not respect authority.",
" had a strange accident.",
" was struck by lightning."
}
local function kill(player, source_player)
if player.character then
player.character.die("player")
game.print(player.name .. kill_messages[math.random(1, #kill_messages)], { r=0.98, g=0.66, b=0.22})
admin_only_message(source_player.name .. " killed " .. player.name)
end
end
local enemy_messages = {
"Shoot on sight!",
"Wanted dead or alive!"
}
local function enemy(player, source_player)
if not game.forces.enemy_players then game.create_force("enemy_players") end
player.force = game.forces.enemy_players
game.print(player.name .. " is now an enemy! " .. enemy_messages[math.random(1, #enemy_messages)], {r=0.95, g=0.15, b=0.15})
admin_only_message(source_player.name .. " has turned " .. player.name .. " into an enemy")
end
local function ally(player, source_player)
player.force = game.forces.player
game.print(player.name .. " is our ally again!", {r=0.98, g=0.66, b=0.22})
admin_only_message(source_player.name .. " made " .. player.name .. " our ally")
end
local function turn_off_global_speakers(player, source_player)
local speakers = source_player.surface.find_entities_filtered({name = "programmable-speaker"})
local counter = 0
for i, speaker in pairs(speakers) do
if speaker.parameters.playback_globally == true then
speaker.surface.create_entity({name = "massive-explosion", position = speaker.position})
speaker.die("player")
counter = counter + 1
end
end
if counter == 0 then return end
if counter == 1 then
game.print(source_player.name .. " has nuked " .. counter .. " global speaker.", { r=0.98, g=0.66, b=0.22})
else
game.print(source_player.name .. " has nuked " .. counter .. " global speakers.", { r=0.98, g=0.66, b=0.22})
end
end
local function delete_all_blueprints(player, source_player)
local counter = 0
for _, ghost in pairs(source_player.surface.find_entities_filtered({type = {"entity-ghost", "tile-ghost"}})) do
ghost.destroy()
counter = counter + 1
end
if counter == 0 then return end
if counter == 1 then
game.print(counter .. " blueprint has been cleared!", { r=0.98, g=0.66, b=0.22})
else
game.print(counter .. " blueprints have been cleared!", { r=0.98, g=0.66, b=0.22})
end
admin_only_message(source_player.name .. " has cleared all blueprints.")
end
local function create_mini_camera_gui(player, caption, position)
if player.gui.center["mini_camera"] then player.gui.center["mini_camera"].destroy() end
local frame = player.gui.center.add({type = "frame", name = "mini_camera", caption = caption})
local camera = frame.add({type = "camera", name = "mini_cam_element", position = position, zoom = 0.6, surface_index = player.surface.index})
camera.style.minimal_width = 640
camera.style.minimal_height = 480
end
local function create_admin_panel(player, frame)
frame.clear()
local player_names = {}
for _, p in pairs(game.connected_players) do
table.insert(player_names, tostring(p.name))
end
table.insert(player_names, "Select Player")
local selected_index = #player_names
if global.admin_panel_selected_player_index then
if global.admin_panel_selected_player_index[player.name] then
if player_names[global.admin_panel_selected_player_index[player.name]] then
selected_index = global.admin_panel_selected_player_index[player.name]
end
end
end
local drop_down = frame.add({type = "drop-down", name = "admin_player_select", items = player_names, selected_index = selected_index})
drop_down.style.right_padding = 12
drop_down.style.left_padding = 12
local t = frame.add({type = "table", column_count = 3})
local buttons = {
t.add({type = "button", caption = "Jail", name = "jail", tooltip = "Jails the player, they will no longer be able to perform any actions except writing in chat."}),
t.add({type = "button", caption = "Free", name = "free", tooltip = "Frees the player from jail."}),
t.add({type = "button", caption = "Bring Player", name = "bring_player", tooltip = "Teleports the selected player to your position."}),
t.add({type = "button", caption = "Make Enemy", name = "enemy", tooltip = "Sets the selected players force to enemy_players. DO NOT USE IN PVP MAPS!!"}),
t.add({type = "button", caption = "Make Ally", name = "ally", tooltip = "Sets the selected players force back to the default player force. DO NOT USE IN PVP MAPS!!"}),
t.add({type = "button", caption = "Go to Player", name = "go_to_player", tooltip = "Teleport yourself to the selected player."}),
t.add({type = "button", caption = "Spank", name = "spank", tooltip = "Hurts the selected player with minor damage. Can not kill the player."}),
t.add({type = "button", caption = "Damage", name = "damage", tooltip = "Damages the selected player with greater damage. Can not kill the player."}),
t.add({type = "button", caption = "Kill", name = "kill", tooltip = "Kills the selected player instantly."})
}
for _, button in pairs(buttons) do
button.style.font = "default-bold"
--button.style.font_color = { r=0.99, g=0.11, b=0.11}
button.style.font_color = { r=0.99, g=0.99, b=0.99}
button.style.minimal_width = 106
end
--local l = frame.add({type = "label", caption = "----------------------------------------------"})
local l = frame.add({type = "label", caption = "Global Actions:"})
local t = frame.add({type = "table", column_count = 2})
local buttons = {
t.add({type = "button", caption = "Destroy global speakers", name = "turn_off_global_speakers", tooltip = "Destroys all speakers that are set to play sounds globally."}),
t.add({type = "button", caption = "Delete blueprints", name = "delete_all_blueprints", tooltip = "Deletes all placed blueprints on the map."})
--- t.add({type = "button", caption = "Cancel all deconstruction orders", name = "remove_all_deconstruction_orders"})
}
for _, button in pairs(buttons) do
button.style.font = "default-bold"
button.style.font_color = { r=0.98, g=0.66, b=0.22}
button.style.minimal_width = 80
end
local histories = {}
if global.friendly_fire_history then table.insert(histories, "Friendly Fire History") end
if global.mining_history then table.insert(histories, "Mining History") end
if global.landfill_history then table.insert(histories, "Landfill History") end
if global.artillery_history then table.insert(histories, "Artillery History") end
if #histories == 0 then return end
local l = frame.add({type = "label", caption = "----------------------------------------------"})
local selected_index = 1
if global.admin_panel_selected_history_index then
if global.admin_panel_selected_history_index[player.name] then
selected_index = global.admin_panel_selected_history_index[player.name]
end
end
local drop_down = frame.add({type = "drop-down", name = "admin_history_select", items = histories, selected_index = selected_index})
drop_down.style.right_padding = 12
drop_down.style.left_padding = 12
local history = frame["admin_history_select"].items[frame["admin_history_select"].selected_index]
local history_index = {
["Friendly Fire History"] = global.friendly_fire_history,
["Mining History"] = global.mining_history,
["Landfill History"] = global.landfill_history,
["Artillery History"] = global.artillery_history
}
local t = frame.add({type = "table", column_count = 1})
l.style.font = "default-listbox"
l.style.font_color = { r=0.98, g=0.66, b=0.22}
local scroll_pane = t.add({ type = "scroll-pane", direction = "vertical", horizontal_scroll_policy = "never", vertical_scroll_policy = "auto"})
scroll_pane.style.maximal_height = 200
for i = #history_index[history], 1, -1 do
scroll_pane.add({type = "label", caption = history_index[history][i], tooltip = "Click to open mini camera."})
end
end
local admin_functions = {
["jail"] = jail,
["free"] = free,
["bring_player"] = bring_player,
["spank"] = spank,
["damage"] = damage,
["kill"] = kill,
["turn_off_global_speakers"] = turn_off_global_speakers,
["delete_all_blueprints"] = delete_all_blueprints,
--["remove_all_deconstruction_orders"] = remove_all_deconstruction_orders,
["enemy"] = enemy,
["ally"] = ally,
["go_to_player"] = go_to_player
}
local function get_position_from_string(str)
if not str then return end
if str == "" then return end
str = string.lower(str)
local x_pos = string.find(str, "x:")
local y_pos = string.find(str, "y:")
if not x_pos then return false end
if not y_pos then return false end
x_pos = x_pos + 2
y_pos = y_pos + 2
local a = 1
for i = 1, string.len(str), 1 do
local s = string.sub(str, x_pos + i, x_pos + i)
if not s then break end
if string.byte(s) == 32 then break end
a = a + 1
end
local x = string.sub(str, x_pos, x_pos + a)
local a = 1
for i = 1, string.len(str), 1 do
local s = string.sub(str, y_pos + i, y_pos + i)
if not s then break end
if string.byte(s) == 32 then break end
a = a + 1
end
local y = string.sub(str, y_pos, y_pos + a)
x = tonumber(x)
y = tonumber(y)
local position = {x = x, y = y}
return position
end
local function on_gui_click(event)
local player = game.players[event.player_index]
local frame = comfy_panel_get_active_frame(player)
if not frame then return end
if frame.name ~= "Admin" then return end
local name = event.element.name
if admin_functions[name] then
local target_player_name = frame["admin_player_select"].items[frame["admin_player_select"].selected_index]
if not target_player_name then return end
if target_player_name == "Select Player" then
player.print("No target player selected.", {r=0.88, g=0.88, b=0.88})
return
end
local target_player = game.players[target_player_name]
if target_player.connected == true then
admin_functions[name](target_player, player)
end
end
if name == "mini_camera" or name == "mini_cam_element" then
player.gui.center["mini_camera"].destroy()
return
end
if not frame then return end
if not event.element.caption then return end
local position = get_position_from_string(event.element.caption)
if not position then return end
if player.gui.center["mini_camera"] then
if player.gui.center["mini_camera"].caption == event.element.caption then
player.gui.center["mini_camera"].destroy()
return
end
end
create_mini_camera_gui(player, event.element.caption, position)
end
local function on_gui_selection_state_changed(event)
local player = game.players[event.player_index]
local name = event.element.name
if name == "admin_history_select" then
if not global.admin_panel_selected_history_index then global.admin_panel_selected_history_index = {} end
global.admin_panel_selected_history_index[player.name] = event.element.selected_index
local frame = comfy_panel_get_active_frame(player)
if not frame then return end
if frame.name ~= "Admin" then return end
create_admin_panel(player, frame)
end
end
comfy_panel_tabs["Admin"] = create_admin_panel
event.add(defines.events.on_gui_click, on_gui_click)
event.add(defines.events.on_gui_selection_state_changed, on_gui_selection_state_changed)

221
comfy_panel/group.lua Normal file
View File

@@ -0,0 +1,221 @@
-- this script adds a group button to create groups for your players --
local function build_group_gui(player, frame)
local group_name_width = 150
local description_width = 240
local members_width = 90
local member_columns = 3
local actions_width = 80
local total_height = frame.style.minimal_height - 60
frame.clear()
local t = frame.add({type = "table", column_count = 5})
local headings = {{"Title", group_name_width}, {"Description", description_width}, {"Members", members_width * member_columns}, {"", actions_width}}
for _, h in pairs (headings) do
local l = t.add({ type = "label", caption = h[1]})
l.style.font_color = { r=0.98, g=0.66, b=0.22}
l.style.font = "default-listbox"
l.style.top_padding = 6
l.style.minimal_height = 40
l.style.minimal_width = h[2]
l.style.maximal_width = h[2]
end
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 = total_height - 50
scroll_pane.style.minimal_height = total_height - 50
local t = scroll_pane.add({type = "table", name = "groups_table", column_count = 4})
for _, h in pairs (headings) do
local l = t.add({ type = "label", caption = ""})
l.style.minimal_width = h[2]
l.style.maximal_width = h[2]
end
for _, group in pairs (global.tag_groups) do
local l = t.add({ type = "label", caption = group.name})
l.style.font = "default-bold"
l.style.top_padding = 16
l.style.bottom_padding = 16
l.style.minimal_width = group_name_width
l.style.maximal_width = group_name_width
local color = game.players[group.founder].color
color = {r = color.r * 0.6 + 0.4, g = color.g * 0.6 + 0.4, b = color.b * 0.6 + 0.4, a = 1}
l.style.font_color = color
l.style.single_line = false
local l = t.add({ type = "label", caption = group.description})
l.style.top_padding = 16
l.style.bottom_padding = 16
l.style.minimal_width = description_width
l.style.maximal_width = description_width
l.style.font_color = {r = 0.90, g = 0.90, b = 0.90}
l.style.single_line = false
local tt = t.add({ type = "table", column_count = member_columns})
for _, p in pairs (game.connected_players) do
if group.name == global.player_group[p.name] then
local l = tt.add({ type = "label", caption = p.name})
local color = {r = p.color.r * 0.6 + 0.4, g = p.color.g * 0.6 + 0.4, b = p.color.b * 0.6 + 0.4, a = 1}
l.style.font_color = color
--l.style.minimal_width = members_width
l.style.maximal_width = members_width * 2
end
end
local tt = t.add({ type = "table", name = group.name, column_count = 1})
if group.name ~= global.player_group[player.name] then
local b = tt.add({ type = "button", caption = "Join"})
b.style.font = "default-bold"
b.style.minimal_width = actions_width
b.style.maximal_width = actions_width
else
local b = tt.add({ type = "button", caption = "Leave"})
b.style.font = "default-bold"
b.style.minimal_width = actions_width
b.style.maximal_width = actions_width
end
if player.admin == true or group.founder == player.name then
local b = tt.add({ type = "button", caption = "Delete"})
b.style.font = "default-bold"
b.style.minimal_width = actions_width
b.style.maximal_width = actions_width
else
local l = tt.add({ type = "label", caption = ""})
l.style.minimal_width = actions_width
l.style.maximal_width = actions_width
end
end
local frame2 = frame.add({type = "frame", name = "frame2"})
local t = frame2.add({type = "table", name = "group_table", column_count = 3})
local textfield = t.add({ type = "textfield", name = "new_group_name", text = "Name" })
textfield.style.minimal_width = 200
local textfield = t.add({ type = "textfield", name = "new_group_description", text = "Description" })
textfield.style.minimal_width = 400
local b = t.add({type = "button", name = "create_new_group", caption = "Create"})
b.style.minimal_width = 150
b.style.font = "default-bold"
end
local function refresh_gui()
for _, p in pairs(game.connected_players) do
local frame = comfy_panel_get_active_frame(p)
if frame then
if frame.name == "Groups" then
local new_group_name = frame.frame2.group_table.new_group_name.text
local new_group_description = frame.frame2.group_table.new_group_description.text
build_group_gui(p, frame)
local frame = comfy_panel_get_active_frame(p)
frame.frame2.group_table.new_group_name.text = new_group_name
frame.frame2.group_table.new_group_description.text = new_group_description
end
end
end
end
local function on_player_joined_game(event)
local player = game.players[event.player_index]
if not global.player_group then global.player_group = {} end
if not global.player_group[player.name] then global.player_group[player.name] = "[Group]" end
if not global.join_spam_protection then global.join_spam_protection = {} end
if not global.join_spam_protection[player.name] then global.join_spam_protection[player.name] = game.tick end
if not global.tag_groups then global.tag_groups = {} 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.element.player_index]
local name = event.element.name
local frame = comfy_panel_get_active_frame(player)
if not frame then return end
if frame.name ~= "Groups" then return end
if not frame then return end
if name == "create_new_group" then
local new_group_name = frame.frame2.group_table.new_group_name.text
local new_group_description = frame.frame2.group_table.new_group_description.text
if new_group_name ~= "" and new_group_name ~= "Name" and new_group_description ~= "Description" then
if string.len(new_group_name) > 64 then
player.print("Group name is too long. 64 characters maximum.", { r=0.90, g=0.0, b=0.0})
return
end
if string.len(new_group_description) > 128 then
player.print("Description is too long. 128 characters maximum.", { r=0.90, g=0.0, b=0.0})
return
end
global.tag_groups[new_group_name] = {name = new_group_name, description = new_group_description, founder = player.name}
local color = {r = player.color.r * 0.7 + 0.3, g = player.color.g * 0.7 + 0.3, b = player.color.b * 0.7 + 0.3, a = 1}
game.print(player.name .. " has founded a new group!", color)
game.print('>> ' .. new_group_name, { r=0.98, g=0.66, b=0.22})
game.print(new_group_description, { r=0.85, g=0.85, b=0.85})
frame.frame2.group_table.new_group_name.text = "Name"
frame.frame2.group_table.new_group_description.text = "Description"
refresh_gui()
return
end
end
local p = event.element.parent
if p then p = p.parent end
if p then
if p.name == "groups_table" then
if event.element.type == "button" and event.element.caption == "Join" then
global.player_group[player.name] = event.element.parent.name
local str = "[" .. event.element.parent.name
str = str .. "]"
player.tag = str
if game.tick - global.join_spam_protection[player.name] > 600 then
local color = {r = player.color.r * 0.7 + 0.3, g = player.color.g * 0.7 + 0.3, b = player.color.b * 0.7 + 0.3, a = 1}
game.print(player.name .. ' has joined group "' .. event.element.parent.name .. '"', color)
global.join_spam_protection[player.name] = game.tick
end
refresh_gui()
return
end
if event.element.type == "button" and event.element.caption == "Delete" then
for _, p in pairs(game.players) do
if global.player_group[p.name] then
if global.player_group[p.name] == event.element.parent.name then
global.player_group[p.name] = "[Group]"
p.tag = ""
end
end
end
game.print(player.name .. ' deleted group "' .. event.element.parent.name .. '"')
global.tag_groups[event.element.parent.name] = nil
refresh_gui()
return
end
if event.element.type == "button" and event.element.caption == "Leave" then
global.player_group[player.name] = "[Group]"
player.tag = ""
refresh_gui()
return
end
end
end
end
comfy_panel_tabs["Groups"] = build_group_gui
local event = require 'utils.event'
event.add(defines.events.on_gui_click, on_gui_click)
event.add(defines.events.on_player_joined_game, on_player_joined_game)

89
comfy_panel/main.lua Normal file
View File

@@ -0,0 +1,89 @@
--[[
Comfy Panel
To add a tab, insert into the "comfy_panel_tabs" table.
Example: comfy_panel_tabs["mapscores"] = draw_map_scores
draw_map_scores would be a function with the player and the frame as arguments
]]
comfy_panel_tabs = {}
function comfy_panel_get_active_frame(player)
if not player.gui.left.comfy_panel then return false end
if not player.gui.left.comfy_panel.tabbed_pane.selected_tab_index then return player.gui.left.comfy_panel.tabbed_pane.tabs[1].content end
return player.gui.left.comfy_panel.tabbed_pane.tabs[player.gui.left.comfy_panel.tabbed_pane.selected_tab_index].content
end
function comfy_panel_refresh_active_tab(player)
local frame = comfy_panel_get_active_frame(player)
if not frame then return end
comfy_panel_tabs[frame.name](player, frame)
end
local function top_button(player)
if player.gui.top["comfy_panel_top_button"] then return end
local button = player.gui.top.add({type = "sprite-button", name = "comfy_panel_top_button", sprite = "item/raw-fish"})
button.style.minimal_height = 38
button.style.minimal_width = 38
button.style.padding = -2
end
local function main_frame(player)
if player.gui.left["comfy_panel"] then return end
local frame = player.gui.left.add({type = "frame", name = "comfy_panel"})
frame.style.margin = 8
local tabbed_pane = frame.add({type = "tabbed-pane", name = "tabbed_pane"})
for name, func in pairs(comfy_panel_tabs) do
if name == "Admin" then
if player.admin then
local tab = tabbed_pane.add({type = "tab", caption = name})
local frame = tabbed_pane.add({type = "frame", name = name, direction = "vertical"})
frame.style.minimal_height = 480
frame.style.minimal_width = 800
frame.style.maximal_width = 800
tabbed_pane.add_tab(tab, frame)
end
else
local tab = tabbed_pane.add({type = "tab", caption = name})
local frame = tabbed_pane.add({type = "frame", name = name, direction = "vertical"})
frame.style.minimal_height = 480
frame.style.minimal_width = 800
frame.style.maximal_width = 800
tabbed_pane.add_tab(tab, frame)
end
end
comfy_panel_refresh_active_tab(player)
end
local function on_player_joined_game(event)
top_button(game.players[event.player_index])
end
local function on_gui_click(event)
if not event.element then return end
if not event.element.valid then return end
local player = game.players[event.player_index]
if event.element.name == "comfy_panel_top_button" then
if player.gui.left.comfy_panel then
player.gui.left.comfy_panel.destroy()
return
else
main_frame(player)
return
end
end
if not event.element.caption then return end
if event.element.type ~= "tab" then return end
comfy_panel_refresh_active_tab(player)
end
local event = require 'utils.event'
event.add(defines.events.on_player_joined_game, on_player_joined_game)
event.add(defines.events.on_gui_click, on_gui_click)

382
comfy_panel/player_list.lua Normal file
View File

@@ -0,0 +1,382 @@
--[[
Hello there!
This will add a player list with "ranks" to your server.
Oh.. and you can also "poke" a player.
pokemessages = 80% by redlabel
To install, add: require "player_list"
to your scenario control.lua.
---MewMew---
Minor changes by ~~~Gerkiz~~~
--]]
local event = require 'utils.event'
local play_time = require 'utils.session_data'
local symbol_asc = ""
local symbol_desc = ""
local pokemessages = {"a stick", "a leaf", "a moldy carrot", "a crispy slice of bacon", "a french fry", "a realistic toygun", "a broomstick", "a thirteen inch iron stick", "a mechanical keyboard", "a fly fishing cane",
"a selfie stick", "an oversized fidget spinner", "a thumb extender", "a dirty straw", "a green bean", "a banana", "an umbrella", "grandpa's walking stick", "live firework", "a toilet brush", "a fake hand",
"an undercooked hotdog", "a slice of yesterday's microwaved pizza", "bubblegum", "a biter leg", "grandma's toothbrush", "charred octopus", "a dollhouse bathtub", "a length of copper wire",
"a decommissioned nuke", "a smelly trout", "an unopened can of deodorant", "a stone brick", "a half full barrel of lube", "a half empty barrel of lube", "an unexploded cannon shell", "a blasting programmable speaker",
"a not so straight rail", "a mismatched pipe to ground", "a surplus box of landmines", "decommissioned yellow rounds", "an oily pumpjack shaft", "a melted plastic bar in the shape of the virgin mary",
"a bottle of watermelon vitamin water", "a slice of watermelon", "a stegosaurus tibia", "a basking musician's clarinet", "a twig", "an undisclosed pokey item", "a childhood trophy everyone else got","a dead starfish",
"a titanium toothpick", "a nail file","a stamp collection","a bucket of lego","a rolled up carpet","a rolled up WELCOME doormat","Bobby's favorite bone","an empty bottle of cheap vodka","a tattooing needle",
"a peeled cucumber","a stack of cotton candy","a signed baseball bat","that 5 dollar bill grandma sent for christmas","a stack of overdue phone bills","the 'relax' section of the white pages",
"a bag of gym clothes which never made it to the washing machine","a handful of peanut butter","a pheasant's feather","a rusty pickaxe","a diamond sword","the bill of rights of a banana republic",
"one of those giant airport Toblerone's", "a long handed inserter", "a wiimote","an easter chocolate rabbit","a ball of yarn the cat threw up","a slightly expired but perfectly edible cheese sandwich",
"conclusive proof of lizard people existence","a pen drive full of high res wallpapers","a pet hamster","an oversized goldfish","a one foot extension cord","a CD from Walmart's 1 dollar bucket","a magic wand","a list of disappointed people who believed in you","murder exhibit no. 3","a paperback copy of 'Great Expectations'", "a baby biter", "a little biter fang", "the latest diet fad","a belt that no longer fits you","an abandoned pet rock","a lava lamp", "some spirit herbs","a box of fish sticks found at the back of the freezer","a bowl of tofu rice", "a bowl of ramen noodles", "a live lobster!", "a miniature golf cart","dunce cap","a fully furnished x-mas tree", "an orphaned power pole", "an horphaned power pole","an box of overpriced girl scout cookies","the cheapest item from the yard sale","a Sharpie","a glowstick","a thick unibrow hair","a very detailed map of Kazakhstan","the official Factorio installation DVD","a Liberal Arts degree","a pitcher of Kool-Aid","a 1/4 pound vegan burrito","a bottle of expensive wine","a hamster sized gravestone","a counterfeit Cuban cigar","an old Nokia phone","a huge inferiority complex","a dead real state agent","a deck of tarot cards","unreleased Wikileaks documents","a mean-looking garden dwarf","the actual mythological OBESE cat","a telescope used to spy on the MILF next door","a fancy candelabra","the comic version of the Kama Sutra","an inflatable 'Netflix & chill' doll","whatever it is redlabel gets high on","Obama's birth certificate","a deck of Cards Against Humanity","a copy of META MEME HUMOR for Dummies","an abandoned, not-so-young-anymore puppy","one of those useless items advertised on TV","a genetic blueprint of a Japanese teen idol" }
local function get_formatted_playtime(x)
local time_one = 216000
local time_two = 3600
if x < 5184000 then
local y = x / 216000
y = tostring(y)
local h = ""
for i=1,10,1 do
local z = string.sub(y, i, i)
if z == "." then
break
else
h = h .. z
end
end
local m = x % 216000
m = m / 3600
m = math.floor(m)
m = tostring(m)
if h == "0" then
local str = m .. " minutes"
return str
else
local str = h .. " hours "
str = str .. m
str = str .. " minutes"
return str
end
else
local y = x / 5184000
y = tostring(y)
local h = ""
for i=1,10,1 do
local z = string.sub(y, i, i)
if z == "." then
break
else
h = h .. z
end
end
local m = x % 5184000
m = m / 216000
m = math.floor(m)
m = tostring(m)
if h == "0" then
local str = m .. " days"
return str
else
local str = h .. " days "
str = str .. m
str = str .. " hours"
return str
end
end
end
local function get_rank(player)
local play_table = play_time.get_session_table()
local t = 0
if play_table then
if play_table[player.name] then t = play_table[player.name] end
end
local m = (player.online_time + t) / 3600
local ranks = {
"item/burner-mining-drill","item/burner-inserter","item/stone-furnace","item/light-armor","item/steam-engine",
"item/inserter", "item/transport-belt", "item/underground-belt", "item/splitter","item/assembling-machine-1","item/long-handed-inserter","item/electronic-circuit","item/electric-mining-drill","item/dummy-steel-axe",
"item/heavy-armor","item/steel-furnace","item/gun-turret","item/fast-transport-belt", "item/fast-underground-belt", "item/fast-splitter","item/assembling-machine-2","item/fast-inserter","item/radar","item/filter-inserter",
"item/defender-capsule","item/pumpjack","item/chemical-plant","item/solar-panel","item/advanced-circuit","item/modular-armor","item/accumulator", "item/construction-robot",
"item/distractor-capsule","item/stack-inserter","item/electric-furnace","item/express-transport-belt","item/express-underground-belt", "item/express-splitter","item/assembling-machine-3","item/processing-unit","item/power-armor","item/logistic-robot","item/laser-turret",
"item/stack-filter-inserter","item/destroyer-capsule","item/power-armor-mk2","item/flamethrower-turret","item/beacon",
"item/steam-turbine","item/centrifuge","item/nuclear-reactor"
}
--52 ranks
local time_needed = 240 -- in minutes between rank upgrades
m = m / time_needed
m = math.floor(m)
m = m + 1
if m > #ranks then m = #ranks end
return ranks[m]
end
local comparators = {
["pokes_asc"] = function (a, b) return a.pokes > b.pokes end,
["pokes_desc"] = function (a, b) return a.pokes < b.pokes end,
["total_time_played_asc"] = function (a,b) return a.total_played_ticks < b.total_played_ticks end,
["total_time_played_desc"] = function (a,b) return a.total_played_ticks > b.total_played_ticks end,
["time_played_asc"] = function (a,b) return a.played_ticks < b.played_ticks end,
["time_played_desc"] = function (a,b) return a.played_ticks > b.played_ticks end,
["name_asc"] = function (a,b) return a.name:lower() < b.name:lower() end,
["name_desc"] = function (a,b) return a.name:lower() > b.name:lower() end
}
local function get_comparator(sort_by)
return comparators[sort_by]
end
local function get_sorted_list(sort_by)
local play_table = play_time.get_session_table()
local player_list = {}
for i, player in pairs(game.connected_players) do
player_list[i] = {}
player_list[i].rank = get_rank(player)
player_list[i].name = player.name
local t = 0
if play_table[player.name] then t = play_table[player.name] end
player_list[i].total_played_time = get_formatted_playtime(t + player.online_time)
player_list[i].total_played_ticks = t + player.online_time
player_list[i].played_time = get_formatted_playtime(player.online_time)
player_list[i].played_ticks = player.online_time
player_list[i].pokes = global.player_list.pokes[player.index]
player_list[i].player_index = player.index
end
local comparator = get_comparator(sort_by)
table.sort(player_list, comparator)
return player_list
end
local column_widths = {40, 250, 250, 150, 100}
local function player_list_show(player, frame, sort_by)
-- Frame management
frame.clear()
frame.style.padding = 8
-- Header management
local t = frame.add { type = "table", name = "player_list_panel_header_table", column_count = 5 }
for _, w in ipairs(column_widths) do
local label = t.add { type = "label", caption = "" }
label.style.minimal_width = w
label.style.maximal_width = w
end
local headers = {
[1] = "[color=0.1,0.7,0.1]" -- green
.. tostring(#game.connected_players)
.. "[/color]",
[2] = "Online"
.. " / "
.. "[color=0.7,0.1,0.1]" -- red
.. tostring(#game.players - #game.connected_players)
.. "[/color]"
.. " Offline",
[3] = "Total Time",
[4] = "Current Time",
[5] = "Poke"
}
local header_modifier = {
["name_asc"] = function (h) h[2] = symbol_asc .. h[2] end,
["name_desc"] = function (h) h[2] = symbol_desc .. h[2] end,
["total_time_played_asc"] = function (h) h[3] = symbol_asc .. h[3] end,
["total_time_played_desc"] = function (h) h[3] = symbol_desc .. h[3] end,
["time_played_asc"] = function (h) h[4] = symbol_asc .. h[4] end,
["time_played_desc"] = function (h) h[4] = symbol_desc .. h[4] end,
["pokes_asc"] = function (h) h[5] = symbol_asc .. h[5] end,
["pokes_desc"] = function (h) h[5] = symbol_desc .. h[5] end
}
if sort_by then
header_modifier[sort_by](headers)
else
header_modifier["total_time_played_desc"](headers)
end
for k, v in ipairs(headers) do
local label = t.add {
type = "label",
name = "player_list_panel_header_" .. k,
caption = v
}
label.style.font = "default-bold"
label.style.font_color = { r=0.98, g=0.66, b=0.22 }
end
-- special style on first header
local label = t["player_list_panel_header_1"]
label.style.minimal_width = 36
label.style.maximal_width = 36
label.style.horizontal_align = "right"
-- List management
local player_list_panel_table = frame.add { type = "scroll-pane", name = "scroll_pane", direction = "vertical", horizontal_scroll_policy = "never", vertical_scroll_policy = "auto"}
player_list_panel_table.style.maximal_height = 530
player_list_panel_table = player_list_panel_table.add { type = "table", name = "player_list_panel_table", column_count = 5 }
local player_list = get_sorted_list(sort_by)
for i = 1, #player_list, 1 do
-- Icon
local sprite = player_list_panel_table.add { type = "sprite", name = "player_rank_sprite_" .. i, sprite = player_list[i].rank }
sprite.style.minimal_width = column_widths[1]
sprite.style.maximal_width = column_widths[1]
-- Name
local label = player_list_panel_table.add { type = "label", name = "player_list_panel_player_names_" .. i, caption = player_list[i].name }
label.style.font = "default"
label.style.font_color = {
r = .4 + game.players[player_list[i].player_index].color.r * 0.6,
g = .4 + game.players[player_list[i].player_index].color.g * 0.6,
b = .4 + game.players[player_list[i].player_index].color.b * 0.6,
}
label.style.minimal_width = column_widths[2]
label.style.maximal_width = column_widths[2]
-- Total time
local label = player_list_panel_table.add { type = "label", name = "player_list_panel_player_total_time_played_" .. i, caption = player_list[i].total_played_time }
label.style.minimal_width = column_widths[3]
label.style.maximal_width = column_widths[3]
-- Current time
local label = player_list_panel_table.add { type = "label", name = "player_list_panel_player_time_played_" .. i, caption = player_list[i].played_time }
label.style.minimal_width = column_widths[4]
label.style.maximal_width = column_widths[4]
-- Poke
local flow = player_list_panel_table.add { type = "flow", name = "button_flow_" .. i, direction = "horizontal" }
flow.add { type = "label", name = "button_spacer_" .. i, caption = "" }
local button = flow.add { type = "button", name = "poke_player_" .. player_list[i].name, caption = player_list[i].pokes }
button.style.font = "default"
label.style.font_color = { r=0.83, g=0.83, b=0.83}
button.style.minimal_height = 30
button.style.minimal_width = 30
button.style.maximal_height = 30
button.style.maximal_width = 30
button.style.top_padding = 0
button.style.left_padding = 0
button.style.right_padding = 0
button.style.bottom_padding = 0
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
if not event.element.name then return end
local player = game.players[event.element.player_index]
local frame = comfy_panel_get_active_frame(player)
if not frame then return end
if frame.name ~= "Players" then return end
local name = event.element.name
local actions = {
["player_list_panel_header_2"] = function ()
if string.find(event.element.caption, symbol_desc) then
player_list_show(player, frame, "name_asc")
else
player_list_show(player, frame,"name_desc")
end
end,
["player_list_panel_header_3"] = function ()
if string.find(event.element.caption, symbol_desc) then
player_list_show(player, frame,"total_time_played_asc")
else
player_list_show(player, frame,"total_time_played_desc")
end
end,
["player_list_panel_header_4"] = function ()
if string.find(event.element.caption, symbol_desc) then
player_list_show(player, frame,"time_played_asc")
else
player_list_show(player, frame,"time_played_desc")
end
end,
["player_list_panel_header_5"] = function ()
if string.find(event.element.caption, symbol_desc) then
player_list_show(player, frame,"pokes_asc")
else
player_list_show(player, frame,"pokes_desc")
end
end,
}
if actions[name] then
actions[name]()
return
end
if not event.element.valid then return end
--Poke other players
if string.sub(event.element.name, 1, 11) == "poke_player" then
local poked_player = string.sub(event.element.name, 13, string.len(event.element.name))
--if player.name == poked_player then return end
if global.player_list.last_poke_tick[event.element.player_index] + 300 < game.tick then
local str = ">> "
str = str .. player.name
str = str .. " has poked "
str = str .. poked_player
str = str .. " with "
local z = math.random(1,#pokemessages)
str = str .. pokemessages[z]
str = str .. " <<"
game.print(str)
global.player_list.last_poke_tick[event.element.player_index] = game.tick
local p = game.players[poked_player]
global.player_list.pokes[p.index] = global.player_list.pokes[p.index] + 1
end
end
end
local function on_player_joined_game(event)
local player = game.players[event.player_index]
if not global.player_list.last_poke_tick[event.player_index] then
global.player_list.pokes[event.player_index] = 0
global.player_list.last_poke_tick[event.player_index] = 0
end
local frame = comfy_panel_get_active_frame(player)
if not frame then return end
if frame.name ~= "Players" then return end
player_list_show(player, frame, "total_time_played_desc")
end
comfy_panel_tabs["Players"] = player_list_show
local function on_init()
global.player_list = {}
global.player_list.last_poke_tick = {}
global.player_list.pokes = {}
end
event.on_init(on_init)
event.add(defines.events.on_player_joined_game, on_player_joined_game)
event.add(defines.events.on_gui_click, on_gui_click)

View File

@@ -11,13 +11,20 @@ require "utils.color_data"
require "utils.session_data"
require "chatbot"
require "commands"
require "comfy_panel.main"
require "comfy_panel.player_list"
require "comfy_panel.group"
require "comfy_panel.admin"
require "antigrief"
require "antigrief_admin_panel"
require "group"
require "player_list"
--require "antigrief_admin_panel"
--require "group"
--require "player_list"
require "player_modifiers"
require "poll"
require "score"
--require "score"
require "modules.autostash"
require "modules.corpse_markers"
require "modules.floaty_chat"
@@ -43,7 +50,6 @@ require "modules.floaty_chat"
--require "modules.fish_respawner"
--require "modules.fluids_are_explosive"
--require "modules.hunger"
--require "modules.rpg"
--require "modules.hunger_games"
--require "modules.players_trample_paths"
--require "modules.railgun_enhancer"
@@ -58,13 +64,14 @@ require "modules.floaty_chat"
--require "modules.no_blueprint_library"
--require "modules.explosives"
--require "modules.biter_pets"
--require "modules.wave_defense.main"
-----------------------------
---- enable maps here ----
--require "maps.fish_defender.main"
--require "maps.fish_defender_v1.fish_defender"
--require "maps.biter_battles_v2.main"
require "maps.mountain_fortress_v2.main"
--require "maps.mountain_fortress_v2.main"
--require "maps.mountain_fortress"
--require "maps.island_troopers.main"
--require "maps.tank_conquest.tank_conquest"
@@ -74,6 +81,7 @@ require "maps.mountain_fortress_v2.main"
--require "maps.wave_of_death.WoD"
--require "maps.stone_maze.main"
--require "maps.overgrowth"
--require "maps.wave_defense"
--require "maps.quarters"
--require "maps.tetris.main"
--require "maps.maze_challenge"
@@ -108,12 +116,11 @@ require "maps.mountain_fortress_v2.main"
-----------------------------
---- more modules here ----
--require "modules.rpg"
--require "modules.trees_grow"
--require "modules.trees_randomly_die"
------
local event = require 'utils.event'
if _DUMP_ENV then
require 'utils.dump_env'
end
@@ -136,5 +143,6 @@ function require(path)
return loaded[path] or error('Can only require files at runtime that have been required in the control stage.', 2)
end
local event = require 'utils.event'
event.on_init(on_init)
event.add(defines.events.on_player_created, on_player_created)