9 Commits

Author SHA1 Message Date
Michael Fabian 'Xaymar' Dirks e609fb09f4 gamemode: Add support for name plates above players
Name plates are an easy way to identify other players without looking at them or relying on the Target id to appear (which should no longer happen). Several new cvars have been added to make this possible:

- ph_nameplates_show: Show or hide name plates.
- ph_nameplates_scale: World scale, a value of 1 makes 1 pixel equal 1 unit.
- ph_nameplates_height: Height above the player.
- ph_nameplates_tint_hue
- ph_nameplates_tint_saturation
- ph_nameplates_tint_value
- ph_nameplates_tint_health: Tint nameplate using the remaining health, 100% health = green, 0% health = red.
- ph_nameplates_tint_team: Tint nameplates using the players team.
2017-11-24 01:22:18 +01:00
Michael Fabian 'Xaymar' Dirks b5209f4b60 gamemode: Updated author and contact info
Before the 13th June 2016, the gamemode was indeed largely based on the version Kow@lski released to the Workshop (which was based on the original version AMT released). On 13th June 2016, I took it upon myself to completely rewrite the existing game mode to future proof it for years to come and make it incredibly easy to change.

This means that after the 13th June 2016, the sole author was and still is Michael Fabian 'Xaymar' Dirks.
2017-11-24 01:06:53 +01:00
Michael Fabian 'Xaymar' Dirks 3607102698 media: Use new and improved workshop logo 2017-11-20 05:03:21 +01:00
Michael Fabian 'Xaymar' Dirks 4ee354662f media: Improve ingame icon sharpness 2017-11-20 03:21:24 +01:00
Michael Fabian 'Xaymar' Dirks 98df2f2783 media: Convert ingame icon to Photoshop 2017-11-20 03:21:07 +01:00
Michael Fabian 'Xaymar' Dirks b8a7259d29 Merge code from old remote
The code was previously uploaded to GitLab on my own server, but that will soon no longer be available. Before this happens, here is the code and all updates that were done over there (matching the current released version).

# 27.12.2016 19:17

- Fixed ph_debug_log not showing player taunts.
- Fixed ph_taunt_hiders and ph_taunt_seekers showing left over code debugging messages.
- Fixed ph_teams_weighted the Seeker team, causing players winning Seekers to stay on the Seeker team.
- Added client and server camera ConVars (ph_camera_).
- Fixed camera collisions not using smooth transitions.
- Fixed player model incorrectly hiding too early.

# 18.12.2016 00:55

- Fixed ConVars not being taken from 'Start New Game' menu.
- Added descriptions for each Console Variable.
- Fixed Lua Error appearing when pressing Q as Spectator or Seeker.
- Fixed automatic Taunt Pack loading being overridden by ConVars.
- Fixed Blind Time being stuck at 0 seconds.

# 20.08.2016 18:24

- Fixed: Team Swapping now actually works instead of breaking when there is less than 4 players.
- Changed: Slightly reduced Prop Hitbox size to fix players getting stuck on each other.

# 20.07.2016 21:27

- Fixed a bug which would create both a clientside and a serverside ragdoll on listen servers.
- Added support for MapVote.
- Fixed PostMatch not checking for Round Limit and Map Limit properly.

# 20.06.2016 20:52

- Added taunting ability (ShowSpare1) and convars to define custom packs.
- Added ph_teams_weighted that will assign players using a weighted Score.
- Added convar to unlock Hider rotation to 3-Dimensional mode. (ph_hider_allow_full_rotation)
- Added debug command to print game statistics. (ph_debug_stats)
- Fixed Prop Rotation randomly being delayed by sending additional information.
- Fixed ph_teams_randomize that would assign all players to Seekers.
- Fixed a bug with ph_round_timelimit that made it ignore the blind time or double it.
- Changed Team convars to use the ph_teams_ prefix instead.
- Updated Game UI to look a little bit more modern.

# 19.06.2016 16:58

- Implemented a Gamemode hook to respect the current mp_friendlyfire setting. (0 = Off, 1 = On, 2 = Self-Damage)
- Implemented network messages for synchronized Kill Notifications.
- Implemented ConVars for Taunts for Seekers & Hiders. (ph_taunts_seekers,ph_taunts_hiders)
- Fixed a bug in which Seekers would be able to sprint while sprinting was disabled (and the other way around).
- Implemented Team randomization for 'Original' Gametype. (ph_round_randomizeteams)
2017-11-19 21:12:58 +01:00
Michael Fabian 'Xaymar' Dirks 704d38dd76 tools: Update logo location 2017-11-19 20:35:16 +01:00
Michael Fabian 'Xaymar' Dirks d331880199 Move Media to sub directory 2017-11-19 20:33:16 +01:00
Michael Fabian 'Xaymar' Dirks 282998baeb Automatically try both 32 and 64-bit paths for Tools 2017-11-19 20:32:08 +01:00
40 changed files with 1557 additions and 881 deletions
+3 -1
View File
@@ -1 +1,3 @@
Pack.gma Pack.gma
Changelog.txt
Description.txt
-15
View File
@@ -1,15 +0,0 @@
Changelist
-
ToDo:
- Replace all createconvar with getconvar?
- Other game modes
- UI stuff
- Scoreboard
- Custom Collisions for Hiders? Allows to copy the prop geometry/align with rotation
- Spectator: Spectate players(team only), first & third person
- UI: Proper Scoreboard replacement
- UI: Proper Team Selection replacement
- PostMatch: Implement Round Limit & Map Time Limit checking.
- PostMatch: Implement MapVoting? Or add support for MapVote addon?
- Seekers, Hiders: Taunts! And custom Taunts. And everything that belongs to that.
BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 269 KiB

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 212 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 152 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1003 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1003 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

@@ -23,7 +23,15 @@ function ENT:Think()
-- Angles -- Angles
if (self.Owner:GetNWBool("PropRotation")) then if (self.Owner:GetNWBool("PropRotation")) then
self:SetAngles(self.Owner:EyeAngles()) self:ApplyRotation(self.Owner:EyeAngles())
end end
end end
function ENT:ApplyRotation(ang)
if !(GAMEMODE.Config.Hider:AllowFullRotation()) then
ang.p = 0
ang.r = 0
end
self:SetAngles(ang)
end
@@ -0,0 +1,259 @@
-- 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"
}
-- 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"
}
-- 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"
}
-- 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"
}
@@ -41,8 +41,8 @@ function GM:Initialize()
print("Prop Hunt CL: Initializing Gamemode Data...") print("Prop Hunt CL: Initializing Gamemode Data...")
self.Data = {} self.Data = {}
print("Prop Hunt CL: Creating Huge Ass Font...") print("Prop Hunt CL: Creating Fonts...")
surface.CreateFont("PHHugeAssFont", {font="Roboto Bold Condensed", extended=true, size=160, weight=800, antialias=true}) surface.CreateFont("RobotoBoldCondensed160", {font="Roboto Bold Condensed", extended=true, size=160, weight=800, antialias=true})
print("Prop Hunt CL: Complete.") print("Prop Hunt CL: Complete.")
print("-------------------------------------------------------------------------") print("-------------------------------------------------------------------------")
@@ -51,7 +51,7 @@ end
function GM:Think() end function GM:Think() end
function GM:InitialPlayerSpawn() function GM:InitialPlayerSpawn()
print("Prop Hunt CL: InitialPlayerSpawn") if GAMEMODE.Config:DebugLog() then print("Prop Hunt CL: InitialPlayerSpawn") end
-- Delay execution until LocalPlayer() is valid. -- Delay execution until LocalPlayer() is valid.
if (!LocalPlayer()) || (!IsValid(LocalPlayer())) then if (!LocalPlayer()) || (!IsValid(LocalPlayer())) then
@@ -59,13 +59,13 @@ function GM:InitialPlayerSpawn()
return return
end end
print("Prop Hunt CL: InitialPlayerSpawn Valid") if GAMEMODE.Config:DebugLog() then print("Prop Hunt CL: InitialPlayerSpawn Valid") end
player_manager.RunClass(LocalPlayer(), "InitialClientSpawn") player_manager.RunClass(LocalPlayer(), "InitialClientSpawn")
end end
function GM:PlayerSpawn() function GM:PlayerSpawn()
print("Prop Hunt CL: PlayerSpawn") if GAMEMODE.Config:DebugLog() then print("Prop Hunt CL: PlayerSpawn") end
-- Delay execution until LocalPlayer() is valid. -- Delay execution until LocalPlayer() is valid.
if (!LocalPlayer()) || (!IsValid(LocalPlayer())) then if (!LocalPlayer()) || (!IsValid(LocalPlayer())) then
@@ -73,7 +73,7 @@ function GM:PlayerSpawn()
return return
end end
print("Prop Hunt CL: PlayerSpawn Valid") if GAMEMODE.Config:DebugLog() then print("Prop Hunt CL: PlayerSpawn Valid") end
if !(LocalPlayer().Data) then if !(LocalPlayer().Data) then
LocalPlayer().Data = {} LocalPlayer().Data = {}
@@ -106,8 +106,9 @@ function GM:PlayerSetViewOffset(vo, voduck)
if !(GAMEMODE.TempData) then GAMEMODE.TempData = {} end if !(GAMEMODE.TempData) then GAMEMODE.TempData = {} end
GAMEMODE.TempData.ViewOffset = vo GAMEMODE.TempData.ViewOffset = vo
GAMEMODE.TempData.ViewOffsetDuck = voduck GAMEMODE.TempData.ViewOffsetDuck = voduck
timer.Simple(.1, function()
timer.Simple(.1, function() GAMEMODE:PlayerSetViewOffset(GAMEMODE.TempData.ViewOffset, GAMEMODE.TempData.ViewOffsetDuck) end) GAMEMODE:PlayerSetViewOffset(GAMEMODE.TempData.ViewOffset, GAMEMODE.TempData.ViewOffsetDuck)
end)
return return
end end
@@ -126,8 +127,8 @@ function GM:PlayerSetHull(hullMin, hullMax)
if !(GAMEMODE.TempData) then GAMEMODE.TempData = {} end if !(GAMEMODE.TempData) then GAMEMODE.TempData = {} end
GAMEMODE.TempData.HullMin = hullMin GAMEMODE.TempData.HullMin = hullMin
GAMEMODE.TempData.HullMax = hullMax GAMEMODE.TempData.HullMax = hullMax
timer.Simple(.1, function()
timer.Simple(.1, function() GAMEMODE:PlayerSetHull(GAMEMODE.TempData.HullMin, GAMEMODE.TempData.HullMax) end) GAMEMODE:PlayerSetHull(GAMEMODE.TempData.HullMin, GAMEMODE.TempData.HullMax) end)
return return
end end
@@ -146,20 +147,24 @@ function GM:OnContextMenuOpen()
end end
function GM:OnContextMenuClose() function GM:OnContextMenuClose()
print("Prop Hunt CL: Toggled View Mode") if GAMEMODE.Config:DebugLog() then print("Prop Hunt CL: Toggled View Mode") end
LocalPlayer().Data.ThirdPerson = !LocalPlayer().Data.ThirdPerson LocalPlayer().Data.ThirdPerson = !LocalPlayer().Data.ThirdPerson
end end
function GM:OnSpawnMenuOpen() function GM:OnSpawnMenuOpen()
print("Prop Hunt CL: Enabling Prop Rotation") if GAMEMODE.Config:DebugLog() then print("Prop Hunt CL: Enabling Prop Rotation") end
LocalPlayer():SetNWBool("PropRotation", true) LocalPlayer():SetNWBool("PropRotation", true)
net.Start("PlayerEnablePropRotation");net.SendToServer() net.Start("PlayerEnablePropRotation")
net.WriteAngle(LocalPlayer():EyeAngles())
net.SendToServer()
end end
function GM:OnSpawnMenuClose() function GM:OnSpawnMenuClose()
print("Prop Hunt CL: Disabling Prop Rotation") if GAMEMODE.Config:DebugLog() then print("Prop Hunt CL: Disabling Prop Rotation") end
LocalPlayer():SetNWBool("PropRotation", false) LocalPlayer():SetNWBool("PropRotation", false)
net.Start("PlayerDisablePropRotation");net.SendToServer() net.Start("PlayerDisablePropRotation")
net.WriteAngle(LocalPlayer():EyeAngles())
net.SendToServer()
end end
function GM:ShowHelpUI() function GM:ShowHelpUI()
@@ -187,29 +192,46 @@ net.Receive( "PlayerViewOffset", function(len, pl)
GAMEMODE:PlayerSetViewOffset(vo, voduck) GAMEMODE:PlayerSetViewOffset(vo, voduck)
end) end)
-- ------------------------------------------------------------------------- --
--! Special Drawing
-- ------------------------------------------------------------------------- --
function DrawNamePlates(bDrawingDepth, bDrawingSkybox)
if (!GAMEMODE.Config.NamePlates:Show()) then
return
end
local scale = GAMEMODE.Config.NamePlates:Scale()
local pls = team.GetPlayers(GAMEMODE.Teams.Seekers)
if (LocalPlayer():Team() == GAMEMODE.Teams.Hiders) then
pls = table.Add(pls, team.GetPlayers(GAMEMODE.Teams.Hiders))
end
for i,v in ipairs(pls) do
if (v:Alive() && v != LocalPlayer()) then
local color = HSVToColor(GAMEMODE.Config.NamePlates:TintHue(),
GAMEMODE.Config.NamePlates:TintSaturation(),
GAMEMODE.Config.NamePlates:TintValue())
if GAMEMODE.Config.NamePlates:TintHealth() then
local healthPrc = v:Health() / v:GetMaxHealth()
color = HSVToColor(120 * healthPrc, 1.0, 1.0)
elseif GAMEMODE.Config.NamePlates:TintTeam() then
color = team.GetColor(v:Team())
end
local pos = v:GetPos() + v:GetViewOffset() + Vector(0, 0, GAMEMODE.Config.NamePlates:Height())
local ang = Angle(0, LocalPlayer():EyeAngles().y - 90, 90 - LocalPlayer():EyeAngles().x)
cam.Start3D2D(pos, ang, scale)
draw.DrawText(v:GetName(), "RobotoBoldCondensed160", 0, -draw.GetFontHeight("RobotoBoldCondensed160") / 2, color, TEXT_ALIGN_CENTER)
cam.End3D2D()
end
end
end
hook.Add("PostDrawTranslucentRenderables", "PHDrawNamePlates", DrawNamePlates)
-- ------------------------------------------------------------------------- -- -- ------------------------------------------------------------------------- --
--! Old Code --! Old Code
-- ------------------------------------------------------------------------- -- -- ------------------------------------------------------------------------- --
--[[ --[[
-- Render halos and player names.
function DrawPlayerNames(bDrawingDepth, bDrawingSkybox)
for i,v in ipairs(player.GetAll()) do
if v:Alive() && v != LocalPlayer() then
local pos = v:GetPos() + v:GetViewOffset() + Vector(0, 0, 5)
local ang = Angle(0, LocalPlayer():EyeAngles().y - 90, 90 - LocalPlayer():EyeAngles().x)
local healthPrc = v:Health() / v:GetMaxHealth()
local healthCol = HSVToColor(120 * healthPrc, 1.0, 1.0)
if v:Team() == TEAM_HUNTERS || LocalPlayer():Team() == TEAM_PROPS then
cam.Start3D2D(pos, ang, 0.15)
draw.DrawText(v:GetName(), "Trebuchet24", 0, -draw.GetFontHeight("Trebuchet24"), healthCol, TEXT_ALIGN_CENTER)
cam.End3D2D()
end
end
end
end
hook.Add("PostDrawTranslucentRenderables", "PH_DrawPlayerNames", DrawPlayerNames)
function DrawPlayerHalos(bDrawingDepth, bDrawingSkybox) function DrawPlayerHalos(bDrawingDepth, bDrawingSkybox)
for i,v in ipairs(player.GetAll()) do for i,v in ipairs(player.GetAll()) do
if v:Alive() then if v:Alive() then
@@ -23,7 +23,7 @@
--]] --]]
local PANEL = vgui.Create("DFrame") local PANEL = vgui.Create("DFrame")
PANEL:SetSize(400, 300) PANEL:SetSize(640, 480)
PANEL:SetTitle("Help") PANEL:SetTitle("Help")
PANEL:SetDraggable(true) PANEL:SetDraggable(true)
PANEL:SetVisible(false) PANEL:SetVisible(false)
@@ -32,30 +32,51 @@ PANEL:SetSizable(true)
PANEL:ShowCloseButton(true) PANEL:ShowCloseButton(true)
PANEL:SetDeleteOnClose(false) PANEL:SetDeleteOnClose(false)
function PANEL:Init()
DFrame.Init(self)
-- Sheets
self.Sheets = vgui.Create("DPropertySheet", self)
self.Sheets:Dock(FILL)
-- Basic Info
self.BasicInfoSheet = vgui.Create("DPanel", self.Sheets)
function self.BasicInfoSheet:Paint(w, h)
draw.RoundedBox(4, 0, 0, 100, 100, Color(0,128,255))
end
self.Sheets:AddSheet("The Gamemode", self.BasicInfoSheet)
end
function PANEL:Show() function PANEL:Show()
self:SetSize(ScrW(), ScrH()) --self:SetSize(ScrW(), ScrH())
self:Center() self:Center()
self:SetVisible(true) self:SetVisible(true)
self:SetFocusTopLevel(true) self:SetFocusTopLevel(true)
self:SlideDown(.5) self:SlideDown(.5)
self:MakePopup() self:MakePopup()
end end
function PANEL:Hide()
self:Close()
self:SetVisible(false)
end
GAMEMODE.UI.Help = PANEL function PANEL:Paint(w, h)
draw.RoundedBox(0, 0, 0, w, h, Color(0,0,0,240))
end
-- Sheets
local Element = vgui.Create("DPropertySheet", PANEL)
function Element:PAINT(w,h)
draw.RoundedBox(0, 0, 0, w, h, Color(0,0,0,240))
end
Element:Dock(FILL)
PANEL.Sheets = Element
PANEL.Sheet = {}
-- Basic Info
local Element = vgui.Create("DPanel", PANEL.Sheets)
function Element:Paint(w,h) end
PANEL.Sheets:AddSheet("The Gamemode", Element)
PANEL.Sheet.TheGamemode = Element
local Element = vgui.Create("DLabel", PANEL.Sheet.TheGamemode)
Element:Dock(TOP)
Element:SetMultiline(true)
Element:SetText([[
Prop Hunt Extended is a Gamemode based on the original Prop Hunt Gamemode. It changes many gameplay elements and features, adding the ability to easily integrate Taunt Packs, Configure Game parameters, rotate your prop and much more.
]])
-- Settings
PANEL.SettingsSheet = vgui.Create("DPanel", PANEL.Sheets)
PANEL.Sheets:AddSheet("Settings", PANEL.SettingsSheet)
GM.UI.Help = PANEL
@@ -22,6 +22,19 @@
SOFTWARE. SOFTWARE.
--]] --]]
local PANEL = vgui.Create("DFrame")
PANEL:SetSize(400, 300)
PANEL:SetTitle("Select a Team")
PANEL:SetDraggable(true)
PANEL:SetVisible(false)
PANEL:SetDraggable(true)
PANEL:SetSizable(true)
PANEL:ShowCloseButton(true)
PANEL:SetDeleteOnClose(false)
TeamSelectionUI = {} TeamSelectionUI = {}
TeamSelectionUI.Frame = vgui.Create("DFrame") TeamSelectionUI.Frame = vgui.Create("DFrame")
TeamSelectionUI.Frame:SetPos(0, 0) TeamSelectionUI.Frame:SetPos(0, 0)
@@ -0,0 +1,30 @@
--[[
The MIT License (MIT)
Copyright (c) 2015 Xaymar
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
--]]
local ELEMENT = {}
function ELEMENT:Paint()
end
vgui.Register("DMultilineLabel", ELEMENT, "Panel")
@@ -33,17 +33,36 @@ function CompatTauntPackLoader()
-- Run the old hook name. -- Run the old hook name.
hook.Run("ph_AddTaunts", nil) hook.Run("ph_AddTaunts", nil)
-- Insert the taunts into the new structure. -- Insert the taunts into the new structure (cvar).
for k,v in ipairs(GAMEMODE.Hunter_Taunts) do Taunts = {}
-- ToDo: string.GetFileFromFilename is broken! for i,t in ipairs(GAMEMODE.Prop_Taunts) do
--pcall(GAMEMODE.Config.Taunts.Add("TauntPackLoader."..string.GetFileFromFilename(v), v, TEAM_SEEKERES, nil)) ty = type(t)
if (ty == "string") then
Taunts[#Taunts+1] = t
elseif (ty == "table") then
Taunts[#Taunts+1] = t[2]
-- for j,snd in ipairs(t) do
-- HiderTaunts[#HiderTaunts+1] = snd
-- end
end
end end
for k,v in ipairs(GAMEMODE.Prop_Taunts) do GAMEMODE.Config.Taunt.HidersCacheStatic = Taunts
--pcall(GAMEMODE.Config.Taunts.Add("TauntPackLoader."..string.GetFileFromFilename(v), v, TEAM_HIDERS, nil)) Taunts = {}
for i,t in ipairs(GAMEMODE.Hunter_Taunts) do
ty = type(t)
if (ty == "string") then
Taunts[#Taunts+1] = t
elseif (ty == "table") then
Taunts[#Taunts+1] = t[2]
-- for j,snd in ipairs(t) do
-- SeekerTaunts[#SeekerTaunts+1] = snd
-- end
end
end end
GAMEMODE.Config.Taunt.SeekersCacheStatic = Taunts
-- Clean up after ourselves -- Clean up after ourselves
GAMEMODE.Prop_Taunts = nil GAMEMODE.Prop_Taunts = nil
GAMEMODE.Hunter_Taunts = nil GAMEMODE.Hunter_Taunts = nil
end end
hook.Add("OnPropHuntInitialized", "CompatTauntPackLoader", CompatTauntPackLoader) hook.Add("Initialize", "CompatTauntPackLoader", CompatTauntPackLoader)
@@ -28,7 +28,6 @@
-- Shared -- Shared
AddCSLuaFile("sh_init.lua") AddCSLuaFile("sh_init.lua")
AddCSLuaFile("sh_config.lua") AddCSLuaFile("sh_config.lua")
AddCSLuaFile("sh_player.lua")
AddCSLuaFile("player_class/class_default.lua") AddCSLuaFile("player_class/class_default.lua")
AddCSLuaFile("player_class/class_spectator.lua") AddCSLuaFile("player_class/class_spectator.lua")
AddCSLuaFile("player_class/class_seeker.lua") AddCSLuaFile("player_class/class_seeker.lua")
@@ -46,7 +45,6 @@ AddCSLuaFile("client/cl_ui_teamselection.lua")
include "sh_init.lua" include "sh_init.lua"
-- Server Only -- Server Only
include "server/config.lua"
include "compat/compat_tauntpackloader.lua" include "compat/compat_tauntpackloader.lua"
include "server/roundmanager.lua" include "server/roundmanager.lua"
include "server/states/state_prematch.lua" include "server/states/state_prematch.lua"
@@ -63,7 +61,6 @@ function GM:Initialize()
print("Prop Hunt: Registering Networked Messages...") print("Prop Hunt: Registering Networked Messages...")
util.AddNetworkString("PlayerManagerInitialClientSpawn") util.AddNetworkString("PlayerManagerInitialClientSpawn")
util.AddNetworkString("PlayerManagerClientSpawn") util.AddNetworkString("PlayerManagerClientSpawn")
util.AddNetworkString("PlayerSetHull") util.AddNetworkString("PlayerSetHull")
util.AddNetworkString("PlayerResetHull") util.AddNetworkString("PlayerResetHull")
util.AddNetworkString("PlayerViewOffset") util.AddNetworkString("PlayerViewOffset")
@@ -73,10 +70,15 @@ function GM:Initialize()
print("Prop Hunt: Initializing Gamemode Data...") print("Prop Hunt: Initializing Gamemode Data...")
self.Data = {} self.Data = {}
self.Data.StartTime = CurTime()
print("Prop Hunt: Setting initial RoundManager State...") print("Prop Hunt: Setting initial RoundManager State...")
self.RoundManager:SetState(StatePreMatch) self.RoundManager:SetState(StatePreMatch)
print("Prop Hunt: Precaching...")
GAMEMODE.Config.Taunt:Seekers()
GAMEMODE.Config.Taunt:Hiders()
print("Prop Hunt: Complete.") print("Prop Hunt: Complete.")
print("-------------------------------------------------------------------------") print("-------------------------------------------------------------------------")
end end
@@ -87,28 +89,29 @@ end
-- Player Connected -- Player Connected
function GM:PlayerConnect(name, ip) function GM:PlayerConnect(name, ip)
print("Prop Hunt: Player '"..name.."' connecting from IP '"..ip.."'.") if GAMEMODE.Config:DebugLog() then print("Prop Hunt: Player '"..name.."' connecting from IP '"..ip.."'.") end
end end
-- Player Authenticated -- Player Authenticated
function GM:PlayerAuthed(ply, steamid, uniqueid) function GM:PlayerAuthed(ply, steamid, uniqueid)
print("Prop Hunt: Player '"..ply:GetName().."' (SteamID: "..ply:SteamID()..") authenticated.") if GAMEMODE.Config:DebugLog() then print("Prop Hunt: Player '"..ply:GetName().."' (SteamID: "..ply:SteamID()..") authenticated.") end
end end
-- Player Disconnected -- Player Disconnected
function GM:PlayerDisconnected(ply) function GM:PlayerDisconnected(ply)
print("Prop Hunt: Player '"..ply:GetName().."' (SteamID: "..ply:SteamID()..") disconnected.") if GAMEMODE.Config:DebugLog() then print("Prop Hunt: Player '"..ply:GetName().."' (SteamID: "..ply:SteamID()..") disconnected.") end
end end
-- Player Spawn (Initial) -- Player Spawn (Initial)
function GM:PlayerInitialSpawn(ply) function GM:PlayerInitialSpawn(ply)
print("Prop Hunt: Player '"..ply:GetName().."' (SteamID: "..ply:SteamID()..") spawned for the first time, applying defaults...") if GAMEMODE.Config:DebugLog() then print("Prop Hunt: Player '"..ply:GetName().."' (SteamID: "..ply:SteamID()..") spawned for the first time, applying defaults...") end
if (!ply.Data) then if (!ply.Data) then
-- Initialize Data Structure -- Initialize Data Structure
ply.Data = {} ply.Data = {}
ply.Data.Alive = false ply.Data.Alive = false
ply.Data.AliveTime = 0 ply.Data.AliveTime = 0
ply.Data.RandomWeight = 0 -- Higher means higher chance of becoming Seeker instead of Hider.
end end
-- Kill Silently -- Kill Silently
@@ -121,10 +124,10 @@ function GM:PlayerInitialSpawn(ply)
-- Bot: Auto Assign to Team -- Bot: Auto Assign to Team
if (ply:IsBot()) then if (ply:IsBot()) then
if team.NumPlayers(self.Teams.Hiders) > team.NumPlayers(self.Teams.Seekers) then if team.NumPlayers(self.Teams.Hiders) > team.NumPlayers(self.Teams.Seekers) then
print("Prop Hunt: Bot '"..ply:GetName().."' assigned to Seekers.") if GAMEMODE.Config:DebugLog() then print("Prop Hunt: Bot '"..ply:GetName().."' assigned to Seekers.") end
ply:SetTeam(self.Teams.Seekers) ply:SetTeam(self.Teams.Seekers)
else else
print("Prop Hunt: Bot '"..ply:GetName().."' assigned to Hiders.") if GAMEMODE.Config:DebugLog() then print("Prop Hunt: Bot '"..ply:GetName().."' assigned to Hiders.") end
ply:SetTeam(self.Teams.Hiders) ply:SetTeam(self.Teams.Hiders)
end end
end end
@@ -138,7 +141,7 @@ end
-- Player Spawn -- Player Spawn
function GM:PlayerSpawn(ply) function GM:PlayerSpawn(ply)
print("Prop Hunt: Player '"..ply:GetName().."' (SteamID: "..ply:SteamID()..") spawned in.") if GAMEMODE.Config:DebugLog() then print("Prop Hunt: Player '"..ply:GetName().."' (SteamID: "..ply:SteamID()..") spawned in.") end
-- Player Manager: Assign Player Class -- Player Manager: Assign Player Class
local class = team.GetClass(ply:Team()) local class = team.GetClass(ply:Team())
@@ -167,7 +170,7 @@ end
-- Player requests Team Change -- Player requests Team Change
function GM:PlayerRequestTeam(ply, teamId) function GM:PlayerRequestTeam(ply, teamId)
if self:PlayerCanJoinTeam(ply, teamId) then if self:PlayerCanJoinTeam(ply, teamId) then
print("Prop Hunt: Player '"..ply:GetName().."' (SteamID: "..ply:SteamID()..") requested to join Team "..team.GetName(teamId)..".") if GAMEMODE.Config:DebugLog() then print("Prop Hunt: Player '"..ply:GetName().."' (SteamID: "..ply:SteamID()..") requested to join Team "..team.GetName(teamId)..".") end
if (ply:Team() != teamId) then if (ply:Team() != teamId) then
ply:KillSilent() ply:KillSilent()
@@ -178,7 +181,7 @@ function GM:PlayerRequestTeam(ply, teamId)
ply.AliveTime = CurTime() ply.AliveTime = CurTime()
end end
else else
print("Prop Hunt: Player '"..ply:GetName().."' (SteamID: "..ply:SteamID()..") attempted to rejoin the Team it is already in.") if GAMEMODE.Config:DebugLog() then print("Prop Hunt: Player '"..ply:GetName().."' (SteamID: "..ply:SteamID()..") attempted to rejoin the Team it is already in.") end
end end
end end
end end
@@ -187,7 +190,38 @@ end
--! Player Manager Binding --! Player Manager Binding
-- ------------------------------------------------------------------------- -- -- ------------------------------------------------------------------------- --
function GM:PlayerLoadout(ply) player_manager.RunClass(ply, "Loadout") end function GM:PlayerLoadout(ply) player_manager.RunClass(ply, "Loadout") end
function GM:PlayerDeath(ply, inflictor, attacker) player_manager.RunClass(ply, "Death", inflictor, attacker) end function GM:PlayerDeath(ply, inflictor, attacker)
player_manager.RunClass(ply, "Death", inflictor, attacker)
-- Signal Client Stuff
if IsValid(attacker) then
if attacker:IsPlayer() then
if (attacker == ply) then
net.Start("PlayerKilledSelf")
net.WriteEntity(ply)
net.Broadcast()
else
net.Start("PlayerKilledByPlayer")
net.WriteEntity(ply)
net.WriteString(inflictor:GetName())
net.WriteEntity(attacker)
net.Broadcast()
end
else
net.Start("PlayerKilled")
net.WriteEntity(ply)
net.WriteString(inflictor:GetName())
net.WriteString(attacker:GetClass())
net.Broadcast()
end
else
net.Start("PlayerKilled")
net.WriteEntity(ply)
net.WriteString(inflictor:GetName())
net.WriteString("World")
net.Broadcast()
end
end
function GM:PlayerSilentDeath(ply) player_manager.RunClass(ply, "SilentDeath") end function GM:PlayerSilentDeath(ply) player_manager.RunClass(ply, "SilentDeath") end
function GM:PostPlayerDeath(ply) function GM:PostPlayerDeath(ply)
player_manager.RunClass(ply, "PostDeath") player_manager.RunClass(ply, "PostDeath")
@@ -195,10 +229,10 @@ function GM:PostPlayerDeath(ply)
-- Debug Mode: Respawn after Death -- Debug Mode: Respawn after Death
if (GAMEMODE.Config:Debug()) then if (GAMEMODE.Config:Debug()) then
ply.Data.Alive = true ply.Data.Alive = true
print("Prop Hunt: Debug Mode active, Player "..ply:GetName().." was respawned.") if GAMEMODE.Config:DebugLog() then print("Prop Hunt: Debug Mode active, Player "..ply:GetName().." was respawned.") end
end end
end end
--function GM:DoPlayerDeath(ply, attacker, dmg) player_manager.RunClass(ply, "DoDeath", attacker, dmg) end function GM:DoPlayerDeath(ply, attacker, dmg) player_manager.RunClass(ply, "DoDeath", attacker, dmg) end
function GM:PlayerDeathThink(ply) return player_manager.RunClass(ply, "DeathThink") end function GM:PlayerDeathThink(ply) return player_manager.RunClass(ply, "DeathThink") end
function GM:CanPlayerSuicide(ply) return player_manager.RunClass(ply, "CanSuicide") end function GM:CanPlayerSuicide(ply) return player_manager.RunClass(ply, "CanSuicide") end
function GM:PlayerCanPickupWeapon(ply, weapon) return player_manager.RunClass(ply, "CanPickupWeapon", weapon) end function GM:PlayerCanPickupWeapon(ply, weapon) return player_manager.RunClass(ply, "CanPickupWeapon", weapon) end
@@ -219,6 +253,10 @@ end
-- ------------------------------------------------------------------------- -- -- ------------------------------------------------------------------------- --
--! Gamemode Functionality --! Gamemode Functionality
-- ------------------------------------------------------------------------- -- -- ------------------------------------------------------------------------- --
function GM:SetRound(Round)
SetGlobalInt("Round", Round)
end
function GM:SetRoundState(State) function GM:SetRoundState(State)
SetGlobalInt("RoundState", State) SetGlobalInt("RoundState", State)
end end
@@ -241,6 +279,7 @@ function GM:PlayerHullFromEntity(ply, ent)
hull.x = hull.y hull.x = hull.y
end end
hull:Mul(0.5) hull:Mul(0.5)
hull:Mul(0.95) -- Reduce size slightly
local hullmin = Vector(-hull.x, -hull.y, 0) local hullmin = Vector(-hull.x, -hull.y, 0)
local hullmax = Vector(hull.x, hull.y, hull.z * 2) local hullmax = Vector(hull.x, hull.y, hull.z * 2)
@@ -289,153 +328,65 @@ function GM:ShowTeam(ply)
ply:ConCommand("ph_select_team") ply:ConCommand("ph_select_team")
end end
-- F3/ShowSpare1 function GM:ShowSpare1(ply) player_manager.RunClass(ply, "ShowSpare1") end -- F3/ShowSpare1
function GM:ShowSpare1(ply) end function GM:ShowSpare2(ply) player_manager.RunClass(ply, "ShowSpare2") end -- F4/ShowSpare2
-- F4/ShowSpare2
function GM:ShowSpare2(ply) end
-- Debug Command: Print All Players -- Debug Command: Print All Players
concommand.Add("ph_debug_printplayers", function(ply, cmd, args, argStr) concommand.Add("ph_debug_printplayers", function(ply, cmd, args, argStr)
print ("All Players:") if GAMEMODE.Config:DebugLog() then
for i,ply in ipairs(player.GetAll()) do print ("All Players:")
print(" "..ply:GetName().." (SteamID: "..ply:SteamID()..") - Team "..team.GetName(ply:Team()).. " - Alive "..tostring(ply.Data.Alive)) for i,ply in ipairs(player.GetAll()) do
print(" "..ply:GetName().." (SteamID: "..ply:SteamID()..") - Team "..team.GetName(ply:Team()).. " - Alive "..tostring(ply.Data.Alive))
end
print ("Spectators:")
for i,ply in ipairs(team.GetPlayers(GAMEMODE.Teams.Spectators)) do
print(" "..ply:GetName().." (SteamID: "..ply:SteamID()..")")
end
print ("Seekers:")
for i,ply in ipairs(team.GetPlayers(GAMEMODE.Teams.Seekers)) do
print(" "..ply:GetName().." (SteamID: "..ply:SteamID()..")")
end
print ("Hiders:")
for i,ply in ipairs(team.GetPlayers(GAMEMODE.Teams.Hiders)) do
print(" "..ply:GetName().." (SteamID: "..ply:SteamID()..")")
end
end end
print ("Spectators:")
for i,ply in ipairs(team.GetPlayers(GAMEMODE.Teams.Spectators)) do
print(" "..ply:GetName().." (SteamID: "..ply:SteamID()..")")
end
print ("Seekers:")
for i,ply in ipairs(team.GetPlayers(GAMEMODE.Teams.Seekers)) do
print(" "..ply:GetName().." (SteamID: "..ply:SteamID()..")")
end
print ("Hiders:")
for i,ply in ipairs(team.GetPlayers(GAMEMODE.Teams.Hiders)) do
print(" "..ply:GetName().." (SteamID: "..ply:SteamID()..")")
end
end, nil, nil, FCVAR_CLIENTCMD_CAN_EXECUTE + FCVAR_CHEAT) end, nil, nil, FCVAR_CLIENTCMD_CAN_EXECUTE + FCVAR_CHEAT)
-- Debug Command: Print All Players
concommand.Add("ph_debug_stats", function(ply, cmd, args, argStr)
if GAMEMODE.Config:DebugLog() then
for i,ply in ipairs(player.GetAll()) do
print(ply:GetName().." (SteamID: "..ply:SteamID()..")")
print(" Team: "..team.GetName(ply:Team()))
print(" Alive: "..tostring(ply.Data.Alive))
print(" AliveTime: "..tostring(ply.Data.AliveTime))
print(" Score: "..tostring(ply.Data.RandomWeight))
end
end
end, nil, nil, FCVAR_CLIENTCMD_CAN_EXECUTE + FCVAR_CHEAT)
-- ------------------------------------------------------------------------- -- -- ------------------------------------------------------------------------- --
--! Network Messages --! Network Messages
-- ------------------------------------------------------------------------- -- -- ------------------------------------------------------------------------- --
net.Receive("PlayerEnablePropRotation", function(len, ply) net.Receive("PlayerEnablePropRotation", function(len, ply)
if (ply:Team() != GAMEMODE.Teams.Hiders) then
return
end
print("Prop Hunt: Enabling Prop Rotation") print("Prop Hunt: Enabling Prop Rotation")
ply:SetNWBool("PropRotation", true) ply:SetNWBool("PropRotation", true)
ply.Data.Prop:ApplyRotation(net.ReadAngle())
end) end)
net.Receive("PlayerDisablePropRotation", function(len, ply) net.Receive("PlayerDisablePropRotation", function(len, ply)
if (ply:Team() != GAMEMODE.Teams.Hiders) then
return
end
print("Prop Hunt: Disabling Prop Rotation") print("Prop Hunt: Disabling Prop Rotation")
ply:SetNWBool("PropRotation", false) ply:SetNWBool("PropRotation", false)
end) ply.Data.Prop:ApplyRotation(net.ReadAngle())
end)
-- ------------------------------------------------------------------------- --
--! LEGACY CODE - TO BE REPLACED SOON
-- ------------------------------------------------------------------------- --
--[[
function AnnounceVictory(players, force)
for i,pl in ipairs(players) do
if pl:Alive() || force || pl:Team() == TEAM_SPECTATOR then
announcer = table.Random(VICTORY_SOUNDS);
print("Prop Hunt: '"..pl:GetName().."' announcing victory with '"..announcer.."'.")
pl:EmitSound(announcer, 200, 100, 0.5, CHAN_VOICE2)
end
end
end
function AnnounceLoss(players, force)
for i,pl in ipairs(players) do
if pl:Alive() || force || pl:Team() == TEAM_SPECTATOR then
announcer = table.Random(LOSS_SOUNDS);
print("Prop Hunt: '"..pl:GetName().."' announcing loss with '"..announcer.."'.")
pl:EmitSound(announcer, 100, 100, 0.5, CHAN_VOICE2)
end
end
end
-- If there is a mapfile send it to the client (sometimes servers want to change settings for certain maps)
if file.Exists("maps/"..game.GetMap()..".lua", "LUA") then
AddCSLuaFile("maps/"..game.GetMap()..".lua")
end
-- Send the required resources to the client
for _, announcer in pairs(LOSS_SOUNDS) do resource.AddFile("sound/"..announcer) end
for _, announcer in pairs(VICTORY_SOUNDS) do resource.AddFile("source/"..announcer) end
for _, taunt in pairs(HUNTER_TAUNTS) do resource.AddFile("sound/"..taunt) end
for _, taunt in pairs(PROP_TAUNTS) do resource.AddFile("sound/"..taunt) end
-- Called alot
function GM:CheckPlayerDeathRoundEnd()
if !GAMEMODE.RoundBased || !GAMEMODE:InRound() then
return
end
local Teams = GAMEMODE:GetTeamAliveCounts()
if table.Count(Teams) == 0 then
GAMEMODE:RoundEndWithResult(1001, "Draw, everyone loses!")
AnnounceLoss(player.GetAll(), true)
return
end
if table.Count(Teams) == 1 then
-- Play victory and loss sounds.
if Teams[0] == TEAM_HUNTERS then
AnnounceVictory(team.GetPlayers(TEAM_HUNTERS))
AnnounceLoss(team.GetPlayers(TEAM_PROPS))
elseif Teams[0] == TEAM_PROPS then
AnnounceLoss(team.GetPlayers(TEAM_HUNTERS))
AnnounceVictory(team.GetPlayers(TEAM_PROPS))
end
local TeamID = table.GetFirstKey(Teams)
GAMEMODE:RoundEndWithResult(TeamID, team.GetName(TeamID).." win!")
return
end
end
-- Called when player presses [F3]. Plays a taunt for their team
function GM:ShowSpare1(pl)
if GAMEMODE:InRound() && pl:Alive() && (pl:Team() == TEAM_HUNTERS || pl:Team() == TEAM_PROPS) && pl.last_taunt_time + TAUNT_DELAY <= CurTime() && #PROP_TAUNTS > 1 && #HUNTER_TAUNTS > 1 then
-- repeat
if pl:Team() == TEAM_HUNTERS then
rand_taunt = table.Random(HUNTER_TAUNTS)
else
rand_taunt = table.Random(PROP_TAUNTS)
end
-- until rand_taunt != pl.last_taunt
pl.last_taunt_time = CurTime()
pl.last_taunt = rand_taunt
print("Prop Hunt: '"..pl:GetName().."' taunting with '"..rand_taunt.."'.")
local vol = 1.0
if pl:Team() == TEAM_HUNTERS then vol = vol * 0.5 end
pl:EmitSound(rand_taunt, 100, 100, vol, CHAN_VOICE2)
end
end
-- Allow player to rotate the prop. (Either F4 or ducking)
function GM:ShowSpare2(pl)
if pl:Alive() && (pl:Team() == TEAM_PROPS) then
pl.ph_prop:SetApplyNewAngles(!pl.ph_prop:GetApplyNewAngles())
-- pl.ph_prop:SetNewAngles(pl:GetAngles())
end
end
-- Removes all weapons on a map
function RemoveWeaponsAndItems()
for _, wep in pairs(ents.FindByClass("weapon_*")) do
wep:Remove()
end
for _, item in pairs(ents.FindByClass("item_*")) do
item:Remove()
end
end
hook.Add("InitPostEntity", "PH_RemoveWeaponsAndItems", RemoveWeaponsAndItems)
]]
@@ -49,6 +49,7 @@ function CLASS:Spawn() end
function CLASS:Loadout() end function CLASS:Loadout() end
-- Damage -- Damage
function CLASS:ShouldTakeDamage(attacker) return true end -- Should take damage from attacker?
function CLASS:Hurt(victim, attacker, healthRemaining, damageTaken) end -- Damage Taken function CLASS:Hurt(victim, attacker, healthRemaining, damageTaken) end -- Damage Taken
function CLASS:Damage(victim, attacker, healthRemaining, damageDealt) end -- Damage Dealt function CLASS:Damage(victim, attacker, healthRemaining, damageDealt) end -- Damage Dealt
function CLASS:DamageEntity(ent, attacker, dmginfo) end -- Damage Dealt To Entity function CLASS:DamageEntity(ent, attacker, dmginfo) end -- Damage Dealt To Entity
@@ -63,9 +64,7 @@ function CLASS:SilentDeath()
self.Player.Data.AliveTime = CurTime() self.Player.Data.AliveTime = CurTime()
end end
function CLASS:PostDeath() end function CLASS:PostDeath() end
function CLASS:DoDeath() end function CLASS:DoDeath() end
function CLASS:DeathThink() function CLASS:DeathThink()
if (CurTime() - self.Player.Data.AliveTime) > 5 then if (CurTime() - self.Player.Data.AliveTime) > 5 then
self.Player:Spawn() self.Player:Spawn()
@@ -73,7 +72,6 @@ function CLASS:DeathThink()
end end
return false return false
end end
function CLASS:CanSuicide() return true end function CLASS:CanSuicide() return true end
-- Visible Stuff -- Visible Stuff
@@ -109,6 +107,16 @@ function CLASS:AllowPickup(ent) return false end
function CLASS:CanPickupWeapon(ent) return false end function CLASS:CanPickupWeapon(ent) return false end
function CLASS:CanPickupItem(ent) return false end function CLASS:CanPickupItem(ent) return false end
-- Menu (Always Server)
function CLASS:ShowSpare1()
local lastTaunt = (self.Player.Data.LastTaunt or 0)
if ((CurTime() - lastTaunt) <= GAMEMODE.Config.Taunt:Cooldown()) then
return true
end
self.Player.Data.LastTaunt = CurTime()
end
function CLASS:ShowSpare2() end
-- ------------------------------------------------------------------------- -- -- ------------------------------------------------------------------------- --
--! Shared --! Shared
-- ------------------------------------------------------------------------- -- -- ------------------------------------------------------------------------- --
@@ -130,72 +138,52 @@ function CLASS:GetHandsModel() return BaseClass.GetHandsModel(self) end
function CLASS:ShouldDrawLocal() return false end function CLASS:ShouldDrawLocal() return false end
function CLASS:HUDPaint() function CLASS:HUDPaint()
local State = GetGlobalInt("RoundState", GAMEMODE.States.PreMatch) local State = GetGlobalInt("RoundState", GAMEMODE.States.PreMatch)
if State == -1 then
return
end
-- Show Status at the top center -- Status Box at the top.
local statusX, statusY, statusW, statusH local statusW, statusH = 256,48
statusW = 192 local statusX, statusY = ScrW() / 2 - statusW / 2, 0
statusH = 64 draw.RoundedBox(0, statusX, statusY, statusW, statusH, Color(0,0,0,204)) -- Background
statusX = ScrW() / 2 - statusW / 2 draw.RoundedBox(0, statusX, statusY+statusH, statusW, 4, team.GetColor(LocalPlayer():Team())) -- Team Bar
statusY = 16
-- Status -- Title
if (State == GAMEMODE.States.PreMatch) then -- Pre Match surface.SetFont("Trebuchet18")
draw.RoundedBox(16, statusX, statusY, statusW, statusH, Color(0, 0, 0, 204)) surface.SetTextColor(Color(255,255,255,255))
surface.SetFont( "Trebuchet24" ) local titleText = ""
surface.SetTextColor( 255, 255, 255, 255 ) if (State == GAMEMODE.States.PreMatch) then
local w,h = surface.GetTextSize("Waiting for Players") titleText = "Waiting for Players"
surface.SetTextPos( statusX + statusW/2 - w / 2, statusY + statusH/2 - h / 2) elseif (State == GAMEMODE.States.PreRound) then
surface.DrawText("Waiting for Players") titleText = "Preparing Round..."
elseif (State == GAMEMODE.States.PreRound) then -- Pre Round
draw.RoundedBox(16, statusX, statusY, statusW, statusH, Color(0, 0, 0, 204))
surface.SetFont( "Trebuchet24" )
surface.SetTextColor( 255, 255, 255, 255 )
local w,h = surface.GetTextSize("Preparing...")
surface.SetTextPos( statusX + statusW/2 - w / 2, statusY + statusH/2 - h / 2)
surface.DrawText( "Preparing..." )
elseif (State == GAMEMODE.States.Hide) then -- Hide elseif (State == GAMEMODE.States.Hide) then -- Hide
local strTime = tostring(math.ceil(GetGlobalInt("RoundTime"))) titleText = "Seekers unblinded in:"
-- Show Status at the top center
draw.RoundedBox(16, statusX, statusY, statusW, statusH, Color(0, 0, 0, 204))
surface.SetTextColor(255,255,255,255)
surface.SetFont("Trebuchet18")
local w,h = surface.GetTextSize("Seekers unblinded in:")
surface.SetTextPos(statusX + statusW/2 - w / 2, statusY + statusH/4 - h / 2)
surface.DrawText("Seekers unblinded in:")
surface.SetFont( "Trebuchet24" )
local w,h = surface.GetTextSize(strTime.." Seconds!")
surface.SetTextPos( statusX + statusW/2 - w / 2, statusY + statusH/1.5 - h / 2)
surface.DrawText(strTime.." Seconds!")
elseif (State == GAMEMODE.States.Seek) then -- Seek elseif (State == GAMEMODE.States.Seek) then -- Seek
titleText = "Seek Time!"
elseif (State == GAMEMODE.States.PostRound) then -- Post Round
titleText = "Match Result:"
elseif (State == GAMEMODE.States.PostMatch) then -- Post Match
end
local w,h = surface.GetTextSize(titleText)
surface.SetTextPos(statusX + statusW/2 - w/2, statusY)
surface.DrawText(titleText)
-- Subtitle
local stateText = ""
surface.SetFont("Trebuchet24")
surface.SetTextColor(Color(255,255,255,255))
if (State == GAMEMODE.States.PreMatch) then
stateText = tostring(team.NumPlayers(GAMEMODE.Teams.Seekers)) .. " Seeker(s), " .. tostring(team.NumPlayers(GAMEMODE.Teams.Hiders)) .. " Hider(s)"
elseif (State == GAMEMODE.States.PreRound) then
stateText = "Initiating..."
elseif (State == GAMEMODE.States.Hide) -- Hide
|| (State == GAMEMODE.States.Seek) then -- Seek
local intTime = math.ceil(GetGlobalInt("RoundTime")) local intTime = math.ceil(GetGlobalInt("RoundTime"))
local strTime = string.format("%d:%02d", math.floor(intTime / 60), math.ceil(intTime % 60)) local strTime = string.format("%d:%02d", math.floor(intTime / 60), math.ceil(intTime % 60))
stateText = strTime
-- Show Status at the top center
draw.RoundedBox(16, statusX, statusY, statusW, statusH, Color(0, 0, 0, 204))
surface.SetTextColor(255,255,255,255)
surface.SetFont("Trebuchet18")
local w,h = surface.GetTextSize("Hunting Time!")
surface.SetTextPos(statusX + statusW/2 - w / 2, statusY + statusH/4 - h / 2)
surface.DrawText("Hunting Time!")
surface.SetFont( "Trebuchet24" )
local w,h = surface.GetTextSize(strTime)
surface.SetTextPos( statusX + statusW/2 - w / 2, statusY + statusH/1.5 - h / 2)
surface.DrawText(strTime)
elseif (State == GAMEMODE.States.PostRound) then -- Post Round elseif (State == GAMEMODE.States.PostRound) then -- Post Round
-- Show Status at the top center
draw.RoundedBox(16, statusX, statusY, statusW, statusH, Color(0, 0, 0, 204))
surface.SetTextColor(255,255,255,255)
surface.SetFont("Trebuchet18")
local w,h = surface.GetTextSize("Match Result")
surface.SetTextPos(statusX + statusW/2 - w / 2, statusY + statusH/4 - h / 2)
surface.DrawText("Match Result")
local victor = GAMEMODE:GetRoundWinner() local victor = GAMEMODE:GetRoundWinner()
local victorName = "Unknown" local victorName = "Draw"
if (victor == GAMEMODE.Teams.Spectator) then if (victor == GAMEMODE.Teams.Spectator) then
victorName = "Draw" victorName = "Draw"
elseif (victor == GAMEMODE.Teams.Hiders) then elseif (victor == GAMEMODE.Teams.Hiders) then
@@ -203,17 +191,69 @@ function CLASS:HUDPaint()
elseif (victor == GAMEMODE.Teams.Seekers) then elseif (victor == GAMEMODE.Teams.Seekers) then
victorName = "Seekers Win" victorName = "Seekers Win"
end end
stateText = victorName
surface.SetTextColor(team.GetColor(victor)) surface.SetTextColor(team.GetColor(victor))
surface.SetFont( "Trebuchet24" )
local w,h = surface.GetTextSize(victorName)
surface.SetTextPos( statusX + statusW/2 - w / 2, statusY + statusH/1.5 - h / 2)
surface.DrawText(victorName)
elseif (State == GAMEMODE.States.PostMatch) then -- Post Match elseif (State == GAMEMODE.States.PostMatch) then -- Post Match
end end
local w,h = surface.GetTextSize(stateText)
surface.SetTextPos(statusX + statusW/2 - w/2, statusY + 32 - h / 2)
surface.DrawText(stateText)
-- Death Notices
GAMEMODE:DrawDeathNotice((ScrW() - 192) / ScrW() , 24 / ScrH())
end
function CLASS:CalcView(camdata)
-- Config
local cameraCollision = GAMEMODE.Config.Camera:Collisions()
local cameraDistance = GAMEMODE.Config.Camera:Distance()
local cameraDistanceRight = GAMEMODE.Config.Camera:DistanceRight()
local cameraDistanceUp = GAMEMODE.Config.Camera:DistanceUp()
local cameraLag = GAMEMODE.Config.Camera:Lag()
local cameraLagInv = 1 - cameraLag
-- First/Third Person Target Distance
local targetDistance = 0
if (self.Player.Data.ThirdPerson) then -- Incremental Distance instead of instant.
targetDistance = cameraDistance
if (cameraCollision == true) then
-- Trace from Player to would-be camera position
local trace = {
start = camdata.origin,
endpos = camdata.origin - (camdata.angles:Forward() * cameraDistance),
--filter = { "worldspawn", "ph_prop", "player" },
--[-[
filter = function(ent)
local filter = { "worldspawn", "ph_prop", "player" }
if (ent:IsPlayer())
|| (table.HasValue(filter, ent:GetClass()))
|| (ent == LocalPlayer()) || (ent == LocalPlayer():GetHands()) then
return false
end
return true
end,
--]]
}
local result = util.TraceLine(trace)
-- The Camera has a Sphere radius of 10.
if (result.Hit) then -- Configurable?
targetDistance = math.Clamp(result.HitPos:Distance(camdata.origin), 0, cameraDistance)
end
end
else
targetDistance = 0
end
-- Fade between Target and Current Distance
self.Player.Data.ViewDistance = math.Clamp(((self.Player.Data.ViewDistance or targetDistance) * cameraLag) + (targetDistance * cameraLagInv), 0, GAMEMODE.Config.Camera:DistanceMax())
-- Adjust CamData and return
camdata.origin = camdata.origin - (camdata.angles:Forward() * math.Clamp(self.Player.Data.ViewDistance - 10, 0, self.Player.Data.ViewDistance)) + (camdata.angles:Right() * cameraDistanceRight) + (camdata.angles:Up() * cameraDistanceUp)
return camdata
end end
function CLASS:CalcView(camdata) return camdata end
-- ------------------------------------------------------------------------- -- -- ------------------------------------------------------------------------- --
--! Register --! Register
@@ -35,26 +35,31 @@ CLASS.UseVMHands = false -- Uses viewmodel hands
-- ------------------------------------------------------------------------- -- -- ------------------------------------------------------------------------- --
-- Spawn -- Spawn
function CLASS:Spawn() function CLASS:Spawn()
print("Prop Hunt: Hider '"..self.Player:GetName().."' (SteamID: "..self.Player:SteamID()..") spawned.") if GAMEMODE.Config:DebugLog() then print("Prop Hunt: Hider '"..self.Player:GetName().."' (SteamID: "..self.Player:SteamID()..") spawned.") end
BaseClass.Spawn(self, self.Player) BaseClass.Spawn(self, self.Player)
-- Sprinting
if (!GAMEMODE.Config:Sprinting()) then
self.Player:SetRunSpeed(self.WalkSpeed)
end
-- Settings -- Settings
self.Player:SetMaxHealth(GAMEMODE.Config.Hider:HealthMax()) self.Player:SetMaxHealth(GAMEMODE.Config.Hider:HealthMax())
self.Player:SetHealth(GAMEMODE.Config.Hider:Health()) self.Player:SetHealth(GAMEMODE.Config.Hider:Health())
self.Player:SetRenderMode(RENDERMODE_TRANSALPHA) self.Player:SetRenderMode(RENDERMODE_TRANSALPHA)
self.Player:SetColor(Color(0,0,0,0)) self.Player:SetColor(Color(0,0,0,0))
-- Speed and Jump Power
self.Player:SetWalkSpeed(GAMEMODE.Config.Hider:WalkSpeed())
if (GAMEMODE.Config.Hider:Sprint()) then
self.Player:SetRunSpeed(GAMEMODE.Config.Hider:SprintSpeed())
else
self.Player:SetRunSpeed(GAMEMODE.Config.Hider:WalkSpeed())
end
self.Player:SetJumpPower(GAMEMODE.Config.Hider:JumpPower())
-- Hull & View Offset -- Hull & View Offset
GAMEMODE:PlayerHullFromEntity(self.Player, nil) GAMEMODE:PlayerHullFromEntity(self.Player, nil)
GAMEMODE:PlayerSetViewOffset(self.Player, Vector(0,0,72), Vector(0,0,72)) GAMEMODE:PlayerSetViewOffset(self.Player, Vector(0,0,72), Vector(0,0,72))
-- Collision Group -- Collision Group
self.Player:SetCollisionGroup(COLLISION_GROUP_PLAYER) self.Player:SetCollisionGroup(COLLISION_GROUP_PLAYER)
self.Player:SetSolid(SOLID_VPHYSICS)
-- Prop Stuff -- Prop Stuff
self.Player.Data.Prop = ents.Create("ph_prop") self.Player.Data.Prop = ents.Create("ph_prop")
@@ -70,7 +75,7 @@ end
-- Death -- Death
function CLASS:PostDeath(attacker, dmginfo) function CLASS:PostDeath(attacker, dmginfo)
print("Prop Hunt: Hider '"..self.Player:GetName().."' (SteamID: "..self.Player:SteamID()..") died.") if GAMEMODE.Config:DebugLog() then print("Prop Hunt: Hider '"..self.Player:GetName().."' (SteamID: "..self.Player:SteamID()..") died.") end
BaseClass.PostDeath(self, inflictor, attacker) BaseClass.PostDeath(self, inflictor, attacker)
-- Delete Hands Model -- Delete Hands Model
@@ -120,11 +125,11 @@ function CLASS:Use(ent)
end end
-- Check Lists and other Parameters -- Check Lists and other Parameters
if (!table.HasValue(GAMEMODE.Config.Lists:ClassWhitelist(), ent:GetClass()))-- Class is not Whitelisted if (!table.HasValue(GAMEMODE.Config.Lists:ClassWhitelist(), ent:GetClass())) -- Class is not Whitelisted
|| (GAMEMODE.Config.Lists.ModelBlacklist[ent:GetModel()]) -- Model is Blacklisted || (table.HasValue(GAMEMODE.Config.Lists:ModelBlacklist(), ent:GetModel())) -- Model is Blacklisted
|| !((ent:GetPhysicsObject()) && (ent:GetPhysicsObject():IsValid())) -- Entity doesn't have Physics || !((ent:GetPhysicsObject()) && (ent:GetPhysicsObject():IsValid())) -- Entity doesn't have Physics
then then
print("Prop Hunt: Hider '"..self.Player:GetName().."' (SteamID: "..self.Player:SteamID()..") attempted to turn into "..ent:GetClass().." ("..ent:GetModel()..").") if GAMEMODE.Config:DebugLog() then print("Prop Hunt: Hider '"..self.Player:GetName().."' (SteamID: "..self.Player:SteamID()..") attempted to turn into "..ent:GetClass().." ("..ent:GetModel()..").") end
return true -- Use instead of erroring. return true -- Use instead of erroring.
end end
@@ -155,11 +160,22 @@ function CLASS:Use(ent)
self.Player:SetMaxHealth(maxhealth) self.Player:SetMaxHealth(maxhealth)
end end
print("Prop Hunt: Hider '"..self.Player:GetName().."' (SteamID: "..self.Player:SteamID()..") turned into "..ent:GetClass().." ("..ent:GetModel()..").") if GAMEMODE.Config:DebugLog() then print("Prop Hunt: Hider '"..self.Player:GetName().."' (SteamID: "..self.Player:SteamID()..") turned into "..ent:GetClass().." ("..ent:GetModel()..").") end
end end
function CLASS:AllowPickup(ent) return true end function CLASS:AllowPickup(ent) return true end
-- Menu Buttons
function CLASS:ShowSpare1()
if BaseClass.ShowSpare1(self) then return end
-- Play a taunt
local tauntList = GAMEMODE.Config.Taunt:Hiders()
local index = math.random(#tauntList)
self.Player:EmitSound(tauntList[index], SNDLVL_NORM, 100, 1, CHAN_VOICE)
if GAMEMODE.Config:DebugLog() then print("Prop Hunt: Hider '"..self.Player:GetName().."' (SteamID: "..self.Player:SteamID()..") taunted with sound '"..tauntList[index].."'.") end
end
-- ------------------------------------------------------------------------- -- -- ------------------------------------------------------------------------- --
--! Shared --! Shared
-- ------------------------------------------------------------------------- -- -- ------------------------------------------------------------------------- --
@@ -168,71 +184,26 @@ function CLASS:AllowPickup(ent) return true end
--! Client-Side --! Client-Side
-- ------------------------------------------------------------------------- -- -- ------------------------------------------------------------------------- --
function CLASS:ClientSpawn() function CLASS:ClientSpawn()
print("Prop Hunt CL: Hider '"..self.Player:GetName().."' (SteamID: "..self.Player:SteamID()..") spawned.") if GAMEMODE.Config:DebugLog() then print("Prop Hunt CL: Hider '"..self.Player:GetName().."' (SteamID: "..self.Player:SteamID()..") spawned.") end
BaseClass.ClientSpawn(self, self.Player) BaseClass.ClientSpawn(self, self.Player)
self.Player:SetRenderMode(RENDERMODE_TRANSALPHA) self.Player:SetRenderMode(RENDERMODE_TRANSALPHA)
end end
function CLASS:ShouldDrawLocal() function CLASS:ShouldDrawLocal()
return false if (self.Player.Data.ViewDistance or 0) >= 10 then
end
function CLASS:CalcView(camdata)
-- ThirdPerson Settings (ToDo: client config maybe?)
local maxViewDist = 100
local viewDist = self.Player.Data.ViewDistance or 0
-- First/Third
if (self.Player.Data.ThirdPerson) then
if (IsValid(self.Player:GetHands())) then if (IsValid(self.Player:GetHands())) then
self.Player:GetHands():SetRenderMode(RENDERMODE_TRANSALPHA) self.Player:GetHands():SetRenderMode(RENDERMODE_TRANSALPHA)
self.Player:GetHands():SetColor(Color(255, 255, 255, 127)) self.Player:GetHands():SetColor(Color(255, 255, 255, 127))
end end
-- Incremental Distance instead of instant.
viewDist = math.Clamp(viewDist * 0.95 + maxViewDist * 0.05, 0, maxViewDist) -- Zoom Out
else else
if (IsValid(self.Player:GetHands())) then if (IsValid(self.Player:GetHands())) then
self.Player:GetHands():SetRenderMode(RENDERMODE_TRANSALPHA) self.Player:GetHands():SetRenderMode(RENDERMODE_TRANSALPHA)
self.Player:GetHands():SetColor(Color(255, 255, 255, 0)) self.Player:GetHands():SetColor(Color(255, 255, 255, 0))
end end
viewDist = math.Clamp(viewDist * 0.95, 0, maxViewDist) -- Zoom In
end end
-- Trace from Player to would-be camera position return (self.Player.Data.ViewDistance or 0) >= 10
local trace = {
start = camdata.origin,
endpos = camdata.origin - (camdata.angles:Forward() * viewDist),
--filter = { "worldspawn", "ph_prop" },
filter = function(ent)
local filter = { "worldspawn", "ph_prop" }
if (ent:IsPlayer())
|| (table.HasValue(filter, ent:GetClass()))
|| (ent == LocalPlayer()) || (ent == LocalPlayer():GetHands()) then
return false
end
return true
end
}
local result = util.TraceLine(trace)
-- The Camera has a Sphere radius of 10.
if (result.Hit) then -- Configurable?
viewDist = math.Clamp(result.HitPos:Distance(camdata.origin), 0, maxViewDist)
end
-- Store ViewDistance
self.Player.Data.ViewDistance = viewDist
-- Adjust CamData
camdata.origin = camdata.origin - (camdata.angles:Forward() * math.Clamp(viewDist - 10, 0, maxViewDist))
camdata.drawviewer = false
-- Return
return camdata
end end
-- Register -- Register
@@ -44,20 +44,24 @@ CLASS.DropWeaponOnDie = true
-- ------------------------------------------------------------------------- -- -- ------------------------------------------------------------------------- --
-- Spawn -- Spawn
function CLASS:Spawn() function CLASS:Spawn()
print("Prop Hunt: Seeker '"..self.Player:GetName().."' (SteamID: "..self.Player:SteamID()..") spawned.") if (GAMEMODE.Config:DebugLog()) then print("Prop Hunt: Seeker '"..self.Player:GetName().."' (SteamID: "..self.Player:SteamID()..") spawned.") end
BaseClass.Spawn(self) BaseClass.Spawn(self)
-- Sprinting
if (GAMEMODE.Config:Sprinting()) then
self.Player:SetRunSpeed(self.WalkSpeed)
end
-- Settings -- Settings
self.Player:SetMaxHealth(GAMEMODE.Config.Seeker:HealthMax()) self.Player:SetMaxHealth(GAMEMODE.Config.Seeker:HealthMax())
self.Player:SetHealth(GAMEMODE.Config.Seeker:Health()) self.Player:SetHealth(GAMEMODE.Config.Seeker:Health())
self.Player:SetRenderMode(RENDERMODE_NORMAL) self.Player:SetRenderMode(RENDERMODE_NORMAL)
self.Player:SetColor(Color(255,255,255,255)) self.Player:SetColor(Color(255,255,255,255))
-- Speed and Jump Power
self.Player:SetWalkSpeed(GAMEMODE.Config.Seeker:WalkSpeed())
if (GAMEMODE.Config.Seeker:Sprint()) then
self.Player:SetRunSpeed(GAMEMODE.Config.Seeker:SprintSpeed())
else
self.Player:SetRunSpeed(GAMEMODE.Config.Seeker:WalkSpeed())
end
self.Player:SetJumpPower(GAMEMODE.Config.Seeker:JumpPower())
-- Hull & View Offset -- Hull & View Offset
GAMEMODE:PlayerHullFromEntity(self.Player, nil) GAMEMODE:PlayerHullFromEntity(self.Player, nil)
GAMEMODE:PlayerSetViewOffset(self.Player, Vector(0,0,64), Vector(0,0,32)) GAMEMODE:PlayerSetViewOffset(self.Player, Vector(0,0,64), Vector(0,0,32))
@@ -85,15 +89,33 @@ function CLASS:Loadout()
end end
-- Damage -- Damage
function CLASS:Damage(victim, attacker, healthRemaining, damageDealt) end function CLASS:ShouldTakeDamage(attacker)
if (IsValid(attacker)) then
if (attacker:IsPlayer()) then
if (attacker:Team() == self.Player:Team()) then
local ffmode = GetConVarNumber("mp_friendlyfire")
if (ffmode == 0) then -- Not Allowed
return false
elseif (ffmode == 2) then -- Damage self instead
if (IsValid(attacker) && attacker:IsPlayer()) then
attacker:SetHealth(attacker:Health() - damageTaken)
end
return false
end
end
end
end
return true
end
function CLASS:DamageEntity(ent, att, dmg) function CLASS:DamageEntity(ent, att, dmg)
print("Prop Hunt: Seeker '"..self.Player:GetName().."' (SteamID: "..self.Player:SteamID()..") damaged entity "..ent:GetClass()..".") if (GAMEMODE.Config:DebugLog()) then print("Prop Hunt: Seeker '"..self.Player:GetName().."' (SteamID: "..self.Player:SteamID()..") damaged entity "..ent:GetClass()..".") end
-- Only take damage during this phase. -- Only take damage during this phase.
if (GAMEMODE:GetRoundState() == GAMEMODE.States.Seek) then if (GAMEMODE:GetRoundState() == GAMEMODE.States.Seek) then
if IsValid(ent) && (!(ent:IsPlayer())) then if IsValid(ent) && (!(ent:IsPlayer())) then
if (ent:GetClass() == "ph_prop") then if (ent:GetClass() == "ph_prop") then
ent:GetOwner():TakeDamageInfo(dmg) ent:GetOwner():TakeDamageInfo(dmg)
self.Player.Data.RandomWeight = self.Player.Data.RandomWeight - 1
elseif (ent:GetClass() == "func_breakable") then -- ToDo: Make Configurable which entities don't hurt? elseif (ent:GetClass() == "func_breakable") then -- ToDo: Make Configurable which entities don't hurt?
else else
att:TakeDamage(GAMEMODE.Config.Seeker:HealthPenalty(), ent, ent) att:TakeDamage(GAMEMODE.Config.Seeker:HealthPenalty(), ent, ent)
@@ -106,11 +128,14 @@ end
function CLASS:Death(inflictor, attacker) function CLASS:Death(inflictor, attacker)
BaseClass.Death(self, inflictor, attacker) BaseClass.Death(self, inflictor, attacker)
self.Player:CreateRagdoll() if SERVER then
self.Player:SetShouldServerRagdoll(true)
--self.Player:CreateRagdoll()
end
end end
function CLASS:PostDeath() function CLASS:PostDeath()
print("Prop Hunt: Seeker '"..self.Player:GetName().."' (SteamID: "..self.Player:SteamID()..") died.") if (GAMEMODE.Config:DebugLog()) then print("Prop Hunt: Seeker '"..self.Player:GetName().."' (SteamID: "..self.Player:SteamID()..") died.") end
BaseClass.PostDeath(self, inflictor, attacker) BaseClass.PostDeath(self, inflictor, attacker)
self.Player:UnLock() self.Player:UnLock()
@@ -148,11 +173,22 @@ function CLASS:AllowPickup(ent) return true end
function CLASS:CanPickupItem(ent) return true end function CLASS:CanPickupItem(ent) return true end
function CLASS:CanPickupWeapon(ent) return true end function CLASS:CanPickupWeapon(ent) return true end
-- Menu Buttons
function CLASS:ShowSpare1()
if BaseClass.ShowSpare1(self) then return end
-- Play a taunt
local tauntList = GAMEMODE.Config.Taunt:Seekers()
local index = math.random(#tauntList)
self.Player:EmitSound(tauntList[index], SNDLVL_NORM, 100, 1, CHAN_VOICE)
if GAMEMODE.Config:DebugLog() then print("Prop Hunt: Seeker '"..self.Player:GetName().."' (SteamID: "..self.Player:SteamID()..") taunted with sound '"..tauntList[index].."'.") end
end
-- ------------------------------------------------------------------------- -- -- ------------------------------------------------------------------------- --
--! Client-Side --! Client-Side
-- ------------------------------------------------------------------------- -- -- ------------------------------------------------------------------------- --
function CLASS:ClientSpawn() function CLASS:ClientSpawn()
print("Prop Hunt CL: Seeker '"..self.Player:GetName().."' (SteamID: "..self.Player:SteamID()..") spawned.") if (GAMEMODE.Config:DebugLog()) then print("Prop Hunt CL: Seeker '"..self.Player:GetName().."' (SteamID: "..self.Player:SteamID()..") spawned.") end
BaseClass.ClientSpawn(self) BaseClass.ClientSpawn(self)
end end
@@ -181,53 +217,7 @@ function CLASS:HUDPaint()
end end
function CLASS:ShouldDrawLocal() function CLASS:ShouldDrawLocal()
return self.Player.Data.ThirdPerson return (self.Player.Data.ViewDistance or 0) >= 10
end
function CLASS:CalcView(camdata)
-- ThirdPerson Settings (ToDo: client config maybe?)
local maxViewDist = 100
local viewDist = self.Player.Data.ViewDistance or 0
-- First/Third
if (self.Player.Data.ThirdPerson) then
viewDist = math.Clamp(viewDist * 0.95 + maxViewDist * 0.05, 0, maxViewDist) -- Zoom Out
else
viewDist = math.Clamp(viewDist * 0.95, 0, maxViewDist) -- Zoom In
end
-- Trace from Player to would-be camera position
local trace = {
start = camdata.origin,
endpos = camdata.origin - (camdata.angles:Forward() * viewDist),
--filter = { "worldspawn", "ph_prop" },
filter = function(ent)
local filter = { "worldspawn", "ph_prop" }
if (ent:IsPlayer())
|| (table.HasValue(filter, ent:GetClass()))
|| (ent == LocalPlayer()) || (ent == LocalPlayer():GetHands()) then
return false
end
return true
end
}
local result = util.TraceLine(trace)
-- The Camera has a Sphere radius of 10.
if (result.Hit) then -- Configurable?
viewDist = math.Clamp(result.HitPos:Distance(camdata.origin), 0, maxViewDist)
end
-- Store ViewDistance
self.Player.Data.ViewDistance = viewDist
-- Adjust CamData
camdata.origin = camdata.origin - (camdata.angles:Forward() * math.Clamp(viewDist - 10, 0, maxViewDist))
--camdata.drawviewer = false
-- Return
return camdata
end end
-- Register -- Register
@@ -35,7 +35,7 @@ CLASS.UseVMHands = false -- Uses viewmodel hands
-- ------------------------------------------------------------------------- -- -- ------------------------------------------------------------------------- --
-- Spawn -- Spawn
function CLASS:Spawn() function CLASS:Spawn()
print("Prop Hunt: Spectator '"..self.Player:GetName().."' (SteamID: "..self.Player:SteamID()..") spawned.") if GAMEMODE.Config:DebugLog() then print("Prop Hunt: Spectator '"..self.Player:GetName().."' (SteamID: "..self.Player:SteamID()..") spawned.") end
BaseClass.Spawn(self) BaseClass.Spawn(self)
self.Player:Spectate(OBS_MODE_ROAMING) self.Player:Spectate(OBS_MODE_ROAMING)
@@ -48,7 +48,7 @@ end
-- Death -- Death
function CLASS:PostDeath(inflictor, attacker) function CLASS:PostDeath(inflictor, attacker)
print("Prop Hunt: Spectator '"..self.Player:GetName().."' (SteamID: "..self.Player:SteamID()..") died.") if GAMEMODE.Config:DebugLog() then print("Prop Hunt: Spectator '"..self.Player:GetName().."' (SteamID: "..self.Player:SteamID()..") died.") end
BaseClass.PostDeath(self, inflictor, attacker) BaseClass.PostDeath(self, inflictor, attacker)
self.Player:Spectate(OBS_MODE_NONE) self.Player:Spectate(OBS_MODE_NONE)
@@ -77,9 +77,10 @@ function CLASS:CanPickupItem(ent) return false end
--! Client-Side --! Client-Side
-- ------------------------------------------------------------------------- -- -- ------------------------------------------------------------------------- --
function CLASS:ClientSpawn() function CLASS:ClientSpawn()
print("Prop Hunt CL: Spectator '"..self.Player:GetName().."' (SteamID: "..self.Player:SteamID()..") spawned.") if GAMEMODE.Config:DebugLog() then print("Prop Hunt CL: Spectator '"..self.Player:GetName().."' (SteamID: "..self.Player:SteamID()..") spawned.") end
end end
function CLASS:ShouldDrawLocal() return false end function CLASS:ShouldDrawLocal() return false end
function CLASS:CalcView(camdata) return camdata end
player_manager.RegisterClass( "Spectator", CLASS, "Default") player_manager.RegisterClass( "Spectator", CLASS, "Default")
@@ -25,7 +25,7 @@
StateHide = {} StateHide = {}
function StateHide:OnEnter(OldState) function StateHide:OnEnter(OldState)
if GAMEMODE.Config:Debug() then print("StateHide: OnEnter") end if GAMEMODE.Config:DebugLog() then print("StateHide: OnEnter") end
GAMEMODE:SetRoundState(GAMEMODE.States.Hide) GAMEMODE:SetRoundState(GAMEMODE.States.Hide)
-- Round Data -- Round Data
@@ -59,4 +59,7 @@ end
function StateHide:OnLeave(NewState) function StateHide:OnLeave(NewState)
if GAMEMODE.Config:Debug() then print("StateHide: OnLeave") end if GAMEMODE.Config:Debug() then print("StateHide: OnLeave") end
-- Fretta Hooks
hook.Run("PropHuntUnblind")
end end
@@ -25,15 +25,30 @@
StatePostMatch = {} StatePostMatch = {}
function StatePostMatch:OnEnter(OldState) function StatePostMatch:OnEnter(OldState)
if GAMEMODE.Config:Debug() then print("StatePostMatch: OnEnter") end if GAMEMODE.Config:DebugLog() then print("StatePostMatch: OnEnter") end
GAMEMODE:SetRoundState(GAMEMODE.States.PostMatch) GAMEMODE:SetRoundState(GAMEMODE.States.PostMatch)
self.NextState = StatePreMatch
-- Check Change map conditions.
if ((GAMEMODE.Config:TimeLimit() > 0) && ((CurTime() - GAMEMODE.Data.StartTime) >= (GAMEMODE.Config:TimeLimit() * 60))) -- Over Time
|| (GAMEMODE:GetRound() >= GAMEMODE.Config.Round:Limit()) -- Over Round Limit
then
-- Advance to nothing
GAMEMODE:SetRoundState(-1)
self.NextState = nil
-- MapVote
if (MapVote != nil) then MapVote.Start(30, true, 30, "ph_") return end
end
end end
function StatePostMatch:Tick() function StatePostMatch:Tick()
-- Advance State -- Advance State
GAMEMODE.RoundManager:SetState(StatePreMatch) GAMEMODE.RoundManager:SetState(self.NextState)
end end
function StatePostMatch:OnLeave(NewState) function StatePostMatch:OnLeave(NewState)
if GAMEMODE.Config:Debug() then print("StatePostMatch: OnLeave") end if GAMEMODE.Config:DebugLog() then print("StatePostMatch: OnLeave") end
end end
@@ -25,35 +25,118 @@
StatePostRound = {} StatePostRound = {}
function StatePostRound:OnEnter(OldState) function StatePostRound:OnEnter(OldState)
if GAMEMODE.Config:Debug() then print("StatePostRound: OnEnter") end if GAMEMODE.Config:DebugLog() then print("StatePostRound: OnEnter") end
GAMEMODE:SetRoundState(GAMEMODE.States.PostRound) GAMEMODE:SetRoundState(GAMEMODE.States.PostRound)
GAMEMODE.Data.RoundStartTime = CurTime() GAMEMODE.Data.RoundStartTime = CurTime()
-- Fretta Hooks
hook.Run("RoundEnd")
end end
function StatePostRound:Tick() function StatePostRound:Tick()
-- Advance State -- Advance State
if (CurTime() - GAMEMODE.Data.RoundStartTime) >= 5 then -- ToDo: configureable time? if (CurTime() - GAMEMODE.Data.RoundStartTime) >= 5 then -- ToDo: configureable time?
GAMEMODE.RoundManager:SetState(StatePostMatch) GAMEMODE.RoundManager:SetState(StatePostMatch)
local players = team.GetPlayers(GAMEMODE.Teams.Seekers)
table.Add(players, team.GetPlayers(GAMEMODE.Teams.Hiders))
-- Assign end of round weighted points.
local aliveSeekers = 0
local aliveHiders = 0
for i,ply in ipairs(players) do
if ply:Alive() then
if (ply:Team() == GAMEMODE.Teams.Hiders) then
aliveHiders = aliveHiders + 1
elseif (ply:Team() == GAMEMODE.Teams.Seekers) then
aliveSeekers = aliveSeekers + 1
end
end
end
for i,ply in ipairs(players) do
local score = 0
if (ply:Team() == GAMEMODE:GetRoundWinner()) then
if (ply:Alive()) then
score = 2
else
score = 1
end
if (ply:Team() == GAMEMODE.Teams.Hiders) then
score = score * aliveHiders
elseif (ply:Team() == GAMEMODE.Teams.Seekers) then
score = -1 * score * aliveSeekers
end
end
ply.Data.RandomWeight = ply.Data.RandomWeight + score
end
-- Team Distribution
if (GAMEMODE.Config.Teams:Weighted() == true) then
-- Weighted Teams
if GAMEMODE.Config:DebugLog() then print("Prop Hunt: Randomizing Teams using weighted Score.") end
-- table.sort function returns true if it should a should be before b.
table.sort(players, function(a, b)
if (a.Data.RandomWeight == b.Data.RandomWeight) then
return math.random(100) > 50
else
return a.Data.RandomWeight > b.Data.RandomWeight
end
end)
elseif (GAMEMODE.Config.Teams:Randomize() == true) then
-- Randomize Teams
if GAMEMODE.Config:DebugLog() then print("Prop Hunt: Randomizing Teams.") end
table.sort(players, function(a,b)
return math.random(100) > 50
end)
else
-- Swap Teams
if GAMEMODE.Config:DebugLog() then print("Prop Hunt: Swapping Teams.") end
table.sort(players, function(a,b)
return math.random(100) > 50
end)
table.sort(players, function(a,b)
if (b:Team() == GAMEMODE.Teams.Seekers) then
return (a:Team() == GAMEMODE.Teams.Hiders)
end
return false
end)
end
-- Team Distribution Logic
local hiders, seekers = {}, {}
if (GAMEMODE.Config:GameType() == GAMEMODE.Types.Original) then
-- Game Mode: Basic
local plyCount, finalPlyCount = #players, math.max(math.ceil(#players / 2), 1)
for c = 1,finalPlyCount do
seekers[c] = table.remove(players, 1)
end
hiders = players
elseif (GAMEMODE.Config:GameType() == GAMEMODE.Types.TheDeadHunt) then
-- Game Mode: The Dead Hunt
local plyCount, finalPlyCount = #players, math.max(math.ceil(#players * GAMEMODE.Config.Teams:SeekerPercentage()), 1)
for c = 1,finalPlyCount do
seekers[c] = table.remove(players, 1)
end
hiders = players
end
-- Kill & Assign Teams
for i, ply in ipairs(hiders) do
if GAMEMODE.Config:DebugLog() then print("Prop Hunt: Assigned '"..ply:GetName().."' (SteamID: "..ply:SteamID()..") to Team Hiders.") end
ply:KillSilent()
ply:SetTeam(GAMEMODE.Teams.Hiders)
end
for i, ply in ipairs(seekers) do
if GAMEMODE.Config:DebugLog() then print("Prop Hunt: Assigned '"..ply:GetName().."' (SteamID: "..ply:SteamID()..") to Team Seekers.") end
ply:KillSilent()
ply:SetTeam(GAMEMODE.Teams.Seekers)
end
end end
end end
function StatePostRound:OnLeave(NewState) function StatePostRound:OnLeave(NewState)
if GAMEMODE.Config:Debug() then print("StatePostRound: OnLeave") end if GAMEMODE.Config:DebugLog() then print("StatePostRound: OnLeave") end
-- Game Mode: Basic
if (GAMEMODE.Config:GameMode() == GAMEMODE.Modes.Original) then
-- Swap Teams
local hiders, seekers = team.GetPlayers(GAMEMODE.Teams.Hiders), team.GetPlayers(GAMEMODE.Teams.Seekers)
for i, ply in ipairs(hiders) do
ply:KillSilent()
ply:SetTeam(GAMEMODE.Teams.Seekers)
end
for i, ply in ipairs(seekers) do
ply:KillSilent()
ply:SetTeam(GAMEMODE.Teams.Hiders)
end
-- TODO: Other Gamemodes
end
end end
@@ -26,29 +26,30 @@
StatePreMatch = {} StatePreMatch = {}
function StatePreMatch:OnEnter(OldState) function StatePreMatch:OnEnter(OldState)
if GAMEMODE.Config:Debug() then print("StatePreMatch: OnEnter") end if GAMEMODE.Config:DebugLog() then print("StatePreMatch: OnEnter") end
GAMEMODE:SetRoundState(GAMEMODE.States.PreMatch) GAMEMODE:SetRoundState(GAMEMODE.States.PreMatch)
SetGlobalInt("Round", GetGlobalInt("Round", 0) + 1) math.randomseed(CurTime())
end end
function StatePreMatch:Tick() function StatePreMatch:Tick()
-- Debug: Auto Advance to PreRound State -- Debug: Auto Advance to PreRound State
if (GAMEMODE.Config:Debug()) then if (GAMEMODE.Config:Debug()) then
print("StatePreMatch: Advancing to StatePreRound") if GAMEMODE.Config:DebugLog() then print("StatePreMatch: Advancing to StatePreRound") end
GAMEMODE.RoundManager:SetState(StatePreRound) GAMEMODE.RoundManager:SetState(StatePreRound)
end end
-- Game Mode: Basic -- Game Mode: Basic
if (GAMEMODE.Config:GameMode() == GAMEMODE.Modes.Original) then if (GAMEMODE.Config:GameType() == GAMEMODE.Types.Original) then
-- Both Teams must have at least 1 player. -- Both Teams must have at least 1 player.
if ((team.NumPlayers(GAMEMODE.Teams.Seekers) >= 1) && (team.NumPlayers(GAMEMODE.Teams.Hiders) >= 1)) then if ((team.NumPlayers(GAMEMODE.Teams.Seekers) >= 1) && (team.NumPlayers(GAMEMODE.Teams.Hiders) >= 1)) then
GAMEMODE.RoundManager:SetState(StatePreRound) GAMEMODE.RoundManager:SetState(StatePreRound)
if GAMEMODE.Config:DebugLog() then print("StatePreMatch: <Original> Have enough players to start match.") end
end end
-- TODO: Other Gamemodes -- TODO: Other Gamemodes
end end
end end
function StatePreMatch:OnLeave(NewState) function StatePreMatch:OnLeave(NewState)
if GAMEMODE.Config:Debug() then print("StatePreMatch: OnLeave") end if GAMEMODE.Config:DebugLog() then print("StatePreMatch: OnLeave") end
end end
@@ -25,8 +25,9 @@
StatePreRound = {} StatePreRound = {}
function StatePreRound:OnEnter(OldState) function StatePreRound:OnEnter(OldState)
if GAMEMODE.Config:Debug() then print("StatePreRound: OnEnter") end if GAMEMODE.Config:DebugLog() then print("StatePreRound: OnEnter") end
GAMEMODE:SetRoundState(GAMEMODE.States.PreRound) GAMEMODE:SetRoundState(GAMEMODE.States.PreRound)
GAMEMODE:SetRound(GAMEMODE:GetRound() + 1)
-- Clean Up the Map -- Clean Up the Map
game.CleanUpMap() game.CleanUpMap()
@@ -37,7 +38,7 @@ function StatePreRound:Tick()
GAMEMODE.RoundManager:SetState(StateHide) GAMEMODE.RoundManager:SetState(StateHide)
end end
function StatePreRound:OnLeave(NewState) function StatePreRound:OnLeave(NewState)
if GAMEMODE.Config:Debug() then print("StatePreRound: OnLeave") end if GAMEMODE.Config:DebugLog() then print("StatePreRound: OnLeave") end
-- Respawn Everyone -- Respawn Everyone
for i, ply in ipairs(player.GetAll()) do for i, ply in ipairs(player.GetAll()) do
@@ -46,5 +47,15 @@ function StatePreRound:OnLeave(NewState)
ply:Spawn() ply:Spawn()
ply:ScreenFade(SCREENFADE.PURGE, color_black, 0, 0) ply:ScreenFade(SCREENFADE.PURGE, color_black, 0, 0)
ply:ScreenFade(SCREENFADE.IN, color_black, 1, 0) ply:ScreenFade(SCREENFADE.IN, color_black, 1, 0)
-- Weighted Score: Adjust towards other Team.
if (ply:Team() == GAMEMODE.Teams.Hiders) then
ply.Data.RandomWeight = ply.Data.RandomWeight + 1
elseif (ply:Team() == GAMEMODE.Teams.Seekers) then
ply.Data.RandomWeight = ply.Data.RandomWeight - 1
end
end end
-- Fretta Hooks
hook.Run("RoundStart")
end end
@@ -25,7 +25,7 @@
StateSeek = {} StateSeek = {}
function StateSeek:OnEnter(OldState) function StateSeek:OnEnter(OldState)
if GAMEMODE.Config:Debug() then print("StateSeek: OnEnter") end if GAMEMODE.Config:DebugLog() then print("StateSeek: OnEnter") end
GAMEMODE:SetRoundState(GAMEMODE.States.Seek) GAMEMODE:SetRoundState(GAMEMODE.States.Seek)
-- Round Data -- Round Data
@@ -75,7 +75,7 @@ function StateSeek:Tick()
GAMEMODE.RoundManager:SetState(StatePostRound) GAMEMODE.RoundManager:SetState(StatePostRound)
else else
if (GAMEMODE.Data.RoundTime <= 0) then -- No Time remaining if (GAMEMODE.Data.RoundTime <= 0) then -- No Time remaining
GAMEMODE:SetRoundWinner(GAMEMODE.Teams.Hiders) GAMEMODE:SetRoundWinner(GAMEMODE.Teams.Hiders)
GAMEMODE.RoundManager:SetState(StatePostRound) GAMEMODE.RoundManager:SetState(StatePostRound)
end end
end end
@@ -83,5 +83,13 @@ function StateSeek:Tick()
end end
function StateSeek:OnLeave(NewState) function StateSeek:OnLeave(NewState)
if GAMEMODE.Config:Debug() then print("StateSeek: OnLeave") end if GAMEMODE.Config:DebugLog() then print("StateSeek: OnLeave") end
if GAMEMODE:GetRoundWinner() == GAMEMODE.Teams.Seekers then
hook.Run("RoundVictorySeeker")
elseif GAMEMODE:GetRoundWinner() == GAMEMODE.Teams.Hiders then
hook.Run("RoundVictoryHider")
else
hook.Run("RoundVictoryDraw")
end
end end
@@ -1,294 +1,464 @@
-- Sounds played by members of the losing team at the end of the round. --[[
LOSS_SOUNDS = { The MIT License (MIT)
"bot/aw_hell.wav",
"bot/aww_man.wav", Copyright (c) 2015 Xaymar
"bot/anyone_see_anything.wav",
"bot/anyone_see_them.wav", Permission is hereby granted, free of charge, to any person obtaining a copy
"bot/come_out_and_fight_like_a_man.wav", of this software and associated documentation files (the "Software"), to deal
"bot/come_out_wherever_you_are.wav", in the Software without restriction, including without limitation the rights
"bot/he_got_away.wav", to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
"bot/he_got_away2.wav", copies of the Software, and to permit persons to whom the Software is
"bot/i_dont_know_where_he_went.wav", furnished to do so, subject to the following conditions:
"bot/i_got_nothing.wav",
"bot/nothing_happening_over_here.wav", The above copyright notice and this permission notice shall be included in all
"bot/nothing_here.wav", copies or substantial portions of the Software.
"bot/nothing_moving_over_here.wav",
"bot/thats_not_good.wav", THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
"bot/theres_too_many.wav", IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
"bot/theres_too_many_of_them.wav", FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
"bot/theyre_all_over_the_place2.wav", AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
"bot/theyre_everywhere2.wav", LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
"bot/too_many2.wav", OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
"bot/what_happened.wav", SOFTWARE.
"bot/what_have_you_done.wav", --]]
"bot/where_are_they.wav",
"bot/where_are_you_hiding.wav" --! Initialize configuration table.
} GM.Config = { }
if (! file.Exists("prop_hunt/sounds_loss.txt", "DATA")) then GM.Config.ConVars = {}
file.Write("prop_hunt/sounds_loss.txt", util.TableToKeyValues(LOSS_SOUNDS))
end function CreateConVarIfNotExists(name, value, flags, helptext)
local fileContent = file.Read("prop_hunt/sounds_loss.txt", "DATA"); cv = GetConVar(name)
if fileContent then if (cv == nil) then
local fileTable = util.KeyValuesToTable(fileContent) cv = CreateConVar(name, value, flags, helptext)
if fileTable then LOSS_SOUNDS = fileTable end -- else
-- ncv = CreateConVar(name, value, flags, helptext)
end
return cv
end end
-- Sounds played by members of the winning team at the end of the round. -- ------------------------------------------------------------------------- --
VICTORY_SOUNDS = { --! Debug Settings
"bot/and_thats_how_its_done.wav", -- ------------------------------------------------------------------------- --
"bot/come_to_papa.wav", -- Debug Mode
"bot/do_not_mess_with_me.wav", GM.Config.ConVars.Debug = CreateConVarIfNotExists("ph_debug", "0", FCVAR_CHEAT + FCVAR_REPLICATED, "Prop Hunt: Enable Debug Mode")
"bot/dropped_him.wav", function GM.Config:Debug()
"bot/enemy_down.wav", return self.ConVars.Debug:GetBool()
"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 end
-- Taunts played when Hunters hit their Spare1 binding. -- Debug Log
HUNTER_TAUNTS = { GM.Config.ConVars.DebugLog = CreateConVarIfNotExists("ph_debug_log", "0", FCVAR_REPLICATED, "Prop Hunt: Enable Debug Logging")
"bot/a_bunch_of_them.wav", function GM.Config:DebugLog()
"bot/come_out_and_fight_like_a_man.wav", return self.ConVars.DebugLog:GetBool()
"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 end
-- Taunts played when Props hit their Spare1 binding. -- ------------------------------------------------------------------------- --
PROP_TAUNTS = { --! Basic Settings
-- "ambient/alarms/apc_alarm_loop1.wav", -- ------------------------------------------------------------------------- --
"ambient/alarms/apc_alarm_pass1.wav", -- Game Mode (See sh_init.lua)
-- "ambient/alarms/citadel_alert_loop2.wav", GM.Config.ConVars.GameType = CreateConVarIfNotExists("ph_gametype", GM.Types.Original, FCVAR_REPLICATED, "Prop Hunt: Which Game Type should be played? ("..GM.Types.Original.." = Original Prop Hunt, "..GM.Types.TheDeadHunt.." = The Dead Hunt Mode)")
-- "ambient/alarms/city_firebell_loop1.wav", function GM.Config:GameType()
-- "ambient/alarms/city_siren_loop2.wav", return self.ConVars.GameType:GetInt()
-- "ambient/alarms/combine_bank_alarm_loop1.wav", end
-- "ambient/alarms/combine_bank_alarm_loop4.wav",
-- "ambient/alarms/klaxon1.wav", -- Timelimit in minutes
"ambient/alarms/manhack_alert_pass1.wav", GM.Config.ConVars.TimeLimit = CreateConVarIfNotExists("mp_timelimit", "20", FCVAR_REPLICATED, "Map Time Limit (in Minutes)")
"ambient/alarms/razortrain_horn1.wav", function GM.Config:TimeLimit()
"ambient/alarms/scanner_alert_pass1.wav", return self.ConVars.TimeLimit:GetFloat()
-- "ambient/alarms/siren.wav", end
-- "ambient/alarms/train_crossing_bell_loop1.wav",
"ambient/alarms/train_horn2.wav", -- ------------------------------------------------------------------------- --
"ambient/alarms/train_horn_distant1.wav", --! Round Settings
"ambient/alarms/warningbell1.wav", -- ------------------------------------------------------------------------- --
-- "ambient/chatter/cb_radio_chatter_1.wav", GM.Config.Round = {}
-- "ambient/chatter/cb_radio_chatter_2.wav", GM.Config.Round.ConVars = {}
-- "ambient/chatter/cb_radio_chatter_3.wav",
"ambient/energy/whiteflash.wav", -- How many rounds should the GM attempt to fit into the map timelimit, if there is any?
"ambient/intro/alyxremove.wav", GM.Config.Round.ConVars.Limit = CreateConVarIfNotExists("ph_round_limit", "10", FCVAR_REPLICATED, "Round Manager: Maximum Rounds to Play on a single Map")
"ambient/intro/logosfx.wav", function GM.Config.Round:Limit()
-- "ambient/levels/labs/teleport_alarm_loop1.wav", return self.ConVars.Limit:GetInt()
"ambient/levels/launch/1stfiringwarning.wav", end
"ambient/levels/launch/rockettakeoffblast.wav",
-- "ambient/levels/outland/basealarmloop.wav", -- Round Time Limit (Seconds, Default 3 minutes)
-- "ambient/machines/60hzhum.wav", GM.Config.Round.ConVars.Time = CreateConVarIfNotExists("ph_round_timelimit", "180", FCVAR_REPLICATED, "Round Manager: Time Limit per Round (in Seconds)")
"ambient/misc/ambulance1.wav", function GM.Config.Round:Time()
"ambient/misc/carhonk1.wav", return math.max(self.ConVars.Time:GetFloat() - math.min(self:BlindTime(),0),0)
"ambient/misc/carhonk2.wav", end
"ambient/misc/carhonk3.wav",
-- "ambient/music/bongo.wav", -- For how many seconds are the Seekers blinded? (Seconds)
-- "ambient/music/country_rock_am_radio_loop.wav", GM.Config.Round.ConVars.BlindTime = CreateConVarIfNotExists("ph_round_blindtime", "-30", FCVAR_REPLICATED, "Round Manager: Blind Time for Seekers (in Seconds, positive takes away from ph_round_timelimit, negative adds extra time to ph_round_timelimit")
-- "ambient/music/cubanmusic1.wav", function GM.Config.Round:BlindTime()
-- "ambient/music/dustmusic1.wav", return self.ConVars.BlindTime:GetFloat()
-- "ambient/music/dustmusic2.wav", end
-- "ambient/music/dustmusic3.wav",
-- "ambient/music/flamenco.wav", -- ------------------------------------------------------------------------- --
-- "ambient/music/latin.wav", --! Team Settings
-- "ambient/music/mirame_radio_thru_wall.wav", -- ------------------------------------------------------------------------- --
-- "ambient/music/piano1.wav", GM.Config.Teams = {}
-- "ambient/music/piano2.wav", GM.Config.Teams.ConVars = {}
"ambient/outro/gunshipcrash.wav",
"ambient/3dmeagle.wav", -- Should teams be ranomized each round?
-- "ambient/guit1.wav", GM.Config.Teams.ConVars.Randomize = CreateConVarIfNotExists("ph_teams_randomize", "0", FCVAR_REPLICATED, "Teams: Randomize Each Round")
-- "ambient/opera.wav", function GM.Config.Teams:Randomize()
-- "ambient/sheep.wav", return self.ConVars.Randomize:GetBool()
"beams/beamstart5.wav", end
"buttons/bell1.wav",
"buttons/weapon_cant_buy.wav", -- Should teams be using weighted randomization?
"common/bass.wav", -- Weighted randomization works by using a score calculated over the entire session.
"common/bugreporter_failed.wav", -- * Round Start: Adjust Score towards the other Team by 1 (Positive = Seeker, Negative = Hider)
"common/warning.wav", -- * Round Win: Adjust score by how many players are still alive on the winning team towards the other team.
"doors/door_squeek1.wav", -- * Alive players get double the score.
"friends/friend_join.wav", GM.Config.Teams.ConVars.Weighted = CreateConVarIfNotExists("ph_teams_weighted", "1", FCVAR_REPLICATED, "Teams: Use Weighted Randomization")
"friends/friend_online.wav", function GM.Config.Teams:Weighted()
"friends/message.wav", return self.ConVars.Weighted:GetBool()
"hostage/hunuse/comeback.wav", end
"hostage/hunuse/dontleaveme.wav",
"hostage/hunuse/yeahillstay.wav", -- The Dead Hunt: Percent of players to assign to seeker.
"items/gift_drop.wav", GM.Config.Teams.ConVars.SeekerPercentage = CreateConVarIfNotExists("ph_teams_seekerpct", "25", FCVAR_REPLICATED, "Teams: Initial percentage of Seekers in Dead Hunt Game Type")
"music/radio1.mp3", function GM.Config.Teams:SeekerPercentage()
"phx/eggcrack.wav", return self.ConVars.Teams:GetFloat() / 100
"plats/elevbell1.wav", end
"player/headshot1.wav",
"player/headshot2.wav", -- ------------------------------------------------------------------------- --
"player/sprayer.wav", --! Seeker Settings
"radio/enemydown.wav", -- ------------------------------------------------------------------------- --
"radio/go.wav", GM.Config.Seeker = {}
"radio/locknload.wav", GM.Config.Seeker.ConVars = {}
"radio/negative.wav",
"radio/rounddraw.wav", GM.Config.Seeker.ConVars.Health = CreateConVarIfNotExists("ph_seeker_health", "100", FCVAR_REPLICATED, "Seekers: Initial Health")
"radio/takepoint.wav", function GM.Config.Seeker:Health()
"resource/warning.wav", return self.ConVars.Health:GetInt()
-- "test/temp/soundscape_test/tv_music.wav", end
"ui/achievement_earned.wav",
"ui/freeze_cam.wav", GM.Config.Seeker.ConVars.HealthMax = CreateConVarIfNotExists("ph_seeker_health_max", "100", FCVAR_REPLICATED, "Seekers: Maximum Health")
"vehicles/junker/radar_ping_friendly1.wav", function GM.Config.Seeker:HealthMax()
"weapons/c4/c4_beep1.wav", return self.ConVars.HealthMax:GetInt()
"weapons/c4/c4_click.wav", end
"weapons/awp/awp1.wav",
"vo/canals/female01/gunboat_giveemhell.wav", GM.Config.Seeker.ConVars.HealthBonus = CreateConVarIfNotExists("ph_seeker_health_bonus", "20", FCVAR_REPLICATED, "Seekers: Health Bonus per Kill")
"vo/canals/female01/gunboat_justintime.wav", function GM.Config.Seeker:HealthBonus()
"vo/canals/female01/stn6_incoming.wav", return self.ConVars.HealthBonus:GetInt()
"vo/canals/male01/gunboat_giveemhell.wav", end
"vo/canals/male01/gunboat_justintime.wav",
"vo/canals/male01/stn6_incoming.wav", GM.Config.Seeker.ConVars.HealthPenalty = CreateConVarIfNotExists("ph_seeker_health_penalty", "5", FCVAR_REPLICATED, "Seekers: Health Penalty per wrong Shot")
"vo/canals/al_radio_stn6.wav", function GM.Config.Seeker:HealthPenalty()
"vo/canals/arrest_getgoing.wav", return self.ConVars.HealthPenalty:GetInt()
"vo/canals/arrest_helpme.wav", end
"vo/canals/arrest_lookingforyou.wav",
"vo/canals/boxcar_lethimhelp.wav", GM.Config.Seeker.ConVars.Weapons = CreateConVarIfNotExists("ph_seeker_weapons", "weapon_crowbar,weapon_pistol,weapon_ph_smg,weapon_shotgun", FCVAR_REPLICATED, "Seekers: Initial Weapons (Weapon,Weapon,...)")
"vo/canals/matt_closecall.wav", function GM.Config.Seeker:Weapons()
"vo/canals/premassacre.wav", return string.Split(self.ConVars.Weapons:GetString(), ",")
"vo/ravenholm/aimforhead.wav", end
"vo/ravenholm/bucket_patience.wav",
"vo/ravenholm/madlaugh01.wav", GM.Config.Seeker.ConVars.Ammo = CreateConVarIfNotExists("ph_seeker_ammo", "Pistol:100,SMG1:300,SMG1_Grenade:1,Buckshot:64", FCVAR_REPLICATED, "Seekers: Initial Ammo (Ammo:Amount,Ammo:Amount,...)")
"vo/ravenholm/madlaugh02.wav", function GM.Config.Seeker:Ammo()
"vo/ravenholm/madlaugh03.wav", return string.Split(self.ConVars.Ammo:GetString(), ",")
"vo/ravenholm/madlaugh04.wav", end
"weapons/strider_buster/ol12_stickybombcreator.wav",
"weapons/c4/c4_explode1.wav", GM.Config.Seeker.ConVars.WalkSpeed = CreateConVarIfNotExists("ph_seeker_walk_speed", "250", 0, "Seekers: Walk Speed")
"weapons/357/357_fire2.wav", function GM.Config.Seeker:WalkSpeed()
"weapons/357/357_fire3.wav", return self.ConVars.WalkSpeed:GetFloat()
"weapons/scout/scout_fire-1.wav", end
"weapons/smokegrenade/sg_explode.wav",
"weapons/grenade_launcher1.wav", GM.Config.Seeker.ConVars.Sprint = CreateConVarIfNotExists("ph_seeker_sprint", "1", FCVAR_REPLICATED, "Seekers: Allow Sprinting")
"weapons/explode3.wav", function GM.Config.Seeker:Sprint()
"weapons/underwater_explode3.wav", return self.ConVars.Sprint:GetBool()
"items/nvg_on.wav", end
"hostage/huse/letsdoit.wav",
"hostage/huse/illfollow.wav", GM.Config.Seeker.ConVars.SprintSpeed = CreateConVarIfNotExists("ph_seeker_sprint_speed", "500", 0, "Seekers: Sprint Speed")
"hostage/huse/getouttahere.wav", function GM.Config.Seeker:SprintSpeed()
"doors/door_screen_move1.wav", return self.ConVars.SprintSpeed:GetFloat()
"doors/heavy_metal_stop1.wav", end
"doors/default_move.wav",
"common/stuck2.wav", GM.Config.Seeker.ConVars.JumpPower = CreateConVarIfNotExists("ph_seeker_jump_power", "200", 0, "Seekers: Jump Power")
"ambient/water_splash1.wav", function GM.Config.Seeker:JumpPower()
"ambient/water_splash2.wav", return self.ConVars.JumpPower:GetFloat()
"ambient/water_splash3.wav", end
"ambient/weather/thunder1.wav",
"ambient/weather/thunder2.wav", -- ------------------------------------------------------------------------- --
"ambient/weather/thunder3.wav", --! Hider Settings
"ambient/weather/thunder4.wav", -- ------------------------------------------------------------------------- --
"ambient/weather/thunder5.wav", GM.Config.Hider = {}
"ambient/weather/thunder6.wav", GM.Config.Hider.ConVars = {}
"ambient/outro/thunder7.wav",
"ambient/voices/crying_loop1.wav", GM.Config.Hider.ConVars.Health = CreateConVarIfNotExists("ph_hider_health", "100", FCVAR_REPLICATED, "Hiders: Initial Health")
"ambient/voices/playground_memory.wav", function GM.Config.Hider:Health()
"ambient/voices/f_scream1.wav", return self.ConVars.Health:GetInt()
"ambient/voices/m_scream1.wav", end
"ambient/voices/cough1.wav",
"ambient/voices/cough2.wav", GM.Config.Hider.ConVars.HealthMax = CreateConVarIfNotExists("ph_hider_health_max", "100", FCVAR_REPLICATED, "Hiders: Maximum Health")
"ambient/voices/cough3.wav", function GM.Config.Hider:HealthMax()
"ambient/voices/cough4.wav", return self.ConVars.HealthMax:GetInt()
"ambient/overhead/plane1.wav", end
"ambient/overhead/plane2.wav",
"ambient/overhead/plane3.wav", GM.Config.Hider.ConVars.HealthScaling = CreateConVarIfNotExists("ph_hider_health_scaling", "1", FCVAR_REPLICATED, "Hiders: Enable Health Scaling")
"ambient/overhead/hel1.wav", function GM.Config.Hider:HealthScaling()
"ambient/overhead/hel2.wav", return self.ConVars.HealthScaling:GetBool()
"ambient/misc/truck_backup1.wav", end
"ambient/misc/truck_drive1.wav",
"ambient/misc/truck_drive2.wav", GM.Config.Hider.ConVars.HealthScalingMax = CreateConVarIfNotExists("ph_hider_health_scaling_max", "200", FCVAR_REPLICATED, "Hiders: Maximum scaled Health")
"ambient/machines/pneumatic_drill_1.wav", function GM.Config.Hider:HealthScalingMax()
"ambient/machines/pneumatic_drill_2.wav", return self.ConVars.HealthScalingMax:GetInt()
"ambient/machines/pneumatic_drill_3.wav", end
"ambient/machines/pneumatic_drill_4.wav",
"ambient/machines/station_train_squeel.wav", GM.Config.Hider.ConVars.AllowFullRotation = CreateConVarIfNotExists("ph_hider_allow_full_rotation", "0", FCVAR_REPLICATED, "Hiders: Enable full 3D Rotation")
"ambient/machines/ticktock.wav", function GM.Config.Hider:AllowFullRotation()
"ambient/creatures/teddy.wav", return self.ConVars.AllowFullRotation:GetBool()
"ambient/creatures/town_child_scream1.wav", end
"ambient/creatures/town_moan1.wav",
"ambient/creatures/town_muffled_cry1.wav", GM.Config.Hider.ConVars.WalkSpeed = CreateConVarIfNotExists("ph_hider_walk_speed", "250", 0, "Hiders: Walk Speed")
"ambient/creatures/town_scared_breathing1.wav", function GM.Config.Hider:WalkSpeed()
"ambient/creatures/town_scared_breathing2.wav", return self.ConVars.WalkSpeed:GetFloat()
"ambient/creatures/town_scared_sob1.wav", end
"ambient/creatures/town_scared_sob2.wav",
"ambient/creatures/town_zombie_call1.wav" GM.Config.Hider.ConVars.Sprint = CreateConVarIfNotExists("ph_hider_sprint", "0", FCVAR_REPLICATED, "Hiders: Allow Sprinting")
} function GM.Config.Hider:Sprint()
if (! file.Exists("prop_hunt/sounds_taunt_prop.txt", "DATA")) then return self.ConVars.Sprint:GetBool()
file.Write("prop_hunt/sounds_taunt_prop.txt", util.TableToKeyValues(PROP_TAUNTS)) end
GM.Config.Hider.ConVars.SprintSpeed = CreateConVarIfNotExists("ph_hider_sprint_speed", "500", 0, "Hiders: Sprint Speed")
function GM.Config.Hider:SprintSpeed()
return self.ConVars.SprintSpeed:GetFloat()
end
GM.Config.Hider.ConVars.JumpPower = CreateConVarIfNotExists("ph_hider_jump_power", "200", 0, "Hiders: Jump Power")
function GM.Config.Hider:JumpPower()
return self.ConVars.JumpPower:GetFloat()
end
-- ------------------------------------------------------------------------- --
--! Whitelist & Blacklist
-- ------------------------------------------------------------------------- --
GM.Config.Lists = {}
GM.Config.Lists.ConVars = {}
-- Class Whitelist
GM.Config.Lists.ConVars.ClassWhitelist = CreateConVarIfNotExists("ph_list_class_whitelist", "prop_physics,prop_physics_multiplayer,prop_physics_respawnable", FCVAR_REPLICATED, "Anti-Cheat: Whitelisted Hider Classes")
function GM.Config.Lists:ClassWhitelist()
local str = self.ConVars.ClassWhitelist:GetString()
if (self.ClassWhitelistCache != str) then
self.ClassWhitelistCache = str
self.ClassWhitelistCacheTbl = string.Split(self.ClassWhitelistCache, ",")
end
return self.ClassWhitelistCacheTbl
end
-- Abuse Blacklist
GM.Config.Lists.ConVars.AbuseBlacklist = CreateConVarIfNotExists("ph_list_abuse_blacklist", "func_button,func_door,func_door_rotation,prop_door_rotation,func_tracktrain,func_tanktrain,func_breakable", FCVAR_REPLICATED, "Anti-Cheat: Entity Abuse Blacklist")
function GM.Config.Lists:AbuseBlacklist()
local str = self.ConVars.AbuseBlacklist:GetString()
if (self.AbuseBlacklistCache != str) then
self.AbuseBlacklistCache = str
self.AbuseBlacklistCacheTbl = string.Split(self.AbuseBlacklistCache, ",")
end
return self.AbuseBlacklistCacheTbl
end
-- Model Blacklist
GM.Config.Lists.ConVars.ModelBlacklist = CreateConVarIfNotExists("ph_list_model_blacklist", "models/props/cs_assault/dollar.mdl,models/props/cs_assault/money.mdl,models/props/cs_office/snowman_arm.mdl,models/props/cs_office/projector_remote.mdl", FCVAR_REPLICATED, "Anti-Cheat: Model Abuse Blacklist")
function GM.Config.Lists:ModelBlacklist()
local str = self.ConVars.ModelBlacklist:GetString()
if (self.ModelBlacklistCache != str) then
self.ModelBlacklistCache = str
self.ModelBlacklistCacheTbl = string.Split(self.ModelBlacklistCache, ",")
end
return self.ModelBlacklistCacheTbl
end
-- ------------------------------------------------------------------------- --
--! Taunts
-- ------------------------------------------------------------------------- --
GM.Config.Taunt = {}
GM.Config.Taunt.ConVars = {}
-- Cooldown (Seconds)
GM.Config.Taunt.ConVars.Cooldown = CreateConVarIfNotExists("ph_taunt_cooldown", 5, FCVAR_REPLICATED, "Prop Hunt: Cooldown between Taunts")
function GM.Config.Taunt:Cooldown()
return self.ConVars.Cooldown:GetFloat()
end
-- Seeker
GM.Config.Taunt.SeekersCache = ""
GM.Config.Taunt.SeekersCacheDynamic = nil
GM.Config.Taunt.SeekersCacheStatic = nil
GM.Config.Taunt.SeekersCacheFull = nil
GM.Config.Taunt.ConVars.Seekers = CreateConVarIfNotExists("ph_taunt_seekers", "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", 0, "Prop Hunt: Seeker Taunts")
function GM.Config.Taunt:Seekers()
local str = self.ConVars.Seekers:GetString()
if (self.SeekersCache != str) then
self.SeekersCache = str
self.SeekersCacheDynamic = string.Split(self.SeekersCache, ",")
self.SeekersCacheFull = table.Add(self.SeekersCacheDynamic, self.SeekersCacheStatic)
for i,snd in ipairs(self.SeekersCacheFull) do
util.PrecacheSound(snd)
end
end
return self.SeekersCacheFull
end
-- Hider
GM.Config.Taunt.HidersCache = ""
GM.Config.Taunt.HidersCacheDynamic = nil
GM.Config.Taunt.HidersCacheStatic = nil
GM.Config.Taunt.HidersCacheFull = nil
GM.Config.Taunt.ConVars.Hiders = CreateConVarIfNotExists("ph_taunt_hiders", "ambient/alarms/apc_alarm_pass1.wav,ambient/alarms/manhack_alert_pass1.wav,ambient/alarms/razortrain_horn1.wav,ambient/alarms/scanner_alert_pass1.wav,ambient/alarms/train_horn2.wav,ambient/alarms/train_horn_distant1.wav,ambient/alarms/warningbell1.wav,ambient/energy/whiteflash.wav,ambient/intro/alyxremove.wav,ambient/intro/logosfx.wav,ambient/levels/launch/1stfiringwarning.wav,ambient/levels/launch/rockettakeoffblast.wav,ambient/misc/ambulance1.wav,ambient/misc/carhonk1.wav,ambient/misc/carhonk2.wav,ambient/misc/carhonk3.wav,ambient/outro/gunshipcrash.wav,ambient/3dmeagle.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,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", 0, "Prop Hunt: Hider Taunts")
function GM.Config.Taunt:Hiders()
local str = self.ConVars.Hiders:GetString()
if (self.HidersCacheDynamic == nil)
|| (self.HidersCache != str) then
self.HidersCache = str
self.HidersCacheDynamic = string.Split(self.HidersCache, ",")
self.HidersCacheFull = table.Add(self.HidersCacheDynamic, self.HidersCacheStatic)
for i,snd in ipairs(self.HidersCacheFull) do
util.PrecacheSound(snd)
end
end
return self.HidersCacheFull
end
-- ------------------------------------------------------------------------- --
--! Announcers
-- ------------------------------------------------------------------------- --
-- --! Announcers (Round Start, Unblind, Win, Loss)
-- GM.Config.Announcers = {
-- Start = { },
-- Unblind = { },
-- Win = { },
-- Loss = { }
-- }
-- ------------------------------------------------------------------------- --
--! Camera
-- ------------------------------------------------------------------------- --
GM.Config.Camera = {}
GM.Config.Camera.ConVars = {}
-- Allow Camera No Clip
GM.Config.Camera.ConVars.AllowNoClip = CreateConVarIfNotExists("ph_camera_allow_noclip", "0", FCVAR_REPLICATED, "Camera: Allow clients to disable camera collision.")
function GM.Config.Camera:AllowNoClip()
return self.ConVars.AllowNoClip:GetBool()
end
-- Camera Distance Maximum
GM.Config.Camera.ConVars.DistanceMax = CreateConVarIfNotExists("ph_camera_distance_max", "150", FCVAR_REPLICATED, "Camera: Maximum allowed distance to player.")
function GM.Config.Camera:DistanceMax()
return self.ConVars.DistanceMax:GetFloat()
end
-- Camera Distance Minimum
GM.Config.Camera.ConVars.DistanceMin = CreateConVarIfNotExists("ph_camera_distance_min", "30", FCVAR_REPLICATED, "Camera: Minimum allowed distance to player.")
function GM.Config.Camera:DistanceMin()
return self.ConVars.DistanceMin:GetFloat()
end
-- Camera Distance Right Maximum
GM.Config.Camera.ConVars.DistanceRightRange = CreateConVarIfNotExists("ph_camera_distance_right_range", "20", FCVAR_REPLICATED, "Camera: Horizontal allowed camera distance range.")
function GM.Config.Camera:DistanceRightRange()
return self.ConVars.DistanceRightRange:GetFloat()
end
-- Camera Distance Up Maximum
GM.Config.Camera.ConVars.DistanceUpRange = CreateConVarIfNotExists("ph_camera_distance_up_range", "20", FCVAR_REPLICATED, "Camera: Vertical allowed camera distance range.")
function GM.Config.Camera:DistanceUpRange()
return self.ConVars.DistanceUpRange:GetFloat()
end
-- Lag Minimum
GM.Config.Camera.ConVars.LagMinimum = CreateConVarIfNotExists("ph_camera_lag_min", "0.01", FCVAR_REPLICATED, "Camera: Minimum Camera Lag.")
function GM.Config.Camera:LagMinimum()
return self.ConVars.LagMinimum:GetFloat()
end
-- Lag Maximum
GM.Config.Camera.ConVars.LagMaximum = CreateConVarIfNotExists("ph_camera_lag_max", "0.95", FCVAR_REPLICATED, "Camera: Maximum Camera Lag.")
function GM.Config.Camera:LagMaximum()
return self.ConVars.LagMaximum:GetFloat()
end
if CLIENT then
-- Collisions
GM.Config.Camera.ConVars.Collisions = CreateConVarIfNotExists("ph_camera_collisions", "1", FCVAR_ARCHIVE + FCVAR_CLIENTDLL, "Camera: Enable collisions with the world and objects in it.")
function GM.Config.Camera:Collisions()
if self:AllowNoClip() then
return self.ConVars.Collisions:GetBool()
else
return true
end
end
-- Distance
GM.Config.Camera.ConVars.Distance = CreateConVarIfNotExists("ph_camera_distance", "100", FCVAR_ARCHIVE + FCVAR_CLIENTDLL, "Camera: Ideal Distance to player.")
function GM.Config.Camera:Distance()
return math.Clamp(self.ConVars.Distance:GetFloat(), self:DistanceMin(), self:DistanceMax())
end
-- Distance Right
GM.Config.Camera.ConVars.DistanceRight = CreateConVarIfNotExists("ph_camera_distance_right", "0", FCVAR_ARCHIVE + FCVAR_CLIENTDLL, "Camera: Ideal Distance to player horizontally.")
function GM.Config.Camera:DistanceRight()
return math.Clamp(self.ConVars.DistanceRight:GetFloat(), -self:DistanceRightRange(), self:DistanceRightRange())
end
-- Distance Up
GM.Config.Camera.ConVars.DistanceUp = CreateConVarIfNotExists("ph_camera_distance_up", "0", FCVAR_ARCHIVE + FCVAR_CLIENTDLL, "Camera: Ideal Distance to player vertically.")
function GM.Config.Camera:DistanceUp()
return math.Clamp(self.ConVars.DistanceUp:GetFloat(), -self:DistanceUpRange(), self:DistanceUpRange())
end
-- Lag
GM.Config.Camera.ConVars.Lag = CreateConVarIfNotExists("ph_camera_lag", "0.95", FCVAR_ARCHIVE + FCVAR_CLIENTDLL, "Camera: Percentage of camera lag (higher = slower, lower = faster).")
function GM.Config.Camera:Lag()
return math.Clamp(self.ConVars.Lag:GetFloat(), self:LagMinimum(), self:LagMaximum())
end
end
-- ------------------------------------------------------------------------- --
--! Name Plates
-- ------------------------------------------------------------------------- --
GM.Config.NamePlates = {}
GM.Config.NamePlates.ConVars = {}
if CLIENT then
-- Show
GM.Config.NamePlates.ConVars.Show = CreateConVarIfNotExists("ph_nameplates_show", "1", FCVAR_ARCHIVE + FCVAR_CLIENTDLL, "Nameplates: Show a name plate above each player in your team (or all players if spectating).")
function GM.Config.NamePlates:Show()
return self.ConVars.Show:GetBool()
end
-- Scale
GM.Config.NamePlates.ConVars.Scale = CreateConVarIfNotExists("ph_nameplates_scale", "0.05", FCVAR_ARCHIVE + FCVAR_CLIENTDLL, "Nameplates: World scale of name plate, a setting of 1 means 1px = 1unit.")
function GM.Config.NamePlates:Scale()
return self.ConVars.Scale:GetFloat()
end
-- Height
GM.Config.NamePlates.ConVars.Height = CreateConVarIfNotExists("ph_nameplates_height", "10", FCVAR_ARCHIVE + FCVAR_CLIENTDLL, "Nameplates: Height above player.")
function GM.Config.NamePlates:Height()
return self.ConVars.Height:GetFloat()
end
-- Tint Color
GM.Config.NamePlates.ConVars.TintHue = CreateConVarIfNotExists("ph_nameplates_tint_hue", "0", FCVAR_ARCHIVE + FCVAR_CLIENTDLL, "Nameplates: Tint hue.")
function GM.Config.NamePlates:TintHue()
return self.ConVars.TintHue:GetFloat()
end
GM.Config.NamePlates.ConVars.TintSaturation = CreateConVarIfNotExists("ph_nameplates_tint_saturation", "0", FCVAR_ARCHIVE + FCVAR_CLIENTDLL, "Nameplates: Tint saturation.")
function GM.Config.NamePlates:TintSaturation()
return self.ConVars.TintSaturation:GetFloat()
end
GM.Config.NamePlates.ConVars.TintValue = CreateConVarIfNotExists("ph_nameplates_tint_value", "1", FCVAR_ARCHIVE + FCVAR_CLIENTDLL, "Nameplates: Tint value.")
function GM.Config.NamePlates:TintValue()
return self.ConVars.TintValue:GetFloat()
end
-- Tint By Health
GM.Config.NamePlates.ConVars.TintHealth = CreateConVarIfNotExists("ph_nameplates_tint_health", "0", FCVAR_ARCHIVE + FCVAR_CLIENTDLL, "Nameplates: Tint the nameplate using their health percent.")
function GM.Config.NamePlates:TintHealth()
return self.ConVars.TintHealth:GetBool()
end
-- Tint By Team
GM.Config.NamePlates.ConVars.TintTeam = CreateConVarIfNotExists("ph_nameplates_tint_team", "0", FCVAR_ARCHIVE + FCVAR_CLIENTDLL, "Nameplates: Tint the nameplate with the team colors.")
function GM.Config.NamePlates:TintTeam()
return self.ConVars.TintTeam:GetBool()
end
end 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
@@ -26,23 +26,14 @@
--! Gamemode Information --! Gamemode Information
-- ------------------------------------------------------------------------- -- -- ------------------------------------------------------------------------- --
GM.Name = "Prop Hunt Extended" GM.Name = "Prop Hunt Extended"
GM.Author = "Michael 'Xaymar' Dirks (Based on Kow@lskis Version, Original by AMT)" GM.Author = "Michael Fabian 'Xaymar' Dirks"
GM.Email = "michael.fabian.dirks@gmail.com" GM.Email = "info@xaymar.com"
GM.Website = "http://xaymar.com/" GM.Website = "http://xaymar.com/"
GM.TeamBased = true GM.TeamBased = true
GM.AllowAutoTeam = true GM.AllowAutoTeam = true
GM.SecondsBetweenTeamSwitches = 10 GM.SecondsBetweenTeamSwitches = 10
-- ------------------------------------------------------------------------- --
--! Includes
-- ------------------------------------------------------------------------- --
-- Player Classes
include "player_class/class_default.lua"
include "player_class/class_spectator.lua"
include "player_class/class_seeker.lua"
include "player_class/class_hider.lua"
-- ------------------------------------------------------------------------- -- -- ------------------------------------------------------------------------- --
--! Code --! Code
-- ------------------------------------------------------------------------- -- -- ------------------------------------------------------------------------- --
@@ -56,10 +47,9 @@ GM.States.PostRound = 4
GM.States.PostMatch = 5 GM.States.PostMatch = 5
-- Game Modes -- Game Modes
GM.Modes = {} GM.Types = {}
GM.Modes.Original = 0 GM.Types.Original = 0
GM.Modes.SwizzleEffect = 1 -- Randomizes Teams each Round GM.Types.TheDeadHunt = 1 -- One Hunter, Dead Prop become Hunter, Props can't see each other.
GM.Modes.TheDeadHunt = 2 -- One Hunter, Dead Prop become Hunter, Props can't see each other.
-- Teams -- Teams
GM.Teams = {} GM.Teams = {}
@@ -75,13 +65,15 @@ function GM:CreateTeams()
"info_player_combine", "info_player_combine",
"info_player_counterterrorist", "info_player_counterterrorist",
"info_player_allies", "info_player_allies",
"info_player_terrorist" "info_player_terrorist",
"info_player_start"
}) })
team.SetClass(self.Teams.Spectators, { "Spectator", "Spectator" }) team.SetClass(self.Teams.Spectators, { "Spectator", "Spectator" })
-- Seekers: "Hunters" -- Seekers: "Hunters"
team.SetUp(self.Teams.Seekers, "Seekers", Color(0, 128, 255, 255)) team.SetUp(self.Teams.Seekers, "Seekers", Color(0, 128, 255, 255))
team.SetSpawnPoint(self.Teams.Seekers, { team.SetSpawnPoint(self.Teams.Seekers, {
"info_player_start",
"info_player_spawn", "info_player_spawn",
"info_player_deathmatch", "info_player_deathmatch",
"info_player_combine", "info_player_combine",
@@ -92,6 +84,7 @@ function GM:CreateTeams()
-- Hiders: "Props" -- Hiders: "Props"
team.SetUp(self.Teams.Hiders, "Hiders", Color(255, 128, 0, 255)) team.SetUp(self.Teams.Hiders, "Hiders", Color(255, 128, 0, 255))
team.SetSpawnPoint(self.Teams.Hiders, { team.SetSpawnPoint(self.Teams.Hiders, {
"info_player_start",
"info_player_spawn", "info_player_spawn",
"info_player_deathmatch", "info_player_deathmatch",
"info_player_allies", "info_player_allies",
@@ -112,17 +105,23 @@ function GM:PlayerTick(ply, mv)
end end
function GM:PlayerHurt(victim, attacker, healthRemaining, damageTaken) function GM:PlayerHurt(victim, attacker, healthRemaining, damageTaken)
if (victim != nil && victim:IsPlayer()) then player_manager.RunClass(victim, "Hurt", victim, attacker, healthRemaining, damageTaken)
player_manager.RunClass(victim, "Hurt", victim, attacker, healthRemaining, damageTaken)
end if (IsValid(attacker) && attacker:IsPlayer()) then
if (attacker != nil && attacker:IsPlayer()) then
player_manager.RunClass(attacker, "Damage", victim, attacker, healthRemaining, damageTaken) player_manager.RunClass(attacker, "Damage", victim, attacker, healthRemaining, damageTaken)
end end
end end
function GM:PlayerShouldTakeDamage(victim, attacker)
return player_manager.RunClass(victim, "ShouldTakeDamage", attacker)
end
-- ------------------------------------------------------------------------- -- -- ------------------------------------------------------------------------- --
--! Gamemode Functionality --! Gamemode Functionality
-- ------------------------------------------------------------------------- -- -- ------------------------------------------------------------------------- --
function GM:GetRound()
return GetGlobalInt("Round", 0)
end
function GM:GetRoundState() function GM:GetRoundState()
return GetGlobalInt("RoundState", self.States.PreMatch) return GetGlobalInt("RoundState", self.States.PreMatch)
end end
@@ -133,4 +132,15 @@ end
function GM:GetRoundWinner() function GM:GetRoundWinner()
return GetGlobalInt("RoundWinner", GAMEMODE.Teams.Spectator) return GetGlobalInt("RoundWinner", GAMEMODE.Teams.Spectator)
end end
-- ------------------------------------------------------------------------- --
--! Includes
-- ------------------------------------------------------------------------- --
include "sh_config.lua"
-- Player Classes
include "player_class/class_default.lua"
include "player_class/class_spectator.lua"
include "player_class/class_seeker.lua"
include "player_class/class_hider.lua"
Binary file not shown.

Before

Width:  |  Height:  |  Size: 52 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

@@ -2,181 +2,242 @@
{ {
"base" "base" "base" "base"
"title" "Prop Hunt Extended" "title" "Prop Hunt Extended"
"maps" "^ph_|^cs_|^de_|^ttt_" "maps" "^ph_"
"menusystem" "1" "menusystem" "1"
"workshopid" "468149739" "workshopid" "468149739"
"settings" "settings"
{ {
// Game Settings // Debug Settings
1 1
{ {
"name" "ph_gamemode" "name" "ph_debug"
"text" "G: Game Mode" "text" "Enable Debug Mode"
"help" "0: Basic, 1: Swizzle Effect (Random Teams), 2: The Dead Hunt (One Hunter, Dead Props become Hunters)" "type" "CheckBox"
"type" "Numeric"
"default" "0" "default" "0"
} }
2 2
{ {
"name" "mp_timelimit" "name" "ph_debug_log"
"text" "G: Time Limit" "text" "Enable Debug Logging"
"help" "Time Limit in Minutes for how long should we stay on one map. (0 to disable)"
"type" "Numeric"
"default" "20"
}
3
{
"name" "ph_sprinting"
"text" "G: Enable Sprinting"
"help" "Should sprinting be possible?"
"type" "CheckBox" "type" "CheckBox"
"default" "0" "default" "1"
} }
4 // Basic Settings
{
"name" "ph_tauntcooldown"
"text" "G: Taunt Cooldown"
"help" "How much time must pass before another taunt may be played."
"type" "Numeric"
"default" "5"
}
// Round Settings
10
{
"name" "ph_round_limit"
"text" "R: Rounds per Map"
"help" "How many rounds are played per map."
"type" "Numeric"
"default" "10"
}
11 11
{ {
"name" "ph_round_timelimit" "name" "ph_gametype"
"text" "R: Round Duration (Seconds)" "text" "Game Type to use"
"help" "How long is each round going to last?"
"type" "Numeric" "type" "Numeric"
"default" "300" "default" "0"
} }
12 12
{ {
"name" "ph_round_blindtime" "name" "mp_timelimit"
"text" "R: Hiding Time (Seconds)" "text" "Map Time Limit"
"help" "How long are hunters blinded? (positive values will be inside the round time limit, negative will add to the round time limit)"
"type" "Numeric" "type" "Numeric"
"default" "30" "default" "0"
}
// Seeker Settings
20
{
"name" "ph_seeker_health"
"text" "S: Health"
"type" "Numeric"
"default" "100"
} }
13
{
"name" "ph_sprinting"
"text" "Enable Sprinting"
"type" "CheckBox"
"default" "0"
}
// Round Settings
21 21
{ {
"name" "ph_seeker_health_max" "name" "ph_round_limit"
"text" "S: Max Health" "text" "Maximum Rounds Played"
"type" "Numeric" "type" "Numeric"
"default" "100" "default" "10"
} }
22 22
{ {
"name" "ph_seeker_health_bonus" "name" "ph_round_timelimit"
"text" "S: Health Kill-Bonus" "text" "Time Limit per Round"
"help" "Health gained on kill."
"type" "Numeric" "type" "Numeric"
"default" "20" "default" "180"
} }
23 23
{ {
"name" "ph_seeker_health_penalty" "name" "ph_round_blindtime"
"text" "S: Health Penalty" "text" "Seeker Blind time per Round"
"help" "Health lost on wrong shot."
"type" "Numeric" "type" "Numeric"
"default" "5" "default" "-30"
}
24
{
"name" "ph_seeker_weapons"
"text" "S: Weapons to be given to Seekers"
"help" "Format: Weapon,Weapon,..."
"type" "Text"
"default" "weapon_crowbar,weapon_pistol,weapon_ph_smg,weapon_shotgun,weapon_physcannon"
}
25
{
"name" "ph_seeker_ammo"
"text" "S: Ammo to give to Seekers"
"help" "Format: Name:Amount,Name:Amount,..."
"type" "Text"
"default" "Pistol:100,SMG1:300,SMG1_Grenade:1,Buckshot:64"
}
// Hider Settings
30
{
"name" "ph_hider_health"
"text" "H: Health"
"type" "Numeric"
"default" "100"
} }
// Team Settings
31 31
{ {
"name" "ph_hider_health_max" "name" "ph_teams_randomize"
"text" "H: Max Health" "text" "Randomize Teams"
"type" "Numeric" "type" "CheckBox"
"default" "100" "default" "1"
} }
32 32
{ {
"name" "ph_hider_health_scaling" "name" "ph_teams_weighted"
"text" "H: Enable Health Scaling" "text" "Randomize with weighted Score"
"help" "Larger & heavier objects have more health, smaller less."
"type" "CheckBox" "type" "CheckBox"
"default" "1" "default" "1"
} }
33 33
{
"name" "ph_teams_seekerpct"
"text" "Pct of Pl. becoming Seeker"
"type" "Numeric"
"default" "25"
}
// Seeker Settings
41
{
"name" "ph_seeker_health"
"text" "Seeker Health"
"type" "Numeric"
"default" "100"
}
42
{
"name" "ph_seeker_health_max"
"text" "Seeker Max Health"
"type" "Numeric"
"default" "100"
}
43
{
"name" "ph_seeker_health_bonus"
"text" "Seeker Health Kill-Bonus"
"type" "Numeric"
"default" "20"
}
44
{
"name" "ph_seeker_health_penalty"
"text" "Seeker Health Penalty"
"type" "Numeric"
"default" "5"
}
45
{
"name" "ph_seeker_weapons"
"text" "Seeker Weapons"
"type" "Text"
"default" "weapon_crowbar,weapon_pistol,weapon_ph_smg,weapon_shotgun"
}
46
{
"name" "ph_seeker_ammo"
"text" "Seeker Ammo"
"type" "Text"
"default" "Pistol:100,SMG1:300,SMG1_Grenade:1,Buckshot:64"
}
// Hider Settings
51
{
"name" "ph_hider_health"
"text" "Hider Health"
"type" "Numeric"
"default" "100"
}
52
{
"name" "ph_hider_health_max"
"text" "Hider Max Health"
"type" "Numeric"
"default" "100"
}
53
{
"name" "ph_hider_health_scaling"
"text" "Hider Enable Health Scaling"
"type" "CheckBox"
"default" "1"
}
54
{ {
"name" "ph_hider_health_scaling_max" "name" "ph_hider_health_scaling_max"
"text" "H: Scaled Max Health" "text" "Hider Scaled Max Health"
"type" "Numeric" "type" "Numeric"
"default" "200" "default" "200"
} }
55
{
"name" "ph_hider_allow_full_rotation"
"text" "Hider 3-Dimensional Rotation"
"type" "CheckBox"
"default" "0"
}
// Whitelist & Blacklist // Whitelist & Blacklist
40 61
{ {
"name" "ph_list_class_whitelist" "name" "ph_list_class_whitelist"
"text" "L: Allowed Entity Classes" "text" "Allowed Entity Classes"
"help" "Hiders can only use these for changing model and skin."
"type" "Text" "type" "Text"
"default" "ph_prop,prop_physics,prop_physics_multiplayer,prop_physics_respawnable" "default" "ph_prop,prop_physics,prop_physics_multiplayer,prop_physics_respawnable"
} }
41 62
{ {
"name" "ph_list_abuse_blacklist" "name" "ph_list_abuse_blacklist"
"text" "L: Abuse Blacklist" "text" "Abuse Blacklist"
"help" "Fix interact spam with certain entities so that all areas stay accessible."
"type" "Text" "type" "Text"
"default" ""func_button,func_door,func_door_rotation,prop_door_rotation,func_tracktrain,func_tanktrain,func_breakable"" "default" "func_button,func_door,func_door_rotation,prop_door_rotation,func_tracktrain,func_tanktrain,func_breakable"
}
63
{
"name" "ph_list_model_blacklist"
"text" "Model Blacklist"
"type" "Text"
"default" "models/props/cs_assault/dollar.mdl,models/props/cs_assault/money.mdl,models/props/cs_office/snowman_arm.mdl,models/props/cs_office/projector_remote.mdl"
}
// Taunts
71
{
"name" "ph_taunt_cooldown"
"text" "Cooldown for Taunts"
"type" "Numeric"
"default" "5"
}
72
{
"name" "ph_taunt_seekers"
"text" "Seeker Taunts"
"type" "Text"
"default" "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"
}
73
{
"name" "ph_taunt_hiders"
"text" "Hider Taunts"
"type" "Text"
"default" "ambient/alarms/apc_alarm_pass1.wav,ambient/alarms/manhack_alert_pass1.wav,ambient/alarms/razortrain_horn1.wav,ambient/alarms/scanner_alert_pass1.wav,ambient/alarms/train_horn2.wav,ambient/alarms/train_horn_distant1.wav,ambient/alarms/warningbell1.wav,ambient/energy/whiteflash.wav,ambient/intro/alyxremove.wav,ambient/intro/logosfx.wav,ambient/levels/launch/1stfiringwarning.wav,ambient/levels/launch/rockettakeoffblast.wav,ambient/misc/ambulance1.wav,ambient/misc/carhonk1.wav,ambient/misc/carhonk2.wav,ambient/misc/carhonk3.wav,ambient/outro/gunshipcrash.wav,ambient/3dmeagle.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,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"
} }
} }
} }
+2 -5
View File
@@ -1,7 +1,4 @@
@ECHO OFF @ECHO OFF
:: Retrieve Garry's Mod path from Regristry call env.win.bat
:: 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=C:\Program Files (x86)\Steam\steamapps\common\GarrysMod"
SET "PATH=%CD%;%GARRYSMODPATH%\bin;%PATH%" SET "PATH=%CD%;%GARRYSMODPATH%\bin;%PATH%"
CMD CMD
+2 -4
View File
@@ -1,6 +1,4 @@
@ECHO OFF @ECHO OFF
SET "PWD=%~dp0" call env.win.bat
CALL build-env.bat "%GARRYSMODPATH%\bin\gmad.exe" create -folder "%CD%\Source" -out "%CD%\Pack.gma"
"%TOOLPATH%\bin\gmad.exe" create -folder "%PWD%\Source" -out "%PWD%\Pack.gma"
PAUSE PAUSE
+2 -4
View File
@@ -1,6 +1,4 @@
@ECHO OFF @ECHO OFF
SET "PWD=%~dp0" call env.win.bat
CALL build-env.bat "%GARRYSMODPATH%\bin\gmpublish.exe" update -id 468149739 -icon "media\gamemode_workshop.jpg" -addon "Pack.gma" -changes ""
"%GARRYSMODPATH%\bin\gmpublish.exe" update -id %WORKSHOPID% -icon "Logo.jpg" -addon "Pack.gma" -changes ""
PAUSE PAUSE
-2
View File
@@ -1,2 +0,0 @@
SET "WORKSHOPID=468149739"
FOR /F "tokens=2* delims= " %%A IN ('REG QUERY "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Steam App 4000" /v InstallLocation') DO SET "TOOLPATH=%%B"
+11
View File
@@ -0,0 +1,11 @@
@ECHO OFF
:: Garry's Mod
SET "GARRYSMODPATH=C:\Program Files (x86)\Steam\steamapps\common\GarrysMod"
FOR /F "tokens=2* delims= " %%A IN ('REG QUERY "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Steam App 4000" /v InstallLocation') DO SET "GARRYSMODPATH=%%B"
IF "%GARRYSMODPATH%" == "" (
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"
)
IF "%GARRYSMODPATH%" == "" (
ECHO Failed to figure out where Garry's Mod is installed.
)
Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

Binary file not shown.