462 lines
16 KiB
Lua
462 lines
16 KiB
Lua
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, <path file>) 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 "<path/sound/file.wav>" 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)
|