AddCSLuaFile( "cl_init.lua" )
AddCSLuaFile( "tables.lua" )
AddCSLuaFile( "admin.lua" )
AddCSLuaFile( "inventories.lua" )
AddCSLuaFile( "awards.lua" )
AddCSLuaFile( "shared.lua" )
AddCSLuaFile( "cl_postprocess.lua" )
AddCSLuaFile( "cl_spawnmenu.lua" )
AddCSLuaFile( "cl_scoreboard.lua" )
AddCSLuaFile( "cl_hudpickup.lua" )
AddCSLuaFile( "cl_deathnotice.lua" )
AddCSLuaFile( "cl_notice.lua" )
AddCSLuaFile( "cl_hudstains.lua" )
include( "tables.lua" )
include( "admin.lua" )
include( "inventories.lua" )
include( "awards.lua" )
include( "shared.lua" )
include( "player.lua" )
include( "ply_extension.lua" )
include( "powerups.lua" )
include( "anims.lua" )
if GameInfo.MusicEnabled then
resource.AddFile("sound/"..GameInfo.LastMinuteSong)
end
for k,v in pairs({4,6,8}) do
resource.AddFile("models/Zed/malezed_0"..v..".dx80.vtx")
resource.AddFile("models/Zed/malezed_0"..v..".dx90.vtx")
resource.AddFile("models/Zed/malezed_0"..v..".mdl")
resource.AddFile("models/Zed/malezed_0"..v..".phy")
resource.AddFile("models/Zed/malezed_0"..v..".sw.vtx")
resource.AddFile("models/Zed/malezed_0"..v..".vvd")
end
resource.AddFile("models/Zed/male_shared.mdl")
resource.AddFile("materials/models/Zed/Male/pupil_l.vmt")
resource.AddFile("materials/models/Zed/Male/pupil_l.vtf")
resource.AddFile("materials/models/Zed/Male/pupil_r.vmt")
resource.AddFile("materials/models/Zed/Male/pupil_r.vtf")
resource.AddFile("materials/models/Zed/Male/eyeball_l.vmt")
resource.AddFile("materials/models/Zed/Male/eyeball_l.vtf")
resource.AddFile("materials/models/Zed/Male/eyeball_r.vmt")
resource.AddFile("materials/models/Zed/Male/eyeball_r.vtf")
resource.AddFile("materials/models/Zed/Male/dark_eyeball_l.vmt")
resource.AddFile("materials/models/Zed/Male/dark_eyeball_l.vtf")
resource.AddFile("materials/models/Zed/Male/dark_eyeball_r.vmt")
resource.AddFile("materials/models/Zed/Male/dark_eyeball_r.vtf")
resource.AddFile("materials/models/Zed/Male/glint.vmt")
resource.AddFile("materials/models/Zed/Male/glint.vtf")
resource.AddFile("materials/models/Zed/Male/mouth.vmt")
resource.AddFile("materials/models/Zed/Male/mouth.vtf")
resource.AddFile("materials/models/Zed/Male/citizen_sheet.vmt")
resource.AddFile("materials/models/Zed/Male/citizen_sheet.vtf")
resource.AddFile("materials/models/Zed/Male/blood_sheet.vmt")
resource.AddFile("materials/models/Zed/Male/blood_sheet.vtf")
resource.AddFile("materials/models/Zed/Male/grey_sheet.vmt")
resource.AddFile("materials/models/Zed/Male/grey_sheet.vtf")
resource.AddFile("materials/models/Zed/Male/plaid_sheet.vmt")
resource.AddFile("materials/models/Zed/Male/plaid_sheet.vtf")
resource.AddFile("materials/models/Zed/Male/service_sheet.vmt")
resource.AddFile("materials/models/Zed/Male/service_sheet.vtf")
resource.AddFile("materials/models/Zed/Male/jackson_sheet.vmt")
resource.AddFile("materials/models/Zed/Male/jackson_sheet.vtf")
resource.AddFile("materials/models/Zed/Male/eric_facemap.vmt")
resource.AddFile("materials/models/Zed/Male/eric_facemap.vtf")
resource.AddFile("materials/models/Zed/Male/joe_facemap.vmt")
resource.AddFile("materials/models/Zed/Male/joe_facemap.vtf")
resource.AddFile("materials/models/Zed/Male/sandro_facemap.vmt")
resource.AddFile("materials/models/Zed/Male/sandro_facemap.vtf")
resource.AddFile("materials/models/Zed/Male/vance_facemap.vmt")
resource.AddFile("materials/models/Zed/Male/vance_facemap.vtf")
for i=1,4 do
for e=1,5 do
resource.AddFile("materials/models/Zed/Male/g"..i.."_0"..e.."_sheet.vmt")
end
end
resource.AddFile("resource/fonts/typenoksidi.ttf")
resource.AddFile("resource/fonts/mortbats.ttf")
resource.AddFile("materials/gmod/scope.vtf")
resource.AddFile("materials/gmod/scope.vmt")
resource.AddFile("materials/gmod/scope-refract.vmt")
resource.AddFile("materials/gmod/scope-refract.vtf")
resource.AddFile("materials/blood/Blood1.vmt")
resource.AddFile("materials/blood/Blood2.vmt")
resource.AddFile("materials/blood/Blood3.vmt")
resource.AddFile("materials/blood/Blood4.vmt")
resource.AddFile("materials/blood/Blood5.vmt")
resource.AddFile("materials/blood/Blood6.vmt")
resource.AddFile("materials/blood/Blood7.vmt")
resource.AddFile("materials/blood/Blood8.vmt")
resource.AddFile("materials/ReDead/allyvision.vmt")
resource.AddFile("materials/ReDead/allyvisionblue.vtf")
resource.AddFile("models/Zed/weapons/v_undead.vvd")
resource.AddFile("models/Zed/weapons/v_undead.mdl")
resource.AddFile("models/Zed/weapons/v_undead.sw.vtx")
resource.AddFile("models/Zed/weapons/v_undead.dx80.vtx")
resource.AddFile("models/Zed/weapons/v_undead.dx90.vtx")
resource.AddFile("models/Zed/weapons/v_wretch.vvd")
resource.AddFile("models/Zed/weapons/v_wretch.mdl")
resource.AddFile("models/Zed/weapons/v_wretch.sw.vtx")
resource.AddFile("models/Zed/weapons/v_wretch.dx80.vtx")
resource.AddFile("models/Zed/weapons/v_wretch.dx90.vtx")
resource.AddFile("models/Zed/weapons/v_banshee.vvd")
resource.AddFile("models/Zed/weapons/v_banshee.mdl")
resource.AddFile("models/Zed/weapons/v_banshee.sw.vtx")
resource.AddFile("models/Zed/weapons/v_banshee.dx80.vtx")
resource.AddFile("models/Zed/weapons/v_banshee.dx90.vtx")
resource.AddFile("models/Zed/weapons/v_disease.vvd")
resource.AddFile("models/Zed/weapons/v_disease.mdl")
resource.AddFile("models/Zed/weapons/v_disease.sw.vtx")
resource.AddFile("models/Zed/weapons/v_disease.dx80.vtx")
resource.AddFile("models/Zed/weapons/v_disease.dx90.vtx")
resource.AddFile("models/Zed/weapons/v_ghoul.vvd")
resource.AddFile("models/Zed/weapons/v_ghoul.mdl")
resource.AddFile("models/Zed/weapons/v_ghoul.sw.vtx")
resource.AddFile("models/Zed/weapons/v_ghoul.dx80.vtx")
resource.AddFile("models/Zed/weapons/v_ghoul.dx90.vtx")
resource.AddFile("models/Weapons/v_shot_m3super91.dx80.vtx")
resource.AddFile("models/Weapons/v_shot_m3super91.dx90.vtx")
resource.AddFile("models/Weapons/v_shot_m3super91.sw.vtx")
resource.AddFile("models/Weapons/v_shot_m3super91.vvd")
resource.AddFile("models/Weapons/v_shot_m3super91.mdl")
resource.AddFile("materials/Models/Weapons/v_models/shot_m3super91/shot_m3super91.vmt")
resource.AddFile("materials/Models/Weapons/v_models/shot_m3super91/shot_m3super91.vtf")
resource.AddFile("materials/Models/Weapons/v_models/shot_m3super91/shot_m3super91_norm.vtf")
resource.AddFile("materials/Models/Weapons/v_models/shot_m3super91/shot_m3super91_norm.vmt")
resource.AddFile("materials/Models/Weapons/v_models/shot_m3super91/shot_m3super91_2.vtf")
resource.AddFile("materials/Models/Weapons/v_models/shot_m3super91/shot_m3super91_2.vmt")
resource.AddFile("materials/Models/Weapons/v_models/shot_m3super91/shot_m3super91_2_norm.vtf")
resource.AddFile("materials/Models/Weapons/v_models/shot_m3super91/shot_m3super91_2_norm.vmt")
////////////////////////////////////////////////////////////////////
function GM:Initialize( )
self.BaseClass:Initialize( )
self:SetupTeams()
game.ConsoleCommand("sv_maxvelocity 9999\n")
game.ConsoleCommand("sk_dynamic_resupply_modifier 0\n")
game.ConsoleCommand("mapcyclefile "..GameInfo.CycleFile.."\n")
GameInfo.Disconnected = {}
GameInfo.HumanSpawnTime = CurTime() + GameInfo.DeadLine*60
GameInfo.TimeLimit = GameInfo.TimeLimit*60
GameInfo.SurviveTimeRatio = 0
GameInfo.GameOver = false
GameInfo.EndTime = CurTime() + GameInfo.TimeLimit
GameInfo.Unlock = .2
GameInfo.NpcInterval = CurTime() + 25
if GameInfo.RealisticFallDamage then
game.ConsoleCommand("mp_falldamage 1\n")
else
game.ConsoleCommand("mp_falldamage 0\n")
end
timer.Create("LastMinute", GameInfo.TimeLimit - 60, 1, GAMEMODE.LastMinute, GAMEMODE)
timer.Create("CheckTimer", GameInfo.TimeLimit * .2, 4, GAMEMODE.CheckTime, GAMEMODE)
end
function GM:LastMinute()
for k,v in pairs(player.GetAll()) do
if v:Team() == TEAM_HUMANS then
if GameInfo.MusicEnabled then
v:ClientSound(GameInfo.LastMinuteSong)
end
Inventory.Notice(v, "One minute left", Inventory.White)
end
end
end
function GM:CheckTime()
GameInfo.Unlock = GameInfo.Unlock + .2
for k,v in pairs(team.GetPlayers(TEAM_HUMANS)) do
v:VoiceSound(ChooseRandom(v.Alert),100,math.Rand(3,5))
v:ClientSound(ChooseRandom(GameSounds.AmbientScream))
umsg.Start("UnlockClass", v)
umsg.Float(GameInfo.Unlock)
umsg.End()
local percent = GameInfo.Unlock * 100
Inventory.Notice(v, percent.."% mortality", Inventory.White)
if percent == 40 then
timer.Simple(4, function(v) Inventory.Notice(v, "The mortality rate is a warning", Inventory.White) end, v )
timer.Simple(6, function(v) Inventory.Notice(v, "Each time it increases, more zombies spawn", Inventory.White) end, v )
timer.Simple(8, function(v) Inventory.Notice(v, "New zombie types will also appear", Inventory.White) end, v )
end
end
for k,v in pairs(team.GetPlayers(TEAM_UNDEAD)) do
v:VoiceSound(ChooseRandom(v.Taunt),100,math.Rand(0,3))
umsg.Start("UnlockClass", v)
umsg.Float(GameInfo.Unlock)
umsg.End()
Inventory.Notice(v, "New classes unlocked", Inventory.Green)
end
if team.NumPlayers(TEAM_HUMANS) < 1 then
GAMEMODE:EndGame()
end
end
function GM:ChangeCureLocation( noPunish )
if GameInfo.EndTime < CurTime() + 120 then return end
local oldpos = Vector(0,0,0)
if GameInfo.Cure then
oldpos = GameInfo.Cure:GetPos()
GameInfo.Cure:Remove()
GameInfo.Cure = nil
end
local effectdata = EffectData()
effectdata:SetOrigin(oldpos)
util.Effect("antidote_die", effectdata)
local distance = 1
local newpos = Vector(0,0,0)
local ent
while distance < 1500 do
ent = ChooseRandom(ents.FindByClass("prop_physics*"))
newpos = ent:GetPos()
distance = oldpos:Distance(newpos)
local pos = ent:LocalToWorld(ent:OBBCenter())
if not util.IsInWorld(pos) then
distance = 1
end
end
local pos = ent:LocalToWorld(ent:OBBCenter())
local cure = ents.Create("sent_antidote")
cure:SetCollisionGroup(COLLISION_GROUP_WEAPON)
cure:Spawn()
cure:SetPos(pos)
GameInfo.Cure = cure
for k,v in pairs(player.GetAll()) do
v:SetNetworkedVector("antidotepos",cure:LocalToWorld(cure:OBBCenter()))
Inventory.Notice(v, "Antidote zone changed", Inventory.White)
umsg.Start("UpdateCureTime",v)
umsg.Short( CurTime() + (GameInfo.LocationInterval*60) )
umsg.End()
end
for k,v in pairs(team.GetPlayers(TEAM_HUMANS)) do
v:VoiceSound(ChooseRandom(v.Alert),100,math.Rand(.1,1))
if not noPunish then
if not v:Immune() then
v:DoInfection()
Inventory.Notice(v, "Your immune system failed", Inventory.Red)
if not v.AntHint then
v.AntHint = true
timer.Simple(4, function(v) Inventory.Notice(v, "To cure infections, go to the antidote", Inventory.White) end, v )
timer.Simple(6, function(v) Inventory.Notice(v, "The antidote zone is marked on your screen", Inventory.White) end, v )
end
else
v:SetImmune(false)
end
end
end
end
function GM:Think()
for k,v in pairs(player.GetAll()) do
if v:Alive() then
v:DoOnFire()
v:DoPoisoned()
v:DoInfected()
v:DoStamina()
v:DoBleeding()
v:DoBlindness()
v:DoDrown()
end
end
if CurTime() > GameInfo.TimeLimit and not GameInfo.GameOver then
GAMEMODE:EndGame()
end
GAMEMODE:SpawnNpcs()
end
function GM:SpawnNpcs()
if not GameInfo.NpcInterval then
if not GameInfo.NpcSpawns then
GameInfo.NpcSpawns = ents.FindByClass( "info_player_counterterrorist" )
GameInfo.NpcSpawns = table.Add(GameInfo.NpcSpawns, ents.FindByClass( "info_player_rebel" ))
GameInfo.NpcSpawns = table.Add(GameInfo.NpcSpawns, ents.FindByClass( "info_player_undead" ))
GameInfo.NpcSpawns = table.Add(GameInfo.NpcSpawns, ents.FindByClass( "info_player_zombie" ))
if GameInfo.NpcSpawns == nil or table.Count(GameInfo.NpcSpawns) < 2 then
GameInfo.NpcSpawns = ents.FindByClass( "info_player_human" )
end
end
if team.NumPlayers(TEAM_HUMANS) == 0 then
GameInfo.NpcInterval = CurTime() + GameInfo.NpcSpawnTime + math.random(-5,5)
return
end
for i=0,team.NumPlayers(TEAM_HUMANS) + math.random(1,3) do
GAMEMODE:SpawnUndead("npc_undead")
end
if GameInfo.Unlock > .2 then
for i=1,math.random(1,2) do
GAMEMODE:SpawnUndead("npc_ghoul")
GAMEMODE:SpawnUndead("npc_undead")
end
end
if GameInfo.Unlock > .4 then
for i=1,math.Clamp(math.Round(team.NumPlayers(TEAM_HUMANS) / 2),1,8) do
GAMEMODE:SpawnUndead("npc_wretch")
end
GAMEMODE:SpawnUndead("npc_undead")
end
if GameInfo.Unlock > .6 then
GAMEMODE:SpawnUndead("npc_disease")
GAMEMODE:SpawnUndead("npc_undead")
end
GameInfo.NpcInterval = CurTime() + GameInfo.NpcSpawnTime + math.random(-5,5)
elseif GameInfo.NpcInterval < CurTime() then
GameInfo.NpcInterval = nil
end
end
function GM:SpawnUndead(ztype)
local zombies = ents.FindByClass("npc_*")
if table.Count(zombies) > MAX_NUM_ZOMBIES then return end
local point = ChooseRandom(GameInfo.NpcSpawns)
local pos = point:GetPos() + Vector(0,0,5)
local block
for k, ent in pairs(ents.FindInBox(point:GetPos() + Vector(-48, -48, 0), point:GetPos() + Vector(48, 48, 60))) do
if ent and ent:IsNPC() then
block = ent
end
end
if block then
if block:IsValid() then
GAMEMODE:SpawnUndead(block:GetClass())
block:Remove()
end
end
local undead = ents.Create(ztype)
undead:SetPos(pos)
undead:Spawn()
undead:Activate()
end
function GM:InitPostEntity( )
GAMEMODE:ChangeCureLocation(true)
timer.Create("CureTimer", (60*GameInfo.LocationInterval), 0, GAMEMODE.ChangeCureLocation, GAMEMODE)
if not GameInfo.NpcSpawns then
GameInfo.NpcSpawns = ents.FindByClass( "info_player_counterterrorist" )
GameInfo.NpcSpawns = table.Add(GameInfo.NpcSpawns, ents.FindByClass( "info_player_rebel" ))
GameInfo.NpcSpawns = table.Add(GameInfo.NpcSpawns, ents.FindByClass( "info_player_undead" ))
GameInfo.NpcSpawns = table.Add(GameInfo.NpcSpawns, ents.FindByClass( "info_player_zombie" ))
if GameInfo.NpcSpawns == nil or table.Count(GameInfo.NpcSpawns) < 2 then
GameInfo.NpcSpawns = ents.FindByClass( "info_player_human" )
end
end
GAMEMODE:EditProps()
end
Replace = {}
Replace[1] = {Class="prop_physics", Replace=nil}
Replace[2] = {Class="prop_physics_override", Replace=nil}
Replace[3] = {Class="weapon_*", Replace=Inventory.AmmoItems}
Replace[4] = {Class="item_*", Replace=Inventory.AidItems}
Replace[5] = {Class="npc_*", Replace=Inventory.KitItems}
Replace[6] = {Class="env_fire", Replace=Inventory.KitItems}
Replace[7] = {Class="prop_vehicle*", Replace=Inventory.KitItems}
Replace[8] = {Class="prop_ragdoll", Replace=Inventory.KitItems}
Replace[9] = {Class="point_template", Replace=Inventory.KitItems}
ReplacedModels = {"models/items/boxmrounds.mdl",
"models/items/boxsrounds.mdl",
"models/items/boxbuckshot.mdl",
"models/items/357ammobox.mdl",
"models/items/357ammo.mdl",
"models/items/battery.mdl",
"models/healthvial.mdl"}
function GM:EditProps()
for k,v in pairs(ReplacedModels) do
for i=1,math.random(1,2) do
local amm = ents.Create("prop_physics_respawnable")
util.PrecacheModel(v)
amm:SetModel(v)
amm:SetPos(ChooseRandom(ents.FindByClass("prop_physics")):GetPos() + Vector(0,0,20))
amm:SetAngles(Angle(0,0,0))
amm:Spawn()
end
end
for i=1,math.random(3,6) do
local item = ents.Create("sent_weapon")
local model = ChooseRandom({"models/weapons/w_pistol.mdl",
"models/weapons/w_pist_deagle.mdl",
"models/weapons/w_pist_elite_dropped.mdl",
"models/weapons/w_smg_mac10.mdl",
"models/weapons/w_smg_tmp.mdl"})
util.PrecacheModel(model)
item:SetModel(model)
item:SetPos(ChooseRandom(ents.FindByClass("prop_physics")):GetPos() + Vector(0,0,20))
item:SetAngles(Angle(0,0,0))
item:Spawn()
end
for c,d in pairs(Replace) do
for k,v in pairs(ents.FindByClass(d.Class)) do
if not string.find(v:GetClass(),"_multiplayer") then
timer.Create("PropSpawn"..k.."p", 0.1 * math.random(10,30), 1, GAMEMODE.SpawnItem, GAMEMODE, v:GetModel(), d.Replace, v:GetPos(), v:GetAngles(), v:GetSkin())
v:Remove()
end
end
end
local radi = ents.Create("point_radiation")
radi:SetPos(ChooseRandom(GameInfo.NpcSpawns):GetPos() + Vector(0,0,50))
radi:Spawn()
radi:Activate()
end
function GM:SpawnItem(model,replace,pos,angles,skin)
model = string.Replace(model,"//","/")
local prop = ents.Create("prop_physics_respawnable")
prop:SetPos(pos + Vector(0,0,1))
prop:SetAngles(angles)
if replace then
prop:SetModel(ChooseRandom(replace))
elseif string.find(string.lower(model),"oildrum001_explosive.mdl") or table.HasValue(ReplacedModels,string.lower(model)) then
prop:SetModel(ChooseRandom(Inventory.KitItems))
else
prop:SetModel(model)
end
prop:SetSkin(skin)
prop:Spawn()
prop:SetHealth(150)
if not prop:IsValid() then
timer.Create("RePropSpawn"..math.random(1,900), 0.1 * math.random(10,30), 1, GAMEMODE.SpawnItem, GAMEMODE, model, replace, pos + Vector(0,0,5), Angle(0,0,0), values)
end
end
function GM:GetGameDescription()
if GameInfo.ModdedName == "" then
if GameInfo.HumanDamageScale > 1.0 or
GameInfo.HumanDamageScale < 1.0 or
GameInfo.ZombieItemChance > 50 or
GameInfo.NpcSpawnTime > 60 or
Points["Undead"] > 1 or
Points["Wretch"] > 2 or
Points["Ghoul"] > 2 then
GameInfo.ModdedName = "Edited"
end
end
return self.Name.." "..GameInfo.ModdedName
end
function GM:PlayerInitialSpawn( ply )
if (team.NumPlayers(TEAM_HUMANS) >= GameInfo.HumanCount and team.NumPlayers(TEAM_UNDEAD) < 1) then
local chosen = ChooseRandom(team.GetPlayers(TEAM_HUMANS))
chosen:SetTeam(TEAM_UNDEAD)
chosen.ZombieClass = "Dead"
chosen:Kill()
Inventory.Notice(chosen, "You were chosen to join the undead", Inventory.White)
chosen:AddPowerup(math.random(1,3))
chosen:AddAwardPoints(AWARD_BAD_POINTS,100)
chosen:AddAwardPoints(AWARD_BAD_KILLS,100)
chosen:AddAwardPoints(AWARD_BAD_HEADSHOT,100)
end
self.BaseClass:PlayerInitialSpawn( ply )
ply.HumanClass = ChooseRandom({"Militant","Support","Medic","Engineer"})
ply.ZombieClass = "Undead"
if table.HasValue(GameInfo.Disconnected,ply:SteamID())
or (GameInfo.HumanSpawnTime < CurTime() and team.NumPlayers(TEAM_HUMANS) > 0) then
if team.NumPlayers(TEAM_UNDEAD) < 1 then
ply:AddPowerup(math.random(1,3))
end
ply:SetTeam(TEAM_UNDEAD)
ply:SetNetworkedString("available","99")
umsg.Start("UnlockClass", ply)
umsg.Float(GameInfo.Unlock)
umsg.End()
umsg.Start("UpdateTime", ply)
umsg.Short(GameInfo.EndTime)
umsg.End()
else
local prof = OpenFromFile(string.sub(ply:SteamID(),11))
if prof[1] then
ply:SetNetworkedString("classdisable",tostring(prof[1]))
else
ply:SetNetworkedString("classdisable",ply.HumanClass)
timer.Simple(10, function(ply) Inventory.Notice(ply, "Press F1 for a helpful guide", Inventory.White) end, ply )
timer.Simple(15, function(ply) Inventory.Notice(ply, "Press F4 to open the options menu", Inventory.White) end, ply )
timer.Simple(20, function(ply) Inventory.Notice(ply, "Press F2 to quick-buy items", Inventory.White) end, ply )
timer.Simple(25, function(ply) Inventory.Notice(ply, "Press NumPad 0 for voice commands", Inventory.White) end, ply )
end
Inventory.UpdateClientStock(ply)
ply:SetTeam(TEAM_SPECTATOR)
ply:Spawn()
ply:Spectate(OBS_MODE_ROAMING)
ply:SetMoveType(MOVETYPE_NOCLIP)
ply:SetColor(0,0,0,0)
ply.MenuOpen = true
for i=0,3 do
numpad.OnDown( ply, i, "VoiceChat", i )
end
//numpad.OnDown( ply, 0, "VoiceChat", 0 )
end
end
function GM:LoadClassMenu(ply)
umsg.Start("ClassMenu", ply)
umsg.Short(TEAM_HUMANS)
umsg.End()
umsg.Start("InvSynch", ply)
umsg.End()
end
function GM:HumanSetup( ply )
ply.LastItem = "Pistol Rounds"
ply:SetColor(255,255,255,255)
ply:EmptyInventory()
if ply:IsFemale() then
for i=1,#HumanClass do
if (string.lower(HumanClass[i].Name) == string.lower(ply.HumanClass)) then
GAMEMODE:SetPlayerSpeed( ply, HumanClass[i].Speed, HumanClass[i].Speed )
ply.WalkSpeed = HumanClass[i].Speed
ply:SetHealth(HumanClass[i].Health)
ply.MaxHealth = HumanClass[i].Health
ply.WeaponSlots = HumanClass[i].WeaponSlots
ply:SetModel(ChooseRandom(HumanClass[i].F_Model))
ply.Alert = HumanClass[i].F_Alert
ply.Death = HumanClass[i].F_Death
ply.Pain = HumanClass[i].F_Pain
ply.Taunt = HumanClass[i].F_Taunt
ply.Burn = HumanClass[i].F_Burn
ply.Pickup = HumanClass[i].F_Pickup
ply.Cough = HumanClass[i].F_Cough
ply.Scared = HumanClass[i].F_Scared
ply.Heal = HumanClass[i].F_Heal
ply.Reload = HumanClass[i].F_Reload
ply.Supply = HumanClass[i].F_Supply
ply:SetInvSlots(HumanClass[i].InventorySlots)
ply.DeathType = "normal"
ply.Class = HumanClass[i].Name
ply:Give("weapon_inventory")
for k,v in pairs(HumanClass[i].Primaries) do
ply:Give(v)
end
ply:SelectWeapon(HumanClass[i].Primaries[2])
end
end
else
for i=1,#HumanClass do
if (string.lower(HumanClass[i].Name) == string.lower(ply.HumanClass)) then
GAMEMODE:SetPlayerSpeed( ply, HumanClass[i].Speed, HumanClass[i].Speed )
ply.WalkSpeed = HumanClass[i].Speed
ply:SetHealth(HumanClass[i].Health)
ply.MaxHealth = HumanClass[i].Health
ply.WeaponSlots = HumanClass[i].WeaponSlots
ply:SetModel(ChooseRandom(HumanClass[i].M_Model))
ply.Alert = HumanClass[i].M_Alert
ply.Death = HumanClass[i].M_Death
ply.Pain = HumanClass[i].M_Pain
ply.Taunt = HumanClass[i].M_Taunt
ply.Burn = HumanClass[i].M_Burn
ply.Pickup = HumanClass[i].M_Pickup
ply.Cough = HumanClass[i].M_Cough
ply.Scared = HumanClass[i].M_Scared
ply.Heal = HumanClass[i].M_Heal
ply.Reload = HumanClass[i].M_Reload
ply.Supply = HumanClass[i].M_Supply
ply:SetInvSlots(HumanClass[i].InventorySlots)
ply.DeathType = "normal"
ply.Class = HumanClass[i].Name
ply:Give("weapon_inventory")
for k,v in pairs(HumanClass[i].Primaries) do
ply:Give(v)
end
ply:SelectWeapon(HumanClass[i].Primaries[2])
end
end
end
ply.Pitch = {95,105}
if ply.HumanClass != "Support" then
ply:SetAmmunition("pistol",80)
ply:SetAmmunition("smg1",60)
ply:SetAmmunition("buckshot",20)
ply:SetAmmunition("ar2",60)
else
ply:SetAmmunition("pistol",100)
ply:SetAmmunition("smg1",90)
ply:SetAmmunition("buckshot",30)
ply:SetAmmunition("ar2",90)
end
ply:SetStamina(100)
if math.random(1,3) == 1 then
local item = ents.Create("prop_physics")
item:SetModel("models/props_lab/binderblue.mdl")
item:SetPos(ply:GetPos() + Vector(0,0,100))
item:SetAngles(Angle(0,0,0))
item:Spawn()
end
WriteToFile(string.sub(ply:SteamID(),11),{ply.HumanClass})
end
function GM:ZombieSetup( ply )
for i=1,#ZombieClass do
if (string.lower(ZombieClass[i].Name) == string.lower(ply.ZombieClass)) then
GAMEMODE:SetPlayerSpeed( ply, ZombieClass[i].Speed, ZombieClass[i].Speed )
ply.WalkSpeed = ZombieClass[i].Speed
ply:SetModel(ZombieClass[i].Model)
ply.CorpseModel = ZombieClass[i].Corpse
ply:SetHealth(ZombieClass[i].Health)
ply.MaxHealth = ZombieClass[i].Health
ply.Death = ZombieClass[i].Death
ply.Pain = ZombieClass[i].Pain
ply.Taunt = ZombieClass[i].Taunt
ply.Pitch = ZombieClass[i].Pitch
ply.DeathType = "normal"
ply.Class = ZombieClass[i].Name
ply:Give(ZombieClass[i].Primary)
end
end
ply:DoExtinguish()
ply:StopPoison()
ply:StopBleeding()
ply:StopInfection()
ply:EmptyInventory()
ply:SetImmune(true)
local block
for k, ent in pairs(ents.FindInBox(ply:GetPos() + Vector(-48, -48, 0), ply:GetPos() + Vector(48, 48, 60))) do
if ent and ent:IsValid() then
block = ent
end
end
if block then
if block:IsNPC() then
GAMEMODE:SpawnUndead(block:GetClass())
block:Remove()
else
block:SetPos(ply:GetPos() + ply:GetForward() * 90)
end
end
end
function GM:PlayerSpawn( ply )
if ply.ZombieClass == "Dead" then
ply.ZombieClass = "Undead"
ply:SetTeam(TEAM_UNDEAD)
//zombie class hint
timer.Simple(5, function(ply) Inventory.Notice(ply, "Press F3 to change your class", Inventory.White) end, ply )
timer.Simple(10, function(ply) Inventory.Notice(ply, "Kill humans to earn upgrades", Inventory.White) end, ply )
end
ply:ShouldDropWeapon(false)
ply:UnSpectate()
if ply:Team() == TEAM_HUMANS then
ply:StripWeapons()
GAMEMODE:HumanSetup(ply)
ply:ClientSound(ChooseRandom(GameSounds.OpeningMusic))
ply:SetImmune(false)
ply:SetNetworkedVector("antidotepos",GameInfo.Cure:LocalToWorld(GameInfo.Cure:OBBCenter()))
umsg.Start("UpdateCureTime",v)
umsg.Short( CurTime() + (GameInfo.LocationInterval*60) )
umsg.End()
elseif ply:Team() == TEAM_UNDEAD then
GAMEMODE:ZombieSetup(ply)
else
ply.MaxHealth = 100
end
umsg.Start("MaxHealth", ply)
umsg.Short( ply.MaxHealth )
umsg.End()
end
function GM:SetupMove(ply, mv)
if not ply:Alive() then return end
if ply:Team() == TEAM_HUMANS then
if ply == nil or !ply:Alive() then
return
end
if ply:KeyDown( IN_SPEED ) and mv:GetForwardSpeed() > 20 then
if ply:GetStamina() <= GameInfo.StaminaRegen then
ply:SetRunSpeed( ply.WalkSpeed )
else
if ply:KeyDown( IN_DUCK ) or ply:KeyDown( IN_WALK ) then
ply:SetRunSpeed( ply.WalkSpeed - 90 )
else
ply:SetRunSpeed( ply.WalkSpeed + 120 )
end
end
return
elseif ply:KeyDown( IN_WALK ) then
ply:SetWalkSpeed( ply.WalkSpeed - 95 )
return
elseif ply:KeyDown( IN_BACK ) then
ply:SetWalkSpeed( ply.WalkSpeed - 80 )
return
elseif ply:KeyDown( IN_DUCK ) then
ply:SetWalkSpeed( ply.WalkSpeed - 75 )
return
else
ply:SetWalkSpeed( ply.WalkSpeed )
return
end
elseif ply:Team() == TEAM_UNDEAD then //zombie players
if ply == nil or !ply:Alive() then
return
end
if ply:KeyDown( IN_BACK ) then
mv:SetMaxClientSpeed( ply.WalkSpeed - 40 )
return
else
mv:SetMaxClientSpeed( ply.WalkSpeed )
return
end
else //spec
ply:SetWalkSpeed( 10 )
ply:SetRunSpeed( 10 )
end
end
function GM:PlayerUse(ply, entity)
if not entity then return end
if not entity:IsValid() then return end
if ply:Team() == TEAM_UNDEAD then
if entity:GetClass() == "prop_door_rotating" or entity:GetClass() == "func_ladder"
or entity:GetClass() == "func_button" or entity:GetClass() == "func_useableladder" then
return false
end
end
return true
end
function GM:KeyRelease( ply, key )
if key == IN_USE and ply:Team() == TEAM_HUMANS then
if not ply.TraceTimer then
Inventory.PlayerTrace(ply)
ply.TraceTimer = CurTime() + .3
elseif ply.TraceTimer < CurTime() then
Inventory.PlayerTrace(ply)
ply.TraceTimer = CurTime() + .3
end
end
end
function GM:ShowHelp(ply)
if ply.HelpMenu then return end
umsg.Start("ShowHelp", ply)
umsg.End()
ply.HelpMenu = true
end
function CloseHelpMenu(ply,cmd,args)
ply.HelpMenu = false
end
concommand.Add("closehelpmenu", CloseHelpMenu)
function GM:ShowSpare1(ply)
if GameInfo.GameOver or ply.InMenu then return end
ply.MenuTimer = ply.MenuTimer or CurTime() - 1
if ply:Team() == TEAM_HUMANS and ply.MenuTimer < CurTime() then
umsg.Start("MerchantMenu", ply)
umsg.End()
ply.MenuTimer = CurTime() + 2
ply.InMenu = true
ply:ClientSound(ChooseRandom(GameSounds.RadioBeep))
elseif ply:Team() == TEAM_UNDEAD and ply.MenuTimer < CurTime() and ply:Alive() then
ply.MenuTimer = CurTime() + 5
umsg.Start("ClassMenu", ply)
umsg.Short(TEAM_UNDEAD)
umsg.End()
ply.MenuOpen = true
end
end
function GM:ShowSpare2(ply)
ply.MenuTimer = ply.MenuTimer or CurTime() - 1
if ply.MenuTimer < CurTime() and ply:Alive() then
ply.MenuTimer = CurTime() + 5
umsg.Start("OptionsMenu", ply)
umsg.End()
ply.MenuOpen = true
end
end
function GM:ShowTeam(ply)
if not ply.AutoBuy then
Inventory.Notice(ply, "Hit F2 again to buy item: "..ply.LastItem, Inventory.Blue)
timer.Create("ShowTeam"..ply:Name(), 2.5, 1, function(ply) ply:ResetAutoBuy() end, ply)
ply.AutoBuy = CurTime() + 2.5
else
if Inventory.MerchantTrace(ply) then
ply:ResetAutoBuy()
BuyItem(ply,1,{ply.LastItem})
else
Inventory.Notice(ply,"You need to be outdoors",Inventory.Red)
ply:ClientSound(ChooseRandom(GameSounds.Deny))
end
end
end
function GM:PlayerDisconnected(ply)
ply:SetTeam(TEAM_UNDEAD)
table.insert(GameInfo.Disconnected,ply:SteamID())
if team.NumPlayers(TEAM_HUMANS) < 1 and GameInfo.Unlock > 0.2 then
GAMEMODE:EndGame()
end
end
function GM:PlayerDeathSound()
return true
end
function GM:EntityTakeDamage( ent, inflictor, attacker, amount, dmginfo )
if not ent:IsPlayer() then return end
if not ent:Alive() then return end
if ent.ZombieClass == "Dead" then dmginfo:SetDamage(0) return end
if string.find(attacker:GetClass(),"bomb") then
dmginfo:SetDamage(10)
end
if attacker:IsWorld() or dmginfo:GetAttacker():IsWorld() then
if ent:Team() == TEAM_UNDEAD then
dmginfo:SetDamage(10)
end
end
if ent:Team() == TEAM_HUMANS and ent:Health() < 30 then
if attacker:IsPlayer() or attacker:IsWorld() then
ent.DeathType = "normal"
end
end
if attacker and attacker != NULL and attacker != nil then
if attacker:IsValid() then
local aclass = attacker:GetClass()
if string.find(aclass, "prop_") then
dmginfo:SetDamage(10)
ent:SetVelocity(Vector(0,0,0))
elseif string.find(aclass,"npc_") then
ent.DeathType = "normal"
ent:VoiceSound(ChooseRandom(ent.Pain),100,.1)
umsg.Start("BloodStain", ent)
umsg.End()
elseif string.find(aclass,"molotov") then
ent:VoiceSound(ChooseRandom(ent.Pain),100,.1)
end
end
end
end
function GM:ScalePlayerDamage( ply, group, dmginfo )
if ply:Team() == TEAM_HUMANS then return dmginfo end
if not dmginfo:GetAttacker():IsPlayer() then return dmginfo end
ply.DeathType = "normal"
if ply:Team() == TEAM_UNDEAD then
umsg.Start("BloodStain", ply)
umsg.End()
end
if group == HITGROUP_HEAD then
dmginfo:ScaleDamage(2.2)
ply:AddAttackerDamage(dmginfo:GetAttacker(),dmginfo:GetDamage(),true)
elseif group == HITGROUP_CHEST then
dmginfo:ScaleDamage(.7)
ply:AddAttackerDamage(dmginfo:GetAttacker(),dmginfo:GetDamage(),false)
elseif group == HITGROUP_STOMACH then
dmginfo:ScaleDamage(.55)
ply:AddAttackerDamage(dmginfo:GetAttacker(),dmginfo:GetDamage(),false)
else
dmginfo:ScaleDamage(.3)
ply:AddAttackerDamage(dmginfo:GetAttacker(),dmginfo:GetDamage(),false)
end
return dmginfo end
function GM:ScaleNPCDamage( npc, group, dmginfo )
if not dmginfo:GetAttacker():IsPlayer() then return dmginfo end
if group == HITGROUP_HEAD then
dmginfo:ScaleDamage(2.2)
npc:AddAttackerDamage(dmginfo:GetAttacker(),dmginfo:GetDamage(),true)
local attacker = dmginfo:GetAttacker()
if not attacker.HeadsHint then
if math.random(1,3) == 1 then
attacker.HeadsHint = true
Inventory.Notice(attacker, "Headshot combos will earn you bonus "..GameInfo.PointName.."s", Inventory.White)
end
end
elseif group == HITGROUP_CHEST then
dmginfo:ScaleDamage(.7)
npc:AddAttackerDamage(dmginfo:GetAttacker(),dmginfo:GetDamage(),false)
elseif group == HITGROUP_STOMACH then
dmginfo:ScaleDamage(.55)
npc:AddAttackerDamage(dmginfo:GetAttacker(),dmginfo:GetDamage(),false)
else
dmginfo:ScaleDamage(.3)
npc:AddAttackerDamage(dmginfo:GetAttacker(),dmginfo:GetDamage(),false)
end
return dmginfo end
function GM:CalculateKiller(victim,killer,dmginfo) //OBSOLETE
local tbl = victim:GetAttackerTable()
if tbl == {} then return end
local dmg,headshot = victim:FindAttackerDamage(killer)
if not killer or not killer:IsValid() then return end
if GameInfo.KillCalculator == "lastkiller" then
killer:AddAwardPoints(AWARD_GOOD_KILLS,1)
killer:AddAwardPoints(AWARD_BAD_KILLS,1)
if headshot then
//killer:AddPoints(Points[victim.ZombieClass] + 1)
victim:SpawnPlutonium(Points[victim.ZombieClass] + 1,killer)
killer:AddAwardPoints(AWARD_GOOD_HEADSHOT,1)
killer:AddAwardPoints(AWARD_BAD_HEADSHOT,1)
else
//killer:AddPoints(Points[victim.ZombieClass])
victim:SpawnPlutonium(Points[victim.ZombieClass],killer)
end
elseif GameInfo.KillCalculator == "mostdamage" then
local winnar = killer
local highest = 1
for k,v in pairs(tbl) do
if v.Damage > highest then
highest = v.Damage
winnar = v.Player
headshot = v.Headshot
end
end
winnar:AddAwardPoints(AWARD_GOOD_KILLS,1)
winnar:AddAwardPoints(AWARD_BAD_KILLS,1)
if headshot then
//winnar:AddPoints(Points[victim.ZombieClass] + 1)
victim:SpawnPlutonium(Points[victim.ZombieClass] + 1,winnar)
winnar:AddAwardPoints(AWARD_GOOD_HEADSHOT,1)
winnar:AddAwardPoints(AWARD_BAD_HEADSHOT,1)
else
//winnar:AddPoints(Points[victim.ZombieClass])
victim:SpawnPlutonium(Points[victim.ZombieClass],winnar)
end
else //points are shared
local minimum = 20
for k,v in pairs(tbl) do
//Msg("PLAYER:"..v.Player:Name().." DMG:"..v.Damage.." HS:"..tostring(v.Headshot).."\n")
if v.Damage > minimum or killer == v.Player then
if v.Headshot then
//v.Player:AddPoints(Points[victim.ZombieClass] + 1)
victim:SpawnPlutonium(Points[victim.ZombieClass] + 1,v.Player)
v.Player:AddAwardPoints(AWARD_GOOD_HEADSHOT,1)
v.Player:AddAwardPoints(AWARD_BAD_HEADSHOT,1)
else
//v.Player:AddPoints(Points[self.Name])
victim:SpawnPlutonium(Points[victim.ZombieClass],v.Player)
end
v.Player:AddAwardPoints(AWARD_GOOD_KILLS,1)
v.Player:AddAwardPoints(AWARD_BAD_KILLS,1)
end
end
end
end
function GM:PlayerDeathThink( ply )
if ply.RespawnTime and ply.RespawnTime < CurTime() then
ply:Spawn()
else
return
end
if ( ply:KeyPressed( IN_ATTACK ) || ply:KeyPressed( IN_ATTACK2 ) || ply:KeyPressed( IN_JUMP ) ) then
ply:Spawn()
end
if not ply:GetNetworkedEntity("corpse"):IsValid() then
ply:Spawn()
end
end
function GM:DoPlayerDeath(ply, attacker, dmginfo)
ply.RespawnTime = CurTime() + 8
ply:Flashlight(false)
ply:Freeze(false)
ply:VoiceSound(ChooseRandom(ply.Death),100)
// All we need is to spawn the corpse/gun/effects.
local ent = ents.Create( "prop_ragdoll" )
ent:SetKeyValue("origin", ply:GetPos().x.." "..ply:GetPos().y.." "..ply:GetPos().z + 1)
ent:SetKeyValue("angles", ply:GetAngles().p + math.random(-3,3).." "..ply:GetAngles().y + math.random(-3,3).." "..ply:GetAngles().r + math.random(-3,3))
local dtype = ply.DeathType
if dtype == "burn" or dtype == "explosion" then
if ply:Team() == TEAM_HUMANS then
ent:SetModel(ChooseRandom(PlayerGibs))
else
if ply.CorpseModel then
ent:SetModel(ply.CorpseModel)
else
ent:SetModel(ply:GetModel())
end
end
else
if ply.CorpseModel then
ent:SetModel(ply.CorpseModel)
else
ent:SetModel(ply:GetModel())
end
end
ent:Spawn()
ent:Activate()
ent:SetCollisionGroup( COLLISION_GROUP_WEAPON )
ent:Fire("kill",1,math.Clamp(GameInfo.RagdollDieTime,10,90))
ply:SetNetworkedEntity("corpse",ent)
for i=1,128 do
local bone = ent:GetPhysicsObjectNum( i )
if ValidEntity( bone ) then
local bonepos, boneang = ent:GetBonePosition( ent:TranslatePhysBoneToBone( i ) )
bone:SetPos( bonepos )
bone:SetAngle( boneang )
end
end
if dtype == "burn" or dtype == "explosion" then
local effectdata = EffectData()
effectdata:SetEntity(ent)
util.Effect("corpse_fire", effectdata)
end
if ply:Team() == TEAM_UNDEAD and attacker != ply and attacker != nil and attacker:IsPlayer() then
ply:SpawnPlutonium(1,attacker)
if ply.ZombieClass == "Disease" then
ply:SpawnGasClouds(ent:GetPos() + Vector(0,0,5))
end
ply:DoExtinguish()
//GAMEMODE:CalculateKiller(ply,attacker,dmginfo) OBSOLETE
end
if ply:Team() == TEAM_HUMANS then
//make all this shit stop
ply:DoExtinguish()
ply:StopPoison()
ply:StopBleeding()
ply:StopInfection()
//make them zombies
ply.ZombieClass = "Dead"
ply:SetTeam(TEAM_UNDEAD)
for k,v in pairs(team.GetPlayers(TEAM_HUMANS)) do
if v:GetPos():Distance(ply:GetPos()) < 900 and v != ply then
v:VoiceSound(ChooseRandom(v.Scared),100,math.Rand(0,3))
end
end
if team.NumPlayers(TEAM_UNDEAD) < 1 then
ply:AddPowerup(math.random(1,3))
end
if attacker:IsPlayer() then
if attacker:Team() == TEAM_UNDEAD then
attacker:AddPowerup()
end
end
local num = math.floor(ply:GetPoints() / 25)
if num >= 1 then
timer.Simple(5, function(ply,num)
Inventory.Notice(ply, "Your "..GameInfo.PointName.."s were converted to upgrades", Inventory.White)
for i=1,num do
ply:AddPowerup()
end
end, ply, num )
end
ply:ClientSound(ChooseRandom(GameSounds.DeathMusic))
ply:SetNetworkedString("available","99")
if team.NumPlayers(TEAM_HUMANS) < 1 and table.Count(player.GetAll()) >= 2 then
GAMEMODE:EndGame()
end
end
local phys = ent:GetPhysicsObject()
if phys:IsValid() then
phys:SetMass(50)
end
local fnum = 700
if dmginfo:IsExplosionDamage() or dtype == "explosion" then
fnum = phys:GetMass()^3.2
elseif GameInfo.ExaggeratedDeath then
fnum = phys:GetMass()^2.3 // i dew it foar the lols
else
fnum = phys:GetMass()^2
end
if attacker != nil and attacker:IsPlayer() then
local dir = (ent:GetPos() - attacker:GetPos() + (VectorRand() * 2)):Normalize()
phys:ApplyForceCenter(attacker:GetAimVector() * fnum) //(dir * fnum)
phys:AddAngleVelocity(Angle(math.random(-1*(fnum/3),fnum/3),math.random(-1*(fnum/2),fnum/2),math.random(-1*(fnum/3),fnum/3)))
if attacker:IsPlayer() then
local taunt = math.random(1,3)
if taunt == 1 and attacker:Alive() then
attacker:VoiceSound(ChooseRandom(attacker.Taunt),100,math.Rand(1,1.5))
end
end
else
local dir = VectorRand():Normalize()
local vel = ply:GetVelocity()
phys:ApplyForceCenter((dir * (fnum/3)) + vel)
local ang = Angle(math.random(-1*(fnum/4),fnum/4),math.random(-1*(fnum/4),fnum/4),math.random(-1*(fnum/4),fnum/4))
phys:AddAngleVelocity(ang)
end
if ply.ZombieClass == "Dead" then
local items = ply:GetItemInventory()
local madeitem = false
for k,v in pairs(items) do
local tbl = Inventory.FindTable(v)
if tbl.Weight <= 2 then
if not madeitem then
madeitem = true
local hpos = ent:LookupAttachment("anim_attachment_LH")
local att = ent:GetAttachment(hpos)
if att == nil then
att = {}
att.Ang = Angle(0,0,0)
att.Pos = ent:GetPos() + Vector(0,0,5)
end
local item = ents.Create("prop_physics")
item:SetModel(tbl.Model)
item:SetPos(att.Pos)
item:SetAngles(att.Ang)
item:Spawn()
item:SetHealth(150)
end
end
end
madeitem = false
local weps = ply:GetWeapons()
local allowed = {"smg1","ar2","pistol","buckshot"}
for k,v in pairs(weps) do
if not madeitem then
if table.HasValue(allowed,v:GetUsedAmmoType()) then
madeitem = true
local hpos = ent:LookupAttachment("anim_attachment_RH")
local att = ent:GetAttachment(hpos)
if att == nil then
att = {}
att.Ang = Angle(0,0,0)
att.Pos = ent:GetPos() + Vector(0,0,5)
end
local item = ents.Create("sent_weapon")
item:SetModel(v:GetWorldModel())
item:SetPos(att.Pos)
item:SetAngles(att.Ang)
item:Spawn()
end
end
end
end
end
function GM:ForceSpawn(ply)
if !ply:IsValid() or ply:Alive() then return end
ply:Spawn()
end
function GM:CanPlayerSuicide( ply )
Inventory.Notice(ply,"Suicide is not the answer",Inventory.Red)
return false//true
end
function GM:PlayerTraceAttack( ply, dmginfo, dir, trace )
local attacker = dmginfo:GetAttacker()
if !attacker:IsValid() or attacker == ply then
return
end
if attacker:Team() != ply:Team() and ply:Health() > 50 then
ply.DeathType = "normal"
if math.random(1,5) == 1 then
if SERVER then
ply:VoiceSound(Sound(ChooseRandom(ply.Pain)),100,math.random(95,105))
end
end
end
util.Decal("Blood", trace.HitPos + trace.HitNormal, trace.HitPos - trace.HitNormal)
local effectdata = EffectData()
effectdata:SetOrigin(trace.HitPos)
effectdata:SetNormal(trace.HitNormal)
util.Effect("bodyshot", effectdata)
return self.BaseClass:PlayerTraceAttack(ply, dmginfo, dir, trace)
end
function VoiceChat(ply,key)
if ply:Team() == TEAM_UNDEAD then return end
ply.ChatTimer = ply.ChatTimer or 0
if key == 0 then
if ply.ChatTimer < CurTime() then
ply.ChatTimer = CurTime() + 4
timer.Simple(1, function(ply) Inventory.Notice(ply, "Press NumPad 1 to call for help", Inventory.White) end, ply )
timer.Simple(3, function(ply) Inventory.Notice(ply, "Press NumPad 2 to spot zombies", Inventory.White) end, ply )
timer.Simple(5, function(ply) Inventory.Notice(ply, "Press NumPad 3 to signal retreat", Inventory.White) end, ply )
end
end
if ply.ChatTimer < CurTime() then
ply.ChatTimer = CurTime() + 4
if key == 1 then
if ply:IsFemale() then
ply:VoiceSound(ChooseRandom(GameInfo.Fem1),100)
else
ply:VoiceSound(ChooseRandom(GameInfo.Male1),100)
end
ply:ConCommand("say "..ChooseRandom({"I need assistance!","I'm over here!","Help me!","I need backup"}))
elseif key == 2 then
if ply:IsFemale() then
ply:VoiceSound(ChooseRandom(GameInfo.Fem2),100)
else
ply:VoiceSound(ChooseRandom(GameInfo.Male2),100)
end
ply:ConCommand("say "..ChooseRandom({"I see zombies!","Incoming!","Take cover!","Here they come!"}))
else
if ply:IsFemale() then
ply:VoiceSound(ChooseRandom(GameInfo.Fem3),100)
else
ply:VoiceSound(ChooseRandom(GameInfo.Male3),100)
end
ply:ConCommand("say "..ChooseRandom({"We should keep moving","Run away!","Follow me!","Come with me"}))
end
end
end
numpad.Register( "VoiceChat", VoiceChat )
function BuyItem(ply,cmd,args)
if args[1] == nil then ply.InMenu = false return end
ply.InMenu = false
if ply:Team() == TEAM_HUMANS then
local tbl = nil
for k,v in pairs(Inventory.Merchant) do
if v.Name == args[1] then
tbl = table.Copy(v)
end
end
if not ply:HasPoints(tbl.Price) or tbl == nil then
ply:ClientSound(ChooseRandom(GameSounds.Deny))
Inventory.Notice(ply, "You can't afford that item", Inventory.Red)
return
end
if tbl.Stock < 1 then
ply:ClientSound(ChooseRandom(GameSounds.Deny))
Inventory.Notice(ply, "That item is not in stock", Inventory.Red)
return
end
if tbl.Weapon then
if Inventory.WeaponCount(ply) < ply.WeaponSlots then
local weps = ply:GetWeapons()
for k,v in pairs(weps) do
if v:GetWorldModel() == tbl.Model then
Inventory.Notice(ply, "You already have that gun", Inventory.Red)
ply:ClientSound(ChooseRandom(GameSounds.Deny))
return
end
end
local atypes = {"_tp","_sg","_sh","_ar"}
local names = {"pistol","smg1","buckshot","ar2"}
local amts = {20,30,12,30}
for k,v in pairs(atypes) do
if string.find(tbl.Weapon,v) then
ply:AddAmmunition(names[k],amts[k])
end
end
ply:Give(tbl.Weapon)
Inventory.Notice(ply, "Purchased gun: "..tbl.Name, Inventory.Blue)
if ply:HasInvItem("models/props/de_prodigy/desk_console1b.mdl")
or ply:HasInvItem("models/props/cs_office/phone.mdl")
or ply:HasInvItem("models/props/cs_office/phone_p2.mdl") then
ply:TakePoints(tbl.Price - 5)
Inventory.Notice(ply, "You were discounted 5 "..GameInfo.PointName.."s", Inventory.Yellow)
else
ply:TakePoints(tbl.Price)
end
ply:AddAwardPoints(AWARD_GOOD_POINTS,tbl.Price)
ply:AddAwardPoints(AWARD_BAD_POINTS,tbl.Price)
ply:ClientSound(ChooseRandom(GameSounds.Cash))
Inventory.ReduceStock(tbl.Name)
ply:SelectWeapon(tbl.Weapon)
else
Inventory.Notice(ply, "You need to drop a gun first", Inventory.Red)
ply:ClientSound(ChooseRandom(GameSounds.Deny))
end
elseif tbl.Ammo then
ply:AddAmmunition(tbl.Ammo,tbl.Weight)
Inventory.Notice(ply, "Purchased ammo: "..tbl.Name, Inventory.Blue)
ply:TakePoints(tbl.Price)
ply:AddAwardPoints(AWARD_GOOD_POINTS,tbl.Price)
ply:AddAwardPoints(AWARD_BAD_POINTS,tbl.Price)
ply:ClientSound(ChooseRandom(GameSounds.Cash))
ply:EmitSound(Inventory.ItemPickup,100,math.random(90,100))
Inventory.ReduceStock(tbl.Name)
ply.LastItem = tbl.Name
elseif tbl.Weight then
if tbl.Name == "Mystery Item" then
local lol = ChooseRandom(Inventory.MysteryItems)
local canhave = ply:CanAddToInventory(lol)
if canhave then
local prop = ents.Create("prop_physics")
prop:SetPos(ply:GetPos() + Vector(0,0,100))
prop:SetModel(lol)
prop:Spawn()
prop:SetColor(0,0,0,0)
prop:SetHealth(150)
if Inventory.CheckItem(ply,prop) then
ply:AddToInventory(prop)
Inventory.Notice(ply, "Purchased item: "..tbl.Name, Inventory.Blue)
ply:TakePoints(tbl.Price)
ply:ClientSound(ChooseRandom(GameSounds.Cash))
ply:SynchInventory()
ply:ConCommand("invnext")
end
Inventory.ReduceStock(tbl.Name)
else
ply:ClientSound(ChooseRandom(GameSounds.Deny))
//Inventory.Notice(ply, "You can't carry that item", Inventory.Red)
end
return
end
local canhave = ply:CanAddToInventory(tbl.Model)
if canhave then
local prop = ents.Create("prop_physics")
prop:SetPos(ply:GetPos() + Vector(0,0,100))
prop:SetModel(tbl.Model)
prop:Spawn()
prop:SetColor(0,0,0,0)
prop:SetHealth(150)
ply:AddToInventory(prop)
Inventory.Notice(ply, "Purchased item: "..tbl.Name, Inventory.Blue)
ply:TakePoints(tbl.Price)
ply:AddAwardPoints(AWARD_GOOD_POINTS,tbl.Price)
ply:AddAwardPoints(AWARD_BAD_POINTS,tbl.Price)
ply:ClientSound(ChooseRandom(GameSounds.Cash))
Inventory.ReduceStock(tbl.Name)
ply.LastItem = tbl.Name
else
ply:ClientSound(ChooseRandom(GameSounds.Deny))
//Inventory.Notice(ply, "You can't carry that item", Inventory.Red)
end
end
end
end
concommand.Add("buyitem", BuyItem)
function ChangeClass(ply,cmd,args)
if not ply.MenuOpen then return end
if args[1] == nil then return end
//if not string.find(ply:GetNetworkedString("available","12"),tostring(args[2])) and ply:Team() == TEAM_HUMANS then Inventory.Notice(ply,"Nice try",Inventory.Red) return end
if ply:Team() == TEAM_SPECTATOR then
ply:SetTeam(TEAM_HUMANS)
if table.HasValue({"Medic","Engineer","Militant","Support"},tostring(args[1])) then
ply.HumanClass = tostring(args[1])
else
ply.HumanClass = "Militant"
ply.ZombieClass = "Dead"
ply:Kill()
return
end
ply:Spawn()
for k,v in pairs(player.GetAll()) do
v:ChatPrint(ply:Name().." chose class: "..ply.HumanClass)
end
umsg.Start("UpdateTime", ply)
umsg.Short( GameInfo.EndTime )
umsg.End()
elseif ply:Team() == TEAM_UNDEAD then
if table.HasValue({"Ghoul","Wretch","Undead","Disease","Banshee"},tostring(args[1])) then
ply.ZombieClass = tostring(args[1])
else
ply.ZombieClass = "Undead"
end
ply:Kill()
end
ply.MenuOpen = false
ply:EmitSound(ChooseRandom(GameSounds.WindGusts))
end
concommand.Add("changeclass", ChangeClass)
function DebugMsg(txt)
for k,v in pairs(player.GetAll()) do
v:ChatPrint("DEBUG: "..tostring(txt))
end
return txt end
function DebugTrace()
player.GetByID(1):ChatPrint("debug trace:")
local trace = util.GetPlayerTrace(player.GetByID(1))
local tr = util.TraceLine(trace)
DebugMsg("model: "..tr.Entity:GetModel().." - class: "..tr.Entity:GetClass().." - physbone: "..tr.PhysicsBone)
end