Large backend update
Players are no longer implicitly zombies if they're not humans. Players are no longer implicitly humans if they're not zombies. This is preparation for a third, optional spectator team. A few small optimizations and fixes.
This commit is contained in:
parent
f5c064a0e9
commit
bd937c290e
30 changed files with 175 additions and 157 deletions
|
@ -4,7 +4,10 @@ AddCSLuaFile("shared.lua")
|
|||
include('shared.lua')
|
||||
|
||||
function ENT:Initialize()
|
||||
self.DieTime = CurTime() + 15
|
||||
self.Touched = {}
|
||||
self.OriginalAngles = self:GetAngles()
|
||||
|
||||
self:Fire("kill", "", 15)
|
||||
|
||||
self:SetModel("models/Items/CrossbowRounds.mdl")
|
||||
self:PhysicsInit(SOLID_VPHYSICS)
|
||||
|
@ -18,25 +21,18 @@ function ENT:Initialize()
|
|||
phys:EnableDrag(false)
|
||||
phys:Wake()
|
||||
end
|
||||
self.Touched = {}
|
||||
self.OriginalAngles = self:GetAngles()
|
||||
|
||||
self:EmitSound("weapons/crossbow/bolt_fly4.wav")
|
||||
end
|
||||
|
||||
function ENT:Think()
|
||||
if self.DieTime <= CurTime() then
|
||||
self:Remove()
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:PhysicsCollide(data, phys)
|
||||
if self.Done then return end
|
||||
self.Done = true
|
||||
|
||||
self:Fire("kill", "", 8)
|
||||
|
||||
phys:EnableMotion(false)
|
||||
self:EmitSound("physics/metal/sawblade_stick"..math.random(3)..".wav")
|
||||
self.DieTime = CurTime() + 8
|
||||
|
||||
self:SetPos(data.HitPos)
|
||||
self:SetAngles(data.HitNormal:Angle())
|
||||
|
@ -51,18 +47,15 @@ function ENT:PhysicsCollide(data, phys)
|
|||
end
|
||||
|
||||
function ENT:StartTouch(ent)
|
||||
if not self.Done and not self.Touched[tostring(ent)] and ent:IsValid() then
|
||||
if self.Done or self.Touched[ent] or not ent:IsValid() then return end
|
||||
|
||||
local owner = self:GetOwner()
|
||||
if not owner:IsValid() then owner = self end
|
||||
|
||||
if ent ~= owner and not (ent:IsPlayer() and ent:Team() == self.Team) then
|
||||
ent:TakeDamage(100, owner, self)
|
||||
ent:EmitSound("weapons/crossbow/hitbod"..math.random(1,2)..".wav")
|
||||
self.Touched[tostring(ent)] = true
|
||||
end
|
||||
end
|
||||
end
|
||||
if ent == owner or ent:IsPlayer() and (ent:Team() == self.Team or not ent:Alive()) then return end
|
||||
|
||||
function ENT:UpdateTransmitState()
|
||||
return TRANSMIT_PVS
|
||||
self.Touched[ent] = true
|
||||
|
||||
ent:TakeDamage(100, owner, self)
|
||||
ent:EmitSound("weapons/crossbow/hitbod"..math.random(2)..".wav")
|
||||
end
|
||||
|
|
|
@ -24,7 +24,7 @@ end
|
|||
|
||||
function ENT:Think()
|
||||
if self.PhysicsData then
|
||||
self:Explode(self.PhysicsData.HitPos, self.PhysicsData.HitNormal, self.PhysicsData.HitEntity, self.PhysicsData.OurOldVelocity)
|
||||
self:Hit(self.PhysicsData.HitPos, self.PhysicsData.HitNormal, self.PhysicsData.HitEntity, self.PhysicsData.OurOldVelocity)
|
||||
end
|
||||
|
||||
local parent = self:GetParent()
|
||||
|
@ -33,7 +33,7 @@ function ENT:Think()
|
|||
end
|
||||
end
|
||||
|
||||
function ENT:Explode(vHitPos, vHitNormal, eHitEntity, vOldVelocity)
|
||||
function ENT:Hit(vHitPos, vHitNormal, eHitEntity, vOldVelocity)
|
||||
if self:GetHitTime() ~= 0 then return end
|
||||
self:SetHitTime(CurTime())
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ end
|
|||
|
||||
function ENT:Think()
|
||||
if self.PhysicsData then
|
||||
self:Explode(self.PhysicsData.HitPos, self.PhysicsData.HitNormal, self.PhysicsData.HitEntity)
|
||||
self:Hit(self.PhysicsData.HitPos, self.PhysicsData.HitNormal, self.PhysicsData.HitEntity)
|
||||
end
|
||||
|
||||
if self.DeathTime <= CurTime() then
|
||||
|
@ -32,7 +32,7 @@ function ENT:Think()
|
|||
end
|
||||
end
|
||||
|
||||
function ENT:Explode(vHitPos, vHitNormal, eHitEntity)
|
||||
function ENT:Hit(vHitPos, vHitNormal, eHitEntity)
|
||||
if self.Exploded then return end
|
||||
self.Exploded = true
|
||||
self.DeathTime = 0
|
||||
|
|
|
@ -38,7 +38,7 @@ function ENT:PhysicsCollide(data, phys)
|
|||
end
|
||||
|
||||
function ENT:StartTouch(ent)
|
||||
if self.DieTime ~= 0 and ent:IsValid() and ent:IsPlayer() then
|
||||
if self.DieTime ~= 0 and ent:IsValid() and ent:IsPlayer() and ent:Alive() then
|
||||
local owner = self:GetOwner()
|
||||
if not owner:IsValid() then owner = self end
|
||||
|
||||
|
|
|
@ -50,7 +50,7 @@ function ENT:Use(activator, caller)
|
|||
self:GiveToActivator(activator, caller)
|
||||
end
|
||||
function ENT:GiveToActivator(activator, caller)
|
||||
if activator:IsPlayer() and activator:Alive() and not activator:KeyDown(GAMEMODE.UtilityKey) and activator:Team() ~= TEAM_UNDEAD and not self.Removing then
|
||||
if activator:IsPlayer() and activator:Alive() and not activator:KeyDown(GAMEMODE.UtilityKey) and activator:Team() == TEAM_HUMAN and not self.Removing then
|
||||
if self.IgnorePickupCount or (not self.PlacedInMap or not GAMEMODE.MaxAmmoPickups or (activator.AmmoPickups or 0) < GAMEMODE.MaxAmmoPickups or team.NumPlayers(TEAM_HUMAN) <= 1) then
|
||||
if self.PlacedInMap and GAMEMODE.WeaponRequiredForAmmo and team.NumPlayers(TEAM_HUMAN) > 1 then
|
||||
local hasweapon = false
|
||||
|
|
|
@ -66,7 +66,7 @@ function ENT:DrawTranslucent()
|
|||
local lp = LocalPlayer()
|
||||
local owner = self:GetOwner()
|
||||
|
||||
if lp:IsValid() and lp:Team() ~= TEAM_UNDEAD and owner:IsValid() and owner:IsPlayer() then
|
||||
if lp:IsValid() and lp:Team() == TEAM_HUMAN and owner:IsValid() and owner:IsPlayer() then
|
||||
local ang = EyeAngles()
|
||||
ang.pitch = 0
|
||||
local right = ang:Right()
|
||||
|
|
|
@ -19,6 +19,9 @@ ENT.CanPackUp = true
|
|||
ENT.IsBarricadeObject = true
|
||||
ENT.AlwaysGhostable = true
|
||||
|
||||
local NextCache = 0
|
||||
local CachedFilter = {}
|
||||
|
||||
function ENT:GetLocalAnglesToTarget(target)
|
||||
return self:WorldToLocalAngles(self:GetAnglesToTarget(target))
|
||||
end
|
||||
|
@ -79,14 +82,13 @@ function ENT:GetScanFilter()
|
|||
end
|
||||
|
||||
-- Getting all of some team is straining every frame when there's 5 or so turrets. I could probably use CONTENTS_TEAM* if I knew what they did.
|
||||
ENT.NextCache = 0
|
||||
function ENT:GetCachedScanFilter()
|
||||
if CurTime() < self.NextCache and self.CachedFilter then return self.CachedFilter end
|
||||
if CurTime() < NextCache and CachedFilter then return CachedFilter end
|
||||
|
||||
self.CachedFilter = self:GetScanFilter()
|
||||
self.NextCache = CurTime() + 1
|
||||
CachedFilter = self:GetScanFilter()
|
||||
NextCache = CurTime() + 1
|
||||
|
||||
return self.CachedFilter
|
||||
return CachedFilter
|
||||
end
|
||||
|
||||
local tabSearch = {mask = MASK_SHOT}
|
||||
|
|
|
@ -88,7 +88,7 @@ function ENT:DrawTranslucent()
|
|||
local lp = LocalPlayer()
|
||||
local owner = self:GetOwner()
|
||||
|
||||
if lp:IsValid() and lp:Team() ~= TEAM_UNDEAD and owner:IsValid() and owner:IsPlayer() then
|
||||
if lp:IsValid() and lp:Team() == TEAM_HUMAN and owner:IsValid() and owner:IsPlayer() then
|
||||
local ang = EyeAngles()
|
||||
ang.pitch = 0
|
||||
local right = ang:Right()
|
||||
|
|
|
@ -49,7 +49,7 @@ function ENT:OnTakeDamage(dmginfo)
|
|||
if not self.Destroyed then
|
||||
local attacker = dmginfo:GetAttacker()
|
||||
if not (attacker:IsValid() and attacker:IsPlayer() and attacker:Team() == TEAM_HUMAN) then
|
||||
if attacker.LifeBarricadeDamage ~= nil and self:HumanNearby() then
|
||||
if attacker:Team() == TEAM_UNDEAD and self:HumanNearby() then
|
||||
attacker:AddLifeBarricadeDamage(dmginfo:GetDamage())
|
||||
end
|
||||
|
||||
|
|
|
@ -67,7 +67,7 @@ function ENT:DrawTranslucent()
|
|||
local deployer = self:GetOwner()
|
||||
if deployer:IsValid() then
|
||||
displayowner = deployer:Name()
|
||||
if deployer:Team() == TEAM_UNDEAD or not deployer:Alive() then
|
||||
if deployer:Team() ~= TEAM_HUMAN or not deployer:Alive() then
|
||||
displayowner = "(DEAD) "..displayowner
|
||||
redname = true
|
||||
end
|
||||
|
|
|
@ -6,7 +6,7 @@ function ENT:Think()
|
|||
local owner = self:GetOwner()
|
||||
if not owner:IsValid() or not owner:Alive() then return end
|
||||
|
||||
if owner:Team() == TEAM_UNDEAD then self:Remove() return end
|
||||
if owner:Team() ~= TEAM_HUMAN then self:Remove() return end
|
||||
|
||||
if self:IsUnderwater() then
|
||||
if owner:WaterLevel() < 3 and not (owner.NoAirBrush and owner.NoAirBrush:IsValid()) then
|
||||
|
|
|
@ -72,7 +72,7 @@ function ENT:OnRemove()
|
|||
|
||||
owner:DrawWorldModel(true)
|
||||
|
||||
if owner:Alive() and owner:Team() ~= TEAM_UNDEAD then
|
||||
if owner:Alive() and owner:Team() == TEAM_HUMAN then
|
||||
local wep = owner:GetActiveWeapon()
|
||||
if wep:IsValid() then
|
||||
wep:SendWeaponAnim(ACT_VM_DRAW)
|
||||
|
|
|
@ -48,7 +48,6 @@ function SWEP:SecondaryAttack()
|
|||
if CurTime() < self:GetNextPrimaryFire() or CurTime() < self:GetNextSecondaryFire() then return end
|
||||
|
||||
local owner = self.Owner
|
||||
if owner:Team() ~= TEAM_UNDEAD then owner:Kill() return end
|
||||
|
||||
self:SetSwingAnimTime(CurTime() + 1)
|
||||
self.Owner:DoAnimationEvent(ACT_RANGE_ATTACK2)
|
||||
|
|
|
@ -54,12 +54,7 @@ function SWEP:Think()
|
|||
|
||||
owner:ResetSpeed()
|
||||
|
||||
if ent:IsValid() then
|
||||
local phys = ent:GetPhysicsObject()
|
||||
if ent:IsPlayer() and (ent:Team() ~= TEAM_UNDEAD or ent:GetZombieClassTable().Name ~= "Crow") then
|
||||
return
|
||||
end
|
||||
|
||||
if ent:IsValid() and ent:IsPlayer() and ent:Team() == TEAM_UNDEAD and ent:Alive() and ent:GetZombieClassTable().Name == "Crow" then
|
||||
ent:TakeSpecialDamage(2, DMG_SLASH, owner, self)
|
||||
end
|
||||
end
|
||||
|
@ -68,8 +63,6 @@ function SWEP:PrimaryAttack()
|
|||
if CurTime() < self:GetNextPrimaryFire() or not self.Owner:IsOnGround() then return end
|
||||
self:SetNextPrimaryFire(CurTime() + self.Primary.Delay)
|
||||
|
||||
if self.Owner:Team() ~= TEAM_UNDEAD then self.Owner:Kill() return end
|
||||
|
||||
self.Owner:EmitSound("NPC_Crow.Squawk")
|
||||
self.Owner.EatAnim = CurTime() + 2
|
||||
|
||||
|
@ -82,8 +75,6 @@ function SWEP:SecondaryAttack()
|
|||
if CurTime() < self:GetNextSecondaryFire() then return end
|
||||
self:SetNextSecondaryFire(CurTime() + 1.6)
|
||||
|
||||
if self.Owner:Team() ~= TEAM_UNDEAD then self.Owner:Kill() return end
|
||||
|
||||
self.Owner:EmitSound("NPC_Crow.Alert")
|
||||
end
|
||||
|
||||
|
|
|
@ -51,12 +51,12 @@ end
|
|||
|
||||
function SWEP:SecondaryAttack()
|
||||
if CurTime() < self:GetNextPrimaryFire() or CurTime() < self:GetNextSecondaryFire() then return end
|
||||
local owner = self.Owner
|
||||
if owner:Team() ~= TEAM_UNDEAD then owner:Kill() return end
|
||||
|
||||
self.Owner:DoAnimationEvent(ACT_RANGE_ATTACK2)
|
||||
self.Owner:EmitSound("NPC_PoisonZombie.Throw")
|
||||
self.Owner:SetSpeed(1)
|
||||
local owner = self.Owner
|
||||
|
||||
owner:DoAnimationEvent(ACT_RANGE_ATTACK2)
|
||||
owner:EmitSound("NPC_PoisonZombie.Throw")
|
||||
owner:SetSpeed(1)
|
||||
self:SetNextSecondaryFire(CurTime() + 4)
|
||||
self:SetNextPrimaryFire(CurTime() + self.Primary.Delay)
|
||||
|
||||
|
|
|
@ -93,7 +93,7 @@ function SWEP:DoAlert()
|
|||
local mouthpos = owner:EyePos() + owner:GetUp() * -3
|
||||
local screampos = mouthpos + owner:GetAimVector() * 16
|
||||
for _, ent in pairs(ents.FindInSphere(screampos, 92)) do
|
||||
if ent and ent:IsValid() and ent:IsPlayer() and ent:Team() ~= owner:Team() then
|
||||
if ent and ent:IsValid() and ent:IsPlayer() and ent:Team() == TEAM_HUMAN then
|
||||
local entearpos = ent:EyePos()
|
||||
local dist = screampos:Distance(entearpos)
|
||||
if dist <= 92 and TrueVisible(entearpos, screampos) then
|
||||
|
|
|
@ -465,7 +465,7 @@ function GM:PostRender()
|
|||
if self.m_ZombieVision and MySelf:IsValid() and MySelf:Team() == TEAM_UNDEAD then
|
||||
local eyepos = EyePos()
|
||||
local eyedir = EyeAngles():Forward()
|
||||
local tr = util.TraceLine({start = eyepos, endpos = eyepos + eyedir * 128, mask = MASK_SOLID_BRUSHONLY})
|
||||
--local tr = util.TraceLine({start = eyepos, endpos = eyepos + eyedir * 128, mask = MASK_SOLID_BRUSHONLY})
|
||||
|
||||
local dlight = DynamicLight(MySelf:EntIndex())
|
||||
if dlight then
|
||||
|
@ -701,7 +701,7 @@ function GM:_HUDPaint()
|
|||
|
||||
if myteam == TEAM_UNDEAD then
|
||||
self:ZombieHUD()
|
||||
else
|
||||
elseif myteam == TEAM_HUMAN then
|
||||
self:HumanHUD(screenscale)
|
||||
end
|
||||
|
||||
|
@ -1082,7 +1082,7 @@ function GM:_HUDPaintBackground()
|
|||
surface_DrawTexturedRectRotated(bordersize / 2, h / 2, bordersize, h, 180)
|
||||
surface_DrawTexturedRect(w - bordersize, 0, bordersize, h)]]
|
||||
|
||||
if self.FilmGrainEnabled and MySelf:Team() == TEAM_HUMAN then
|
||||
if self.FilmGrainEnabled and MySelf:Team() ~= TEAM_UNDEAD then
|
||||
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)
|
||||
|
@ -1275,7 +1275,8 @@ function GM:_CreateMove(cmd)
|
|||
BHopTime = CurTime() + 0.065
|
||||
end
|
||||
|
||||
if MySelf:Team() == TEAM_HUMAN then
|
||||
local myteam = MySelf:Team()
|
||||
if myteam == TEAM_HUMAN then
|
||||
if MySelf:Alive() then
|
||||
local lockon = self.HumanMenuLockOn
|
||||
if lockon then
|
||||
|
@ -1305,7 +1306,7 @@ function GM:_CreateMove(cmd)
|
|||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
elseif myteam == TEAM_UNDEAD then
|
||||
local buttons = cmd:GetButtons()
|
||||
if bit.band(buttons, IN_ZOOM) ~= 0 then
|
||||
cmd:SetButtons(buttons - IN_ZOOM)
|
||||
|
@ -1361,15 +1362,17 @@ function GM:_PrePlayerDraw(pl)
|
|||
if pl.status_overridemodel and pl.status_overridemodel:IsValid() and self:ShouldDrawLocalPlayer(MySelf) then -- We need to do this otherwise the player's real model shows up for some reason.
|
||||
undomodelblend = true
|
||||
render.SetBlend(0)
|
||||
elseif MySelf:Team() == pl:Team() and pl ~= MySelf and not self.MedicalAura then
|
||||
else
|
||||
local myteam = MySelf:Team()
|
||||
if myteam == pl:Team() and pl ~= MySelf and not self.MedicalAura then
|
||||
local radius = self.TransparencyRadius
|
||||
if radius > 0 then
|
||||
local eyepos = EyePos()
|
||||
local dist = pl:NearestPoint(eyepos):Distance(eyepos)
|
||||
if dist < radius then
|
||||
local blend = math.max((dist / radius) ^ 1.4, MySelf:Team() == TEAM_HUMAN and 0.04 or 0.1)
|
||||
local blend = math.max((dist / radius) ^ 1.4, myteam == TEAM_HUMAN and 0.04 or 0.1)
|
||||
render.SetBlend(blend)
|
||||
if MySelf:Team() == TEAM_HUMAN and blend < 0.4 then
|
||||
if myteam == TEAM_HUMAN and blend < 0.4 then
|
||||
render.ModelMaterialOverride(matWhite)
|
||||
render.SetColorModulation(0.2, 0.2, 0.2)
|
||||
shadowman = true
|
||||
|
@ -1378,6 +1381,7 @@ function GM:_PrePlayerDraw(pl)
|
|||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
pl.ShadowMan = shadowman
|
||||
|
||||
|
|
|
@ -214,7 +214,7 @@ function GM:_PostDrawOpaqueRenderables()
|
|||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
elseif MySelf:Team() == TEAM_HUMAN then
|
||||
self:DrawCraftingEntity()
|
||||
|
||||
local holding = MySelf.status_human_holding
|
||||
|
|
|
@ -145,6 +145,8 @@ function PANEL:CreatePlayerPanel(pl)
|
|||
local curpan = self:GetPlayerPanel(pl)
|
||||
if curpan and curpan:Valid() then return curpan end
|
||||
|
||||
if pl:Team() == TEAM_SPECTATOR then return end
|
||||
|
||||
local panel = vgui.Create("ZSPlayerPanel", pl:Team() == TEAM_UNDEAD and self.ZombieList or self.HumanList)
|
||||
panel:SetPlayer(pl)
|
||||
panel:Dock(TOP)
|
||||
|
@ -162,13 +164,13 @@ function PANEL:Refresh()
|
|||
|
||||
if self.PlayerPanels == nil then self.PlayerPanels = {} end
|
||||
|
||||
for _, panel in pairs(self.PlayerPanels) do
|
||||
if not panel:Valid() then
|
||||
for pl, panel in pairs(self.PlayerPanels) do
|
||||
if not panel:Valid() or pl:IsValid() and pl:IsSpectator() then
|
||||
self:RemovePlayerPanel(panel)
|
||||
end
|
||||
end
|
||||
|
||||
for _, pl in pairs(player.GetAll()) do
|
||||
for _, pl in pairs(player.GetAllActive()) do
|
||||
self:CreatePlayerPanel(pl)
|
||||
end
|
||||
end
|
||||
|
@ -250,7 +252,7 @@ function PANEL:Paint()
|
|||
if pl:IsValid() then
|
||||
col = team.GetColor(pl:Team())
|
||||
|
||||
if pl:SteamID() == "STEAM_0:1:3307510" then
|
||||
if self.m_Flash then
|
||||
mul = 0.6 + math.abs(math.sin(RealTime() * 6)) * 0.4
|
||||
elseif pl == MySelf then
|
||||
mul = 0.8
|
||||
|
@ -366,6 +368,8 @@ function PANEL:SetPlayer(pl)
|
|||
self.m_SpecialImage:SetTooltip()
|
||||
self.m_SpecialImage:SetVisible(false)
|
||||
end
|
||||
|
||||
self.m_Flash = pl:SteamID() == "STEAM_0:1:3307510"
|
||||
else
|
||||
self.m_Avatar:SetVisible(false)
|
||||
self.m_SpecialImage:SetVisible(false)
|
||||
|
|
|
@ -53,13 +53,15 @@ function GM:HUDDrawTargetID(teamid)
|
|||
trace.filter[1] = MySelf
|
||||
trace.filter[2] = MySelf:GetObserverTarget()
|
||||
|
||||
local isspectator = MySelf:IsSpectator()
|
||||
|
||||
local entity = util.TraceHull(trace).Entity
|
||||
if entity:IsValid() and entity:IsPlayer() and entity:Team() == teamid then
|
||||
if entity:IsValid() and entity:IsPlayer() and (entity:Team() == teamid or isspectator) then
|
||||
entitylist[entity] = CurTime()
|
||||
end
|
||||
|
||||
for ent, time in pairs(entitylist) do
|
||||
if ent:IsValid() and not (ent:IsPlayer() and ent:Team() ~= teamid) and CurTime() < time + 2 then
|
||||
if ent:IsValid() and ent:IsPlayer() and (ent:Team() == teamid or isspectator) and CurTime() < time + 2 then
|
||||
self:DrawTargetID(ent, 1 - math.Clamp((CurTime() - time) / 2, 0, 1))
|
||||
else
|
||||
entitylist[ent] = nil
|
||||
|
|
|
@ -10,27 +10,7 @@ This was my first ever gamemode. A lot of stuff is from years ago and some stuff
|
|||
|
||||
]]
|
||||
|
||||
-- CRAFTING AND ITEM IDEAS
|
||||
--[[
|
||||
ITEMS
|
||||
nighkeez: you run a bit faster while wearing them. Also attaches white boot props to your feet.
|
||||
AWTH barrel: if it so much as bangs in to something then it blows up with a huge explosion (like fire bomb size).
|
||||
stabber: stubber with a knife in the barrel. A melee weapon with very low size but high reach.
|
||||
hot milk: puts you to sleep for a stupid amount of time and you regenerate health a little bit.
|
||||
gelbanana: green gel banana. using it gives you 8 health.
|
||||
body armor: nullifies one hit that does 20 or more damage and then immediately breaks.
|
||||
|
||||
RECIPEES
|
||||
boot prop + boot prop = nighkeez
|
||||
nighkeez + bananas prop = clown shoes
|
||||
explosive barrel + explosive barrel = big explosive barrel
|
||||
oxygen canister + big explosive barrel = AWTH barrel
|
||||
stubber + knife = stabber
|
||||
milk + heat source = hot milk
|
||||
ammonia + bleach = mustard gas on the spot. spams yellow fumes everywhere and lethally poisons the user.
|
||||
bananas + microwave = gelbanana
|
||||
metal barrel + something = body armor
|
||||
--]]
|
||||
-- TODO: player introduced to a "main menu" sort of thing. auto joins as spectator. Requires recoding of a lot of logic because right now we assume only two possible teams and no spectator for humans.
|
||||
|
||||
AddCSLuaFile("cl_init.lua")
|
||||
AddCSLuaFile("shared.lua")
|
||||
|
@ -155,11 +135,11 @@ function GM:CreateGibs(pos, headoffset)
|
|||
end
|
||||
|
||||
function GM:TryHumanPickup(pl, entity)
|
||||
if self.ZombieEscape or pl.NoObjectPickup then return end
|
||||
if self.ZombieEscape or pl.NoObjectPickup or not pl:Alive() or pl:Team() ~= TEAM_HUMAN then return end
|
||||
|
||||
if entity:IsValid() and not entity.m_NoPickup then
|
||||
local entclass = string.sub(entity:GetClass(), 1, 12)
|
||||
if (entclass == "prop_physics" or entclass == "func_physbox" or entity.HumanHoldable and entity:HumanHoldable(pl)) and pl:Team() == TEAM_HUMAN and not entity:IsNailed() and pl:Alive() and entity:GetMoveType() == MOVETYPE_VPHYSICS and entity:GetPhysicsObject():IsValid() and entity:GetPhysicsObject():GetMass() <= CARRY_MAXIMUM_MASS and entity:GetPhysicsObject():IsMoveable() and entity:OBBMins():Length() + entity:OBBMaxs():Length() <= CARRY_MAXIMUM_VOLUME then
|
||||
if (entclass == "prop_physics" or entclass == "func_physbox" or entity.HumanHoldable and entity:HumanHoldable(pl)) and not entity:IsNailed() and entity:GetMoveType() == MOVETYPE_VPHYSICS and entity:GetPhysicsObject():IsValid() and entity:GetPhysicsObject():GetMass() <= CARRY_MAXIMUM_MASS and entity:GetPhysicsObject():IsMoveable() and entity:OBBMins():Length() + entity:OBBMaxs():Length() <= CARRY_MAXIMUM_VOLUME then
|
||||
local holder, status = entity:GetHolder()
|
||||
if not holder and not pl:IsHolding() and CurTime() >= (pl.NextHold or 0)
|
||||
and pl:GetShootPos():Distance(entity:NearestPoint(pl:GetShootPos())) <= 64 and pl:GetGroundEntity() ~= entity then
|
||||
|
@ -449,7 +429,7 @@ function GM:ShowSpare1(pl)
|
|||
else
|
||||
pl:SendLua("GAMEMODE:OpenClassSelect()")
|
||||
end
|
||||
else
|
||||
elseif pl:Team() == TEAM_HUMAN then
|
||||
pl:SendLua("MakepWeapons()")
|
||||
end
|
||||
end
|
||||
|
@ -497,6 +477,7 @@ function GM:SetupSpawnPoints()
|
|||
|
||||
team.SetSpawnPoint(TEAM_UNDEAD, ztab)
|
||||
team.SetSpawnPoint(TEAM_HUMAN, htab)
|
||||
team.SetSpawnPoint(TEAM_SPECTATOR, htab)
|
||||
|
||||
self.RedeemSpawnPoints = ents.FindByClass("info_player_redeemed")
|
||||
self.BossSpawnPoints = table.Add(ents.FindByClass("info_player_zombie_boss"), ents.FindByClass("info_player_undead_boss"))
|
||||
|
@ -901,7 +882,6 @@ function GM:Think()
|
|||
|
||||
local humans = team.GetPlayers(TEAM_HUMAN)
|
||||
for _, pl in pairs(humans) do
|
||||
if pl:Team() == TEAM_HUMAN then
|
||||
if pl:GetBarricadeGhosting() then
|
||||
pl:BarricadeGhostingThink()
|
||||
end
|
||||
|
@ -910,7 +890,6 @@ function GM:Think()
|
|||
pl:PointCashOut((pl.m_LastDamageDealtPosition or pl:GetPos()) + Vector(0, 0, 32), FM_NONE)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if wave == 0 then
|
||||
self:CalculateZombieVolunteers()
|
||||
|
@ -1021,7 +1000,7 @@ function GM:CalculateInfliction(victim, attacker)
|
|||
local humans = 0
|
||||
local wonhumans = 0
|
||||
local hum
|
||||
for _, pl in pairs(player.GetAll()) do
|
||||
for _, pl in pairs(player.GetAllActive()) do
|
||||
if not pl.Disconnecting then
|
||||
if pl:Team() == TEAM_UNDEAD then
|
||||
zombies = zombies + 1
|
||||
|
@ -1413,8 +1392,8 @@ function GM:InitPostEntityMap(fromze)
|
|||
end]]
|
||||
end
|
||||
|
||||
local function EndRoundPlayerShouldTakeDamage(pl, attacker) return pl:Team() ~= TEAM_HUMAN or not attacker:IsPlayer() end
|
||||
local function EndRoundPlayerCanSuicide(pl) return pl:Team() ~= TEAM_HUMAN end
|
||||
local function EndRoundPlayerShouldTakeDamage(pl, attacker) return pl:Team() == TEAM_UNDEAD or not attacker:IsPlayer() end
|
||||
local function EndRoundPlayerCanSuicide(pl) return pl:Team() == TEAM_UNDEAD end
|
||||
|
||||
local function EndRoundSetupPlayerVisibility(pl)
|
||||
if GAMEMODE.LastHumanPosition and GAMEMODE.RoundEnded then
|
||||
|
@ -1502,11 +1481,13 @@ function GM:PlayerReadyRound(pl)
|
|||
if pl:Team() == TEAM_UNDEAD then
|
||||
-- This is just so they get updated on what class they are and have their hulls set up right.
|
||||
pl:DoHulls(classid, TEAM_UNDEAD)
|
||||
elseif self:GetWave() <= 0 and self.StartingWorth > 0 and not self.StartingLoadout and not self.ZombieEscape then
|
||||
elseif pl:Team() == TEAM_HUMAN then
|
||||
if self:GetWave() <= 0 and self.StartingWorth > 0 and not self.StartingLoadout and not self.ZombieEscape then
|
||||
pl:SendLua("MakepWorth()")
|
||||
else
|
||||
gamemode.Call("GiveDefaultOrRandomEquipment", pl)
|
||||
end
|
||||
end
|
||||
|
||||
if self.RoundEnded then
|
||||
pl:SendLua("gamemode.Call(\"EndRound\", "..tostring(ROUNDWINNER)..", \""..game.GetMapNext().."\")")
|
||||
|
@ -1671,7 +1652,10 @@ function GM:PlayerInitialSpawnRound(pl)
|
|||
if self.PreviouslyDied[uniqueid] then
|
||||
-- They already died and reconnected.
|
||||
pl:ChangeTeam(TEAM_UNDEAD)
|
||||
elseif LASTHUMAN then
|
||||
--[[else
|
||||
pl:ChangeTeam(TEAM_SPECTATOR)
|
||||
pl:Spectate(OBS_MODE_ROAMING)]]
|
||||
elseif LASTHUMAN then ----
|
||||
-- Joined during last human.
|
||||
pl.SpawnedTime = CurTime()
|
||||
pl:ChangeTeam(TEAM_UNDEAD)
|
||||
|
@ -1688,7 +1672,7 @@ function GM:PlayerInitialSpawnRound(pl)
|
|||
pl:ChangeTeam(TEAM_HUMAN)
|
||||
if self.DynamicSpawning then
|
||||
timer.Simple(0, function() GAMEMODE:AttemptHumanDynamicSpawn(pl) end)
|
||||
end
|
||||
end ----
|
||||
end
|
||||
|
||||
if pl:Team() == TEAM_UNDEAD and not self:GetWaveActive() and self.ZombieClasses["Crow"] then
|
||||
|
@ -1751,7 +1735,7 @@ function GM:PlayerDisconnected(pl)
|
|||
self.StoredUndeadFrags[uid] = pl:Frags()
|
||||
end
|
||||
|
||||
if pl:Health() > 0 then
|
||||
if pl:Health() > 0 and not pl:IsSpectator() then
|
||||
local lastattacker = pl:GetLastAttacker()
|
||||
if IsValid(lastattacker) then
|
||||
pl:TakeDamage(1000, lastattacker, lastattacker)
|
||||
|
@ -2540,6 +2524,13 @@ function GM:OnPlayerChangedTeam(pl, oldteam, newteam)
|
|||
self.PreviouslyDied[pl:UniqueID()] = nil
|
||||
end
|
||||
|
||||
pl:SetLastAttacker(nil)
|
||||
for _, p in pairs(player.GetAll()) do
|
||||
if p.LastAttacker == pl then
|
||||
p.LastAttacker = nil
|
||||
end
|
||||
end
|
||||
|
||||
pl.m_PointQueue = 0
|
||||
|
||||
timer.Simple(0, function() gamemode.Call("CalculateInfliction") end)
|
||||
|
@ -2675,7 +2666,7 @@ function GM:SetBabyMode(mode)
|
|||
end
|
||||
|
||||
function GM:SetClosestsToZombie()
|
||||
local allplayers = player.GetAll()
|
||||
local allplayers = player.GetAllActive()
|
||||
local numplayers = #allplayers
|
||||
if numplayers <= 1 then return end
|
||||
|
||||
|
@ -2764,8 +2755,10 @@ function GM:PlayerHurt(victim, attacker, healthremaining, damage)
|
|||
attacker.DamageDealt[myteam] = attacker.DamageDealt[myteam] + damage
|
||||
|
||||
if myteam == TEAM_UNDEAD then
|
||||
if otherteam == TEAM_HUMAN then
|
||||
attacker:AddLifeHumanDamage(damage)
|
||||
elseif otherteam == TEAM_UNDEAD then
|
||||
end
|
||||
elseif myteam == TEAM_HUMAN and otherteam == TEAM_UNDEAD then
|
||||
victim.DamagedBy[attacker] = (victim.DamagedBy[attacker] or 0) + damage
|
||||
if (not victim.m_LastWaveStartSpawn or CurTime() >= victim.m_LastWaveStartSpawn + 3)
|
||||
and (healthremaining <= 0 or not victim.m_LastGasHeal or CurTime() >= victim.m_LastGasHeal + 2) then
|
||||
|
@ -3087,7 +3080,7 @@ function GM:DoPlayerDeath(pl, attacker, dmginfo)
|
|||
end
|
||||
end
|
||||
|
||||
if not revive and attacker:Team() ~= TEAM_UNDEAD then
|
||||
if not revive and attacker:Team() == TEAM_HUMAN then
|
||||
assistpl = gamemode.Call("HumanKilledZombie", pl, attacker, inflictor, dmginfo, headshot, suicide)
|
||||
end
|
||||
end
|
||||
|
@ -3101,7 +3094,7 @@ function GM:DoPlayerDeath(pl, attacker, dmginfo)
|
|||
end
|
||||
|
||||
pl:CallZombieFunction("PostOnKilled", attacker, inflictor, suicide, headshot, dmginfo)
|
||||
else
|
||||
elseif plteam == TEAM_HUMAN then
|
||||
pl.NextSpawnTime = ct + 4
|
||||
|
||||
pl:PlayDeathSound()
|
||||
|
@ -3143,7 +3136,7 @@ function GM:DoPlayerDeath(pl, attacker, dmginfo)
|
|||
end
|
||||
end
|
||||
|
||||
if revive or pl:CallZombieFunction("NoDeathMessage", attacker, dmginfo) then return end
|
||||
if revive or pl:CallZombieFunction("NoDeathMessage", attacker, dmginfo) or pl:IsSpectator() then return end
|
||||
|
||||
if attacker == pl then
|
||||
net.Start("zs_pl_kill_self")
|
||||
|
@ -3189,6 +3182,8 @@ function GM:PlayerKilledByPlayer(pl, attacker, inflictor, headshot, dmginfo)
|
|||
end
|
||||
|
||||
function GM:PlayerCanPickupWeapon(pl, ent)
|
||||
if pl:IsSpectator() then return false end
|
||||
|
||||
if pl:Team() == TEAM_UNDEAD then return ent:GetClass() == pl:GetZombieClassTable().SWEP end
|
||||
|
||||
return not ent.ZombieOnly and ent:GetClass() ~= "weapon_stunstick"
|
||||
|
@ -3516,7 +3511,7 @@ function GM:PlayerSpawn(pl)
|
|||
pl.SpawnedOnSpawnPoint = nil
|
||||
|
||||
pl:CallZombieFunction("OnSpawned")
|
||||
else
|
||||
elseif pl:Team() == TEAM_HUMAN then
|
||||
pl.m_PointQueue = 0
|
||||
pl.PackedItems = {}
|
||||
|
||||
|
@ -3705,8 +3700,7 @@ function GM:WaveStateChanged(newstate)
|
|||
net.WriteFloat(self:GetWaveEnd())
|
||||
net.Broadcast()
|
||||
|
||||
for _, pl in pairs(player.GetAll()) do
|
||||
if pl:Team() == TEAM_UNDEAD then
|
||||
for _, pl in pairs(team.GetPlayers(TEAM_UNDEAD)) do
|
||||
pl.m_LastWaveStartSpawn = CurTime()
|
||||
if pl:GetZombieClassTable().Name == "Crow" then
|
||||
pl:SetZombieClass(pl.DeathClass or 1)
|
||||
|
@ -3715,7 +3709,6 @@ function GM:WaveStateChanged(newstate)
|
|||
pl:UnSpectateAndSpawn()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local curwave = self:GetWave()
|
||||
for _, ent in pairs(ents.FindByClass("logic_waves")) do
|
||||
|
@ -3848,7 +3841,7 @@ function GM:PlayerSwitchFlashlight(pl, newstate)
|
|||
return false
|
||||
end
|
||||
|
||||
return true
|
||||
return pl:Team() == TEAM_HUMAN
|
||||
end
|
||||
|
||||
function GM:PlayerStepSoundTime(pl, iType, bWalking)
|
||||
|
|
|
@ -208,7 +208,7 @@ function meta:ThrowFromPosition(pos, force, noknockdown)
|
|||
self:SetGroundEntity(NULL)
|
||||
if SERVER and not noknockdown and self:IsPlayer() then
|
||||
local absforce = math.abs(force)
|
||||
if absforce >= 512 or self.Clumsy and self:Team() ~= TEAM_UNDEAD and absforce >= 32 then
|
||||
if absforce >= 512 or self.Clumsy and self:Team() == TEAM_HUMAN and absforce >= 32 then
|
||||
self:KnockDown()
|
||||
end
|
||||
end
|
||||
|
@ -240,7 +240,7 @@ function meta:ThrowFromPositionSetZ(pos, force, zmul, noknockdown)
|
|||
self:SetGroundEntity(NULL)
|
||||
if SERVER and not noknockdown and self:IsPlayer() then
|
||||
local absforce = math.max(math.abs(force) * math.abs(zmul), math.abs(force))
|
||||
if absforce >= 512 or self.Clumsy and self:Team() ~= TEAM_UNDEAD and absforce >= 32 then
|
||||
if absforce >= 512 or self.Clumsy and self:Team() == TEAM_HUMAN and absforce >= 32 then
|
||||
self:KnockDown()
|
||||
end
|
||||
end
|
||||
|
@ -264,7 +264,7 @@ function meta:PoisonDamage(damage, attacker, inflictor, hitpos, noreduction)
|
|||
local dmginfo = DamageInfo()
|
||||
|
||||
if self:IsPlayer() then
|
||||
if self:Team() == TEAM_UNDEAD then return end
|
||||
if self:Team() ~= TEAM_HUMAN then return end
|
||||
|
||||
if self.BuffResistant then
|
||||
damage = damage / 2
|
||||
|
|
|
@ -30,6 +30,11 @@ function meta:HasWon()
|
|||
return false
|
||||
end
|
||||
|
||||
local TEAM_SPECTATOR = TEAM_SPECTATOR
|
||||
function meta:IsSpectator()
|
||||
return self:Team() == TEAM_SPECTATOR
|
||||
end
|
||||
|
||||
function meta:GetBossZombieIndex()
|
||||
local bossclasses = {}
|
||||
for _, classtable in pairs(GAMEMODE.ZombieClasses) do
|
||||
|
@ -261,7 +266,7 @@ function meta:ProcessDamage(dmginfo)
|
|||
end
|
||||
|
||||
function meta:KnockDown(time)
|
||||
if self:Team() ~= TEAM_UNDEAD then
|
||||
if self:Team() == TEAM_HUMAN then
|
||||
self:GiveStatus("knockdown", time or 3)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -876,10 +876,10 @@ end
|
|||
|
||||
function meta:GetLastAttacker()
|
||||
local ent = self.LastAttacker
|
||||
if ent and ent:IsValid() and ent:Team() ~= self:Team() and CurTime() <= self.LastAttacked + 10 then
|
||||
if ent and ent:IsValid() and CurTime() <= self.LastAttacked + 10 then
|
||||
return ent
|
||||
end
|
||||
self:SetLastAttacker()
|
||||
--self:SetLastAttacker()
|
||||
end
|
||||
|
||||
function meta:SetLastAttacker(ent)
|
||||
|
|
|
@ -2,7 +2,7 @@ local TEAM_UNDEAD = TEAM_UNDEAD
|
|||
local ACT_MP_STAND_IDLE = ACT_MP_STAND_IDLE
|
||||
|
||||
function GM:PlayerShouldTaunt(pl, actid)
|
||||
return (pl:Team() == TEAM_HUMAN or pl:GetZombieClassTable().CanTaunt) and not IsValid(pl.Revive) and not IsValid(pl.FeignDeath)
|
||||
return (pl:Team() == TEAM_HUMAN or pl:Team() == TEAM_UNDEAD and pl:GetZombieClassTable().CanTaunt) and not IsValid(pl.Revive) and not IsValid(pl.FeignDeath)
|
||||
end
|
||||
|
||||
function GM:CalcMainActivity(pl, velocity)
|
||||
|
|
|
@ -1,3 +1,27 @@
|
|||
function player.GetAllActive()
|
||||
local t = {}
|
||||
|
||||
for _, pl in pairs(player.GetAll()) do
|
||||
if not pl:IsSpectator() then
|
||||
t[#t + 1] = pl
|
||||
end
|
||||
end
|
||||
|
||||
return t
|
||||
end
|
||||
|
||||
function player.GetAllSpectators()
|
||||
local t = {}
|
||||
|
||||
for _, pl in pairs(player.GetAll()) do
|
||||
if pl:IsSpectator() then
|
||||
t[#t + 1] = pl
|
||||
end
|
||||
end
|
||||
|
||||
return t
|
||||
end
|
||||
|
||||
function FindStartingItem(id)
|
||||
if not id then return end
|
||||
|
||||
|
|
|
@ -427,8 +427,9 @@ function GM:PlayerCanPurchase(pl)
|
|||
return pl:Team() == TEAM_HUMAN and self:GetWave() > 0 and pl:Alive() and pl:NearArsenalCrate()
|
||||
end
|
||||
|
||||
local TEAM_SPECTATOR = TEAM_SPECTATOR
|
||||
function GM:PlayerCanHearPlayersVoice(listener, talker)
|
||||
return listener:IsValid() and talker:IsValid() and listener:Team() == talker:Team()
|
||||
return listener:IsValid() and talker:IsValid() and listener:Team() == talker:Team() or listener:Team() == TEAM_SPECTATOR
|
||||
--[[if self:GetEndRound() then return true, false end
|
||||
|
||||
if listener:Team() == talker:Team() then
|
||||
|
@ -462,7 +463,7 @@ function GM:ScalePlayerDamage(pl, hitgroup, dmginfo)
|
|||
end
|
||||
|
||||
function GM:CanDamageNail(ent, attacker, inflictor, damage, dmginfo)
|
||||
return not attacker:IsPlayer() or attacker:Team() ~= TEAM_HUMAN
|
||||
return not attacker:IsPlayer() or attacker:Team() == TEAM_UNDEAD
|
||||
end
|
||||
|
||||
function GM:CanPlaceNail(pl, tr)
|
||||
|
|
|
@ -121,7 +121,7 @@ function GM:ProfilerPlayerValid(pl)
|
|||
|
||||
-- Are they inside something?
|
||||
local pos = plpos + Vector(0, 0, 1)
|
||||
if util.TraceHull({start = pos, endpos = pos + playerheight, mins = playermins, maxs = playermaxs, mask = MASK_SOLID, filter = team.GetPlayers(pl:Team())}).Hit then
|
||||
if util.TraceHull({start = pos, endpos = pos + playerheight, mins = playermins, maxs = playermaxs, mask = MASK_SOLID, filter = team.GetPlayers(TEAM_HUMAN)}).Hit then
|
||||
--print('inside')
|
||||
return false
|
||||
end
|
||||
|
|
|
@ -62,7 +62,7 @@ hook.Add("PlayerSpawn", "zombieescape", function(pl)
|
|||
timer.Simple(0, function()
|
||||
if not pl:IsValid() then return end
|
||||
|
||||
if GAMEMODE:GetWave() == 0 and not GAMEMODE:GetWaveActive() and (pl:Team() == TEAM_UNDEAD or CurTime() < GAMEMODE:GetWaveStart() - GAMEMODE.ZE_FreezeTime) then
|
||||
if GAMEMODE:GetWave() == 0 and not GAMEMODE:GetWaveActive() and (pl:Team() == TEAM_UNDEAD or pl:Team() == TEAM_HUMAN and CurTime() < GAMEMODE:GetWaveStart() - GAMEMODE.ZE_FreezeTime) then
|
||||
pl.ZEFreeze = true
|
||||
pl:Freeze(true)
|
||||
pl:GodEnable()
|
||||
|
|
|
@ -115,7 +115,7 @@ function CLASS:OnKilled(pl, attacker, inflictor, suicide, headshot, dmginfo)
|
|||
if attacker:IsPlayer() and attacker ~= pl then
|
||||
if attacker:Team() == TEAM_HUMAN then
|
||||
attacker.CrowKills = attacker.CrowKills + 1
|
||||
elseif attacker:GetZombieClassTable().Name == "Crow" then
|
||||
elseif attacker:Team() == TEAM_UNDEAD and attacker:GetZombieClassTable().Name == "Crow" then
|
||||
attacker.CrowVsCrowKills = attacker.CrowVsCrowKills + 1
|
||||
|
||||
net.Start("zs_crow_kill_crow")
|
||||
|
|
Loading…
Reference in a new issue