It's back bitches!
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"title" : "Prop Hunt Extended",
|
||||
"type" : "gamemode",
|
||||
"tags" : [ "fun" ],
|
||||
"ignore" : [
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
"TableToKeyValues"
|
||||
{
|
||||
"1" "models/props/cs_assault/dollar.mdl"
|
||||
"2" "models/props/cs_assault/money.mdl"
|
||||
"3" "models/props/cs_office/snowman_arm.mdl"
|
||||
"4" "models/props_junk/garbage_plasticbottle001a.mdl"
|
||||
"5" "models/props/cs_office/projector_remote.mdl"
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
"TableToKeyValues"
|
||||
{
|
||||
"TAUNT_DELAY" "0.1"
|
||||
"ROUNDS_PER_MAP" "20"
|
||||
"ROUND_TIME" "240"
|
||||
"SWAP_TEAM_EVERY_ROUND" "1"
|
||||
"GAME_TIME" "20"
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
"TableToKeyValues"
|
||||
{
|
||||
"1" "bot/aw_hell.wav"
|
||||
"2" "bot/aww_man.wav"
|
||||
"3" "bot/anyone_see_anything.wav"
|
||||
"4" "bot/anyone_see_them.wav"
|
||||
"5" "bot/come_out_and_fight_like_a_man.wav"
|
||||
"6" "bot/come_out_wherever_you_are.wav"
|
||||
"7" "bot/he_got_away.wav"
|
||||
"8" "bot/he_got_away2.wav"
|
||||
"9" "bot/i_dont_know_where_he_went.wav"
|
||||
"10" "bot/i_got_nothing.wav"
|
||||
"11" "bot/nothing_happening_over_here.wav"
|
||||
"12" "bot/nothing_here.wav"
|
||||
"13" "bot/nothing_moving_over_here.wav"
|
||||
"14" "bot/thats_not_good.wav"
|
||||
"15" "bot/theres_too_many.wav"
|
||||
"16" "bot/theres_too_many_of_them.wav"
|
||||
"17" "bot/theyre_all_over_the_place2.wav"
|
||||
"18" "bot/theyre_everywhere2.wav"
|
||||
"19" "bot/too_many2.wav"
|
||||
"20" "bot/what_happened.wav"
|
||||
"21" "bot/what_have_you_done.wav"
|
||||
"22" "bot/where_are_they.wav"
|
||||
"23" "bot/where_are_you_hiding.wav"
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
"TableToKeyValues"
|
||||
{
|
||||
"1" "bot/a_bunch_of_them.wav"
|
||||
"2" "bot/come_out_and_fight_like_a_man.wav"
|
||||
"3" "bot/come_out_wherever_you_are.wav"
|
||||
"4" "bot/come_to_papa.wav"
|
||||
"5" "bot/dont_worry_hell_get_it.wav"
|
||||
"6" "bot/hang_on_i_heard_something.wav"
|
||||
"7" "bot/hang_on_im_coming.wav"
|
||||
"8" "bot/i_dont_think_so.wav"
|
||||
"9" "bot/i_have_the_hostages.wav"
|
||||
"10" "bot/i_see_our_target.wav"
|
||||
"11" "bot/im_waiting_here.wav"
|
||||
"12" "bot/keeping_an_eye_on_the_hostages.wav"
|
||||
"13" "bot/nnno_sir.wav"
|
||||
"14" "bot/spotted_the_delivery_boy.wav"
|
||||
"15" "bot/target_acquired.wav"
|
||||
"16" "bot/target_spotted.wav"
|
||||
"17" "bot/you_heard_the_man_lets_go.wav"
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
"TableToKeyValues"
|
||||
{
|
||||
"1" "ambient/alarms/apc_alarm_pass1.wav"
|
||||
"2" "ambient/alarms/manhack_alert_pass1.wav"
|
||||
"3" "ambient/alarms/razortrain_horn1.wav"
|
||||
"4" "ambient/alarms/scanner_alert_pass1.wav"
|
||||
"5" "ambient/alarms/train_horn2.wav"
|
||||
"6" "ambient/alarms/train_horn_distant1.wav"
|
||||
"7" "ambient/alarms/warningbell1.wav"
|
||||
"8" "ambient/energy/whiteflash.wav"
|
||||
"9" "ambient/intro/alyxremove.wav"
|
||||
"10" "ambient/intro/logosfx.wav"
|
||||
"11" "ambient/levels/launch/1stfiringwarning.wav"
|
||||
"12" "ambient/levels/launch/rockettakeoffblast.wav"
|
||||
"13" "ambient/misc/ambulance1.wav"
|
||||
"14" "ambient/misc/carhonk1.wav"
|
||||
"15" "ambient/misc/carhonk2.wav"
|
||||
"16" "ambient/misc/carhonk3.wav"
|
||||
"17" "ambient/outro/gunshipcrash.wav"
|
||||
"18" "ambient/3dmeagle.wav"
|
||||
"19" "beams/beamstart5.wav"
|
||||
"20" "buttons/bell1.wav"
|
||||
"21" "buttons/weapon_cant_buy.wav"
|
||||
"22" "common/bass.wav"
|
||||
"23" "common/bugreporter_failed.wav"
|
||||
"24" "common/warning.wav"
|
||||
"25" "doors/door_squeek1.wav"
|
||||
"26" "friends/friend_join.wav"
|
||||
"27" "friends/friend_online.wav"
|
||||
"28" "friends/message.wav"
|
||||
"29" "hostage/hunuse/comeback.wav"
|
||||
"30" "hostage/hunuse/dontleaveme.wav"
|
||||
"31" "hostage/hunuse/yeahillstay.wav"
|
||||
"32" "items/gift_drop.wav"
|
||||
"33" "music/radio1.mp3"
|
||||
"34" "phx/eggcrack.wav"
|
||||
"35" "plats/elevbell1.wav"
|
||||
"36" "player/headshot1.wav"
|
||||
"37" "player/headshot2.wav"
|
||||
"38" "player/sprayer.wav"
|
||||
"39" "radio/enemydown.wav"
|
||||
"40" "radio/go.wav"
|
||||
"41" "radio/locknload.wav"
|
||||
"42" "radio/negative.wav"
|
||||
"43" "radio/rounddraw.wav"
|
||||
"44" "radio/takepoint.wav"
|
||||
"45" "resource/warning.wav"
|
||||
"46" "ui/achievement_earned.wav"
|
||||
"47" "ui/freeze_cam.wav"
|
||||
"48" "vehicles/junker/radar_ping_friendly1.wav"
|
||||
"49" "weapons/c4/c4_beep1.wav"
|
||||
"50" "weapons/c4/c4_click.wav"
|
||||
"51" "weapons/awp/awp1.wav"
|
||||
"52" "vo/canals/female01/gunboat_giveemhell.wav"
|
||||
"53" "vo/canals/female01/gunboat_justintime.wav"
|
||||
"54" "vo/canals/female01/stn6_incoming.wav"
|
||||
"55" "vo/canals/male01/gunboat_giveemhell.wav"
|
||||
"56" "vo/canals/male01/gunboat_justintime.wav"
|
||||
"57" "vo/canals/male01/stn6_incoming.wav"
|
||||
"58" "vo/canals/al_radio_stn6.wav"
|
||||
"59" "vo/canals/arrest_getgoing.wav"
|
||||
"60" "vo/canals/arrest_helpme.wav"
|
||||
"61" "vo/canals/arrest_lookingforyou.wav"
|
||||
"62" "vo/canals/boxcar_lethimhelp.wav"
|
||||
"63" "vo/canals/matt_closecall.wav"
|
||||
"64" "vo/canals/premassacre.wav"
|
||||
"65" "vo/ravenholm/aimforhead.wav"
|
||||
"66" "vo/ravenholm/bucket_patience.wav"
|
||||
"67" "vo/ravenholm/madlaugh01.wav"
|
||||
"68" "vo/ravenholm/madlaugh02.wav"
|
||||
"69" "vo/ravenholm/madlaugh03.wav"
|
||||
"70" "vo/ravenholm/madlaugh04.wav"
|
||||
"71" "weapons/strider_buster/ol12_stickybombcreator.wav"
|
||||
"72" "weapons/c4/c4_explode1.wav"
|
||||
"73" "weapons/357/357_fire2.wav"
|
||||
"74" "weapons/357/357_fire3.wav"
|
||||
"75" "weapons/scout/scout_fire-1.wav"
|
||||
"76" "weapons/smokegrenade/sg_explode.wav"
|
||||
"77" "weapons/grenade_launcher1.wav"
|
||||
"78" "weapons/explode3.wav"
|
||||
"79" "weapons/underwater_explode3.wav"
|
||||
"80" "items/nvg_on.wav"
|
||||
"81" "hostage/huse/letsdoit.wav"
|
||||
"82" "hostage/huse/illfollow.wav"
|
||||
"83" "hostage/huse/getouttahere.wav"
|
||||
"84" "doors/door_screen_move1.wav"
|
||||
"85" "doors/heavy_metal_stop1.wav"
|
||||
"86" "doors/default_move.wav"
|
||||
"87" "common/stuck2.wav"
|
||||
"88" "ambient/water_splash1.wav"
|
||||
"89" "ambient/water_splash2.wav"
|
||||
"90" "ambient/water_splash3.wav"
|
||||
"91" "ambient/weather/thunder1.wav"
|
||||
"92" "ambient/weather/thunder2.wav"
|
||||
"93" "ambient/weather/thunder3.wav"
|
||||
"94" "ambient/weather/thunder4.wav"
|
||||
"95" "ambient/weather/thunder5.wav"
|
||||
"96" "ambient/weather/thunder6.wav"
|
||||
"97" "ambient/outro/thunder7.wav"
|
||||
"98" "ambient/voices/crying_loop1.wav"
|
||||
"99" "ambient/voices/playground_memory.wav"
|
||||
"100" "ambient/voices/f_scream1.wav"
|
||||
"101" "ambient/voices/m_scream1.wav"
|
||||
"102" "ambient/voices/cough1.wav"
|
||||
"103" "ambient/voices/cough2.wav"
|
||||
"104" "ambient/voices/cough3.wav"
|
||||
"105" "ambient/voices/cough4.wav"
|
||||
"106" "ambient/overhead/plane1.wav"
|
||||
"107" "ambient/overhead/plane2.wav"
|
||||
"108" "ambient/overhead/plane3.wav"
|
||||
"109" "ambient/overhead/hel1.wav"
|
||||
"110" "ambient/overhead/hel2.wav"
|
||||
"111" "ambient/misc/truck_backup1.wav"
|
||||
"112" "ambient/misc/truck_drive1.wav"
|
||||
"113" "ambient/misc/truck_drive2.wav"
|
||||
"114" "ambient/machines/pneumatic_drill_1.wav"
|
||||
"115" "ambient/machines/pneumatic_drill_2.wav"
|
||||
"116" "ambient/machines/pneumatic_drill_3.wav"
|
||||
"117" "ambient/machines/pneumatic_drill_4.wav"
|
||||
"118" "ambient/machines/station_train_squeel.wav"
|
||||
"119" "ambient/machines/ticktock.wav"
|
||||
"120" "ambient/creatures/teddy.wav"
|
||||
"121" "ambient/creatures/town_child_scream1.wav"
|
||||
"122" "ambient/creatures/town_moan1.wav"
|
||||
"123" "ambient/creatures/town_muffled_cry1.wav"
|
||||
"124" "ambient/creatures/town_scared_breathing1.wav"
|
||||
"125" "ambient/creatures/town_scared_breathing2.wav"
|
||||
"126" "ambient/creatures/town_scared_sob1.wav"
|
||||
"127" "ambient/creatures/town_scared_sob2.wav"
|
||||
"128" "ambient/creatures/town_zombie_call1.wav"
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
"TableToKeyValues"
|
||||
{
|
||||
"1" "bot/and_thats_how_its_done.wav"
|
||||
"2" "bot/come_to_papa.wav"
|
||||
"3" "bot/do_not_mess_with_me.wav"
|
||||
"4" "bot/dropped_him.wav"
|
||||
"5" "bot/enemy_down.wav"
|
||||
"6" "bot/enemy_down2.wav"
|
||||
"7" "bot/good_job_team.wav"
|
||||
"8" "bot/got_him.wav"
|
||||
"9" "bot/hes_broken.wav"
|
||||
"10" "bot/hes_dead.wav"
|
||||
"11" "bot/hes_done.wav"
|
||||
"12" "bot/hes_down.wav"
|
||||
"13" "bot/its_a_party.wav"
|
||||
"14" "bot/i_am_dangerous.wav"
|
||||
"15" "bot/i_am_on_fire.wav"
|
||||
"16" "bot/i_got_more_where_that_came_from.wav"
|
||||
"17" "bot/i_wasnt_worried_for_a_minute.wav"
|
||||
"18" "bot/killed_him.wav"
|
||||
"19" "bot/look_out_brag.wav"
|
||||
"20" "bot/made_him_cry.wav"
|
||||
"21" "bot/oh_yea.wav"
|
||||
"22" "bot/oh_yea2.wav"
|
||||
"23" "bot/owned.wav"
|
||||
"24" "bot/ruined_his_day.wav"
|
||||
"25" "bot/tag_them_and_bag_them.wav"
|
||||
"26" "bot/thats_the_way_this_is_done.wav"
|
||||
"27" "bot/that_was_a_close_one.wav"
|
||||
"28" "bot/that_was_it.wav"
|
||||
"29" "bot/that_was_the_last_guy.wav"
|
||||
"30" "bot/that_was_the_last_one.wav"
|
||||
"31" "bot/they_never_knew_what_hit_them.wav"
|
||||
"32" "bot/they_will_not_escape.wav"
|
||||
"33" "bot/they_wont_get_away.wav"
|
||||
"34" "bot/they_wont_get_away2.wav"
|
||||
"35" "bot/this_is_my_house.wav"
|
||||
"36" "bot/took_him_down.wav"
|
||||
"37" "bot/took_him_out.wav"
|
||||
"38" "bot/took_him_out2.wav"
|
||||
"39" "bot/wasted_him.wav"
|
||||
"40" "bot/way_to_be_team.wav"
|
||||
"41" "bot/well_done.wav"
|
||||
"42" "bot/we_owned_them.wav"
|
||||
"43" "bot/whew_that_was_close.wav"
|
||||
"44" "bot/whoo.wav"
|
||||
"45" "bot/whoo2.wav"
|
||||
"46" "bot/whos_the_man.wav"
|
||||
"47" "bot/who_wants_some_more.wav"
|
||||
"48" "bot/yesss.wav"
|
||||
"49" "bot/yesss2.wav"
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
-- Include needed files
|
||||
include("shared.lua")
|
||||
|
||||
-- Draw entity model.
|
||||
function ENT:Draw()
|
||||
self:DrawModel()
|
||||
end
|
||||
@@ -0,0 +1,8 @@
|
||||
--Thanks to Blasteh for gmod update the fix and nifnat for spectate fix!
|
||||
|
||||
-- Send required files to client
|
||||
AddCSLuaFile("cl_init.lua")
|
||||
AddCSLuaFile("shared.lua")
|
||||
|
||||
-- Include needed files
|
||||
include("shared.lua")
|
||||
@@ -0,0 +1,24 @@
|
||||
-- Entity information
|
||||
ENT.Type = "anim"
|
||||
ENT.Base = "base_anim"
|
||||
|
||||
-- Initialize
|
||||
function ENT:Initialize()
|
||||
self:SetModel("models/Kleiner.mdl")
|
||||
self:SetCollisionGroup(COLLISION_GROUP_PLAYER)
|
||||
self:SetSolid(SOLID_OBB)
|
||||
self:SetRenderMode(RENDERMODE_TRANSALPHA)
|
||||
self:SetColor(Color(255,255,255,255))
|
||||
end
|
||||
|
||||
-- Update position
|
||||
function ENT:Think()
|
||||
local hullOBBMin = self:OBBMins()
|
||||
local hullOBBMax = self:OBBMaxs()
|
||||
local hullOBB = hullOBBMax - hullOBBMin
|
||||
local pos = -Vector(0, 0, hullOBBMin.z)
|
||||
|
||||
self:SetPos(self.Owner:GetPos() + pos)
|
||||
self:SetVelocity(self:GetOwner():GetVelocity())
|
||||
end
|
||||
--]]
|
||||
@@ -0,0 +1,218 @@
|
||||
-- SWEP Information
|
||||
SWEP.Author = "Michael 'Xaymar' Dirks"
|
||||
SWEP.Contact = "info@project-kube.de"
|
||||
SWEP.Purpose = "More accurate SMG for Prop Hunt."
|
||||
SWEP.Instructions = "Fire away! Alternative fire to fire a grenade."
|
||||
SWEP.Category = "Prop Hunt Weapons"
|
||||
|
||||
-- Weapon Information
|
||||
SWEP.Weight = 5
|
||||
SWEP.AutoSwitchTo = false
|
||||
SWEP.AutoSwitchFrom = false
|
||||
|
||||
SWEP.Slot = 2
|
||||
SWEP.SlotPos = 1
|
||||
SWEP.DrawAmmo = true
|
||||
SWEP.DrawCrosshair = true
|
||||
|
||||
-- Weapon is spawnable for everyone, not just administrators.
|
||||
SWEP.Spawnable = true
|
||||
SWEP.AdminSpawnable = true
|
||||
|
||||
-- Model
|
||||
SWEP.ViewModel = "models/weapons/c_smg1.mdl"
|
||||
SWEP.WorldModel = "models/weapons/w_smg1.mdl"
|
||||
SWEP.UseHands = true
|
||||
|
||||
-- Primary Ammunition: SMG
|
||||
SWEP.Primary.ClipSize = 45
|
||||
SWEP.Primary.DefaultClip = 45
|
||||
SWEP.Primary.Automatic = true
|
||||
SWEP.Primary.Ammo = "SMG1"
|
||||
SWEP.Primary.Damage = 5
|
||||
|
||||
-- Secondary Ammunition: SMG Grenades
|
||||
SWEP.Secondary.ClipSize = 1
|
||||
SWEP.Secondary.DefaultClip = 0
|
||||
SWEP.Secondary.Automatic = false
|
||||
SWEP.Secondary.Ammo = "SMG1_Grenade"
|
||||
SWEP.Secondary.Damage = 100
|
||||
|
||||
-- Recoil
|
||||
SWEP.Recoil = {}
|
||||
SWEP.Recoil.SingleFire = 1.0
|
||||
SWEP.Recoil.BurstFire = 4.0
|
||||
SWEP.Recoil.SecondaryFire = 8.0
|
||||
|
||||
-- Accuracy
|
||||
SWEP.Accuracy = {}
|
||||
SWEP.Accuracy.Primary = {}
|
||||
SWEP.Accuracy.Primary.Min = 0.975
|
||||
SWEP.Accuracy.Primary.Max = 1.00
|
||||
SWEP.Accuracy.Primary.Reduction = 0.005
|
||||
SWEP.Accuracy.Primary.Recovery = 0.0025
|
||||
SWEP.Accuracy.Primary.Delay = 0.1
|
||||
SWEP.Accuracy.Secondary = {}
|
||||
SWEP.Accuracy.Secondary.Min = 1.00
|
||||
SWEP.Accuracy.Secondary.Max = 1.00
|
||||
SWEP.Accuracy.Secondary.Reduction = 0.00
|
||||
SWEP.Accuracy.Secondary.Recovery = 0.00
|
||||
SWEP.Accuracy.Secondary.Delay = 0.00
|
||||
|
||||
-- Sounds
|
||||
SWEP.Sound = {}
|
||||
SWEP.Sound.SwitchSingle = "weapons/smg1/switch_single.wav"
|
||||
SWEP.Sound.SwitchBurst = "weapons/smg1/switch_burst.wav"
|
||||
SWEP.Sound.SingleFire = "weapons/smg1/smg1_fire1.wav"
|
||||
SWEP.Sound.BurstFire = "weapons/smg1/smg1_fireburst1.wav"
|
||||
SWEP.Sound.SecondaryFire = "weapons/ar2/ar2_altfire.wav"
|
||||
SWEP.Sound.Reload = "weapons/smg1/smg1_reload.wav"
|
||||
SWEP.Sound.NoPrimaryAmmo = "weapons/pistol/pistol_empty.wav"
|
||||
SWEP.Sound.NoSecondaryAmmo = "weapons/pistol/pistol_empty.wav"
|
||||
|
||||
-- Initialization
|
||||
function SWEP:Initialize()
|
||||
-- Set holding type to smg.
|
||||
self:SetHoldType("smg");
|
||||
|
||||
-- Precache sounds for lagless experience.
|
||||
for i,v in ipairs(self.Sound) do
|
||||
util.PrecacheSound(v)
|
||||
end
|
||||
|
||||
-- Initialize default values.
|
||||
self.BurstFire = false
|
||||
self.PrimaryAccuracy = self.Accuracy.Primary.Max
|
||||
self.LastPrimaryAttack = CurTime()
|
||||
self.SecondaryAccuracy = self.Accuracy.Secondary.Max
|
||||
self.LastSecondaryAttack = CurTime()
|
||||
end
|
||||
|
||||
-- Primary Attack
|
||||
function SWEP:CanPrimaryAttack()
|
||||
-- Check if there is ammo in the clip.
|
||||
if (self:Clip1() <= 0) then
|
||||
-- If not, check if there's ammo available.
|
||||
if (self:Ammo1() > 0) then
|
||||
-- If yes, reload and wait for weapon to be ready again.
|
||||
self:EmitSound(self.Sound.NoPrimaryAmmo)
|
||||
self:Reload()
|
||||
return false
|
||||
end
|
||||
|
||||
-- If no, emit empty sound for primary fire.
|
||||
self:EmitSound(self.Sound.NoPrimaryAmmo)
|
||||
self:SetNextPrimaryFire(CurTime() + 0.1)
|
||||
return false
|
||||
end
|
||||
|
||||
-- Otherwise, return true.
|
||||
return true
|
||||
end
|
||||
|
||||
function SWEP:PrimaryAttack()
|
||||
-- Can't fire without Ammo
|
||||
if (!self:CanPrimaryAttack()) then return end
|
||||
|
||||
if (self.BurstFire == false) then
|
||||
-- Single Mode: fire and take one bullet from the clip.
|
||||
self:ShootBullet(self.Primary.Damage, bullet_count, 1.0 - self.PrimaryAccuracy)
|
||||
self:TakePrimaryAmmo(1)
|
||||
self:EmitSound(self.Sound.SingleFire)
|
||||
self:SetNextPrimaryFire( CurTime() + 0.1 )
|
||||
|
||||
-- Apply recoil
|
||||
self.Owner:ViewPunch( Angle(-1, 0, 0) * self.Recoil.SingleFire * (1 + (1 - self.PrimaryAccuracy)) )
|
||||
|
||||
-- Decrease accuracy
|
||||
self.PrimaryAccuracy = math.Clamp(self.PrimaryAccuracy - self.Accuracy.Primary.Reduction, self.Accuracy.Primary.Min, self.Accuracy.Primary.Max)
|
||||
else
|
||||
-- Burst Mode: fire and take up to three bullets from the clip
|
||||
local bulletCount = math.Clamp(self:Clip1(), 1, 3)
|
||||
self:ShootBullet(self.Primary.Damage, bullet_count, 1.0 - self.PrimaryAccuracy)
|
||||
self:TakePrimaryAmmo(bulletCount)
|
||||
self:EmitSound(self.Sound.BurstFire)
|
||||
self:SetNextPrimaryFire( CurTime() + 0.5 * (bulletCount / 3.0) )
|
||||
|
||||
-- Apply recoil
|
||||
self.Owner:ViewPunch(Angle(-1, 0, 0) * self.Recoil.BurstFire * (bulletCount / 3.0) * (1 + (1 - self.PrimaryAccuracy)))
|
||||
|
||||
-- Decrease accuracy
|
||||
self.PrimaryAccuracy = math.Clamp(self.PrimaryAccuracy - self.Accuracy.Primary.Reduction * bulletCount, self.Accuracy.Primary.Min, self.Accuracy.Primary.Max)
|
||||
end
|
||||
|
||||
-- Set Animation and attack time.
|
||||
self:SendWeaponAnim(ACT_VM_PRIMARYATTACK)
|
||||
self.LastPrimaryAttack = CurTime()
|
||||
return
|
||||
end
|
||||
|
||||
|
||||
-- Secondary Attack
|
||||
function SWEP:CanSecondaryAttack()
|
||||
if (self:Clip2() == 0) then
|
||||
if (self:Ammo2() == 0) then
|
||||
self:EmitSound(self.Sound.NoSecondaryAmmo)
|
||||
self:SetNextSecondaryFire( CurTime() + 1.0 )
|
||||
return false
|
||||
else
|
||||
self:SetClip2( 1 )
|
||||
self.Owner:SetAmmo( self.Owner:GetAmmoCount( self:GetSecondaryAmmoType() ) - 1, self:GetSecondaryAmmoType() )
|
||||
end
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function SWEP:SecondaryAttack()
|
||||
-- Can't fire without Ammo
|
||||
if (!self:CanSecondaryAttack()) then return end
|
||||
|
||||
-- Emit a sound.
|
||||
self:EmitSound(self.Sound.SecondaryFire)
|
||||
self:SetNextSecondaryFire( CurTime() + 1.0 )
|
||||
self:TakeSecondaryAmmo(1)
|
||||
|
||||
-- Create grenade
|
||||
if SERVER then
|
||||
local grenade = ents.Create("grenade_ar2")
|
||||
if (!IsValid(grenade)) then return end
|
||||
grenade:SetPos( self.Owner:GetShootPos() + self.Owner:GetAimVector() * 30 )
|
||||
grenade:SetVelocity( self.Owner:GetAimVector() * 1000 )
|
||||
grenade:SetAngles( self.Owner:GetAngles() )
|
||||
grenade:SetOwner( self.Owner )
|
||||
grenade:Spawn()
|
||||
grenade:SetPhysicsAttacker( self.Owner, 60 )
|
||||
end
|
||||
|
||||
-- Set Animation and attack time.
|
||||
self:SendWeaponAnim(ACT_VM_SECONDARYATTACK)
|
||||
self.LastSecondaryAttack = CurTime()
|
||||
return
|
||||
end
|
||||
|
||||
-- Reload: Combination of reloading and switching fire type.
|
||||
function SWEP:Reload()
|
||||
if self:DefaultReload(ACT_VM_RELOAD) then
|
||||
self:EmitSound(self.Sound.Reload)
|
||||
else
|
||||
if (self.LastReload) && ((CurTime() - self.LastReload) > 1) then
|
||||
self:GetOwner():ChatPrint("BurstToggle")
|
||||
self.BurstFire = !self.BurstFire
|
||||
end
|
||||
end
|
||||
self.LastReload = CurTime()
|
||||
return
|
||||
end
|
||||
|
||||
-- Think: Restore accuracy over time.
|
||||
function SWEP:Think()
|
||||
local ThinkTime = CurTime()
|
||||
|
||||
if (ThinkTime >= (self.LastPrimaryAttack + self.Accuracy.Primary.Delay)) then
|
||||
self.PrimaryAccuracy = math.Clamp(self.PrimaryAccuracy + self.Accuracy.Primary.Recovery, self.Accuracy.Primary.Min, self.Accuracy.Primary.Max)
|
||||
end
|
||||
if (ThinkTime >= (self.LastSecondaryAttack + self.Accuracy.Secondary.Delay)) then
|
||||
self.SecondaryAccuracy = math.Clamp(self.SecondaryAccuracy + self.Accuracy.Secondary.Recovery, self.Accuracy.Secondary.Min, self.Accuracy.Secondary.Max)
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,290 @@
|
||||
--[[
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Xaymar
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
--]]
|
||||
|
||||
-- ------------------------------------------------------------------------- --
|
||||
--! Includes
|
||||
-- ------------------------------------------------------------------------- --
|
||||
include("sh_init.lua")
|
||||
|
||||
include("client/cl_ui_teamselection.lua")
|
||||
|
||||
-- ------------------------------------------------------------------------- --
|
||||
--! Code
|
||||
-- ------------------------------------------------------------------------- --
|
||||
function GM:Initialize()
|
||||
print("-------------------------------------------------------------------------")
|
||||
print("Prop Hunt CL: Initializing...")
|
||||
|
||||
print("Prop Hunt CL: Initializing Gamemode Data...")
|
||||
self.Data = {}
|
||||
|
||||
print("Prop Hunt CL: Creating Huge Ass Font...")
|
||||
surface.CreateFont("PHHugeAssFont", {font="Roboto Bold Condensed", extended=true, size=160, weight=800, antialias=true})
|
||||
|
||||
print("Prop Hunt CL: Complete.")
|
||||
print("-------------------------------------------------------------------------")
|
||||
|
||||
end
|
||||
|
||||
function GM:Think() end
|
||||
|
||||
function GM:InitialPlayerSpawn()
|
||||
print("Prop Hunt CL: InitialPlayerSpawn")
|
||||
|
||||
-- Delay execution until LocalPlayer() is valid.
|
||||
if (!LocalPlayer()) || (!IsValid(LocalPlayer())) then
|
||||
timer.Simple(.1, function() GAMEMODE:InitialPlayerSpawn() end)
|
||||
return
|
||||
end
|
||||
|
||||
print("Prop Hunt CL: InitialPlayerSpawn Valid")
|
||||
|
||||
player_manager.RunClass(LocalPlayer(), "InitialClientSpawn")
|
||||
end
|
||||
|
||||
function GM:PlayerSpawn()
|
||||
print("Prop Hunt CL: PlayerSpawn")
|
||||
|
||||
-- Delay execution until LocalPlayer() is valid.
|
||||
if (!LocalPlayer()) || (!IsValid(LocalPlayer())) then
|
||||
timer.Simple(.1, function() GAMEMODE:PlayerSpawn() end)
|
||||
return
|
||||
end
|
||||
|
||||
print("Prop Hunt CL: PlayerSpawn Valid")
|
||||
|
||||
if !(LocalPlayer().Data) then
|
||||
LocalPlayer().Data = {}
|
||||
LocalPlayer().Data.ThirdPerson = true
|
||||
end
|
||||
|
||||
player_manager.RunClass(LocalPlayer(), "ClientSpawn")
|
||||
end
|
||||
|
||||
function GM:HUDPaint()
|
||||
local State = GetGlobalInt("RoundState", GAMEMODE.States.PreMatch)
|
||||
|
||||
-- Show Status at the top center
|
||||
local statusX, statusY, statusW, statusH
|
||||
statusW = 192
|
||||
statusH = 64
|
||||
statusX = ScrW() / 2 - statusW / 2
|
||||
statusY = 16
|
||||
|
||||
--! States
|
||||
-- Pre Match
|
||||
if (State == GAMEMODE.States.PreMatch) then
|
||||
-- Show Status at the top center
|
||||
draw.RoundedBox(16, statusX, statusY, statusW, statusH, Color(0, 0, 0, 204))
|
||||
surface.SetFont( "Trebuchet24" )
|
||||
surface.SetTextColor( 255, 255, 255, 255 )
|
||||
local w,h = surface.GetTextSize("Waiting...")
|
||||
surface.SetTextPos( statusX + statusW/2 - w / 2, statusY + statusH/2 - h / 2)
|
||||
surface.DrawText( "Waiting..." )
|
||||
|
||||
-- Pre Round
|
||||
elseif (State == GAMEMODE.States.PreRound) then
|
||||
-- Show Status at the top center
|
||||
draw.RoundedBox(16, statusX, statusY, statusW, statusH, Color(0, 0, 0, 204))
|
||||
surface.SetFont( "Trebuchet24" )
|
||||
surface.SetTextColor( 255, 255, 255, 255 )
|
||||
local w,h = surface.GetTextSize("Preparing...")
|
||||
surface.SetTextPos( statusX + statusW/2 - w / 2, statusY + statusH/2 - h / 2)
|
||||
surface.DrawText( "Preparing..." )
|
||||
|
||||
-- Hide!
|
||||
elseif (State == GAMEMODE.States.Hide) then
|
||||
local strTime = tostring(math.ceil(GetGlobalInt("RoundTime")))
|
||||
|
||||
-- Show Status at the top center
|
||||
draw.RoundedBox(16, statusX, statusY, statusW, statusH, Color(0, 0, 0, 204))
|
||||
surface.SetTextColor(255,255,255,255)
|
||||
surface.SetFont("Trebuchet18")
|
||||
local w,h = surface.GetTextSize("Seekers unblinded in:")
|
||||
surface.SetTextPos(statusX + statusW/2 - w / 2, statusY + statusH/4 - h / 2)
|
||||
surface.DrawText("Seekers unblinded in:")
|
||||
|
||||
surface.SetFont( "Trebuchet24" )
|
||||
local w,h = surface.GetTextSize(strTime.." Seconds!")
|
||||
surface.SetTextPos( statusX + statusW/2 - w / 2, statusY + statusH/1.5 - h / 2)
|
||||
surface.DrawText(strTime.." Seconds!")
|
||||
elseif (State == GAMEMODE.States.Seek) then
|
||||
local intTime = math.ceil(GetGlobalInt("RoundTime"))
|
||||
local strTime = string.format("%d:%02d", math.floor(intTime / 60), math.ceil(intTime % 60))
|
||||
|
||||
-- Show Status at the top center
|
||||
draw.RoundedBox(16, statusX, statusY, statusW, statusH, Color(0, 0, 0, 204))
|
||||
surface.SetTextColor(255,255,255,255)
|
||||
surface.SetFont("Trebuchet18")
|
||||
local w,h = surface.GetTextSize("Hunting Time!")
|
||||
surface.SetTextPos(statusX + statusW/2 - w / 2, statusY + statusH/4 - h / 2)
|
||||
surface.DrawText("Hunting Time!")
|
||||
|
||||
surface.SetFont( "Trebuchet24" )
|
||||
local w,h = surface.GetTextSize(strTime)
|
||||
surface.SetTextPos( statusX + statusW/2 - w / 2, statusY + statusH/1.5 - h / 2)
|
||||
surface.DrawText(strTime)
|
||||
|
||||
elseif (State == GAMEMODE.States.PostRound) then
|
||||
|
||||
elseif (State == GAMEMODE.States.PostMatch) then
|
||||
|
||||
end
|
||||
|
||||
player_manager.RunClass(LocalPlayer(), "HUDPaint")
|
||||
end
|
||||
|
||||
function GM:ShowTeamSelection()
|
||||
TeamSelectionUI:Show()
|
||||
end
|
||||
concommand.Add("ph_select_team", function() GAMEMODE:ShowTeamSelection() end)
|
||||
|
||||
function GM:GetHandsModel()
|
||||
return player_manager.RunClass(LocalPlayer(), "GetHandsModel")
|
||||
end
|
||||
|
||||
function GM:PostDrawViewModel( vm, ply, weapon )
|
||||
if ( weapon.UseHands || !weapon:IsScripted() ) then
|
||||
local hands = LocalPlayer():GetHands()
|
||||
if ( IsValid( hands ) ) then hands:DrawModel() end
|
||||
end
|
||||
end
|
||||
|
||||
-- ------------------------------------------------------------------------- --
|
||||
--! Player Manager Binding
|
||||
-- ------------------------------------------------------------------------- --
|
||||
function GM:CalcView(ply, pos, ang, fov, nearZ, farZ)
|
||||
return player_manager.RunClass(LocalPlayer(), "CalcView", {origin = pos, angles = ang, fov = fov, znear = nearZ, zfar = farZ})
|
||||
end
|
||||
|
||||
-- ------------------------------------------------------------------------- --
|
||||
--! Gamemode Functionality
|
||||
-- ------------------------------------------------------------------------- --
|
||||
function GM:PlayerSetViewOffset(vo, voduck)
|
||||
-- Delay execution until LocalPlayer() is valid.
|
||||
if (!LocalPlayer()) || (!IsValid(LocalPlayer())) then
|
||||
if !(GAMEMODE.TempData) then GAMEMODE.TempData = {} end
|
||||
GAMEMODE.TempData.ViewOffset = vo
|
||||
GAMEMODE.TempData.ViewOffsetDuck = voduck
|
||||
|
||||
timer.Simple(.1, function() GAMEMODE:PlayerSetViewOffset(GAMEMODE.TempData.ViewOffset, GAMEMODE.TempData.ViewOffsetDuck) end)
|
||||
return
|
||||
end
|
||||
|
||||
LocalPlayer():SetViewOffset(vo)
|
||||
LocalPlayer():SetViewOffsetDucked(voduck)
|
||||
if LocalPlayer():Crouching() then
|
||||
LocalPlayer():SetCurrentViewOffset(voduck)
|
||||
else
|
||||
LocalPlayer():SetCurrentViewOffset(vo)
|
||||
end
|
||||
end
|
||||
|
||||
function GM:PlayerSetHull(hullMin, hullMax)
|
||||
-- Delay execution until LocalPlayer() is valid.
|
||||
if (!LocalPlayer()) || (!IsValid(LocalPlayer())) then
|
||||
if !(GAMEMODE.TempData) then GAMEMODE.TempData = {} end
|
||||
GAMEMODE.TempData.HullMin = hullMin
|
||||
GAMEMODE.TempData.HullMax = hullMax
|
||||
|
||||
timer.Simple(.1, function() GAMEMODE:PlayerSetHull(GAMEMODE.TempData.HullMin, GAMEMODE.TempData.HullMax) end)
|
||||
return
|
||||
end
|
||||
|
||||
if (hullMin == hullMax) && (hullMin == nil) then
|
||||
LocalPlayer():ResetHull()
|
||||
else
|
||||
LocalPlayer():SetHull(hullMin, hullMax)
|
||||
LocalPlayer():SetHullDuck(hullMin, hullMax)
|
||||
end
|
||||
end
|
||||
|
||||
-- ------------------------------------------------------------------------- --
|
||||
--! Commands
|
||||
-- ------------------------------------------------------------------------- --
|
||||
function GM:OnContextMenuOpen()
|
||||
end
|
||||
|
||||
function GM:OnContextMenuClose()
|
||||
print("Prop Hunt CL: Toggled View Mode")
|
||||
LocalPlayer().Data.ThirdPerson = !LocalPlayer().Data.ThirdPerson
|
||||
end
|
||||
|
||||
-- ------------------------------------------------------------------------- --
|
||||
--! Network Messages
|
||||
-- ------------------------------------------------------------------------- --
|
||||
net.Receive("PlayerManagerInitialClientSpawn", function(len, pl) GAMEMODE:InitialPlayerSpawn() end)
|
||||
net.Receive("PlayerManagerClientSpawn", function(len, pl) GAMEMODE:PlayerSpawn() end)
|
||||
net.Receive( "PlayerSetHull", function(len, pl)
|
||||
local hullMin, hullMax = net.ReadVector(), net.ReadVector();
|
||||
GAMEMODE:PlayerSetHull(hullMin, hullMax)
|
||||
end)
|
||||
net.Receive( "PlayerResetHull", function(len, pl) GAMEMODE:PlayerSetHull(nil, nil) end)
|
||||
net.Receive( "PlayerViewOffset", function(len, pl)
|
||||
local vo, voduck = net.ReadVector(), net.ReadVector()
|
||||
GAMEMODE:PlayerSetViewOffset(vo, voduck)
|
||||
end)
|
||||
|
||||
-- ------------------------------------------------------------------------- --
|
||||
--! Old Code
|
||||
-- ------------------------------------------------------------------------- --
|
||||
--[[
|
||||
-- Render halos and player names.
|
||||
function DrawPlayerNames(bDrawingDepth, bDrawingSkybox)
|
||||
for i,v in ipairs(player.GetAll()) do
|
||||
if v:Alive() && v != LocalPlayer() then
|
||||
local pos = v:GetPos() + v:GetViewOffset() + Vector(0, 0, 5)
|
||||
local ang = Angle(0, LocalPlayer():EyeAngles().y - 90, 90 - LocalPlayer():EyeAngles().x)
|
||||
local healthPrc = v:Health() / v:GetMaxHealth()
|
||||
local healthCol = HSVToColor(120 * healthPrc, 1.0, 1.0)
|
||||
|
||||
if v:Team() == TEAM_HUNTERS || LocalPlayer():Team() == TEAM_PROPS then
|
||||
cam.Start3D2D(pos, ang, 0.15)
|
||||
draw.DrawText(v:GetName(), "Trebuchet24", 0, -draw.GetFontHeight("Trebuchet24"), healthCol, TEXT_ALIGN_CENTER)
|
||||
cam.End3D2D()
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
hook.Add("PostDrawTranslucentRenderables", "PH_DrawPlayerNames", DrawPlayerNames)
|
||||
|
||||
function DrawPlayerHalos(bDrawingDepth, bDrawingSkybox)
|
||||
for i,v in ipairs(player.GetAll()) do
|
||||
if v:Alive() then
|
||||
local pos = v:GetPos() + Vector(0, 0, 1) * (v:OBBMaxs().z - v:OBBMins().z + 5)
|
||||
local ang = Angle(0, LocalPlayer():EyeAngles().y - 90, 90 - LocalPlayer():EyeAngles().x)
|
||||
local healthPrc = v:Health() / v:GetMaxHealth()
|
||||
local healthCol = HSVToColor(120 * healthPrc, 1.0, 1.0)
|
||||
|
||||
if v:Team() == TEAM_HUNTERS || LocalPlayer():Team() == TEAM_PROPS then
|
||||
local ent = v
|
||||
if v.ph_prop && v.ph_prop:IsValid() then ent = v.ph_prop end
|
||||
|
||||
halo.Add({ent}, healthCol, 2, 2, 1)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
--hook.Add("PostDrawEffects", "PH_DrawPlayerHalos", DrawPlayerHalos)
|
||||
]]
|
||||
@@ -0,0 +1,75 @@
|
||||
--[[
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Xaymar
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
--]]
|
||||
|
||||
TeamSelectionUI = {}
|
||||
TeamSelectionUI.Frame = vgui.Create("DFrame")
|
||||
TeamSelectionUI.Frame:SetPos(0, 0)
|
||||
TeamSelectionUI.Frame:SetSize(400, 320)
|
||||
TeamSelectionUI.Frame:Center()
|
||||
TeamSelectionUI.Frame:SetTitle("Select a Team")
|
||||
TeamSelectionUI.Frame:SetVisible(false)
|
||||
TeamSelectionUI.Frame:SetDraggable(true)
|
||||
TeamSelectionUI.Frame:SetSizable(false)
|
||||
TeamSelectionUI.Frame:ShowCloseButton(true)
|
||||
TeamSelectionUI.Frame:SetDeleteOnClose(false)
|
||||
function TeamSelectionUI.Frame:Paint(w, h)
|
||||
draw.RoundedBox(0, 0, 0, w, h, Color(0, 0, 0, 225))
|
||||
end
|
||||
|
||||
function TeamSelectionUI:Show()
|
||||
self.Frame:MakePopup()
|
||||
TeamSelectionUI.Frame:SetVisible(true)
|
||||
end
|
||||
|
||||
function TeamSelectionUI:Hide()
|
||||
TeamSelectionUI.Frame:Close()
|
||||
TeamSelectionUI.Frame:SetVisible(false)
|
||||
end
|
||||
|
||||
TeamSelectionUI.SelectSeeker = vgui.Create("DButton", TeamSelectionUI.Frame)
|
||||
TeamSelectionUI.SelectSeeker:SetPos(0, 20)
|
||||
TeamSelectionUI.SelectSeeker:SetSize(200, 200)
|
||||
TeamSelectionUI.SelectSeeker:SetText("Seeker")
|
||||
TeamSelectionUI.SelectSeeker.DoClick = function()
|
||||
TeamSelectionUI:Hide()
|
||||
LocalPlayer():ConCommand("changeteam " .. tostring(GAMEMODE.Teams.Seekers))
|
||||
end
|
||||
|
||||
TeamSelectionUI.SelectHider = vgui.Create("DButton", TeamSelectionUI.Frame)
|
||||
TeamSelectionUI.SelectHider:SetPos(200, 20)
|
||||
TeamSelectionUI.SelectHider:SetSize(200, 200)
|
||||
TeamSelectionUI.SelectHider:SetText("Hiders")
|
||||
TeamSelectionUI.SelectHider.DoClick = function()
|
||||
TeamSelectionUI:Hide()
|
||||
LocalPlayer():ConCommand("changeteam " .. tostring(GAMEMODE.Teams.Hiders))
|
||||
end
|
||||
|
||||
TeamSelectionUI.Spectate = vgui.Create("DButton", TeamSelectionUI.Frame)
|
||||
TeamSelectionUI.Spectate:SetPos(0, 220)
|
||||
TeamSelectionUI.Spectate:SetSize(400, 100)
|
||||
TeamSelectionUI.Spectate:SetText("Spectate")
|
||||
TeamSelectionUI.Spectate.DoClick = function()
|
||||
TeamSelectionUI:Hide()
|
||||
LocalPlayer():ConCommand("changeteam " .. tostring(GAMEMODE.Teams.Spectators))
|
||||
end
|
||||
@@ -0,0 +1,49 @@
|
||||
--[[
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Xaymar
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
--]]
|
||||
|
||||
-- This file adds compatability to the older Taunt Pack loader format, which
|
||||
-- directly modifies the gamemode tables (something that shouldn't be done).
|
||||
|
||||
function CompatTauntPackLoader()
|
||||
-- Prepare an empty table for the taunts.
|
||||
GAMEMODE.Prop_Taunts = {}
|
||||
GAMEMODE.Hunter_Taunts = {}
|
||||
|
||||
-- Run the old hook name.
|
||||
hook.Run("ph_AddTaunts", nil)
|
||||
|
||||
-- Insert the taunts into the new structure.
|
||||
for k,v in ipairs(GAMEMODE.Hunter_Taunts) do
|
||||
-- ToDo: string.GetFileFromFilename is broken!
|
||||
--pcall(GAMEMODE.Config.Taunts.Add("TauntPackLoader."..string.GetFileFromFilename(v), v, TEAM_SEEKERES, nil))
|
||||
end
|
||||
for k,v in ipairs(GAMEMODE.Prop_Taunts) do
|
||||
--pcall(GAMEMODE.Config.Taunts.Add("TauntPackLoader."..string.GetFileFromFilename(v), v, TEAM_HIDERS, nil))
|
||||
end
|
||||
|
||||
-- Clean up after ourselves
|
||||
GAMEMODE.Prop_Taunts = nil
|
||||
GAMEMODE.Hunter_Taunts = nil
|
||||
end
|
||||
hook.Add("OnPropHuntInitialized", "CompatTauntPackLoader", CompatTauntPackLoader)
|
||||
@@ -0,0 +1,414 @@
|
||||
--[[
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Xaymar
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
--]]
|
||||
|
||||
-- ------------------------------------------------------------------------- --
|
||||
--! Downloadable Lua
|
||||
-- ------------------------------------------------------------------------- --
|
||||
-- Shared
|
||||
AddCSLuaFile("sh_init.lua")
|
||||
AddCSLuaFile("sh_config.lua")
|
||||
AddCSLuaFile("sh_player.lua")
|
||||
AddCSLuaFile("player_class/class_default.lua")
|
||||
AddCSLuaFile("player_class/class_spectator.lua")
|
||||
AddCSLuaFile("player_class/class_seeker.lua")
|
||||
AddCSLuaFile("player_class/class_hider.lua")
|
||||
|
||||
-- Client-Only
|
||||
AddCSLuaFile("cl_init.lua")
|
||||
AddCSLuaFile("client/cl_ui_teamselection.lua")
|
||||
|
||||
-- ------------------------------------------------------------------------- --
|
||||
--! Code
|
||||
-- ------------------------------------------------------------------------- --
|
||||
-- Shared
|
||||
include "sh_init.lua"
|
||||
|
||||
-- Server Only
|
||||
include "server/config.lua"
|
||||
include "compat/compat_tauntpackloader.lua"
|
||||
include "server/roundmanager.lua"
|
||||
include "server/states/state_prematch.lua"
|
||||
include "server/states/state_preround.lua"
|
||||
include "server/states/state_hide.lua"
|
||||
include "server/states/state_seek.lua"
|
||||
include "server/states/state_postround.lua"
|
||||
|
||||
function GM:Initialize()
|
||||
print("-------------------------------------------------------------------------")
|
||||
print("Prop Hunt: Initializing...")
|
||||
|
||||
print("Prop Hunt: Registering Networked Messages...")
|
||||
util.AddNetworkString("PlayerManagerInitialClientSpawn")
|
||||
util.AddNetworkString("PlayerManagerClientSpawn")
|
||||
|
||||
util.AddNetworkString("PlayerSetHull")
|
||||
util.AddNetworkString("PlayerResetHull")
|
||||
util.AddNetworkString("PlayerViewOffset")
|
||||
util.AddNetworkString("PlayerRegisterPropEntity")
|
||||
|
||||
print("Prop Hunt: Initializing Gamemode Data...")
|
||||
self.Data = {}
|
||||
|
||||
print("Prop Hunt: Setting initial RoundManager State...")
|
||||
self.RoundManager:SetState(StatePreMatch)
|
||||
|
||||
print("Prop Hunt: Complete.")
|
||||
print("-------------------------------------------------------------------------")
|
||||
end
|
||||
|
||||
function GM:Think()
|
||||
self.RoundManager:Tick()
|
||||
end
|
||||
|
||||
-- Player Connected
|
||||
function GM:PlayerConnect(name, ip)
|
||||
print("Prop Hunt: Player '"..name.."' connecting from IP '"..ip.."'.")
|
||||
end
|
||||
|
||||
-- Player Authenticated
|
||||
function GM:PlayerAuthed(ply, steamid, uniqueid)
|
||||
print("Prop Hunt: Player '"..ply:GetName().."' (SteamID: "..ply:SteamID()..") authenticated.")
|
||||
end
|
||||
|
||||
-- Player Disconnected
|
||||
function GM:PlayerDisconnected(ply)
|
||||
print("Prop Hunt: Player '"..ply:GetName().."' (SteamID: "..ply:SteamID()..") disconnected.")
|
||||
end
|
||||
|
||||
-- Player Spawn (Initial)
|
||||
function GM:PlayerInitialSpawn(ply)
|
||||
print("Prop Hunt: Player '"..ply:GetName().."' (SteamID: "..ply:SteamID()..") spawned for the first time, applying defaults...")
|
||||
|
||||
if (!ply.Data) then
|
||||
-- Initialize Data Structure
|
||||
ply.Data = {}
|
||||
ply.Data.Alive = false
|
||||
ply.Data.AliveTime = 0
|
||||
end
|
||||
|
||||
-- Kill Silently
|
||||
ply:KillSilent()
|
||||
|
||||
-- Show Team Selection Menu
|
||||
ply:SetTeam(GAMEMODE.Teams.Spectators)
|
||||
self:ShowTeam(ply)
|
||||
|
||||
-- Bot: Auto Assign to Team
|
||||
if (ply:IsBot()) then
|
||||
if team.NumPlayers(self.Teams.Hiders) > team.NumPlayers(self.Teams.Seekers) then
|
||||
print("Prop Hunt: Bot '"..ply:GetName().."' assigned to Seekers.")
|
||||
ply:SetTeam(self.Teams.Seekers)
|
||||
else
|
||||
print("Prop Hunt: Bot '"..ply:GetName().."' assigned to Hiders.")
|
||||
ply:SetTeam(self.Teams.Hiders)
|
||||
end
|
||||
end
|
||||
|
||||
-- Notify Player Manager
|
||||
player_manager.RunClass(ply, "InitialSpawn")
|
||||
|
||||
-- Signal Client
|
||||
net.Start("PlayerManagerInitialClientSpawn");net.Send(ply)
|
||||
end
|
||||
|
||||
-- Player Spawn
|
||||
function GM:PlayerSpawn(ply)
|
||||
print("Prop Hunt: Player '"..ply:GetName().."' (SteamID: "..ply:SteamID()..") spawned in.")
|
||||
|
||||
-- Player Manager: Assign Player Class
|
||||
local class = team.GetClass(ply:Team())
|
||||
if (class) then
|
||||
if (ply.Data.Alive) then -- Alive Class
|
||||
player_manager.SetPlayerClass(ply, class[1])
|
||||
else -- Dead Class (Spectator)
|
||||
player_manager.SetPlayerClass(ply, class[2])
|
||||
end
|
||||
else
|
||||
player_manager.SetPlayerClass(ply, "Spectator")
|
||||
end
|
||||
|
||||
-- Notify Player Manager
|
||||
player_manager.OnPlayerSpawn(ply)
|
||||
player_manager.RunClass(ply, "Spawn")
|
||||
|
||||
-- Some hooks are not called
|
||||
hook.Call("PlayerSetModel", self, ply)
|
||||
hook.Call("PlayerLoadout", self, ply)
|
||||
|
||||
-- Signal Client
|
||||
net.Start("PlayerManagerClientSpawn");net.Send(ply)
|
||||
end
|
||||
|
||||
-- Player requests Team Change
|
||||
function GM:PlayerRequestTeam(ply, teamId)
|
||||
if self:PlayerCanJoinTeam(ply, teamId) then
|
||||
print("Prop Hunt: Player '"..ply:GetName().."' (SteamID: "..ply:SteamID()..") requested to join Team "..team.GetName(teamId)..".")
|
||||
|
||||
if (ply:Team() != teamId) then
|
||||
ply:KillSilent()
|
||||
ply:SetTeam(teamId)
|
||||
|
||||
if (GetGlobalInt("RoundState", GAMEMODE.States.PreMatch) <= GAMEMODE.States.PreRound) then
|
||||
ply.Alive = true
|
||||
ply.AliveTime = CurTime()
|
||||
end
|
||||
else
|
||||
print("Prop Hunt: Player '"..ply:GetName().."' (SteamID: "..ply:SteamID()..") attempted to rejoin the Team it is already in.")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- ------------------------------------------------------------------------- --
|
||||
--! Player Manager Binding
|
||||
-- ------------------------------------------------------------------------- --
|
||||
function GM:PlayerLoadout(ply) player_manager.RunClass(ply, "Loadout") end
|
||||
function GM:PlayerDeath(ply, inflictor, attacker) player_manager.RunClass(ply, "Death", inflictor, attacker) end
|
||||
function GM:PlayerSilentDeath(ply) player_manager.RunClass(ply, "SilentDeath") end
|
||||
function GM:PostPlayerDeath(ply)
|
||||
player_manager.RunClass(ply, "PostDeath")
|
||||
|
||||
-- Debug Mode: Respawn after Death
|
||||
if (GAMEMODE.Config:Debug()) then
|
||||
ply.Data.Alive = true
|
||||
print("Prop Hunt: Debug Mode active, Player "..ply:GetName().." was respawned.")
|
||||
end
|
||||
end
|
||||
--function GM:DoPlayerDeath(ply, attacker, dmg) player_manager.RunClass(ply, "DoDeath", attacker, dmg) end
|
||||
function GM:PlayerDeathThink(ply) return player_manager.RunClass(ply, "DeathThink") end
|
||||
function GM:CanPlayerSuicide(ply) return player_manager.RunClass(ply, "CanSuicide") end
|
||||
function GM:PlayerCanPickupWeapon(ply, weapon) return player_manager.RunClass(ply, "CanPickupWeapon", weapon) end
|
||||
function GM:PlayerCanPickupItem(ply, item) return player_manager.RunClass(ply, "CanPickupItem", item) end
|
||||
function GM:PlayerUse(ply, ent) return player_manager.RunClass(ply, "Use", ent) end
|
||||
function GM:AllowPlayerPickup(ply, ent) return player_manager.RunClass(ply, "AllowPickup", ent) end
|
||||
function GM:PlayerSetModel(ply) return player_manager.RunClass(ply, "SetModel") end
|
||||
|
||||
-- Called when an entity takes damage
|
||||
function GM:EntityTakeDamage(ent, dmg)
|
||||
local att = dmg:GetAttacker()
|
||||
|
||||
if (att) && (att:IsValid()) && (att:IsPlayer()) then
|
||||
player_manager.RunClass(att, "DamageEntity", ent, att, dmg)
|
||||
end
|
||||
end
|
||||
|
||||
-- ------------------------------------------------------------------------- --
|
||||
--! Gamemode Functionality
|
||||
-- ------------------------------------------------------------------------- --
|
||||
function GM:SetRoundState(State)
|
||||
SetGlobalInt("RoundState", State)
|
||||
end
|
||||
|
||||
function GM:PlayerHullFromEntity(ply, ent)
|
||||
if (ent) && (ent:IsValid()) then
|
||||
local hmin, hmax = ent:OBBMins(), ent:OBBMaxs()
|
||||
local hull = Vector(hmax.x - hmin.x, hmax.y - hmin.y, hmax.z - hmin.z)
|
||||
if hull.x <= hull.y then
|
||||
hull.y = hull.x
|
||||
else
|
||||
hull.x = hull.y
|
||||
end
|
||||
hull:Mul(0.5)
|
||||
|
||||
local hullmin = Vector(-hull.x, -hull.y, 0)
|
||||
local hullmax = Vector(hull.x, hull.y, hull.z * 2)
|
||||
|
||||
ply:SetHull(hullmin, hullmax)
|
||||
ply:SetHullDuck(hullmin, hullmax)
|
||||
net.Start("PlayerSetHull")
|
||||
net.WriteVector(hullmin)
|
||||
net.WriteVector(hullmax)
|
||||
net.Send(ply)
|
||||
return {hullmin, hullmax}
|
||||
else
|
||||
ply:ResetHull()
|
||||
net.Start("PlayerResetHull")
|
||||
net.Send(ply)
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
function GM:PlayerSetViewOffset(ply, vo, voduck)
|
||||
ply:SetViewOffset(vo)
|
||||
ply:SetViewOffsetDucked(voduck)
|
||||
if ply:Crouching() then
|
||||
ply:SetCurrentViewOffset(voduck)
|
||||
else
|
||||
ply:SetCurrentViewOffset(vo)
|
||||
end
|
||||
|
||||
-- Signal Client
|
||||
net.Start("PlayerViewOffset")
|
||||
net.WriteVector(vo)
|
||||
net.WriteVector(voduck)
|
||||
net.Send(ply)
|
||||
end
|
||||
|
||||
-- ------------------------------------------------------------------------- --
|
||||
--! Commands
|
||||
-- ------------------------------------------------------------------------- --
|
||||
-- F1/ShowHelp
|
||||
function GM:ShowHelp(ply) end
|
||||
|
||||
-- F2/ShowTeam - Select Team
|
||||
function GM:ShowTeam(ply)
|
||||
ply:ConCommand("ph_select_team")
|
||||
end
|
||||
|
||||
-- F3/ShowSpare1
|
||||
function GM:ShowSpare1(ply) end
|
||||
|
||||
-- F4/ShowSpare2
|
||||
function GM:ShowSpare2(ply) end
|
||||
|
||||
-- Debug Command: Print All Players
|
||||
concommand.Add("ph_debug_printplayers", function(ply, cmd, args, argStr)
|
||||
print ("All Players:")
|
||||
for i,ply in ipairs(player.GetAll()) do
|
||||
print(" "..ply:GetName().." (SteamID: "..ply:SteamID()..") - Team "..team.GetName(ply:Team()).. " - Alive "..tostring(ply.Data.Alive))
|
||||
end
|
||||
|
||||
print ("Spectators:")
|
||||
for i,ply in ipairs(team.GetPlayers(GAMEMODE.Teams.Spectators)) do
|
||||
print(" "..ply:GetName().." (SteamID: "..ply:SteamID()..")")
|
||||
end
|
||||
|
||||
print ("Seekers:")
|
||||
for i,ply in ipairs(team.GetPlayers(GAMEMODE.Teams.Seekers)) do
|
||||
print(" "..ply:GetName().." (SteamID: "..ply:SteamID()..")")
|
||||
end
|
||||
|
||||
print ("Hiders:")
|
||||
for i,ply in ipairs(team.GetPlayers(GAMEMODE.Teams.Hiders)) do
|
||||
print(" "..ply:GetName().." (SteamID: "..ply:SteamID()..")")
|
||||
end
|
||||
|
||||
end, nil, nil, FCVAR_CLIENTCMD_CAN_EXECUTE + FCVAR_CHEAT)
|
||||
|
||||
-- ------------------------------------------------------------------------- --
|
||||
--! LEGACY CODE - TO BE REPLACED SOON
|
||||
-- ------------------------------------------------------------------------- --
|
||||
--[[
|
||||
function AnnounceVictory(players, force)
|
||||
for i,pl in ipairs(players) do
|
||||
if pl:Alive() || force || pl:Team() == TEAM_SPECTATOR then
|
||||
announcer = table.Random(VICTORY_SOUNDS);
|
||||
print("Prop Hunt: '"..pl:GetName().."' announcing victory with '"..announcer.."'.")
|
||||
pl:EmitSound(announcer, 200, 100, 0.5, CHAN_VOICE2)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function AnnounceLoss(players, force)
|
||||
for i,pl in ipairs(players) do
|
||||
if pl:Alive() || force || pl:Team() == TEAM_SPECTATOR then
|
||||
announcer = table.Random(LOSS_SOUNDS);
|
||||
print("Prop Hunt: '"..pl:GetName().."' announcing loss with '"..announcer.."'.")
|
||||
pl:EmitSound(announcer, 100, 100, 0.5, CHAN_VOICE2)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- If there is a mapfile send it to the client (sometimes servers want to change settings for certain maps)
|
||||
if file.Exists("maps/"..game.GetMap()..".lua", "LUA") then
|
||||
AddCSLuaFile("maps/"..game.GetMap()..".lua")
|
||||
end
|
||||
|
||||
-- Send the required resources to the client
|
||||
for _, announcer in pairs(LOSS_SOUNDS) do resource.AddFile("sound/"..announcer) end
|
||||
for _, announcer in pairs(VICTORY_SOUNDS) do resource.AddFile("source/"..announcer) end
|
||||
for _, taunt in pairs(HUNTER_TAUNTS) do resource.AddFile("sound/"..taunt) end
|
||||
for _, taunt in pairs(PROP_TAUNTS) do resource.AddFile("sound/"..taunt) end
|
||||
|
||||
-- Called alot
|
||||
function GM:CheckPlayerDeathRoundEnd()
|
||||
if !GAMEMODE.RoundBased || !GAMEMODE:InRound() then
|
||||
return
|
||||
end
|
||||
|
||||
local Teams = GAMEMODE:GetTeamAliveCounts()
|
||||
|
||||
if table.Count(Teams) == 0 then
|
||||
GAMEMODE:RoundEndWithResult(1001, "Draw, everyone loses!")
|
||||
AnnounceLoss(player.GetAll(), true)
|
||||
return
|
||||
end
|
||||
|
||||
if table.Count(Teams) == 1 then
|
||||
-- Play victory and loss sounds.
|
||||
if Teams[0] == TEAM_HUNTERS then
|
||||
AnnounceVictory(team.GetPlayers(TEAM_HUNTERS))
|
||||
AnnounceLoss(team.GetPlayers(TEAM_PROPS))
|
||||
elseif Teams[0] == TEAM_PROPS then
|
||||
AnnounceLoss(team.GetPlayers(TEAM_HUNTERS))
|
||||
AnnounceVictory(team.GetPlayers(TEAM_PROPS))
|
||||
end
|
||||
|
||||
local TeamID = table.GetFirstKey(Teams)
|
||||
GAMEMODE:RoundEndWithResult(TeamID, team.GetName(TeamID).." win!")
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
-- Called when player presses [F3]. Plays a taunt for their team
|
||||
function GM:ShowSpare1(pl)
|
||||
if GAMEMODE:InRound() && pl:Alive() && (pl:Team() == TEAM_HUNTERS || pl:Team() == TEAM_PROPS) && pl.last_taunt_time + TAUNT_DELAY <= CurTime() && #PROP_TAUNTS > 1 && #HUNTER_TAUNTS > 1 then
|
||||
-- repeat
|
||||
if pl:Team() == TEAM_HUNTERS then
|
||||
rand_taunt = table.Random(HUNTER_TAUNTS)
|
||||
else
|
||||
rand_taunt = table.Random(PROP_TAUNTS)
|
||||
end
|
||||
-- until rand_taunt != pl.last_taunt
|
||||
|
||||
pl.last_taunt_time = CurTime()
|
||||
pl.last_taunt = rand_taunt
|
||||
|
||||
print("Prop Hunt: '"..pl:GetName().."' taunting with '"..rand_taunt.."'.")
|
||||
local vol = 1.0
|
||||
if pl:Team() == TEAM_HUNTERS then vol = vol * 0.5 end
|
||||
pl:EmitSound(rand_taunt, 100, 100, vol, CHAN_VOICE2)
|
||||
end
|
||||
end
|
||||
|
||||
-- Allow player to rotate the prop. (Either F4 or ducking)
|
||||
function GM:ShowSpare2(pl)
|
||||
if pl:Alive() && (pl:Team() == TEAM_PROPS) then
|
||||
pl.ph_prop:SetApplyNewAngles(!pl.ph_prop:GetApplyNewAngles())
|
||||
-- pl.ph_prop:SetNewAngles(pl:GetAngles())
|
||||
end
|
||||
end
|
||||
|
||||
-- Removes all weapons on a map
|
||||
function RemoveWeaponsAndItems()
|
||||
for _, wep in pairs(ents.FindByClass("weapon_*")) do
|
||||
wep:Remove()
|
||||
end
|
||||
|
||||
for _, item in pairs(ents.FindByClass("item_*")) do
|
||||
item:Remove()
|
||||
end
|
||||
end
|
||||
hook.Add("InitPostEntity", "PH_RemoveWeaponsAndItems", RemoveWeaponsAndItems)
|
||||
|
||||
]]
|
||||
@@ -0,0 +1,137 @@
|
||||
--[[
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Xaymar
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
--]]
|
||||
|
||||
DEFINE_BASECLASS("player_default")
|
||||
local CLASS = {}
|
||||
CLASS.DisplayName = "Default"
|
||||
CLASS.WalkSpeed = 250 -- How fast to move when not running
|
||||
CLASS.RunSpeed = 500 -- How fast to move when running
|
||||
CLASS.CrouchedWalkSpeed = 0.5 -- Multiply move speed by this when crouching
|
||||
CLASS.DuckSpeed = 0.2 -- How fast to go from not ducking, to ducking
|
||||
CLASS.UnDuckSpeed = 0.2 -- How fast to go from ducking, to not ducking
|
||||
CLASS.JumpPower = 200 -- How powerful our jump should be
|
||||
CLASS.CanUseFlashlight = false -- Can we use the flashlight
|
||||
CLASS.MaxHealth = 100 -- Max health we can have
|
||||
CLASS.StartHealth = 100 -- How much health we start with
|
||||
CLASS.StartArmor = 0 -- How much armour we start with
|
||||
CLASS.DropWeaponOnDie = false -- Do we drop our weapon when we die
|
||||
CLASS.TeammateNoCollide = true -- Do we collide with teammates or run straight through them
|
||||
CLASS.AvoidPlayers = true -- Automatically swerves around other players
|
||||
CLASS.UseVMHands = true -- Uses viewmodel hands
|
||||
|
||||
-- ------------------------------------------------------------------------- --
|
||||
--! Server-Side
|
||||
-- ------------------------------------------------------------------------- --
|
||||
-- Spawn
|
||||
function CLASS:InitialSpawn() end
|
||||
function CLASS:Spawn() end
|
||||
function CLASS:Loadout() end
|
||||
|
||||
-- Damage
|
||||
function CLASS:Hurt(victim, attacker, healthRemaining, damageTaken) end -- Damage Taken
|
||||
function CLASS:Damage(victim, attacker, healthRemaining, damageDealt) end -- Damage Dealt
|
||||
function CLASS:DamageEntity(ent, attacker, dmginfo) end -- Damage Dealt To Entity
|
||||
|
||||
-- Death
|
||||
function CLASS:Death(inflictor, attacker)
|
||||
self.Player.Data.Alive = false
|
||||
self.Player.Data.AliveTime = CurTime()
|
||||
end
|
||||
function CLASS:SilentDeath()
|
||||
self.Player.Data.Alive = false
|
||||
self.Player.Data.AliveTime = CurTime()
|
||||
end
|
||||
function CLASS:PostDeath() end
|
||||
|
||||
function CLASS:DoDeath() end
|
||||
|
||||
function CLASS:DeathThink()
|
||||
if (CurTime() - self.Player.Data.AliveTime) > 2 then
|
||||
self.Player:Spawn()
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function CLASS:CanSuicide() return true end
|
||||
|
||||
-- Visible Stuff
|
||||
function CLASS:SetModel() BaseClass.SetModel( self ) end
|
||||
|
||||
-- Interaction
|
||||
function CLASS:Use(ent)
|
||||
-- Entity must be valid and not a player.
|
||||
if (!ent) || (!ent:IsValid()) || (ent:IsPlayer()) then
|
||||
return false
|
||||
end
|
||||
|
||||
-- Cool Down
|
||||
if (self.Player.Data.UseTime) then
|
||||
local timeSinceUse = (CurTime() - self.Player.Data.UseTime)
|
||||
if (0.2 > timeSinceUse) then
|
||||
return false
|
||||
end
|
||||
|
||||
-- Abuse Blacklist (Buttons, Doors, etc)
|
||||
if (5 > timeSinceUse) then
|
||||
local abuseBlacklist = GAMEMODE.Config.Lists:AbuseBlacklist()
|
||||
if (table.HasValue(abuseBlacklist, ent:GetClass())) then
|
||||
return false
|
||||
end
|
||||
end
|
||||
end
|
||||
self.Player.Data.UseTime = CurTime()
|
||||
|
||||
return true
|
||||
end
|
||||
function CLASS:AllowPickup(ent) return false end
|
||||
function CLASS:CanPickupWeapon(ent) return false end
|
||||
function CLASS:CanPickupItem(ent) return false end
|
||||
|
||||
-- ------------------------------------------------------------------------- --
|
||||
--! Shared
|
||||
-- ------------------------------------------------------------------------- --
|
||||
function CLASS:PostThink() end
|
||||
function CLASS:Tick(mv) end
|
||||
|
||||
-- ------------------------------------------------------------------------- --
|
||||
--! Client-Side
|
||||
-- ------------------------------------------------------------------------- --
|
||||
-- Spawn
|
||||
function CLASS:InitialClientSpawn()
|
||||
self.Player.Data = {}
|
||||
self.Player.Data.ThirdPerson = false -- Default to FirstPerson View
|
||||
end
|
||||
function CLASS:ClientSpawn() end
|
||||
|
||||
-- View & HUD
|
||||
function CLASS:GetHandsModel() return BaseClass.GetHandsModel(self) end
|
||||
function CLASS:ShouldDrawLocal() return false end
|
||||
function CLASS:HUDPaint() end
|
||||
function CLASS:CalcView(camdata) return camdata end
|
||||
|
||||
-- ------------------------------------------------------------------------- --
|
||||
--! Register
|
||||
-- ------------------------------------------------------------------------- --
|
||||
player_manager.RegisterClass( "Default", CLASS, "player_default")
|
||||
@@ -0,0 +1,234 @@
|
||||
--[[
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Xaymar
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
--]]
|
||||
|
||||
DEFINE_BASECLASS( "Default" )
|
||||
local CLASS = {}
|
||||
CLASS.DisplayName = "Hider"
|
||||
CLASS.DuckSpeed = 0.0 -- How fast to go from not ducking, to ducking
|
||||
CLASS.UnDuckSpeed = 0.0 -- How fast to go from ducking, to not ducking
|
||||
CLASS.CanUseFlashlight = false -- Can we use the flashlight
|
||||
CLASS.UseVMHands = false -- Uses viewmodel hands
|
||||
|
||||
-- ------------------------------------------------------------------------- --
|
||||
--! Server-Side
|
||||
-- ------------------------------------------------------------------------- --
|
||||
-- Spawn
|
||||
function CLASS:Spawn()
|
||||
print("Prop Hunt: Hider '"..self.Player:GetName().."' (SteamID: "..self.Player:SteamID()..") spawned.")
|
||||
BaseClass.Spawn(self, self.Player)
|
||||
|
||||
-- Sprinting
|
||||
if (!GAMEMODE.Config:Sprinting()) then
|
||||
self.Player:SetRunSpeed(self.WalkSpeed)
|
||||
end
|
||||
|
||||
-- Settings
|
||||
self.Player:SetMaxHealth(GAMEMODE.Config.Hider:HealthMax())
|
||||
self.Player:SetHealth(GAMEMODE.Config.Hider:Health())
|
||||
self.Player:SetRenderMode(RENDERMODE_TRANSALPHA)
|
||||
self.Player:SetColor(Color(0,0,0,0))
|
||||
|
||||
-- Hull & View Offset
|
||||
GAMEMODE:PlayerHullFromEntity(self.Player, nil)
|
||||
GAMEMODE:PlayerSetViewOffset(self.Player, Vector(0,0,72), Vector(0,0,72))
|
||||
|
||||
-- Collision Group
|
||||
self.Player:SetCollisionGroup(COLLISION_GROUP_PLAYER)
|
||||
|
||||
-- Prop Stuff
|
||||
self.Player.Data.Prop = ents.Create("ph_prop")
|
||||
self.Player.Data.Prop:SetOwner(self.Player)
|
||||
self.Player.Data.Prop:Spawn()
|
||||
self.Player:DeleteOnRemove(self.Player.Data.Prop)
|
||||
|
||||
-- Assign Hands (Auto Networked Sync!)
|
||||
local oldhands = self.Player:GetHands()
|
||||
if (IsValid(oldhands)) then oldhands:Remove() end
|
||||
self.Player:SetHands(self.Player.Data.Prop)
|
||||
end
|
||||
|
||||
-- Death
|
||||
function CLASS:PostDeath(attacker, dmginfo)
|
||||
print("Prop Hunt: Hider '"..self.Player:GetName().."' (SteamID: "..self.Player:SteamID()..") died.")
|
||||
BaseClass.PostDeath(self, inflictor, attacker)
|
||||
|
||||
-- Delete Hands Model
|
||||
self.Player:GetHands():Remove()
|
||||
|
||||
-- Collision Group
|
||||
self.Player:SetCollisionGroup(COLLISION_GROUP_PLAYER)
|
||||
|
||||
-- Hull
|
||||
GAMEMODE:PlayerHullFromEntity(self.Player, nil)
|
||||
|
||||
-- Rendering
|
||||
self.Player:SetRenderMode(RENDERMODE_NORMAL)
|
||||
self.Player:SetColor(Color(255,255,255,255))
|
||||
end
|
||||
|
||||
function CLASS:CanSuicide()
|
||||
return true
|
||||
end
|
||||
|
||||
function CLASS:DeathThink()
|
||||
if 1 > (CurTime() - self.Player.Data.AliveTime) then
|
||||
return false
|
||||
end
|
||||
|
||||
self.Player:Spawn()
|
||||
return true
|
||||
end
|
||||
|
||||
-- Visible Stuff
|
||||
function CLASS:SetModel() self.Player:SetModel("models/Gibs/Antlion_gib_small_3.mdl") end -- does "" even work?
|
||||
|
||||
-- Interaction
|
||||
function CLASS:Use(ent)
|
||||
if (!(BaseClass.Use(self, ent))) then
|
||||
return false
|
||||
end
|
||||
|
||||
-- Allow interacting while crouched instead of turning into the prop.
|
||||
if (self.Player:Crouching()) then
|
||||
return true
|
||||
end
|
||||
|
||||
-- Check Lists and other Parameters
|
||||
if (!table.HasValue(GAMEMODE.Config.Lists:ClassWhitelist(), ent:GetClass()))-- Class is not Whitelisted
|
||||
|| (GAMEMODE.Config.Lists.ModelBlacklist[ent:GetModel()]) -- Model is Blacklisted
|
||||
|| !((ent:GetPhysicsObject()) && (ent:GetPhysicsObject():IsValid())) -- Entity doesn't have Physics
|
||||
then
|
||||
print("Prop Hunt: Hider '"..self.Player:GetName().."' (SteamID: "..self.Player:SteamID()..") attempted to turn into "..ent:GetClass().." ("..ent:GetModel()..").")
|
||||
return true -- Use instead of erroring.
|
||||
end
|
||||
|
||||
-- Turn into the prop
|
||||
local eProp = self.Player:GetHands()
|
||||
util.PrecacheModel(ent:GetModel())
|
||||
eProp:SetModel(ent:GetModel())
|
||||
eProp:SetSkin(ent:GetSkin())
|
||||
eProp:SetHealth(100)
|
||||
eProp:SetMaxHealth(100)
|
||||
eProp:SetRenderMode(RENDERMODE_TRANSALPHA)
|
||||
|
||||
-- Hull (Optimize into single function? Code is repeated often)
|
||||
local hull = GAMEMODE:PlayerHullFromEntity(self.Player, ent)
|
||||
|
||||
-- View Offset
|
||||
local vo = Vector(0, 0, hull[2].z)
|
||||
GAMEMODE:PlayerSetViewOffset(self.Player, vo, vo)
|
||||
|
||||
-- Health Scaling
|
||||
if (GAMEMODE.Config.Hider:HealthScaling()) then
|
||||
local prc = math.Clamp(self.Player:Health() / self.Player:GetMaxHealth(), 0, 1)
|
||||
local maxhealth = math.Clamp(ent:GetPhysicsObject():GetVolume() / 250, 1, GAMEMODE.Config.Hider:HealthScalingMax())
|
||||
local health = math.Clamp(maxhealth * prc, 1, maxhealth)
|
||||
|
||||
-- Set Health
|
||||
self.Player:SetHealth(health)
|
||||
self.Player:SetMaxHealth(maxhealth)
|
||||
end
|
||||
|
||||
print("Prop Hunt: Hider '"..self.Player:GetName().."' (SteamID: "..self.Player:SteamID()..") turned into "..ent:GetClass().." ("..ent:GetModel()..").")
|
||||
end
|
||||
|
||||
function CLASS:AllowPickup(ent) return true end
|
||||
|
||||
-- ------------------------------------------------------------------------- --
|
||||
--! Shared
|
||||
-- ------------------------------------------------------------------------- --
|
||||
|
||||
-- ------------------------------------------------------------------------- --
|
||||
--! Client-Side
|
||||
-- ------------------------------------------------------------------------- --
|
||||
function CLASS:ClientSpawn()
|
||||
print("Prop Hunt CL: Hider '"..self.Player:GetName().."' (SteamID: "..self.Player:SteamID()..") spawned.")
|
||||
BaseClass.ClientSpawn(self, self.Player)
|
||||
|
||||
self.Player:SetRenderMode(RENDERMODE_TRANSALPHA)
|
||||
end
|
||||
|
||||
function CLASS:ShouldDrawLocal()
|
||||
return false
|
||||
end
|
||||
|
||||
function CLASS:CalcView(camdata)
|
||||
-- ThirdPerson Settings (ToDo: client config maybe?)
|
||||
local maxViewDist = 100
|
||||
local viewDist = self.Player.Data.ViewDistance or 0
|
||||
|
||||
-- First/Third
|
||||
if (self.Player.Data.ThirdPerson) then
|
||||
if (IsValid(self.Player:GetHands())) then
|
||||
self.Player:GetHands():SetRenderMode(RENDERMODE_TRANSALPHA)
|
||||
self.Player:GetHands():SetColor(Color(255, 255, 255, 127))
|
||||
end
|
||||
|
||||
-- Incremental Distance instead of instant.
|
||||
viewDist = math.Clamp(viewDist * 0.9 + maxViewDist * 0.1, 0, maxViewDist) -- Zoom Out
|
||||
else
|
||||
if (IsValid(self.Player:GetHands())) then
|
||||
self.Player:GetHands():SetRenderMode(RENDERMODE_TRANSALPHA)
|
||||
self.Player:GetHands():SetColor(Color(255, 255, 255, 0))
|
||||
end
|
||||
|
||||
viewDist = math.Clamp(viewDist * 0.9, 0, maxViewDist) -- Zoom In
|
||||
end
|
||||
|
||||
-- Trace from Player to would-be camera position
|
||||
local trace = {
|
||||
start = camdata.origin,
|
||||
endpos = camdata.origin - (camdata.angles:Forward() * viewDist),
|
||||
--filter = { "worldspawn", "ph_prop" },
|
||||
filter = function(ent)
|
||||
local filter = { "worldspawn", "ph_prop" }
|
||||
|
||||
if (ent:IsPlayer())
|
||||
|| (table.HasValue(filter, ent:GetClass()))
|
||||
|| (ent == LocalPlayer()) || (ent == LocalPlayer():GetHands()) then
|
||||
return false
|
||||
end
|
||||
return true
|
||||
end
|
||||
}
|
||||
local result = util.TraceLine(trace)
|
||||
|
||||
-- The Camera has a Sphere radius of 10.
|
||||
if (result.Hit) then -- Configurable?
|
||||
viewDist = math.Clamp(result.HitPos:Distance(camdata.origin), 0, maxViewDist)
|
||||
end
|
||||
|
||||
-- Store ViewDistance
|
||||
self.Player.Data.ViewDistance = viewDist
|
||||
|
||||
-- Adjust CamData
|
||||
camdata.origin = camdata.origin - (camdata.angles:Forward() * math.Clamp(viewDist - 10, 0, maxViewDist))
|
||||
camdata.drawviewer = false
|
||||
|
||||
-- Return
|
||||
return camdata
|
||||
end
|
||||
|
||||
-- Register
|
||||
player_manager.RegisterClass("Hider", CLASS, "Default")
|
||||
@@ -0,0 +1,235 @@
|
||||
--[[
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Xaymar
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
--]]
|
||||
|
||||
--! This file defines the Seeker player class.
|
||||
-- A seeker is someone who is looking for the hiders, using weapons or other
|
||||
-- means of detecting idiots. Also someone who looks like a diaper baby.
|
||||
-- Weapons and Ammo are granted upon spawn and have to be used sparingly or
|
||||
-- they'll be stuck with the crowbar. Bad seeker, bad.
|
||||
-- Gain health upon killing a hider, lose health when attacking non-hiders.
|
||||
-- Death upon health reaching 0.
|
||||
|
||||
DEFINE_BASECLASS( "Default" )
|
||||
local CLASS = {}
|
||||
CLASS.DisplayName = "Seeker"
|
||||
CLASS.CanUseFlashlight = true -- Can we use the flashlight
|
||||
CLASS.MaxHealth = 100
|
||||
CLASS.StartHealth = 100
|
||||
CLASS.StartArmor = 0
|
||||
CLASS.DropWeaponOnDie = true
|
||||
|
||||
-- ------------------------------------------------------------------------- --
|
||||
--! Server-Side
|
||||
-- ------------------------------------------------------------------------- --
|
||||
-- Spawn
|
||||
function CLASS:Spawn()
|
||||
print("Prop Hunt: Seeker '"..self.Player:GetName().."' (SteamID: "..self.Player:SteamID()..") spawned.")
|
||||
BaseClass.Spawn(self)
|
||||
|
||||
-- Sprinting
|
||||
if (GAMEMODE.Config:Sprinting()) then
|
||||
self.Player:SetRunSpeed(self.WalkSpeed)
|
||||
end
|
||||
|
||||
-- Settings
|
||||
self.Player:SetMaxHealth(GAMEMODE.Config.Seeker:HealthMax())
|
||||
self.Player:SetHealth(GAMEMODE.Config.Seeker:Health())
|
||||
self.Player:SetRenderMode(RENDERMODE_NORMAL)
|
||||
self.Player:SetColor(Color(255,255,255,255))
|
||||
|
||||
-- Hull & View Offset
|
||||
GAMEMODE:PlayerHullFromEntity(self.Player, nil)
|
||||
GAMEMODE:PlayerSetViewOffset(self.Player, Vector(0,0,64), Vector(0,0,32))
|
||||
end
|
||||
|
||||
function CLASS:Loadout()
|
||||
-- Give the weapons the admin told us to.
|
||||
local weapons = GAMEMODE.Config.Seeker:Weapons()
|
||||
for i,weapon in ipairs(weapons) do
|
||||
self.Player:Give(weapon)
|
||||
end
|
||||
|
||||
-- Give the ammo the admin told us to.
|
||||
local ammos = GAMEMODE.Config.Seeker:Ammo()
|
||||
for i,ammo in ipairs(ammos) do
|
||||
local typeCount = string.Split(ammo, ":")
|
||||
self.Player:GiveAmmo(tonumber(typeCount[2]), typeCount[1], true)
|
||||
end
|
||||
|
||||
-- Default weapon stuff
|
||||
local cl_defaultweapon = self.Player:GetInfo("cl_defaultweapon")
|
||||
if self.Player:HasWeapon(cl_defaultweapon) then
|
||||
self.Player:SelectWeapon(cl_defaultweapon)
|
||||
end
|
||||
end
|
||||
|
||||
-- Damage
|
||||
function CLASS:Damage(victim, attacker, healthRemaining, damageDealt) end
|
||||
function CLASS:DamageEntity(ent, att, dmg)
|
||||
print("Prop Hunt: Seeker '"..self.Player:GetName().."' (SteamID: "..self.Player:SteamID()..") damaged entity "..ent:GetClass()..".")
|
||||
|
||||
-- Only take damage during this phase.
|
||||
if (GAMEMODE:GetRoundState() == GAMEMODE.States.Seek) then
|
||||
if IsValid(ent) && (!(ent:IsPlayer())) then
|
||||
if (ent:GetClass() == "ph_prop") then
|
||||
ent:GetOwner():TakeDamageInfo(dmg)
|
||||
elseif (ent:GetClass() == "func_breakable") then -- ToDo: Make Configurable which entities don't hurt
|
||||
else
|
||||
att:TakeDamage(GAMEMODE.Config.Seeker:HealthPenalty(), ent, ent)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Death
|
||||
function CLASS:Death(inflictor, attacker)
|
||||
BaseClass.Death(self, inflictor, attacker)
|
||||
|
||||
self.Player:CreateRagdoll()
|
||||
end
|
||||
|
||||
function CLASS:PostDeath()
|
||||
print("Prop Hunt: Seeker '"..self.Player:GetName().."' (SteamID: "..self.Player:SteamID()..") died.")
|
||||
BaseClass.PostDeath(self, inflictor, attacker)
|
||||
|
||||
self.Player:UnLock()
|
||||
end
|
||||
|
||||
function CLASS:CanSuicide()
|
||||
return true
|
||||
end
|
||||
|
||||
function CLASS:DeathThink()
|
||||
if (CurTime() - self.Player.Data.AliveTime) > 1 then
|
||||
self.Player:Spawn()
|
||||
return true
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
-- Visible Stuff
|
||||
function CLASS:SetModel()
|
||||
local cl_playermodel = self.Player:GetInfo( "cl_playermodel" )
|
||||
local modelname = player_manager.TranslatePlayerModel( cl_playermodel )
|
||||
if !(util.IsValidModel(modelname)) then
|
||||
modelname = "models/player/combine_super_soldier.mdl"
|
||||
end
|
||||
util.PrecacheModel(modelname)
|
||||
self.Player:SetModel(modelname)
|
||||
|
||||
-- Hands
|
||||
self.Player:SetupHands()
|
||||
end
|
||||
|
||||
-- Interaction
|
||||
function CLASS:AllowPickup(ent) return true end
|
||||
function CLASS:CanPickupItem(ent) return true end
|
||||
function CLASS:CanPickupWeapon(ent) return true end
|
||||
|
||||
-- ------------------------------------------------------------------------- --
|
||||
--! Client-Side
|
||||
-- ------------------------------------------------------------------------- --
|
||||
function CLASS:ClientSpawn()
|
||||
print("Prop Hunt CL: Seeker '"..self.Player:GetName().."' (SteamID: "..self.Player:SteamID()..") spawned.")
|
||||
BaseClass.ClientSpawn(self)
|
||||
end
|
||||
|
||||
function CLASS:HUDPaint()
|
||||
local State = GetGlobalInt("RoundState", GAMEMODE.States.PreMatch)
|
||||
if (State == GAMEMODE.States.Hide) then
|
||||
local intTime = math.ceil(GetGlobalInt("RoundTime"))
|
||||
local strTime = tostring(intTime)
|
||||
|
||||
-- Seekers are blinded in this Phase.
|
||||
draw.RoundedBox(0, 0, 0, surface.ScreenWidth(), surface.ScreenHeight(), Color(0, 0, 0, 255))
|
||||
|
||||
-- Show Status at the center
|
||||
surface.SetTextColor( 255, 255, 255, 255 )
|
||||
if (intTime >= 1) then
|
||||
surface.SetFont("CloseCaption_Bold")
|
||||
local w,h = surface.GetTextSize("Unblinded in "..strTime.." seconds...")
|
||||
surface.SetTextPos( ScrW()/2 - w / 2, ScrH()/2 - h / 2)
|
||||
surface.DrawText("Unblinded in "..strTime.." seconds...")
|
||||
else
|
||||
surface.SetFont("PHHugeAssFont")
|
||||
local w,h = surface.GetTextSize("NOW")
|
||||
surface.SetTextPos( ScrW()/2 - w / 2, ScrH()/2 - h / 2)
|
||||
surface.DrawText("NOW")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function CLASS:ShouldDrawLocal()
|
||||
return self.Player.Data.ThirdPerson
|
||||
end
|
||||
|
||||
function CLASS:CalcView(camdata)
|
||||
-- ThirdPerson Settings (ToDo: client config maybe?)
|
||||
local maxViewDist = 100
|
||||
local viewDist = self.Player.Data.ViewDistance or 0
|
||||
|
||||
-- First/Third
|
||||
if (self.Player.Data.ThirdPerson) then
|
||||
viewDist = math.Clamp(viewDist * 0.9 + maxViewDist * 0.1, 0, maxViewDist) -- Zoom Out
|
||||
else
|
||||
viewDist = math.Clamp(viewDist * 0.9, 0, maxViewDist) -- Zoom In
|
||||
end
|
||||
|
||||
-- Trace from Player to would-be camera position
|
||||
local trace = {
|
||||
start = camdata.origin,
|
||||
endpos = camdata.origin - (camdata.angles:Forward() * viewDist),
|
||||
--filter = { "worldspawn", "ph_prop" },
|
||||
filter = function(ent)
|
||||
local filter = { "worldspawn", "ph_prop" }
|
||||
|
||||
if (ent:IsPlayer())
|
||||
|| (table.HasValue(filter, ent:GetClass()))
|
||||
|| (ent == LocalPlayer()) || (ent == LocalPlayer():GetHands()) then
|
||||
return false
|
||||
end
|
||||
return true
|
||||
end
|
||||
}
|
||||
local result = util.TraceLine(trace)
|
||||
|
||||
-- The Camera has a Sphere radius of 10.
|
||||
if (result.Hit) then -- Configurable?
|
||||
viewDist = math.Clamp(result.HitPos:Distance(camdata.origin), 0, maxViewDist)
|
||||
end
|
||||
|
||||
-- Store ViewDistance
|
||||
self.Player.Data.ViewDistance = viewDist
|
||||
|
||||
-- Adjust CamData
|
||||
camdata.origin = camdata.origin - (camdata.angles:Forward() * math.Clamp(viewDist - 10, 0, maxViewDist))
|
||||
--camdata.drawviewer = false
|
||||
|
||||
-- Return
|
||||
return camdata
|
||||
end
|
||||
|
||||
-- Register
|
||||
player_manager.RegisterClass("Seeker", CLASS, "Default")
|
||||
@@ -0,0 +1,85 @@
|
||||
--[[
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Xaymar
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
--]]
|
||||
|
||||
DEFINE_BASECLASS("Default")
|
||||
local CLASS = {}
|
||||
CLASS.DisplayName = "Spectator"
|
||||
CLASS.DuckSpeed = 0.0 -- How fast to go from not ducking, to ducking
|
||||
CLASS.UnDuckSpeed = 0.0 -- How fast to go from ducking, to not ducking
|
||||
CLASS.CanUseFlashlight = false -- Can we use the flashlight
|
||||
CLASS.UseVMHands = false -- Uses viewmodel hands
|
||||
|
||||
-- ------------------------------------------------------------------------- --
|
||||
--! Server-Side
|
||||
-- ------------------------------------------------------------------------- --
|
||||
-- Spawn
|
||||
function CLASS:Spawn()
|
||||
print("Prop Hunt: Spectator '"..self.Player:GetName().."' (SteamID: "..self.Player:SteamID()..") spawned.")
|
||||
BaseClass.Spawn(self)
|
||||
|
||||
self.Player:Spectate(OBS_MODE_ROAMING)
|
||||
self.Player:SetRenderMode(RENDERMODE_NONE)
|
||||
|
||||
-- View Offset & Hull
|
||||
GAMEMODE:PlayerSetViewOffset(self.Player, Vector(0,0,0), Vector(0,0,0))
|
||||
GAMEMODE:PlayerHullFromEntity(self.Player, nil)
|
||||
end
|
||||
|
||||
-- Death
|
||||
function CLASS:PostDeath(inflictor, attacker)
|
||||
print("Prop Hunt: Spectator '"..self.Player:GetName().."' (SteamID: "..self.Player:SteamID()..") died.")
|
||||
BaseClass.PostDeath(self, inflictor, attacker)
|
||||
|
||||
self.Player:Spectate(OBS_MODE_NONE)
|
||||
self.Player:UnSpectate()
|
||||
|
||||
-- Hull
|
||||
GAMEMODE:PlayerHullFromEntity(self.Player, nil)
|
||||
|
||||
self.Player:SetRenderMode(RENDERMODE_NORMAL)
|
||||
end
|
||||
|
||||
-- Visible Stuff
|
||||
function CLASS:SetModel()
|
||||
self.Player:SetModel("")
|
||||
|
||||
-- Hands
|
||||
self.Player:SetupHands()
|
||||
end
|
||||
|
||||
-- Interaction
|
||||
function CLASS:Use(ent) return false end
|
||||
function CLASS:AllowPickup(ent) return false end
|
||||
function CLASS:CanPickupWeapon(ent) return false end
|
||||
function CLASS:CanPickupItem(ent) return false end
|
||||
-- ------------------------------------------------------------------------- --
|
||||
--! Client-Side
|
||||
-- ------------------------------------------------------------------------- --
|
||||
function CLASS:ClientSpawn()
|
||||
print("Prop Hunt CL: Spectator '"..self.Player:GetName().."' (SteamID: "..self.Player:SteamID()..") spawned.")
|
||||
end
|
||||
|
||||
function CLASS:ShouldDrawLocal() return false end
|
||||
|
||||
player_manager.RegisterClass( "Spectator", CLASS, "Default")
|
||||
@@ -0,0 +1,549 @@
|
||||
--[[
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Xaymar
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
--]]
|
||||
|
||||
--! Initialize configuration table.
|
||||
GM.Config = { }
|
||||
GM.Config.ConVars = {}
|
||||
|
||||
-- ------------------------------------------------------------------------- --
|
||||
--! Basic Settings
|
||||
-- ------------------------------------------------------------------------- --
|
||||
-- Debug Mode
|
||||
GM.Config.ConVars.Debug = CreateConVar("ph_debug", 0, FCVAR_CHEAT + FCVAR_REPLICATED)
|
||||
function GM.Config:Debug()
|
||||
return self.ConVars.Debug:GetBool()
|
||||
end
|
||||
|
||||
-- Game Mode (See sh_init.lua)
|
||||
GM.Config.ConVars.GameMode = CreateConVar("ph_gamemode", GM.Modes.Original, FCVAR_REPLICATED)
|
||||
function GM.Config:GameMode()
|
||||
return self.ConVars.GameMode:GetInt()
|
||||
end
|
||||
|
||||
-- Timelimit in minutes
|
||||
GM.Config.ConVars.TimeLimit = GetConVar("mp_timelimit")
|
||||
function GM.Config:TimeLimit()
|
||||
return self.ConVars.TimeLimit:GetFloat()
|
||||
end
|
||||
|
||||
-- Enable Sprinting?
|
||||
GM.Config.ConVars.Sprinting = CreateConVar("ph_sprinting", 0, FCVAR_REPLICATED)
|
||||
function GM.Config:Sprinting()
|
||||
return self.ConVars.Sprinting:GetBool()
|
||||
end
|
||||
|
||||
-- Taunt Cooldown (Seconds)
|
||||
GM.Config.ConVars.TauntCoolDown = CreateConVar("ph_tauntcooldown", 5, FCVAR_REPLICATED)
|
||||
function GM.Config:TauntCoolDown()
|
||||
return self.ConVars.TauntCoolDown:GetFloat()
|
||||
end
|
||||
|
||||
-- ------------------------------------------------------------------------- --
|
||||
--! Round Settings
|
||||
-- ------------------------------------------------------------------------- --
|
||||
GM.Config.Round = {}
|
||||
GM.Config.Round.ConVars = {}
|
||||
|
||||
-- How many rounds should the gamemode attempt to fit into the map timelimit, if there is any?
|
||||
GM.Config.Round.ConVars.Amount = CreateConVar("ph_round_limit", 10, FCVAR_REPLICATED)
|
||||
function GM.Config.Round:Amount()
|
||||
return self.ConVars.Amount:GetInt()
|
||||
end
|
||||
|
||||
-- Round Time Limit (Seconds, Default 3 minutes)
|
||||
GM.Config.Round.ConVars.Time = CreateConVar("ph_round_timelimit", 180, FCVAR_REPLICATED)
|
||||
function GM.Config.Round:Time()
|
||||
return self.ConVars.Time:GetInt() - GAMEMODE.Config.Round:BlindTime()
|
||||
end
|
||||
|
||||
-- For how many seconds are the Seekers blinded? (Seconds)
|
||||
GM.Config.Round.ConVars.BlindTime = CreateConVar("ph_round_blindtime", 30, FCVAR_REPLICATED, "How long are hunters blinded? (positive values will be inside the round time limit, negative will add to the round time limit)")
|
||||
function GM.Config.Round:BlindTime()
|
||||
return self.ConVars.BlindTime:GetInt()
|
||||
end
|
||||
|
||||
-- ------------------------------------------------------------------------- --
|
||||
--! Seeker Settings
|
||||
-- ------------------------------------------------------------------------- --
|
||||
GM.Config.Seeker = {}
|
||||
GM.Config.Seeker.ConVars = {}
|
||||
|
||||
GM.Config.Seeker.ConVars.Health = CreateConVar("ph_seeker_health", 100, FCVAR_REPLICATED)
|
||||
function GM.Config.Seeker:Health()
|
||||
return self.ConVars.Health:GetInt()
|
||||
end
|
||||
|
||||
GM.Config.Seeker.ConVars.HealthMax = CreateConVar("ph_seeker_health_max", 100, FCVAR_REPLICATED)
|
||||
function GM.Config.Seeker:HealthMax()
|
||||
return self.ConVars.HealthMax:GetInt()
|
||||
end
|
||||
|
||||
GM.Config.Seeker.ConVars.HealthBonus = CreateConVar("ph_seeker_health_bonus", 20, FCVAR_REPLICATED)
|
||||
function GM.Config.Seeker:HealthBonus()
|
||||
return self.ConVars.HealthBonus:GetInt()
|
||||
end
|
||||
|
||||
GM.Config.Seeker.ConVars.HealthPenalty = CreateConVar("ph_seeker_health_penalty", 5, FCVAR_REPLICATED)
|
||||
function GM.Config.Seeker:HealthPenalty()
|
||||
return self.ConVars.HealthPenalty:GetInt()
|
||||
end
|
||||
|
||||
GM.Config.Seeker.ConVars.Weapons = CreateConVar("ph_seeker_weapons", "weapon_crowbar,weapon_pistol,weapon_ph_smg,weapon_shotgun", FCVAR_REPLICATED)
|
||||
function GM.Config.Seeker:Weapons()
|
||||
return string.Split(self.ConVars.Weapons:GetString(), ",")
|
||||
end
|
||||
|
||||
GM.Config.Seeker.ConVars.Ammo = CreateConVar("ph_seeker_ammo", "Pistol:100,SMG1:300,SMG1_Grenade:1,Buckshot:64", FCVAR_REPLICATED)
|
||||
function GM.Config.Seeker:Ammo()
|
||||
return string.Split(self.ConVars.Ammo:GetString(), ",")
|
||||
end
|
||||
|
||||
-- ------------------------------------------------------------------------- --
|
||||
--! Hider Settings
|
||||
-- ------------------------------------------------------------------------- --
|
||||
GM.Config.Hider = {}
|
||||
GM.Config.Hider.ConVars = {}
|
||||
|
||||
GM.Config.Hider.ConVars.Health = CreateConVar("ph_hider_health", 100, FCVAR_REPLICATED)
|
||||
function GM.Config.Hider:Health()
|
||||
return self.ConVars.Health:GetInt()
|
||||
end
|
||||
|
||||
GM.Config.Hider.ConVars.HealthMax = CreateConVar("ph_hider_health_max", 100, FCVAR_REPLICATED)
|
||||
function GM.Config.Hider:HealthMax()
|
||||
return self.ConVars.HealthMax:GetInt()
|
||||
end
|
||||
|
||||
GM.Config.Hider.ConVars.HealthScaling = CreateConVar("ph_hider_health_scaling", 100, FCVAR_REPLICATED)
|
||||
function GM.Config.Hider:HealthScaling()
|
||||
return self.ConVars.HealthScaling:GetBool()
|
||||
end
|
||||
|
||||
GM.Config.Hider.ConVars.HealthScalingMax = CreateConVar("ph_hider_health_scaling_max", 200, FCVAR_REPLICATED)
|
||||
function GM.Config.Hider:HealthScalingMax()
|
||||
return self.ConVars.HealthScalingMax:GetInt()
|
||||
end
|
||||
|
||||
-- ------------------------------------------------------------------------- --
|
||||
--! Whitelist & Blacklist
|
||||
-- ------------------------------------------------------------------------- --
|
||||
GM.Config.Lists = {}
|
||||
GM.Config.Lists.ConVars = {}
|
||||
GM.Config.Lists.ConCmds = {}
|
||||
|
||||
GM.Config.Lists.ConVars.ClassWhitelist = CreateConVar("ph_list_class_whitelist", "prop_physics,prop_physics_multiplayer,prop_physics_respawnable", FCVAR_REPLICATED)
|
||||
function GM.Config.Lists:ClassWhitelist()
|
||||
return string.Split(self.ConVars.ClassWhitelist:GetString(), ",")
|
||||
end
|
||||
|
||||
-- Use Abuse Blacklist
|
||||
GM.Config.Lists.ConVars.AbuseBlacklist = CreateConVar("ph_list_abuse_blacklist", "func_button,func_door,func_door_rotation,prop_door_rotation,func_tracktrain,func_tanktrain,func_breakable", FCVAR_REPLICATED)
|
||||
function GM.Config.Lists:AbuseBlacklist()
|
||||
return string.Split(self.ConVars.AbuseBlacklist:GetString(), ",")
|
||||
end
|
||||
|
||||
-- Model Blacklist
|
||||
GM.Config.Lists.ModelBlacklist = {}
|
||||
GM.Config.Lists.ModelBlacklist["models/props/cs_assault/dollar.mdl"] = true
|
||||
GM.Config.Lists.ModelBlacklist["models/props/cs_assault/money.mdl"] = true
|
||||
GM.Config.Lists.ModelBlacklist["models/props/cs_office/snowman_arm.mdl"] = true
|
||||
GM.Config.Lists.ModelBlacklist["models/props_junk/garbage_plasticbottle001a.mdl"] = true
|
||||
GM.Config.Lists.ModelBlacklist["models/props/cs_office/projector_remote.mdl"] = true
|
||||
|
||||
GM.Config.Lists.ConCmds.ModelBlacklistList = concommand.Add("ph_list_model_blacklist_list", function(ply, cmd, args, argStr)
|
||||
print("Model Blacklist:")
|
||||
for k,v in pairs(GAMEMODE.Config.Lists.ModelBlacklist) do
|
||||
print(" "..k)
|
||||
end
|
||||
end, "List all blacklisted models.")
|
||||
|
||||
GM.Config.Lists.ConCmds.ModelBlacklistClear = concommand.Add("ph_list_model_blacklist_list", function(ply, cmd, args, argStr)
|
||||
GM.Config.Lists.ModelBlacklist = {}
|
||||
end, "Clear blacklisted models.")
|
||||
|
||||
GM.Config.Lists.ConCmds.ModelBlacklistAdd = concommand.Add("ph_list_model_blacklist_add", function(ply, cmd, args, argStr)
|
||||
if (table.count(args) > 0) then
|
||||
GAMEMODE.Config.Lists.ModelBlacklist[args[1]] = true
|
||||
else
|
||||
print("Missing model name")
|
||||
end
|
||||
end, "Add a new blacklisted model.")
|
||||
|
||||
GM.Config.Lists.ConCmds.ModelBlacklistRemove = concommand.Add("ph_list_model_blacklist_remove", function(ply, cmd, args, argStr)
|
||||
if (table.count(args) > 0) then
|
||||
GAMEMODE.Config.Lists.ModelBlacklist[args[1]] = nil
|
||||
else
|
||||
print("Missing model name")
|
||||
end
|
||||
end, "Removes a blacklisted model.")
|
||||
|
||||
-- ------------------------------------------------------------------------- --
|
||||
--! Taunts
|
||||
-- ------------------------------------------------------------------------- --
|
||||
-- GM.Config.Taunts = {
|
||||
-- Seeker = { },
|
||||
-- Hider = { },
|
||||
-- }
|
||||
|
||||
-- -- Taunts.Clear()
|
||||
-- --@desc: Clears the current taunt list.
|
||||
-- GM.Config.Taunts.Clear = function()
|
||||
-- this.Seeker = {}
|
||||
-- this.Hider = {}
|
||||
-- end
|
||||
|
||||
-- -- Taunts.Load(sTauntListFile)
|
||||
-- --@desc: Loads the taunt list from disk.
|
||||
-- --@param:
|
||||
-- -- sTauntListFile - A string containing the path to the taunt list to load.
|
||||
-- --@return: true or false depending on success.
|
||||
-- GM.Config.Taunts.Load = function(sTauntListFile)
|
||||
-- if GAMEMODE.Config:Debug() then print("Prop Hunt.Taunts.Load: Loading taunt list from file '"..sTauntListFile.."'...") end
|
||||
|
||||
-- -- Safeguard against idiots.
|
||||
-- if type(sTauntListFile) != "string" then
|
||||
-- if GAMEMODE.Config:Debug() then print("Prop Hunt.Taunts.Load: <sTauntListFile> is not a string.") end
|
||||
-- return false
|
||||
-- end
|
||||
|
||||
-- -- Given file must exist for us to continue.
|
||||
-- if ! file.Exists(sTauntListFile, "GAME") then
|
||||
-- if GAMEMODE.Config:Debug() then print("Prop Hunt.Taunts.Load: File not found.") end
|
||||
-- return false
|
||||
-- end
|
||||
|
||||
-- -- Read the file and check if it's empty.
|
||||
-- sTauntListData = file.Read(sTauntListFile, "GAME")
|
||||
-- if sTauntListData == "" then
|
||||
-- if GAMEMODE.Config:Debug() then print("Prop Hunt.Taunts.Load: File is empty.") end
|
||||
-- return false
|
||||
-- end
|
||||
|
||||
-- -- Convert JSON to a table for us to use.
|
||||
-- sTauntList = util.JSONToTable(sTauntListData)
|
||||
|
||||
-- -- Is it nil? Then it's not valid JSON
|
||||
-- if sTauntList == nil then
|
||||
-- if GAMEMODE.Config:Debug() then print("Prop Hunt.Taunts.Load: File contains invalid JSON.") end
|
||||
-- return false
|
||||
-- end
|
||||
|
||||
-- -- Finally, append the taunt lists.
|
||||
-- if sTauntList.Seeker != nil then
|
||||
-- if GAMEMODE.Config:Debug() then print("Prop Hunt.Taunts.Load: Adding Seeker taunts...") end
|
||||
-- for k,v in pairs(sTauntList.Seeker) do
|
||||
-- GAMEMODE.Taunts.Seeker[k] = v
|
||||
-- end
|
||||
-- end
|
||||
-- if sTauntList.Hider != nil then
|
||||
-- if GAMEMODE.Config:Debug() then print("Prop Hunt.Taunts.Load: Adding Hider taunts...") end
|
||||
-- for k,v in pairs(sTauntList.Hider) do
|
||||
-- GAMEMODE.Taunts.Hider[k] = v
|
||||
-- end
|
||||
-- end
|
||||
|
||||
-- if GAMEMODE.Config:Debug() then print("Prop Hunt.Taunts.Load: Complete.") end
|
||||
-- return true
|
||||
-- end
|
||||
|
||||
-- -- Taunts.Save(sTauntListFile)
|
||||
-- --@desc: Saves the current taunt list to disk.
|
||||
-- --@param:
|
||||
-- -- sTauntListFile - A string containing the path to the file to save to.
|
||||
-- --@return: true or false depending on success.
|
||||
-- GM.Config.Taunts.Save = function(sTauntListFile)
|
||||
-- if GAMEMODE.Config:Debug() then print("Prop Hunt.Taunts.Save: Saving taunt list to file '"..sTauntListFile.."'...") end
|
||||
|
||||
-- -- Safeguard against idiots.
|
||||
-- if type(sTauntListFile) != "string" then
|
||||
-- if GAMEMODE.Config:Debug() then print("Prop Hunt.Taunts.Save: <sTauntListFile> is not a string.") end
|
||||
-- return false
|
||||
-- end
|
||||
|
||||
-- -- File must not be nil, otherwise we can't write to it.
|
||||
-- if sTauntListFile == nil then
|
||||
-- if GAMEMODE.Config:Debug() then print("Prop Hunt.Taunts.Save: No file given.") end
|
||||
-- return false
|
||||
-- end
|
||||
|
||||
-- -- Convert our taunt table to JSON.
|
||||
-- sTauntListData = util.TableToJSON(GAMEMODE.Taunts);
|
||||
-- if sTauntListData == nil then
|
||||
-- if GAMEMODE.Config:Debug() then print("Prop Hunt.Taunts.Save: Corrupted GAMEMODE table.") end
|
||||
-- return false
|
||||
-- end
|
||||
|
||||
-- -- Write out JSON out to file
|
||||
-- if ! file.Write(sTauntListFile, sTauntListData) then
|
||||
-- if GAMEMODE.Config:Debug() then print("Prop Hunt.Taunts.Save: Failed to write to file.") end
|
||||
-- return false
|
||||
-- end
|
||||
|
||||
-- if GAMEMODE.Config:Debug() then print("Prop Hunt.Taunts.Save: Complete.") end
|
||||
-- return true
|
||||
-- end
|
||||
|
||||
-- -- Taunts.Add(sTauntName, sSoundFile, iTeamID, mPropFilter)
|
||||
-- --@desc: Registers a new taunt with the given name, file, team and filter.
|
||||
-- --@param:
|
||||
-- -- sTauntName - The unique name of the taunt.
|
||||
-- -- sSoundFile - A sound file to play when this taunt is selected.
|
||||
-- -- iTeamID - The team that should receive the taunt or nil for all teams.
|
||||
-- -- mPropFilter - A string or a table containing strings for props that should be able to use this taunt.
|
||||
-- --@return: true or false depending on success.
|
||||
-- GM.Config.Taunts.Add = function(sTauntName, sSoundFile, iTeamID, mPropFilter)
|
||||
-- if GAMEMODE.Config:Debug() then print("Prop Hunt.Taunts.Add: Adding new taunt '"..sTauntName.."'...") end
|
||||
|
||||
-- -- Safeguard against idiots.
|
||||
-- if type(sTauntName) != "string" then
|
||||
-- if GAMEMODE.Config:Debug() then print("Prop Hunt.Taunts.Add: <sTauntName> is not a string.") end
|
||||
-- return false
|
||||
-- end
|
||||
-- if type(sSoundFile) != "string" then
|
||||
-- if GAMEMODE.Config:Debug() then print("Prop Hunt.Taunts.Add: <sSoundFile> is not a string.") end
|
||||
-- return false
|
||||
-- end
|
||||
-- if (type(iTeamID) != "number" && iTeamID != nil) then
|
||||
-- if GAMEMODE.Config:Debug() then print("Prop Hunt.Taunts.Add: <iTeamID> is not a number or nil.") end
|
||||
-- return false
|
||||
-- end
|
||||
-- if (type(mPropFilter) != "string" && type(mPropFilter) != "table" && mPropFilter != nil) then
|
||||
-- if GAMEMODE.Config:Debug() then print("Prop Hunt.Taunts.Add: <mPropFilter> is not a string, table or nil.") end
|
||||
-- return false
|
||||
-- end
|
||||
|
||||
-- -- Check if the sound file actually exists
|
||||
-- if !file.Exists("sound/"..sSoundFile, "GAME") then
|
||||
-- if GAMEMODE.Config:Debug() then print("Prop Hunt.Taunts.Add: File '"..sSoundFile.."' does not exist.") end
|
||||
-- return false
|
||||
-- end
|
||||
|
||||
-- -- Make sure that our prop filter is a table listing the props it's supposed to work for.
|
||||
-- if (mPropFilter == nil) then
|
||||
-- mPropFilter = { }
|
||||
-- elseif type(mPropFilter) == "string" then
|
||||
-- mPropFilter = { mPropFilter }
|
||||
-- end
|
||||
|
||||
-- -- Prepare Taunt table
|
||||
-- Taunt = {
|
||||
-- File = sSoundFile,
|
||||
-- Filter = mPropFilter
|
||||
-- }
|
||||
|
||||
-- -- If iTeamID is nil, both teams will receive the taunt.
|
||||
-- if iTeamID == nil then
|
||||
-- GAMEMODE.Taunts.Seeker[sTauntName] = Taunt
|
||||
-- GAMEMODE.Taunts.Hider[sTauntName] = Taunt
|
||||
-- else
|
||||
-- -- Make sure that the team is valid.
|
||||
-- if ! team.Valid(iTeamID) then
|
||||
-- if GAMEMODE.Config:Debug() then print("Prop Hunt.Taunts.Add: Team "..iTeamID.."' does not exist.") end
|
||||
-- return false
|
||||
-- end
|
||||
|
||||
-- if (iTeamID == TEAM_SEEKERS) then
|
||||
-- GAMEMODE.Taunts.Seeker[sTauntName] = Taunt
|
||||
-- elseif (iTeamID == TEAM_HIDERS) then
|
||||
-- GAMEMODE.Taunts.Hider[sTauntName] = Taunt
|
||||
-- else
|
||||
-- if GAMEMODE.Config:Debug() then print("Prop Hunt.Taunts.Add: Team "..iTeamID.."' can't have taunts.") end
|
||||
-- return false
|
||||
-- end
|
||||
-- end
|
||||
|
||||
-- if GAMEMODE.Config:Debug() then print("Prop Hunt.Taunts.Add: Complete.") end
|
||||
-- return true
|
||||
-- end
|
||||
|
||||
-- -- Taunts.Remove(sTauntName, iTeamID)
|
||||
-- --@desc: Removes a registered taunt with the given name and team.
|
||||
-- --@param:
|
||||
-- -- sTauntName - The unique name of the taunt.
|
||||
-- -- iTeamID - The team that the taunt should be removed from or nil for all teams.
|
||||
-- --@return: true or false depending on success.
|
||||
-- GM.Config.Taunts.Remove = function(sTauntName, iTeamID)
|
||||
-- if GAMEMODE.Config:Debug() then print("Prop Hunt.Taunts.Remove: Removing taunt '"..sTauntName.."'...") end
|
||||
|
||||
-- -- Safeguard against idiots.
|
||||
-- if type(sTauntName) != "string" then
|
||||
-- if GAMEMODE.Config:Debug() then print("Prop Hunt.Taunts.Remove: <sTauntName> is not a string.") end
|
||||
-- return false
|
||||
-- end
|
||||
-- if (type(iTeamID) != "number" && iTeamID != nil) then
|
||||
-- if GAMEMODE.Config:Debug() then print("Prop Hunt.Taunts.Remove: <iTeamID> is not a number or nil.") end
|
||||
-- return false
|
||||
-- end
|
||||
|
||||
-- -- if iTeamID is nil, both teams will have the taunt removed.
|
||||
-- if (iTeamID == nil) then
|
||||
-- GAMEMODE.Taunts.Seeker[sTauntName] = nil
|
||||
-- GAMEMODE.Taunts.Hider[sTauntName] = nil
|
||||
-- else
|
||||
-- -- Make sure we have a valid Team.
|
||||
-- if ! team.Valid(iTeamID) then
|
||||
-- if GAMEMODE.Config:Debug() then print("Prop Hunt.Taunts.Remove: Team "..iTeamID.."' does not exist.") end
|
||||
-- return false
|
||||
-- end
|
||||
|
||||
-- if iTeamID == TEAM_SEEKERS then
|
||||
-- GAMEMODE.Taunts.Seeker[sTauntName] = nil
|
||||
-- elseif iTeamID == TEAM_HIDERS then
|
||||
-- GAMEMODE.Taunts.Hider[sTauntName] = nil
|
||||
-- else
|
||||
-- if GAMEMODE.Config:Debug() then print("Prop Hunt.Taunts.Remove: Team "..iTeamID.."' can't have taunts.") end
|
||||
-- return false
|
||||
-- end
|
||||
-- end
|
||||
|
||||
-- if GAMEMODE.Config:Debug() then print("Prop Hunt.Taunts.Remove: Complete.") end
|
||||
-- return true
|
||||
-- end
|
||||
|
||||
-- -- ToDo: Taunts.Get(iTeamID, sPropName)
|
||||
|
||||
-- --! Announcers (Round Start, Unblind, Win, Loss)
|
||||
-- GM.Config.Announcers = {
|
||||
-- Start = { },
|
||||
-- Unblind = { },
|
||||
-- Win = { },
|
||||
-- Loss = { }
|
||||
-- }
|
||||
|
||||
-- -- Announcers.Clear()
|
||||
-- --@desc: Clears the current announcer list.
|
||||
-- GM.Config.Announcers.Clear = function()
|
||||
-- Announcers.Start = { }
|
||||
-- Announcers.Unblind = { }
|
||||
-- Announcers.Win = { }
|
||||
-- Announcers.Loss = { }
|
||||
-- end
|
||||
|
||||
-- -- Announcers.Load(sAnnouncerListFile)
|
||||
-- --@desc: Tries to load the given announcer list.
|
||||
-- --@param:
|
||||
-- -- sAnnouncerListFile - A string containing the path to the announcer list to load.
|
||||
-- --@return: true or false depending on success.
|
||||
-- GM.Config.Announcers.Load = function(sAnnouncerListFile)
|
||||
-- if GAMEMODE.Config:Debug() then print("Prop Hunt.Announcers.Load: Loading announcer list from file '"..sAnnouncerListFile.."'...") end
|
||||
|
||||
-- -- Safeguard against idiots.
|
||||
-- if type(sAnnouncerListFile) != "string" then
|
||||
-- if GAMEMODE.Config:Debug() then print("Prop Hunt.Announcers.Load: <sAnnouncerListFile> is not a string.") end
|
||||
-- return false
|
||||
-- end
|
||||
|
||||
-- -- Given file must exist for us to continue.
|
||||
-- if ! file.Exists(sAnnouncerListFile, "GAME") then
|
||||
-- if GAMEMODE.Config:Debug() then print("Prop Hunt.Announcers.Load: File not found.") end
|
||||
-- return false
|
||||
-- end
|
||||
|
||||
-- -- Read the file and check if it's empty.
|
||||
-- sAnnouncerListData = file.Read(sAnnouncerListFile, "GAME")
|
||||
-- if sAnnouncerListData == "" then
|
||||
-- if GAMEMODE.Config:Debug() then print("Prop Hunt.Announcers.Load: File is empty.") end
|
||||
-- return false
|
||||
-- end
|
||||
|
||||
-- -- Convert JSON to a table for us to use.
|
||||
-- sAnnouncerList = util.JSONToTable(sAnnouncerListData)
|
||||
|
||||
-- -- Is it nil? Then it's not valid JSON
|
||||
-- if sAnnouncerList == nil then
|
||||
-- if GAMEMODE.Config:Debug() then print("Prop Hunt.Announcers.Load: File contains invalid JSON.") end
|
||||
-- return false
|
||||
-- end
|
||||
|
||||
-- -- Finally, insert the announcer lists.
|
||||
-- if sAnnouncerList.Start != nil then
|
||||
-- if GAMEMODE.Config:Debug() then print("Prop Hunt.Announcers.Load: Adding Start announcers...") end
|
||||
-- for k,v in pairs(sAnnouncerList.Start) do
|
||||
-- GAMEMODE.Announcers.Start[k] = v
|
||||
-- end
|
||||
-- end
|
||||
-- if sAnnouncerList.Unblind != nil then
|
||||
-- if GAMEMODE.Config:Debug() then print("Prop Hunt.Announcers.Load: Adding Unblind announcers...") end
|
||||
-- for k,v in pairs(sAnnouncerList.Unblind) do
|
||||
-- GAMEMODE.Announcers.Unblind[k] = v
|
||||
-- end
|
||||
-- end
|
||||
-- if sAnnouncerList.Win != nil then
|
||||
-- if GAMEMODE.Config:Debug() then print("Prop Hunt.Announcers.Load: Adding Win announcers...") end
|
||||
-- for k,v in pairs(sAnnouncerList.Win) do
|
||||
-- GAMEMODE.Announcers.Win[k] = v
|
||||
-- end
|
||||
-- end
|
||||
-- if sAnnouncerList.Loss != nil then
|
||||
-- if GAMEMODE.Config:Debug() then print("Prop Hunt.Announcers.Load: Adding Loss announcers...") end
|
||||
-- for k,v in pairs(sAnnouncerList.Loss) do
|
||||
-- GAMEMODE.Announcers.Loss[k] = v
|
||||
-- end
|
||||
-- end
|
||||
|
||||
-- if GAMEMODE.Config:Debug() then print("Prop Hunt.Announcers.Load: Complete.") end
|
||||
-- return true
|
||||
-- end
|
||||
|
||||
-- -- Announcers.Save(sAnnouncerListFile)
|
||||
-- --@desc: Saves the current taunt list to disk.
|
||||
-- --@param:
|
||||
-- -- sAnnouncerListFile - A string containing the path to the file to save to.
|
||||
-- --@return: true or false depending on success.
|
||||
-- GM.Config.Announcers.Save = function(sAnnouncerListFile)
|
||||
-- if GAMEMODE.Config:Debug() then print("Prop Hunt.Announcers.Save: Saving announcer list to file '"..sAnnouncerListFile.."'...") end
|
||||
|
||||
-- -- Safeguard against idiots.
|
||||
-- if type(sAnnouncerListFile) != "string" then
|
||||
-- if GAMEMODE.Config:Debug() then print("Prop Hunt.Announcers.Save: <sAnnouncerListFile> is not a string.") end
|
||||
-- return false
|
||||
-- end
|
||||
|
||||
-- -- File must not be nil, otherwise we can't write to it.
|
||||
-- if sAnnouncerListFile == nil then
|
||||
-- if GAMEMODE.Config:Debug() then print("Prop Hunt.Announcers.Save: No file given.") end
|
||||
-- return false
|
||||
-- end
|
||||
|
||||
-- -- Convert our taunt table to JSON.
|
||||
-- sAnnouncerListData = util.TableToJSON(GAMEMODE.Announcers);
|
||||
-- if sAnnouncerListData == nil then
|
||||
-- if GAMEMODE.Config:Debug() then print("Prop Hunt.Announcers.Save: Corrupted GAMEMODE table.") end
|
||||
-- return false
|
||||
-- end
|
||||
|
||||
-- -- Write out JSON out to file
|
||||
-- if ! file.Write(sAnnouncerListFile, sAnnouncerListData) then
|
||||
-- if GAMEMODE.Config:Debug() then print("Prop Hunt.Announcers.Save: Failed to write to file.") end
|
||||
-- return false
|
||||
-- end
|
||||
|
||||
|
||||
-- if GAMEMODE.Config:Debug() then print("Prop Hunt.Announcers.Save: Complete.") end
|
||||
-- return true
|
||||
-- end
|
||||
|
||||
-- -- ToDo: Announcers.Add
|
||||
-- -- ToDo: Announcers.Remove
|
||||
-- -- ToDo: Announcers.Get(iType)
|
||||
@@ -0,0 +1,63 @@
|
||||
--[[
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Xaymar
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
--]]
|
||||
|
||||
GM.RoundManager = {}
|
||||
GM.RoundManager.State = nil;
|
||||
GM.RoundManager.NextState = nil;
|
||||
|
||||
function GM.RoundManager:Tick(...)
|
||||
if (self.State != nil) then
|
||||
if (self.State.Tick != nil) then
|
||||
self.State:Tick(...)
|
||||
end
|
||||
end
|
||||
|
||||
-- Advance States
|
||||
if (self.NextState != self.State) then
|
||||
-- Call OnLeave(NewState)
|
||||
if (self.State != nil) then
|
||||
if (self.State.OnLeave != nil) then
|
||||
self.State:OnLeave(self.NextState)
|
||||
end
|
||||
end
|
||||
|
||||
-- Call OnEnter(OldState)
|
||||
if (self.NextState != nil) then
|
||||
if (self.NextState.OnEnter != nil) then
|
||||
self.NextState:OnEnter(self.State)
|
||||
end
|
||||
end
|
||||
|
||||
-- Set State
|
||||
self.State = self.NextState
|
||||
end
|
||||
end
|
||||
|
||||
function GM.RoundManager:GetState()
|
||||
return self.State
|
||||
end
|
||||
|
||||
function GM.RoundManager:SetState(State)
|
||||
self.NextState = State
|
||||
end
|
||||
@@ -0,0 +1,61 @@
|
||||
--[[
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Xaymar
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
--]]
|
||||
|
||||
StateHide = {}
|
||||
|
||||
function StateHide:OnEnter(OldState)
|
||||
if GAMEMODE.Config:Debug() then print("StateHide: OnEnter") end
|
||||
GAMEMODE:SetRoundState(GAMEMODE.States.Hide)
|
||||
|
||||
-- Round Data
|
||||
GAMEMODE.Data.RoundTime = math.abs(GAMEMODE.Config.Round:BlindTime())
|
||||
GAMEMODE.Data.RoundStartTime = CurTime()
|
||||
|
||||
SetGlobalInt("RoundTime", GAMEMODE.Data.RoundTime)
|
||||
|
||||
-- Freeze Seekers
|
||||
for i, ply in ipairs(team.GetPlayers(GAMEMODE.Teams.Seekers)) do
|
||||
ply:Freeze(true)
|
||||
ply:Lock()
|
||||
end
|
||||
end
|
||||
|
||||
function StateHide:Tick()
|
||||
-- Update Game Time
|
||||
GAMEMODE.Data.RoundTime = math.abs(GAMEMODE.Config.Round:BlindTime()) - (CurTime() - GAMEMODE.Data.RoundStartTime)
|
||||
SetGlobalInt("RoundTime", math.ceil(GAMEMODE.Data.RoundTime))
|
||||
|
||||
-- Advance to Seeking State
|
||||
if (GAMEMODE.Data.RoundTime <= 0) then
|
||||
if GAMEMODE.Config:Debug() then print("StateHide: Advancing to Seek stage.") end
|
||||
|
||||
GAMEMODE.RoundManager:SetState(StateSeek)
|
||||
end
|
||||
|
||||
-- ToDo: Logic for more game modes here?
|
||||
end
|
||||
|
||||
function StateHide:OnLeave(NewState)
|
||||
if GAMEMODE.Config:Debug() then print("StateHide: OnLeave") end
|
||||
end
|
||||
@@ -0,0 +1,39 @@
|
||||
--[[
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Xaymar
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
--]]
|
||||
|
||||
StatePostMatch = {}
|
||||
|
||||
function StatePostMatch:OnEnter(OldState)
|
||||
if GAMEMODE.Config:Debug() then print("StatePostMatch: OnEnter") end
|
||||
GAMEMODE:SetRoundState(GAMEMODE.States.PostMatch)
|
||||
end
|
||||
|
||||
function StatePostMatch:Tick()
|
||||
-- Advance State
|
||||
GAMEMODE.RoundManager:SetState(StatePreMatch)
|
||||
end
|
||||
|
||||
function StatePostMatch:OnLeave(NewState)
|
||||
if GAMEMODE.Config:Debug() then print("StatePostMatch: OnLeave") end
|
||||
end
|
||||
@@ -0,0 +1,55 @@
|
||||
--[[
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Xaymar
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
--]]
|
||||
|
||||
StatePostRound = {}
|
||||
|
||||
function StatePostRound:OnEnter(OldState)
|
||||
if GAMEMODE.Config:Debug() then print("StatePostRound: OnEnter") end
|
||||
GAMEMODE:SetRoundState(GAMEMODE.States.PostRound)
|
||||
end
|
||||
|
||||
function StatePostRound:Tick()
|
||||
-- Advance State
|
||||
GAMEMODE.RoundManager:SetState(StatePreRound) -- Test: Reset to Hide
|
||||
end
|
||||
|
||||
function StatePostRound:OnLeave(NewState)
|
||||
if GAMEMODE.Config:Debug() then print("StatePostRound: OnLeave") end
|
||||
|
||||
-- Game Mode: Basic
|
||||
if (GAMEMODE.Config:GameMode() == GAMEMODE.Modes.Original) then
|
||||
-- Swap Teams
|
||||
local hiders, seekers = team.GetPlayers(GAMEMODE.Teams.Hiders), team.GetPlayers(GAMEMODE.Teams.Seekers)
|
||||
for i, ply in ipairs(hiders) do
|
||||
ply:SetTeam(GAMEMODE.Teams.Seekers)
|
||||
player_manager.SetPlayerClass(ply, "Seeker")
|
||||
end
|
||||
for i, ply in ipairs(seekers) do
|
||||
ply:SetTeam(GAMEMODE.Teams.Hiders)
|
||||
player_manager.SetPlayerClass(ply, "Hider")
|
||||
end
|
||||
|
||||
-- TODO: Other Gamemodes
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,54 @@
|
||||
--[[
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Xaymar
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
--]]
|
||||
|
||||
-- Precache Network Message
|
||||
StatePreMatch = {}
|
||||
|
||||
function StatePreMatch:OnEnter(OldState)
|
||||
if GAMEMODE.Config:Debug() then print("StatePreMatch: OnEnter") end
|
||||
GAMEMODE:SetRoundState(GAMEMODE.States.PreMatch)
|
||||
|
||||
SetGlobalInt("Round", GetGlobalInt("Round", 0) + 1)
|
||||
end
|
||||
|
||||
function StatePreMatch:Tick()
|
||||
-- Debug: Auto Advance to PreRound State
|
||||
if (GAMEMODE.Config:Debug()) then
|
||||
print("StatePreMatch: Advancing to StatePreRound")
|
||||
GAMEMODE.RoundManager:SetState(StatePreRound)
|
||||
end
|
||||
|
||||
-- Game Mode: Basic
|
||||
if (GAMEMODE.Config:GameMode() == GAMEMODE.Modes.Original) then
|
||||
-- Both Teams must have at least 1 player.
|
||||
if ((team.NumPlayers(GAMEMODE.Teams.Seekers) >= 1) && (team.NumPlayers(GAMEMODE.Teams.Hiders) >= 1)) then
|
||||
GAMEMODE.RoundManager:SetState(StatePreRound)
|
||||
end
|
||||
-- TODO: Other Gamemodes
|
||||
end
|
||||
end
|
||||
|
||||
function StatePreMatch:OnLeave(NewState)
|
||||
if GAMEMODE.Config:Debug() then print("StatePreMatch: OnLeave") end
|
||||
end
|
||||
@@ -0,0 +1,52 @@
|
||||
--[[
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Xaymar
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
--]]
|
||||
|
||||
StatePreRound = {}
|
||||
|
||||
function StatePreRound:OnEnter(OldState)
|
||||
if GAMEMODE.Config:Debug() then print("StatePreRound: OnEnter") end
|
||||
GAMEMODE:SetRoundState(GAMEMODE.States.PreRound)
|
||||
|
||||
-- Clean Up the Map
|
||||
game.CleanUpMap()
|
||||
|
||||
end
|
||||
function StatePreRound:Tick()
|
||||
-- Advance State
|
||||
GAMEMODE.RoundManager:SetState(StateHide)
|
||||
end
|
||||
function StatePreRound:OnLeave(NewState)
|
||||
if GAMEMODE.Config:Debug() then print("StatePreRound: OnLeave") end
|
||||
|
||||
-- Game Mode: Basic
|
||||
if (GAMEMODE.Config:GameMode() == GAMEMODE.Modes.Original) then
|
||||
-- Respawn Everyone
|
||||
for i, ply in ipairs(player.GetAll()) do
|
||||
ply:KillSilent()
|
||||
ply.Data.Alive = true
|
||||
ply:Spawn()
|
||||
end
|
||||
-- TODO: Other Gamemodes
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,83 @@
|
||||
--[[
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Xaymar
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
--]]
|
||||
|
||||
StateSeek = {}
|
||||
|
||||
function StateSeek:OnEnter(OldState)
|
||||
if GAMEMODE.Config:Debug() then print("StateSeek: OnEnter") end
|
||||
GAMEMODE:SetRoundState(GAMEMODE.States.Seek)
|
||||
|
||||
-- Round Data
|
||||
GAMEMODE.Data.RoundTime = GAMEMODE.Config.Round:Time()
|
||||
|
||||
-- Unfreeze Seekers
|
||||
for i, ply in ipairs(team.GetPlayers(GAMEMODE.Teams.Seekers)) do
|
||||
ply:Freeze(false)
|
||||
ply:UnLock()
|
||||
end
|
||||
end
|
||||
|
||||
function StateSeek:Tick()
|
||||
-- Update Game Time
|
||||
GAMEMODE.Data.RoundTime = GAMEMODE.Config.Round:Time() - (CurTime() - GAMEMODE.Data.RoundStartTime)
|
||||
SetGlobalInt("RoundTime", math.ceil(GAMEMODE.Data.RoundTime))
|
||||
|
||||
-- Conditions for moving to the next State
|
||||
if (GAMEMODE.Data.RoundTime <= 0) then -- No Time remaining
|
||||
GAMEMODE.Data.Winner = GAMEMODE.Teams.Hiders
|
||||
GAMEMODE.RoundManager:SetState(StatePostRound)
|
||||
end
|
||||
|
||||
-- Condition: No Seekers / Hiders alive.
|
||||
local hiders, seekers = team.GetPlayers(GAMEMODE.Teams.Hiders), team.GetPlayers(GAMEMODE.Teams.Seekers)
|
||||
local hiderAlive, seekerAlive = false, false
|
||||
for i,ply in ipairs(hiders) do
|
||||
if (ply.Data.Alive) then
|
||||
hiderAlive = true
|
||||
end
|
||||
end
|
||||
for i,ply in ipairs(seekers) do
|
||||
if (ply.Data.Alive) then
|
||||
seekerAlive = true
|
||||
end
|
||||
end
|
||||
if (hiderAlive == false) then
|
||||
if (seekerAlive == false) then
|
||||
GAMEMODE.Data.Winner = GAMEMODE.Teams.Spectators -- Shows as Draw
|
||||
GAMEMODE.RoundManager:SetState(StatePostRound)
|
||||
else
|
||||
GAMEMODE.Data.Winner = GAMEMODE.Teams.Seekers
|
||||
GAMEMODE.RoundManager:SetState(StatePostRound)
|
||||
end
|
||||
else
|
||||
if (seekerAlive == false) then
|
||||
GAMEMODE.Data.Winner = GAMEMODE.Teams.Hiders
|
||||
GAMEMODE.RoundManager:SetState(StatePostRound)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function StateSeek:OnLeave(NewState)
|
||||
if GAMEMODE.Config:Debug() then print("StateSeek: OnLeave") end
|
||||
end
|
||||
@@ -0,0 +1,294 @@
|
||||
-- Sounds played by members of the losing team at the end of the round.
|
||||
LOSS_SOUNDS = {
|
||||
"bot/aw_hell.wav",
|
||||
"bot/aww_man.wav",
|
||||
"bot/anyone_see_anything.wav",
|
||||
"bot/anyone_see_them.wav",
|
||||
"bot/come_out_and_fight_like_a_man.wav",
|
||||
"bot/come_out_wherever_you_are.wav",
|
||||
"bot/he_got_away.wav",
|
||||
"bot/he_got_away2.wav",
|
||||
"bot/i_dont_know_where_he_went.wav",
|
||||
"bot/i_got_nothing.wav",
|
||||
"bot/nothing_happening_over_here.wav",
|
||||
"bot/nothing_here.wav",
|
||||
"bot/nothing_moving_over_here.wav",
|
||||
"bot/thats_not_good.wav",
|
||||
"bot/theres_too_many.wav",
|
||||
"bot/theres_too_many_of_them.wav",
|
||||
"bot/theyre_all_over_the_place2.wav",
|
||||
"bot/theyre_everywhere2.wav",
|
||||
"bot/too_many2.wav",
|
||||
"bot/what_happened.wav",
|
||||
"bot/what_have_you_done.wav",
|
||||
"bot/where_are_they.wav",
|
||||
"bot/where_are_you_hiding.wav"
|
||||
}
|
||||
if (! file.Exists("prop_hunt/sounds_loss.txt", "DATA")) then
|
||||
file.Write("prop_hunt/sounds_loss.txt", util.TableToKeyValues(LOSS_SOUNDS))
|
||||
end
|
||||
local fileContent = file.Read("prop_hunt/sounds_loss.txt", "DATA");
|
||||
if fileContent then
|
||||
local fileTable = util.KeyValuesToTable(fileContent)
|
||||
if fileTable then LOSS_SOUNDS = fileTable end
|
||||
end
|
||||
|
||||
-- Sounds played by members of the winning team at the end of the round.
|
||||
VICTORY_SOUNDS = {
|
||||
"bot/and_thats_how_its_done.wav",
|
||||
"bot/come_to_papa.wav",
|
||||
"bot/do_not_mess_with_me.wav",
|
||||
"bot/dropped_him.wav",
|
||||
"bot/enemy_down.wav",
|
||||
"bot/enemy_down2.wav",
|
||||
"bot/good_job_team.wav",
|
||||
"bot/got_him.wav",
|
||||
"bot/hes_broken.wav",
|
||||
"bot/hes_dead.wav",
|
||||
"bot/hes_done.wav",
|
||||
"bot/hes_down.wav",
|
||||
"bot/its_a_party.wav",
|
||||
"bot/i_am_dangerous.wav",
|
||||
"bot/i_am_on_fire.wav",
|
||||
"bot/i_got_more_where_that_came_from.wav",
|
||||
"bot/i_wasnt_worried_for_a_minute.wav",
|
||||
"bot/killed_him.wav",
|
||||
"bot/look_out_brag.wav",
|
||||
"bot/made_him_cry.wav",
|
||||
"bot/oh_yea.wav",
|
||||
"bot/oh_yea2.wav",
|
||||
"bot/owned.wav",
|
||||
"bot/ruined_his_day.wav",
|
||||
"bot/tag_them_and_bag_them.wav",
|
||||
"bot/thats_the_way_this_is_done.wav",
|
||||
"bot/that_was_a_close_one.wav",
|
||||
"bot/that_was_it.wav",
|
||||
"bot/that_was_the_last_guy.wav",
|
||||
"bot/that_was_the_last_one.wav",
|
||||
"bot/they_never_knew_what_hit_them.wav",
|
||||
"bot/they_will_not_escape.wav",
|
||||
"bot/they_wont_get_away.wav",
|
||||
"bot/they_wont_get_away2.wav",
|
||||
"bot/this_is_my_house.wav",
|
||||
"bot/took_him_down.wav",
|
||||
"bot/took_him_out.wav",
|
||||
"bot/took_him_out2.wav",
|
||||
"bot/wasted_him.wav",
|
||||
"bot/way_to_be_team.wav",
|
||||
"bot/well_done.wav",
|
||||
"bot/we_owned_them.wav",
|
||||
"bot/whew_that_was_close.wav",
|
||||
"bot/whoo.wav",
|
||||
"bot/whoo2.wav",
|
||||
"bot/whos_the_man.wav",
|
||||
"bot/who_wants_some_more.wav",
|
||||
"bot/yesss.wav",
|
||||
"bot/yesss2.wav"
|
||||
}
|
||||
if (! file.Exists("prop_hunt/sounds_victory.txt", "DATA")) then
|
||||
file.Write("prop_hunt/sounds_victory.txt", util.TableToKeyValues(VICTORY_SOUNDS))
|
||||
end
|
||||
local fileContent = file.Read("prop_hunt/sounds_victory.txt", "DATA");
|
||||
if fileContent then
|
||||
local fileTable = util.KeyValuesToTable(fileContent)
|
||||
if fileTable then VICTORY_SOUNDS = fileTable end
|
||||
end
|
||||
|
||||
-- Taunts played when Hunters hit their Spare1 binding.
|
||||
HUNTER_TAUNTS = {
|
||||
"bot/a_bunch_of_them.wav",
|
||||
"bot/come_out_and_fight_like_a_man.wav",
|
||||
"bot/come_out_wherever_you_are.wav",
|
||||
"bot/come_to_papa.wav",
|
||||
"bot/dont_worry_hell_get_it.wav",
|
||||
"bot/hang_on_i_heard_something.wav",
|
||||
"bot/hang_on_im_coming.wav",
|
||||
"bot/i_dont_think_so.wav",
|
||||
"bot/i_have_the_hostages.wav",
|
||||
"bot/i_see_our_target.wav",
|
||||
"bot/im_waiting_here.wav",
|
||||
"bot/keeping_an_eye_on_the_hostages.wav",
|
||||
"bot/nnno_sir.wav",
|
||||
"bot/spotted_the_delivery_boy.wav",
|
||||
"bot/target_acquired.wav",
|
||||
"bot/target_spotted.wav",
|
||||
"bot/you_heard_the_man_lets_go.wav"
|
||||
}
|
||||
if (! file.Exists("prop_hunt/sounds_taunt_hunter.txt", "DATA")) then
|
||||
file.Write("prop_hunt/sounds_taunt_hunter.txt", util.TableToKeyValues(HUNTER_TAUNTS))
|
||||
end
|
||||
local fileContent = file.Read("prop_hunt/sounds_taunt_hunter.txt", "DATA");
|
||||
if fileContent then
|
||||
local fileTable = util.KeyValuesToTable(fileContent)
|
||||
if fileTable then HUNTER_TAUNTS = fileTable end
|
||||
end
|
||||
|
||||
-- Taunts played when Props hit their Spare1 binding.
|
||||
PROP_TAUNTS = {
|
||||
-- "ambient/alarms/apc_alarm_loop1.wav",
|
||||
"ambient/alarms/apc_alarm_pass1.wav",
|
||||
-- "ambient/alarms/citadel_alert_loop2.wav",
|
||||
-- "ambient/alarms/city_firebell_loop1.wav",
|
||||
-- "ambient/alarms/city_siren_loop2.wav",
|
||||
-- "ambient/alarms/combine_bank_alarm_loop1.wav",
|
||||
-- "ambient/alarms/combine_bank_alarm_loop4.wav",
|
||||
-- "ambient/alarms/klaxon1.wav",
|
||||
"ambient/alarms/manhack_alert_pass1.wav",
|
||||
"ambient/alarms/razortrain_horn1.wav",
|
||||
"ambient/alarms/scanner_alert_pass1.wav",
|
||||
-- "ambient/alarms/siren.wav",
|
||||
-- "ambient/alarms/train_crossing_bell_loop1.wav",
|
||||
"ambient/alarms/train_horn2.wav",
|
||||
"ambient/alarms/train_horn_distant1.wav",
|
||||
"ambient/alarms/warningbell1.wav",
|
||||
-- "ambient/chatter/cb_radio_chatter_1.wav",
|
||||
-- "ambient/chatter/cb_radio_chatter_2.wav",
|
||||
-- "ambient/chatter/cb_radio_chatter_3.wav",
|
||||
"ambient/energy/whiteflash.wav",
|
||||
"ambient/intro/alyxremove.wav",
|
||||
"ambient/intro/logosfx.wav",
|
||||
-- "ambient/levels/labs/teleport_alarm_loop1.wav",
|
||||
"ambient/levels/launch/1stfiringwarning.wav",
|
||||
"ambient/levels/launch/rockettakeoffblast.wav",
|
||||
-- "ambient/levels/outland/basealarmloop.wav",
|
||||
-- "ambient/machines/60hzhum.wav",
|
||||
"ambient/misc/ambulance1.wav",
|
||||
"ambient/misc/carhonk1.wav",
|
||||
"ambient/misc/carhonk2.wav",
|
||||
"ambient/misc/carhonk3.wav",
|
||||
-- "ambient/music/bongo.wav",
|
||||
-- "ambient/music/country_rock_am_radio_loop.wav",
|
||||
-- "ambient/music/cubanmusic1.wav",
|
||||
-- "ambient/music/dustmusic1.wav",
|
||||
-- "ambient/music/dustmusic2.wav",
|
||||
-- "ambient/music/dustmusic3.wav",
|
||||
-- "ambient/music/flamenco.wav",
|
||||
-- "ambient/music/latin.wav",
|
||||
-- "ambient/music/mirame_radio_thru_wall.wav",
|
||||
-- "ambient/music/piano1.wav",
|
||||
-- "ambient/music/piano2.wav",
|
||||
"ambient/outro/gunshipcrash.wav",
|
||||
"ambient/3dmeagle.wav",
|
||||
-- "ambient/guit1.wav",
|
||||
-- "ambient/opera.wav",
|
||||
-- "ambient/sheep.wav",
|
||||
"beams/beamstart5.wav",
|
||||
"buttons/bell1.wav",
|
||||
"buttons/weapon_cant_buy.wav",
|
||||
"common/bass.wav",
|
||||
"common/bugreporter_failed.wav",
|
||||
"common/warning.wav",
|
||||
"doors/door_squeek1.wav",
|
||||
"friends/friend_join.wav",
|
||||
"friends/friend_online.wav",
|
||||
"friends/message.wav",
|
||||
"hostage/hunuse/comeback.wav",
|
||||
"hostage/hunuse/dontleaveme.wav",
|
||||
"hostage/hunuse/yeahillstay.wav",
|
||||
"items/gift_drop.wav",
|
||||
"music/radio1.mp3",
|
||||
"phx/eggcrack.wav",
|
||||
"plats/elevbell1.wav",
|
||||
"player/headshot1.wav",
|
||||
"player/headshot2.wav",
|
||||
"player/sprayer.wav",
|
||||
"radio/enemydown.wav",
|
||||
"radio/go.wav",
|
||||
"radio/locknload.wav",
|
||||
"radio/negative.wav",
|
||||
"radio/rounddraw.wav",
|
||||
"radio/takepoint.wav",
|
||||
"resource/warning.wav",
|
||||
-- "test/temp/soundscape_test/tv_music.wav",
|
||||
"ui/achievement_earned.wav",
|
||||
"ui/freeze_cam.wav",
|
||||
"vehicles/junker/radar_ping_friendly1.wav",
|
||||
"weapons/c4/c4_beep1.wav",
|
||||
"weapons/c4/c4_click.wav",
|
||||
"weapons/awp/awp1.wav",
|
||||
"vo/canals/female01/gunboat_giveemhell.wav",
|
||||
"vo/canals/female01/gunboat_justintime.wav",
|
||||
"vo/canals/female01/stn6_incoming.wav",
|
||||
"vo/canals/male01/gunboat_giveemhell.wav",
|
||||
"vo/canals/male01/gunboat_justintime.wav",
|
||||
"vo/canals/male01/stn6_incoming.wav",
|
||||
"vo/canals/al_radio_stn6.wav",
|
||||
"vo/canals/arrest_getgoing.wav",
|
||||
"vo/canals/arrest_helpme.wav",
|
||||
"vo/canals/arrest_lookingforyou.wav",
|
||||
"vo/canals/boxcar_lethimhelp.wav",
|
||||
"vo/canals/matt_closecall.wav",
|
||||
"vo/canals/premassacre.wav",
|
||||
"vo/ravenholm/aimforhead.wav",
|
||||
"vo/ravenholm/bucket_patience.wav",
|
||||
"vo/ravenholm/madlaugh01.wav",
|
||||
"vo/ravenholm/madlaugh02.wav",
|
||||
"vo/ravenholm/madlaugh03.wav",
|
||||
"vo/ravenholm/madlaugh04.wav",
|
||||
"weapons/strider_buster/ol12_stickybombcreator.wav",
|
||||
"weapons/c4/c4_explode1.wav",
|
||||
"weapons/357/357_fire2.wav",
|
||||
"weapons/357/357_fire3.wav",
|
||||
"weapons/scout/scout_fire-1.wav",
|
||||
"weapons/smokegrenade/sg_explode.wav",
|
||||
"weapons/grenade_launcher1.wav",
|
||||
"weapons/explode3.wav",
|
||||
"weapons/underwater_explode3.wav",
|
||||
"items/nvg_on.wav",
|
||||
"hostage/huse/letsdoit.wav",
|
||||
"hostage/huse/illfollow.wav",
|
||||
"hostage/huse/getouttahere.wav",
|
||||
"doors/door_screen_move1.wav",
|
||||
"doors/heavy_metal_stop1.wav",
|
||||
"doors/default_move.wav",
|
||||
"common/stuck2.wav",
|
||||
"ambient/water_splash1.wav",
|
||||
"ambient/water_splash2.wav",
|
||||
"ambient/water_splash3.wav",
|
||||
"ambient/weather/thunder1.wav",
|
||||
"ambient/weather/thunder2.wav",
|
||||
"ambient/weather/thunder3.wav",
|
||||
"ambient/weather/thunder4.wav",
|
||||
"ambient/weather/thunder5.wav",
|
||||
"ambient/weather/thunder6.wav",
|
||||
"ambient/outro/thunder7.wav",
|
||||
"ambient/voices/crying_loop1.wav",
|
||||
"ambient/voices/playground_memory.wav",
|
||||
"ambient/voices/f_scream1.wav",
|
||||
"ambient/voices/m_scream1.wav",
|
||||
"ambient/voices/cough1.wav",
|
||||
"ambient/voices/cough2.wav",
|
||||
"ambient/voices/cough3.wav",
|
||||
"ambient/voices/cough4.wav",
|
||||
"ambient/overhead/plane1.wav",
|
||||
"ambient/overhead/plane2.wav",
|
||||
"ambient/overhead/plane3.wav",
|
||||
"ambient/overhead/hel1.wav",
|
||||
"ambient/overhead/hel2.wav",
|
||||
"ambient/misc/truck_backup1.wav",
|
||||
"ambient/misc/truck_drive1.wav",
|
||||
"ambient/misc/truck_drive2.wav",
|
||||
"ambient/machines/pneumatic_drill_1.wav",
|
||||
"ambient/machines/pneumatic_drill_2.wav",
|
||||
"ambient/machines/pneumatic_drill_3.wav",
|
||||
"ambient/machines/pneumatic_drill_4.wav",
|
||||
"ambient/machines/station_train_squeel.wav",
|
||||
"ambient/machines/ticktock.wav",
|
||||
"ambient/creatures/teddy.wav",
|
||||
"ambient/creatures/town_child_scream1.wav",
|
||||
"ambient/creatures/town_moan1.wav",
|
||||
"ambient/creatures/town_muffled_cry1.wav",
|
||||
"ambient/creatures/town_scared_breathing1.wav",
|
||||
"ambient/creatures/town_scared_breathing2.wav",
|
||||
"ambient/creatures/town_scared_sob1.wav",
|
||||
"ambient/creatures/town_scared_sob2.wav",
|
||||
"ambient/creatures/town_zombie_call1.wav"
|
||||
}
|
||||
if (! file.Exists("prop_hunt/sounds_taunt_prop.txt", "DATA")) then
|
||||
file.Write("prop_hunt/sounds_taunt_prop.txt", util.TableToKeyValues(PROP_TAUNTS))
|
||||
end
|
||||
local fileContent = file.Read("prop_hunt/sounds_taunt_prop.txt", "DATA");
|
||||
if fileContent then
|
||||
local fileTable = util.KeyValuesToTable(fileContent)
|
||||
if fileTable then PROP_TAUNTS = fileTable end
|
||||
end
|
||||
@@ -0,0 +1,130 @@
|
||||
--[[
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Xaymar
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
--]]
|
||||
|
||||
-- ------------------------------------------------------------------------- --
|
||||
--! Gamemode Information
|
||||
-- ------------------------------------------------------------------------- --
|
||||
GM.Name = "Prop Hunt Extended"
|
||||
GM.Author = "Michael 'Xaymar' Dirks (Based on Kow@lskis Version, Original by AMT)"
|
||||
GM.Email = "michael.fabian.dirks@gmail.com"
|
||||
GM.Website = "http://xaymar.com/"
|
||||
|
||||
GM.TeamBased = true
|
||||
GM.AllowAutoTeam = true
|
||||
GM.SecondsBetweenTeamSwitches = 10
|
||||
|
||||
-- ------------------------------------------------------------------------- --
|
||||
--! Includes
|
||||
-- ------------------------------------------------------------------------- --
|
||||
-- Player Classes
|
||||
include "player_class/class_default.lua"
|
||||
include "player_class/class_spectator.lua"
|
||||
include "player_class/class_seeker.lua"
|
||||
include "player_class/class_hider.lua"
|
||||
|
||||
-- ------------------------------------------------------------------------- --
|
||||
--! Code
|
||||
-- ------------------------------------------------------------------------- --
|
||||
-- Game States
|
||||
GM.States = {}
|
||||
GM.States.PreMatch = 0
|
||||
GM.States.PreRound = 1
|
||||
GM.States.Hide = 2
|
||||
GM.States.Seek = 3
|
||||
GM.States.PostRound = 4
|
||||
GM.States.PostMatch = 5
|
||||
|
||||
-- Game Modes
|
||||
GM.Modes = {}
|
||||
GM.Modes.Original = 0
|
||||
GM.Modes.SwizzleEffect = 1 -- Randomizes Teams each Round
|
||||
GM.Modes.TheDeadHunt = 2 -- One Hunter, Dead Prop become Hunter, Props can't see each other.
|
||||
|
||||
-- Teams
|
||||
GM.Teams = {}
|
||||
GM.Teams.Spectators = 0
|
||||
GM.Teams.Seekers = 1
|
||||
GM.Teams.Hiders = 2
|
||||
|
||||
function GM:CreateTeams()
|
||||
-- Specators
|
||||
team.SetUp(self.Teams.Spectators, "Spectators", Color(127, 127, 127, 255))
|
||||
team.SetSpawnPoint(self.Teams.Spectators, {
|
||||
"info_player_deathmatch",
|
||||
"info_player_axis",
|
||||
"info_player_combine",
|
||||
"info_player_counterterrorist",
|
||||
"info_player_allies",
|
||||
"info_player_terrorist"
|
||||
})
|
||||
team.SetClass(self.Teams.Spectators, { "Spectator", "Spectator" })
|
||||
|
||||
-- Seekers: "Hunters"
|
||||
team.SetUp(self.Teams.Seekers, "Seekers", Color(0, 128, 255, 255))
|
||||
team.SetSpawnPoint(self.Teams.Seekers, {
|
||||
"info_player_spawn",
|
||||
"info_player_deathmatch",
|
||||
"info_player_axis",
|
||||
"info_player_combine",
|
||||
"info_player_counterterrorist"
|
||||
})
|
||||
team.SetClass(self.Teams.Seekers, { "Seeker", "Spectator" })
|
||||
|
||||
-- Hiders: "Props"
|
||||
team.SetUp(self.Teams.Hiders, "Hiders", Color(255, 128, 0, 255))
|
||||
team.SetSpawnPoint(self.Teams.Hiders, {
|
||||
"info_player_spawn",
|
||||
"info_player_deathmatch",
|
||||
"info_player_allies",
|
||||
"info_player_terrorist"
|
||||
})
|
||||
team.SetClass(self.Teams.Hiders, { "Hider", "Spectator" })
|
||||
end
|
||||
|
||||
-- ------------------------------------------------------------------------- --
|
||||
--! Player Manager Binding
|
||||
-- ------------------------------------------------------------------------- --
|
||||
function GM:PlayerPostThink(ply)
|
||||
return player_manager.RunClass(ply, "PostThink")
|
||||
end
|
||||
|
||||
function GM:PlayerTick(ply, mv)
|
||||
return player_manager.RunClass(ply, "Tick", mv)
|
||||
end
|
||||
|
||||
function GM:PlayerHurt(victim, attacker, healthRemaining, damageTaken)
|
||||
if (victim != nil && victim:IsPlayer()) then
|
||||
player_manager.RunClass(victim, "Hurt", victim, attacker, healthRemaining, damageTaken)
|
||||
end
|
||||
if (attacker != nil && attacker:IsPlayer()) then
|
||||
player_manager.RunClass(attacker, "Damage", victim, attacker, healthRemaining, damageTaken)
|
||||
end
|
||||
end
|
||||
|
||||
-- ------------------------------------------------------------------------- --
|
||||
--! Gamemode Functionality
|
||||
-- ------------------------------------------------------------------------- --
|
||||
function GM:GetRoundState()
|
||||
return GetGlobalInt("RoundState", self.States.PreMatch)
|
||||
end
|
||||
@@ -0,0 +1,49 @@
|
||||
-- Finds the player meta table or terminates
|
||||
local meta = FindMetaTable("Player")
|
||||
if !meta then return end
|
||||
|
||||
-- Blinds the player by setting view out into the void
|
||||
function meta:Blind(bool)
|
||||
if !self:IsValid() then return end
|
||||
|
||||
if SERVER then
|
||||
umsg.Start("SetBlind", self)
|
||||
if bool then
|
||||
umsg.Bool(true)
|
||||
else
|
||||
umsg.Bool(false)
|
||||
end
|
||||
umsg.End()
|
||||
elseif CLIENT then
|
||||
blind = bool
|
||||
end
|
||||
end
|
||||
|
||||
-- Blinds the player by setting view out into the void
|
||||
function meta:RemoveProp()
|
||||
if CLIENT || !self:IsValid() then return end
|
||||
|
||||
if self.ph_prop && self.ph_prop:IsValid() then
|
||||
self.ph_prop:Remove()
|
||||
self.ph_prop = nil
|
||||
end
|
||||
end
|
||||
|
||||
-- Sets a new Hull for a player.
|
||||
function meta:NewHull(hullOBBMin, hullOBBMax)
|
||||
if !self:IsValid() then return end
|
||||
if hullOBBMax == nil then return end
|
||||
if hullOBBMin == nil then return end
|
||||
|
||||
local hullOBB = hullOBBMax - hullOBBMin
|
||||
local hullOBBXY = math.max(hullOBB.x, hullOBB.y)
|
||||
|
||||
local xyMul = 0.5
|
||||
local hullMin = Vector(-hullOBBXY * xyMul, -hullOBBXY * xyMul, 0)
|
||||
local hullMax = Vector( hullOBBXY * xyMul, hullOBBXY * xyMul, hullOBB.z)
|
||||
|
||||
self:SetHull(hullMin, hullMax)
|
||||
self:SetHullDuck(hullMin, hullMax)
|
||||
self:SetViewOffset(Vector(0, 0, hullOBB.z))
|
||||
self:SetViewOffsetDucked(Vector(0, 0, hullOBB.z / 2.0))
|
||||
end
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 48 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 127 KiB |
@@ -0,0 +1,182 @@
|
||||
"prophuntextended"
|
||||
{
|
||||
"base" "base"
|
||||
"title" "Prop Hunt Extended"
|
||||
"maps" "^ph_|^cs_|^de_|^ttt_"
|
||||
"menusystem" "1"
|
||||
"workshopid" "468149739"
|
||||
|
||||
"settings"
|
||||
{
|
||||
// Game Settings
|
||||
1
|
||||
{
|
||||
"name" "ph_gamemode"
|
||||
"text" "G: Game Mode"
|
||||
"help" "0: Basic, 1: Swizzle Effect (Random Teams), 2: The Dead Hunt (One Hunter, Dead Props become Hunters)"
|
||||
"type" "Numeric"
|
||||
"default" "0"
|
||||
}
|
||||
|
||||
2
|
||||
{
|
||||
"name" "mp_timelimit"
|
||||
"text" "G: Time Limit"
|
||||
"help" "Time Limit in Minutes for how long should we stay on one map. (0 to disable)"
|
||||
"type" "Numeric"
|
||||
"default" "20"
|
||||
}
|
||||
|
||||
3
|
||||
{
|
||||
"name" "ph_sprinting"
|
||||
"text" "G: Enable Sprinting"
|
||||
"help" "Should sprinting be possible?"
|
||||
"type" "CheckBox"
|
||||
"default" "0"
|
||||
}
|
||||
|
||||
4
|
||||
{
|
||||
"name" "ph_tauntcooldown"
|
||||
"text" "G: Taunt Cooldown"
|
||||
"help" "How much time must pass before another taunt may be played."
|
||||
"type" "Numeric"
|
||||
"default" "5"
|
||||
}
|
||||
|
||||
// Round Settings
|
||||
10
|
||||
{
|
||||
"name" "ph_round_limit"
|
||||
"text" "R: Rounds per Map"
|
||||
"help" "How many rounds are played per map."
|
||||
"type" "Numeric"
|
||||
"default" "10"
|
||||
}
|
||||
|
||||
11
|
||||
{
|
||||
"name" "ph_round_timelimit"
|
||||
"text" "R: Round Duration (Seconds)"
|
||||
"help" "How long is each round going to last?"
|
||||
"type" "Numeric"
|
||||
"default" "300"
|
||||
}
|
||||
|
||||
12
|
||||
{
|
||||
"name" "ph_round_blindtime"
|
||||
"text" "R: Hiding Time (Seconds)"
|
||||
"help" "How long are hunters blinded? (positive values will be inside the round time limit, negative will add to the round time limit)"
|
||||
"type" "Numeric"
|
||||
"default" "30"
|
||||
}
|
||||
|
||||
// Seeker Settings
|
||||
20
|
||||
{
|
||||
"name" "ph_seeker_health"
|
||||
"text" "S: Health"
|
||||
"type" "Numeric"
|
||||
"default" "100"
|
||||
}
|
||||
|
||||
21
|
||||
{
|
||||
"name" "ph_seeker_health_max"
|
||||
"text" "S: Max Health"
|
||||
"type" "Numeric"
|
||||
"default" "100"
|
||||
}
|
||||
|
||||
22
|
||||
{
|
||||
"name" "ph_seeker_health_bonus"
|
||||
"text" "S: Health Kill-Bonus"
|
||||
"help" "Health gained on kill."
|
||||
"type" "Numeric"
|
||||
"default" "20"
|
||||
}
|
||||
|
||||
23
|
||||
{
|
||||
"name" "ph_seeker_health_penalty"
|
||||
"text" "S: Health Penalty"
|
||||
"help" "Health lost on wrong shot."
|
||||
"type" "Numeric"
|
||||
"default" "5"
|
||||
}
|
||||
|
||||
24
|
||||
{
|
||||
"name" "ph_seeker_weapons"
|
||||
"text" "S: Weapons to be given to Seekers"
|
||||
"help" "Format: Weapon,Weapon,..."
|
||||
"type" "Text"
|
||||
"default" "weapon_crowbar,weapon_pistol,weapon_ph_smg,weapon_shotgun,weapon_physcannon"
|
||||
}
|
||||
|
||||
25
|
||||
{
|
||||
"name" "ph_seeker_ammo"
|
||||
"text" "S: Ammo to give to Seekers"
|
||||
"help" "Format: Name:Amount,Name:Amount,..."
|
||||
"type" "Text"
|
||||
"default" "Pistol:100,SMG1:300,SMG1_Grenade:1,Buckshot:64"
|
||||
}
|
||||
|
||||
// Hider Settings
|
||||
30
|
||||
{
|
||||
"name" "ph_hider_health"
|
||||
"text" "H: Health"
|
||||
"type" "Numeric"
|
||||
"default" "100"
|
||||
}
|
||||
|
||||
31
|
||||
{
|
||||
"name" "ph_hider_health_max"
|
||||
"text" "H: Max Health"
|
||||
"type" "Numeric"
|
||||
"default" "100"
|
||||
}
|
||||
|
||||
32
|
||||
{
|
||||
"name" "ph_hider_health_scaling"
|
||||
"text" "H: Enable Health Scaling"
|
||||
"help" "Larger & heavier objects have more health, smaller less."
|
||||
"type" "CheckBox"
|
||||
"default" "1"
|
||||
}
|
||||
|
||||
33
|
||||
{
|
||||
"name" "ph_hider_health_scaling_max"
|
||||
"text" "H: Scaled Max Health"
|
||||
"type" "Numeric"
|
||||
"default" "200"
|
||||
}
|
||||
|
||||
// Whitelist & Blacklist
|
||||
40
|
||||
{
|
||||
"name" "ph_list_class_whitelist"
|
||||
"text" "L: Allowed Entity Classes"
|
||||
"help" "Hiders can only use these for changing model and skin."
|
||||
"type" "Text"
|
||||
"default" "ph_prop,prop_physics,prop_physics_multiplayer,prop_physics_respawnable"
|
||||
}
|
||||
|
||||
41
|
||||
{
|
||||
"name" "ph_list_abuse_blacklist"
|
||||
"text" "L: Abuse Blacklist"
|
||||
"help" "Fix interact spam with certain entities so that all areas stay accessible."
|
||||
"type" "Text"
|
||||
"default" ""func_button,func_door,func_door_rotation,prop_door_rotation,func_tracktrain,func_tanktrain,func_breakable""
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user