This commit is contained in:
Evil Factory
2021-04-14 01:00:56 -03:00
parent d557b4491d
commit bb0ea74961
8 changed files with 851 additions and 58 deletions

View File

@@ -0,0 +1,493 @@
local traitormod = {}
traitormod.peoplePercentages = {}
traitormod.roundtraitors = {}
traitormod.selectedCodeResponses = {}
traitormod.selectedCodePhrases = {}
traitormod.enabled = true
traitormod.traitorShipEnabled = true
traitormod.roundGamemode = ""
local traitorAssignDelay = 0
local traitorsAssigned = true
local warningClients = {}
Game.OverrideTraitors(true) -- shutup old traitors
local config = dofile("lua/traitormod/traitorconfig.lua")
local util = dofile("lua/traitormod/util.lua")
traitormod.config = config
traitormod.setPercentage = function(client, amount)
if client == nil then return end
if traitormod.peoplePercentages[client.SteamID] == nil then
traitormod.peoplePercentages[client.SteamID] = {}
traitormod.peoplePercentages[client.SteamID].penalty = 1
traitormod.peoplePercentages[client.SteamID].p = config.firstJoinPercentage
end
traitormod.peoplePercentages[client.SteamID].p = amount
end
traitormod.addPenalty = function (client, amount)
if client == nil then return end
if traitormod.peoplePercentages[client.SteamID] == nil then
traitormod.peoplePercentages[client.SteamID] = {}
traitormod.peoplePercentages[client.SteamID].penalty = 1
traitormod.peoplePercentages[client.SteamID].p = config.firstJoinPercentage
end
traitormod.peoplePercentages[client.SteamID].penalty = traitormod.peoplePercentages[client.SteamID].penalty + amount
end
traitormod.getPenalty = function (client)
if client == nil then return end
if traitormod.peoplePercentages[client.SteamID] == nil then
traitormod.peoplePercentages[client.SteamID] = {}
traitormod.peoplePercentages[client.SteamID].penalty = 1
traitormod.peoplePercentages[client.SteamID].p = config.firstJoinPercentage
end
return traitormod.peoplePercentages[client.SteamID].penalty
end
traitormod.addPercentage = function(client, amount)
if client == nil then return end
if traitormod.peoplePercentages[client.SteamID] == nil then
traitormod.peoplePercentages[client.SteamID] = {}
traitormod.peoplePercentages[client.SteamID].penalty = 1
traitormod.peoplePercentages[client.SteamID].p = config.firstJoinPercentage
end
traitormod.peoplePercentages[client.SteamID].p = traitormod.peoplePercentages[client.SteamID].p + amount
end
traitormod.getPercentage = function (client)
if client == nil then return end
if traitormod.peoplePercentages[client.SteamID] == nil then
traitormod.peoplePercentages[client.SteamID] = {}
traitormod.peoplePercentages[client.SteamID].penalty = 1
traitormod.peoplePercentages[client.SteamID].p = config.firstJoinPercentage
end
return traitormod.peoplePercentages[client.SteamID].p
end
traitormod.chooseCodes = function()
local codewords = dofile("lua/traitormod/traitorconfig.lua").codewords -- copy
local amount = config.amountCodewords
for i = 1, amount, 1 do
local rand = Random.Range(1, #codewords + 1)
table.insert(traitormod.selectedCodeResponses, codewords[rand])
table.remove(codewords, rand)
end
for i = 1, amount, 1 do
local rand = Random.Range(1, #codewords + 1)
table.insert(traitormod.selectedCodePhrases, codewords[rand])
table.remove(codewords, rand)
end
end
traitormod.selectPlayerPercentages = function(ignore)
local players = util.GetValidPlayersNoBotsAndNoTraitors(
traitormod.roundtraitors)
for i = 1, #players, 1 do
for key, value in pairs(ignore) do
if players[i] == value then
table.remove(players, i)
end
end
end
local total = 0
for key, value in pairs(players) do
local client = util.clientChar(value)
total = total + traitormod.getPercentage(client)
end
local rng = Random.Range(0, total)
local addup = 0
for key, value in pairs(players) do
local client = util.clientChar(value)
local percentage = traitormod.getPercentage(client)
if rng >= addup and rng <= addup + percentage then return value end
addup = addup + percentage
end
return nil
end
traitormod.chooseTraitors = function(amount)
local traitors = {}
for i = 1, amount, 1 do
local found = traitormod.selectPlayerPercentages(traitors)
if found == nil then
print("Not enough players")
break
else
table.insert(traitors, found)
end
end
return traitors
end
traitormod.sendTraitorMessage = function(msg, client, notchatbox)
if client == nil then return end
if notchatbox == true then
Game.SendDirectChatMessage("", msg, nil, 11, client)
else
Game.SendDirectChatMessage("", msg, nil, 7, client)
end
Game.SendDirectChatMessage("", msg, nil, 1, client)
end
traitormod.assignNormalTraitors = function(amount)
local traitors = traitormod.chooseTraitors(amount)
for key, value in pairs(traitors) do traitormod.roundtraitors[value] = {} end
local targets = util.GetValidPlayersNoTraitors(traitormod.roundtraitors)
for key, value in pairs(traitors) do
traitormod.roundtraitors[value].objectiveType = "kill"
traitormod.roundtraitors[value].objectiveTarget =
targets[Random.Range(1, #targets + 1)]
local mess =
"You are a traitor! Your secret mission is to assassinate " ..
traitormod.roundtraitors[value].objectiveTarget.name ..
"! Avoid being loud, make the death look like an accident. We will provide you more information after you finish your current mission."
if util.TableCount(traitormod.roundtraitors) > 1 then
mess = mess ..
"\n\nIt is possible that there are other agents on this submarine. You dont know their names, but you do have a method of communication. Use the code words to greet the agent and code response to respond. Disguise such words in a normal-looking phrase so the crew doesn't suspect anything."
mess = mess .. "\n\n The code words are: "
for key, va in pairs(traitormod.selectedCodePhrases) do
mess = mess .. "\"" .. va .. "\" "
end
mess = mess .. "\n The code response is: "
for key, va in pairs(traitormod.selectedCodeResponses) do
mess = mess .. "\"" .. va .. "\" "
end
end
Game.Log(value.name ..
" Was assigned to be traitor, his first mission is to kill " ..
traitormod.roundtraitors[value].objectiveTarget.name, 6)
traitormod.sendTraitorMessage(mess, util.clientChar(value))
end
end
traitormod.chooseNextObjective = function(key, value)
local players = util.GetValidPlayersNoTraitors(traitormod.roundtraitors)
if #players == 0 then
traitormod.sendTraitorMessage("Good job agent, You did it.",
util.clientChar(key), true)
value.needNewObjective = false
return
end
local assassinate = players[Random.Range(1, #players + 1)]
traitormod.sendTraitorMessage("Your next mission is to assassinate " ..
assassinate.name, util.clientChar(key),
true)
Game.Log(key.name ..
" Was assigned another traitor mission, His mission is to kill " ..
assassinate.name, 6)
value.objectiveTarget = assassinate
value.objectiveType = "kill"
value.needNewObjective = false
end
Hook.Add("roundStart", "traitor_start", function()
if not traitormod.enabled then return end
local players = util.GetValidPlayersNoBots()
for key, value in pairs(players) do
local client = util.clientChar(value)
if traitormod.getPenalty(client) > 1 then
traitormod.addPenalty(client, -1)
end
traitormod.addPercentage(client, config.roundEndPercentageIncrease / traitormod.getPenalty(client))
end
traitormod.chooseCodes()
local rng = Random.Range(0, 100)
if rng < config.traitorShipChance and traitormod.traitorShipEnabled == true then
local amount = config.getAmountShipTraitors(#util.GetValidPlayers())
Game.Log("Infiltraiton Gamemode selected, Random = " .. rng, 6)
traitormod.roundGamemode = "Infiltraiton"
traitormod.traitorShipRoundStart(amount)
else
traitorsAssigned = false
traitorAssignDelay = Timer.GetTime() + config.traitorSpawnDelay
Game.Log("Assasination Gamemode was selected, Random = " .. rng, 6)
traitormod.roundGamemode = "Assasination"
traitormod.spawnTraitorShipAndHide()
end
for key, value in pairs(Player.GetAllClients()) do
Game.SendTraitorMessage(value, 'traitor', 'traitor', TraitorMessageType.Objective) -- enable everyone to sabotage
end
Game.SendMessage(
"We are using Custom Traitors Plugin by EvilFactory (https://steamcommunity.com/id/evilfactory/)\n Join discord.gg/f9zvNNuxu9",
3)
end)
Hook.Add("roundEnd", "traitor_end", function()
if not traitormod.enabled then return end
local msg = "Traitors of the round: "
for key, value in pairs(traitormod.roundtraitors) do
msg = msg .. "\"" .. key.name .. "\" "
end
msg = msg .. "\n\nGamemode: " .. traitormod.roundGamemode
Game.SendMessage(msg, 1)
for key, value in pairs(traitormod.roundtraitors) do
local c = util.clientChar(key)
traitormod.setPercentage(c, config.traitorPercentageSet)
traitormod.addPenalty(c, config.traitorPenalty)
end
traitormod.roundtraitors = {}
traitormod.selectedCodeResponses = {}
traitormod.selectedCodePhrases = {}
warningClients = {}
end)
Hook.Add("think", "traitor_think", function()
if not traitormod.enabled then return end
if not traitorsAssigned and traitorAssignDelay < Timer.GetTime() then
local amount = config.getAmountTraitors(#util.GetValidPlayers())
traitormod.assignNormalTraitors(amount)
traitorsAssigned = true
end
for key, value in pairs(Player.GetAllCharacters()) do
if warningClients[value] == nil then
if value.IsDead == true then
local attackers = value.LastAttacker
-- and attackers ~= value
if util.characterIsTraitor(attackers, traitormod.roundtraitors) and
attackers ~= value then
traitormod.sendTraitorMessage(
"Your death was caused by a traitor on a secret mission.",
util.clientChar(value), true)
end
warningClients[value] = true
end
end
end
for key, value in pairs(traitormod.roundtraitors) do
if key ~= nil and key.IsDead == false then
if value.needNewObjective == true and Timer.GetTime() >
value.objectiveTimer then
traitormod.chooseNextObjective(key, value)
end
if value.objectiveTarget ~= nil then
if value.objectiveTarget.IsDead then
traitormod.sendTraitorMessage(
"Great job, You killed " .. value.objectiveTarget.name ..
". We will provide you your next mission shortly.",
util.clientChar(key), true)
value.objectiveTarget = nil
value.needNewObjective = true
value.objectiveTimer =
Timer.GetTime() + config.nextMissionDelay
end
end
end
end
end)
Hook.Add("chatMessage", "chatcommands", function(msg, client)
if bit32.band(client.Permissions, 0x40) == 0x40 then
if msg == "!toggletraitormod" then
traitormod.enabled = not traitormod.enabled
if traitormod.enabled then
Game.SendDirectChatMessage("", "TraitorMod Enabled", nil, 1,
client)
else
Game.SendDirectChatMessage("", "TraitorMod Disabled", nil, 1,
client)
end
Game.OverrideTraitors(traitormod.enabled)
return true
end
if msg == "!toggletraitorship" then
traitormod.traitorShipEnabled = not traitormod.traitorShipEnabled
if traitormod.traitorShipEnabled then
Game.SendDirectChatMessage("", "Traitor Ship Enabled", nil, 1,
client)
else
Game.SendDirectChatMessage("", "Traitor Ship Disabled", nil, 1,
client)
end
return true
end
if msg == "!traitors" then
local tosend = "Traitors of the round: "
for key, value in pairs(traitormod.roundtraitors) do
tosend = tosend .. "\"" .. key.name .. "\" "
end
traitormod.sendTraitorMessage(tosend, client)
return true
end
if msg == "!traitoralive" then
local num = 0
for key, value in pairs(traitormod.roundtraitors) do
if key.IsDead == false then
num = num + 1
end
end
if num > 0 then
traitormod.sendTraitorMessage("There are traitors alive.", client)
else
traitormod.sendTraitorMessage("All traitors are dead!", client)
end
return true
end
if msg == "!percentages" then
local msg = ""
for key, value in pairs(Player.GetAllClients()) do
msg = msg .. value.name .. " - " ..
math.floor(traitormod.getPercentage(value)) .. "%\n"
end
traitormod.sendTraitorMessage(msg, client)
return true
end
end
if msg == "!percentage" then
traitormod.sendTraitorMessage("You have " ..
math.floor(traitormod.getPercentage(client)) ..
"% of being traitor", client)
return true
end
if util.stringstarts(msg, "!traitor") then
if util.characterIsTraitor(client.Character, traitormod.roundtraitors) then
local msg = "You are a traitor. "
if traitormod.roundtraitors[client.Character].objectiveTarget ~= nil then
msg = msg .. "\nCurrent Mission: kill " ..
traitormod.roundtraitors[client.Character]
.objectiveTarget.name
end
if util.TableCount(traitormod.roundtraitors) > 1 then
msg = msg .. "\n\n The code words are: "
for key, va in pairs(traitormod.selectedCodePhrases) do
msg = msg .. "\"" .. va .. "\" "
end
msg = msg .. "\n The code response is: "
for key, va in pairs(traitormod.selectedCodeResponses) do
msg = msg .. "\"" .. va .. "\" "
end
end
traitormod.sendTraitorMessage(msg, client)
else
traitormod.sendTraitorMessage("You are not a traitor.", client)
end
return true
end
end)
Traitormod = traitormod

View File

@@ -0,0 +1,129 @@
local traitormod = Traitormod
local respawnshuttle = nil
local loadedpeople = {}
local config = dofile("lua/traitormod/traitorconfig.lua")
local util = dofile("lua/traitormod/util.lua")
Game.OverrideRespawnSub(true)
Hook.Add("think", "traitorShip", function()
if respawnshuttle ~= nil then
local pos1 = Submarine.MainSub.WorldPosition
local pos2 = respawnshuttle.WorldPosition
if Vector2.Distance(pos1, pos2) < config.traitorShipGodModeDistance then
respawnshuttle.GodMode = false
end
for key, value in pairs(traitormod.roundtraitors) do
local client = util.clientChar(key)
if client ~= nil then
if client.InGame == true and loadedpeople[key] == nil then
loadedpeople[key] = {}
loadedpeople[key].next = Timer.GetTime() + 15
elseif loadedpeople[key] ~= nil and Timer.GetTime() <
loadedpeople[key].next then
Player.SetClientCharacter(client, key)
end
end
end
end
end)
Hook.Add("roundEnd", "traitorShipRemove", function()
respawnshuttle = nil
loadedpeople = {}
end)
traitormod.spawnTraitorShipAndHide = function()
Game.SetRespawnSubTeam(2)
Game.DispatchRespawnSub()
local sub = Game.GetRespawnSub()
sub.ShowSonarMarker = false
sub.GodMode = true
local steering = Game.GetSubmarineSteering(sub)
steering.AutoPilot = false
sub.SetPosition({0, Level.Loaded.BottomPos + 1000})
return sub
end
traitormod.spawnTraitorShip = function()
Game.SetRespawnSubTeam(2)
Game.DispatchRespawnSub()
local sub = Game.GetRespawnSub()
respawnshuttle = sub
sub.ShowSonarMarker = false
local positions = Level.Loaded.PositionsOfInterest
local goodpositions = {}
for key, value in ipairs(positions) do
if value.PositionType == PositionType.MainPath then
table.insert(goodpositions, value)
end
end
-- sub.SetPosition({Level.Loaded.EndPosition[1], Level.Loaded.EndPosition[2] - 10000})
sub.SetPosition(goodpositions[math.floor(#goodpositions / 2)].Position
.ToVector2())
sub.GodMode = true
local steering = Game.GetSubmarineSteering(sub)
steering.AutoPilot = false
return sub
end
traitormod.traitorShipRoundStart = function(maxplayers)
local sub = traitormod.spawnTraitorShip()
local assignedNowTraitors = traitormod.chooseTraitors(maxplayers)
for index, value in pairs(assignedNowTraitors) do
traitormod.roundtraitors[value] = {}
local mess =
"You are a traitor! Your mission is to exterminate the Main Sub's Crew, cooperate with your fellow agents."
mess = mess ..
"\n\nUse the codewords to communicate with the other agents."
mess = mess .. "\n\n The code words are: "
for key, va in pairs(traitormod.selectedCodePhrases) do
mess = mess .. "\"" .. va .. "\" "
end
mess = mess .. "\n The code response is: "
for key, va in pairs(traitormod.selectedCodeResponses) do
mess = mess .. "\"" .. va .. "\" "
end
Game.Log(value.name .. " Was assigned to be Ship traitor", 6)
local cl = util.clientChar(value)
traitormod.sendTraitorMessage(mess, cl)
local waypoint = WayPoint.GetRandom(SpawnType.Human, nil, sub)
value.TeleportTo(waypoint.WorldPosition)
-- Player.SetClientCharacter(cl, value)
end
end

View File

@@ -0,0 +1,36 @@
local config = {}
local codewords = {
"pomegrenade", "tabacco", "fish", "nonsense", "europa", "clown",
"thalamus", "hungry", "renegade", "angry", "green", "flamingos", "sink",
"mask", "boomer", "sweet", "ice", "charybdis", "cult", "secret", "moloch",
"husk", "rusted", "ruins", "red", "boat", "cats", "rats", "jeepers", "bench",
"tire", "trunk", "blow sticks", "thrashers"
}
config.codewords = codewords
config.amountCodewords = 2
config.traitorSpawnDelay = 60
config.nextMissionDelay = 60
config.traitorShipChance = 15
config.traitorShipGodModeDistance = 4000
-- Traitor Selection Options
config.roundEndPercentageIncrease = 10
config.firstJoinPercentage = 10
config.traitorPercentageSet = 5
config.traitorPenalty = 5
-- >=12 players = 3 traitors, >=8 players = 2 traitors, default = 1 traitor
config.getAmountTraitors = function (amountClients)
if amountClients >= 12 then return 3 end
if amountClients >= 8 then return 2 end
return 1
end
-- shipTraitors and normal traitors will be selected equally
config.getAmountShipTraitors = config.getAmountTraitors
return config;

View File

@@ -0,0 +1,116 @@
local util = {}
util.clientChar = function(char)
local clients = Player.GetAllClients()
for key, client in pairs(clients) do
if (client.Character == char) then return client end
end
return nil
end
util.GetDeadClients = function()
local valid = {}
for key, value in pairs(Player.GetAllClients()) do
if value.InGame then
if value.Character == nil then table.insert(valid, value) end
if value.Character ~= nil and value.Character.IsDead == true then
table.insert(valid, value)
end
end
end
return valid
end
util.GetValidPlayers = function()
local chars = Player.GetAllCharacters()
local valid = {}
for key, value in pairs(chars) do
if (value.IsHuman == true and value.IsDead == false) and
value.ClientDisconnected == false then
table.insert(valid, value)
end
end
return valid
end
function util.stringstarts(String, Start)
return string.sub(String, 1, string.len(Start)) == Start
end
util.characterIsTraitor = function(char, traitors)
for key, value in pairs(traitors) do
if char == key then return true end
end
return false
end
util.GetValidPlayersNoBotsAndNoTraitors = function(traitors)
local chars = Player.GetAllCharacters()
local valid = {}
for key, value in pairs(chars) do
if (value.IsHuman == true and value.IsDead == false) and
value.ClientDisconnected == false then
if value.IsBot == false and traitors[value] == nil then table.insert(valid, value) end
end
end
return valid
end
util.GetValidPlayersNoBots = function()
local chars = Player.GetAllCharacters()
local valid = {}
for key, value in pairs(chars) do
if (value.IsHuman == true and value.IsDead == false) and
value.ClientDisconnected == false then
if value.IsBot == false then table.insert(valid, value) end
end
end
return valid
end
util.TableCount = function (tbl)
local count = 0
for key, value in pairs(tbl) do
count = count + 1
end
return count
end
util.GetValidPlayersNoTraitors = function(traitors)
local chars = Player.GetAllCharacters()
local valid = {}
for key, value in pairs(chars) do
if (value.IsHuman == true and value.IsDead == false) and
value.ClientDisconnected == false then
if traitors[value] == nil then
table.insert(valid, value)
end
end
end
return valid
end
return util