mirror of
https://github.com/Refactorio/RedMew.git
synced 2025-03-03 14:53:01 +02:00
merge develop
This commit is contained in:
commit
3768a6a3ca
@ -56,7 +56,7 @@ local STD_BASE_CONTROL = 'lua52c+factorio+factorio_control+factorio_defines+fact
|
||||
--[Assume Factorio Control stage as default]--
|
||||
-------------------------------------------------------------------------------
|
||||
std = STD_CONTROL
|
||||
globals = {'math', 'table', '_DEBUG', 'MARKET_ITEM', 'newline'} -- RedMew-specific globals
|
||||
globals = {'math', 'table', '_DEBUG', '_CHEATS', 'MARKET_ITEM', 'newline'} -- RedMew-specific globals
|
||||
max_line_length = LINE_LENGTH
|
||||
|
||||
not_globals = NOT_GLOBALS
|
||||
|
@ -5,15 +5,24 @@ All notable changes to this project will be documented in this file.
|
||||
## Next version
|
||||
|
||||
### Features
|
||||
- [Core] Change /find-player to /find #417
|
||||
- [Core] Using `/regular <name>` now defaults to promoting the player. #417
|
||||
- [Diggy] Added new formula to calculate experience requirement for next level #402
|
||||
- [Diggy] Added health bonus on level up #402
|
||||
- [Diggy] Added new level system to replace stone sent to surface #402
|
||||
- [Diggy] Mining rocks no longer gives stone or coal #402
|
||||
- [Diggy] Added particles when a biter mines a rock upon spawning #424
|
||||
- [Diggy] Added bot mining #434
|
||||
- [Map] Add Tetris map #433
|
||||
- [Map] Add World Thanksgiving map #433
|
||||
- [Diggy] Added bot mining levels and rock mining/destruction particles #442
|
||||
|
||||
### Bugfixes
|
||||
- [Diggy] Stones killed by damage no longer spill. #395
|
||||
- [Core] Fix /kill non-functional if walkabout is disabled. Fix walkabout giving from variable definition. #425
|
||||
- [Diggy] Improved biter spawning algorithm #408
|
||||
- [Core] Fix null reference in chat_triggers #431
|
||||
- [Core] Fix nil ref in train_station_names #441
|
||||
|
||||
### Internal
|
||||
- [Core] Cleanup of code formatting. #413 #415 #414 #412 #411
|
||||
|
@ -1,4 +1,5 @@
|
||||
_DEBUG = false
|
||||
_CHEATS = false
|
||||
MARKET_ITEM = 'coin'
|
||||
|
||||
global.scenario = {}
|
||||
@ -18,6 +19,8 @@ global.scenario.config.nuke_control.enable_autokick = true
|
||||
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'
|
||||
|
||||
|
@ -8,7 +8,6 @@ require 'map_gen.shared.perlin_noise'
|
||||
require 'map_layout'
|
||||
|
||||
-- Specific to RedMew hosts, can be disabled safely if not hosting on RedMew servers
|
||||
require 'features.bot'
|
||||
Server = require 'server'
|
||||
ServerCommands = require 'server_commands'
|
||||
|
||||
|
@ -1,59 +0,0 @@
|
||||
local Event = require 'utils.event'
|
||||
local Game = require 'utils.game'
|
||||
|
||||
Event.add(
|
||||
defines.events.on_player_died,
|
||||
function(event)
|
||||
local player = event.player_index
|
||||
if Game.get_player_by_index(player).name ~= nil then
|
||||
print('PLAYER$die,' .. player .. ',' .. Game.get_player_by_index(player).name .. ',' .. Game.get_player_by_index(player).force.name)
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
Event.add(
|
||||
defines.events.on_player_respawned,
|
||||
function(event)
|
||||
local player = event.player_index
|
||||
if Game.get_player_by_index(player).name ~= nil then
|
||||
print('PLAYER$respawn,' .. player .. ',' .. Game.get_player_by_index(player).name .. ',' .. Game.get_player_by_index(player).force.name)
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
Event.add(
|
||||
defines.events.on_player_joined_game,
|
||||
function(event)
|
||||
local player = event.player_index
|
||||
if Game.get_player_by_index(player).name ~= nil then
|
||||
print('PLAYER$join,' .. player .. ',' .. Game.get_player_by_index(player).name .. ',' .. Game.get_player_by_index(player).force.name)
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
Event.add(
|
||||
defines.events.on_player_left_game,
|
||||
function(event)
|
||||
local player = event.player_index
|
||||
if Game.get_player_by_index(player).name ~= nil then
|
||||
print('PLAYER$leave,' .. player .. ',' .. Game.get_player_by_index(player).name .. ',' .. Game.get_player_by_index(player).force.name)
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
function heartbeat()
|
||||
--Do nothing, this is just so managepgm can call something as a heartbeat without any errors occurring
|
||||
end
|
||||
|
||||
function playerQuery()
|
||||
if #game.connected_players == 0 then
|
||||
print('output$pquery$none')
|
||||
else
|
||||
local response = 'output&pquery$'
|
||||
for _, player in pairs(game.connected_players) do
|
||||
local playerdata = player.name .. '-' .. player.force.name
|
||||
response = response .. playerdata .. ','
|
||||
end
|
||||
print(response:sub(1, #str - 1))
|
||||
end
|
||||
end
|
37
features/create_particles.lua
Normal file
37
features/create_particles.lua
Normal file
@ -0,0 +1,37 @@
|
||||
local random = math.random
|
||||
|
||||
local CreateParticles = {}
|
||||
|
||||
---@param create_entity function a reference to a surface.create_entity
|
||||
---@param particle_count number particle count to spawn
|
||||
---@param position Position
|
||||
function CreateParticles.destroy_rock(create_entity, particle_count, position)
|
||||
for _ = particle_count, 1, -1 do
|
||||
create_entity({
|
||||
position = position,
|
||||
name = 'stone-particle',
|
||||
movement = {random(-5, 5) * 0.01, random(-5, 5) * 0.01},
|
||||
frame_speed = 1,
|
||||
vertical_speed = random(12, 14) * 0.01,
|
||||
height = random(9, 11) * 0.1,
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
---@param create_entity function a reference to a surface.create_entity
|
||||
---@param particle_count number particle count to spawn
|
||||
---@param position Position
|
||||
function CreateParticles.mine_rock(create_entity, particle_count, position)
|
||||
for _ = particle_count, 1, -1 do
|
||||
create_entity({
|
||||
position = position,
|
||||
name = 'stone-particle',
|
||||
movement = {random(-5, 5) * 0.01, random(-5, 5) * 0.01},
|
||||
frame_speed = 1,
|
||||
vertical_speed = random(8, 10) * 0.01,
|
||||
height = random(5, 8) * 0.1,
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
return CreateParticles
|
@ -22,7 +22,6 @@ local function invoke(cmd)
|
||||
local pos = game.player.surface.find_non_colliding_position('player', game.player.position, 0, 1)
|
||||
game.players[target].teleport({pos.x, pos.y}, game.player.surface)
|
||||
game.print(target .. ', get your ass over here!')
|
||||
Utils.log_command(game.player.name, cmd.name, cmd.parameter)
|
||||
end
|
||||
|
||||
--- Takes a target and teleports player to target. (admin only)
|
||||
@ -41,7 +40,6 @@ local function teleport_player(cmd)
|
||||
game.player.teleport(pos, surface)
|
||||
game.print(target .. "! watcha doin'?!")
|
||||
game.player.print('You have teleported to ' .. game.players[target].name)
|
||||
Utils.log_command(game.player.name, cmd.name, cmd.parameter)
|
||||
end
|
||||
|
||||
--- Takes a selected entity and teleports player to entity. (admin only)
|
||||
@ -56,7 +54,6 @@ local function teleport_location(cmd)
|
||||
end
|
||||
local pos = game.player.surface.find_non_colliding_position('player', game.player.selected.position, 0, 1)
|
||||
game.player.teleport(pos)
|
||||
Utils.log_command(game.player.name, cmd.name, false)
|
||||
end
|
||||
|
||||
--- Kill a player with fish as the cause of death.
|
||||
@ -91,8 +88,8 @@ local function kill(cmd)
|
||||
end
|
||||
|
||||
if global.walking then
|
||||
if global.walking[player.index] == true or global.walking[target.index] == true then
|
||||
player.print("A player on walkabout cannot be killed by a mere fish, don't waste your efforts.")
|
||||
if (player and global.walking[player.index]) or global.walking[target.index] then
|
||||
Game.player_print("A player on walkabout cannot be killed by a mere fish, don't waste your efforts.")
|
||||
return
|
||||
end
|
||||
end
|
||||
@ -110,7 +107,6 @@ local function kill(cmd)
|
||||
if not do_fish_kill(target) then
|
||||
Game.player_print(table.concat {"'Sorry, '", target.name, "' doesn't have a character to kill."})
|
||||
end
|
||||
Utils.log_command(game.player.name, cmd.name, param)
|
||||
else
|
||||
Game.player_print("Sorry you don't have permission to use the kill command on other players.")
|
||||
end
|
||||
@ -132,24 +128,25 @@ local function regular(cmd)
|
||||
Utils.cant_run(cmd.name)
|
||||
return
|
||||
end
|
||||
|
||||
if cmd.parameter == nil then
|
||||
Game.player_print('Command failed. Usage: /regular <promote, demote>, <player>')
|
||||
return
|
||||
end
|
||||
|
||||
local params = {}
|
||||
for param in string.gmatch(cmd.parameter, '%S+') do
|
||||
table.insert(params, param)
|
||||
end
|
||||
if params[2] == nil then
|
||||
Game.player_print('Command failed. Usage: /regular <promote, demote>, <player>')
|
||||
return
|
||||
elseif (params[1] == 'promote') then
|
||||
UserGroups.add_regular(params[2])
|
||||
Utils.log_command(game.player.name, cmd.name, cmd.parameter)
|
||||
elseif (params[1] == 'demote') then
|
||||
UserGroups.remove_regular(params[2])
|
||||
Utils.log_command(game.player.name, cmd.name, cmd.parameter)
|
||||
if #params == 2 then
|
||||
if params[1] == 'promote' then
|
||||
UserGroups.add_regular(params[2])
|
||||
elseif params[1] == 'demote' then
|
||||
UserGroups.remove_regular(params[2])
|
||||
else
|
||||
Game.player_print('Command failed. Usage: /regular <promote, demote>, <player>')
|
||||
end
|
||||
elseif #params == 1 and params[1] ~= 'promote' and params[1] ~= 'demote' then
|
||||
UserGroups.add_regular(params[1])
|
||||
else
|
||||
Game.player_print('Command failed. Usage: /regular <promote, demote>, <player>')
|
||||
end
|
||||
@ -270,11 +267,9 @@ local function toggle_tp_mode(cmd)
|
||||
if toggled then
|
||||
global.tp_players[index] = nil
|
||||
Game.player_print('tp mode is now off')
|
||||
Utils.log_command(game.player.name, cmd.name, 'off')
|
||||
else
|
||||
global.tp_players[index] = true
|
||||
Game.player_print('tp mode is now on - place a ghost entity to teleport there.')
|
||||
Utils.log_command(game.player.name, cmd.name, 'on')
|
||||
end
|
||||
end
|
||||
|
||||
@ -329,7 +324,6 @@ local function tempban(cmd)
|
||||
local group = get_group()
|
||||
|
||||
game.print(Utils.get_actor() .. ' put ' .. params[1] .. ' in timeout for ' .. params[2] .. ' minutes.')
|
||||
Utils.log_command(game.player.name, cmd.name, cmd.parameter)
|
||||
if group then
|
||||
group.add_player(params[1])
|
||||
if not tonumber(cmd.parameter) then
|
||||
@ -375,7 +369,6 @@ local function pool(cmd)
|
||||
end
|
||||
game.player.surface.set_tiles(t)
|
||||
game.player.surface.create_entity {name = 'fish', position = {p.x + 0.5, p.y + 5}}
|
||||
Utils.log_command(game.player.name, cmd.name, false)
|
||||
end
|
||||
end
|
||||
|
||||
@ -527,7 +520,6 @@ commands.add_command(
|
||||
function()
|
||||
if game.player and game.player.admin then
|
||||
game.player.cheat_mode = not game.player.cheat_mode
|
||||
Utils.log_command(game.player, 'hax', false)
|
||||
end
|
||||
end
|
||||
)
|
||||
@ -556,7 +548,7 @@ commands.add_command('tpmode', 'Toggles tp mode. When on place a ghost entity to
|
||||
commands.add_command('tempban', '<player> <minutes> Temporarily bans a player (Admins only)', tempban)
|
||||
commands.add_command('zoom', '<number> Sets your zoom.', zoom)
|
||||
commands.add_command('pool', 'Spawns a pool', pool)
|
||||
commands.add_command('find-player', '<player> shows an alert on the map where the player is located', find_player)
|
||||
commands.add_command('find', '<player> shows an alert on the map where the player is located', find_player)
|
||||
commands.add_command('jail', '<player> disables all actions a player can perform except chatting. (Admins only)', jail_player)
|
||||
commands.add_command('unjail', '<player> restores ability for a player to perform actions. (Admins only)', Report.unjail_player)
|
||||
commands.add_command('a', 'Admin chat. Messages all other admins (Admins only)', admin_chat)
|
||||
|
@ -2,6 +2,7 @@
|
||||
local Global = require 'utils.global'
|
||||
local Event = require 'utils.event'
|
||||
local raise_event = script.raise_event
|
||||
local ceil = math.ceil
|
||||
local max = math.max
|
||||
|
||||
-- this, things that can be done run-time
|
||||
@ -18,19 +19,15 @@ local ForceControlBuilder = {}
|
||||
-- all force data being monitored
|
||||
local forces = {}
|
||||
|
||||
-- the table holding the function that calculates the experience to next level
|
||||
local next_level_cap_calculator = {
|
||||
execute = nil
|
||||
}
|
||||
-- the function that calculates the experience to next level
|
||||
local calculate_next_level_cap = nil
|
||||
|
||||
Global.register(
|
||||
{
|
||||
forces = forces,
|
||||
next_level_cap_calculator = next_level_cap_calculator
|
||||
},
|
||||
function(tbl)
|
||||
forces = tbl.forces
|
||||
next_level_cap_calculator = tbl.next_level_cap_calculator
|
||||
end
|
||||
)
|
||||
|
||||
@ -147,11 +144,11 @@ end
|
||||
---Register the config and initialize the feature.
|
||||
---@param level_up_formula function
|
||||
function ForceControl.register(level_up_formula)
|
||||
if next_level_cap_calculator.execute then
|
||||
if calculate_next_level_cap then
|
||||
error('Can only register one force control.')
|
||||
end
|
||||
|
||||
next_level_cap_calculator.execute = level_up_formula
|
||||
calculate_next_level_cap = level_up_formula
|
||||
|
||||
return ForceControlBuilder
|
||||
end
|
||||
@ -159,7 +156,7 @@ end
|
||||
---Registers a new force to participate.
|
||||
---@param lua_force_or_name LuaForce|string
|
||||
function ForceControl.register_force(lua_force_or_name)
|
||||
if not next_level_cap_calculator.execute then
|
||||
if not calculate_next_level_cap then
|
||||
error('Can only register a force when the config has been initialized via ForceControl.register(config_table).')
|
||||
end
|
||||
local force = get_valid_force(lua_force_or_name)
|
||||
@ -169,14 +166,15 @@ function ForceControl.register_force(lua_force_or_name)
|
||||
|
||||
forces[force.name] = {
|
||||
current_experience = 0,
|
||||
total_experience = 0,
|
||||
current_level = 0,
|
||||
experience_level_up_cap = next_level_cap_calculator.execute(0)
|
||||
experience_level_up_cap = calculate_next_level_cap(0)
|
||||
}
|
||||
end
|
||||
|
||||
---Returns the ForceControlBuilder.
|
||||
function ForceControl.get_force_control_builder()
|
||||
if not next_level_cap_calculator.execute then
|
||||
if not calculate_next_level_cap then
|
||||
error('Can only get the force control builder when the config has been initialized via ForceControl.register(config_table).')
|
||||
end
|
||||
|
||||
@ -185,7 +183,8 @@ end
|
||||
|
||||
---Removes experience from a force. Won't cause de-level nor go below 0.
|
||||
---@param lua_force_or_name LuaForce|string
|
||||
---@param experience number amount of experience to add
|
||||
---@param experience number amount of experience to remove
|
||||
---@return number the experience being removed
|
||||
function ForceControl.remove_experience(lua_force_or_name, experience)
|
||||
assert_type('number', experience, 'Argument experience of function ForceControl.remove_experience')
|
||||
|
||||
@ -200,14 +199,39 @@ function ForceControl.remove_experience(lua_force_or_name, experience)
|
||||
if not force_config then
|
||||
return
|
||||
end
|
||||
|
||||
local backup_current_experience = force_config.current_experience
|
||||
force_config.current_experience = max(0, force_config.current_experience - experience)
|
||||
force_config.total_experience = (force_config.current_experience == 0) and force_config.total_experience - backup_current_experience or max(0, force_config.total_experience - experience)
|
||||
return backup_current_experience - force_config.current_experience
|
||||
end
|
||||
|
||||
---Removes experience from a force, based on a percentage of the total obtained experience
|
||||
---@param lua_force_or_name LuaForce|string
|
||||
---@param percentage number percentage of total obtained experience to remove
|
||||
---@param min_experience number minimum amount of experience to remove (optional)
|
||||
---@return number the experience being removed
|
||||
---@see ForceControl.remove_experience
|
||||
function ForceControl.remove_experience_percentage(lua_force_or_name, percentage, min_experience)
|
||||
local min_experience = min_experience ~= nil and min_experience or 0
|
||||
local force = get_valid_force(lua_force_or_name)
|
||||
if not force then
|
||||
return
|
||||
end
|
||||
local force_config = forces[force.name]
|
||||
if not force_config then
|
||||
return
|
||||
end
|
||||
|
||||
local penalty = force_config.total_experience * percentage
|
||||
penalty = (penalty >= min_experience) and ceil(penalty) or ceil(min_experience)
|
||||
return ForceControl.remove_experience(lua_force_or_name, penalty)
|
||||
end
|
||||
|
||||
---Adds experience to a force.
|
||||
---@param lua_force_or_name LuaForce|string
|
||||
---@param experience number amount of experience to add
|
||||
function ForceControl.add_experience(lua_force_or_name, experience)
|
||||
---@param resursive_call boolean whether or not the function is called recursively (optional)
|
||||
function ForceControl.add_experience(lua_force_or_name, experience, recursive_call)
|
||||
assert_type('number', experience, 'Argument experience of function ForceControl.add_experience')
|
||||
|
||||
if experience < 1 then
|
||||
@ -224,6 +248,9 @@ function ForceControl.add_experience(lua_force_or_name, experience)
|
||||
|
||||
local new_experience = force_config.current_experience + experience
|
||||
local experience_level_up_cap = force_config.experience_level_up_cap
|
||||
if not recursive_call then
|
||||
force_config.total_experience = force_config.total_experience + experience
|
||||
end
|
||||
|
||||
if (new_experience < experience_level_up_cap) then
|
||||
force_config.current_experience = new_experience
|
||||
@ -234,11 +261,10 @@ function ForceControl.add_experience(lua_force_or_name, experience)
|
||||
local new_level = force_config.current_level + 1
|
||||
force_config.current_level = new_level
|
||||
force_config.current_experience = 0
|
||||
force_config.experience_level_up_cap = next_level_cap_calculator.execute(new_level)
|
||||
|
||||
force_config.experience_level_up_cap = calculate_next_level_cap(new_level)
|
||||
raise_event(ForceControl.events.on_level_up, {level_reached = new_level, force = force})
|
||||
|
||||
ForceControl.add_experience(force, new_experience - experience_level_up_cap)
|
||||
ForceControl.add_experience(force, new_experience - experience_level_up_cap, true)
|
||||
end
|
||||
|
||||
---Return the force data as {
|
||||
@ -261,10 +287,29 @@ function ForceControl.get_force_data(lua_force_or_name)
|
||||
|
||||
return {
|
||||
current_experience = force_config.current_experience,
|
||||
total_experience = force_config.total_experience,
|
||||
current_level = force_config.current_level,
|
||||
experience_level_up_cap = force_config.experience_level_up_cap,
|
||||
experience_percentage = (force_config.current_experience / force_config.experience_level_up_cap) * 100
|
||||
}
|
||||
end
|
||||
|
||||
function ForceControl.get_formatted_force_data(lua_force_or_name)
|
||||
local force_config = ForceControl.get_force_data(lua_force_or_name)
|
||||
if not force_config then
|
||||
return
|
||||
end
|
||||
|
||||
local result =
|
||||
string.format(
|
||||
'Current experience: %d Total experience: %d Current level: %d Next level at: %d Percentage to level up: %d%%',
|
||||
force_config.current_experience,
|
||||
force_config.total_experience,
|
||||
force_config.current_level,
|
||||
force_config.experience_level_up_cap,
|
||||
math.floor(force_config.experience_percentage * 100) / 100
|
||||
)
|
||||
return result
|
||||
end
|
||||
|
||||
return ForceControl
|
||||
|
@ -86,9 +86,8 @@ local function popup(cmd)
|
||||
show_popup(p, message)
|
||||
end
|
||||
|
||||
player.print('Popup sent')
|
||||
Utils.print_admins(player.name .. ' sent a popup to all players', false)
|
||||
Utils.log_command(game.player.name, cmd.name, cmd.parameter)
|
||||
Game.player_print('Popup sent')
|
||||
Utils.print_admins(Utils.get_actor() .. ' sent a popup to all players', false)
|
||||
end
|
||||
|
||||
-- Creates a popup dialog for all players, specifically for the server upgrading factorio versions
|
||||
@ -105,9 +104,8 @@ local function popup_update(cmd)
|
||||
show_popup(p, message)
|
||||
end
|
||||
|
||||
player.print('Popup sent')
|
||||
Utils.print_admins(player.name .. ' sent a popup to all players', false)
|
||||
Utils.log_command(game.player.name, cmd.name, message)
|
||||
Game.player_print('Popup sent')
|
||||
Utils.print_admins(Utils.get_actor() .. ' sent a popup to all players', false)
|
||||
end
|
||||
|
||||
-- Creates a popup dialog for the specifically targetted player
|
||||
@ -141,8 +139,7 @@ local function popup_player(cmd)
|
||||
|
||||
show_popup(target, message)
|
||||
|
||||
player.print('Popup sent')
|
||||
Utils.log_command(game.player.name, cmd.name, cmd.parameter)
|
||||
Game.player_print('Popup sent')
|
||||
end
|
||||
|
||||
commands.add_command('popup', '<message> - Shows a popup to all connected players (Admins only)', popup)
|
||||
|
@ -207,7 +207,7 @@ function Module.jail(target_player, player)
|
||||
target_player.print('Please respond to inquiries from the admins.', {r = 1, g = 1, b = 0, a = 1})
|
||||
target_player.print(prefix_e)
|
||||
Utils.print_admins(target_player.name .. ' has been jailed by ' .. player.name)
|
||||
Utils.log_command(player, 'jail', target_player.name)
|
||||
Utils.log_command(Utils.get_actor(), 'jail', target_player.name)
|
||||
else
|
||||
-- Let admin know it didn't work.
|
||||
print('Something went wrong in the jailing of ' .. target_player.name .. '. You can still change their group via /permissions.')
|
||||
@ -264,7 +264,7 @@ function Module.unjail_player(cmd)
|
||||
target_player.print('Your ability to perform actions has been restored', {r = 0, g = 1, b = 0, a = 1})
|
||||
target_player.print(prefix_e)
|
||||
Utils.print_admins(target_player.name .. ' has been released from jail by ' .. player.name)
|
||||
Utils.log_command(player, 'unjail', target_player.name)
|
||||
Utils.log_command(Utils.get_actor(), 'unjail', target_player.name)
|
||||
else
|
||||
-- Let admin know it didn't work.
|
||||
Game.player_print('Something went wrong in the unjailing of ' .. target .. '. You can still change their group via /permissions and inform them.')
|
||||
|
159
features/silly_player_names.lua
Normal file
159
features/silly_player_names.lua
Normal file
@ -0,0 +1,159 @@
|
||||
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
|
@ -2,12 +2,6 @@
|
||||
|
||||
-- this
|
||||
local Config = {
|
||||
-- enable debug mode, shows extra messages
|
||||
debug = false,
|
||||
|
||||
-- allow cheats, primarily configured under SetupPlayer
|
||||
cheats = false,
|
||||
|
||||
-- a list of features to register and enable
|
||||
-- to disable a feature, change the flag
|
||||
features = {
|
||||
@ -49,13 +43,18 @@ local Config = {
|
||||
character_health_bonus = 1000000,
|
||||
|
||||
-- unlock all research by default, only useful when testing
|
||||
unlock_all_research = true,
|
||||
unlock_all_research = false,
|
||||
|
||||
-- adds additional items to the player force when starting in addition to defined in start_items above
|
||||
starting_items = {
|
||||
{name = 'power-armor-mk2', count = 1},
|
||||
{name = 'submachine-gun', count = 1},
|
||||
{name = 'uranium-rounds-magazine', count = 1000},
|
||||
{name = 'roboport', count = 2},
|
||||
{name = 'construction-robot', count = 50},
|
||||
{name = 'electric-energy-interface', count = 1},
|
||||
{name = 'medium-electric-pole', count = 50},
|
||||
{name = 'logistic-chest-storage', count = 50},
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -70,6 +69,12 @@ local Config = {
|
||||
|
||||
-- enables commands like /clear-void
|
||||
enable_debug_commands = false,
|
||||
|
||||
-- initial damage per tick it damages a rock to mine, can be enhanced by robot_damage_per_mining_prod_level
|
||||
robot_initial_mining_damage = 4,
|
||||
|
||||
-- damage added per level of mining productivity level research
|
||||
robot_damage_per_mining_prod_level = 1,
|
||||
},
|
||||
|
||||
-- adds the ability to collapse caves
|
||||
@ -295,8 +300,8 @@ local Config = {
|
||||
cluster_mode = true,
|
||||
|
||||
-- location of file to find the cluster definition file
|
||||
cluster_file_location = 'map_gen.Diggy.Orepattern.Tendrils',
|
||||
--cluster_file_location = 'map_gen.Diggy.Orepattern.Clusters',
|
||||
ore_pattern = require 'map_gen.Diggy.Orepattern.Tendrils',
|
||||
--ore_pattern = require 'map_gen.Diggy.Orepattern.Clusters',
|
||||
|
||||
},
|
||||
|
||||
@ -343,7 +348,7 @@ local Config = {
|
||||
-- market config
|
||||
market_spawn_position = {x = 0, y = 3},
|
||||
stone_to_surface_amount = 50,
|
||||
currency_item = 'stone',
|
||||
currency_item = 'coin',
|
||||
|
||||
-- locations where chests will be automatically cleared from currency_item
|
||||
void_chest_tiles = {
|
||||
@ -355,52 +360,42 @@ local Config = {
|
||||
|
||||
-- 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 = 50, name = 'iron-axe'},
|
||||
{level = 2, price = 50, name = 'raw-wood'},
|
||||
{level = 2, price = 20, name = 'raw-fish'},
|
||||
{level = 3, price = 50, name = 'stone-brick'},
|
||||
{level = 5, price = 125, name = 'stone-wall'},
|
||||
{level = 7, price = 25, name = 'small-lamp'},
|
||||
{level = 9, price = 50, name = 'firearm-magazine'},
|
||||
{level = 9, price = 250, name = 'pistol'},
|
||||
{level = 11, price = 850, name = 'shotgun'},
|
||||
{level = 11, price = 50, name = 'shotgun-shell'},
|
||||
{level = 14, price = 500, name = 'light-armor'},
|
||||
{level = 16, price = 850, name = 'submachine-gun'},
|
||||
{level = 16, price = 50, name = 'steel-axe'},
|
||||
{level = 19, price = 100, name = 'piercing-rounds-magazine'},
|
||||
{level = 19, price = 100, name = 'piercing-shotgun-shell'},
|
||||
{level = 21, price = 750, name = 'heavy-armor'},
|
||||
{level = 25, price = 1500, name = 'modular-armor'},
|
||||
{level = 25, price = 1000, name = 'landfill'},
|
||||
{level = 28, price = {{"stone", 900}, {"coin", 25}}, name = 'personal-roboport-equipment'},
|
||||
{level = 28, price = {{"stone", 250}, {"coin", 10}}, name = 'construction-robot'},
|
||||
{level = 32, price = {{"stone", 2500}, {"coin", 100}}, name = 'power-armor'},
|
||||
{level = 34, price = {{"stone", 150}, {"coin", 10}}, name = 'battery-equipment'},
|
||||
{level = 33, price = {{"stone", 2000}, {"coin", 75}}, name = 'fusion-reactor-equipment'},
|
||||
{level = 36, price = {{"stone", 750}, {"coin", 20}}, name = 'energy-shield-equipment'},
|
||||
{level = 1, price = 5, name = 'iron-axe'},
|
||||
{level = 2, price = 5, name = 'raw-wood'},
|
||||
{level = 2, price = 10, name = 'raw-fish'},
|
||||
{level = 3, price = 5, name = 'stone-brick'},
|
||||
{level = 5, price = 12, name = 'stone-wall'},
|
||||
{level = 7, price = 6, name = 'small-lamp'},
|
||||
{level = 9, price = 5, name = 'firearm-magazine'},
|
||||
{level = 9, price = 25, name = 'pistol'},
|
||||
{level = 11, price = 85, name = 'shotgun'},
|
||||
{level = 11, price = 5, name = 'shotgun-shell'},
|
||||
{level = 14, price = 50, name = 'light-armor'},
|
||||
{level = 16, price = 85, name = 'submachine-gun'},
|
||||
{level = 16, price = 25, name = 'steel-axe'},
|
||||
{level = 19, price = 15, name = 'piercing-rounds-magazine'},
|
||||
{level = 19, price = 15, name = 'piercing-shotgun-shell'},
|
||||
{level = 21, 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 = 1000, name = 'combat-shotgun'},
|
||||
{level = 46, price = 250, name = 'uranium-rounds-magazine'},
|
||||
{level = 58, price = {{"stone", 1500}, {"coin", 25}}, name = 'rocket-launcher'},
|
||||
{level = 58, price = {{"stone", 500}, {"coin", 5}}, name = 'rocket'},
|
||||
{level = 66, price = {{"stone", 1000}, {"coin", 10}}, name = 'explosive-rocket'},
|
||||
{level = 73, price = {{"stone", 1000}, {"coin", 200}}, name = 'satellite'},
|
||||
{level = 100, price = {{"stone", 5000}, {"coin", 9999}}, name = 'atomic-bomb'},
|
||||
{level = 58, price = 250, name = 'rocket-launcher'},
|
||||
{level = 58, price = 50, name = 'rocket'},
|
||||
{level = 66, price = 100, name = 'explosive-rocket'},
|
||||
{level = 73, price = 2000, name = 'satellite'},
|
||||
{level = 100, price = 1, name = 'iron-stick'},
|
||||
}
|
||||
),
|
||||
|
||||
buffs = { --Define new buffs here, they are handed out for each level
|
||||
{prototype = {name = 'mining_speed', value = 5}},
|
||||
{prototype = {name = 'inventory_slot', value = 1}},
|
||||
{prototype = {name = 'stone_automation', value = 3}},
|
||||
},
|
||||
|
||||
-- controls the formula for calculating level up costs in stone sent to surface
|
||||
difficulty_scale = 25, -- Diggy default 25. Higher increases difficulty, lower decreases (Only affects the stone requirement/cost to level up) (Only integers has been tested succesful)
|
||||
start_stone = 50, -- Diggy default 50. This sets the price for the first level.
|
||||
cost_precision = 2, -- Diggy default 2. This sets the precision of the stone requirements to level up. E.g. 1234 becomes 1200 with precision 2 and 1230 with precision 3.
|
||||
},
|
||||
|
||||
|
||||
@ -409,7 +404,40 @@ local Config = {
|
||||
enabled = true,
|
||||
autojail = true,
|
||||
allowed_collapses_first_hour = 4
|
||||
}
|
||||
},
|
||||
|
||||
Experience = {
|
||||
enabled = true,
|
||||
-- controls the formula for calculating level up costs in stone sent to surface
|
||||
difficulty_scale = 25, -- Diggy default 25. Higher increases experience requirement climb
|
||||
first_lvl_xp = 600, -- Diggy default 600. This sets the price for the first level.
|
||||
xp_fine_tune = 200, -- Diggy default 200. This value is used to fine tune the overall requirement climb without affecting the speed
|
||||
cost_precision = 3, -- Diggy default 3. This sets the precision of the required experience to level up. E.g. 1234 becomes 1200 with precision 2 and 1230 with precision 3.
|
||||
|
||||
-- percentage * mining productivity level gets added to mining speed
|
||||
mining_speed_productivity_multiplier = 5,
|
||||
|
||||
XP = {
|
||||
['sand-rock-big'] = 5,
|
||||
['rock-huge'] = 10,
|
||||
['rocket_launch'] = 5000, -- XP reward for a single rocket launch
|
||||
['science-pack-1'] = 2,
|
||||
['science-pack-2'] = 4,
|
||||
['science-pack-3'] = 10,
|
||||
['military-science-pack'] = 8,
|
||||
['production-science-pack'] = 25,
|
||||
['high-tech-science-pack'] = 50,
|
||||
['space-science-pack'] = 10,
|
||||
['enemy_killed'] = 10, -- Base XP for killing biters and spitters. This value is multiplied by the alien_coin_modifiers from ArtefactHunting
|
||||
['death-penalty'] = 0.005, -- XP deduct in percentage of total experience when a player dies (Diggy default: 0.005 which equals 0.5%)
|
||||
},
|
||||
|
||||
buffs = { --Define new buffs here, they are handed out for each level.
|
||||
['mining_speed'] = {value = 5},
|
||||
['inventory_slot'] = {value = 1},
|
||||
['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)
|
||||
},
|
||||
},
|
||||
|
||||
},
|
||||
}
|
||||
|
@ -53,7 +53,7 @@ function Debug.print_serpent(message)
|
||||
end
|
||||
|
||||
--[[--
|
||||
Shows the given message if _DEBUG == true for a given position.
|
||||
Shows the given message if debug is on.
|
||||
|
||||
@param x number
|
||||
@param y number
|
||||
|
@ -6,10 +6,11 @@
|
||||
local Event = require 'utils.event'
|
||||
local Global = require 'utils.global'
|
||||
local Token = require 'utils.global_token'
|
||||
local Task = require 'utils.task'
|
||||
local Task = require 'utils.Task'
|
||||
local AlienEvolutionProgress = require 'map_gen.Diggy.AlienEvolutionProgress'
|
||||
local Debug = require 'map_gen.Diggy.Debug'
|
||||
local Template = require 'map_gen.Diggy.Template'
|
||||
local CreateParticles = require 'features.create_particles'
|
||||
local random = math.random
|
||||
local floor = math.floor
|
||||
local ceil = math.ceil
|
||||
@ -54,16 +55,7 @@ local do_alien_mining = Token.register(function(params)
|
||||
local particle_count = 16 - ((#rocks - 1) * 5)
|
||||
for _, rock in pairs(rocks) do
|
||||
raise_event(defines.events.on_entity_died, {entity = rock})
|
||||
for _ = particle_count, 1, -1 do
|
||||
create_entity({
|
||||
position = rock.position,
|
||||
name = 'stone-particle',
|
||||
movement = {random(-5, 5) * 0.01, random(-5, 5) * 0.01},
|
||||
frame_speed = 1,
|
||||
vertical_speed = random(12, 14) * 0.01,
|
||||
height = random(9, 11) * 0.1,
|
||||
})
|
||||
end
|
||||
CreateParticles.destroy_rock(create_entity, particle_count, rock.position)
|
||||
rock.destroy()
|
||||
end
|
||||
end
|
||||
|
@ -24,17 +24,13 @@ local function redraw_table(data)
|
||||
|
||||
data.frame.caption = 'Scoretable'
|
||||
|
||||
local score_keys = ScoreTable.all_keys()
|
||||
|
||||
for _, data in pairs(score_keys) do
|
||||
local val = ScoreTable.get(data)
|
||||
|
||||
for name, value in pairs(ScoreTable.all()) do
|
||||
local table = list.add({type = 'table', column_count = 2})
|
||||
|
||||
local key = table.add({type = 'label', name = 'Diggy.ArtefactHunting.Frame.List.Key', caption = data})
|
||||
local key = table.add({type = 'label', name = 'Diggy.ArtefactHunting.Frame.List.Key', caption = name})
|
||||
key.style.minimal_width = 175
|
||||
|
||||
local val = table.add({type = 'label', name = 'Diggy.ArtefactHunting.Frame.List.Val', caption = utils.comma_value(val)})
|
||||
local val = table.add({type = 'label', name = 'Diggy.ArtefactHunting.Frame.List.Val', caption = utils.comma_value(value)})
|
||||
val.style.minimal_width = 225
|
||||
end
|
||||
end
|
||||
|
@ -6,193 +6,65 @@
|
||||
-- dependencies
|
||||
local Event = require 'utils.event'
|
||||
local Global = require 'utils.global'
|
||||
local Game = require 'utils.game'
|
||||
local Scanner = require 'map_gen.Diggy.Scanner'
|
||||
local Template = require 'map_gen.Diggy.Template'
|
||||
local ScoreTable = require 'map_gen.Diggy.ScoreTable'
|
||||
local Debug = require 'map_gen.Diggy.Debug'
|
||||
local CreateParticles = require 'features.create_particles'
|
||||
local insert = table.insert
|
||||
local random = math.random
|
||||
local raise_event = script.raise_event
|
||||
|
||||
-- todo remove this dependency
|
||||
local ResourceConfig = require 'map_gen.Diggy.Config'.features.ScatteredResources
|
||||
|
||||
local Perlin = require 'map_gen.shared.perlin_noise'
|
||||
local Simplex = require 'map_gen.shared.simplex_noise'
|
||||
|
||||
-- this
|
||||
local DiggyHole = {}
|
||||
|
||||
-- keeps track of the amount of times per player when they mined with a full inventory in a row
|
||||
local full_inventory_mining_cache = {}
|
||||
|
||||
-- keeps track of the buffs for the bot mining mining_efficiency
|
||||
local robot_mining = {
|
||||
damage = 0,
|
||||
active_modifier = 0,
|
||||
research_modifier = 0,
|
||||
}
|
||||
|
||||
Global.register({
|
||||
full_inventory_mining_cache = full_inventory_mining_cache,
|
||||
bot_mining_damage = robot_mining,
|
||||
}, function (tbl)
|
||||
full_inventory_mining_cache = tbl.full_inventory_mining_cache
|
||||
robot_mining = tbl.bot_mining_damage
|
||||
end)
|
||||
|
||||
local function reset_player_full_inventory_cache(player)
|
||||
if not full_inventory_mining_cache[player.index] then
|
||||
return
|
||||
end
|
||||
local function update_robot_mining_damage()
|
||||
-- remove the current buff
|
||||
local old_modifier = robot_mining.damage - robot_mining.active_modifier
|
||||
|
||||
full_inventory_mining_cache[player.index] = nil
|
||||
-- update the active modifier
|
||||
robot_mining.active_modifier = robot_mining.research_modifier
|
||||
|
||||
-- add the new active modifier to the non-buffed modifier
|
||||
robot_mining.damage = old_modifier + robot_mining.active_modifier
|
||||
|
||||
ScoreTable.set('Robot mining damage', robot_mining.damage)
|
||||
end
|
||||
|
||||
local full_inventory_message = 'Miner, you have a full inventory!\n\nMake sure to empty it before you continue digging.'
|
||||
|
||||
local function trigger_inventory_warning(player)
|
||||
local player_index = player.index
|
||||
local count = full_inventory_mining_cache[player_index]
|
||||
if not count then
|
||||
full_inventory_mining_cache[player_index] = 1
|
||||
player.print('## - ' .. full_inventory_message, {r = 1, g = 1, b = 0, a = 1})
|
||||
player.play_sound{path='utility/new_objective', volume_modifier = 1 }
|
||||
return
|
||||
end
|
||||
|
||||
full_inventory_mining_cache[player_index] = count + 1
|
||||
|
||||
if count % 5 == 0 then
|
||||
require 'features.gui.popup'.player(player, full_inventory_message)
|
||||
end
|
||||
end
|
||||
|
||||
--[[--
|
||||
Triggers a diggy diggy hole for a given sand-rock-big or rock-huge.
|
||||
|
||||
Will return true even if the tile behind it is immune.
|
||||
|
||||
@param entity LuaEntity
|
||||
]]
|
||||
---Triggers a diggy diggy hole for a given sand-rock-big or rock-huge.
|
||||
---@param entity LuaEntity
|
||||
local function diggy_hole(entity)
|
||||
local name = entity.name
|
||||
if name ~= 'sand-rock-big' and name ~= 'rock-huge' then
|
||||
return
|
||||
end
|
||||
|
||||
local tiles = {}
|
||||
local rocks = {}
|
||||
local surface = entity.surface
|
||||
local position = entity.position
|
||||
local x = position.x
|
||||
local y = position.y
|
||||
|
||||
local out_of_map_found = Scanner.scan_around_position(surface, position, 'out-of-map');
|
||||
local distance = ResourceConfig.distance(x, y)
|
||||
|
||||
-- source of noise for resource generation
|
||||
-- index determines offset
|
||||
-- '-1' is reserved for cluster mode
|
||||
-- compound clusters use as many indexes as needed > 1
|
||||
local base_seed
|
||||
local function seeded_noise(surface, x, y, index, sources)
|
||||
base_seed = base_seed or surface.map_gen_settings.seed + surface.index + 4000
|
||||
local noise = 0
|
||||
for _, settings in ipairs(sources) do
|
||||
settings.type = settings.type or 'perlin'
|
||||
settings.offset = settings.offset or 0
|
||||
if settings.type == 'zero' then
|
||||
noise = noise + 0
|
||||
elseif settings.type == 'one' then
|
||||
noise = noise + settings.weight * 1
|
||||
elseif settings.type == 'perlin' then
|
||||
noise = noise + settings.weight * Perlin.noise(x/settings.variance, y/settings.variance,
|
||||
base_seed + 2000*index + settings.offset)
|
||||
elseif settings.type == 'simplex' then
|
||||
noise = noise + settings.weight * Simplex.d2(x/settings.variance, y/settings.variance,
|
||||
base_seed + 2000*index + settings.offset)
|
||||
else
|
||||
Debug.print('noise type \'' .. settings.type .. '\' not recognized')
|
||||
end
|
||||
|
||||
end
|
||||
return noise
|
||||
end
|
||||
|
||||
-- global config values
|
||||
local resource_richness_weights = ResourceConfig.resource_richness_weights
|
||||
local resource_richness_weights_sum = 0
|
||||
for _, weight in pairs(resource_richness_weights) do
|
||||
resource_richness_weights_sum = resource_richness_weights_sum + weight
|
||||
end
|
||||
|
||||
local s_resource_weights = ResourceConfig.scattered_resource_weights
|
||||
local s_resource_weights_sum = 0
|
||||
for _, weight in pairs(s_resource_weights) do
|
||||
s_resource_weights_sum = s_resource_weights_sum + weight
|
||||
end
|
||||
|
||||
-- compound cluster spawning
|
||||
local c_mode = ResourceConfig.cluster_mode
|
||||
-- local c_clusters = Config.features.ScatteredResources.clusters
|
||||
local c_clusters = require(ResourceConfig.cluster_file_location)
|
||||
if ('table' ~= type(c_clusters)) then
|
||||
error('cluster_file_location invalid')
|
||||
end
|
||||
|
||||
local c_count = 0
|
||||
for _, cluster in ipairs(c_clusters) do
|
||||
c_count = c_count + 1
|
||||
cluster.weights_sum = 0
|
||||
for _, weight in pairs(cluster.weights) do
|
||||
cluster.weights_sum = cluster.weights_sum + weight
|
||||
end
|
||||
end
|
||||
|
||||
local function spawn_cluster_resource(surface, x, y, cluster_index, cluster)
|
||||
for name, weight in pairs(cluster.weights) do
|
||||
if name == 'skip' then return false end
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
local huge_rock_inserted = false
|
||||
for _, position in pairs(out_of_map_found) do
|
||||
insert(tiles, {name = 'dirt-' .. random(1, 7), position = position})
|
||||
-- if (random() > 0.50) then
|
||||
-- insert(rocks, {name = 'rock-huge', position = position})
|
||||
|
||||
|
||||
if c_mode then
|
||||
for index,cluster in ipairs(c_clusters) do
|
||||
if distance >= cluster.min_distance and cluster.noise_settings.type ~= 'skip' then
|
||||
if cluster.noise_settings.type == "connected_tendril" then
|
||||
local noise = seeded_noise(surface, x, y, index, cluster.noise_settings.sources)
|
||||
if -1 * cluster.noise_settings.threshold < noise and noise < cluster.noise_settings.threshold then
|
||||
if spawn_cluster_resource(surface, x, y, index, cluster) then
|
||||
insert(rocks, {name = 'rock-huge', position = position})
|
||||
huge_rock_inserted = true
|
||||
end
|
||||
end
|
||||
elseif cluster.noise_settings.type == "fragmented_tendril" then
|
||||
local noise1 = seeded_noise(surface, x, y, index, cluster.noise_settings.sources)
|
||||
local noise2 = seeded_noise(surface, x, y, index, cluster.noise_settings.discriminator)
|
||||
if -1 * cluster.noise_settings.threshold < noise1 and noise1 < cluster.noise_settings.threshold
|
||||
and -1 * cluster.noise_settings.discriminator_threshold < noise2
|
||||
and noise2 < cluster.noise_settings.discriminator_threshold then
|
||||
if spawn_cluster_resource(surface, x, y, index, cluster) then
|
||||
insert(rocks, {name = 'rock-huge', position = position})
|
||||
huge_rock_inserted = true
|
||||
end
|
||||
end
|
||||
else
|
||||
local noise = seeded_noise(surface, x, y, index, cluster.noise_settings.sources)
|
||||
if noise >= cluster.noise_settings.threshold then
|
||||
if spawn_cluster_resource(surface, x, y, index, cluster) then
|
||||
insert(rocks, {name = 'rock-huge', position = position})
|
||||
huge_rock_inserted = true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if (huge_rock_inserted == false) then
|
||||
insert(rocks, {name = 'sand-rock-big', position = position})
|
||||
for _, void_position in ipairs(out_of_map_found) do
|
||||
insert(tiles, {name = 'dirt-' .. random(1, 7), position = void_position })
|
||||
if random() < 0.35 then
|
||||
insert(rocks, {name = 'rock-huge', position = void_position })
|
||||
else
|
||||
insert(rocks, {name = 'sand-rock-big', position = void_position })
|
||||
end
|
||||
end
|
||||
|
||||
@ -226,10 +98,20 @@ end
|
||||
Registers all event handlers.
|
||||
]]
|
||||
function DiggyHole.register(config)
|
||||
robot_mining.damage = config.robot_initial_mining_damage
|
||||
ScoreTable.set('Robot mining damage', robot_mining.damage)
|
||||
ScoreTable.reset('Void removed')
|
||||
|
||||
Event.add(defines.events.on_entity_died, function (event)
|
||||
diggy_hole(event.entity)
|
||||
local entity = event.entity
|
||||
local name = entity.name
|
||||
if name ~= 'sand-rock-big' and name ~= 'rock-huge' then
|
||||
return
|
||||
end
|
||||
diggy_hole(entity)
|
||||
if event.cause then
|
||||
CreateParticles.destroy_rock(entity.surface.create_entity, 10, entity.position)
|
||||
end
|
||||
end)
|
||||
|
||||
Event.add(defines.events.on_entity_damaged, function (event)
|
||||
@ -257,11 +139,8 @@ function DiggyHole.register(config)
|
||||
end
|
||||
|
||||
local health = entity.health
|
||||
local remove = event.buffer.remove
|
||||
|
||||
health = health - 10
|
||||
remove({name = 'stone', count = 100})
|
||||
remove({name = 'coal', count = 100})
|
||||
health = health - robot_mining.damage
|
||||
event.buffer.clear()
|
||||
|
||||
local graphics_variation = entity.graphics_variation
|
||||
local create_entity = entity.surface.create_entity
|
||||
@ -270,12 +149,14 @@ function DiggyHole.register(config)
|
||||
|
||||
if health < 1 then
|
||||
raise_event(defines.events.on_entity_died, {entity = entity, force = force})
|
||||
CreateParticles.mine_rock(create_entity, 6, position)
|
||||
entity.destroy()
|
||||
return
|
||||
end
|
||||
|
||||
entity.destroy()
|
||||
|
||||
local rock = create_entity({name = name, position = position})
|
||||
CreateParticles.mine_rock(create_entity, 1, position)
|
||||
rock.graphics_variation = graphics_variation
|
||||
rock.order_deconstruction(force)
|
||||
rock.health = health
|
||||
@ -284,24 +165,14 @@ function DiggyHole.register(config)
|
||||
Event.add(defines.events.on_player_mined_entity, function (event)
|
||||
local entity = event.entity
|
||||
local name = entity.name
|
||||
|
||||
if name == 'sand-rock-big' or name == 'rock-huge' then
|
||||
event.buffer.remove({name = 'coal', count = 100})
|
||||
|
||||
-- this logic can be replaced once we've fully replaced the stone to surface functionality
|
||||
if enable_digging_warning then
|
||||
local player = Game.get_player_by_index(event.player_index)
|
||||
if player and player.valid then
|
||||
if player.get_main_inventory().can_insert({name = 'stone'}) then
|
||||
reset_player_full_inventory_cache(player)
|
||||
else
|
||||
trigger_inventory_warning(player)
|
||||
end
|
||||
end
|
||||
end
|
||||
if name ~= 'sand-rock-big' and name ~= 'rock-huge' then
|
||||
return
|
||||
end
|
||||
|
||||
event.buffer.clear()
|
||||
|
||||
diggy_hole(entity)
|
||||
CreateParticles.mine_rock(entity.surface.create_entity, 6, entity.position)
|
||||
end)
|
||||
|
||||
Event.add(defines.events.on_robot_mined_tile, function (event)
|
||||
@ -316,6 +187,18 @@ function DiggyHole.register(config)
|
||||
ScoreTable.increment('Void removed')
|
||||
end)
|
||||
|
||||
Event.add(defines.events.on_research_finished, function (event)
|
||||
local new_modifier = event.research.force.mining_drill_productivity_bonus * 50 * config.robot_damage_per_mining_prod_level
|
||||
|
||||
if (robot_mining.research_modifier == new_modifier) then
|
||||
-- something else was researched
|
||||
return
|
||||
end
|
||||
|
||||
robot_mining.research_modifier = new_modifier
|
||||
update_robot_mining_damage()
|
||||
end)
|
||||
|
||||
if config.enable_debug_commands then
|
||||
commands.add_command('clear-void', '<left top x> <left top y> <width> <height> <surface index> triggers Template.insert for the given area.', function(cmd)
|
||||
local params = {}
|
||||
@ -351,6 +234,7 @@ end
|
||||
|
||||
function DiggyHole.on_init()
|
||||
game.forces.player.technologies['landfill'].enabled = false
|
||||
game.forces.player.technologies['atomic-bomb'].enabled = false
|
||||
end
|
||||
|
||||
return DiggyHole
|
||||
|
331
map_gen/Diggy/Feature/Experience.lua
Normal file
331
map_gen/Diggy/Feature/Experience.lua
Normal file
@ -0,0 +1,331 @@
|
||||
-- dependencies
|
||||
local Event = require 'utils.event'
|
||||
local Game = require 'utils.game'
|
||||
local Global = require 'utils.global'
|
||||
local ForceControl = require 'features.force_control'
|
||||
local Debug = require 'map_gen.Diggy.Debug'
|
||||
|
||||
-- Will be registered in Experience.register
|
||||
local ForceControl_builder = {}
|
||||
|
||||
-- this
|
||||
local Experience = {}
|
||||
|
||||
local mining_efficiency = {
|
||||
active_modifier = 0,
|
||||
research_modifier = 0,
|
||||
level_modifier = 0,
|
||||
}
|
||||
|
||||
local inventory_slots = {
|
||||
active_modifier = 0,
|
||||
research_modifier = 0,
|
||||
level_modifier = 0,
|
||||
}
|
||||
|
||||
local health_bonus = {
|
||||
active_modifier = 0,
|
||||
research_modifier = 0,
|
||||
level_modifier = 0,
|
||||
}
|
||||
|
||||
Global.register({
|
||||
mining_efficiency = mining_efficiency,
|
||||
inventory_slots = inventory_slots,
|
||||
health_bonus = health_bonus
|
||||
}, function(tbl)
|
||||
mining_efficiency = tbl.mining_efficiency
|
||||
inventory_slots = tbl.inventory_slots
|
||||
health_bonus = tbl.health_bonus
|
||||
end)
|
||||
|
||||
|
||||
local config = {}
|
||||
local string_format = string.format
|
||||
local alien_coin_modifiers = require 'map_gen.Diggy.Config'.features.ArtefactHunting.alien_coin_modifiers
|
||||
local floor = math.floor
|
||||
|
||||
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 difficulty_scale = floor(Config.difficulty_scale)
|
||||
local level_fine_tune = floor(Config.xp_fine_tune)
|
||||
local start_value = (floor(Config.first_lvl_xp) * 0.5)
|
||||
local precision = (floor(Config.cost_precision))
|
||||
local function formula(level)
|
||||
return (
|
||||
difficulty_scale * (level) ^ 3
|
||||
+ (level_fine_tune + start_value) * (level) ^ 2
|
||||
+ start_value * (level)
|
||||
- difficulty_scale * (level)
|
||||
- level_fine_tune * (level)
|
||||
)
|
||||
end
|
||||
local value = formula(level_reached + 1)
|
||||
local lower_value = formula(level_reached)
|
||||
value = value - (value % (10 ^ (floor(log(value,10)) - precision)))
|
||||
if lower_value == 0 then
|
||||
return value - lower_value
|
||||
end
|
||||
lower_value = lower_value - (lower_value % (10 ^ (floor(log(lower_value, 10)) - precision)))
|
||||
return value - lower_value
|
||||
end)
|
||||
|
||||
---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 level_up number a level if updating as part of a level up (optional)
|
||||
function Experience.update_mining_speed(force, level_up)
|
||||
level_up = level_up ~= nil and level_up or 0
|
||||
local buff = config.buffs['mining_speed']
|
||||
if level_up > 0 and buff ~= nil then
|
||||
local value = (buff.double_level ~= nil and level_up % buff.double_level == 0) and buff.value * 2 or buff.value
|
||||
mining_efficiency.level_modifier = mining_efficiency.level_modifier + (value * 0.01)
|
||||
end
|
||||
-- remove the current buff
|
||||
local old_modifier = force.manual_mining_speed_modifier - mining_efficiency.active_modifier
|
||||
|
||||
-- update the active modifier
|
||||
mining_efficiency.active_modifier = mining_efficiency.research_modifier + mining_efficiency.level_modifier
|
||||
|
||||
-- add the new active modifier to the non-buffed modifier
|
||||
force.manual_mining_speed_modifier = old_modifier + mining_efficiency.active_modifier
|
||||
end
|
||||
|
||||
---Updates a forces inventory slots. By removing active modifiers and re-adding
|
||||
---@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)
|
||||
function Experience.update_inventory_slots(force, level_up)
|
||||
level_up = level_up ~= nil and level_up or 0
|
||||
local buff = config.buffs['inventory_slot']
|
||||
if level_up > 0 and buff ~= nil then
|
||||
local value = (buff.double_level ~= nil and level_up % buff.double_level == 0) and buff.value * 2 or buff.value
|
||||
inventory_slots.level_modifier = inventory_slots.level_modifier + value
|
||||
end
|
||||
|
||||
-- remove the current buff
|
||||
local old_modifier = force.character_inventory_slots_bonus - inventory_slots.active_modifier
|
||||
|
||||
-- update the active modifier
|
||||
inventory_slots.active_modifier = inventory_slots.research_modifier + inventory_slots.level_modifier
|
||||
|
||||
-- add the new active modifier to the non-buffed modifier
|
||||
force.character_inventory_slots_bonus = old_modifier + inventory_slots.active_modifier
|
||||
end
|
||||
|
||||
---Updates a forces inventory slots. By removing active modifiers and re-adding
|
||||
---@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)
|
||||
function Experience.update_health_bonus(force, level_up)
|
||||
level_up = level_up ~= nil and level_up or 0
|
||||
local buff = config.buffs['health_bonus']
|
||||
if level_up > 0 and buff ~= nil then
|
||||
local value = (buff.double_level ~= nil and level_up%buff.double_level == 0) and buff.value*2 or buff.value
|
||||
health_bonus.level_modifier = health_bonus.level_modifier + value
|
||||
end
|
||||
|
||||
-- remove the current buff
|
||||
local old_modifier = force.character_health_bonus - health_bonus.active_modifier
|
||||
|
||||
-- update the active modifier
|
||||
health_bonus.active_modifier = health_bonus.research_modifier + health_bonus.level_modifier
|
||||
|
||||
-- add the new active modifier to the non-buffed modifier
|
||||
force.character_health_bonus = old_modifier + health_bonus.active_modifier
|
||||
end
|
||||
|
||||
-- declaration of variables to prevent table lookups @see Experience.register
|
||||
local sand_rock_xp
|
||||
local rock_huge_xp
|
||||
|
||||
---Awards experience when a rock has been mined
|
||||
---@param event LuaEvent
|
||||
local function on_player_mined_entity(event)
|
||||
local entity = event.entity
|
||||
local player_index = event.player_index
|
||||
local force = Game.get_player_by_index(player_index).force
|
||||
local exp
|
||||
if entity.name == 'sand-rock-big' then
|
||||
exp = sand_rock_xp
|
||||
elseif entity.name == 'rock-huge' then
|
||||
exp = rock_huge_xp
|
||||
else
|
||||
return
|
||||
end
|
||||
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)
|
||||
ForceControl.add_experience(force, exp)
|
||||
end
|
||||
|
||||
---Awards experience when a research has finished, based on ingredient cost of research
|
||||
---@param event LuaEvent
|
||||
local function on_research_finished(event)
|
||||
local research = event.research
|
||||
local force = research.force
|
||||
local award_xp = 0
|
||||
|
||||
for _, ingredient in pairs(research.research_unit_ingredients) do
|
||||
local name = ingredient.name
|
||||
local reward = config.XP[name]
|
||||
award_xp = award_xp + reward
|
||||
end
|
||||
local exp = award_xp * research.research_unit_count
|
||||
local text = string_format('Research completed! +%d XP', exp)
|
||||
for _, p in pairs(game.connected_players) do
|
||||
local player_index = p.index
|
||||
Game.print_player_floating_text_position(player_index, text, {r = 144, g = 202, b = 249}, -1, -0.5)
|
||||
end
|
||||
ForceControl.add_experience(force, exp)
|
||||
|
||||
|
||||
local current_modifier = mining_efficiency.research_modifier
|
||||
local new_modifier = force.mining_drill_productivity_bonus * config.mining_speed_productivity_multiplier * 0.5
|
||||
|
||||
if (current_modifier == new_modifier) then
|
||||
-- something else was researched
|
||||
return
|
||||
end
|
||||
|
||||
mining_efficiency.research_modifier = new_modifier
|
||||
inventory_slots.research_modifier = force.mining_drill_productivity_bonus * 50 -- 1 per level
|
||||
|
||||
Experience.update_inventory_slots(force, 0)
|
||||
Experience.update_mining_speed(force, 0)
|
||||
|
||||
game.forces.player.technologies['landfill'].enabled = false
|
||||
end
|
||||
|
||||
---Awards experience when a rocket has been launched
|
||||
---@param event LuaEvent
|
||||
local function on_rocket_launched(event)
|
||||
local exp = config.XP['rocket_launch']
|
||||
local force = event.force
|
||||
local text = string_format('Rocket launched! +%d XP', exp)
|
||||
for _, p in pairs(game.connected_players) do
|
||||
local player_index = p.index
|
||||
Game.print_player_floating_text_position(player_index, text, {r = 144, g = 202, b = 249},-1, -0.5)
|
||||
end
|
||||
ForceControl.add_experience(force, exp)
|
||||
end
|
||||
|
||||
---Awards experience when a player kills an enemy, based on type of enemy
|
||||
---@param event LuaEvent
|
||||
local function on_entity_died (event)
|
||||
local entity = event.entity
|
||||
local force = event.force
|
||||
|
||||
local cause = event.cause
|
||||
|
||||
--For bot mining
|
||||
if not cause or cause.type ~= 'player' or not cause.valid then
|
||||
local exp
|
||||
if force.name == 'player' then
|
||||
if entity.name == 'sand-rock-big' then
|
||||
exp = floor(sand_rock_xp/2)
|
||||
elseif entity.name == 'rock-huge' then
|
||||
exp = floor(rock_huge_xp/2)
|
||||
else
|
||||
return
|
||||
end
|
||||
elseif 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]
|
||||
local text = string_format('+ %d XP', exp)
|
||||
Game.print_floating_text(cause.surface, cause.position, text, {r = 144, g = 202, b = 249})
|
||||
ForceControl.add_experience(force, exp)
|
||||
return
|
||||
else
|
||||
return
|
||||
end
|
||||
local text = string_format('+ %d XP', exp)
|
||||
Game.print_floating_text(entity.surface, entity.position, text, {r = 144, g = 202, b = 249})
|
||||
ForceControl.add_experience(force, exp)
|
||||
return
|
||||
end
|
||||
|
||||
if entity.force.name ~= 'enemy' then
|
||||
return
|
||||
end
|
||||
|
||||
local exp = config.XP['enemy_killed'] * alien_coin_modifiers[entity.name]
|
||||
local text = string_format('+ %d XP', exp)
|
||||
local player_index = cause.player.index
|
||||
Game.print_player_floating_text_position(player_index, text, {r = 144, g = 202, b = 249},-1, -0.5)
|
||||
ForceControl.add_experience(force, exp)
|
||||
end
|
||||
|
||||
---Deducts experience when a player respawns, based on a percentage of total experience
|
||||
---@param event LuaEvent
|
||||
local function on_player_respawned(event)
|
||||
local player = Game.get_player_by_index(event.player_index)
|
||||
local force = player.force
|
||||
local exp = ForceControl.remove_experience_percentage(force, config.XP['death-penalty'], 50)
|
||||
local text = string_format('%s died! -%d XP', player.name, exp)
|
||||
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)
|
||||
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 = {}
|
||||
---Get experiment requirement for a given level
|
||||
---Primarily used for the market GUI to display total experience required to unlock a specific item
|
||||
---@param level number a number specifying the level
|
||||
---@return number required total experience to reach supplied level
|
||||
function Experience.calculate_level_xp(level)
|
||||
if level_table[level] == nil then
|
||||
local value
|
||||
if level == 1 then
|
||||
value = level_up_formula(level-1)
|
||||
else
|
||||
value = level_up_formula(level-1)+Experience.calculate_level_xp(level-1)
|
||||
end
|
||||
table.insert(level_table, level, value)
|
||||
end
|
||||
return level_table[level]
|
||||
end
|
||||
|
||||
function Experience.register(cfg)
|
||||
config = cfg
|
||||
|
||||
--Adds the function on how to calculate level caps (When to level up)
|
||||
ForceControl_builder = ForceControl.register(level_up_formula)
|
||||
|
||||
--Adds a function that'll be executed at every level up
|
||||
ForceControl_builder.register_on_every_level(function (level_reached, force)
|
||||
force.print(string_format('%s Leveled up to %d!', '## - ', level_reached))
|
||||
force.play_sound{path='utility/new_objective', volume_modifier = 1 }
|
||||
local Experience = require 'map_gen.Diggy.Feature.Experience'
|
||||
Experience.update_inventory_slots(force, level_reached)
|
||||
Experience.update_mining_speed(force, level_reached)
|
||||
Experience.update_health_bonus(force, level_reached)
|
||||
local MarketExchange = require 'map_gen.Diggy.Feature.MarketExchange'
|
||||
local market = MarketExchange.get_market()
|
||||
MarketExchange.update_market_contents(market, force)
|
||||
MarketExchange.update_gui()
|
||||
end)
|
||||
|
||||
-- Events
|
||||
Event.add(defines.events.on_player_mined_entity, on_player_mined_entity)
|
||||
Event.add(defines.events.on_research_finished, on_research_finished)
|
||||
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_entity_died, on_entity_died)
|
||||
|
||||
-- Prevents table lookup thousands of times
|
||||
sand_rock_xp = config.XP['sand-rock-big']
|
||||
rock_huge_xp = config.XP['rock-huge']
|
||||
end
|
||||
|
||||
function Experience.on_init()
|
||||
--Adds the 'player' force to participate in the force control system.
|
||||
local force = game.forces.player
|
||||
ForceControl.register_force(force)
|
||||
end
|
||||
|
||||
return Experience
|
@ -9,128 +9,33 @@ 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 Global = require 'utils.global'
|
||||
local Game = require 'utils.game'
|
||||
local MarketUnlockables = require 'map_gen.Diggy.MarketUnlockables'
|
||||
local calculate_level = MarketUnlockables.calculate_level
|
||||
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'
|
||||
local prefix = '## - '
|
||||
|
||||
-- this
|
||||
local MarketExchange = {}
|
||||
|
||||
local config = {}
|
||||
|
||||
local stone_tracker = {
|
||||
stone_sent_to_surface = 0,
|
||||
previous_stone_sent_to_surface = 0,
|
||||
current_level = 0,
|
||||
}
|
||||
|
||||
local stone_collecting = {
|
||||
initial_value = 0,
|
||||
active_modifier = 0,
|
||||
research_modifier = 0,
|
||||
market_modifier = 0,
|
||||
}
|
||||
|
||||
local mining_efficiency = {
|
||||
active_modifier = 0,
|
||||
research_modifier = 0,
|
||||
market_modifier = 0,
|
||||
}
|
||||
|
||||
local inventory_slots = {
|
||||
active_modifier = 0,
|
||||
research_modifier = 0,
|
||||
market_modifier = 0,
|
||||
}
|
||||
|
||||
Global.register({
|
||||
stone_collecting = stone_collecting,
|
||||
stone_tracker = stone_tracker,
|
||||
mining_efficiency = mining_efficiency,
|
||||
inventory_slots = inventory_slots,
|
||||
}, function(tbl)
|
||||
stone_collecting = tbl.stone_collecting
|
||||
stone_tracker = tbl.stone_tracker
|
||||
mining_efficiency = tbl.mining_efficiency
|
||||
inventory_slots = tbl.inventory_slots
|
||||
end)
|
||||
|
||||
local function send_stone_to_surface(total)
|
||||
stone_tracker.previous_stone_sent_to_surface = stone_tracker.stone_sent_to_surface
|
||||
stone_tracker.stone_sent_to_surface = stone_tracker.stone_sent_to_surface + total
|
||||
end
|
||||
|
||||
local on_market_timeout_finished = Token.register(function(params)
|
||||
Template.market(params.surface, params.position, params.player_force, {})
|
||||
|
||||
local tiles = {}
|
||||
for _, position in pairs(params.void_chest_tiles) do
|
||||
insert(tiles, {name = 'tutorial-grid', position = position})
|
||||
end
|
||||
|
||||
params.surface.set_tiles(tiles)
|
||||
Template.market(params.surface, params.position, params.player_force)
|
||||
end)
|
||||
|
||||
local function update_mining_speed(force)
|
||||
-- remove the current buff
|
||||
local old_modifier = force.manual_mining_speed_modifier - mining_efficiency.active_modifier
|
||||
|
||||
-- update the active modifier
|
||||
mining_efficiency.active_modifier = mining_efficiency.research_modifier + mining_efficiency.market_modifier
|
||||
|
||||
-- add the new active modifier to the non-buffed modifier
|
||||
force.manual_mining_speed_modifier = old_modifier + mining_efficiency.active_modifier
|
||||
end
|
||||
|
||||
local function update_inventory_slots(force)
|
||||
-- remove the current buff
|
||||
local old_modifier = force.character_inventory_slots_bonus - inventory_slots.active_modifier
|
||||
|
||||
-- update the active modifier
|
||||
inventory_slots.active_modifier = inventory_slots.research_modifier + inventory_slots.market_modifier
|
||||
|
||||
-- add the new active modifier to the non-buffed modifier
|
||||
force.character_inventory_slots_bonus = old_modifier + inventory_slots.active_modifier
|
||||
end
|
||||
|
||||
local function update_stone_collecting()
|
||||
-- remove the current buff
|
||||
local old_modifier = stone_collecting.initial_value - stone_collecting.active_modifier
|
||||
|
||||
-- update the active modifier
|
||||
stone_collecting.active_modifier = stone_collecting.research_modifier + stone_collecting.market_modifier
|
||||
|
||||
-- add the new active modifier to the non-buffed modifier
|
||||
stone_collecting.initial_value = old_modifier + stone_collecting.active_modifier
|
||||
end
|
||||
|
||||
|
||||
--Handles the updating of market items when unlocked, also handles the buffs
|
||||
local function update_market_contents(market)
|
||||
if (stone_tracker.previous_stone_sent_to_surface == stone_tracker.stone_sent_to_surface) then
|
||||
return
|
||||
end
|
||||
|
||||
local should_update_mining_speed = false
|
||||
local should_update_inventory_slots = false
|
||||
local should_update_stone_collecting = false
|
||||
---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 old_level = stone_tracker.current_level
|
||||
local print = game.print
|
||||
local item_unlocked = false
|
||||
|
||||
if (calculate_level(stone_tracker.current_level+1) <= stone_tracker.stone_sent_to_surface) then
|
||||
stone_tracker.current_level = stone_tracker.current_level + 1
|
||||
end
|
||||
|
||||
for _, unlockable in pairs(config.unlockables) do
|
||||
local stone_unlock = calculate_level(unlockable.level)
|
||||
local is_in_range = stone_unlock > stone_tracker.previous_stone_sent_to_surface and stone_unlock <= stone_tracker.stone_sent_to_surface
|
||||
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
|
||||
@ -153,84 +58,18 @@ local function update_market_contents(market)
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
MarketExchange.update_gui()
|
||||
|
||||
if (old_level < stone_tracker.current_level) then
|
||||
if item_unlocked then
|
||||
print(prefix..'We have reached level ' .. stone_tracker.current_level .. '! New items are available from the market!')
|
||||
else
|
||||
print(prefix..'We have reached level ' .. stone_tracker.current_level .. '!')
|
||||
end
|
||||
for _, buffs in pairs(config.buffs) do
|
||||
if (buffs.prototype.name == 'mining_speed') then
|
||||
local value = buffs.prototype.value
|
||||
Debug.print('Mining Foreman: Increased mining speed by ' .. value .. '%!')
|
||||
should_update_mining_speed = true
|
||||
mining_efficiency.market_modifier = mining_efficiency.market_modifier + (value / 100)
|
||||
elseif (buffs.prototype.name == 'inventory_slot') then
|
||||
local value = buffs.prototype.value
|
||||
Debug.print('Mining Foreman: Increased inventory slots by ' .. value .. '!')
|
||||
should_update_inventory_slots = true
|
||||
inventory_slots.market_modifier = inventory_slots.market_modifier + value
|
||||
elseif (buffs.prototype.name == 'stone_automation') then
|
||||
local value = buffs.prototype.value
|
||||
if (stone_tracker.current_level == 1) then
|
||||
print('Mining Foreman: We can now automatically send stone to the surface from a chest below the market!')
|
||||
else
|
||||
Debug.print('Mining Foreman: We can now automatically send ' .. value .. ' more stones!')
|
||||
end
|
||||
should_update_stone_collecting = true
|
||||
stone_collecting.market_modifier = stone_collecting.market_modifier + value
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local force
|
||||
|
||||
if (should_update_mining_speed) then
|
||||
force = force or game.forces.player
|
||||
update_mining_speed(force)
|
||||
end
|
||||
|
||||
if (should_update_inventory_slots) then
|
||||
force = force or game.forces.player
|
||||
update_inventory_slots(force)
|
||||
end
|
||||
|
||||
if (should_update_stone_collecting) then
|
||||
update_stone_collecting()
|
||||
end
|
||||
end
|
||||
|
||||
local function on_research_finished(event)
|
||||
local force = game.forces.player
|
||||
local current_modifier = mining_efficiency.research_modifier
|
||||
local new_modifier = force.mining_drill_productivity_bonus * config.mining_speed_productivity_multiplier * 0.5
|
||||
|
||||
if (current_modifier == new_modifier) then
|
||||
-- something else was researched
|
||||
return
|
||||
end
|
||||
|
||||
mining_efficiency.research_modifier = new_modifier
|
||||
inventory_slots.research_modifier = force.mining_drill_productivity_bonus * 50 -- 1 per level
|
||||
stone_collecting.research_modifier = force.mining_drill_productivity_bonus * 1250 -- 25 per level
|
||||
|
||||
update_inventory_slots(force)
|
||||
update_mining_speed(force)
|
||||
update_stone_collecting()
|
||||
end
|
||||
|
||||
local function redraw_title(data)
|
||||
data.frame.caption = utils.comma_value(stone_tracker.stone_sent_to_surface) .. ' ' .. config.currency_item .. ' sent to the surface'
|
||||
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 calculate_level(data.level) == stone and data.type == type then
|
||||
if data.level == stone and data.type == type then
|
||||
insert(result, data)
|
||||
end
|
||||
end
|
||||
@ -259,23 +98,14 @@ local function redraw_heading(data, header)
|
||||
end
|
||||
|
||||
local function redraw_progressbar(data)
|
||||
|
||||
local force_data = force_control.get_force_data('player')
|
||||
local flow = data.market_progressbars
|
||||
Gui.clear(flow)
|
||||
|
||||
-- progress bar for next level
|
||||
local act_stone = (stone_tracker.current_level ~= 0) and calculate_level(stone_tracker.current_level) or 0
|
||||
local next_stone = calculate_level(stone_tracker.current_level+1)
|
||||
|
||||
local range = next_stone - act_stone
|
||||
local sent = stone_tracker.stone_sent_to_surface - act_stone
|
||||
local percentage = (math.floor((sent / range)*1000))*0.001
|
||||
percentage = (percentage < 0) and (percentage*-1) or percentage
|
||||
|
||||
apply_heading_style(flow.add({type = 'label', tooltip = 'Currently at level: ' .. stone_tracker.current_level .. '\nNext level at: ' .. utils.comma_value(next_stone) ..'\nRemaining stone: ' .. utils.comma_value(range - sent), name = 'Diggy.MarketExchange.Frame.Progress.Level', caption = 'Progress to next level:'}).style)
|
||||
local level_progressbar = flow.add({type = 'progressbar', tooltip = percentage * 100 .. '% stone to next level'})
|
||||
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 = percentage
|
||||
level_progressbar.value = force_data.experience_percentage * 0.01
|
||||
end
|
||||
|
||||
local function redraw_table(data)
|
||||
@ -296,10 +126,10 @@ local function redraw_table(data)
|
||||
|
||||
-- create table
|
||||
for i = 1, #config.unlockables do
|
||||
if calculate_level(config.unlockables[i].level) ~= last_stone then
|
||||
if config.unlockables[i].level ~= last_stone then
|
||||
|
||||
-- get items and buffs for each stone value
|
||||
items = get_data(config.unlockables, calculate_level(config.unlockables[i].level), 'market')
|
||||
items = get_data(config.unlockables, config.unlockables[i].level, 'market')
|
||||
|
||||
-- get number of rows
|
||||
number_of_rows = max(#buffs, #items)
|
||||
@ -311,8 +141,7 @@ local function redraw_table(data)
|
||||
local level = item.level
|
||||
|
||||
-- 1st column
|
||||
result[6] = calculate_level(level)
|
||||
result[1] = 'Level ' ..level
|
||||
result[1] = level
|
||||
-- 3rd column
|
||||
if items[j] ~= nil then
|
||||
result[3] = '+ ' .. item.prototype.name
|
||||
@ -337,23 +166,23 @@ local function redraw_table(data)
|
||||
end
|
||||
|
||||
-- save lastStone
|
||||
last_stone = calculate_level(config.unlockables[i].level)
|
||||
last_stone = config.unlockables[i].level
|
||||
end
|
||||
|
||||
-- print table
|
||||
for _, unlockable in pairs(row) do
|
||||
local is_unlocked = unlockable[6] <= stone_tracker.stone_sent_to_surface
|
||||
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 = unlockable[1]
|
||||
caption = 'Level ' .. unlockable[1]
|
||||
else
|
||||
caption = ''
|
||||
end
|
||||
local tag_stone = list.add {type = 'label', name = tag_label_stone, caption = caption}
|
||||
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]}
|
||||
@ -378,30 +207,27 @@ local function redraw_buff(data) --! Almost equals to the redraw_table() functio
|
||||
local buff_scroll_pane = data.buff_scroll_pane
|
||||
Gui.clear(buff_scroll_pane)
|
||||
|
||||
local buffs = {}
|
||||
local number_of_rows = 0
|
||||
local buffs = Experience.get_buffs()
|
||||
local row = {}
|
||||
|
||||
for i = 1, #config.buffs do
|
||||
-- get items and buffs for each stone value
|
||||
buffs = config.buffs
|
||||
|
||||
local i = 0
|
||||
for k, v in pairs(buffs) do
|
||||
i = i + 1
|
||||
local result = {}
|
||||
|
||||
-- 1st column
|
||||
result[1] = 'All levels'
|
||||
|
||||
-- 2nd column
|
||||
if buffs[i].prototype.name == 'mining_speed' then
|
||||
result[2] = '+ '.. buffs[i].prototype.value .. '% mining speed'
|
||||
elseif buffs[i].prototype.name == 'inventory_slot' then
|
||||
if buffs[i].prototype.value > 1 then
|
||||
result[2] = '+ '.. buffs[i].prototype.value .. ' inventory slots'
|
||||
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] = '+ '.. buffs[i].prototype.value .. ' inventory slot'
|
||||
result[2] = '+ '.. v.value .. ' inventory slot'
|
||||
end
|
||||
elseif buffs[i].prototype.name == 'stone_automation' then
|
||||
result[2] = '+ '.. buffs[i].prototype.value .. ' stones automatically sent'
|
||||
elseif k == 'health_bonus' then
|
||||
result[2] = '+ '.. v.value .. ' max health'
|
||||
else
|
||||
result[2] = 'Description missing: unknown buff. Please contact admin'
|
||||
end
|
||||
@ -437,34 +263,29 @@ local function redraw_buff(data) --! Almost equals to the redraw_table() functio
|
||||
end
|
||||
end
|
||||
|
||||
local function on_market_item_purchased(event)
|
||||
if (1 ~= event.offer_index) then
|
||||
---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
|
||||
|
||||
local sum = config.stone_to_surface_amount * event.count
|
||||
Game.print_player_floating_text(event.player_index, '-' .. sum .. ' stone', {r = 0.6, g = 0.55, b = 0.42})
|
||||
|
||||
send_stone_to_surface(sum)
|
||||
update_market_contents(event.market)
|
||||
return markets[1]
|
||||
end
|
||||
|
||||
local function on_placed_entity(event)
|
||||
local market = event.entity
|
||||
if ('market' ~= market.name) then
|
||||
if 'market' ~= market.name then
|
||||
return
|
||||
end
|
||||
|
||||
market.add_market_item({
|
||||
price = {{config.currency_item, 50}},
|
||||
offer = {type = 'nothing', effect_description = 'Send ' .. config.stone_to_surface_amount .. ' ' .. config.currency_item .. ' to the surface. To see the overall progress and rewards, click the market button in the menu.'}
|
||||
})
|
||||
|
||||
update_market_contents(market)
|
||||
end
|
||||
|
||||
function MarketExchange.get_extra_map_info(config)
|
||||
return 'Market Exchange, trade your stone or send it to the surface'
|
||||
return 'Market Exchange, come make a deal at the foreman\'s shop'
|
||||
end
|
||||
|
||||
local function toggle(event)
|
||||
@ -530,6 +351,7 @@ 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']
|
||||
@ -537,20 +359,16 @@ function MarketExchange.update_gui()
|
||||
if frame and frame.valid then
|
||||
local data = {player = p, trigger = 'update_gui'}
|
||||
toggle(data)
|
||||
--toggle(data)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function MarketExchange.on_init()
|
||||
Task.set_timeout_in_ticks(50, on_market_timeout_finished, {
|
||||
Task.set_timeout_in_ticks(1, on_market_timeout_finished, {
|
||||
surface = game.surfaces.nauvis,
|
||||
position = config.market_spawn_position,
|
||||
player_force = game.forces.player,
|
||||
void_chest_tiles = config.void_chest_tiles,
|
||||
})
|
||||
|
||||
update_mining_speed(game.forces.player)
|
||||
end
|
||||
|
||||
--[[--
|
||||
@ -559,91 +377,10 @@ end
|
||||
function MarketExchange.register(cfg)
|
||||
config = cfg
|
||||
|
||||
Event.add(defines.events.on_research_finished, on_research_finished)
|
||||
Event.add(defines.events.on_market_item_purchased, on_market_item_purchased)
|
||||
--Events
|
||||
Event.add(Template.events.on_placed_entity, on_placed_entity)
|
||||
Event.add(defines.events.on_player_created, on_player_created)
|
||||
|
||||
local x_min
|
||||
local y_min
|
||||
local x_max
|
||||
local y_max
|
||||
|
||||
for _, position in pairs(config.void_chest_tiles) do
|
||||
local x = position.x
|
||||
local y = position.y
|
||||
|
||||
if (nil == x_min or x < x_min) then
|
||||
x_min = x
|
||||
end
|
||||
|
||||
if (nil == x_max or x > x_max) then
|
||||
x_max = x
|
||||
end
|
||||
|
||||
if (nil == y_min or y < y_min) then
|
||||
y_min = y
|
||||
end
|
||||
|
||||
if (nil == y_max or y > y_max) then
|
||||
y_max = y
|
||||
end
|
||||
end
|
||||
|
||||
local area = {{x_min, y_min}, {x_max + 1, y_max + 1}}
|
||||
local message_x = (x_max + x_min) * 0.5
|
||||
local message_y = (y_max + y_min) * 0.5
|
||||
|
||||
Event.on_nth_tick(config.void_chest_frequency, function ()
|
||||
local send_to_surface = 0
|
||||
local surface = game.surfaces.nauvis
|
||||
local find_entities_filtered = surface.find_entities_filtered
|
||||
local chests = find_entities_filtered({area = area, type = {'container', 'logistic-container'}})
|
||||
local to_fetch = stone_collecting.active_modifier
|
||||
|
||||
for _, chest in pairs(chests) do
|
||||
local chest_contents = chest.get_inventory(defines.inventory.chest)
|
||||
local stone_in_chest = chest_contents.get_item_count(config.currency_item)
|
||||
local delta = to_fetch
|
||||
|
||||
if (stone_in_chest < delta) then
|
||||
delta = stone_in_chest
|
||||
end
|
||||
|
||||
if (delta > 0) then
|
||||
chest_contents.remove({name = config.currency_item, count = delta})
|
||||
send_to_surface = send_to_surface + delta
|
||||
end
|
||||
end
|
||||
|
||||
if (send_to_surface == 0) then
|
||||
if (0 == to_fetch) then
|
||||
return
|
||||
end
|
||||
|
||||
local message = 'Missing chests below market'
|
||||
if (#chests > 0) then
|
||||
message = 'No stone in chests found'
|
||||
end
|
||||
|
||||
Game.print_floating_text(surface, {x = message_x, y = message_y}, message, { r = 220, g = 100, b = 50})
|
||||
return
|
||||
end
|
||||
|
||||
local markets = 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
|
||||
|
||||
local message = send_to_surface .. ' stone sent to the surface'
|
||||
|
||||
Game.print_floating_text(surface, {x = message_x, y = message_y}, message, { r = 0.6, g = 0.55, b = 0.42})
|
||||
|
||||
send_stone_to_surface(send_to_surface)
|
||||
update_market_contents(markets[1])
|
||||
end)
|
||||
Event.on_nth_tick(61, MarketExchange.update_gui)
|
||||
end
|
||||
|
||||
return MarketExchange
|
||||
|
@ -96,9 +96,9 @@ function ScatteredResources.register(config)
|
||||
|
||||
-- compound cluster spawning
|
||||
local c_mode = config.cluster_mode
|
||||
local c_clusters = require(config.cluster_file_location)
|
||||
if ('table' ~= type(c_clusters)) then
|
||||
error('cluster_file_location invalid')
|
||||
local c_clusters = config.ore_pattern
|
||||
if 'table' ~= type(c_clusters) then
|
||||
error('ore_pattern invalid')
|
||||
end
|
||||
local c_count = 0
|
||||
for _, cluster in ipairs(c_clusters) do
|
||||
|
@ -1,54 +0,0 @@
|
||||
-- dependencies
|
||||
local Config = require 'map_gen.Diggy.Config'.features.MarketExchange
|
||||
|
||||
-- this
|
||||
local MarketUnlockables = {}
|
||||
local floor = math.floor
|
||||
local ceil = math.ceil
|
||||
local log10 = math.log10
|
||||
|
||||
--- Handles a truncation of numbers to create simple large numbers
|
||||
-- eg. 1593251 could become 1590000 with precision 3
|
||||
-- number larger than 10 million will have an precision of +1
|
||||
-- @param precision number of the precision wanted (number of significant digits)
|
||||
-- @param precise_number number that needs to be truncated/simplified
|
||||
--
|
||||
local function truncate(precision, precise_number)
|
||||
local number = precise_number
|
||||
local number_length = floor(log10(number)+1)
|
||||
precision = (number_length >= 8) and (precision+1) or precision
|
||||
local exponent = number_length -precision
|
||||
number = number/10^exponent
|
||||
number = floor(number)*10^exponent
|
||||
return number, number_length
|
||||
end
|
||||
|
||||
--- Handles the level requirement to stone sent. Calculates based on a formula one number corresponding to that levels cost
|
||||
-- You can configure this in Diggy.Config.lua under features.MarketExchange
|
||||
-- @param level number of a level
|
||||
-- @returns number of cost corresponding to the level based on a calculation
|
||||
--
|
||||
function MarketUnlockables.calculate_level(level) -- all configurable variables must be integers.
|
||||
local b = floor(Config.difficulty_scale) or 25 -- Default 25 <-- Controls how much stone is needed.
|
||||
local start_value = floor(Config.start_stone) or 50 -- The start value/the first level cost
|
||||
local formula = b*(level^3)+(start_value-b)
|
||||
|
||||
local precision = floor(Config.cost_precision) or 2 -- Sets the precision
|
||||
|
||||
-- Truncates to the precision and prevents duplicates by incrementing with 5 in the third highest place.
|
||||
-- First evaluates loosely if the previous level requirement would return same number after truncating.
|
||||
-- If true evaluates down all levels to level 1 for the precise number
|
||||
-- (In case itself got incremented)
|
||||
-- Only useful if three or more values turns out to be the same after truncating, thus the loosely evaluation to save an expensive recursive function
|
||||
local number, number_lenght = truncate(precision, formula)
|
||||
local prev_number = truncate(precision, b*((level-1)^3)+(start_value-b))
|
||||
if (level ~= 1 and number == prev_number) then
|
||||
local prev_number = MarketUnlockables.calculate_level((level-1))
|
||||
while (prev_number >= number) do
|
||||
number = (prev_number < number) and number or ceil(number + (5*10^(number_lenght -3)))
|
||||
end
|
||||
end
|
||||
return number
|
||||
end
|
||||
|
||||
return MarketUnlockables
|
@ -39,7 +39,7 @@ end
|
||||
--[[--
|
||||
Register the events required to initialize the scenario.
|
||||
]]
|
||||
function Scenario.register(debug)
|
||||
function Scenario.register(debug, cheats)
|
||||
if global.diggy_scenario_registered then
|
||||
error('Cannot register the Diggy scenario multiple times.')
|
||||
return
|
||||
@ -50,15 +50,11 @@ function Scenario.register(debug)
|
||||
global.scenario.config.fish_market.enable = nil
|
||||
end
|
||||
|
||||
if ('boolean' == type(debug)) then
|
||||
Config.Debug = debug
|
||||
end
|
||||
|
||||
if (Config.debug) then
|
||||
if debug then
|
||||
Debug.enable_debug()
|
||||
end
|
||||
|
||||
if (Config.cheats) then
|
||||
if cheats then
|
||||
Debug.enable_cheats()
|
||||
end
|
||||
|
||||
|
@ -12,73 +12,47 @@ Global.register({
|
||||
scores = tbl.scores
|
||||
end)
|
||||
|
||||
--[[--
|
||||
Resets the score 0 for the given name
|
||||
|
||||
@param name String
|
||||
]]
|
||||
---Resets the score 0 for the given name
|
||||
---@param name string
|
||||
function ScoreTable.reset(name)
|
||||
scores[name] = 0
|
||||
end
|
||||
|
||||
--[[--
|
||||
Adds score.
|
||||
|
||||
@param name String
|
||||
@param value int amount to add
|
||||
|
||||
@return int the sum for the score added by name
|
||||
]]
|
||||
---Adds score.
|
||||
---@param name string
|
||||
---@param value number the sum for the score added by name
|
||||
---@return number the sum for the score added by the name
|
||||
function ScoreTable.add(name, value)
|
||||
local new = (scores[name] or 0) + value
|
||||
scores[name] = new
|
||||
return new
|
||||
end
|
||||
|
||||
--[[--
|
||||
Increments the score by 1 for name.
|
||||
---Sets score.
|
||||
---@param name string
|
||||
---@param value number the sum for the score added by name
|
||||
function ScoreTable.set(name, value)
|
||||
scores[name] = value
|
||||
end
|
||||
|
||||
@param name String
|
||||
|
||||
@return int the sum for the score incremented by name
|
||||
]]
|
||||
---Increments the score by 1 for name.
|
||||
---@param name string
|
||||
---@return number the sum for the score incremented by name
|
||||
function ScoreTable.increment(name)
|
||||
return ScoreTable.add(name, 1)
|
||||
end
|
||||
|
||||
--[[--
|
||||
Returns the score for a single key.
|
||||
|
||||
@param
|
||||
]]
|
||||
---Returns the score for a single key.
|
||||
---@param name string
|
||||
---@return number the sum for the score by name
|
||||
function ScoreTable.get(name)
|
||||
return scores[name] or 0
|
||||
end
|
||||
|
||||
--[[--
|
||||
Returns all scores.
|
||||
|
||||
@return table {[string] = int}
|
||||
]]
|
||||
---Returns all scores.
|
||||
---@return table {[string] = int}
|
||||
function ScoreTable.all()
|
||||
return scores
|
||||
end
|
||||
|
||||
--[[--
|
||||
Returns all keys of table scores.
|
||||
|
||||
@return table {[string] = name of key}
|
||||
]]
|
||||
function ScoreTable.all_keys()
|
||||
local keyset = {}
|
||||
local n = 0
|
||||
|
||||
for k, v in pairs(scores) do
|
||||
n = n + 1
|
||||
keyset[n] = k
|
||||
end
|
||||
|
||||
return keyset
|
||||
end
|
||||
|
||||
return ScoreTable
|
||||
|
@ -163,15 +163,10 @@ end
|
||||
@param force LuaForce
|
||||
@param market_items Table
|
||||
]]
|
||||
function Template.market(surface, position, force, market_inventory)
|
||||
function Template.market(surface, position, force)
|
||||
local market = surface.create_entity({name = 'market', position = position})
|
||||
local add_market_item = market.add_market_item
|
||||
market.destructible = false
|
||||
|
||||
for _, item in ipairs(market_inventory) do
|
||||
add_market_item(item)
|
||||
end
|
||||
|
||||
force.add_chart_tag(surface, {
|
||||
text = 'Market',
|
||||
position = position,
|
||||
|
@ -1,2 +1,2 @@
|
||||
-- authors Linaori, valansch
|
||||
require 'map_gen.Diggy.Scenario'.register(_DEBUG)
|
||||
require 'map_gen.Diggy.Scenario'.register(_DEBUG, _CHEATS)
|
||||
|
159
map_gen/misc/silly_player_names.lua
Normal file
159
map_gen/misc/silly_player_names.lua
Normal file
@ -0,0 +1,159 @@
|
||||
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
|
@ -5,6 +5,7 @@
|
||||
-- Obtain items using silent commands from scenarios\RedMew\map_gen\data\presets\tetris\
|
||||
-- Place the blueprint on the island south of spawn
|
||||
-- Teleport to centre of island and run the second command in tetris_theme_items_command.txt
|
||||
-- Excellent tetris themed music generated from midi files, credit to mgabor of miditorio.com
|
||||
|
||||
local b = require 'map_gen.shared.builders'
|
||||
local math = require 'utils.math'
|
||||
|
@ -139,6 +139,7 @@ local terrain_modules = {
|
||||
--require 'map_gen.misc.nightfall'
|
||||
--require 'map_gen.misc.creep_spread'
|
||||
--require 'map_gen.misc.car_body'
|
||||
--require 'features.silly_player_names'
|
||||
|
||||
if #entity_modules > 0 then
|
||||
shape = shape or b.full_shape
|
||||
|
253
resources/naming_words.lua
Normal file
253
resources/naming_words.lua
Normal file
@ -0,0 +1,253 @@
|
||||
-- Currently geared towards the winter holidays but we can always revise if needed.
|
||||
-- (Ex. a table of standard/common words and tables for season-specific words, then combined for specific purposes/use-cases)
|
||||
|
||||
local Module = {}
|
||||
|
||||
Module.adverbs = {
|
||||
'Abnormally',
|
||||
'Accidentally',
|
||||
'Adventurously',
|
||||
'Anxiously',
|
||||
'Arrogantly',
|
||||
'Awkwardly',
|
||||
'Bashfully',
|
||||
'Beautifully',
|
||||
'Blindly',
|
||||
'Blissfully',
|
||||
'Boastfully',
|
||||
'Boldly',
|
||||
'Bravely',
|
||||
'Calmly',
|
||||
'Carefully',
|
||||
'Carelessly',
|
||||
'Cautiously',
|
||||
'Certainly',
|
||||
'Cheerfully',
|
||||
'Clearly',
|
||||
'Closely',
|
||||
'Continually',
|
||||
'Courageously',
|
||||
'Cruelly',
|
||||
'Curiously',
|
||||
'Dearly',
|
||||
'Deeply',
|
||||
'Defiantly',
|
||||
'Deliberately',
|
||||
'Delightfully',
|
||||
'Dimly',
|
||||
'Doubtfully',
|
||||
'Dreamily',
|
||||
'Easily',
|
||||
'Elegantly',
|
||||
'Energetically',
|
||||
'Enormously',
|
||||
'Enthusiastically',
|
||||
'Especially',
|
||||
'Eventually',
|
||||
'Excitedly',
|
||||
'Extremely',
|
||||
'Fairly',
|
||||
'Faithfully',
|
||||
'Famously',
|
||||
'Fatally',
|
||||
'Ferociously',
|
||||
'Fervently',
|
||||
'Fiercely',
|
||||
'Fondly',
|
||||
'Foolishly',
|
||||
'Frantically',
|
||||
'Frightfully',
|
||||
'Furiously',
|
||||
'Generally',
|
||||
'Generously',
|
||||
'Gently',
|
||||
'Gladly',
|
||||
'Gleefully',
|
||||
'Gracefully',
|
||||
'Greatly',
|
||||
'Happily',
|
||||
'Heavily',
|
||||
'Helpfully',
|
||||
'Helplessly',
|
||||
'Honestly',
|
||||
'Hopelessly',
|
||||
'Hungrily',
|
||||
'Innocently',
|
||||
'Inquisitively',
|
||||
'Intensely',
|
||||
'Interestingly',
|
||||
'Irritably',
|
||||
'Jovially',
|
||||
'Joyfully',
|
||||
'Kindheartedly',
|
||||
'Kindly',
|
||||
'Knowingly',
|
||||
'Lazily',
|
||||
'Lively',
|
||||
'Longingly',
|
||||
'Loosely',
|
||||
'Loudly',
|
||||
'Lovingly',
|
||||
'Loyally',
|
||||
'Madly',
|
||||
'Majestically',
|
||||
'Merrily',
|
||||
'Miserably',
|
||||
'Mockingly',
|
||||
'Mostly',
|
||||
'Mysteriously',
|
||||
'Naturally',
|
||||
'Nearly',
|
||||
'Nicely',
|
||||
'Noisily',
|
||||
'Obnoxiously',
|
||||
'Offensively',
|
||||
'Optimistically',
|
||||
'Painfully',
|
||||
'Patiently',
|
||||
'Perfectly',
|
||||
'Playfully',
|
||||
'Politely',
|
||||
'Positively',
|
||||
'Powerfully',
|
||||
'Questionably',
|
||||
'Quickly',
|
||||
'Quietly',
|
||||
'Randomly',
|
||||
'Rapidly',
|
||||
'Readily',
|
||||
'Reluctantly',
|
||||
'Righteously',
|
||||
'Safely',
|
||||
'Seemingly',
|
||||
'Selfishly',
|
||||
'Silently',
|
||||
'Sleepily',
|
||||
'Stealthily',
|
||||
'Successfully',
|
||||
'Suddenly',
|
||||
'Surprisingly',
|
||||
'Suspiciously',
|
||||
'Sweetly',
|
||||
'Tenderly',
|
||||
'Thankfully',
|
||||
'Unbearably',
|
||||
'Unexpectedly',
|
||||
'Unfortunately',
|
||||
'Unimpressively',
|
||||
'Unnecessarily',
|
||||
'Urgently',
|
||||
'Uselessly',
|
||||
'Vaguely',
|
||||
'Warmly',
|
||||
'Wildly',
|
||||
'Wisely',
|
||||
'Wrongly',
|
||||
'Youthfully',
|
||||
}
|
||||
|
||||
Module.adjectives = {
|
||||
'Amazing',
|
||||
'Attractive',
|
||||
'Awesome',
|
||||
'Beautiful',
|
||||
'Big',
|
||||
'Blissful',
|
||||
'Brave',
|
||||
'Breathtaking',
|
||||
'Careful',
|
||||
'Caroling',
|
||||
'Chubby',
|
||||
'Clever',
|
||||
'Clumsy',
|
||||
'Dazzling',
|
||||
'Delightful',
|
||||
'Eager',
|
||||
'Excitable',
|
||||
'Fabulous',
|
||||
'Faithful',
|
||||
'Fancy',
|
||||
'Fantastic',
|
||||
'Fantastical',
|
||||
'Fierce',
|
||||
'Gentle',
|
||||
'Glamorous',
|
||||
'Gorgeous',
|
||||
'Great',
|
||||
'Grumpy',
|
||||
'Happy',
|
||||
'Helpful',
|
||||
'Interesting',
|
||||
'Jolly',
|
||||
'Kind',
|
||||
'Lazy',
|
||||
'Magical',
|
||||
'Magnificent',
|
||||
'Merry',
|
||||
'Muscular',
|
||||
'Mystical',
|
||||
'Naughty',
|
||||
'Nice',
|
||||
'Obedient',
|
||||
'Peaceful',
|
||||
'Plump',
|
||||
'Polite',
|
||||
'Quaint',
|
||||
'Remarkable',
|
||||
'Roasting',
|
||||
'Scary',
|
||||
'Silly',
|
||||
'Small',
|
||||
'Tender',
|
||||
'Thoughtful',
|
||||
'White',
|
||||
'Witty',
|
||||
'Wonderful',
|
||||
}
|
||||
|
||||
Module.nouns = {
|
||||
'Advent',
|
||||
'Angel',
|
||||
'Bear',
|
||||
'Bell',
|
||||
'Candy Cane',
|
||||
'Caroler',
|
||||
'Chestnut',
|
||||
'Christmas Stocking',
|
||||
'Decoration',
|
||||
'Elf',
|
||||
'Feast',
|
||||
'Fruit Cake',
|
||||
'Garland',
|
||||
'Gift',
|
||||
'Grinch',
|
||||
'Ham',
|
||||
'Helper',
|
||||
'Holiday Dinner',
|
||||
'Holiday Sweater',
|
||||
'Holly',
|
||||
'Ice Skate',
|
||||
'Ivy',
|
||||
'Menora',
|
||||
'Miracle',
|
||||
'Mistletoe',
|
||||
'Ornament',
|
||||
'Package',
|
||||
'Party',
|
||||
'Present',
|
||||
'Reindeer',
|
||||
'Ribbon',
|
||||
'Scarf',
|
||||
'Scrooge',
|
||||
'Sleigh',
|
||||
'Snowball',
|
||||
'Snowflake',
|
||||
'Snowman',
|
||||
'Sugarplum',
|
||||
'Toy',
|
||||
'Tree',
|
||||
'Turkey',
|
||||
'Wreath',
|
||||
}
|
||||
|
||||
return Module
|
@ -68,7 +68,6 @@ end
|
||||
|
||||
--[[
|
||||
Creates a floating text entity at the player location with the specified color in {r, g, b} format.
|
||||
|
||||
Example: "+10 iron" or "-10 coins"
|
||||
|
||||
@param text String to display
|
||||
@ -76,14 +75,19 @@ end
|
||||
|
||||
@return the created entity
|
||||
]]
|
||||
function Game.print_player_floating_text(player_index, text, color)
|
||||
|
||||
function Game.print_player_floating_text_position(player_index, text, color, x_offset, y_offset)
|
||||
local player = Game.get_player_by_index(player_index)
|
||||
if not player or not player.valid then
|
||||
return
|
||||
end
|
||||
|
||||
local position = player.position
|
||||
return Game.print_floating_text(player.surface, {x = position.x, y = position.y - 1.5}, text, color)
|
||||
return Game.print_floating_text(player.surface, {x = position.x + x_offset, y = position.y + y_offset}, text, color)
|
||||
end
|
||||
|
||||
function Game.print_player_floating_text(player_index, text, color)
|
||||
Game.print_player_floating_text_position(player_index, text, color, 0, -1.5)
|
||||
end
|
||||
|
||||
return Game
|
||||
|
@ -16,7 +16,9 @@ Module.print_except = function(msg, player)
|
||||
end
|
||||
end
|
||||
|
||||
-- Takes a LuaPlayer or string as source
|
||||
--- Prints a message to all online admins
|
||||
--@param1 The message to print, as a string
|
||||
--@param2 The source of the message, as a string, LuaPlayer, or nil.
|
||||
Module.print_admins = function(msg, source)
|
||||
local source_name
|
||||
local chat_color
|
||||
@ -41,6 +43,7 @@ Module.print_admins = function(msg, source)
|
||||
end
|
||||
end
|
||||
|
||||
--- Returns a valid string with the name of the actor of a command.
|
||||
Module.get_actor = function()
|
||||
if game.player then
|
||||
return game.player.name
|
||||
@ -119,22 +122,20 @@ Module.format_time = function(ticks)
|
||||
return table.concat(result, ' ')
|
||||
end
|
||||
|
||||
--- Prints a message letting the player know they cannot run a command
|
||||
-- @param1 name of the command
|
||||
Module.cant_run = function(name)
|
||||
Game.player_print("Can't run command (" .. name .. ') - insufficient permission.')
|
||||
end
|
||||
|
||||
Module.log_command = function(user, command, parameters)
|
||||
local name
|
||||
|
||||
-- We can use a LuaPlayer or a string (ex. "Server").
|
||||
if type(user) == 'string' then
|
||||
name = user
|
||||
else
|
||||
name = user.name
|
||||
end
|
||||
local action = table.concat {'[Admin-Command] ', name, ' used: ', command}
|
||||
--- Logs the use of a command and its user
|
||||
-- @param1 takes a string with the actor's name (usually acquired by calling get_actor)
|
||||
-- @param2 the command's name as table element
|
||||
-- @param3 the command's parameters as a table element (optional)
|
||||
Module.log_command = function(actor, command, parameters)
|
||||
local action = table.concat {'[Admin-Command] ', actor, ' used: ', command}
|
||||
if parameters then
|
||||
action = table.concat {'[Admin-Command] ', name, ' used: ', command, ' ', parameters}
|
||||
action = table.concat {action, ' ', parameters}
|
||||
end
|
||||
log(action)
|
||||
end
|
||||
|
Loading…
x
Reference in New Issue
Block a user