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
if (self.Owner:GetNWBool("PropRotation")) then
self:SetAngles(self.Owner:EyeAngles())
self:ApplyRotation(self.Owner:EyeAngles())
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...")
self.Data = {}
print("Prop Hunt CL: Creating Huge Ass Font...")
surface.CreateFont("PHHugeAssFont", {font="Roboto Bold Condensed", extended=true, size=160, weight=800, antialias=true})
print("Prop Hunt CL: Creating Fonts...")
surface.CreateFont("RobotoBoldCondensed160", {font="Roboto Bold Condensed", extended=true, size=160, weight=800, antialias=true})
print("Prop Hunt CL: Complete.")
print("-------------------------------------------------------------------------")
@@ -51,7 +51,7 @@ end
function GM:Think() end
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.
if (!LocalPlayer()) || (!IsValid(LocalPlayer())) then
@@ -59,13 +59,13 @@ function GM:InitialPlayerSpawn()
return
end
print("Prop Hunt CL: InitialPlayerSpawn Valid")
if GAMEMODE.Config:DebugLog() then print("Prop Hunt CL: InitialPlayerSpawn Valid") end
player_manager.RunClass(LocalPlayer(), "InitialClientSpawn")
end
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.
if (!LocalPlayer()) || (!IsValid(LocalPlayer())) then
@@ -73,7 +73,7 @@ function GM:PlayerSpawn()
return
end
print("Prop Hunt CL: PlayerSpawn Valid")
if GAMEMODE.Config:DebugLog() then print("Prop Hunt CL: PlayerSpawn Valid") end
if !(LocalPlayer().Data) then
LocalPlayer().Data = {}
@@ -106,8 +106,9 @@ function GM:PlayerSetViewOffset(vo, voduck)
if !(GAMEMODE.TempData) then GAMEMODE.TempData = {} end
GAMEMODE.TempData.ViewOffset = vo
GAMEMODE.TempData.ViewOffsetDuck = voduck
timer.Simple(.1, function() GAMEMODE:PlayerSetViewOffset(GAMEMODE.TempData.ViewOffset, GAMEMODE.TempData.ViewOffsetDuck) end)
timer.Simple(.1, function()
GAMEMODE:PlayerSetViewOffset(GAMEMODE.TempData.ViewOffset, GAMEMODE.TempData.ViewOffsetDuck)
end)
return
end
@@ -126,8 +127,8 @@ function GM:PlayerSetHull(hullMin, hullMax)
if !(GAMEMODE.TempData) then GAMEMODE.TempData = {} end
GAMEMODE.TempData.HullMin = hullMin
GAMEMODE.TempData.HullMax = hullMax
timer.Simple(.1, function() GAMEMODE:PlayerSetHull(GAMEMODE.TempData.HullMin, GAMEMODE.TempData.HullMax) end)
timer.Simple(.1, function()
GAMEMODE:PlayerSetHull(GAMEMODE.TempData.HullMin, GAMEMODE.TempData.HullMax) end)
return
end
@@ -146,20 +147,24 @@ function GM:OnContextMenuOpen()
end
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
end
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)
net.Start("PlayerEnablePropRotation");net.SendToServer()
net.Start("PlayerEnablePropRotation")
net.WriteAngle(LocalPlayer():EyeAngles())
net.SendToServer()
end
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)
net.Start("PlayerDisablePropRotation");net.SendToServer()
net.Start("PlayerDisablePropRotation")
net.WriteAngle(LocalPlayer():EyeAngles())
net.SendToServer()
end
function GM:ShowHelpUI()
@@ -187,29 +192,46 @@ net.Receive( "PlayerViewOffset", function(len, pl)
GAMEMODE:PlayerSetViewOffset(vo, voduck)
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
-- ------------------------------------------------------------------------- --
--[[
-- Render halos and player names.
function DrawPlayerNames(bDrawingDepth, bDrawingSkybox)
for i,v in ipairs(player.GetAll()) do
if v:Alive() && v != LocalPlayer() then
local pos = v:GetPos() + v:GetViewOffset() + Vector(0, 0, 5)
local ang = Angle(0, LocalPlayer():EyeAngles().y - 90, 90 - LocalPlayer():EyeAngles().x)
local healthPrc = v:Health() / v:GetMaxHealth()
local healthCol = HSVToColor(120 * healthPrc, 1.0, 1.0)
if v:Team() == TEAM_HUNTERS || LocalPlayer():Team() == TEAM_PROPS then
cam.Start3D2D(pos, ang, 0.15)
draw.DrawText(v:GetName(), "Trebuchet24", 0, -draw.GetFontHeight("Trebuchet24"), healthCol, TEXT_ALIGN_CENTER)
cam.End3D2D()
end
end
end
end
hook.Add("PostDrawTranslucentRenderables", "PH_DrawPlayerNames", DrawPlayerNames)
function DrawPlayerHalos(bDrawingDepth, bDrawingSkybox)
for i,v in ipairs(player.GetAll()) do
if v:Alive() then
@@ -23,7 +23,7 @@
--]]
local PANEL = vgui.Create("DFrame")
PANEL:SetSize(400, 300)
PANEL:SetSize(640, 480)
PANEL:SetTitle("Help")
PANEL:SetDraggable(true)
PANEL:SetVisible(false)
@@ -32,30 +32,51 @@ PANEL:SetSizable(true)
PANEL:ShowCloseButton(true)
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()
self:SetSize(ScrW(), ScrH())
--self:SetSize(ScrW(), ScrH())
self:Center()
self:SetVisible(true)
self:SetFocusTopLevel(true)
self:SlideDown(.5)
self:MakePopup()
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.
--]]
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.Frame = vgui.Create("DFrame")
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.
hook.Run("ph_AddTaunts", nil)
-- Insert the taunts into the new structure.
for k,v in ipairs(GAMEMODE.Hunter_Taunts) do
-- ToDo: string.GetFileFromFilename is broken!
--pcall(GAMEMODE.Config.Taunts.Add("TauntPackLoader."..string.GetFileFromFilename(v), v, TEAM_SEEKERES, nil))
-- Insert the taunts into the new structure (cvar).
Taunts = {}
for i,t in ipairs(GAMEMODE.Prop_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
-- HiderTaunts[#HiderTaunts+1] = snd
-- end
end
end
for k,v in ipairs(GAMEMODE.Prop_Taunts) do
--pcall(GAMEMODE.Config.Taunts.Add("TauntPackLoader."..string.GetFileFromFilename(v), v, TEAM_HIDERS, nil))
GAMEMODE.Config.Taunt.HidersCacheStatic = Taunts
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
GAMEMODE.Config.Taunt.SeekersCacheStatic = Taunts
-- Clean up after ourselves
GAMEMODE.Prop_Taunts = nil
GAMEMODE.Hunter_Taunts = nil
end
hook.Add("OnPropHuntInitialized", "CompatTauntPackLoader", CompatTauntPackLoader)
hook.Add("Initialize", "CompatTauntPackLoader", CompatTauntPackLoader)
@@ -28,7 +28,6 @@
-- Shared
AddCSLuaFile("sh_init.lua")
AddCSLuaFile("sh_config.lua")
AddCSLuaFile("sh_player.lua")
AddCSLuaFile("player_class/class_default.lua")
AddCSLuaFile("player_class/class_spectator.lua")
AddCSLuaFile("player_class/class_seeker.lua")
@@ -46,7 +45,6 @@ AddCSLuaFile("client/cl_ui_teamselection.lua")
include "sh_init.lua"
-- Server Only
include "server/config.lua"
include "compat/compat_tauntpackloader.lua"
include "server/roundmanager.lua"
include "server/states/state_prematch.lua"
@@ -63,7 +61,6 @@ function GM:Initialize()
print("Prop Hunt: Registering Networked Messages...")
util.AddNetworkString("PlayerManagerInitialClientSpawn")
util.AddNetworkString("PlayerManagerClientSpawn")
util.AddNetworkString("PlayerSetHull")
util.AddNetworkString("PlayerResetHull")
util.AddNetworkString("PlayerViewOffset")
@@ -73,10 +70,15 @@ function GM:Initialize()
print("Prop Hunt: Initializing Gamemode Data...")
self.Data = {}
self.Data.StartTime = CurTime()
print("Prop Hunt: Setting initial RoundManager State...")
self.RoundManager:SetState(StatePreMatch)
print("Prop Hunt: Precaching...")
GAMEMODE.Config.Taunt:Seekers()
GAMEMODE.Config.Taunt:Hiders()
print("Prop Hunt: Complete.")
print("-------------------------------------------------------------------------")
end
@@ -87,28 +89,29 @@ end
-- Player Connected
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
-- Player Authenticated
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
-- Player Disconnected
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
-- Player Spawn (Initial)
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
-- Initialize Data Structure
ply.Data = {}
ply.Data.Alive = false
ply.Data.AliveTime = 0
ply.Data.RandomWeight = 0 -- Higher means higher chance of becoming Seeker instead of Hider.
end
-- Kill Silently
@@ -121,10 +124,10 @@ function GM:PlayerInitialSpawn(ply)
-- Bot: Auto Assign to Team
if (ply:IsBot()) then
if team.NumPlayers(self.Teams.Hiders) > team.NumPlayers(self.Teams.Seekers) then
print("Prop Hunt: Bot '"..ply:GetName().."' assigned to Seekers.")
if GAMEMODE.Config:DebugLog() then print("Prop Hunt: Bot '"..ply:GetName().."' assigned to Seekers.") end
ply:SetTeam(self.Teams.Seekers)
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)
end
end
@@ -138,7 +141,7 @@ end
-- Player Spawn
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
local class = team.GetClass(ply:Team())
@@ -167,7 +170,7 @@ end
-- Player requests Team Change
function GM:PlayerRequestTeam(ply, teamId)
if self:PlayerCanJoinTeam(ply, teamId) then
print("Prop Hunt: Player '"..ply:GetName().."' (SteamID: "..ply:SteamID()..") requested to join Team "..team.GetName(teamId)..".")
if 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
ply:KillSilent()
@@ -178,7 +181,7 @@ function GM:PlayerRequestTeam(ply, teamId)
ply.AliveTime = CurTime()
end
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
@@ -187,7 +190,38 @@ end
--! Player Manager Binding
-- ------------------------------------------------------------------------- --
function GM:PlayerLoadout(ply) player_manager.RunClass(ply, "Loadout") end
function GM:PlayerDeath(ply, inflictor, attacker) player_manager.RunClass(ply, "Death", inflictor, attacker) end
function GM: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:PostPlayerDeath(ply)
player_manager.RunClass(ply, "PostDeath")
@@ -195,10 +229,10 @@ function GM:PostPlayerDeath(ply)
-- Debug Mode: Respawn after Death
if (GAMEMODE.Config:Debug()) then
ply.Data.Alive = true
print("Prop Hunt: Debug Mode active, Player "..ply:GetName().." was respawned.")
if GAMEMODE.Config:DebugLog() then print("Prop Hunt: Debug Mode active, Player "..ply:GetName().." was respawned.") 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:CanPlayerSuicide(ply) return player_manager.RunClass(ply, "CanSuicide") end
function GM:PlayerCanPickupWeapon(ply, weapon) return player_manager.RunClass(ply, "CanPickupWeapon", weapon) end
@@ -219,6 +253,10 @@ end
-- ------------------------------------------------------------------------- --
--! Gamemode Functionality
-- ------------------------------------------------------------------------- --
function GM:SetRound(Round)
SetGlobalInt("Round", Round)
end
function GM:SetRoundState(State)
SetGlobalInt("RoundState", State)
end
@@ -241,6 +279,7 @@ function GM:PlayerHullFromEntity(ply, ent)
hull.x = hull.y
end
hull:Mul(0.5)
hull:Mul(0.95) -- Reduce size slightly
local hullmin = Vector(-hull.x, -hull.y, 0)
local hullmax = Vector(hull.x, hull.y, hull.z * 2)
@@ -289,153 +328,65 @@ function GM:ShowTeam(ply)
ply:ConCommand("ph_select_team")
end
-- F3/ShowSpare1
function GM:ShowSpare1(ply) end
-- F4/ShowSpare2
function GM:ShowSpare2(ply) end
function GM:ShowSpare1(ply) player_manager.RunClass(ply, "ShowSpare1") end -- F3/ShowSpare1
function GM:ShowSpare2(ply) player_manager.RunClass(ply, "ShowSpare2") end -- F4/ShowSpare2
-- Debug Command: Print All Players
concommand.Add("ph_debug_printplayers", function(ply, cmd, args, argStr)
print ("All Players:")
for i,ply in ipairs(player.GetAll()) do
print(" "..ply:GetName().." (SteamID: "..ply:SteamID()..") - Team "..team.GetName(ply:Team()).. " - Alive "..tostring(ply.Data.Alive))
if GAMEMODE.Config:DebugLog() then
print ("All Players:")
for i,ply in ipairs(player.GetAll()) do
print(" "..ply:GetName().." (SteamID: "..ply:SteamID()..") - Team "..team.GetName(ply:Team()).. " - Alive "..tostring(ply.Data.Alive))
end
print ("Spectators:")
for i,ply in ipairs(team.GetPlayers(GAMEMODE.Teams.Spectators)) do
print(" "..ply:GetName().." (SteamID: "..ply:SteamID()..")")
end
print ("Seekers:")
for i,ply in ipairs(team.GetPlayers(GAMEMODE.Teams.Seekers)) do
print(" "..ply:GetName().." (SteamID: "..ply:SteamID()..")")
end
print ("Hiders:")
for i,ply in ipairs(team.GetPlayers(GAMEMODE.Teams.Hiders)) do
print(" "..ply:GetName().." (SteamID: "..ply:SteamID()..")")
end
end
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)
-- 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
-- ------------------------------------------------------------------------- --
net.Receive("PlayerEnablePropRotation", function(len, ply)
if (ply:Team() != GAMEMODE.Teams.Hiders) then
return
end
print("Prop Hunt: Enabling Prop Rotation")
ply:SetNWBool("PropRotation", true)
ply.Data.Prop:ApplyRotation(net.ReadAngle())
end)
net.Receive("PlayerDisablePropRotation", function(len, ply)
if (ply:Team() != GAMEMODE.Teams.Hiders) then
return
end
print("Prop Hunt: Disabling Prop Rotation")
ply:SetNWBool("PropRotation", false)
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)
]]
ply.Data.Prop:ApplyRotation(net.ReadAngle())
end)
@@ -49,6 +49,7 @@ function CLASS:Spawn() end
function CLASS:Loadout() end
-- 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:Damage(victim, attacker, healthRemaining, damageDealt) end -- Damage Dealt
function CLASS:DamageEntity(ent, attacker, dmginfo) end -- Damage Dealt To Entity
@@ -63,9 +64,7 @@ function CLASS:SilentDeath()
self.Player.Data.AliveTime = CurTime()
end
function CLASS:PostDeath() end
function CLASS:DoDeath() end
function CLASS:DeathThink()
if (CurTime() - self.Player.Data.AliveTime) > 5 then
self.Player:Spawn()
@@ -73,7 +72,6 @@ function CLASS:DeathThink()
end
return false
end
function CLASS:CanSuicide() return true end
-- Visible Stuff
@@ -109,6 +107,16 @@ function CLASS:AllowPickup(ent) return false end
function CLASS:CanPickupWeapon(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
-- ------------------------------------------------------------------------- --
@@ -130,72 +138,52 @@ function CLASS:GetHandsModel() return BaseClass.GetHandsModel(self) end
function CLASS:ShouldDrawLocal() return false end
function CLASS:HUDPaint()
local State = GetGlobalInt("RoundState", GAMEMODE.States.PreMatch)
if State == -1 then
return
end
-- Show Status at the top center
local statusX, statusY, statusW, statusH
statusW = 192
statusH = 64
statusX = ScrW() / 2 - statusW / 2
statusY = 16
-- Status Box at the top.
local statusW, statusH = 256,48
local statusX, statusY = ScrW() / 2 - statusW / 2, 0
draw.RoundedBox(0, statusX, statusY, statusW, statusH, Color(0,0,0,204)) -- Background
draw.RoundedBox(0, statusX, statusY+statusH, statusW, 4, team.GetColor(LocalPlayer():Team())) -- Team Bar
-- Status
if (State == GAMEMODE.States.PreMatch) then -- Pre Match
draw.RoundedBox(16, statusX, statusY, statusW, statusH, Color(0, 0, 0, 204))
surface.SetFont( "Trebuchet24" )
surface.SetTextColor( 255, 255, 255, 255 )
local w,h = surface.GetTextSize("Waiting for Players")
surface.SetTextPos( statusX + statusW/2 - w / 2, statusY + statusH/2 - h / 2)
surface.DrawText("Waiting for Players")
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..." )
-- Title
surface.SetFont("Trebuchet18")
surface.SetTextColor(Color(255,255,255,255))
local titleText = ""
if (State == GAMEMODE.States.PreMatch) then
titleText = "Waiting for Players"
elseif (State == GAMEMODE.States.PreRound) then
titleText = "Preparing Round..."
elseif (State == GAMEMODE.States.Hide) then -- Hide
local strTime = tostring(math.ceil(GetGlobalInt("RoundTime")))
-- Show Status at the top center
draw.RoundedBox(16, statusX, statusY, statusW, statusH, Color(0, 0, 0, 204))
surface.SetTextColor(255,255,255,255)
surface.SetFont("Trebuchet18")
local w,h = surface.GetTextSize("Seekers unblinded in:")
surface.SetTextPos(statusX + statusW/2 - w / 2, statusY + statusH/4 - h / 2)
surface.DrawText("Seekers unblinded in:")
surface.SetFont( "Trebuchet24" )
local w,h = surface.GetTextSize(strTime.." Seconds!")
surface.SetTextPos( statusX + statusW/2 - w / 2, statusY + statusH/1.5 - h / 2)
surface.DrawText(strTime.." Seconds!")
titleText = "Seekers unblinded in:"
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 strTime = string.format("%d:%02d", math.floor(intTime / 60), math.ceil(intTime % 60))
-- Show Status at the top center
draw.RoundedBox(16, statusX, statusY, statusW, statusH, Color(0, 0, 0, 204))
surface.SetTextColor(255,255,255,255)
surface.SetFont("Trebuchet18")
local w,h = surface.GetTextSize("Hunting Time!")
surface.SetTextPos(statusX + statusW/2 - w / 2, statusY + statusH/4 - h / 2)
surface.DrawText("Hunting Time!")
surface.SetFont( "Trebuchet24" )
local w,h = surface.GetTextSize(strTime)
surface.SetTextPos( statusX + statusW/2 - w / 2, statusY + statusH/1.5 - h / 2)
surface.DrawText(strTime)
stateText = strTime
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 victorName = "Unknown"
local victorName = "Draw"
if (victor == GAMEMODE.Teams.Spectator) then
victorName = "Draw"
elseif (victor == GAMEMODE.Teams.Hiders) then
@@ -203,17 +191,69 @@ function CLASS:HUDPaint()
elseif (victor == GAMEMODE.Teams.Seekers) then
victorName = "Seekers Win"
end
stateText = victorName
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
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
function CLASS:CalcView(camdata) return camdata end
-- ------------------------------------------------------------------------- --
--! Register
@@ -35,26 +35,31 @@ CLASS.UseVMHands = false -- Uses viewmodel hands
-- ------------------------------------------------------------------------- --
-- 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)
-- Sprinting
if (!GAMEMODE.Config:Sprinting()) then
self.Player:SetRunSpeed(self.WalkSpeed)
end
-- Settings
self.Player:SetMaxHealth(GAMEMODE.Config.Hider:HealthMax())
self.Player:SetHealth(GAMEMODE.Config.Hider:Health())
self.Player:SetRenderMode(RENDERMODE_TRANSALPHA)
self.Player:SetColor(Color(0,0,0,0))
-- 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
GAMEMODE:PlayerHullFromEntity(self.Player, nil)
GAMEMODE:PlayerSetViewOffset(self.Player, Vector(0,0,72), Vector(0,0,72))
-- Collision Group
self.Player:SetCollisionGroup(COLLISION_GROUP_PLAYER)
self.Player:SetSolid(SOLID_VPHYSICS)
-- Prop Stuff
self.Player.Data.Prop = ents.Create("ph_prop")
@@ -70,7 +75,7 @@ end
-- Death
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)
-- Delete Hands Model
@@ -120,11 +125,11 @@ function CLASS:Use(ent)
end
-- Check Lists and other Parameters
if (!table.HasValue(GAMEMODE.Config.Lists:ClassWhitelist(), ent:GetClass()))-- Class is not Whitelisted
|| (GAMEMODE.Config.Lists.ModelBlacklist[ent:GetModel()]) -- Model is Blacklisted
|| !((ent:GetPhysicsObject()) && (ent:GetPhysicsObject():IsValid())) -- Entity doesn't have Physics
if (!table.HasValue(GAMEMODE.Config.Lists:ClassWhitelist(), ent:GetClass())) -- Class is not Whitelisted
|| (table.HasValue(GAMEMODE.Config.Lists:ModelBlacklist(), ent:GetModel())) -- Model is Blacklisted
|| !((ent:GetPhysicsObject()) && (ent:GetPhysicsObject():IsValid())) -- Entity doesn't have Physics
then
print("Prop Hunt: Hider '"..self.Player:GetName().."' (SteamID: "..self.Player:SteamID()..") attempted to turn into "..ent:GetClass().." ("..ent:GetModel()..").")
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.
end
@@ -155,11 +160,22 @@ function CLASS:Use(ent)
self.Player:SetMaxHealth(maxhealth)
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
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
-- ------------------------------------------------------------------------- --
@@ -168,71 +184,26 @@ function CLASS:AllowPickup(ent) return true end
--! Client-Side
-- ------------------------------------------------------------------------- --
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)
self.Player:SetRenderMode(RENDERMODE_TRANSALPHA)
end
function CLASS:ShouldDrawLocal()
return false
end
function CLASS:CalcView(camdata)
-- ThirdPerson Settings (ToDo: client config maybe?)
local maxViewDist = 100
local viewDist = self.Player.Data.ViewDistance or 0
-- First/Third
if (self.Player.Data.ThirdPerson) then
if (self.Player.Data.ViewDistance or 0) >= 10 then
if (IsValid(self.Player:GetHands())) then
self.Player:GetHands():SetRenderMode(RENDERMODE_TRANSALPHA)
self.Player:GetHands():SetColor(Color(255, 255, 255, 127))
end
-- Incremental Distance instead of instant.
viewDist = math.Clamp(viewDist * 0.95 + maxViewDist * 0.05, 0, maxViewDist) -- Zoom Out
else
if (IsValid(self.Player:GetHands())) then
self.Player:GetHands():SetRenderMode(RENDERMODE_TRANSALPHA)
self.Player:GetHands():SetColor(Color(255, 255, 255, 0))
end
viewDist = math.Clamp(viewDist * 0.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
return (self.Player.Data.ViewDistance or 0) >= 10
end
-- Register
@@ -44,20 +44,24 @@ CLASS.DropWeaponOnDie = true
-- ------------------------------------------------------------------------- --
-- 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)
-- Sprinting
if (GAMEMODE.Config:Sprinting()) then
self.Player:SetRunSpeed(self.WalkSpeed)
end
-- Settings
self.Player:SetMaxHealth(GAMEMODE.Config.Seeker:HealthMax())
self.Player:SetHealth(GAMEMODE.Config.Seeker:Health())
self.Player:SetRenderMode(RENDERMODE_NORMAL)
self.Player:SetColor(Color(255,255,255,255))
-- 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
GAMEMODE:PlayerHullFromEntity(self.Player, nil)
GAMEMODE:PlayerSetViewOffset(self.Player, Vector(0,0,64), Vector(0,0,32))
@@ -85,15 +89,33 @@ function CLASS:Loadout()
end
-- 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)
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.
if (GAMEMODE:GetRoundState() == GAMEMODE.States.Seek) then
if IsValid(ent) && (!(ent:IsPlayer())) then
if (ent:GetClass() == "ph_prop") then
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?
else
att:TakeDamage(GAMEMODE.Config.Seeker:HealthPenalty(), ent, ent)
@@ -106,11 +128,14 @@ end
function CLASS:Death(inflictor, attacker)
BaseClass.Death(self, inflictor, attacker)
self.Player:CreateRagdoll()
if SERVER then
self.Player:SetShouldServerRagdoll(true)
--self.Player:CreateRagdoll()
end
end
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)
self.Player:UnLock()
@@ -148,11 +173,22 @@ function CLASS:AllowPickup(ent) return true end
function CLASS:CanPickupItem(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
-- ------------------------------------------------------------------------- --
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)
end
@@ -181,53 +217,7 @@ function CLASS:HUDPaint()
end
function CLASS:ShouldDrawLocal()
return self.Player.Data.ThirdPerson
end
function CLASS:CalcView(camdata)
-- ThirdPerson Settings (ToDo: client config maybe?)
local maxViewDist = 100
local viewDist = self.Player.Data.ViewDistance or 0
-- First/Third
if (self.Player.Data.ThirdPerson) then
viewDist = math.Clamp(viewDist * 0.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
return (self.Player.Data.ViewDistance or 0) >= 10
end
-- Register
@@ -35,7 +35,7 @@ CLASS.UseVMHands = false -- Uses viewmodel hands
-- ------------------------------------------------------------------------- --
-- 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)
self.Player:Spectate(OBS_MODE_ROAMING)
@@ -48,7 +48,7 @@ end
-- Death
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)
self.Player:Spectate(OBS_MODE_NONE)
@@ -77,9 +77,10 @@ function CLASS:CanPickupItem(ent) return false end
--! Client-Side
-- ------------------------------------------------------------------------- --
function CLASS:ClientSpawn()
print("Prop Hunt CL: Spectator '"..self.Player:GetName().."' (SteamID: "..self.Player:SteamID()..") spawned.")
if GAMEMODE.Config:DebugLog() then print("Prop Hunt CL: Spectator '"..self.Player:GetName().."' (SteamID: "..self.Player:SteamID()..") spawned.") end
end
function CLASS:ShouldDrawLocal() return false end
function CLASS:CalcView(camdata) return camdata end
player_manager.RegisterClass( "Spectator", CLASS, "Default")
@@ -25,7 +25,7 @@
StateHide = {}
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)
-- Round Data
@@ -59,4 +59,7 @@ end
function StateHide:OnLeave(NewState)
if GAMEMODE.Config:Debug() then print("StateHide: OnLeave") end
-- Fretta Hooks
hook.Run("PropHuntUnblind")
end
@@ -25,15 +25,30 @@
StatePostMatch = {}
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)
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
function StatePostMatch:Tick()
-- Advance State
GAMEMODE.RoundManager:SetState(StatePreMatch)
GAMEMODE.RoundManager:SetState(self.NextState)
end
function StatePostMatch:OnLeave(NewState)
if GAMEMODE.Config:Debug() then print("StatePostMatch: OnLeave") end
if GAMEMODE.Config:DebugLog() then print("StatePostMatch: OnLeave") end
end
@@ -25,35 +25,118 @@
StatePostRound = {}
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.Data.RoundStartTime = CurTime()
-- Fretta Hooks
hook.Run("RoundEnd")
end
function StatePostRound:Tick()
-- Advance State
if (CurTime() - GAMEMODE.Data.RoundStartTime) >= 5 then -- ToDo: configureable time?
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
function StatePostRound:OnLeave(NewState)
if GAMEMODE.Config:Debug() then print("StatePostRound: OnLeave") end
-- Game Mode: Basic
if (GAMEMODE.Config:GameMode() == GAMEMODE.Modes.Original) then
-- Swap Teams
local hiders, seekers = team.GetPlayers(GAMEMODE.Teams.Hiders), team.GetPlayers(GAMEMODE.Teams.Seekers)
for i, ply in ipairs(hiders) do
ply: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
if GAMEMODE.Config:DebugLog() then print("StatePostRound: OnLeave") end
end
@@ -26,29 +26,30 @@
StatePreMatch = {}
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)
SetGlobalInt("Round", GetGlobalInt("Round", 0) + 1)
math.randomseed(CurTime())
end
function StatePreMatch:Tick()
-- Debug: Auto Advance to PreRound State
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)
end
-- 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.
if ((team.NumPlayers(GAMEMODE.Teams.Seekers) >= 1) && (team.NumPlayers(GAMEMODE.Teams.Hiders) >= 1)) then
GAMEMODE.RoundManager:SetState(StatePreRound)
if GAMEMODE.Config:DebugLog() then print("StatePreMatch: <Original> Have enough players to start match.") end
end
-- TODO: Other Gamemodes
end
end
function StatePreMatch:OnLeave(NewState)
if GAMEMODE.Config:Debug() then print("StatePreMatch: OnLeave") end
if GAMEMODE.Config:DebugLog() then print("StatePreMatch: OnLeave") end
end
@@ -25,8 +25,9 @@
StatePreRound = {}
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:SetRound(GAMEMODE:GetRound() + 1)
-- Clean Up the Map
game.CleanUpMap()
@@ -37,7 +38,7 @@ function StatePreRound:Tick()
GAMEMODE.RoundManager:SetState(StateHide)
end
function StatePreRound:OnLeave(NewState)
if GAMEMODE.Config:Debug() then print("StatePreRound: OnLeave") end
if GAMEMODE.Config:DebugLog() then print("StatePreRound: OnLeave") end
-- Respawn Everyone
for i, ply in ipairs(player.GetAll()) do
@@ -46,5 +47,15 @@ function StatePreRound:OnLeave(NewState)
ply:Spawn()
ply:ScreenFade(SCREENFADE.PURGE, color_black, 0, 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
-- Fretta Hooks
hook.Run("RoundStart")
end
@@ -25,7 +25,7 @@
StateSeek = {}
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)
-- Round Data
@@ -75,7 +75,7 @@ function StateSeek:Tick()
GAMEMODE.RoundManager:SetState(StatePostRound)
else
if (GAMEMODE.Data.RoundTime <= 0) then -- No Time remaining
GAMEMODE:SetRoundWinner(GAMEMODE.Teams.Hiders)
GAMEMODE:SetRoundWinner(GAMEMODE.Teams.Hiders)
GAMEMODE.RoundManager:SetState(StatePostRound)
end
end
@@ -83,5 +83,13 @@ function StateSeek:Tick()
end
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
@@ -1,294 +1,464 @@
-- Sounds played by members of the losing team at the end of the round.
LOSS_SOUNDS = {
"bot/aw_hell.wav",
"bot/aww_man.wav",
"bot/anyone_see_anything.wav",
"bot/anyone_see_them.wav",
"bot/come_out_and_fight_like_a_man.wav",
"bot/come_out_wherever_you_are.wav",
"bot/he_got_away.wav",
"bot/he_got_away2.wav",
"bot/i_dont_know_where_he_went.wav",
"bot/i_got_nothing.wav",
"bot/nothing_happening_over_here.wav",
"bot/nothing_here.wav",
"bot/nothing_moving_over_here.wav",
"bot/thats_not_good.wav",
"bot/theres_too_many.wav",
"bot/theres_too_many_of_them.wav",
"bot/theyre_all_over_the_place2.wav",
"bot/theyre_everywhere2.wav",
"bot/too_many2.wav",
"bot/what_happened.wav",
"bot/what_have_you_done.wav",
"bot/where_are_they.wav",
"bot/where_are_you_hiding.wav"
}
if (! file.Exists("prop_hunt/sounds_loss.txt", "DATA")) then
file.Write("prop_hunt/sounds_loss.txt", util.TableToKeyValues(LOSS_SOUNDS))
end
local fileContent = file.Read("prop_hunt/sounds_loss.txt", "DATA");
if fileContent then
local fileTable = util.KeyValuesToTable(fileContent)
if fileTable then LOSS_SOUNDS = fileTable end
--[[
The MIT License (MIT)
Copyright (c) 2015 Xaymar
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
--]]
--! Initialize configuration table.
GM.Config = { }
GM.Config.ConVars = {}
function CreateConVarIfNotExists(name, value, flags, helptext)
cv = GetConVar(name)
if (cv == nil) then
cv = CreateConVar(name, value, flags, helptext)
-- else
-- ncv = CreateConVar(name, value, flags, helptext)
end
return cv
end
-- Sounds played by members of the winning team at the end of the round.
VICTORY_SOUNDS = {
"bot/and_thats_how_its_done.wav",
"bot/come_to_papa.wav",
"bot/do_not_mess_with_me.wav",
"bot/dropped_him.wav",
"bot/enemy_down.wav",
"bot/enemy_down2.wav",
"bot/good_job_team.wav",
"bot/got_him.wav",
"bot/hes_broken.wav",
"bot/hes_dead.wav",
"bot/hes_done.wav",
"bot/hes_down.wav",
"bot/its_a_party.wav",
"bot/i_am_dangerous.wav",
"bot/i_am_on_fire.wav",
"bot/i_got_more_where_that_came_from.wav",
"bot/i_wasnt_worried_for_a_minute.wav",
"bot/killed_him.wav",
"bot/look_out_brag.wav",
"bot/made_him_cry.wav",
"bot/oh_yea.wav",
"bot/oh_yea2.wav",
"bot/owned.wav",
"bot/ruined_his_day.wav",
"bot/tag_them_and_bag_them.wav",
"bot/thats_the_way_this_is_done.wav",
"bot/that_was_a_close_one.wav",
"bot/that_was_it.wav",
"bot/that_was_the_last_guy.wav",
"bot/that_was_the_last_one.wav",
"bot/they_never_knew_what_hit_them.wav",
"bot/they_will_not_escape.wav",
"bot/they_wont_get_away.wav",
"bot/they_wont_get_away2.wav",
"bot/this_is_my_house.wav",
"bot/took_him_down.wav",
"bot/took_him_out.wav",
"bot/took_him_out2.wav",
"bot/wasted_him.wav",
"bot/way_to_be_team.wav",
"bot/well_done.wav",
"bot/we_owned_them.wav",
"bot/whew_that_was_close.wav",
"bot/whoo.wav",
"bot/whoo2.wav",
"bot/whos_the_man.wav",
"bot/who_wants_some_more.wav",
"bot/yesss.wav",
"bot/yesss2.wav"
}
if (! file.Exists("prop_hunt/sounds_victory.txt", "DATA")) then
file.Write("prop_hunt/sounds_victory.txt", util.TableToKeyValues(VICTORY_SOUNDS))
end
local fileContent = file.Read("prop_hunt/sounds_victory.txt", "DATA");
if fileContent then
local fileTable = util.KeyValuesToTable(fileContent)
if fileTable then VICTORY_SOUNDS = fileTable end
-- ------------------------------------------------------------------------- --
--! Debug Settings
-- ------------------------------------------------------------------------- --
-- Debug Mode
GM.Config.ConVars.Debug = CreateConVarIfNotExists("ph_debug", "0", FCVAR_CHEAT + FCVAR_REPLICATED, "Prop Hunt: Enable Debug Mode")
function GM.Config:Debug()
return self.ConVars.Debug:GetBool()
end
-- Taunts played when Hunters hit their Spare1 binding.
HUNTER_TAUNTS = {
"bot/a_bunch_of_them.wav",
"bot/come_out_and_fight_like_a_man.wav",
"bot/come_out_wherever_you_are.wav",
"bot/come_to_papa.wav",
"bot/dont_worry_hell_get_it.wav",
"bot/hang_on_i_heard_something.wav",
"bot/hang_on_im_coming.wav",
"bot/i_dont_think_so.wav",
"bot/i_have_the_hostages.wav",
"bot/i_see_our_target.wav",
"bot/im_waiting_here.wav",
"bot/keeping_an_eye_on_the_hostages.wav",
"bot/nnno_sir.wav",
"bot/spotted_the_delivery_boy.wav",
"bot/target_acquired.wav",
"bot/target_spotted.wav",
"bot/you_heard_the_man_lets_go.wav"
}
if (! file.Exists("prop_hunt/sounds_taunt_hunter.txt", "DATA")) then
file.Write("prop_hunt/sounds_taunt_hunter.txt", util.TableToKeyValues(HUNTER_TAUNTS))
end
local fileContent = file.Read("prop_hunt/sounds_taunt_hunter.txt", "DATA");
if fileContent then
local fileTable = util.KeyValuesToTable(fileContent)
if fileTable then HUNTER_TAUNTS = fileTable end
-- Debug Log
GM.Config.ConVars.DebugLog = CreateConVarIfNotExists("ph_debug_log", "0", FCVAR_REPLICATED, "Prop Hunt: Enable Debug Logging")
function GM.Config:DebugLog()
return self.ConVars.DebugLog:GetBool()
end
-- Taunts played when Props hit their Spare1 binding.
PROP_TAUNTS = {
-- "ambient/alarms/apc_alarm_loop1.wav",
"ambient/alarms/apc_alarm_pass1.wav",
-- "ambient/alarms/citadel_alert_loop2.wav",
-- "ambient/alarms/city_firebell_loop1.wav",
-- "ambient/alarms/city_siren_loop2.wav",
-- "ambient/alarms/combine_bank_alarm_loop1.wav",
-- "ambient/alarms/combine_bank_alarm_loop4.wav",
-- "ambient/alarms/klaxon1.wav",
"ambient/alarms/manhack_alert_pass1.wav",
"ambient/alarms/razortrain_horn1.wav",
"ambient/alarms/scanner_alert_pass1.wav",
-- "ambient/alarms/siren.wav",
-- "ambient/alarms/train_crossing_bell_loop1.wav",
"ambient/alarms/train_horn2.wav",
"ambient/alarms/train_horn_distant1.wav",
"ambient/alarms/warningbell1.wav",
-- "ambient/chatter/cb_radio_chatter_1.wav",
-- "ambient/chatter/cb_radio_chatter_2.wav",
-- "ambient/chatter/cb_radio_chatter_3.wav",
"ambient/energy/whiteflash.wav",
"ambient/intro/alyxremove.wav",
"ambient/intro/logosfx.wav",
-- "ambient/levels/labs/teleport_alarm_loop1.wav",
"ambient/levels/launch/1stfiringwarning.wav",
"ambient/levels/launch/rockettakeoffblast.wav",
-- "ambient/levels/outland/basealarmloop.wav",
-- "ambient/machines/60hzhum.wav",
"ambient/misc/ambulance1.wav",
"ambient/misc/carhonk1.wav",
"ambient/misc/carhonk2.wav",
"ambient/misc/carhonk3.wav",
-- "ambient/music/bongo.wav",
-- "ambient/music/country_rock_am_radio_loop.wav",
-- "ambient/music/cubanmusic1.wav",
-- "ambient/music/dustmusic1.wav",
-- "ambient/music/dustmusic2.wav",
-- "ambient/music/dustmusic3.wav",
-- "ambient/music/flamenco.wav",
-- "ambient/music/latin.wav",
-- "ambient/music/mirame_radio_thru_wall.wav",
-- "ambient/music/piano1.wav",
-- "ambient/music/piano2.wav",
"ambient/outro/gunshipcrash.wav",
"ambient/3dmeagle.wav",
-- "ambient/guit1.wav",
-- "ambient/opera.wav",
-- "ambient/sheep.wav",
"beams/beamstart5.wav",
"buttons/bell1.wav",
"buttons/weapon_cant_buy.wav",
"common/bass.wav",
"common/bugreporter_failed.wav",
"common/warning.wav",
"doors/door_squeek1.wav",
"friends/friend_join.wav",
"friends/friend_online.wav",
"friends/message.wav",
"hostage/hunuse/comeback.wav",
"hostage/hunuse/dontleaveme.wav",
"hostage/hunuse/yeahillstay.wav",
"items/gift_drop.wav",
"music/radio1.mp3",
"phx/eggcrack.wav",
"plats/elevbell1.wav",
"player/headshot1.wav",
"player/headshot2.wav",
"player/sprayer.wav",
"radio/enemydown.wav",
"radio/go.wav",
"radio/locknload.wav",
"radio/negative.wav",
"radio/rounddraw.wav",
"radio/takepoint.wav",
"resource/warning.wav",
-- "test/temp/soundscape_test/tv_music.wav",
"ui/achievement_earned.wav",
"ui/freeze_cam.wav",
"vehicles/junker/radar_ping_friendly1.wav",
"weapons/c4/c4_beep1.wav",
"weapons/c4/c4_click.wav",
"weapons/awp/awp1.wav",
"vo/canals/female01/gunboat_giveemhell.wav",
"vo/canals/female01/gunboat_justintime.wav",
"vo/canals/female01/stn6_incoming.wav",
"vo/canals/male01/gunboat_giveemhell.wav",
"vo/canals/male01/gunboat_justintime.wav",
"vo/canals/male01/stn6_incoming.wav",
"vo/canals/al_radio_stn6.wav",
"vo/canals/arrest_getgoing.wav",
"vo/canals/arrest_helpme.wav",
"vo/canals/arrest_lookingforyou.wav",
"vo/canals/boxcar_lethimhelp.wav",
"vo/canals/matt_closecall.wav",
"vo/canals/premassacre.wav",
"vo/ravenholm/aimforhead.wav",
"vo/ravenholm/bucket_patience.wav",
"vo/ravenholm/madlaugh01.wav",
"vo/ravenholm/madlaugh02.wav",
"vo/ravenholm/madlaugh03.wav",
"vo/ravenholm/madlaugh04.wav",
"weapons/strider_buster/ol12_stickybombcreator.wav",
"weapons/c4/c4_explode1.wav",
"weapons/357/357_fire2.wav",
"weapons/357/357_fire3.wav",
"weapons/scout/scout_fire-1.wav",
"weapons/smokegrenade/sg_explode.wav",
"weapons/grenade_launcher1.wav",
"weapons/explode3.wav",
"weapons/underwater_explode3.wav",
"items/nvg_on.wav",
"hostage/huse/letsdoit.wav",
"hostage/huse/illfollow.wav",
"hostage/huse/getouttahere.wav",
"doors/door_screen_move1.wav",
"doors/heavy_metal_stop1.wav",
"doors/default_move.wav",
"common/stuck2.wav",
"ambient/water_splash1.wav",
"ambient/water_splash2.wav",
"ambient/water_splash3.wav",
"ambient/weather/thunder1.wav",
"ambient/weather/thunder2.wav",
"ambient/weather/thunder3.wav",
"ambient/weather/thunder4.wav",
"ambient/weather/thunder5.wav",
"ambient/weather/thunder6.wav",
"ambient/outro/thunder7.wav",
"ambient/voices/crying_loop1.wav",
"ambient/voices/playground_memory.wav",
"ambient/voices/f_scream1.wav",
"ambient/voices/m_scream1.wav",
"ambient/voices/cough1.wav",
"ambient/voices/cough2.wav",
"ambient/voices/cough3.wav",
"ambient/voices/cough4.wav",
"ambient/overhead/plane1.wav",
"ambient/overhead/plane2.wav",
"ambient/overhead/plane3.wav",
"ambient/overhead/hel1.wav",
"ambient/overhead/hel2.wav",
"ambient/misc/truck_backup1.wav",
"ambient/misc/truck_drive1.wav",
"ambient/misc/truck_drive2.wav",
"ambient/machines/pneumatic_drill_1.wav",
"ambient/machines/pneumatic_drill_2.wav",
"ambient/machines/pneumatic_drill_3.wav",
"ambient/machines/pneumatic_drill_4.wav",
"ambient/machines/station_train_squeel.wav",
"ambient/machines/ticktock.wav",
"ambient/creatures/teddy.wav",
"ambient/creatures/town_child_scream1.wav",
"ambient/creatures/town_moan1.wav",
"ambient/creatures/town_muffled_cry1.wav",
"ambient/creatures/town_scared_breathing1.wav",
"ambient/creatures/town_scared_breathing2.wav",
"ambient/creatures/town_scared_sob1.wav",
"ambient/creatures/town_scared_sob2.wav",
"ambient/creatures/town_zombie_call1.wav"
}
if (! file.Exists("prop_hunt/sounds_taunt_prop.txt", "DATA")) then
file.Write("prop_hunt/sounds_taunt_prop.txt", util.TableToKeyValues(PROP_TAUNTS))
-- ------------------------------------------------------------------------- --
--! Basic Settings
-- ------------------------------------------------------------------------- --
-- Game Mode (See sh_init.lua)
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)")
function GM.Config:GameType()
return self.ConVars.GameType:GetInt()
end
-- Timelimit in minutes
GM.Config.ConVars.TimeLimit = CreateConVarIfNotExists("mp_timelimit", "20", FCVAR_REPLICATED, "Map Time Limit (in Minutes)")
function GM.Config:TimeLimit()
return self.ConVars.TimeLimit:GetFloat()
end
-- ------------------------------------------------------------------------- --
--! Round Settings
-- ------------------------------------------------------------------------- --
GM.Config.Round = {}
GM.Config.Round.ConVars = {}
-- How many rounds should the GM attempt to fit into the map timelimit, if there is any?
GM.Config.Round.ConVars.Limit = CreateConVarIfNotExists("ph_round_limit", "10", FCVAR_REPLICATED, "Round Manager: Maximum Rounds to Play on a single Map")
function GM.Config.Round:Limit()
return self.ConVars.Limit:GetInt()
end
-- Round Time Limit (Seconds, Default 3 minutes)
GM.Config.Round.ConVars.Time = CreateConVarIfNotExists("ph_round_timelimit", "180", FCVAR_REPLICATED, "Round Manager: Time Limit per Round (in Seconds)")
function GM.Config.Round:Time()
return math.max(self.ConVars.Time:GetFloat() - math.min(self:BlindTime(),0),0)
end
-- For how many seconds are the Seekers blinded? (Seconds)
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")
function GM.Config.Round:BlindTime()
return self.ConVars.BlindTime:GetFloat()
end
-- ------------------------------------------------------------------------- --
--! Team Settings
-- ------------------------------------------------------------------------- --
GM.Config.Teams = {}
GM.Config.Teams.ConVars = {}
-- Should teams be ranomized each round?
GM.Config.Teams.ConVars.Randomize = CreateConVarIfNotExists("ph_teams_randomize", "0", FCVAR_REPLICATED, "Teams: Randomize Each Round")
function GM.Config.Teams:Randomize()
return self.ConVars.Randomize:GetBool()
end
-- Should teams be using weighted randomization?
-- Weighted randomization works by using a score calculated over the entire session.
-- * Round Start: Adjust Score towards the other Team by 1 (Positive = Seeker, Negative = Hider)
-- * Round Win: Adjust score by how many players are still alive on the winning team towards the other team.
-- * Alive players get double the score.
GM.Config.Teams.ConVars.Weighted = CreateConVarIfNotExists("ph_teams_weighted", "1", FCVAR_REPLICATED, "Teams: Use Weighted Randomization")
function GM.Config.Teams:Weighted()
return self.ConVars.Weighted:GetBool()
end
-- The Dead Hunt: Percent of players to assign to seeker.
GM.Config.Teams.ConVars.SeekerPercentage = CreateConVarIfNotExists("ph_teams_seekerpct", "25", FCVAR_REPLICATED, "Teams: Initial percentage of Seekers in Dead Hunt Game Type")
function GM.Config.Teams:SeekerPercentage()
return self.ConVars.Teams:GetFloat() / 100
end
-- ------------------------------------------------------------------------- --
--! Seeker Settings
-- ------------------------------------------------------------------------- --
GM.Config.Seeker = {}
GM.Config.Seeker.ConVars = {}
GM.Config.Seeker.ConVars.Health = CreateConVarIfNotExists("ph_seeker_health", "100", FCVAR_REPLICATED, "Seekers: Initial Health")
function GM.Config.Seeker:Health()
return self.ConVars.Health:GetInt()
end
GM.Config.Seeker.ConVars.HealthMax = CreateConVarIfNotExists("ph_seeker_health_max", "100", FCVAR_REPLICATED, "Seekers: Maximum Health")
function GM.Config.Seeker:HealthMax()
return self.ConVars.HealthMax:GetInt()
end
GM.Config.Seeker.ConVars.HealthBonus = CreateConVarIfNotExists("ph_seeker_health_bonus", "20", FCVAR_REPLICATED, "Seekers: Health Bonus per Kill")
function GM.Config.Seeker:HealthBonus()
return self.ConVars.HealthBonus:GetInt()
end
GM.Config.Seeker.ConVars.HealthPenalty = CreateConVarIfNotExists("ph_seeker_health_penalty", "5", FCVAR_REPLICATED, "Seekers: Health Penalty per wrong Shot")
function GM.Config.Seeker:HealthPenalty()
return self.ConVars.HealthPenalty:GetInt()
end
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,...)")
function GM.Config.Seeker:Weapons()
return string.Split(self.ConVars.Weapons:GetString(), ",")
end
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,...)")
function GM.Config.Seeker:Ammo()
return string.Split(self.ConVars.Ammo:GetString(), ",")
end
GM.Config.Seeker.ConVars.WalkSpeed = CreateConVarIfNotExists("ph_seeker_walk_speed", "250", 0, "Seekers: Walk Speed")
function GM.Config.Seeker:WalkSpeed()
return self.ConVars.WalkSpeed:GetFloat()
end
GM.Config.Seeker.ConVars.Sprint = CreateConVarIfNotExists("ph_seeker_sprint", "1", FCVAR_REPLICATED, "Seekers: Allow Sprinting")
function GM.Config.Seeker:Sprint()
return self.ConVars.Sprint:GetBool()
end
GM.Config.Seeker.ConVars.SprintSpeed = CreateConVarIfNotExists("ph_seeker_sprint_speed", "500", 0, "Seekers: Sprint Speed")
function GM.Config.Seeker:SprintSpeed()
return self.ConVars.SprintSpeed:GetFloat()
end
GM.Config.Seeker.ConVars.JumpPower = CreateConVarIfNotExists("ph_seeker_jump_power", "200", 0, "Seekers: Jump Power")
function GM.Config.Seeker:JumpPower()
return self.ConVars.JumpPower:GetFloat()
end
-- ------------------------------------------------------------------------- --
--! Hider Settings
-- ------------------------------------------------------------------------- --
GM.Config.Hider = {}
GM.Config.Hider.ConVars = {}
GM.Config.Hider.ConVars.Health = CreateConVarIfNotExists("ph_hider_health", "100", FCVAR_REPLICATED, "Hiders: Initial Health")
function GM.Config.Hider:Health()
return self.ConVars.Health:GetInt()
end
GM.Config.Hider.ConVars.HealthMax = CreateConVarIfNotExists("ph_hider_health_max", "100", FCVAR_REPLICATED, "Hiders: Maximum Health")
function GM.Config.Hider:HealthMax()
return self.ConVars.HealthMax:GetInt()
end
GM.Config.Hider.ConVars.HealthScaling = CreateConVarIfNotExists("ph_hider_health_scaling", "1", FCVAR_REPLICATED, "Hiders: Enable Health Scaling")
function GM.Config.Hider:HealthScaling()
return self.ConVars.HealthScaling:GetBool()
end
GM.Config.Hider.ConVars.HealthScalingMax = CreateConVarIfNotExists("ph_hider_health_scaling_max", "200", FCVAR_REPLICATED, "Hiders: Maximum scaled Health")
function GM.Config.Hider:HealthScalingMax()
return self.ConVars.HealthScalingMax:GetInt()
end
GM.Config.Hider.ConVars.AllowFullRotation = CreateConVarIfNotExists("ph_hider_allow_full_rotation", "0", FCVAR_REPLICATED, "Hiders: Enable full 3D Rotation")
function GM.Config.Hider:AllowFullRotation()
return self.ConVars.AllowFullRotation:GetBool()
end
GM.Config.Hider.ConVars.WalkSpeed = CreateConVarIfNotExists("ph_hider_walk_speed", "250", 0, "Hiders: Walk Speed")
function GM.Config.Hider:WalkSpeed()
return self.ConVars.WalkSpeed:GetFloat()
end
GM.Config.Hider.ConVars.Sprint = CreateConVarIfNotExists("ph_hider_sprint", "0", FCVAR_REPLICATED, "Hiders: Allow Sprinting")
function GM.Config.Hider:Sprint()
return self.ConVars.Sprint:GetBool()
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
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
-- ------------------------------------------------------------------------- --
GM.Name = "Prop Hunt Extended"
GM.Author = "Michael 'Xaymar' Dirks (Based on Kow@lskis Version, Original by AMT)"
GM.Email = "michael.fabian.dirks@gmail.com"
GM.Author = "Michael Fabian 'Xaymar' Dirks"
GM.Email = "info@xaymar.com"
GM.Website = "http://xaymar.com/"
GM.TeamBased = true
GM.AllowAutoTeam = true
GM.SecondsBetweenTeamSwitches = 10
-- ------------------------------------------------------------------------- --
--! Includes
-- ------------------------------------------------------------------------- --
-- Player Classes
include "player_class/class_default.lua"
include "player_class/class_spectator.lua"
include "player_class/class_seeker.lua"
include "player_class/class_hider.lua"
-- ------------------------------------------------------------------------- --
--! Code
-- ------------------------------------------------------------------------- --
@@ -56,10 +47,9 @@ GM.States.PostRound = 4
GM.States.PostMatch = 5
-- Game Modes
GM.Modes = {}
GM.Modes.Original = 0
GM.Modes.SwizzleEffect = 1 -- Randomizes Teams each Round
GM.Modes.TheDeadHunt = 2 -- One Hunter, Dead Prop become Hunter, Props can't see each other.
GM.Types = {}
GM.Types.Original = 0
GM.Types.TheDeadHunt = 1 -- One Hunter, Dead Prop become Hunter, Props can't see each other.
-- Teams
GM.Teams = {}
@@ -75,13 +65,15 @@ function GM:CreateTeams()
"info_player_combine",
"info_player_counterterrorist",
"info_player_allies",
"info_player_terrorist"
"info_player_terrorist",
"info_player_start"
})
team.SetClass(self.Teams.Spectators, { "Spectator", "Spectator" })
-- Seekers: "Hunters"
team.SetUp(self.Teams.Seekers, "Seekers", Color(0, 128, 255, 255))
team.SetSpawnPoint(self.Teams.Seekers, {
"info_player_start",
"info_player_spawn",
"info_player_deathmatch",
"info_player_combine",
@@ -92,6 +84,7 @@ function GM:CreateTeams()
-- Hiders: "Props"
team.SetUp(self.Teams.Hiders, "Hiders", Color(255, 128, 0, 255))
team.SetSpawnPoint(self.Teams.Hiders, {
"info_player_start",
"info_player_spawn",
"info_player_deathmatch",
"info_player_allies",
@@ -112,17 +105,23 @@ function GM:PlayerTick(ply, mv)
end
function GM:PlayerHurt(victim, attacker, healthRemaining, damageTaken)
if (victim != nil && victim:IsPlayer()) then
player_manager.RunClass(victim, "Hurt", victim, attacker, healthRemaining, damageTaken)
end
if (attacker != nil && attacker:IsPlayer()) then
player_manager.RunClass(victim, "Hurt", victim, attacker, healthRemaining, damageTaken)
if (IsValid(attacker) && attacker:IsPlayer()) then
player_manager.RunClass(attacker, "Damage", victim, attacker, healthRemaining, damageTaken)
end
end
function GM:PlayerShouldTakeDamage(victim, attacker)
return player_manager.RunClass(victim, "ShouldTakeDamage", attacker)
end
-- ------------------------------------------------------------------------- --
--! Gamemode Functionality
-- ------------------------------------------------------------------------- --
function GM:GetRound()
return GetGlobalInt("Round", 0)
end
function GM:GetRoundState()
return GetGlobalInt("RoundState", self.States.PreMatch)
end
@@ -133,4 +132,15 @@ end
function GM:GetRoundWinner()
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"
"title" "Prop Hunt Extended"
"maps" "^ph_|^cs_|^de_|^ttt_"
"maps" "^ph_"
"menusystem" "1"
"workshopid" "468149739"
"settings"
{
// Game Settings
// Debug Settings
1
{
"name" "ph_gamemode"
"text" "G: Game Mode"
"help" "0: Basic, 1: Swizzle Effect (Random Teams), 2: The Dead Hunt (One Hunter, Dead Props become Hunters)"
"type" "Numeric"
"name" "ph_debug"
"text" "Enable Debug Mode"
"type" "CheckBox"
"default" "0"
}
2
{
"name" "mp_timelimit"
"text" "G: Time Limit"
"help" "Time Limit in Minutes for how long should we stay on one map. (0 to disable)"
"type" "Numeric"
"default" "20"
}
3
{
"name" "ph_sprinting"
"text" "G: Enable Sprinting"
"help" "Should sprinting be possible?"
"name" "ph_debug_log"
"text" "Enable Debug Logging"
"type" "CheckBox"
"default" "0"
"default" "1"
}
4
{
"name" "ph_tauntcooldown"
"text" "G: Taunt Cooldown"
"help" "How much time must pass before another taunt may be played."
"type" "Numeric"
"default" "5"
}
// Round Settings
10
{
"name" "ph_round_limit"
"text" "R: Rounds per Map"
"help" "How many rounds are played per map."
"type" "Numeric"
"default" "10"
}
// Basic Settings
11
{
"name" "ph_round_timelimit"
"text" "R: Round Duration (Seconds)"
"help" "How long is each round going to last?"
"name" "ph_gametype"
"text" "Game Type to use"
"type" "Numeric"
"default" "300"
"default" "0"
}
12
{
"name" "ph_round_blindtime"
"text" "R: Hiding Time (Seconds)"
"help" "How long are hunters blinded? (positive values will be inside the round time limit, negative will add to the round time limit)"
"name" "mp_timelimit"
"text" "Map Time Limit"
"type" "Numeric"
"default" "30"
}
// Seeker Settings
20
{
"name" "ph_seeker_health"
"text" "S: Health"
"type" "Numeric"
"default" "100"
"default" "0"
}
13
{
"name" "ph_sprinting"
"text" "Enable Sprinting"
"type" "CheckBox"
"default" "0"
}
// Round Settings
21
{
"name" "ph_seeker_health_max"
"text" "S: Max Health"
"name" "ph_round_limit"
"text" "Maximum Rounds Played"
"type" "Numeric"
"default" "100"
"default" "10"
}
22
{
"name" "ph_seeker_health_bonus"
"text" "S: Health Kill-Bonus"
"help" "Health gained on kill."
"name" "ph_round_timelimit"
"text" "Time Limit per Round"
"type" "Numeric"
"default" "20"
"default" "180"
}
23
{
"name" "ph_seeker_health_penalty"
"text" "S: Health Penalty"
"help" "Health lost on wrong shot."
"name" "ph_round_blindtime"
"text" "Seeker Blind time per Round"
"type" "Numeric"
"default" "5"
}
24
{
"name" "ph_seeker_weapons"
"text" "S: Weapons to be given to Seekers"
"help" "Format: Weapon,Weapon,..."
"type" "Text"
"default" "weapon_crowbar,weapon_pistol,weapon_ph_smg,weapon_shotgun,weapon_physcannon"
}
25
{
"name" "ph_seeker_ammo"
"text" "S: Ammo to give to Seekers"
"help" "Format: Name:Amount,Name:Amount,..."
"type" "Text"
"default" "Pistol:100,SMG1:300,SMG1_Grenade:1,Buckshot:64"
}
// Hider Settings
30
{
"name" "ph_hider_health"
"text" "H: Health"
"type" "Numeric"
"default" "100"
"default" "-30"
}
// Team Settings
31
{
"name" "ph_hider_health_max"
"text" "H: Max Health"
"type" "Numeric"
"default" "100"
"name" "ph_teams_randomize"
"text" "Randomize Teams"
"type" "CheckBox"
"default" "1"
}
32
{
"name" "ph_hider_health_scaling"
"text" "H: Enable Health Scaling"
"help" "Larger & heavier objects have more health, smaller less."
"name" "ph_teams_weighted"
"text" "Randomize with weighted Score"
"type" "CheckBox"
"default" "1"
}
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"
"text" "H: Scaled Max Health"
"text" "Hider Scaled Max Health"
"type" "Numeric"
"default" "200"
}
55
{
"name" "ph_hider_allow_full_rotation"
"text" "Hider 3-Dimensional Rotation"
"type" "CheckBox"
"default" "0"
}
// Whitelist & Blacklist
40
61
{
"name" "ph_list_class_whitelist"
"text" "L: Allowed Entity Classes"
"help" "Hiders can only use these for changing model and skin."
"text" "Allowed Entity Classes"
"type" "Text"
"default" "ph_prop,prop_physics,prop_physics_multiplayer,prop_physics_respawnable"
}
41
62
{
"name" "ph_list_abuse_blacklist"
"text" "L: Abuse Blacklist"
"help" "Fix interact spam with certain entities so that all areas stay accessible."
"text" "Abuse Blacklist"
"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
:: Retrieve Garry's Mod path from Regristry
:: FOR /F "tokens=2* delims= " %%A IN ('REG QUERY "HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\Steam App 4000" /v InstallLocation') DO SET "GARRYSMODPATH=%%B"
SET "GARRYSMODPATH=C:\Program Files (x86)\Steam\steamapps\common\GarrysMod"
call env.win.bat
SET "PATH=%CD%;%GARRYSMODPATH%\bin;%PATH%"
CMD
CMD
+2 -4
View File
@@ -1,6 +1,4 @@
@ECHO OFF
SET "PWD=%~dp0"
CALL build-env.bat
"%TOOLPATH%\bin\gmad.exe" create -folder "%PWD%\Source" -out "%PWD%\Pack.gma"
call env.win.bat
"%GARRYSMODPATH%\bin\gmad.exe" create -folder "%CD%\Source" -out "%CD%\Pack.gma"
PAUSE
+2 -4
View File
@@ -1,6 +1,4 @@
@ECHO OFF
SET "PWD=%~dp0"
CALL build-env.bat
"%GARRYSMODPATH%\bin\gmpublish.exe" update -id %WORKSHOPID% -icon "Logo.jpg" -addon "Pack.gma" -changes ""
call env.win.bat
"%GARRYSMODPATH%\bin\gmpublish.exe" update -id 468149739 -icon "media\gamemode_workshop.jpg" -addon "Pack.gma" -changes ""
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.