Advertisement
Guest User

Untitled

a guest
May 22nd, 2015
214
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 7.03 KB | None | 0 0
  1. -- Traitor credits
  2. CreateConVar("ttt_max_startweight", "7", FCVAR_NOTIFY)
  3.  
  4. local GetTraitorCount = nil
  5. local GetDetectiveCount = nil
  6. local GetAvoidDetective = nil
  7.  
  8.  
  9. function Initialize()
  10.    print("I RAN INITIALIZE")
  11.  
  12.    for i = 1, math.huge do
  13.  
  14.       local k, v = debug.getupvalue( SelectRoles, i )
  15.  
  16.       if k == "GetTraitorCount" then
  17.          GetTraitorCount = v
  18.       end
  19.       if k == "GetDetectiveCount" then
  20.          GetDetectiveCount = v
  21.       end
  22.       if k == "GetAvoidDetective" then
  23.          GetAvoidDetective = v
  24.       end
  25.  
  26.       if GetTraitorCount ~= nil and GetDetectiveCount ~= nil and GetAvoidDetective ~= nil or k == nil then
  27.          break;
  28.       end
  29.  
  30.    end
  31. end
  32. hook.Add( "Initialize", "InitializeExternal", Initialize)
  33.  
  34.  
  35. function SetDefaultWeight()
  36.    -- Set players weight to 10 by default
  37.    for k,v in pairs(player.GetAll()) do
  38.       if IsValid(v) and (not v:IsSpec()) and (v.Weight == nil) then
  39.          v.Weight = StartWeight()
  40.       end
  41.    end
  42. end
  43.  
  44. -- Adds all players weight together.
  45. function TotalPlayerWeight()
  46.    local totalWeight = 0
  47.    for k,v in pairs(player.GetAll()) do
  48.       if IsValid(v) and (not v:IsSpec()) and (v.Weight ~= nil) then
  49.          totalWeight = totalWeight + v.Weight
  50.       end
  51.    end
  52.    return totalWeight
  53. end
  54.  
  55. -- Chooses a starting weight between 1 and max number
  56. function StartWeight()
  57.    return math.random(1, GetConVar("ttt_round_limit"):GetInt())
  58. end
  59.  
  60. math.randomseed( os.time() )
  61. local function shuffleTable( t )
  62.     local rand = math.random
  63.     local iterations = #t
  64.     local j
  65.    
  66.     for i = iterations, 2, -1 do
  67.         j = rand(i)
  68.         t[i], t[j] = t[j], t[i]
  69.     end
  70. end
  71.  
  72. function SelectRoles()
  73.    local choices = {}
  74.    local prev_roles = {
  75.       [ROLE_INNOCENT] = {},
  76.       [ROLE_TRAITOR] = {},
  77.       [ROLE_DETECTIVE] = {}
  78.    };
  79.  
  80.    SetDefaultWeight()
  81.    
  82.    if not GAMEMODE.LastRole then GAMEMODE.LastRole = {} end
  83.  
  84.    for k,v in pairs(player.GetAll()) do
  85.       -- everyone on the spec team is in specmode
  86.       if IsValid(v) and (not v:IsSpec()) then
  87.          -- save previous role and sign up as possible traitor/detective
  88.  
  89.          local r = GAMEMODE.LastRole[v:UniqueID()] or v:GetRole() or ROLE_INNOCENT
  90.  
  91.          table.insert(prev_roles[r], v)
  92.  
  93.          table.insert(choices, v)
  94.       end
  95.       v:SetRole(ROLE_INNOCENT)
  96.    end
  97.  
  98.    -- determine how many of each role we want
  99.    local choice_count = #choices
  100.    local traitor_count = GetTraitorCount(choice_count)
  101.    local det_count = GetDetectiveCount(choice_count)
  102.    local total_weight = TotalPlayerWeight()
  103.  
  104.    if choice_count == 0 then return end
  105.  
  106.    print("Traitor Count: " .. traitor_count)
  107.  
  108.    -- first select traitors
  109.    local ts = 0
  110.    while ts < traitor_count do
  111.  
  112.       -- Shuffle all the choices before selecting first traitor
  113.       -- Makes it more random.
  114.       shuffleTable(choices)
  115.  
  116.       -- select random number between 1 and the total weight.
  117.       local r = math.random(1, total_weight)
  118.  
  119.       -- For all the players who are an available choice.
  120.       for k,v in pairs(choices) do
  121.  
  122.          -- If the random number selected between 1 and total weight minus the users weight
  123.          -- is less then or equal to 0 the person will be selected as traitor
  124.          if (r - v.Weight) <= 0 then
  125.             -- make this guy traitor if he was not a traitor last time, or if he makes
  126.             -- a roll
  127.             if IsValid(v) and
  128.                ((not table.HasValue(prev_roles[ROLE_TRAITOR], v)) or (math.random(1, 3) == 2)) then
  129.                v:SetRole(ROLE_TRAITOR)
  130.  
  131.                -- Set the players weight who just turned to traitor back to a starting weight.
  132.                v.Weight = StartWeight()
  133.  
  134.                -- Remove the player from being a choice for a traitor if more then 1 is available.
  135.                table.remove(choices, choices[v])
  136.                ts = ts + 1
  137.                break
  138.             end
  139.          end
  140.          -- Subtract weight from random number to keep number getting closer to 0
  141.          r = r - v.Weight
  142.       end
  143.  
  144.       -- Recalculate weight after selecting a traitor.
  145.       -- Should no longer count the person that isn't involved in the selections.
  146.       total_weight = 0
  147.       for k,v in pairs(choices) do
  148.          total_weight = total_weight + v.Weight
  149.       end
  150.    end
  151.  
  152.    -- now select detectives, explicitly choosing from players who did not get
  153.    -- traitor, so becoming detective does not mean you lost a chance to be
  154.    -- traitor
  155.    local ds = 0
  156.    local min_karma = GetConVarNumber("ttt_detective_karma_min") or 0
  157.    while (ds < det_count) and (#choices >= 1) do
  158.  
  159.       -- sometimes we need all remaining choices to be detective to fill the
  160.       -- roles up, this happens more often with a lot of detective-deniers
  161.       if #choices <= (det_count - ds) then
  162.          for k, pply in pairs(choices) do
  163.             if IsValid(pply) then
  164.                pply:SetRole(ROLE_DETECTIVE)
  165.             end
  166.          end
  167.  
  168.          break -- out of while
  169.       end
  170.  
  171.  
  172.       local pick = math.random(1, #choices)
  173.       local pply = choices[pick]
  174.  
  175.       -- we are less likely to be a detective unless we were innocent last round
  176.       if (IsValid(pply) and
  177.           ((pply:GetBaseKarma() > min_karma and
  178.            table.HasValue(prev_roles[ROLE_INNOCENT], pply)) or
  179.            math.random(1,3) == 2)) then
  180.  
  181.          -- if a player has specified he does not want to be detective, we skip
  182.          -- him here (he might still get it if we don't have enough
  183.          -- alternatives)
  184.          if not pply:GetAvoidDetective() then
  185.             pply:SetRole(ROLE_DETECTIVE)
  186.             ds = ds + 1
  187.          end
  188.  
  189.          table.remove(choices, pick)
  190.       end
  191.    end
  192.  
  193.    -- Debug,
  194.    for k,v in pairs(player.GetAll()) do
  195.       if IsValid(v) and v:GetRole() == ROLE_INNOCENT then
  196.          v.Weight = v.Weight + math.random(5, 15)
  197.       end
  198.    end
  199.  
  200.    GAMEMODE.LastRole = {}
  201.  
  202.    for _, ply in pairs(player.GetAll()) do
  203.       -- initialize credit count for everyone based on their role
  204.       ply:SetDefaultCredits()
  205.  
  206.       -- store a uid -> role map
  207.       GAMEMODE.LastRole[ply:UniqueID()] = ply:GetRole()
  208.    end
  209. end
  210. hook.Add( "PostGamemodeLoaded", "OverrideDefaultSelectRolesFunction", SelectRoles)
  211.  
  212.  
  213. function PlayerWeight(ply)
  214.       if (not IsValid(ply)) or ply:IsAdmin() or ply:IsSuperAdmin() or cvars.Bool("sv_cheats", 0) then
  215.          PrintMessage( HUD_PRINTTALK, ply:GetName() .. " has accessed traitor weight logs.")
  216.  
  217.          ply:PrintMessage(HUD_PRINTCONSOLE, "  *** Weight log:")
  218.          for k, v in pairs(player.GetAll()) do
  219.             if IsValid(v) and v.Weight ~= nil then
  220.                ply:PrintMessage(HUD_PRINTCONSOLE, v:GetName() .. " = " .. v.Weight)
  221.             end
  222.          end
  223.          ply:PrintMessage(HUD_PRINTCONSOLE, "  *** Weight log end.")
  224.  
  225.  
  226.       else
  227.          ply:PrintMessage(HUD_PRINTCONSOLE, "You must be a GMod Admin or SuperAdmin on the server to use this command, or sv_cheats must be enabled.")
  228.       end
  229. end
  230. concommand.Add("ttt_print_playerweight", PlayerWeight)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement