diff --git a/Lua/commands.lua b/Lua/commands.lua index 6100adae..0901bd34 100644 --- a/Lua/commands.lua +++ b/Lua/commands.lua @@ -198,7 +198,7 @@ Traitormod.AddCommand({"!allpoint", "!allpoints"}, function (client, args) local messageToSend = "" for index, value in pairs(Client.ClientList) do - messageToSend = messageToSend .. "\n" .. value.Name .. ": " .. math.floor(Traitormod.GetData(value, "Points") or 0) .. " Points - " .. math.floor(Traitormod.GetData(value, "Weight") or 0) .. " Weight" + messageToSend = messageToSend .. "\n" .. value.Name .. ": " .. Traitormod.GetPointsRounded(value) .. " Points - " .. math.floor(Traitormod.GetData(value, "Weight") or 0) .. " Weight" end Traitormod.SendMessage(client, messageToSend) @@ -613,7 +613,7 @@ Traitormod.AddCommand({"!droppoints", "!droppoint", "!dropoint", "!dropoints"}, return true end - local availablePoints = Traitormod.GetData(client, "Points") or 0 + local availablePoints = Traitormod.GetPoints(client) if amount > availablePoints then Traitormod.SendMessage(client, "You don't have enough points to drop.") diff --git a/Lua/config/baseconfig.lua b/Lua/config/baseconfig.lua index 550e7c32..50b4df8f 100644 --- a/Lua/config/baseconfig.lua +++ b/Lua/config/baseconfig.lua @@ -121,6 +121,23 @@ config.GamemodeConfig = { ClearAlienRuins = 2000, Default = 1000, }, + + RoleLock = { + LockIf = function(client, params) + local time = params[1] + local points = params[2] + if Traitormod.GetPlaytime(client) <= time and Traitormod.GetPoints(client) <= points then return true end + return false + end + , + -- If the client doesnt meet the requirements, it wont be selected as that role + LockedRoles = { + ["securityofficer"] = {4*60*60, 100000000000000000}, + ["captain"] = {6*60*60, 20000} + }, + SubstituteRoles = {"assistant"}, -- A random one will be selected + }, + PointsGainedFromCrewMissionsCompleted = 1000, LivesGainedFromCrewMissionsCompleted = 1, diff --git a/Lua/gamemodes/gamemode.lua b/Lua/gamemodes/gamemode.lua index 2b82799e..044c5652 100644 --- a/Lua/gamemodes/gamemode.lua +++ b/Lua/gamemodes/gamemode.lua @@ -4,6 +4,28 @@ gm.Name = "Gamemode" function gm:PreStart() Traitormod.Pointshop.Initialize(self.PointshopCategories or {}) + + Hook.Patch("Barotrauma.Networking.GameServer", "AssignJobs", function (instance, ptable) + local gamemode = Traitormod.SelectedGamemode + if gamemode.RoleLock == nil then return end + + for index, client in pairs(ptable["unassigned"]) do + local flag = false + local jobName = client.AssignedJob.Prefab.Identifier.ToString() + for role, params in pairs(gamemode.RoleLock.LockedRoles) do + if jobName == role then + if gamemode.RoleLock.LockIf(client, params) then + flag = true + end + break + end + end + if flag then + Traitormod.SendMessage(client, string.format(Traitormod.Language.RoleLocked, jobName)) + client.AssignedJob = Traitormod.GetJobVariant(gamemode.RoleLock.SubstituteRoles[math.random(1, #gamemode.RoleLock.SubstituteRoles)]) + end + end + end, Hook.HookMethodType.After) end function gm:Start() diff --git a/Lua/language/english.lua b/Lua/language/english.lua index af5fa58e..79f88204 100644 --- a/Lua/language/english.lua +++ b/Lua/language/english.lua @@ -120,6 +120,8 @@ language.Death = "You lost a life. You have %s left before you lose points." language.NoLives = "You lost all your lives. As a result you lose some points." language.MaxLives = "You have the maximum amount of lives." +language.RoleLocked = "You didn't meet the requirements to be selected as a %s." + language.Codewords = "Code Words: %s" language.CodeResponses = "Code Responses: %s" diff --git a/Lua/midroundspawn.lua b/Lua/midroundspawn.lua index 0e5a77c3..cc4f9779 100644 --- a/Lua/midroundspawn.lua +++ b/Lua/midroundspawn.lua @@ -37,11 +37,6 @@ m.CrewHasJob = function(job) return false end -m.GetJobVariant = function(jobId) - local prefab = JobPrefab.Get(jobId) - return JobVariant.__new(prefab, 0) -end - -- TryCreateClientCharacter inspied by Oiltanker m.TryCreateClientCharacter = function(submarine, client) local session = Game.GameSession @@ -54,14 +49,14 @@ m.TryCreateClientCharacter = function(submarine, client) if jobPreference == nil then -- if no jobPreference, set assistant - jobPreference = m.GetJobVariant("assistant") + jobPreference = Traitormod.GetJobVariant("assistant") elseif preventMultiCaptain and jobPreference.Prefab.Identifier == "captain" then -- if crew has a captain, spawn as security if m.CrewHasJob("captain") then Traitormod.Log(client.Name .. " tried to mid-round spawn as second captain - assigning security instead.") -- set jobPreference = security - jobPreference = m.GetJobVariant("securityofficer") + jobPreference = Traitormod.GetJobVariant("securityofficer") end end diff --git a/Lua/playtime.lua b/Lua/playtime.lua index 8ba841fc..4aace006 100644 --- a/Lua/playtime.lua +++ b/Lua/playtime.lua @@ -7,8 +7,9 @@ end) Traitormod.AddCommand({"!playtime", "!pt"}, function (client, args) Traitormod.SendChatMessage( client, - string.format(Traitormod.Language.CMDPlaytime, Traitormod.FormatTime(math.ceil(Traitormod.GetData(client, "Playtime") or 0))), + string.format(Traitormod.Language.CMDPlaytime, Traitormod.FormatTime(Traitormod.GetPlaytime(client))), Color.Green ) return true -end) \ No newline at end of file +end) + diff --git a/Lua/pointshop.lua b/Lua/pointshop.lua index 1ea46492..9d3846e1 100644 --- a/Lua/pointshop.lua +++ b/Lua/pointshop.lua @@ -278,7 +278,7 @@ end ps.BuyProduct = function(client, product) local price = 0 if not Traitormod.Config.TestMode then - local points = Traitormod.GetData(client, "Points") or 0 + local points = Traitormod.GetPoints(client) price = ps.GetProductPrice(client, product) if product.CanBuy then @@ -323,12 +323,12 @@ ps.HandleProductBuy = function (client, product, result, quantity) elseif result == ps.ProductBuyFailureReason.NoStock then textPromptUtils.Prompt(Traitormod.Language.PointshopNoStock, {}, client, function (id, client) end, "gambler") elseif result == nil then - textPromptUtils.Prompt(string.format(Traitormod.Language.PointshopPurchased, ps.GetProductName(product), ps.GetProductPrice(client, product), math.floor(Traitormod.GetData(client, "Points") or 0)), {}, client, function (id, client) end, "gambler") + textPromptUtils.Prompt(string.format(Traitormod.Language.PointshopPurchased, ps.GetProductName(product), ps.GetProductPrice(client, product), Traitormod.GetPointsRounded(client)), {}, client, function (id, client) end, "gambler") if true then return end -- Don't let the player rebuy products that need installation or have timelimit if ps.GetProductHasInstallation(product) or product.Timeout ~= nil or ps.GetProductLimit(client, product) < 2 then - textPromptUtils.Prompt(string.format(Traitormod.Language.PointshopPurchased, ps.GetProductName(product), ps.GetProductPrice(client, product), math.floor(Traitormod.GetData(client, "Points") or 0)), {}, client, function (id, client) end, "gambler") + textPromptUtils.Prompt(string.format(Traitormod.Language.PointshopPurchased, ps.GetProductName(product), ps.GetProductPrice(client, product), Traitormod.GetPointsRounded(client)), {}, client, function (id, client) end, "gambler") return end -- Buy again menu @@ -338,7 +338,7 @@ ps.HandleProductBuy = function (client, product, result, quantity) table.insert(options, " - " .. tostring(i)) end -- Handle rebuying multiple times - textPromptUtils.Prompt(string.format("Purchased %sx \"%s\" for %s points\n\nNew point balance is: %s points.\nIf you want to buy again enter the amount:", quantity, ps.GetProductName(product), ps.GetProductPrice(client, product) * quantity, math.floor(Traitormod.GetData(client, "Points") or 0)), options, client, function (id, client) + textPromptUtils.Prompt(string.format("Purchased %sx \"%s\" for %s points\n\nNew point balance is: %s points.\nIf you want to buy again enter the amount:", quantity, ps.GetProductName(product), ps.GetProductPrice(client, product) * quantity, Traitormod.GetPointsRounded(client)), options, client, function (id, client) -- id-1 is the quantity that player chose if id > 1 then local successCount = 0 -- If you select more than product has in stock it will handle it @@ -386,7 +386,7 @@ ps.ShowCategoryItems = function(client, category) table.insert(options, "") -- FIXME: some hud scaling settings will hide list items end - local points = Traitormod.GetData(client, "Points") or 0 + local points = Traitormod.GetPoints(client) textPromptUtils.Prompt( string.format(Traitormod.Language.PointshopWishBuy, math.floor(points)), @@ -443,7 +443,7 @@ ps.ShowCategory = function(client) table.insert(options, "") table.insert(options, "") -- FIXME: for some reason when the bar is full, the last item is never shown? - local points = Traitormod.GetData(client, "Points") or 0 + local points = Traitormod.GetPoints(client) -- note: we have two different client variables here to prevent cheating textPromptUtils.Prompt(string.format(Traitormod.Language.PointshopWishCategory, math.floor(points)), options, client, function (id, client2) diff --git a/Lua/traitormod.lua b/Lua/traitormod.lua index 7c3e31e7..d8416964 100644 --- a/Lua/traitormod.lua +++ b/Lua/traitormod.lua @@ -147,7 +147,7 @@ Hook.Add("missionsEnded", "Traitormod.MissionsEnded", function(missions) for key, value in pairs(Client.ClientList) do -- add weight according to points and config conversion - Traitormod.AddData(value, "Weight", Traitormod.Config.AmountWeightWithPoints(Traitormod.GetData(value, "Points") or 0)) + Traitormod.AddData(value, "Weight", Traitormod.Config.AmountWeightWithPoints(Traitormod.GetPoints(value))) end Traitormod.Debug("Round " .. Traitormod.RoundNumber .. " ended.") @@ -429,6 +429,7 @@ Traitormod.AddGamemode(dofile(Traitormod.Path .. "/Lua/gamemodes/secret.lua")) Traitormod.AddGamemode(dofile(Traitormod.Path .. "/Lua/gamemodes/pvp.lua")) Traitormod.AddGamemode(dofile(Traitormod.Path .. "/Lua/gamemodes/submarineroyale.lua")) Traitormod.AddGamemode(dofile(Traitormod.Path .. "/Lua/gamemodes/attackdefend.lua")) +dofile(Traitormod.Path .. "/Lua/playtime.lua") Traitormod.RoleManager.AddObjective(dofile(Traitormod.Path .. "/Lua/objectives/objective.lua")) Traitormod.RoleManager.AddObjective(dofile(Traitormod.Path .. "/Lua/objectives/assassinate.lua")) diff --git a/Lua/traitormodutil.lua b/Lua/traitormodutil.lua index fbecf6eb..48a72276 100644 --- a/Lua/traitormodutil.lua +++ b/Lua/traitormodutil.lua @@ -47,7 +47,7 @@ Traitormod.LoadRemoteData = function (client, loaded) end if result.Points then - local originalPoints = Traitormod.GetData(client, "Points") or 0 + local originalPoints = Traitormod.GetPoints(client) Traitormod.Log("Retrieved points from server for " .. client.SteamID .. ": " .. originalPoints .. " -> " .. result.Points) Traitormod.SetData(client, "Points", result.Points) end @@ -120,6 +120,18 @@ Traitormod.AddData = function(client, name, amount) Traitormod.SetData(client, name, math.max((Traitormod.GetData(client, name) or 0) + amount, 0)) end +Traitormod.GetPoints = function(client) + return Traitormod.GetData(client, "Points") or 0 +end + +Traitormod.GetPointsRounded = function(client) + return math.floor(Traitormod.GetPoints(client)) +end + +Traitormod.GetPlaytime = function(client) + return math.ceil(Traitormod.GetData(client, "Playtime") or 0) -- In seconds +end + Traitormod.FindClient = function (name) for key, value in pairs(Client.ClientList) do if value.Name == name or tostring(value.SteamID) == name then @@ -335,7 +347,7 @@ Traitormod.LoadExperience = function (client) Traitormod.Error("Loading experience failed! Client.Character or .Info was null! " .. Traitormod.ClientLogName(client)) return end - local amount = Traitormod.Config.AmountExperienceWithPoints(Traitormod.GetData(client, "Points") or 0) + local amount = Traitormod.Config.AmountExperienceWithPoints(Traitormod.GetPoints(client)) local max = Traitormod.Config.MaxExperienceFromPoints or 2000000000 -- must be int32 if amount > max then @@ -404,7 +416,7 @@ Traitormod.AdjustLives = function (client, amount) -- if no lives left, reduce amount of points, reset to maxLives Traitormod.Log("Player ".. client.Name .." lost all lives. Reducing points...") if not Traitormod.Config.TestMode then - local oldAmount = Traitormod.GetData(client, "Points") or 0 + local oldAmount = Traitormod.GetPoints(client) local newAmount = Traitormod.Config.PointsLostAfterNoLives(oldAmount) Traitormod.SetData(client, "Points", newAmount) Traitormod.Stats.AddClientStat("PointsLost", client, oldAmount - newAmount) @@ -447,7 +459,7 @@ Traitormod.GetDataInfo = function(client, showWeights) weightInfo = "\n\n" .. string.format(Traitormod.Language.TraitorInfo, math.floor(percentage)) end - return string.format(Traitormod.Language.PointsInfo, math.floor(Traitormod.GetData(client, "Points") or 0), Traitormod.GetData(client, "Lives") or Traitormod.Config.MaxLives, Traitormod.Config.MaxLives) .. weightInfo + return string.format(Traitormod.Language.PointsInfo, Traitormod.GetPointsRounded(client), Traitormod.GetData(client, "Lives") or Traitormod.Config.MaxLives, Traitormod.Config.MaxLives) .. weightInfo end Traitormod.ClientLogName = function(client, name) @@ -527,4 +539,9 @@ end Traitormod.FormatTime = function(seconds) return TimeSpan.FromSeconds(seconds).ToString() +end + +Traitormod.GetJobVariant = function(jobId) + local prefab = JobPrefab.Get(jobId) + return JobVariant.__new(prefab, 0) end \ No newline at end of file