Merge with current nox changes.

Random starting loadouts now include things that aren't weapons (ammo,
traits, etc.).
Added an option to disable the automatic suicide when changing zombie
classes.
Zombies will no longer receive damage resistance when only one human
remains.
Players can no longer claim the arsenal crate that gets spawned in the
human spawn when nobody has one. Any player can pack it up though.
The Ghoul's ghoul touch special ability has been changed. It will no
longer slow targets but will debuff them for the next 10 seconds. They
will take 40% more damage (the extra damage is attributed to the person
who ghoul touched them last) for the next 10 seconds as well as slightly
disorienting them.
The Ghoul movement speed has been reduced from 185 to 170.
Added crafting recipe: 'Waraxe' Handgun. Combine two 'Battleaxe'
Handguns to craft this. Slightly better version of the Owens.
The Flesh Creeper model has been changed to one that doesn't have
severely awkward hitboxes.
The Flesh Creeper can no longer jump and attack at the same time.
The Lead Pipe special trait has been changed from a disorientation to a
severe view punch/snap on a global cooldown of 1.5 seconds.
The Regenerative trait is now 1 health every 6 seconds under 50% health
instead of 1 health every 5 seconds under 50% health.
Fast Zombie Legs have been changed to be a slightly faster but slightly
weaker version of Zombie Legs.
Zombies that have just spawned or enter zombie gas will now have a
temporary buff which gives 25% extra speed and 40% damage resistance.
This buff lasts for 3 seconds and is refreshed by entering the gas. Gas
will no longer heal. Zombies with this buff on will strobe dark green.
Added crafting recipe: Bladehack. Combine a saw blade with a manhack to
get this. Slower but has more health, does more damage, and has less of
a knockback when hitting something.
Resupply Boxes now award the owner a point for every 2 people who use
their box instead of every single person (so half as many points).
Fixed Fast Zombie Legs spawning much more abundantly than intended.
Fixed Flesh Creepers not being able to jump over obstacles due to their
insanely low jump height.
Fixed zombies taking themselves in to account when calculating horde
damage resistance (bosses always had full resistance because of this).
Fixed allowing people to use worth menu after redeeming.
This commit is contained in:
JetBoom 2014-11-07 00:03:40 -05:00
parent 18126da912
commit 53743b1aee
29 changed files with 423 additions and 109 deletions

View file

@ -84,7 +84,8 @@ end
function ENT:Use(activator, caller) function ENT:Use(activator, caller)
local ishuman = activator:Team() == TEAM_HUMAN and activator:Alive() local ishuman = activator:Team() == TEAM_HUMAN and activator:Alive()
if not self:GetObjectOwner():IsValid() and ishuman then
if not self.NoTakeOwnership and not self:GetObjectOwner():IsValid() and ishuman then
self:SetObjectOwner(activator) self:SetObjectOwner(activator)
end end

View file

@ -146,7 +146,9 @@ function ENT:Use(activator, caller)
if activator ~= owner and owner:IsValid() and owner:IsPlayer() and owner:Team() == TEAM_HUMAN then if activator ~= owner and owner:IsValid() and owner:IsPlayer() and owner:Team() == TEAM_HUMAN then
owner.ResupplyBoxUsedByOthers = owner.ResupplyBoxUsedByOthers + 1 owner.ResupplyBoxUsedByOthers = owner.ResupplyBoxUsedByOthers + 1
owner:AddPoints(1) if owner.ResupplyBoxUsedByOthers % 2 == 0 then
owner:AddPoints(1)
end
net.Start("zs_commission") net.Start("zs_commission")
net.WriteEntity(self) net.WriteEntity(self)

View file

@ -0,0 +1,104 @@
AddCSLuaFile()
ENT.Type = "anim"
ENT.Base = "status__base"
ENT.RenderGroup = RENDERGROUP_TRANSLUCENT
ENT.DamageScale = 1.3
ENT.LifeTime = 10
ENT.Model = Model("models/gibs/HGIBS.mdl")
function ENT:Initialize()
self.BaseClass.Initialize(self)
self:SetModel(self.Model)
self:DrawShadow(false)
if SERVER then
hook.Add("EntityTakeDamage", self, self.EntityTakeDamage)
hook.Add("PlayerHurt", self, self.PlayerHurt)
self:EmitSound("beams/beamstart5.wav", 65, 140)
end
if CLIENT then
hook.Add("PrePlayerDraw", self, self.PrePlayerDraw)
hook.Add("PostPlayerDraw", self, self.PostPlayerDraw)
hook.Add("RenderScreenspaceEffects", self, self.RenderScreenspaceEffects)
end
self.DieTime = CurTime() + self.LifeTime
end
if SERVER then
function ENT:EntityTakeDamage(ent, dmginfo)
if ent ~= self:GetOwner() then return end
local attacker = dmginfo:GetAttacker()
if attacker:IsValid() and attacker:IsPlayer() and attacker:Team() == TEAM_UNDEAD then
dmginfo:SetDamage(dmginfo:GetDamage() * self.DamageScale)
end
end
function ENT:PlayerHurt(pl, attacker, healthleft, damage)
if attacker:IsValid() and attacker:IsPlayer() and attacker ~= pl and attacker:Team() == TEAM_UNDEAD then
local attributeddamage = damage
if healthleft < 0 then
attributeddamage = attributeddamage + healthleft
end
if attributeddamage > 0 then
local myteam = pl:Team()
attributeddamage = attributeddamage * (self.DamageScale - 1)
attacker.DamageDealt[myteam] = attacker.DamageDealt[myteam] + attributeddamage
attacker:AddLifeHumanDamage(attributeddamage)
end
end
end
end
if not CLIENT then return end
function ENT:DrawTranslucent()
local owner = self:GetOwner()
if not owner:IsValid() then return end
render.SetColorModulation(1, 0, 0)
render.SetBlend(self:GetPower() * 0.95)
render.SuppressEngineLighting(true)
self:SetRenderOrigin(owner:GetPos() + Vector(0, 0, owner:OBBMaxs().z + math.abs(math.sin(CurTime() * 2)) * 4))
self:SetRenderAngles(Angle(0, CurTime() * 270, 0))
self:DrawModel()
render.SuppressEngineLighting(false)
render.SetBlend(1)
render.SetColorModulation(1, 1, 1)
end
function ENT:PrePlayerDraw(pl)
if pl ~= self:GetOwner() then return end
local r = 1 - math.abs(math.sin((CurTime() + self:EntIndex()) * 3)) * 0.2
render.SetColorModulation(r, 0.1, 0.1)
end
function ENT:PostPlayerDraw(pl)
if pl ~= self:GetOwner() then return end
render.SetColorModulation(1, 1, 1)
end
function ENT:GetPower()
return math.Clamp(self.DieTime - CurTime(), 0, 1)
end
function ENT:RenderScreenspaceEffects()
if LocalPlayer() ~= self:GetOwner() then return end
DrawMotionBlur(0.1, self:GetPower() * 0.3, 0.01)
end

View file

@ -101,6 +101,9 @@ function ENT:OnRemove()
object:CollisionRulesChanged() object:CollisionRulesChanged()
end end
object._LastDroppedBy = owner
object._LastDropped = CurTime()
for _, ent in pairs(ents.FindByClass("logic_pickupdrop")) do for _, ent in pairs(ents.FindByClass("logic_pickupdrop")) do
if ent.EntityToWatch == object:GetName() and ent:IsValid() then if ent.EntityToWatch == object:GetName() and ent:IsValid() then
ent:Input("ondropped", owner, object, "") ent:Input("ondropped", owner, object, "")

View file

@ -0,0 +1,47 @@
AddCSLuaFile()
ENT.Type = "anim"
ENT.Base = "status__base"
function ENT:Initialize()
self.BaseClass.Initialize(self)
hook.Add("Move", self, self.Move)
hook.Add("EntityTakeDamage", self, self.EntityTakeDamage)
if CLIENT then
hook.Add("PrePlayerDraw", self, self.PrePlayerDraw)
hook.Add("PostPlayerDraw", self, self.PostPlayerDraw)
end
end
function ENT:Move(pl, move)
if pl ~= self:GetOwner() then return end
move:SetMaxSpeed(move:GetMaxSpeed() * 1.25)
move:SetMaxClientSpeed(move:GetMaxSpeed())
end
function ENT:EntityTakeDamage(ent, dmginfo)
if ent ~= self:GetOwner() then return end
local attacker = dmginfo:GetAttacker()
if attacker:IsValid() and attacker:IsPlayer() then
dmginfo:SetDamage(dmginfo:GetDamage() * 0.4)
end
end
if not CLIENT then return end
function ENT:PrePlayerDraw(pl)
if pl ~= self:GetOwner() then return end
local r = math.abs(math.sin((CurTime() + self:EntIndex()) * 3)) * 0.6
render.SetColorModulation(r, 1, r)
end
function ENT:PostPlayerDraw(pl)
if pl ~= self:GetOwner() then return end
render.SetColorModulation(1, 1, 1)
end

View file

@ -54,6 +54,7 @@ function ENT:Touch(ent)
local prevpos = ent:GetPos() local prevpos = ent:GetPos()
local prevang = ent:EyeAngles() local prevang = ent:EyeAngles()
ent:SetZombieClass(k) ent:SetZombieClass(k)
ent.DidntSpawnOnSpawnPoint = true
ent:UnSpectateAndSpawn() ent:UnSpectateAndSpawn()
if self.OneTime then if self.OneTime then
ent.DeathClass = prev ent.DeathClass = prev
@ -87,6 +88,7 @@ function ENT:EndTouch(ent)
local prevpos = ent:GetPos() local prevpos = ent:GetPos()
local prevang = ent:GetAngles() local prevang = ent:GetAngles()
ent:SetZombieClass(k) ent:SetZombieClass(k)
ent.DidntSpawnOnSpawnPoint = true
ent:UnSpectateAndSpawn() ent:UnSpectateAndSpawn()
if self.OneTime then if self.OneTime then
ent.DeathClass = prev ent.DeathClass = prev

View file

@ -39,12 +39,14 @@ function ENT:AcceptInput(name, activator, caller, arg)
for _, ent in pairs(ents.FindInSphere(vPos, self:GetRadius())) do for _, ent in pairs(ents.FindInSphere(vPos, self:GetRadius())) do
if ent:IsPlayer() and ent:Alive() and WorldVisible(vPos, ent:NearestPoint(vPos)) then if ent:IsPlayer() and ent:Alive() and WorldVisible(vPos, ent:NearestPoint(vPos)) then
if ent:Team() == TEAM_UNDEAD then if ent:Team() == TEAM_UNDEAD then
if ent:Health() < ent:GetMaxHealth() and not ent:GetZombieClassTable().Boss then --[[if ent:Health() < ent:GetMaxHealth() and not ent:GetZombieClassTable().Boss then
ent:SetHealth(math.min(ent:GetMaxZombieHealth(), ent:Health() + self.Heal)) ent:SetHealth(math.min(ent:GetMaxZombieHealth(), ent:Health() + self.Heal))
ent.m_LastGasHeal = CurTime() ent.m_LastGasHeal = CurTime()
end end]]
ent:GiveStatus("zombiespawnbuff", 3)
elseif 1 < ent:Health() then elseif 1 < ent:Health() then
ent:PoisonDamage(math.min(10, ent:Health() - 1), self, self) --ent:PoisonDamage(math.min(10, ent:Health() - 1), self, self)
ent:PoisonDamage(math.min(5, ent:Health() - 1), self, self)
end end
end end
end end

View file

@ -6,13 +6,18 @@ end
SWEP.Base = "weapon_zs_zombie" SWEP.Base = "weapon_zs_zombie"
SWEP.MeleeDamage = 26 SWEP.MeleeDamage = 15
SWEP.MeleeForceScale = 0.1 SWEP.MeleeForceScale = 0.5
SWEP.SlowDownScale = 0.25
--[[SWEP.MeleeForceScale = 0.1
SWEP.SlowDownScale = 2.25 SWEP.SlowDownScale = 2.25
SWEP.SlowDownImmunityTime = 2 SWEP.SlowDownImmunityTime = 2]]
function SWEP:ApplyMeleeDamage(ent, trace, damage) function SWEP:ApplyMeleeDamage(ent, trace, damage)
ent:PoisonDamage(damage, self.Owner, self, trace.HitPos) ent:PoisonDamage(damage, self.Owner, self, trace.HitPos)
if SERVER and ent:IsPlayer() then
ent:GiveStatus("ghoultouch", 10)
end
end end
function SWEP:Reload() function SWEP:Reload()

View file

@ -50,8 +50,22 @@ end
if SERVER then if SERVER then
function SWEP:OnMeleeHit(hitent, hitflesh, tr) function SWEP:OnMeleeHit(hitent, hitflesh, tr)
if hitent:IsValid() and hitent:IsPlayer() and hitent:GetZombieClassTable().Name ~= "Shade" then if hitent:IsValid() and hitent:IsPlayer() and hitent:GetZombieClassTable().Name ~= "Shade" and CurTime() >= (hitent._NextLeadPipeEffect or 0) then
hitent:GiveStatus("disorientation") hitent._NextLeadPipeEffect = CurTime() + 1.5
--hitent:GiveStatus("disorientation")
local x = math.Rand(0.75, 1)
x = x * (math.random(2) == 2 and 1 or -1)
local ang = Angle(1 - x, x, 0) * 38
hitent:ViewPunch(ang)
local eyeangles = hitent:EyeAngles()
eyeangles:RotateAroundAxis(eyeangles:Up(), ang.yaw)
eyeangles:RotateAroundAxis(eyeangles:Right(), ang.pitch)
eyeangles.pitch = math.Clamp(ang.pitch, -89, 89)
eyeangles.roll = 0
hitent:SetEyeAngles(eyeangles)
end end
end end
end end

View file

@ -20,15 +20,18 @@ if CLIENT then
} }
end end
SWEP.Primary.Damage = 18 SWEP.Primary.Damage = 14
SWEP.Primary.NumShots = 2 SWEP.Primary.NumShots = 2
SWEP.Primary.Delay = 0.2 SWEP.Primary.Delay = 0.2
SWEP.Primary.ClipSize = 15 SWEP.Primary.ClipSize = 14
SWEP.Primary.Automatic = false SWEP.Primary.Automatic = false
SWEP.Primary.Ammo = "pistol" SWEP.Primary.Ammo = "pistol"
GAMEMODE:SetupDefaultClip(SWEP.Primary) GAMEMODE:SetupDefaultClip(SWEP.Primary)
SWEP.ConeMax = 0.07
SWEP.ConeMin = 0.03
function SWEP:EmitFireSound() function SWEP:EmitFireSound()
self:EmitSound(self.Primary.Sound, 80, 75) self:EmitSound(self.Primary.Sound, 80, 75)
end end

View file

@ -1,37 +0,0 @@
AddCSLuaFile()
if _FIXEDEMITTERS_ or not CLIENT then return end
_FIXEDEMITTERS_ = true
local emitter3d, emitter2d
local ParticleEmitterOld = ParticleEmitter
function ParticleEmitter(vec, threedee)
if threedee then
if emitter3d == nil then
emitter3d = ParticleEmitterOld(vec, true)
else
emitter3d:SetPos(vec)
end
return emitter3d
end
if emitter2d == nil then
emitter2d = ParticleEmitterOld(vec)
else
emitter2d:SetPos(vec)
end
return emitter2d
end
local meta = FindMetaTable("CLuaEmitter")
if not meta then return end
local oldadd = meta.Add
function meta:Add(a, b, c)
self:SetPos(b)
return oldadd(self, a, b, c)
end

View file

@ -128,6 +128,28 @@ local draw_GetFontHeight = draw.GetFontHeight
local MedicalAuraDistance = 400 local MedicalAuraDistance = 400
GM.LifeStatsBrainsEaten = 0
GM.LifeStatsHumanDamage = 0
GM.LifeStatsBarricadeDamage = 0
GM.InputMouseX = 0
GM.InputMouseY = 0
GM.LastTimeDead = 0
GM.LastTimeAlive = 0
GM.HeartBeatTime = 0
GM.FOVLerp = 1
GM.HurtEffect = 0
GM.PrevHealth = 0
GM.SuppressArsenalTime = 0
GM.ZombieThirdPerson = false
GM.Beats = {}
GM.DeathFog = 0
GM.FogStart = 0
GM.FogEnd = 8000
GM.FogRed = 30
GM.FogGreen = 30
GM.FogBlue = 30
function GM:ClickedPlayerButton(pl, button) function GM:ClickedPlayerButton(pl, button)
end end
@ -146,8 +168,6 @@ function GM:TopNotify(...)
end end
end end
GM.InputMouseX = 0
GM.InputMouseY = 0
function GM:_InputMouseApply(cmd, x, y, ang) function GM:_InputMouseApply(cmd, x, y, ang)
self.InputMouseX = x self.InputMouseX = x
self.InputMouseY = y self.InputMouseY = y
@ -295,12 +315,6 @@ function GM:PostDrawSkyBox()
cam.End3D() cam.End3D()
end end
GM.DeathFog = 0
GM.FogStart = 0
GM.FogEnd = 8000
GM.FogRed = 30
GM.FogGreen = 30
GM.FogBlue = 30
function GM:GetFogData() function GM:GetFogData()
local fogstart, fogend = render.GetFogDistances() local fogstart, fogend = render.GetFogDistances()
local fogr, fogg, fogb = render.GetFogColor() local fogr, fogg, fogb = render.GetFogColor()
@ -427,9 +441,6 @@ function GM:GetDynamicSpawning()
return not GetGlobalBool("DynamicSpawningDisabled", false) return not GetGlobalBool("DynamicSpawningDisabled", false)
end end
GM.LastTimeDead = 0
GM.LastTimeAlive = 0
function GM:TrackLastDeath() function GM:TrackLastDeath()
if MySelf:Alive() then if MySelf:Alive() then
self.LastTimeAlive = CurTime() self.LastTimeAlive = CurTime()
@ -467,10 +478,6 @@ function GM:PostRender()
end end
local lastwarntim = -1 local lastwarntim = -1
GM.HeartBeatTime = 0
GM.FOVLerp = 1
GM.HurtEffect = 0
GM.PrevHealth = 0
local NextGas = 0 local NextGas = 0
function GM:_Think() function GM:_Think()
if self:GetEscapeStage() == ESCAPESTAGE_DEATH then if self:GetEscapeStage() == ESCAPESTAGE_DEATH then
@ -980,7 +987,6 @@ local function FirstOfGoodType(a)
end end
end end
GM.Beats = {}
function GM:InitializeBeats() function GM:InitializeBeats()
local _, dirs = file.Find("sound/zombiesurvival/beats/*", "GAME") local _, dirs = file.Find("sound/zombiesurvival/beats/*", "GAME")
for _, dirname in pairs(dirs) do for _, dirname in pairs(dirs) do
@ -1144,7 +1150,6 @@ function GM:HumanMenu()
panel:OpenMenu() panel:OpenMenu()
end end
GM.ZombieThirdPerson = false
function GM:PlayerBindPress(pl, bind, wasin) function GM:PlayerBindPress(pl, bind, wasin)
if bind == "gmod_undo" or bind == "undo" then if bind == "gmod_undo" or bind == "undo" then
RunConsoleCommand("+zoom") RunConsoleCommand("+zoom")
@ -1276,6 +1281,11 @@ function GM:_CreateMove(cmd)
end end
end end
else else
local buttons = cmd:GetButtons()
if bit.band(buttons, IN_ZOOM) ~= 0 then
cmd:SetButtons(buttons - IN_ZOOM)
end
MySelf:CallZombieFunction("CreateMove", cmd) MySelf:CallZombieFunction("CreateMove", cmd)
end end
end end
@ -1566,7 +1576,6 @@ function GM:CloseWorth()
end end
end end
GM.SuppressArsenalTime = 0
function GM:SuppressArsenalUpgrades(suppresstime) function GM:SuppressArsenalUpgrades(suppresstime)
self.SuppressArsenalTime = math.max(CurTime() + suppresstime, self.SuppressArsenalTime) self.SuppressArsenalTime = math.max(CurTime() + suppresstime, self.SuppressArsenalTime)
end end

View file

@ -34,6 +34,11 @@ end)
CreateClientConVar("zs_noredeem", "0", true, true) CreateClientConVar("zs_noredeem", "0", true, true)
CreateClientConVar("zs_alwaysvolunteer", "0", true, true) CreateClientConVar("zs_alwaysvolunteer", "0", true, true)
GM.SuicideOnChangeClass = CreateClientConVar("zs_suicideonchange", "1", true, false):GetBool()
cvars.AddChangeCallback("zs_suicideonchange", function(cvar, oldvalue, newvalue)
GAMEMODE.SuicideOnChangeClass = tonumber(newvalue) == 1
end)
GM.BeatsEnabled = CreateClientConVar("zs_beats", "1", true, false):GetBool() GM.BeatsEnabled = CreateClientConVar("zs_beats", "1", true, false):GetBool()
cvars.AddChangeCallback("zs_beats", function(cvar, oldvalue, newvalue) cvars.AddChangeCallback("zs_beats", function(cvar, oldvalue, newvalue)
GAMEMODE.BeatsEnabled = tonumber(newvalue) == 1 GAMEMODE.BeatsEnabled = tonumber(newvalue) == 1

View file

@ -798,11 +798,14 @@ function GM:PlayerSelectSpawn(pl)
if spawn then if spawn then
LastSpawnPoints[teamid] = spawn LastSpawnPoints[teamid] = spawn
self:CheckDynamicSpawnHR(spawn) self:CheckDynamicSpawnHR(spawn)
pl.SpawnedOnSpawnPoint = true
return spawn return spawn
end end
end end
end end
pl.SpawnedOnSpawnPoint = true
-- Fallback. -- Fallback.
return LastSpawnPoints[teamid] or #tab > 0 and table.Random(tab) or pl return LastSpawnPoints[teamid] or #tab > 0 and table.Random(tab) or pl
end end
@ -1369,7 +1372,6 @@ function GM:InitPostEntityMap(fromze)
for _, ent in pairs(ents.FindByClass("prop_ammo")) do ent.PlacedInMap = true end for _, ent in pairs(ents.FindByClass("prop_ammo")) do ent.PlacedInMap = true end
for _, ent in pairs(ents.FindByClass("prop_weapon")) do ent.PlacedInMap = true end for _, ent in pairs(ents.FindByClass("prop_weapon")) do ent.PlacedInMap = true end
for _, ent in pairs(ents.FindByClass("prop_flashlightbattery")) do ent.PlacedInMap = true end
if self.ObjectiveMap then if self.ObjectiveMap then
self:SetDynamicSpawning(false) self:SetDynamicSpawning(false)
@ -2219,17 +2221,26 @@ function GM:EntityTakeDamage(ent, dmginfo)
local dmgtype = dmginfo:GetDamageType() local dmgtype = dmginfo:GetDamageType()
if dmgtype == DMG_BLAST or dmgtype == DMG_BURN or dmgtype == DMG_SLOWBURN then if dmgtype == DMG_BLAST or dmgtype == DMG_BURN or dmgtype == DMG_SLOWBURN then
if ent:IsPlayer() then if ent:IsPlayer() then
if inflictor.LastExplosionTeam == ent:Team() and inflictor.LastExplosionAttacker ~= ent and inflictor.LastExplosionTime and CurTime() < inflictor.LastExplosionTime + 10 then -- Player damaged by physics object explosion. if inflictor.LastExplosionTeam == ent:Team() and inflictor.LastExplosionAttacker ~= ent and inflictor.LastExplosionTime and CurTime() < inflictor.LastExplosionTime + 10 then -- Player damaged by physics object explosion / fire.
dmginfo:SetDamage(0) dmginfo:SetDamage(0)
dmginfo:ScaleDamage(0) dmginfo:ScaleDamage(0)
return return
end end
elseif inflictor ~= ent and string.sub(ent:GetClass(), 1, 12) == "prop_physics" and string.sub(inflictor:GetClass(), 1, 12) == "prop_physics" then -- Physics object damaged by physics object explosion. elseif inflictor ~= ent and string.sub(ent:GetClass(), 1, 12) == "prop_physics" and string.sub(inflictor:GetClass(), 1, 12) == "prop_physics" then -- Physics object damaged by physics object explosion / fire.
ent.LastExplosionAttacker = inflictor.LastExplosionAttacker ent.LastExplosionAttacker = inflictor.LastExplosionAttacker
ent.LastExplosionTeam = inflictor.LastExplosionTeam ent.LastExplosionTeam = inflictor.LastExplosionTeam
ent.LastExplosionTime = CurTime() ent.LastExplosionTime = CurTime()
end end
elseif inflictor:IsPlayer() and string.sub(ent:GetClass(), 1, 12) == "prop_physics" then -- Physics object damaged by player. elseif inflictor:IsPlayer() and string.sub(ent:GetClass(), 1, 12) == "prop_physics" then -- Physics object damaged by player.
if inflictor:Team() == TEAM_HUMAN then
local phys = ent:GetPhysicsObject()
if phys:IsValid() and phys:HasGameFlag(FVPHYSICS_PLAYER_HELD) and inflictor:GetCarry() ~= ent or ent._LastDropped and CurTime() < ent._LastDropped + 3 and ent._LastDroppedBy ~= inflictor then -- Human player damaged a physics object while it was being carried or recently carried. They weren't the carrier.
dmginfo:SetDamage(0)
dmginfo:ScaleDamage(0)
return
end
end
ent.LastExplosionAttacker = inflictor ent.LastExplosionAttacker = inflictor
ent.LastExplosionTeam = inflictor:Team() ent.LastExplosionTeam = inflictor:Team()
ent.LastExplosionTime = CurTime() ent.LastExplosionTime = CurTime()
@ -2960,6 +2971,7 @@ end
function GM:DoPlayerDeath(pl, attacker, dmginfo) function GM:DoPlayerDeath(pl, attacker, dmginfo)
pl:RemoveStatus("confusion", false, true) pl:RemoveStatus("confusion", false, true)
pl:RemoveStatus("ghoultouch", false, true)
local inflictor = dmginfo:GetInflictor() local inflictor = dmginfo:GetInflictor()
local plteam = pl:Team() local plteam = pl:Team()
@ -3451,6 +3463,12 @@ function GM:PlayerSpawn(pl)
pl.ForceSpawnAngles = nil pl.ForceSpawnAngles = nil
end end
if pl.SpawnedOnSpawnPoint and not pl.DidntSpawnOnSpawnPoint and not pl.Revived and not pl:GetZombieClassTable().NeverAlive then
pl:GiveStatus("zombiespawnbuff", 3)
end
pl.DidntSpawnOnSpawnPoint = nil
pl.SpawnedOnSpawnPoint = nil
pl:CallZombieFunction("OnSpawned") pl:CallZombieFunction("OnSpawned")
else else
pl.m_PointQueue = 0 pl.m_PointQueue = 0
@ -3612,6 +3630,7 @@ function GM:WaveStateChanged(newstate)
ent:Spawn() ent:Spawn()
ent:DropToFloor() ent:DropToFloor()
ent:SetCollisionGroup(COLLISION_GROUP_DEBRIS_TRIGGER) -- Just so no one gets stuck in it. ent:SetCollisionGroup(COLLISION_GROUP_DEBRIS_TRIGGER) -- Just so no one gets stuck in it.
ent.NoTakeOwnership = true
end end
end end
end end
@ -3789,7 +3808,8 @@ end
concommand.Add("zs_class", function(sender, command, arguments) concommand.Add("zs_class", function(sender, command, arguments)
if sender:Team() ~= TEAM_UNDEAD or sender.Revive or GAMEMODE.PantsMode or GAMEMODE:IsClassicMode() or GAMEMODE:IsBabyMode() or GAMEMODE.ZombieEscape then return end if sender:Team() ~= TEAM_UNDEAD or sender.Revive or GAMEMODE.PantsMode or GAMEMODE:IsClassicMode() or GAMEMODE:IsBabyMode() or GAMEMODE.ZombieEscape then return end
local classname = table.concat(arguments, " ") local classname = arguments[1]
local suicide = arguments[2] == "1"
local classtab = GAMEMODE.ZombieClasses[classname] local classtab = GAMEMODE.ZombieClasses[classname]
if not classtab or classtab.Hidden and not (classtab.CanUse and classtab:CanUse(sender)) then return end if not classtab or classtab.Hidden and not (classtab.CanUse and classtab:CanUse(sender)) then return end
@ -3801,7 +3821,7 @@ concommand.Add("zs_class", function(sender, command, arguments)
sender.DeathClass = classtab.Index sender.DeathClass = classtab.Index
sender:CenterNotify(translate.ClientFormat(sender, "you_will_spawn_as_a_x", translate.ClientGet(sender, classtab.TranslationName))) sender:CenterNotify(translate.ClientFormat(sender, "you_will_spawn_as_a_x", translate.ClientGet(sender, classtab.TranslationName)))
if sender:Alive() and not sender:GetZombieClassTable().Boss and gamemode.Call("CanPlayerSuicide", sender) then if suicide and sender:Alive() and not sender:GetZombieClassTable().Boss and gamemode.Call("CanPlayerSuicide", sender) then
sender:Kill() sender:Kill()
end end
end end

View file

@ -209,7 +209,7 @@ LANGUAGE.description_zombie = "The basic zombie is very durable and has po
LANGUAGE.description_poison_zombie = "This mutated zombie is not only extremely durable but has abnormal strength.\nIts body is extremely toxic and will even tear out and toss its own flesh at things too far away to hit." LANGUAGE.description_poison_zombie = "This mutated zombie is not only extremely durable but has abnormal strength.\nIts body is extremely toxic and will even tear out and toss its own flesh at things too far away to hit."
LANGUAGE.description_fast_zombie = "This boney cadaver is much faster than other zombies.\nThey aren't much of a threat by themselves but can reach nearly any area by climbing with their razor sharp claws\nThey also have no problem hunting down weak or hurt humans." LANGUAGE.description_fast_zombie = "This boney cadaver is much faster than other zombies.\nThey aren't much of a threat by themselves but can reach nearly any area by climbing with their razor sharp claws\nThey also have no problem hunting down weak or hurt humans."
LANGUAGE.description_bloated_zombie = "Their body is comprised of volatile, toxic chemicals.\nAlthough they move slower, they can take slightly more of a beating." LANGUAGE.description_bloated_zombie = "Their body is comprised of volatile, toxic chemicals.\nAlthough they move slower, they can take slightly more of a beating."
LANGUAGE.description_ghoul = "This zombie has highly toxic flesh.\nIt's slightly weaker than other zombies but makes up for it with its poison attacks.\nIts claws can debilitate a human for a short time and it will eject poison through its wounds if hit with enough damage." LANGUAGE.description_ghoul = "This zombie has highly toxic flesh.\nIt's slightly weaker than other zombies but makes up for it with its debilitating attacks.\nIts claws can debuff a human for a short time, causing increased damage from other attacks."
LANGUAGE.description_headcrab = "Headcrabs are what caused the initial infection.\nNo one knows where they truely came from.\nTheir method of attack is lunging with the sharp beaks on their belly." LANGUAGE.description_headcrab = "Headcrabs are what caused the initial infection.\nNo one knows where they truely came from.\nTheir method of attack is lunging with the sharp beaks on their belly."
LANGUAGE.description_fast_headcrab = "The male headcrab is considerably faster but less beefy than the female.\nEither way, it's equally as annoying and deadly in groups." LANGUAGE.description_fast_headcrab = "The male headcrab is considerably faster but less beefy than the female.\nEither way, it's equally as annoying and deadly in groups."
LANGUAGE.description_poison_headcrab = "This Headcrab is full of deadly nuerotoxins.\nOne bite is usually enough to kill an adult human.\nIt also has the ability to spit a less potent version of its poisons.\nThe spit is just as deadly if its victim is hit in the face." LANGUAGE.description_poison_headcrab = "This Headcrab is full of deadly nuerotoxins.\nOne bite is usually enough to kill an adult human.\nIt also has the ability to spit a less potent version of its poisons.\nThe spit is just as deadly if its victim is hit in the face."

View file

@ -1,17 +1,126 @@
local function PlayerInitialSpawn(pl) -- TODO: Make requests buffer for 3 seconds or so using ?steamids=a,b,c,d
http.Fetch("http://www.noxiousnet.com/api/player/memberlevel?steamid="..pl:SteamID(), function(body, len, headers, code) -- TODO: _SUPPORTER_ needs to be networked
local level = tonumber(body)
if level == 1 or level == 2 then local SUPPORTER_MESSAGE = "JetBoom says \"thank you for supporting my gamemodes!\" to you."
pl._SUPPORTER_ = true
pl:PrintMessage(HUD_PRINTCONSOLE, "GREETINGS FROM NOX, FELLOW SUPPORTER!") local CACHE = {
MaxSize = 128,
Cache = {}
}
function CACHE:Set(steamid, memberlevel, nolookup)
if nolookup then
table.insert(self.Cache, {steamid, memberlevel})
else
for i, tab in pairs(self.Cache) do
if tab[1] == steamid then
tab[2] = memberlevel
return
end
end end
end)
table.insert(self.Cache, {steamid, memberlevel})
end
if #self.Cache > self.MaxSize then
table.remove(self.Cache, 1)
end
end end
--if not NDB then function CACHE:Get(steamid)
--hook.Add("PlayerInitialSpawn", "noxapi", PlayerInitialSpawn) for i, tab in pairs(self.Cache) do
--end if tab[1] == steamid then
return tab[2]
end
end
end
function CACHE:Remove(steamid)
for i, tab in pairs(self.Cache) do
if tab[1] == steamid then
table.remove(self.Cache, i)
break
end
end
end
function CACHE:Save()
local tosave = {}
for steamid, level in pairs(self.Cache) do
table.insert(tosave, steamid.."="..level)
end
file.Write("noxapi_cache.txt", table.concat(tosave, "\n"))
end
function CACHE:Load()
if file.Exists("noxapi_cache.txt", "DATA") then
self.Cache = {}
for i, line in pairs(string.Explode("\n", file.Read("noxapi_cache.txt", "DATA"))) do
local cont = string.Explode("=", line)
local steamid, memberlevel = cont[1], tonumber(cont[2]) or 0
self:Set(steamid, memberlevel, true)
end
end
end
--[[hook.Add("PlayerInitialSpawn", "noxapi", function(pl)
if NDB then return end
local steamid = pl:SteamID()
local memberlevel = CACHE:Get(steamid)
if memberlevel then
if level == 1 or level == 2 then
pl._SUPPORTER_ = true
pl:PrintMessage(HUD_PRINTCONSOLE, SUPPORTER_MESSAGE)
end
else
http.Fetch("http://www.noxiousnet.com/api/player/memberlevel?steamid="..steamid, function(body, len, headers, code)
local level = tonumber(body) or 0
if level == 1 or level == 2 then
pl._SUPPORTER_ = true
pl:PrintMessage(HUD_PRINTCONSOLE, SUPPORTER_MESSAGE)
end
CACHE:Set(steamid, level)
end)
end
end)
hook.Add("Initialize", "noxapi", function() hook.Add("Initialize", "noxapi", function()
resource.AddFile("materials/noxiousnet/noxicon.png") resource.AddFile("materials/noxiousnet/noxicon.png")
if not NDB then
CACHE:Load()
end
end) end)
hook.Add("ShutDown", "noxapi", function()
if not NDB then
CACHE:Save()
end
end)
concommand.Add("noxapi_forcerefresh", function(sender, command, arguments)
if NDB or sender._ForcedNoxAPILookup or sender._SUPPORTER_ then return end
sender._ForcedNoxAPILookup = true
local steamid = sender:SteamID()
CACHE:Remove(steamid)
http.Fetch("http://www.noxiousnet.com/api/player/memberlevel?steamid="..steamid, function(body, len, headers, code)
local level = tonumber(body) or 0
if level == 1 or level == 2 then
pl._SUPPORTER_ = true
pl:PrintMessage(HUD_PRINTCONSOLE, SUPPORTER_MESSAGE)
end
CACHE:Set(steamid, level)
end)
end)]]

View file

@ -61,11 +61,6 @@ local function CheckItemCreated(self)
table.insert(tab, ent) table.insert(tab, ent)
end end
end end
for _, ent in pairs(ents.FindByClass("prop_flashlightbattery")) do
if not ent.PlacedInMap then
table.insert(tab, ent)
end
end
for _, ent in pairs(ents.FindByClass("prop_weapon")) do for _, ent in pairs(ents.FindByClass("prop_weapon")) do
if not ent.PlacedInMap then if not ent.PlacedInMap then
table.insert(tab, ent) table.insert(tab, ent)

View file

@ -217,7 +217,7 @@ function meta:ProcessDamage(dmginfo)
if self:Team() == TEAM_UNDEAD then if self:Team() == TEAM_UNDEAD then
if self ~= attacker then if self ~= attacker then
dmginfo:SetDamage(dmginfo:GetDamage() * GAMEMODE:GetZombieDamageScale(dmginfo:GetDamagePosition(), pl)) dmginfo:SetDamage(dmginfo:GetDamage() * GAMEMODE:GetZombieDamageScale(dmginfo:GetDamagePosition(), self))
end end
return self:CallZombieFunction("ProcessDamage", dmginfo) return self:CallZombieFunction("ProcessDamage", dmginfo)

View file

@ -101,6 +101,7 @@ function meta:TrySpawnAsGoreChild()
local deathclass = self.DeathClass local deathclass = self.DeathClass
self:SetZombieClassName("Gore Child") self:SetZombieClassName("Gore Child")
self.DeathClass = nil self.DeathClass = nil
self.DidntSpawnOnSpawnPoint = true
self:UnSpectateAndSpawn() self:UnSpectateAndSpawn()
self.DeathClass = deathclass self.DeathClass = deathclass
self:SetPos(ent:GetPos()) self:SetPos(ent:GetPos())

View file

@ -1,15 +1,3 @@
color_black_alpha220 = Color(0, 0, 0, 180)
color_black_alpha200 = Color(0, 0, 0, 180)
color_black_alpha180 = Color(0, 0, 0, 180)
color_black_alpha120 = Color(0, 0, 0, 120)
color_black_alpha90 = Color(0, 0, 0, 90)
color_white_alpha220 = Color(255, 255, 255, 200)
color_white_alpha200 = Color(255, 255, 255, 200)
color_white_alpha180 = Color(255, 255, 255, 180)
color_white_alpha120 = Color(255, 255, 255, 120)
color_white_alpha90 = Color(255, 255, 255, 90)
COLOR_GRAY = Color(190, 190, 190) COLOR_GRAY = Color(190, 190, 190)
COLOR_RED = Color(255, 0, 0) COLOR_RED = Color(255, 0, 0)
COLOR_BLUE = Color(0, 0, 255) COLOR_BLUE = Color(0, 0, 255)
@ -31,6 +19,18 @@ COLOR_SCRATCHED = Color(80, 210, 0)
COLOR_HURT = Color(150, 50, 0) COLOR_HURT = Color(150, 50, 0)
COLOR_CRITICAL = COLOR_DARKRED COLOR_CRITICAL = COLOR_DARKRED
color_black_alpha220 = Color(0, 0, 0, 180)
color_black_alpha200 = Color(0, 0, 0, 180)
color_black_alpha180 = Color(0, 0, 0, 180)
color_black_alpha120 = Color(0, 0, 0, 120)
color_black_alpha90 = Color(0, 0, 0, 90)
color_white_alpha220 = Color(255, 255, 255, 200)
color_white_alpha200 = Color(255, 255, 255, 200)
color_white_alpha180 = Color(255, 255, 255, 180)
color_white_alpha120 = Color(255, 255, 255, 120)
color_white_alpha90 = Color(255, 255, 255, 90)
function util.ColorCopy(source, dest, copyalpha) function util.ColorCopy(source, dest, copyalpha)
dest.r = source.r dest.r = source.r
dest.g = source.g dest.g = source.g

View file

@ -97,6 +97,8 @@ GM.BarricadeHealthMax = 1100
GM.BarricadeHealthMassFactor = 3 GM.BarricadeHealthMassFactor = 3
GM.BarricadeHealthVolumeFactor = 4 GM.BarricadeHealthVolumeFactor = 4
GM.BossZombiePlayersRequired = 16
GM.HumanGibs = { GM.HumanGibs = {
Model("models/gibs/HGIBS.mdl"), Model("models/gibs/HGIBS.mdl"),
Model("models/gibs/HGIBS_spine.mdl"), Model("models/gibs/HGIBS_spine.mdl"),

View file

@ -156,7 +156,7 @@ local item = GM:AddStartingItem("manhack", "Manhack", nil, ITEMCAT_TOOLS, 60, "w
item.Countables = "prop_manhack" item.Countables = "prop_manhack"
GM:AddStartingItem("wrench", "Mechanic's Wrench", nil, ITEMCAT_TOOLS, 15, "weapon_zs_wrench").NoClassicMode = true GM:AddStartingItem("wrench", "Mechanic's Wrench", nil, ITEMCAT_TOOLS, 15, "weapon_zs_wrench").NoClassicMode = true
GM:AddStartingItem("crphmr", "Carpenter's Hammer", nil, ITEMCAT_TOOLS, 45, "weapon_zs_hammer").NoClassicMode = true GM:AddStartingItem("crphmr", "Carpenter's Hammer", nil, ITEMCAT_TOOLS, 45, "weapon_zs_hammer").NoClassicMode = true
GM:AddStartingItem("6nails", "Box of 12 nails", "An extra box of nails for all your barricading needs.", ITEMCAT_TOOLS, 25, nil, function(pl) pl:GiveAmmo(6, "GaussEnergy", true) end, "models/Items/BoxMRounds.mdl") GM:AddStartingItem("6nails", "Box of 12 nails", "An extra box of nails for all your barricading needs.", ITEMCAT_TOOLS, 25, nil, function(pl) pl:GiveAmmo(12, "GaussEnergy", true) end, "models/Items/BoxMRounds.mdl")
GM:AddStartingItem("junkpack", "Junk Pack", nil, ITEMCAT_TOOLS, 40, "weapon_zs_boardpack") GM:AddStartingItem("junkpack", "Junk Pack", nil, ITEMCAT_TOOLS, 40, "weapon_zs_boardpack")
GM:AddStartingItem("spotlamp", "Spot Lamp", nil, ITEMCAT_TOOLS, 25, "weapon_zs_spotlamp").Countables = "prop_spotlamp" GM:AddStartingItem("spotlamp", "Spot Lamp", nil, ITEMCAT_TOOLS, 25, "weapon_zs_spotlamp").Countables = "prop_spotlamp"
GM:AddStartingItem("msgbeacon", "Message Beacon", nil, ITEMCAT_TOOLS, 10, "weapon_zs_messagebeacon").Countables = "prop_messagebeacon" GM:AddStartingItem("msgbeacon", "Message Beacon", nil, ITEMCAT_TOOLS, 10, "weapon_zs_messagebeacon").Countables = "prop_messagebeacon"

View file

@ -491,6 +491,8 @@ function GM:ShouldUseAlternateDynamicSpawn()
end end
function GM:GetZombieDamageScale(pos, ignore) function GM:GetZombieDamageScale(pos, ignore)
if LASTHUMAN then return self.ZombieDamageMultiplier end
return self.ZombieDamageMultiplier * (1 - self:GetDamageResistance(self:GetFearMeterPower(pos, TEAM_UNDEAD, ignore))) return self.ZombieDamageMultiplier * (1 - self:GetDamageResistance(self:GetFearMeterPower(pos, TEAM_UNDEAD, ignore)))
end end

View file

@ -18,11 +18,6 @@ cvars.AddChangeCallback("zs_bosszombies", function(cvar, oldvalue, newvalue)
GAMEMODE.BossZombies = tonumber(newvalue) == 1 GAMEMODE.BossZombies = tonumber(newvalue) == 1
end) end)
GM.BossZombiePlayersRequired = CreateConVar("zs_bosszombiethreshold", "10", FCVAR_ARCHIVE + FCVAR_NOTIFY, "Don't summon boss zombies if less than this amount of players. 0 to disable."):GetInt()
cvars.AddChangeCallback("zs_bosszombiethreshold", function(cvar, oldvalue, newvalue)
GAMEMODE.BossZombiePlayersRequired = tonumber(newvalue) or 0
end)
GM.OutnumberedHealthBonus = CreateConVar("zs_outnumberedhealthbonus", "4", FCVAR_ARCHIVE + FCVAR_NOTIFY, "Give zombies some extra maximum health if there are less than or equal to this many zombies. 0 to disable."):GetInt() GM.OutnumberedHealthBonus = CreateConVar("zs_outnumberedhealthbonus", "4", FCVAR_ARCHIVE + FCVAR_NOTIFY, "Give zombies some extra maximum health if there are less than or equal to this many zombies. 0 to disable."):GetInt()
cvars.AddChangeCallback("zs_outnumberedhealthbonus", function(cvar, oldvalue, newvalue) cvars.AddChangeCallback("zs_outnumberedhealthbonus", function(cvar, oldvalue, newvalue)
GAMEMODE.OutnumberedHealthBonus = tonumber(newvalue) or 0 GAMEMODE.OutnumberedHealthBonus = tonumber(newvalue) or 0

View file

@ -200,7 +200,7 @@ function PANEL:DoClick()
RunConsoleCommand("zs_bossclass", self.ClassTable.Name) RunConsoleCommand("zs_bossclass", self.ClassTable.Name)
GAMEMODE:CenterNotify(translate.Format("boss_class_select", self.ClassTable.Name)) GAMEMODE:CenterNotify(translate.Format("boss_class_select", self.ClassTable.Name))
else else
RunConsoleCommand("zs_class", self.ClassTable.Name) RunConsoleCommand("zs_class", self.ClassTable.Name, GAMEMODE.SuicideOnChangeClass and "1" or "0")
end end
end end

View file

@ -130,6 +130,12 @@ function MakepOptions()
check:SizeToContents() check:SizeToContents()
list:AddItem(check) list:AddItem(check)
local check = vgui.Create("DCheckBoxLabel", Window)
check:SetText("Automatic suicide when changing classes")
check:SetConVar("zs_suicideonchange")
check:SizeToContents()
list:AddItem(check)
list:AddItem(EasyLabel(Window, "Weapon HUD display style", "DefaultFontSmall", color_white)) list:AddItem(EasyLabel(Window, "Weapon HUD display style", "DefaultFontSmall", color_white))
local dropdown = vgui.Create("DComboBox", Window) local dropdown = vgui.Create("DComboBox", Window)
dropdown:SetMouseInputEnabled(true) dropdown:SetMouseInputEnabled(true)

View file

@ -35,6 +35,8 @@ function PANEL:Init()
if lp:IsValid() then if lp:IsValid() then
return lp:GetPoisonDamage() return lp:GetPoisonDamage()
end end
return 0
end end
poisonstatus.MemberMaxValue = 50 poisonstatus.MemberMaxValue = 50
poisonstatus:Dock(TOP) poisonstatus:Dock(TOP)
@ -49,10 +51,31 @@ function PANEL:Init()
if lp:IsValid() then if lp:IsValid() then
return lp:GetBleedDamage() return lp:GetBleedDamage()
end end
return 0
end end
bleedstatus.MemberMaxValue = 20 bleedstatus.MemberMaxValue = 20
bleedstatus:Dock(TOP) bleedstatus:Dock(TOP)
local ghoultouchstatus = vgui.Create("ZSHealthStatus", contents)
ghoultouchstatus:SetTall(20)
ghoultouchstatus:SetAlpha(200)
ghoultouchstatus:SetColor(Color(255, 0, 0))
ghoultouchstatus:SetMemberName("GHOUL TOUCH!")
ghoultouchstatus.GetMemberValue = function(me)
local lp = LocalPlayer()
if lp:IsValid() then
local status = lp:GetStatus("ghoultouch")
if status and status:IsValid() then
return math.max(status.DieTime - CurTime(), 0)
end
end
return 0
end
ghoultouchstatus.MemberMaxValue = 10
ghoultouchstatus:Dock(TOP)
self:ParentToHUD() self:ParentToHUD()
self:InvalidateLayout() self:InvalidateLayout()
end end

View file

@ -10,6 +10,7 @@ CLASS.Health = 100
CLASS.SWEP = "weapon_zs_fleshcreeper" CLASS.SWEP = "weapon_zs_fleshcreeper"
CLASS.Model = Model("models/antlion.mdl") CLASS.Model = Model("models/antlion.mdl")
CLASS.Speed = 175 CLASS.Speed = 175
CLASS.JumpPower = 220
CLASS.Points = 4 CLASS.Points = 4

View file

@ -7,7 +7,7 @@ CLASS.Wave = 0
CLASS.Unlocked = true CLASS.Unlocked = true
CLASS.Health = 150 CLASS.Health = 150
CLASS.Speed = 170 CLASS.Speed = 160
CLASS.Points = 4 CLASS.Points = 4