zombiesurvival-evolved/gamemodes/zombiesurvival/gamemode/obj_player_extend_sv.lua

908 lines
24 KiB
Lua
Raw Normal View History

2014-10-02 08:49:54 +08:00
local meta = FindMetaTable("Player")
if not meta then return end
function meta:FakeDeath(sequenceid, modelscale, length)
for _, ent in pairs(ents.FindByClass("fakedeath")) do
if ent:GetOwner() == self then
ent:Remove()
end
end
local ent = ents.Create("fakedeath")
if ent:IsValid() then
ent:SetOwner(self)
ent:SetModel(self:GetModel())
ent:SetSkin(self:GetSkin())
ent:SetColor(self:GetColor())
ent:SetMaterial(self:GetMaterial())
ent:SetPos(self:GetPos() + Vector(0, 0, 64))
ent:Spawn()
ent:SetModelScale(modelscale or self:GetModelScale(), 0)
ent:SetDeathSequence(sequenceid or 0)
ent:SetDeathAngles(self:GetAngles())
ent:SetDeathSequenceLength(length or 1)
self:DeleteOnRemove(ent)
end
return ent
end
local MuscularBones = {
["ValveBiped.Bip01_R_Upperarm"] = Vector(1, 2, 2),
["ValveBiped.Bip01_R_Forearm"] = Vector(1, 2, 2),
["ValveBiped.Bip01_L_Upperarm"] = Vector(1, 2, 2),
["ValveBiped.Bip01_L_Forearm"] = Vector(1, 2, 2)
}
function meta:DoMuscularBones()
if self.BuffMuscular and self:Team() == TEAM_HUMAN then
self.MuscularBones = {}
for bonename, newscale in pairs(MuscularBones) do
local boneid = self:LookupBone(bonename)
if boneid and boneid > 0 then
table.insert(self.MuscularBones, boneid)
self:ManipulateBoneScale(boneid, newscale)
end
end
elseif self.MuscularBones then
for _, boneid in pairs(self.MuscularBones) do
self:ManipulateBoneScale(boneid, Vector(1, 1, 1))
end
self.MuscularBones = nil
end
end
local NoodleArmBones = {
["ValveBiped.Bip01_R_Upperarm"] = Vector(1, 0.4, 0.4),
["ValveBiped.Bip01_R_Forearm"] = Vector(1, 0.4, 0.4),
["ValveBiped.Bip01_L_Upperarm"] = Vector(1, 0.4, 0.4),
["ValveBiped.Bip01_L_Forearm"] = Vector(1, 0.4, 0.4)
}
function meta:DoNoodleArmBones()
if self.NoObjectPickup and self:Team() == TEAM_HUMAN then
self.NoodleArmBones = {}
for bonename, newscale in pairs(NoodleArmBones) do
local boneid = self:LookupBone(bonename)
if boneid and boneid > 0 then
table.insert(self.NoodleArmBones, boneid)
self:ManipulateBoneScale(boneid, newscale)
end
end
elseif self.NoodleArmBones then
for _, boneid in pairs(self.NoodleArmBones) do
self:ManipulateBoneScale(boneid, Vector(1, 1, 1))
end
self.NoodleArmBones = nil
end
end
function meta:ChangeTeam(teamid)
local oldteam = self:Team()
self:SetTeam(teamid)
if oldteam ~= teamid then
gamemode.Call("OnPlayerChangedTeam", self, oldteam, teamid)
end
self:CollisionRulesChanged()
end
function meta:TrySpawnAsGoreChild()
for _, ent in pairs(ents.FindByClass("prop_thrownbaby")) do
if not ent.SpawnedOn then
ent.SpawnedOn = true
local ang = self:EyeAngles()
ang.roll = 0
ang.pitch = 0
local deathclass = self.DeathClass
self:SetZombieClassName("Gore Child")
self.DeathClass = nil
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.
2014-11-07 13:03:40 +08:00
self.DidntSpawnOnSpawnPoint = true
2014-10-02 08:49:54 +08:00
self:UnSpectateAndSpawn()
self.DeathClass = deathclass
self:SetPos(ent:GetPos())
self:SetEyeAngles(ang)
self:StartFeignDeath(true)
if IsValid(self.FeignDeath) then
self.FeignDeath:SetState(1)
self.FeignDeath:SetDirection(math.random(2) == 1 and DIR_FORWARD or DIR_BACK)
end
ent:Remove()
break
end
end
end
function meta:AddLifeBarricadeDamage(amount)
self.LifeBarricadeDamage = self.LifeBarricadeDamage + amount
if not self:Alive() and not self:GetZombieClassTable().NeverAlive then
net.Start("zs_lifestatsbd")
net.WriteUInt(self.LifeBarricadeDamage, 24)
net.Send(self)
end
end
function meta:AddLifeHumanDamage(amount)
self.LifeHumanDamage = self.LifeHumanDamage + amount
if not self:Alive() then
net.Start("zs_lifestatshd")
net.WriteUInt(math.ceil(self.LifeHumanDamage), 24)
net.Send(self)
end
end
function meta:AddLifeBrainsEaten(amount)
self.LifeBrainsEaten = self.LifeBrainsEaten + amount
if not self:Alive() then
net.Start("zs_lifestatsbe")
net.WriteUInt(self.LifeBrainsEaten, 16)
net.Send(self)
end
end
function meta:FloatingScore(victimorpos, effectname, frags, flags)
if type(victimorpos) == "Vector" then
net.Start("zs_floatscore_vec")
net.WriteVector(victimorpos)
net.WriteString(effectname)
net.WriteInt(frags, 24)
net.WriteUInt(flags, 8)
net.Send(self)
else
net.Start("zs_floatscore")
net.WriteEntity(victimorpos)
net.WriteString(effectname)
net.WriteInt(frags, 24)
net.WriteUInt(flags, 8)
net.Send(self)
end
end
function meta:MarkAsBadProfile()
self.NoProfiling = true
end
function meta:CenterNotify(...)
net.Start("zs_centernotify")
net.WriteTable({...})
net.Send(self)
end
function meta:TopNotify(...)
net.Start("zs_topnotify")
net.WriteTable({...})
net.Send(self)
end
function meta:RefreshDynamicSpawnPoint()
local target = self:GetObserverTarget()
if (GAMEMODE:GetDynamicSpawning() and self:GetObserverMode() == OBS_MODE_CHASE and target and target:IsValid()) and
(self.ZombieEscape and target:IsPlayer() and target:Team() == TEAM_UNDEAD
or not self.ZombieEscape and target:GetClass() == "prop_creepernest" and target:GetNestBuilt()
or string.sub(target:GetClass(), 1, 12) == "info_player_") then
self.ForceDynamicSpawn = target
self.ForceSpawnAngles = self:EyeAngles()
else
self.ForceDynamicSpawn = nil
self.ForceSpawnAngles = nil
end
end
function meta:PushPackedItem(class, ...)
if self.PackedItems and ... ~= nil then
local packed = {...}
self.PackedItems[class] = self.PackedItems[class] or {}
table.insert(self.PackedItems[class], packed)
end
end
function meta:PopPackedItem(class)
if self.PackedItems and self.PackedItems[class] and self.PackedItems[class][1] ~= nil then
local index = #self.PackedItems[class]
local data = self.PackedItems[class][index]
table.remove(self.PackedItems[class], index)
return data
end
end
function meta:ChangeToCrow()
self.StartCrowing = nil
local crowclass = GAMEMODE.ZombieClasses["Crow"]
if not crowclass then return end
local curclass = self.DeathClass or self:GetZombieClass()
local crowindex = crowclass.Index
self:SetZombieClass(crowindex)
self:DoHulls(crowindex, TEAM_UNDEAD)
self.DeathClass = nil
self:UnSpectateAndSpawn()
self.DeathClass = curclass
end
function meta:SelectRandomPlayerModel()
self:SetModel(player_manager.TranslatePlayerModel(GAMEMODE.RandomPlayerModels[math.random(#GAMEMODE.RandomPlayerModels)]))
end
function meta:GiveEmptyWeapon(weptype)
if not self:HasWeapon(weptype) then
local wep = self:Give(weptype)
if wep:IsValid() and wep:IsWeapon() then
wep:EmptyAll()
end
return wep
end
end
-- Here for when garry makes weapons use 357 ammo like he does every other update.
--[[local oldgive = meta.Give
function meta:Give(...)
local wep = oldgive(self, ...)
if wep:IsValid() then
if wep.Primary and wep.Primary.Ammo and wep.Primary.Ammo ~= "none" then
self:RemoveAmmo(wep.Primary.DefaultClip - wep.Primary.ClipSize, "357")
wep:SetClip1(0)
if wep.Primary.DefaultClip > wep.Primary.ClipSize then
self:GiveAmmo(wep.Primary.DefaultClip, wep.Primary.Ammo, true)
end
wep:SetClip1(wep.Primary.ClipSize)
self:RemoveAmmo(wep.Primary.ClipSize, wep.Primary.Ammo)
end
if wep.Secondary and wep.Secondary.Ammo and wep.Secondary.Ammo ~= "none" then
self:RemoveAmmo(wep.Secondary.DefaultClip - wep.Secondary.ClipSize, "357")
wep:SetClip2(0)
if wep.Secondary.DefaultClip > wep.Secondary.ClipSize then
self:GiveAmmo(wep.Secondary.DefaultClip, wep.Secondary.Ammo, true)
end
wep:SetClip2(wep.Secondary.ClipSize)
self:RemoveAmmo(wep.Secondary.ClipSize, wep.Secondary.Ammo)
end
end
return wep
end]]
function meta:StartFeignDeath(force)
local feigndeath = self.FeignDeath
if feigndeath and feigndeath:IsValid() then
if CurTime() >= feigndeath:GetStateEndTime() then
feigndeath:SetState(1)
feigndeath:SetStateEndTime(CurTime() + 1.5)
end
elseif force or self:IsOnGround() and not self:IsPlayingTaunt() then
local wep = self:GetActiveWeapon()
if force or wep:IsValid() and not wep:IsSwinging() and CurTime() > wep:GetNextPrimaryFire() then
if wep:IsValid() and wep.StopMoaning then
wep:StopMoaning()
end
local status = self:GiveStatus("feigndeath")
if status and status:IsValid() then
status:SetStateEndTime(CurTime() + 1.5)
end
end
end
end
function meta:UpdateLegDamage()
net.Start("zs_legdamage")
net.WriteFloat(self.LegDamage)
net.Send(self)
end
function meta:SendHint()
end
local function RemoveSkyCade(groundent, timername)
if not groundent:IsValid() or not (groundent.IsBarricadeObject or groundent:IsNailedToWorldHierarchy()) then
timer.Destroy(timername)
return
end
for _, pl in pairs(player.GetAll()) do
if pl:Alive() and pl:GetGroundEntity() == groundent then
groundent:TakeDamage(3, groundent, groundent)
pl:ViewPunch(Angle(math.Rand(-25, 25), math.Rand(-25, 25), math.Rand(-25, 25)))
if math.random(9) == 1 then
groundent:EmitSound("npc/strider/creak"..math.random(4)..".wav", 65, math.random(95, 105))
end
return
end
end
timer.Destroy(timername)
end
local checkoffset = Vector(0, 0, -128)
function meta:PreventSkyCade()
local groundent = self:GetGroundEntity()
if groundent:IsValid() then
if groundent:IsNailedToWorldHierarchy() then
local phys = groundent:GetPhysicsObject()
if phys:IsValid() and phys:GetMass() <= CARRY_DRAG_MASS then
local timername = "RemoveSkyCade"..tostring(groundent)
local start = groundent:WorldSpaceCenter()
if not timer.Exists(timername) and not util.TraceHull({start = start,
endpos = start + checkoffset,
mins = groundent:OBBMins() * 0.85, maxs = groundent:OBBMaxs() * 0.85,
mask = MASK_SOLID_BRUSHONLY}).Hit then
self:MarkAsBadProfile()
timer.Create(timername, 0.25, 0, function() RemoveSkyCade(groundent, timername) end) -- Oh dear.
end
end
elseif groundent.IsBarricadeObject then
local timername = "RemoveSkyCade"..tostring(groundent)
local start = groundent:WorldSpaceCenter()
if not timer.Exists(timername) and not util.TraceHull({start = start,
endpos = start + checkoffset,
mins = groundent:OBBMins() * 0.85, maxs = groundent:OBBMaxs() * 0.85,
mask = MASK_SOLID_BRUSHONLY}).Hit then
self:MarkAsBadProfile()
timer.Create(timername, 0.25, 0, function() RemoveSkyCade(groundent, timername) end) -- Oh dear.
end
end
end
end
function meta:CoupleWith(plheadcrab)
if self:GetZombieClassTable().Headcrab == plheadcrab:GetZombieClassTable().Name then
local status = self:GiveStatus("headcrabcouple")
if status:IsValid() then
status:SetCouple(plheadcrab)
end
end
end
function meta:FixModelAngles(velocity)
local eye = self:EyeAngles()
self:SetLocalAngles(eye)
self:SetPoseParameter("move_yaw", math.NormalizeAngle(velocity:Angle().yaw - eye.y))
end
function meta:RemoveAllStatus(bSilent, bInstant)
if bInstant then
for _, ent in pairs(ents.FindByClass("status_*")) do
if not ent.NoRemoveOnDeath and ent:GetOwner() == self then
ent:Remove()
end
end
else
for _, ent in pairs(ents.FindByClass("status_*")) do
if not ent.NoRemoveOnDeath and ent:GetOwner() == self then
ent.SilentRemove = bSilent
ent:SetDie()
end
end
end
end
function meta:RemoveStatus(sType, bSilent, bInstant, sExclude)
local removed
for _, ent in pairs(ents.FindByClass("status_"..sType)) do
if ent:GetOwner() == self and not (sExclude and ent:GetClass() == "status_"..sExclude) then
if bInstant then
ent:Remove()
else
ent.SilentRemove = bSilent
ent:SetDie()
end
removed = true
end
end
return removed
end
function meta:GetStatus(sType)
local ent = self["status_"..sType]
if ent and ent:IsValid() and ent.Owner == self then return ent end
end
function meta:GiveStatus(sType, fDie)
local cur = self:GetStatus(sType)
if cur then
if fDie then
cur:SetDie(fDie)
end
cur:SetPlayer(self, true)
return cur
else
local ent = ents.Create("status_"..sType)
if ent:IsValid() then
ent:Spawn()
if fDie then
ent:SetDie(fDie)
end
ent:SetPlayer(self)
return ent
end
end
end
function meta:UnSpectateAndSpawn()
self:UnSpectate()
self:Spawn()
end
function meta:SecondWind(pl)
if self.Gibbed or self:Alive() or self:Team() ~= TEAM_UNDEAD then return end
local pos = self:GetPos()
local angles = self:EyeAngles()
local lastattacker = self:GetLastAttacker()
local dclass = self.DeathClass
self.DeathClass = nil
self.Revived = true
self:UnSpectateAndSpawn()
self.Revived = nil
self.DeathClass = dclass
self:SetLastAttacker(lastattacker)
self:SetPos(pos)
self:SetHealth(self:Health() * 0.2)
self:SetEyeAngles(angles)
self:CallZombieFunction("OnSecondWind")
end
function meta:DropAll()
self:DropAllAmmo()
self:DropAllWeapons()
end
local function CreateRagdoll(pl)
if pl:IsValid() then pl:OldCreateRagdoll() end
end
local function SetModel(pl, mdl)
if pl:IsValid() then
pl:SetModel(mdl)
timer.Simple(0, function() CreateRagdoll(pl) end)
end
end
meta.OldCreateRagdoll = meta.CreateRagdoll
function meta:CreateRagdoll()
local status = self.status_overridemodel
if status and status:IsValid() then
local mdl = status:GetModel()
timer.Simple(0, function() SetModel(self, mdl) end)
status:SetRenderMode(RENDERMODE_NONE)
else
self:OldCreateRagdoll()
end
end
function meta:DropWeaponByType(class)
if GAMEMODE.ZombieEscape then return end
local wep = self:GetWeapon(class)
if wep and wep:IsValid() and not wep.Undroppable then
local ent = ents.Create("prop_weapon")
if ent:IsValid() then
ent:SetWeaponType(class)
ent:Spawn()
ent:SetClip1(wep:Clip1())
ent:SetClip2(wep:Clip2())
self:StripWeapon(class)
return ent
end
end
end
function meta:DropAllWeapons()
local vPos = self:GetPos()
local vVel = self:GetVelocity()
local zmax = self:OBBMaxs().z * 0.75
for _, wep in pairs(self:GetWeapons()) do
local ent = self:DropWeaponByType(wep:GetClass())
if ent and ent:IsValid() then
ent:SetPos(vPos + Vector(math.Rand(-16, 16), math.Rand(-16, 16), math.Rand(2, zmax)))
ent:SetAngles(VectorRand():Angle())
local phys = ent:GetPhysicsObject()
if phys:IsValid() then
phys:AddAngleVelocity(Vector(math.Rand(-720, 720), math.Rand(-720, 720), math.Rand(-720, 720)))
phys:ApplyForceCenter(phys:GetMass() * (math.Rand(32, 328) * VectorRand():GetNormalized() + vVel))
end
end
end
end
function meta:DropAmmoByType(ammotype, amount)
if GAMEMODE.ZombieEscape then return end
local mycount = self:GetAmmoCount(ammotype)
amount = math.min(mycount, amount or mycount)
if not amount or amount <= 0 then return end
local ent = ents.Create("prop_ammo")
if ent:IsValid() then
ent:SetAmmoType(ammotype)
ent:SetAmmo(amount)
ent:Spawn()
self:RemoveAmmo(amount, ammotype)
return ent
end
end
function meta:DropAllAmmo()
local vPos = self:GetPos()
local vVel = self:GetVelocity()
local zmax = self:OBBMaxs().z * 0.75
for ammotype in pairs(GAMEMODE.AmmoCache) do
local ent = self:DropAmmoByType(ammotype)
if ent and ent:IsValid() then
ent:SetPos(vPos + Vector(math.Rand(-16, 16), math.Rand(-16, 16), math.Rand(2, zmax)))
ent:SetAngles(VectorRand():Angle())
local phys = ent:GetPhysicsObject()
if phys:IsValid() then
phys:AddAngleVelocity(Vector(math.Rand(-720, 720), math.Rand(-720, 720), math.Rand(-720, 720)))
phys:ApplyForceCenter(phys:GetMass() * (math.Rand(32, 328) * VectorRand():GetNormalized() + vVel))
end
end
end
end
-- Lets other players know about our maximum health.
meta.OldSetMaxHealth = FindMetaTable("Entity").SetMaxHealth
function meta:SetMaxHealth(num)
num = math.ceil(num)
self:SetDTInt(0, num)
self:OldSetMaxHealth(num)
end
function meta:PointCashOut(ent, fmtype)
if self.m_PointQueue >= 1 and self:Team() == TEAM_HUMAN then
local points = math.floor(self.m_PointQueue)
self.m_PointQueue = self.m_PointQueue - points
self:AddPoints(points)
self:FloatingScore(ent or self.m_LastDamageDealtPosition or vector_origin, "floatingscore", points, fmtype or FM_NONE)
end
end
function meta:AddPoints(points)
self:AddFrags(points)
self:SetPoints(self:GetPoints() + points)
gamemode.Call("PlayerPointsAdded", self, points)
end
function meta:TakePoints(points)
self:SetPoints(self:GetPoints() - points)
end
function meta:UpdateAllZombieClasses()
for _, pl in pairs(player.GetAll()) do
if pl ~= self and pl:Team() == TEAM_UNDEAD then
local id = pl:GetZombieClass()
if id and 0 < id then
net.Start("zs_zclass")
net.WriteEntity(pl)
net.WriteUInt(id, 8)
net.Send(self)
end
end
end
end
function meta:CreateAmbience(class)
class = "status_"..class
for _, ent in pairs(ents.FindByClass(class)) do
if ent:GetOwner() == self then return end
end
local ent = ents.Create(class)
if ent:IsValid() then
ent:SetPos(self:LocalToWorld(self:OBBCenter()))
self[class] = ent
ent:SetOwner(self)
ent:SetParent(self)
ent:Spawn()
end
end
function meta:SetZombieClass(cl, onlyupdate, filter)
if onlyupdate then
net.Start("zs_zclass")
net.WriteEntity(self)
net.WriteUInt(cl, 8)
if filter then
net.Send(filter)
else
net.Broadcast()
end
return
end
self:CallZombieFunction("SwitchedAway")
local classtab = GAMEMODE.ZombieClasses[cl]
if classtab then
self.Class = cl
if self:Team() == TEAM_UNDEAD then
self:DoHulls(cl)
end
self:CallZombieFunction("SwitchedTo")
net.Start("zs_zclass")
net.WriteEntity(self)
net.WriteUInt(cl, 8)
if filter then
net.Send(filter)
else
net.Broadcast()
end
end
end
function meta:DoHulls(classid, teamid)
teamid = teamid or self:Team()
classid = classid or self:GetZombieClass()
if teamid == TEAM_UNDEAD then
local classtab = GAMEMODE.ZombieClasses[classid]
if classtab then
if self:Alive() then
self:SetMoveType(classtab.MoveType or MOVETYPE_WALK)
end
if classtab.ModelScale then
self:SetModelScale(classtab.ModelScale, 0)
elseif self:GetModelScale() ~= DEFAULT_MODELSCALE then
self:SetModelScale(DEFAULT_MODELSCALE, 0)
end
if not classtab.Hull or not classtab.HullDuck then
self:ResetHull()
end
if classtab.ViewOffset then
self:SetViewOffset(classtab.ViewOffset)
elseif self:GetViewOffset() ~= DEFAULT_VIEW_OFFSET then
self:SetViewOffset(DEFAULT_VIEW_OFFSET)
end
if classtab.ViewOffsetDucked then
self:SetViewOffsetDucked(classtab.ViewOffsetDucked)
elseif self:GetViewOffsetDucked() ~= DEFAULT_VIEW_OFFSET_DUCKED then
self:SetViewOffsetDucked(DEFAULT_VIEW_OFFSET_DUCKED)
end
if classtab.HullDuck then
self:SetHullDuck(classtab.HullDuck[1], classtab.HullDuck[2])
end
if classtab.Hull then
self:SetHull(classtab.Hull[1], classtab.Hull[2])
end
if classtab.StepSize then
self:SetStepSize(classtab.StepSize)
elseif self:GetStepSize() ~= DEFAULT_STEP_SIZE then
self:SetStepSize(DEFAULT_STEP_SIZE)
end
if classtab.JumpPower then
self:SetJumpPower(classtab.JumpPower)
elseif self:GetJumpPower() ~= DEFAULT_JUMP_POWER then
self:SetJumpPower(DEFAULT_JUMP_POWER)
end
self:DrawShadow(not classtab.NoShadow)
self.NoCollideAll = classtab.NoCollideAll
self.AllowTeamDamage = classtab.AllowTeamDamage
self.NeverAlive = classtab.NeverAlive
local phys = self:GetPhysicsObject()
if phys:IsValid() then
phys:SetMass(classtab.Mass or DEFAULT_MASS)
end
end
else
self:SetModelScale(DEFAULT_MODELSCALE, 0)
self:ResetHull()
self:SetViewOffset(DEFAULT_VIEW_OFFSET)
self:SetViewOffsetDucked(DEFAULT_VIEW_OFFSET_DUCKED)
self:SetStepSize(DEFAULT_STEP_SIZE)
self:SetJumpPower(DEFAULT_JUMP_POWER)
self:DrawShadow(true)
self.NoCollideAll = nil
self.AllowTeamDamage = nil
self.NeverAlive = nil
local phys = self:GetPhysicsObject()
if phys:IsValid() then
phys:SetMass(DEFAULT_MASS)
end
end
net.Start("zs_dohulls")
net.WriteEntity(self)
net.WriteUInt(classid, 16)
net.WriteUInt(teamid, 16)
net.Broadcast()
self:CollisionRulesChanged()
end
function meta:Redeem()
gamemode.Call("PlayerRedeemed", self)
end
function meta:RedeemNextFrame()
timer.Simple(0, function()
if IsValid(self) then
self:CheckRedeem(true)
end
end)
end
function meta:TakeBrains(amount)
self:AddFrags(-amount)
self.BrainsEaten = self.BrainsEaten - 1
end
function meta:AddBrains(amount)
self:AddFrags(amount)
self.BrainsEaten = self.BrainsEaten + 1
self:CheckRedeem()
end
function meta:CheckRedeem(instant)
if self:IsValid() and self:Team() == TEAM_UNDEAD and GAMEMODE:GetRedeemBrains() > 0 and GAMEMODE:GetRedeemBrains() <= self:Frags() and GAMEMODE:GetWave() ~= GAMEMODE:GetNumberOfWaves() and not self.NoRedeeming and not self:GetZombieClassTable().Boss then
if instant then
self:Redeem()
else
self:RedeemNextFrame()
end
end
end
function meta:AntiGrief(dmginfo, overridenostrict)
if GAMEMODE.GriefStrict and not overridenostrict then
dmginfo:SetDamage(0)
dmginfo:ScaleDamage(0)
return
end
dmginfo:SetDamage(dmginfo:GetDamage() * GAMEMODE.GriefForgiveness)
self:GivePenalty(math.ceil(dmginfo:GetDamage() * 0.5))
self:ReflectDamage(dmginfo:GetDamage())
end
function meta:GivePenalty(amount)
self.m_PenaltyCarry = (self.m_PenaltyCarry or 0) + amount * 0.1
local frags = math.floor(self.m_PenaltyCarry)
if frags > 0 then
self.m_PenaltyCarry = self.m_PenaltyCarry - frags
self:GivePointPenalty(frags)
end
end
function meta:GivePointPenalty(amount)
self:SetFrags(self:Frags() - amount)
net.Start("zs_penalty")
net.WriteUInt(amount, 16)
net.Send(self)
end
function meta:ReflectDamage(damage)
local frags = self:Frags()
if frags < GAMEMODE.GriefReflectThreshold then
self:TakeDamage(math.ceil(damage * frags * -0.05 * GAMEMODE.GriefDamageMultiplier))
end
end
function meta:GiveWeaponByType(weapon, plyr, ammo)
if ammo then
local wep = self:GetActiveWeapon()
if not wep or not wep:IsValid() or not wep.Primary then return end
local ammotype = wep:ValidPrimaryAmmo()
local ammocount = wep:GetPrimaryAmmoCount()
if ammotype and ammocount then
local desiredgive = math.min(ammocount, math.ceil((GAMEMODE.AmmoCache[ammotype] or wep.Primary.ClipSize) * 5))
if desiredgive >= 1 then
wep:TakeCombinedPrimaryAmmo(desiredgive)
plyr:GiveAmmo(desiredgive, ammotype)
self:PlayGiveAmmoSound()
self:RestartGesture(ACT_GMOD_GESTURE_ITEM_GIVE)
end
end
end
local wep = self:GetActiveWeapon()
if wep:IsValid() then
local primary = wep:ValidPrimaryAmmo()
if primary and 0 < wep:Clip1() then
self:GiveAmmo(wep:Clip1(), primary, true)
wep:SetClip1(0)
end
local secondary = wep:ValidSecondaryAmmo()
if secondary and 0 < wep:Clip2() then
self:GiveAmmo(wep:Clip2(), secondary, true)
wep:SetClip2(0)
end
self:StripWeapon(weapon:GetClass())
local wep2 = plyr:Give(weapon:GetClass())
if wep2 and wep2:IsValid() then
if wep2.Primary then
local primary = wep2:ValidPrimaryAmmo()
if primary then
wep2:SetClip1(0)
plyr:RemoveAmmo(math.max(0, wep2.Primary.DefaultClip - wep2.Primary.ClipSize), primary)
end
end
if wep2.Secondary then
local secondary = wep2:ValidSecondaryAmmo()
if secondary then
wep2:SetClip2(0)
plyr:RemoveAmmo(math.max(0, wep2.Secondary.DefaultClip - wep2.Secondary.ClipSize), secondary)
end
end
end
end
end
function meta:Gib()
local pos = self:WorldSpaceCenter()
local headoffset = self:LocalToWorld(self:OBBMaxs()).z - pos.z
local effectdata = EffectData()
effectdata:SetEntity(self)
effectdata:SetOrigin(pos)
util.Effect("gib_player", effectdata, true, true)
self.Gibbed = CurTime()
timer.Simple(0, function() GAMEMODE:CreateGibs(pos, pos2) end)
end
function meta:GetLastAttacker()
local ent = self.LastAttacker
if ent and ent:IsValid() and ent:Team() ~= self:Team() and CurTime() <= self.LastAttacked + 10 then
return ent
end
self:SetLastAttacker()
end
function meta:SetLastAttacker(ent)
if ent then
if ent ~= self then
self.LastAttacker = ent
self.LastAttacked = CurTime()
end
else
self.LastAttacker = nil
self.LastAttacked = nil
end
end
meta.OldUnSpectate = meta.UnSpectate
function meta:UnSpectate()
if self:GetObserverMode() ~= OBS_MODE_NONE then
self:OldUnSpectate(obsm)
end
end