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:
JetBoom 2015-03-09 13:45:47 -04:00
parent f5c064a0e9
commit bd937c290e
30 changed files with 175 additions and 157 deletions

View file

@ -4,13 +4,16 @@ 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)
self:SetCollisionGroup(COLLISION_GROUP_WEAPON)
self:SetTrigger(true)
local phys = self:GetPhysicsObject()
if phys:IsValid() then
phys:SetMass(4)
@ -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
local owner = self:GetOwner()
if not owner:IsValid() then owner = self end
if self.Done or self.Touched[ent] or not ent:IsValid() then return 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
local owner = self:GetOwner()
if not owner:IsValid() then owner = self end
function ENT:UpdateTransmitState()
return TRANSMIT_PVS
if ent == owner or ent:IsPlayer() and (ent:Team() == self.Team or not ent:Alive()) then return end
self.Touched[ent] = true
ent:TakeDamage(100, owner, self)
ent:EmitSound("weapons/crossbow/hitbod"..math.random(2)..".wav")
end

View file

@ -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())

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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()

View file

@ -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}

View file

@ -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()

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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)

View file

@ -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)

View file

@ -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

View file

@ -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)

View file

@ -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

View file

@ -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
@ -776,9 +776,9 @@ function GM:ZombieHUD()
if obsmode ~= OBS_MODE_NONE then
self:ZombieObserverHUD(obsmode)
elseif not self:GetWaveActive() and not MySelf:Alive() then
local th = draw_GetFontHeight("ZSHUDFont")
local x = ScrW() * 0.5
local y = ScrH() * 0.3
local th = draw_GetFontHeight("ZSHUDFont")
local x = ScrW() * 0.5
local y = ScrH() * 0.3
draw_SimpleTextBlur(translate.Get("waiting_for_next_wave"), "ZSHUDFont", x, y, COLOR_DARKRED, TEXT_ALIGN_CENTER)
local pl = GAMEMODE.NextBossZombie
local bossname = GAMEMODE.NextBossZombieClass
@ -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,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.
undomodelblend = true
render.SetBlend(0)
elseif MySelf:Team() == 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)
render.SetBlend(blend)
if MySelf:Team() == TEAM_HUMAN and blend < 0.4 then
render.ModelMaterialOverride(matWhite)
render.SetColorModulation(0.2, 0.2, 0.2)
shadowman = true
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, myteam == TEAM_HUMAN and 0.04 or 0.1)
render.SetBlend(blend)
if myteam == TEAM_HUMAN and blend < 0.4 then
render.ModelMaterialOverride(matWhite)
render.SetColorModulation(0.2, 0.2, 0.2)
shadowman = true
end
undomodelblend = true
end
undomodelblend = true
end
end
end

View file

@ -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

View file

@ -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)

View file

@ -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

View file

@ -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,14 +882,12 @@ 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
if pl:GetBarricadeGhosting() then
pl:BarricadeGhostingThink()
end
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)
end
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)
end
end
@ -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,10 +1481,12 @@ 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
pl:SendLua("MakepWorth()")
else
gamemode.Call("GiveDefaultOrRandomEquipment", pl)
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
@ -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
attacker:AddLifeHumanDamage(damage)
elseif otherteam == TEAM_UNDEAD then
if otherteam == TEAM_HUMAN then
attacker:AddLifeHumanDamage(damage)
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,15 +3700,13 @@ function GM:WaveStateChanged(newstate)
net.WriteFloat(self:GetWaveEnd())
net.Broadcast()
for _, pl in pairs(player.GetAll()) do
if pl:Team() == TEAM_UNDEAD then
pl.m_LastWaveStartSpawn = CurTime()
if pl:GetZombieClassTable().Name == "Crow" then
pl:SetZombieClass(pl.DeathClass or 1)
pl:UnSpectateAndSpawn()
elseif not pl:Alive() and not pl.Revive then
pl:UnSpectateAndSpawn()
end
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)
pl:UnSpectateAndSpawn()
elseif not pl:Alive() and not pl.Revive then
pl:UnSpectateAndSpawn()
end
end
@ -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)

View file

@ -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

View file

@ -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

View file

@ -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)

View file

@ -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)

View file

@ -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

View file

@ -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)

View file

@ -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

View file

@ -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()

View file

@ -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")