CreateClientConVar("ph_cl_halos", "1", true, true, "Toggle Enable/Disable Halo effects when choosing a prop.") CreateClientConVar("ph_cl_pltext", "1", true, false, "Options for Text above players. 0 = Disable. 1 = Enable.") CreateClientConVar("ph_cl_endround_sound", "1", true, false, "Play a sound when round ends? 0 to disable.") CreateClientConVar("ph_cl_autoclose_taunt", "1", true, false, "Auto close the taunt window (When Double Clicking on them)?") CreateClientConVar("ph_cl_spec_hunter_line", "1", true, false, "Draw a line on hunters so we can see their aim in spectator mode.") CreateClientConVar("cl_enable_luckyballs_icon", "1", true,false, "Enable 'Lucky ball' icon to be displayed once they spawned") CreateClientConVar("cl_enable_devilballs_icon", "1", true,false, "Enable 'Devil ball' icon to be displayed once they spawned") CreateClientConVar("ph_hud_use_new", "1", true, false, "Use new PH: Enhanced HUD") CreateClientConVar("ph_show_team_topbar", "1", true, false, "Show total alive team players bar on the top left (Experimental)") CreateClientConVar("ph_show_custom_crosshair","1",true,false,"Show custom crosshair for props") CreateClientConVar("ph_show_tutor_control","1",true,false,"Show 'Prop Gameplay Control' hud on each prop spawns. This only show twice and reset until map changes/user disconnect.") surface.CreateFont( "HunterBlindLockFont", { font = "Arial", size = 14, weight = 1200, antialias = true, underline = false }) surface.CreateFont("TrebuchetBig", { font = "Impact", size = 40 }) include("sh_init.lua") include("sh_config.lua") CL_GLOBAL_LIGHT_STATE = 0 include("cl_hud_mask.lua") include("cl_hud.lua") include("cl_menu.lua") include("cl_tauntwindow.lua") include("cl_targetid.lua") include("cl_autotaunt.lua") include("cl_credits.lua") -- Called immediately after starting the gamemode function Initialize() cHullz = 64 client_prop_light = false blind = false CL_GLIMPCAM = 0 MAT_LASERDOT = Material("sprites/glow04_noz") end hook.Add("Initialize", "PH_Initialize", Initialize) -- Decides where the player view should be (forces third person for props) function GM:CalcView(pl, origin, angles, fov) local view = {} if blind then view.origin = Vector(20000, 0, 0) view.angles = Angle(0, 0, 0) view.fov = fov return view end view.origin = origin view.angles = angles view.fov = fov -- Give the active weapon a go at changing the viewmodel position if pl:Team() == TEAM_PROPS && pl:Alive() then if GetConVar("ph_prop_camera_collisions"):GetBool() then local trace = {} local filterent = ents.FindByClass("ph_prop") table.insert(filterent, pl) if cHullz < 24 then trace.start = origin + Vector(0, 0, cHullz + (24-cHullz)) trace.endpos = origin + Vector(0, 0, cHullz + (24-cHullz)) + (angles:Forward() * -80) elseif cHullz > 84 then trace.start = origin + Vector(0, 0, cHullz - 84) trace.endpos = origin + Vector(0, 0, cHullz - 84) + (angles:Forward() * -80) else trace.start = origin + Vector(0, 0, 8) trace.endpos = origin + Vector(0, 0, 8) + (angles:Forward() * -80) end trace.filter = filterent local tr = util.TraceLine(trace) view.origin = tr.HitPos else if cHullz < 24 then view.origin = origin + Vector(0, 0, cHullz + (24-cHullz)) + (angles:Forward() * -80) elseif cHullz > 84 then view.origin = origin + Vector(0, 0, cHullz - 84) + (angles:Forward() * -80) else view.origin = origin + Vector(0, 0, 8) + (angles:Forward() * -80) end end elseif pl:Team() == TEAM_HUNTERS && pl:Alive() then local wep = pl:GetActiveWeapon() if wep && wep != NULL then local func = wep.GetViewModelPosition if func then view.vm_origin, view.vm_angles = func(wep, origin*1, angles*1) end local func = wep.CalcView if func then view.origin, view.angles, view.fov = func(wep, pl, origin*1, angles*1, fov) end end -- hunter glimpse of thirdperson if CL_GLIMPCAM > CurTime() then local trace = {} trace.start = origin trace.endpos = origin + (angles:Forward() * -80) trace.filter = player.GetAll() trace.maxs = Vector(4, 4, 4) trace.mins = Vector(-4, -4, -4) local tr = util.TraceHull(trace) view.drawviewer = true view.origin = tr.HitPos end end return view end local mat = "prophunt_enhanced/sprites/luckyball" local pointer = "prophunt_enhanced/sprites/luckyball_pointer" local dmat = "prophunt_enhanced/sprites/devilball" local dpointer = "prophunt_enhanced/sprites/devilball_pointer" local crosshair = Material("vgui/hud_crosshair") -- Draw round timeleft and hunter release timeleft function HUDPaint() -- Draw player texts if GetConVar("ph_enable_plnames"):GetBool() && GetConVar("ph_cl_pltext"):GetBool() && LocalPlayer():Team() != TEAM_SPECTATOR then for _, pl in pairs(player.GetAll()) do if pl != LocalPlayer() && (pl && pl:IsValid() && pl:Alive() && pl:Team() == LocalPlayer():Team()) then local addvector = Vector(0, 0, math.Clamp(pl:EyePos():Distance(LocalPlayer():EyePos())*0.04, 16, 64)) -- todo: text will disappear in a specified distance. draw.DrawText(pl:Name().." ("..pl:Health().."%)", "TargetIDSmall", (pl:EyePos() + addvector):ToScreen().x, (pl:EyePos() + addvector):ToScreen().y, team.GetColor(pl:Team()), TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER) end end end -- Hunter Blindlock Time if GetGlobalBool("InRound", false) then local blindlock_time_left = (GetConVarNumber("ph_hunter_blindlock_time") - (CurTime() - GetGlobalFloat("RoundStartTime", 0))) + 1 if blindlock_time_left < 1 && blindlock_time_left > -6 then blindlock_time_left_msg = "Ready or not, here we come!" elseif blindlock_time_left > 0 then blindlock_time_left_msg = "Hunters will be unblinded and released in "..string.ToMinutesSeconds(blindlock_time_left) else blindlock_time_left_msg = nil end if blindlock_time_left_msg then surface.SetFont("HunterBlindLockFont") local tw, th = surface.GetTextSize(blindlock_time_left_msg) draw.RoundedBox(8, 20, 20, tw + 20, 26, Color(0, 0, 0, 75)) draw.DrawText(blindlock_time_left_msg, "HunterBlindLockFont", 31, 26, Color(255, 255, 0, 255), TEXT_ALIGN_LEFT) end end -- Draw Lucky Balls Icon if GetConVar("cl_enable_luckyballs_icon"):GetBool() && LocalPlayer():Team() == TEAM_HUNTERS then local offset = Vector( 0, 0, 45 ) local ang = LocalPlayer():EyeAngles() local w = ScrW() local h = ScrH() local cX = w/2 local cY = h/2 for _,ent in pairs(ents.FindByClass('ph_luckyball')) do local pos = ent:GetPos() + offset local poscr = pos:ToScreen() if LocalPlayer():IsLineOfSightClear(ent) then if ((poscr.x > 32 && poscr.x < (w-43)) && (poscr.y > 32 && poscr.y < (h-38))) then surface.SetDrawColor(255,255,255,255) surface.SetTexture(surface.GetTextureID(mat)) surface.DrawTexturedRect( poscr.x-32, poscr.y, 64, 64 ) else local r = math.Round(cX/2) local rad = math.atan2(poscr.y-cY, poscr.x-cX) local deg = 0 - math.Round(math.deg(rad)) surface.SetDrawColor(255,255,255,255) surface.SetTexture(surface.GetTextureID(pointer)) surface.DrawTexturedRectRotated(math.cos(rad)*r+cX, math.sin(rad)*r+cY,64,64,deg+90) end end end end -- Draw Devil Ball Icon if GetConVar("cl_enable_devilballs_icon"):GetBool() && LocalPlayer():Team() == TEAM_PROPS then local offset = Vector( 0, 0, 35 ) local ang = LocalPlayer():EyeAngles() local w = ScrW() local h = ScrH() local cX = w/2 local cY = h/2 for _,ent in pairs(ents.FindByClass('ph_devilball')) do local pos = ent:GetPos() + offset local poscr = pos:ToScreen() if LocalPlayer():IsLineOfSightClear(ent) then if ((poscr.x > 32 && poscr.x < (w-43)) && (poscr.y > 32 && poscr.y < (h-38))) then surface.SetDrawColor(255,255,255,255) surface.SetTexture(surface.GetTextureID(dmat)) surface.DrawTexturedRect( poscr.x-32, poscr.y, 64, 64 ) else local r = math.Round(cX/2) local rad = math.atan2(poscr.y-cY, poscr.x-cX) local deg = 0 - math.Round(math.deg(rad)) surface.SetDrawColor(255,255,255,255) surface.SetTexture(surface.GetTextureID(dpointer)) surface.DrawTexturedRectRotated(math.cos(rad)*r+cX, math.sin(rad)*r+cY,64,64,deg+90) end end end end -- Prop Crosshair if GetConVar("ph_show_custom_crosshair"):GetBool() && LocalPlayer():Team() == TEAM_PROPS && LocalPlayer():Alive() then local color local trace = {} if cHullz < 24 then trace.start = LocalPlayer():EyePos() + Vector(0, 0, cHullz + (24-cHullz)) trace.endpos = LocalPlayer():EyePos() + Vector(0, 0, cHullz + (24-cHullz)) + LocalPlayer():EyeAngles():Forward() * 100 elseif cHullz > 84 then trace.start = LocalPlayer():EyePos() + Vector(0, 0, cHullz - 84) trace.endpos = LocalPlayer():EyePos() + Vector(0, 0, cHullz - 84) + LocalPlayer():EyeAngles():Forward() * 300 else trace.start = LocalPlayer():EyePos() + Vector(0, 0, 8) trace.endpos = LocalPlayer():EyePos() + Vector(0, 0, 8) + LocalPlayer():EyeAngles():Forward() * 100 end trace.filter = ents.FindByClass("ph_prop") local trace2 = util.TraceLine(trace) if trace2.Entity && trace2.Entity:IsValid() && table.HasValue(PHE.USABLE_PROP_ENTITIES, trace2.Entity:GetClass()) then color = Color(10,255,10,255) else color = Color(255,255,255,255) end surface.SetDrawColor( color ) surface.SetMaterial( crosshair ) surface.DrawTexturedRect( ScrW() / 2 - ( 64 / 2 ), ScrH() / 2 - ( 64 / 2 ), 64, 64 ) end -- The 'You were Killed By' text, or the Freeze Cam text. if LocalPlayer():GetNWBool("InFreezeCam", false) then local w1, h1 = surface.GetTextSize("You were killed by "..LocalPlayer():GetNWEntity("PlayerKilledByPlayerEntity", nil):Name() ); local textx = ScrW()/2 local steamx = (ScrW()/2) - 32 draw.SimpleTextOutlined("You were killed by "..LocalPlayer():GetNWEntity("PlayerKilledByPlayerEntity", nil):Name(), "TrebuchetBig", textx, ScrH()*0.75, Color(255, 10, 10, 255), TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER, 1.5, Color(0, 0, 0, 255)) end end hook.Add("HUDPaint", "PH_HUDPaint", HUDPaint) -- After the player has been drawn function PH_PostPlayerDraw(pl) -- Draw a line on hunters if GetConVar("ph_cl_spec_hunter_line"):GetBool() && (!LocalPlayer():Alive() || LocalPlayer():Team() == TEAM_SPECTATOR) then if IsValid(pl) && pl:Alive() && pl:Team() == TEAM_HUNTERS then render.DrawLine(pl:GetShootPos(), pl:GetEyeTrace().HitPos, team.GetColor(pl:Team()), true) render.SetMaterial(MAT_LASERDOT) render.DrawSprite(pl:GetEyeTrace().HitPos, 8, 8, team.GetColor(pl:Team())) end end end hook.Add("PostPlayerDraw", "PH_PostPlayerDraw", PH_PostPlayerDraw) hook.Add("PrePlayerDraw", "PHE.HidePlayer", function(ply) if ply:Team() == TEAM_PROPS then return true end end) -- Draws halos on team members function PHEDrawPropselectHalos() if GetConVar("ph_cl_halos"):GetBool() then -- Something to tell if the prop is selectable if LocalPlayer():Team() == TEAM_PROPS && LocalPlayer():Alive() then local trace = {} -- fix for smaller prop size. They should stay horizontal rather than looking straight down. if cHullz < 24 then trace.start = LocalPlayer():EyePos() + Vector(0, 0, cHullz + (24-cHullz)) trace.endpos = LocalPlayer():EyePos() + Vector(0, 0, cHullz + (24-cHullz)) + LocalPlayer():EyeAngles():Forward() * 100 elseif cHullz > 84 then trace.start = LocalPlayer():EyePos() + Vector(0, 0, cHullz - 84) trace.endpos = LocalPlayer():EyePos() + Vector(0, 0, cHullz - 84) + LocalPlayer():EyeAngles():Forward() * 300 else trace.start = LocalPlayer():EyePos() + Vector(0, 0, 8) trace.endpos = LocalPlayer():EyePos() + Vector(0, 0, 8) + LocalPlayer():EyeAngles():Forward() * 100 end trace.filter = ents.FindByClass("ph_prop") local trace2 = util.TraceLine(trace) if trace2.Entity && trace2.Entity:IsValid() && table.HasValue(PHE.USABLE_PROP_ENTITIES, trace2.Entity:GetClass()) then local ent_table = {} table.insert(ent_table, trace2.Entity) halo.Add(ent_table, Color(20, 250, 0), 1.2, 1.2, 1, true, true) end end end end hook.Add("PreDrawHalos", "PHEDrawPropselectHalos", PHEDrawPropselectHalos) -- Play random taunt hook.Add("KeyPress", "tracetest.GetPropInfo", function(pl, key) if ((pl:Team() == TEAM_PROPS && pl:Alive()) && key == IN_ATTACK2) then LocalPlayer():ConCommand("gm_showspare1") end end) -- Called every client frame function GM:Think() -- Prop light if client_prop_light && LocalPlayer() && LocalPlayer():IsValid() && LocalPlayer():Alive() && LocalPlayer():Team() == TEAM_PROPS then local prop_light = DynamicLight(LocalPlayer():EntIndex()) if prop_light then prop_light.pos = LocalPlayer():GetPos() prop_light.r = 255 prop_light.g = 255 prop_light.b = 255 prop_light.brightness = 0.25 prop_light.decay = 1 prop_light.size = 180 prop_light.dietime = CurTime() + 0.1 end end end -- ///////////////////\\\\\\\\\\\\\\\\\ -- -- Net Receives Hooks -- -- ///////////////////\\\\\\\\\\\\\\\\\ -- local tutormat = "vgui/hud_control_help.png" local curshow = 0 net.Receive("PH_ShowTutor", function() if GetConVar("ph_show_tutor_control"):GetBool() && LocalPlayer():Alive() then if curshow <= 2 then local xNotify = vgui.Create( "DNotify" ) xNotify:SetPos( ScrW() - 300 , 60 ) xNotify:SetSize( 256, 256 ) xNotify:SetLife(12) local bg = vgui.Create( "DPanel", xNotify ) bg:Dock( FILL ) bg:SetBackgroundColor( Color( 16, 16, 16, 180 ) ) local image = vgui.Create( "DImage", bg ) image:SetImage(tutormat) image:Dock(FILL) xNotify:AddItem(bg) curshow = curshow + 1 end end end) -- Receive the Winning Notification net.Receive("PH_RoundDraw_Snd", function(len) if GetConVar("ph_cl_endround_sound"):GetBool() then surface.PlaySound(table.Random(PHE.WINNINGSOUNDS["Draw"])) end end) net.Receive("PH_TeamWinning_Snd", function(len) local snd = net.ReadString() if GetConVar("ph_cl_endround_sound"):GetBool() then surface.PlaySound(snd) end end) -- Resets the player hull net.Receive("ResetHull", function() if LocalPlayer() && LocalPlayer():IsValid() then LocalPlayer():ResetHull() cHullz = 64 end end) -- Sets the local blind variable to be used in CalcView net.Receive("SetBlind", function() blind = net.ReadBool() end) --[[ Here you can add more than 2 additional freeze cam sounds. You can add more sounds by using table.insert(PHE.FreezeCamSnd, ) repeatedly outside of this code scope. Example: table.insert(PHE.FreezeCamSnd, "vo/k_lab/kl_fiddlesticks.wav") table.insert(PHE.FreezeCamSnd, "vo/k_lab/kl_ohdear.wav") ...more ]] -- If you wish to use a single sound instead, use ph_fc_use_single_sound 1 & ph_fc_cue_path "" convar to override. PHE.FreezeCamSnd = { -- do not manually add sounds in here, which this may break the sound list. Use table.insert instead! "misc/freeze_cam.wav", "misc/freeze_cam_sad1.wav" } -- Plays the Freeze Cam sound net.Receive("PlayFreezeCamSound", function() if GetConVar("ph_fc_use_single_sound"):GetBool() then surface.PlaySound(GetConVar("ph_fc_cue_path"):GetString()) else surface.PlaySound(table.Random(PHE.FreezeCamSnd)) end end) -- Sets the player hull net.Receive("SetHull", function() local hullxy = net.ReadInt(32) local huz = net.ReadInt(32) local hulldz = net.ReadInt(32) local new_health = net.ReadInt(9) cHullz = huz LocalPlayer():SetHull(Vector(hullxy * -1, hullxy * -1, 0), Vector(hullxy, hullxy, huz)) LocalPlayer():SetHullDuck(Vector(hullxy * -1, hullxy * -1, 0), Vector(hullxy, hullxy, hulldz)) LocalPlayer():SetHealth(new_health) end) -- Replaces the flashlight with a client-side dynamic light for props net.Receive("PlayerSwitchDynamicLight", function() if client_prop_light then client_prop_light = false surface.PlaySound("prop_idbs/light_off1.wav") CL_GLOBAL_LIGHT_STATE = 0 else client_prop_light = true surface.PlaySound("prop_idbs/light_on.wav") CL_GLOBAL_LIGHT_STATE = 1 end end) -- Turns the dynamic light OFF net.Receive("DisableDynamicLight", function() if client_prop_light then client_prop_light = false end end)