mirror of
https://github.com/Refactorio/RedMew.git
synced 2025-01-18 03:21:47 +02:00
Merge branch 'develop' into chat_triggers
This commit is contained in:
commit
06a1a1927a
@ -56,7 +56,7 @@ local STD_BASE_CONTROL = 'lua52c+factorio+factorio_control+factorio_defines+fact
|
|||||||
--[Assume Factorio Control stage as default]--
|
--[Assume Factorio Control stage as default]--
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
std = STD_CONTROL
|
std = STD_CONTROL
|
||||||
globals = {'math', 'table', '_DEBUG', '_CHEATS', 'MARKET_ITEM', 'newline'} -- RedMew-specific globals
|
globals = {'print', 'math', 'table', '_DEBUG', '_CHEATS', 'MARKET_ITEM', 'ServerCommands'} -- RedMew-specific globals
|
||||||
max_line_length = LINE_LENGTH
|
max_line_length = LINE_LENGTH
|
||||||
|
|
||||||
not_globals = NOT_GLOBALS
|
not_globals = NOT_GLOBALS
|
||||||
@ -625,7 +625,7 @@ stds.factorio_defines = {
|
|||||||
"on_gui_closed", "on_gui_value_changed", "on_player_muted", "on_player_unmuted", "on_player_cheat_mode_enabled", "on_player_cheat_mode_disabled",
|
"on_gui_closed", "on_gui_value_changed", "on_player_muted", "on_player_unmuted", "on_player_cheat_mode_enabled", "on_player_cheat_mode_disabled",
|
||||||
"on_character_corpse_expired", "on_pre_ghost_deconstructed", "on_player_pipette", "on_player_display_resolution_changed", "on_player_display_scale_changed",
|
"on_character_corpse_expired", "on_pre_ghost_deconstructed", "on_player_pipette", "on_player_display_resolution_changed", "on_player_display_scale_changed",
|
||||||
"on_pre_player_crafted_item", "on_player_cancelled_crafting", "on_chunk_charted", "on_technology_effects_reset", "on_land_mine_armed", "on_forces_merged",
|
"on_pre_player_crafted_item", "on_player_cancelled_crafting", "on_chunk_charted", "on_technology_effects_reset", "on_land_mine_armed", "on_forces_merged",
|
||||||
"on_player_trash_inventory_changed",
|
"on_player_trash_inventory_changed", "on_server_started"
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
alert_type = {
|
alert_type = {
|
||||||
|
46
config.lua
46
config.lua
@ -1,34 +1,30 @@
|
|||||||
|
-- global: the global table
|
||||||
|
-- global.scenario: the only segment of global we should touch
|
||||||
|
-- global.
|
||||||
_DEBUG = false
|
_DEBUG = false
|
||||||
_CHEATS = false
|
_CHEATS = false
|
||||||
MARKET_ITEM = 'coin'
|
MARKET_ITEM = 'coin'
|
||||||
|
|
||||||
global.scenario = {}
|
global.config = {}
|
||||||
global.scenario.variables = {}
|
global.config.player_list = {}
|
||||||
global.scenario.variables.player_positions = {}
|
global.config.player_list.enable_coin_col = true
|
||||||
global.player_walk_distances = {}
|
global.config.paint = {}
|
||||||
global.scenario.variables.player_deaths = {}
|
global.config.paint.enable = true
|
||||||
global.scenario.config = {}
|
global.config.fish_market = {}
|
||||||
global.scenario.config.player_list = {}
|
global.config.fish_market.enable = true
|
||||||
global.scenario.config.player_list.enable_coin_col = true
|
global.config.nuke_control = {}
|
||||||
global.scenario.config.paint = {}
|
global.config.nuke_control.enable_autokick = true
|
||||||
global.scenario.config.paint.enable = true
|
global.config.nuke_control.enable_autoban = true
|
||||||
global.scenario.config.fish_market = {}
|
global.config.hodor = true
|
||||||
global.scenario.config.fish_market.enable = true
|
global.config.auto_respond = true
|
||||||
global.scenario.config.nuke_control = {}
|
global.config.mentions = true
|
||||||
global.scenario.config.nuke_control.enable_autokick = true
|
global.config.nuke_control.nuke_min_time_hours = 3 --how long a player must be on the server to be allowed to use the nuke
|
||||||
global.scenario.config.nuke_control.enable_autoban = true
|
|
||||||
global.scenario.custom_functions = {}
|
|
||||||
global.scenario.config.nuke_control.nuke_min_time_hours = 3 --how long a player must be on the server to be allowed to use the nuke
|
|
||||||
global.scenario.config.players_assigned_names = false -- assigns players random names when they first join
|
|
||||||
global.scenario.config.players_roll_names = false -- allows players to roll random names
|
|
||||||
global.newline = '\n'
|
|
||||||
newline = '\n'
|
|
||||||
|
|
||||||
-- The title of the map
|
-- The title of the map
|
||||||
global.scenario.config.map_name_key = 'This Map has no name'
|
global.config.map_name_key = 'This Map has no name'
|
||||||
-- The long description of the map, typically 1 paragraph
|
-- The long description of the map, typically 1 paragraph
|
||||||
global.scenario.config.map_description_key = "By default this section is blank as it's supposed to be filled out on a per map basis. (If you're seeing this message, ping the admin team to get a description added for this map)"
|
global.config.map_description_key = "By default this section is blank as it's supposed to be filled out on a per map basis. (If you're seeing this message, ping the admin team to get a description added for this map)"
|
||||||
-- The feature list of the map
|
-- The feature list of the map
|
||||||
global.scenario.config.map_extra_info_key = 'This map has no extra infomation'
|
global.config.map_extra_info_key = 'This map has no extra infomation'
|
||||||
-- New Scenario Features, appears in the "What's new" tab
|
-- New Scenario Features, appears in the "What's new" tab
|
||||||
global.scenario.config.new_info_key = 'Nothing is new. The world is at peace'
|
global.config.new_info_key = 'Nothing is new. The world is at peace'
|
||||||
|
@ -7,6 +7,10 @@ require 'utils.math'
|
|||||||
require 'map_gen.shared.perlin_noise'
|
require 'map_gen.shared.perlin_noise'
|
||||||
require 'map_layout'
|
require 'map_layout'
|
||||||
|
|
||||||
|
-- Specific to RedMew hosts, can be disabled safely if not hosting on RedMew servers
|
||||||
|
require 'features.server'
|
||||||
|
require 'features.server_commands'
|
||||||
|
|
||||||
-- Library modules which, if missing, will cause other feature modules to fail
|
-- Library modules which, if missing, will cause other feature modules to fail
|
||||||
require 'features.base_data'
|
require 'features.base_data'
|
||||||
--require 'features.follow' -- Nothing currently uses anything inside follow
|
--require 'features.follow' -- Nothing currently uses anything inside follow
|
||||||
@ -21,7 +25,6 @@ require 'features.donator_messages'
|
|||||||
require 'features.train_saviour'
|
require 'features.train_saviour'
|
||||||
require 'features.fish_market'
|
require 'features.fish_market'
|
||||||
require 'features.free_item_logging'
|
require 'features.free_item_logging'
|
||||||
--require 'features.infinite_storage_chest'
|
|
||||||
require 'features.nuke_control'
|
require 'features.nuke_control'
|
||||||
require 'features.player_colors'
|
require 'features.player_colors'
|
||||||
require 'features.reactor_meltdown'
|
require 'features.reactor_meltdown'
|
||||||
|
@ -74,6 +74,6 @@ your own resources (for example bobs or angels) with a value and the scenario wi
|
|||||||
spawn chances.
|
spawn chances.
|
||||||
|
|
||||||
### Adding Market Items
|
### Adding Market Items
|
||||||
Items can be configured by adding the desired item under the `MarketExchange` configuration. You only have to define a
|
Items can be configured by adding the desired item under the `Experience` configuration. You only have to define a level
|
||||||
level at which it unlocks, a price or prices in case it can cost more, and what the item prototype is. For a list of
|
at which it unlocks and a price. For a list of items, you can look up each possible item on the
|
||||||
items, you can look up each possible item on the [Factorio raw data page](https://wiki.factorio.com/Data.raw#item).
|
[Factorio raw data page](https://wiki.factorio.com/Data.raw#item).
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
local Game = require 'utils.game'
|
local Game = require 'utils.game'
|
||||||
local Event = require 'utils.event'
|
local Event = require 'utils.event'
|
||||||
local Donators = require 'resources.donators'
|
local UserGroups = require 'features.user_groups'
|
||||||
|
|
||||||
local function player_joined(event)
|
local function player_joined(event)
|
||||||
local player = Game.get_player_by_index(event.player_index)
|
local player = Game.get_player_by_index(event.player_index)
|
||||||
@ -8,7 +8,7 @@ local function player_joined(event)
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
local message = Donators.welcome_messages[player.name]
|
local message = UserGroups.get_donator_welcome_message(player.name)
|
||||||
if not message then
|
if not message then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
@ -410,7 +410,7 @@ local function fish_player_crafted_item(event)
|
|||||||
end
|
end
|
||||||
|
|
||||||
local function init()
|
local function init()
|
||||||
if global.scenario.config.fish_market.enable then
|
if global.config.fish_market.enable then
|
||||||
commands.add_command('market', 'Places a fish market near you. (Admins only)', spawn_market)
|
commands.add_command('market', 'Places a fish market near you. (Admins only)', spawn_market)
|
||||||
|
|
||||||
Event.on_nth_tick(180, on_180_ticks)
|
Event.on_nth_tick(180, on_180_ticks)
|
||||||
|
@ -4,6 +4,8 @@ local Event = require 'utils.event'
|
|||||||
local raise_event = script.raise_event
|
local raise_event = script.raise_event
|
||||||
local ceil = math.ceil
|
local ceil = math.ceil
|
||||||
local max = math.max
|
local max = math.max
|
||||||
|
local floor = math.floor
|
||||||
|
local format = string.format
|
||||||
|
|
||||||
-- this, things that can be done run-time
|
-- this, things that can be done run-time
|
||||||
local ForceControl = {}
|
local ForceControl = {}
|
||||||
@ -323,16 +325,14 @@ function ForceControl.get_formatted_force_data(lua_force_or_name)
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
local result =
|
return format(
|
||||||
string.format(
|
'Current experience: %d Total experience: %d Current level: %d Next level at: %d Percentage to level up: %d%%',
|
||||||
'Current experience: %d Total experience: %d Current level: %d Next level at: %d Percentage to level up: %d%%',
|
force_config.current_experience,
|
||||||
force_config.current_experience,
|
force_config.total_experience,
|
||||||
force_config.total_experience,
|
force_config.current_level,
|
||||||
force_config.current_level,
|
force_config.experience_level_up_cap,
|
||||||
force_config.experience_level_up_cap,
|
floor(force_config.experience_percentage * 100) * 0.01
|
||||||
math.floor(force_config.experience_percentage * 100) / 100
|
)
|
||||||
)
|
|
||||||
return result
|
|
||||||
end
|
end
|
||||||
|
|
||||||
return ForceControl
|
return ForceControl
|
||||||
|
@ -21,10 +21,10 @@ local new_info_key = 4
|
|||||||
local welcomed_players = {}
|
local welcomed_players = {}
|
||||||
|
|
||||||
local editable_info = {
|
local editable_info = {
|
||||||
[map_name_key] = global.scenario.config.map_name_key,
|
[map_name_key] = global.config.map_name_key,
|
||||||
[map_description_key] = global.scenario.config.map_description_key,
|
[map_description_key] = global.config.map_description_key,
|
||||||
[map_extra_info_key] = global.scenario.config.map_extra_info_key,
|
[map_extra_info_key] = global.config.map_extra_info_key,
|
||||||
[new_info_key] = global.scenario.config.new_info_key
|
[new_info_key] = global.config.new_info_key
|
||||||
}
|
}
|
||||||
|
|
||||||
Global.register(
|
Global.register(
|
||||||
|
@ -41,7 +41,7 @@ local filter_table_close_button_name = Gui.uid_name()
|
|||||||
|
|
||||||
global.paint_brushes_by_player = {}
|
global.paint_brushes_by_player = {}
|
||||||
local function player_build_tile(event)
|
local function player_build_tile(event)
|
||||||
if not global.scenario.config.paint.enable then
|
if not global.config.paint.enable then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
if event.item.name ~= brush_tool then
|
if event.item.name ~= brush_tool then
|
||||||
@ -75,7 +75,7 @@ local function player_build_tile(event)
|
|||||||
end
|
end
|
||||||
|
|
||||||
local function player_joined(event)
|
local function player_joined(event)
|
||||||
if not global.scenario.config.paint.enable then
|
if not global.config.paint.enable then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
local player = Game.get_player_by_index(event.player_index)
|
local player = Game.get_player_by_index(event.player_index)
|
||||||
|
@ -448,7 +448,7 @@ local function get_default_player_settings()
|
|||||||
distance_heading_name
|
distance_heading_name
|
||||||
}
|
}
|
||||||
local offset = 6
|
local offset = 6
|
||||||
if global.scenario.config.player_list.enable_coin_col then
|
if global.config.player_list.enable_coin_col then
|
||||||
columns[6] = coin_heading_name
|
columns[6] = coin_heading_name
|
||||||
offset = 7
|
offset = 7
|
||||||
end
|
end
|
||||||
|
@ -5,6 +5,7 @@ local UserGroups = require 'features.user_groups'
|
|||||||
local Game = require 'utils.game'
|
local Game = require 'utils.game'
|
||||||
local math = require 'utils.math'
|
local math = require 'utils.math'
|
||||||
local Utils = require 'utils.utils'
|
local Utils = require 'utils.utils'
|
||||||
|
local Server = require 'features.server'
|
||||||
|
|
||||||
local default_poll_duration = 300 * 60 -- in ticks
|
local default_poll_duration = 300 * 60 -- in ticks
|
||||||
local duration_max = 3600 -- in seconds
|
local duration_max = 3600 -- in seconds
|
||||||
@ -108,6 +109,48 @@ local function do_remaining_time(poll, remaining_time_label)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function send_poll_result_to_discord(poll)
|
||||||
|
local result = {'Poll #', poll.id}
|
||||||
|
|
||||||
|
local created_by_player = poll.created_by
|
||||||
|
if created_by_player and created_by_player.valid then
|
||||||
|
table.insert(result, ' Created by ')
|
||||||
|
table.insert(result, created_by_player.name)
|
||||||
|
end
|
||||||
|
|
||||||
|
local edited_by_players = poll.edited_by
|
||||||
|
if next(edited_by_players) then
|
||||||
|
table.insert(result, ' Edited by ')
|
||||||
|
for pi, _ in pairs(edited_by_players) do
|
||||||
|
local p = game.players[pi]
|
||||||
|
if p and p.valid then
|
||||||
|
table.insert(result, p.name)
|
||||||
|
table.insert(result, ', ')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
table.remove(result)
|
||||||
|
end
|
||||||
|
|
||||||
|
table.insert(result, '\\n**Question: ')
|
||||||
|
table.insert(result, poll.question)
|
||||||
|
table.insert(result, '**\\n')
|
||||||
|
|
||||||
|
local answers = poll.answers
|
||||||
|
local answers_count = #answers
|
||||||
|
for i, a in ipairs(answers) do
|
||||||
|
table.insert(result, '[')
|
||||||
|
table.insert(result, a.voted_count)
|
||||||
|
table.insert(result, '] - ')
|
||||||
|
table.insert(result, a.text)
|
||||||
|
if i ~= answers_count then
|
||||||
|
table.insert(result, '\\n')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local message = table.concat(result)
|
||||||
|
Server.to_discord_embed(message)
|
||||||
|
end
|
||||||
|
|
||||||
local function redraw_poll_viewer_content(data)
|
local function redraw_poll_viewer_content(data)
|
||||||
local poll_viewer_content = data.poll_viewer_content
|
local poll_viewer_content = data.poll_viewer_content
|
||||||
local remaining_time_label = data.remaining_time_label
|
local remaining_time_label = data.remaining_time_label
|
||||||
@ -657,6 +700,7 @@ local function create_poll(event)
|
|||||||
table.insert(polls, poll_data)
|
table.insert(polls, poll_data)
|
||||||
|
|
||||||
show_new_poll(poll_data)
|
show_new_poll(poll_data)
|
||||||
|
send_poll_result_to_discord(poll_data)
|
||||||
|
|
||||||
Gui.remove_data_recursivly(frame)
|
Gui.remove_data_recursivly(frame)
|
||||||
frame.destroy()
|
frame.destroy()
|
||||||
@ -1199,6 +1243,7 @@ function Class.poll(data)
|
|||||||
table.insert(polls, poll_data)
|
table.insert(polls, poll_data)
|
||||||
|
|
||||||
show_new_poll(poll_data)
|
show_new_poll(poll_data)
|
||||||
|
send_poll_result_to_discord(poll_data)
|
||||||
|
|
||||||
return true, id
|
return true, id
|
||||||
end
|
end
|
||||||
@ -1273,6 +1318,23 @@ local function poll_result_command(cmd)
|
|||||||
Game.player_print(result)
|
Game.player_print(result)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function Class.send_poll_result_to_discord(id)
|
||||||
|
if type(id) ~= 'number' then
|
||||||
|
Server.to_discord_embed('poll-id must be a number')
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
for _, poll_data in ipairs(polls) do
|
||||||
|
if poll_data.id == id then
|
||||||
|
send_poll_result_to_discord(poll_data)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local message = table.concat {'poll #', id, ' not found'}
|
||||||
|
Server.to_discord_embed(message)
|
||||||
|
end
|
||||||
|
|
||||||
commands.add_command(
|
commands.add_command(
|
||||||
'poll',
|
'poll',
|
||||||
'<{question = "question", answers = {"answer 1", "answer 2"}, duration = 300 | nil}> - Creates a new poll (Admin and regulars only).',
|
'<{question = "question", answers = {"answer 1", "answer 2"}, duration = 300 | nil}> - Creates a new poll (Admin and regulars only).',
|
||||||
|
@ -5,7 +5,7 @@ local Game = require 'utils.game'
|
|||||||
|
|
||||||
local function allowed_to_nuke(player)
|
local function allowed_to_nuke(player)
|
||||||
if type(player) == 'table' then
|
if type(player) == 'table' then
|
||||||
return player.admin or UserGroups.is_regular(player.name) or ((player.online_time / 216000) > global.scenario.config.nuke_control.nuke_min_time_hours)
|
return player.admin or UserGroups.is_regular(player.name) or ((player.online_time / 216000) > global.config.nuke_control.nuke_min_time_hours)
|
||||||
elseif type(player) == 'number' then
|
elseif type(player) == 'number' then
|
||||||
return allowed_to_nuke(Game.get_player_by_index(player))
|
return allowed_to_nuke(Game.get_player_by_index(player))
|
||||||
end
|
end
|
||||||
@ -109,7 +109,7 @@ local function on_capsule_used(event)
|
|||||||
local item = event.item
|
local item = event.item
|
||||||
local player = Game.get_player_by_index(event.player_index)
|
local player = Game.get_player_by_index(event.player_index)
|
||||||
|
|
||||||
if not player or not player.valid or (global.scenario.config.nuke_control.enable_autokick and global.scenario.config.nuke_control.enable_autoban) then
|
if not player or not player.valid or (global.config.nuke_control.enable_autokick and global.config.nuke_control.enable_autoban) then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -132,12 +132,12 @@ local function on_capsule_used(event)
|
|||||||
end
|
end
|
||||||
if count > 8 then
|
if count > 8 then
|
||||||
if global.players_warned[event.player_index] then
|
if global.players_warned[event.player_index] then
|
||||||
if global.scenario.config.nuke_control.enable_autokick then
|
if global.config.nuke_control.enable_autokick then
|
||||||
game.ban_player(player, string.format('Damaged %i entities with %s. This action was performed automatically. If you want to contest this ban please visit redmew.com/discord.', count, event.item.name))
|
game.ban_player(player, string.format('Damaged %i entities with %s. This action was performed automatically. If you want to contest this ban please visit redmew.com/discord.', count, event.item.name))
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
global.players_warned[event.player_index] = true
|
global.players_warned[event.player_index] = true
|
||||||
if global.scenario.config.nuke_control.enable_autoban then
|
if global.config.nuke_control.enable_autoban then
|
||||||
game.print(player, string.format('Damaged %i entities with %s -Antigrief', count, event.item.name))
|
game.print(player, string.format('Damaged %i entities with %s -Antigrief', count, event.item.name))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -11,7 +11,7 @@ local function player_created(event)
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
if (global.scenario.config.fish_market.enable) then
|
if (global.config.fish_market.enable) then
|
||||||
player.insert {name = MARKET_ITEM, count = 10}
|
player.insert {name = MARKET_ITEM, count = 10}
|
||||||
end
|
end
|
||||||
player.insert {name = 'iron-gear-wheel', count = 8}
|
player.insert {name = 'iron-gear-wheel', count = 8}
|
||||||
|
104
features/retailer.lua
Normal file
104
features/retailer.lua
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
local Global = require 'utils.global'
|
||||||
|
local insert = table.insert
|
||||||
|
|
||||||
|
local Retailer = {}
|
||||||
|
|
||||||
|
---Global storage
|
||||||
|
---Markets are indexed by the group_name and is a sequential list of LuaEntities
|
||||||
|
---Items are indexed by the group name and is a list indexed by the item name and contains the prices per item
|
||||||
|
local memory = {
|
||||||
|
markets = {},
|
||||||
|
items = {},
|
||||||
|
}
|
||||||
|
|
||||||
|
Global.register({
|
||||||
|
memory = memory,
|
||||||
|
}, function (tbl)
|
||||||
|
memory = tbl.memory
|
||||||
|
end)
|
||||||
|
|
||||||
|
---Add a market to the group_name retailer.
|
||||||
|
---@param group_name string
|
||||||
|
---@param market_entity LuaEntity
|
||||||
|
function Retailer.add_market(group_name, market_entity)
|
||||||
|
if not memory.markets[group_name] then
|
||||||
|
memory.markets[group_name] = {market_entity}
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
insert(memory.markets[group_name], market_entity)
|
||||||
|
end
|
||||||
|
|
||||||
|
---Sets an item for all the group_name markets.
|
||||||
|
---@param group_name string
|
||||||
|
---@param item_name string
|
||||||
|
---@param prices table associative table where the key is the currency item and the value the amount of it
|
||||||
|
function Retailer.set_item(group_name, item_name, prices)
|
||||||
|
if not memory.items[group_name] then
|
||||||
|
memory.items[group_name] = {}
|
||||||
|
end
|
||||||
|
|
||||||
|
local market_format_prices = {}
|
||||||
|
for currency, amount in pairs(prices) do
|
||||||
|
insert(market_format_prices, {currency, amount})
|
||||||
|
end
|
||||||
|
|
||||||
|
memory.items[group_name][item_name] = market_format_prices
|
||||||
|
end
|
||||||
|
|
||||||
|
---Returns all item for the group_name retailer.
|
||||||
|
---@param group_name string
|
||||||
|
function Retailer.get_items(group_name)
|
||||||
|
return memory.items[group_name] or {}
|
||||||
|
end
|
||||||
|
|
||||||
|
---Removes an item from the markets for the group_name retailer.
|
||||||
|
---@param group_name string
|
||||||
|
---@param item_name string
|
||||||
|
function Retailer.remove_item(group_name, item_name)
|
||||||
|
if not memory.items[group_name] then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
memory.items[group_name][item_name] = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
---Ships the current list of items with their prices to all markets for the group_name retailer.
|
||||||
|
---@param group_name string
|
||||||
|
function Retailer.ship_items(group_name)
|
||||||
|
local markets = memory.markets[group_name]
|
||||||
|
if not markets then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local market_items = memory.items[group_name]
|
||||||
|
if not market_items then
|
||||||
|
-- items have not been added yet
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
for _, market in ipairs(markets) do
|
||||||
|
if market.valid then
|
||||||
|
-- clean the current inventory
|
||||||
|
local remove_market_item = market.remove_market_item
|
||||||
|
-- remove re-indexes the offers, to prevent shifting, go backwards
|
||||||
|
local current_market_items = market.get_market_items()
|
||||||
|
if current_market_items then
|
||||||
|
for current_index = #current_market_items, 1, -1 do
|
||||||
|
remove_market_item(current_index)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- re-add the whole list
|
||||||
|
local add_market_item = market.add_market_item
|
||||||
|
for item_name, prices in pairs(market_items) do
|
||||||
|
add_market_item({
|
||||||
|
price = prices,
|
||||||
|
offer = {type = 'give-item', item = item_name, count = 1}
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return Retailer
|
353
features/server.lua
Normal file
353
features/server.lua
Normal file
@ -0,0 +1,353 @@
|
|||||||
|
--- See documentation at https://github.com/Refactorio/RedMew/pull/469
|
||||||
|
|
||||||
|
local Token = require 'utils.global_token'
|
||||||
|
|
||||||
|
local Public = {}
|
||||||
|
|
||||||
|
local raw_print = print
|
||||||
|
function print(str)
|
||||||
|
raw_print('[PRINT] ' .. str)
|
||||||
|
end
|
||||||
|
|
||||||
|
local discord_tag = '[DISCORD]'
|
||||||
|
local discord_raw_tag = '[DISCORD-RAW]'
|
||||||
|
local discord_bold_tag = '[DISCORD-BOLD]'
|
||||||
|
local discord_admin_tag = '[DISCORD-ADMIN]'
|
||||||
|
local discord_admin_raw_tag = '[DISCORD-ADMIN-RAW]'
|
||||||
|
local discord_embed_tag = '[DISCORD-EMBED]'
|
||||||
|
local discord_embed_raw_tag = '[DISCORD-EMBED-RAW]'
|
||||||
|
local discord_admin_embed_tag = '[DISCORD-ADMIN-EMBED]'
|
||||||
|
local discord_admin_embed_raw_tag = '[DISCORD-ADMIN-EMBED-RAW]'
|
||||||
|
local start_scenario_tag = '[START-SCENARIO]'
|
||||||
|
local ping_tag = '[PING]'
|
||||||
|
local data_set_tag = '[DATA-SET]'
|
||||||
|
local data_get_tag = '[DATA-GET]'
|
||||||
|
local data_get_all_tag = '[DATA-GET-ALL]'
|
||||||
|
local data_tracked_tag = '[DATA-TRACKED]'
|
||||||
|
|
||||||
|
Public.raw_print = raw_print
|
||||||
|
|
||||||
|
local data_set_handlers = {}
|
||||||
|
|
||||||
|
--- The event id for the on_server_started event.
|
||||||
|
-- The event is raised whenever the server goes from the starting state to the running state.
|
||||||
|
-- It provides a good opportunity to request data from the web server.
|
||||||
|
-- Note that if the server is stopped then started again, this event will be raised again.
|
||||||
|
-- @usage
|
||||||
|
-- local Server = require 'features.server'
|
||||||
|
-- local Event = require 'utils.event'
|
||||||
|
--
|
||||||
|
-- Event.add(Server.events.on_server_started,
|
||||||
|
-- function()
|
||||||
|
-- Server.try_get_all_data('regulars', callback)
|
||||||
|
-- end)
|
||||||
|
Public.events = {on_server_started = script.generate_event_name()}
|
||||||
|
|
||||||
|
--- Sends a message to the linked discord channel. The message is sanitized of markdown server side.
|
||||||
|
-- @param message<string> message to send.
|
||||||
|
-- @usage
|
||||||
|
-- local Server = require 'features.server'
|
||||||
|
-- Server.to_discord('Hello from scenario script!')
|
||||||
|
function Public.to_discord(message)
|
||||||
|
raw_print(discord_tag .. message)
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Sends a message to the linked discord channel. The message is not sanitized of markdown.
|
||||||
|
-- @param message<string> message to send.
|
||||||
|
function Public.to_discord_raw(message)
|
||||||
|
raw_print(discord_raw_tag .. message)
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Sends a message to the linked discord channel. The message is sanitized of markdown server side, then made bold.
|
||||||
|
-- @param message<string> message to send.
|
||||||
|
function Public.to_discord_bold(message)
|
||||||
|
raw_print(discord_bold_tag .. message)
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Sends a message to the linked admin discord channel. The message is sanitized of markdown server side.
|
||||||
|
-- @param message<string> message to send.
|
||||||
|
function Public.to_admin(message)
|
||||||
|
raw_print(discord_admin_tag .. message)
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Sends a message to the linked admin discord channel. The message is not sanitized of markdown.
|
||||||
|
-- @param message<string> message to send.
|
||||||
|
function Public.to_admin_raw(message)
|
||||||
|
raw_print(discord_admin_raw_tag .. message)
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Sends a embed message to the linked discord channel. The message is sanitized of markdown server side.
|
||||||
|
-- @param message<string> the content of the embed.
|
||||||
|
function Public.to_discord_embed(message)
|
||||||
|
raw_print(discord_embed_tag .. message)
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Sends a embed message to the linked discord channel. The message is not sanitized of markdown.
|
||||||
|
-- @param message<string> the content of the embed.
|
||||||
|
function Public.to_discord_embed_raw(message)
|
||||||
|
raw_print(discord_embed_raw_tag .. message)
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Sends a embed message to the linked admin discord channel. The message is sanitized of markdown server side.
|
||||||
|
-- @param message<string> the content of the embed.
|
||||||
|
function Public.to_admin_embed(message)
|
||||||
|
raw_print(discord_admin_embed_tag .. message)
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Sends a embed message to the linked admin discord channel. The message is not sanitized of markdown.
|
||||||
|
-- @param message<string> the content of the embed.
|
||||||
|
function Public.to_admin_embed_raw(message)
|
||||||
|
raw_print(discord_admin_embed_raw_tag .. message)
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Stops and saves the factorio server and starts the named scenario.
|
||||||
|
-- @param scenario_name<string> The name of the scenario as appears in the scenario table on http://redmew.com/admin
|
||||||
|
-- @usage
|
||||||
|
-- local Server = require 'features.server'
|
||||||
|
-- Server.start_scenario('my_scenario_name')
|
||||||
|
function Public.start_scenario(scenario_name)
|
||||||
|
if type(scenario_name) ~= 'string' then
|
||||||
|
game.print('start_scenario - scenario_name ' .. tostring(scenario_name) .. ' must be a string.')
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local message = start_scenario_tag .. scenario_name
|
||||||
|
|
||||||
|
raw_print(message)
|
||||||
|
end
|
||||||
|
|
||||||
|
local default_ping_token =
|
||||||
|
Token.register(
|
||||||
|
function(sent_tick)
|
||||||
|
local now = game.tick
|
||||||
|
local diff = now - sent_tick
|
||||||
|
|
||||||
|
local message = table.concat({'Pong in ', diff, ' tick(s) ', 'sent tick: ', sent_tick, ' received tick: ', now})
|
||||||
|
game.print(message)
|
||||||
|
end
|
||||||
|
)
|
||||||
|
|
||||||
|
--- Pings the web server.
|
||||||
|
-- @param func_token<token> The function that is called when the web server replies.
|
||||||
|
-- The function is passed the tick that the ping was sent.
|
||||||
|
function Public.ping(func_token)
|
||||||
|
local message = table.concat({ping_tag, func_token or default_ping_token, ' ', game.tick})
|
||||||
|
raw_print(message)
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Sets the web server's persistent data storage. If you pass nil for the value removes the data.
|
||||||
|
-- Data set this will by synced in with other server if they choose to.
|
||||||
|
-- There can only be one key for each data_set.
|
||||||
|
-- @param data_set<string>
|
||||||
|
-- @param key<string>
|
||||||
|
-- @param value<nil|boolean|number|string|table> Any type that is not a function. set to nil to remove the data.
|
||||||
|
-- @usage
|
||||||
|
-- local Server = require 'features.server'
|
||||||
|
-- Server.set_data('my data set', 'key 1', 123)
|
||||||
|
-- Server.set_data('my data set', 'key 2', 'abc')
|
||||||
|
-- Server.set_data('my data set', 'key 3', {'some', 'data', ['is_set'] = true})
|
||||||
|
--
|
||||||
|
-- Server.set_data('my data set', 'key 1', nil) -- this will remove 'key 1'
|
||||||
|
-- Server.set_data('my data set', 'key 2', 'def') -- this will change the value for 'key 2' to 'def'
|
||||||
|
function Public.set_data(data_set, key, value)
|
||||||
|
if type(data_set) ~= 'string' then
|
||||||
|
error('data_set must be a string')
|
||||||
|
end
|
||||||
|
if type(key) ~= 'string' then
|
||||||
|
error('key must be a string')
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Excessive escaping because the data is serialized twice.
|
||||||
|
data_set = data_set:gsub('\\', '\\\\\\\\'):gsub('"', '\\\\\\"')
|
||||||
|
key = key:gsub('\\', '\\\\\\\\'):gsub('"', '\\\\\\"')
|
||||||
|
|
||||||
|
local message
|
||||||
|
local vt = type(value)
|
||||||
|
if vt == 'nil' then
|
||||||
|
message = table.concat({data_set_tag, '{data_set:"', data_set, '",key:"', key, '"}'})
|
||||||
|
elseif vt == 'string' then
|
||||||
|
-- Excessive escaping because the data is serialized twice.
|
||||||
|
value = value:gsub('\\', '\\\\\\\\'):gsub('"', '\\\\\\"')
|
||||||
|
|
||||||
|
message = table.concat({data_set_tag, '{data_set:"', data_set, '",key:"', key, '",value:"\\"', value, '\\""}'})
|
||||||
|
elseif vt == 'number' then
|
||||||
|
message = table.concat({data_set_tag, '{data_set:"', data_set, '",key:"', key, '",value:"', value, '"}'})
|
||||||
|
elseif vt == 'boolean' then
|
||||||
|
message =
|
||||||
|
table.concat({data_set_tag, '{data_set:"', data_set, '",key:"', key, '",value:"', tostring(value), '"}'})
|
||||||
|
elseif vt == 'function' then
|
||||||
|
error('value cannot be a function')
|
||||||
|
else -- table
|
||||||
|
value = serpent.line(value)
|
||||||
|
|
||||||
|
-- Less escaping than the string case as serpent provides one level of escaping.
|
||||||
|
-- Need to escape single quotes as serpent uses double quotes for strings.
|
||||||
|
value = value:gsub('\\', '\\\\'):gsub("'", "\\'")
|
||||||
|
|
||||||
|
message = table.concat({data_set_tag, '{data_set:"', data_set, '",key:"', key, "\",value:'", value, "'}"})
|
||||||
|
end
|
||||||
|
|
||||||
|
raw_print(message)
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Gets data from the web server's persistent data storage.
|
||||||
|
-- The callback is passed a table {data_set: string, key: string, value: any}.
|
||||||
|
-- If the value is nil, it means there is no stored data for that data_set key pair.
|
||||||
|
-- @param data_set<string>
|
||||||
|
-- @param key<string>
|
||||||
|
-- @param callback_token<token>
|
||||||
|
-- @usage
|
||||||
|
-- local Server = require 'features.server'
|
||||||
|
-- local Token = require 'utils.global_token'
|
||||||
|
--
|
||||||
|
-- local callback =
|
||||||
|
-- Token.register(
|
||||||
|
-- function(data)
|
||||||
|
-- local data_set = data.data_set
|
||||||
|
-- local key = data.key
|
||||||
|
-- local value = data.value -- will be nil if no data
|
||||||
|
--
|
||||||
|
-- game.print(data_set .. ':' .. key .. ':' .. tostring(value))
|
||||||
|
-- end
|
||||||
|
-- )
|
||||||
|
--
|
||||||
|
-- Server.try_get_data('my data set', 'key 1', callback)
|
||||||
|
function Public.try_get_data(data_set, key, callback_token)
|
||||||
|
if type(data_set) ~= 'string' then
|
||||||
|
error('data_set must be a string')
|
||||||
|
end
|
||||||
|
if type(key) ~= 'string' then
|
||||||
|
error('key must be a string')
|
||||||
|
end
|
||||||
|
if type(callback_token) ~= 'number' then
|
||||||
|
error('callback_token must be a number')
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Excessive escaping because the data is serialized twice.
|
||||||
|
data_set = data_set:gsub('\\', '\\\\\\\\'):gsub('"', '\\\\\\"')
|
||||||
|
key = key:gsub('\\', '\\\\\\\\'):gsub('"', '\\\\\\"')
|
||||||
|
|
||||||
|
local message = table.concat {data_get_tag, callback_token, ' {', 'data_set:"', data_set, '",key:"', key, '"}'}
|
||||||
|
raw_print(message)
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Gets all the data for the data_set from the web server's persistent data storage.
|
||||||
|
-- The callback is passed a table {data_set: string, entries: {dictionary key -> value}}.
|
||||||
|
-- If there is no data stored for the data_set entries will be nil.
|
||||||
|
-- @param data_set<string>
|
||||||
|
-- @param callback_token<token>
|
||||||
|
-- @usage
|
||||||
|
-- local Server = require 'features.server'
|
||||||
|
-- local Token = require 'utils.global_token'
|
||||||
|
--
|
||||||
|
-- local callback =
|
||||||
|
-- Token.register(
|
||||||
|
-- function(data)
|
||||||
|
-- local data_set = data.data_set
|
||||||
|
-- local entries = data.entries -- will be nil if no data
|
||||||
|
-- local value2 = entries['key 2']
|
||||||
|
-- local value3 = entries['key 3']
|
||||||
|
-- end
|
||||||
|
-- )
|
||||||
|
--
|
||||||
|
-- Server.try_get_all_data('my data set', callback)
|
||||||
|
function Public.try_get_all_data(data_set, callback_token)
|
||||||
|
if type(data_set) ~= 'string' then
|
||||||
|
error('data_set must be a string')
|
||||||
|
end
|
||||||
|
if type(callback_token) ~= 'number' then
|
||||||
|
error('callback_token must be a number')
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Excessive escaping because the data is serialized twice.
|
||||||
|
data_set = data_set:gsub('\\', '\\\\\\\\'):gsub('"', '\\\\\\"')
|
||||||
|
|
||||||
|
local message = table.concat {data_get_all_tag, callback_token, ' {', 'data_set:"', data_set, '"}'}
|
||||||
|
raw_print(message)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function data_set_changed(data)
|
||||||
|
local handlers = data_set_handlers[data.data_set]
|
||||||
|
if handlers == nil then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if _DEBUG then
|
||||||
|
for _, handler in ipairs(handlers) do
|
||||||
|
local success, err = pcall(handler, data)
|
||||||
|
if not success then
|
||||||
|
log(err)
|
||||||
|
error(err)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
for _, handler in ipairs(handlers) do
|
||||||
|
local success, err = pcall(handler, data)
|
||||||
|
if not success then
|
||||||
|
log(err)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Register a handler to be called when the data_set changes.
|
||||||
|
-- The handler is passed a table {data_set:string, key:string, value:any}
|
||||||
|
-- If value is nil that means the key was removed.
|
||||||
|
-- The handler may be called even if the value hasn't changed. It's up to the implementer
|
||||||
|
-- to determine if the value has changed, or not care.
|
||||||
|
-- To prevent desyncs the same handlers must be registered for all clients. The easiest way to do this
|
||||||
|
-- is in the control stage, i.e before on_init or on_load would be called.
|
||||||
|
-- @param data_set<string>
|
||||||
|
-- @param handler<function>
|
||||||
|
-- @usage
|
||||||
|
-- local Server = require 'features.server'
|
||||||
|
-- Server.on_data_set_changed(
|
||||||
|
-- 'my data set',
|
||||||
|
-- function(data)
|
||||||
|
-- local data_set = data.data_set
|
||||||
|
-- local key = data.key
|
||||||
|
-- local value = data.value -- will be nil if data was removed.
|
||||||
|
-- end
|
||||||
|
-- )
|
||||||
|
function Public.on_data_set_changed(data_set, handler)
|
||||||
|
if type(data_set) ~= 'string' then
|
||||||
|
error('data_set must be a string')
|
||||||
|
end
|
||||||
|
|
||||||
|
local handlers = data_set_handlers[data_set]
|
||||||
|
if handlers == nil then
|
||||||
|
handlers = {handler}
|
||||||
|
data_set_handlers[data_set] = handlers
|
||||||
|
else
|
||||||
|
table.insert(handlers, handler)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Called by the web server to notify the client that a data_set has changed.
|
||||||
|
Public.raise_data_set = data_set_changed
|
||||||
|
|
||||||
|
--- Called by the web server to determine which data_sets are being tracked.
|
||||||
|
function Public.get_tracked_data_sets()
|
||||||
|
local message = {data_tracked_tag, '['}
|
||||||
|
|
||||||
|
for k, _ in pairs(data_set_handlers) do
|
||||||
|
-- Excessive escaping because the data is serialized twice.
|
||||||
|
k = k:gsub('\\', '\\\\\\\\'):gsub('"', '\\\\\\"')
|
||||||
|
|
||||||
|
table.insert(message, '"')
|
||||||
|
table.insert(message, k)
|
||||||
|
table.insert(message, '"')
|
||||||
|
table.insert(message, ',')
|
||||||
|
end
|
||||||
|
|
||||||
|
if message[#message] == ',' then
|
||||||
|
table.remove(message)
|
||||||
|
end
|
||||||
|
|
||||||
|
table.insert(message, ']')
|
||||||
|
|
||||||
|
message = table.concat(message)
|
||||||
|
raw_print(message)
|
||||||
|
end
|
||||||
|
|
||||||
|
return Public
|
28
features/server_commands.lua
Normal file
28
features/server_commands.lua
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
local Poll = require 'features.gui.poll'
|
||||||
|
local UserGroups = require 'features.user_groups'
|
||||||
|
local Token = require 'utils.global_token'
|
||||||
|
local Server = require 'features.server'
|
||||||
|
|
||||||
|
--- This module is for the web server to call functions and raise events.
|
||||||
|
-- Not intended to be called by scripts.
|
||||||
|
-- Needs to be in the _G table so it can be accessed by the web server.
|
||||||
|
ServerCommands = {}
|
||||||
|
|
||||||
|
ServerCommands.get_poll_result = Poll.send_poll_result_to_discord
|
||||||
|
|
||||||
|
ServerCommands.regular_sync = UserGroups.sync_regulars
|
||||||
|
ServerCommands.donator_sync = UserGroups.sync_donators
|
||||||
|
|
||||||
|
function ServerCommands.raise_callback(func_token, data)
|
||||||
|
local func = Token.get(func_token)
|
||||||
|
func(data)
|
||||||
|
end
|
||||||
|
|
||||||
|
ServerCommands.raise_data_set = Server.raise_data_set
|
||||||
|
ServerCommands.get_tracked_data_sets = Server.get_tracked_data_sets
|
||||||
|
|
||||||
|
function ServerCommands.server_started()
|
||||||
|
script.raise_event(Server.events.on_server_started, {})
|
||||||
|
end
|
||||||
|
|
||||||
|
return ServerCommands
|
@ -1,159 +0,0 @@
|
|||||||
require 'utils.list_utils'
|
|
||||||
local Game = require 'utils.game'
|
|
||||||
local Event = require 'utils.event'
|
|
||||||
local naming_words = require 'resources.naming_words'
|
|
||||||
local Utils = require('utils.utils')
|
|
||||||
global.actual_name = {}
|
|
||||||
global.silly_names = {}
|
|
||||||
global.silly_names.count = 0
|
|
||||||
|
|
||||||
local name_combinations = #naming_words.adverbs * #naming_words.adjectives * #naming_words.nouns
|
|
||||||
|
|
||||||
--- Creates name by combining elements from the passed table
|
|
||||||
-- @param1 table including adverbs, adjectives, and nouns
|
|
||||||
-- @returns name as a string
|
|
||||||
local function create_name(words_table)
|
|
||||||
local adverb, adjective, noun
|
|
||||||
adverb = table.get_random(words_table.adverbs)
|
|
||||||
adjective = table.get_random(words_table.adjectives)
|
|
||||||
noun = table.get_random(words_table.nouns)
|
|
||||||
return adverb .. '_' .. adjective .. '_' .. noun
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Calls create_name until a unique name is returned
|
|
||||||
-- @param1 table including adverbs, adjectives, and nouns
|
|
||||||
-- @returns name as a string
|
|
||||||
local function create_unique_name(words_table)
|
|
||||||
local silly_names = global.silly_names
|
|
||||||
local name = create_name(words_table)
|
|
||||||
|
|
||||||
while table.contains(silly_names, name) do
|
|
||||||
name = create_name(words_table)
|
|
||||||
end
|
|
||||||
return name
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Assigns a player a name, stores their old and silly names
|
|
||||||
-- @param1 Takes a LuaPlayer
|
|
||||||
local function name_player(player)
|
|
||||||
-- Store a player's original name in case they want it back.
|
|
||||||
if not global.actual_name[player.index] then
|
|
||||||
global.actual_name[player.index] = player.name
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Because create_unique_name enters a while loop looking for a unique name, ensure we never get stuck.
|
|
||||||
local ceiling = math.min(name_combinations * 0.25, 10000)
|
|
||||||
if global.silly_names.count > ceiling then
|
|
||||||
global.silly_names = {}
|
|
||||||
global.silly_names.count = 0
|
|
||||||
end
|
|
||||||
|
|
||||||
local name = create_unique_name(naming_words)
|
|
||||||
|
|
||||||
table.insert(global.silly_names, name)
|
|
||||||
global.silly_names.count = global.silly_names.count + 1
|
|
||||||
local str = player.name .. ' will now be known as: ' .. name
|
|
||||||
game.print(str)
|
|
||||||
Utils.print_admins(str .. ' (ID: ' .. player.index .. ')', false)
|
|
||||||
player.name = name
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Restores a player's actual name
|
|
||||||
local function restore_name(cmd)
|
|
||||||
local player = Game.get_player_by_index(cmd.player_index)
|
|
||||||
player.name = global.actual_name[player.index]
|
|
||||||
player.print('Your true name has been restored.')
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Passes _event_ on to name_players
|
|
||||||
local function name_player_event(event)
|
|
||||||
local player = Game.get_player_by_index(event.player_index)
|
|
||||||
name_player(player)
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Passes target or player on to name_players
|
|
||||||
local function name_player_command(cmd)
|
|
||||||
local player = game.player
|
|
||||||
local param = cmd.parameter
|
|
||||||
local target
|
|
||||||
|
|
||||||
if param then
|
|
||||||
target = game.players[param]
|
|
||||||
if player and not player.admin then
|
|
||||||
-- Yes param, yes player, no admin/server = fail, non-admins, non-server cannot use command on others
|
|
||||||
Game.player_print("Sorry you don't have permission to use the roll-name command on other players.")
|
|
||||||
return
|
|
||||||
else
|
|
||||||
-- Yes param, yes admin/server = check target
|
|
||||||
if target then
|
|
||||||
-- Yes param, yes admin/server, yes target = change name
|
|
||||||
name_player(target)
|
|
||||||
return
|
|
||||||
else
|
|
||||||
-- Yes param, yes admin/server, no target = fail, wrong player name
|
|
||||||
Game.player_print(table.concat {"Sorry, player '", param, "' was not found."})
|
|
||||||
return
|
|
||||||
end
|
|
||||||
end
|
|
||||||
else
|
|
||||||
-- No param = check if server
|
|
||||||
if not player then
|
|
||||||
-- No param, no player = server trying to change its name
|
|
||||||
Game.player_print('The server cannot change its name')
|
|
||||||
return
|
|
||||||
end
|
|
||||||
-- No param, not server = change self name
|
|
||||||
name_player(player)
|
|
||||||
return
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Prints the original name of the target
|
|
||||||
local function check_name(cmd)
|
|
||||||
local current_name = cmd.parameter
|
|
||||||
if not current_name then
|
|
||||||
Game.player_print('Usage: /name-check <player>')
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
local target = game.players[current_name]
|
|
||||||
if not target then
|
|
||||||
Game.player_print('player ' .. current_name .. ' not found')
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
local actual_name = global.actual_name[target.index]
|
|
||||||
Game.player_print(target.name .. ' is actually: ' .. actual_name)
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Prints the index of the target
|
|
||||||
local function get_player_id(cmd)
|
|
||||||
local player = game.player
|
|
||||||
-- Check if the player can run the command
|
|
||||||
if player and not player.admin then
|
|
||||||
Utils.cant_run(cmd.name)
|
|
||||||
return
|
|
||||||
end
|
|
||||||
-- Check if the target is valid
|
|
||||||
local target_name = cmd['parameter']
|
|
||||||
if not target_name then
|
|
||||||
Game.player_print('Usage: /get-player-id <player>')
|
|
||||||
return
|
|
||||||
end
|
|
||||||
local target_index = game.players[target_name].index
|
|
||||||
Game.player_print(target_name .. ' -- ' .. target_index)
|
|
||||||
end
|
|
||||||
|
|
||||||
if global.scenario.config.players_assigned_names == true then
|
|
||||||
Event.add(defines.events.on_player_created, name_player_event)
|
|
||||||
end
|
|
||||||
|
|
||||||
if global.scenario.config.players_roll_names == true then
|
|
||||||
commands.add_command('name-roll', 'Assigns you a random, silly name', name_player_command)
|
|
||||||
end
|
|
||||||
|
|
||||||
if global.scenario.config.players_roll_names == true or global.scenario.config.players_assigned_names == true then
|
|
||||||
commands.add_command('name-restore', 'Removes your fun name and gives you back your actual name', restore_name)
|
|
||||||
commands.add_command('name-check', '<player> Check the original name of a player', check_name)
|
|
||||||
commands.add_command('get-player-id', 'Gets the ID of a player (Admin only)', get_player_id)
|
|
||||||
end
|
|
@ -1,62 +1,63 @@
|
|||||||
global.regulars = require 'resources.regulars'
|
|
||||||
local Donators = require 'resources.donators'
|
|
||||||
global.donators = Donators.donators
|
|
||||||
local Event = require 'utils.event'
|
local Event = require 'utils.event'
|
||||||
local Utils = require 'utils.utils'
|
local Utils = require 'utils.utils'
|
||||||
|
local Server = require 'features.server'
|
||||||
|
local Donators = require 'resources.donators'
|
||||||
local Game = require 'utils.game'
|
local Game = require 'utils.game'
|
||||||
|
local Token = require 'utils.global_token'
|
||||||
|
|
||||||
|
global.regulars = {}
|
||||||
|
global.donators = Donators.donators
|
||||||
|
|
||||||
local Module = {}
|
local Module = {}
|
||||||
|
|
||||||
local function update_file()
|
|
||||||
local data = {'{\n'}
|
|
||||||
for player_name, _ in pairs(global.regulars) do
|
|
||||||
table.insert(data, "['")
|
|
||||||
table.insert(data, player_name)
|
|
||||||
table.insert(data, "''] = true,\n")
|
|
||||||
end
|
|
||||||
table.insert(data, '}')
|
|
||||||
|
|
||||||
game.write_file('regulars.lua', table.concat(data), false, 0)
|
|
||||||
end
|
|
||||||
|
|
||||||
Module.is_regular =
|
Module.is_regular =
|
||||||
function(player_name)
|
function(player_name)
|
||||||
return Utils.cast_bool(global.regulars[player_name] or global.regulars[player_name:lower()]) --to make it backwards compatible
|
return Utils.cast_bool(global.regulars[player_name] or global.regulars[player_name:lower()]) --to make it backwards compatible
|
||||||
end
|
end
|
||||||
|
|
||||||
Module.add_regular = function(player_name)
|
Module.add_regular = function(player_name)
|
||||||
local actor = Utils.get_actor()
|
local actor = Utils.get_actor()
|
||||||
if Module.is_regular(player_name) then
|
|
||||||
|
if (Module.is_regular(player_name)) then
|
||||||
Game.player_print(player_name .. ' is already a regular.')
|
Game.player_print(player_name .. ' is already a regular.')
|
||||||
else
|
else
|
||||||
if game.players[player_name] then
|
global.regulars[player_name] = true
|
||||||
player_name = game.players[player_name].name
|
Server.set_data('regulars', player_name, true)
|
||||||
game.print(actor .. ' promoted ' .. player_name .. ' to regular.')
|
game.print(actor .. ' promoted ' .. player_name .. ' to regular.')
|
||||||
global.regulars[player_name] = true
|
|
||||||
update_file()
|
|
||||||
else
|
|
||||||
Game.player_print(player_name .. ' does not exist.')
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
Module.remove_regular =
|
Module.remove_regular = function(player_name)
|
||||||
function(player_name)
|
|
||||||
local actor = Utils.get_actor()
|
local actor = Utils.get_actor()
|
||||||
if game.players[player_name] then
|
|
||||||
player_name = game.players[player_name].name
|
if (Module.is_regular(player_name)) then
|
||||||
if Module.is_regular(player_name) then
|
|
||||||
game.print(player_name .. ' was demoted from regular by ' .. actor .. '.')
|
|
||||||
end
|
|
||||||
global.regulars[player_name] = nil
|
global.regulars[player_name] = nil
|
||||||
global.regulars[player_name:lower()] = nil --backwards compatible
|
Server.set_data('regulars', player_name, nil)
|
||||||
update_file()
|
game.print(player_name .. ' was demoted from regular by ' .. actor .. '.')
|
||||||
|
else
|
||||||
|
Game.player_print(player_name .. ' is not a regular.')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local sync_regulars_callback =
|
||||||
|
Token.register(
|
||||||
|
function(data)
|
||||||
|
global.regulars = data.entries or {}
|
||||||
|
end
|
||||||
|
)
|
||||||
|
|
||||||
|
function Module.sync_regulars()
|
||||||
|
Server.try_get_all_data('regulars', sync_regulars_callback)
|
||||||
|
end
|
||||||
|
|
||||||
Module.print_regulars = function()
|
Module.print_regulars = function()
|
||||||
|
local result = {}
|
||||||
for k, _ in pairs(global.regulars) do
|
for k, _ in pairs(global.regulars) do
|
||||||
Game.player_print(k)
|
table.insert(result, k)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
result = table.concat(result, ', ')
|
||||||
|
Game.player_print(result)
|
||||||
end
|
end
|
||||||
|
|
||||||
function Module.get_rank(player)
|
function Module.get_rank(player)
|
||||||
@ -70,7 +71,7 @@ function Module.get_rank(player)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function Module.is_donator(player_name)
|
function Module.is_donator(player_name)
|
||||||
return global.donators[player_name]
|
return global.donators[player_name] ~= nil
|
||||||
end
|
end
|
||||||
|
|
||||||
function Module.player_has_donator_perk(player_name, perk_flag)
|
function Module.player_has_donator_perk(player_name, perk_flag)
|
||||||
@ -79,19 +80,84 @@ function Module.player_has_donator_perk(player_name, perk_flag)
|
|||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
return bit32.band(d, perk_flag) == perk_flag
|
local flags = d.perk_flags
|
||||||
|
if not flags then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
return bit32.band(flags, perk_flag) == perk_flag
|
||||||
|
end
|
||||||
|
|
||||||
|
function Module.get_donator_welcome_message(player_name)
|
||||||
|
local d = global.donators[player_name]
|
||||||
|
if not d then
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
return d.welcome_messages
|
||||||
|
end
|
||||||
|
|
||||||
|
function Module.set_donator(player_name, data)
|
||||||
|
global.donators[player_name] = data
|
||||||
|
Server.set_data('donators', player_name, data)
|
||||||
|
end
|
||||||
|
|
||||||
|
local sync_donators_callback =
|
||||||
|
Token.register(
|
||||||
|
function(data)
|
||||||
|
global.donators = data.entries or {}
|
||||||
|
end
|
||||||
|
)
|
||||||
|
|
||||||
|
function Module.sync_donators()
|
||||||
|
Server.try_get_all_data('donators', sync_donators_callback)
|
||||||
|
end
|
||||||
|
|
||||||
|
function Module.print_donators()
|
||||||
|
local result = {}
|
||||||
|
|
||||||
|
for k, _ in pairs(global.donators) do
|
||||||
|
table.insert(result, k)
|
||||||
|
end
|
||||||
|
|
||||||
|
result = table.concat(result, ', ')
|
||||||
|
Game.player_print(result)
|
||||||
end
|
end
|
||||||
|
|
||||||
Event.add(
|
Event.add(
|
||||||
defines.events.on_player_joined_game,
|
defines.events.on_player_joined_game,
|
||||||
function(event)
|
function(event)
|
||||||
local correctCaseName = Game.get_player_by_index(event.player_index).name
|
local correctCaseName = Game.get_player_by_index(event.player_index).name
|
||||||
if global.regulars[correctCaseName:lower()] and not global.regulars[correctCaseName] then
|
local lowerCaseName = correctCaseName:lower()
|
||||||
global.regulars[correctCaseName:lower()] = nil
|
if correctCaseName ~= lowerCaseName and global.regulars[lowerCaseName] then
|
||||||
|
global.regulars[lowerCaseName] = nil
|
||||||
global.regulars[correctCaseName] = true
|
global.regulars[correctCaseName] = true
|
||||||
update_file()
|
Server.set_data('regulars', lowerCaseName, nil)
|
||||||
|
Server.set_data('regulars', correctCaseName, true)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
)
|
)
|
||||||
|
|
||||||
|
Event.add(
|
||||||
|
Server.events.on_server_started,
|
||||||
|
function()
|
||||||
|
Module.sync_regulars()
|
||||||
|
Module.sync_donators()
|
||||||
|
end
|
||||||
|
)
|
||||||
|
|
||||||
|
Server.on_data_set_changed(
|
||||||
|
'regulars',
|
||||||
|
function(data)
|
||||||
|
global.regulars[data.key] = data.value
|
||||||
|
end
|
||||||
|
)
|
||||||
|
|
||||||
|
Server.on_data_set_changed(
|
||||||
|
'donators',
|
||||||
|
function(data)
|
||||||
|
global.donators[data.key] = data.value
|
||||||
|
end
|
||||||
|
)
|
||||||
|
|
||||||
return Module
|
return Module
|
||||||
|
@ -11,6 +11,9 @@ local Config = {
|
|||||||
|
|
||||||
-- initial starting position size, higher values are not recommended
|
-- initial starting position size, higher values are not recommended
|
||||||
starting_size = 8,
|
starting_size = 8,
|
||||||
|
|
||||||
|
-- where the market should spawn
|
||||||
|
market_spawn_position = {x = 0, y = 3},
|
||||||
},
|
},
|
||||||
|
|
||||||
-- controls the Daylight (Default diggy: enabled = true)
|
-- controls the Daylight (Default diggy: enabled = true)
|
||||||
@ -34,7 +37,7 @@ local Config = {
|
|||||||
manual_mining_speed_modifier = 1000,
|
manual_mining_speed_modifier = 1000,
|
||||||
|
|
||||||
-- increase the amount of inventory slots for the player force
|
-- increase the amount of inventory slots for the player force
|
||||||
character_inventory_slots_bonus = 1000,
|
character_inventory_slots_bonus = 0,
|
||||||
|
|
||||||
-- increases the run speed of all characters for the player force
|
-- increases the run speed of all characters for the player force
|
||||||
character_running_speed_modifier = 2,
|
character_running_speed_modifier = 2,
|
||||||
@ -43,7 +46,7 @@ local Config = {
|
|||||||
character_health_bonus = 1000000,
|
character_health_bonus = 1000000,
|
||||||
|
|
||||||
-- unlock all research by default, only useful when testing
|
-- unlock all research by default, only useful when testing
|
||||||
unlock_all_research = false,
|
unlock_all_research = true,
|
||||||
|
|
||||||
-- adds additional items to the player force when starting in addition to defined in start_items above
|
-- adds additional items to the player force when starting in addition to defined in start_items above
|
||||||
starting_items = {
|
starting_items = {
|
||||||
@ -114,9 +117,9 @@ local Config = {
|
|||||||
['refined-concrete'] = 0.06,
|
['refined-concrete'] = 0.06,
|
||||||
},
|
},
|
||||||
cracking_sounds = {
|
cracking_sounds = {
|
||||||
'CRACK',
|
'CRACK',
|
||||||
'KRRRR',
|
'KRRRR',
|
||||||
'R U N',
|
'R U N',
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -338,58 +341,6 @@ local Config = {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
-- controls the market and buffs
|
|
||||||
MarketExchange = {
|
|
||||||
enabled = true,
|
|
||||||
|
|
||||||
-- percentage * mining productivity level gets added to mining speed
|
|
||||||
mining_speed_productivity_multiplier = 5,
|
|
||||||
|
|
||||||
-- market config
|
|
||||||
market_spawn_position = {x = 0, y = 3},
|
|
||||||
currency_item = 'coin',
|
|
||||||
|
|
||||||
-- add or remove a table entry to add or remove a unlockable item from the mall.
|
|
||||||
-- format: {unlock_at_level, price, prototype_name},
|
|
||||||
-- alternative format: {level = 32, price = {{"stone", 2500}, {"coin", 100}}, name = 'power-armor'},
|
|
||||||
unlockables = require('map_gen.Diggy.FormatMarketItems').initialize_unlockables(
|
|
||||||
{
|
|
||||||
{level = 1, price = 5, name = 'iron-axe'},
|
|
||||||
{level = 2, price = 5, name = 'raw-wood'},
|
|
||||||
{level = 3, price = 20, name = 'pistol'},
|
|
||||||
{level = 3, price = 2, name = 'firearm-magazine'},
|
|
||||||
{level = 5, price = 2, name = 'stone-brick'},
|
|
||||||
{level = 6, price = 6, name = 'small-lamp'},
|
|
||||||
{level = 6, price = 5, name = 'raw-fish'},
|
|
||||||
{level = 8, price = 10, name = 'stone-wall'},
|
|
||||||
{level = 10, price = 85, name = 'shotgun'},
|
|
||||||
{level = 10, price = 2, name = 'shotgun-shell'},
|
|
||||||
{level = 13, price = 25, name = 'steel-axe'},
|
|
||||||
{level = 13, price = 50, name = 'light-armor'},
|
|
||||||
{level = 15, price = 85, name = 'submachine-gun'},
|
|
||||||
{level = 18, price = 8, name = 'piercing-rounds-magazine'},
|
|
||||||
{level = 18, price = 8, name = 'piercing-shotgun-shell'},
|
|
||||||
{level = 20, price = 100, name = 'heavy-armor'},
|
|
||||||
{level = 25, price = 250, name = 'modular-armor'},
|
|
||||||
{level = 25, price = 100, name = 'landfill'},
|
|
||||||
{level = 28, price = 250, name = 'personal-roboport-equipment'},
|
|
||||||
{level = 28, price = 75, name = 'construction-robot'},
|
|
||||||
{level = 32, price = 850, name = 'power-armor'},
|
|
||||||
{level = 34, price = 100, name = 'battery-equipment'},
|
|
||||||
{level = 33, price = 1000, name = 'fusion-reactor-equipment'},
|
|
||||||
{level = 36, price = 150, name = 'energy-shield-equipment'},
|
|
||||||
{level = 42, price = 650, name = 'combat-shotgun'},
|
|
||||||
{level = 46, price = 25, name = 'uranium-rounds-magazine'},
|
|
||||||
{level = 58, price = 250, name = 'rocket-launcher'},
|
|
||||||
{level = 58, price = 40, name = 'rocket'},
|
|
||||||
{level = 66, price = 80, name = 'explosive-rocket'},
|
|
||||||
{level = 73, price = 2000, name = 'satellite'},
|
|
||||||
{level = 100, price = 1, name = 'iron-stick'},
|
|
||||||
}
|
|
||||||
),
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
--Tracks players causing collapses
|
--Tracks players causing collapses
|
||||||
Antigrief = {
|
Antigrief = {
|
||||||
enabled = true,
|
enabled = true,
|
||||||
@ -423,10 +374,47 @@ local Config = {
|
|||||||
['death-penalty'] = 0.002, -- XP deduct in percentage of total experience when a player dies (Diggy default: 0.002 which equals 0.2%)
|
['death-penalty'] = 0.002, -- XP deduct in percentage of total experience when a player dies (Diggy default: 0.002 which equals 0.2%)
|
||||||
},
|
},
|
||||||
|
|
||||||
buffs = { --Define new buffs here, they are handed out for each level.
|
buffs = {
|
||||||
['mining_speed'] = {value = 5},
|
-- define new buffs here, they are handed out for each level
|
||||||
['inventory_slot'] = {value = 1},
|
mining_speed = {value = 5},
|
||||||
['health_bonus'] = {value = 2.5, double_level = 5}, -- double_level is the level interval for receiving a double bonus (Diggy default: 5 which equals every 5th level)
|
inventory_slot = {value = 1},
|
||||||
|
-- double_level is the level interval for receiving a double bonus (Diggy default: 5 which equals every 5th level)
|
||||||
|
health_bonus = {value = 2.5, double_level = 5},
|
||||||
|
},
|
||||||
|
|
||||||
|
-- add or remove a table entry to add or remove a unlockable item from the market.
|
||||||
|
unlockables = {
|
||||||
|
{level = 1, price = 5, name = 'iron-axe'},
|
||||||
|
{level = 2, price = 5, name = 'raw-wood'},
|
||||||
|
{level = 3, price = 20, name = 'pistol'},
|
||||||
|
{level = 3, price = 2, name = 'firearm-magazine'},
|
||||||
|
{level = 5, price = 2, name = 'stone-brick'},
|
||||||
|
{level = 6, price = 6, name = 'small-lamp'},
|
||||||
|
{level = 6, price = 5, name = 'raw-fish'},
|
||||||
|
{level = 8, price = 10, name = 'stone-wall'},
|
||||||
|
{level = 10, price = 85, name = 'shotgun'},
|
||||||
|
{level = 10, price = 2, name = 'shotgun-shell'},
|
||||||
|
{level = 13, price = 25, name = 'steel-axe'},
|
||||||
|
{level = 13, price = 50, name = 'light-armor'},
|
||||||
|
{level = 15, price = 85, name = 'submachine-gun'},
|
||||||
|
{level = 18, price = 8, name = 'piercing-rounds-magazine'},
|
||||||
|
{level = 18, price = 8, name = 'piercing-shotgun-shell'},
|
||||||
|
{level = 20, price = 100, name = 'heavy-armor'},
|
||||||
|
{level = 25, price = 250, name = 'modular-armor'},
|
||||||
|
{level = 25, price = 100, name = 'landfill'},
|
||||||
|
{level = 28, price = 250, name = 'personal-roboport-equipment'},
|
||||||
|
{level = 28, price = 75, name = 'construction-robot'},
|
||||||
|
{level = 32, price = 850, name = 'power-armor'},
|
||||||
|
{level = 34, price = 100, name = 'battery-equipment'},
|
||||||
|
{level = 33, price = 1000, name = 'fusion-reactor-equipment'},
|
||||||
|
{level = 36, price = 150, name = 'energy-shield-equipment'},
|
||||||
|
{level = 42, price = 650, name = 'combat-shotgun'},
|
||||||
|
{level = 46, price = 25, name = 'uranium-rounds-magazine'},
|
||||||
|
{level = 58, price = 250, name = 'rocket-launcher'},
|
||||||
|
{level = 58, price = 40, name = 'rocket'},
|
||||||
|
{level = 66, price = 80, name = 'explosive-rocket'},
|
||||||
|
{level = 73, price = 2000, name = 'satellite'},
|
||||||
|
{level = 100, price = 1, name = 'iron-stick'},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -4,9 +4,18 @@ local Game = require 'utils.game'
|
|||||||
local Global = require 'utils.global'
|
local Global = require 'utils.global'
|
||||||
local ForceControl = require 'features.force_control'
|
local ForceControl = require 'features.force_control'
|
||||||
local Debug = require 'map_gen.Diggy.Debug'
|
local Debug = require 'map_gen.Diggy.Debug'
|
||||||
|
local Retailer = require 'features.retailer'
|
||||||
|
local Gui = require 'utils.gui'
|
||||||
|
local force_control = require 'features.force_control'
|
||||||
|
local utils = require 'utils.utils'
|
||||||
|
local format = string.format
|
||||||
|
local string_format = string.format
|
||||||
|
local floor = math.floor
|
||||||
|
local log = math.log
|
||||||
|
local insert = table.insert
|
||||||
|
|
||||||
-- Will be registered in Experience.register
|
-- hack
|
||||||
local ForceControl_builder = {}
|
local alien_coin_modifiers = require 'map_gen.Diggy.Config'.features.ArtefactHunting.alien_coin_modifiers
|
||||||
|
|
||||||
-- this
|
-- this
|
||||||
local Experience = {}
|
local Experience = {}
|
||||||
@ -39,15 +48,14 @@ Global.register({
|
|||||||
health_bonus = tbl.health_bonus
|
health_bonus = tbl.health_bonus
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
|
||||||
local config = {}
|
local config = {}
|
||||||
local string_format = string.format
|
|
||||||
local alien_coin_modifiers = require 'map_gen.Diggy.Config'.features.ArtefactHunting.alien_coin_modifiers
|
local gain_xp_color = {r = 144, g = 202, b = 249}
|
||||||
local floor = math.floor
|
local lose_xp_color = {r = 255, g = 0, b = 0}
|
||||||
|
local unlocked_color = {r = 255, g = 255, b = 255}
|
||||||
|
local locked_color = {r = 127, g = 127, b = 127}
|
||||||
|
|
||||||
local level_up_formula = (function (level_reached)
|
local level_up_formula = (function (level_reached)
|
||||||
local floor = math.floor
|
|
||||||
local log = math.log
|
|
||||||
local Config = require 'map_gen.Diggy.Config'.features.Experience
|
local Config = require 'map_gen.Diggy.Config'.features.Experience
|
||||||
local difficulty_scale = floor(Config.difficulty_scale)
|
local difficulty_scale = floor(Config.difficulty_scale)
|
||||||
local level_fine_tune = floor(Config.xp_fine_tune)
|
local level_fine_tune = floor(Config.xp_fine_tune)
|
||||||
@ -72,6 +80,20 @@ local level_up_formula = (function (level_reached)
|
|||||||
return value - lower_value
|
return value - lower_value
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
---Updates the market contents based on the current level.
|
||||||
|
---@param force LuaForce the force which the unlocking requirement should be based of
|
||||||
|
function Experience.update_market_contents(force)
|
||||||
|
local current_level = ForceControl.get_force_data(force).current_level
|
||||||
|
local force_name = force.name
|
||||||
|
for _, prototype in ipairs(config.unlockables) do
|
||||||
|
if (current_level >= prototype.level) then
|
||||||
|
Retailer.set_item(force_name, prototype.name, {coin = prototype.price})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
Retailer.ship_items(force_name)
|
||||||
|
end
|
||||||
|
|
||||||
---Updates a forces manual mining speed modifier. By removing active modifiers and re-adding
|
---Updates a forces manual mining speed modifier. By removing active modifiers and re-adding
|
||||||
---@param force LuaForce the force of which will be updated
|
---@param force LuaForce the force of which will be updated
|
||||||
---@param level_up number a level if updating as part of a level up (optional)
|
---@param level_up number a level if updating as part of a level up (optional)
|
||||||
@ -156,7 +178,7 @@ local function on_player_mined_entity(event)
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
local text = string_format('+%d XP', exp)
|
local text = string_format('+%d XP', exp)
|
||||||
Game.print_player_floating_text_position(player_index, text, {r = 144, g = 202, b = 249},0, -0.5)
|
Game.print_player_floating_text_position(player_index, text, gain_xp_color,0, -0.5)
|
||||||
ForceControl.add_experience(force, exp)
|
ForceControl.add_experience(force, exp)
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -176,7 +198,7 @@ local function on_research_finished(event)
|
|||||||
local text = string_format('Research completed! +%d XP', exp)
|
local text = string_format('Research completed! +%d XP', exp)
|
||||||
for _, p in pairs(game.connected_players) do
|
for _, p in pairs(game.connected_players) do
|
||||||
local player_index = p.index
|
local player_index = p.index
|
||||||
Game.print_player_floating_text_position(player_index, text, {r = 144, g = 202, b = 249}, -1, -0.5)
|
Game.print_player_floating_text_position(player_index, text, gain_xp_color, -1, -0.5)
|
||||||
end
|
end
|
||||||
ForceControl.add_experience(force, exp)
|
ForceControl.add_experience(force, exp)
|
||||||
|
|
||||||
@ -206,7 +228,7 @@ local function on_rocket_launched(event)
|
|||||||
local text = string_format('Rocket launched! +%d XP', exp)
|
local text = string_format('Rocket launched! +%d XP', exp)
|
||||||
for _, p in pairs(game.connected_players) do
|
for _, p in pairs(game.connected_players) do
|
||||||
local player_index = p.index
|
local player_index = p.index
|
||||||
Game.print_player_floating_text_position(player_index, text, {r = 144, g = 202, b = 249},-1, -0.5)
|
Game.print_player_floating_text_position(player_index, text, gain_xp_color,-1, -0.5)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -224,7 +246,7 @@ local function on_entity_died (event)
|
|||||||
if cause and (cause.name == 'artillery-turret' or cause.name == 'gun-turret' or cause.name == 'laser-turret' or cause.name == 'flamethrower-turret') then
|
if cause and (cause.name == 'artillery-turret' or cause.name == 'gun-turret' or cause.name == 'laser-turret' or cause.name == 'flamethrower-turret') then
|
||||||
exp = config.XP['enemy_killed'] * alien_coin_modifiers[entity.name]
|
exp = config.XP['enemy_killed'] * alien_coin_modifiers[entity.name]
|
||||||
local text = string_format('+ %d XP', exp)
|
local text = string_format('+ %d XP', exp)
|
||||||
Game.print_floating_text(cause.surface, cause.position, text, {r = 144, g = 202, b = 249})
|
Game.print_floating_text(cause.surface, cause.position, text, gain_xp_color)
|
||||||
ForceControl.add_experience(force, exp)
|
ForceControl.add_experience(force, exp)
|
||||||
return
|
return
|
||||||
else
|
else
|
||||||
@ -238,9 +260,11 @@ local function on_entity_died (event)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
local text = string_format('+ %d XP', exp)
|
if exp then
|
||||||
Game.print_floating_text(entity.surface, entity.position, text, {r = 144, g = 202, b = 249})
|
local text = string_format('+ %d XP', exp)
|
||||||
ForceControl.add_experience(force, exp)
|
Game.print_floating_text(entity.surface, entity.position, text, gain_xp_color)
|
||||||
|
ForceControl.add_experience(force, exp)
|
||||||
|
end
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -250,7 +274,7 @@ local function on_entity_died (event)
|
|||||||
local exp = config.XP['enemy_killed'] * alien_coin_modifiers[entity.name]
|
local exp = config.XP['enemy_killed'] * alien_coin_modifiers[entity.name]
|
||||||
local text = string_format('+ %d XP', exp)
|
local text = string_format('+ %d XP', exp)
|
||||||
local player_index = cause.player.index
|
local player_index = cause.player.index
|
||||||
Game.print_player_floating_text_position(player_index, text, {r = 144, g = 202, b = 249},-1, -0.5)
|
Game.print_player_floating_text_position(player_index, text, gain_xp_color,-1, -0.5)
|
||||||
ForceControl.add_experience(force, exp)
|
ForceControl.add_experience(force, exp)
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -262,53 +286,232 @@ local function on_player_respawned(event)
|
|||||||
local exp = ForceControl.remove_experience_percentage(force, config.XP['death-penalty'], 50)
|
local exp = ForceControl.remove_experience_percentage(force, config.XP['death-penalty'], 50)
|
||||||
local text = string_format('%s resurrected! -%d XP', player.name, exp)
|
local text = string_format('%s resurrected! -%d XP', player.name, exp)
|
||||||
for _, p in pairs(game.connected_players) do
|
for _, p in pairs(game.connected_players) do
|
||||||
Game.print_player_floating_text_position(p.index, text, {r = 255, g = 0, b = 0},-1, -0.5)
|
Game.print_player_floating_text_position(p.index, text, lose_xp_color, -1, -0.5)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
---Get list of defined buffs
|
|
||||||
---@return table with the same format as in the Diggy Config
|
|
||||||
---@see Diggy.Config.features.Experience.Buffs
|
|
||||||
function Experience.get_buffs()
|
|
||||||
return config.buffs
|
|
||||||
end
|
|
||||||
|
|
||||||
local level_table = {}
|
local level_table = {}
|
||||||
---Get experiment requirement for a given level
|
---Get experiment requirement for a given level
|
||||||
---Primarily used for the market GUI to display total experience required to unlock a specific item
|
---Primarily used for the Experience GUI to display total experience required to unlock a specific item
|
||||||
---@param level number a number specifying the level
|
---@param level number a number specifying the level
|
||||||
---@return number required total experience to reach supplied level
|
---@return number required total experience to reach supplied level
|
||||||
function Experience.calculate_level_xp(level)
|
local function calculate_level_xp(level)
|
||||||
if level_table[level] == nil then
|
if level_table[level] == nil then
|
||||||
local value
|
local value
|
||||||
if level == 1 then
|
if level == 1 then
|
||||||
value = level_up_formula(level-1)
|
value = level_up_formula(level-1)
|
||||||
else
|
else
|
||||||
value = level_up_formula(level-1)+Experience.calculate_level_xp(level-1)
|
value = level_up_formula(level-1)+calculate_level_xp(level-1)
|
||||||
end
|
end
|
||||||
table.insert(level_table, level, value)
|
insert(level_table, level, value)
|
||||||
end
|
end
|
||||||
return level_table[level]
|
return level_table[level]
|
||||||
end
|
end
|
||||||
|
local function redraw_title(data)
|
||||||
|
local force_data = force_control.get_force_data('player')
|
||||||
|
data.frame.caption = utils.comma_value(force_data.total_experience) .. ' total experience earned!'
|
||||||
|
end
|
||||||
|
|
||||||
|
local function apply_heading_style(style, width)
|
||||||
|
style.font = 'default-bold'
|
||||||
|
style.width = width
|
||||||
|
end
|
||||||
|
|
||||||
|
local function redraw_heading(data, header)
|
||||||
|
local head_condition = (header == 1)
|
||||||
|
local frame = (head_condition) and data.experience_list_heading or data.buff_list_heading
|
||||||
|
local header_caption = (head_condition) and 'Reward Item' or 'Reward Buff'
|
||||||
|
Gui.clear(frame)
|
||||||
|
|
||||||
|
local heading_table = frame.add({type = 'table', column_count = 2})
|
||||||
|
apply_heading_style(heading_table.add({ type = 'label', caption = 'Requirement'}).style, 100)
|
||||||
|
apply_heading_style(heading_table.add({type = 'label', caption = header_caption}).style, 220)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function redraw_progressbar(data)
|
||||||
|
local force_data = force_control.get_force_data('player')
|
||||||
|
local flow = data.experience_progressbars
|
||||||
|
Gui.clear(flow)
|
||||||
|
|
||||||
|
apply_heading_style(flow.add({type = 'label', tooltip = 'Currently at level: ' .. force_data.current_level .. '\nNext level at: ' .. utils.comma_value((force_data.total_experience - force_data.current_experience) + force_data.experience_level_up_cap) ..' xp\nRemaining xp: ' .. utils.comma_value(force_data.experience_level_up_cap - force_data.current_experience), name = 'Diggy.Experience.Frame.Progress.Level', caption = 'Progress to next level:'}).style)
|
||||||
|
local level_progressbar = flow.add({type = 'progressbar', tooltip = floor(force_data.experience_percentage*100)*0.01 .. '% xp to next level'})
|
||||||
|
level_progressbar.style.width = 350
|
||||||
|
level_progressbar.value = force_data.experience_percentage * 0.01
|
||||||
|
end
|
||||||
|
|
||||||
|
local function redraw_table(data)
|
||||||
|
local experience_scroll_pane = data.experience_scroll_pane
|
||||||
|
Gui.clear(experience_scroll_pane)
|
||||||
|
|
||||||
|
redraw_progressbar(data)
|
||||||
|
redraw_heading(data, 1)
|
||||||
|
|
||||||
|
local last_level = 0
|
||||||
|
local current_force_level = force_control.get_force_data('player').current_level
|
||||||
|
|
||||||
|
for _, prototype in ipairs(config.unlockables) do
|
||||||
|
local current_item_level = prototype.level
|
||||||
|
local first_item_for_level = current_item_level ~= last_level
|
||||||
|
local color
|
||||||
|
|
||||||
|
if current_force_level >= current_item_level then
|
||||||
|
color = unlocked_color
|
||||||
|
else
|
||||||
|
color = locked_color
|
||||||
|
end
|
||||||
|
|
||||||
|
local list = experience_scroll_pane.add({type = 'table', column_count = 2})
|
||||||
|
|
||||||
|
local level_caption = ''
|
||||||
|
if first_item_for_level then
|
||||||
|
level_caption = 'level ' .. current_item_level
|
||||||
|
end
|
||||||
|
|
||||||
|
local level_column = list.add({
|
||||||
|
type = 'label',
|
||||||
|
caption = level_caption,
|
||||||
|
tooltip = 'XP: ' .. utils.comma_value(calculate_level_xp(current_item_level)),
|
||||||
|
})
|
||||||
|
level_column.style.minimal_width = 100
|
||||||
|
level_column.style.font_color = color
|
||||||
|
|
||||||
|
local item_column = list.add({
|
||||||
|
type = 'label',
|
||||||
|
caption = prototype.name
|
||||||
|
})
|
||||||
|
item_column.style.minimal_width = 22
|
||||||
|
item_column.style.font_color = color
|
||||||
|
|
||||||
|
last_level = current_item_level
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function redraw_buff(data)
|
||||||
|
local buff_scroll_pane = data.buff_scroll_pane
|
||||||
|
Gui.clear(buff_scroll_pane)
|
||||||
|
|
||||||
|
local all_levels_shown = false
|
||||||
|
for name, effects in pairs(config.buffs) do
|
||||||
|
local list = buff_scroll_pane.add({type = 'table', column_count = 2})
|
||||||
|
list.style.horizontal_spacing = 16
|
||||||
|
|
||||||
|
local level_caption = ''
|
||||||
|
if not all_levels_shown then
|
||||||
|
all_levels_shown = true
|
||||||
|
level_caption = 'All levels'
|
||||||
|
end
|
||||||
|
|
||||||
|
local level_label = list.add({type = 'label', caption = level_caption})
|
||||||
|
level_label.style.minimal_width = 100
|
||||||
|
level_label.style.font_color = unlocked_color
|
||||||
|
|
||||||
|
local buff_caption
|
||||||
|
local effect_value = effects.value
|
||||||
|
if name == 'mining_speed' then
|
||||||
|
buff_caption = format('+ %d mining speed', effect_value)
|
||||||
|
elseif name == 'inventory_slot' then
|
||||||
|
buff_caption = format('+ %d inventory slot%s', effect_value, effect_value > 1 and 's' or '')
|
||||||
|
elseif name == 'health_bonus' then
|
||||||
|
buff_caption = format('+ %d max health', effect_value)
|
||||||
|
else
|
||||||
|
buff_caption = format('+ %d %s', effect_value, name)
|
||||||
|
end
|
||||||
|
|
||||||
|
local buffs_label = list.add({ type = 'label', caption = buff_caption})
|
||||||
|
buffs_label.style.minimal_width = 220
|
||||||
|
buffs_label.style.font_color = unlocked_color
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function toggle(event)
|
||||||
|
local player = event.player
|
||||||
|
local left = player.gui.left
|
||||||
|
local frame = left['Diggy.Experience.Frame']
|
||||||
|
|
||||||
|
if (frame and event.trigger == nil) then
|
||||||
|
Gui.destroy(frame)
|
||||||
|
return
|
||||||
|
elseif (frame) then
|
||||||
|
local data = Gui.get_data(frame)
|
||||||
|
redraw_title(data)
|
||||||
|
redraw_progressbar(data)
|
||||||
|
redraw_table(data)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
frame = left.add({name = 'Diggy.Experience.Frame', type = 'frame', direction = 'vertical'})
|
||||||
|
|
||||||
|
local experience_progressbars = frame.add({ type = 'flow', direction = 'vertical'})
|
||||||
|
local experience_list_heading = frame.add({type = 'flow', direction = 'horizontal'})
|
||||||
|
|
||||||
|
local experience_scroll_pane = frame.add({ type = 'scroll-pane'})
|
||||||
|
experience_scroll_pane.style.maximal_height = 300
|
||||||
|
|
||||||
|
local buff_list_heading = frame.add({type = 'flow', direction = 'horizontal'})
|
||||||
|
|
||||||
|
local buff_scroll_pane = frame.add({type = 'scroll-pane'})
|
||||||
|
buff_scroll_pane.style.maximal_height = 100
|
||||||
|
|
||||||
|
frame.add({type = 'button', name = 'Diggy.Experience.Button', caption = 'Close'})
|
||||||
|
|
||||||
|
local data = {
|
||||||
|
frame = frame,
|
||||||
|
experience_progressbars = experience_progressbars,
|
||||||
|
experience_list_heading = experience_list_heading,
|
||||||
|
experience_scroll_pane = experience_scroll_pane,
|
||||||
|
buff_list_heading = buff_list_heading,
|
||||||
|
buff_scroll_pane = buff_scroll_pane,
|
||||||
|
}
|
||||||
|
|
||||||
|
redraw_title(data)
|
||||||
|
redraw_table(data)
|
||||||
|
|
||||||
|
redraw_heading(data, 2)
|
||||||
|
redraw_buff(data)
|
||||||
|
|
||||||
|
Gui.set_data(frame, data)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function on_player_created(event)
|
||||||
|
Game.get_player_by_index(event.player_index).gui.top.add({
|
||||||
|
name = 'Diggy.Experience.Button',
|
||||||
|
type = 'sprite-button',
|
||||||
|
sprite = 'entity/market',
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
Gui.on_click('Diggy.Experience.Button', toggle)
|
||||||
|
Gui.on_custom_close('Diggy.Experience.Frame', function (event)
|
||||||
|
event.element.destroy()
|
||||||
|
end)
|
||||||
|
|
||||||
|
---Updates the experience progress gui for every player that has it open
|
||||||
|
local function update_gui()
|
||||||
|
for _, p in ipairs(game.connected_players) do
|
||||||
|
local frame = p.gui.left['Diggy.Experience.Frame']
|
||||||
|
|
||||||
|
if frame and frame.valid then
|
||||||
|
local data = {player = p, trigger = 'update_gui'}
|
||||||
|
toggle(data)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
function Experience.register(cfg)
|
function Experience.register(cfg)
|
||||||
config = cfg
|
config = cfg
|
||||||
|
|
||||||
--Adds the function on how to calculate level caps (When to level up)
|
--Adds the function on how to calculate level caps (When to level up)
|
||||||
ForceControl_builder = ForceControl.register(level_up_formula)
|
local ForceControlBuilder = ForceControl.register(level_up_formula)
|
||||||
|
|
||||||
--Adds a function that'll be executed at every level up
|
--Adds a function that'll be executed at every level up
|
||||||
ForceControl_builder.register_on_every_level(function (level_reached, force)
|
ForceControlBuilder.register_on_every_level(function (level_reached, force)
|
||||||
force.print(string_format('%s Leveled up to %d!', '## - ', level_reached))
|
force.print(string_format('%s Leveled up to %d!', '## - ', level_reached))
|
||||||
force.play_sound{path='utility/new_objective', volume_modifier = 1 }
|
force.play_sound{path='utility/new_objective', volume_modifier = 1 }
|
||||||
local Experience = require 'map_gen.Diggy.Feature.Experience'
|
local Experience = require 'map_gen.Diggy.Feature.Experience'
|
||||||
Experience.update_inventory_slots(force, level_reached)
|
Experience.update_inventory_slots(force, level_reached)
|
||||||
Experience.update_mining_speed(force, level_reached)
|
Experience.update_mining_speed(force, level_reached)
|
||||||
Experience.update_health_bonus(force, level_reached)
|
Experience.update_health_bonus(force, level_reached)
|
||||||
local MarketExchange = require 'map_gen.Diggy.Feature.MarketExchange'
|
Experience.update_market_contents(force)
|
||||||
local market = MarketExchange.get_market()
|
|
||||||
MarketExchange.update_market_contents(market, force)
|
|
||||||
MarketExchange.update_gui()
|
|
||||||
end)
|
end)
|
||||||
|
|
||||||
-- Events
|
-- Events
|
||||||
@ -317,6 +520,8 @@ function Experience.register(cfg)
|
|||||||
Event.add(defines.events.on_rocket_launched, on_rocket_launched)
|
Event.add(defines.events.on_rocket_launched, on_rocket_launched)
|
||||||
Event.add(defines.events.on_player_respawned, on_player_respawned)
|
Event.add(defines.events.on_player_respawned, on_player_respawned)
|
||||||
Event.add(defines.events.on_entity_died, on_entity_died)
|
Event.add(defines.events.on_entity_died, on_entity_died)
|
||||||
|
Event.add(defines.events.on_player_created, on_player_created)
|
||||||
|
Event.on_nth_tick(61, update_gui)
|
||||||
|
|
||||||
-- Prevents table lookup thousands of times
|
-- Prevents table lookup thousands of times
|
||||||
sand_rock_xp = config.XP['sand-rock-big']
|
sand_rock_xp = config.XP['sand-rock-big']
|
||||||
|
@ -1,386 +0,0 @@
|
|||||||
--[[-- info
|
|
||||||
Provides the ability to purchase items from the market.
|
|
||||||
]]
|
|
||||||
|
|
||||||
-- dependencies
|
|
||||||
local Event = require 'utils.event'
|
|
||||||
local Token = require 'utils.global_token'
|
|
||||||
local Task = require 'utils.Task'
|
|
||||||
local Gui = require 'utils.gui'
|
|
||||||
local Debug = require 'map_gen.Diggy.Debug'
|
|
||||||
local Template = require 'map_gen.Diggy.Template'
|
|
||||||
local Game = require 'utils.game'
|
|
||||||
local insert = table.insert
|
|
||||||
local force_control = require 'features.force_control'
|
|
||||||
local Experience = require 'map_gen.Diggy.Feature.Experience'
|
|
||||||
local max = math.max
|
|
||||||
local floor = math.floor
|
|
||||||
local utils = require 'utils.utils'
|
|
||||||
|
|
||||||
-- this
|
|
||||||
local MarketExchange = {}
|
|
||||||
|
|
||||||
local config = {}
|
|
||||||
|
|
||||||
local on_market_timeout_finished = Token.register(function(params)
|
|
||||||
Template.market(params.surface, params.position, params.player_force)
|
|
||||||
end)
|
|
||||||
|
|
||||||
---Updates market content with new items if they are to be unlocked
|
|
||||||
---Primarily used by the force control system at every level up
|
|
||||||
---@param market LuaEntity The market to be updated
|
|
||||||
---@param force LuaForce the force which the unlocking requirement should be based of
|
|
||||||
function MarketExchange.update_market_contents(market, force)
|
|
||||||
local add_market_item
|
|
||||||
local item_unlocked = false
|
|
||||||
|
|
||||||
for _, unlockable in pairs(config.unlockables) do
|
|
||||||
local is_in_range = force_control.get_force_data(force).current_level == unlockable.level
|
|
||||||
|
|
||||||
-- only add the item to the market if it's between the old and new stone range
|
|
||||||
if (is_in_range and unlockable.type == 'market') then
|
|
||||||
add_market_item = add_market_item or market.add_market_item
|
|
||||||
|
|
||||||
local name = unlockable.prototype.name
|
|
||||||
local price = unlockable.prototype.price
|
|
||||||
if type(price) == 'number' then
|
|
||||||
add_market_item({
|
|
||||||
price = {{config.currency_item, price}},
|
|
||||||
offer = {type = 'give-item', item = name, count = 1}
|
|
||||||
})
|
|
||||||
elseif type(price) == 'table' then
|
|
||||||
add_market_item({
|
|
||||||
price = price,
|
|
||||||
offer = {type = 'give-item', item = name, count = 1}
|
|
||||||
})
|
|
||||||
end
|
|
||||||
item_unlocked = true
|
|
||||||
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local function redraw_title(data)
|
|
||||||
local force_data = force_control.get_force_data('player')
|
|
||||||
data.frame.caption = utils.comma_value(force_data.total_experience) .. ' total experience earned!'
|
|
||||||
end
|
|
||||||
|
|
||||||
local function get_data(unlocks, stone, type)
|
|
||||||
local result = {}
|
|
||||||
|
|
||||||
for _, data in pairs(unlocks) do
|
|
||||||
if data.level == stone and data.type == type then
|
|
||||||
insert(result, data)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
return result
|
|
||||||
end
|
|
||||||
|
|
||||||
local tag_label_stone = Gui.uid_name()
|
|
||||||
local tag_label_buff = Gui.uid_name()
|
|
||||||
local tag_label_item = Gui.uid_name()
|
|
||||||
|
|
||||||
local function apply_heading_style(style, width)
|
|
||||||
style.font = 'default-bold'
|
|
||||||
style.width = width
|
|
||||||
end
|
|
||||||
|
|
||||||
local function redraw_heading(data, header)
|
|
||||||
local head_condition = (header == 1)
|
|
||||||
local frame = (head_condition) and data.market_list_heading or data.buff_list_heading
|
|
||||||
local header_caption = (head_condition) and 'Reward Item' or 'Reward Buff'
|
|
||||||
Gui.clear(frame)
|
|
||||||
|
|
||||||
local heading_table = frame.add({type = 'table', column_count = 2})
|
|
||||||
apply_heading_style(heading_table.add({type = 'label', name = tag_label_stone, caption = 'Requirement'}).style, 100)
|
|
||||||
apply_heading_style(heading_table.add({type = 'label', name = tag_label_buff, caption = header_caption}).style, 220)
|
|
||||||
end
|
|
||||||
|
|
||||||
local function redraw_progressbar(data)
|
|
||||||
local force_data = force_control.get_force_data('player')
|
|
||||||
local flow = data.market_progressbars
|
|
||||||
Gui.clear(flow)
|
|
||||||
|
|
||||||
apply_heading_style(flow.add({type = 'label', tooltip = 'Currently at level: ' .. force_data.current_level .. '\nNext level at: ' .. utils.comma_value((force_data.total_experience - force_data.current_experience) + force_data.experience_level_up_cap) ..' xp\nRemaining xp: ' .. utils.comma_value(force_data.experience_level_up_cap - force_data.current_experience), name = 'Diggy.MarketExchange.Frame.Progress.Level', caption = 'Progress to next level:'}).style)
|
|
||||||
local level_progressbar = flow.add({type = 'progressbar', tooltip = floor(force_data.experience_percentage*100)*0.01 .. '% xp to next level'})
|
|
||||||
level_progressbar.style.width = 350
|
|
||||||
level_progressbar.value = force_data.experience_percentage * 0.01
|
|
||||||
end
|
|
||||||
|
|
||||||
local function redraw_table(data)
|
|
||||||
local market_scroll_pane = data.market_scroll_pane
|
|
||||||
Gui.clear(market_scroll_pane)
|
|
||||||
|
|
||||||
local buffs = {}
|
|
||||||
local items = {}
|
|
||||||
local last_stone = 0
|
|
||||||
local number_of_rows = 0
|
|
||||||
local row = {}
|
|
||||||
|
|
||||||
-- create the progress bars in the window
|
|
||||||
redraw_progressbar(data)
|
|
||||||
|
|
||||||
-- create table headings
|
|
||||||
redraw_heading(data, 1)
|
|
||||||
|
|
||||||
-- create table
|
|
||||||
for i = 1, #config.unlockables do
|
|
||||||
if config.unlockables[i].level ~= last_stone then
|
|
||||||
|
|
||||||
-- get items and buffs for each stone value
|
|
||||||
items = get_data(config.unlockables, config.unlockables[i].level, 'market')
|
|
||||||
|
|
||||||
-- get number of rows
|
|
||||||
number_of_rows = max(#buffs, #items)
|
|
||||||
|
|
||||||
-- loop through buffs and items for number of rows
|
|
||||||
for j = 1, number_of_rows do
|
|
||||||
local result = {}
|
|
||||||
local item = items[j]
|
|
||||||
local level = item.level
|
|
||||||
|
|
||||||
-- 1st column
|
|
||||||
result[1] = level
|
|
||||||
-- 3rd column
|
|
||||||
if items[j] ~= nil then
|
|
||||||
result[3] = '+ ' .. item.prototype.name
|
|
||||||
else
|
|
||||||
result[3] = ''
|
|
||||||
end
|
|
||||||
-- indicator to stop print stone number
|
|
||||||
if j > 1 then
|
|
||||||
result[4] = true
|
|
||||||
else
|
|
||||||
result[4] = false
|
|
||||||
end
|
|
||||||
-- indicator to draw horizontal line
|
|
||||||
if j == number_of_rows then
|
|
||||||
result[5] = true
|
|
||||||
else
|
|
||||||
result[5] = false
|
|
||||||
end
|
|
||||||
|
|
||||||
insert(row, result)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- save lastStone
|
|
||||||
last_stone = config.unlockables[i].level
|
|
||||||
end
|
|
||||||
|
|
||||||
-- print table
|
|
||||||
for _, unlockable in pairs(row) do
|
|
||||||
local is_unlocked = unlockable[1] <= force_control.get_force_data('player').current_level
|
|
||||||
local list = market_scroll_pane.add {type = 'table', column_count = 2 }
|
|
||||||
|
|
||||||
list.style.horizontal_spacing = 16
|
|
||||||
|
|
||||||
local caption = ''
|
|
||||||
if unlockable[4] ~= true then
|
|
||||||
caption = 'Level ' .. unlockable[1]
|
|
||||||
else
|
|
||||||
caption = ''
|
|
||||||
end
|
|
||||||
local tag_stone = list.add {type = 'label', name = tag_label_stone, caption = caption, tooltip = 'XP: ' .. utils.comma_value(Experience.calculate_level_xp(unlockable[1]))}
|
|
||||||
tag_stone.style.minimal_width = 100
|
|
||||||
|
|
||||||
local tag_items = list.add {type = 'label', name = tag_label_item, caption = unlockable[3]}
|
|
||||||
tag_items.style.minimal_width = 220
|
|
||||||
|
|
||||||
-- draw horizontal line
|
|
||||||
if unlockable[5] == true then
|
|
||||||
list.draw_horizontal_line_after_headers = true
|
|
||||||
end
|
|
||||||
|
|
||||||
if (is_unlocked) then
|
|
||||||
tag_stone.style.font_color = {r = 1, g = 1, b = 1 }
|
|
||||||
tag_items.style.font_color = {r = 1, g = 1, b = 1 }
|
|
||||||
else
|
|
||||||
tag_stone.style.font_color = {r = 0.5, g = 0.5, b = 0.5 }
|
|
||||||
tag_items.style.font_color = {r = 0.5, g = 0.5, b = 0.5 }
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local function redraw_buff(data) --! Almost equals to the redraw_table() function !
|
|
||||||
local buff_scroll_pane = data.buff_scroll_pane
|
|
||||||
Gui.clear(buff_scroll_pane)
|
|
||||||
|
|
||||||
local buffs = Experience.get_buffs()
|
|
||||||
local row = {}
|
|
||||||
local i = 0
|
|
||||||
for k, v in pairs(buffs) do
|
|
||||||
i = i + 1
|
|
||||||
local result = {}
|
|
||||||
|
|
||||||
-- 1st column
|
|
||||||
result[1] = 'All levels'
|
|
||||||
|
|
||||||
-- 2nd column
|
|
||||||
if k == 'mining_speed' then
|
|
||||||
result[2] = '+ '.. v.value .. '% mining speed'
|
|
||||||
elseif k == 'inventory_slot' then
|
|
||||||
if v.value > 1 then
|
|
||||||
result[2] = '+ '.. v.value .. ' inventory slots'
|
|
||||||
else
|
|
||||||
result[2] = '+ '.. v.value .. ' inventory slot'
|
|
||||||
end
|
|
||||||
elseif k == 'health_bonus' then
|
|
||||||
result[2] = '+ '.. v.value .. ' max health'
|
|
||||||
else
|
|
||||||
result[2] = 'Description missing: unknown buff. Please contact admin'
|
|
||||||
end
|
|
||||||
|
|
||||||
-- 3rd column
|
|
||||||
result[3] = ''
|
|
||||||
-- indicator to stop print level number
|
|
||||||
if i > 1 then
|
|
||||||
result[4] = true
|
|
||||||
else
|
|
||||||
result[4] = false
|
|
||||||
end
|
|
||||||
insert(row, result)
|
|
||||||
end
|
|
||||||
for _, unlockable in pairs(row) do
|
|
||||||
local list = buff_scroll_pane.add {type = 'table', column_count = 2 }
|
|
||||||
list.style.horizontal_spacing = 16
|
|
||||||
|
|
||||||
local caption = ''
|
|
||||||
if unlockable[4] ~= true then
|
|
||||||
caption = unlockable[1]
|
|
||||||
else
|
|
||||||
caption = ''
|
|
||||||
end
|
|
||||||
local tag_stone = list.add {type = 'label', name = buff_tag_label_stone, caption = caption}
|
|
||||||
tag_stone.style.minimal_width = 100
|
|
||||||
|
|
||||||
local tag_buffs = list.add {type = 'label', name = buff_tag_label_buff, caption = unlockable[2]}
|
|
||||||
tag_buffs.style.minimal_width = 220
|
|
||||||
|
|
||||||
tag_stone.style.font_color = {r = 1, g = 1, b = 1 }
|
|
||||||
tag_buffs.style.font_color = {r = 1, g = 1, b = 1 }
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
---Interface for force control system to access the primary market
|
|
||||||
---@return LuaEntity the primary market (The one at spawn)
|
|
||||||
function MarketExchange.get_market()
|
|
||||||
|
|
||||||
local markets = game.surfaces.nauvis.find_entities_filtered({name = 'market', position = config.market_spawn_position, limit = 1})
|
|
||||||
|
|
||||||
if (#markets == 0) then
|
|
||||||
Debug.print_position(config.market_spawn_position, 'Unable to find a market')
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
return markets[1]
|
|
||||||
end
|
|
||||||
|
|
||||||
local function on_placed_entity(event)
|
|
||||||
local market = event.entity
|
|
||||||
if 'market' ~= market.name then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function MarketExchange.get_extra_map_info(config)
|
|
||||||
return 'Market Exchange, come make a deal at the foreman\'s shop'
|
|
||||||
end
|
|
||||||
|
|
||||||
local function toggle(event)
|
|
||||||
local player = event.player
|
|
||||||
local left = player.gui.left
|
|
||||||
local frame = left['Diggy.MarketExchange.Frame']
|
|
||||||
|
|
||||||
if (frame and event.trigger == nil) then
|
|
||||||
Gui.destroy(frame)
|
|
||||||
return
|
|
||||||
elseif (frame) then
|
|
||||||
local data = Gui.get_data(frame)
|
|
||||||
redraw_title(data)
|
|
||||||
redraw_progressbar(data)
|
|
||||||
redraw_table(data)
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
frame = left.add({name = 'Diggy.MarketExchange.Frame', type = 'frame', direction = 'vertical'})
|
|
||||||
|
|
||||||
local market_progressbars = frame.add({type = 'flow', direction = 'vertical'})
|
|
||||||
local market_list_heading = frame.add({type = 'flow', direction = 'horizontal'})
|
|
||||||
|
|
||||||
local market_scroll_pane = frame.add({type = 'scroll-pane'})
|
|
||||||
market_scroll_pane.style.maximal_height = 300
|
|
||||||
|
|
||||||
local buff_list_heading = frame.add({type = 'flow', direction = 'horizontal'})
|
|
||||||
|
|
||||||
local buff_scroll_pane = frame.add({type = 'scroll-pane'})
|
|
||||||
buff_scroll_pane.style.maximal_height = 100
|
|
||||||
|
|
||||||
frame.add({ type = 'button', name = 'Diggy.MarketExchange.Button', caption = 'Close'})
|
|
||||||
|
|
||||||
local data = {
|
|
||||||
frame = frame,
|
|
||||||
market_progressbars = market_progressbars,
|
|
||||||
market_list_heading = market_list_heading,
|
|
||||||
market_scroll_pane = market_scroll_pane,
|
|
||||||
buff_list_heading = buff_list_heading,
|
|
||||||
buff_scroll_pane = buff_scroll_pane,
|
|
||||||
}
|
|
||||||
|
|
||||||
redraw_title(data)
|
|
||||||
redraw_table(data)
|
|
||||||
|
|
||||||
redraw_heading(data, 2)
|
|
||||||
redraw_buff(data)
|
|
||||||
|
|
||||||
Gui.set_data(frame, data)
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
local function on_player_created(event)
|
|
||||||
Game.get_player_by_index(event.player_index).gui.top.add({
|
|
||||||
name = 'Diggy.MarketExchange.Button',
|
|
||||||
type = 'sprite-button',
|
|
||||||
sprite = 'entity/market',
|
|
||||||
})
|
|
||||||
end
|
|
||||||
|
|
||||||
Gui.on_click('Diggy.MarketExchange.Button', toggle)
|
|
||||||
Gui.on_custom_close('Diggy.MarketExchange.Frame', function (event)
|
|
||||||
event.element.destroy()
|
|
||||||
end)
|
|
||||||
|
|
||||||
---Updates the market progress gui for every player that has it open
|
|
||||||
function MarketExchange.update_gui()
|
|
||||||
for _, p in ipairs(game.connected_players) do
|
|
||||||
local frame = p.gui.left['Diggy.MarketExchange.Frame']
|
|
||||||
|
|
||||||
if frame and frame.valid then
|
|
||||||
local data = {player = p, trigger = 'update_gui'}
|
|
||||||
toggle(data)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function MarketExchange.on_init()
|
|
||||||
Task.set_timeout_in_ticks(1, on_market_timeout_finished, {
|
|
||||||
surface = game.surfaces.nauvis,
|
|
||||||
position = config.market_spawn_position,
|
|
||||||
player_force = game.forces.player,
|
|
||||||
})
|
|
||||||
end
|
|
||||||
|
|
||||||
--[[--
|
|
||||||
Registers all event handlers.
|
|
||||||
]]
|
|
||||||
function MarketExchange.register(cfg)
|
|
||||||
config = cfg
|
|
||||||
|
|
||||||
--Events
|
|
||||||
Event.add(Template.events.on_placed_entity, on_placed_entity)
|
|
||||||
Event.add(defines.events.on_player_created, on_player_created)
|
|
||||||
Event.on_nth_tick(61, MarketExchange.update_gui)
|
|
||||||
end
|
|
||||||
|
|
||||||
return MarketExchange
|
|
@ -6,11 +6,13 @@ local Event = require 'utils.event'
|
|||||||
local Token = require 'utils.global_token'
|
local Token = require 'utils.global_token'
|
||||||
local Template = require 'map_gen.Diggy.Template'
|
local Template = require 'map_gen.Diggy.Template'
|
||||||
local Debug = require 'map_gen.Diggy.Debug'
|
local Debug = require 'map_gen.Diggy.Debug'
|
||||||
|
local Retailer = require 'features.retailer'
|
||||||
local DiggyCaveCollapse = require 'map_gen.Diggy.Feature.DiggyCaveCollapse'
|
local DiggyCaveCollapse = require 'map_gen.Diggy.Feature.DiggyCaveCollapse'
|
||||||
local insert = table.insert
|
local insert = table.insert
|
||||||
local random = math.random
|
local random = math.random
|
||||||
local sqrt = math.sqrt
|
local sqrt = math.sqrt
|
||||||
local floor = math.floor
|
local floor = math.floor
|
||||||
|
local raise_event = script.raise_event
|
||||||
|
|
||||||
-- this
|
-- this
|
||||||
local StartingZone = {}
|
local StartingZone = {}
|
||||||
@ -67,7 +69,23 @@ function StartingZone.register(config)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
Template.insert(event.surface, tiles, rocks)
|
Template.insert(surface, tiles, rocks)
|
||||||
|
|
||||||
|
local position = config.market_spawn_position;
|
||||||
|
local player_force = game.forces.player;
|
||||||
|
|
||||||
|
local market = surface.create_entity({name = 'market', position = position})
|
||||||
|
market.destructible = false
|
||||||
|
|
||||||
|
Retailer.add_market(player_force.name, market)
|
||||||
|
Retailer.ship_items(player_force.name)
|
||||||
|
|
||||||
|
player_force.add_chart_tag(surface, {
|
||||||
|
text = 'Market',
|
||||||
|
position = position,
|
||||||
|
})
|
||||||
|
|
||||||
|
raise_event(Template.events.on_placed_entity, {entity = market})
|
||||||
|
|
||||||
Event.remove_removable(defines.events.on_chunk_generated, callback_token)
|
Event.remove_removable(defines.events.on_chunk_generated, callback_token)
|
||||||
end
|
end
|
||||||
@ -77,5 +95,4 @@ function StartingZone.register(config)
|
|||||||
Event.add_removable(defines.events.on_chunk_generated, callback_token)
|
Event.add_removable(defines.events.on_chunk_generated, callback_token)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
return StartingZone
|
return StartingZone
|
||||||
|
@ -1,45 +0,0 @@
|
|||||||
-- dependencies
|
|
||||||
|
|
||||||
-- this
|
|
||||||
local FormatMarketItems = {}
|
|
||||||
|
|
||||||
local market_prototype_items = {}
|
|
||||||
local insert = table.insert
|
|
||||||
|
|
||||||
--- Returns the correct format for Diggy.Feature.MarketExhange.lua to process
|
|
||||||
-- @param self_level number of the level the given item should be unlocked at
|
|
||||||
-- @param self_price number of the price in the configured currency_item the given item should cost
|
|
||||||
-- @param self_name string of the factorio entity prototype-name
|
|
||||||
--
|
|
||||||
local function add(self_level, self_price, self_name)
|
|
||||||
if (not market_prototype_items[self_level]) then
|
|
||||||
insert(market_prototype_items, self_level, {})
|
|
||||||
end
|
|
||||||
insert(market_prototype_items[self_level], {price = self_price, name = self_name})
|
|
||||||
end
|
|
||||||
|
|
||||||
--- handles the unlockable market items from Config.lua in map_gen.Diggy
|
|
||||||
-- serves as a handler for an array of items and passes it on to FormatMarketItems.add() that returns the correct format for Diggy.Feature.MarketExhange.lua to process.
|
|
||||||
-- @param items table of items where each item is an table with keys: level (integer level it unlocks at), price (price in the configured currency_item) and name (has to be an entity's prototype-name)
|
|
||||||
-- @returns table of items formated in the correct way for Diggy.Feature.MarketExhange.lua to interpret.
|
|
||||||
-- @usage Pass an table with each value being another table with these members:
|
|
||||||
-- @field level number of the level wished to unlock the item
|
|
||||||
-- @field price number of the price in the configured currency_item to buy the item in the market
|
|
||||||
-- @field name string of the factorio prototype-name for the entity to be unlocked
|
|
||||||
--
|
|
||||||
function FormatMarketItems.initialize_unlockables(items)
|
|
||||||
local unlockables = {}
|
|
||||||
for _, item in ipairs(items) do
|
|
||||||
add(item.level, item.price, item.name)
|
|
||||||
end
|
|
||||||
|
|
||||||
for lvl, v in pairs(market_prototype_items) do
|
|
||||||
for _, w in ipairs(v) do
|
|
||||||
insert(unlockables, {level = lvl, type = 'market', prototype = w})
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
return unlockables
|
|
||||||
end
|
|
||||||
|
|
||||||
return FormatMarketItems
|
|
@ -45,9 +45,9 @@ function Scenario.register(debug, cheats)
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
global.scenario.config.player_list.enable_coin_col = false
|
global.config.player_list.enable_coin_col = false
|
||||||
if global.scenario.config then
|
if global.config then
|
||||||
global.scenario.config.fish_market.enable = nil
|
global.config.fish_market.enable = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
if debug then
|
if debug then
|
||||||
|
@ -10,8 +10,8 @@ local raise_event = script.raise_event
|
|||||||
-- this
|
-- this
|
||||||
local Template = {}
|
local Template = {}
|
||||||
|
|
||||||
local tiles_per_call = 5 --how many tiles are inserted with each call of insert_action
|
local tiles_per_call = 256 --how many tiles are inserted with each call of insert_action
|
||||||
local entities_per_call = 5 --how many entities are inserted with each call of insert_action
|
local entities_per_call = 8 --how many entities are inserted with each call of insert_action
|
||||||
|
|
||||||
Template.events = {
|
Template.events = {
|
||||||
--[[--
|
--[[--
|
||||||
@ -71,7 +71,7 @@ local function insert_next_entities(data)
|
|||||||
for i = data.entity_iterator, min(data.entity_iterator + entities_per_call - 1, data.entities_n) do
|
for i = data.entity_iterator, min(data.entity_iterator + entities_per_call - 1, data.entities_n) do
|
||||||
local entity = data.entities[i]
|
local entity = data.entities[i]
|
||||||
local created_entity = create_entity(entity)
|
local created_entity = create_entity(entity)
|
||||||
if (nil == created_entity) then
|
if not created_entity then
|
||||||
error('Failed creating entity ' .. entity.name .. ' on surface.')
|
error('Failed creating entity ' .. entity.name .. ' on surface.')
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -128,7 +128,7 @@ function Template.insert(surface, tiles, entities)
|
|||||||
}
|
}
|
||||||
|
|
||||||
local continue = true
|
local continue = true
|
||||||
for i = 1, 4 do
|
for _ = 1, 4 do
|
||||||
continue = insert_action(data)
|
continue = insert_action(data)
|
||||||
if not continue then
|
if not continue then
|
||||||
return
|
return
|
||||||
@ -155,24 +155,4 @@ function Template.resources(surface, resources)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
--[[--
|
|
||||||
Designed to spawn a market.
|
|
||||||
|
|
||||||
@param surface LuaSurface
|
|
||||||
@param position Position
|
|
||||||
@param force LuaForce
|
|
||||||
@param market_items Table
|
|
||||||
]]
|
|
||||||
function Template.market(surface, position, force)
|
|
||||||
local market = surface.create_entity({name = 'market', position = position})
|
|
||||||
market.destructible = false
|
|
||||||
|
|
||||||
force.add_chart_tag(surface, {
|
|
||||||
text = 'Market',
|
|
||||||
position = position,
|
|
||||||
})
|
|
||||||
|
|
||||||
raise_event(Template.events.on_placed_entity, {entity = market})
|
|
||||||
end
|
|
||||||
|
|
||||||
return Template
|
return Template
|
||||||
|
@ -41,22 +41,22 @@ But be careful, eating too much might have it´s consequences too...
|
|||||||
]])
|
]])
|
||||||
|
|
||||||
|
|
||||||
if global.scenario and global.scenario.config then
|
if global.scenario and global.config then
|
||||||
if global.scenario.config.player_list then
|
if global.config.player_list then
|
||||||
global.scenario.config.player_list.enable_coin_col = nil
|
global.config.player_list.enable_coin_col = nil
|
||||||
end
|
end
|
||||||
if global.scenario.config.fish_market then
|
if global.config.fish_market then
|
||||||
global.scenario.config.fish_market.enable = nil
|
global.config.fish_market.enable = nil
|
||||||
end
|
end
|
||||||
if global.scenario.config.paint then
|
if global.config.paint then
|
||||||
global.scenario.config.paint.enable = nil
|
global.config.paint.enable = nil
|
||||||
end
|
end
|
||||||
if global.scenario.nuke_control then
|
if global.scenario.nuke_control then
|
||||||
global.scenario.nuke_control.enable_autokick = nil
|
global.scenario.nuke_control.enable_autokick = nil
|
||||||
global.scenario.nuke_control.enable_autoban = nil
|
global.scenario.nuke_control.enable_autoban = nil
|
||||||
end
|
end
|
||||||
if global.scenario.config.fish_market then
|
if global.config.fish_market then
|
||||||
global.scenario.config.fish_market.enable = nil
|
global.config.fish_market.enable = nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -570,7 +570,7 @@ Global.register_init(
|
|||||||
tbl.outpost_seed = outpost_seed or seed
|
tbl.outpost_seed = outpost_seed or seed
|
||||||
tbl.ore_seed = ore_seed or seed
|
tbl.ore_seed = ore_seed or seed
|
||||||
|
|
||||||
global.scenario.config.fish_market.enable = false
|
global.config.fish_market.enable = false
|
||||||
end,
|
end,
|
||||||
function(tbl)
|
function(tbl)
|
||||||
outpost_seed = tbl.outpost_seed
|
outpost_seed = tbl.outpost_seed
|
||||||
|
@ -105,7 +105,7 @@ end
|
|||||||
|
|
||||||
map = b.apply_effect(map, effect)
|
map = b.apply_effect(map, effect)
|
||||||
|
|
||||||
local Spawn_Control = require 'features.spawn_control'
|
local Spawn_Control = require 'map_gen.misc.spawn_control'
|
||||||
|
|
||||||
Spawn_Control.add_spawn('left', -88, -88)
|
Spawn_Control.add_spawn('left', -88, -88)
|
||||||
Spawn_Control.add_spawn('right', 88, 88)
|
Spawn_Control.add_spawn('right', 88, 88)
|
||||||
|
@ -139,8 +139,9 @@ local terrain_modules = {
|
|||||||
--require 'map_gen.misc.nightfall' -- forces idle biters to attack at night
|
--require 'map_gen.misc.nightfall' -- forces idle biters to attack at night
|
||||||
--require 'map_gen.misc.creep_spread'
|
--require 'map_gen.misc.creep_spread'
|
||||||
--require 'map_gen.misc.car_body' -- gives players cars instead of characters
|
--require 'map_gen.misc.car_body' -- gives players cars instead of characters
|
||||||
--require 'features.silly_player_names' -- assigns players random names when they first join
|
--require 'map_gen.misc.silly_player_names' -- assigns players random names when they first join
|
||||||
--require 'map_gen.misc.naughty_words' -- admonishes players for cursing
|
--require 'map_gen.misc.naughty_words' -- admonishes players for cursing
|
||||||
|
--require 'map_gen.misc.infinite_storage_chest'
|
||||||
|
|
||||||
if #entity_modules > 0 then
|
if #entity_modules > 0 then
|
||||||
shape = shape or b.full_shape
|
shape = shape or b.full_shape
|
||||||
|
@ -5,35 +5,6 @@ Module.donator_perk_flags = {
|
|||||||
train = 0x2
|
train = 0x2
|
||||||
}
|
}
|
||||||
|
|
||||||
local d = Module.donator_perk_flags
|
Module.donators = {}
|
||||||
|
|
||||||
Module.donators = {
|
|
||||||
['aldldl'] = d.rank,
|
|
||||||
['Geostyx'] = d.rank,
|
|
||||||
['Linaori'] = d.rank,
|
|
||||||
['Xertez'] = d.rank,
|
|
||||||
['Chevalier1200'] = d.rank + d.train,
|
|
||||||
['DraugTheWhopper'] = d.rank + d.train,
|
|
||||||
['der-dave.com'] = d.rank + d.train,
|
|
||||||
['Jayefuu'] = d.rank,
|
|
||||||
['Valansch'] = d.rank,
|
|
||||||
['plague006'] = d.rank,
|
|
||||||
['chromaddict'] = d.rank,
|
|
||||||
['InphinitePhractals'] = d.rank + d.train,
|
|
||||||
['shoghicp'] = d.rank + d.train,
|
|
||||||
['DuelleuD'] = d.rank + d.train,
|
|
||||||
['henrycn1997'] = d.rank + d.train,
|
|
||||||
['Raiguard'] = d.rank + d.train,
|
|
||||||
}
|
|
||||||
|
|
||||||
Module.welcome_messages = {
|
|
||||||
['Linaori'] = 'I present to you Linaori of house Refactorio, Lady of the Void, Remover of Spaghetti, Queen of the Endless Nauvis, Breaker of Biters and Mother of Code!',
|
|
||||||
['Valansch'] = 'Welcome Valansch, <insert custom welcome message here>.',
|
|
||||||
['der-dave.com'] = "Dave doesn't want a welcome message.",
|
|
||||||
['plague006'] = 'plague wrote this dumb message you have to read. If you want your own dumb on-join message be sure to donate on Patreon!',
|
|
||||||
['shoghicp'] = 'Need more servers!',
|
|
||||||
['aldldl'] = "ALo's Here",
|
|
||||||
['Raiguard'] = "I am... was... God. The one you call 'The Almighty'. The creator of Factories. But now, I am dead. The Biters killed me. I am sorry.",
|
|
||||||
}
|
|
||||||
|
|
||||||
return Module
|
return Module
|
||||||
|
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user