Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- include("shared.lua")
- -- Define GM12 fonts for compatibility
- surface.CreateFont("DefaultBold", {font = "Tahoma",
- size = 13,
- weight = 1000})
- surface.CreateFont("TabLarge", {font = "Tahoma",
- size = 13,
- weight = 700,
- shadow = true, antialias = false})
- surface.CreateFont("Trebuchet22", {font = "Trebuchet MS",
- size = 22,
- weight = 900})
- include("scoring_shd.lua")
- include("corpse_shd.lua")
- include("player_ext_shd.lua")
- include("weaponry_shd.lua")
- include("vgui/ColoredBox.lua")
- include("vgui/SimpleIcon.lua")
- include("vgui/ProgressBar.lua")
- include("vgui/ScrollLabel.lua")
- include("cl_radio.lua")
- include("cl_disguise.lua")
- include("cl_transfer.lua")
- include("cl_targetid.lua")
- include("cl_search.lua")
- include("cl_radar.lua")
- include("cl_tbuttons.lua")
- include("cl_scoreboard.lua")
- include("cl_tips.lua")
- include("cl_help.lua")
- include("cl_hud.lua")
- include("cl_msgstack.lua")
- include("cl_hudpickup.lua")
- include("cl_keys.lua")
- include("cl_wepswitch.lua")
- include("cl_scoring.lua")
- include("cl_scoring_events.lua")
- include("cl_popups.lua")
- include("cl_equip.lua")
- include("cl_voice.lua")
- function GM:Initialize()
- MsgN("TTT Client initializing...")
- GAMEMODE.round_state = ROUND_WAIT
- LANG.Init()
- self.BaseClass:Initialize()
- RunConsoleCommand("ttt_spectate", GetConVar("ttt_spectator_mode"):GetInt())
- end
- function GM:InitPostEntity()
- MsgN("TTT Client post-init...")
- if not game.SinglePlayer() then
- timer.Create("idlecheck", 5, 0, CheckIdle)
- end
- -- make sure player class extensions are loaded up, and then do some
- -- initialization on them
- if IsValid(LocalPlayer()) and LocalPlayer().GetTraitor then
- GAMEMODE:ClearClientState()
- end
- timer.Create("cache_ents", 1, 0, GAMEMODE.DoCacheEnts)
- RunConsoleCommand("_ttt_request_serverlang")
- RunConsoleCommand("_ttt_request_rolelist")
- end
- function GM:DoCacheEnts()
- RADAR:CacheEnts()
- TBHUD:CacheEnts()
- end
- function GM:HUDClear()
- RADAR:Clear()
- TBHUD:Clear()
- end
- KARMA = {}
- function KARMA.IsEnabled() return GetGlobalBool("ttt_karma", false) end
- function GetRoundState() return GAMEMODE.round_state end
- local function RoundStateChange(o, n)
- if n == ROUND_PREP then
- -- prep starts
- GAMEMODE:ClearClientState()
- GAMEMODE:CleanUpMap()
- -- show warning to spec mode players
- if GetConVar("ttt_spectator_mode"):GetBool() and IsValid(LocalPlayer())then
- LANG.Msg("spec_mode_warning")
- end
- -- reset cached server language in case it has changed
- RunConsoleCommand("_ttt_request_serverlang")
- elseif n == ROUND_ACTIVE then
- -- round starts
- VOICE.CycleMuteState(MUTE_NONE)
- CLSCORE:ClearPanel()
- -- people may have died and been searched during prep
- for _, p in pairs(player.GetAll()) do
- p.search_result = nil
- end
- -- clear blood decals produced during prep
- RunConsoleCommand("r_cleardecals")
- GAMEMODE.StartingPlayers = #util.GetAlivePlayers()
- elseif n == ROUND_POST then
- RunConsoleCommand("ttt_cl_traitorpopup_close")
- end
- -- stricter checks when we're talking about hooks, because this function may
- -- be called with for example o = WAIT and n = POST, for newly connecting
- -- players, which hooking code may not expect
- if n == ROUND_PREP then
- -- can enter PREP from any phase due to ttt_roundrestart
- hook.Call("TTTPrepareRound", GAMEMODE)
- elseif (o == ROUND_PREP) and (n == ROUND_ACTIVE) then
- hook.Call("TTTBeginRound", GAMEMODE)
- elseif (o == ROUND_ACTIVE) and (n == ROUND_POST) then
- hook.Call("TTTEndRound", GAMEMODE)
- end
- -- whatever round state we get, clear out the voice flags
- for k,v in pairs(player.GetAll()) do
- v.traitor_gvoice = false
- end
- end
- concommand.Add("ttt_print_playercount", function() print(GAMEMODE.StartingPlayers) end)
- --- optional sound cues on round start and end
- CreateConVar("ttt_cl_soundcues", "0", FCVAR_ARCHIVE)
- local cues = {
- Sound("ttt/thump01e.mp3"),
- Sound("ttt/thump02e.mp3")
- };
- local function PlaySoundCue()
- if GetConVar("ttt_cl_soundcues"):GetBool() then
- surface.PlaySound(table.Random(cues))
- end
- end
- GM.TTTBeginRound = PlaySoundCue
- GM.TTTEndRound = PlaySoundCue
- --- usermessages
- local function ReceiveRole()
- local client = LocalPlayer()
- local role = net.ReadUInt(2)
- -- after a mapswitch, server might have sent us this before we are even done
- -- loading our code
- if not client.SetRole then return end
- client:SetRole(role)
- Msg("You are: ")
- if client:IsTraitor() then MsgN("TRAITOR")
- elseif client:IsDetective() then MsgN("DETECTIVE")
- else MsgN("INNOCENT") end
- end
- net.Receive("TTT_Role", ReceiveRole)
- local function ReceiveRoleList()
- local role = net.ReadUInt(2)
- local num_ids = net.ReadUInt(8)
- for i=1, num_ids do
- local eidx = net.ReadUInt(7) + 1 -- we - 1 worldspawn=0
- local ply = player.GetByID(eidx)
- if IsValid(ply) and ply.SetRole then
- ply:SetRole(role)
- if ply:IsTraitor() then
- ply.traitor_gvoice = false -- assume traitorchat by default
- end
- end
- end
- end
- net.Receive("TTT_RoleList", ReceiveRoleList)
- -- Round state comm
- local function ReceiveRoundState()
- local o = GetRoundState()
- GAMEMODE.round_state = net.ReadUInt(3)
- if o != GAMEMODE.round_state then
- RoundStateChange(o, GAMEMODE.round_state)
- end
- MsgN("Round state: " .. GAMEMODE.round_state)
- end
- net.Receive("TTT_RoundState", ReceiveRoundState)
- -- Cleanup at start of new round
- function GM:ClearClientState()
- GAMEMODE:HUDClear()
- local client = LocalPlayer()
- if not client.SetRole then return end -- code not loaded yet
- client:SetRole(ROLE_INNOCENT)
- client.equipment_items = EQUIP_NONE
- client.equipment_credits = 0
- client.bought = {}
- client.last_id = nil
- client.radio = nil
- client.called_corpses = {}
- VOICE.InitBattery()
- for _, p in pairs(player.GetAll()) do
- if IsValid(p) then
- p.sb_tag = nil
- p:SetRole(ROLE_INNOCENT)
- p.search_result = nil
- end
- end
- VOICE.CycleMuteState(MUTE_NONE)
- RunConsoleCommand("ttt_mute_team_check", "0")
- if GAMEMODE.ForcedMouse then
- gui.EnableScreenClicker(false)
- end
- end
- net.Receive("TTT_ClearClientState", GM.ClearClientState)
- function GM:CleanUpMap()
- -- Ragdolls sometimes stay around on clients. Deleting them can create issues
- -- so all we can do is try to hide them.
- for _, ent in pairs(ents.FindByClass("prop_ragdoll")) do
- if IsValid(ent) and CORPSE.GetPlayerNick(ent, "") != "" then
- ent:SetNoDraw(true)
- ent:SetSolid(SOLID_NONE)
- ent:SetColor(Color(0,0,0,0))
- -- Horrible hack to make targetid ignore this ent, because we can't
- -- modify the collision group clientside.
- ent.NoTarget = true
- end
- end
- -- This cleans up decals since GMod v100
- game.CleanUpMap()
- end
- -- server tells us to call this when our LocalPlayer has spawned
- local function PlayerSpawn()
- local as_spec = net.ReadBit() == 1
- if as_spec then
- TIPS.Show()
- else
- TIPS.Hide()
- end
- end
- net.Receive("TTT_PlayerSpawned", PlayerSpawn)
- local function PlayerDeath()
- TIPS.Show()
- end
- net.Receive("TTT_PlayerDied", PlayerDeath)
- function GM:ShouldDrawLocalPlayer(ply) return false end
- local view = {origin = vector_origin, angles = angle_zero, fov=0}
- function GM:CalcView( ply, origin, angles, fov )
- view.origin = origin
- view.angles = angles
- view.fov = fov
- -- first person ragdolling
- if ply:Team() == TEAM_SPEC and ply:GetObserverMode() == OBS_MODE_IN_EYE then
- local tgt = ply:GetObserverTarget()
- if IsValid(tgt) and (not tgt:IsPlayer()) then
- -- assume if we are in_eye and not speccing a player, we spec a ragdoll
- local eyes = tgt:LookupAttachment("eyes") or 0
- eyes = tgt:GetAttachment(eyes)
- if eyes then
- view.origin = eyes.Pos
- view.angles = eyes.Ang
- end
- end
- end
- local wep = ply:GetActiveWeapon()
- if IsValid(wep) then
- local func = wep.CalcView
- if func then
- view.origin, view.angles, view.fov = func( wep, ply, origin*1, angles*1, fov )
- end
- end
- return view
- end
- function GM:AddDeathNotice() end
- function GM:DrawDeathNotice() end
- function GM:Tick()
- local client = LocalPlayer()
- if IsValid(client) then
- if client:Alive() and client:Team() != TEAM_SPEC then
- WSWITCH:Think()
- RADIO:StoreTarget()
- end
- VOICE.Tick()
- end
- end
- -- Simple client-based idle checking
- local idle = {ang = nil, pos = nil, mx = 0, my = 0, t = 0}
- function CheckIdle()
- local client = LocalPlayer()
- if not IsValid(client) then return end
- if not idle.ang or not idle.pos then
- -- init things
- idle.ang = client:GetAngles()
- idle.pos = client:GetPos()
- idle.mx = gui.MouseX()
- idle.my = gui.MouseY()
- idle.t = CurTime()
- return
- end
- if GetRoundState() == ROUND_ACTIVE and client:IsTerror() and client:Alive() then
- local idle_limit = GetGlobalInt("ttt_idle_limit", 300) or 300
- if idle_limit <= 0 then idle_limit = 300 end -- networking sucks sometimes
- if client:GetAngles() != idle.ang then
- -- Normal players will move their viewing angles all the time
- idle.ang = client:GetAngles()
- idle.t = CurTime()
- elseif gui.MouseX() != idle.mx or gui.MouseY() != idle.my then
- -- Players in eg. the Help will move their mouse occasionally
- idle.mx = gui.MouseX()
- idle.my = gui.MouseY()
- idle.t = CurTime()
- elseif client:GetPos():Distance(idle.pos) > 10 then
- -- Even if players don't move their mouse, they might still walk
- idle.pos = client:GetPos()
- idle.t = CurTime()
- elseif CurTime() > (idle.t + idle_limit) then
- RunConsoleCommand("say", "(AUTOMATED MESSAGE) I have been moved to the Spectator team because I was idle/AFK.")
- timer.Simple(0.3, function()
- RunConsoleCommand("ttt_spectator_mode", 1)
- RunConsoleCommand("ttt_cl_idlepopup")
- end)
- elseif CurTime() > (idle.t + (idle_limit / 2)) then
- -- will repeat
- LANG.Msg("idle_warning")
- end
- end
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement