Code update, forgot to actually do this... *hides in a corner*
This commit is contained in:
@@ -0,0 +1,14 @@
|
|||||||
|
Based on the original "Prop Hunt" game mode, Xaymar's Custom Prop Hunt brings you some much needed changes to freshen up the gamemode.
|
||||||
|
|
||||||
|
New features:
|
||||||
|
- Easy configuration - configuration is now stored inside data\prop_hunt\ as a key-values table!
|
||||||
|
- Default Taunts are no longer infringing on copyrighted material - taunt your life away as a streamer or YouTuber!
|
||||||
|
- Taunt Pack support - add new taunts by just downloading addons, no file modification needed!
|
||||||
|
- Prop Rotation - Hit F4 and dance- err I ment rotate!
|
||||||
|
|
||||||
|
Fixes:
|
||||||
|
- Camera can now no longer glitch through the world.
|
||||||
|
- Camera root position now closely follows the prop size.
|
||||||
|
- Prop sizes are now set correctly - previously you could make your way behind things with props way too big.
|
||||||
|
- Props can no longer heal themselves by becoming prop, they'll always keep the same percentage of health.
|
||||||
|
- Picking a prop is now more accurate, picking from where your camera is looking.
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"title" : "Xaymar's Custom Prop Hunt ",
|
||||||
|
"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,50 @@
|
|||||||
|
--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")
|
||||||
|
|
||||||
|
-- Called when we take damge
|
||||||
|
function ENT:OnTakeDamage(dmg)
|
||||||
|
local pl = self.Owner
|
||||||
|
local attacker = dmg:GetAttacker()
|
||||||
|
local inflictor = dmg:GetInflictor()
|
||||||
|
|
||||||
|
-- Health
|
||||||
|
if pl && pl:IsValid() && pl:Alive() && pl:IsPlayer() && attacker:IsPlayer() && dmg:GetDamage() > 0 then
|
||||||
|
pl:SetHealth(pl:Health() - dmg:GetDamage())
|
||||||
|
|
||||||
|
if pl:Health() <= 0 then
|
||||||
|
-- Figure out real attacker.
|
||||||
|
if inflictor && inflictor == attacker && inflictor:IsPlayer() then
|
||||||
|
inflictor = inflictor:GetActiveWeapon()
|
||||||
|
if !inflictor || inflictor == NULL then inflictor = attacker end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Kill player and remove the prop
|
||||||
|
pl:KillSilent()
|
||||||
|
pl:RemoveProp() -- Needs to be executed before net.Broadcast
|
||||||
|
|
||||||
|
-- Send kill message.
|
||||||
|
net.Start( "PlayerKilledByPlayer" )
|
||||||
|
net.WriteEntity( pl )
|
||||||
|
net.WriteString( inflictor:GetClass() )
|
||||||
|
net.WriteEntity( attacker )
|
||||||
|
net.Broadcast()
|
||||||
|
|
||||||
|
-- Broadcast same message to all players in console.
|
||||||
|
MsgAll(attacker:Name() .. " found and killed " .. pl:Name() .. "\n")
|
||||||
|
|
||||||
|
-- Increment frags and deaths.
|
||||||
|
attacker:AddFrags(1)
|
||||||
|
pl:AddDeaths(1)
|
||||||
|
|
||||||
|
-- Update attacker health
|
||||||
|
attacker:SetHealth(math.Clamp(attacker:Health() + GetConVar("HUNTER_KILL_BONUS"):GetInt(), 1, 100))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
-- Entity information
|
||||||
|
ENT.Type = "anim"
|
||||||
|
ENT.Base = "base_anim"
|
||||||
|
|
||||||
|
-- Initialize
|
||||||
|
function ENT:Initialize()
|
||||||
|
self:SetModel("models/player/Kleiner.mdl")
|
||||||
|
self:DrawShadow(true);
|
||||||
|
|
||||||
|
-- Physical properties
|
||||||
|
self:SetSolid(SOLID_OBB)
|
||||||
|
|
||||||
|
-- Initialize Networked Variables
|
||||||
|
self:SetApplyNewAngles(false)
|
||||||
|
self:SetHealth(100)
|
||||||
|
if SERVER then self:SetMaxHealth(100) end
|
||||||
|
if CLIENT then self.Owner.ph_prop = self.Entity end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Set up shared Data.
|
||||||
|
function ENT:SetupDataTables()
|
||||||
|
self:NetworkVar( "Bool", 0, "ApplyNewAngles" )
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Update position
|
||||||
|
function ENT:Think()
|
||||||
|
-- Calculate hull size.
|
||||||
|
local hullOBBMin = self:OBBMins()
|
||||||
|
local hullOBBMax = self:OBBMaxs()
|
||||||
|
local hullOBB = hullOBBMax - hullOBBMin
|
||||||
|
|
||||||
|
-- Shared update
|
||||||
|
local pos = -Vector(0, 0, hullOBBMin.z)
|
||||||
|
self:SetPos(self.Owner:GetPos() + pos)
|
||||||
|
self:SetVelocity(self:GetOwner():GetVelocity())
|
||||||
|
|
||||||
|
-- Server only updates
|
||||||
|
if SERVER then
|
||||||
|
-- Prevent confusion by updating angles only on the server.
|
||||||
|
if self:GetApplyNewAngles() then
|
||||||
|
self:SetAngles(Angle(0, self:GetOwner():GetAngles().yaw, 0))
|
||||||
|
end
|
||||||
|
|
||||||
|
self:NextThink( CurTime() )
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,210 @@
|
|||||||
|
-- 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) end
|
||||||
|
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,178 @@
|
|||||||
|
-- Include the needed files
|
||||||
|
include("sh_init.lua")
|
||||||
|
--include("cl_hints.lua")
|
||||||
|
|
||||||
|
-- Draw round timeleft and hunter release timeleft
|
||||||
|
function HUDPaint()
|
||||||
|
if GetGlobalBool("InRound", false) then
|
||||||
|
local blindlock_time_left = (GetConVar("HUNTER_BLINDLOCK_TIME"):GetInt() - (CurTime() - GetGlobalFloat("RoundStartTime", 0))) + 1
|
||||||
|
|
||||||
|
if blindlock_time_left < 1 && blindlock_time_left > -6 then
|
||||||
|
blindlock_time_left_msg = "Hunters have been released!"
|
||||||
|
elseif blindlock_time_left > 0 then
|
||||||
|
blindlock_time_left_msg = "Hunters will be unblinded and released in "..string.ToMinutesSeconds(blindlock_time_left)
|
||||||
|
else
|
||||||
|
blindlock_time_left_msg = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
if LocalPlayer():Team() == TEAM_HUNTERS && blindlock_time_left > 1 then
|
||||||
|
draw.RoundedBox(0, 0, 0, surface.ScreenWidth(), surface.ScreenHeight(), Color(20, 20, 20, 255))
|
||||||
|
end
|
||||||
|
|
||||||
|
if blindlock_time_left_msg then
|
||||||
|
surface.SetFont("MyFont")
|
||||||
|
local tw, th = surface.GetTextSize(blindlock_time_left_msg)
|
||||||
|
|
||||||
|
draw.RoundedBox(8, 20, 20, tw + 20, 26, Color(0, 0, 0, 75))
|
||||||
|
draw.DrawText(blindlock_time_left_msg, "MyFont", 31, 26, Color(255, 255, 0, 255), TEXT_ALIGN_LEFT)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
hook.Add("HUDPaint", "PH_HUDPaint", HUDPaint)
|
||||||
|
|
||||||
|
-- Called immediately after starting the gamemode
|
||||||
|
function Initialize()
|
||||||
|
hullz = 80
|
||||||
|
--surface.CreateFont("Arial", 14, 1200, true, false, "ph_arial")
|
||||||
|
surface.CreateFont( "MyFont",
|
||||||
|
{
|
||||||
|
font = "Arial",
|
||||||
|
size = 14,
|
||||||
|
weight = 1200,
|
||||||
|
antialias = true,
|
||||||
|
underline = false
|
||||||
|
})
|
||||||
|
end
|
||||||
|
hook.Add("Initialize", "PH_Initialize", Initialize)
|
||||||
|
|
||||||
|
|
||||||
|
-- Resets the player hull
|
||||||
|
function ResetHull(um)
|
||||||
|
if LocalPlayer() && LocalPlayer():IsValid() then
|
||||||
|
LocalPlayer():ResetHull()
|
||||||
|
LocalPlayer():SetViewOffset(Vector(0, 0, 64))
|
||||||
|
LocalPlayer():SetViewOffsetDucked(Vector(0, 0, 28))
|
||||||
|
hullz = 80
|
||||||
|
end
|
||||||
|
end
|
||||||
|
usermessage.Hook("ResetHull", ResetHull)
|
||||||
|
|
||||||
|
|
||||||
|
-- Sets the local blind variable to be used in CalcView
|
||||||
|
function SetBlind(um)
|
||||||
|
blind = um:ReadBool()
|
||||||
|
end
|
||||||
|
usermessage.Hook("SetBlind", SetBlind)
|
||||||
|
|
||||||
|
|
||||||
|
function GM:ShouldDrawLocalPlayer()
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
function GM:CalcView( ply, pos, ang, fov )
|
||||||
|
local view = {
|
||||||
|
origin = pos,
|
||||||
|
angles = ang,
|
||||||
|
fov = fov
|
||||||
|
}
|
||||||
|
|
||||||
|
if ply:Team() == TEAM_PROPS && ply:Alive() then
|
||||||
|
-- Fix lua errors by doing this instead.
|
||||||
|
if LocalPlayer().ThirdPersonDistance == nil then
|
||||||
|
LocalPlayer().ThirdPersonDistance = 100
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Slowly return ThirdPersonDistance to 100
|
||||||
|
local traceDist = math.Clamp(LocalPlayer().ThirdPersonDistance * 0.98 + 100 * 0.02, 0, 100)
|
||||||
|
|
||||||
|
-- Trace a line to find the correct position for the camera.
|
||||||
|
local tracePos = pos
|
||||||
|
local trace = {
|
||||||
|
-- Start somewhat outside the prop.
|
||||||
|
start = tracePos - (ang:Forward() * 5),
|
||||||
|
endpos = tracePos - (ang:Forward() * (traceDist + 10)),
|
||||||
|
filter = function(ent)
|
||||||
|
if (ent == LocalPlayer() || ent == LocalPlayer().ph_prop || ent == LocalPlayer().ThirdPersonFilter || ent == ThirdPersonFilter) then
|
||||||
|
return false
|
||||||
|
elseif (ent:GetClass() == "ph_prop" || ent:GetClass() == "worldspawn") then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
}
|
||||||
|
local traceResult = util.TraceLine(trace);
|
||||||
|
|
||||||
|
-- Readjust trace hit distance to force camera outside of the hit position.
|
||||||
|
if traceResult.Hit then
|
||||||
|
traceDist = math.max(traceResult.HitPos:Distance(tracePos) - 10, 0)
|
||||||
|
end
|
||||||
|
LocalPlayer().ThirdPersonDistance = traceDist
|
||||||
|
|
||||||
|
-- Correct view position
|
||||||
|
view.origin = tracePos - (ang:Forward() * traceDist)
|
||||||
|
--[[ else
|
||||||
|
local wep = ply:GetActiveWeapon()
|
||||||
|
if wep && wep != NULL then
|
||||||
|
local func = wep.GetViewModelPosition
|
||||||
|
if func then
|
||||||
|
view.vm_origin, view.vm_angles = func(wep, origin*1, angles*1) -- Note: *1 to copy the object so the child function can't edit it.
|
||||||
|
end
|
||||||
|
|
||||||
|
local func = wep.CalcView
|
||||||
|
if func then
|
||||||
|
view.origin, view.angles, view.fov = func(wep, pl, origin*1, angles*1, fov) -- Note: *1 to copy the object so the child function can't edit it.
|
||||||
|
end
|
||||||
|
end--]]
|
||||||
|
end
|
||||||
|
|
||||||
|
return view;
|
||||||
|
end
|
||||||
|
|
||||||
|
-- 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)
|
||||||
|
|
||||||
|
-- UMSG: Update player Hull and health.
|
||||||
|
function UMSGSetHull(um)
|
||||||
|
local hullOBBMin = um:ReadVector()
|
||||||
|
local hullOBBMax = um:ReadVector()
|
||||||
|
local new_health = um:ReadShort()
|
||||||
|
|
||||||
|
LocalPlayer():NewHull(hullOBBMin, hullOBBMax)
|
||||||
|
LocalPlayer():SetHealth(new_health)
|
||||||
|
end
|
||||||
|
usermessage.Hook("SetHull", UMSGSetHull)
|
||||||
@@ -0,0 +1,93 @@
|
|||||||
|
|
||||||
|
|
||||||
|
surface.CreateFont( "GModWorldtip",
|
||||||
|
{
|
||||||
|
font = "Helvetica",
|
||||||
|
size = 20,
|
||||||
|
weight = 700
|
||||||
|
})
|
||||||
|
|
||||||
|
local cl_drawworldtooltips = CreateConVar( "cl_drawworldtooltips", "1", { FCVAR_ARCHIVE } )
|
||||||
|
local WorldTip = nil
|
||||||
|
|
||||||
|
local TipColor = Color( 250, 250, 200, 255 )
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Adds a hint to the queue
|
||||||
|
--
|
||||||
|
function AddWorldTip( unused1, text, unused2, pos, ent )
|
||||||
|
|
||||||
|
WorldTip = {}
|
||||||
|
|
||||||
|
WorldTip.dietime = SysTime() + 0.05
|
||||||
|
WorldTip.text = text
|
||||||
|
WorldTip.pos = pos
|
||||||
|
WorldTip.ent = ent
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
local function DrawWorldTip( tip )
|
||||||
|
|
||||||
|
if ( IsValid( tip.ent ) ) then
|
||||||
|
tip.pos = tip.ent:GetPos()
|
||||||
|
end
|
||||||
|
|
||||||
|
local pos = tip.pos:ToScreen()
|
||||||
|
|
||||||
|
local black = Color( 0, 0, 0, 255 )
|
||||||
|
local tipcol = Color( TipColor.r, TipColor.g, TipColor.b, 255 )
|
||||||
|
|
||||||
|
local x = 0
|
||||||
|
local y = 0
|
||||||
|
local padding = 10
|
||||||
|
local offset = 50
|
||||||
|
|
||||||
|
surface.SetFont( "GModWorldtip" )
|
||||||
|
local w, h = surface.GetTextSize( tip.text )
|
||||||
|
|
||||||
|
x = pos.x - w
|
||||||
|
y = pos.y - h
|
||||||
|
|
||||||
|
x = x - offset
|
||||||
|
y = y - offset
|
||||||
|
|
||||||
|
draw.RoundedBox( 8, x-padding-2, y-padding-2, w+padding*2+4, h+padding*2+4, black )
|
||||||
|
|
||||||
|
|
||||||
|
local verts = {}
|
||||||
|
verts[1] = { x=x+w/1.5-2, y=y+h+2 }
|
||||||
|
verts[2] = { x=x+w+2, y=y+h/2-1 }
|
||||||
|
verts[3] = { x=pos.x-offset/2+2, y=pos.y-offset/2+2 }
|
||||||
|
|
||||||
|
draw.NoTexture()
|
||||||
|
surface.SetDrawColor( 0, 0, 0, tipcol.a )
|
||||||
|
surface.DrawPoly( verts )
|
||||||
|
|
||||||
|
|
||||||
|
draw.RoundedBox( 8, x-padding, y-padding, w+padding*2, h+padding*2, tipcol )
|
||||||
|
|
||||||
|
local verts = {}
|
||||||
|
verts[1] = { x=x+w/1.5, y=y+h }
|
||||||
|
verts[2] = { x=x+w, y=y+h/2 }
|
||||||
|
verts[3] = { x=pos.x-offset/2, y=pos.y-offset/2 }
|
||||||
|
|
||||||
|
draw.NoTexture()
|
||||||
|
surface.SetDrawColor( tipcol.r, tipcol.g, tipcol.b, tipcol.a )
|
||||||
|
surface.DrawPoly( verts )
|
||||||
|
|
||||||
|
|
||||||
|
draw.DrawText( tip.text, "GModWorldtip", x + w/2, y, black, TEXT_ALIGN_CENTER )
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function GM:PaintWorldTips()
|
||||||
|
|
||||||
|
if ( !cl_drawworldtooltips:GetBool() ) then return end
|
||||||
|
|
||||||
|
if ( WorldTip && WorldTip.dietime > SysTime() ) then
|
||||||
|
DrawWorldTip( WorldTip )
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
--[[
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2015 Project Kube
|
||||||
|
|
||||||
|
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,401 @@
|
|||||||
|
--[[
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2015 Project Kube
|
||||||
|
|
||||||
|
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.
|
||||||
|
--]]
|
||||||
|
|
||||||
|
--! Client Files
|
||||||
|
AddCSLuaFile("cl_init.lua")
|
||||||
|
AddCSLuaFile("sh_init.lua")
|
||||||
|
|
||||||
|
--! Include shared lua.
|
||||||
|
include "sh_init.lua"
|
||||||
|
|
||||||
|
--! Include server lua.
|
||||||
|
include "server/config.lua"
|
||||||
|
include "server/console/variables.lua"
|
||||||
|
include "compat/compat_tauntpackloader.lua"
|
||||||
|
|
||||||
|
-- ------------------------------------------------------------------------- --
|
||||||
|
--! Gamemode
|
||||||
|
-- ------------------------------------------------------------------------- --
|
||||||
|
|
||||||
|
-- GameStates
|
||||||
|
GM_STATES_SETUP = 0
|
||||||
|
GM_STATES_HIDE = 1
|
||||||
|
GM_STATES_SEEK = 2
|
||||||
|
GM_STATES_SHAMING = 3 -- Do your best, hiders!
|
||||||
|
|
||||||
|
--! Initialize
|
||||||
|
function GM:Initialize()
|
||||||
|
self.State = GM_STATES_SETUP
|
||||||
|
self.StatePrev = self.State
|
||||||
|
|
||||||
|
--! Run any hooked functions that addons have registered for Prop Hunt.
|
||||||
|
hook.Run("OnPropHuntInitialized")
|
||||||
|
end
|
||||||
|
|
||||||
|
--! Check Victory and Loss conditions
|
||||||
|
function GM:Think()
|
||||||
|
if (self.State == GM_STATES_SETUP) then
|
||||||
|
--! GameState: Setup
|
||||||
|
-- Here we do all the stuff that would be ridiculous to do while playing.
|
||||||
|
if (self.StatePrev != self.State) then
|
||||||
|
game.CleanUpMap()
|
||||||
|
|
||||||
|
-- Assign correct teams depending on Sub-Gamemode.
|
||||||
|
if (self.Config.Modes.SwapTeams == 1) then
|
||||||
|
for i,pl in ipairs(player.GetAll()) do
|
||||||
|
if (pl:Team() == TEAM_HIDERS) then
|
||||||
|
pl:SetTeam(TEAM_SEEKERS)
|
||||||
|
elseif (pl:Team() == TEAM_SEEKERS) then
|
||||||
|
pl:SetTeam(TEAM_HIDERS)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
elseif (self.Config.Modes.RandomizeTeams == 1) then
|
||||||
|
local plys = player.GetAll()
|
||||||
|
--local plyCount =
|
||||||
|
|
||||||
|
elseif (self.Config.Modes.TheDeadHunt == 1) then
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Respawn players
|
||||||
|
for i,pl in ipairs(player.GetAll()) do
|
||||||
|
pl:Respawn()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Advanced to next GameState if we have enough players
|
||||||
|
self.StatePrev = self.State
|
||||||
|
self.State = GM_STATES_HIDE
|
||||||
|
elseif (self.State == GM_STATES_HIDE) then
|
||||||
|
|
||||||
|
elseif (self.State == GM_STATES_SEEK) then
|
||||||
|
|
||||||
|
elseif (self.State == GM_STATES_SHAMING) then
|
||||||
|
|
||||||
|
else
|
||||||
|
-- Invalid State, we have to reset
|
||||||
|
self.StatePrev = self.State
|
||||||
|
self.State = GM_STATES_SETUP
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- ------------------------------------------------------------------------- --
|
||||||
|
--! LEGACY CODE - TO BE REPLACED SOON
|
||||||
|
-- ------------------------------------------------------------------------- --
|
||||||
|
function GM:AllowPlayerPickup(player, entity)
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
|
||||||
|
-- Server only constants
|
||||||
|
EXPLOITABLE_DOORS = {
|
||||||
|
"func_door",
|
||||||
|
"prop_door_rotating",
|
||||||
|
"func_door_rotating"
|
||||||
|
}
|
||||||
|
USABLE_PROP_ENTITIES = {
|
||||||
|
"prop_physics",
|
||||||
|
"prop_physics_multiplayer"
|
||||||
|
}
|
||||||
|
|
||||||
|
-- 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 an entity takes damage
|
||||||
|
function EntityTakeDamage(ent, dmginfo)
|
||||||
|
local att = dmginfo:GetAttacker()
|
||||||
|
if GAMEMODE:InRound() && ent && ent:GetClass() != "ph_prop" && !ent:IsPlayer() && att && att:IsPlayer() && att:Team() == TEAM_HUNTERS && att:Alive() then
|
||||||
|
att:SetHealth(att:Health() - GetConVar("HUNTER_FIRE_PENALTY"):GetInt())
|
||||||
|
if att:Health() <= 0 then
|
||||||
|
MsgAll(att:Name() .. " felt guilty for hurting so many innocent props and committed suicide\n")
|
||||||
|
att:Kill()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
hook.Add("EntityTakeDamage", "PH_EntityTakeDamage", EntityTakeDamage)
|
||||||
|
|
||||||
|
|
||||||
|
-- Called when player tries to pickup a weapon
|
||||||
|
function GM:PlayerCanPickupWeapon(pl, ent)
|
||||||
|
if pl:Team() != TEAM_HUNTERS then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-- Called when player needs a model
|
||||||
|
function GM:PlayerSetModel(pl)
|
||||||
|
local player_model = pl:GetModel()
|
||||||
|
|
||||||
|
if pl:Team() == TEAM_HUNTERS then
|
||||||
|
player_model = "models/player/combine_super_soldier.mdl"
|
||||||
|
elseif pl:Team() == TEAM_PROPS then
|
||||||
|
player_model = "models/Gibs/Antlion_gib_small_3.mdl"
|
||||||
|
end
|
||||||
|
|
||||||
|
util.PrecacheModel(player_model)
|
||||||
|
pl:SetModel(player_model)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-- Called when a player tries to use an object
|
||||||
|
function GM:PlayerUse(pl, ent)
|
||||||
|
if !pl:Alive() || pl:Team() == TEAM_SPECTATOR then return false end
|
||||||
|
|
||||||
|
-- if pl:Team() == TEAM_PROPS && pl:IsOnGround() && !pl:Crouching() && table.HasValue(USABLE_PROP_ENTITIES, ent:GetClass()) && ent:GetModel() then
|
||||||
|
if pl:Team() == TEAM_PROPS && table.HasValue(USABLE_PROP_ENTITIES, ent:GetClass()) && ent:GetModel() then
|
||||||
|
if table.HasValue(BANNED_PROP_MODELS, ent:GetModel()) then
|
||||||
|
pl:ChatPrint("That prop has been banned by the server.")
|
||||||
|
elseif ent:GetPhysicsObject():IsValid() then -- && pl.ph_prop:GetModel() != ent:GetModel() then
|
||||||
|
local ent_health = math.Clamp(ent:GetPhysicsObject():GetVolume() / 250, 1, 200)
|
||||||
|
|
||||||
|
-- Prevent props from gaining health by changing.
|
||||||
|
local per = math.min(pl:Health() / pl:GetMaxHealth(), pl.tempHealthPc || 1.0)
|
||||||
|
if (pl.tempHealthPc == nil) || (per <= pl.tempHealthPc) then pl.tempHealthPc = per end
|
||||||
|
local new_health = math.Clamp(per * ent_health, 1, 200)
|
||||||
|
|
||||||
|
pl:SetJumpPower(math.Clamp(ent:GetPhysicsObject():GetVolume() / 333, 200, 600));
|
||||||
|
|
||||||
|
-- Set Prop Data
|
||||||
|
pl.ph_prop:SetHealth(new_health)
|
||||||
|
pl.ph_prop:SetMaxHealth(ent_health)
|
||||||
|
pl.ph_prop:SetModel(ent:GetModel())
|
||||||
|
pl.ph_prop:SetSkin(ent:GetSkin())
|
||||||
|
|
||||||
|
-- Update Hull and Health
|
||||||
|
pl:NewHull(ent:OBBMins(), ent:OBBMaxs())
|
||||||
|
pl:SetHealth(new_health)
|
||||||
|
pl:SetMaxHealth(ent_health)
|
||||||
|
umsg.Start("SetHull", pl)
|
||||||
|
umsg.Vector(ent:OBBMins())
|
||||||
|
umsg.Vector(ent:OBBMaxs())
|
||||||
|
umsg.Short(new_health)
|
||||||
|
umsg.End()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Prevent the door exploit
|
||||||
|
if table.HasValue(EXPLOITABLE_DOORS, ent:GetClass()) && pl.last_door_time && pl.last_door_time + 1 > CurTime() then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
pl.last_door_time = CurTime()
|
||||||
|
return true
|
||||||
|
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
|
||||||
|
|
||||||
|
-- Called when the gamemode is initialized
|
||||||
|
function Initialize()
|
||||||
|
game.ConsoleCommand("mp_flashlight 0\n")
|
||||||
|
end
|
||||||
|
hook.Add("Initialize", "PH_Initialize", Initialize)
|
||||||
|
|
||||||
|
|
||||||
|
-- Called when a player leaves
|
||||||
|
function PlayerDisconnected(pl)
|
||||||
|
pl:RemoveProp()
|
||||||
|
end
|
||||||
|
hook.Add("PlayerDisconnected", "PH_PlayerDisconnected", PlayerDisconnected)
|
||||||
|
|
||||||
|
|
||||||
|
-- Called when the players spawns
|
||||||
|
function PlayerSpawn(pl)
|
||||||
|
pl:Blind(false)
|
||||||
|
pl:RemoveProp()
|
||||||
|
pl:SetColor( Color(255, 255, 255, 255))
|
||||||
|
pl:SetRenderMode( RENDERMODE_TRANSALPHA )
|
||||||
|
pl:UnLock()
|
||||||
|
pl:ResetHull()
|
||||||
|
pl:SetViewOffset(Vector(0, 0, 64))
|
||||||
|
pl:SetViewOffsetDucked(Vector(0, 0, 28))
|
||||||
|
pl.last_taunt_time = 0
|
||||||
|
pl:SetupHands()
|
||||||
|
|
||||||
|
umsg.Start("ResetHull", pl)
|
||||||
|
umsg.End()
|
||||||
|
-- umsg.Start("ThirdPerson", pl)
|
||||||
|
-- umsg.Bool(pl:Team() == TEAM_PROPS)
|
||||||
|
-- umsg.Entity(nil)
|
||||||
|
-- umsg.End()
|
||||||
|
|
||||||
|
pl:SetCollisionGroup(COLLISION_GROUP_PASSABLE_DOOR)
|
||||||
|
end
|
||||||
|
hook.Add("PlayerSpawn", "PH_PlayerSpawn", PlayerSpawn)
|
||||||
|
|
||||||
|
function GM:PlayerSetHandsModel( ply, ent )
|
||||||
|
local simplemodel = player_manager.TranslateToPlayerModelName( ply:GetModel() )
|
||||||
|
local info = player_manager.TranslatePlayerHands( simplemodel )
|
||||||
|
if ( info ) then
|
||||||
|
ent:SetModel( info.model )
|
||||||
|
ent:SetSkin( info.skin )
|
||||||
|
ent:SetBodyGroups( info.body )
|
||||||
|
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)
|
||||||
|
|
||||||
|
|
||||||
|
-- Called when round ends
|
||||||
|
function RoundEnd()
|
||||||
|
for _, pl in pairs(team.GetPlayers(TEAM_HUNTERS)) do
|
||||||
|
pl:Blind(false)
|
||||||
|
pl:UnLock()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
hook.Add("RoundEnd", "PH_RoundEnd", RoundEnd)
|
||||||
|
|
||||||
|
|
||||||
|
-- This is called when the round time ends (props win)
|
||||||
|
function GM:RoundTimerEnd()
|
||||||
|
if !GAMEMODE:InRound() then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
GAMEMODE:RoundEndWithResult(TEAM_PROPS, "Props win!")
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-- Called before start of round
|
||||||
|
function GM:OnPreRoundStart(num)
|
||||||
|
game.CleanUpMap()
|
||||||
|
|
||||||
|
if GetGlobalInt("RoundNumber") != 1 && (SWAP_TEAMS_EVERY_ROUND == 1 || ((team.GetScore(TEAM_PROPS) + team.GetScore(TEAM_HUNTERS)) > 0 || SWAP_TEAMS_POINTS_ZERO==1)) then
|
||||||
|
for _, pl in pairs(player.GetAll()) do
|
||||||
|
if pl:Team() == TEAM_PROPS || pl:Team() == TEAM_HUNTERS then
|
||||||
|
if pl:Team() == TEAM_PROPS then
|
||||||
|
pl:SetTeam(TEAM_HUNTERS)
|
||||||
|
else
|
||||||
|
pl:SetTeam(TEAM_PROPS)
|
||||||
|
end
|
||||||
|
|
||||||
|
pl:ChatPrint("Teams have been swapped!")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
UTIL_StripAllPlayers()
|
||||||
|
UTIL_SpawnAllPlayers()
|
||||||
|
UTIL_FreezeAllPlayers()
|
||||||
|
end
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
-- Create new class
|
||||||
|
DEFINE_BASECLASS( "player_default" )
|
||||||
|
local CLASS = {}
|
||||||
|
|
||||||
|
-- Some settings for the class
|
||||||
|
CLASS.DisplayName = "Hider"
|
||||||
|
CLASS.WalkSpeed = 250
|
||||||
|
CLASS.CrouchedWalkSpeed = 0.2
|
||||||
|
CLASS.RunSpeed = 250
|
||||||
|
CLASS.DuckSpeed = 0.2
|
||||||
|
CLASS.DrawTeamRing = false
|
||||||
|
|
||||||
|
-- Called by spawn and sets loadout
|
||||||
|
function CLASS:Loadout(pl)
|
||||||
|
-- Props don't get anything
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Called when player spawns with this class
|
||||||
|
function CLASS:OnSpawn(pl)
|
||||||
|
pl:SetColor( Color(255, 255, 255, 0))
|
||||||
|
|
||||||
|
pl.ph_prop = ents.Create("ph_prop")
|
||||||
|
pl.ph_prop:SetPos(pl:GetPos())
|
||||||
|
pl.ph_prop:SetAngles(pl:GetAngles())
|
||||||
|
pl.ph_prop:Spawn()
|
||||||
|
pl.ph_prop:SetOwner(pl)
|
||||||
|
|
||||||
|
pl:SetJumpPower(200);
|
||||||
|
|
||||||
|
-- Update Hull and Health
|
||||||
|
pl:SetHealth(100)
|
||||||
|
pl:SetMaxHealth(100)
|
||||||
|
pl.ph_prop:SetHealth(100)
|
||||||
|
pl.ph_prop:SetMaxHealth(100)
|
||||||
|
|
||||||
|
local hullMin = Vector(-20, -20, -10)
|
||||||
|
local hullMax = Vector( 20, 20, 60)
|
||||||
|
pl:NewHull(hullMin, hullMax)
|
||||||
|
umsg.Start("SetHull", pl)
|
||||||
|
umsg.Vector(hullMin)
|
||||||
|
umsg.Vector(hullMax)
|
||||||
|
umsg.Short(100)
|
||||||
|
umsg.End()
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Called when a player dies with this class
|
||||||
|
function CLASS:OnDeath(pl, attacker, dmginfo)
|
||||||
|
pl:RemoveProp()
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Register
|
||||||
|
player_manager.RegisterClass("Hider", CLASS)
|
||||||
@@ -0,0 +1,120 @@
|
|||||||
|
--[[
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2015 Project Kube
|
||||||
|
|
||||||
|
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( "player_default" )
|
||||||
|
local SEEKER = {}
|
||||||
|
SEEKER.DisplayName = "Seeker"
|
||||||
|
SEEKER.WalkSpeed = 230 -- How fast to move when not running
|
||||||
|
SEEKER.RunSpeed = 460 -- How fast to move when running
|
||||||
|
SEEKER.CrouchedWalkSpeed = 0.2 -- Multiply move speed by this when crouching
|
||||||
|
SEEKER.DuckSpeed = 0.2 -- How fast to go from not ducking, to ducking
|
||||||
|
SEEKER.UnDuckSpeed = 0.2 -- How fast to go from ducking, to not ducking
|
||||||
|
SEEKER.JumpPower = 200 -- How powerful our jump should be
|
||||||
|
SEEKER.CanUseFlashlight = true -- Can we use the flashlight
|
||||||
|
SEEKER.MaxHealth = 100 -- Max health we can have
|
||||||
|
SEEKER.StartHealth = 100 -- How much health we start with
|
||||||
|
SEEKER.StartArmor = 0 -- How much armour we start with
|
||||||
|
SEEKER.DropWeaponOnDie = false -- Do we drop our weapon when we die
|
||||||
|
SEEKER.TeammateNoCollide = true -- Do we collide with teammates or run straight through them
|
||||||
|
SEEKER.AvoidPlayers = true -- Automatically swerves around other players
|
||||||
|
SEEKER.UseVMHands = true -- Uses viewmodel hands
|
||||||
|
|
||||||
|
-- Called by spawn and sets loadout
|
||||||
|
function SEEKER:Loadout(pl)
|
||||||
|
-- Give the weapons the admin told us to.
|
||||||
|
local weapons = string.Split(GM.Config.Seeker.Weapons, ",")
|
||||||
|
for i,weapon in ipairs(weapons) do
|
||||||
|
pl:Give(weapon)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Give the ammo the admin told us to.
|
||||||
|
local ammos = string.Split(GM.Config.Seeker.Ammo, ",")
|
||||||
|
for i,ammo in ipairs(ammos) do
|
||||||
|
local typeCount = string.Split(ammo, ":")
|
||||||
|
pl:GiveAmmo(typeCount[1], typeCount[0], true)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Default weapon stuff
|
||||||
|
local cl_defaultweapon = pl:GetInfo("cl_defaultweapon")
|
||||||
|
if pl:HasWeapon(cl_defaultweapon) then
|
||||||
|
pl:SelectWeapon(cl_defaultweapon)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Called when player spawns with this class
|
||||||
|
function SEEKER:OnSpawn(pl)
|
||||||
|
local unlock_time = math.Clamp(GetConVar("ph_rounds_blindtime"):GetInt() - (CurTime() - GetGlobalFloat("RoundStartTime", 0)), 0, GetConVar("ph_rounds_blindtime"):GetInt()) - 1
|
||||||
|
-- !TODO! ph_rounds_blindtime
|
||||||
|
|
||||||
|
--function MyLockFunc()
|
||||||
|
--function MyUnlockFunc()
|
||||||
|
|
||||||
|
local unblindfunc = function()
|
||||||
|
if pl:IsValid() == false then return end
|
||||||
|
--MyUnblindFunc(pl.Blind(false))
|
||||||
|
pl:Blind(false)
|
||||||
|
end
|
||||||
|
local lockfunc = function()
|
||||||
|
if pl:IsValid() == false then return end
|
||||||
|
--MyLockFunc(pl.Lock())
|
||||||
|
pl.Lock(pl)
|
||||||
|
end
|
||||||
|
local unlockfunc = function()
|
||||||
|
if pl:IsValid() == false then return end
|
||||||
|
--MyUnlockFunc(pl.UnLock())
|
||||||
|
pl.UnLock(pl)
|
||||||
|
end
|
||||||
|
|
||||||
|
if unlock_time > 2 then
|
||||||
|
pl:Blind(true)
|
||||||
|
|
||||||
|
timer.Simple(unlock_time, unblindfunc)
|
||||||
|
|
||||||
|
timer.Simple(1, lockfunc)
|
||||||
|
timer.Simple(unlock_time, unlockfunc)
|
||||||
|
end
|
||||||
|
|
||||||
|
pl:SetupHands()
|
||||||
|
end
|
||||||
|
|
||||||
|
function SEEKER:GetHandsModel()
|
||||||
|
return { model = "models/weapons/c_arms_combine.mdl", skin = 1, body = "0100000" }
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Called when a player dies with this SEEKER
|
||||||
|
function SEEKER:OnDeath(pl, attacker, dmginfo)
|
||||||
|
pl:CreateRagdoll()
|
||||||
|
pl:UnLock()
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Register
|
||||||
|
player_manager.RegisterClass("Seeker", SEEKER)
|
||||||
@@ -0,0 +1,433 @@
|
|||||||
|
--[[
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2015 Project Kube
|
||||||
|
|
||||||
|
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 = { }
|
||||||
|
|
||||||
|
--! Basic Settings
|
||||||
|
-- Timelimit in minutes
|
||||||
|
GM.Config.TimeLimit = math.max(GetConVarNumber("mp_timelimit"),0)
|
||||||
|
-- You have to wait x seconds to taunt again.
|
||||||
|
GM.Config.TauntWaitTime = 5
|
||||||
|
-- Is sprinting enabled?
|
||||||
|
GM.Config.Sprinting = 0 --false
|
||||||
|
|
||||||
|
--! Round Settings
|
||||||
|
GM.Config.Rounds = {}
|
||||||
|
-- How many rounds should we attempt to have?
|
||||||
|
GM.Config.Rounds.Amount = 10
|
||||||
|
-- Rounds last x seconds.
|
||||||
|
GM.Config.Rounds.Time = 300
|
||||||
|
-- Time for HIders to hide.
|
||||||
|
GM.Config.Rounds.BlindTime = 30
|
||||||
|
|
||||||
|
--! Game Modes
|
||||||
|
GM.Config.Modes = {}
|
||||||
|
-- Sub-mode: Simple Team Swap
|
||||||
|
GM.Config.Modes.SwapTeams = 1--true
|
||||||
|
-- Sub-mode: Randomize Teams
|
||||||
|
GM.Config.Modes.RandomizeTeams = 0--false
|
||||||
|
-- Sub-mode: The Dead Hunt (Dead Prop becomes Hunter)
|
||||||
|
GM.Config.Modes.TheDeadHunt = 0--false
|
||||||
|
|
||||||
|
--! Seeker Settings
|
||||||
|
GM.Config.Seeker = {}
|
||||||
|
GM.Config.Seeker.HealthStart = 100
|
||||||
|
GM.Config.Seeker.HealthMax = 100
|
||||||
|
GM.Config.Seeker.HealthBonus = 10
|
||||||
|
GM.Config.Seeker.HealthPenalty = 1
|
||||||
|
GM.Config.Seeker.Weapons = "weapon_crowbar,weapon_pistol,weapon_ph_smg,weapon_shotgun"
|
||||||
|
GM.Config.Seeker.Ammo = "Pistol:100,SMG1:300,SMG1_Grenade:1,Buckshot:64"
|
||||||
|
|
||||||
|
--! Hider Settings
|
||||||
|
GM.Config.Hider = {}
|
||||||
|
GM.Config.Hider.HealthStart = 100
|
||||||
|
GM.Config.Hider.HealthMax = 100
|
||||||
|
GM.Config.Hider.HealthScaling = 1--true
|
||||||
|
GM.Config.Hider.HealthScalingMax = 200
|
||||||
|
|
||||||
|
--! 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.Debug then print("Prop Hunt.Taunts.Load: Loading taunt list from file '"..sTauntListFile.."'...") end
|
||||||
|
|
||||||
|
-- Safeguard against idiots.
|
||||||
|
if type(sTauntListFile) != "string" then
|
||||||
|
if GAMEMODE.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.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.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.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.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.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.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.Debug then print("Prop Hunt.Taunts.Save: Saving taunt list to file '"..sTauntListFile.."'...") end
|
||||||
|
|
||||||
|
-- Safeguard against idiots.
|
||||||
|
if type(sTauntListFile) != "string" then
|
||||||
|
if GAMEMODE.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.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.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.Debug then print("Prop Hunt.Taunts.Save: Failed to write to file.") end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
if GAMEMODE.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.Debug then print("Prop Hunt.Taunts.Add: Adding new taunt '"..sTauntName.."'...") end
|
||||||
|
|
||||||
|
-- Safeguard against idiots.
|
||||||
|
if type(sTauntName) != "string" then
|
||||||
|
if GAMEMODE.Debug then print("Prop Hunt.Taunts.Add: <sTauntName> is not a string.") end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
if type(sSoundFile) != "string" then
|
||||||
|
if GAMEMODE.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.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.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.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.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.Debug then print("Prop Hunt.Taunts.Add: Team "..iTeamID.."' can't have taunts.") end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if GAMEMODE.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.Debug then print("Prop Hunt.Taunts.Remove: Removing taunt '"..sTauntName.."'...") end
|
||||||
|
|
||||||
|
-- Safeguard against idiots.
|
||||||
|
if type(sTauntName) != "string" then
|
||||||
|
if GAMEMODE.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.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.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.Debug then print("Prop Hunt.Taunts.Remove: Team "..iTeamID.."' can't have taunts.") end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if GAMEMODE.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.Debug then print("Prop Hunt.Announcers.Load: Loading announcer list from file '"..sAnnouncerListFile.."'...") end
|
||||||
|
|
||||||
|
-- Safeguard against idiots.
|
||||||
|
if type(sAnnouncerListFile) != "string" then
|
||||||
|
if GAMEMODE.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.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.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.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.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.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.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.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.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.Debug then print("Prop Hunt.Announcers.Save: Saving announcer list to file '"..sAnnouncerListFile.."'...") end
|
||||||
|
|
||||||
|
-- Safeguard against idiots.
|
||||||
|
if type(sAnnouncerListFile) != "string" then
|
||||||
|
if GAMEMODE.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.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.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.Debug then print("Prop Hunt.Announcers.Save: Failed to write to file.") end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
if GAMEMODE.Debug then print("Prop Hunt.Announcers.Save: Complete.") end
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
-- ToDo: Announcers.Add
|
||||||
|
-- ToDo: Announcers.Remove
|
||||||
|
-- ToDo: Announcers.Get(iType)
|
||||||
|
|
||||||
|
--! Whitelists and Blacklists
|
||||||
|
-- Hiders: Entity Whitelist (exact match)
|
||||||
|
GM.Config.EntityWhitelist = {
|
||||||
|
"prop_physics",
|
||||||
|
"prop_physics_multiplayer"
|
||||||
|
}
|
||||||
|
|
||||||
|
-- Hiders: Prop Blacklist (exact match)
|
||||||
|
GM.Config.PropBlacklist = {}
|
||||||
|
|
||||||
|
-- Both: Entity Use-abuse Blacklist (exact match)
|
||||||
|
GM.Config.EntityAbuseBlacklist = {
|
||||||
|
"func_door",
|
||||||
|
"func_door_rotating",
|
||||||
|
"prop_door_rotating"
|
||||||
|
}
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
--[[
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2015 Project Kube
|
||||||
|
|
||||||
|
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.
|
||||||
|
--]]
|
||||||
|
|
||||||
|
CreateConVar("ph_tauntwaittime", GM.Config.TauntWaitTime)
|
||||||
|
CreateConVar("ph_sprinting", GM.Config.Sprinting)
|
||||||
|
CreateConVar("ph_rounds", GM.Config.Rounds.Amount)
|
||||||
|
CreateConVar("ph_rounds_time", GM.Config.Rounds.Time)
|
||||||
|
CreateConVar("ph_rounds_blindtime", GM.Config.Rounds.BlindTime)
|
||||||
|
|
||||||
|
CreateConVar("ph_modes_swap", GM.Config.Modes.SwapTeams)
|
||||||
|
CreateConVar("ph_modes_randomize", GM.Config.Modes.RandomizeTeams)
|
||||||
|
CreateConVar("ph_modes_thedeadhunt", GM.Config.Modes.TheDeadHunt)
|
||||||
|
|
||||||
|
CreateConVar("ph_seeker_health", GM.Config.Seeker.HealthStart)
|
||||||
|
CreateConVar("ph_seeker_health_max", GM.Config.Seeker.HealthMax)
|
||||||
|
CreateConVar("ph_seeker_health_killbonus", GM.Config.Seeker.HealthBonus)
|
||||||
|
CreateConVar("ph_seeker_health_penalty", GM.Config.Seeker.HealthPenalty)
|
||||||
|
CreateConVar("ph_seeker_weapons", GM.Config.Seeker.Weapons)
|
||||||
|
CreateConVar("ph_seeker_ammo", GM.Config.Seeker.Ammo)
|
||||||
|
|
||||||
|
CreateConVar("ph_hider_health", GM.Config.Hider.HealthStart)
|
||||||
|
CreateConVar("ph_hider_health_max", GM.Config.Hider.HealthMax)
|
||||||
|
CreateConVar("ph_hider_health_scale", GM.Config.Hider.HealthScaling)
|
||||||
|
CreateConVar("ph_hider_health_scaled_max", GM.Config.Hider.HealthScalingMax)
|
||||||
@@ -0,0 +1,366 @@
|
|||||||
|
if !file.IsDir("prop_hunt", "DATA") then file.CreateDir("prop_hunt") end
|
||||||
|
|
||||||
|
-- These are Models that the Prop team can not become.
|
||||||
|
-- Usually you'd put invisible or impossible to hit models in here.
|
||||||
|
BANNED_PROP_MODELS = {
|
||||||
|
"models/props/cs_assault/dollar.mdl",
|
||||||
|
"models/props/cs_assault/money.mdl",
|
||||||
|
"models/props/cs_office/snowman_arm.mdl",
|
||||||
|
"models/props_junk/garbage_plasticbottle001a.mdl",
|
||||||
|
"models/props/cs_office/projector_remote.mdl"
|
||||||
|
}
|
||||||
|
if (! file.Exists("prop_hunt/banned_props.txt", "DATA")) then
|
||||||
|
file.Write("prop_hunt/banned_props.txt", util.TableToKeyValues(BANNED_PROP_MODELS))
|
||||||
|
end
|
||||||
|
local fileContent = file.Read("prop_hunt/banned_props.txt", "DATA");
|
||||||
|
if fileContent then
|
||||||
|
local fileTable = util.KeyValuesToTable(fileContent)
|
||||||
|
if fileTable then BANNED_PROP_MODELS = fileTable end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- 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
|
||||||
|
|
||||||
|
-- Maximum time (in minutes) for this fretta gamemode (Default: 30)
|
||||||
|
GAME_TIME = math.max(GetConVarNumber("mp_timelimit"),1)
|
||||||
|
|
||||||
|
-- Number of seconds hunters are blinded/locked at the beginning of the map (Default: 30)
|
||||||
|
CreateConVar("HUNTER_BLINDLOCK_TIME", "30", FCVAR_REPLICATED)
|
||||||
|
|
||||||
|
--Create the convars here
|
||||||
|
-- Health points removed from hunters when they shoot (Default: 5)
|
||||||
|
CreateConVar( "HUNTER_FIRE_PENALTY", "5", FCVAR_REPLICATED)
|
||||||
|
|
||||||
|
-- How much health to give back to the Hunter after killing a prop (Default: 20)
|
||||||
|
CreateConVar( "HUNTER_KILL_BONUS", "20", FCVAR_REPLICATED)
|
||||||
|
|
||||||
|
--Whether or not we include grenade launcher ammo (default: 1)
|
||||||
|
CreateConVar( "WEAPONS_ALLOW_GRENADE", "1", FCVAR_REPLICATED)
|
||||||
|
|
||||||
|
-- Seconds a player has to wait before they can taunt again (Default: 5)
|
||||||
|
TAUNT_DELAY = 2
|
||||||
|
|
||||||
|
-- Rounds played on a map (Default: 10)
|
||||||
|
ROUNDS_PER_MAP = 60
|
||||||
|
|
||||||
|
-- Time (in seconds) for each round (Default: 300)
|
||||||
|
ROUND_TIME = 300
|
||||||
|
|
||||||
|
-- Determains if players should be team swapped every round [0 = No, 1 = Yes] (Default: 1)
|
||||||
|
SWAP_TEAMS_EVERY_ROUND = 1
|
||||||
|
|
||||||
|
-- Update above values with values from configuration.
|
||||||
|
if (! file.Exists("prop_hunt/config.txt", "DATA")) then
|
||||||
|
file.Write("prop_hunt/config.txt", util.TableToKeyValues({
|
||||||
|
-- GAME_TIME = 30,
|
||||||
|
TAUNT_DELAY = 2,
|
||||||
|
ROUNDS_PER_MAP = 60,
|
||||||
|
ROUND_TIME = 300,
|
||||||
|
SWAP_TEAM_EVERY_ROUND = 1
|
||||||
|
}))
|
||||||
|
end
|
||||||
|
local fileContent = file.Read("prop_hunt/config.txt", "DATA");
|
||||||
|
if fileContent then
|
||||||
|
local fileTable = util.KeyValuesToTable(fileContent)
|
||||||
|
if fileTable then
|
||||||
|
-- if fileTable.GAME_TIME then GAME_TIME = fileTable.GAME_TIME end
|
||||||
|
if fileTable.TAUNT_DELAY then TAUNT_DELAY = fileTable.TAUNT_DELAY end
|
||||||
|
if fileTable.ROUNDS_PER_MAP then ROUNDS_PER_MAP = fileTable.ROUNDS_PER_MAP end
|
||||||
|
if fileTable.ROUND_TIME then ROUND_TIME = fileTable.ROUND_TIME end
|
||||||
|
if fileTable.SWAP_TEAM_EVERY_ROUND then ROUND_TIME = fileTable.SWAP_TEAM_EVERY_ROUND end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
GAME_TIME = math.max(GetConVarNumber("mp_timelimit"),1)
|
||||||
@@ -0,0 +1,93 @@
|
|||||||
|
-- Gamemode Information
|
||||||
|
GM.Name = "Prop Hunt"
|
||||||
|
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.Debug = (cvars.Number("developer") != 0)
|
||||||
|
|
||||||
|
-- ToDo: Remove fretta as a base gamemode (it's outdated and doesn't help us much).
|
||||||
|
DeriveGamemode("fretta13")
|
||||||
|
|
||||||
|
-- Shared Lua Files
|
||||||
|
if SERVER then
|
||||||
|
AddCSLuaFile("sh_config.lua")
|
||||||
|
AddCSLuaFile("sh_player.lua")
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Player Classes
|
||||||
|
if SERVER then
|
||||||
|
AddCSLuaFile("player_class/class_seeker.lua")
|
||||||
|
AddCSLuaFile("player_class/class_hider.lua")
|
||||||
|
end
|
||||||
|
include "player_class/class_seeker.lua"
|
||||||
|
include "player_class/class_hider.lua"
|
||||||
|
|
||||||
|
-- Set up Teams
|
||||||
|
TEAM_SPECTATOR = 0
|
||||||
|
TEAM_SEEKERS = 1
|
||||||
|
TEAM_HIDERS = 2
|
||||||
|
TEAM_HUNTERS = TEAM_SEEKERS -- Deprecated
|
||||||
|
TEAM_PROPS = TEAM_HIDERS -- Deprecated
|
||||||
|
|
||||||
|
function GM:CreateTeams()
|
||||||
|
-- Seekers: "Hunters"
|
||||||
|
team.SetUp(TEAM_SEEKERS, "Seekers", Color(153, 204, 255, 255))
|
||||||
|
team.SetSpawnPoint(TEAM_SEEKERS, {
|
||||||
|
"info_player_deathmatch",
|
||||||
|
"info_player_axis",
|
||||||
|
"info_player_combine",
|
||||||
|
"info_player_counterterrorist"
|
||||||
|
})
|
||||||
|
team.SetClass(TEAM_SEEKERS, { "Seeker" })
|
||||||
|
|
||||||
|
-- Hiders: "Props"
|
||||||
|
team.SetUp(TEAM_HIDERS, "Hiders", Color(255, 204, 153, 255))
|
||||||
|
team.SetSpawnPoint(TEAM_HIDERS, {
|
||||||
|
"info_player_deathmatch",
|
||||||
|
"info_player_allies",
|
||||||
|
"info_player_terrorist"
|
||||||
|
})
|
||||||
|
team.SetClass(TEAM_HIDERS, { "Hider" })
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-- Gamemode Player Code & Data
|
||||||
|
include("sh_player.lua")
|
||||||
|
|
||||||
|
-- Gamemode Configuration Code & Data
|
||||||
|
include("sh_config.lua")
|
||||||
|
|
||||||
|
-- Include the configuration for this map
|
||||||
|
if file.Exists("maps/"..game.GetMap()..".lua", "LUA") || file.Exists("maps/"..game.GetMap()..".lua", "LUA") then
|
||||||
|
include("maps/"..game.GetMap()..".lua")
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Help info
|
||||||
|
GM.Help = [[Prop Hunt is a twist on the classic backyard game Hide and Seek.
|
||||||
|
|
||||||
|
As a Prop you have ]]..GetConVar("HUNTER_BLINDLOCK_TIME"):GetInt()..[[ seconds to replicate an existing prop on the map and then find a good hiding spot. Press [E] to replicate the prop you are looking at. Your health is scaled based on the size of the prop you replicate.
|
||||||
|
|
||||||
|
As a Hunter you will be blindfolded for the first ]]..GetConVar("HUNTER_BLINDLOCK_TIME"):GetInt()..[[ seconds of the round while the Props hide. When your blindfold is taken off, you will need to find props controlled by players and kill them. Damaging non-player props will lower your health significantly. However, killing a Prop will increase your health by ]]..GetConVar("HUNTER_KILL_BONUS"):GetInt()..[[ points.
|
||||||
|
|
||||||
|
Both teams can press [F3] to play a taunt sound. Props can press F4 to enable rotation.]]
|
||||||
|
|
||||||
|
|
||||||
|
-- Fretta configuration
|
||||||
|
GM.AddFragsToTeamScore = true
|
||||||
|
GM.CanOnlySpectateOwnTeam = true
|
||||||
|
GM.Data = {}
|
||||||
|
GM.EnableFreezeCam = true
|
||||||
|
GM.GameLength = GAME_TIME
|
||||||
|
GM.NoAutomaticSpawning = true
|
||||||
|
GM.NoNonPlayerPlayerDamage = true
|
||||||
|
GM.NoPlayerPlayerDamage = true
|
||||||
|
GM.RoundBased = true
|
||||||
|
GM.RoundLimit = ROUNDS_PER_MAP
|
||||||
|
GM.RoundLength = ROUND_TIME
|
||||||
|
GM.RoundPreStartTime = 0
|
||||||
|
GM.SelectModel = false
|
||||||
|
GM.SuicideString = "couldn't take the pressure and committed suicide."
|
||||||
|
GM.TeamBased = true
|
||||||
@@ -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
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
--[[
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2015 Project Kube
|
||||||
|
|
||||||
|
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.
|
||||||
|
--]]
|
||||||
|
|
||||||
|
--! Our custom RoundManager
|
||||||
|
-- We need to keep track of three states in a round: Hide, Seek and PostRound.
|
||||||
|
|
||||||
|
--! Round States
|
||||||
|
ROUNDSTATE_HIDE = 1
|
||||||
|
ROUNDSTATE_SEEK = 2
|
||||||
|
ROUNDSTATE_POSTROUND = 3
|
||||||
|
|
||||||
|
function RoundManagerInit()
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
function RoundManagerAdvance()
|
||||||
|
|
||||||
|
end
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 48 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 127 KiB |
@@ -0,0 +1,50 @@
|
|||||||
|
<NotepadPlus>
|
||||||
|
<Project name="Prop Hunt">
|
||||||
|
<Folder name="gamemode">
|
||||||
|
<Folder name="compat">
|
||||||
|
<File name="gamemode\compat\compat_tauntpackloader.lua" />
|
||||||
|
</Folder>
|
||||||
|
<Folder name="player_class">
|
||||||
|
<File name="gamemode\player_class\class_seeker.lua" />
|
||||||
|
<File name="gamemode\player_class\class_hider.lua" />
|
||||||
|
</Folder>
|
||||||
|
<Folder name="server">
|
||||||
|
<Folder name="console">
|
||||||
|
<File name="gamemode\server\console\variables.lua" />
|
||||||
|
</Folder>
|
||||||
|
<File name="gamemode\server\config.lua" />
|
||||||
|
</Folder>
|
||||||
|
<File name="gamemode\cl_init.lua" />
|
||||||
|
<File name="gamemode\cl_worldtips.lua" />
|
||||||
|
<File name="gamemode\init.lua" />
|
||||||
|
<File name="gamemode\sh_config.lua" />
|
||||||
|
<File name="gamemode\sh_init.lua" />
|
||||||
|
<File name="gamemode\sh_player.lua" />
|
||||||
|
</Folder>
|
||||||
|
<Folder name="data">
|
||||||
|
<Folder name="prop_hunt">
|
||||||
|
<File name="data\prop_hunt\banned_props.txt" />
|
||||||
|
<File name="data\prop_hunt\config.txt" />
|
||||||
|
<File name="data\prop_hunt\sounds_loss.txt" />
|
||||||
|
<File name="data\prop_hunt\sounds_taunt_hunter.txt" />
|
||||||
|
<File name="data\prop_hunt\sounds_taunt_prop.txt" />
|
||||||
|
<File name="data\prop_hunt\sounds_victory.txt" />
|
||||||
|
</Folder>
|
||||||
|
</Folder>
|
||||||
|
<Folder name="entities">
|
||||||
|
<Folder name="entities">
|
||||||
|
<Folder name="ph_prop">
|
||||||
|
<File name="entities\entities\ph_prop\cl_init.lua" />
|
||||||
|
<File name="entities\entities\ph_prop\init.lua" />
|
||||||
|
<File name="entities\entities\ph_prop\shared.lua" />
|
||||||
|
</Folder>
|
||||||
|
</Folder>
|
||||||
|
<Folder name="weapons">
|
||||||
|
<File name="entities\weapons\weapon_ph_smg.lua" />
|
||||||
|
</Folder>
|
||||||
|
</Folder>
|
||||||
|
<File name="icon24.png" />
|
||||||
|
<File name="logo.png" />
|
||||||
|
<File name="xaymars_prop_hunt.txt" />
|
||||||
|
</Project>
|
||||||
|
</NotepadPlus>
|
||||||
@@ -0,0 +1,196 @@
|
|||||||
|
"xaymars_prop_hunt"
|
||||||
|
{
|
||||||
|
"base" "base"
|
||||||
|
"title" "Prop Hunt"
|
||||||
|
"maps" "^ph_|^cs_|^de_|^ttt_"
|
||||||
|
|
||||||
|
"fretta_maps"
|
||||||
|
{
|
||||||
|
"1" "ph_"
|
||||||
|
"2" "cs_"
|
||||||
|
"3" "de_"
|
||||||
|
"4" "ttt_"
|
||||||
|
}
|
||||||
|
"selectable" "1"
|
||||||
|
|
||||||
|
"menusystem" "1"
|
||||||
|
"workshopid" "468149739"
|
||||||
|
|
||||||
|
"settings"
|
||||||
|
{
|
||||||
|
// Game Settings
|
||||||
|
1
|
||||||
|
{
|
||||||
|
"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"
|
||||||
|
}
|
||||||
|
|
||||||
|
2
|
||||||
|
{
|
||||||
|
"name" "ph_sprinting"
|
||||||
|
"text" "G: Enable Sprinting"
|
||||||
|
"help" "Should sprinting be possible?"
|
||||||
|
"type" "CheckBox"
|
||||||
|
"default" "0"
|
||||||
|
}
|
||||||
|
|
||||||
|
3
|
||||||
|
{
|
||||||
|
"name" "ph_tauntwaittime"
|
||||||
|
"text" "G: Taunt Cooldown"
|
||||||
|
"help" "How much time must pass before another taunt may be played."
|
||||||
|
"type" "Numeric"
|
||||||
|
"default" "5"
|
||||||
|
}
|
||||||
|
|
||||||
|
// Round Settings
|
||||||
|
4
|
||||||
|
{
|
||||||
|
"name" "ph_rounds"
|
||||||
|
"text" "R: Rounds per Map"
|
||||||
|
"help" "How many rounds are played per map."
|
||||||
|
"type" "Numeric"
|
||||||
|
"default" "10"
|
||||||
|
}
|
||||||
|
|
||||||
|
5
|
||||||
|
{
|
||||||
|
"name" "ph_rounds_time"
|
||||||
|
"text" "R: Round Duration (Seconds)"
|
||||||
|
"help" "How long is each round going to last?"
|
||||||
|
"type" "Numeric"
|
||||||
|
"default" "300"
|
||||||
|
}
|
||||||
|
|
||||||
|
6
|
||||||
|
{
|
||||||
|
"name" "ph_rounds_blindtime"
|
||||||
|
"text" "R: Hiding Time (Seconds)"
|
||||||
|
"help" "How long are Seekers blinded in seconds?"
|
||||||
|
"type" "Numeric"
|
||||||
|
"default" "30"
|
||||||
|
}
|
||||||
|
|
||||||
|
7
|
||||||
|
{
|
||||||
|
"name" "ph_rounds_teams_swap"
|
||||||
|
"text" "R: Swap Teams every round?"
|
||||||
|
"help" "Should teams be swapped every round? (Can't be used with Randomize)"
|
||||||
|
"type" "CheckBox"
|
||||||
|
"default" "1"
|
||||||
|
}
|
||||||
|
|
||||||
|
8
|
||||||
|
{
|
||||||
|
"name" "ph_rounds_teams_randomize"
|
||||||
|
"text" "R: Randomize Teams every round?"
|
||||||
|
"help" "Should teams be randomized every round? (Can't be used with Swap)"
|
||||||
|
"type" "CheckBox"
|
||||||
|
"default" "0"
|
||||||
|
}
|
||||||
|
|
||||||
|
// Seeker Settings
|
||||||
|
9
|
||||||
|
{
|
||||||
|
"name" "ph_seeker_health"
|
||||||
|
"text" "S: Health"
|
||||||
|
"type" "Numeric"
|
||||||
|
"default" "100"
|
||||||
|
}
|
||||||
|
|
||||||
|
10
|
||||||
|
{
|
||||||
|
"name" "ph_seeker_health_max"
|
||||||
|
"text" "S: Max Health"
|
||||||
|
"type" "Numeric"
|
||||||
|
"default" "100"
|
||||||
|
}
|
||||||
|
|
||||||
|
11
|
||||||
|
{
|
||||||
|
"name" "ph_seeker_health_killbonus"
|
||||||
|
"text" "S: Health Kill-Bonus"
|
||||||
|
"help" "Health gained on kill."
|
||||||
|
"type" "Numeric"
|
||||||
|
"default" "10"
|
||||||
|
}
|
||||||
|
|
||||||
|
11
|
||||||
|
{
|
||||||
|
"name" "ph_seeker_health_penalty"
|
||||||
|
"text" "S: Health Penalty"
|
||||||
|
"help" "Health lost on wrong shot."
|
||||||
|
"type" "Numeric"
|
||||||
|
"default" "1"
|
||||||
|
}
|
||||||
|
|
||||||
|
12
|
||||||
|
{
|
||||||
|
"name" "ph_seeker_ammo_pistol"
|
||||||
|
"text" "S: Ammo for Pistol"
|
||||||
|
"type" "Numeric"
|
||||||
|
"default" "40"
|
||||||
|
}
|
||||||
|
|
||||||
|
13
|
||||||
|
{
|
||||||
|
"name" "ph_seeker_ammo_smg"
|
||||||
|
"text" "S: Ammo for SMG"
|
||||||
|
"type" "Numeric"
|
||||||
|
"default" "300"
|
||||||
|
}
|
||||||
|
|
||||||
|
14
|
||||||
|
{
|
||||||
|
"name" "ph_seeker_ammo_smggrenade"
|
||||||
|
"text" "S: Ammo for SMG Grenade"
|
||||||
|
"type" "Numeric"
|
||||||
|
"default" "1"
|
||||||
|
}
|
||||||
|
|
||||||
|
15
|
||||||
|
{
|
||||||
|
"name" "ph_seeker_ammo_shotgun"
|
||||||
|
"text" "S: Ammo for Shotgun"
|
||||||
|
"type" "Numeric"
|
||||||
|
"default" "60"
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hider Settings
|
||||||
|
16
|
||||||
|
{
|
||||||
|
"name" "ph_hider_health"
|
||||||
|
"text" "H: Health"
|
||||||
|
"type" "Numeric"
|
||||||
|
"default" "100"
|
||||||
|
}
|
||||||
|
|
||||||
|
17
|
||||||
|
{
|
||||||
|
"name" "ph_hider_health_max"
|
||||||
|
"text" "H: Max Health"
|
||||||
|
"type" "Numeric"
|
||||||
|
"default" "100"
|
||||||
|
}
|
||||||
|
|
||||||
|
18
|
||||||
|
{
|
||||||
|
"name" "ph_hider_health_scale"
|
||||||
|
"text" "H: Enable Health Scaling"
|
||||||
|
"help" "Larger & heavier objects have more health, smaller less."
|
||||||
|
"type" "CheckBox"
|
||||||
|
"default" "1"
|
||||||
|
}
|
||||||
|
|
||||||
|
19
|
||||||
|
{
|
||||||
|
"name" "ph_hider_health_scaled_max"
|
||||||
|
"text" "H: Scaled Max Health"
|
||||||
|
"type" "Numeric"
|
||||||
|
"default" "200"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
Binary file not shown.
|
After Width: | Height: | Size: 321 KiB |
@@ -0,0 +1,7 @@
|
|||||||
|
@ECHO OFF
|
||||||
|
:: Retrieve Garry's Mod path from Regristry
|
||||||
|
:: FOR /F "tokens=2* delims= " %%A IN ('REG QUERY "HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\Steam App 4000" /v InstallLocation') DO SET "GARRYSMODPATH=%%B"
|
||||||
|
SET "GARRYSMODPATH=D:\Program Files (x86)\Steam\steamapps\common\GarrysMod"
|
||||||
|
|
||||||
|
SET "PATH=%CD%;%GARRYSMODPATH%\bin;%PATH%"
|
||||||
|
CMD
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
@ECHO OFF
|
||||||
|
:: Fallback
|
||||||
|
SET "GARRYSMODPATH=D:\Program Files (x86)\Steam\steamapps\common\GarrysMod"
|
||||||
|
|
||||||
|
:: Retrieve Garry's Mod path from Regristry
|
||||||
|
FOR /F "tokens=2* delims= " %%A IN ('REG QUERY "HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\Steam App 4000" /v InstallLocation') DO SET "GARRYSMODPATH=%%B"
|
||||||
|
|
||||||
|
"%GARRYSMODPATH%\bin\gmad.exe" create -folder "%CD%/Gamemode" -out "%CD%/Pack.gma"
|
||||||
|
PAUSE
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
@ECHO OFF
|
||||||
|
:: Fallback
|
||||||
|
SET "GARRYSMODPATH=D:\Program Files (x86)\Steam\steamapps\common\GarrysMod"
|
||||||
|
|
||||||
|
:: Retrieve Garry's Mod path from Regristry
|
||||||
|
FOR /F "tokens=2* delims= " %%A IN ('REG QUERY "HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\Steam App 4000" /v InstallLocation') DO SET "GARRYSMODPATH=%%B"
|
||||||
|
|
||||||
|
SET /P CHANGES=Changes:
|
||||||
|
"%GARRYSMODPATH%\bin\gmpublish.exe" update -id 468149739 -icon "Logo.jpg" -addon "Pack.gma" -changes "%CHANGES%
|
||||||
|
PAUSE
|
||||||
Reference in New Issue
Block a user