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:
parent
18126da912
commit
53743b1aee
29 changed files with 423 additions and 109 deletions
|
@ -84,7 +84,8 @@ end
|
|||
|
||||
function ENT:Use(activator, caller)
|
||||
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)
|
||||
end
|
||||
|
||||
|
|
|
@ -146,7 +146,9 @@ function ENT:Use(activator, caller)
|
|||
if activator ~= owner and owner:IsValid() and owner:IsPlayer() and owner:Team() == TEAM_HUMAN then
|
||||
owner.ResupplyBoxUsedByOthers = owner.ResupplyBoxUsedByOthers + 1
|
||||
|
||||
if owner.ResupplyBoxUsedByOthers % 2 == 0 then
|
||||
owner:AddPoints(1)
|
||||
end
|
||||
|
||||
net.Start("zs_commission")
|
||||
net.WriteEntity(self)
|
||||
|
|
104
gamemodes/zombiesurvival/entities/entities/status_ghoultouch.lua
Normal file
104
gamemodes/zombiesurvival/entities/entities/status_ghoultouch.lua
Normal 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
|
|
@ -101,6 +101,9 @@ function ENT:OnRemove()
|
|||
object:CollisionRulesChanged()
|
||||
end
|
||||
|
||||
object._LastDroppedBy = owner
|
||||
object._LastDropped = CurTime()
|
||||
|
||||
for _, ent in pairs(ents.FindByClass("logic_pickupdrop")) do
|
||||
if ent.EntityToWatch == object:GetName() and ent:IsValid() then
|
||||
ent:Input("ondropped", owner, object, "")
|
||||
|
|
|
@ -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
|
|
@ -54,6 +54,7 @@ function ENT:Touch(ent)
|
|||
local prevpos = ent:GetPos()
|
||||
local prevang = ent:EyeAngles()
|
||||
ent:SetZombieClass(k)
|
||||
ent.DidntSpawnOnSpawnPoint = true
|
||||
ent:UnSpectateAndSpawn()
|
||||
if self.OneTime then
|
||||
ent.DeathClass = prev
|
||||
|
@ -87,6 +88,7 @@ function ENT:EndTouch(ent)
|
|||
local prevpos = ent:GetPos()
|
||||
local prevang = ent:GetAngles()
|
||||
ent:SetZombieClass(k)
|
||||
ent.DidntSpawnOnSpawnPoint = true
|
||||
ent:UnSpectateAndSpawn()
|
||||
if self.OneTime then
|
||||
ent.DeathClass = prev
|
||||
|
|
|
@ -39,12 +39,14 @@ function ENT:AcceptInput(name, activator, caller, arg)
|
|||
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: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.m_LastGasHeal = CurTime()
|
||||
end
|
||||
end]]
|
||||
ent:GiveStatus("zombiespawnbuff", 3)
|
||||
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
|
||||
|
|
|
@ -6,13 +6,18 @@ end
|
|||
|
||||
SWEP.Base = "weapon_zs_zombie"
|
||||
|
||||
SWEP.MeleeDamage = 26
|
||||
SWEP.MeleeForceScale = 0.1
|
||||
SWEP.MeleeDamage = 15
|
||||
SWEP.MeleeForceScale = 0.5
|
||||
SWEP.SlowDownScale = 0.25
|
||||
--[[SWEP.MeleeForceScale = 0.1
|
||||
SWEP.SlowDownScale = 2.25
|
||||
SWEP.SlowDownImmunityTime = 2
|
||||
SWEP.SlowDownImmunityTime = 2]]
|
||||
|
||||
function SWEP:ApplyMeleeDamage(ent, trace, damage)
|
||||
ent:PoisonDamage(damage, self.Owner, self, trace.HitPos)
|
||||
if SERVER and ent:IsPlayer() then
|
||||
ent:GiveStatus("ghoultouch", 10)
|
||||
end
|
||||
end
|
||||
|
||||
function SWEP:Reload()
|
||||
|
|
|
@ -50,8 +50,22 @@ end
|
|||
|
||||
if SERVER then
|
||||
function SWEP:OnMeleeHit(hitent, hitflesh, tr)
|
||||
if hitent:IsValid() and hitent:IsPlayer() and hitent:GetZombieClassTable().Name ~= "Shade" then
|
||||
hitent:GiveStatus("disorientation")
|
||||
if hitent:IsValid() and hitent:IsPlayer() and hitent:GetZombieClassTable().Name ~= "Shade" and CurTime() >= (hitent._NextLeadPipeEffect or 0) then
|
||||
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
|
||||
|
|
|
@ -20,15 +20,18 @@ if CLIENT then
|
|||
}
|
||||
end
|
||||
|
||||
SWEP.Primary.Damage = 18
|
||||
SWEP.Primary.Damage = 14
|
||||
SWEP.Primary.NumShots = 2
|
||||
SWEP.Primary.Delay = 0.2
|
||||
|
||||
SWEP.Primary.ClipSize = 15
|
||||
SWEP.Primary.ClipSize = 14
|
||||
SWEP.Primary.Automatic = false
|
||||
SWEP.Primary.Ammo = "pistol"
|
||||
GAMEMODE:SetupDefaultClip(SWEP.Primary)
|
||||
|
||||
SWEP.ConeMax = 0.07
|
||||
SWEP.ConeMin = 0.03
|
||||
|
||||
function SWEP:EmitFireSound()
|
||||
self:EmitSound(self.Primary.Sound, 80, 75)
|
||||
end
|
||||
|
|
|
@ -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
|
|
@ -128,6 +128,28 @@ local draw_GetFontHeight = draw.GetFontHeight
|
|||
|
||||
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)
|
||||
end
|
||||
|
||||
|
@ -146,8 +168,6 @@ function GM:TopNotify(...)
|
|||
end
|
||||
end
|
||||
|
||||
GM.InputMouseX = 0
|
||||
GM.InputMouseY = 0
|
||||
function GM:_InputMouseApply(cmd, x, y, ang)
|
||||
self.InputMouseX = x
|
||||
self.InputMouseY = y
|
||||
|
@ -295,12 +315,6 @@ function GM:PostDrawSkyBox()
|
|||
cam.End3D()
|
||||
end
|
||||
|
||||
GM.DeathFog = 0
|
||||
GM.FogStart = 0
|
||||
GM.FogEnd = 8000
|
||||
GM.FogRed = 30
|
||||
GM.FogGreen = 30
|
||||
GM.FogBlue = 30
|
||||
function GM:GetFogData()
|
||||
local fogstart, fogend = render.GetFogDistances()
|
||||
local fogr, fogg, fogb = render.GetFogColor()
|
||||
|
@ -427,9 +441,6 @@ function GM:GetDynamicSpawning()
|
|||
return not GetGlobalBool("DynamicSpawningDisabled", false)
|
||||
end
|
||||
|
||||
GM.LastTimeDead = 0
|
||||
GM.LastTimeAlive = 0
|
||||
|
||||
function GM:TrackLastDeath()
|
||||
if MySelf:Alive() then
|
||||
self.LastTimeAlive = CurTime()
|
||||
|
@ -467,10 +478,6 @@ function GM:PostRender()
|
|||
end
|
||||
|
||||
local lastwarntim = -1
|
||||
GM.HeartBeatTime = 0
|
||||
GM.FOVLerp = 1
|
||||
GM.HurtEffect = 0
|
||||
GM.PrevHealth = 0
|
||||
local NextGas = 0
|
||||
function GM:_Think()
|
||||
if self:GetEscapeStage() == ESCAPESTAGE_DEATH then
|
||||
|
@ -980,7 +987,6 @@ local function FirstOfGoodType(a)
|
|||
end
|
||||
end
|
||||
|
||||
GM.Beats = {}
|
||||
function GM:InitializeBeats()
|
||||
local _, dirs = file.Find("sound/zombiesurvival/beats/*", "GAME")
|
||||
for _, dirname in pairs(dirs) do
|
||||
|
@ -1144,7 +1150,6 @@ function GM:HumanMenu()
|
|||
panel:OpenMenu()
|
||||
end
|
||||
|
||||
GM.ZombieThirdPerson = false
|
||||
function GM:PlayerBindPress(pl, bind, wasin)
|
||||
if bind == "gmod_undo" or bind == "undo" then
|
||||
RunConsoleCommand("+zoom")
|
||||
|
@ -1276,6 +1281,11 @@ function GM:_CreateMove(cmd)
|
|||
end
|
||||
end
|
||||
else
|
||||
local buttons = cmd:GetButtons()
|
||||
if bit.band(buttons, IN_ZOOM) ~= 0 then
|
||||
cmd:SetButtons(buttons - IN_ZOOM)
|
||||
end
|
||||
|
||||
MySelf:CallZombieFunction("CreateMove", cmd)
|
||||
end
|
||||
end
|
||||
|
@ -1566,7 +1576,6 @@ function GM:CloseWorth()
|
|||
end
|
||||
end
|
||||
|
||||
GM.SuppressArsenalTime = 0
|
||||
function GM:SuppressArsenalUpgrades(suppresstime)
|
||||
self.SuppressArsenalTime = math.max(CurTime() + suppresstime, self.SuppressArsenalTime)
|
||||
end
|
||||
|
|
|
@ -34,6 +34,11 @@ end)
|
|||
CreateClientConVar("zs_noredeem", "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()
|
||||
cvars.AddChangeCallback("zs_beats", function(cvar, oldvalue, newvalue)
|
||||
GAMEMODE.BeatsEnabled = tonumber(newvalue) == 1
|
||||
|
|
|
@ -798,11 +798,14 @@ function GM:PlayerSelectSpawn(pl)
|
|||
if spawn then
|
||||
LastSpawnPoints[teamid] = spawn
|
||||
self:CheckDynamicSpawnHR(spawn)
|
||||
pl.SpawnedOnSpawnPoint = true
|
||||
return spawn
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
pl.SpawnedOnSpawnPoint = true
|
||||
|
||||
-- Fallback.
|
||||
return LastSpawnPoints[teamid] or #tab > 0 and table.Random(tab) or pl
|
||||
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_weapon")) do ent.PlacedInMap = true end
|
||||
for _, ent in pairs(ents.FindByClass("prop_flashlightbattery")) do ent.PlacedInMap = true end
|
||||
|
||||
if self.ObjectiveMap then
|
||||
self:SetDynamicSpawning(false)
|
||||
|
@ -2219,17 +2221,26 @@ function GM:EntityTakeDamage(ent, dmginfo)
|
|||
local dmgtype = dmginfo:GetDamageType()
|
||||
if dmgtype == DMG_BLAST or dmgtype == DMG_BURN or dmgtype == DMG_SLOWBURN 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:ScaleDamage(0)
|
||||
return
|
||||
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.LastExplosionTeam = inflictor.LastExplosionTeam
|
||||
ent.LastExplosionTime = CurTime()
|
||||
end
|
||||
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.LastExplosionTeam = inflictor:Team()
|
||||
ent.LastExplosionTime = CurTime()
|
||||
|
@ -2960,6 +2971,7 @@ end
|
|||
|
||||
function GM:DoPlayerDeath(pl, attacker, dmginfo)
|
||||
pl:RemoveStatus("confusion", false, true)
|
||||
pl:RemoveStatus("ghoultouch", false, true)
|
||||
|
||||
local inflictor = dmginfo:GetInflictor()
|
||||
local plteam = pl:Team()
|
||||
|
@ -3451,6 +3463,12 @@ function GM:PlayerSpawn(pl)
|
|||
pl.ForceSpawnAngles = nil
|
||||
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")
|
||||
else
|
||||
pl.m_PointQueue = 0
|
||||
|
@ -3612,6 +3630,7 @@ function GM:WaveStateChanged(newstate)
|
|||
ent:Spawn()
|
||||
ent:DropToFloor()
|
||||
ent:SetCollisionGroup(COLLISION_GROUP_DEBRIS_TRIGGER) -- Just so no one gets stuck in it.
|
||||
ent.NoTakeOwnership = true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -3789,7 +3808,8 @@ end
|
|||
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
|
||||
|
||||
local classname = table.concat(arguments, " ")
|
||||
local classname = arguments[1]
|
||||
local suicide = arguments[2] == "1"
|
||||
local classtab = GAMEMODE.ZombieClasses[classname]
|
||||
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: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()
|
||||
end
|
||||
end
|
||||
|
|
|
@ -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_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_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_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."
|
||||
|
|
|
@ -1,17 +1,126 @@
|
|||
local function PlayerInitialSpawn(pl)
|
||||
http.Fetch("http://www.noxiousnet.com/api/player/memberlevel?steamid="..pl:SteamID(), function(body, len, headers, code)
|
||||
local level = tonumber(body)
|
||||
if level == 1 or level == 2 then
|
||||
pl._SUPPORTER_ = true
|
||||
pl:PrintMessage(HUD_PRINTCONSOLE, "GREETINGS FROM NOX, FELLOW SUPPORTER!")
|
||||
-- TODO: Make requests buffer for 3 seconds or so using ?steamids=a,b,c,d
|
||||
-- TODO: _SUPPORTER_ needs to be networked
|
||||
|
||||
local SUPPORTER_MESSAGE = "JetBoom says \"thank you for supporting my gamemodes!\" to you."
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
--hook.Add("PlayerInitialSpawn", "noxapi", PlayerInitialSpawn)
|
||||
--end
|
||||
function CACHE:Get(steamid)
|
||||
for i, tab in pairs(self.Cache) do
|
||||
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()
|
||||
resource.AddFile("materials/noxiousnet/noxicon.png")
|
||||
|
||||
if not NDB then
|
||||
CACHE:Load()
|
||||
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)]]
|
||||
|
|
|
@ -61,11 +61,6 @@ local function CheckItemCreated(self)
|
|||
table.insert(tab, ent)
|
||||
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
|
||||
if not ent.PlacedInMap then
|
||||
table.insert(tab, ent)
|
||||
|
|
|
@ -217,7 +217,7 @@ function meta:ProcessDamage(dmginfo)
|
|||
|
||||
if self:Team() == TEAM_UNDEAD then
|
||||
if self ~= attacker then
|
||||
dmginfo:SetDamage(dmginfo:GetDamage() * GAMEMODE:GetZombieDamageScale(dmginfo:GetDamagePosition(), pl))
|
||||
dmginfo:SetDamage(dmginfo:GetDamage() * GAMEMODE:GetZombieDamageScale(dmginfo:GetDamagePosition(), self))
|
||||
end
|
||||
|
||||
return self:CallZombieFunction("ProcessDamage", dmginfo)
|
||||
|
|
|
@ -101,6 +101,7 @@ function meta:TrySpawnAsGoreChild()
|
|||
local deathclass = self.DeathClass
|
||||
self:SetZombieClassName("Gore Child")
|
||||
self.DeathClass = nil
|
||||
self.DidntSpawnOnSpawnPoint = true
|
||||
self:UnSpectateAndSpawn()
|
||||
self.DeathClass = deathclass
|
||||
self:SetPos(ent:GetPos())
|
||||
|
|
|
@ -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_RED = Color(255, 0, 0)
|
||||
COLOR_BLUE = Color(0, 0, 255)
|
||||
|
@ -31,6 +19,18 @@ COLOR_SCRATCHED = Color(80, 210, 0)
|
|||
COLOR_HURT = Color(150, 50, 0)
|
||||
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)
|
||||
dest.r = source.r
|
||||
dest.g = source.g
|
||||
|
|
|
@ -97,6 +97,8 @@ GM.BarricadeHealthMax = 1100
|
|||
GM.BarricadeHealthMassFactor = 3
|
||||
GM.BarricadeHealthVolumeFactor = 4
|
||||
|
||||
GM.BossZombiePlayersRequired = 16
|
||||
|
||||
GM.HumanGibs = {
|
||||
Model("models/gibs/HGIBS.mdl"),
|
||||
Model("models/gibs/HGIBS_spine.mdl"),
|
||||
|
|
|
@ -156,7 +156,7 @@ local item = GM:AddStartingItem("manhack", "Manhack", nil, ITEMCAT_TOOLS, 60, "w
|
|||
item.Countables = "prop_manhack"
|
||||
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("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("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"
|
||||
|
|
|
@ -491,6 +491,8 @@ function GM:ShouldUseAlternateDynamicSpawn()
|
|||
end
|
||||
|
||||
function GM:GetZombieDamageScale(pos, ignore)
|
||||
if LASTHUMAN then return self.ZombieDamageMultiplier end
|
||||
|
||||
return self.ZombieDamageMultiplier * (1 - self:GetDamageResistance(self:GetFearMeterPower(pos, TEAM_UNDEAD, ignore)))
|
||||
end
|
||||
|
||||
|
|
|
@ -18,11 +18,6 @@ cvars.AddChangeCallback("zs_bosszombies", function(cvar, oldvalue, newvalue)
|
|||
GAMEMODE.BossZombies = tonumber(newvalue) == 1
|
||||
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()
|
||||
cvars.AddChangeCallback("zs_outnumberedhealthbonus", function(cvar, oldvalue, newvalue)
|
||||
GAMEMODE.OutnumberedHealthBonus = tonumber(newvalue) or 0
|
||||
|
|
|
@ -200,7 +200,7 @@ function PANEL:DoClick()
|
|||
RunConsoleCommand("zs_bossclass", self.ClassTable.Name)
|
||||
GAMEMODE:CenterNotify(translate.Format("boss_class_select", self.ClassTable.Name))
|
||||
else
|
||||
RunConsoleCommand("zs_class", self.ClassTable.Name)
|
||||
RunConsoleCommand("zs_class", self.ClassTable.Name, GAMEMODE.SuicideOnChangeClass and "1" or "0")
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -130,6 +130,12 @@ function MakepOptions()
|
|||
check:SizeToContents()
|
||||
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))
|
||||
local dropdown = vgui.Create("DComboBox", Window)
|
||||
dropdown:SetMouseInputEnabled(true)
|
||||
|
|
|
@ -35,6 +35,8 @@ function PANEL:Init()
|
|||
if lp:IsValid() then
|
||||
return lp:GetPoisonDamage()
|
||||
end
|
||||
|
||||
return 0
|
||||
end
|
||||
poisonstatus.MemberMaxValue = 50
|
||||
poisonstatus:Dock(TOP)
|
||||
|
@ -49,10 +51,31 @@ function PANEL:Init()
|
|||
if lp:IsValid() then
|
||||
return lp:GetBleedDamage()
|
||||
end
|
||||
|
||||
return 0
|
||||
end
|
||||
bleedstatus.MemberMaxValue = 20
|
||||
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:InvalidateLayout()
|
||||
end
|
||||
|
|
|
@ -10,6 +10,7 @@ CLASS.Health = 100
|
|||
CLASS.SWEP = "weapon_zs_fleshcreeper"
|
||||
CLASS.Model = Model("models/antlion.mdl")
|
||||
CLASS.Speed = 175
|
||||
CLASS.JumpPower = 220
|
||||
|
||||
CLASS.Points = 4
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ CLASS.Wave = 0
|
|||
CLASS.Unlocked = true
|
||||
|
||||
CLASS.Health = 150
|
||||
CLASS.Speed = 170
|
||||
CLASS.Speed = 160
|
||||
|
||||
CLASS.Points = 4
|
||||
|
||||
|
|
Loading…
Reference in a new issue