Improved Auto Assign

This commit is contained in:
Cooldude2606
2020-09-08 18:40:33 +01:00
parent bdf94bf275
commit a84c42aa3c
2 changed files with 51 additions and 28 deletions

View File

@@ -174,6 +174,7 @@ Roles.new_role('Veteran','Vet')
'command/chat-bot', 'command/chat-bot',
} }
:set_auto_assign_condition(function(player) :set_auto_assign_condition(function(player)
game.print('Checked auto assign vet')
if player.online_time > 10*216000 then if player.online_time > 10*216000 then
return true return true
end end
@@ -204,6 +205,7 @@ Roles.new_role('Regular','Reg')
'standard-decon' 'standard-decon'
} }
:set_auto_assign_condition(function(player) :set_auto_assign_condition(function(player)
game.print('Checked auto assign reg')
if player.online_time > 3*216000 then if player.online_time > 3*216000 then
return true return true
end end
@@ -238,7 +240,7 @@ local default = Roles.new_role('Guest','')
Roles.new_role('Jail') Roles.new_role('Jail')
:set_permission_group('Restricted') :set_permission_group('Restricted')
:set_custom_color{r=50,g=50,b=50} :set_custom_color{r=50,g=50,b=50}
:set_block_auto_promote(true) :set_block_auto_assign(true)
:disallow(default.allowed) :disallow(default.allowed)
--- System defaults which are required to be set --- System defaults which are required to be set

View File

@@ -123,7 +123,8 @@ local Roles = {
roles = {}, -- Contains the raw info for the roles, indexed by role name roles = {}, -- Contains the raw info for the roles, indexed by role name
flags = {}, -- Contains functions that run when a flag is added/removed from a player flags = {}, -- Contains functions that run when a flag is added/removed from a player
internal = {}, -- Contains all internally accessed roles, such as root, default internal = {}, -- Contains all internally accessed roles, such as root, default
players = {} -- Contains the roles that players have players = {}, -- Contains the roles that players have
auto_assign = {} -- Contains references to all roles which have auto assign conditions
}, },
events = { events = {
on_role_assigned = script.generate_event_name(), on_role_assigned = script.generate_event_name(),
@@ -807,7 +808,7 @@ end
--[[-- Sets an auto assign condition that is checked every 60 seconds, if true is returned then the player will receive the role --[[-- Sets an auto assign condition that is checked every 60 seconds, if true is returned then the player will receive the role
nb: this is one way, failing false after already gaining the role will not revoke the role nb: this is one way, failing false after already gaining the role will not revoke the role
@tparam function callback receives only one param which is player to promote, return true to promote the player @tparam function callback receives only one param which is player to assign, return true to assign the player
@treturn Roles._prototype allows chaining @treturn Roles._prototype allows chaining
@usage-- Give this role to a user if there are admin, ran every 60 seconds @usage-- Give this role to a user if there are admin, ran every 60 seconds
@@ -818,21 +819,33 @@ end)
]] ]]
function Roles._prototype:set_auto_assign_condition(callback) function Roles._prototype:set_auto_assign_condition(callback)
_C.error_if_runtime() _C.error_if_runtime()
self.auto_promote_condition = callback self.auto_assign_condition = true
Roles.config.auto_assign[self.name] = callback
return self return self
end end
--[[-- Get the auto assign condition for this role, returns nil if no condition is set
@treturn function The callback which was assigned as the auto assign condition
@usage-- Give this role to a user if there are admin, ran every 60 seconds
local condition = role:get_auto_assign_condition()
]]
function Roles._prototype:get_auto_assign_condition()
return Roles.config.auto_assign[self.name]
end
--[[-- Sets the role to not allow players to have auto assign effect them, useful to keep people locked to a role --[[-- Sets the role to not allow players to have auto assign effect them, useful to keep people locked to a role
@tparam[opt=true] boolean state when true the players with this role will not be auto assigned to other roles @tparam[opt=true] boolean state when true the players with this role will not be auto assigned to other roles
@treturn Roles._prototype allows chaining @treturn Roles._prototype allows chaining
@usage-- Make a role stop players from being auto assigned to other roles @usage-- Make a role stop players from being auto assigned to other roles
role:set_block_auto_promote() role:set_block_auto_assign()
]] ]]
function Roles._prototype:set_block_auto_promote(state) function Roles._prototype:set_block_auto_assign(state)
if state == nil then state = true end if state == nil then state = true end
self.block_auto_promote = not not state -- forces a boolean value self.block_auto_assign = not not state -- forces a boolean value
return self return self
end end
@@ -993,35 +1006,43 @@ local function role_update(event)
end end
end end
--- Used internally to test if a player should be auto assigned a role
local function auto_assign(event)
local player = game.players[event.player_index]
local roles = Roles.config.players[player.name] or {}
local lookup = {}
for _, role in ipairs(roles) do lookup[role] = true end
local assigns, ctn = {}, 0
for role, condition in pairs(Roles.config.auto_assign) do
if not lookup[role] then
local success, rtn = pcall(condition, player)
if not success then
log{'expcore-roles.error-log-format-assign', role.name, rtn}
elseif rtn == true then
ctn = ctn + 1
assigns[ctn] = role
end
end
end
if ctn > 0 then Roles.assign_player(player, assigns) end
end
--- When a player joined or has a role change then the update is triggered --- When a player joined or has a role change then the update is triggered
Event.add(Roles.events.on_role_assigned, role_update) Event.add(Roles.events.on_role_assigned, role_update)
Event.add(Roles.events.on_role_unassigned, role_update) Event.add(Roles.events.on_role_unassigned, role_update)
Event.add(defines.events.on_player_joined_game, role_update) Event.add(defines.events.on_player_joined_game, role_update)
-- Every 60 seconds the auto promote check is preformed
--- Every 60 seconds and on join auto role assignment is checked
Event.add(defines.events.on_player_joined_game, auto_assign)
Event.on_nth_tick(3600, function() Event.on_nth_tick(3600, function()
local promotes = {}
for _, player in ipairs(game.connected_players) do for _, player in ipairs(game.connected_players) do
for _, role in pairs(Roles.config.roles) do auto_assign{ player_index = player.index }
if role.auto_promote_condition then
local success, err = pcall(role.auto_promote_condition, player)
if not success then
log{'expcore-roles.error-log-format-promote', role.name, err}
else
if err == true and not Roles.player_has_role(player, role) then
if promotes[player.name] then
table.insert(promotes[player.name], role.name)
else
promotes[player.name] = {role.name}
end
end
end
end
end
end
for player_name, roles in pairs(promotes) do
Roles.assign_player(player_name, roles)
end end
end) end)
-- Return Roles -- Return Roles
return Roles return Roles