mirror of
https://github.com/CFC-Servers/cfc_ulx_commands.git
synced 2025-03-04 03:13:28 -05:00
Allow ulx curse to specify an amount of random effects to give (#144)
* Allow ulx curse to specify an amount of random effects to give * Filter out incompatible effects between each draw * Safety checks * Clamp instead of abort * A smidge of pazazz * Clarity
This commit is contained in:
parent
5068562a71
commit
ae0b65eb75
@ -1,5 +1,6 @@
|
||||
CFCUlxCommands.curse = CFCUlxCommands.curse or {}
|
||||
local cmd = CFCUlxCommands.curse
|
||||
local multiCurseLimit = 100
|
||||
|
||||
CATEGORY_NAME = "Fun"
|
||||
|
||||
@ -9,6 +10,36 @@ do -- Load curse effects
|
||||
end
|
||||
|
||||
|
||||
local function getDurationStrings( durationSeconds, effectOverride )
|
||||
local hasCustomDuration = durationSeconds > 0 and ( not effectOverride or not effectOverride.blockCustomDuration )
|
||||
local durationAppend = ""
|
||||
local briefly = " briefly"
|
||||
|
||||
if hasCustomDuration then
|
||||
local durationStr = durationSeconds >= 60 and
|
||||
ULib.secondsToStringTime( durationSeconds ) or
|
||||
math.Round( durationSeconds ) .. " seconds"
|
||||
|
||||
durationAppend = " for " .. durationStr
|
||||
briefly = ""
|
||||
end
|
||||
|
||||
return durationAppend, briefly
|
||||
end
|
||||
|
||||
local function getOneTimeEffects()
|
||||
local out = {}
|
||||
|
||||
for _, effect in ipairs( CFCUlxCurse.Effects ) do
|
||||
if not effect.excludeFromOnetime then
|
||||
table.insert( out, effect )
|
||||
end
|
||||
end
|
||||
|
||||
return out
|
||||
end
|
||||
|
||||
|
||||
-- Returns true if the curse effect could not be applied/removed.
|
||||
function cmd.curse( ply, effectOverride, durationSeconds, shouldUncurse )
|
||||
if shouldUncurse then
|
||||
@ -36,11 +67,28 @@ function cmd.cursePlayers( callingPlayer, targetPlayers, effectName, durationMin
|
||||
local effectOverride
|
||||
isSilent = isSilent or false
|
||||
|
||||
local isSpecificEffect =
|
||||
local isSpecificEffect = -- Gave a non-random effect name AND is either cursing or not doing 'uncurse all'
|
||||
type( effectName ) == "string" and
|
||||
effectName ~= "random" and
|
||||
( not shouldUncurse or effectName ~= "all" )
|
||||
|
||||
local amount = -- Cursing and gave a specific number of effects to apply
|
||||
isSpecificEffect and
|
||||
not shouldUncurse and
|
||||
tonumber( effectName ) or nil
|
||||
|
||||
if amount == 1 then
|
||||
amount = false
|
||||
isSpecificEffect = false
|
||||
effectName = "random"
|
||||
end
|
||||
|
||||
if amount then
|
||||
amount = math.floor( amount )
|
||||
amount = math.Clamp( amount, 1, multiCurseLimit )
|
||||
isSpecificEffect = false
|
||||
end
|
||||
|
||||
if isSpecificEffect then
|
||||
effectOverride = CFCUlxCurse.GetEffectByName( effectName )
|
||||
|
||||
@ -52,13 +100,54 @@ function cmd.cursePlayers( callingPlayer, targetPlayers, effectName, durationMin
|
||||
end
|
||||
|
||||
local durationSeconds = durationMinutes and durationMinutes * 60 or 0
|
||||
local smallestAmount = amount
|
||||
local largestAmount = 0
|
||||
|
||||
for i = #targetPlayers, 1, -1 do
|
||||
local ply = targetPlayers[i]
|
||||
local applyFailed = cmd.curse( ply, effectOverride, durationSeconds, shouldUncurse )
|
||||
if amount then
|
||||
-- Curse each person with multiple random effects. Doesn't allow uncursing.
|
||||
for i = #targetPlayers, 1, -1 do
|
||||
local plyAmount = amount
|
||||
local ply = targetPlayers[i]
|
||||
local availableEffects = CFCUlxCurse.FilterCompatibleEffects( ply, getOneTimeEffects() )
|
||||
|
||||
if applyFailed then
|
||||
table.remove( targetPlayers, i )
|
||||
-- Only allow a given effect to be applied at most one time during the following loop.
|
||||
-- This rule doesn't count for effects the player already has, allowing them to be refreshed one time. (new duration, new seed, etc.)
|
||||
|
||||
for _ = 1, amount do
|
||||
local effectsLeft = #availableEffects
|
||||
|
||||
if effectsLeft == 0 then
|
||||
plyAmount = plyAmount - 1
|
||||
else
|
||||
local effectInd = math.random( 1, effectsLeft )
|
||||
local effect = availableEffects[effectInd]
|
||||
local applyFailed = cmd.curse( ply, effect, durationSeconds, shouldUncurse )
|
||||
|
||||
if applyFailed then
|
||||
plyAmount = plyAmount - 1
|
||||
else
|
||||
table.remove( availableEffects, effectInd )
|
||||
availableEffects = CFCUlxCurse.FilterCompatibleEffects( ply, availableEffects ) -- Filter out effects that might be incompatible with the new one.
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if plyAmount == 0 then
|
||||
table.remove( targetPlayers, i )
|
||||
else
|
||||
smallestAmount = math.min( smallestAmount, plyAmount )
|
||||
largestAmount = math.max( largestAmount, plyAmount )
|
||||
end
|
||||
end
|
||||
else
|
||||
-- (un)curse each person with a single effect.
|
||||
for i = #targetPlayers, 1, -1 do
|
||||
local ply = targetPlayers[i]
|
||||
local applyFailed = cmd.curse( ply, effectOverride, durationSeconds, shouldUncurse )
|
||||
|
||||
if applyFailed then
|
||||
table.remove( targetPlayers, i )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -72,6 +161,26 @@ function cmd.cursePlayers( callingPlayer, targetPlayers, effectName, durationMin
|
||||
return
|
||||
end
|
||||
|
||||
if smallestAmount == largestAmount and smallestAmount == 1 then
|
||||
amount = false
|
||||
end
|
||||
|
||||
if amount then
|
||||
local amountStr
|
||||
|
||||
if smallestAmount == largestAmount then
|
||||
amountStr = tostring( smallestAmount )
|
||||
else
|
||||
amountStr = smallestAmount .. " to " .. largestAmount
|
||||
end
|
||||
|
||||
local durationAppend, briefly = getDurationStrings( durationSeconds, false )
|
||||
|
||||
ulx.fancyLogAdmin( callingPlayer, isSilent, "#A" .. briefly .. " afflicted #T with " .. amountStr .. " random curses" .. durationAppend, targetPlayers )
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
local onetimeCursedPlayers = {}
|
||||
local longCursedPlayers = {}
|
||||
|
||||
@ -100,25 +209,14 @@ function cmd.cursePlayers( callingPlayer, targetPlayers, effectName, durationMin
|
||||
end
|
||||
end
|
||||
else
|
||||
local hasCustomDuration = durationSeconds > 0 and ( not effectOverride or not effectOverride.blockCustomDuration )
|
||||
local durationAppend = ""
|
||||
local briefly = " briefly"
|
||||
|
||||
if hasCustomDuration then
|
||||
local durationStr = durationSeconds >= 60 and
|
||||
ULib.secondsToStringTime( durationSeconds ) or
|
||||
math.Round( durationSeconds ) .. " seconds"
|
||||
|
||||
durationAppend = " for " .. durationStr
|
||||
briefly = ""
|
||||
end
|
||||
local durationAppend, briefly = getDurationStrings( durationSeconds, effectOverride )
|
||||
|
||||
if effectOverride then -- Manually selected effect
|
||||
local effectPrettyName = effectOverride.nameUpper
|
||||
|
||||
ulx.fancyLogAdmin( callingPlayer, isSilent, "#A" .. briefly .. " cursed #T with " .. effectPrettyName .. durationAppend, targetPlayers )
|
||||
else -- Random effect
|
||||
ulx.fancyLogAdmin( callingPlayer, isSilent, "#A" .. briefly .. " cursed #T with a random effect" .. durationAppend, targetPlayers )
|
||||
ulx.fancyLogAdmin( callingPlayer, isSilent, "#A" .. briefly .. " afflicted #T with a random curse" .. durationAppend, targetPlayers )
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -129,9 +227,17 @@ local function silentCursePlayers( callingPlayer, targetPlayers, effectName, dur
|
||||
end
|
||||
|
||||
|
||||
local curseOptions = table.Copy( CFCUlxCurse.GetEffectNames() )
|
||||
table.insert( curseOptions, "random" )
|
||||
|
||||
for i = 1, 10 do
|
||||
table.insert( curseOptions, tostring( i ) )
|
||||
end
|
||||
|
||||
|
||||
local curseCommand = ulx.command( CATEGORY_NAME, "ulx curse", cmd.cursePlayers, "!curse" )
|
||||
curseCommand:addParam{ type = ULib.cmds.PlayersArg }
|
||||
curseCommand:addParam{ type = ULib.cmds.StringArg, default = "random", ULib.cmds.optional, completes = CFCUlxCurse.GetEffectNames() }
|
||||
curseCommand:addParam{ type = ULib.cmds.StringArg, default = "random", ULib.cmds.optional, completes = curseOptions }
|
||||
curseCommand:addParam{ type = ULib.cmds.NumArg, min = 0, max = 24 * 60, default = 0, ULib.cmds.optional, ULib.cmds.allowTimeString, hint = "duration" }
|
||||
curseCommand:addParam{ type = ULib.cmds.BoolArg, invisible = true }
|
||||
curseCommand:defaultAccess( ULib.ACCESS_ADMIN )
|
||||
@ -140,7 +246,7 @@ curseCommand:setOpposite( "ulx uncurse", { _, _, _, _, true }, "!uncurse" )
|
||||
|
||||
local silentCurseCommand = ulx.command( CATEGORY_NAME, "ulx scurse", silentCursePlayers, "!scurse" )
|
||||
silentCurseCommand:addParam{ type = ULib.cmds.PlayersArg }
|
||||
silentCurseCommand:addParam{ type = ULib.cmds.StringArg, default = "random", ULib.cmds.optional, completes = CFCUlxCurse.GetEffectNames() }
|
||||
silentCurseCommand:addParam{ type = ULib.cmds.StringArg, default = "random", ULib.cmds.optional, completes = curseOptions }
|
||||
silentCurseCommand:addParam{ type = ULib.cmds.NumArg, min = 0, max = 24 * 60, default = 0, ULib.cmds.optional, ULib.cmds.allowTimeString, hint = "duration" }
|
||||
silentCurseCommand:addParam{ type = ULib.cmds.BoolArg, invisible = true }
|
||||
silentCurseCommand:defaultAccess( ULib.ACCESS_ADMIN )
|
||||
|
Loading…
Reference in New Issue
Block a user