mirror of
https://github.com/PHIDIAS0303/ExpCluster.git
synced 2026-11-14 16:14:53 +09:00
Merge branch 'release/5.7.0'
This commit is contained in:
commit
79c98c316f
30 files changed
+1246
-152
No files matched your search
@@ -23,6 +23,7 @@ return {
|
||||
'modules.commands.spawn',
|
||||
'modules.commands.warnings',
|
||||
'modules.commands.find',
|
||||
'modules.commands.bonus',
|
||||
-- QoL Addons
|
||||
'modules.addons.chat-popups',
|
||||
'modules.addons.damage-popups',
|
||||
@@ -33,9 +34,11 @@ return {
|
||||
'modules.addons.scorched-earth',
|
||||
'modules.addons.pollution-grading',
|
||||
'modules.addons.random-player-colours',
|
||||
'modules.addons.discord-alerts',
|
||||
-- GUI
|
||||
'modules.gui.rocket-info',
|
||||
'modules.gui.science-info',
|
||||
'modules.gui.warp-list',
|
||||
'modules.gui.task-list',
|
||||
'modules.gui.player-list',
|
||||
'modules.commands.debug',
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
--- Lists all bonuses which can be used, name followed by min max
|
||||
return {
|
||||
character_mining_speed_modifier={0,3},
|
||||
character_crafting_speed_modifier={0,3},
|
||||
character_running_speed_modifier={0,3},
|
||||
character_build_distance_bonus={0,20},
|
||||
character_reach_distance_bonus={0,20},
|
||||
character_inventory_slots_bonus={0,200}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
--- Config file used to enable and disable different push messages for discord
|
||||
return {
|
||||
player_reports=true,
|
||||
player_warnings=true,
|
||||
player_bans=true,
|
||||
player_mutes=true,
|
||||
player_kicks=true,
|
||||
player_promotes=false,
|
||||
config=true,
|
||||
purge=true,
|
||||
c=true,
|
||||
command=true,
|
||||
['silent-command']=true,
|
||||
['measured-command']=true,
|
||||
['banlist']=true,
|
||||
['permissions']=true,
|
||||
['editor']=true,
|
||||
['cheat']=true,
|
||||
['open']=false,
|
||||
}
|
||||
@@ -60,8 +60,7 @@ Permission_Groups.new_group('Standard')
|
||||
'change_programmable_speaker_alert_parameters', -- standard
|
||||
'drop_item',
|
||||
'reset_assembling_machine',
|
||||
'set_auto_launch_rocket',
|
||||
'cancel_research'
|
||||
'set_auto_launch_rocket'
|
||||
}
|
||||
|
||||
Permission_Groups.new_group('Guest')
|
||||
@@ -84,7 +83,6 @@ Permission_Groups.new_group('Guest')
|
||||
'drop_item',
|
||||
'reset_assembling_machine',
|
||||
'set_auto_launch_rocket',
|
||||
'cancel_research',
|
||||
'change_programmable_speaker_parameters', -- guest
|
||||
'change_train_stop_station',
|
||||
'deconstruct',
|
||||
@@ -93,7 +91,8 @@ Permission_Groups.new_group('Guest')
|
||||
'reset_assembling_machine',
|
||||
'rotate_entity',
|
||||
'use_artillery_remote',
|
||||
'launch_rocket'
|
||||
'launch_rocket',
|
||||
'cancel_research'
|
||||
}
|
||||
|
||||
Permission_Groups.new_group('Restricted')
|
||||
|
||||
+12
-1
@@ -34,6 +34,7 @@ Roles.new_role('System','SYS')
|
||||
:set_flag('is_admin')
|
||||
:set_flag('is_spectator')
|
||||
:set_flag('report-immune')
|
||||
:set_flag('instance-respawn')
|
||||
:set_allow_all()
|
||||
|
||||
Roles.new_role('Senior Administrator','SAdmin')
|
||||
@@ -41,6 +42,7 @@ Roles.new_role('Senior Administrator','SAdmin')
|
||||
:set_flag('is_admin')
|
||||
:set_flag('is_spectator')
|
||||
:set_flag('report-immune')
|
||||
:set_flag('instance-respawn')
|
||||
:set_parent('Administrator')
|
||||
:allow{
|
||||
'command/interface',
|
||||
@@ -54,8 +56,10 @@ Roles.new_role('Administrator','Admin')
|
||||
:set_flag('is_admin')
|
||||
:set_flag('is_spectator')
|
||||
:set_flag('report-immune')
|
||||
:set_flag('instance-respawn')
|
||||
:set_parent('Moderator')
|
||||
:allow{
|
||||
'gui/warp-list/no-limit',
|
||||
}
|
||||
|
||||
Roles.new_role('Moderator','Mod')
|
||||
@@ -64,6 +68,7 @@ Roles.new_role('Moderator','Mod')
|
||||
:set_flag('is_admin')
|
||||
:set_flag('is_spectator')
|
||||
:set_flag('report-immune')
|
||||
:set_flag('instance-respawn')
|
||||
:set_parent('Trainee')
|
||||
:allow{
|
||||
'command/assign-role',
|
||||
@@ -76,6 +81,7 @@ Roles.new_role('Moderator','Mod')
|
||||
'command/clear-warnings',
|
||||
'command/clear-temp-ban',
|
||||
'command/clear-inventory',
|
||||
'command/bonus',
|
||||
'gui/rocket-info/toggle-active',
|
||||
'gui/rocket-info/remote_launch',
|
||||
}
|
||||
@@ -106,6 +112,7 @@ Roles.new_role('Sponsor','Spon')
|
||||
:set_custom_color{r=247,g=246,b=54}
|
||||
:set_flag('is_spectator')
|
||||
:set_flag('report-immune')
|
||||
:set_flag('instance-respawn')
|
||||
:set_parent('Pay to Win')
|
||||
:allow{
|
||||
}
|
||||
@@ -115,10 +122,12 @@ Roles.new_role('Pay to Win','P2W')
|
||||
:set_custom_color{r=238,g=172,b=44}
|
||||
:set_flag('is_spectator')
|
||||
:set_flag('report-immune')
|
||||
:set_flag('instance-respawn')
|
||||
:set_parent('Donator')
|
||||
:allow{
|
||||
'gui/rocket-info/toggle-active',
|
||||
'gui/rocket-info/remote_launch',
|
||||
'command/bonus',
|
||||
}
|
||||
|
||||
Roles.new_role('Donator','Don')
|
||||
@@ -159,7 +168,8 @@ Roles.new_role('Member','Mem')
|
||||
:set_custom_color{r=24,g=172,b=188}
|
||||
:set_parent('Regular')
|
||||
:allow{
|
||||
'gui/task-list/edit'
|
||||
'gui/task-list/edit',
|
||||
'gui/warp-list/edit'
|
||||
}
|
||||
|
||||
Roles.new_role('Regular','Reg')
|
||||
@@ -193,6 +203,7 @@ local default = Roles.new_role('Guest','')
|
||||
'gui/rocket-info',
|
||||
'gui/science-info',
|
||||
'gui/task-list',
|
||||
'gui/warp-list',
|
||||
}
|
||||
|
||||
--- Jail role
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
--- This file contains all the different settings for the warp system and gui
|
||||
return {
|
||||
recharge_time = 60, -- The amount of time in seconds that the player must wait between warps, acts as a balance
|
||||
update_smothing = 10, -- Higher is better, the amount of smothing applied to recharge timer and other gui updates, max is 60
|
||||
minimum_distance = 100, -- The minimum distance that must be between warp points, creating new ones is blocked when too close
|
||||
activation_range = 4, -- The distance the player must be to a warp in order to use the warp gui, gui can still be viewd but not used
|
||||
spawn_activation_range = 20, -- A second activation range which is used for the forces spawn point
|
||||
default_icon = 'discharge-defense-equipment', -- The deafult icon which is used by warps; must be an item name
|
||||
user_can_edit_own_warps = false, -- When true the user can always edit warps which they created regaudless of other settings
|
||||
any_user_can_add_new_warp = false, -- When true any user is able to create new warps, however editing may still be restricted
|
||||
only_admins_can_edit = false, -- When true only admins can edit warps
|
||||
edit_warps_role_permision = 'gui/warp-list/edit', -- Role permission used by the role system to allow editing warps
|
||||
bypass_warp_limits_permision = 'gui/warp-list/no-limit', -- Role permission used by the role system to allow bypassing the time and distance restrctions
|
||||
entities = { -- The entites which are created for warps
|
||||
{'small-lamp',-3,-2},{'small-lamp',-3,2},{'small-lamp',3,-2},{'small-lamp',3,2},
|
||||
{'small-lamp',-2,-3},{'small-lamp',2,-3},{'small-lamp',-2,3},{'small-lamp',2,3},
|
||||
{'small-electric-pole',-3,-3},{'small-electric-pole',3,3},{'small-electric-pole',-3,3},{'small-electric-pole',3,-3}
|
||||
},
|
||||
base_tile = 'tutorial-grid', -- The tile which is used for the warps
|
||||
tiles = { -- The tiles which are created for warps
|
||||
{-3,-2},{-3,-1},{-3,0},{-3,1},{-3,2},{3,-2},{3,-1},{3,0},{3,1},{3,2},
|
||||
{-2,-3},{-1,-3},{0,-3},{1,-3},{2,-3},{-2,3},{-1,3},{0,3},{1,3},{2,3}
|
||||
}
|
||||
}
|
||||
@@ -427,7 +427,7 @@ end
|
||||
|
||||
--- Adds a new param to the command this will be displayed in the help and used to parse the input
|
||||
-- @tparam string name the name of the new param that is being added to the command
|
||||
-- @tparam[opt=true] boolean optional is this param required for this command, these must be after all required params
|
||||
-- @tparam[opt=false] boolean optional is this param required for this command, these must be after all required params
|
||||
-- @tparam[opt=pass function through] ?string|function parse this function will take the input and return a new (or same) value
|
||||
-- @param[opt] ... extra args you want to pass to the parse function; for example if the parse is general use
|
||||
-- parse param - input: string - the input given by the user for this param
|
||||
@@ -436,12 +436,17 @@ end
|
||||
-- parse return - the value that will be passed to the command callback, must not be nil and if reject then command is not run
|
||||
-- @treturn Commands._prototype pass through to allow more functions to be called
|
||||
function Commands._prototype:add_param(name,optional,parse,...)
|
||||
if optional ~= false then optional = true end
|
||||
local parse_args = {...}
|
||||
if type(optional) ~= 'boolean' then
|
||||
parse_args = {parse,...}
|
||||
parse = optional
|
||||
optional = false
|
||||
end
|
||||
parse = parse or function(string) return string end
|
||||
self.params[name] = {
|
||||
optional=optional,
|
||||
parse=parse,
|
||||
parse_args={...}
|
||||
parse_args=parse_args
|
||||
}
|
||||
self.max_param_count = self.max_param_count+1
|
||||
if not optional then
|
||||
@@ -617,7 +622,7 @@ function Commands.run_command(command_event)
|
||||
-- splits the arguments
|
||||
local input_string = command_event.parameter or ''
|
||||
local quote_params = {} -- stores any " " params
|
||||
input_string = input_string:gsub('"[^"]-"',function(w)
|
||||
input_string = input_string:gsub(' "[^"]-"',function(w)
|
||||
-- finds all " " params are removes spaces for the next part
|
||||
local no_spaces = w:gsub('%s','_')
|
||||
local no_quotes = w:sub(2,-2)
|
||||
|
||||
+67
-16
@@ -510,26 +510,77 @@ function Common.auto_complete(options,input,use_key,rtn_key)
|
||||
return rtn[1]
|
||||
end
|
||||
|
||||
--- Returns all the keys of a table
|
||||
-- @tparam table tbl table the to get the keys of
|
||||
-- @treturn table an array of the table keys
|
||||
function Common.table_keys(tbl)
|
||||
local rtn = {}
|
||||
for key,_ in pairs(tbl) do
|
||||
table.insert(rtn,key)
|
||||
--- Default table comparator sort function.
|
||||
-- @local
|
||||
-- @param x one comparator operand
|
||||
-- @param y the other comparator operand
|
||||
-- @return true if x logically comes before y in a list, false otherwise
|
||||
local function sortFunc(x, y) --sorts tables with mixed index types.
|
||||
local tx = type(x)
|
||||
local ty = type(y)
|
||||
if tx == ty then
|
||||
if type(x) == 'string' then
|
||||
return string.lower(x) < string.lower(y)
|
||||
else
|
||||
return x < y
|
||||
end
|
||||
elseif tx == 'number' then
|
||||
return true --only x is a number and goes first
|
||||
else
|
||||
return false --only y is a number and goes first
|
||||
end
|
||||
return rtn
|
||||
end
|
||||
|
||||
--- Returns all the values of a table
|
||||
-- @tparam table tbl table the to get the values of
|
||||
-- @treturn table an array of the table values
|
||||
function Common.table_values(tbl)
|
||||
local rtn = {}
|
||||
for _,value in pairs(tbl) do
|
||||
table.insert(rtn,value)
|
||||
--- Returns a copy of all of the values in the table.
|
||||
-- @tparam table table tbl the to copy the keys from, or an empty table if tbl is nil
|
||||
-- @tparam[opt] boolean sorted whether to sort the keys (slower) or keep the random order from pairs()
|
||||
-- @tparam[opt] boolean as_string whether to try and parse the values as strings, or leave them as their existing type
|
||||
-- @treturn array an array with a copy of all the values in the table
|
||||
function Common.table_values(tbl, sorted, as_string)
|
||||
if not tbl then return {} end
|
||||
local valueset = {}
|
||||
local n = 0
|
||||
if as_string then --checking as_string /before/ looping is faster
|
||||
for _, v in pairs(tbl) do
|
||||
n = n + 1
|
||||
valueset[n] = tostring(v)
|
||||
end
|
||||
else
|
||||
for _, v in pairs(tbl) do
|
||||
n = n + 1
|
||||
valueset[n] = v
|
||||
end
|
||||
end
|
||||
return rtn
|
||||
if sorted then
|
||||
table.sort(valueset,sortFunc)
|
||||
end
|
||||
return valueset
|
||||
end
|
||||
|
||||
--- Returns a copy of all of the keys in the table.
|
||||
-- @tparam table table tbl the to copy the keys from, or an empty table if tbl is nil
|
||||
-- @tparam[opt] boolean sorted whether to sort the keys (slower) or keep the random order from pairs()
|
||||
-- @tparam[opt] boolean as_string whether to try and parse the keys as strings, or leave them as their existing type
|
||||
-- @treturn array an array with a copy of all the keys in the table
|
||||
function Common.table_keys(tbl, sorted, as_string)
|
||||
if not tbl then return {} end
|
||||
local keyset = {}
|
||||
local n = 0
|
||||
if as_string then --checking as_string /before/ looping is faster
|
||||
for k, _ in pairs(tbl) do
|
||||
n = n + 1
|
||||
keyset[n] = tostring(k)
|
||||
end
|
||||
else
|
||||
for k, _ in pairs(tbl) do
|
||||
n = n + 1
|
||||
keyset[n] = k
|
||||
end
|
||||
end
|
||||
if sorted then
|
||||
table.sort(keyset,sortFunc)
|
||||
end
|
||||
return keyset
|
||||
end
|
||||
|
||||
--- Returns the list is a sorted way that would be expected by people (this is by key)
|
||||
|
||||
@@ -258,6 +258,8 @@ local function change_value_prototype(self,amount,category,filter)
|
||||
local maximum = self.default_maximum or 1
|
||||
local new_value = value + (amount/maximum)
|
||||
|
||||
self:set_store(category,new_value)
|
||||
|
||||
if self.count_down and new_value <= 0
|
||||
or not self.count_down and new_value >= 1 then
|
||||
self:clear_store(category)
|
||||
@@ -265,9 +267,9 @@ local function change_value_prototype(self,amount,category,filter)
|
||||
if self.events.on_store_complete then
|
||||
self.events.on_store_complete(category,reset_store)
|
||||
end
|
||||
end
|
||||
|
||||
self:set_store(category,new_value)
|
||||
return
|
||||
end
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
+7
-2
@@ -240,8 +240,13 @@ Event.add(Store.on_value_update,function(event)
|
||||
Store.callbacks[event.location](event.value,event.child)
|
||||
end
|
||||
|
||||
if not event.from_sync then
|
||||
write_json('log/store.log',event)
|
||||
if not event.from_sync and Store.synced[event.location] then
|
||||
write_json('log/store.log',{
|
||||
tick=event.tick,
|
||||
location=event.location,
|
||||
child=event.child,
|
||||
value=event.value,
|
||||
})
|
||||
end
|
||||
end)
|
||||
|
||||
|
||||
+18
-1
@@ -77,4 +77,21 @@ confirm-tooltip=Save changes
|
||||
cancel-tooltip=Discard changes
|
||||
edit-tooltip=Currently being edited by: __1__
|
||||
edit-tooltip-none=Currently being edited by: Nobody
|
||||
discord-tooltip=Remove task
|
||||
discard-tooltip=Remove task
|
||||
|
||||
[warp-list]
|
||||
main-caption=Warp List
|
||||
main-tooltip=Warp list, must be within __1__ tiles to use
|
||||
sub-tooltip=Warps can only be used every __1__ seconds and when within __2__ tiles
|
||||
too-close=Cant make warp; too close to warp: __1__
|
||||
last-edit=Last edited by __1__ at __2__
|
||||
add-tooltip=Add new warp
|
||||
confirm-tooltip=Save changes
|
||||
cancel-tooltip=Discard changes
|
||||
edit-tooltip=Currently being edited by: __1__
|
||||
edit-tooltip-none=Currently being edited by: Nobody
|
||||
discard-tooltip=Remove warp
|
||||
timer-tooltip=Warp charge, charge time __1__ seconds
|
||||
goto-tooltip=Go to x __1__ y __2__
|
||||
goto-disabled=You must be on a warp point and have a full charge to warp
|
||||
goto-edit=Edit warp icon
|
||||
@@ -0,0 +1,233 @@
|
||||
local Event = require 'utils.event'
|
||||
local Game = require 'utils.game'
|
||||
local Colors = require 'resources.color_presets'
|
||||
local write_json,format_time = ext_require('expcore.common','write_json','format_time')
|
||||
local config = require 'config.discord_alerts'
|
||||
|
||||
local function get_player_name(event)
|
||||
local player = Game.get_player_by_index(event.player_index)
|
||||
return player.name, event.by_player_name
|
||||
end
|
||||
|
||||
local function to_hex(color)
|
||||
local hex_digits = '0123456789ABCDEF'
|
||||
local function hex(bit)
|
||||
local major, minor = math.modf(bit/16)
|
||||
minor = minor*16
|
||||
return hex_digits:sub(major,major)..hex_digits:sub(minor,minor)
|
||||
end
|
||||
|
||||
return hex(color.r)..hex(color.g)..hex(color.b)
|
||||
end
|
||||
|
||||
local function emit_event(args)
|
||||
local title = args.title or ''
|
||||
local color = args.color or '0x0'
|
||||
local description = args.description or ''
|
||||
|
||||
if type(color) == 'table' then
|
||||
color = to_hex(color)
|
||||
end
|
||||
|
||||
local tick = args.tick or 0
|
||||
local tick_formated = format_time(tick,{hours = true,minutes = true,string = true,long = true})
|
||||
|
||||
local players_online = 0
|
||||
local admins_online = 0
|
||||
for _,player in pairs(game.connected_players) do
|
||||
players_online = players_online+1
|
||||
if player.admin then
|
||||
admins_online = admins_online + 1
|
||||
end
|
||||
end
|
||||
|
||||
local done = {title=true,color=true,description=true}
|
||||
local fields = {{
|
||||
name='Server Details',
|
||||
value=string.format('Server name: ${serverName} Players: %d Admins: %d Time: %s',players_online,admins_online,tick_formated)
|
||||
}}
|
||||
|
||||
for key,value in pairs(args) do
|
||||
if not done[key] then
|
||||
done[key] = true
|
||||
local field = {
|
||||
name=key,
|
||||
value=value,
|
||||
inline=false
|
||||
}
|
||||
|
||||
local new_value, inline = value:gsub('<inline>','',1)
|
||||
if inline then
|
||||
field.value = new_value
|
||||
field.inline = true
|
||||
end
|
||||
|
||||
table.insert(fields,field)
|
||||
end
|
||||
end
|
||||
|
||||
write_json('log/discord.log',{
|
||||
title=title,
|
||||
description=description,
|
||||
color=color,
|
||||
fields=fields
|
||||
})
|
||||
end
|
||||
|
||||
--- Reports added and removed
|
||||
if config.player_reports then
|
||||
local Reports = require 'modules.addons.reports-control'
|
||||
Event.add(Reports.player_report_added,function(event)
|
||||
local player_name,by_player_name = get_player_name(event)
|
||||
emit_event{
|
||||
title='Report',
|
||||
description='A player was reported',
|
||||
color=Colors.yellow,
|
||||
['Player:']='<inline>'..player_name,
|
||||
['By:']='<inline>'..by_player_name,
|
||||
['Reason:']=event.reason
|
||||
}
|
||||
end)
|
||||
Event.add(Reports.player_report_removed,function(event)
|
||||
local player_name,by_player_name = get_player_name(event)
|
||||
emit_event{
|
||||
title='Report Removed',
|
||||
description='A player has a report removed',
|
||||
color=Colors.green,
|
||||
['Player:']='<inline>'..player_name,
|
||||
['By:']='<inline>'..by_player_name
|
||||
}
|
||||
end)
|
||||
end
|
||||
|
||||
--- Warnings added and removed
|
||||
if config.player_warnings then
|
||||
local Warnings = require 'modules.addons.warnings-control'
|
||||
Event.add(Warnings.player_warning_added,function(event)
|
||||
local player_name,by_player_name = get_player_name(event)
|
||||
emit_event{
|
||||
title='Warning',
|
||||
description='A player has been given a warning',
|
||||
color=Colors.yellow,
|
||||
['Player:']='<inline>'..player_name,
|
||||
['By:']='<inline>'..by_player_name
|
||||
}
|
||||
end)
|
||||
Event.add(Warnings.player_warning_removed,function(event)
|
||||
local player_name,by_player_name = get_player_name(event)
|
||||
emit_event{
|
||||
title='Warning Removed',
|
||||
description='A player has a warning removed',
|
||||
color=Colors.green,
|
||||
['Player:']='<inline>'..player_name,
|
||||
['By:']='<inline>'..by_player_name
|
||||
}
|
||||
end)
|
||||
end
|
||||
|
||||
--- Ban and unban
|
||||
if config.player_bans then
|
||||
Event.add(defines.events.on_player_banned,function(event)
|
||||
if event.by_player then
|
||||
local by_player = Game.get_player_by_index(event.by_player)
|
||||
emit_event{
|
||||
title='Banned',
|
||||
description='A player has been banned',
|
||||
color=Colors.red,
|
||||
['Player:']='<inline>'..event.player_name,
|
||||
['By:']='<inline>'..by_player.name,
|
||||
['Reason:']=event.reason
|
||||
}
|
||||
end
|
||||
end)
|
||||
Event.add(defines.events.on_player_unbanned,function(event)
|
||||
if event.by_player then
|
||||
local by_player = Game.get_player_by_index(event.by_player)
|
||||
emit_event{
|
||||
title='Un-Banned',
|
||||
description='A player has been un-banned',
|
||||
color=Colors.green,
|
||||
['Player:']='<inline>'..event.player_name,
|
||||
['By:']='<inline>'..by_player.name
|
||||
}
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
--- Mute and unmute
|
||||
if config.player_mutes then
|
||||
Event.add(defines.events.on_player_muted,function(event)
|
||||
local player_name = get_player_name(event)
|
||||
emit_event{
|
||||
title='Muted',
|
||||
description='A player has been muted',
|
||||
color=Colors.yellow,
|
||||
['Player:']='<inline>'..player_name
|
||||
}
|
||||
end)
|
||||
Event.add(defines.events.on_player_unmuted,function(event)
|
||||
local player_name = get_player_name(event)
|
||||
emit_event{
|
||||
title='Un-Muted',
|
||||
description='A player has been un-muted',
|
||||
color=Colors.green,
|
||||
['Player:']='<inline>'..player_name
|
||||
}
|
||||
end)
|
||||
end
|
||||
|
||||
--- Kick
|
||||
if config.player_kicks then
|
||||
Event.add(defines.events.on_player_kicked,function(event)
|
||||
if event.by_player then
|
||||
local player_name = get_player_name(event)
|
||||
local by_player = Game.get_player_by_index(event.by_player)
|
||||
emit_event{
|
||||
title='Kick',
|
||||
description='A player has been kicked',
|
||||
color=Colors.orange,
|
||||
['Player:']='<inline>'..player_name,
|
||||
['By:']='<inline>'..by_player.name,
|
||||
['Reason:']=event.reason
|
||||
}
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
--- Promote and demote
|
||||
if config.player_promotes then
|
||||
Event.add(defines.events.on_player_promoted,function(event)
|
||||
local player_name = get_player_name(event)
|
||||
emit_event{
|
||||
title='Promote',
|
||||
description='A player has been promoted',
|
||||
color=Colors.green,
|
||||
['Player:']='<inline>'..player_name
|
||||
}
|
||||
end)
|
||||
Event.add(defines.events.on_player_demoted,function(event)
|
||||
local player_name = get_player_name(event)
|
||||
emit_event{
|
||||
title='Demote',
|
||||
description='A player has been demoted',
|
||||
color=Colors.yellow,
|
||||
['Player:']='<inline>'..player_name
|
||||
}
|
||||
end)
|
||||
end
|
||||
|
||||
--- Other commands
|
||||
Event.add(defines.events.on_console_command,function(event)
|
||||
if event.player_index then
|
||||
local player_name = get_player_name(event)
|
||||
if config[event.command] then
|
||||
emit_event{
|
||||
title=event.command:gsub('^%l',string.upper),
|
||||
description='/'..event.command..' was used',
|
||||
color=Colors.grey,
|
||||
['By:']='<inline>'..player_name,
|
||||
['Details:']=event.parameters
|
||||
}
|
||||
end
|
||||
end
|
||||
end)
|
||||
@@ -0,0 +1,58 @@
|
||||
local Commands = require 'expcore.commands'
|
||||
local Roles = require 'expcore.roles'
|
||||
local Event = require 'utils.event'
|
||||
local Game = require 'utils.game'
|
||||
local Store = require 'expcore.store'
|
||||
local config = require 'config.bonuses'
|
||||
require 'config.expcore-commands.parse_general'
|
||||
|
||||
local bonus_store =
|
||||
Store.register(function(value,category)
|
||||
local player = Game.get_player_from_any(category)
|
||||
for bonus,min_max in pairs(config) do
|
||||
local increase = min_max[2]*value
|
||||
player[bonus] = min_max[1]+increase
|
||||
end
|
||||
end)
|
||||
|
||||
Commands.new_command('bonus','Changes the amount of bonus you receive')
|
||||
:add_param('amount','integer-range',0,50)
|
||||
:register(function(player,amount)
|
||||
local percent = amount/100
|
||||
Store.set(bonus_store,player.name,percent)
|
||||
end)
|
||||
|
||||
Event.add(defines.events.on_player_respawned,function(event)
|
||||
local player = Game.get_player_by_index(event.player_index)
|
||||
local value = Store.get(bonus_store,player.name)
|
||||
if value then
|
||||
for bonus,min_max in pairs(config) do
|
||||
local increase = min_max[2]*value
|
||||
player[bonus] = min_max[1]+increase
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
Event.add(defines.events.on_pre_player_died,function(event)
|
||||
local player = Game.get_player_by_index(event.player_index)
|
||||
if Roles.player_has_flag(player,'instance-respawn') then
|
||||
player.ticks_to_respawn = 120
|
||||
-- manually dispatch death event because it is not fired when ticks_to_respawn is set pre death
|
||||
Event.dispatch{
|
||||
name=defines.events.on_player_died,
|
||||
tick=event.tick,
|
||||
player_index=event.player_index,
|
||||
cause = event.cause
|
||||
}
|
||||
end
|
||||
end)
|
||||
|
||||
local function role_update(event)
|
||||
local player = Game.get_player_by_index(event.player_index)
|
||||
if not Roles.player_allowed(player,'command/bonus') then
|
||||
Store.clear(bonus_store,player.name)
|
||||
end
|
||||
end
|
||||
|
||||
Event.add(Roles.player_role_assigned,role_update)
|
||||
Event.add(Roles.player_role_unassigned,role_update)
|
||||
@@ -561,7 +561,7 @@ Event.add(defines.events.on_rocket_launched,function(event)
|
||||
rocket_times[force_name][rockets_launched] = event.tick
|
||||
|
||||
local remove_rocket = rockets_launched-largest_rolling_avg
|
||||
if remove_rocket > 0 and not table.includes(config.milestones,remove_rocket) then
|
||||
if remove_rocket > 0 and not table.contains(config.milestones,remove_rocket) then
|
||||
rocket_times[force_name][remove_rocket] = nil
|
||||
end
|
||||
|
||||
|
||||
+12
-12
@@ -133,14 +133,14 @@ end)
|
||||
local discard_task =
|
||||
Gui.new_button()
|
||||
:set_sprites('utility/trash')
|
||||
:set_tooltip{'task-list.discord-tooltip'}
|
||||
:set_tooltip{'task-list.discard-tooltip'}
|
||||
:set_style('tool_button',function(style)
|
||||
Gui.set_padding_style(style,-2,-2,-2,-2)
|
||||
style.height = 20
|
||||
style.width = 20
|
||||
end)
|
||||
:on_click(function(player,element)
|
||||
local task_id = element.parent.caption
|
||||
local task_id = element.parent.name
|
||||
remove_task(task_id)
|
||||
update_all()
|
||||
end)
|
||||
@@ -156,10 +156,10 @@ Gui.new_button()
|
||||
style.width = 20
|
||||
end)
|
||||
:on_click(function(player,element)
|
||||
local task_id = element.parent.caption
|
||||
local task_id = element.parent.name
|
||||
local details = task_details[task_id]
|
||||
details.editing[player.name] = true
|
||||
generate_task(player,element.parent.parent,task_id)
|
||||
generate_task(player,element.parent.parent.parent,task_id)
|
||||
end)
|
||||
|
||||
--[[ Generates each task, handles both view and edit mode
|
||||
@@ -212,17 +212,17 @@ function generate_task(player,element,task_id)
|
||||
|
||||
-- if the player can edit then it adds the edit and delete button
|
||||
local flow = Gui.create_right_align(element,'edit-'..task_id)
|
||||
flow.caption = task_id
|
||||
local sub_flow = flow.add{type='flow',name=task_id}
|
||||
|
||||
edit_task(flow)
|
||||
discard_task(flow)
|
||||
edit_task(sub_flow)
|
||||
discard_task(sub_flow)
|
||||
|
||||
end
|
||||
|
||||
-- update the number indexes and the current editing players
|
||||
element['count-'..task_id].caption = task_number..')'
|
||||
|
||||
local edit_area = element['edit-'..task_id]
|
||||
local edit_area = element['edit-'..task_id][task_id]
|
||||
local players = table_keys(details.editing)
|
||||
local allowed = player_allowed_edit(player,task_id)
|
||||
|
||||
@@ -243,8 +243,8 @@ function generate_task(player,element,task_id)
|
||||
|
||||
elseif not editing then
|
||||
-- create the label, view mode
|
||||
if element['edit-'..task_id] then
|
||||
element['edit-'..task_id][edit_task.name].enabled = true
|
||||
if edit_area then
|
||||
edit_area[edit_task.name].enabled = true
|
||||
end
|
||||
|
||||
task_area.clear()
|
||||
@@ -261,8 +261,8 @@ function generate_task(player,element,task_id)
|
||||
|
||||
elseif editing and element_type ~= 'textfield' then
|
||||
-- create the text field, edit mode, update it omited as value is being edited
|
||||
if element['edit-'..task_id] then
|
||||
element['edit-'..task_id][edit_task.name].enabled = false
|
||||
if edit_area then
|
||||
edit_area[edit_task.name].enabled = false
|
||||
end
|
||||
|
||||
task_area.clear()
|
||||
|
||||
@@ -0,0 +1,766 @@
|
||||
local Gui = require 'expcore.gui'
|
||||
local Store = require 'expcore.store'
|
||||
local Global = require 'utils.global'
|
||||
local Event = require 'utils.event'
|
||||
local Game = require 'utils.game'
|
||||
local Roles = require 'expcore.roles'
|
||||
local Token = require 'utils.token'
|
||||
local Colors = require 'resources.color_presets'
|
||||
local config = require 'config.warps'
|
||||
local format_time,table_keys,table_values,table_keysort = ext_require('expcore.common','format_time','table_keys','table_values','table_keysort')
|
||||
|
||||
local warp_list
|
||||
local warp_name_store = 'gui.left.warps.names'
|
||||
local warp_icon_store = 'gui.left.warps.tags'
|
||||
local warp_player_in_range_store = 'gui.left.warps.allowed'
|
||||
|
||||
local warp_details = {}
|
||||
local force_warps = {}
|
||||
Global.register({
|
||||
warp_details=warp_details,
|
||||
force_warps=force_warps
|
||||
},function(tbl)
|
||||
force_warps = tbl.force_warps
|
||||
warp_details = tbl.warp_details
|
||||
end)
|
||||
|
||||
--- Returns if a player is allowed to edit the given warp
|
||||
local function player_allowed_edit(player,warp_id)
|
||||
if warp_id then
|
||||
local details = warp_details[warp_id]
|
||||
if not details.editing then
|
||||
return false
|
||||
end
|
||||
if config.user_can_edit_own_warps and details.last_edit_player == player.name then
|
||||
return true
|
||||
end
|
||||
else
|
||||
if config.any_user_can_add_new_warp then
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
if config.only_admins_can_edit and not player.admin then
|
||||
return false
|
||||
end
|
||||
|
||||
if config.edit_warps_role_permision and not Roles.player_allowed(player,config.edit_warps_role_permision) then
|
||||
return false
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
--- Makes a map marker for this warp; updates it if already present
|
||||
local function make_warp_tag(warp_id)
|
||||
local warp = warp_details[warp_id]
|
||||
if not warp then return end
|
||||
|
||||
local icon = Store.get(warp_icon_store,warp_id)
|
||||
local name = Store.get(warp_name_store,warp_id)
|
||||
|
||||
if warp.tag and warp.tag.valid then
|
||||
warp.tag.text = 'Warp: '..name
|
||||
warp.tag.icon = {type='item',name=icon}
|
||||
return
|
||||
end
|
||||
|
||||
local force = game.forces[warp.force]
|
||||
local surface = warp.surface
|
||||
local position = warp.position
|
||||
|
||||
local tag = force.add_chart_tag(surface,{
|
||||
position={position.x+0.5,position.y+0.5},
|
||||
text='Warp: '..name,
|
||||
icon={type='item',name=icon}
|
||||
})
|
||||
|
||||
warp.tag = tag
|
||||
end
|
||||
|
||||
-- This creates the area for the warp; this is not required but helps players know where the warps are
|
||||
local function make_warp_area(warp_id)
|
||||
local warp = warp_details[warp_id]
|
||||
if not warp then return end
|
||||
|
||||
local position = warp.position
|
||||
local posx = position.x
|
||||
local posy = position.y
|
||||
local surface = warp.surface
|
||||
local radius = config.activation_range
|
||||
local radius2 = radius^2
|
||||
|
||||
local old_tile = surface.get_tile(position).name
|
||||
warp.old_tile = old_tile
|
||||
|
||||
local base_tile = config.base_tile
|
||||
local base_tiles = {}
|
||||
-- this makes a base plate to make the warp point
|
||||
for x = -radius, radius do
|
||||
local x2 = x^2
|
||||
for y = -radius, radius do
|
||||
local y2 = y^2
|
||||
if x2+y2 < radius2 then
|
||||
table.insert(base_tiles,{name=base_tile,position={x+posx,y+posy}})
|
||||
end
|
||||
end
|
||||
end
|
||||
surface.set_tiles(base_tiles)
|
||||
|
||||
-- this adds the tile pattern
|
||||
local tiles = {}
|
||||
for _,pos in pairs(config.tiles) do
|
||||
table.insert(tiles,{name=base_tile,position={pos[1]+posx,pos[2]+posy}})
|
||||
end
|
||||
surface.set_tiles(tiles)
|
||||
|
||||
-- this adds the enitites
|
||||
for _,entity in pairs(config.entities) do
|
||||
entity = surface.create_entity{
|
||||
name=entity[1],
|
||||
position={entity[2]+posx,entity[3]+posy},
|
||||
force='neutral'
|
||||
}
|
||||
entity.destructible = false
|
||||
entity.health = 0
|
||||
entity.minable = false
|
||||
entity.rotatable = false
|
||||
end
|
||||
end
|
||||
|
||||
--- This removes the warp area, also restores the old tile
|
||||
local function clear_warp_area(warp_id)
|
||||
local warp = warp_details[warp_id]
|
||||
if not warp then return end
|
||||
|
||||
local position = warp.position
|
||||
local surface = warp.surface
|
||||
local radius = config.activation_range
|
||||
local radius2 = radius^2
|
||||
|
||||
local base_tile = warp.old_tile
|
||||
local tiles = {}
|
||||
-- clears the area where the warp was
|
||||
for x = -radius, radius do
|
||||
local x2 = x^2
|
||||
for y = -radius, radius do
|
||||
local y2 = y^2
|
||||
if x2+y2 < radius2 then
|
||||
table.insert(tiles,{name=base_tile,position={x+position.x,y+position.y}})
|
||||
end
|
||||
end
|
||||
end
|
||||
surface.set_tiles(tiles)
|
||||
|
||||
-- removes all entites (in the area) on the neutral force
|
||||
local entities = surface.find_entities_filtered{
|
||||
force='neutral',
|
||||
area={
|
||||
{position.x-radius,position.y-radius},
|
||||
{position.x+radius,position.y+radius}
|
||||
}
|
||||
}
|
||||
for _,entity in pairs(entities) do if entity.name ~= 'player' then entity.destroy() end end
|
||||
|
||||
if warp.tag and warp.tag.valid then warp.tag.destroy() end
|
||||
end
|
||||
|
||||
--- Speaial case for the warps; adds the spawn warp which cant be removed
|
||||
local function add_spawn(player)
|
||||
local warp_id = tostring(Token.uid())
|
||||
local force = player.force
|
||||
local force_name = force.name
|
||||
local surface = player.surface
|
||||
local spawn = force.get_spawn_position(surface)
|
||||
|
||||
if not force_warps[force_name] then
|
||||
force_warps[force_name] = {}
|
||||
end
|
||||
table.insert(force_warps[force_name],warp_id)
|
||||
|
||||
warp_details[warp_id] = {
|
||||
warp_id = warp_id,
|
||||
force = force.name,
|
||||
position = {
|
||||
x=math.floor(spawn.x),
|
||||
y=math.floor(spawn.y)
|
||||
},
|
||||
surface = surface,
|
||||
last_edit_player='System',
|
||||
last_edit_time=game.tick,
|
||||
editing=false
|
||||
}
|
||||
|
||||
Store.set(warp_name_store,warp_id,'Spawn')
|
||||
Store.set(warp_icon_store,warp_id,config.default_icon)
|
||||
end
|
||||
|
||||
--- General case for the warps; will make a new warp and set the player to be editing it
|
||||
local function add_warp(player)
|
||||
local warp_id = tostring(Token.uid())
|
||||
local force_name = player.force.name
|
||||
|
||||
if not force_warps[force_name] then
|
||||
add_spawn(player)
|
||||
end
|
||||
table.insert(force_warps[force_name],warp_id)
|
||||
|
||||
local position = player.position
|
||||
|
||||
warp_details[warp_id] = {
|
||||
warp_id = warp_id,
|
||||
force = force_name,
|
||||
position = {
|
||||
x=math.floor(position.x),
|
||||
y=math.floor(position.y)
|
||||
},
|
||||
surface = player.surface,
|
||||
last_edit_player=player.name,
|
||||
last_edit_time=game.tick,
|
||||
editing={[player.name]=true}
|
||||
}
|
||||
|
||||
Store.set(warp_name_store,warp_id,'New warp')
|
||||
Store.set(warp_icon_store,warp_id,config.default_icon)
|
||||
|
||||
make_warp_area(warp_id)
|
||||
end
|
||||
|
||||
--- Removes all refrences to a warp
|
||||
local function remove_warp(warp_id)
|
||||
local force_name = warp_details[warp_id].force
|
||||
local key = table.index_of(force_warps[force_name],warp_id)
|
||||
force_warps[force_name][key] = nil
|
||||
Store.clear(warp_name_store,warp_id)
|
||||
Store.clear(warp_icon_store,warp_id)
|
||||
warp_details[warp_id] = nil
|
||||
end
|
||||
|
||||
--- This timer controls when a player is able to warp, eg every 60 seconds
|
||||
local warp_timer =
|
||||
Gui.new_progressbar()
|
||||
:set_tooltip{'warp-list.timer-tooltip',config.recharge_time}
|
||||
:set_default_maximum(math.floor(config.recharge_time*config.update_smothing))
|
||||
:add_store(Gui.player_store)
|
||||
:set_style(nil,function(style)
|
||||
style.horizontally_stretchable = true
|
||||
style.color = Colors.light_blue
|
||||
end)
|
||||
:on_store_complete(function(player_name,reset)
|
||||
Store.set(warp_player_in_range_store,player_name,true)
|
||||
end)
|
||||
|
||||
--- When the button is clicked it will teleport the player
|
||||
local goto_warp =
|
||||
Gui.new_button()
|
||||
:set_sprites('item/'..config.default_icon)
|
||||
:set_tooltip{'warp-list.goto-tooltip',0,0}
|
||||
:set_style('quick_bar_slot_button',function(style)
|
||||
style.height = 32
|
||||
style.width = 32
|
||||
end)
|
||||
:on_click(function(player,element)
|
||||
local warp_id = element.parent.caption
|
||||
local warp = warp_details[warp_id]
|
||||
local surface = warp.surface
|
||||
local position = {
|
||||
x=warp.position.x+0.5,
|
||||
y=warp.position.y+0.5
|
||||
}
|
||||
|
||||
local goto_position = surface.find_non_colliding_position('character',position,32,1)
|
||||
if player.driving then player.driving = false end
|
||||
player.teleport(goto_position,surface)
|
||||
|
||||
if config.bypass_warp_limits_permision and not Roles.player_allowed(player,config.bypass_warp_limits_permision) then
|
||||
warp_timer:set_store(player.name,0)
|
||||
Store.set(warp_player_in_range_store,player.name,false)
|
||||
end
|
||||
end)
|
||||
|
||||
--- Will add a new warp to the list, checks if the player is too close to an existing one
|
||||
local add_new_warp =
|
||||
Gui.new_button()
|
||||
:set_sprites('utility/add')
|
||||
:set_tooltip{'warp-list.add-tooltip'}
|
||||
:set_style('tool_button',function(style)
|
||||
Gui.set_padding_style(style,-2,-2,-2,-2)
|
||||
style.height = 20
|
||||
style.width = 20
|
||||
end)
|
||||
:on_click(function(player,element)
|
||||
local position = player.position
|
||||
local posx = position.x
|
||||
local posy = position.y
|
||||
local dist2 = config.minimum_distance^2
|
||||
|
||||
local warps = Store.get_children(warp_name_store)
|
||||
for _,warp_id in pairs(warps) do
|
||||
local warp = warp_details[warp_id]
|
||||
local pos = warp.position
|
||||
if (posx-pos.x)^2+(posy-pos.y)^2 < dist2 then
|
||||
local warp_name = Store.get(warp_name_store,warp_id)
|
||||
player.print{'warp-list.too-close',warp_name}
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
add_warp(player)
|
||||
end)
|
||||
|
||||
--- Confirms the edit to name or icon of the warp
|
||||
local confirm_edit =
|
||||
Gui.new_button()
|
||||
:set_sprites('utility/downloaded')
|
||||
:set_tooltip{'warp-list.confirm-tooltip'}
|
||||
:set_style('tool_button',function(style)
|
||||
Gui.set_padding_style(style,-2,-2,-2,-2)
|
||||
style.height = 20
|
||||
style.width = 20
|
||||
end)
|
||||
:on_click(function(player,element)
|
||||
local warp_id = element.parent.name
|
||||
local warp_name = element.parent.warp.text
|
||||
local warp_icon = element.parent.parent['icon-'..warp_id].icon.elem_value
|
||||
local warp = warp_details[warp_id]
|
||||
warp.editing[player.name] = nil
|
||||
warp.last_edit_player = player.name
|
||||
warp.last_edit_time = game.tick
|
||||
Store.set(warp_name_store,warp_id,warp_name)
|
||||
Store.set(warp_icon_store,warp_id,warp_icon)
|
||||
end)
|
||||
|
||||
--- Cancels the editing changes of the selected warp name or icon
|
||||
local generate_warp
|
||||
local cancel_edit =
|
||||
Gui.new_button()
|
||||
:set_sprites('utility/close_black')
|
||||
:set_tooltip{'warp-list.cancel-tooltip'}
|
||||
:set_style('tool_button',function(style)
|
||||
Gui.set_padding_style(style,-2,-2,-2,-2)
|
||||
style.height = 20
|
||||
style.width = 20
|
||||
end)
|
||||
:on_click(function(player,element)
|
||||
local warp_id = element.parent.name
|
||||
local details = warp_details[warp_id]
|
||||
details.editing[player.name] = nil
|
||||
generate_warp(player,element.parent.parent,warp_id)
|
||||
end)
|
||||
|
||||
--- Removes a warp from the list, including the physical area and map tag
|
||||
local discard_warp =
|
||||
Gui.new_button()
|
||||
:set_sprites('utility/trash')
|
||||
:set_tooltip{'warp-list.discard-tooltip'}
|
||||
:set_style('tool_button',function(style)
|
||||
Gui.set_padding_style(style,-2,-2,-2,-2)
|
||||
style.height = 20
|
||||
style.width = 20
|
||||
end)
|
||||
:on_click(function(player,element)
|
||||
local warp_id = element.parent.name
|
||||
remove_warp(warp_id)
|
||||
end)
|
||||
|
||||
--- Opens edit mode for the warp
|
||||
local edit_warp =
|
||||
Gui.new_button()
|
||||
:set_sprites('utility/rename_icon_normal')
|
||||
:set_tooltip{'warp-list.edit-tooltip-none'}
|
||||
:set_style('tool_button',function(style)
|
||||
Gui.set_padding_style(style,-2,-2,-2,-2)
|
||||
style.height = 20
|
||||
style.width = 20
|
||||
end)
|
||||
:on_click(function(player,element)
|
||||
local warp_id = element.parent.name
|
||||
local details = warp_details[warp_id]
|
||||
details.editing[player.name] = true
|
||||
generate_warp(player,element.parent.parent.parent,warp_id)
|
||||
end)
|
||||
|
||||
--[[ Generates each task, handles both view and edit mode
|
||||
element
|
||||
> icon-"warp_id"
|
||||
>> goto_warp or icon
|
||||
> "warp_id"
|
||||
>> warp
|
||||
>> cancel_edit (edit mode)
|
||||
>> confirm_edit (edit mode)
|
||||
> edit-"warp_id"
|
||||
>> "warp_id"
|
||||
>>> edit_warp
|
||||
>>> discard_warp
|
||||
]]
|
||||
function generate_warp(player,element,warp_id)
|
||||
local warp_name = Store.get(warp_name_store,warp_id)
|
||||
local warp_icon = Store.get(warp_icon_store,warp_id) or config.default_icon
|
||||
local warp = warp_details[warp_id]
|
||||
|
||||
local editing = warp.editing and warp.editing[player.name]
|
||||
local last_edit_player = warp.last_edit_player
|
||||
local last_edit_time = warp.last_edit_time
|
||||
local position = warp.position
|
||||
|
||||
if not warp_name then
|
||||
-- task is nil so remove it from the list
|
||||
Gui.destory_if_valid(element['icon-'..warp_id])
|
||||
Gui.destory_if_valid(element['edit-'..warp_id])
|
||||
Gui.destory_if_valid(element[warp_id])
|
||||
|
||||
else
|
||||
-- if it is not already present then add it now
|
||||
local warp_area = element[warp_id]
|
||||
local icon_area = element['icon-'..warp_id]
|
||||
if not warp_area then
|
||||
-- area to store the warp icon
|
||||
icon_area =
|
||||
element.add{
|
||||
name='icon-'..warp_id,
|
||||
type='flow',
|
||||
caption=warp_id
|
||||
}
|
||||
Gui.set_padding(icon_area)
|
||||
|
||||
-- area which stores the task and buttons
|
||||
warp_area =
|
||||
element.add{
|
||||
name=warp_id,
|
||||
type='flow',
|
||||
}
|
||||
Gui.set_padding(warp_area)
|
||||
|
||||
-- if the player can edit then it adds the edit and delete button
|
||||
local flow = Gui.create_right_align(element,'edit-'..warp_id)
|
||||
local sub_flow = flow.add{type='flow',name=warp_id}
|
||||
|
||||
edit_warp(sub_flow)
|
||||
discard_warp(sub_flow)
|
||||
|
||||
end
|
||||
|
||||
local edit_area = element['edit-'..warp_id][warp_id]
|
||||
local players = warp.editing and table_keys(warp.editing) or {}
|
||||
local allowed = player_allowed_edit(player,warp_id)
|
||||
|
||||
edit_area.visible = allowed
|
||||
|
||||
if #players > 0 then
|
||||
edit_area[edit_warp.name].tooltip = {'task-list.edit-tooltip',table.concat(players,', ')}
|
||||
else
|
||||
edit_area[edit_warp.name].tooltip = {'task-list.edit-tooltip-none'}
|
||||
end
|
||||
|
||||
-- draws/updates the warp area
|
||||
local element_type = warp_area.warp and warp_area.warp.type or nil
|
||||
if not editing and element_type == 'label' then
|
||||
-- update the label already present
|
||||
warp_area.warp.caption = warp_name
|
||||
warp_area.warp.tooltip = {'warp-list.last-edit',last_edit_player,format_time(last_edit_time)}
|
||||
icon_area[goto_warp.name].sprite = 'item/'..warp_icon
|
||||
|
||||
elseif not editing then
|
||||
-- create the label, view mode
|
||||
if edit_area then
|
||||
edit_area[edit_warp.name].enabled = true
|
||||
end
|
||||
|
||||
-- redraws the icon for the warp
|
||||
icon_area.clear()
|
||||
|
||||
local btn = goto_warp(icon_area)
|
||||
btn.sprite = 'item/'..warp_icon
|
||||
btn.tooltip = {'warp-list.goto-tooltip',position.x,position.y}
|
||||
|
||||
local timer = warp_timer:get_store(player.name)
|
||||
local enabled = not timer and Store.get(warp_player_in_range_store,player.name)
|
||||
if not enabled then
|
||||
btn.enabled = false
|
||||
btn.tooltip = {'warp-list.goto-disabled'}
|
||||
end
|
||||
|
||||
-- redraws the label for the warp name
|
||||
warp_area.clear()
|
||||
|
||||
local label =
|
||||
warp_area.add{
|
||||
name='warp',
|
||||
type='label',
|
||||
caption=warp_name,
|
||||
tooltip={'warp-list.last-edit',last_edit_player,format_time(last_edit_time)}
|
||||
}
|
||||
label.style.single_line = false
|
||||
label.style.maximal_width = 150
|
||||
|
||||
elseif editing and element_type ~= 'textfield' then
|
||||
-- create the text field, edit mode, update it omited as value is being edited
|
||||
if edit_area then
|
||||
edit_area[edit_warp.name].enabled = false
|
||||
end
|
||||
|
||||
-- redraws the icon for the warp and allows selection
|
||||
icon_area.clear()
|
||||
|
||||
local btn =
|
||||
icon_area.add{
|
||||
name='icon',
|
||||
type='choose-elem-button',
|
||||
elem_type='item',
|
||||
item=warp_icon,
|
||||
tooltip={'warp-list.goto-edit'},
|
||||
}
|
||||
btn.style.height = 32
|
||||
btn.style.width = 32
|
||||
|
||||
-- redraws the label for the warp name and allows editing
|
||||
warp_area.clear()
|
||||
|
||||
local entry =
|
||||
warp_area.add{
|
||||
name='warp',
|
||||
type='textfield',
|
||||
text=warp_name
|
||||
}
|
||||
entry.style.maximal_width = 150
|
||||
entry.style.height = 20
|
||||
|
||||
cancel_edit(warp_area)
|
||||
confirm_edit(warp_area)
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
--[[ generates the main gui structure
|
||||
element
|
||||
> container
|
||||
>> header
|
||||
>>> right aligned add_new_task
|
||||
>> scroll
|
||||
>>> table
|
||||
>> warp_timer
|
||||
]]
|
||||
local function generate_container(player,element)
|
||||
Gui.set_padding(element,2,2,2,2)
|
||||
element.style.minimal_width = 200
|
||||
|
||||
-- main container which contains the other elements
|
||||
local container =
|
||||
element.add{
|
||||
name='container',
|
||||
type='frame',
|
||||
direction='vertical',
|
||||
style='window_content_frame_packed'
|
||||
}
|
||||
Gui.set_padding(container)
|
||||
container.style.vertically_stretchable = false
|
||||
|
||||
-- main header for the gui
|
||||
local header =
|
||||
container.add{
|
||||
name='header',
|
||||
type='frame',
|
||||
style='subheader_frame'
|
||||
}
|
||||
Gui.set_padding(header,2,2,4,4)
|
||||
header.style.horizontally_stretchable = true
|
||||
header.style.use_header_filler = false
|
||||
|
||||
--- Caption for the header bar
|
||||
header.add{
|
||||
type='label',
|
||||
style='heading_1_label',
|
||||
caption={'warp-list.main-caption'},
|
||||
tooltip={'warp-list.sub-tooltip',config.recharge_time,config.activation_range}
|
||||
}
|
||||
|
||||
--- Right aligned button to toggle the section
|
||||
if player_allowed_edit(player) then
|
||||
local right_align = Gui.create_right_align(header)
|
||||
add_new_warp(right_align)
|
||||
end
|
||||
|
||||
-- main flow for the data
|
||||
local flow =
|
||||
container.add{
|
||||
name='scroll',
|
||||
type='scroll-pane',
|
||||
direction='vertical',
|
||||
horizontal_scroll_policy='never',
|
||||
vertical_scroll_policy='auto-and-reserve-space'
|
||||
}
|
||||
Gui.set_padding(flow,1,1,2,2)
|
||||
flow.style.horizontally_stretchable = true
|
||||
flow.style.maximal_height = 258
|
||||
|
||||
-- table that stores all the data
|
||||
local flow_table =
|
||||
flow.add{
|
||||
name='table',
|
||||
type='table',
|
||||
column_count=3
|
||||
}
|
||||
Gui.set_padding(flow_table)
|
||||
flow_table.style.horizontally_stretchable = true
|
||||
flow_table.style.top_cell_padding = 3
|
||||
flow_table.style.bottom_cell_padding = 3
|
||||
|
||||
warp_timer(container)
|
||||
|
||||
return flow_table
|
||||
end
|
||||
|
||||
--- Registers the warp list
|
||||
warp_list =
|
||||
Gui.new_left_frame('gui/warp-list')
|
||||
:set_sprites('item/'..config.default_icon)
|
||||
:set_tooltip{'warp-list.main-tooltip',config.activation_range}
|
||||
:set_direction('vertical')
|
||||
:on_draw(function(player,element)
|
||||
local data_table = generate_container(player,element)
|
||||
local force_name = player.force.name
|
||||
|
||||
local warps = force_warps[force_name] or {}
|
||||
for _,warp_id in pairs(warps) do
|
||||
generate_warp(player,data_table,warp_id)
|
||||
end
|
||||
end)
|
||||
:on_update(function(player,element)
|
||||
local data_table = element.container.scroll.table
|
||||
local force_name = player.force.name
|
||||
|
||||
data_table.clear()
|
||||
|
||||
local warps = force_warps[force_name] or {}
|
||||
for _,warp_id in pairs(warps) do
|
||||
generate_warp(player,data_table,warp_id)
|
||||
end
|
||||
end)
|
||||
|
||||
--- When the name of a warp is updated this is triggered
|
||||
Store.register(warp_name_store,function(value,warp_id)
|
||||
local warp = warp_details[warp_id]
|
||||
local force = game.forces[warp.force]
|
||||
|
||||
local names = {}
|
||||
local spawn_id
|
||||
for _,_warp_id in pairs(force_warps[force.name]) do
|
||||
local name = Store.get(warp_name_store,_warp_id)
|
||||
if not warp_details[_warp_id].editing then
|
||||
spawn_id = _warp_id
|
||||
else
|
||||
names[name.._warp_id] = _warp_id
|
||||
end
|
||||
end
|
||||
|
||||
force_warps[force.name] = table_values(table_keysort(names))
|
||||
table.insert(force_warps[force.name],1,spawn_id)
|
||||
|
||||
for _,player in pairs(force.players) do
|
||||
warp_list:update(player)
|
||||
end
|
||||
end)
|
||||
|
||||
--- When the icon is updated this is called
|
||||
Store.register(warp_icon_store,function(value,warp_id)
|
||||
local warp = warp_details[warp_id]
|
||||
local force = game.forces[warp.force]
|
||||
|
||||
for _,player in pairs(force.players) do
|
||||
local frame = warp_list:get_frame(player)
|
||||
local element = frame.container.scroll.table
|
||||
generate_warp(player,element,warp_id)
|
||||
end
|
||||
|
||||
if value then
|
||||
make_warp_tag(warp_id)
|
||||
else
|
||||
clear_warp_area(warp_id)
|
||||
end
|
||||
end)
|
||||
|
||||
--- When the player leaves or enters range of a warp this is triggered
|
||||
Store.register(warp_player_in_range_store,function(value,player_name)
|
||||
local player = game.players[player_name]
|
||||
local force = player.force
|
||||
local frame = warp_list:get_frame(player_name)
|
||||
local table_area = frame.container.scroll.table
|
||||
local timer = warp_timer:get_store(player_name)
|
||||
local state = not timer and value
|
||||
|
||||
if force_warps[force.name] then
|
||||
for _,warp_id in pairs(force_warps[force.name]) do
|
||||
local element = table_area['icon-'..warp_id][goto_warp.name]
|
||||
if element and element.valid then
|
||||
element.enabled = state
|
||||
if state then
|
||||
local position = warp_details[warp_id].position
|
||||
element.tooltip = {'warp-list.goto-tooltip',position.x,position.y}
|
||||
else
|
||||
element.tooltip = {'warp-list.goto-disabled'}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
--- Handles updating the timer and checking distance from a warp
|
||||
local r2 = config.activation_range^2
|
||||
local rs2 = config.spawn_activation_range^2
|
||||
Event.on_nth_tick(math.floor(60/config.update_smothing),function()
|
||||
local categories = Store.get_children(warp_timer.store)
|
||||
for _,category in pairs(categories) do
|
||||
warp_timer:increment(1,category)
|
||||
end
|
||||
|
||||
for _,player in pairs(game.connected_players) do
|
||||
local timer = warp_timer:get_store(player.name)
|
||||
local role = config.bypass_warp_limits_permision and Roles.player_allowed(player,config.bypass_warp_limits_permision)
|
||||
|
||||
if not timer and not role then
|
||||
local force = player.force
|
||||
local warps = force_warps[force.name]
|
||||
|
||||
if warps then
|
||||
local surface = player.surface.index
|
||||
local pos = player.position
|
||||
local px,py = pos.x,pos.y
|
||||
|
||||
for _,warp_id in pairs(warps) do
|
||||
local warp = warp_details[warp_id]
|
||||
local wpos = warp.position
|
||||
if warp.surface.index == surface then
|
||||
local dx,dy = px-wpos.x,py-wpos.y
|
||||
if not warp.editing and (dx*dx)+(dy*dy) < rs2 or (dx*dx)+(dy*dy) < r2 then
|
||||
Store.set(warp_player_in_range_store,player.name,true)
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Store.set(warp_player_in_range_store,player.name,false)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end)
|
||||
|
||||
--- When a player is created it will set them being in range to false to stop warping on join
|
||||
Event.add(defines.events.on_player_created,function(event)
|
||||
local player = Game.get_player_by_index(event.player_index)
|
||||
local force_name = player.force.name
|
||||
|
||||
local allowed = config.bypass_warp_limits_permision and Roles.player_allowed(player,config.bypass_warp_limits_permision) or false
|
||||
Store.set(warp_player_in_range_store,player.name,allowed)
|
||||
|
||||
if not force_warps[force_name] then
|
||||
add_spawn(player)
|
||||
end
|
||||
end)
|
||||
|
||||
return warp_list
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -1,87 +0,0 @@
|
||||
--- A full ranking system for factorio.
|
||||
-- @module ExpGamingCommands.bonus@^4.0.0
|
||||
-- @author Cooldude2606
|
||||
-- @license https://github.com/explosivegaming/scenario/blob/master/LICENSE
|
||||
|
||||
local global = {}
|
||||
Global.register(global,function(tbl) global = tbl end)
|
||||
local Game = require('FactorioStdLib.Game')
|
||||
|
||||
-- these are the settings which are changed with scale being as +100%
|
||||
local settings = {
|
||||
character_mining_speed_modifier=3,
|
||||
character_crafting_speed_modifier=3,
|
||||
character_running_speed_modifier=3,
|
||||
character_build_distance_bonus=20,
|
||||
character_reach_distance_bonus=20,
|
||||
character_inventory_slots_bonus=200
|
||||
}
|
||||
|
||||
--- Allows a player to set there bonus
|
||||
-- @command bonus
|
||||
-- @param bonus the amount of bonus there will get
|
||||
commands.add_command('bonus', 'Set your player bonus (default is 20, guest has 0)', {
|
||||
['bonus'] = {true,'number-range-int',-1,50} -- -1 < math.floor(bonus) <= 50
|
||||
}, function(event,args)
|
||||
local player = Game.get_player(event)
|
||||
local bonus = args.bonus
|
||||
for key,setting in pairs(settings) do player[key] = setting*math.floor(bonus)*0.01 end
|
||||
global[player.index]=bonus
|
||||
player_return('Bonus set to: '..math.floor(bonus)..'%')
|
||||
end).default_admin_only = true
|
||||
|
||||
Event.add(defines.events.on_player_respawned,function(event)
|
||||
local player = Game.get_player(event)
|
||||
local bonus = global[player.index]
|
||||
if bonus then
|
||||
for key,setting in pairs(settings) do player[key] = setting*math.floor(bonus)*0.01 end
|
||||
end
|
||||
end)
|
||||
|
||||
-- overridden by ExpGamingCore.Role if present
|
||||
Event.add(defines.events.on_pre_player_died,function(event)
|
||||
local player = Game.get_player(event)
|
||||
if player.admin then
|
||||
player.ticks_to_respawn = 120
|
||||
-- manually dispatch death event because it is not fired when ticks_to_respawn is set pre death
|
||||
Event.dispatch{
|
||||
name=defines.events.on_player_died,
|
||||
tick=event.tick,
|
||||
player_index=event.player_index,
|
||||
cause = event.cause
|
||||
}
|
||||
end
|
||||
end)
|
||||
|
||||
return {
|
||||
on_init= function(self)
|
||||
if loaded_modules['ExpGamingCore.Role'] then
|
||||
local Role = require('ExpGamingCore.Role')
|
||||
-- instant respawn
|
||||
Event.add(defines.events.on_pre_player_died,function(event)
|
||||
local player = Game.get_player(event)
|
||||
if Role.allowed(player,'bonus-respawn') then
|
||||
player.ticks_to_respawn = 120
|
||||
-- manually dispatch death event because it is not fired when ticks_to_respawn is set pre death
|
||||
script.raise_event(defines.events.on_player_died,{
|
||||
name=defines.events.on_player_died,
|
||||
tick=event.tick,
|
||||
player_index=event.player_index,
|
||||
cause = event.cause
|
||||
})
|
||||
end
|
||||
end)
|
||||
-- either clears or adds default when rank changed
|
||||
Event.add(defines.events.role_change,function(event)
|
||||
local player = Game.get_player(event)
|
||||
if Role.allowed(player,'bonus') then
|
||||
for key,setting in pairs(settings) do player[key] = setting*0.2 end
|
||||
global[player.index]=20
|
||||
else
|
||||
for key in pairs(settings) do player[key] = 0 end
|
||||
global[player.index]=nil
|
||||
end
|
||||
end)
|
||||
end
|
||||
end
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
{
|
||||
"name": "ExpGamingCommands.bonus",
|
||||
"version": "4.0.0",
|
||||
"description": "Allows a bonus to be applied to players and instant respawn.",
|
||||
"location": "FSM_ARCHIVE",
|
||||
"keywords": [
|
||||
"Instant Respawn",
|
||||
"Bonus",
|
||||
"Cheat",
|
||||
"Commands",
|
||||
"ExpGaming",
|
||||
"Respawn"
|
||||
],
|
||||
"dependencies": {
|
||||
"FactorioStdLib.Game": "^0.8.0",
|
||||
"ExpGamingLib": "^4.0.0",
|
||||
"ExpGamingCore.Command": "^4.0.0",
|
||||
"ExpGamingCore.Role": "?^4.0.0"
|
||||
},
|
||||
"collection": "ExpGamingCommands@4.0.0",
|
||||
"submodules": {}
|
||||
}
|
||||
Reference in new issue
Block a user