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')
|
include('shared.lua')
|
||||||
|
|
||||||
function ENT:Initialize()
|
function ENT:Initialize()
|
||||||
self.DieTime = CurTime() + 15
|
self.Touched = {}
|
||||||
|
self.OriginalAngles = self:GetAngles()
|
||||||
|
|
||||||
|
self:Fire("kill", "", 15)
|
||||||
|
|
||||||
self:SetModel("models/Items/CrossbowRounds.mdl")
|
self:SetModel("models/Items/CrossbowRounds.mdl")
|
||||||
self:PhysicsInit(SOLID_VPHYSICS)
|
self:PhysicsInit(SOLID_VPHYSICS)
|
||||||
|
@ -18,25 +21,18 @@ function ENT:Initialize()
|
||||||
phys:EnableDrag(false)
|
phys:EnableDrag(false)
|
||||||
phys:Wake()
|
phys:Wake()
|
||||||
end
|
end
|
||||||
self.Touched = {}
|
|
||||||
self.OriginalAngles = self:GetAngles()
|
|
||||||
|
|
||||||
self:EmitSound("weapons/crossbow/bolt_fly4.wav")
|
self:EmitSound("weapons/crossbow/bolt_fly4.wav")
|
||||||
end
|
end
|
||||||
|
|
||||||
function ENT:Think()
|
|
||||||
if self.DieTime <= CurTime() then
|
|
||||||
self:Remove()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function ENT:PhysicsCollide(data, phys)
|
function ENT:PhysicsCollide(data, phys)
|
||||||
if self.Done then return end
|
if self.Done then return end
|
||||||
self.Done = true
|
self.Done = true
|
||||||
|
|
||||||
|
self:Fire("kill", "", 8)
|
||||||
|
|
||||||
phys:EnableMotion(false)
|
phys:EnableMotion(false)
|
||||||
self:EmitSound("physics/metal/sawblade_stick"..math.random(3)..".wav")
|
self:EmitSound("physics/metal/sawblade_stick"..math.random(3)..".wav")
|
||||||
self.DieTime = CurTime() + 8
|
|
||||||
|
|
||||||
self:SetPos(data.HitPos)
|
self:SetPos(data.HitPos)
|
||||||
self:SetAngles(data.HitNormal:Angle())
|
self:SetAngles(data.HitNormal:Angle())
|
||||||
|
@ -51,18 +47,15 @@ function ENT:PhysicsCollide(data, phys)
|
||||||
end
|
end
|
||||||
|
|
||||||
function ENT:StartTouch(ent)
|
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
|
local owner = self:GetOwner()
|
||||||
ent:TakeDamage(100, owner, self)
|
if not owner:IsValid() then owner = self end
|
||||||
ent:EmitSound("weapons/crossbow/hitbod"..math.random(1,2)..".wav")
|
|
||||||
self.Touched[tostring(ent)] = true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function ENT:UpdateTransmitState()
|
if ent == owner or ent:IsPlayer() and (ent:Team() == self.Team or not ent:Alive()) then return end
|
||||||
return TRANSMIT_PVS
|
|
||||||
|
self.Touched[ent] = true
|
||||||
|
|
||||||
|
ent:TakeDamage(100, owner, self)
|
||||||
|
ent:EmitSound("weapons/crossbow/hitbod"..math.random(2)..".wav")
|
||||||
end
|
end
|
||||||
|
|
|
@ -24,7 +24,7 @@ end
|
||||||
|
|
||||||
function ENT:Think()
|
function ENT:Think()
|
||||||
if self.PhysicsData then
|
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
|
end
|
||||||
|
|
||||||
local parent = self:GetParent()
|
local parent = self:GetParent()
|
||||||
|
@ -33,7 +33,7 @@ function ENT:Think()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function ENT:Explode(vHitPos, vHitNormal, eHitEntity, vOldVelocity)
|
function ENT:Hit(vHitPos, vHitNormal, eHitEntity, vOldVelocity)
|
||||||
if self:GetHitTime() ~= 0 then return end
|
if self:GetHitTime() ~= 0 then return end
|
||||||
self:SetHitTime(CurTime())
|
self:SetHitTime(CurTime())
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,7 @@ end
|
||||||
|
|
||||||
function ENT:Think()
|
function ENT:Think()
|
||||||
if self.PhysicsData then
|
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
|
end
|
||||||
|
|
||||||
if self.DeathTime <= CurTime() then
|
if self.DeathTime <= CurTime() then
|
||||||
|
@ -32,7 +32,7 @@ function ENT:Think()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function ENT:Explode(vHitPos, vHitNormal, eHitEntity)
|
function ENT:Hit(vHitPos, vHitNormal, eHitEntity)
|
||||||
if self.Exploded then return end
|
if self.Exploded then return end
|
||||||
self.Exploded = true
|
self.Exploded = true
|
||||||
self.DeathTime = 0
|
self.DeathTime = 0
|
||||||
|
|
|
@ -38,7 +38,7 @@ function ENT:PhysicsCollide(data, phys)
|
||||||
end
|
end
|
||||||
|
|
||||||
function ENT:StartTouch(ent)
|
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()
|
local owner = self:GetOwner()
|
||||||
if not owner:IsValid() then owner = self end
|
if not owner:IsValid() then owner = self end
|
||||||
|
|
||||||
|
|
|
@ -50,7 +50,7 @@ function ENT:Use(activator, caller)
|
||||||
self:GiveToActivator(activator, caller)
|
self:GiveToActivator(activator, caller)
|
||||||
end
|
end
|
||||||
function ENT:GiveToActivator(activator, caller)
|
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.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
|
if self.PlacedInMap and GAMEMODE.WeaponRequiredForAmmo and team.NumPlayers(TEAM_HUMAN) > 1 then
|
||||||
local hasweapon = false
|
local hasweapon = false
|
||||||
|
|
|
@ -66,7 +66,7 @@ function ENT:DrawTranslucent()
|
||||||
local lp = LocalPlayer()
|
local lp = LocalPlayer()
|
||||||
local owner = self:GetOwner()
|
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()
|
local ang = EyeAngles()
|
||||||
ang.pitch = 0
|
ang.pitch = 0
|
||||||
local right = ang:Right()
|
local right = ang:Right()
|
||||||
|
|
|
@ -19,6 +19,9 @@ ENT.CanPackUp = true
|
||||||
ENT.IsBarricadeObject = true
|
ENT.IsBarricadeObject = true
|
||||||
ENT.AlwaysGhostable = true
|
ENT.AlwaysGhostable = true
|
||||||
|
|
||||||
|
local NextCache = 0
|
||||||
|
local CachedFilter = {}
|
||||||
|
|
||||||
function ENT:GetLocalAnglesToTarget(target)
|
function ENT:GetLocalAnglesToTarget(target)
|
||||||
return self:WorldToLocalAngles(self:GetAnglesToTarget(target))
|
return self:WorldToLocalAngles(self:GetAnglesToTarget(target))
|
||||||
end
|
end
|
||||||
|
@ -79,14 +82,13 @@ function ENT:GetScanFilter()
|
||||||
end
|
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.
|
-- 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()
|
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()
|
CachedFilter = self:GetScanFilter()
|
||||||
self.NextCache = CurTime() + 1
|
NextCache = CurTime() + 1
|
||||||
|
|
||||||
return self.CachedFilter
|
return CachedFilter
|
||||||
end
|
end
|
||||||
|
|
||||||
local tabSearch = {mask = MASK_SHOT}
|
local tabSearch = {mask = MASK_SHOT}
|
||||||
|
|
|
@ -88,7 +88,7 @@ function ENT:DrawTranslucent()
|
||||||
local lp = LocalPlayer()
|
local lp = LocalPlayer()
|
||||||
local owner = self:GetOwner()
|
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()
|
local ang = EyeAngles()
|
||||||
ang.pitch = 0
|
ang.pitch = 0
|
||||||
local right = ang:Right()
|
local right = ang:Right()
|
||||||
|
|
|
@ -49,7 +49,7 @@ function ENT:OnTakeDamage(dmginfo)
|
||||||
if not self.Destroyed then
|
if not self.Destroyed then
|
||||||
local attacker = dmginfo:GetAttacker()
|
local attacker = dmginfo:GetAttacker()
|
||||||
if not (attacker:IsValid() and attacker:IsPlayer() and attacker:Team() == TEAM_HUMAN) then
|
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())
|
attacker:AddLifeBarricadeDamage(dmginfo:GetDamage())
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -67,7 +67,7 @@ function ENT:DrawTranslucent()
|
||||||
local deployer = self:GetOwner()
|
local deployer = self:GetOwner()
|
||||||
if deployer:IsValid() then
|
if deployer:IsValid() then
|
||||||
displayowner = deployer:Name()
|
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
|
displayowner = "(DEAD) "..displayowner
|
||||||
redname = true
|
redname = true
|
||||||
end
|
end
|
||||||
|
|
|
@ -6,7 +6,7 @@ function ENT:Think()
|
||||||
local owner = self:GetOwner()
|
local owner = self:GetOwner()
|
||||||
if not owner:IsValid() or not owner:Alive() then return end
|
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 self:IsUnderwater() then
|
||||||
if owner:WaterLevel() < 3 and not (owner.NoAirBrush and owner.NoAirBrush:IsValid()) then
|
if owner:WaterLevel() < 3 and not (owner.NoAirBrush and owner.NoAirBrush:IsValid()) then
|
||||||
|
|
|
@ -72,7 +72,7 @@ function ENT:OnRemove()
|
||||||
|
|
||||||
owner:DrawWorldModel(true)
|
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()
|
local wep = owner:GetActiveWeapon()
|
||||||
if wep:IsValid() then
|
if wep:IsValid() then
|
||||||
wep:SendWeaponAnim(ACT_VM_DRAW)
|
wep:SendWeaponAnim(ACT_VM_DRAW)
|
||||||
|
|
|
@ -48,7 +48,6 @@ function SWEP:SecondaryAttack()
|
||||||
if CurTime() < self:GetNextPrimaryFire() or CurTime() < self:GetNextSecondaryFire() then return end
|
if CurTime() < self:GetNextPrimaryFire() or CurTime() < self:GetNextSecondaryFire() then return end
|
||||||
|
|
||||||
local owner = self.Owner
|
local owner = self.Owner
|
||||||
if owner:Team() ~= TEAM_UNDEAD then owner:Kill() return end
|
|
||||||
|
|
||||||
self:SetSwingAnimTime(CurTime() + 1)
|
self:SetSwingAnimTime(CurTime() + 1)
|
||||||
self.Owner:DoAnimationEvent(ACT_RANGE_ATTACK2)
|
self.Owner:DoAnimationEvent(ACT_RANGE_ATTACK2)
|
||||||
|
|
|
@ -54,12 +54,7 @@ function SWEP:Think()
|
||||||
|
|
||||||
owner:ResetSpeed()
|
owner:ResetSpeed()
|
||||||
|
|
||||||
if ent:IsValid() then
|
if ent:IsValid() and ent:IsPlayer() and ent:Team() == TEAM_UNDEAD and ent:Alive() and ent:GetZombieClassTable().Name == "Crow" then
|
||||||
local phys = ent:GetPhysicsObject()
|
|
||||||
if ent:IsPlayer() and (ent:Team() ~= TEAM_UNDEAD or ent:GetZombieClassTable().Name ~= "Crow") then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
ent:TakeSpecialDamage(2, DMG_SLASH, owner, self)
|
ent:TakeSpecialDamage(2, DMG_SLASH, owner, self)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -68,8 +63,6 @@ function SWEP:PrimaryAttack()
|
||||||
if CurTime() < self:GetNextPrimaryFire() or not self.Owner:IsOnGround() then return end
|
if CurTime() < self:GetNextPrimaryFire() or not self.Owner:IsOnGround() then return end
|
||||||
self:SetNextPrimaryFire(CurTime() + self.Primary.Delay)
|
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:EmitSound("NPC_Crow.Squawk")
|
||||||
self.Owner.EatAnim = CurTime() + 2
|
self.Owner.EatAnim = CurTime() + 2
|
||||||
|
|
||||||
|
@ -82,8 +75,6 @@ function SWEP:SecondaryAttack()
|
||||||
if CurTime() < self:GetNextSecondaryFire() then return end
|
if CurTime() < self:GetNextSecondaryFire() then return end
|
||||||
self:SetNextSecondaryFire(CurTime() + 1.6)
|
self:SetNextSecondaryFire(CurTime() + 1.6)
|
||||||
|
|
||||||
if self.Owner:Team() ~= TEAM_UNDEAD then self.Owner:Kill() return end
|
|
||||||
|
|
||||||
self.Owner:EmitSound("NPC_Crow.Alert")
|
self.Owner:EmitSound("NPC_Crow.Alert")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -51,12 +51,12 @@ end
|
||||||
|
|
||||||
function SWEP:SecondaryAttack()
|
function SWEP:SecondaryAttack()
|
||||||
if CurTime() < self:GetNextPrimaryFire() or CurTime() < self:GetNextSecondaryFire() then return end
|
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)
|
local owner = self.Owner
|
||||||
self.Owner:EmitSound("NPC_PoisonZombie.Throw")
|
|
||||||
self.Owner:SetSpeed(1)
|
owner:DoAnimationEvent(ACT_RANGE_ATTACK2)
|
||||||
|
owner:EmitSound("NPC_PoisonZombie.Throw")
|
||||||
|
owner:SetSpeed(1)
|
||||||
self:SetNextSecondaryFire(CurTime() + 4)
|
self:SetNextSecondaryFire(CurTime() + 4)
|
||||||
self:SetNextPrimaryFire(CurTime() + self.Primary.Delay)
|
self:SetNextPrimaryFire(CurTime() + self.Primary.Delay)
|
||||||
|
|
||||||
|
|
|
@ -93,7 +93,7 @@ function SWEP:DoAlert()
|
||||||
local mouthpos = owner:EyePos() + owner:GetUp() * -3
|
local mouthpos = owner:EyePos() + owner:GetUp() * -3
|
||||||
local screampos = mouthpos + owner:GetAimVector() * 16
|
local screampos = mouthpos + owner:GetAimVector() * 16
|
||||||
for _, ent in pairs(ents.FindInSphere(screampos, 92)) do
|
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 entearpos = ent:EyePos()
|
||||||
local dist = screampos:Distance(entearpos)
|
local dist = screampos:Distance(entearpos)
|
||||||
if dist <= 92 and TrueVisible(entearpos, screampos) then
|
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
|
if self.m_ZombieVision and MySelf:IsValid() and MySelf:Team() == TEAM_UNDEAD then
|
||||||
local eyepos = EyePos()
|
local eyepos = EyePos()
|
||||||
local eyedir = EyeAngles():Forward()
|
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())
|
local dlight = DynamicLight(MySelf:EntIndex())
|
||||||
if dlight then
|
if dlight then
|
||||||
|
@ -701,7 +701,7 @@ function GM:_HUDPaint()
|
||||||
|
|
||||||
if myteam == TEAM_UNDEAD then
|
if myteam == TEAM_UNDEAD then
|
||||||
self:ZombieHUD()
|
self:ZombieHUD()
|
||||||
else
|
elseif myteam == TEAM_HUMAN then
|
||||||
self:HumanHUD(screenscale)
|
self:HumanHUD(screenscale)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -776,9 +776,9 @@ function GM:ZombieHUD()
|
||||||
if obsmode ~= OBS_MODE_NONE then
|
if obsmode ~= OBS_MODE_NONE then
|
||||||
self:ZombieObserverHUD(obsmode)
|
self:ZombieObserverHUD(obsmode)
|
||||||
elseif not self:GetWaveActive() and not MySelf:Alive() then
|
elseif not self:GetWaveActive() and not MySelf:Alive() then
|
||||||
local th = draw_GetFontHeight("ZSHUDFont")
|
local th = draw_GetFontHeight("ZSHUDFont")
|
||||||
local x = ScrW() * 0.5
|
local x = ScrW() * 0.5
|
||||||
local y = ScrH() * 0.3
|
local y = ScrH() * 0.3
|
||||||
draw_SimpleTextBlur(translate.Get("waiting_for_next_wave"), "ZSHUDFont", x, y, COLOR_DARKRED, TEXT_ALIGN_CENTER)
|
draw_SimpleTextBlur(translate.Get("waiting_for_next_wave"), "ZSHUDFont", x, y, COLOR_DARKRED, TEXT_ALIGN_CENTER)
|
||||||
local pl = GAMEMODE.NextBossZombie
|
local pl = GAMEMODE.NextBossZombie
|
||||||
local bossname = GAMEMODE.NextBossZombieClass
|
local bossname = GAMEMODE.NextBossZombieClass
|
||||||
|
@ -1082,7 +1082,7 @@ function GM:_HUDPaintBackground()
|
||||||
surface_DrawTexturedRectRotated(bordersize / 2, h / 2, bordersize, h, 180)
|
surface_DrawTexturedRectRotated(bordersize / 2, h / 2, bordersize, h, 180)
|
||||||
surface_DrawTexturedRect(w - bordersize, 0, bordersize, h)]]
|
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_SetMaterial(matFilmGrain)
|
||||||
surface_SetDrawColor(0, 0, 0, (0.25 + 0.75 * self:CachedFearPower()) * self.FilmGrainOpacity)
|
surface_SetDrawColor(0, 0, 0, (0.25 + 0.75 * self:CachedFearPower()) * self.FilmGrainOpacity)
|
||||||
surface_DrawTexturedRectUV(0, 0, ScrW(), ScrH(), 2, 2, 0, 0)
|
surface_DrawTexturedRectUV(0, 0, ScrW(), ScrH(), 2, 2, 0, 0)
|
||||||
|
@ -1275,7 +1275,8 @@ function GM:_CreateMove(cmd)
|
||||||
BHopTime = CurTime() + 0.065
|
BHopTime = CurTime() + 0.065
|
||||||
end
|
end
|
||||||
|
|
||||||
if MySelf:Team() == TEAM_HUMAN then
|
local myteam = MySelf:Team()
|
||||||
|
if myteam == TEAM_HUMAN then
|
||||||
if MySelf:Alive() then
|
if MySelf:Alive() then
|
||||||
local lockon = self.HumanMenuLockOn
|
local lockon = self.HumanMenuLockOn
|
||||||
if lockon then
|
if lockon then
|
||||||
|
@ -1305,7 +1306,7 @@ function GM:_CreateMove(cmd)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
else
|
elseif myteam == TEAM_UNDEAD then
|
||||||
local buttons = cmd:GetButtons()
|
local buttons = cmd:GetButtons()
|
||||||
if bit.band(buttons, IN_ZOOM) ~= 0 then
|
if bit.band(buttons, IN_ZOOM) ~= 0 then
|
||||||
cmd:SetButtons(buttons - IN_ZOOM)
|
cmd:SetButtons(buttons - IN_ZOOM)
|
||||||
|
@ -1361,20 +1362,23 @@ 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.
|
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
|
undomodelblend = true
|
||||||
render.SetBlend(0)
|
render.SetBlend(0)
|
||||||
elseif MySelf:Team() == pl:Team() and pl ~= MySelf and not self.MedicalAura then
|
else
|
||||||
local radius = self.TransparencyRadius
|
local myteam = MySelf:Team()
|
||||||
if radius > 0 then
|
if myteam == pl:Team() and pl ~= MySelf and not self.MedicalAura then
|
||||||
local eyepos = EyePos()
|
local radius = self.TransparencyRadius
|
||||||
local dist = pl:NearestPoint(eyepos):Distance(eyepos)
|
if radius > 0 then
|
||||||
if dist < radius then
|
local eyepos = EyePos()
|
||||||
local blend = math.max((dist / radius) ^ 1.4, MySelf:Team() == TEAM_HUMAN and 0.04 or 0.1)
|
local dist = pl:NearestPoint(eyepos):Distance(eyepos)
|
||||||
render.SetBlend(blend)
|
if dist < radius then
|
||||||
if MySelf:Team() == TEAM_HUMAN and blend < 0.4 then
|
local blend = math.max((dist / radius) ^ 1.4, myteam == TEAM_HUMAN and 0.04 or 0.1)
|
||||||
render.ModelMaterialOverride(matWhite)
|
render.SetBlend(blend)
|
||||||
render.SetColorModulation(0.2, 0.2, 0.2)
|
if myteam == TEAM_HUMAN and blend < 0.4 then
|
||||||
shadowman = true
|
render.ModelMaterialOverride(matWhite)
|
||||||
|
render.SetColorModulation(0.2, 0.2, 0.2)
|
||||||
|
shadowman = true
|
||||||
|
end
|
||||||
|
undomodelblend = true
|
||||||
end
|
end
|
||||||
undomodelblend = true
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -214,7 +214,7 @@ function GM:_PostDrawOpaqueRenderables()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
else
|
elseif MySelf:Team() == TEAM_HUMAN then
|
||||||
self:DrawCraftingEntity()
|
self:DrawCraftingEntity()
|
||||||
|
|
||||||
local holding = MySelf.status_human_holding
|
local holding = MySelf.status_human_holding
|
||||||
|
|
|
@ -145,6 +145,8 @@ function PANEL:CreatePlayerPanel(pl)
|
||||||
local curpan = self:GetPlayerPanel(pl)
|
local curpan = self:GetPlayerPanel(pl)
|
||||||
if curpan and curpan:Valid() then return curpan end
|
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)
|
local panel = vgui.Create("ZSPlayerPanel", pl:Team() == TEAM_UNDEAD and self.ZombieList or self.HumanList)
|
||||||
panel:SetPlayer(pl)
|
panel:SetPlayer(pl)
|
||||||
panel:Dock(TOP)
|
panel:Dock(TOP)
|
||||||
|
@ -162,13 +164,13 @@ function PANEL:Refresh()
|
||||||
|
|
||||||
if self.PlayerPanels == nil then self.PlayerPanels = {} end
|
if self.PlayerPanels == nil then self.PlayerPanels = {} end
|
||||||
|
|
||||||
for _, panel in pairs(self.PlayerPanels) do
|
for pl, panel in pairs(self.PlayerPanels) do
|
||||||
if not panel:Valid() then
|
if not panel:Valid() or pl:IsValid() and pl:IsSpectator() then
|
||||||
self:RemovePlayerPanel(panel)
|
self:RemovePlayerPanel(panel)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
for _, pl in pairs(player.GetAll()) do
|
for _, pl in pairs(player.GetAllActive()) do
|
||||||
self:CreatePlayerPanel(pl)
|
self:CreatePlayerPanel(pl)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -250,7 +252,7 @@ function PANEL:Paint()
|
||||||
if pl:IsValid() then
|
if pl:IsValid() then
|
||||||
col = team.GetColor(pl:Team())
|
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
|
mul = 0.6 + math.abs(math.sin(RealTime() * 6)) * 0.4
|
||||||
elseif pl == MySelf then
|
elseif pl == MySelf then
|
||||||
mul = 0.8
|
mul = 0.8
|
||||||
|
@ -366,6 +368,8 @@ function PANEL:SetPlayer(pl)
|
||||||
self.m_SpecialImage:SetTooltip()
|
self.m_SpecialImage:SetTooltip()
|
||||||
self.m_SpecialImage:SetVisible(false)
|
self.m_SpecialImage:SetVisible(false)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
self.m_Flash = pl:SteamID() == "STEAM_0:1:3307510"
|
||||||
else
|
else
|
||||||
self.m_Avatar:SetVisible(false)
|
self.m_Avatar:SetVisible(false)
|
||||||
self.m_SpecialImage:SetVisible(false)
|
self.m_SpecialImage:SetVisible(false)
|
||||||
|
|
|
@ -53,13 +53,15 @@ function GM:HUDDrawTargetID(teamid)
|
||||||
trace.filter[1] = MySelf
|
trace.filter[1] = MySelf
|
||||||
trace.filter[2] = MySelf:GetObserverTarget()
|
trace.filter[2] = MySelf:GetObserverTarget()
|
||||||
|
|
||||||
|
local isspectator = MySelf:IsSpectator()
|
||||||
|
|
||||||
local entity = util.TraceHull(trace).Entity
|
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()
|
entitylist[entity] = CurTime()
|
||||||
end
|
end
|
||||||
|
|
||||||
for ent, time in pairs(entitylist) do
|
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))
|
self:DrawTargetID(ent, 1 - math.Clamp((CurTime() - time) / 2, 0, 1))
|
||||||
else
|
else
|
||||||
entitylist[ent] = nil
|
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
|
-- 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.
|
||||||
--[[
|
|
||||||
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
|
|
||||||
--]]
|
|
||||||
|
|
||||||
AddCSLuaFile("cl_init.lua")
|
AddCSLuaFile("cl_init.lua")
|
||||||
AddCSLuaFile("shared.lua")
|
AddCSLuaFile("shared.lua")
|
||||||
|
@ -155,11 +135,11 @@ function GM:CreateGibs(pos, headoffset)
|
||||||
end
|
end
|
||||||
|
|
||||||
function GM:TryHumanPickup(pl, entity)
|
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
|
if entity:IsValid() and not entity.m_NoPickup then
|
||||||
local entclass = string.sub(entity:GetClass(), 1, 12)
|
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()
|
local holder, status = entity:GetHolder()
|
||||||
if not holder and not pl:IsHolding() and CurTime() >= (pl.NextHold or 0)
|
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
|
and pl:GetShootPos():Distance(entity:NearestPoint(pl:GetShootPos())) <= 64 and pl:GetGroundEntity() ~= entity then
|
||||||
|
@ -449,7 +429,7 @@ function GM:ShowSpare1(pl)
|
||||||
else
|
else
|
||||||
pl:SendLua("GAMEMODE:OpenClassSelect()")
|
pl:SendLua("GAMEMODE:OpenClassSelect()")
|
||||||
end
|
end
|
||||||
else
|
elseif pl:Team() == TEAM_HUMAN then
|
||||||
pl:SendLua("MakepWeapons()")
|
pl:SendLua("MakepWeapons()")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -497,6 +477,7 @@ function GM:SetupSpawnPoints()
|
||||||
|
|
||||||
team.SetSpawnPoint(TEAM_UNDEAD, ztab)
|
team.SetSpawnPoint(TEAM_UNDEAD, ztab)
|
||||||
team.SetSpawnPoint(TEAM_HUMAN, htab)
|
team.SetSpawnPoint(TEAM_HUMAN, htab)
|
||||||
|
team.SetSpawnPoint(TEAM_SPECTATOR, htab)
|
||||||
|
|
||||||
self.RedeemSpawnPoints = ents.FindByClass("info_player_redeemed")
|
self.RedeemSpawnPoints = ents.FindByClass("info_player_redeemed")
|
||||||
self.BossSpawnPoints = table.Add(ents.FindByClass("info_player_zombie_boss"), ents.FindByClass("info_player_undead_boss"))
|
self.BossSpawnPoints = table.Add(ents.FindByClass("info_player_zombie_boss"), ents.FindByClass("info_player_undead_boss"))
|
||||||
|
@ -901,14 +882,12 @@ function GM:Think()
|
||||||
|
|
||||||
local humans = team.GetPlayers(TEAM_HUMAN)
|
local humans = team.GetPlayers(TEAM_HUMAN)
|
||||||
for _, pl in pairs(humans) do
|
for _, pl in pairs(humans) do
|
||||||
if pl:Team() == TEAM_HUMAN then
|
if pl:GetBarricadeGhosting() then
|
||||||
if pl:GetBarricadeGhosting() then
|
pl:BarricadeGhostingThink()
|
||||||
pl:BarricadeGhostingThink()
|
end
|
||||||
end
|
|
||||||
|
|
||||||
if pl.m_PointQueue >= 1 and time >= pl.m_LastDamageDealt + 3 then
|
if pl.m_PointQueue >= 1 and time >= pl.m_LastDamageDealt + 3 then
|
||||||
pl:PointCashOut((pl.m_LastDamageDealtPosition or pl:GetPos()) + Vector(0, 0, 32), FM_NONE)
|
pl:PointCashOut((pl.m_LastDamageDealtPosition or pl:GetPos()) + Vector(0, 0, 32), FM_NONE)
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -1021,7 +1000,7 @@ function GM:CalculateInfliction(victim, attacker)
|
||||||
local humans = 0
|
local humans = 0
|
||||||
local wonhumans = 0
|
local wonhumans = 0
|
||||||
local hum
|
local hum
|
||||||
for _, pl in pairs(player.GetAll()) do
|
for _, pl in pairs(player.GetAllActive()) do
|
||||||
if not pl.Disconnecting then
|
if not pl.Disconnecting then
|
||||||
if pl:Team() == TEAM_UNDEAD then
|
if pl:Team() == TEAM_UNDEAD then
|
||||||
zombies = zombies + 1
|
zombies = zombies + 1
|
||||||
|
@ -1413,8 +1392,8 @@ function GM:InitPostEntityMap(fromze)
|
||||||
end]]
|
end]]
|
||||||
end
|
end
|
||||||
|
|
||||||
local function EndRoundPlayerShouldTakeDamage(pl, attacker) return pl:Team() ~= TEAM_HUMAN or not attacker:IsPlayer() end
|
local function EndRoundPlayerShouldTakeDamage(pl, attacker) return pl:Team() == TEAM_UNDEAD or not attacker:IsPlayer() end
|
||||||
local function EndRoundPlayerCanSuicide(pl) return pl:Team() ~= TEAM_HUMAN end
|
local function EndRoundPlayerCanSuicide(pl) return pl:Team() == TEAM_UNDEAD end
|
||||||
|
|
||||||
local function EndRoundSetupPlayerVisibility(pl)
|
local function EndRoundSetupPlayerVisibility(pl)
|
||||||
if GAMEMODE.LastHumanPosition and GAMEMODE.RoundEnded then
|
if GAMEMODE.LastHumanPosition and GAMEMODE.RoundEnded then
|
||||||
|
@ -1502,10 +1481,12 @@ function GM:PlayerReadyRound(pl)
|
||||||
if pl:Team() == TEAM_UNDEAD then
|
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.
|
-- This is just so they get updated on what class they are and have their hulls set up right.
|
||||||
pl:DoHulls(classid, TEAM_UNDEAD)
|
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
|
||||||
pl:SendLua("MakepWorth()")
|
if self:GetWave() <= 0 and self.StartingWorth > 0 and not self.StartingLoadout and not self.ZombieEscape then
|
||||||
else
|
pl:SendLua("MakepWorth()")
|
||||||
gamemode.Call("GiveDefaultOrRandomEquipment", pl)
|
else
|
||||||
|
gamemode.Call("GiveDefaultOrRandomEquipment", pl)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if self.RoundEnded then
|
if self.RoundEnded then
|
||||||
|
@ -1671,7 +1652,10 @@ function GM:PlayerInitialSpawnRound(pl)
|
||||||
if self.PreviouslyDied[uniqueid] then
|
if self.PreviouslyDied[uniqueid] then
|
||||||
-- They already died and reconnected.
|
-- They already died and reconnected.
|
||||||
pl:ChangeTeam(TEAM_UNDEAD)
|
pl:ChangeTeam(TEAM_UNDEAD)
|
||||||
elseif LASTHUMAN then
|
--[[else
|
||||||
|
pl:ChangeTeam(TEAM_SPECTATOR)
|
||||||
|
pl:Spectate(OBS_MODE_ROAMING)]]
|
||||||
|
elseif LASTHUMAN then ----
|
||||||
-- Joined during last human.
|
-- Joined during last human.
|
||||||
pl.SpawnedTime = CurTime()
|
pl.SpawnedTime = CurTime()
|
||||||
pl:ChangeTeam(TEAM_UNDEAD)
|
pl:ChangeTeam(TEAM_UNDEAD)
|
||||||
|
@ -1688,7 +1672,7 @@ function GM:PlayerInitialSpawnRound(pl)
|
||||||
pl:ChangeTeam(TEAM_HUMAN)
|
pl:ChangeTeam(TEAM_HUMAN)
|
||||||
if self.DynamicSpawning then
|
if self.DynamicSpawning then
|
||||||
timer.Simple(0, function() GAMEMODE:AttemptHumanDynamicSpawn(pl) end)
|
timer.Simple(0, function() GAMEMODE:AttemptHumanDynamicSpawn(pl) end)
|
||||||
end
|
end ----
|
||||||
end
|
end
|
||||||
|
|
||||||
if pl:Team() == TEAM_UNDEAD and not self:GetWaveActive() and self.ZombieClasses["Crow"] then
|
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()
|
self.StoredUndeadFrags[uid] = pl:Frags()
|
||||||
end
|
end
|
||||||
|
|
||||||
if pl:Health() > 0 then
|
if pl:Health() > 0 and not pl:IsSpectator() then
|
||||||
local lastattacker = pl:GetLastAttacker()
|
local lastattacker = pl:GetLastAttacker()
|
||||||
if IsValid(lastattacker) then
|
if IsValid(lastattacker) then
|
||||||
pl:TakeDamage(1000, lastattacker, lastattacker)
|
pl:TakeDamage(1000, lastattacker, lastattacker)
|
||||||
|
@ -2540,6 +2524,13 @@ function GM:OnPlayerChangedTeam(pl, oldteam, newteam)
|
||||||
self.PreviouslyDied[pl:UniqueID()] = nil
|
self.PreviouslyDied[pl:UniqueID()] = nil
|
||||||
end
|
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
|
pl.m_PointQueue = 0
|
||||||
|
|
||||||
timer.Simple(0, function() gamemode.Call("CalculateInfliction") end)
|
timer.Simple(0, function() gamemode.Call("CalculateInfliction") end)
|
||||||
|
@ -2675,7 +2666,7 @@ function GM:SetBabyMode(mode)
|
||||||
end
|
end
|
||||||
|
|
||||||
function GM:SetClosestsToZombie()
|
function GM:SetClosestsToZombie()
|
||||||
local allplayers = player.GetAll()
|
local allplayers = player.GetAllActive()
|
||||||
local numplayers = #allplayers
|
local numplayers = #allplayers
|
||||||
if numplayers <= 1 then return end
|
if numplayers <= 1 then return end
|
||||||
|
|
||||||
|
@ -2764,8 +2755,10 @@ function GM:PlayerHurt(victim, attacker, healthremaining, damage)
|
||||||
attacker.DamageDealt[myteam] = attacker.DamageDealt[myteam] + damage
|
attacker.DamageDealt[myteam] = attacker.DamageDealt[myteam] + damage
|
||||||
|
|
||||||
if myteam == TEAM_UNDEAD then
|
if myteam == TEAM_UNDEAD then
|
||||||
attacker:AddLifeHumanDamage(damage)
|
if otherteam == TEAM_HUMAN then
|
||||||
elseif otherteam == TEAM_UNDEAD then
|
attacker:AddLifeHumanDamage(damage)
|
||||||
|
end
|
||||||
|
elseif myteam == TEAM_HUMAN and otherteam == TEAM_UNDEAD then
|
||||||
victim.DamagedBy[attacker] = (victim.DamagedBy[attacker] or 0) + damage
|
victim.DamagedBy[attacker] = (victim.DamagedBy[attacker] or 0) + damage
|
||||||
if (not victim.m_LastWaveStartSpawn or CurTime() >= victim.m_LastWaveStartSpawn + 3)
|
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
|
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
|
||||||
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)
|
assistpl = gamemode.Call("HumanKilledZombie", pl, attacker, inflictor, dmginfo, headshot, suicide)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -3101,7 +3094,7 @@ function GM:DoPlayerDeath(pl, attacker, dmginfo)
|
||||||
end
|
end
|
||||||
|
|
||||||
pl:CallZombieFunction("PostOnKilled", attacker, inflictor, suicide, headshot, dmginfo)
|
pl:CallZombieFunction("PostOnKilled", attacker, inflictor, suicide, headshot, dmginfo)
|
||||||
else
|
elseif plteam == TEAM_HUMAN then
|
||||||
pl.NextSpawnTime = ct + 4
|
pl.NextSpawnTime = ct + 4
|
||||||
|
|
||||||
pl:PlayDeathSound()
|
pl:PlayDeathSound()
|
||||||
|
@ -3143,7 +3136,7 @@ function GM:DoPlayerDeath(pl, attacker, dmginfo)
|
||||||
end
|
end
|
||||||
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
|
if attacker == pl then
|
||||||
net.Start("zs_pl_kill_self")
|
net.Start("zs_pl_kill_self")
|
||||||
|
@ -3189,6 +3182,8 @@ function GM:PlayerKilledByPlayer(pl, attacker, inflictor, headshot, dmginfo)
|
||||||
end
|
end
|
||||||
|
|
||||||
function GM:PlayerCanPickupWeapon(pl, ent)
|
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
|
if pl:Team() == TEAM_UNDEAD then return ent:GetClass() == pl:GetZombieClassTable().SWEP end
|
||||||
|
|
||||||
return not ent.ZombieOnly and ent:GetClass() ~= "weapon_stunstick"
|
return not ent.ZombieOnly and ent:GetClass() ~= "weapon_stunstick"
|
||||||
|
@ -3516,7 +3511,7 @@ function GM:PlayerSpawn(pl)
|
||||||
pl.SpawnedOnSpawnPoint = nil
|
pl.SpawnedOnSpawnPoint = nil
|
||||||
|
|
||||||
pl:CallZombieFunction("OnSpawned")
|
pl:CallZombieFunction("OnSpawned")
|
||||||
else
|
elseif pl:Team() == TEAM_HUMAN then
|
||||||
pl.m_PointQueue = 0
|
pl.m_PointQueue = 0
|
||||||
pl.PackedItems = {}
|
pl.PackedItems = {}
|
||||||
|
|
||||||
|
@ -3705,15 +3700,13 @@ function GM:WaveStateChanged(newstate)
|
||||||
net.WriteFloat(self:GetWaveEnd())
|
net.WriteFloat(self:GetWaveEnd())
|
||||||
net.Broadcast()
|
net.Broadcast()
|
||||||
|
|
||||||
for _, pl in pairs(player.GetAll()) do
|
for _, pl in pairs(team.GetPlayers(TEAM_UNDEAD)) do
|
||||||
if pl:Team() == TEAM_UNDEAD then
|
pl.m_LastWaveStartSpawn = CurTime()
|
||||||
pl.m_LastWaveStartSpawn = CurTime()
|
if pl:GetZombieClassTable().Name == "Crow" then
|
||||||
if pl:GetZombieClassTable().Name == "Crow" then
|
pl:SetZombieClass(pl.DeathClass or 1)
|
||||||
pl:SetZombieClass(pl.DeathClass or 1)
|
pl:UnSpectateAndSpawn()
|
||||||
pl:UnSpectateAndSpawn()
|
elseif not pl:Alive() and not pl.Revive then
|
||||||
elseif not pl:Alive() and not pl.Revive then
|
pl:UnSpectateAndSpawn()
|
||||||
pl:UnSpectateAndSpawn()
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -3848,7 +3841,7 @@ function GM:PlayerSwitchFlashlight(pl, newstate)
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
return true
|
return pl:Team() == TEAM_HUMAN
|
||||||
end
|
end
|
||||||
|
|
||||||
function GM:PlayerStepSoundTime(pl, iType, bWalking)
|
function GM:PlayerStepSoundTime(pl, iType, bWalking)
|
||||||
|
|
|
@ -208,7 +208,7 @@ function meta:ThrowFromPosition(pos, force, noknockdown)
|
||||||
self:SetGroundEntity(NULL)
|
self:SetGroundEntity(NULL)
|
||||||
if SERVER and not noknockdown and self:IsPlayer() then
|
if SERVER and not noknockdown and self:IsPlayer() then
|
||||||
local absforce = math.abs(force)
|
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()
|
self:KnockDown()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -240,7 +240,7 @@ function meta:ThrowFromPositionSetZ(pos, force, zmul, noknockdown)
|
||||||
self:SetGroundEntity(NULL)
|
self:SetGroundEntity(NULL)
|
||||||
if SERVER and not noknockdown and self:IsPlayer() then
|
if SERVER and not noknockdown and self:IsPlayer() then
|
||||||
local absforce = math.max(math.abs(force) * math.abs(zmul), math.abs(force))
|
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()
|
self:KnockDown()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -264,7 +264,7 @@ function meta:PoisonDamage(damage, attacker, inflictor, hitpos, noreduction)
|
||||||
local dmginfo = DamageInfo()
|
local dmginfo = DamageInfo()
|
||||||
|
|
||||||
if self:IsPlayer() then
|
if self:IsPlayer() then
|
||||||
if self:Team() == TEAM_UNDEAD then return end
|
if self:Team() ~= TEAM_HUMAN then return end
|
||||||
|
|
||||||
if self.BuffResistant then
|
if self.BuffResistant then
|
||||||
damage = damage / 2
|
damage = damage / 2
|
||||||
|
|
|
@ -30,6 +30,11 @@ function meta:HasWon()
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local TEAM_SPECTATOR = TEAM_SPECTATOR
|
||||||
|
function meta:IsSpectator()
|
||||||
|
return self:Team() == TEAM_SPECTATOR
|
||||||
|
end
|
||||||
|
|
||||||
function meta:GetBossZombieIndex()
|
function meta:GetBossZombieIndex()
|
||||||
local bossclasses = {}
|
local bossclasses = {}
|
||||||
for _, classtable in pairs(GAMEMODE.ZombieClasses) do
|
for _, classtable in pairs(GAMEMODE.ZombieClasses) do
|
||||||
|
@ -261,7 +266,7 @@ function meta:ProcessDamage(dmginfo)
|
||||||
end
|
end
|
||||||
|
|
||||||
function meta:KnockDown(time)
|
function meta:KnockDown(time)
|
||||||
if self:Team() ~= TEAM_UNDEAD then
|
if self:Team() == TEAM_HUMAN then
|
||||||
self:GiveStatus("knockdown", time or 3)
|
self:GiveStatus("knockdown", time or 3)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -876,10 +876,10 @@ end
|
||||||
|
|
||||||
function meta:GetLastAttacker()
|
function meta:GetLastAttacker()
|
||||||
local ent = self.LastAttacker
|
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
|
return ent
|
||||||
end
|
end
|
||||||
self:SetLastAttacker()
|
--self:SetLastAttacker()
|
||||||
end
|
end
|
||||||
|
|
||||||
function meta:SetLastAttacker(ent)
|
function meta:SetLastAttacker(ent)
|
||||||
|
|
|
@ -2,7 +2,7 @@ local TEAM_UNDEAD = TEAM_UNDEAD
|
||||||
local ACT_MP_STAND_IDLE = ACT_MP_STAND_IDLE
|
local ACT_MP_STAND_IDLE = ACT_MP_STAND_IDLE
|
||||||
|
|
||||||
function GM:PlayerShouldTaunt(pl, actid)
|
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
|
end
|
||||||
|
|
||||||
function GM:CalcMainActivity(pl, velocity)
|
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)
|
function FindStartingItem(id)
|
||||||
if not id then return end
|
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()
|
return pl:Team() == TEAM_HUMAN and self:GetWave() > 0 and pl:Alive() and pl:NearArsenalCrate()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local TEAM_SPECTATOR = TEAM_SPECTATOR
|
||||||
function GM:PlayerCanHearPlayersVoice(listener, talker)
|
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 self:GetEndRound() then return true, false end
|
||||||
|
|
||||||
if listener:Team() == talker:Team() then
|
if listener:Team() == talker:Team() then
|
||||||
|
@ -462,7 +463,7 @@ function GM:ScalePlayerDamage(pl, hitgroup, dmginfo)
|
||||||
end
|
end
|
||||||
|
|
||||||
function GM:CanDamageNail(ent, attacker, inflictor, damage, dmginfo)
|
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
|
end
|
||||||
|
|
||||||
function GM:CanPlaceNail(pl, tr)
|
function GM:CanPlaceNail(pl, tr)
|
||||||
|
|
|
@ -121,7 +121,7 @@ function GM:ProfilerPlayerValid(pl)
|
||||||
|
|
||||||
-- Are they inside something?
|
-- Are they inside something?
|
||||||
local pos = plpos + Vector(0, 0, 1)
|
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')
|
--print('inside')
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
|
@ -62,7 +62,7 @@ hook.Add("PlayerSpawn", "zombieescape", function(pl)
|
||||||
timer.Simple(0, function()
|
timer.Simple(0, function()
|
||||||
if not pl:IsValid() then return end
|
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.ZEFreeze = true
|
||||||
pl:Freeze(true)
|
pl:Freeze(true)
|
||||||
pl:GodEnable()
|
pl:GodEnable()
|
||||||
|
|
|
@ -115,7 +115,7 @@ function CLASS:OnKilled(pl, attacker, inflictor, suicide, headshot, dmginfo)
|
||||||
if attacker:IsPlayer() and attacker ~= pl then
|
if attacker:IsPlayer() and attacker ~= pl then
|
||||||
if attacker:Team() == TEAM_HUMAN then
|
if attacker:Team() == TEAM_HUMAN then
|
||||||
attacker.CrowKills = attacker.CrowKills + 1
|
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
|
attacker.CrowVsCrowKills = attacker.CrowVsCrowKills + 1
|
||||||
|
|
||||||
net.Start("zs_crow_kill_crow")
|
net.Start("zs_crow_kill_crow")
|
||||||
|
|
Loading…
Reference in a new issue