mirror of
https://github.com/Refactorio/RedMew.git
synced 2025-09-16 09:16:22 +02:00
Initial commit. Imported RedMew 1.7
This commit is contained in:
441
band.lua
Normal file
441
band.lua
Normal file
@@ -0,0 +1,441 @@
|
||||
-- Give players the option to set their preferred role as a tag
|
||||
-- Version 0.1.6
|
||||
-- https://github.com/Befzz/factorio_random/tree/master/scenarios/befzz_test
|
||||
|
||||
-- Requires event.lua to work ( https://github.com/3RaGaming/utils )
|
||||
|
||||
-- SETTINGS
|
||||
local option_band_change_interval = 60 * 3 -- in ticks
|
||||
|
||||
-- Role list: "band_roles.lua"
|
||||
local band_roles = require "band_roles"
|
||||
local to_print, roles = band_roles.to_print, band_roles.roles
|
||||
|
||||
do
|
||||
local i = 1
|
||||
for _, roledata in pairs(roles) do
|
||||
roledata.index = i
|
||||
i = i + 1
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local expand_band_gui
|
||||
local band_last_change = -option_band_change_interval
|
||||
|
||||
-- store current role
|
||||
local local_role
|
||||
|
||||
local function create_band_gui(event)
|
||||
local player = game.players[event.player_index]
|
||||
if player.gui.top.band_toggle_btn == nil then
|
||||
local button = player.gui.top.add { name = "band_toggle_btn", type = "sprite-button", caption = "Tag", style = "dialog_button_style" }
|
||||
button.style.font = "default-bold"
|
||||
button.style.minimal_height = 38
|
||||
button.style.minimal_width = 38
|
||||
button.style.top_padding = 2
|
||||
button.style.left_padding = 4
|
||||
button.style.right_padding = 4
|
||||
button.style.bottom_padding = 2
|
||||
|
||||
-- expand_band_gui(player)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- Make a list of random names with roles
|
||||
local function test_fake_players( t )
|
||||
local limit = math.random(20,120)
|
||||
|
||||
local roles_ind = {}
|
||||
for role in pairs(roles) do
|
||||
table.insert( roles_ind, role)
|
||||
end
|
||||
|
||||
for i = 1,limit do
|
||||
local rolei = math.random(1, #roles_ind)
|
||||
local role = roles_ind[rolei]
|
||||
|
||||
table.insert(t[role],
|
||||
{
|
||||
"Fake#" .. (tostring(math.random())):sub(3,-math.random(1,10)),
|
||||
{
|
||||
r=math.random(),
|
||||
g=math.random(),
|
||||
b=math.random()
|
||||
}
|
||||
}
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
local function get_random_from_table(tbl)
|
||||
return tbl[math.random(1,#tbl)]
|
||||
end
|
||||
|
||||
local function subgui_update_role_counter(gui_parent, count_diff)
|
||||
local count_label
|
||||
if gui_parent["role_counter"] then
|
||||
count_label = gui_parent["role_counter"]
|
||||
else
|
||||
count_label = gui_parent.add {type = "label", caption = 0, name = "role_counter", single_line = false}
|
||||
count_label.style.font = "default-small-bold"
|
||||
count_label.style.maximal_height = 10
|
||||
count_label.style.top_padding = 0
|
||||
count_label.style.left_padding = 0
|
||||
count_label.style.right_padding = 0
|
||||
count_label.style.bottom_padding = 0
|
||||
count_label.style.font_color = {r=.55,g=.55,b=.55}
|
||||
end
|
||||
|
||||
local new_count = tonumber(count_label.caption) + count_diff
|
||||
count_label.caption = new_count
|
||||
if new_count == 0 then
|
||||
count_label.style.visible = false
|
||||
else
|
||||
count_label.style.visible = true
|
||||
end
|
||||
end
|
||||
|
||||
local function subgui_add_player_label(gui_parent, pname, pcolor)
|
||||
local color_k = 0.6
|
||||
|
||||
local name_label = gui_parent.add {type = "label", name = "list_players_"..pname, caption = pname, want_ellipsis = true, single_line = false}
|
||||
name_label.style.font = "default"
|
||||
name_label.style.top_padding = 0
|
||||
name_label.style.right_padding = 4
|
||||
name_label.style.left_padding = 2
|
||||
name_label.style.bottom_padding = 0
|
||||
name_label.style.maximal_height = 11
|
||||
name_label.style.minimal_height = 11
|
||||
name_label.style.maximal_width = 120
|
||||
name_label.style.minimal_width = 120
|
||||
name_label.style.font_color = {
|
||||
r = .4 + pcolor.r * color_k,
|
||||
g = .4 + pcolor.g * color_k,
|
||||
b = .4 + pcolor.b * color_k,
|
||||
}
|
||||
end
|
||||
|
||||
-- dev_icons(ctrl + click): show icon-choose buttons
|
||||
-- dev_addfakes(alt + click): add random number of player names w/ color
|
||||
expand_band_gui = function(player, dev_icons, dev_addfakes, right_click)
|
||||
player.gui.left.direction = "horizontal"
|
||||
local frame = player.gui.left["band_panel"]
|
||||
if (frame) then
|
||||
frame.destroy()
|
||||
|
||||
if player.gui.center["textfield_item_icon_frame"] then
|
||||
player.gui.center["textfield_item_icon_frame"].destroy()
|
||||
end
|
||||
if player.tag ~= "" then
|
||||
player.gui.top.band_toggle_btn.tooltip = "Tag: "..player.tag.."\n Right Click to show offline players with tags."
|
||||
if player.admin then
|
||||
player.gui.top.band_toggle_btn.tooltip = player.gui.top.band_toggle_btn.tooltip.."\n CTRL + Click to explore icons.\n ALT + Click to add fake names"
|
||||
end
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
local player_role = player.tag:sub(2,-2)
|
||||
|
||||
-- Will be filled: { roleN = {{name,color},...} , ...}
|
||||
local players_by_role = {}
|
||||
|
||||
for role in pairs(roles) do
|
||||
players_by_role[role] = {}
|
||||
end
|
||||
|
||||
if right_click then
|
||||
for _, oplayer in pairs(game.players) do
|
||||
local prole = oplayer.tag:sub(2,-2)
|
||||
if prole ~= "" then
|
||||
if oplayer.connected then
|
||||
table.insert( players_by_role[prole], {oplayer.name, oplayer.color})
|
||||
else
|
||||
table.insert( players_by_role[prole], {oplayer.name, {r=0,g=0,b=0}})
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
for _, oplayer in pairs(game.connected_players) do
|
||||
local prole = oplayer.tag:sub(2,-2)
|
||||
if prole ~= "" then
|
||||
table.insert( players_by_role[prole], {oplayer.name, oplayer.color})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
if dev_addfakes then
|
||||
test_fake_players(players_by_role)
|
||||
end
|
||||
|
||||
player.gui.top.band_toggle_btn.tooltip = ""
|
||||
|
||||
local button--reusable variable :D
|
||||
local frame = player.gui.left.add { type = "frame", direction = "vertical", name = "band_panel", caption = "Choose your role:"}
|
||||
frame.style.font = "default-listbox"
|
||||
frame.style.font_color = { r=0.98, g=0.66, b=0.22}
|
||||
|
||||
if dev_icons then
|
||||
local choose
|
||||
local chooselist = frame.add { type = "flow", direction = "horizontal" }
|
||||
-- ["signal"] = {type = "virtual", name = "signal-A"}
|
||||
for itype, ivalue in pairs({["item"] = "green-wire", ["entity"] = "medium-spitter", ["tile"] = "grass"}) do
|
||||
choose = chooselist.add { type = "choose-elem-button", elem_type = itype, [itype] = ivalue, name = "help_item_icon_choose_"..itype }
|
||||
choose.style.minimal_height = 36
|
||||
choose.style.minimal_width = 36
|
||||
choose.style.top_padding = 2
|
||||
choose.style.left_padding = 2
|
||||
choose.style.right_padding = 2
|
||||
choose.style.bottom_padding = 2
|
||||
end
|
||||
end
|
||||
|
||||
local scroll = frame.add{type = "scroll-pane", name = "scroll", horizontal_scroll_policy = "never", vertical_scroll_policy = "auto"}
|
||||
scroll.style.maximal_height = 600
|
||||
scroll.style.minimal_width = 250
|
||||
scroll.style.bottom_padding = 10
|
||||
|
||||
local table_roles = scroll.add{type = "table", name = "table_roles", colspan = 2}
|
||||
table_roles.style.horizontal_spacing = 15
|
||||
table_roles.style.vertical_spacing = 4
|
||||
|
||||
|
||||
local name_label
|
||||
local pname
|
||||
local pcolor
|
||||
|
||||
local show_role_tooltip = math.random() > .5
|
||||
|
||||
for role, role_icons in pairs(roles) do
|
||||
|
||||
local role_line = table_roles.add { type = "flow", direction = "horizontal" }
|
||||
|
||||
button = role_line.add { type = "sprite-button", sprite = get_random_from_table(role_icons), name = "band_role_"..role, style = "recipe_slot_button_style"}
|
||||
button.style.top_padding = 4
|
||||
button.style.left_padding = 0
|
||||
button.style.right_padding = 0
|
||||
button.style.bottom_padding = 4
|
||||
if show_role_tooltip and role_icons.tooltip then
|
||||
button.tooltip = get_random_from_table( role_icons.tooltip )
|
||||
end
|
||||
|
||||
local role_cap_line = role_line.add { type = "flow", name = "role_cap_line", direction = "horizontal" }
|
||||
role_cap_line.style.max_on_row = 1
|
||||
|
||||
local role_label = role_cap_line.add { type = "label", caption = role, single_line = true}
|
||||
-- role_label.style.minimal_width = 0
|
||||
role_label.style.minimal_height = 0
|
||||
role_label.style.maximal_height = 12
|
||||
role_label.style.top_padding = 0
|
||||
role_label.style.left_padding = 0
|
||||
role_label.style.right_padding = 0
|
||||
role_label.style.bottom_padding = 0
|
||||
role_label.style.font = "default-bold"
|
||||
if role == player_role then
|
||||
role_label.style.font_color = {r=.7,g=1,b=.7}
|
||||
end
|
||||
|
||||
subgui_update_role_counter(role_cap_line, #players_by_role[role])
|
||||
|
||||
local list_players = table_roles.add { type = "flow", direction = "horizontal" }
|
||||
list_players.style.max_on_row = 3
|
||||
list_players.style.top_padding = 0
|
||||
list_players.style.bottom_padding = 7
|
||||
|
||||
if players_by_role[role] then
|
||||
for _,pdata in pairs(players_by_role[role]) do
|
||||
pname = pdata[1]
|
||||
pcolor = pdata[2]
|
||||
subgui_add_player_label(list_players, pname, pcolor)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local close_btn_flow = frame.add { type = "flow", direction = "horizontal" }
|
||||
button = close_btn_flow.add { type = "button", caption = "Close", name = "band_close" }
|
||||
button.style.font = "default-bold"
|
||||
button.style.minimal_width = 80
|
||||
button.style.maximal_height = 26
|
||||
button.style.top_padding = 0
|
||||
button.style.left_padding = 2
|
||||
button.style.right_padding = 2
|
||||
button.style.bottom_padding = 0
|
||||
|
||||
button = close_btn_flow.add { type = "button", caption = "Clear tag", name = "band_clear" }
|
||||
button.style.font = "default-bold"
|
||||
button.style.font_color = {r=1, g=.7, b=.7}
|
||||
button.style.minimal_width = 80
|
||||
button.style.maximal_height = 28
|
||||
button.style.top_padding = 0
|
||||
button.style.left_padding = 2
|
||||
button.style.right_padding = 2
|
||||
button.style.bottom_padding = 0
|
||||
end
|
||||
|
||||
local function print_role_change(name, role)
|
||||
local str = nil
|
||||
if role then
|
||||
if roles[role].verbs and math.random() > 0.7 then
|
||||
str = (get_random_from_table(to_print))
|
||||
else
|
||||
str = ("[%band] squad has `" .. get_random_from_table(roles[role].verbs) .. "` with %name.")
|
||||
end
|
||||
str = str:gsub('%%band', role)
|
||||
--[[elseif local_role then
|
||||
str = "%name is not in a squad anymore"
|
||||
if math.random() > .9 then
|
||||
str = str .. " (["..local_role.."] squad will miss you)."
|
||||
end]]--
|
||||
end
|
||||
|
||||
if str then
|
||||
str = str:gsub('%%name', name)
|
||||
game.print(str)
|
||||
end
|
||||
end
|
||||
|
||||
-- messy (bcs WIP)
|
||||
local function update_player_role(player, role)
|
||||
|
||||
global.update_player_name = player
|
||||
global.update_player_role_name = role
|
||||
|
||||
if global.update_player_role_name then
|
||||
global.update_player_name.tag = "[" .. global.update_player_role_name .. "]"
|
||||
else
|
||||
global.update_player_name.tag = ""
|
||||
end
|
||||
|
||||
-- update other player gui (counter & label)
|
||||
--[[
|
||||
for _,cplayer in pairs( game.connected_players ) do
|
||||
if cplayer.gui.left.band_panel then
|
||||
local troles = cplayer.gui.left.band_panel.scroll.table_roles
|
||||
|
||||
if local_role then
|
||||
local player_label = troles.children[roles[local_role].index*2]["list_players_" .. cplayer.name]
|
||||
if player_label then
|
||||
player_label.destroy()
|
||||
end
|
||||
end
|
||||
|
||||
if global.update_player_role_name then
|
||||
subgui_add_player_label( troles.children[roles[global.update_player_role_name].index*2], cplayer.name, cplayer.color)
|
||||
subgui_update_role_counter( troles.children[roles[global.update_player_role_name].index*2 - 1].role_cap_line, 1)
|
||||
end
|
||||
|
||||
if local_role then
|
||||
subgui_update_role_counter( troles.children[roles[local_role].index*2 - 1].role_cap_line, -1)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- update local player gui (role label color)
|
||||
local troles_local = player.gui.left.band_panel.scroll.table_roles
|
||||
|
||||
if local_role then
|
||||
troles_local.children[roles[local_role].index*2 - 1].children[2].children[1].style.font_color = {r=1,g=1,b=1}
|
||||
end
|
||||
|
||||
if global.update_player_role_name then
|
||||
troles_local.children[roles[global.update_player_role_name].index*2 - 1].children[2].children[1].style.font_color = {r=.7,g=1,b=.7}
|
||||
end
|
||||
--]]
|
||||
|
||||
print_role_change(global.update_player_name.name, global.update_player_role_name)
|
||||
expand_band_gui(player)
|
||||
expand_band_gui(player)
|
||||
|
||||
local_role = role
|
||||
end
|
||||
|
||||
local function on_gui_click(event)
|
||||
if not (event and event.element and event.element.valid) then return end
|
||||
local player = game.players[event.element.player_index]
|
||||
local name = event.element.name
|
||||
|
||||
if (name == "band_toggle_btn") then
|
||||
--player, dev_icons, dev_addfakes
|
||||
expand_band_gui(player,
|
||||
player.admin and event.control,
|
||||
player.admin and event.alt,
|
||||
event.button == defines.mouse_button_type.right)
|
||||
end
|
||||
|
||||
if (name == "band_close") then
|
||||
expand_band_gui(player)
|
||||
return
|
||||
end
|
||||
|
||||
if (name == "band_clear") then
|
||||
|
||||
update_player_role(player, nil)
|
||||
|
||||
player.gui.top.band_toggle_btn.caption = "Tag"
|
||||
player.gui.top.band_toggle_btn.tooltip = ""
|
||||
player.gui.top.band_toggle_btn.sprite = ""
|
||||
-- expand_band_gui(player)
|
||||
return
|
||||
end
|
||||
|
||||
--role button clicked
|
||||
if name:find("band_role_") == 1 then
|
||||
if not player.admin and event.tick - band_last_change < option_band_change_interval then
|
||||
player.print("Too fast! Please wait... " .. math.floor(1+(band_last_change + option_band_change_interval - event.tick)/60).." s.")
|
||||
return
|
||||
end
|
||||
local _,role_ind_start = name:find("band_role_")
|
||||
local name_role = name:sub(role_ind_start + 1)
|
||||
|
||||
if player.tag:find(name_role) then
|
||||
-- current tag = new tag
|
||||
return
|
||||
end
|
||||
|
||||
for role, role_icons in pairs(roles) do
|
||||
if (name_role == role) then
|
||||
band_last_change = event.tick
|
||||
|
||||
player.gui.top.band_toggle_btn.caption = ""
|
||||
player.gui.top.band_toggle_btn.sprite = event.element.sprite --get_random_from_table(role_icons)
|
||||
|
||||
update_player_role(player, role)
|
||||
-- expand_band_gui(player)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--handle choose-item button
|
||||
local function on_gui_elem_changed(event)
|
||||
if not (event and event.element and event.element.valid) then return end
|
||||
local player = game.players[event.element.player_index]
|
||||
local name = event.element.name
|
||||
if name:find("help_item_icon_choose") then
|
||||
if player.gui.center["textfield_item_icon_frame"] then
|
||||
player.gui.center["textfield_item_icon_frame"].destroy()
|
||||
end
|
||||
if event.element.elem_type and event.element.elem_value then
|
||||
local frame = player.gui.center.add{ type = "frame", name = "textfield_item_icon_frame", caption = "SpritePath"}
|
||||
frame.style.minimal_width = 310
|
||||
local textfield
|
||||
-- if type(event.element.elem_value ) == 'table' then
|
||||
-- textfield = frame.add { name = "textfield_item_icon", type = "textfield", text = "virtual-signal/" .. event.element.elem_value.name }
|
||||
-- else
|
||||
textfield = frame.add { name = "textfield_item_icon", type = "textfield", text = event.element.elem_type .. "/" .. event.element.elem_value }
|
||||
-- end
|
||||
|
||||
--buggy
|
||||
textfield.style.minimal_width = 300
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
Event.register(defines.events.on_gui_elem_changed, on_gui_elem_changed)
|
||||
Event.register(defines.events.on_gui_click, on_gui_click)
|
||||
Event.register(defines.events.on_player_joined_game, create_band_gui)
|
230
band_roles.lua
Normal file
230
band_roles.lua
Normal file
@@ -0,0 +1,230 @@
|
||||
-- A part of band.lua
|
||||
-- Feel free to edit.
|
||||
|
||||
return {
|
||||
|
||||
["to_print"] = {
|
||||
-- "%name now in the [%band] group.",
|
||||
"%name has joined the [%band] party.",
|
||||
"%name is now supporting the [%band] party."
|
||||
},
|
||||
|
||||
["roles"] = {
|
||||
|
||||
["Trooper"] = {
|
||||
"item/tank",
|
||||
tooltip = {
|
||||
"Incoming!!!",
|
||||
"If the facts don't fit the theory, change the facts.",
|
||||
"I suppose it is tempting, if the only tool you have is a hammer, to treat everything as if it were a nail.",
|
||||
"There's a fine line between genius and insanity. I have erased this line."
|
||||
},
|
||||
verbs = {
|
||||
"strengthened",
|
||||
}
|
||||
},
|
||||
|
||||
["Mining"] = {
|
||||
--"item/steel-axe",
|
||||
"item/iron-axe",
|
||||
-- "item/iron-ore",
|
||||
-- "item/copper-ore",
|
||||
tooltip = {
|
||||
"Mine or not to mine",
|
||||
"The nation behaves well if it treats the natural resources as assets which\n it must turn over to the next generation increased, and not impaired, in value."
|
||||
},
|
||||
verbs = {
|
||||
"enriched"
|
||||
-- "smelted"
|
||||
}
|
||||
},
|
||||
|
||||
["Smelting"] = {
|
||||
--"item/assembling-machine-1",
|
||||
"item/steel-furnace",
|
||||
--"item/assembling-machine-3",
|
||||
--"item/inserter",
|
||||
--"item/stack-inserter",
|
||||
tooltip = {
|
||||
"Mirrors are ice which do not melt: what melts are those who admire themselves in them.",
|
||||
"It's as certain that as long as fossil fuels are the cheapest energy, we will just keep burning them."
|
||||
},
|
||||
verbs = {
|
||||
"fused"
|
||||
}
|
||||
},
|
||||
|
||||
["Production"] = {
|
||||
"item/assembling-machine-1",
|
||||
"item/assembling-machine-2",
|
||||
"item/assembling-machine-3",
|
||||
--"item/inserter",
|
||||
--"item/stack-inserter",
|
||||
tooltip = {
|
||||
"When every physical and mental resources is focused, one's power to solve a problem multiplies tremendously.",
|
||||
"The production of too many useful things results in too many useless people. ",
|
||||
"Everything must be made as simple as possible. But not simpler."
|
||||
},
|
||||
verbs = {
|
||||
"enhanced"
|
||||
}
|
||||
},
|
||||
|
||||
["Science"] = {
|
||||
"item/science-pack-1",
|
||||
"item/science-pack-2",
|
||||
"item/science-pack-3",
|
||||
"item/military-science-pack",
|
||||
"item/production-science-pack",
|
||||
"item/high-tech-science-pack",
|
||||
"item/space-science-pack",
|
||||
tooltip = {
|
||||
"Science without religion is lame, religion without science is blind",
|
||||
"If we knew what it was we were doing, it would not be called research, would it?",
|
||||
"Somewhere, something incredible is waiting to be known.",
|
||||
"I'm sure the universe is full of intelligent life. It's just been too intelligent to come here."
|
||||
},
|
||||
verbs = {
|
||||
"advanced"
|
||||
}
|
||||
},
|
||||
|
||||
["Wizard"] = {
|
||||
|
||||
"item/green-wire",
|
||||
"item/red-wire",
|
||||
"item/arithmetic-combinator",
|
||||
"item/decider-combinator",
|
||||
|
||||
tooltip = {
|
||||
"Without mathematics, there's nothing you can do. Everything around you is mathematics. Everything around you is numbers.",
|
||||
"Pure mathematics is, in its way, the poetry of logical ideas.",
|
||||
"God used beautiful mathematics in creating the world.",
|
||||
"The numbers may be said to rule the whole world of quantity, and the four rules of arithmetic may be regarded as the complete equipment of the mathematician.",
|
||||
"But if the technological Singularity can happen, it will."
|
||||
--"One day it will have a mind of it´s own!."
|
||||
},
|
||||
verbs = {
|
||||
"combinated",
|
||||
"equaled"
|
||||
}
|
||||
},
|
||||
|
||||
["Trains"] = {
|
||||
--"entity/curved-rail",
|
||||
--"item/cargo-wagon",
|
||||
--"item/fluid-wagon",
|
||||
"item/locomotive",
|
||||
--"item/rail-signal",
|
||||
--"item/rail",
|
||||
tooltip = {
|
||||
"Ch, ch, choooo!",
|
||||
"The only way of catching a train I have ever discovered is to miss the train before. ",
|
||||
"If a trainstation is where the train stops, what's a workstation...?"
|
||||
},
|
||||
verbs = {
|
||||
"expanded",
|
||||
"derailed"
|
||||
}
|
||||
},
|
||||
|
||||
["Oil"] = {
|
||||
--"item/storage-tank",
|
||||
--"item/pipe-to-ground",
|
||||
--"item/oil-refinery",
|
||||
--"item/chemical-plant",
|
||||
"item/pumpjack",
|
||||
"fluid/crude-oil",
|
||||
--"fluid/heavy-oil",
|
||||
--"fluid/light-oil",
|
||||
--"fluid/petroleum-gas",
|
||||
--"fluid/lubricant",
|
||||
--"fluid/sulfuric-acid",
|
||||
tooltip = {
|
||||
"We're running out of oil!",
|
||||
"Black gold",
|
||||
"Naturally occurring, yellow-to-black liquid found in geological formations beneath the Earth's surface, which is commonly refined into various types of fuels.",
|
||||
"Components of petroleum are separated using a technique called fractional distillation.",
|
||||
"The petroleum industry generally classifies crude oil by the geographic location it is produced in (e.g. West Texas Intermediate, Brent, or Oman), its API gravity (an oil industry measure of density), and its sulfur content."
|
||||
},
|
||||
verbs = {
|
||||
"lubricated",
|
||||
"sulfured"
|
||||
}
|
||||
},
|
||||
|
||||
["Powah!"] = {
|
||||
"item/steam-turbine",
|
||||
--"item/nuclear-reactor",
|
||||
--"item/heat-exchanger",
|
||||
"item/steam-engine",
|
||||
"item/solar-panel",
|
||||
"item/accumulator",
|
||||
--"item/boiler",
|
||||
--"fluid/steam",
|
||||
tooltip = {
|
||||
"I ve Got The power!",
|
||||
"Power Overwhelming!!!111",
|
||||
"Its Over 9000!!!",
|
||||
"If you want to find the secrets of the universe, think in terms of energy, frequency and vibration."
|
||||
},
|
||||
verbs = {
|
||||
"amplified",
|
||||
"teslaed",
|
||||
"electrified"
|
||||
}
|
||||
},
|
||||
|
||||
["Spaceman"] = {
|
||||
"item/rocket-silo",
|
||||
"item/rocket-control-unit",
|
||||
"item/satellite",
|
||||
"item/rocket-fuel",
|
||||
tooltip = {
|
||||
"That's one small step for a man, one giant leap for mankind.",
|
||||
"The sky is the limit only for those who aren't afraid to fly!",
|
||||
"Apocalyptic explosions, dead reactors, terrorists, mass murder, death-slugs, and now a blindness plague. This is a terrible planet. We should not have come here.",
|
||||
"A still more glorious dawn awaits. Not a sunrise, but a galaxy rise. A morning filled with 400 billion suns. The rising of the milky way",
|
||||
"The Universe is under no obligation to make sense to you."
|
||||
},
|
||||
verbs = {
|
||||
"warped"
|
||||
}
|
||||
},
|
||||
|
||||
["Cat"] = {
|
||||
"item/raw-fish",
|
||||
|
||||
tooltip = {
|
||||
"=^.^=",
|
||||
"Meow",
|
||||
"In a cat's eye, all things belong to cats.",
|
||||
"Cats don't like change without their consent.",
|
||||
"Heard melodies are sweet, but those unheard, are sweeter"
|
||||
},
|
||||
verbs = {
|
||||
"mewed",
|
||||
"purred",
|
||||
"miaowed"
|
||||
}
|
||||
},
|
||||
|
||||
["Dog"] = {
|
||||
"entity/small-biter",
|
||||
"entity/medium-biter",
|
||||
"entity/big-biter",
|
||||
"entity/behemoth-biter",
|
||||
tooltip = {
|
||||
"Not a cat",
|
||||
"Friend",
|
||||
"It's not the size of the dog in the fight, it's the size of the fight in the dog.",
|
||||
"When what you want is a relationship, and not a person, get a dog",
|
||||
"A dog has one aim in life... to bestow his heart."
|
||||
},
|
||||
verbs = {
|
||||
"woofed",
|
||||
"howled"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
9
base_data.lua
Normal file
9
base_data.lua
Normal file
@@ -0,0 +1,9 @@
|
||||
if not global.score_biter_total_kills then global.score_biter_total_kills = 0 end
|
||||
|
||||
local function biter_kill_counter(event)
|
||||
if event.entity.force.name == "enemy" then
|
||||
global.score_biter_total_kills = global.score_biter_total_kills + 1
|
||||
end
|
||||
end
|
||||
|
||||
Event.register(defines.events.on_entity_died, biter_kill_counter)
|
BIN
blueprint.dat
Normal file
BIN
blueprint.dat
Normal file
Binary file not shown.
15
config.lua
Normal file
15
config.lua
Normal file
@@ -0,0 +1,15 @@
|
||||
Event.register(-1, function()
|
||||
global.scenario = {}
|
||||
global.scenario.config = {}
|
||||
global.scenario.config.announcements_enabled = false -- if true announcements will be shown
|
||||
global.scenario.config.announcement_delay = 1000 -- number of seconds between each announcement
|
||||
global.scenario.config.score_delay = 8 -- delay in seconds before hiding rocket score window (0 = never show)
|
||||
global.scenario.config.autolaunch_default = false -- default autolaunch option
|
||||
global.scenario.config.logistic_research_enabled = true -- if true then research for requesters and active providers will be enabled.
|
||||
global.scenario.config.mapsettings = global.scenario.config.mapsettings or {}
|
||||
global.scenario.config.mapsettings.cross_width = 200 -- total width of cross
|
||||
global.scenario.config.mapsettings.spiral_land_width = 70 -- width of land in spiral
|
||||
global.scenario.config.mapsettings.spiral_water_width = 70 -- width of water in spiral
|
||||
global.scenario.custom_functions = {}
|
||||
end)
|
||||
|
118
control.lua
Normal file
118
control.lua
Normal file
@@ -0,0 +1,118 @@
|
||||
require "util"
|
||||
require "locale/utils/event"
|
||||
require "config"
|
||||
require "locale/utils/utils"
|
||||
require "base_data"
|
||||
require "info"
|
||||
require "poll"
|
||||
require "band"
|
||||
require "fish_market"
|
||||
require "train_station_names"
|
||||
require "score"
|
||||
require "map_layout"
|
||||
|
||||
|
||||
function player_joined(event)
|
||||
local player = game.players[event.player_index]
|
||||
player.insert { name = "raw-fish", count = 4 }
|
||||
player.insert { name = "iron-gear-wheel", count = 8 }
|
||||
player.insert { name = "iron-plate", count = 16 }
|
||||
--player.insert { name = "pistol", count = 1 }
|
||||
--player.insert { name = "firearm-magazine", count = 8 }
|
||||
--player.insert { name = "train-stop", count = 16 }
|
||||
--player.insert { name = "roboport", count = 16 }
|
||||
--player.insert { name = "construction-robot", count = 16 }
|
||||
--player.insert { name = "solar-panel", count = 16 }
|
||||
--player.insert { name = "substation", count = 16 }
|
||||
--player.insert { name = "logistic-chest-passive-provider", count = 16 }
|
||||
--player.insert { name = "power-armor", count = 1 }
|
||||
player.print("bar")
|
||||
player.print("And remember.. Keep Calm And Spaghetti!")
|
||||
end
|
||||
|
||||
function walkabout(player_name, distance)
|
||||
|
||||
if distance == nil then
|
||||
--game.print("Specify rough distance for the walkabout.")
|
||||
distance = math.random(5000, 10000)
|
||||
return
|
||||
end
|
||||
|
||||
if distance == "close" then
|
||||
distance = math.random(3000, 7000)
|
||||
end
|
||||
if distance == "far" then
|
||||
distance = math.random(7000, 11000)
|
||||
end
|
||||
if distance == "very far" then
|
||||
distance = math.random(11000, 15000)
|
||||
end
|
||||
|
||||
local x = 1
|
||||
while game.players[x] ~= nil do
|
||||
local player = game.players[x]
|
||||
if player_name == player.name then
|
||||
local repeat_attempts = 5
|
||||
local r = 1
|
||||
local surface = game.surfaces[1]
|
||||
local distance_max = distance * 1.05
|
||||
local distance_min = distance * 0.95
|
||||
distance_max = round(distance_max, 0)
|
||||
distance_min = round(distance_min, 0)
|
||||
|
||||
--while r <= repeat_attempts do
|
||||
x = math.random(distance_min, distance_max)
|
||||
if 1 == math.random(1, 2) then
|
||||
x = x * -1
|
||||
end
|
||||
|
||||
y = math.random(distance_min, distance_max)
|
||||
if 1 == math.random(1, 2) then
|
||||
y = y * -1
|
||||
end
|
||||
|
||||
if 1 == math.random(1, 2) then
|
||||
z = distance_max * -1
|
||||
x = math.random(z, distance_max)
|
||||
else
|
||||
z = distance_max * -1
|
||||
y = math.random(z, distance_max)
|
||||
end
|
||||
|
||||
--r = r + 1
|
||||
--local tile = surface.get_tile(x,y)
|
||||
--game.print(tile.name)
|
||||
--if tile.name == "deep-water" or tile.name == "water" then
|
||||
--if r >= repeat_attempts then
|
||||
--game.print(player_name .. " tried to go on a walkabout, but could only find water.")
|
||||
--return
|
||||
--end
|
||||
--else
|
||||
local pos = {x, y}
|
||||
player.teleport(pos)
|
||||
game.print(player_name .. " went on a walkabout, to find himself.")
|
||||
return
|
||||
--end
|
||||
--end
|
||||
end
|
||||
x = x + 1
|
||||
end
|
||||
game.print(player_name .. " could not go on a walkabout.")
|
||||
end
|
||||
--function player_respawned(event)
|
||||
--local player = game.players[event.player_index]
|
||||
--player.insert { name = "pistol", count = 1 }
|
||||
--player.insert { name = "firearm-magazine", count = 10 }
|
||||
--end
|
||||
|
||||
Event.register(defines.events.on_research_finished, function (event)
|
||||
local research = event.research
|
||||
if global.scenario.config.logistic_research_enabled then
|
||||
research.force.technologies["logistic-system"].enabled=true
|
||||
else
|
||||
research.force.technologies["logistic-system"].enabled=false
|
||||
end
|
||||
end)
|
||||
|
||||
Event.register(defines.events.on_player_created, player_joined)
|
||||
Event.register(defines.events.on_player_respawned, player_respawned)
|
168
fish_market.lua
Normal file
168
fish_market.lua
Normal file
@@ -0,0 +1,168 @@
|
||||
--[[
|
||||
Hello there script explorer!
|
||||
|
||||
With this you can add a "Fish Market" to your World
|
||||
You can earn fish by killing alot of biters or by mining wood, ores, rocks.
|
||||
To spawn the market, do "/c market()" in your chat ingame as the games host.
|
||||
It will spawn a few tiles north of the current position where your character is.
|
||||
|
||||
---MewMew---
|
||||
--]]
|
||||
|
||||
function market()
|
||||
local radius = 10
|
||||
local surface = game.surfaces[1]
|
||||
-- clear trees and landfill in start area
|
||||
local start_area = {left_top = {-20, -20}, right_bottom = {20, 20}}
|
||||
for _, e in pairs(surface.find_entities_filtered{area=start_area, type="tree"}) do
|
||||
--e.destroy()
|
||||
end
|
||||
for i = -radius, radius, 1 do
|
||||
for j = -radius, radius, 1 do
|
||||
if (surface.get_tile(i,j).collides_with("water-tile")) then
|
||||
--surface.set_tiles{{name = "grass", position = {i,j}}}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local player = game.players[1]
|
||||
|
||||
local market_location = {x = player.position.x, y = player.position.y}
|
||||
market_location.y = market_location.y - 4
|
||||
|
||||
-- create water around market
|
||||
local waterTiles = {}
|
||||
for i = -4, 4 do
|
||||
for j = -4, 4 do
|
||||
--table.insert(waterTiles, {name = "water-green", position={market_location.x + i, market_location.y + j}})
|
||||
end
|
||||
end
|
||||
surface.set_tiles(waterTiles)
|
||||
local market = surface.create_entity{name="market", position=market_location, force=force}
|
||||
market.destructible = false
|
||||
|
||||
market.add_market_item{price={{"raw-fish", 1}}, offer={type="give-item", item="rail", count=2}}
|
||||
market.add_market_item{price={{"raw-fish", 2}}, offer={type="give-item", item="rail-signal"}}
|
||||
market.add_market_item{price={{"raw-fish", 2}}, offer={type="give-item", item="rail-chain-signal"}}
|
||||
market.add_market_item{price={{"raw-fish", 15}}, offer={type="give-item", item="train-stop"}}
|
||||
market.add_market_item{price={{"raw-fish", 75}}, offer={type="give-item", item="locomotive"}}
|
||||
market.add_market_item{price={{"raw-fish", 250}}, offer={type="give-item", item="small-plane"}}
|
||||
market.add_market_item{price={{"raw-fish", 30}}, offer={type="give-item", item="cargo-wagon"}}
|
||||
market.add_market_item{price={{"raw-fish", 1}}, offer={type="give-item", item="red-wire", count=2}}
|
||||
market.add_market_item{price={{"raw-fish", 1}}, offer={type="give-item", item="green-wire", count=2}}
|
||||
market.add_market_item{price={{"raw-fish", 3}}, offer={type="give-item", item="decider-combinator"}}
|
||||
market.add_market_item{price={{"raw-fish", 3}}, offer={type="give-item", item="arithmetic-combinator"}}
|
||||
market.add_market_item{price={{"raw-fish", 3}}, offer={type="give-item", item="constant-combinator"}}
|
||||
market.add_market_item{price={{"raw-fish", 7}}, offer={type="give-item", item="programmable-speaker"}}
|
||||
market.add_market_item{price={{"raw-fish", 3}}, offer={type="give-item", item="piercing-rounds-magazine"}}
|
||||
market.add_market_item{price={{"raw-fish", 2}}, offer={type="give-item", item="grenade"}}
|
||||
market.add_market_item{price={{"raw-fish", 1}}, offer={type="give-item", item="land-mine"}}
|
||||
market.add_market_item{price={{"raw-fish", 1}}, offer={type="give-item", item="solid-fuel"}}
|
||||
market.add_market_item{price={{"raw-fish", 125}}, offer={type="give-item", item="rocket-launcher"}}
|
||||
market.add_market_item{price={{"raw-fish", 15}}, offer={type="give-item", item="rocket"}}
|
||||
market.add_market_item{price={{"raw-fish", 20}}, offer={type="give-item", item="explosive-rocket"}}
|
||||
market.add_market_item{price={{"raw-fish", 2500}}, offer={type="give-item", item="atomic-bomb"}}
|
||||
market.add_market_item{price={{"raw-fish", 1000}}, offer={type="give-item", item="belt-immunity-equipment"}}
|
||||
|
||||
end
|
||||
|
||||
local function create_market_init_button(event)
|
||||
local player = game.players[1]
|
||||
|
||||
if player.gui.top.poll == nil then
|
||||
local button = player.gui.top.add { name = "poll", type = "sprite-button", sprite = "item/programmable-speaker" }
|
||||
button.style.font = "default-bold"
|
||||
button.style.minimal_height = 38
|
||||
button.style.minimal_width = 38
|
||||
button.style.top_padding = 2
|
||||
button.style.left_padding = 4
|
||||
button.style.right_padding = 4
|
||||
button.style.bottom_padding = 2
|
||||
end
|
||||
end
|
||||
|
||||
local fish_market_message = {}
|
||||
|
||||
local fish_market_bonus_message = {"Why don’t fish like basketball? Cause they’re afraid of the net", "What do you get when you cross a banker with a fish? A Loan shark!", "How do you make an Octupus laugh? With ten-tickles", "What do you call a fish that needs help with his or her vocals? Autotuna", "What is the difference between a piano and a fish? You can tune a piano but you cannot tuna fish.", "What did the blind man say when he passed the fish market? Good morning ladies.", "Did you hear about the goldfish who went bankrupt? Now he’s a bronze fish.", "What happens when you put nutella on salmon? You get salmonella", "What do you call a fish with no eyes?…Fsh", "What kind of money do fishermen make?…Net profits", "What do you get if you cross a salmon, a bird’s leg and a hand?…Birdsthigh fish fingers", "Why is a fish easy to weigh?…Because it has its own scales", "Why are gold fish orange?…The water makes them rusty", "What was the Tsar of Russia’s favorite fish?…Tsardines", "Why did the dog jump into the sea?…He wanted to chase the catfish", "Which fish dresses the best?…The Swordfish – It always looks sharp", "What do you get if you cross an abbot with a trout?…Monkfish", "What do you call a big fish who makes you an offer you can’t refuse?…The Codfather", "Why is a swordfish’s nose 11 inches long?…If it were 12 inches long it would be a foot", "What do you get if you cross a trout with an apartment?…A flat fish", "Why are fish no good at tennis?…They don’t like to get too close to the net", "How do the fish get to school?…By octobus", "What fish make the best sandwich?…A peanut butter and jellyfish", "Man: Can I have a fly rod and reel for my son?…Fishing Shop Owner: Sorry sir we don’t do trades", "Where do fish keep their money?…In the river bank", "Why do fish like arcade games?…Because they are finball wizards", "What is a mermaid?…A deep-she fish", "What do you get if you cross a whale with rotten fish?…Moby Sick", "Why didn’t the lobster share his toys?…He was too shellfish", "What do fish use to make telephone calls?…a Shell phone", "Why don’t fish make very good tennis balls?…They keep getting caught in the net", "Electric eels and electric rays have enough electricity to kill a horse.", "Most fish have taste buds all over their body.", "Most brands of lipstick contain fish scales.", "A fish does not add new scales as it grows, but the scales it has increase in size. In this way, growth rings are formed and the rings reveal the age of a fish.", "An inflated porcupine fish can reach a diameter of up to 35 inches. It puffs up by swallowing water and then storing it in its stomach.", "Most fish cannot swim backwards. Those that can are mainly members of one of the eel families.", "The fastest fish is the sailfish. It can swim as fast as a car travels on the highway.","Some desert pupfish can live in hot springs that reach temperatures greater than 113° F.","Anableps, four-eyed fish, can see above and below water at the same time.","Catfish have over 27,000 taste buds. Humans have around 7,000.","One hagfish can make enough slime in one minute to fill a bucket.","A female sunfish can lay 300 million eggs each year.", "Fish feel pain and suffer stress just like mammals and birds.", "The Dwarf Seahorse is so slow you can’t see it move", "Some fish are as small as a grain of rice", "There's a species of fish called 'Slippery Dick'", "Herrings communicate through farts.", "One Puffer Fish contains enough poison to kill 30 medium-biters.", "When Anglerfish mate, they melt into each other and share their bodies forever.", "A koi fish named 'Hanako' lived for 225 years."}
|
||||
|
||||
local total_fish_market_messages = #fish_market_message
|
||||
local total_fish_market_bonus_messages = #fish_market_bonus_message
|
||||
|
||||
if not global.fish_market_fish_caught then global.fish_market_fish_caught = {} end
|
||||
|
||||
local function fish_earned(event, amount)
|
||||
|
||||
local player = game.players[event.player_index]
|
||||
player.insert { name = "raw-fish", count = amount }
|
||||
|
||||
if global.fish_market_fish_caught[event.player_index] then
|
||||
global.fish_market_fish_caught[event.player_index] = global.fish_market_fish_caught[event.player_index] + 1
|
||||
else
|
||||
global.fish_market_fish_caught[event.player_index] = 1
|
||||
end
|
||||
|
||||
if global.fish_market_fish_caught[event.player_index] <= total_fish_market_messages then
|
||||
local x = global.fish_market_fish_caught[event.player_index]
|
||||
player.print(fish_market_message[x])
|
||||
end
|
||||
|
||||
local x = global.fish_market_fish_caught[event.player_index] % 7
|
||||
if x == 0 then
|
||||
local z = math.random(1,total_fish_market_bonus_messages)
|
||||
player.print(fish_market_bonus_message[z])
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
local function preplayer_mined_item(event)
|
||||
|
||||
-- game.print(event.entity.name)
|
||||
-- game.print(event.entity.type)
|
||||
|
||||
if event.entity.type == "resource" then
|
||||
local x = math.random(1,2)
|
||||
if x == 1 then
|
||||
fish_earned(event, 1)
|
||||
end
|
||||
end
|
||||
|
||||
if event.entity.name == "fish" then
|
||||
fish_earned(event, 0)
|
||||
end
|
||||
|
||||
if event.entity.name == "stone-rock" then
|
||||
fish_earned(event, 10)
|
||||
end
|
||||
|
||||
if event.entity.name == "huge-rock" then
|
||||
fish_earned(event, 25)
|
||||
end
|
||||
|
||||
if event.entity.name == "big-rock" then
|
||||
fish_earned(event, 15)
|
||||
end
|
||||
|
||||
if event.entity.type == "tree" then
|
||||
local x = math.random(1,4)
|
||||
if x == 1 then
|
||||
fish_earned(event, 4)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function fish_drop_entity_died(event)
|
||||
|
||||
if event.entity.force.name == "enemy" then
|
||||
-- global.score_biter_total_kills = global.score_biter_total_kills + 1
|
||||
-- game.print(global.score_biter_total_kills)
|
||||
if global.score_biter_total_kills % 30 == 0 then
|
||||
local surface = event.entity.surface
|
||||
local x = math.random(1,3)
|
||||
surface.spill_item_stack(event.entity.position, { name = "raw-fish", count = x }, 1)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
Event.register(defines.events.on_preplayer_mined_item, preplayer_mined_item)
|
||||
Event.register(defines.events.on_entity_died, fish_drop_entity_died)
|
86
info.lua
Normal file
86
info.lua
Normal file
@@ -0,0 +1,86 @@
|
||||
local function create_info_button(event)
|
||||
local player = game.players[event.player_index]
|
||||
|
||||
if player.gui.top.info == nil then
|
||||
local button = player.gui.top.add({ type = "sprite-button", name = "info_button", sprite = "item/raw-fish" })
|
||||
button.style.minimal_height = 38
|
||||
button.style.minimal_width = 38
|
||||
button.style.top_padding = 2
|
||||
button.style.left_padding = 4
|
||||
button.style.right_padding = 4
|
||||
button.style.bottom_padding = 2
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
local function info_show(player)
|
||||
|
||||
local infotext = [===[
|
||||
Hi stranger, I'm a fish..
|
||||
|
||||
And this is what you ought to know:
|
||||
|
||||
- Please be nice and don't grief.
|
||||
- Fix personal confrontations diplomatically.
|
||||
- No political, racist, or misogynistic content.
|
||||
- If you suspect you desync while connecting,
|
||||
close and relaunch Factorio ASAP. Very bad for us.
|
||||
- Join our community on discord.me/redmew
|
||||
for questions and feedback. Also on /r/redmew (reddit)
|
||||
- You can contribute to server costs and upgrades
|
||||
with bitcoin: 13qh5uJh3UDUiWKyQaybkpxC1gfLVDB1ww
|
||||
]===]
|
||||
|
||||
player.gui.left.direction = "horizontal"
|
||||
local frame = player.gui.left.add { type = "frame", name = "info_panel"}
|
||||
frame.style.top_padding = 20
|
||||
frame.style.left_padding = 20
|
||||
frame.style.right_padding = 20
|
||||
frame.style.bottom_padding = 20
|
||||
local info_table = frame.add { type = "table", colspan = 1, name = "info_table" }
|
||||
local headline_label = info_table.add { type = "label", name = "headline_label", caption = "redmew fishy info" }
|
||||
headline_label.style.font = "default-listbox"
|
||||
headline_label.style.font_color = { r=0.98, g=0.66, b=0.22}
|
||||
|
||||
|
||||
local text_box = info_table.add { type = "text-box", text = infotext, name = "text_box" }
|
||||
text_box.read_only = true
|
||||
text_box.selectable = true
|
||||
text_box.word_wrap = false
|
||||
text_box.style.right_padding = 5
|
||||
text_box.style.top_padding = 5
|
||||
text_box.style.left_padding = 5
|
||||
text_box.style.bottom_padding = 5
|
||||
|
||||
local info_table_2 = info_table.add { type = "table", colspan = 2, name = "info_table" }
|
||||
info_table_2.add { type = "label", caption = " " }
|
||||
local close_button = info_table_2.add { type = "button", caption = "CLOSE", name = "info_close_button" }
|
||||
close_button.style.font = "default-listbox"
|
||||
end
|
||||
|
||||
|
||||
local function on_gui_click(event)
|
||||
if not (event and event.element and event.element.valid) then return end
|
||||
|
||||
local player = game.players[event.element.player_index]
|
||||
local name = event.element.name
|
||||
local frame = player.gui.left["info_panel"]
|
||||
|
||||
if (name == "info_button") and (frame == nil) then
|
||||
info_show(player)
|
||||
else
|
||||
if (name == "info_button") then
|
||||
frame.destroy()
|
||||
end
|
||||
end
|
||||
|
||||
if (name == "info_close_button") then
|
||||
frame.destroy()
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
Event.register(defines.events.on_gui_click, on_gui_click)
|
||||
Event.register(defines.events.on_player_joined_game, create_info_button)
|
6
locale/en/announcements.cfg
Normal file
6
locale/en/announcements.cfg
Normal file
@@ -0,0 +1,6 @@
|
||||
[announcements]
|
||||
msg-intro1=Welcome to our Server. You can join our Discord at: discord.gg/dtXMQq6
|
||||
msg-intro2=And remember.. Keep Calm And Spaghetti!
|
||||
msg-intro3=
|
||||
msg-announce1=
|
||||
msg-announce2=
|
1
locale/en/freeplay.cfg
Normal file
1
locale/en/freeplay.cfg
Normal file
@@ -0,0 +1 @@
|
||||
msg-intro=This is the Factorio freeplay. Your task is to launch a rocket into space. Do this by constructing a Rocket Silo and launching a rocket with a satellite. You will need to research advanced technologies in order to unlock the Rocket Silo. Start small, work your way up with automation and don't forget to protect yourself from the natives.
|
17
locale/en/score-extended.cfg
Normal file
17
locale/en/score-extended.cfg
Normal file
@@ -0,0 +1,17 @@
|
||||
[score-extended]
|
||||
score-gui-title=Score
|
||||
score-gui-tot=Total: __1__ rockets
|
||||
score-gui-nb=Count: __1__ rockets
|
||||
score-gui-delay=Delay: __1__ sec
|
||||
score-gui-delay-tt=Delay since last counter reset
|
||||
score-gui-av1h=Average: __1__ rkts/hr
|
||||
score-gui-av1m=Average: __1__ rkts/min
|
||||
score-gui-av2m=Average: __1__ min/rkt
|
||||
score-gui-av2s=Average: __1__ sec/rkt
|
||||
score-gui-reset=Reset
|
||||
score-gui-reset-tt=Reset counter to last launch time
|
||||
score-gui-prec-up-tt=Increase precision
|
||||
score-gui-prec-down-tt=Lower precision
|
||||
score-gui-count-tot=Total
|
||||
score-gui-autolaunch=Autolaunch
|
||||
score-gui-autoshow=Autoshow/hide
|
40
locale/utils/Colors.lua
Normal file
40
locale/utils/Colors.lua
Normal file
@@ -0,0 +1,40 @@
|
||||
-- Colors Module
|
||||
-- Collection of common colors
|
||||
-- @author Denis Zholob (DDDGamer)
|
||||
-- github: https://github.com/DDDGamer/factorio-dz-softmod
|
||||
-- ======================================================= --
|
||||
|
||||
Colors = {
|
||||
black = { r=0, g=0, b=0 },
|
||||
darkgrey = { r=65, g=65, b=65 },
|
||||
grey = { r=130, g=130, b=130 },
|
||||
lightgrey = { r=190, g=190, b=190 },
|
||||
white = { r=255, g=255, b=255 },
|
||||
|
||||
darkgreen = { r=0, g=130, b=0 },
|
||||
green = {r=25, g=255, b=51 },
|
||||
lightgreen = { r=130, g=255, b=130 },
|
||||
|
||||
cyan = { r=20, g=220, b=190 },
|
||||
|
||||
darkblue = { r=30, g=30, b=180 },
|
||||
blue = { r=0, g=100, b=255 },
|
||||
lightblue = { r=20, g=180, b=235 },
|
||||
|
||||
darkpurple = { r=160, g=50, b=255 },
|
||||
purple = { r=179, g=102, b=255 },
|
||||
violet = { r=130, g=130, b=255 },
|
||||
|
||||
pink = { r=255, g= 0, b=255 },
|
||||
|
||||
darkred = { r=160, g=0, b=0 },
|
||||
red = { r=255, g=0, b=25 },
|
||||
lightred = { r=255, g=130, b=130 },
|
||||
|
||||
darkorange = { r=242, g=70, b=13 },
|
||||
orange = { r=255, g=140, b=25 },
|
||||
yellow = { r=255, g=255, b=0 },
|
||||
brown = { r=0.6, g=0.4, b=0.1 },
|
||||
}
|
||||
|
||||
return Colors
|
26
locale/utils/Time.lua
Normal file
26
locale/utils/Time.lua
Normal file
@@ -0,0 +1,26 @@
|
||||
-- Time Helper Module
|
||||
-- Common Time functions
|
||||
-- @author Denis Zholob (DDDGamer)
|
||||
-- github: https://github.com/DDDGamer/factorio-dz-softmod
|
||||
-- ======================================================= --
|
||||
|
||||
Time = {}
|
||||
|
||||
-- Rounding helper function
|
||||
function round(number, precision)
|
||||
return math.floor(number*math.pow(10,precision)+0.5) / math.pow(10,precision)
|
||||
end
|
||||
|
||||
-- Returns hours converted from game ticks
|
||||
function Time.tick_to_hour(t)
|
||||
local time = game.speed * (t / 60) / 3600
|
||||
return round(time, 1)
|
||||
end
|
||||
|
||||
-- Returns hours converted from game ticks
|
||||
function Time.tick_to_min(t)
|
||||
local time = game.speed * (t / 60) / 60
|
||||
return round(time, 1)
|
||||
end
|
||||
|
||||
return Time
|
10
locale/utils/defines.lua
Normal file
10
locale/utils/defines.lua
Normal file
@@ -0,0 +1,10 @@
|
||||
local player_inventories = {
|
||||
defines.inventory.player_vehicle,
|
||||
defines.inventory.player_armor,
|
||||
defines.inventory.player_tools,
|
||||
defines.inventory.player_guns,
|
||||
defines.inventory.player_ammo,
|
||||
defines.inventory.player_quickbar,
|
||||
defines.inventory.player_main,
|
||||
defines.inventory.player_trash,
|
||||
}
|
131
locale/utils/event.lua
Normal file
131
locale/utils/event.lua
Normal file
@@ -0,0 +1,131 @@
|
||||
--Event Capture
|
||||
--A 3Ra Gaming revision, original from Factorio-Stdlib by Afforess
|
||||
-- @module Event
|
||||
|
||||
function fail_if_missing(var, msg)
|
||||
if not var then
|
||||
if msg then
|
||||
error(msg, 3)
|
||||
else
|
||||
error("Missing value", 3)
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
|
||||
Event = {
|
||||
_registry = {},
|
||||
core_events = {
|
||||
init = -1,
|
||||
load = -2,
|
||||
configuration_changed = -3,
|
||||
_register = function(id)
|
||||
if id == Event.core_events.init then
|
||||
script.on_init(function()
|
||||
Event.dispatch({ name = Event.core_events.init, tick = game.tick })
|
||||
end)
|
||||
elseif id == Event.core_events.load then
|
||||
script.on_load(function()
|
||||
Event.dispatch({ name = Event.core_events.load, tick = -1 })
|
||||
end)
|
||||
elseif id == Event.core_events.configuration_changed then
|
||||
script.on_configuration_changed(function(data)
|
||||
Event.dispatch({ name = Event.core_events.configuration_changed, tick = game.tick, data = data })
|
||||
end)
|
||||
end
|
||||
end
|
||||
}
|
||||
}
|
||||
|
||||
--- Registers a function for a given event
|
||||
-- @param event or array containing events to register
|
||||
-- @param handler Function to call when event is triggered
|
||||
-- @return #Event
|
||||
function Event.register(event, handler)
|
||||
fail_if_missing(event, "missing event argument")
|
||||
|
||||
if type(event) == "number" then
|
||||
event = { event }
|
||||
end
|
||||
|
||||
for _, event_id in pairs(event) do
|
||||
fail_if_missing(event_id, "missing event id")
|
||||
if handler == nil then
|
||||
Event._registry[event_id] = nil
|
||||
script.on_event(event_id, nil)
|
||||
else
|
||||
if not Event._registry[event_id] then
|
||||
Event._registry[event_id] = {}
|
||||
|
||||
if event_id >= 0 then
|
||||
script.on_event(event_id, Event.dispatch)
|
||||
else
|
||||
Event.core_events._register(event_id)
|
||||
end
|
||||
end
|
||||
table.insert(Event._registry[event_id], handler)
|
||||
end
|
||||
end
|
||||
return Event
|
||||
end
|
||||
|
||||
--- Calls the registerd handlers
|
||||
-- @param event LuaEvent as created by game.raise_event
|
||||
function Event.dispatch(event)
|
||||
fail_if_missing(event, "missing event argument")
|
||||
if Event._registry[event.name] then
|
||||
for _, handler in pairs(Event._registry[event.name]) do
|
||||
local metatbl = { __index = function(tbl, key) if key == '_handler' then return handler else return rawget(tbl, key) end end }
|
||||
setmetatable(event, metatbl)
|
||||
local success, err = pcall(handler, event)
|
||||
if not success then
|
||||
-- may be nil in on_load
|
||||
local identifier = event.name
|
||||
for i,v in pairs(defines.events) do
|
||||
if v == event.name then
|
||||
identifier = i
|
||||
end
|
||||
end
|
||||
err = string.gsub(err, "\n", " : ")
|
||||
if event.name < -1 or global.last_error ~= identifier then
|
||||
print("output$Error in event "..identifier..": \""..err.."\".")
|
||||
log("Error in event "..identifier..": \""..err.."\".")
|
||||
if event.name > -2 then
|
||||
global.last_error = identifier
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--- Removes the handler from the event
|
||||
-- @param event event or array containing events to remove the handler
|
||||
-- @param handler to remove
|
||||
-- @return #Event
|
||||
function Event.remove(event, handler)
|
||||
fail_if_missing(event, "missing event argument")
|
||||
fail_if_missing(handler, "missing handler argument")
|
||||
|
||||
if type(event) == "number" then
|
||||
event = { event }
|
||||
end
|
||||
|
||||
for _, event_id in pairs(event) do
|
||||
fail_if_missing(event_id, "missing event id")
|
||||
if Event._registry[event_id] then
|
||||
for i = #Event._registry[event_id], 1, -1 do
|
||||
if Event._registry[event_id][i] == handler then
|
||||
table.remove(Event._registry[event_id], i)
|
||||
end
|
||||
end
|
||||
if #Event._registry[event_id] == 0 then
|
||||
Event._registry[event_id] = nil
|
||||
script.on_event(event_id, nil)
|
||||
end
|
||||
end
|
||||
end
|
||||
return Event
|
||||
end
|
||||
return Event
|
196
locale/utils/game-info.lua
Normal file
196
locale/utils/game-info.lua
Normal file
@@ -0,0 +1,196 @@
|
||||
-- Dependencies
|
||||
require "gui-2"
|
||||
require "Time"
|
||||
|
||||
-- Master button controlls the visibility of the readme window
|
||||
local MASTER_BTN = {name = "btn_readme", caption = "Read Me", tooltip = "Server rules, information, and more"}
|
||||
-- Master frame(window), holds all the contents
|
||||
local MASTER_FRAME = {name = "frame_readme"}
|
||||
|
||||
-- Tabs and the corresponding buttons to put in the master frame
|
||||
local FRAME_TABS = {
|
||||
rules = {btn = {name = "btn_readme_rules", caption = "Server Rules", tooltip = ""}, win = {name = "win_readme_rules"}},
|
||||
comm = {btn = {name = "btn_readme_help", caption = "Info", tooltip = ""}, win = {name = "win_readme_help"}},
|
||||
resources = {btn = {name = "btn_readme_resources", caption = "Changelog", tooltip = ""}, win = {name = "win_readme_resources"}},
|
||||
players = {btn = {name = "btn_readme_players", caption = "Players", tooltip = ""}, win = {name = "win_readme_players"}},
|
||||
about = {btn = {name = "btn_readme_about", caption = "About", tooltip = ""}, win = {name = "win_readme_about"}},
|
||||
close = {
|
||||
btn = {name = "btn_readme_close", caption = "Close", tooltip = ""},
|
||||
win = {name = "win_readme_close"} -- no window created, just for consistency to use in loop
|
||||
}
|
||||
}
|
||||
|
||||
-- Static Content
|
||||
local CONTENT = {
|
||||
rules = {""},
|
||||
comm = {""},
|
||||
resources = {""},
|
||||
about = {""}
|
||||
}
|
||||
|
||||
-- On Player Join
|
||||
-- Display the master button, and show rules if new player
|
||||
-- @param event on_player_joined_game
|
||||
function on_player_join(event)
|
||||
local player = game.players[event.player_index]
|
||||
draw_master_readme_btn(player)
|
||||
-- Force a gui refresh in case there where updates
|
||||
if player.gui.center[MASTER_FRAME.name] ~= nil then
|
||||
player.gui.center[MASTER_FRAME.name].destroy()
|
||||
end
|
||||
-- Show readme window (rules) when player (not admin) first joins, but not at later times
|
||||
if not player.admin and Time.tick_to_min(player.online_time) < 1 then
|
||||
draw_master_readme_frame(player, FRAME_TABS.rules.win.name)
|
||||
end
|
||||
end
|
||||
|
||||
-- On Player Leave
|
||||
-- Clean up the GUI in case this mod gets removed next time
|
||||
-- @param event on_player_left_game
|
||||
function on_player_leave(event)
|
||||
local player = game.players[event.player_index]
|
||||
if player.gui.center[MASTER_FRAME.name] ~= nil then
|
||||
player.gui.center[MASTER_FRAME.name].destroy()
|
||||
end
|
||||
if player.gui.top[MASTER_BTN.name] ~= nil then
|
||||
player.gui.top[MASTER_BTN.name].destroy()
|
||||
end
|
||||
end
|
||||
|
||||
-- On GUI Click
|
||||
-- Depending of what button was click open a different tab
|
||||
-- @param event on_gui_click
|
||||
function on_gui_click(event)
|
||||
local player = game.players[event.player_index]
|
||||
local el_name = event.element.name
|
||||
-- Master frame gui button?
|
||||
if el_name == MASTER_BTN.name then
|
||||
-- Call toggle if frame has been created
|
||||
if (player.gui.center[MASTER_FRAME.name] ~= nil) then
|
||||
GUI.toggle_element(player.gui.center[MASTER_FRAME.name])
|
||||
else
|
||||
-- Call create if it hasnt
|
||||
draw_master_readme_frame(player, FRAME_TABS.rules.win.name)
|
||||
end
|
||||
end
|
||||
-- One of the tabs?
|
||||
for i, frame_tab in pairs(FRAME_TABS) do
|
||||
if el_name == frame_tab.btn.name then
|
||||
draw_master_readme_frame(player, frame_tab.win.name)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Draws the master readme button on the top of the screen
|
||||
-- @param player
|
||||
function draw_master_readme_btn(player)
|
||||
if player.gui.top[MASTER_BTN.name] == nil then
|
||||
player.gui.top.add {type = "button", name = MASTER_BTN.name, caption = MASTER_BTN.caption, tooltip = MASTER_BTN.tooltip}
|
||||
end
|
||||
end
|
||||
|
||||
-- Draws the master frame and a tab inside it base on arg
|
||||
-- *Recursive (only 1 deep)
|
||||
-- @param player
|
||||
-- @param window_name - which window to display in the frame
|
||||
function draw_master_readme_frame(player, window_name)
|
||||
-- Master frame is already created, just draw a new tab
|
||||
if player.gui.center[MASTER_FRAME.name] ~= nil then
|
||||
-- Rules
|
||||
if window_name == FRAME_TABS.rules.win.name then
|
||||
-- Comm
|
||||
draw_static_content(player.gui.center[MASTER_FRAME.name]["scroll_content"], CONTENT.rules)
|
||||
elseif window_name == FRAME_TABS.comm.win.name then
|
||||
-- Resourses
|
||||
draw_static_content(player.gui.center[MASTER_FRAME.name]["scroll_content"], CONTENT.comm)
|
||||
elseif window_name == FRAME_TABS.resources.win.name then
|
||||
-- About
|
||||
draw_static_content(player.gui.center[MASTER_FRAME.name]["scroll_content"], CONTENT.resources)
|
||||
elseif window_name == FRAME_TABS.about.win.name then
|
||||
-- Players
|
||||
draw_static_content(player.gui.center[MASTER_FRAME.name]["scroll_content"], CONTENT.about)
|
||||
elseif window_name == FRAME_TABS.players.win.name then
|
||||
-- Close
|
||||
draw_players(player.gui.center[MASTER_FRAME.name]["scroll_content"])
|
||||
elseif window_name == FRAME_TABS.close.win.name then
|
||||
GUI.toggle_element(player.gui.center[MASTER_FRAME.name])
|
||||
end
|
||||
else
|
||||
-- create the master frame and call function again to draw specific tab
|
||||
local frame = player.gui.center.add {type = "frame", direction = "vertical", name = MASTER_FRAME.name}
|
||||
-- make a nav container and add nav buttons
|
||||
frame.add {type = "flow", name = "readme_nav", direction = "horizontal"}
|
||||
draw_frame_nav(frame.readme_nav)
|
||||
-- make a tab content container
|
||||
frame.add {type = "scroll-pane", name = "scroll_content", direction = "vertical", vertical_scroll_policy = "always", horizontal_scroll_policy = "auto"}
|
||||
-- Style config for nav
|
||||
frame.readme_nav.style.maximal_width = 600
|
||||
frame.readme_nav.style.minimal_width = 600
|
||||
-- Style config for content
|
||||
frame.scroll_content.style.maximal_height = 500
|
||||
frame.scroll_content.style.minimal_height = 500
|
||||
frame.scroll_content.style.maximal_width = 600
|
||||
frame.scroll_content.style.minimal_width = 600
|
||||
-- Recursive call
|
||||
draw_master_readme_frame(player, window_name)
|
||||
end
|
||||
end
|
||||
|
||||
-- Draws the nav buttons for readme frame
|
||||
-- @param nav_container GUI element to add the buttons to
|
||||
function draw_frame_nav(nav_container)
|
||||
for i, frame_tab in pairs(FRAME_TABS) do
|
||||
nav_container.add {type = "button", name = frame_tab.btn.name, caption = frame_tab.btn.caption, tooltip = frame_tab.btn.tooltip}
|
||||
end
|
||||
end
|
||||
|
||||
-- Draws a list of labels from content passed in
|
||||
-- @param container - gui element to add to
|
||||
-- @param content - array list of string to display
|
||||
function draw_static_content(container, content)
|
||||
GUI.clear_element(container) -- Clear the current info before adding new
|
||||
for i, text in pairs(content) do
|
||||
container.add {type = "label", name = i, caption = text}
|
||||
end
|
||||
end
|
||||
|
||||
-- Draws a list of players on the server with their playtime
|
||||
-- @param container - gui element to add to
|
||||
function draw_players(container)
|
||||
GUI.clear_element(container) -- Clear the current info before adding new
|
||||
|
||||
local table_name = "tbl_readme_players"
|
||||
container.add {type = "label", name = "lbl_player_tile", caption = "=== ALL TIME PLAYERS ==="}
|
||||
container.add {type = "table", name = table_name, colspan = 2}
|
||||
container[table_name].style.minimal_width = 500
|
||||
container[table_name].style.maximal_width = 500
|
||||
container[table_name].add {type = "label", name = "lbl_hours", caption = "Time (h:m)"}
|
||||
container[table_name].add {type = "label", name = "lbl_name", caption = "Name"}
|
||||
|
||||
-- Copy player list into local list
|
||||
local player_list = {}
|
||||
for i, player in pairs(game.players) do
|
||||
table.insert(player_list, {name = player.name, online_time = player.online_time})
|
||||
end
|
||||
|
||||
-- Sort players based on time played
|
||||
table.sort(
|
||||
player_list,
|
||||
function(a, b)
|
||||
return a.online_time > b.online_time
|
||||
end
|
||||
)
|
||||
|
||||
-- Add in gui list
|
||||
for i, player in pairs(player_list) do
|
||||
local total_min = Time.tick_to_min(player.online_time)
|
||||
local time_str = math.floor(total_min / 60) .. ":" .. math.floor(total_min % 60)
|
||||
container[table_name].add {type = "label", name = "lbl_" .. player.name .. "_time", caption = time_str}
|
||||
container[table_name].add {type = "label", name = "lbl_" .. player.name .. "_name", caption = player.name}
|
||||
end
|
||||
end
|
||||
|
||||
-- Event Handlers
|
||||
Event.register(defines.events.on_gui_click, on_gui_click)
|
||||
Event.register(defines.events.on_player_joined_game, on_player_join)
|
||||
Event.register(defines.events.on_player_left_game, on_player_leave)
|
31
locale/utils/gui-2.lua
Normal file
31
locale/utils/gui-2.lua
Normal file
@@ -0,0 +1,31 @@
|
||||
-- GUI Helper Module
|
||||
-- Common GUI functions
|
||||
-- @author Denis Zholob (DDDGamer)
|
||||
-- github: https://github.com/DDDGamer/factorio-dz-softmod
|
||||
-- ======================================================= --
|
||||
|
||||
GUI = {}
|
||||
|
||||
-- Destroyes the children of a GUI element
|
||||
-- @param el <- element to toggle destroy childen of
|
||||
function GUI.clear_element( el )
|
||||
if el ~= nil then
|
||||
for i, child in pairs(el.children_names) do
|
||||
el[child].destroy()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Toggles element on off (visibility)
|
||||
-- @param el <- element to toggle visibility
|
||||
function GUI.toggle_element( el )
|
||||
if el ~= nil then
|
||||
if el.style.visible == false then
|
||||
el.style.visible = true
|
||||
else
|
||||
el.style.visible = false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return GUI
|
131
locale/utils/gui.lua
Normal file
131
locale/utils/gui.lua
Normal file
@@ -0,0 +1,131 @@
|
||||
--- Gui module
|
||||
--A 3Ra Gaming revision, original from Factorio-Stdlib by Afforess
|
||||
-- @module Gui
|
||||
Gui = {}
|
||||
|
||||
Gui.Event = {
|
||||
_registry = {},
|
||||
_dispatch = {}
|
||||
}
|
||||
|
||||
--- Registers a function for a given event and matching gui element pattern
|
||||
-- @param event Valid values are defines.event.on_gui_*
|
||||
-- @param gui_element_pattern the name or string regular expression to match the gui element
|
||||
-- @param handler Function to call when event is triggered
|
||||
-- @return #Gui.Event
|
||||
function Gui.Event.register(event, gui_element_pattern, handler)
|
||||
fail_if_missing(event, "missing event name argument")
|
||||
fail_if_missing(gui_element_pattern, "missing gui name or pattern argument")
|
||||
|
||||
if type(gui_element_pattern) ~= "string" then
|
||||
error("gui_element_pattern argument must be a string")
|
||||
end
|
||||
|
||||
if handler == nil then
|
||||
Gui.Event.remove(event, gui_element_pattern)
|
||||
return Gui.Event
|
||||
end
|
||||
|
||||
if not Gui.Event._registry[event] then
|
||||
Gui.Event._registry[event] = {}
|
||||
end
|
||||
Gui.Event._registry[event][gui_element_pattern] = handler
|
||||
|
||||
-- Use custom Gui event dispatcher to pass off the event to the correct sub-handler
|
||||
if not Gui.Event._dispatch[event] then
|
||||
Event.register(event, Gui.Event.dispatch)
|
||||
Gui.Event._dispatch[event] = true
|
||||
end
|
||||
|
||||
return Gui.Event
|
||||
end
|
||||
|
||||
--- Calls the registered handlers
|
||||
-- @param event LuaEvent as created by game.raise_event
|
||||
function Gui.Event.dispatch(event)
|
||||
fail_if_missing(event, "missing event argument")
|
||||
|
||||
local gui_element = event.element
|
||||
if gui_element and gui_element.valid then
|
||||
local gui_element_name = gui_element.name;
|
||||
local gui_element_state = nil;
|
||||
local gui_element_text = nil;
|
||||
|
||||
if event.name == defines.events.on_gui_checked_state_changed then
|
||||
gui_element_state = gui_element.state
|
||||
end
|
||||
|
||||
if event.name == defines.events.on_gui_text_changed then
|
||||
gui_element_text = gui_element.text
|
||||
end
|
||||
|
||||
for gui_element_pattern, handler in pairs(Gui.Event._registry[event.name]) do
|
||||
local match_str = string.match(gui_element_name, gui_element_pattern)
|
||||
if match_str ~= nil then
|
||||
local new_event = { tick = event.tick, name = event.name, _handler = handler, match = match_str, element = gui_element, state=gui_element_state, text=gui_element_text, player_index = event.player_index , _event = event}
|
||||
local success, err = pcall(handler, new_event)
|
||||
if not success then
|
||||
Game.print_all(err)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--- Removes the handler with matching gui element pattern from the event
|
||||
-- @param event Valid values are defines.event.on_gui_*
|
||||
-- @param gui_element_pattern the name or string regular expression to remove the handler for
|
||||
-- @return #Gui.Event
|
||||
function Gui.Event.remove(event, gui_element_pattern)
|
||||
fail_if_missing(event, "missing event argument")
|
||||
fail_if_missing(gui_element_pattern, "missing gui_element_pattern argument")
|
||||
|
||||
if type(gui_element_pattern) ~= "string" then
|
||||
error("gui_element_pattern argument must be a string")
|
||||
end
|
||||
|
||||
local function tablelength(T)
|
||||
local count = 0
|
||||
for _ in pairs(T) do count = count + 1 end
|
||||
return count
|
||||
end
|
||||
|
||||
if Gui.Event._registry[event] then
|
||||
if Gui.Event._registry[event][gui_element_pattern] then
|
||||
Gui.Event._registry[event][gui_element_pattern] = nil
|
||||
end
|
||||
if tablelength(Gui.Event._registry[event]) == 0 then
|
||||
Event.remove(event, Gui.Event.dispatch)
|
||||
Gui.Event._registry[event] = nil
|
||||
Gui.Event._dispatch[event] = false
|
||||
end
|
||||
end
|
||||
return Gui.Event
|
||||
end
|
||||
|
||||
--- Registers a function for a given gui element name or pattern when the element is clicked
|
||||
-- @param gui_element_pattern the name or string regular expression to match the gui element
|
||||
-- @param handler Function to call when gui element is clicked
|
||||
-- @return #Gui
|
||||
function Gui.on_click(gui_element_pattern, handler)
|
||||
Gui.Event.register(defines.events.on_gui_click, gui_element_pattern, handler)
|
||||
return Gui
|
||||
end
|
||||
|
||||
--- Registers a function for a given gui element name or pattern when the element checked state changes
|
||||
-- @param gui_element_pattern the name or string regular expression to match the gui element
|
||||
-- @param handler Function to call when gui element checked state changes
|
||||
-- @return #Gui
|
||||
function Gui.on_checked_state_changed(gui_element_pattern, handler)
|
||||
Gui.Event.register(defines.events.on_gui_checked_state_changed, gui_element_pattern, handler)
|
||||
return Gui
|
||||
end
|
||||
|
||||
--- Registers a function for a given gui element name or pattern when the element text changes
|
||||
-- @param gui_element_pattern the name or string regular expression to match the gui element
|
||||
-- @param handler Function to call when gui element text changes
|
||||
-- @return #Gui
|
||||
function Gui.on_text_changed(gui_element_pattern, handler)
|
||||
Gui.Event.register(defines.events.on_gui_text_changed, gui_element_pattern, handler)
|
||||
return Gui
|
||||
end
|
104
locale/utils/player-list.lua
Normal file
104
locale/utils/player-list.lua
Normal file
@@ -0,0 +1,104 @@
|
||||
-- Player List Soft Mod
|
||||
-- Adds a player list sidebar that displays online players along with their online time.
|
||||
-- @author Denis Zholob (DDDGamer)
|
||||
-- github: https://github.com/DDDGamer/factorio-dz-softmod
|
||||
-- ======================================================= --
|
||||
|
||||
-- Dependencies
|
||||
require "gui-2"
|
||||
require "Time"
|
||||
require "Colors"
|
||||
|
||||
|
||||
|
||||
local OWNER = "chpich"
|
||||
|
||||
-- Roles
|
||||
local ROLES = {
|
||||
owner = {tag = "Owner", color = Colors.black}, -- server owner
|
||||
admin = {tag = "Admin", color = Colors.gray} -- server admin
|
||||
}
|
||||
|
||||
-- Regular player ranks (time in hrs)
|
||||
local RANKS =
|
||||
{lvl1 = {time = 0, color = Colors.white, tag = "Engineer Trainee", },
|
||||
lvl2 = {time = 1, color = Colors.green, tag = "Jr. Engineer"},
|
||||
lvl3 = {time = 2, color = Colors.cyan, tag = "Associate Engineer"},
|
||||
lvl4 = {time = 3, color = Colors.blue, tag = "Engineer I"},
|
||||
lvl5 = {time = 4, color = Colors.darkblue, tag = "Intermediate Engineer"},
|
||||
lvl6 = {time = 5, color = Colors.yellow, tag = "Engineer II"},
|
||||
lvl7 = {time = 7, color = Colors.orange, tag = "Sr. Engineer"},
|
||||
lvl8 = {time = 9, color = Colors.darkorange, tag = "Engineer III"},
|
||||
lvl9 = {time = 12, color = Colors.red, tag = "Engineering Specialist"},
|
||||
lvl10 = {time = 15, color = Colors.darkred, tag = "Chief Engineer"},
|
||||
lvl11 = {time = 20, color = Colors.grey, tag = "Sr. Chief Engineer", }}
|
||||
|
||||
|
||||
|
||||
-- When new player joins add the playerlist btn to their GUI
|
||||
-- Redraw the playerlist frame to update with the new player
|
||||
-- @param event on_player_joined_game
|
||||
function on_player_join(event)
|
||||
local player = game.players[event.player_index]
|
||||
draw_playerlist_btn(player)
|
||||
draw_playerlist_frame()
|
||||
end
|
||||
|
||||
-- On Player Leave
|
||||
-- Clean up the GUI in case this mod gets removed next time
|
||||
-- Redraw the playerlist frame to update
|
||||
-- @param event on_player_left_game
|
||||
function on_player_leave(event)
|
||||
local player = game.players[event.player_index]
|
||||
if player.gui.left["frame_playerlist"] ~= nil then
|
||||
player.gui.left["frame_playerlist"].destroy()
|
||||
end
|
||||
if player.gui.top["btn_menu_playerlist"] ~= nil then
|
||||
player.gui.top["btn_menu_playerlist"].destroy()
|
||||
end
|
||||
draw_playerlist_frame()
|
||||
end
|
||||
|
||||
-- Toggle playerlist is called if gui element is playerlist button
|
||||
-- @param event on_gui_click
|
||||
local function on_gui_click(event)
|
||||
local player = game.players[event.player_index]
|
||||
local el_name = event.element.name
|
||||
|
||||
if el_name == "btn_menu_playerlist" then
|
||||
GUI.toggle_element(player.gui.left["frame_playerlist"])
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- Add a player to the GUI list
|
||||
-- @param player
|
||||
-- @param p_online
|
||||
-- @param color
|
||||
-- @param tag
|
||||
function add_player_to_list(player, p_online, color, tag)
|
||||
local played_hrs = tostring(Time.tick_to_hour(p_online.online_time))
|
||||
player.gui.left["frame_playerlist"].add {type = "label", style = "caption_label_style", name = p_online.name, caption = {"", played_hrs, " hr - ", p_online.name, " ", "[" .. tag .. "]"}}
|
||||
player.gui.left["frame_playerlist"][p_online.name].style.font_color = color
|
||||
p_online.tag = "[" .. tag .. "]"
|
||||
end
|
||||
|
||||
-- Refresh the playerlist after 10 min
|
||||
-- @param event on_tick
|
||||
function on_tick(event)
|
||||
global.last_refresh = global.last_refresh or 0
|
||||
local cur_time = game.tick / 60
|
||||
local refresh_period = 10 -- 600 seconds (10 min)
|
||||
local refresh_time_passed = cur_time - global.last_refresh
|
||||
if refresh_time_passed > refresh_period then
|
||||
draw_playerlist_frame()
|
||||
global.last_refresh = cur_time
|
||||
end
|
||||
end
|
||||
|
||||
-- Event Handlers
|
||||
Event.register(defines.events.on_gui_click, on_gui_click)
|
||||
Event.register(defines.events.on_player_joined_game, on_player_join)
|
||||
Event.register(defines.events.on_player_left_game, on_player_leave)
|
||||
Event.register(defines.events.on_tick, on_tick)
|
||||
|
515
locale/utils/utils.lua
Normal file
515
locale/utils/utils.lua
Normal file
@@ -0,0 +1,515 @@
|
||||
-- utils.lua by binbinhfr, v1.0.16
|
||||
-- A 3Ra Gaming revision
|
||||
-- define debug_status to 1 or nil in the control.lua, before statement require("utils")
|
||||
-- define also debug_file and debug_mod_name
|
||||
|
||||
colors = {
|
||||
white = { r = 1, g = 1, b = 1 },
|
||||
black = { r = 0, g = 0, b = 0 },
|
||||
darkgrey = { r = 0.25, g = 0.25, b = 0.25 },
|
||||
grey = { r = 0.5, g = 0.5, b = 0.5 },
|
||||
lightgrey = { r = 0.75, g = 0.75, b = 0.75 },
|
||||
red = { r = 1, g = 0, b = 0 },
|
||||
darkred = { r = 0.5, g = 0, b = 0 },
|
||||
lightred = { r = 1, g = 0.5, b = 0.5 },
|
||||
green = { r = 0, g = 1, b = 0 },
|
||||
darkgreen = { r = 0, g = 0.5, b = 0 },
|
||||
lightgreen = { r = 0.5, g = 1, b = 0.5 },
|
||||
blue = { r = 0, g = 0, b = 1 },
|
||||
darkblue = { r = 0, g = 0, b = 0.5 },
|
||||
lightblue = { r = 0.5, g = 0.5, b = 1 },
|
||||
orange = { r = 1, g = 0.55, b = 0.1 },
|
||||
yellow = { r = 1, g = 1, b = 0 },
|
||||
pink = { r = 1, g = 0, b = 1 },
|
||||
purple = { r = 0.6, g = 0.1, b = 0.6 },
|
||||
brown = { r = 0.6, g = 0.4, b = 0.1 },
|
||||
}
|
||||
|
||||
anticolors = {
|
||||
white = colors.black,
|
||||
black = colors.white,
|
||||
darkgrey = colors.white,
|
||||
grey = colors.black,
|
||||
lightgrey = colors.black,
|
||||
red = colors.white,
|
||||
darkred = colors.white,
|
||||
lightred = colors.black,
|
||||
green = colors.black,
|
||||
darkgreen = colors.white,
|
||||
lightgreen = colors.black,
|
||||
blue = colors.white,
|
||||
darkblue = colors.white,
|
||||
lightblue = colors.black,
|
||||
orange = colors.black,
|
||||
yellow = colors.black,
|
||||
pink = colors.white,
|
||||
purple = colors.white,
|
||||
brown = colors.white,
|
||||
}
|
||||
|
||||
lightcolors = {
|
||||
white = colors.lightgrey,
|
||||
grey = colors.darkgrey,
|
||||
lightgrey = colors.grey,
|
||||
red = colors.lightred,
|
||||
green = colors.lightgreen,
|
||||
blue = colors.lightblue,
|
||||
yellow = colors.orange,
|
||||
pink = colors.purple,
|
||||
}
|
||||
|
||||
local author_name1 = "BinbinHfr"
|
||||
local author_name2 = "binbin"
|
||||
|
||||
--------------------------------------------------------------------------------------
|
||||
function read_version(v)
|
||||
local v1, v2, v3 = string.match(v, "(%d+).(%d+).(%d+)")
|
||||
debug_print("version cut = ", v1, v2, v3)
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------------
|
||||
function compare_versions(v1, v2)
|
||||
local v1a, v1b, v1c = string.match(v1, "(%d+).(%d+).(%d+)")
|
||||
local v2a, v2b, v2c = string.match(v2, "(%d+).(%d+).(%d+)")
|
||||
|
||||
v1a = tonumber(v1a)
|
||||
v1b = tonumber(v1b)
|
||||
v1c = tonumber(v1c)
|
||||
v2a = tonumber(v2a)
|
||||
v2b = tonumber(v2b)
|
||||
v2c = tonumber(v2c)
|
||||
|
||||
if v1a > v2a then
|
||||
return 1
|
||||
elseif v1a < v2a then
|
||||
return -1
|
||||
elseif v1b > v2b then
|
||||
return 1
|
||||
elseif v1b < v2b then
|
||||
return -1
|
||||
elseif v1c > v2c then
|
||||
return 1
|
||||
elseif v1c < v2c then
|
||||
return -1
|
||||
else
|
||||
return 0
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------------
|
||||
function older_version(v1, v2)
|
||||
local v1a, v1b, v1c = string.match(v1, "(%d+).(%d+).(%d+)")
|
||||
local v2a, v2b, v2c = string.match(v2, "(%d+).(%d+).(%d+)")
|
||||
local ret
|
||||
|
||||
v1a = tonumber(v1a)
|
||||
v1b = tonumber(v1b)
|
||||
v1c = tonumber(v1c)
|
||||
v2a = tonumber(v2a)
|
||||
v2b = tonumber(v2b)
|
||||
v2c = tonumber(v2c)
|
||||
|
||||
if v1a > v2a then
|
||||
ret = false
|
||||
elseif v1a < v2a then
|
||||
ret = true
|
||||
elseif v1b > v2b then
|
||||
ret = false
|
||||
elseif v1b < v2b then
|
||||
ret = true
|
||||
elseif v1c < v2c then
|
||||
ret = true
|
||||
else
|
||||
ret = false
|
||||
end
|
||||
|
||||
debug_print("older_version ", v1, "<", v2, "=", ret)
|
||||
|
||||
return (ret)
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------------
|
||||
function debug_active(...)
|
||||
-- can be called everywhere, except in on_load where game is not existing
|
||||
local s = ""
|
||||
|
||||
for i, v in ipairs({ ... }) do
|
||||
s = s .. tostring(v)
|
||||
end
|
||||
|
||||
if s == "RAZ" or debug_do_raz == true then
|
||||
game.remove_path(debug_file)
|
||||
debug_do_raz = false
|
||||
elseif s == "CLEAR" then
|
||||
for _, player in pairs(game.players) do
|
||||
if player.connected then player.clear_console() end
|
||||
end
|
||||
end
|
||||
|
||||
s = debug_mod_name .. "(" .. game.tick .. "): " .. s
|
||||
game.write_file(debug_file, s .. "\n", true)
|
||||
|
||||
for _, player in pairs(game.players) do
|
||||
if player.connected then player.print(s) end
|
||||
end
|
||||
end
|
||||
|
||||
if debug_status == 1 then debug_print = debug_active else debug_print = function() end end
|
||||
|
||||
--------------------------------------------------------------------------------------
|
||||
function message_all(s)
|
||||
for _, player in pairs(game.players) do
|
||||
if player.connected then
|
||||
player.print(s)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------------
|
||||
function message_force(force, s)
|
||||
for _, player in pairs(force.players) do
|
||||
if player.connected then
|
||||
player.print(s)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------------
|
||||
function square_area(origin, radius)
|
||||
return {
|
||||
{ x = origin.x - radius, y = origin.y - radius },
|
||||
{ x = origin.x + radius, y = origin.y + radius }
|
||||
}
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------------
|
||||
function distance(pos1, pos2)
|
||||
local dx = pos2.x - pos1.x
|
||||
local dy = pos2.y - pos1.y
|
||||
return (math.sqrt(dx * dx + dy * dy))
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------------
|
||||
function distance_square(pos1, pos2)
|
||||
return (math.max(math.abs(pos2.x - pos1.x), math.abs(pos2.y - pos1.y)))
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------------
|
||||
function pos_offset(pos, offset)
|
||||
return { x = pos.x + offset.x, y = pos.y + offset.y }
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------------
|
||||
function surface_area(surf)
|
||||
local x1, y1, x2, y2 = 0, 0, 0, 0
|
||||
|
||||
for chunk in surf.get_chunks() do
|
||||
if chunk.x < x1 then
|
||||
x1 = chunk.x
|
||||
elseif chunk.x > x2 then
|
||||
x2 = chunk.x
|
||||
end
|
||||
if chunk.y < y1 then
|
||||
y1 = chunk.y
|
||||
elseif chunk.y > y2 then
|
||||
y2 = chunk.y
|
||||
end
|
||||
end
|
||||
|
||||
return ({ { x1 * 32 - 8, y1 * 32 - 8 }, { x2 * 32 + 40, y2 * 32 + 40 } })
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------------
|
||||
function iif(cond, val1, val2)
|
||||
if cond then
|
||||
return val1
|
||||
else
|
||||
return val2
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------------
|
||||
function add_list(list, obj)
|
||||
-- to avoid duplicates...
|
||||
for i, obj2 in pairs(list) do
|
||||
if obj2 == obj then
|
||||
return (false)
|
||||
end
|
||||
end
|
||||
table.insert(list, obj)
|
||||
return (true)
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------------
|
||||
function del_list(list, obj)
|
||||
for i, obj2 in pairs(list) do
|
||||
if obj2 == obj then
|
||||
table.remove(list, i)
|
||||
return (true)
|
||||
end
|
||||
end
|
||||
return (false)
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------------
|
||||
function in_list(list, obj)
|
||||
for k, obj2 in pairs(list) do
|
||||
if obj2 == obj then
|
||||
return (k)
|
||||
end
|
||||
end
|
||||
return (nil)
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------------
|
||||
function size_list(list)
|
||||
local n = 0
|
||||
for i in pairs(list) do
|
||||
n = n + 1
|
||||
end
|
||||
return (n)
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------------
|
||||
function concat_lists(list1, list2)
|
||||
-- add list2 into list1 , do not avoid duplicates...
|
||||
for i, obj in pairs(list2) do
|
||||
table.insert(list1, obj)
|
||||
end
|
||||
end
|
||||
|
||||
------------------------------------------------------------------------------------
|
||||
function is_dev(player)
|
||||
return (player.name == author_name1 or player.name == author_name2)
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------------
|
||||
function dupli_proto(type, name1, name2)
|
||||
if data.raw[type][name1] then
|
||||
local proto = table.deepcopy(data.raw[type][name1])
|
||||
proto.name = name2
|
||||
if proto.minable and proto.minable.result then proto.minable.result = name2 end
|
||||
if proto.place_result then proto.place_result = name2 end
|
||||
if proto.take_result then proto.take_result = name2 end
|
||||
if proto.result then proto.result = name2 end
|
||||
return (proto)
|
||||
else
|
||||
error("prototype unknown " .. name1)
|
||||
return (nil)
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------------
|
||||
function debug_guis(guip, indent)
|
||||
if guip == nil then return end
|
||||
debug_print(indent .. string.rep("....", indent) .. " " .. guip.name)
|
||||
indent = indent + 1
|
||||
for k, gui in pairs(guip.children_names) do
|
||||
debug_guis(guip[gui], indent)
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------------
|
||||
function extract_monolith(filename, x, y, w, h)
|
||||
return {
|
||||
type = "monolith",
|
||||
top_monolith_border = 0,
|
||||
right_monolith_border = 0,
|
||||
bottom_monolith_border = 0,
|
||||
left_monolith_border = 0,
|
||||
monolith_image = {
|
||||
filename = filename,
|
||||
priority = "extra-high-no-scale",
|
||||
width = w,
|
||||
height = h,
|
||||
x = x,
|
||||
y = y,
|
||||
},
|
||||
}
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------------
|
||||
-- rounds number (num) to certain number of decimal places (idp)
|
||||
function round(num, idp)
|
||||
local mult = 10 ^ (idp or 0)
|
||||
return math.floor(num * mult + 0.5) / mult
|
||||
end
|
||||
|
||||
-- cleans up the color values, gets rid of floating point innacuracy
|
||||
function clean_color(input_color)
|
||||
local temp_r = round(input_color.r, 6)
|
||||
local temp_g = round(input_color.g, 6)
|
||||
local temp_b = round(input_color.b, 6)
|
||||
local temp_a = round(input_color.a, 6)
|
||||
return { r = temp_r, g = temp_g, b = temp_b, a = temp_a }
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------------
|
||||
-- returns true if colors are the same, false if different
|
||||
function compare_colors(color1, color2)
|
||||
local clean_color1 = clean_color(color1)
|
||||
local clean_color2 = clean_color(color2)
|
||||
if clean_color1.r ~= clean_color2.r then
|
||||
return false
|
||||
end
|
||||
if clean_color1.g ~= clean_color2.g then
|
||||
return false
|
||||
end
|
||||
if clean_color1.b ~= clean_color2.b then
|
||||
return false
|
||||
end
|
||||
if clean_color1.a ~= clean_color2.a then
|
||||
return false
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------------
|
||||
-- Provide a player's name to put their inventory into a chest somewhere near spawn.
|
||||
function return_inventory(player_name)
|
||||
local success, err = pcall(return_inventory_p, player_name)
|
||||
if not success then
|
||||
game.print(err)
|
||||
return
|
||||
end
|
||||
if err then
|
||||
return
|
||||
end
|
||||
end
|
||||
function return_inventory_p(player_name)
|
||||
local stolen_inventories = {
|
||||
main = game.players[player_name].get_inventory(defines.inventory.player_main),
|
||||
quickbar = game.players[player_name].get_inventory(defines.inventory.player_quickbar),
|
||||
guns = game.players[player_name].get_inventory(defines.inventory.player_guns),
|
||||
ammo = game.players[player_name].get_inventory(defines.inventory.player_ammo),
|
||||
armor = game.players[player_name].get_inventory(defines.inventory.player_armor),
|
||||
tools = game.players[player_name].get_inventory(defines.inventory.player_tools),
|
||||
vehicle = game.players[player_name].get_inventory(defines.inventory.player_vehicle),
|
||||
trash = game.players[player_name].get_inventory(defines.inventory.player_trash)
|
||||
}
|
||||
local chest_location = game.surfaces.nauvis.find_non_colliding_position("steel-chest", game.forces.player.get_spawn_position(game.surfaces.nauvis), 0, 1)
|
||||
local return_chest = game.surfaces.nauvis.create_entity{name = "steel-chest", position = chest_location, force = game.forces.player}
|
||||
local chest_inventory = return_chest.get_inventory(defines.inventory.chest)
|
||||
for _,inventory in pairs(stolen_inventories) do
|
||||
for name,count in pairs(inventory.get_contents()) do
|
||||
local inserted = chest_inventory.insert{name = name, count = count}
|
||||
if inserted > 0 then
|
||||
inventory.remove{name = name, count = inserted}
|
||||
end
|
||||
if inserted < count then
|
||||
chest_location = game.surfaces.nauvis.find_non_colliding_position("steel-chest", chest_location, 0, 1)
|
||||
chest_inventory = game.surfaces.nauvis.create_entity{name = "steel-chest", position = chest_location, force = game.forces.player}
|
||||
inserted = chest_inventory.insert{name = name, count = (count - inserted)}
|
||||
if inserted > 0 then
|
||||
inventory.remove{name = name, count = inserted}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
game.print("The now banned griefer " .. player_name .. "'s inventory has been returned somewhere near the spawn. Look for one or more steel chests.")
|
||||
end
|
||||
--------------------------------------------------------------------------------------
|
||||
-- Currently console only, as print() is used to print the results
|
||||
function show_inventory(player_name)
|
||||
local success, err = pcall(show_inventory_p, player_name)
|
||||
if not success then
|
||||
game.print(err)
|
||||
return
|
||||
end
|
||||
if err then
|
||||
return
|
||||
end
|
||||
end
|
||||
function show_inventory_p(player_name)
|
||||
local player = game.players[player_name]
|
||||
local inventories = {
|
||||
main = game.players[player_name].get_inventory(defines.inventory.player_main),
|
||||
quickbar = game.players[player_name].get_inventory(defines.inventory.player_quickbar),
|
||||
guns = game.players[player_name].get_inventory(defines.inventory.player_guns),
|
||||
ammo = game.players[player_name].get_inventory(defines.inventory.player_ammo),
|
||||
armor = game.players[player_name].get_inventory(defines.inventory.player_armor),
|
||||
tools = game.players[player_name].get_inventory(defines.inventory.player_tools),
|
||||
vehicle = game.players[player_name].get_inventory(defines.inventory.player_vehicle),
|
||||
trash = game.players[player_name].get_inventory(defines.inventory.player_trash)
|
||||
}
|
||||
for invname,inventory in pairs(inventories) do
|
||||
if not inventory.is_empty() then print("Items in " .. invname .. " inventory:") end
|
||||
for name,count in pairs(inventory.get_contents()) do
|
||||
print(" " .. name .. " - " .. count)
|
||||
end
|
||||
end
|
||||
end
|
||||
--------------------------------------------------------------------------------------
|
||||
--This command simply deletes the inventory of the listed player
|
||||
function delete_inventory(player_name)
|
||||
local success, err = pcall(delete_inventory_p, player_name)
|
||||
if not success then
|
||||
game.print(err)
|
||||
return
|
||||
end
|
||||
if err then
|
||||
return
|
||||
end
|
||||
end
|
||||
function delete_inventory_p(player_name)
|
||||
local stolen_inventories = {
|
||||
main = game.players[player_name].get_inventory(defines.inventory.player_main),
|
||||
quickbar = game.players[player_name].get_inventory(defines.inventory.player_quickbar),
|
||||
guns = game.players[player_name].get_inventory(defines.inventory.player_guns),
|
||||
ammo = game.players[player_name].get_inventory(defines.inventory.player_ammo),
|
||||
armor = game.players[player_name].get_inventory(defines.inventory.player_armor),
|
||||
tools = game.players[player_name].get_inventory(defines.inventory.player_tools),
|
||||
vehicle = game.players[player_name].get_inventory(defines.inventory.player_vehicle),
|
||||
trash = game.players[player_name].get_inventory(defines.inventory.player_trash)
|
||||
}
|
||||
for _,inventory in pairs(stolen_inventories) do
|
||||
for name,count in pairs(inventory.get_contents()) do
|
||||
inventory.remove{name = name, count = count}
|
||||
end
|
||||
end
|
||||
end
|
||||
--------------------------------------------------------------------------------------
|
||||
--Send chat only to a specific force
|
||||
--name can be either the name of a player or the name of a force
|
||||
--message is the actual message to send
|
||||
function force_chat(name, message)
|
||||
local force
|
||||
if game.players[name] then force = game.players[name].force
|
||||
else force = game.forces[name] end
|
||||
if force then force.print("[WEB] " .. message) end
|
||||
end
|
||||
|
||||
function check_name(function_name)
|
||||
for i,v in pairs(global.scenario.custom_functions) do
|
||||
if v.name == function_name:lower() then
|
||||
return i
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function add_global_event(event, func, name)
|
||||
local p = game.player and game.player.print or print
|
||||
if not event then p("Missing event parameter") return end
|
||||
if not func then p("Missing function parameter") return end
|
||||
if not name then p("Missing name parameter") return end
|
||||
if check_name(name) then p("Function name \""..name.."\" already in use.") return end
|
||||
table.insert(global.scenario.custom_functions, {event = event, name = name, func = func})
|
||||
Event.register(event, func)
|
||||
end
|
||||
|
||||
function remove_global_event(name)
|
||||
local reg = check_name(name)
|
||||
if reg then
|
||||
Event.remove(global.scenario.custom_functions[reg].event, global.scenario.custom_functions[reg].func)
|
||||
table.remove(global.scenario.custom_functions, reg)
|
||||
else
|
||||
game.print("Function with name \""..name.."\" not found")
|
||||
end
|
||||
end
|
||||
|
||||
Event.register(-2, function()
|
||||
for i,v in pairs(global.scenario.custom_functions) do
|
||||
Event.register(v.event, v.func)
|
||||
end
|
||||
end)
|
16
map_layout.lua
Normal file
16
map_layout.lua
Normal file
@@ -0,0 +1,16 @@
|
||||
if not global.map_layout_name then global.map_layout_name = "" end
|
||||
|
||||
local function chunk_modification(event)
|
||||
if global.map_layout_name == "Up" then
|
||||
local tiles = {}
|
||||
if event.area.left_top.y > 50 or event.area.left_top.x > 96 or event.area.left_top.x < -128 then
|
||||
for x = event.area.left_top.x, event.area.right_bottom.x do
|
||||
for y = event.area.left_top.y, event.area.right_bottom.y do
|
||||
table.insert(tiles, {name = "out-of-map", position = {x,y}})
|
||||
end
|
||||
end
|
||||
surface.set_tiles(tiles)
|
||||
end
|
||||
end
|
||||
|
||||
Event.register(defines.events.on_chunk_generated, chunk_modification)
|
328
poll.lua
Normal file
328
poll.lua
Normal file
@@ -0,0 +1,328 @@
|
||||
----------------------------------------------------------------------------------------------------------------------------------------
|
||||
-- Create Polls for your Factory Workers
|
||||
-- by MewMew -- with some help from RedLabel, Klonan, Morcup, BrainClot
|
||||
----------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
local function create_poll_gui(event)
|
||||
local player = game.players[event.player_index]
|
||||
|
||||
if player.gui.top.poll == nil then
|
||||
local button = player.gui.top.add { name = "poll", type = "sprite-button", sprite = "item/programmable-speaker" }
|
||||
button.style.font = "default-bold"
|
||||
button.style.minimal_height = 38
|
||||
button.style.minimal_width = 38
|
||||
button.style.top_padding = 2
|
||||
button.style.left_padding = 4
|
||||
button.style.right_padding = 4
|
||||
button.style.bottom_padding = 2
|
||||
end
|
||||
end
|
||||
|
||||
local function poll_show(player)
|
||||
|
||||
player.gui.left.direction = "horizontal"
|
||||
local frame = player.gui.left.add { type = "frame", name = "poll-panel", direction = "vertical" }
|
||||
|
||||
frame.add { type = "table", name = "poll_panel_table", colspan = 2 }
|
||||
|
||||
local poll_panel_table = frame.poll_panel_table
|
||||
|
||||
if not (global.poll_question == "") then
|
||||
|
||||
local str = "Poll #" .. global.score_total_polls_created .. ":"
|
||||
if global.score_total_polls_created > 1 then
|
||||
local x = game.tick
|
||||
x = ((x / 60) / 60) / 60
|
||||
x = global.score_total_polls_created / x
|
||||
x = round(x, 0)
|
||||
str = str .. " (Polls/hour: "
|
||||
str = str .. x
|
||||
str = str .. ")"
|
||||
end
|
||||
|
||||
poll_panel_table.add { type = "label", caption = str, single_line = false, name = "poll_number_label" }
|
||||
poll_panel_table.poll_number_label.style.font_color = { r=0.75, g=0.75, b=0.75}
|
||||
poll_panel_table.add { type = "label"}
|
||||
--poll_panel_table.add { caption = "----------------------------", type = "label" }
|
||||
--poll_panel_table.add { type = "label" }
|
||||
poll_panel_table.add { type = "label", caption = global.poll_question, single_line = false, name = "question_label" }
|
||||
poll_panel_table.question_label.style.maximal_width = 208
|
||||
poll_panel_table.question_label.style.maximal_height = 170
|
||||
poll_panel_table.question_label.style.font = "default-bold"
|
||||
poll_panel_table.question_label.style.font_color = { r=0.98, g=0.66, b=0.22}
|
||||
poll_panel_table.add { type = "label" }
|
||||
end
|
||||
|
||||
local y = 1
|
||||
while (y < 4) do
|
||||
|
||||
if not (global.poll_answers[y] == "") then
|
||||
|
||||
local z = tostring(y)
|
||||
|
||||
poll_panel_table.add { type = "label", caption = global.poll_answers[y], single_line = false, name = "answer_label_" .. z }
|
||||
local answer_label = poll_panel_table["answer_label_" .. z]
|
||||
answer_label.style.maximal_width = 208
|
||||
answer_label.style.minimal_width = 208
|
||||
answer_label.style.maximal_height = 165
|
||||
answer_label.style.font = "default"
|
||||
|
||||
local answerbutton = poll_panel_table.add { type = "button", caption = global.poll_button_votes[y], name = "answer_button_" .. z }
|
||||
answerbutton.style.font = "default-listbox"
|
||||
end
|
||||
y = y + 1
|
||||
end
|
||||
|
||||
frame.add { type = "table", name = "poll_panel_button_table", colspan = 3 }
|
||||
local poll_panel_button_table = frame.poll_panel_button_table
|
||||
poll_panel_button_table.add { type = "button", caption = "New Poll", name = "new_poll_assembler_button" }
|
||||
|
||||
|
||||
|
||||
global.poll_panel_creation_time[player.index] = game.tick
|
||||
|
||||
local str = "Hide (" .. global.poll_duration_in_seconds
|
||||
str = str .. ")"
|
||||
|
||||
|
||||
poll_panel_button_table.add { type = "button", caption = str, name = "poll_hide_button" }
|
||||
|
||||
poll_panel_button_table.poll_hide_button.style.minimal_width = 70
|
||||
poll_panel_button_table.new_poll_assembler_button.style.font = "default-bold"
|
||||
poll_panel_button_table.new_poll_assembler_button.style.minimal_height = 38
|
||||
poll_panel_button_table.poll_hide_button.style.font = "default-bold"
|
||||
poll_panel_button_table.poll_hide_button.style.minimal_height = 38
|
||||
poll_panel_button_table.add { type = "checkbox", caption = "Show Polls", state = global.autoshow_polls_for_player[player.name], name = "auto_show_polls_checkbox" }
|
||||
end
|
||||
|
||||
local function poll(player)
|
||||
|
||||
local frame = player.gui.left["poll-assembler"]
|
||||
frame = frame.table_poll_assembler
|
||||
|
||||
global.poll_question = ""
|
||||
global.poll_question = frame.textfield_question.text
|
||||
if (global.poll_question == "") then
|
||||
return
|
||||
end
|
||||
|
||||
|
||||
global.poll_answers = {"","",""}
|
||||
global.poll_answers[1] = frame.textfield_answer_1.text
|
||||
global.poll_answers[2] = frame.textfield_answer_2.text
|
||||
global.poll_answers[3] = frame.textfield_answer_3.text
|
||||
if (global.poll_answers[3] .. global.poll_answers[2] .. global.poll_answers[1] == "") then
|
||||
return
|
||||
end
|
||||
|
||||
local msg = player.name
|
||||
msg = msg .. " has created a new Poll!"
|
||||
|
||||
global.score_total_polls_created = global.score_total_polls_created + 1
|
||||
|
||||
local frame = player.gui.left["poll-assembler"]
|
||||
frame.destroy()
|
||||
|
||||
global.poll_voted = nil
|
||||
global.poll_voted = {}
|
||||
global.poll_button_votes = {0,0,0}
|
||||
|
||||
local x = 1
|
||||
|
||||
while (game.players[x] ~= nil) do
|
||||
|
||||
local player = game.players[x]
|
||||
|
||||
local frame = player.gui.left["poll-panel"]
|
||||
|
||||
if (frame) then
|
||||
frame.destroy()
|
||||
end
|
||||
|
||||
if (global.autoshow_polls_for_player[player.name] == true) then
|
||||
poll_show(player)
|
||||
end
|
||||
|
||||
player.print(msg)
|
||||
|
||||
x = x + 1
|
||||
end
|
||||
|
||||
|
||||
---------------------
|
||||
-- data for score.lua
|
||||
---------------------
|
||||
--global.score_total_polls_created = global.score_total_polls_created + 1
|
||||
--refresh_score()
|
||||
|
||||
end
|
||||
|
||||
|
||||
local function poll_refresh()
|
||||
|
||||
local x = 1
|
||||
|
||||
while (game.players[x] ~= nil) do
|
||||
|
||||
local player = game.players[x]
|
||||
|
||||
if (player.gui.left["poll-panel"]) then
|
||||
local frame = player.gui.left["poll-panel"]
|
||||
frame = frame.poll_panel_table
|
||||
|
||||
if not (frame.answer_button_1 == nil) then
|
||||
frame.answer_button_1.caption = global.poll_button_votes[1]
|
||||
end
|
||||
if not (frame.answer_button_2 == nil) then
|
||||
frame.answer_button_2.caption = global.poll_button_votes[2]
|
||||
end
|
||||
if not (frame.answer_button_3 == nil) then
|
||||
frame.answer_button_3.caption = global.poll_button_votes[3]
|
||||
end
|
||||
end
|
||||
x = x + 1
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
local function poll_assembler(player)
|
||||
local frame = player.gui.left.add { type = "frame", name = "poll-assembler", caption = "" }
|
||||
local frame_table = frame.add { type = "table", name = "table_poll_assembler", colspan = 2 }
|
||||
frame_table.add { type = "label", caption = "Question:" }
|
||||
frame_table.add { type = "textfield", name = "textfield_question", text = "" }
|
||||
frame_table.add { type = "label", caption = "Answer #1:" }
|
||||
frame_table.add { type = "textfield", name = "textfield_answer_1", text = "" }
|
||||
frame_table.add { type = "label", caption = "Answer #2:" }
|
||||
frame_table.add { type = "textfield", name = "textfield_answer_2", text = "" }
|
||||
frame_table.add { type = "label", caption = "Answer #3:" }
|
||||
frame_table.add { type = "textfield", name = "textfield_answer_3", text = "" }
|
||||
frame_table.add { type = "label", caption = "" }
|
||||
frame_table.add { type = "button", name = "create_new_poll_button", caption = "Create" }
|
||||
|
||||
end
|
||||
|
||||
function poll_sync_for_new_joining_player(event)
|
||||
|
||||
if not global.poll_voted then global.poll_voted = {} end
|
||||
if not global.poll_question then global.poll_question = "" end
|
||||
if not global.poll_answers then global.poll_answers = {"","",""} end
|
||||
if not global.poll_button_votes then global.poll_button_votes = {0,0,0} end
|
||||
if not global.poll_voted then global.poll_voted = {} end
|
||||
if not global.autoshow_polls_for_player then global.autoshow_polls_for_player = {} end
|
||||
if not global.poll_duration_in_seconds then global.poll_duration_in_seconds = 99 end
|
||||
if not global.poll_panel_creation_time then global.poll_panel_creation_time = {} end
|
||||
if not global.score_total_polls_created then global.score_total_polls_created = 0 end
|
||||
|
||||
local player = game.players[event.player_index]
|
||||
|
||||
global.autoshow_polls_for_player[player.name] = true
|
||||
|
||||
local frame = player.gui.left["poll-panel"]
|
||||
if (frame == nil) then
|
||||
if not (global.poll_question == "") then
|
||||
poll_show(player)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
local function on_gui_click(event)
|
||||
if not (event and event.element and event.element.valid) then return end
|
||||
local player = game.players[event.element.player_index]
|
||||
local name = event.element.name
|
||||
|
||||
if (name == "poll") then
|
||||
local frame = player.gui.left["poll-panel"]
|
||||
if (frame) then
|
||||
frame.destroy()
|
||||
else
|
||||
poll_show(player)
|
||||
end
|
||||
|
||||
local frame = player.gui.left["poll-assembler"]
|
||||
if (frame) then
|
||||
frame.destroy()
|
||||
end
|
||||
end
|
||||
|
||||
if (name == "new_poll_assembler_button") then
|
||||
local frame = player.gui.left["poll-assembler"]
|
||||
if (frame) then
|
||||
frame.destroy()
|
||||
else
|
||||
poll_assembler(player)
|
||||
end
|
||||
end
|
||||
|
||||
if (name == "create_new_poll_button") then
|
||||
poll(player)
|
||||
end
|
||||
|
||||
if (name == "poll_hide_button") then
|
||||
local frame = player.gui.left["poll-panel"]
|
||||
if (frame) then
|
||||
frame.destroy()
|
||||
end
|
||||
local frame = player.gui.left["poll-assembler"]
|
||||
if (frame) then
|
||||
frame.destroy()
|
||||
end
|
||||
end
|
||||
|
||||
if (name == "auto_show_polls_checkbox") then
|
||||
global.autoshow_polls_for_player[player.name] = event.element.state
|
||||
end
|
||||
|
||||
if global.poll_voted[event.player_index] == nil then
|
||||
|
||||
if(name == "answer_button_1") then
|
||||
global.poll_button_votes[1] = global.poll_button_votes[1] + 1
|
||||
global.poll_voted[event.player_index] = player.name
|
||||
poll_refresh()
|
||||
end
|
||||
|
||||
if(name == "answer_button_2") then
|
||||
global.poll_button_votes[2] = global.poll_button_votes[2] + 1
|
||||
global.poll_voted[event.player_index] = player.name
|
||||
poll_refresh()
|
||||
end
|
||||
|
||||
if(name == "answer_button_3") then
|
||||
global.poll_button_votes[3] = global.poll_button_votes[3] + 1
|
||||
global.poll_voted[event.player_index] = player.name
|
||||
poll_refresh()
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
local function poll_timeout()
|
||||
if game.tick % 60 == 0 then
|
||||
local x = 1
|
||||
while game.players[x] ~= nil do
|
||||
local player = game.players[x]
|
||||
if global.poll_panel_creation_time[player.index] then
|
||||
local frame = player.gui.left["poll-panel"]
|
||||
if frame then
|
||||
local y = (game.tick - global.poll_panel_creation_time[player.index]) / 60
|
||||
local y = global.poll_duration_in_seconds - y
|
||||
y = round(y, 0)
|
||||
if y == 0 then
|
||||
frame.destroy()
|
||||
global.poll_panel_creation_time[player.index] = nil
|
||||
else
|
||||
y = "Hide (" .. y
|
||||
y = y .. ")"
|
||||
frame.poll_panel_button_table.poll_hide_button.caption = y
|
||||
end
|
||||
end
|
||||
end
|
||||
x = x + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Event.register(defines.events.on_tick, poll_timeout)
|
||||
Event.register(defines.events.on_gui_click, on_gui_click)
|
||||
Event.register(defines.events.on_player_joined_game, create_poll_gui)
|
||||
Event.register(defines.events.on_player_joined_game, poll_sync_for_new_joining_player)
|
98
score.lua
Normal file
98
score.lua
Normal file
@@ -0,0 +1,98 @@
|
||||
if not global.score_rockets_launched then global.score_rockets_launched = 0 end
|
||||
|
||||
local function create_score_gui(event)
|
||||
local player = game.players[event.player_index]
|
||||
|
||||
if player.gui.top.score == nil then
|
||||
local button = player.gui.top.add({ type = "sprite-button", name = "score", sprite = "item/rocket-silo" })
|
||||
button.style.minimal_height = 38
|
||||
button.style.minimal_width = 38
|
||||
button.style.top_padding = 2
|
||||
button.style.left_padding = 4
|
||||
button.style.right_padding = 4
|
||||
button.style.bottom_padding = 2
|
||||
end
|
||||
end
|
||||
|
||||
function refresh_score()
|
||||
local x = 1
|
||||
while (game.players[x] ~= nil) do
|
||||
local player = game.players[x]
|
||||
local frame = player.gui.top["score_panel"]
|
||||
|
||||
if (frame) then
|
||||
frame.score_table.label_rockets_launched.caption = "Rockets launched: " .. global.score_rockets_launched
|
||||
frame.score_table.label_biters_killed.caption = "Biters liberated: " .. global.score_biter_total_kills
|
||||
-- frame.score_table.label_score_polls_created.caption = "Polls created: " .. global.score_total_polls_created
|
||||
end
|
||||
x = x + 1
|
||||
end
|
||||
end
|
||||
|
||||
local function score_show(player)
|
||||
|
||||
local rocket_score_value_string = tostring(global.score_rockets_launched)
|
||||
|
||||
local frame = player.gui.top.add { type = "frame", name = "score_panel" }
|
||||
|
||||
local score_table = frame.add { type = "table", colspan = 5, name = "score_table" }
|
||||
local label = score_table.add { type = "label", caption = "", name = "label_rockets_launched" }
|
||||
label.style.font = "default-bold"
|
||||
label.style.font_color = { r=0.98, g=0.66, b=0.22}
|
||||
label.style.top_padding = 2
|
||||
label.style.left_padding = 4
|
||||
label.style.right_padding = 4
|
||||
|
||||
score_table.add { type = "label", caption = "|"}
|
||||
|
||||
local label = score_table.add { type = "label", caption = "", name = "label_biters_killed" }
|
||||
label.style.font = "default-bold"
|
||||
label.style.font_color = { r=0.98, g=0.11, b=0.11}
|
||||
label.style.top_padding = 2
|
||||
label.style.left_padding = 4
|
||||
label.style.right_padding = 4
|
||||
--[[
|
||||
if global.score_total_polls_created then
|
||||
score_table.add { type = "label", caption = "|"}
|
||||
|
||||
local label = score_table.add { type = "label", caption = "", name = "label_score_polls_created" }
|
||||
label.style.font = "default-bold"
|
||||
label.style.font_color = { r=0.80, g=0.80, b=0.80}
|
||||
label.style.top_padding = 2
|
||||
label.style.left_padding = 4
|
||||
label.style.right_padding = 4
|
||||
end
|
||||
--]]
|
||||
refresh_score()
|
||||
end
|
||||
|
||||
|
||||
local function on_gui_click(event)
|
||||
if not (event and event.element and event.element.valid) then return end
|
||||
|
||||
local player = game.players[event.element.player_index]
|
||||
local name = event.element.name
|
||||
local frame = player.gui.top["score_panel"]
|
||||
|
||||
if (name == "score") and (frame == nil) then
|
||||
score_show(player)
|
||||
else
|
||||
if (name == "score") then
|
||||
frame.destroy()
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
local function rocket_launched(event)
|
||||
global.score_rockets_launched = global.score_rockets_launched + 1
|
||||
game.print ("A rocket has been launched!")
|
||||
refresh_score()
|
||||
end
|
||||
|
||||
|
||||
|
||||
Event.register(defines.events.on_entity_died, refresh_score)
|
||||
Event.register(defines.events.on_gui_click, on_gui_click)
|
||||
Event.register(defines.events.on_player_joined_game, create_score_gui)
|
||||
Event.register(defines.events.on_rocket_launched, rocket_launched)
|
17
train_station_names.lua
Normal file
17
train_station_names.lua
Normal file
@@ -0,0 +1,17 @@
|
||||
local function player_built_entity(event)
|
||||
|
||||
if event.created_entity.name == "train-stop" then
|
||||
local y = math.random(1,3)
|
||||
if y == 1 then
|
||||
else
|
||||
local total_players = #game.players
|
||||
local x = math.random(1,total_players)
|
||||
local player = game.players[x]
|
||||
event.created_entity.backer_name = player.name
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
Event.register(defines.events.on_built_entity, player_built_entity)
|
||||
Event.register(defines.events.on_robot_built_entity, player_built_entity)
|
Reference in New Issue
Block a user