Skip to content

Instantly share code, notes, and snippets.

@gtnardy
Last active October 4, 2020 20:12
Show Gist options
  • Save gtnardy/4a3b8a143531869d41ece2a9b7ff21e1 to your computer and use it in GitHub Desktop.
Save gtnardy/4a3b8a143531869d41ece2a9b7ff21e1 to your computer and use it in GitHub Desktop.
ROLES = {
INNOCENT = 1,
TRAITOR = 2,
DETECTIVE = 3
}
MATCH_STATES = {
WARM_UP = 1,
WAITING_PLAYERS = 2,
IN_PROGRESS = 3,
POST_TIME = 4,
}
TTT = {
remaining_time = 0,
match_state = MATCH_STATES.WAITING_PLAYERS,
}
TTTSettings = {
warmup_time = 6,
match_time = 6,
post_time = 3,
percent_traitors = 0.25,
percent_detectives = 0.13,
min_players_detectives = 10,
}
Character:on("TakeDamage", function(charact, damage, bone, type, FromDirection, Instigator)
charact:SetValue("LastDamager", Instigator)
end)
function PlayerConnected(player)
if (TTT.match_state == MATCH_STATES.WAITING_PLAYERS or TTT.match_state == MATCH_STATES.WARM_UP) then
SpawnCharacter(player)
if (#NanosWorld:GetPlayers() >= 3 and TTT.match_state == MATCH_STATES.WAITING_PLAYERS) then
print("ready!")
StartWarmUP()
end
-- elseif (TTT.match_state == MATCH_STATES.IN_PROGRESS) then
end
for k, v in pairs(NanosWorld:GetPlayers()) do
local tintColor = nil
local c = Character()
v:Possess(c)
c:Destroy()
if v:GetControlledCharacter() ~= nil then
local col = v:GetControlledCharacter():GetTintColor()
tintColor = ("rgba(%s, %s, %s, %s)"):format(col.R * 255, col.G * 255, col.B * 255, col.A * 255)
end
Package:Log(tintColor)
end
end
Player:on("Spawn", PlayerConnected)
function PlayerDisconnected(player)
local is_player_alive = player:GetValue("IsAlive")
if (is_player_alive) then
local player_character = player:GetValue("Character")
player_character:SetHealth(0)
CharacterDie(player_character)
end
end
Player:on("Destroyed", PlayerDisconnected)
function CharacterDie(character)
local last_damager = charact:GetValue("LastDamager")
charact:GetPlayer():SetValue("IsAlive", false)
VerifyWinners()
end
Character:on("Death", CharacterDie)
function VerifyWinners()
local alive_players_count = 0
local traitors_count = 0
for k, player in pairs(NanosWorld:GetPlayers()) do
if (player:GetValue("IsAlive")) then
alive_players_count = alive_players_count + 1
if (player:GetValue("Role") == ROLES.TRAITOR) then
traitors_count = traitors_count + 1
end
end
end
if (traitors_count == 0) then
InnocentWins()
elseif (alive_players_count == traitors_count) then
TraitorWins()
end
end
function TraitorWins()
print("TRAITOR WINS")
FinishRound()
end
function InnocentWins()
print("INNOCENT WINS")
FinishRound()
end
function FinishRound()
UpdateMatchState(MATCH_STATES.POST_TIME)
print("round finished")
end
function StartRound()
UpdateMatchState(MATCH_STATES.IN_PROGRESS)
print("round starting")
local player_count = #NanosWorld:GetPlayers()
local player_list = {}
for k, player in pairs(NanosWorld:GetPlayers()) do
if (not player:GetValue("IsAlive")) then
SpawnCharacter(player)
end
local pos = math.random(1, #player_list + 1)
table.insert(player_list, pos, player)
end
local traitor_count = math.ceil(player_count * TTTSettings.percent_traitors)
local detective_count = math.ceil(player_count * TTTSettings.percent_detectives)
for k, player in pairs(player_list) do
print(k)
if (k <= traitor_count) then
SetPlayerRole(player, ROLES.TRAITOR)
elseif (player_count >= TTTSettings.min_players_detectives and k <= traitor_count + detective_count) then
SetPlayerRole(player, ROLES.DETECTIVE)
else
SetPlayerRole(player, ROLES.INNOCENT)
end
print(player)
end
end
function StartWarmUP()
UpdateMatchState(MATCH_STATES.WARM_UP)
ClearServer()
for k, player in pairs(NanosWorld:GetPlayers()) do
SpawnCharacter(player)
end
-- TODO spawns everything
end
function ClearServer()
for k, character in pairs(NanosWorld:GetCharacters()) do
character:Destroy()
end
for k, prop in pairs(NanosWorld:GetProps()) do
prop:Destroy()
end
for k, weapon in pairs(NanosWorld:GetWeapons()) do
weapon:Destroy()
end
end
function SpawnCharacter(player)
local player_character = player:GetValue("Character")
if (player_character and player_character:IsValid()) then
player_character:Destroy()
end
local character = Character(Vector(0, 0, 100))
player:Possess(character)
player:SetValue("Character", character)
player:SetValue("IsAlive", true)
end
function SetPlayerRole(player, role)
player:SetValue("Role", role)
if (role == ROLES.TRAITOR) then
Server:SendChatMessage(player, "you are TRAITOR!")
print("TRAITOR")
elseif (role == ROLES.DETECTIVE) then
Server:SendChatMessage(player, "you are DETECTIVE!")
print("DETECTIVE")
elseif (role == ROLES.INNOCENT) then
Server:SendChatMessage(player, "you are INNOCENT!")
print("INNOCENT")
end
Events:BroadcastRemote("SetPlayerRole", player, role)
end
function UpdateMatchState(new_state)
TTT.match_state = new_state
if (new_state == MATCH_STATES.WARM_UP) then
TTT.remaining_time = TTTSettings.warmup_time
elseif (new_state == MATCH_STATES.IN_PROGRESS) then
TTT.remaining_time = TTTSettings.match_time
elseif (new_state == MATCH_STATES.WAITING_PLAYERS) then
elseif (new_state == MATCH_STATES.POST_TIME) then
TTT.remaining_time = TTTSettings.post_time
end
Events:BroadcastRemote("UpdateMatchState", {new_state})
end
Timer:SetTimeout(1000, function()
if (TTT.match_state == MATCH_STATES.WARM_UP) then
print("warm up...")
if (DecreaseRemainingTime()) then
StartRound()
end
elseif (TTT.match_state == MATCH_STATES.IN_PROGRESS) then
print("in progress...")
if (DecreaseRemainingTime()) then
InnocentWins()
end
elseif (TTT.match_state == MATCH_STATES.WAITING_PLAYERS) then
print("waiting players...")
elseif (TTT.match_state == MATCH_STATES.POST_TIME) then
print("post time...")
if (DecreaseRemainingTime()) then
StartWarmUP()
end
end
end, {})
function DecreaseRemainingTime()
TTT.remaining_time = TTT.remaining_time - 1
return (TTT.remaining_time <= 0)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment