Advertisement
Terrah

gamemsg

Jun 2nd, 2015
431
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 11.40 KB | None | 0 0
  1. --[[
  2.  
  3.     This script was modified by Terrah 2015-06-01
  4.     as the current version of this time crashes
  5.     when Say is called within the PlayerSay hook.
  6.    
  7.     when this is resolved, restore the original current version
  8.     of this script.
  9. ]]
  10.  
  11. ---- Communicating game state to players
  12.  
  13. local net = net
  14. local string = string
  15. local table = table
  16. local pairs = pairs
  17.  
  18. -- NOTE: most uses of the Msg functions here have been moved to the LANG
  19. -- functions. These functions are essentially deprecated, though they won't be
  20. -- removed and can safely be used by SWEPs and the like.
  21.  
  22. function GameMsg(msg)
  23.    net.Start("TTT_GameMsg")
  24.       net.WriteString(msg)
  25.       net.WriteBit(false)
  26.    net.Broadcast()
  27. end
  28.  
  29. function CustomMsg(ply_or_rf, msg, clr)
  30.    clr = clr or COLOR_WHITE
  31.  
  32.    net.Start("TTT_GameMsgColor")
  33.       net.WriteString(msg)
  34.       net.WriteUInt(clr.r, 8)
  35.       net.WriteUInt(clr.g, 8)
  36.       net.WriteUInt(clr.b, 8)
  37.    if ply_or_rf then net.Send(ply_or_rf)
  38.    else net.Broadcast() end
  39. end
  40.  
  41. -- Basic status message to single player or a recipientfilter
  42. function PlayerMsg(ply_or_rf, msg, traitor_only)
  43.    net.Start("TTT_GameMsg")
  44.       net.WriteString(msg)
  45.       net.WriteBit(traitor_only)
  46.    if ply_or_rf then net.Send(ply_or_rf)
  47.    else net.Broadcast() end
  48. end
  49.  
  50. -- Traitor-specific message that will appear in a special color
  51. function TraitorMsg(ply_or_rfilter, msg)
  52.    PlayerMsg(ply_or_rfilter, msg, true)
  53. end
  54.  
  55. -- Traitorchat
  56. local function RoleChatMsg(sender, role, msg)
  57.    net.Start("TTT_RoleChat")
  58.       net.WriteUInt(role, 2)
  59.       net.WriteEntity(sender)
  60.       net.WriteString(msg)
  61.    net.Send(GetRoleFilter(role))
  62. end
  63.  
  64.  
  65. -- Round start info popup
  66. function ShowRoundStartPopup()
  67.    for k, v in pairs(player.GetAll()) do
  68.       if IsValid(v) and v:Team() == TEAM_TERROR and v:Alive() then
  69.          v:ConCommand("ttt_cl_startpopup")
  70.       end
  71.    end
  72. end
  73.  
  74. local function GetPlayerFilter(pred)
  75.    local filter = {}
  76.    for k, v in pairs(player.GetAll()) do
  77.       if IsValid(v) and pred(v) then
  78.          table.insert(filter, v)
  79.       end
  80.    end
  81.    return filter
  82. end
  83.  
  84. function GetTraitorFilter(alive_only)
  85.    return GetPlayerFilter(function(p) return p:GetTraitor() and (not alive_only or p:Alive()) end)
  86. end
  87.  
  88. function GetDetectiveFilter(alive_only)
  89.    return GetPlayerFilter(function(p) return p:IsDetective() and (not alive_only or p:Alive()) end)
  90. end
  91.  
  92. function GetInnocentFilter(alive_only)
  93.    return GetPlayerFilter(function(p) return (not p:IsTraitor()) and (not alive_only or p:Alive()) end)
  94. end
  95.  
  96. function GetRoleFilter(role, alive_only)
  97.    return GetPlayerFilter(function(p) return p:IsRole(role) and (not alive_only or p:Alive()) end)
  98. end
  99.  
  100. ---- Communication control
  101. CreateConVar("ttt_limit_spectator_chat", "1", FCVAR_ARCHIVE + FCVAR_NOTIFY)
  102. CreateConVar("ttt_limit_spectator_voice", "1", FCVAR_ARCHIVE + FCVAR_NOTIFY)
  103.  
  104. local mumbles = {"mumble", "mm", "hmm", "hum", "mum", "mbm", "mble", "ham", "mammaries", "political situation", "mrmm", "hrm", "uzbekistan", "mumu", "cheese export", "hmhm", "mmh", "mumble", "mphrrt", "mrh", "hmm", "mumble", "mbmm", "hmml", "mfrrm"}
  105.  
  106. -- While a round is active, spectators can only talk among themselves. When they
  107. -- try to speak to all players they could divulge information about who killed
  108. -- them. So we mumblify them. In detective mode, we shut them up entirely.
  109. function GM:PlayerSay(ply, text, team_only)
  110.    if not IsValid(ply) then return ""; end
  111.    
  112.    --ensure we are a string, ERROR: PlayerSay -> non string errors ??
  113.    if type(text)~="string" then
  114.         text="";
  115.     end
  116.    
  117.    if ply:Team() == TEAM_SPEC and (not team_only) and GetRoundState() == ROUND_ACTIVE then
  118.       if not GetConVar("ttt_limit_spectator_chat"):GetBool() then
  119.          return text
  120.       elseif not DetectiveMode() then
  121.          local filtered = {}
  122.          for k, v in pairs(string.Explode(" ", text)) do
  123.             -- grab word characters and whitelisted interpunction
  124.             -- necessary or leetspeek will be used (by trolls especially)
  125.             local word, interp = string.match(v, "(%a*)([%.,;!%?]*)")
  126.             if word != "" then
  127.                table.insert(filtered, mumbles[math.random(1, #mumbles)] .. interp)
  128.             end
  129.          end
  130.  
  131.          -- make sure we have something to say
  132.          if table.Count(filtered) < 1 then
  133.             table.insert(filtered, mumbles[math.random(1, #mumbles)])
  134.          end
  135.  
  136.          table.insert( filtered, 1, "[MUMBLED]")
  137.          
  138.          text = table.concat(filtered, " ");
  139.          
  140.          --Same as above
  141.         if type(text)~="string" then
  142.             text="";
  143.         end
  144.          
  145.          return text
  146.       else
  147.          --calling Say inside the say hook crashes the server
  148.          --ply:Say(text, true)
  149.          return ""
  150.       end
  151.    end
  152.  
  153.    if team_only and ply:Team() != TEAM_SPEC and GetRoundState() == ROUND_ACTIVE then
  154.       if ply:IsSpecial() then
  155.          -- traitor chat handling
  156.          RoleChatMsg(ply, ply:GetRole(), text)
  157.       else
  158.         --calling Say inside the say hook crashes the server
  159.         --restored old behavior to prevent crashes
  160.          LANG.Msg(ply, "inno_globalchat_hint")
  161.       end
  162.  
  163.       return ""
  164.    end
  165. return text;
  166. end
  167.  
  168.  
  169. -- Mute players when we are about to run map cleanup, because it might cause
  170. -- net buffer overflows on clients.
  171. local mute_all = false
  172. function MuteForRestart(state)
  173.    mute_all = state
  174. end
  175.  
  176.  
  177. local loc_voice = CreateConVar("ttt_locational_voice", "0")
  178.  
  179. -- Of course voice has to be limited as well
  180. function GM:PlayerCanHearPlayersVoice( listener, speaker )
  181.    -- Enforced silence
  182.    if mute_all then
  183.       return false, false
  184.    end
  185.  
  186.    if (not IsValid(speaker)) or (not IsValid(listener)) or (listener == speaker) then
  187.       return false, false
  188.    end
  189.  
  190.    -- limited if specific convar is on, or we're in detective mode
  191.    local limit = DetectiveMode() or GetConVar("ttt_limit_spectator_voice"):GetBool()
  192.  
  193.    -- Spectators should not be heard by living players during round
  194.    if speaker:IsSpec() and (not listener:IsSpec()) and limit and GetRoundState() == ROUND_ACTIVE then
  195.       return false, false
  196.    end
  197.  
  198.    -- Specific mute
  199.    if listener:IsSpec() and listener.mute_team == speaker:Team() then
  200.       return false, false
  201.    end
  202.  
  203.    -- Specs should not hear each other locationally
  204.    if speaker:IsSpec() and listener:IsSpec() then
  205.       return true, false
  206.    end
  207.  
  208.    -- Traitors "team"chat by default, non-locationally
  209.    if speaker:IsActiveTraitor() then
  210.       if speaker.traitor_gvoice then
  211.          return true, loc_voice:GetBool()
  212.       elseif listener:IsActiveTraitor() then
  213.          return true, false
  214.       else
  215.          -- unless traitor_gvoice is true, normal innos can't hear speaker
  216.          return false, false
  217.       end
  218.    end
  219.  
  220.    return true, (loc_voice:GetBool() and GetRoundState() != ROUND_POST)
  221. end
  222.  
  223. local function SendTraitorVoiceState(speaker, state)
  224.    -- send umsg to living traitors that this is traitor-only talk
  225.    local rf = GetTraitorFilter(true)
  226.  
  227.    -- make it as small as possible, to get there as fast as possible
  228.    -- we can fit it into a mere byte by being cheeky.
  229.    net.Start("TTT_TraitorVoiceState")
  230.       net.WriteUInt(speaker:EntIndex() - 1, 7) -- player ids can only be 1-128
  231.       net.WriteBit(state)
  232.    if rf then net.Send(rf)
  233.    else net.Broadcast() end
  234. end
  235.  
  236.  
  237. local function TraitorGlobalVoice(ply, cmd, args)
  238.    if not IsValid(ply) or not ply:IsActiveTraitor() then return end
  239.    if not #args == 1 then return end
  240.    local state = tonumber(args[1])
  241.  
  242.    ply.traitor_gvoice = (state == 1)
  243.  
  244.    SendTraitorVoiceState(ply, ply.traitor_gvoice)
  245. end
  246. concommand.Add("tvog", TraitorGlobalVoice)
  247.  
  248. local function MuteTeam(ply, cmd, args)
  249.    if not IsValid(ply) then return end
  250.    if not #args == 1 and tonumber(args[1]) then return end
  251.    if not ply:IsSpec() then
  252.       ply.mute_team = -1
  253.       return
  254.    end
  255.  
  256.    local t = tonumber(args[1])
  257.    ply.mute_team = t
  258.  
  259.    local name = (t != 0) and team.GetName(t) or "None"
  260.    ply:ChatPrint(name .. " muted.")
  261. end
  262. concommand.Add("ttt_mute_team", MuteTeam)
  263.  
  264. local ttt_lastwords = CreateConVar("ttt_lastwords_chatprint", "0")
  265.  
  266. local LastWordContext = {
  267.    [KILL_NORMAL] = "",
  268.    [KILL_SUICIDE] = " *kills self*",
  269.    [KILL_FALL] = " *SPLUT*",
  270.    [KILL_BURN] = " *crackle*"
  271. };
  272.  
  273. local function LastWordsMsg(ply, words)
  274.    -- only append "--" if there's no ending interpunction
  275.    local final = string.match(words, "[\\.\\!\\?]$") != nil
  276.  
  277.    -- add optional context relating to death type
  278.    local context = LastWordContext[ply.death_type] or ""
  279.  
  280.    net.Start("TTT_LastWordsMsg")
  281.       net.WriteEntity(ply)
  282.       net.WriteString(words .. (final and "" or "--") .. context)
  283.    net.Broadcast()
  284. end
  285.  
  286. local function LastWords(ply, cmd, args)
  287.    if IsValid(ply) and (not ply:Alive()) and #args > 1 then
  288.       local id = tonumber(args[1])
  289.       if id and ply.last_words_id and id == ply.last_words_id then
  290.          -- never allow multiple last word stuff
  291.          ply.last_words_id = nil
  292.  
  293.          -- we will be storing this on the ragdoll
  294.          local rag = ply.server_ragdoll
  295.          if not (IsValid(rag) and rag.player_ragdoll) then
  296.             rag = nil
  297.          end
  298.  
  299.          --- last id'd person
  300.          local last_seen = tonumber(args[2])
  301.          if last_seen then
  302.             local ent = Entity(last_seen)
  303.             if IsValid(ent) and ent:IsPlayer() and rag and (not rag.lastid) then
  304.                rag.lastid = {ent=ent, t=CurTime()}
  305.             end
  306.          end
  307.  
  308.          --- last words
  309.          local words = string.Trim(args[3])
  310.  
  311.          -- nothing of interest
  312.          if string.len(words) < 2 then return end
  313.  
  314.          -- ignore admin commands
  315.          local firstchar = string.GetChar(words, 1)
  316.          if firstchar == "!" or firstchar == "@" or firstchar == "/" then return end
  317.  
  318.  
  319.          if ttt_lastwords:GetBool() or ply.death_type == KILL_FALL then
  320.             LastWordsMsg(ply, words)
  321.          end
  322.  
  323.          if rag and (not rag.last_words) then
  324.             rag.last_words = words
  325.          end
  326.       else
  327.          ply.last_words_id = nil
  328.       end
  329.    end
  330. end
  331. concommand.Add("_deathrec", LastWords)
  332.  
  333. -- Override or hook in plugin for spam prevention and whatnot. Return true
  334. -- to block a command.
  335. function GM:TTTPlayerRadioCommand(ply, msg_name, msg_target)
  336. end
  337.  
  338. local function RadioCommand(ply, cmd, args)
  339.    if IsValid(ply) and ply:IsTerror() and #args == 2 then
  340.       local msg_name = args[1]
  341.       local msg_target = args[2]
  342.  
  343.       local name = ""
  344.       local rag_name = nil
  345.  
  346.       if tonumber(msg_target) then
  347.          -- player or corpse ent idx
  348.          local ent = Entity(tonumber(msg_target))
  349.          if IsValid(ent) then
  350.             if ent:IsPlayer() then
  351.                name = ent:Nick()
  352.             elseif ent:GetClass() == "prop_ragdoll" then
  353.                name = LANG.NameParam("quick_corpse_id")
  354.                rag_name = CORPSE.GetPlayerNick(ent, "A Terrorist")
  355.             end
  356.          end
  357.  
  358.          msg_target = ent
  359.       else
  360.          -- lang string
  361.          name = LANG.NameParam(msg_target)
  362.       end
  363.  
  364.       if hook.Call("TTTPlayerRadioCommand", GAMEMODE, ply, msg_name, msg_target) then
  365.          return
  366.       end
  367.  
  368.       net.Start("TTT_RadioMsg")
  369.          net.WriteEntity(ply)
  370.          net.WriteString(msg_name)
  371.          net.WriteString(name)
  372.          if rag_name then
  373.             net.WriteString(rag_name)
  374.          end
  375.       net.Broadcast()
  376.    end
  377. end
  378. concommand.Add("_ttt_radio_send", RadioCommand)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement