zombiesurvival-evolved/gamemodes/zombiesurvival/gamemode/cl_init.lua

2247 lines
74 KiB
Lua
Raw Normal View History

2014-10-02 08:49:54 +08:00
-- Sometimes persistent ones don't get created.
local dummy = CreateClientConVar("_zs_dummyconvar", 1, false, false)
local oldCreateClientConVar = CreateClientConVar
function CreateClientConVar(...)
return oldCreateClientConVar(...) or dummy
end
include("sh_globals.lua")
include("obj_entity_extend_cl.lua")
include("obj_player_extend_cl.lua")
include("obj_weapon_extend_cl.lua")
include("loader.lua")
2014-10-02 08:49:54 +08:00
include("shared.lua")
include("cl_draw.lua")
include("cl_util.lua")
include("cl_options.lua")
include("cl_scoreboard.lua")
include("cl_targetid.lua")
include("cl_postprocess.lua")
include("cl_voicesets.lua")
include("cl_net.lua")
include("skillweb/cl_skillweb.lua")
2014-10-02 08:49:54 +08:00
include("vgui/dteamcounter.lua")
include("vgui/dmodelpanelex.lua")
include("vgui/dammocounter.lua")
include("vgui/dteamheading.lua")
2014-12-08 04:02:40 +08:00
include("vgui/dmodelkillicon.lua")
2014-10-02 08:49:54 +08:00
include("vgui/dexroundedpanel.lua")
include("vgui/dexroundedframe.lua")
include("vgui/dexrotatedimage.lua")
include("vgui/dexnotificationslist.lua")
include("vgui/dexchanginglabel.lua")
include("vgui/mainmenu.lua")
2014-10-02 08:49:54 +08:00
include("vgui/pmainmenu.lua")
include("vgui/poptions.lua")
include("vgui/phelp.lua")
include("vgui/pclassselect.lua")
include("vgui/pweapons.lua")
include("vgui/pendboard.lua")
include("vgui/pworth.lua")
include("vgui/parsenal.lua")
include("vgui/premantle.lua")
2014-10-02 08:49:54 +08:00
include("vgui/dpingmeter.lua")
include("vgui/dsidemenu.lua")
include("vgui/dspawnmenu.lua")
include("vgui/zsgamestate.lua")
2014-10-02 08:49:54 +08:00
include("vgui/zshealtharea.lua")
include("vgui/zsstatusarea.lua")
2014-10-02 08:49:54 +08:00
include("cl_dermaskin.lua")
include("cl_deathnotice.lua")
include("cl_floatingscore.lua")
include("cl_hint.lua")
include("cl_thirdperson.lua")
include("itemstocks/cl_stock.lua")
2014-10-02 08:49:54 +08:00
include("cl_zombieescape.lua")
w, h = ScrW(), ScrH()
MySelf = MySelf or NULL
hook.Add("InitPostEntity", "GetLocal", function()
MySelf = LocalPlayer()
GAMEMODE.HookGetLocal = GAMEMODE.HookGetLocal or function(g) end
2014-10-02 08:49:54 +08:00
gamemode.Call("HookGetLocal", MySelf)
RunConsoleCommand("initpostentity")
MySelf:ApplySkills()
2014-10-02 08:49:54 +08:00
end)
-- Remove when model decal crash is fixed.
--[[function util.Decal()
end]]
2014-10-02 08:49:54 +08:00
-- Save on global lookup time.
local collectgarbage = collectgarbage
2014-10-02 08:49:54 +08:00
local render = render
local surface = surface
local draw = draw
local cam = cam
local player = player
local ents = ents
local util = util
local math = math
local string = string
local bit = bit
local gamemode = gamemode
local hook = hook
local Vector = Vector
local VectorRand = VectorRand
local Angle = Angle
local AngleRand = AngleRand
local Entity = Entity
local Color = Color
local FrameTime = FrameTime
local RealTime = RealTime
local CurTime = CurTime
local SysTime = SysTime
local EyePos = EyePos
local EyeAngles = EyeAngles
local pairs = pairs
local ipairs = ipairs
local tostring = tostring
local tonumber = tonumber
local type = type
local ScrW = ScrW
local ScrH = ScrH
local Lerp = Lerp
local EF_DIMLIGHT = EF_DIMLIGHT
2014-10-02 08:49:54 +08:00
local TEXT_ALIGN_CENTER = TEXT_ALIGN_CENTER
local TEXT_ALIGN_LEFT = TEXT_ALIGN_LEFT
local TEXT_ALIGN_RIGHT = TEXT_ALIGN_RIGHT
local TEXT_ALIGN_TOP = TEXT_ALIGN_TOP
local TEXT_ALIGN_BOTTOM = TEXT_ALIGN_BOTTOM
local TEXT_ALIGN_TOP_REAL = TEXT_ALIGN_TOP_REAL
local TEXT_ALIGN_BOTTOM_REAL = TEXT_ALIGN_BOTTOM_REAL
2014-10-02 08:49:54 +08:00
local TEAM_HUMAN = TEAM_HUMAN
local TEAM_UNDEAD = TEAM_UNDEAD
local translate = translate
local COLOR_PURPLE = COLOR_PURPLE
local COLOR_GRAY = COLOR_GRAY
local COLOR_RED = COLOR_RED
local COLOR_DARKRED = COLOR_DARKRED
local COLOR_DARKGREEN = COLOR_DARKGREEN
local COLOR_GREEN = COLOR_GREEN
local COLOR_WHITE = COLOR_WHITE
local vector_up = Vector(0, 0, 1)
local vector_down = Vector(0, 0, 1)
--local surface_SetFont = surface.SetFont
--local surface_SetTexture = surface.SetTexture
2014-10-02 08:49:54 +08:00
local surface_SetMaterial = surface.SetMaterial
local surface_SetDrawColor = surface.SetDrawColor
--local surface_DrawLine = surface.DrawLine
2014-10-02 08:49:54 +08:00
local surface_DrawRect = surface.DrawRect
local surface_DrawOutlinedRect = surface.DrawOutlinedRect
local surface_DrawTexturedRect = surface.DrawTexturedRect
local surface_DrawTexturedRectRotated = surface.DrawTexturedRectRotated
local surface_DrawTexturedRectUV = surface.DrawTexturedRectUV
local surface_PlaySound = surface.PlaySound
local render_SetBlend = render.SetBlend
local render_ModelMaterialOverride = render.ModelMaterialOverride
local render_SetColorModulation = render.SetColorModulation
local render_SuppressEngineLighting = render.SuppressEngineLighting
local cam_IgnoreZ = cam.IgnoreZ
local render_SetMaterial = render.SetMaterial
local render_DrawQuadEasy = render.DrawQuadEasy
local cam_Start3D = cam.Start3D
local cam_End3D = cam.End3D
local cam_Start3D2D = cam.Start3D2D
local cam_End3D2D = cam.End3D2D
local render_FogMode = render.FogMode
local render_FogStart = render.FogStart
local render_FogEnd = render.FogEnd
local render_FogColor = render.FogColor
local render_FogMaxDensity = render.FogMaxDensity
local render_GetFogDistances = render.GetFogDistances
local render_GetFogColor = render.GetFogColor
local render_GetFogMode = render.GetFogMode
2014-10-02 08:49:54 +08:00
local draw_SimpleText = draw.SimpleText
local draw_SimpleTextBlurry = draw.SimpleTextBlurry
local draw_SimpleTextBlur = draw.SimpleTextBlur
local draw_GetFontHeight = draw.GetFontHeight
local MedicalAuraDistance = 800 ^ 2
local M_Player = FindMetaTable("Player")
local P_Team = M_Player.Team
2014-10-02 08:49:54 +08:00
Merge with current nox changes. Random starting loadouts now include things that aren't weapons (ammo, traits, etc.). Added an option to disable the automatic suicide when changing zombie classes. Zombies will no longer receive damage resistance when only one human remains. Players can no longer claim the arsenal crate that gets spawned in the human spawn when nobody has one. Any player can pack it up though. The Ghoul's ghoul touch special ability has been changed. It will no longer slow targets but will debuff them for the next 10 seconds. They will take 40% more damage (the extra damage is attributed to the person who ghoul touched them last) for the next 10 seconds as well as slightly disorienting them. The Ghoul movement speed has been reduced from 185 to 170. Added crafting recipe: 'Waraxe' Handgun. Combine two 'Battleaxe' Handguns to craft this. Slightly better version of the Owens. The Flesh Creeper model has been changed to one that doesn't have severely awkward hitboxes. The Flesh Creeper can no longer jump and attack at the same time. The Lead Pipe special trait has been changed from a disorientation to a severe view punch/snap on a global cooldown of 1.5 seconds. The Regenerative trait is now 1 health every 6 seconds under 50% health instead of 1 health every 5 seconds under 50% health. Fast Zombie Legs have been changed to be a slightly faster but slightly weaker version of Zombie Legs. Zombies that have just spawned or enter zombie gas will now have a temporary buff which gives 25% extra speed and 40% damage resistance. This buff lasts for 3 seconds and is refreshed by entering the gas. Gas will no longer heal. Zombies with this buff on will strobe dark green. Added crafting recipe: Bladehack. Combine a saw blade with a manhack to get this. Slower but has more health, does more damage, and has less of a knockback when hitting something. Resupply Boxes now award the owner a point for every 2 people who use their box instead of every single person (so half as many points). Fixed Fast Zombie Legs spawning much more abundantly than intended. Fixed Flesh Creepers not being able to jump over obstacles due to their insanely low jump height. Fixed zombies taking themselves in to account when calculating horde damage resistance (bosses always had full resistance because of this). Fixed allowing people to use worth menu after redeeming.
2014-11-07 13:03:40 +08:00
GM.LifeStatsBrainsEaten = 0
GM.LifeStatsHumanDamage = 0
GM.LifeStatsBarricadeDamage = 0
GM.InputMouseX = 0
GM.InputMouseY = 0
GM.LastTimeDead = 0
GM.LastTimeAlive = 0
GM.HeartBeatTime = 0
GM.FOVLerp = 1
GM.HurtEffect = 0
GM.PrevHealth = 0
GM.SuppressArsenalTime = 0
GM.ZombieThirdPerson = false
GM.Beats = {}
GM.CurrentRound = 1
Merge with current nox changes. Random starting loadouts now include things that aren't weapons (ammo, traits, etc.). Added an option to disable the automatic suicide when changing zombie classes. Zombies will no longer receive damage resistance when only one human remains. Players can no longer claim the arsenal crate that gets spawned in the human spawn when nobody has one. Any player can pack it up though. The Ghoul's ghoul touch special ability has been changed. It will no longer slow targets but will debuff them for the next 10 seconds. They will take 40% more damage (the extra damage is attributed to the person who ghoul touched them last) for the next 10 seconds as well as slightly disorienting them. The Ghoul movement speed has been reduced from 185 to 170. Added crafting recipe: 'Waraxe' Handgun. Combine two 'Battleaxe' Handguns to craft this. Slightly better version of the Owens. The Flesh Creeper model has been changed to one that doesn't have severely awkward hitboxes. The Flesh Creeper can no longer jump and attack at the same time. The Lead Pipe special trait has been changed from a disorientation to a severe view punch/snap on a global cooldown of 1.5 seconds. The Regenerative trait is now 1 health every 6 seconds under 50% health instead of 1 health every 5 seconds under 50% health. Fast Zombie Legs have been changed to be a slightly faster but slightly weaker version of Zombie Legs. Zombies that have just spawned or enter zombie gas will now have a temporary buff which gives 25% extra speed and 40% damage resistance. This buff lasts for 3 seconds and is refreshed by entering the gas. Gas will no longer heal. Zombies with this buff on will strobe dark green. Added crafting recipe: Bladehack. Combine a saw blade with a manhack to get this. Slower but has more health, does more damage, and has less of a knockback when hitting something. Resupply Boxes now award the owner a point for every 2 people who use their box instead of every single person (so half as many points). Fixed Fast Zombie Legs spawning much more abundantly than intended. Fixed Flesh Creepers not being able to jump over obstacles due to their insanely low jump height. Fixed zombies taking themselves in to account when calculating horde damage resistance (bosses always had full resistance because of this). Fixed allowing people to use worth menu after redeeming.
2014-11-07 13:03:40 +08:00
GM.DeathFog = 0
GM.FogStart = 0
GM.FogEnd = 8000
GM.FogRed = 30
GM.FogGreen = 30
GM.FogBlue = 30
2014-10-02 08:49:54 +08:00
function GM:ClickedPlayerButton(pl, button)
end
function GM:ClickedEndBoardPlayerButton(pl, button)
end
function GM:CenterNotify(...)
if self.CenterNotificationHUD and self.CenterNotificationHUD:IsValid() then
2014-10-02 08:49:54 +08:00
return self.CenterNotificationHUD:AddNotification(...)
end
end
function GM:TopNotify(...)
if self.TopNotificationHUD and self.TopNotificationHUD:IsValid() then
2014-10-02 08:49:54 +08:00
return self.TopNotificationHUD:AddNotification(...)
end
end
function GM:_InputMouseApply(cmd, x, y, ang)
if MySelf:KeyDown(IN_WALK) and MySelf:IsHolding() then
self.InputMouseX = math.NormalizeAngle(self.InputMouseX - x * 0.02 * GAMEMODE.PropRotationSensitivity)
self.InputMouseY = math.NormalizeAngle(self.InputMouseY - y * 0.02 * GAMEMODE.PropRotationSensitivity)
local snap = GAMEMODE.PropRotationSnap
local snapanglex, snapangley = self.InputMouseX, self.InputMouseY
if snap > 0 then
snapanglex = Angle(self.InputMouseX, 0, 0):SnapTo("p", snap).p
snapangley = Angle(self.InputMouseY, 0, 0):SnapTo("p", snap).p
end
RunConsoleCommand("_zs_rotateang", snapanglex, snapangley)
2014-10-02 08:49:54 +08:00
return true
end
if self:UseOverTheShoulder() and P_Team(MySelf) == TEAM_HUMAN then
self:InputMouseApplyOTS(cmd, x, y, ang)
end
2014-10-02 08:49:54 +08:00
end
function GM:_GUIMousePressed(mc)
end
function GM:TryHumanPickup(pl, entity)
end
function GM:AddExtraOptions(list, window)
end
function GM:SpawnMenuEnabled()
return false
end
function GM:SpawnMenuOpen()
return false
end
function GM:ContextMenuOpen()
return false
end
function GM:_HUDWeaponPickedUp(wep)
if P_Team(MySelf) == TEAM_HUMAN and not wep.NoPickupNotification then
2014-10-02 08:49:54 +08:00
self:Rewarded(wep:GetClass())
end
end
function GM:HUDItemPickedUp(itemname)
end
function GM:HUDAmmoPickedUp(itemname, amount)
end
function GM:InitPostEntity()
self:CreateLateVGUI()
self:AssignItemProperties()
self:FixWeaponBase()
2014-10-02 08:49:54 +08:00
self:LocalPlayerFound()
gamemode.Call("EvaluateFilmMode")
2014-10-02 08:49:54 +08:00
timer.Simple(2, function() GAMEMODE:GetFogData() end)
RunConsoleCommand("pp_bloom", "0")
2014-10-02 08:49:54 +08:00
end
local fogstart = 0
local fogend = 0
local fogr = 0
local fogg = 0
local fogb = 0
2014-10-02 08:49:54 +08:00
function GM:SetupFog()
2014-10-02 08:49:54 +08:00
local power = self.DeathFog
local rpower = 1 - self.DeathFog
fogstart = self.FogStart * rpower
fogend = self.FogEnd * rpower + 150 * power
fogr = self.FogRed * rpower
fogg = self.FogGreen * rpower + 40 * power
fogb = self.FogBlue * rpower
local dimvision = MySelf.DimVision
if dimvision and dimvision:IsValid() then
power = dimvision:GetDim()
fogstart = Lerp(power, fogstart, 1)
fogend = Lerp(power, fogend, math.min(148 / math.max(0.01, MySelf.DimVisionEffMul), fogend))
fogr = Lerp(power, fogr, 0)
fogg = Lerp(power, fogg, 0)
fogb = Lerp(power, fogb, 0)
end
end
function GM:_SetupWorldFog()
if self.DeathFog == 0 and not MySelf.DimVision then return end
self:SetupFog()
2014-10-02 08:49:54 +08:00
render_FogMode(1)
2014-10-02 08:49:54 +08:00
render_FogStart(fogstart)
render_FogEnd(fogend)
render_FogColor(fogr, fogg, fogb)
render_FogMaxDensity(1)
2014-10-02 08:49:54 +08:00
return true
end
function GM:_SetupSkyboxFog(skyboxscale)
if self.DeathFog == 0 and not MySelf.DimVision then return end
2014-10-02 08:49:54 +08:00
self:SetupFog()
2014-10-02 08:49:54 +08:00
render_FogMode(1)
2014-10-02 08:49:54 +08:00
render_FogStart(fogstart * skyboxscale)
render_FogEnd(fogend * skyboxscale)
render_FogColor(fogr, fogg, fogb)
render_FogMaxDensity(1)
2014-10-02 08:49:54 +08:00
return true
end
function GM:PreDrawSkyBox()
self.DrawingInSky = true
end
local matSky = CreateMaterial("SkyOverride", "UnlitGeneric", {["$basetexture"] = "color/white", ["$vertexcolor"] = 1, ["$vertexalpha"] = 1, ["$model"] = 1})
local colSky = Color(0, 30, 0)
function GM:PostDrawSkyBox()
self.DrawingInSky = false
local dimvision = MySelf.DimVision
dimvision = dimvision and dimvision:IsValid() and dimvision:GetDim()
if self.DeathFog > 0 or dimvision then
colSky.a = math.max(self.DeathFog, dimvision or 0) * 230
colSky.g = self.DeathFog * 30
2014-10-02 08:49:54 +08:00
cam_Start3D(EyePos(), EyeAngles())
render_SuppressEngineLighting(true)
2014-10-02 08:49:54 +08:00
render_SetMaterial(matSky)
2014-10-02 08:49:54 +08:00
render_DrawQuadEasy(Vector(0, 0, 10240), Vector(0, 0, -1), 20480, 20480, colSky, 0)
render_DrawQuadEasy(Vector(0, 10240, 0), Vector(0, -1, 0), 20480, 20480, colSky, 0)
render_DrawQuadEasy(Vector(0, -10240, 0), Vector(0, 1, 0), 20480, 20480, colSky, 0)
render_DrawQuadEasy(Vector(10240, 0, 0), Vector(-1, 0, 0), 20480, 20480, colSky, 0)
render_DrawQuadEasy(Vector(-10240, 0, 0), Vector(1, 0, 0), 20480, 20480, colSky, 0)
2014-10-02 08:49:54 +08:00
render_SuppressEngineLighting(false)
cam_End3D()
end
2014-10-02 08:49:54 +08:00
end
function GM:GetFogData()
local _fogstart, _fogend = render_GetFogDistances()
local _fogr, _fogg, _fogb = render_GetFogColor()
self.FogStart = _fogstart
self.FogEnd = _fogend
self.FogRed = _fogr
self.FogGreen = _fogg
self.FogBlue = _fogb
end
2014-10-02 08:49:54 +08:00
function GM:ShouldDraw3DWeaponHUD()
return GAMEMODE.WeaponHUDMode ~= 1
end
function GM:ShouldDraw2DWeaponHUD()
return GAMEMODE.WeaponHUDMode >= 1 or self:UseOverTheShoulder()
2014-10-02 08:49:54 +08:00
end
local matAura = Material("models/debug/debugwhite")
local skip = false
function GM.PostPlayerDrawMedical(pl)
if not skip and P_Team(pl) == TEAM_HUMAN and pl ~= MySelf then
2014-10-02 08:49:54 +08:00
local eyepos = EyePos()
local dist = pl:NearestPoint(eyepos):DistToSqr(eyepos)
2014-10-02 08:49:54 +08:00
if dist < MedicalAuraDistance then
local green = pl:Health() / pl:GetMaxHealth()
pl.SkipDrawHooks = true
skip = true
render_SuppressEngineLighting(true)
render_ModelMaterialOverride(matAura)
render_SetBlend((1 - dist / MedicalAuraDistance) * 0.1 * (1 + math.abs(math.sin((CurTime() + pl:EntIndex()) * 4)) * 0.05))
render_SetColorModulation(1 - green, green, pl:GetDTBool(DT_PLAYER_BOOL_FRAIL) and 1 or 0)
2014-10-02 08:49:54 +08:00
pl:DrawModel()
render_SetColorModulation(1, 1, 1)
render_SetBlend(1)
render_ModelMaterialOverride()
render_SuppressEngineLighting(false)
2014-10-02 08:49:54 +08:00
skip = false
pl.SkipDrawHooks = false
end
end
end
function GM:OnReloaded()
self.BaseClass.OnReloaded(self)
self:LocalPlayerFound()
end
-- The whole point of this is so we don't need to check if the local player is valid 1000 times a second.
-- Empty functions get filled when the local player is found.
function GM:Think() end
GM.HUDWeaponPickedUp = GM.Think
GM.Think = GM._Think
GM.HUDShouldDraw = GM.Think
GM.CachedFearPower = GM.Think
GM.CalcView = GM.Think
GM.ShouldDrawLocalPlayer = GM.Think
GM.PostDrawOpaqueRenderables = GM.Think
GM.PostDrawTranslucentRenderables = GM.Think
GM.HUDPaint = GM.Think
GM.HUDPaintBackground = GM.Think
GM.CreateMove = GM.Think
GM.PrePlayerDraw = GM.Think
GM.PostPlayerDraw = GM.Think
GM.InputMouseApply = GM.Think
GM.GUIMousePressed = GM.Think
GM.HUDWeaponPickedUp = GM.Think
2014-10-02 08:49:54 +08:00
function GM:LocalPlayerFound()
self.Think = self._Think
self.HUDShouldDraw = self._HUDShouldDraw
self.CachedFearPower = self._CachedFearPower
self.CalcView = self._CalcView
self.ShouldDrawLocalPlayer = self._ShouldDrawLocalPlayer
self.PostDrawTranslucentRenderables = self._PostDrawTranslucentRenderables
self.HUDPaint = self._HUDPaint
self.HUDPaintBackground = self._HUDPaintBackground
self.CreateMove = self._CreateMove
self.PrePlayerDraw = self._PrePlayerDraw
self.PostPlayerDraw = self._PostPlayerDraw
self.InputMouseApply = self._InputMouseApply
self.GUIMousePressed = self._GUIMousePressed
self.HUDWeaponPickedUp = self._HUDWeaponPickedUp
self.RenderScene = self._RenderScene
self.SetupSkyboxFog = self._SetupSkyboxFog
self.SetupWorldFog = self._SetupWorldFog
2014-10-02 08:49:54 +08:00
LocalPlayer().LegDamage = 0
LocalPlayer().ArmDamage = 0
2014-10-02 08:49:54 +08:00
if render.GetDXLevel() >= 80 then
self.RenderScreenspaceEffects = self._RenderScreenspaceEffects
end
end
local LastSigilCorrupted = -math.huge
local LastSigilUncorrupted = -math.huge
local function DrawEyeFlash(x, y, size, islast)
local curtime = CurTime()
local bsize = size * (1 + curtime * 2 % 1)
surface_SetDrawColor(220, 0, 0, 240)
surface_DrawTexturedRectRotated(x, y, bsize, bsize, 0)
if islast then
local dt = (curtime - LastSigilCorrupted) / 3
if dt < 1 then
local idt = 1 - dt
surface_SetDrawColor(idt ^ 0.5 * 255, 0, 0, 255)
surface_DrawTexturedRectRotated(x, y, size * dt * 150, size, dt * 10)
surface_DrawTexturedRectRotated(x, y, size, size * dt * 150, dt * 10)
else
dt = (curtime - LastSigilUncorrupted) / 3
if dt < 1 then
local idt = 1 - dt
surface_SetDrawColor(0, dt ^ 0.5 * 255, 0, 255)
surface_DrawTexturedRectRotated(x, y, size * idt * 150, size, idt * 10)
surface_DrawTexturedRectRotated(x, y, size, size * idt * 150, idt * 10)
end
end
end
end
2014-10-02 08:49:54 +08:00
local currentpower = 0
local spawngreen = 0
local matFearMeter = Material("zombiesurvival/fearometer")
local matNeedle = Material("zombiesurvival/fearometerneedle")
local matEyeGlow = Material("Sprites/light_glow02_add_noz")
local matSigil = Material("zombiesurvival/sigil.png")
local matArsenal = Material("zombiesurvival/arsenalcrate.png")
local matResupply = Material("zombiesurvival/resupply.png")
local matRemantler = Material("zombiesurvival/remantler.png")
local matCrossout = Material("zombiesurvival/crossout.png")
local matNest = Material("zombiesurvival/nest.png")
--local matGradientRight = Material("vgui/gradient-r")
--local matGradientLeft = CreateMaterial("gradient-l", "UnlitGeneric", {["$basetexture"] = "vgui/gradient-l", ["$vertexalpha"] = "1", ["$vertexcolor"] = "1", ["$ignorez"] = "1", ["$nomip"] = "1"})
2014-10-02 08:49:54 +08:00
function GM:DrawFearMeter(power, screenscale)
if currentpower < power then
currentpower = math.min(power, currentpower + FrameTime() * (math.tan(currentpower) * 2 + 0.05))
elseif power < currentpower then
currentpower = math.max(power, currentpower - FrameTime() * (math.tan(currentpower) * 2 + 0.05))
end
local w, h = ScrW(), ScrH()
local size = 192 * screenscale
local half_size = size / 2
local mx, my = w / 2 - half_size, h - size
2014-10-02 08:49:54 +08:00
surface_SetMaterial(matFearMeter)
surface_SetDrawColor(140, 140, 140, 240)
surface_DrawTexturedRect(mx, my, size, size)
2014-10-02 08:49:54 +08:00
if currentpower >= 0.75 then
local pulse = CurTime() % 3 - 1
if pulse > 0 then
pulse = pulse ^ 2
local pulsesize = pulse * screenscale * 28
surface_SetDrawColor(140, 140, 140, 120 - pulse * 120)
surface_DrawTexturedRect(mx - pulsesize, my - pulsesize, size + pulsesize * 2, size + pulsesize * 2)
2014-10-02 08:49:54 +08:00
end
end
surface_SetMaterial(matNeedle)
surface_SetDrawColor(160, 160, 160, 225)
local rot = math.Clamp((0.5 - currentpower) + math.sin(RealTime() * 10) * 0.01, -0.5, 0.5) * 300
surface_DrawTexturedRectRotated(w * 0.5 - math.max(0, rot * size * -0.0001), h - half_size - math.abs(rot) * size * 0.00015, size, size, rot)
2014-10-02 08:49:54 +08:00
if P_Team(MySelf) == TEAM_UNDEAD then
2014-10-02 08:49:54 +08:00
if self:GetDynamicSpawning() and self:ShouldUseAlternateDynamicSpawn() then
local obs = MySelf:GetObserverTarget()
spawngreen = math.Approach(spawngreen, self:DynamicSpawnIsValid(obs and obs:IsValid() and obs:IsPlayer() and obs:Team() == TEAM_UNDEAD and obs or MySelf) and 1 or 0, FrameTime() * 4)
local sy = my + size * 0.6953
local gsize = size * 0.085
2014-10-02 08:49:54 +08:00
surface_SetMaterial(matEyeGlow)
surface_SetDrawColor(220 * (1 - spawngreen), 220 * spawngreen, 0, 240)
surface_DrawTexturedRectRotated(mx + size * 0.459, sy, gsize, gsize, 0)
surface_DrawTexturedRectRotated(mx + size * 0.525, sy, gsize, gsize, 0)
2014-10-02 08:49:54 +08:00
end
if currentpower > 0 and not self.ZombieEscape then
draw_SimpleTextBlurry(translate.Format("resist_x", math.ceil(self:GetDamageResistance(currentpower) * 100)), "ZSDamageResistance", w * 0.5, my + size * 0.75, Color(currentpower * 200, 200 - currentpower * 200, 0, 255), TEXT_ALIGN_CENTER)
end
end
if self:GetUseSigils() and self.MaxSigils > 0 then
local sigwid, sighei = screenscale * 18, screenscale * 36
local extrude = size * 0.25 + sighei / 2
local angle_current = -180
local angle_step = 180 / (self.MaxSigils - 1)
local rad, sigil, health, maxhealth, corrupt, damageflash, sigx, sigy, healthfrac
local sigils = GAMEMODE.CachedSigils
local corruptsigils = 0
for i=1, self.MaxSigils do
sigil = sigils[i]
health = 0
maxhealth = 0
corrupt = false
if sigil and sigil:IsValid() then
health = sigil:GetSigilHealth()
maxhealth = sigil:GetSigilMaxHealth()
corrupt = sigil:GetSigilCorrupted()
corruptsigils = corruptsigils + (corrupt and 1 or 0)
end
if health >= 0 then
rad = math.rad(angle_current)
sigx = mx + half_size + math.cos(rad) * extrude
sigy = my + half_size + math.sin(rad) * extrude
if sigil and sigil:IsValid() then
damageflash = math.min((CurTime() - sigil:GetSigilLastDamaged()) * 2, 1) * 255
else
damageflash = 255
end
healthfrac = health / maxhealth
if corrupt then
surface_SetDrawColor((255 - damageflash) * healthfrac, damageflash * healthfrac, 0, 220)
else
surface_SetDrawColor((255 - damageflash) * healthfrac, damageflash * healthfrac, 220, 220)
end
surface_SetMaterial(matSigil)
surface_DrawTexturedRectRotated(sigx, sigy, sigwid, sighei, angle_current + 90)
if corrupt then
surface_SetMaterial(matCrossout)
surface_SetDrawColor(220, 0, 0, 220)
surface_DrawTexturedRect(sigx - sigwid / 2, sigy - sighei / 2, sigwid, sighei)
end
angle_current = angle_current + angle_step
end
end
local des = corruptsigils / self.MaxSigils --self:GetSigilsDestroyed() / self.MaxSigils
if des >= 0.3333 then
surface_SetMaterial(matEyeGlow)
local eye_size = size * 0.125
local sy = my + size * 0.6953
if des >= 0.6666 then
DrawEyeFlash(mx + size * 0.459, sy, eye_size)
DrawEyeFlash(mx + size * 0.525, sy, eye_size, true)
else
DrawEyeFlash(mx + size * 0.459, sy, eye_size, true)
end
2014-10-02 08:49:54 +08:00
end
end
end
function GM:GetDynamicSpawning()
return not GetGlobalBool("DynamicSpawningDisabled", false)
end
function GM:TrackLastDeath()
if MySelf:Alive() then
self.LastTimeAlive = CurTime()
else
self.LastTimeDead = CurTime()
end
end
function GM:IsClassicMode()
return GetGlobalBool("classicmode", false)
end
function GM:IsBabyMode()
return GetGlobalBool("babymode", false)
end
function GM:PostRender()
end
local lastwarntim = -1
--local NextGas = 0
2014-10-02 08:49:54 +08:00
function GM:_Think()
local time = CurTime()
2014-10-02 08:49:54 +08:00
if self:GetEscapeStage() == ESCAPESTAGE_DEATH then
self.DeathFog = math.min(self.DeathFog + FrameTime() / 5, 1)
--[[if time >= NextGas then
NextGas = time + 0.01
2014-10-02 08:49:54 +08:00
local randdir, emitpos, particle
2014-10-02 08:49:54 +08:00
local eyepos = EyePos()
local emitter = ParticleEmitter(eyepos)
for i=1, 3 do
randdir = VectorRand()
2014-10-02 08:49:54 +08:00
randdir.z = math.abs(randdir.z)
randdir:Normalize()
emitpos = eyepos + randdir * math.Rand(0, 1200)
2014-10-02 08:49:54 +08:00
particle = emitter:Add("particles/smokey", emitpos)
2014-10-02 08:49:54 +08:00
particle:SetVelocity(randdir * math.Rand(8, 256))
particle:SetAirResistance(16)
particle:SetDieTime(math.Rand(2.2, 3.5))
particle:SetStartAlpha(math.Rand(70, 90))
particle:SetEndAlpha(0)
particle:SetStartSize(1)
particle:SetEndSize(math.Rand(150, 325))
particle:SetRoll(math.Rand(0, 360))
particle:SetRollDelta(math.Rand(-1, 1))
particle:SetColor(0, math.Rand(20, 45), 0)
end
emitter:Finish() emitter = nil collectgarbage("step", 64)
end]]
2014-10-02 08:49:54 +08:00
elseif self.DeathFog > 0 then
self.DeathFog = math.max(self.DeathFog - FrameTime() / 5, 0)
end
local health = MySelf:Health()
if self.PrevHealth and health < self.PrevHealth then
self.HurtEffect = math.min(self.HurtEffect + (self.PrevHealth - health) * 0.02, 1.5)
elseif self.HurtEffect > 0 then
self.HurtEffect = math.max(0, self.HurtEffect - FrameTime() * 0.65)
end
self.PrevHealth = health
self:TrackLastDeath()
local endtime = self:GetWaveActive() and self:GetWaveEnd() or self:GetWaveStart()
if endtime ~= -1 then
local timleft = math.max(0, endtime - time)
2014-10-02 08:49:54 +08:00
if timleft <= 10 and lastwarntim ~= math.ceil(timleft) then
lastwarntim = math.ceil(timleft)
if 0 < lastwarntim then
LocalPlayer():EmitSound("buttons/lightswitch2.wav", 100, 110 - lastwarntim * 2)
2014-10-02 08:49:54 +08:00
end
end
end
local myteam = P_Team(MySelf)
2014-10-02 08:49:54 +08:00
self:PlayBeats(myteam, self:CachedFearPower())
local thirdperson
2014-10-02 08:49:54 +08:00
if myteam == TEAM_HUMAN then
local wep = MySelf:GetActiveWeapon()
if wep:IsValid() and wep.GetIronsights and wep:GetIronsights() then
self.FOVLerp = math.Approach(self.FOVLerp, wep.IsScoped and not self.DisableScopes and wep.IronsightsMultiplier or not wep.IsScoped and wep.IronsightsMultiplier or 0.6, FrameTime() * 4)
2014-10-02 08:49:54 +08:00
elseif self.FOVLerp ~= 1 then
self.FOVLerp = math.Approach(self.FOVLerp, 1, FrameTime() * 5)
end
if MySelf:GetBarricadeGhosting() then
MySelf:BarricadeGhostingThink()
end
thirdperson = self.OverTheShoulder
2014-10-02 08:49:54 +08:00
else
self.HeartBeatTime = self.HeartBeatTime + (6 + self:CachedFearPower() * 5) * FrameTime()
thirdperson = self.ZombieThirdPerson
2014-10-02 08:49:54 +08:00
--[[if not MySelf:Alive() then
2014-10-02 08:49:54 +08:00
self:ToggleZombieVision(false)
end]]
2014-10-02 08:49:54 +08:00
end
self.TransparencyRadius = thirdperson and self.TransparencyRadius3p or self.TransparencyRadius1p
local tab
2014-10-02 08:49:54 +08:00
for _, pl in pairs(player.GetAll()) do
if P_Team(pl) == TEAM_UNDEAD then
tab = pl:GetZombieClassTable()
2014-10-02 08:49:54 +08:00
if tab.BuildBonePositions then
if not pl.WasBuildingBonePositions then
pl.BuildingBones = pl:GetBoneCount() - 1
pl.WasBuildingBonePositions = true
end
2014-10-02 08:49:54 +08:00
pl:ResetBones()
tab.BuildBonePositions(tab, pl)
elseif pl.WasBuildingBonePositions then
pl.WasBuildingBonePositions = nil
pl:ResetBones()
end
elseif pl.WasBuildingBonePositions then
pl.WasBuildingBonePositions = nil
pl:ResetBones()
end
end
end
function GM:ShouldPlayBeats(teamid, fear)
return not self.RoundEnded and not self.ZombieEscape and not GetGlobalBool("beatsdisabled", false)
end
local cv_ShouldPlayMusic = CreateClientConVar("zs_playmusic", 1, true, false)
local NextBeat = 0
local LastBeatLevel = 0
function GM:PlayBeats(teamid, fear)
if RealTime() <= NextBeat or not gamemode.Call("ShouldPlayBeats", teamid, fear) then return end
--if (LASTHUMAN or self:GetAllSigilsDestroyed()) and cv_ShouldPlayMusic:GetBool() then
2014-10-02 08:49:54 +08:00
if LASTHUMAN and cv_ShouldPlayMusic:GetBool() then
MySelf:EmitSound(self.LastHumanSound, 0, 100, self.BeatsVolume)
NextBeat = RealTime() + SoundDuration(self.LastHumanSound) - 0.025
2014-10-02 08:49:54 +08:00
return
end
if fear <= 0 or not self.BeatsEnabled then return end
local beats = self.Beats[teamid == TEAM_HUMAN and self.BeatSetHuman or self.BeatSetZombie]
if not beats then return end
LastBeatLevel = math.Approach(LastBeatLevel, math.ceil(fear * 10), 3)
local snd = beats[LastBeatLevel]
if snd then
MySelf:EmitSound(snd, 0, 100, self.BeatsVolume)
NextBeat = RealTime() + (self.SoundDuration[snd] or SoundDuration(snd)) - 0.025
end
end
local colPackUp = Color(20, 255, 20, 220)
local colPackUpNotOwner = Color(255, 240, 10, 220)
function GM:DrawPackUpBar(x, y, fraction, notowner, screenscale)
local col = notowner and colPackUpNotOwner or colPackUp
local maxbarwidth = 270 * screenscale
local barheight = 11 * screenscale
local barwidth = maxbarwidth * math.Clamp(fraction, 0, 1)
local startx = x - maxbarwidth * 0.5
surface_SetDrawColor(0, 0, 0, 220)
surface_DrawRect(startx, y, maxbarwidth, barheight)
surface_SetDrawColor(col)
surface_DrawRect(startx + 3, y + 3, barwidth - 6, barheight - 6)
surface_DrawOutlinedRect(startx, y, maxbarwidth, barheight)
draw_SimpleText(notowner and CurTime() % 2 < 1 and translate.Format("requires_x_people", 4) or notowner and translate.Get("packing_others_object") or translate.Get("packing"), "ZSHUDFontSmall", x, y - draw_GetFontHeight("ZSHUDFontSmall") - 2, col, TEXT_ALIGN_CENTER)
end
local colSigilTeleport = Color(125, 215, 255, 220)
function GM:DrawSigilTeleportBar(x, y, fraction, target, screenscale)
local maxbarwidth = 270 * screenscale
local barheight = 11 * screenscale
local barwidth = maxbarwidth * math.Clamp(fraction, 0, 1)
local startx = x - maxbarwidth * 0.5
local letter = "?"
for i, sigil in pairs(ents.FindByClass("prop_obj_sigil")) do
if target == sigil then
letter = string.char(64 + i)
break
end
end
surface_SetDrawColor(0, 0, 0, 220)
surface_DrawRect(startx, y, maxbarwidth, barheight)
surface_SetDrawColor(colSigilTeleport)
surface_DrawRect(startx + 3, y + 3, barwidth - 6, barheight - 6)
surface_DrawOutlinedRect(startx, y, maxbarwidth, barheight)
draw_SimpleText(translate.Format("teleporting_to_sigil", letter), "ZSHUDFontSmall", x, y - draw_GetFontHeight("ZSHUDFontSmall") - 2, colSigilTeleport, TEXT_ALIGN_CENTER)
draw_SimpleText(translate.Get("press_shift_to_cancel"), "ZSHUDFontSmaller", x, y + draw_GetFontHeight("ZSHUDFontSmaller") - 16, colSigilTeleport, TEXT_ALIGN_CENTER)
draw_SimpleText(translate.Get("point_at_a_sigil_to_choose_destination"), "ZSHUDFontSmaller", x, y + draw_GetFontHeight("ZSHUDFontSmaller") * 2 - 16, colSigilTeleport, TEXT_ALIGN_CENTER)
end
2014-10-02 08:49:54 +08:00
function GM:HumanHUD(screenscale)
local curtime = CurTime()
local w, h = ScrW(), ScrH()
local packup = MySelf.PackUp
local sigiltp = MySelf.SigilTeleport
2014-10-02 08:49:54 +08:00
if packup and packup:IsValid() then
self:DrawPackUpBar(w * 0.5, h * 0.55, 1 - packup:GetTimeRemaining() / packup:GetMaxTime(), packup:GetNotOwner(), screenscale)
elseif sigiltp and sigiltp:IsValid() then
self:DrawSigilTeleportBar(w * 0.5, h * 0.55, 1 - sigiltp:GetTimeRemaining() / sigiltp:GetMaxTime(), sigiltp:GetTargetSigil(), screenscale)
2014-10-02 08:49:54 +08:00
end
if not self.RoundEnded then
if self:GetWave() == 0 and not self:GetWaveActive() then
local txth = draw_GetFontHeight("ZSHUDFontSmall")
local desiredzombies = self:GetDesiredStartingZombies()
draw_SimpleTextBlurry(translate.Get("waiting_for_players").." "..util.ToMinutesSecondsCD(math.max(0, self:GetWaveStart() - curtime)), "ZSHUDFontSmall", w * 0.5, h * 0.25, COLOR_GRAY, TEXT_ALIGN_CENTER)
2014-10-02 08:49:54 +08:00
if desiredzombies > 0 then
draw_SimpleTextBlurry(translate.Get(self:HasSigils() and "humans_furthest_from_sigils_are_zombies" or "humans_closest_to_spawns_are_zombies"), "ZSHUDFontSmall", w * 0.5, h * 0.25 + txth, COLOR_GRAY, TEXT_ALIGN_CENTER)
draw_SimpleTextBlurry(translate.Format("number_of_initial_zombies_this_game", self.WaveOneZombies * 100, desiredzombies), "ZSHUDFontSmall", w * 0.5, h * 0.7, COLOR_GRAY, TEXT_ALIGN_CENTER)
2014-10-02 08:49:54 +08:00
for i, pl in ipairs(self.ZombieVolunteers) do
if pl:IsValid() then
draw_SimpleTextBlurry(translate.Get("zombie_volunteers"), "ZSHUDFontSmall", w * 0.5, h * 0.7 + txth, COLOR_GRAY, TEXT_ALIGN_CENTER)
break
end
end
local y = h * 0.7 + txth * 1.9
txth = draw_GetFontHeight("ZSHUDFontTiny")
for i, pl in ipairs(self.ZombieVolunteers) do
if pl:IsValid() then
draw_SimpleTextBlurry(pl:Name(), "ZSHUDFontTiny", w * 0.5, y, pl == MySelf and COLOR_SOFTRED or COLOR_GRAY, TEXT_ALIGN_CENTER)
y = y + txth * 0.8
end
2014-10-02 08:49:54 +08:00
end
end
end
local drown = MySelf.status_drown
if drown and drown:IsValid() then
surface_SetDrawColor(0, 0, 0, 60)
surface_DrawRect(w * 0.4, h * 0.35, w * 0.2, 12)
surface_SetDrawColor(30, 30, 230, 180)
surface_DrawOutlinedRect(w * 0.4, h * 0.35, w * 0.2, 12)
surface_DrawRect(w * 0.4, h * 0.35, w * 0.2 * (1 - drown:GetDrown()), 12)
draw_SimpleTextBlurry(translate.Get("breath").." ", "ZSHUDFontSmall", w * 0.4, h * 0.35 + 6, COLOR_LBLUE, TEXT_ALIGN_RIGHT, TEXT_ALIGN_CENTER)
2014-10-02 08:49:54 +08:00
end
end
local lockon = self.HumanMenuLockOn
if lockon and self:ValidMenuLockOnTarget(MySelf, lockon) then
local txth = draw_GetFontHeight("ZSHUDFontSmall")
draw_SimpleTextBlurry(translate.Format("giving_items_to", lockon:Name()), "ZSHUDFontSmall", w * 0.5, h * 0.55 + txth, COLOR_GRAY, TEXT_ALIGN_CENTER)
2014-10-02 08:49:54 +08:00
end
if gamemode.Call("PlayerCanPurchase", MySelf) then
draw_SimpleTextBlurry(translate.Get("press_f2_for_the_points_shop"), "ZSHUDFontSmall", w * 0.5, screenscale * 135, COLOR_GRAY, TEXT_ALIGN_CENTER)
end
2014-10-02 08:49:54 +08:00
end
function GM:_HUDPaint()
if self.FilmMode then return end
local screenscale = BetterScreenScale()
local myteam = P_Team(MySelf)
2014-10-02 08:49:54 +08:00
self:HUDDrawTargetID(myteam, screenscale)
if self:GetWave() > 0 then
self:DrawFearMeter(self:CachedFearPower(), screenscale)
end
if myteam == TEAM_UNDEAD then
self:ZombieHUD()
elseif myteam == TEAM_HUMAN then
2014-10-02 08:49:54 +08:00
self:HumanHUD(screenscale)
end
if GetGlobalBool("classicmode") then
draw_SimpleTextBlurry(translate.Get("classic_mode"), "ZSHUDFontSmaller", 4, ScrH() - 4, COLOR_GRAY, TEXT_ALIGN_LEFT, TEXT_ALIGN_BOTTOM_REAL)
2014-10-02 08:49:54 +08:00
end
end
function GM:ZombieObserverHUD(obsmode)
local w, h = ScrW(), ScrH()
local texh = draw_GetFontHeight("ZSHUDFontSmall")
if obsmode == OBS_MODE_CHASE then
local target = MySelf:GetObserverTarget()
if target and target:IsValid() then
if target:IsPlayer() and P_Team(target) == TEAM_UNDEAD then
2014-10-02 08:49:54 +08:00
draw_SimpleTextBlur(translate.Format("observing_x", target:Name(), math.max(0, target:Health())), "ZSHUDFontSmall", w * 0.5, h * 0.75 - texh - 32, COLOR_DARKRED, TEXT_ALIGN_CENTER)
end
if target.IsCreeperNest or target.MinionSpawn then
local txt = target.IsCreeperNest and "Nest" or "Gore Child"
draw_SimpleTextBlur(translate.Format("observing_x_simple", txt), "ZSHUDFontSmall", w * 0.5, h * 0.75 - texh - 32, COLOR_DARKRED, TEXT_ALIGN_CENTER)
end
2014-10-02 08:49:54 +08:00
dyn = self:GetDynamicSpawning() and self:DynamicSpawnIsValid(target)
end
end
local space = texh + 2
local x, y = w / 2, h * 0.68
2014-10-02 08:49:54 +08:00
if self:GetWaveActive() then
draw_SimpleTextBlurry(translate.Get("press_lmb_to_spawn"), "ZSHUDFontSmall", x, y, COLOR_GRAY, TEXT_ALIGN_CENTER)
draw_SimpleTextBlurry(translate.Get("press_rmb_to_spawn_close"), "ZSHUDFontSmall", x, y + space, COLOR_GRAY, TEXT_ALIGN_CENTER)
draw_SimpleTextBlurry(translate.Get("press_reload_to_spawn_far"), "ZSHUDFontSmall", x, y + space * 2, COLOR_GRAY, TEXT_ALIGN_CENTER)
draw_SimpleTextBlurry(translate.Get("press_alt_nest_menu"), "ZSHUDFontSmaller", x, y + space * 4, COLOR_GRAY, TEXT_ALIGN_CENTER)
2014-10-02 08:49:54 +08:00
end
draw_SimpleTextBlurry(translate.Get("press_jump_to_free_roam"), "ZSHUDFontSmall", x, y + space * 3, COLOR_GRAY, TEXT_ALIGN_CENTER)
2014-10-02 08:49:54 +08:00
end
local colLifeStats = Color(255, 50, 50, 255)
2014-10-02 08:49:54 +08:00
function GM:ZombieHUD()
if self.LifeStatsEndTime and CurTime() < self.LifeStatsEndTime and (self.LifeStatsBarricadeDamage > 0 or self.LifeStatsHumanDamage > 0 or self.LifeStatsBrainsEaten > 0) then
colLifeStats.a = math.Clamp((self.LifeStatsEndTime - CurTime()) / (self.LifeStatsLifeTime * 0.33), 0, 1) * 255
local th = draw_GetFontHeight("ZSHUDFontSmall")
local x = ScrW() * 0.75
local y = ScrH() * 0.75
draw_SimpleTextBlur(translate.Get("that_life"), "ZSHUDFontSmall", x, y, colLifeStats, TEXT_ALIGN_LEFT)
y = y + th
if self.LifeStatsBarricadeDamage > 0 then
draw_SimpleTextBlur(translate.Format("x_damage_to_barricades", self.LifeStatsBarricadeDamage), "ZSHUDFontSmall", x, y, colLifeStats, TEXT_ALIGN_LEFT)
y = y + th
end
if self.LifeStatsHumanDamage > 0 then
draw_SimpleTextBlur(translate.Format("x_damage_to_humans", self.LifeStatsHumanDamage), "ZSHUDFontSmall", x, y, colLifeStats, TEXT_ALIGN_LEFT)
y = y + th
end
if self.LifeStatsBrainsEaten > 0 then
draw_SimpleTextBlur(translate.Format("x_brains_eaten", self.LifeStatsBrainsEaten), "ZSHUDFontSmall", x, y, colLifeStats, TEXT_ALIGN_LEFT)
y = y + th
end
end
local obsmode = MySelf:GetObserverMode()
if obsmode ~= OBS_MODE_NONE then
self:ZombieObserverHUD(obsmode)
elseif not MySelf:Alive() then
local x = ScrW() * 0.5
local y = ScrH() * 0.3
if not self:GetWaveActive() then
draw_SimpleTextBlur(translate.Get("waiting_for_next_wave"), "ZSHUDFont", x, y, COLOR_DARKRED, TEXT_ALIGN_CENTER)
end
end
if not self:GetWaveActive() and self:GetWave() ~= 0 then
local pl = GAMEMODE.NextBossZombie
if pl and pl:IsValid() then
local x, y = ScrW() / 2, ScrH() * 0.3 + draw_GetFontHeight("ZSHUDFont")
if pl == MySelf then
draw_SimpleTextBlur(translate.Format("you_will_be_x_soon", GAMEMODE.NextBossZombieClass), "ZSHUDFont", x, y, Color(255, 50, 50), TEXT_ALIGN_CENTER)
else
draw_SimpleTextBlur(translate.Format("x_will_be_y_soon", pl:Name(), GAMEMODE.NextBossZombieClass), "ZSHUDFont", x, y, COLOR_GRAY, TEXT_ALIGN_CENTER)
2014-10-02 08:49:54 +08:00
end
end
end
end
function GM:RequestedDefaultCart()
local defaultcart = GetConVar("zs_defaultcart"):GetString()
2014-10-02 08:49:54 +08:00
if #defaultcart > 0 then
defaultcart = string.lower(defaultcart)
for i, carttab in ipairs(self.SavedCarts) do
if carttab[1] and string.lower(carttab[1]) == defaultcart then
gamemode.Call("SuppressArsenalUpgrades", 1)
RunConsoleCommand("worthcheckout", unpack(carttab[2]))
return
end
end
RunConsoleCommand("worthrandom")
end
end
function GM:_PostDrawTranslucentRenderables()
if not self.DrawingInSky then
self:DrawPointWorldHints()
self:DrawWorldHints()
self:DrawSigilIndicators()
self:DrawCrateIndicators()
self:DrawResupplyIndicators()
self:DrawRemantlerIndicators()
self:DrawHumanIndicators()
self:DrawNestIndicators()
end
end
function GM:DrawCrateIndicators()
if P_Team(MySelf) ~= TEAM_HUMAN or not MySelf:IsSkillActive(SKILL_INSIGHT) then return end
local pos, distance, ang, deployable, alpha
local eyepos = EyePos()
surface_SetMaterial(matArsenal)
for i, arsenal in pairs(GAMEMODE.CachedArsenalEntities) do
if not arsenal:IsValid() then continue end
deployable = arsenal.GetObjectOwner
pos = arsenal:GetPos()
pos.z = pos.z + (arsenal:IsPlayer() and 32 or (deployable and 12 or -8))
distance = eyepos:DistToSqr(pos)
if (distance >= 6400 and distance <= 1048576) and (not deployable or not WorldVisible(eyepos, pos)) then -- Limited to Scavenger's Eyes distance.
ang = (eyepos - pos):Angle()
ang:RotateAroundAxis(ang:Right(), 270)
ang:RotateAroundAxis(ang:Up(), 90)
alpha = math.min(220, math.sqrt(distance / 4))
cam_IgnoreZ(true)
cam_Start3D2D(pos, ang, math.max(250, math.sqrt(distance)) / 5000)
surface_SetDrawColor(255, 255, 255, alpha)
surface_DrawTexturedRect(-123, -113, 248, 228)
draw_SimpleTextBlurry("Arsenal Crate", "ZS3D2DFont2Big", 0, 128, COLOR_GRAY, TEXT_ALIGN_CENTER)
cam_End3D2D()
cam_IgnoreZ(false)
end
end
end
function GM:DrawResupplyIndicators()
if P_Team(MySelf) ~= TEAM_HUMAN or not MySelf:IsSkillActive(SKILL_ACUITY) then return end
local pos, distance, ang, deployable, alpha
local eyepos = EyePos()
surface_SetMaterial(matResupply)
for i, resupply in pairs(GAMEMODE.CachedResupplyEntities) do
if not resupply:IsValid() then continue end
deployable = resupply.GetObjectOwner
pos = resupply:GetPos()
pos.z = pos.z + (resupply:IsPlayer() and 32 or (deployable and 12 or -8))
distance = eyepos:DistToSqr(pos)
if (distance >= 6400 and distance <= 1048576) and (not deployable or not WorldVisible(eyepos, pos)) then -- Limited to Scavenger's Eyes distance.
ang = (eyepos - pos):Angle()
ang:RotateAroundAxis(ang:Right(), 270)
ang:RotateAroundAxis(ang:Up(), 90)
alpha = math.min(220, math.sqrt(distance / 4))
cam_IgnoreZ(true)
cam_Start3D2D(pos, ang, math.max(250, math.sqrt(distance)) / 5000)
surface_SetDrawColor(255, 255, 255, alpha)
surface_DrawTexturedRect(-128, -128, 256, 256)
local timeremain = math.ceil(math.max(0, (MySelf.NextUse or 0) - CurTime()))
local txt = not MySelf.NextUse and translate.Get("ready") or timeremain > 0 and timeremain or translate.Get("ready")
draw_SimpleTextBlurry(txt, "ZS3D2DFont2Big", 0, 128, COLOR_GRAY, TEXT_ALIGN_CENTER)
cam_End3D2D()
cam_IgnoreZ(false)
end
end
end
function GM:DrawRemantlerIndicators()
if P_Team(MySelf) ~= TEAM_HUMAN or not MySelf:IsSkillActive(SKILL_VISION) then return end
local pos, distance, ang, deployable, alpha
local eyepos = EyePos()
surface_SetMaterial(matRemantler)
for i, remantler in pairs(GAMEMODE.CachedRemantlerEntities) do
if not remantler:IsValid() then continue end
deployable = remantler.GetObjectOwner
pos = remantler:GetPos()
pos.z = pos.z + (remantler:IsPlayer() and 32 or (deployable and 12 or -8))
distance = eyepos:DistToSqr(pos)
if (distance >= 6400 and distance <= 1048576) and (not deployable or not WorldVisible(eyepos, pos)) then -- Limited to Scavenger's Eyes distance.
ang = (eyepos - pos):Angle()
ang:RotateAroundAxis(ang:Right(), 270)
ang:RotateAroundAxis(ang:Up(), 90)
alpha = math.min(220, math.sqrt(distance / 4))
cam_IgnoreZ(true)
cam_Start3D2D(pos, ang, math.max(250, math.sqrt(distance)) / 5000)
surface_SetDrawColor(255, 255, 255, alpha)
surface_DrawTexturedRect(-128, -128, 256, 256)
draw_SimpleTextBlurry("Weapon Remantler", "ZS3D2DFont2Big", 0, 128, COLOR_GRAY, TEXT_ALIGN_CENTER)
cam_End3D2D()
cam_IgnoreZ(false)
end
end
end
function GM:DrawNestIndicators()
if P_Team(MySelf) ~= TEAM_ZOMBIE then return end
local pos, distance, ang, alpha
local eyepos = EyePos()
surface_SetMaterial(matNest)
for i, nest in pairs(GAMEMODE.CachedNests) do
if not nest:IsValid() then continue end
pos = nest:GetPos()
pos.z = pos.z + 32
distance = eyepos:DistToSqr(pos)
ang = (eyepos - pos):Angle()
ang:RotateAroundAxis(ang:Right(), 270)
ang:RotateAroundAxis(ang:Up(), 90)
alpha = math.min(220, math.sqrt(distance / 4))
cam_IgnoreZ(true)
cam_Start3D2D(pos, ang, math.max(250, math.sqrt(distance)) / 5000)
surface_SetDrawColor(255, 255, 255, alpha)
surface_DrawTexturedRect(-128, -128, 256, 256)
draw_SimpleTextBlurry("Nest", "ZS3D2DFont2Big", 0, 128, COLOR_GRAY, TEXT_ALIGN_CENTER)
if distance < 80000 then
local nown = nest:GetNestOwner()
local ownname = nown:IsValidZombie() and nown:ClippedName() or ""
draw_SimpleTextBlurry(ownname, "ZS3D2DFont2", 0, 256, COLOR_GRAY, TEXT_ALIGN_CENTER)
end
cam_End3D2D()
cam_IgnoreZ(false)
end
end
function GM:DrawSigilIndicators()
if not self:GetUseSigils() then return end
local health, pos, distance, maxhealth, corrupted, damageflash, missinghealthfrac, ang, alpha
local eyepos = EyePos()
surface_SetMaterial(matSigil)
for i, sigil in pairs(GAMEMODE.CachedSigils) do
if not sigil:IsValid() then continue end
health = sigil:GetSigilHealth()
if health > 0 then
pos = sigil:GetPos()
pos.z = pos.z + 48
distance = eyepos:DistToSqr(pos)
maxhealth = sigil:GetSigilMaxHealth()
corrupted = sigil:GetSigilCorrupted()
damageflash = math.min((CurTime() - sigil:GetSigilLastDamaged()) * 2, 1) * 255
missinghealthfrac = 1 - health / maxhealth
alpha = math.min(220, math.sqrt(distance / 4))
ang = (eyepos - pos):Angle()
ang:RotateAroundAxis(ang:Right(), 270)
ang:RotateAroundAxis(ang:Up(), 90)
cam_IgnoreZ(true)
cam_Start3D2D(pos, ang, math.max(250, math.sqrt(distance)) / 5000)
local oldfogmode = render_GetFogMode()
render_FogMode(0)
if corrupted then
surface_SetDrawColor(255 - damageflash, damageflash, 0, alpha)
else
surface_SetDrawColor(damageflash, 255, damageflash, alpha)
end
surface_DrawTexturedRect(-64, -128, 128, 256)
if missinghealthfrac > 0 then
surface_SetDrawColor(40, 40, 40, 255)
surface_DrawTexturedRectUV(-64, -128, 128, 256 * missinghealthfrac, 0, 0, 1, missinghealthfrac)
end
draw_SimpleTextBlurry(string.char(64 + i), "ZS3D2DFont2Big", 0, 128, COLOR_GRAY, TEXT_ALIGN_CENTER)
render_FogMode(oldfogmode)
cam_End3D2D()
cam_IgnoreZ(false)
end
2014-10-02 08:49:54 +08:00
end
end
function GM:RestartRound()
self.TheLastHuman = nil
self.RoundEnded = nil
LASTHUMAN = nil
if pEndBoard and pEndBoard:IsValid() then
2014-10-02 08:49:54 +08:00
pEndBoard:Remove()
pEndBoard = nil
end
self:ClearItemStocks()
2014-10-02 08:49:54 +08:00
self:InitPostEntity()
self:RevertZombieClasses()
end
function GM:_HUDShouldDraw(name)
if self.FilmMode and name ~= "CHudWeaponSelection" then return false end
return name ~= "CHudHealth" and name ~= "CHudBattery"
and name ~= "CHudAmmo" and name ~= "CHudSecondaryAmmo"
and name ~= "CHudDamageIndicator"
end
local Current = 0
local NextCalculate = 0
function GM:_CachedFearPower()
if CurTime() >= NextCalculate then
NextCalculate = CurTime() + 0.15
Current = self:GetFearMeterPower(EyePos(), TEAM_UNDEAD, MySelf)
end
return Current
end
function surface.CreateLegacyFont(font, size, weight, antialias, additive, name, shadow, outline, blursize)
surface.CreateFont(name, {font = font, size = size, weight = weight, antialias = antialias, additive = additive, shadow = shadow, outline = outline, blursize = blursize})
end
local fontfamily = "Ghoulish Fright AOE"
local fontfamilysm = "Remington Noiseless"
local fontfamily3d = "hidden"
local fontsizeadd = 8
local fontweight = 0
function GM:Create3DFonts()
local fontsizeadd3D = 0
2014-10-02 08:49:54 +08:00
local fontweight3D = 0
surface.CreateLegacyFont(fontfamily3d, 28 + fontsizeadd3D, fontweight3D, false, false, "ZS3D2DFontSmaller", false, true)
surface.CreateLegacyFont(fontfamily3d, 48 + fontsizeadd3D, fontweight3D, false, false, "ZS3D2DFontSmall", false, true)
surface.CreateLegacyFont(fontfamily3d, 72 + fontsizeadd3D, fontweight3D, false, false, "ZS3D2DFont", false, true)
surface.CreateLegacyFont(fontfamily3d, 128 + fontsizeadd3D, fontweight3D, false, false, "ZS3D2DFontBig", false, true)
surface.CreateLegacyFont(fontfamily3d, 28 + fontsizeadd3D, fontweight3D, false, false, "ZS3D2DFontSmallerBlur", false, false, 16)
surface.CreateLegacyFont(fontfamily3d, 48 + fontsizeadd3D, fontweight3D, false, false, "ZS3D2DFontSmallBlur", false, false, 16)
surface.CreateLegacyFont(fontfamily3d, 72 + fontsizeadd3D, fontweight3D, false, false, "ZS3D2DFontBlur", false, false, 16)
surface.CreateLegacyFont(fontfamily3d, 128 + fontsizeadd3D, fontweight3D, false, false, "ZS3D2DFontBigBlur", false, false, 16)
surface.CreateLegacyFont(fontfamily, 40 + fontsizeadd3D, fontweight3D, false, false, "ZS3D2DFont2Smaller", false, true)
surface.CreateLegacyFont(fontfamily, 48 + fontsizeadd3D, fontweight3D, false, false, "ZS3D2DFont2Small", false, true)
surface.CreateLegacyFont(fontfamily, 72 + fontsizeadd3D, fontweight3D, false, false, "ZS3D2DFont2", false, true)
surface.CreateLegacyFont(fontfamily, 128 + fontsizeadd3D, fontweight3D, false, false, "ZS3D2DFont2Big", false, true)
surface.CreateLegacyFont(fontfamily, 40 + fontsizeadd3D, fontweight3D, false, false, "ZS3D2DFont2SmallerBlur", false, false, 16)
surface.CreateLegacyFont(fontfamily, 48 + fontsizeadd3D, fontweight3D, false, false, "ZS3D2DFont2SmallBlur", false, false, 16)
surface.CreateLegacyFont(fontfamily, 72 + fontsizeadd3D, fontweight3D, false, false, "ZS3D2DFont2Blur", false, false, 16)
surface.CreateLegacyFont(fontfamily, 128 + fontsizeadd3D, fontweight3D, false, false, "ZS3D2DFont2BigBlur", false, false, 16)
surface.CreateLegacyFont(fontfamilysm, 14 + fontsizeadd3D, fontweight3D, false, false, "ZS3D2DUnstyleTiny", false, true)
surface.CreateLegacyFont(fontfamilysm, 24 + fontsizeadd3D, fontweight3D, false, false, "ZS3D2DUnstyleSmallest", false, true)
surface.CreateLegacyFont(fontfamilysm, 36 + fontsizeadd3D, fontweight3D, false, false, "ZS3D2DUnstyleSmaller", false, true)
end
function GM:CreateNonScaleFonts()
2014-10-02 08:49:54 +08:00
surface.CreateLegacyFont("tahoma", 96, 1000, true, false, "zshintfont", false, true)
-- Default, DefaultBold, DefaultSmall, etc. were changed when gmod13 hit. These are renamed fonts that have the old values.
surface.CreateFont("DefaultFontVerySmall", {font = "tahoma", size = 10, weight = 0, antialias = false})
surface.CreateFont("DefaultFontSmall", {font = "tahoma", size = 11, weight = 0, antialias = false})
surface.CreateFont("DefaultFontSmallDropShadow", {font = "tahoma", size = 11, weight = 0, shadow = true, antialias = false})
surface.CreateFont("DefaultFont", {font = "tahoma", size = 13, weight = 500, antialias = false})
surface.CreateFont("DefaultFontAA", {font = "tahoma", size = 13, weight = 500, antialias = true})
2014-10-02 08:49:54 +08:00
surface.CreateFont("DefaultFontBold", {font = "tahoma", size = 13, weight = 1000, antialias = false})
surface.CreateFont("DefaultFontLarge", {font = "tahoma", size = 16, weight = 0, antialias = false})
surface.CreateFont("DefaultFontLargeAA", {font = "tahoma", size = 16, weight = 0, antialias = true})
surface.CreateFont("DefaultFontLargest", {font = "tahoma", size = 22, weight = 0, antialias = false})
surface.CreateFont("DefaultFontLargestAA", {font = "tahoma", size = 22, weight = 0, antialias = true})
end
function GM:CreateScalingFonts()
local fontaa = true
local fontshadow = false
local fontoutline = true
local screenscale = BetterScreenScale()
surface.CreateLegacyFont("csd", screenscale * 42, 100, true, false, "zsdeathnoticecs", false, false)
surface.CreateLegacyFont("HL2MP", screenscale * 42, 100, true, false, "zsdeathnotice", false, false)
surface.CreateLegacyFont("csd", screenscale * 96, 100, true, false, "zsdeathnoticecsws", false, false)
surface.CreateLegacyFont("HL2MP", screenscale * 96, 100, true, false, "zsdeathnoticews", false, false)
surface.CreateLegacyFont("csd", screenscale * 72, 100, true, false, "zsdeathnoticecspa", false, false)
surface.CreateLegacyFont("HL2MP", screenscale * 72, 100, true, false, "zsdeathnoticepa", false, false)
surface.CreateLegacyFont(fontfamily, screenscale * (16 + fontsizeadd), fontweight, fontaa, false, "ZSHUDFontTiny", fontshadow, fontoutline)
surface.CreateLegacyFont(fontfamily, screenscale * (20 + fontsizeadd), fontweight, fontaa, false, "ZSHUDFontSmallest", fontshadow, fontoutline)
surface.CreateLegacyFont(fontfamily, screenscale * (22 + fontsizeadd), fontweight, fontaa, false, "ZSHUDFontSmaller", fontshadow, fontoutline)
surface.CreateLegacyFont(fontfamily, screenscale * (28 + fontsizeadd), fontweight, fontaa, false, "ZSHUDFontSmall", fontshadow, fontoutline)
surface.CreateLegacyFont(fontfamily, screenscale * (42 + fontsizeadd), fontweight, fontaa, false, "ZSHUDFont", fontshadow, fontoutline)
surface.CreateLegacyFont(fontfamily, screenscale * (72 + fontsizeadd), fontweight, fontaa, false, "ZSHUDFontBig", fontshadow, fontoutline)
surface.CreateLegacyFont(fontfamily, screenscale * (16 + fontsizeadd), fontweight, fontaa, false, "ZSHUDFontTinyBlur", false, false, 8)
surface.CreateLegacyFont(fontfamily, screenscale * (22 + fontsizeadd), fontweight, fontaa, false, "ZSHUDFontSmallerBlur", false, false, 8)
surface.CreateLegacyFont(fontfamily, screenscale * (28 + fontsizeadd), fontweight, fontaa, false, "ZSHUDFontSmallBlur", false, false, 8)
surface.CreateLegacyFont(fontfamily, screenscale * (42 + fontsizeadd), fontweight, fontaa, false, "ZSHUDFontBlur", false, false, 8)
surface.CreateLegacyFont(fontfamily, screenscale * (72 + fontsizeadd), fontweight, fontaa, false, "ZSHUDFontBigBlur", false, false, 8)
surface.CreateLegacyFont(fontfamily, screenscale * (20 + fontsizeadd/2), 0, fontaa, false, "ZSAmmoName", false, false)
local liscreenscale = math.max(0.95, BetterScreenScale())
surface.CreateLegacyFont(fontfamily, liscreenscale * (32 + fontsizeadd), fontweight, true, false, "ZSScoreBoardTitle", false, true)
surface.CreateLegacyFont(fontfamily, liscreenscale * (22 + fontsizeadd), fontweight, true, false, "ZSScoreBoardSubTitle", false, true)
surface.CreateLegacyFont(fontfamily, liscreenscale * (16 + fontsizeadd), fontweight, true, false, "ZSScoreBoardPlayer", false, true)
surface.CreateLegacyFont(fontfamily, liscreenscale * (24 + fontsizeadd), fontweight, true, false, "ZSScoreBoardHeading", false, false)
surface.CreateLegacyFont("arial", 18 * liscreenscale, 0, true, false, "ZSScoreBoardPlayerSmall", false, true)
surface.CreateLegacyFont("arial", 15 * liscreenscale, 0, true, false, "ZSScoreBoardPlayerSmaller", false, true)
surface.CreateLegacyFont("tahoma", 11 * liscreenscale, 0, true, false, "ZSScoreBoardPing")
surface.CreateLegacyFont(fontfamily, screenscale * (16 + fontsizeadd), fontweight, fontaa, false, "ZSHUDFontTinyNS", false, false)
surface.CreateLegacyFont(fontfamily, screenscale * (20 + fontsizeadd), fontweight, fontaa, false, "ZSHUDFontSmallestNS", false, false)
surface.CreateLegacyFont(fontfamily, screenscale * (22 + fontsizeadd), fontweight, fontaa, false, "ZSHUDFontSmallerNS", false, false)
surface.CreateLegacyFont(fontfamily, screenscale * (28 + fontsizeadd), fontweight, fontaa, false, "ZSHUDFontSmallNS", false, false)
surface.CreateLegacyFont(fontfamily, screenscale * (42 + fontsizeadd), fontweight, fontaa, false, "ZSHUDFontNS", false, false)
surface.CreateLegacyFont(fontfamily, screenscale * (72 + fontsizeadd), fontweight, fontaa, false, "ZSHUDFontBigNS", false, false)
surface.CreateLegacyFont(fontfamilysm, screenscale * 13, fontweight, fontaa, false, "ZSBodyTextFontSmall", fontshadow)
surface.CreateLegacyFont(fontfamilysm, screenscale * 15, fontweight, fontaa, false, "ZSBodyTextFont", fontshadow, fontoutline)
surface.CreateLegacyFont(fontfamilysm, screenscale * 20, fontweight, fontaa, false, "ZSBodyTextFontBig", fontshadow, fontoutline)
surface.CreateLegacyFont(fontfamily, screenscale * (20 + fontsizeadd), 0, true, false, "ZSDamageResistance", false, true)
surface.CreateLegacyFont(fontfamily, screenscale * (20 + fontsizeadd), 0, true, false, "ZSDamageResistanceBlur", false, true)
surface.CreateFont("ZSXPBar", {font = "tahoma", size = screenscale * 14, weight = 500, antialias = false, shadow = true})
end
function GM:CreateFonts()
self:Create3DFonts()
self:CreateNonScaleFonts()
self:CreateScalingFonts()
2014-10-02 08:49:54 +08:00
end
function GM:EvaluateFilmMode()
local visible = not self.FilmMode
if self.GameStatePanel and self.GameStatePanel:IsValid() then
2014-10-02 08:49:54 +08:00
self.GameStatePanel:SetVisible(visible)
end
if self.TopNotificationHUD and self.TopNotificationHUD:IsValid() then
2014-10-02 08:49:54 +08:00
self.TopNotificationHUD:SetVisible(visible)
end
if self.CenterNotificationHUD and self.CenterNotificationHUD:IsValid() then
2014-10-02 08:49:54 +08:00
self.CenterNotificationHUD:SetVisible(visible)
end
if self.XPHUD and self.XPHUD:IsValid() then
self.XPHUD:SetVisible(visible and self.DisplayXPHUD)
end
if self.HealthHUD and self.HealthHUD:IsValid() then
2014-10-02 08:49:54 +08:00
self.HealthHUD:SetVisible(visible)
end
if self.StatusHUD and self.StatusHUD:IsValid() then
self.StatusHUD:SetVisible(visible)
end
2014-10-02 08:49:54 +08:00
end
function GM:CreateVGUI()
local screenscale = BetterScreenScale()
self.GameStatePanel = vgui.Create("ZSGameState")
2014-10-02 08:49:54 +08:00
self.GameStatePanel:SetTextFont("ZSHUDFontSmaller")
self.GameStatePanel:SetAlpha(220)
self.GameStatePanel:SetSize(screenscale * 420, screenscale * 80)
self.GameStatePanel:ParentToHUD()
self.TopNotificationHUD = vgui.Create("DEXNotificationsList")
self.TopNotificationHUD:SetAlign(RIGHT)
self.TopNotificationHUD.PerformLayout = function(pan)
pan:SetSize(ScrW() * 0.4, ScrH() * 0.6)
pan:AlignTop(16 * BetterScreenScale())
2014-10-02 08:49:54 +08:00
pan:AlignRight()
end
self.TopNotificationHUD:InvalidateLayout()
self.TopNotificationHUD:ParentToHUD()
self.CenterNotificationHUD = vgui.Create("DEXNotificationsList")
self.CenterNotificationHUD:SetAlign(CENTER)
self.CenterNotificationHUD:SetMessageHeight(36)
self.CenterNotificationHUD.PerformLayout = function(pan)
pan:SetSize(ScrW() / 2, ScrH() * 0.35)
2014-10-02 08:49:54 +08:00
pan:CenterHorizontal()
pan:AlignBottom(16 * BetterScreenScale())
2014-10-02 08:49:54 +08:00
end
self.CenterNotificationHUD:InvalidateLayout()
self.CenterNotificationHUD:ParentToHUD()
end
function GM:CreateLateVGUI()
if not self.HealthHUD then
self.HealthHUD = vgui.Create("ZSHealthArea")
end
if not self.StatusHUD then
self.StatusHUD = vgui.Create("ZSStatusArea")
end
if not self.XPHUD then
self.XPHUD = vgui.Create("ZSExperienceHUD")
self.XPHUD:ParentToHUD()
self.XPHUD:InvalidateLayout()
end
end
2014-10-02 08:49:54 +08:00
function GM:Initialize()
self:FixSkillConnections()
2014-10-02 08:49:54 +08:00
self:CreateFonts()
self:PrecacheResources()
self:CreateVGUI()
self:InitializeBeats()
self:AddCustomAmmo()
self:RegisterFood()
self:CreateWeaponQualities()
self:CreateSpriteMaterials()
-- Not sure if this still crashes, but whatever.
RunConsoleCommand("r_drawmodeldecals", "0")
-- Flashlight dynamic lights of other players.
RunConsoleCommand("r_dynamic", "0")
self:RefreshMapIsObjective()
end
-- These can be accessed without pointing to the IMaterial by using ! before the material string.
function GM:CreateSpriteMaterials()
local params = {["$translucent"] = "1", ["$vertexcolor"] = "1", ["$vertexalpha"] = "1"}
for i=1, 8 do
params["$basetexture"] = "Decals/blood"..i
CreateMaterial("sprite_bloodspray"..i, "UnlitGeneric", params)
end
end
function GM:ShutDown()
RunConsoleCommand("r_drawmodeldecals", "1")
RunConsoleCommand("r_dynamic", "1")
2014-10-02 08:49:54 +08:00
end
local function FirstOfGoodType(a)
local ext
2014-10-02 08:49:54 +08:00
for _, v in pairs(a) do
ext = string.sub(v, -4)
2014-10-02 08:49:54 +08:00
if ext == ".ogg" or ext == ".wav" or ext == ".mp3" then
return v
end
end
end
function GM:InitializeBeats()
local _, dirs = file.Find("sound/zombiesurvival/beats/*", "GAME")
for _, dirname in pairs(dirs) do
if dirname == "none" or dirname == "default" then continue end
self.Beats[dirname] = {}
local highestexist
for i=1, 10 do
local a, __ = file.Find("sound/zombiesurvival/beats/"..dirname.."/"..i..".*", "GAME")
local a1 = FirstOfGoodType(a)
if a1 then
local filename = "zombiesurvival/beats/"..dirname.."/"..a1
if file.Exists("sound/"..filename, "GAME") then
self.Beats[dirname][i] = Sound(filename)
highestexist = filename
continue
end
end
if highestexist then
self.Beats[dirname][i] = highestexist
end
end
end
end
function GM:PlayerDeath(pl, attacker)
end
function GM:ScalePlayerDamage(pl, hitgroup, dmginfo)
end
2014-10-02 08:49:54 +08:00
function GM:LastHuman(pl)
if not IsValid(pl) then pl = nil end
self.TheLastHuman = pl
if not LASTHUMAN then
LASTHUMAN = true
timer.Simple(0.5, function() GAMEMODE:LastHumanMessage() end)
end
end
function GM:LastHumanMessage()
if self.RoundEnded or not MySelf:IsValid() then return end
local icon = self.PantsMode and "weapon_zs_legs" or "default"
if P_Team(MySelf) == TEAM_UNDEAD or not MySelf:Alive() then
2014-10-02 08:49:54 +08:00
self:CenterNotify({killicon = icon}, {font = "ZSHUDFont"}, " ", COLOR_RED, translate.Get(self.PantsMode and "kick_the_last_human" or "kill_the_last_human"), {killicon = icon})
else
self:CenterNotify({font = "ZSHUDFont"}, " ", COLOR_RED, translate.Get("you_are_the_last_human"))
self:CenterNotify({killicon = icon}, " ", COLOR_RED, translate.Format(self.PantsMode and "x_pants_out_to_get_you" or "x_zombies_out_to_get_you", team.NumPlayers(TEAM_UNDEAD)), {killicon = icon})
end
end
function GM:PlayerShouldTakeDamage(pl, attacker)
return pl == attacker or not attacker:IsPlayer() or P_Team(pl) ~= P_Team(attacker) or pl.AllowTeamDamage or attacker.AllowTeamDamage
2014-10-02 08:49:54 +08:00
end
function GM:SetWave(wave)
SetGlobalInt("wave", wave)
end
local matRing = Material("effects/select_ring")
function GM:DrawCircle(x, y, radius, color)
surface.SetMaterial(matRing)
surface.SetDrawColor(color)
surface.DrawTexturedRect(x - radius, y - radius, radius * 2, radius * 2)
end
2014-10-02 08:49:54 +08:00
local matFilmGrain = Material("zombiesurvival/filmgrain/filmgrain")
function GM:_HUDPaintBackground()
if self.FilmGrainEnabled and P_Team(MySelf) ~= TEAM_UNDEAD then
2014-10-02 08:49:54 +08:00
surface_SetMaterial(matFilmGrain)
surface_SetDrawColor(0, 0, 0, (0.25 + 0.75 * self:CachedFearPower()) * self.FilmGrainOpacity)
surface_DrawTexturedRectUV(0, 0, ScrW(), ScrH(), 2, 2, 0, 0)
end
local wep = MySelf:GetActiveWeapon()
if wep:IsValid() and wep.DrawHUDBackground then
wep:DrawHUDBackground()
end
end
local function GiveWeapon()
if GAMEMODE.HumanMenuLockOn then
RunConsoleCommand("zsgiveweapon", GAMEMODE.HumanMenuLockOn:EntIndex(), GAMEMODE.InventoryMenu.SelInv)
end
2014-10-02 08:49:54 +08:00
end
local function GiveWeaponClip()
if GAMEMODE.HumanMenuLockOn then
RunConsoleCommand("zsgiveweaponclip", GAMEMODE.HumanMenuLockOn:EntIndex(), GAMEMODE.InventoryMenu.SelInv)
end
2014-10-02 08:49:54 +08:00
end
local function DropWeapon()
RunConsoleCommand("zsdropweapon", GAMEMODE.InventoryMenu.SelInv)
2014-10-02 08:49:54 +08:00
end
local function EmptyClip()
RunConsoleCommand("zsemptyclip")
end
local function DismantleWeapon()
RunConsoleCommand("zs_dismantle", GAMEMODE.InventoryMenu.SelInv)
end
local function AltSelItemUpd()
local activeweapon = MySelf:GetActiveWeapon()
if not activeweapon or not activeweapon:IsValid() then return end
local actwclass = activeweapon:GetClass()
GAMEMODE.HumanMenuPanel.SelectedItemLabel:SetText(weapons.Get(actwclass).PrintName)
end
function GM:DoAltSelectedItemUpdate()
if self.InventoryMenu.SelInv then
self.HumanMenuPanel.SelectedItemLabel:SetText(self.ZSInventoryItemData[self.InventoryMenu.SelInv].PrintName)
else
timer.Simple(0.25, AltSelItemUpd)
end
end
2014-10-02 08:49:54 +08:00
function GM:HumanMenu()
if self.ZombieEscape then return end
local ent = MySelf:MeleeTrace(48, 2, nil, nil, true).Entity
2014-10-02 08:49:54 +08:00
if self:ValidMenuLockOnTarget(MySelf, ent) then
self.HumanMenuLockOn = ent
else
self.HumanMenuLockOn = nil
end
self:OpenInventory()
if self.HumanMenuPanel and self.HumanMenuPanel:IsValid() then
2014-10-02 08:49:54 +08:00
self.HumanMenuPanel:SetVisible(true)
self.HumanMenuPanel:OpenMenu()
self:DoAltSelectedItemUpdate()
2014-10-02 08:49:54 +08:00
return
end
local panel = vgui.Create("DSideMenu")
self.HumanMenuPanel = panel
local screenscale = BetterScreenScale()
for k, v in pairs(self.AmmoNames) do
local b = vgui.Create("DAmmoCounter", panel)
b:SetAmmoType(k)
b:SetTall(math.max(32, screenscale * 36))
2014-10-02 08:49:54 +08:00
panel:AddItem(b)
end
local hei = draw_GetFontHeight("ZSHUDFontSmall")
local selecteditemtitle = EasyLabel(panel, "Selected Item", "ZSHUDFontSmall", color_white)
selecteditemtitle:SetContentAlignment(5)
panel:AddItem(selecteditemtitle)
local selecteditemlabel = EasyLabel(panel, "Fists", "ZSHUDFontSmaller", color_white)
selecteditemlabel:SetContentAlignment(5)
panel:AddItem(selecteditemlabel)
panel.SelectedItemLabel = selecteditemlabel
local gwbtn = vgui.Create("DButton")
gwbtn:SetFont("ZSHUDFontSmaller")
gwbtn:SetText("Give Item")
gwbtn:SetSize(panel:GetWide() - 8 * screenscale, hei - 4 * screenscale)
gwbtn:CenterHorizontal()
gwbtn.DoClick = GiveWeapon
panel:AddItem(gwbtn)
gwbtn = vgui.Create("DButton")
gwbtn:SetFont("ZSHUDFontSmaller")
gwbtn:SetText("Give Item and 5 clips")
gwbtn:SetSize(panel:GetWide() - 8 * screenscale, hei - 4 * screenscale)
gwbtn:CenterHorizontal()
gwbtn.DoClick = GiveWeaponClip
panel:AddItem(gwbtn)
gwbtn = vgui.Create("DButton")
gwbtn:SetFont("ZSHUDFontSmaller")
gwbtn:SetText("Drop Item")
gwbtn:SetSize(panel:GetWide() - 8 * screenscale, hei - 4 * screenscale)
gwbtn:CenterHorizontal()
gwbtn.DoClick = DropWeapon
panel:AddItem(gwbtn)
gwbtn = vgui.Create("DButton")
gwbtn:SetFont("ZSHUDFontSmaller")
gwbtn:SetText("Empty Weapon Clip")
gwbtn:SetSize(panel:GetWide() - 8 * screenscale, hei - 4 * screenscale)
gwbtn:CenterHorizontal()
gwbtn.DoClick = EmptyClip
panel:AddItem(gwbtn)
gwbtn = vgui.Create("DButton")
gwbtn:SetFont("ZSHUDFontSmaller")
gwbtn:SetText("Dismantle Item")
gwbtn:SetSize(panel:GetWide() - 8 * screenscale, hei - 4 * screenscale)
gwbtn:CenterHorizontal()
gwbtn.DoClick = DismantleWeapon
panel:AddItem(gwbtn)
panel:AddItem(EasyLabel(panel, "Resupply Ammo Selection", "DefaultFont", color_white))
local dropdown = vgui.Create("DComboBox", panel)
dropdown:SetMouseInputEnabled(true)
dropdown:AddChoice("Resupply Held Weapon")
for k,v in pairs(self.AmmoResupply) do
dropdown:AddChoice(self.AmmoNames[k])
end
dropdown.OnSelect = function(me, index, value, data)
if value == "Resupply Held Weapon" then
MySelf.ResupplyChoice = nil
RunConsoleCommand("zs_resupplyammotype", "default")
return
end
for k,v in pairs(self.AmmoNames) do
if value == v then
MySelf.ResupplyChoice = k
RunConsoleCommand("zs_resupplyammotype", k)
break
end
end
end
dropdown:SetText("Resupply Held Weapon")
dropdown:SetTextColor(color_black)
panel:AddItem(dropdown)
self.HumanMenuSupplyChoice = dropdown
panel:OpenMenu()
end
function GM:ZombieSpawnMenu()
if self.ZombieEscape then return end
if self.ZSpawnMenu and self.ZSpawnMenu:IsValid() then
self.ZSpawnMenu:SetVisible(true)
self.ZSpawnMenu:OpenMenu()
self.ZSpawnMenu:RefreshContents()
return
end
local panel = vgui.Create("DZombieSpawnMenu")
self.ZSpawnMenu = panel
2014-10-02 08:49:54 +08:00
panel:OpenMenu()
end
function GM:PlayerBindPress(pl, bind, wasin)
if bind == "gmod_undo" or bind == "undo" then
RunConsoleCommand("+zoom")
timer.Create("ReleaseZoom", 1, 1, function() RunConsoleCommand("-zoom") end)
2014-10-02 08:49:54 +08:00
elseif bind == "+menu_context" then
if P_Team(pl) == TEAM_UNDEAD then
self.ZombieThirdPerson = not self.ZombieThirdPerson
elseif P_Team(pl) == TEAM_HUMAN then
self:ToggleOTSCamera()
end
2019-03-19 06:55:04 +08:00
elseif bind == "impulse 100" then
2019-03-19 03:18:49 +08:00
if P_Team(pl) == TEAM_UNDEAD and pl:Alive() then
2019-03-19 06:55:04 +08:00
self:ToggleZombieVision()
end
2014-10-02 08:49:54 +08:00
end
end
function GM:_ShouldDrawLocalPlayer(pl)
return FROM_CAMERA or P_Team(pl) == TEAM_UNDEAD and (self.ZombieThirdPerson or pl:CallZombieFunction0("ShouldDrawLocalPlayer"))
or P_Team(pl) == TEAM_HUMAN and self:UseOverTheShoulder()
or pl:IsPlayingTaunt()
or pl.Revive and pl.Revive:IsValid()
or pl.KnockedDown and pl.KnockedDown:IsValid()
2014-10-02 08:49:54 +08:00
end
local roll = 0
function GM:_CalcView(pl, origin, angles, fov, znear, zfar)
if pl.Confusion and pl.Confusion:IsValid() then
pl.Confusion:CalcView(pl, origin, angles, fov, znear, zfar)
end
if pl.Revive and pl.Revive:IsValid() and pl.Revive.GetRagdollEyes then
if self.ThirdPersonKnockdown or self.ZombieThirdPerson then
origin = pl:GetThirdPersonCameraPos(origin, angles)
else
local rpos, rang = pl.Revive:GetRagdollEyes(pl)
if rpos then
origin = rpos
angles = rang
end
2014-10-02 08:49:54 +08:00
end
elseif pl.KnockedDown and pl.KnockedDown:IsValid() then
if self.ThirdPersonKnockdown or self:UseOverTheShoulder() then
origin = pl:GetThirdPersonCameraPos(origin, angles)
else
local rpos, rang = self:GetRagdollEyes(pl)
if rpos then
origin = rpos
angles = rang
end
end
elseif pl:ShouldDrawLocalPlayer() and pl:OldAlive() and not pl:HasWon() then
if P_Team(pl) == TEAM_UNDEAD then
origin = pl:GetThirdPersonCameraPos(origin, angles)
elseif self:UseOverTheShoulder() then
self:CalcViewOTS(pl, origin, angles, fov, znear, zfar)
2014-10-02 08:49:54 +08:00
end
end
local targetroll = 0
if self.MovementViewRoll then
local dir = pl:GetVelocity()
local speed = dir:Length()
dir:Normalize()
targetroll = targetroll + dir:Dot(angles:Right()) * math.min(30, speed / 100)
end
if pl:WaterLevel() >= 3 then
targetroll = targetroll + math.sin(CurTime()) * 7
end
roll = math.Approach(roll, targetroll, math.max(0.25, math.sqrt(math.abs(roll))) * 30 * FrameTime())
angles.roll = angles.roll + roll
if pl:IsPlayingTaunt() then
self:CalcViewTaunt(pl, origin, angles, fov, znear, zfar)
2014-10-02 08:49:54 +08:00
end
local target = pl:GetObserverTarget()
if target and target:IsValid() then
local lasttarget = self.LastObserverTarget
if lasttarget and lasttarget:IsValid() and target ~= lasttarget then
if self.LastObserverTargetLerp then
if CurTime() >= self.LastObserverTargetLerp then
self.LastObserverTarget = nil
self.LastObserverTargetLerp = nil
else
local delta = math.Clamp((self.LastObserverTargetLerp - CurTime()) / 0.3333, 0, 1) ^ 0.5
origin:Set(self.LastObserverTargetPos * delta + origin * (1 - delta))
end
else
self.LastObserverTargetLerp = CurTime() + 0.3333
end
else
self.LastObserverTarget = target
self.LastObserverTargetPos = origin
end
end
if pl:GetObserverMode() ~= OBS_MODE_NONE then
angles.roll = 0 --Fixes babies tilting the screen
end
pl:CallZombieFunction2("CalcView", origin, angles)
2014-10-02 08:49:54 +08:00
return self.BaseClass.CalcView(self, pl, origin, angles, fov, znear, zfar)
end
function GM:CalcViewTaunt(pl, origin, angles, fov, znear, zfar)
2014-10-02 08:49:54 +08:00
local tr = util.TraceHull({start = origin, endpos = origin - angles:Forward() * 72, mins = Vector(-2, -2, -2), maxs = Vector(2, 2, 2), mask = MASK_OPAQUE, filter = pl})
origin:Set(tr.HitPos + tr.HitNormal * 2)
end
function GM:CreateMoveTaunt(cmd)
cmd:ClearButtons(0)
cmd:ClearMovement()
end
function GM:PostProcessPermitted(str)
return false
end
function GM:HUDPaintEndRound()
end
function GM:PreDrawViewModel(vm, pl, wep)
if pl and pl:IsValid() and (pl:IsHolding() or GAMEMODE.HideViewModels) then return true end
2014-10-02 08:49:54 +08:00
if wep and wep:IsValid() and wep.PreDrawViewModel then
return wep:PreDrawViewModel(vm)
end
end
function GM:PostDrawViewModel(vm, pl, wep)
if wep and wep:IsValid() then
if wep.UseHands or not wep:IsScripted() then
local hands = pl:GetHands()
if hands and hands:IsValid() then
hands:DrawModel()
end
end
if wep.PostDrawViewModel then
wep:PostDrawViewModel(vm)
end
end
end
local undo = false
2014-10-02 08:49:54 +08:00
local matWhite = Material("models/debug/debugwhite")
local lowhealthcolor = GM.AuraColorEmpty
local fullhealthcolor = GM.AuraColorFull
2014-10-02 08:49:54 +08:00
function GM:_PrePlayerDraw(pl)
local shadowman = false
if pl ~= MySelf and pl:IsEffectActive(EF_DIMLIGHT) then
pl:RemoveEffects(EF_DIMLIGHT)
end
local myteam = P_Team(MySelf)
local theirteam = P_Team(pl)
local radius = self.TransparencyRadius
if radius > 0 and myteam == theirteam and pl ~= MySelf and not (GAMEMODE.AlwaysDrawFriend and pl:IsFriend()) and not self.MedicalAura then
local dist = pl:GetPos():DistToSqr(EyePos())
if dist < radius then
local blend = (dist / radius) ^ 1.4
if blend <= 0.1 then
pl.ShadowMan = true return true
end
render_SetBlend(blend)
if myteam == TEAM_HUMAN and blend < 0.5 then
render_ModelMaterialOverride(matWhite)
render_SetColorModulation(0.2, 0.2, 0.2)
shadowman = true
2014-10-02 08:49:54 +08:00
end
undo = true
2014-10-02 08:49:54 +08:00
end
end
pl.ShadowMan = shadowman
if pl:CallZombieFunction0("PrePlayerDraw") then return true end
if pl.SpawnProtection and (not (pl.status_overridemodel and pl.status_overridemodel:IsValid()) or pl:GetZombieClassTable().NoHideMainModel) then
undo = true
render_ModelMaterialOverride(matWhite)
render_SetBlend(0.02 + (CurTime() + pl:EntIndex() * 0.2) % 0.05)
render_SetColorModulation(0, 0.3, 0)
render_SuppressEngineLighting(true)
end
if self.m_ZombieVision and myteam == TEAM_UNDEAD and theirteam == TEAM_HUMAN then
local dist = pl:GetPos():DistToSqr(EyePos())
if dist <= pl:GetAuraRangeSqr() and (not pl:GetDTBool(DT_PLAYER_BOOL_NECRO) or dist >= 27500) then
undo = true
local healthfrac = pl:Health() / pl:GetMaxHealth()
render_SetBlend(1)
render_ModelMaterialOverride(matWhite)
render_SetColorModulation(
Lerp(healthfrac, lowhealthcolor.r, fullhealthcolor.r) / 255,
Lerp(healthfrac, lowhealthcolor.g, fullhealthcolor.g) / 255,
Lerp(healthfrac, lowhealthcolor.b, fullhealthcolor.b) / 255
)
render_SuppressEngineLighting(true)
cam_IgnoreZ(true)
end
2014-10-02 08:49:54 +08:00
end
end
local colFriend = Color(10, 255, 10, 60)
local matFriendRing = Material("SGM/playercircle")
local matTargetTri = Material("gui/point.png")
2014-10-02 08:49:54 +08:00
function GM:_PostPlayerDraw(pl)
pl:CallZombieFunction0("PostPlayerDraw")
2014-10-02 08:49:54 +08:00
if undo then
render_SetBlend(1)
render_ModelMaterialOverride()
render_SetColorModulation(1, 1, 1)
render_SuppressEngineLighting(false)
cam_IgnoreZ(false)
2014-10-02 08:49:54 +08:00
undo = false
2014-10-02 08:49:54 +08:00
end
local eyepos, ang, tpos, distance, hpf
if MySelf.TargetLocus and self.TraceTargetTeam == pl and pl:IsValidLivingZombie() and not pl:GetZombieClassTable().IgnoreTargetAssist then
tpos = pl:GetPos()
tpos.z = tpos.z + 80
2014-10-02 08:49:54 +08:00
eyepos = MySelf:EyePos()
distance = eyepos:DistToSqr(tpos)
2014-10-02 08:49:54 +08:00
ang = (eyepos - tpos):Angle()
ang:RotateAroundAxis(ang:Right(), 270)
ang:RotateAroundAxis(ang:Up(), 90)
2014-10-02 08:49:54 +08:00
cam_IgnoreZ(true)
cam_Start3D2D(tpos, ang, math.max(750, math.sqrt(distance)) / 6500)
surface_SetMaterial(matTargetTri)
2014-10-02 08:49:54 +08:00
hpf = pl:Health() / pl:GetMaxZombieHealth()
2014-10-02 08:49:54 +08:00
surface_SetDrawColor(255 - (255 * hpf), 255 * hpf, 0, 230)
surface_DrawTexturedRect(-96, -96, 96, 96)
cam_End3D2D()
cam_IgnoreZ(false)
end
if pl ~= MySelf and P_Team(MySelf) == P_Team(pl) and pl:IsFriend() then
local pos = pl:GetPos()
pos.z = pos.z + 2
render_SetMaterial(matFriendRing)
render_DrawQuadEasy(pos, vector_up, 32, 32, colFriend)
render_DrawQuadEasy(pos, vector_down, 32, 32, colFriend)
2014-10-02 08:49:54 +08:00
end
end
function GM:HUDPaintBackgroundEndRound()
local x, y = ScrW() / 2, ScrH() * 0.8
2014-10-02 08:49:54 +08:00
local timleft = math.max(0, self.EndTime + self.EndGameTime - CurTime())
if timleft <= 0 then
draw_SimpleTextBlur(translate.Get("loading"), "ZSHUDFont", x, y, COLOR_WHITE, TEXT_ALIGN_CENTER)
2014-10-02 08:49:54 +08:00
else
draw_SimpleTextBlur(translate.Format("next_round_in_x", util.ToMinutesSecondsCD(timleft)), "ZSHUDFontSmall", x, y, COLOR_WHITE, TEXT_ALIGN_CENTER)
2014-10-02 08:49:54 +08:00
end
end
local function EndRoundCalcView(pl, origin, angles, fov, znear, zfar)
if GAMEMODE.EndTime and CurTime() < GAMEMODE.EndTime + 5 then
local endposition = GAMEMODE.LastHumanPosition
local override = GetGlobalVector("endcamerapos", vector_origin)
if override ~= vector_origin then
2014-10-02 08:49:54 +08:00
endposition = override
end
if endposition then
local delta = math.Clamp((CurTime() - GAMEMODE.EndTime) * 2, 0, 1)
2014-10-02 08:49:54 +08:00
local start = endposition * delta + origin * (1 - delta)
local tr = util.TraceHull({start = start, endpos = start + delta * 64 * Angle(0, CurTime() * 30, 0):Forward(), mins = Vector(-2, -2, -2), maxs = Vector(2, 2, 2), filter = player.GetAll(), mask = MASK_SOLID})
return {origin = tr.HitPos + tr.HitNormal, angles = (start - tr.HitPos):Angle()}
end
return
end
hook.Remove("CalcView", "EndRoundCalcView")
end
local function EndRoundShouldDrawLocalPlayer(pl)
if GAMEMODE.EndTime and CurTime() < GAMEMODE.EndTime + 5 then
return true
end
hook.Remove("ShouldDrawLocalPlayer", "EndRoundShouldDrawLocalPlayer")
end
function GM:EndRound(winner, nextmap)
if self.RoundEnded then return end
self.RoundEnded = true
ROUNDWINNER = winner
self.EndTime = CurTime()
RunConsoleCommand("stopsound")
self.HUDPaint = self.HUDPaintEndRound
self.HUDPaintBackground = self.HUDPaintBackgroundEndRound
if winner == TEAM_UNDEAD and GetGlobalBool("endcamera", true) then
hook.Add("CalcView", "EndRoundCalcView", EndRoundCalcView)
hook.Add("ShouldDrawLocalPlayer", "EndRoundShouldDrawLocalPlayer", EndRoundShouldDrawLocalPlayer)
end
local dvar = winner == TEAM_UNDEAD and self.AllLoseSound or self.HumanWinSound
local snd = GetGlobalString(winner == TEAM_UNDEAD and "losemusic" or "winmusic", dvar)
if snd == "default" then
snd = dvar
elseif snd == "none" then
snd = nil
end
if snd then
timer.Simple(0.5, function() surface_PlaySound(snd) end)
end
timer.Simple(5, function()
if not (pEndBoard and pEndBoard:IsValid()) then
MakepEndBoard(winner)
end
end)
end
function GM:WeaponDeployed(pl, wep)
self:DoChangeDeploySpeed(wep)
2014-10-02 08:49:54 +08:00
end
function GM:LocalPlayerDied(attackername)
LASTDEATH = RealTime()
surface_PlaySound(self.DeathSound)
if attackername then
self:CenterNotify(COLOR_RED, {font = "ZSHUDFont"}, translate.Get("you_have_died"))
self:CenterNotify(COLOR_RED, translate.Format(self.PantsMode and "you_were_kicked_by_x" or "you_were_killed_by_x", tostring(attackername)))
else
self:CenterNotify(COLOR_RED, {font = "ZSHUDFont"}, translate.Get("you_have_died"))
end
end
function GM:KeyPress(pl, key)
if key == self.MenuKey then
local team = P_Team(pl)
if team == TEAM_HUMAN and pl:Alive() and not pl:IsHolding() then
2014-10-02 08:49:54 +08:00
gamemode.Call("HumanMenu")
elseif team == TEAM_ZOMBIE and not pl:Alive() then
gamemode.Call("ZombieSpawnMenu")
2014-10-02 08:49:54 +08:00
end
elseif key == IN_SPEED then
if pl:Alive() then
if P_Team(pl) == TEAM_HUMAN then
2014-10-02 08:49:54 +08:00
pl:DispatchAltUse()
elseif P_Team(pl) == TEAM_UNDEAD then
pl:CallZombieFunction0("AltUse")
end
end
end
end
function GM:KeyRelease(pl, key)
if key == self.MenuKey then
if self.HumanMenuPanel and self.HumanMenuPanel:IsValid() then
if self.InventoryMenu and self.InventoryMenu:IsValid() then
self.InventoryMenu:SetVisible(false)
if self.m_InvViewer and self.m_InvViewer:IsValid() then
self.m_InvViewer:SetVisible(false)
end
end
if self.HumanMenuSupplyChoice then
self.HumanMenuSupplyChoice:CloseMenu()
end
if self.InventoryMenu.SelInv then
self.InventoryMenu.SelInv = nil
self:DoAltSelectedItemUpdate()
local grid = self.InventoryMenu.Grid
for k, v in pairs(grid:GetChildren()) do
v.On = false
end
2014-10-02 08:49:54 +08:00
end
end
end
end
function GM:PlayerStepSoundTime(pl, iType, bWalking)
local time = pl:CallZombieFunction2("PlayerStepSoundTime", iType, bWalking)
2014-10-02 08:49:54 +08:00
if time then
return time
end
if iType == STEPSOUNDTIME_NORMAL or iType == STEPSOUNDTIME_WATER_FOOT then
return 520 - pl:GetVelocity():Length()
end
if iType == STEPSOUNDTIME_ON_LADDER then
return 500
end
if iType == STEPSOUNDTIME_WATER_KNEE then
return 650
end
return 350
end
function GM:PlayerFootstep(pl, vFootPos, iFoot, strSoundName, fVolume)
return pl:CallZombieFunction4("PlayerFootstep", vFootPos, iFoot, strSoundName, fVolume)
2014-10-02 08:49:54 +08:00
end
function GM:PlayerCanCheckout(pl)
return pl:IsValid() and P_Team(pl) == TEAM_HUMAN and pl:Alive() and self:GetWave() <= 0
2014-10-02 08:49:54 +08:00
end
function GM:OpenWorth()
if gamemode.Call("PlayerCanCheckout", MySelf) then
MakepWorth()
end
end
function GM:CloseWorth()
if pWorth and pWorth:IsValid() then
2014-10-02 08:49:54 +08:00
pWorth:Remove()
pWorth = nil
end
end
function GM:SuppressArsenalUpgrades(suppresstime)
self.SuppressArsenalTime = math.max(CurTime() + suppresstime, self.SuppressArsenalTime)
end
function GM:Rewarded(class, amount)
if CurTime() < self.SuppressArsenalTime then return end
class = class or "0"
local toptext = translate.Get("arsenal_upgraded")
local wep = weapons.Get(class)
if wep and wep.PrintName and #wep.PrintName > 0 then
2014-10-02 08:49:54 +08:00
if killicon.Get(class) == killicon.Get("default") then
self:CenterNotify(COLOR_PURPLE, toptext..": ", color_white, wep.PrintName)
else
self:CenterNotify({killicon = class}, " ", COLOR_PURPLE, toptext..": ", color_white, wep.PrintName)
end
elseif amount then
self:CenterNotify(COLOR_PURPLE, toptext..": ", color_white, amount.." "..class)
else
self:CenterNotify(COLOR_PURPLE, toptext)
end
end
function PlayMenuOpenSound()
MySelf:EmitSound("buttons/lightswitch2.wav", 100, 30)
2014-10-02 08:49:54 +08:00
end
function PlayMenuCloseSound()
MySelf:EmitSound("buttons/lightswitch2.wav", 100, 20)
2019-03-19 06:30:04 +08:00
end