Initial Reupload
|
@ -0,0 +1,38 @@
|
|||
# Compiled source #
|
||||
###################
|
||||
*.com
|
||||
*.class
|
||||
*.dll
|
||||
*.exe
|
||||
*.o
|
||||
*.so
|
||||
|
||||
# Packages #
|
||||
############
|
||||
# it's better to unpack these files and commit the raw source
|
||||
# git has its own built in compression methods
|
||||
*.7z
|
||||
*.dmg
|
||||
*.gz
|
||||
*.iso
|
||||
*.jar
|
||||
*.rar
|
||||
*.tar
|
||||
*.zip
|
||||
|
||||
# Logs and databases #
|
||||
######################
|
||||
*.log
|
||||
*.sql
|
||||
*.sqlite
|
||||
|
||||
# OS generated files #
|
||||
######################
|
||||
.DS_Store
|
||||
.DS_Store?
|
||||
._*
|
||||
.Spotlight-V100
|
||||
.Trashes
|
||||
ehthumbs.db
|
||||
Thumbs.db
|
||||
|
69
README.md
|
@ -1,2 +1,67 @@
|
|||
# ph-enhanced
|
||||
Prop Hunt: Enhanced - By Wolvindra [REUPLOAD]
|
||||
# Wolvin's - Prop Hunt: ENHANCED v.15 Rev. I
|
||||
|
||||
![Prop Hunt: Enhanced Logo](https://i.ibb.co/7Yq3PhX/image.png "Prop Hunt: Enhanced v.15")
|
||||
|
||||
![Prop Hunt: Enhanced Cover](https://i.ibb.co/4PV3QSk/image.png "Prop Hunt: Enhanced v.15 New Main Menu")
|
||||
|
||||
## Base Information
|
||||
**Version: 15, Revision: I, Release Type: Stopped/Hiatus**
|
||||
|
||||
Updates to address some exploits and other things. [See Changelog here](https://steamcommunity.com/sharedfiles/filedetails/changelog/417565863) for details.
|
||||
|
||||
## Upcoming "Version 16 Update" Notice
|
||||
|
||||
![Prop Hunt: Enhanced V16 Logo](https://i.ibb.co/gP5qzwc/phe.jpg "Prop Hunt: Enhanced v.16")
|
||||
|
||||
Version 16 will be the major update for the next version release of Prop Hunt: Enhanced. This also includes several changes and improvement for the gamemode which includes:
|
||||
- Smoother Angle Rotation
|
||||
- Prop Chooser UI*
|
||||
- TauntURL*
|
||||
- Minigame*
|
||||
- New HUD, Help Menu, Scoreboard, and others
|
||||
- Language Support
|
||||
- Custom Taunt Additions (Workshop, from Data, etc)
|
||||
- Pointshop Integration Support*
|
||||
- and more...!
|
||||
|
||||
(* This is planned feature, which mean that this feature will be implemented or not based from user survey inputs)
|
||||
|
||||
[Support for V16 Release](https://ko-fi.com/post/Prop-Hunt-Enhanced-XVI---Teaser-T6T2OHNJ)
|
||||
|
||||
### Main gamemode Description
|
||||
Prop Hunt: Enhanced is an enhanced version of Classic original **Prop Hunt** Gamemode. The gamemode is focused to be always maintained and fully customizable with many things.
|
||||
The gamemode also includes several many major changes including the HUD, the code optimisation, Player skins, and other kind of additional features.
|
||||
|
||||
The gamemode was contributted to the old Classic Prop Hunt as for the fixes on march 2015 update (which completely broken) with the viewmodel fix additions. The classic version may no longer
|
||||
maintained anymore.
|
||||
|
||||
### Available Links & Public Server Tests
|
||||
|
||||
#### Available Servers
|
||||
- Soup Network: 103.193.80.135:28380
|
||||
- GFL Clan Server: 208.103.169.70:27030
|
||||
|
||||
#### Links
|
||||
|
||||
[**Workshop Version**](https://steamcommunity.com/sharedfiles/filedetails/?id=417565863)
|
||||
|
||||
[**Main Website**](https://vinzuerio.bitbucket.io/phe)
|
||||
|
||||
[**Wiki (Helps, FAQ, Adding Custom Sound, etc)**](https://vinzuerio.bitbucket.io/phe/faq)
|
||||
|
||||
## Required Addons
|
||||
* ULX Admin Mod. ( Workshop or Legacy Download: http://ulyssesmod.net/downloads.php )
|
||||
* (Optional) M9K/TFA Base. You can optionally subscribe the M9K weapon base if you wish to use custom weapon base for bonus weapon, otherwise will use from default sandbox weapon base.
|
||||
|
||||
## Donate
|
||||
Currently, The donation method can be done by using paypalme links: https://paypal.me/wolvindra or [use from this link](https://vinzuerio.bitbucket.io/phe/#donate).
|
||||
|
||||
Once the website is running active again, this will turn back to main official donation page instead.
|
||||
|
||||
## Reporting an Issue
|
||||
|
||||
### Reporting game issue (Bugs/Glitches)
|
||||
Please provide information with detail so we know what's the actual problem that can occurs on your side. This issue page is not a place for asking help.
|
||||
|
||||
### Community Discussion Thread
|
||||
If you wish to use help, please [open a discussion thread from workshop here](http://steamcommunity.com/sharedfiles/filedetails/discussions/417565863).
|
|
@ -0,0 +1,63 @@
|
|||
hostname "My Prop Hunt Server"
|
||||
sv_password ""
|
||||
sv_lan 0
|
||||
sv_region 255
|
||||
|
||||
// if these configs somehow won't load from your server, try remove any comments that marked as '//'.
|
||||
// Fore more info about all configs:
|
||||
// https://project.wolvindra.net/phe/new/faq/?dir=Config&gettopic=Common_Server_Config
|
||||
// https://project.wolvindra.net/phe/new/faq/?dir=ConVars_and_ConCmds&gettopic=Serverside_ConVars
|
||||
// https://project.wolvindra.net/phe/new/faq/?dir=ConVars_and_ConCmds&gettopic=MapVote_ConVars
|
||||
|
||||
p2p_enabled 0 // change this to 1 to enable P2P Mode.
|
||||
p2p_friendsonly 0 // change this to 1 to only allow Friends Only P2P mode.
|
||||
|
||||
// PH: Enhanced - Gameplay settings
|
||||
ph_hunter_fire_penalty 10
|
||||
ph_hunter_kill_bonus 100
|
||||
ph_swap_teams_every_round 1 //leave this as default.
|
||||
ph_game_time 40 //minutes
|
||||
ph_hunter_blindlock_time 30 //seconds
|
||||
ph_round_time 300 //seconds
|
||||
ph_rounds_per_map 10
|
||||
ph_waitforplayers 1
|
||||
ph_min_waitforplayers 1
|
||||
|
||||
//Verbosely prints any events of Prop Hunt: Enhanced.
|
||||
ph_print_verbose 1
|
||||
|
||||
// PH: Enhanced - Props/Player settings
|
||||
ph_use_custom_plmodel 1
|
||||
ph_use_custom_plmodel_for_prop 1
|
||||
ph_use_playermodeltype 0
|
||||
ph_enable_plnames 0
|
||||
ph_prop_camera_collisions 1
|
||||
ph_prop_collision 1
|
||||
ph_enable_custom_taunts 1
|
||||
ph_autotaunt_enabled 1
|
||||
ph_customtaunts_delay 4
|
||||
ph_normal_taunt_delay 3
|
||||
ph_autotaunt_delay 45
|
||||
ph_prop_jumppower 1.4
|
||||
ph_notice_prop_rotation 1
|
||||
ph_enable_lucky_balls 1
|
||||
|
||||
// Freezecam Settings
|
||||
ph_freezecam 1
|
||||
ph_fc_use_single_sound 0
|
||||
ph_fc_cue_path "misc/freeze_cam.wav"
|
||||
|
||||
// PH: Enhanced - MapVote
|
||||
mv_allowcurmap 1 // 1/0, allow current map or not
|
||||
mv_cooldown 1 // 1/0, enable cooldown
|
||||
mv_mapbeforerevote 2 // number of each map should be cooldown
|
||||
mv_maplimit 30 // allow 30 maps listed in mapvotes
|
||||
mv_rtvcount 3 // Minimum players to allow MapVote
|
||||
mv_timelimit 30 // Time in seconds to begin voting before changing the most choosen maps.
|
||||
|
||||
// Use map listing from ULX Mapvote? This convar will grab any whitelisted maps from your ULX Map List.
|
||||
// 1 = use from ULX mapvote list (which you can whitelist them), 0 = use default maps/*.bsp directory listing.
|
||||
mv_use_ulx_votemaps 0
|
||||
|
||||
// Map Prefixes to start with, for example: ph_ stands for Prop Hunt, de_ stands for CSS, etc...
|
||||
mv_mapprefix "ph_,de_,fy_,"
|
|
@ -0,0 +1,68 @@
|
|||
hostname "My Prop Hunt Server"
|
||||
sv_password ""
|
||||
sv_lan 0
|
||||
sv_region 255
|
||||
|
||||
// if these configs somehow won't load from your server, try remove any comments that marked as '//'.
|
||||
// Fore more info about all configs:
|
||||
// Read the Wiki:
|
||||
// https://project.wolvindra.net/phe/new/faq/?dir=Config&gettopic=Common_Server_Config
|
||||
// https://project.wolvindra.net/phe/new/faq/?dir=ConVars_and_ConCmds&gettopic=Serverside_ConVars
|
||||
// https://project.wolvindra.net/phe/new/faq/?dir=ConVars_and_ConCmds&gettopic=MapVote_ConVars
|
||||
|
||||
// PH: Enhanced - Gameplay settings
|
||||
ph_hunter_fire_penalty 10
|
||||
ph_hunter_kill_bonus 100
|
||||
ph_swap_teams_every_round 1 //leave this as default.
|
||||
ph_game_time 40 //minutes
|
||||
ph_hunter_blindlock_time 30 //seconds
|
||||
ph_round_time 300 //seconds
|
||||
ph_rounds_per_map 10
|
||||
ph_waitforplayers 1
|
||||
ph_min_waitforplayers 1
|
||||
|
||||
//Verbosely prints any events of Prop Hunt: Enhanced.
|
||||
ph_print_verbose 1
|
||||
|
||||
// PH: Enhanced - Props/Player settings
|
||||
ph_use_custom_plmodel 1
|
||||
ph_use_custom_plmodel_for_prop 1
|
||||
ph_use_playermodeltype 0
|
||||
ph_enable_plnames 0
|
||||
ph_prop_camera_collisions 1
|
||||
ph_prop_collision 1
|
||||
ph_enable_custom_taunts 1
|
||||
ph_autotaunt_enabled 1
|
||||
ph_customtaunts_delay 4
|
||||
ph_normal_taunt_delay 3
|
||||
ph_autotaunt_delay 45
|
||||
ph_prop_jumppower 1.4
|
||||
ph_notice_prop_rotation 1
|
||||
ph_enable_lucky_balls 1
|
||||
|
||||
// Freezecam Settings
|
||||
ph_freezecam 1
|
||||
ph_fc_use_single_sound 0
|
||||
ph_fc_cue_path "misc/freeze_cam.wav"
|
||||
|
||||
// PH: Enhanced - MapVote
|
||||
mv_allowcurmap 1 // 1/0, allow current map or not
|
||||
mv_cooldown 1 // 1/0, enable cooldown
|
||||
mv_mapbeforerevote 2 // number of each map should be cooldown
|
||||
mv_maplimit 30 // allow 30 maps listed in mapvotes
|
||||
mv_rtvcount 3 // Minimum players to allow MapVote
|
||||
mv_timelimit 30 // Time in seconds to begin voting before changing the most choosen maps.
|
||||
|
||||
// Use map listing from ULX Mapvote? This convar will grab any whitelisted maps from your ULX Map List.
|
||||
// 1 = use from ULX mapvote list (which you can whitelist them), 0 = use default maps/*.bsp directory listing.
|
||||
mv_use_ulx_votemaps 0
|
||||
|
||||
// Map Prefixes to start with, for example: ph_ stands for Prop Hunt, de_ stands for CSS, etc...
|
||||
mv_mapprefix "ph_,de_,fy_,"
|
||||
|
||||
// Resource: Custom taunts downloads
|
||||
sv_allowdownload 1
|
||||
sv_allowupload 1
|
||||
|
||||
// Specify your fastdl address to make it available for downloads to the clients.
|
||||
sv_downloadurl "http://yoursite/path_of_fastdl/"
|
|
@ -0,0 +1,10 @@
|
|||
"fretta"
|
||||
{
|
||||
"base" "base"
|
||||
"title" "Fretta Gamemode Base"
|
||||
"menusystem" "0"
|
||||
|
||||
"author_name" "TEAM GARRY"
|
||||
"author_email" ""
|
||||
"author_url" "http://www.garrysmod.com/"
|
||||
}
|
|
@ -0,0 +1,180 @@
|
|||
-- di gamemodes\fretta\gamemode\cl_deathnotice.lua
|
||||
-- Copy semuanya
|
||||
|
||||
/*
|
||||
Start of the death message stuff.
|
||||
*/
|
||||
|
||||
include( 'vgui/vgui_gamenotice.lua' )
|
||||
|
||||
local function CreateDeathNotify()
|
||||
|
||||
local x, y = ScrW(), ScrH()
|
||||
|
||||
g_DeathNotify = vgui.Create( "DNotify" )
|
||||
|
||||
g_DeathNotify:SetPos( 0, 25 )
|
||||
g_DeathNotify:SetSize( x - ( 25 ), y )
|
||||
g_DeathNotify:SetAlignment( 9 )
|
||||
g_DeathNotify:SetSkin( GAMEMODE.HudSkin )
|
||||
g_DeathNotify:SetLife( 4 )
|
||||
g_DeathNotify:ParentToHUD()
|
||||
|
||||
end
|
||||
|
||||
hook.Add( "InitPostEntity", "CreateDeathNotify", CreateDeathNotify )
|
||||
|
||||
|
||||
local function RecvPlayerKilledByPlayer()
|
||||
|
||||
local victim = net.ReadEntity();
|
||||
local inflictor = net.ReadString();
|
||||
local attacker = net.ReadEntity();
|
||||
|
||||
|
||||
if ( !IsValid( attacker ) ) then return end
|
||||
if ( !IsValid( victim ) ) then return end
|
||||
|
||||
GAMEMODE:AddDeathNotice( attacker:Name(), attacker:Team(), inflictor, victim:Name(), victim:Team() )
|
||||
|
||||
end
|
||||
|
||||
net.Receive( "PlayerKilledByPlayer", RecvPlayerKilledByPlayer )
|
||||
|
||||
local function RecvPlayerKilledSelf()
|
||||
|
||||
local victim = net.ReadEntity();
|
||||
if ( !IsValid( victim ) ) then return end
|
||||
GAMEMODE:AddDeathNotice( victim:Name(), victim:Team(), "suicide", victim:Name(), victim:Team() )
|
||||
|
||||
end
|
||||
|
||||
net.Receive( "PlayerKilledSelf", RecvPlayerKilledSelf )
|
||||
|
||||
|
||||
local function RecvPlayerKilled()
|
||||
|
||||
local victim = net.ReadEntity();
|
||||
if ( !IsValid( victim ) ) then return end
|
||||
local inflictor = net.ReadString();
|
||||
local attacker = "#" .. net.ReadString();
|
||||
|
||||
GAMEMODE:AddDeathNotice( attacker, -1, inflictor, victim:Name(), victim:Team() )
|
||||
|
||||
end
|
||||
|
||||
net.Receive( "PlayerKilled", RecvPlayerKilled )
|
||||
|
||||
|
||||
local function RecvPlayerKilledNPC()
|
||||
|
||||
local victimtype = net.ReadString();
|
||||
local victim = "#" .. victimtype;
|
||||
local inflictor = net.ReadString();
|
||||
local attacker = net.ReadEntity();
|
||||
|
||||
--
|
||||
-- For some reason the killer isn't known to us, so don't proceed.
|
||||
--
|
||||
if ( !IsValid( attacker ) ) then return end
|
||||
|
||||
GAMEMODE:AddDeathNotice( attacker:Name(), attacker:Team(), inflictor, victim, -1 )
|
||||
|
||||
local bIsLocalPlayer = (IsValid(attacker) && attacker == LocalPlayer())
|
||||
|
||||
local bIsEnemy = IsEnemyEntityName( victimtype )
|
||||
local bIsFriend = IsFriendEntityName( victimtype )
|
||||
|
||||
if ( bIsLocalPlayer && bIsEnemy ) then
|
||||
achievements.IncBaddies();
|
||||
end
|
||||
|
||||
if ( bIsLocalPlayer && bIsFriend ) then
|
||||
achievements.IncGoodies();
|
||||
end
|
||||
|
||||
if ( bIsLocalPlayer && (!bIsFriend && !bIsEnemy) ) then
|
||||
achievements.IncBystander();
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
net.Receive( "PlayerKilledNPC", RecvPlayerKilledNPC )
|
||||
|
||||
|
||||
|
||||
local function RecvNPCKilledNPC()
|
||||
|
||||
local victim = "#" .. net.ReadString();
|
||||
local inflictor = net.ReadString();
|
||||
local attacker = "#" .. net.ReadString();
|
||||
|
||||
GAMEMODE:AddDeathNotice( attacker, -1, inflictor, victim, -1 )
|
||||
|
||||
end
|
||||
|
||||
net.Receive( "NPCKilledNPC", RecvNPCKilledNPC )
|
||||
|
||||
/*---------------------------------------------------------
|
||||
Name: gamemode:AddDeathNotice( Victim, Weapon, Attacker )
|
||||
Desc: Adds an death notice entry
|
||||
---------------------------------------------------------*/
|
||||
--function GM:AddDeathNotice( victim, inflictor, attacker )
|
||||
function GM:AddDeathNotice( Attacker, team1, Inflictor, Victim , team2 )
|
||||
|
||||
local RdmDeathString = {
|
||||
"suicided!",
|
||||
"died mysteriously.",
|
||||
"died from magic.",
|
||||
"no-scoped themself.",
|
||||
"has just ragequit.",
|
||||
"is drunk.",
|
||||
"died... better luck next time!",
|
||||
"slapped themself.",
|
||||
"tripped on a stick.",
|
||||
"died by the force.",
|
||||
"ragdolled."
|
||||
}
|
||||
|
||||
local stringtext = table.Random( RdmDeathString )
|
||||
|
||||
if ( !IsValid( g_DeathNotify ) ) then return end
|
||||
|
||||
local pnl = vgui.Create( "GameNotice", g_DeathNotify )
|
||||
local color1
|
||||
local color2
|
||||
|
||||
|
||||
if ( team1 == -1 ) then color1 = table.Copy( NPC_Color )
|
||||
else color1 = table.Copy( team.GetColor( team1 ) ) end
|
||||
|
||||
if ( team2 == -1 ) then color2 = table.Copy( NPC_Color )
|
||||
else color2 = table.Copy( team.GetColor( team2 ) ) end
|
||||
|
||||
if Victim == Attacker then
|
||||
pnl:AddText( Attacker, color1)
|
||||
pnl:AddText( stringtext )
|
||||
else
|
||||
pnl:AddText( Attacker, color1)
|
||||
pnl:AddIcon( Inflictor )
|
||||
pnl:AddText( Victim, color2 )
|
||||
end
|
||||
|
||||
|
||||
g_DeathNotify:AddItem( pnl )
|
||||
|
||||
end
|
||||
|
||||
function GM:AddPlayerAction( ... )
|
||||
|
||||
if ( !IsValid( g_DeathNotify ) ) then return end
|
||||
|
||||
local pnl = vgui.Create( "GameNotice", g_DeathNotify )
|
||||
|
||||
for k, v in ipairs({...}) do
|
||||
pnl:AddText( v )
|
||||
end
|
||||
|
||||
g_DeathNotify:AddItem( pnl )
|
||||
|
||||
end
|
|
@ -0,0 +1,90 @@
|
|||
g_PlayableGamemodes = {}
|
||||
g_bGotGamemodesTable = false
|
||||
|
||||
function RcvPlayableGamemodes( length )
|
||||
|
||||
g_PlayableGamemodes = net.ReadTable()
|
||||
g_bGotGamemodesTable = true
|
||||
|
||||
end
|
||||
|
||||
net.Receive( "PlayableGamemodes", RcvPlayableGamemodes );
|
||||
|
||||
local GMChooser = nil
|
||||
local function GetVoteScreen()
|
||||
|
||||
if ( IsValid( GMChooser ) ) then return GMChooser end
|
||||
|
||||
GMChooser = vgui.Create( "VoteScreen" )
|
||||
return GMChooser
|
||||
|
||||
end
|
||||
|
||||
|
||||
function GM:ShowGamemodeChooser()
|
||||
|
||||
local votescreen = GetVoteScreen()
|
||||
votescreen:ChooseGamemode()
|
||||
|
||||
end
|
||||
|
||||
function GM:GamemodeWon( mode )
|
||||
|
||||
local votescreen = GetVoteScreen()
|
||||
votescreen:FlashItem( mode )
|
||||
|
||||
end
|
||||
|
||||
function GM:ChangingGamemode( mode, map )
|
||||
|
||||
local votescreen = GetVoteScreen()
|
||||
votescreen:FlashItem( map )
|
||||
|
||||
end
|
||||
|
||||
function GM:ShowMapChooserForGamemode( gmname )
|
||||
|
||||
local votescreen = GetVoteScreen()
|
||||
votescreen:ChooseMap( gmname )
|
||||
|
||||
end
|
||||
|
||||
|
||||
local ClassChooser = nil
|
||||
cl_classsuicide = CreateConVar( "cl_classsuicide", "0", { FCVAR_ARCHIVE } )
|
||||
|
||||
function GM:ShowClassChooser( TEAMID )
|
||||
|
||||
if ( !GAMEMODE.SelectClass ) then return end
|
||||
if ( ClassChooser ) then ClassChooser:Remove() end
|
||||
|
||||
ClassChooser = vgui.CreateFromTable( vgui_Splash )
|
||||
ClassChooser:SetHeaderText( "Choose Class" )
|
||||
ClassChooser:SetHoverText( "What class do you want to be?" );
|
||||
|
||||
Classes = team.GetClass( TEAMID )
|
||||
for k, v in SortedPairs( Classes ) do
|
||||
|
||||
local displayname = v
|
||||
local Class = player_class.Get( v )
|
||||
if ( Class && Class.DisplayName ) then
|
||||
displayname = Class.DisplayName
|
||||
end
|
||||
|
||||
local description = "Click to spawn as " .. displayname
|
||||
|
||||
if( Class and Class.Description ) then
|
||||
description = Class.Description
|
||||
end
|
||||
|
||||
local func = function() if( cl_classsuicide:GetBool() ) then RunConsoleCommand( "kill" ) end RunConsoleCommand( "changeclass", k ) end
|
||||
local btn = ClassChooser:AddSelectButton( displayname, func, description )
|
||||
btn.m_colBackground = team.GetColor( TEAMID )
|
||||
|
||||
end
|
||||
|
||||
ClassChooser:AddCancelButton()
|
||||
ClassChooser:MakePopup()
|
||||
ClassChooser:NoFadeIn()
|
||||
|
||||
end
|
|
@ -0,0 +1,136 @@
|
|||
|
||||
local Help = nil
|
||||
function GM:ShowHelp()
|
||||
|
||||
if ( !IsValid( Help ) ) then
|
||||
|
||||
Help = vgui.CreateFromTable( vgui_Splash )
|
||||
Help:SetHeaderText( GAMEMODE.Name or "Untitled Gamemode" )
|
||||
Help:SetHoverText( GAMEMODE.Help or "No Help Avaliable" );
|
||||
|
||||
Help.lblFooterText.Think = function( panel )
|
||||
local tl = GAMEMODE:GetGameTimeLeft()
|
||||
if ( tl == -1 ) then return end
|
||||
if( GetGlobalBool( "IsEndOfGame", false ) ) then panel:SetText( "Game has ended..." ) return end
|
||||
if( GAMEMODE.RoundBased && CurTime() > GAMEMODE:GetTimeLimit() ) then panel:SetText( "Game will end after this round" ) return end
|
||||
|
||||
panel:SetText( "Time Left: " .. util.ToMinutesSeconds( tl ) )
|
||||
end
|
||||
|
||||
if ( GetConVarNumber( "fretta_voting" ) != 0 ) then
|
||||
local btn = Help:AddSelectButton( "Vote For Change", function() RunConsoleCommand( "say", "rtv" ) end )
|
||||
btn.m_colBackground = Color( 255, 200, 100 )
|
||||
btn:SetDisabled( LocalPlayer():GetNWBool( "WantsVote" ) )
|
||||
end
|
||||
|
||||
-- Internal Select buttons.
|
||||
local btnadd = Help:AddSelectButton("Prop Hunt Menu", function()
|
||||
LocalPlayer():ConCommand("ph_enhanced_show_help")
|
||||
end)
|
||||
btnadd.m_colBackground = Color(255,128,40)
|
||||
|
||||
-- Add a hook if you want to make another custom buttons by calling PH_AddSplashHelpButton.
|
||||
hook.Call("PH_AddSplashHelpButton", nil, Help)
|
||||
|
||||
if ( GAMEMODE.TeamBased ) then
|
||||
local btn = Help:AddSelectButton( "Change Team", function() GAMEMODE:ShowTeam() end )
|
||||
btn.m_colBackground = Color( 120, 255, 100 )
|
||||
end
|
||||
|
||||
if ( !GAMEMODE.TeamBased && GAMEMODE.AllowSpectating ) then
|
||||
|
||||
if ( LocalPlayer():Team() == TEAM_SPECTATOR ) then
|
||||
|
||||
local btn = Help:AddSelectButton( "Join Game", function() RunConsoleCommand( "changeteam", TEAM_UNASSIGNED ) end )
|
||||
btn.m_colBackground = Color( 120, 255, 100 )
|
||||
|
||||
else
|
||||
|
||||
local btn = Help:AddSelectButton( "Spectate", function() RunConsoleCommand( "changeteam", TEAM_SPECTATOR ) end )
|
||||
btn.m_colBackground = Color( 200, 200, 200 )
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
if ( IsValid( LocalPlayer() ) ) then
|
||||
|
||||
local TeamID = LocalPlayer():Team()
|
||||
local Classes = team.GetClass( TeamID )
|
||||
if ( Classes && #Classes > 1 ) then
|
||||
local btn = Help:AddSelectButton( "Change Class", function() GAMEMODE:ShowClassChooser( LocalPlayer():Team() ) end )
|
||||
btn.m_colBackground = Color( 120, 255, 100 )
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
Help:AddCancelButton()
|
||||
|
||||
if ( GAMEMODE.SelectModel ) then
|
||||
|
||||
local function CreateModelPanel()
|
||||
|
||||
local pnl = vgui.Create( "DGrid" )
|
||||
|
||||
pnl:SetCols( 6 )
|
||||
pnl:SetColWide( 66 )
|
||||
pnl:SetRowHeight( 66 )
|
||||
|
||||
for name, model in pairs( list.Get( "PlayerOptionsModel" ) ) do
|
||||
|
||||
local icon = vgui.Create( "SpawnIcon" )
|
||||
icon.DoClick = function() surface.PlaySound( "ui/buttonclickrelease.wav" ) RunConsoleCommand( "cl_playermodel", name ) end
|
||||
icon.PaintOver = function() if ( GetConVarString( "cl_playermodel" ) == name ) then surface.SetDrawColor( Color( 255, 210 + math.sin(RealTime()*10)*40, 0 ) ) surface.DrawOutlinedRect( 4, 4, icon:GetWide()-8, icon:GetTall()-8 ) surface.DrawOutlinedRect( 3, 3, icon:GetWide()-6, icon:GetTall()-6 ) end end
|
||||
icon:SetModel( model )
|
||||
icon:SetSize( 64, 64 )
|
||||
icon:SetTooltip( name )
|
||||
|
||||
pnl:AddItem( icon )
|
||||
|
||||
end
|
||||
|
||||
return pnl
|
||||
|
||||
end
|
||||
|
||||
Help:AddPanelButton( "icon16/user.png", "Choose Player Model", CreateModelPanel )
|
||||
|
||||
end
|
||||
|
||||
if ( GAMEMODE.SelectColor ) then
|
||||
|
||||
local function CreateColorPanel()
|
||||
|
||||
local pnl = vgui.Create( "DGrid" )
|
||||
|
||||
pnl:SetCols( 10 )
|
||||
pnl:SetColWide( 36 )
|
||||
pnl:SetRowHeight( 128 )
|
||||
|
||||
for name, colr in pairs( list.Get( "PlayerColours" ) ) do
|
||||
|
||||
local icon = vgui.Create( "DButton" )
|
||||
icon:SetText( "" )
|
||||
icon.DoClick = function() surface.PlaySound( "ui/buttonclickrelease.wav" ) RunConsoleCommand( "cl_playercolor", name ) end
|
||||
icon.Paint = function() surface.SetDrawColor( colr ) icon:DrawFilledRect() end
|
||||
icon.PaintOver = function() if ( GetConVarString( "cl_playercolor" ) == name ) then surface.SetDrawColor( Color( 255, 210 + math.sin(RealTime()*10)*40, 0 ) ) surface.DrawOutlinedRect( 4, 4, icon:GetWide()-8, icon:GetTall()-8 ) surface.DrawOutlinedRect( 3, 3, icon:GetWide()-6, icon:GetTall()-6 ) end end
|
||||
icon:SetSize( 32, 128 )
|
||||
icon:SetTooltip( name )
|
||||
|
||||
pnl:AddItem( icon )
|
||||
|
||||
end
|
||||
|
||||
return pnl
|
||||
|
||||
end
|
||||
|
||||
Help:AddPanelButton( "icon16/application_view_tile.png", "Choose Player Color", CreateColorPanel )
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
Help:MakePopup()
|
||||
Help:NoFadeIn()
|
||||
|
||||
end
|
|
@ -0,0 +1,291 @@
|
|||
|
||||
local hudScreen = nil
|
||||
local Alive = false
|
||||
local Class = nil
|
||||
local Team = 0
|
||||
local WaitingToRespawn = false
|
||||
local InRound = false
|
||||
local RoundResult = 0
|
||||
local RoundWinner = nil
|
||||
local IsObserver = false
|
||||
local ObserveMode = 0
|
||||
local ObserveTarget = NULL
|
||||
local InVote = false
|
||||
|
||||
function GM:AddHUDItem( item, pos, parent )
|
||||
hudScreen:AddItem( item, parent, pos )
|
||||
end
|
||||
|
||||
function GM:HUDNeedsUpdate()
|
||||
|
||||
if ( !IsValid( LocalPlayer() ) ) then return false end
|
||||
|
||||
if ( Class != LocalPlayer():GetNWString( "Class", "Default" ) ) then return true end
|
||||
if ( Alive != LocalPlayer():Alive() ) then return true end
|
||||
if ( Team != LocalPlayer():Team() ) then return true end
|
||||
if ( WaitingToRespawn != ( (LocalPlayer():GetNWFloat( "RespawnTime", 0 ) > CurTime()) && LocalPlayer():Team() != TEAM_SPECTATOR && !LocalPlayer():Alive()) ) then return true end
|
||||
if ( InRound != GetGlobalBool( "InRound", false ) ) then return true end
|
||||
if ( RoundResult != GetGlobalInt( "RoundResult", 0 ) ) then return true end
|
||||
if ( RoundWinner != GetGlobalEntity( "RoundWinner", nil ) ) then return true end
|
||||
if ( IsObserver != LocalPlayer():IsObserver() ) then return true end
|
||||
if ( ObserveMode != LocalPlayer():GetObserverMode() ) then return true end
|
||||
if ( ObserveTarget != LocalPlayer():GetObserverTarget() ) then return true end
|
||||
if ( InVote != GAMEMODE:InGamemodeVote() ) then return true end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
function GM:OnHUDUpdated()
|
||||
Class = LocalPlayer():GetNWString( "Class", "Default" )
|
||||
Alive = LocalPlayer():Alive()
|
||||
Team = LocalPlayer():Team()
|
||||
WaitingToRespawn = (LocalPlayer():GetNWFloat( "RespawnTime", 0 ) > CurTime()) && LocalPlayer():Team() != TEAM_SPECTATOR && !Alive
|
||||
InRound = GetGlobalBool( "InRound", false )
|
||||
RoundResult = GetGlobalInt( "RoundResult", 0 )
|
||||
RoundWinner = GetGlobalEntity( "RoundWinner", nil )
|
||||
IsObserver = LocalPlayer():IsObserver()
|
||||
ObserveMode = LocalPlayer():GetObserverMode()
|
||||
ObserveTarget = LocalPlayer():GetObserverTarget()
|
||||
InVote = GAMEMODE:InGamemodeVote()
|
||||
end
|
||||
|
||||
function GM:OnHUDPaint()
|
||||
|
||||
end
|
||||
|
||||
function GM:RefreshHUD()
|
||||
|
||||
if ( !GAMEMODE:HUDNeedsUpdate() ) then return end
|
||||
GAMEMODE:OnHUDUpdated()
|
||||
|
||||
if ( IsValid( hudScreen ) ) then hudScreen:Remove() end
|
||||
hudScreen = vgui.Create( "DHudLayout" )
|
||||
|
||||
if ( InVote ) then return end
|
||||
|
||||
if ( RoundWinner and RoundWinner != NULL ) then
|
||||
GAMEMODE:UpdateHUD_RoundResult( RoundWinner, Alive )
|
||||
elseif ( RoundResult != 0 ) then
|
||||
GAMEMODE:UpdateHUD_RoundResult( RoundResult, Alive )
|
||||
elseif ( IsObserver ) then
|
||||
GAMEMODE:UpdateHUD_Observer( WaitingToRespawn, InRound, ObserveMode, ObserveTarget )
|
||||
elseif ( !Alive ) then
|
||||
GAMEMODE:UpdateHUD_Dead( WaitingToRespawn, InRound )
|
||||
else
|
||||
GAMEMODE:UpdateHUD_Alive( InRound )
|
||||
|
||||
if ( GetGlobalBool( "RoundWaitForPlayers" ) && ( ( team.NumPlayers( TEAM_HUNTERS ) < 1 ) || ( team.NumPlayers( TEAM_PROPS ) < 1 ) ) ) then
|
||||
GAMEMODE:UpdateHUD_WaitForPlayers( InRound )
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
function GM:HUDPaint()
|
||||
|
||||
self.BaseClass:HUDPaint()
|
||||
|
||||
GAMEMODE:OnHUDPaint()
|
||||
GAMEMODE:RefreshHUD()
|
||||
|
||||
end
|
||||
|
||||
function GM:UpdateHUD_WaitForPlayers( InRound )
|
||||
|
||||
if ( InRound && Alive ) then
|
||||
|
||||
local WaitText = vgui.Create( "DHudElement" );
|
||||
WaitText:SizeToContents()
|
||||
WaitText:SetText( "Waiting for players..." )
|
||||
GAMEMODE:AddHUDItem( WaitText, 8 )
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
function GM:UpdateHUD_RoundResult( RoundResult, Alive )
|
||||
|
||||
local txt = GetGlobalString( "RRText" )
|
||||
|
||||
if ( type( RoundResult ) == "number" ) && ( team.GetAllTeams()[ RoundResult ] && txt == "" ) then
|
||||
local TeamName = team.GetName( RoundResult )
|
||||
if ( TeamName ) then txt = TeamName .. " Wins!" end
|
||||
elseif ( type( RoundResult ) == "Player" && IsValid( RoundResult ) && txt == "" ) then
|
||||
txt = RoundResult:Name() .. " Wins!"
|
||||
end
|
||||
|
||||
local RespawnText = vgui.Create( "DHudElement" );
|
||||
RespawnText:SizeToContents()
|
||||
RespawnText:SetText( txt )
|
||||
GAMEMODE:AddHUDItem( RespawnText, 8 )
|
||||
|
||||
end
|
||||
|
||||
function GM:UpdateHUD_Observer( bWaitingToSpawn, InRound, ObserveMode, ObserveTarget )
|
||||
|
||||
local lbl = nil
|
||||
local txt = nil
|
||||
local col = Color( 255, 255, 255 );
|
||||
|
||||
if ( IsValid( ObserveTarget ) && ObserveTarget:IsPlayer() && ObserveTarget != LocalPlayer() && ObserveMode != OBS_MODE_ROAMING ) then
|
||||
lbl = "SPECTATING"
|
||||
txt = ObserveTarget:Nick()
|
||||
col = team.GetColor( ObserveTarget:Team() );
|
||||
end
|
||||
|
||||
if ( ObserveMode == OBS_MODE_DEATHCAM || ObserveMode == OBS_MODE_FREEZECAM ) then
|
||||
txt = "You Died!" // were killed by?
|
||||
end
|
||||
|
||||
if ( txt ) then
|
||||
local txtLabel = vgui.Create( "DHudElement" );
|
||||
txtLabel:SetText( txt )
|
||||
if ( lbl ) then txtLabel:SetLabel( lbl ) end
|
||||
txtLabel:SetTextColor( col )
|
||||
|
||||
GAMEMODE:AddHUDItem( txtLabel, 2 )
|
||||
end
|
||||
|
||||
|
||||
GAMEMODE:UpdateHUD_Dead( bWaitingToSpawn, InRound )
|
||||
|
||||
end
|
||||
|
||||
function GM:UpdateHUD_Dead( bWaitingToSpawn, InRound )
|
||||
|
||||
if ( !InRound && GAMEMODE.RoundBased ) then
|
||||
|
||||
local RespawnText = vgui.Create( "DHudElement" );
|
||||
RespawnText:SizeToContents()
|
||||
RespawnText:SetText( "Waiting for round start" )
|
||||
GAMEMODE:AddHUDItem( RespawnText, 8 )
|
||||
return
|
||||
|
||||
end
|
||||
|
||||
if ( bWaitingToSpawn ) then
|
||||
|
||||
local RespawnTimer = vgui.Create( "DHudCountdown" );
|
||||
RespawnTimer:SizeToContents()
|
||||
RespawnTimer:SetValueFunction( function() return LocalPlayer():GetNWFloat( "RespawnTime", 0 ) end )
|
||||
RespawnTimer:SetLabel( "SPAWN IN" )
|
||||
GAMEMODE:AddHUDItem( RespawnTimer, 8 )
|
||||
return
|
||||
|
||||
end
|
||||
|
||||
--[[
|
||||
if ( InRound ) then
|
||||
|
||||
local RoundTimer = vgui.Create( "DHudCountdown" );
|
||||
RoundTimer:SizeToContents()
|
||||
RoundTimer:SetValueFunction( function()
|
||||
if ( GetGlobalFloat( "RoundStartTime", 0 ) > CurTime() ) then return GetGlobalFloat( "RoundStartTime", 0 ) end
|
||||
return GetGlobalFloat( "RoundEndTime" ) end )
|
||||
RoundTimer:SetLabel( "TIME" )
|
||||
GAMEMODE:AddHUDItem( RoundTimer, 8 )
|
||||
return
|
||||
|
||||
end
|
||||
]]--
|
||||
|
||||
local Bar = vgui.Create( "DHudBar" )
|
||||
GAMEMODE:AddHUDItem( Bar, 8 )
|
||||
|
||||
-- This should show on dead players too
|
||||
|
||||
if ( InRound ) then
|
||||
|
||||
local TeamIndicator_Name_AddString = "(DEAD) "
|
||||
if ( LocalPlayer():Team() == TEAM_SPECTATOR ) then TeamIndicator_Name_AddString = "" end
|
||||
|
||||
local TeamIndicator = vgui.Create( "DHudUpdater" );
|
||||
TeamIndicator:SizeToContents()
|
||||
TeamIndicator:SetValueFunction( function()
|
||||
return TeamIndicator_Name_AddString..""..team.GetName( LocalPlayer():Team() )
|
||||
end )
|
||||
TeamIndicator:SetColorFunction( function()
|
||||
return team.GetColor( LocalPlayer():Team() )
|
||||
end )
|
||||
TeamIndicator:SetFont( "HudSelectionText" )
|
||||
Bar:AddItem( TeamIndicator )
|
||||
|
||||
local RoundNumber = vgui.Create( "DHudUpdater" );
|
||||
RoundNumber:SizeToContents()
|
||||
RoundNumber:SetValueFunction( function() return GetGlobalInt( "RoundNumber", 0 ) end )
|
||||
RoundNumber:SetLabel( "ROUND" )
|
||||
Bar:AddItem( RoundNumber )
|
||||
|
||||
local RoundTimer = vgui.Create( "DHudCountdown" );
|
||||
RoundTimer:SizeToContents()
|
||||
RoundTimer:SetValueFunction( function()
|
||||
if ( GetGlobalFloat( "RoundStartTime", 0 ) > CurTime() ) then return GetGlobalFloat( "RoundStartTime", 0 ) end
|
||||
return GetGlobalFloat( "RoundEndTime" ) end )
|
||||
RoundTimer:SetLabel( "TIME" )
|
||||
Bar:AddItem( RoundTimer )
|
||||
|
||||
end
|
||||
|
||||
if ( Team != TEAM_SPECTATOR && !Alive && !GAMEMODE.RoundBased ) then
|
||||
|
||||
local RespawnText = vgui.Create( "DHudElement" );
|
||||
RespawnText:SizeToContents()
|
||||
RespawnText:SetText( "Press Fire to Spawn" )
|
||||
GAMEMODE:AddHUDItem( RespawnText, 8 )
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
function GM:UpdateHUD_Alive( InRound )
|
||||
|
||||
if ( GAMEMODE.RoundBased || GAMEMODE.TeamBased ) then
|
||||
|
||||
local Bar = vgui.Create( "DHudBar" )
|
||||
GAMEMODE:AddHUDItem( Bar, 2 )
|
||||
|
||||
if ( GAMEMODE.TeamBased && GAMEMODE.ShowTeamName ) then
|
||||
|
||||
local TeamIndicator = vgui.Create( "DHudUpdater" );
|
||||
TeamIndicator:SizeToContents()
|
||||
TeamIndicator:SetValueFunction( function()
|
||||
return team.GetName( LocalPlayer():Team() )
|
||||
end )
|
||||
TeamIndicator:SetColorFunction( function()
|
||||
return team.GetColor( LocalPlayer():Team() )
|
||||
end )
|
||||
TeamIndicator:SetFont( "HudSelectionText" )
|
||||
Bar:AddItem( TeamIndicator )
|
||||
|
||||
end
|
||||
|
||||
if ( GAMEMODE.RoundBased ) then
|
||||
|
||||
local RoundNumber = vgui.Create( "DHudUpdater" );
|
||||
RoundNumber:SizeToContents()
|
||||
RoundNumber:SetValueFunction( function() return GetGlobalInt( "RoundNumber", 0 ) end )
|
||||
RoundNumber:SetLabel( "ROUND" )
|
||||
Bar:AddItem( RoundNumber )
|
||||
|
||||
local RoundTimer = vgui.Create( "DHudCountdown" );
|
||||
RoundTimer:SizeToContents()
|
||||
RoundTimer:SetValueFunction( function()
|
||||
if ( GetGlobalFloat( "RoundStartTime", 0 ) > CurTime() ) then return GetGlobalFloat( "RoundStartTime", 0 ) end
|
||||
return GetGlobalFloat( "RoundEndTime" ) end )
|
||||
RoundTimer:SetLabel( "TIME" )
|
||||
Bar:AddItem( RoundTimer )
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
--[[
|
||||
this thing is obsolete/depcretaed. Sorry!
|
||||
|
||||
function GM:UpdateHUD_AddedTime( iTimeAdded )
|
||||
// to do or to override, your choice
|
||||
end
|
||||
usermessage.Hook( "RoundAddedTime", function( um ) if( GAMEMODE && um ) then GAMEMODE:UpdateHUD_AddedTime( um:ReadFloat() ) end end )
|
||||
]]--
|
|
@ -0,0 +1,198 @@
|
|||
|
||||
function surface.CreateLegacyFont(font, size, weight, antialias, additive, name, shadow, outline, blursize)
|
||||
surface.CreateFont(name, {font = font, size = size, weight = weight, antialias = antialias, additive = additive, shadow = shadow, outline = outline, blursize = blursize})
|
||||
end
|
||||
|
||||
include( 'shared.lua' )
|
||||
include( 'cl_splashscreen.lua' )
|
||||
include( 'cl_selectscreen.lua' )
|
||||
include( 'cl_gmchanger.lua' )
|
||||
include( 'cl_help.lua' )
|
||||
include( 'skin.lua' )
|
||||
include( 'vgui/vgui_hudlayout.lua' )
|
||||
include( 'vgui/vgui_hudelement.lua' )
|
||||
include( 'vgui/vgui_hudbase.lua' )
|
||||
include( 'vgui/vgui_hudcommon.lua' )
|
||||
include( 'cl_hud.lua' )
|
||||
include( 'cl_deathnotice.lua' )
|
||||
include( 'cl_scores.lua' )
|
||||
include( 'cl_notify.lua' )
|
||||
|
||||
language.Add( "env_laser", "Laser" )
|
||||
language.Add( "env_explosion", "Explosion" )
|
||||
language.Add( "func_door", "Door" )
|
||||
language.Add( "func_door_rotating", "Door" )
|
||||
language.Add( "trigger_hurt", "Hazard" )
|
||||
language.Add( "func_rotating", "Hazard" )
|
||||
language.Add( "worldspawn", "Gravity" )
|
||||
language.Add( "prop_physics", "Prop" )
|
||||
language.Add( "prop_physics_respawnable", "Prop" )
|
||||
language.Add( "prop_physics_multiplayer", "Prop" )
|
||||
language.Add( "entityflame", "Fire" )
|
||||
|
||||
surface.CreateLegacyFont( "Roboto", 40, 700, true, false, "FRETTA_HUGE" )
|
||||
surface.CreateLegacyFont( "Roboto", 40, 700, true, false, "FRETTA_HUGE_SHADOW", true )
|
||||
surface.CreateLegacyFont( "Roboto", 24, 700, true, false, "FRETTA_LARGE" )
|
||||
surface.CreateLegacyFont( "Roboto", 24, 700, true, false, "FRETTA_LARGE_SHADOW", true )
|
||||
surface.CreateLegacyFont( "Roboto", 19, 700, true, false, "FRETTA_MEDIUM" )
|
||||
surface.CreateLegacyFont( "Roboto", 19, 700, true, false, "FRETTA_MEDIUM_SHADOW", true )
|
||||
surface.CreateLegacyFont( "Roboto", 16, 700, true, false, "FRETTA_SMALL" )
|
||||
|
||||
surface.CreateLegacyFont( "Roboto", ScreenScale( 10 ), 700, true, false, "FRETTA_NOTIFY", true )
|
||||
|
||||
CreateClientConVar( "cl_spec_mode", "5", true, true )
|
||||
|
||||
function GM:Initialize()
|
||||
|
||||
self.BaseClass:Initialize()
|
||||
|
||||
end
|
||||
|
||||
function GM:InitPostEntity()
|
||||
|
||||
if ( GAMEMODE.TeamBased ) then
|
||||
GAMEMODE:ShowTeam();
|
||||
end
|
||||
|
||||
GAMEMODE:ShowSplash();
|
||||
|
||||
end
|
||||
|
||||
local CircleMat = Material( "SGM/playercircle" );
|
||||
|
||||
function GM:DrawPlayerRing( pPlayer )
|
||||
|
||||
if ( !IsValid( pPlayer ) ) then return end
|
||||
if ( !pPlayer:GetNWBool( "DrawRing", false ) ) then return end
|
||||
if ( !pPlayer:Alive() ) then return end
|
||||
|
||||
local trace = {}
|
||||
trace.start = pPlayer:GetPos() + Vector(0,0,50)
|
||||
trace.endpos = trace.start + Vector(0,0,-300)
|
||||
trace.filter = pPlayer
|
||||
|
||||
local tr = util.TraceLine( trace )
|
||||
|
||||
if not tr.HitWorld then
|
||||
tr.HitPos = pPlayer:GetPos()
|
||||
end
|
||||
|
||||
local color = table.Copy( team.GetColor( pPlayer:Team() ) )
|
||||
color.a = 40;
|
||||
|
||||
render.SetMaterial( CircleMat )
|
||||
render.DrawQuadEasy( tr.HitPos + tr.HitNormal, tr.HitNormal, GAMEMODE.PlayerRingSize, GAMEMODE.PlayerRingSize, color )
|
||||
|
||||
end
|
||||
|
||||
hook.Add( "PrePlayerDraw", "DrawPlayerRing", function( ply ) GAMEMODE:DrawPlayerRing( ply ) end )
|
||||
|
||||
function GM:HUDShouldDraw( name )
|
||||
|
||||
if GAMEMODE.ScoreboardVisible then return false end
|
||||
|
||||
// commented out until HUD elements are made
|
||||
//for k, v in pairs{"CHudHealth", "CHudBattery", "CHudAmmo", "CHudSecondaryAmmo"} do
|
||||
// if name == v then return false end
|
||||
//end
|
||||
|
||||
if name == "CHudDamageIndicator" and not LocalPlayer():Alive() then
|
||||
return false
|
||||
end
|
||||
|
||||
return true
|
||||
|
||||
end
|
||||
|
||||
function GM:OnSpawnMenuOpen()
|
||||
RunConsoleCommand( "lastinv" ); // Fretta is derived from base and has no spawn menu, so give it a use, make it lastinv.
|
||||
end
|
||||
|
||||
|
||||
function GM:PlayerBindPress( pl, bind, down )
|
||||
|
||||
// Redirect binds to the spectate system
|
||||
if ( pl:IsObserver() && down ) then
|
||||
|
||||
if ( bind == "+jump" ) then RunConsoleCommand( "spec_mode" ) end
|
||||
if ( bind == "+attack" ) then RunConsoleCommand( "spec_next" ) end
|
||||
if ( bind == "+attack2" ) then RunConsoleCommand( "spec_prev" ) end
|
||||
|
||||
end
|
||||
|
||||
return false
|
||||
|
||||
end
|
||||
|
||||
/*---------------------------------------------------------
|
||||
Name: gamemode:GetTeamColor( ent )
|
||||
---------------------------------------------------------*/
|
||||
function GM:GetTeamColor( ent )
|
||||
|
||||
if ( GAMEMODE.SelectColor && IsValid( ent ) ) then
|
||||
|
||||
local clr = ent:GetNWString( "NameColor", -1 )
|
||||
if ( clr && clr != -1 && clr != "" ) then
|
||||
clr = list.Get( "PlayerColours" )[ clr ]
|
||||
if ( clr ) then return clr end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
local team = TEAM_UNASSIGNED
|
||||
if ( ent.Team and IsValid(ent) ) then team = ent:Team() end
|
||||
return GAMEMODE:GetTeamNumColor( team )
|
||||
|
||||
end
|
||||
|
||||
|
||||
/*---------------------------------------------------------
|
||||
Name: ShouldDrawLocalPlayer
|
||||
---------------------------------------------------------*/
|
||||
function GM:ShouldDrawLocalPlayer( ply )
|
||||
return ply:CallClassFunction( "ShouldDrawLocalPlayer" )
|
||||
end
|
||||
|
||||
|
||||
/*---------------------------------------------------------
|
||||
Name: InputMouseApply
|
||||
---------------------------------------------------------*/
|
||||
function GM:InputMouseApply( cmd, x, y, angle )
|
||||
|
||||
return LocalPlayer():CallClassFunction( "InputMouseApply", cmd, x, y, angle )
|
||||
|
||||
end
|
||||
|
||||
function GM:TeamChangeNotification( ply, oldteam, newteam )
|
||||
|
||||
local random_spectator_text = {
|
||||
"to watch and chill.",
|
||||
"to see them hanging around.",
|
||||
" ", -- you serious?
|
||||
"to see the things."
|
||||
}
|
||||
|
||||
if( ply && ply:IsValid() ) then
|
||||
local nick = ply:Nick();
|
||||
local oldTeamColor = team.GetColor( oldteam );
|
||||
local newTeamName = team.GetName( newteam );
|
||||
local newTeamColor = team.GetColor( newteam );
|
||||
|
||||
if( newteam == TEAM_SPECTATOR ) then
|
||||
chat.AddText( oldTeamColor, nick, color_white, " joined the ", newTeamColor, newTeamName , color_white, " "..table.Random(random_spectator_text));
|
||||
else
|
||||
chat.AddText( oldTeamColor, nick, color_white, " joined ", newTeamColor, newTeamName );
|
||||
end
|
||||
|
||||
surface.PlaySound("buttons/button17.wav")
|
||||
end
|
||||
end
|
||||
net.Receive("fretta_teamchange", function()
|
||||
local ply = net.ReadEntity()
|
||||
local oldt = net.ReadInt(12)
|
||||
local newt = net.ReadInt(12)
|
||||
|
||||
if (GAMEMODE) then
|
||||
GAMEMODE:TeamChangeNotification(ply, oldt, newt)
|
||||
end
|
||||
end)
|
|
@ -0,0 +1,26 @@
|
|||
|
||||
local function CreateLeftNotify()
|
||||
|
||||
local x, y = chat.GetChatBoxPos()
|
||||
|
||||
g_LeftNotify = vgui.Create( "DNotify" )
|
||||
|
||||
g_LeftNotify:SetPos( 32, 0 )
|
||||
g_LeftNotify:SetSize( ScrW(), y - 8 )
|
||||
g_LeftNotify:SetAlignment( 1 )
|
||||
g_LeftNotify:ParentToHUD()
|
||||
|
||||
end
|
||||
|
||||
hook.Add( "InitPostEntity", "CreateLeftNotify", CreateLeftNotify )
|
||||
|
||||
function GM:NotifyGMVote( name, gamemode, votesneeded )
|
||||
|
||||
local dl = vgui.Create( "DLabel" )
|
||||
dl:SetFont( "FRETTA_MEDIUM_SHADOW" )
|
||||
dl:SetTextColor( Color( 255, 255, 255, 255 ) )
|
||||
dl:SetText( Format( "%s voted for %s (need %i more)", name, gamemode, votesneeded ) )
|
||||
dl:SizeToContents()
|
||||
g_LeftNotify:AddItem( dl, 5 )
|
||||
|
||||
end
|
|
@ -0,0 +1,138 @@
|
|||
|
||||
include( "vgui/vgui_scoreboard.lua" )
|
||||
|
||||
function GM:GetScoreboard()
|
||||
|
||||
if ( IsValid( g_ScoreBoard ) ) then
|
||||
g_ScoreBoard:Remove()
|
||||
end
|
||||
|
||||
g_ScoreBoard = vgui.Create( "FrettaScoreboard" )
|
||||
self:CreateScoreboard( g_ScoreBoard )
|
||||
|
||||
return g_ScoreBoard
|
||||
|
||||
end
|
||||
|
||||
function GM:ScoreboardShow()
|
||||
|
||||
GAMEMODE:GetScoreboard():SetVisible( true )
|
||||
GAMEMODE:PositionScoreboard( GAMEMODE:GetScoreboard() )
|
||||
|
||||
end
|
||||
|
||||
function GM:ScoreboardHide()
|
||||
|
||||
GAMEMODE:GetScoreboard():SetVisible( false )
|
||||
|
||||
end
|
||||
|
||||
function GM:AddScoreboardAvatar( ScoreBoard )
|
||||
|
||||
local f = function( ply )
|
||||
local av = vgui.Create( "AvatarImage", ScoreBoard )
|
||||
av:SetSize( 32, 32 )
|
||||
av:SetPlayer( ply )
|
||||
av.Click = function()
|
||||
print( "LOL" )
|
||||
end
|
||||
return av
|
||||
end
|
||||
|
||||
ScoreBoard:AddColumn( "", 32, f, 360 ) // Avatar
|
||||
|
||||
end
|
||||
|
||||
function GM:AddScoreboardSpacer( ScoreBoard, iSize )
|
||||
ScoreBoard:AddColumn( "", 16 )
|
||||
end
|
||||
|
||||
function GM:AddScoreboardName( ScoreBoard )
|
||||
|
||||
local f = function( ply ) return ply:Name() end
|
||||
ScoreBoard:AddColumn( "Name", nil, f, 10, nil, 4, 4 )
|
||||
|
||||
end
|
||||
|
||||
function GM:AddScoreboardKills( ScoreBoard )
|
||||
|
||||
local f = function( ply ) return ply:Frags() end
|
||||
ScoreBoard:AddColumn( "Kills", 40, f, 0.5, nil, 6, 6 )
|
||||
|
||||
end
|
||||
|
||||
function GM:AddScoreboardDeaths( ScoreBoard )
|
||||
|
||||
local f = function( ply ) return ply:Deaths() end
|
||||
ScoreBoard:AddColumn( "Deaths", 60, f, 0.5, nil, 6, 6 )
|
||||
|
||||
end
|
||||
|
||||
function GM:AddScoreboardPing( ScoreBoard )
|
||||
|
||||
local f = function( ply ) return ply:ScoreboardPing() end
|
||||
ScoreBoard:AddColumn( "Ping", 40, f, 0.1, nil, 6, 6 )
|
||||
|
||||
end
|
||||
|
||||
// THESE SHOULD BE THE ONLY FUNCTION YOU NEED TO OVERRIDE
|
||||
|
||||
function GM:PositionScoreboard( ScoreBoard )
|
||||
|
||||
if ( GAMEMODE.TeamBased ) then
|
||||
ScoreBoard:SetSize( ScrW()/1.2, ScrH() - 50 )
|
||||
ScoreBoard:SetPos( (ScrW() - ScoreBoard:GetWide()) * 0.5, 25 )
|
||||
else
|
||||
ScoreBoard:SetSize( 420, ScrH() - 64 )
|
||||
ScoreBoard:SetPos( (ScrW() - ScoreBoard:GetWide()) / 2, 32 )
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
function GM:AddScoreboardWantsChange( ScoreBoard )
|
||||
|
||||
local f = function( ply )
|
||||
if ( ply:GetNWBool( "WantsVote", false ) ) then
|
||||
local lbl = vgui.Create( "DLabel" )
|
||||
lbl:SetFont( "Marlett" )
|
||||
lbl:SetText( "a" )
|
||||
lbl:SetTextColor( Color( 100, 255, 0 ) )
|
||||
lbl:SetContentAlignment( 5 )
|
||||
return lbl
|
||||
end
|
||||
end
|
||||
|
||||
ScoreBoard:AddColumn( "", 16, f, 2, nil, 6, 6 )
|
||||
|
||||
end
|
||||
|
||||
function GM:CreateScoreboard( ScoreBoard )
|
||||
|
||||
// This makes it so that it's behind chat & hides when you're in the menu
|
||||
// Disable this if you want to be able to click on stuff on your scoreboard
|
||||
ScoreBoard:ParentToHUD()
|
||||
|
||||
ScoreBoard:SetRowHeight( 32 )
|
||||
|
||||
ScoreBoard:SetAsBullshitTeam( TEAM_SPECTATOR )
|
||||
ScoreBoard:SetAsBullshitTeam( TEAM_CONNECTING )
|
||||
ScoreBoard:SetShowScoreboardHeaders( GAMEMODE.TeamBased )
|
||||
|
||||
if ( GAMEMODE.TeamBased ) then
|
||||
ScoreBoard:SetAsBullshitTeam( TEAM_UNASSIGNED )
|
||||
ScoreBoard:SetHorizontal( true )
|
||||
end
|
||||
|
||||
ScoreBoard:SetSkin( GAMEMODE.HudSkin )
|
||||
|
||||
self:AddScoreboardAvatar( ScoreBoard ) // 1
|
||||
self:AddScoreboardWantsChange( ScoreBoard ) // 2
|
||||
self:AddScoreboardName( ScoreBoard ) // 3
|
||||
self:AddScoreboardKills( ScoreBoard ) // 4
|
||||
self:AddScoreboardDeaths( ScoreBoard ) // 5
|
||||
self:AddScoreboardPing( ScoreBoard ) // 6
|
||||
|
||||
// Here we sort by these columns (and descending), in this order. You can define up to 4
|
||||
ScoreBoard:SetSortColumns( { 4, true, 5, false, 3, false } )
|
||||
|
||||
end
|
|
@ -0,0 +1,317 @@
|
|||
|
||||
local CENTER_HEIGHT = 250
|
||||
local PANEL = {}
|
||||
|
||||
/*---------------------------------------------------------
|
||||
Init
|
||||
---------------------------------------------------------*/
|
||||
function PANEL:Init()
|
||||
|
||||
self:SetText( "" )
|
||||
self.Buttons = {}
|
||||
self.BottomButtons = {}
|
||||
self:SetSkin( GAMEMODE.HudSkin )
|
||||
|
||||
self.pnlButtons = vgui.Create( "DPanelList", self )
|
||||
self.pnlButtons:SetPadding( 10 )
|
||||
self.pnlButtons:SetSpacing( 10 )
|
||||
self.pnlButtons:SetDrawBackground( false )
|
||||
self.pnlButtons:EnableVerticalScrollbar()
|
||||
|
||||
self.lblMain = vgui.Create( "DLabel", self )
|
||||
self.lblMain:SetText( GAMEMODE.Name )
|
||||
self.lblMain:SetFont( "FRETTA_HUGE" )
|
||||
self.lblMain:SetColor( color_white )
|
||||
|
||||
self.pnlMain = vgui.Create( "DPanelList", self )
|
||||
self.pnlMain:SetNoSizing( true )
|
||||
self.pnlMain:SetDrawBackground( false )
|
||||
self.pnlMain:EnableVerticalScrollbar()
|
||||
|
||||
self.btnCancel = vgui.Create( "DButton", self )
|
||||
self.btnCancel:SetText( "#Close" )
|
||||
self.btnCancel:SetSize( 100, 30 )
|
||||
self.btnCancel:SetFGColor( Color( 0, 0, 0, 200 ) )
|
||||
self.btnCancel:SetFont( "FRETTA_SMALL" )
|
||||
self.btnCancel.DoClick = function() self:Remove() end
|
||||
self.btnCancel:SetVisible( false )
|
||||
|
||||
Derma_Hook( self.btnCancel, "Paint", "Paint", "CancelButton" )
|
||||
Derma_Hook( self.btnCancel, "PaintOver", "PaintOver", "CancelButton" )
|
||||
Derma_Hook( self.btnCancel, "ApplySchemeSettings", "Scheme", "CancelButton" )
|
||||
Derma_Hook( self.btnCancel, "PerformLayout", "Layout", "CancelButton" )
|
||||
|
||||
self.lblHoverText = vgui.Create( "DLabel", self )
|
||||
self.lblHoverText:SetText( "" )
|
||||
self.lblHoverText:SetFont( "FRETTA_MEDIUM" )
|
||||
self.lblHoverText:SetColor( color_white )
|
||||
self.lblHoverText:SetContentAlignment( 8 )
|
||||
self.lblHoverText:SetWrap( true )
|
||||
|
||||
self.lblFooterText = vgui.Create( "DLabel", self )
|
||||
self.lblFooterText:SetText( "" )
|
||||
self.lblFooterText:SetFont( "FRETTA_MEDIUM" )
|
||||
self.lblFooterText:SetColor( color_white )
|
||||
self.lblFooterText:SetContentAlignment( 8 )
|
||||
self.lblFooterText:SetWrap( false )
|
||||
|
||||
self.pnlMain:AddItem( self.lblHoverText )
|
||||
|
||||
self:PerformLayout()
|
||||
|
||||
self.OpenTime = SysTime()
|
||||
|
||||
end
|
||||
|
||||
function PANEL:NoFadeIn()
|
||||
self.OpenTime = 0
|
||||
end
|
||||
|
||||
/*---------------------------------------------------------
|
||||
AddPanelButton
|
||||
---------------------------------------------------------*/
|
||||
function PANEL:AddPanelButton( icon, title, pnlfnc )
|
||||
|
||||
local btn = vgui.Create( "DImageButton", self )
|
||||
btn:SetImage( icon )
|
||||
btn:SetTooltip( title )
|
||||
btn:SetSize( 30, 30 )
|
||||
btn:SetVisible( true )
|
||||
btn.pPanelFnc = pnlfnc
|
||||
btn.pPanel = nil
|
||||
btn:SetStretchToFit( false )
|
||||
|
||||
Derma_Hook( btn, "Paint", "Paint", "PanelButton" )
|
||||
Derma_Hook( btn, "PaintOver", "PaintOver", "PanelButton" )
|
||||
//Derma_Hook( btn, "ApplySchemeSettings", "Scheme", "PanelButton" )
|
||||
//Derma_Hook( btn, "PerformLayout", "Layout", "PanelButton" )
|
||||
|
||||
local fnClick = function()
|
||||
|
||||
if ( !btn.pPanel ) then
|
||||
btn.pPanel = btn.pPanelFnc()
|
||||
btn.pPanel:SetParent( self.pnlMain )
|
||||
btn.pPanel:SetVisible( false )
|
||||
btn.pPanelFnc = nil
|
||||
end
|
||||
|
||||
// Toggle off
|
||||
if ( btn.m_bSelected ) then self:ClearSelectedPanel() return end
|
||||
|
||||
self:ClearSelectedPanel()
|
||||
|
||||
btn.m_bSelected = true
|
||||
|
||||
self.pnlMain:Clear()
|
||||
btn.pPanel:SetVisible( true )
|
||||
self.pnlMain:AddItem( btn.pPanel )
|
||||
|
||||
end
|
||||
btn.DoClick = fnClick
|
||||
|
||||
table.insert( self.BottomButtons, btn )
|
||||
|
||||
return btn
|
||||
|
||||
end
|
||||
|
||||
function PANEL:ClearSelectedPanel()
|
||||
|
||||
self.pnlMain:Clear()
|
||||
self.pnlMain:AddItem( self.lblHoverText )
|
||||
|
||||
for k, btn in pairs( self.BottomButtons ) do
|
||||
|
||||
btn.m_bSelected = false
|
||||
if ( IsValid( btn.pPanel ) ) then
|
||||
btn.pPanel:SetVisible( false )
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
/*---------------------------------------------------------
|
||||
SetHeaderText
|
||||
---------------------------------------------------------*/
|
||||
function PANEL:SetHeaderText( strName )
|
||||
|
||||
self.lblMain:SetText( strName )
|
||||
|
||||
end
|
||||
|
||||
/*---------------------------------------------------------
|
||||
SetHeaderText
|
||||
---------------------------------------------------------*/
|
||||
function PANEL:SetHoverText( strName )
|
||||
|
||||
self.lblHoverText:SetText( strName or "" )
|
||||
|
||||
end
|
||||
|
||||
/*---------------------------------------------------------
|
||||
SetHeaderText
|
||||
---------------------------------------------------------*/
|
||||
function PANEL:GetHoverText( strName )
|
||||
|
||||
return self.lblHoverText:GetValue()
|
||||
|
||||
end
|
||||
|
||||
/*---------------------------------------------------------
|
||||
AddSelectButton
|
||||
---------------------------------------------------------*/
|
||||
function PANEL:AddSelectButton( strName, fnFunction, txt )
|
||||
|
||||
local btn = vgui.Create( "DButton", self.pnlButtons )
|
||||
btn:SetText( strName )
|
||||
btn:SetSize( 200, 30 )
|
||||
btn.DoClick = function() fnFunction() surface.PlaySound( Sound("buttons/lightswitch2.wav") ) self:Remove() end
|
||||
|
||||
Derma_Hook( btn, "Paint", "Paint", "SelectButton" )
|
||||
Derma_Hook( btn, "PaintOver", "PaintOver", "SelectButton" )
|
||||
Derma_Hook( btn, "ApplySchemeSettings", "Scheme", "SelectButton" )
|
||||
Derma_Hook( btn, "PerformLayout", "Layout", "SelectButton" )
|
||||
|
||||
if ( txt ) then
|
||||
btn.OnCursorEntered = function() self.OldHoverText = self:GetHoverText() self:SetHoverText( txt ) end
|
||||
btn.OnCursorExited = function() self:SetHoverText( self.OldHoverText ) self.OldHoverText = nil end
|
||||
end
|
||||
|
||||
self.pnlButtons:AddItem( btn )
|
||||
|
||||
table.insert( self.Buttons, btn )
|
||||
return btn
|
||||
|
||||
end
|
||||
|
||||
/*---------------------------------------------------------
|
||||
SetHeaderText
|
||||
---------------------------------------------------------*/
|
||||
function PANEL:AddSpacer( h )
|
||||
|
||||
local btn = vgui.Create( "Panel", self )
|
||||
btn:SetSize( 200, h )
|
||||
table.insert( self.Buttons, btn )
|
||||
return btn
|
||||
|
||||
end
|
||||
|
||||
/*---------------------------------------------------------
|
||||
SetHeaderText
|
||||
---------------------------------------------------------*/
|
||||
function PANEL:AddCancelButton()
|
||||
|
||||
self.btnCancel:SetVisible( true )
|
||||
|
||||
end
|
||||
|
||||
/*---------------------------------------------------------
|
||||
PerformLayout
|
||||
---------------------------------------------------------*/
|
||||
function PANEL:PerformLayout()
|
||||
|
||||
self:SetSize( ScrW(), ScrH() )
|
||||
|
||||
local CenterY = ScrH() / 2.0
|
||||
local CenterX = ScrW() / 2.0
|
||||
local InnerWidth = 640
|
||||
|
||||
self.lblMain:SizeToContents()
|
||||
self.lblMain:SetPos( ScrW() * 0.5 - self.lblMain:GetWide() * 0.5, CenterY - CENTER_HEIGHT - self.lblMain:GetTall() * 1.2 )
|
||||
|
||||
self.pnlButtons:SetPos( ScrW() * 0.5 - InnerWidth * 0.5, (CenterY - CENTER_HEIGHT) + 20 )
|
||||
self.pnlButtons:SetSize( 210, (CENTER_HEIGHT * 2) - self.btnCancel:GetTall() - 20 - 20 - 20 )
|
||||
|
||||
self.btnCancel:SetPos( ScrW() * 0.5 + InnerWidth * 0.5 - self.btnCancel:GetWide(), CenterY + CENTER_HEIGHT - self.btnCancel:GetTall() - 20 )
|
||||
|
||||
self.lblHoverText:SetPos( ScrW() * 0.5 - InnerWidth * 0.5 + 50, (CenterY - 150) )
|
||||
self.lblHoverText:SetSize( 300, 300 )
|
||||
|
||||
self.pnlMain:SetPos( self.pnlButtons.x + self.pnlButtons:GetWide() + 10, self.pnlButtons.y )
|
||||
self.pnlMain:SetSize( InnerWidth - self.pnlButtons:GetWide() - 10, 400 )
|
||||
|
||||
self.lblFooterText:SetSize( ScrW(), 30 )
|
||||
self.lblFooterText:SetPos( 0, CenterY + CENTER_HEIGHT + 10 )
|
||||
|
||||
local x = self.pnlButtons.x
|
||||
for k, btn in pairs( self.BottomButtons ) do
|
||||
|
||||
btn:SetPos( x, CenterY + CENTER_HEIGHT - btn:GetTall() - 20 )
|
||||
x = x + btn:GetWide() + 8
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
/*---------------------------------------------------------
|
||||
Paint
|
||||
---------------------------------------------------------*/
|
||||
function PANEL:Paint()
|
||||
|
||||
Derma_DrawBackgroundBlur( self, self.OpenTime )
|
||||
|
||||
local CenterY = ScrH() / 2.0
|
||||
local CenterX = ScrW() / 2.0
|
||||
|
||||
surface.SetDrawColor( 0, 0, 0, 200 );
|
||||
surface.DrawRect( 0, CenterY - CENTER_HEIGHT, ScrW(), CENTER_HEIGHT * 2 );
|
||||
surface.DrawRect( 0, CenterY - CENTER_HEIGHT - 4, ScrW(), 2 );
|
||||
surface.DrawRect( 0, CenterY + CENTER_HEIGHT + 2, ScrW(), 2 );
|
||||
|
||||
GAMEMODE:PaintSplashScreen( self:GetWide(), self:GetTall() )
|
||||
|
||||
end
|
||||
|
||||
vgui_Splash = vgui.RegisterTable( PANEL, "DPanel" )
|
||||
local TeamPanel = nil
|
||||
|
||||
function GM:ShowTeam()
|
||||
|
||||
if ( !IsValid( TeamPanel ) ) then
|
||||
|
||||
TeamPanel = vgui.CreateFromTable( vgui_Splash )
|
||||
TeamPanel:SetHeaderText( "Choose Team" )
|
||||
|
||||
local AllTeams = team.GetAllTeams()
|
||||
for ID, TeamInfo in SortedPairs ( AllTeams ) do
|
||||
|
||||
if ( ID != TEAM_CONNECTING && ID != TEAM_UNASSIGNED && ( ID != TEAM_SPECTATOR || GAMEMODE.AllowSpectating ) && team.Joinable(ID) ) then
|
||||
|
||||
if ( ID == TEAM_SPECTATOR ) then
|
||||
TeamPanel:AddSpacer( 10 )
|
||||
end
|
||||
|
||||
local strName = TeamInfo.Name
|
||||
local func = function() RunConsoleCommand( "changeteam", ID ) end
|
||||
|
||||
local btn = TeamPanel:AddSelectButton( strName, func )
|
||||
btn.m_colBackground = TeamInfo.Color
|
||||
btn.Think = function( self )
|
||||
self:SetText( Format( "%s (%i)", strName, team.NumPlayers( ID ) ))
|
||||
self:SetDisabled( GAMEMODE:TeamHasEnoughPlayers( ID ) )
|
||||
end
|
||||
|
||||
if ( IsValid( LocalPlayer() ) && LocalPlayer():Team() == ID ) then
|
||||
btn:SetDisabled( true )
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
if ( IsValid( LocalPlayer() ) &&
|
||||
|
||||
( LocalPlayer():Team() == TEAM_UNASSIGNED or
|
||||
LocalPlayer():Team() == TEAM_SPECTATOR or
|
||||
LocalPlayer():Team() == TEAM_HUNTERS or
|
||||
LocalPlayer():Team() == TEAM_PROPS ) ) then
|
||||
|
||||
TeamPanel:AddCancelButton()
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
TeamPanel:MakePopup()
|
||||
|
||||
end
|
|
@ -0,0 +1,107 @@
|
|||
|
||||
local PANEL = {}
|
||||
|
||||
/*---------------------------------------------------------
|
||||
Init
|
||||
---------------------------------------------------------*/
|
||||
function PANEL:Init()
|
||||
|
||||
self:SetText( "" )
|
||||
self.DoClick = function() RunConsoleCommand( "seensplash" ) self:Remove() end
|
||||
self:SetSkin( GAMEMODE.HudSkin )
|
||||
|
||||
self.lblGamemodeName = vgui.Create( "DLabel", self )
|
||||
self.lblGamemodeName:SetText( GAMEMODE.Name )
|
||||
self.lblGamemodeName:SetFont( "FRETTA_LARGE" )
|
||||
self.lblGamemodeName:SetColor( color_white )
|
||||
|
||||
self.lblGamemodeAuthor = vgui.Create( "DLabel", self )
|
||||
self.lblGamemodeAuthor:SetText( "by " .. GAMEMODE.Author )
|
||||
self.lblGamemodeAuthor:SetFont( "FRETTA_MEDIUM" )
|
||||
self.lblGamemodeAuthor:SetColor( color_white )
|
||||
|
||||
self.lblServerName = vgui.Create( "DLabel", self )
|
||||
self.lblServerName:SetText( GetHostName() )
|
||||
self.lblServerName:SetFont( "FRETTA_MEDIUM" )
|
||||
self.lblServerName:SetColor( color_white )
|
||||
|
||||
self.lblIP = vgui.Create( "DLabel", self )
|
||||
self.lblIP:SetText( "0.0.0.0" )
|
||||
self.lblIP:SetFont( "FRETTA_MEDIUM" )
|
||||
self.lblIP:SetColor( color_white )
|
||||
|
||||
|
||||
self:PerformLayout()
|
||||
|
||||
self.FadeInTime = RealTime()
|
||||
|
||||
end
|
||||
|
||||
/*---------------------------------------------------------
|
||||
PerformLayout
|
||||
---------------------------------------------------------*/
|
||||
function PANEL:PerformLayout()
|
||||
|
||||
self:SetSize( ScrW(), ScrH() )
|
||||
|
||||
local CenterY = ScrH() / 2.0
|
||||
|
||||
self.lblGamemodeName:SizeToContents()
|
||||
self.lblGamemodeName:SetPos( ScrW()/2 - self.lblGamemodeName:GetWide()/2, CenterY - 200 - self.lblGamemodeName:GetTall() - self.lblGamemodeAuthor:GetTall() )
|
||||
|
||||
self.lblGamemodeAuthor:SizeToContents()
|
||||
self.lblGamemodeAuthor:SetPos( ScrW()/2 - self.lblGamemodeAuthor:GetWide()/2, CenterY - 200 - self.lblGamemodeAuthor:GetTall() )
|
||||
|
||||
self.lblServerName:SizeToContents()
|
||||
self.lblServerName:SetPos( 100, CenterY + 200 )
|
||||
|
||||
--self.lblIP:SetText( GetConVarString( "ip" ) )
|
||||
self.lblIP:SetText( tostring(game.GetIPAddress()) )
|
||||
self.lblIP:SizeToContents()
|
||||
self.lblIP:SetPos( self:GetWide() - 100 - self.lblIP:GetWide(), CenterY + 200 )
|
||||
|
||||
end
|
||||
|
||||
/*---------------------------------------------------------
|
||||
Paint
|
||||
---------------------------------------------------------*/
|
||||
function PANEL:Paint()
|
||||
|
||||
Derma_DrawBackgroundBlur( self )
|
||||
|
||||
local Fade = RealTime() - self.FadeInTime
|
||||
if ( Fade < 3 ) then
|
||||
|
||||
Fade = 1- (Fade / 3);
|
||||
surface.SetDrawColor( 0,0, 0, Fade * 255 );
|
||||
surface.DrawRect( 0, 0, self:GetWide(), self:GetTall() );
|
||||
|
||||
end
|
||||
|
||||
|
||||
local CenterY = ScrH() / 2.0
|
||||
|
||||
surface.SetDrawColor( 0, 0, 0, 200 );
|
||||
surface.DrawRect( 0, 0, self:GetWide(), CenterY - 180 );
|
||||
|
||||
surface.DrawRect( 0, CenterY + 180, self:GetWide(), self:GetTall() - ( CenterY+ 180 ) );
|
||||
|
||||
GAMEMODE:PaintSplashScreen( self:GetWide(), self:GetTall() )
|
||||
|
||||
end
|
||||
|
||||
local vgui_Splash = vgui.RegisterTable( PANEL, "DButton" )
|
||||
|
||||
function GM:ShowSplash()
|
||||
|
||||
local pnl = vgui.CreateFromTable( vgui_Splash )
|
||||
pnl:MakePopup()
|
||||
|
||||
end
|
||||
|
||||
|
||||
function GM:PaintSplashScreen( w, h )
|
||||
|
||||
// Customised splashscreen render here ( The center bit! )
|
||||
|
||||
end
|
|
@ -0,0 +1,65 @@
|
|||
|
||||
local CLASS = {}
|
||||
|
||||
CLASS.DisplayName = "Default Class"
|
||||
CLASS.WalkSpeed = 400
|
||||
CLASS.CrouchedWalkSpeed = 0.2
|
||||
CLASS.RunSpeed = 600
|
||||
CLASS.DuckSpeed = 0.2
|
||||
CLASS.JumpPower = 200
|
||||
--CLASS.PlayerModel = "models/player.mdl"
|
||||
CLASS.PlayerModel = "models/player/combine_soldier.mdl"
|
||||
CLASS.DrawTeamRing = false
|
||||
CLASS.DrawViewModel = true
|
||||
CLASS.CanUseFlashlight = true
|
||||
CLASS.MaxHealth = 100
|
||||
CLASS.StartHealth = 100
|
||||
CLASS.StartArmor = 0
|
||||
CLASS.RespawnTime = 0 // 0 means use the default spawn time chosen by gamemode
|
||||
CLASS.DropWeaponOnDie = false
|
||||
CLASS.TeammateNoCollide = true
|
||||
CLASS.AvoidPlayers = true // Automatically avoid players that we're no colliding
|
||||
CLASS.Selectable = true // When false, this disables all the team checking
|
||||
CLASS.FullRotation = false // Allow the player's model to rotate upwards, etc etc
|
||||
|
||||
function CLASS:Loadout( pl )
|
||||
|
||||
pl:GiveAmmo( 255, "Pistol", true )
|
||||
|
||||
pl:Give( "weapon_pistol" )
|
||||
|
||||
end
|
||||
|
||||
function CLASS:OnSpawn( pl )
|
||||
end
|
||||
|
||||
function CLASS:OnDeath( pl, attacker, dmginfo )
|
||||
end
|
||||
|
||||
function CLASS:Think( pl )
|
||||
end
|
||||
|
||||
function CLASS:Move( pl, mv )
|
||||
end
|
||||
|
||||
function CLASS:OnKeyPress( pl, key )
|
||||
end
|
||||
|
||||
function CLASS:OnKeyRelease( pl, key )
|
||||
end
|
||||
|
||||
function CLASS:ShouldDrawLocalPlayer( pl )
|
||||
return false
|
||||
end
|
||||
|
||||
function CLASS:CalcView( ply, origin, angles, fov )
|
||||
end
|
||||
|
||||
player_class.Register( "Default", CLASS )
|
||||
|
||||
local CLASS = {}
|
||||
CLASS.DisplayName = "Spectator Class"
|
||||
CLASS.DrawTeamRing = false
|
||||
CLASS.PlayerModel = "models/player.mdl"
|
||||
|
||||
player_class.Register( "Spectator", CLASS )
|
|
@ -0,0 +1,706 @@
|
|||
/*
|
||||
init.lua - Server Component
|
||||
-----------------------------------------------------
|
||||
The entire server side bit of Fretta starts here.
|
||||
*/
|
||||
|
||||
util.AddNetworkString("PlayableGamemodes")
|
||||
util.AddNetworkString("fretta_teamchange")
|
||||
|
||||
AddCSLuaFile( "cl_init.lua" )
|
||||
AddCSLuaFile( "shared.lua" )
|
||||
AddCSLuaFile( 'skin.lua' )
|
||||
AddCSLuaFile( 'player_class.lua' )
|
||||
AddCSLuaFile( 'class_default.lua' )
|
||||
AddCSLuaFile( 'cl_splashscreen.lua' )
|
||||
AddCSLuaFile( 'cl_selectscreen.lua' )
|
||||
AddCSLuaFile( 'cl_gmchanger.lua' )
|
||||
AddCSLuaFile( 'cl_help.lua' )
|
||||
AddCSLuaFile( 'player_extension.lua' )
|
||||
AddCSLuaFile( 'vgui/vgui_hudlayout.lua' )
|
||||
AddCSLuaFile( 'vgui/vgui_hudelement.lua' )
|
||||
AddCSLuaFile( 'vgui/vgui_hudbase.lua' )
|
||||
AddCSLuaFile( 'vgui/vgui_hudcommon.lua' )
|
||||
AddCSLuaFile( 'vgui/vgui_gamenotice.lua' )
|
||||
AddCSLuaFile( 'vgui/vgui_scoreboard.lua' )
|
||||
AddCSLuaFile( 'vgui/vgui_scoreboard_team.lua' )
|
||||
AddCSLuaFile( 'vgui/vgui_scoreboard_small.lua' )
|
||||
AddCSLuaFile( 'cl_hud.lua' )
|
||||
AddCSLuaFile( 'cl_deathnotice.lua' )
|
||||
AddCSLuaFile( 'cl_scores.lua' )
|
||||
AddCSLuaFile( 'cl_notify.lua' )
|
||||
AddCSLuaFile( 'player_colours.lua' )
|
||||
|
||||
include( "shared.lua" )
|
||||
include( "sv_spectator.lua" )
|
||||
include( "round_controller.lua" )
|
||||
include( "utility.lua" )
|
||||
|
||||
GM.ReconnectedPlayers = {}
|
||||
|
||||
function GM:Initialize()
|
||||
|
||||
/*
|
||||
// Disabled - causes games to end in the middle of a round - we don't want that to happen!
|
||||
// ::Think takes care of this anyway.
|
||||
|
||||
if ( GAMEMODE.GameLength > 0 ) then
|
||||
timer.Simple( GAMEMODE.GameLength * 60, function() GAMEMODE:EndOfGame( true ) end )
|
||||
SetGlobalFloat( "GameEndTime", CurTime() + GAMEMODE.GameLength * 60 )
|
||||
end
|
||||
*/
|
||||
|
||||
// If we're round based, wait 3 seconds before the first round starts
|
||||
|
||||
--GAMEMODE:SetInRound( false ) --iguess?
|
||||
|
||||
if ( GAMEMODE.RoundBased ) then
|
||||
timer.Simple( 3, function() GAMEMODE:StartRoundBasedGame() end )
|
||||
end
|
||||
|
||||
if ( GAMEMODE.AutomaticTeamBalance ) then
|
||||
timer.Create( "CheckTeamBalance", 30, 0, function() GAMEMODE:CheckTeamBalance() end )
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
function GM:Think()
|
||||
|
||||
self.BaseClass:Think()
|
||||
|
||||
for k,v in pairs( player.GetAll() ) do
|
||||
|
||||
local Class = v:GetPlayerClass()
|
||||
if ( !Class ) then return end
|
||||
|
||||
v:CallClassFunction( "Think" )
|
||||
|
||||
end
|
||||
|
||||
// Game time related
|
||||
if( !GAMEMODE.IsEndOfGame && ( !GAMEMODE.RoundBased || ( GAMEMODE.RoundBased && GAMEMODE:CanEndRoundBasedGame() ) ) && CurTime() >= GAMEMODE.GetTimeLimit() ) then
|
||||
GAMEMODE:EndOfGame( true )
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
/*---------------------------------------------------------
|
||||
Name: gamemode:CanPlayerSuicide( Player ply )
|
||||
Desc: Is the player allowed to commit suicide?
|
||||
---------------------------------------------------------*/
|
||||
function GM:CanPlayerSuicide( ply )
|
||||
|
||||
if not GAMEMODE:InRound() then return false end
|
||||
|
||||
if( ply:Team() == TEAM_UNASSIGNED || ply:Team() == TEAM_SPECTATOR ) then
|
||||
return false // no suicide in spectator mode
|
||||
end
|
||||
|
||||
return !GAMEMODE.NoPlayerSuicide
|
||||
|
||||
end
|
||||
|
||||
/*---------------------------------------------------------
|
||||
Name: gamemode:PlayerSwitchFlashlight( Player ply, Bool on )
|
||||
Desc: Can we turn our flashlight on or off?
|
||||
---------------------------------------------------------*/
|
||||
function GM:PlayerSwitchFlashlight( ply, on )
|
||||
|
||||
if ( ply:Team() == TEAM_SPECTATOR || ply:Team() == TEAM_UNASSIGNED || ply:Team() == TEAM_CONNECTING ) then
|
||||
return not on
|
||||
end
|
||||
|
||||
return ply:CanUseFlashlight()
|
||||
|
||||
end
|
||||
|
||||
/*---------------------------------------------------------
|
||||
Name: gamemode:PlayerInitialSpawn( Player ply )
|
||||
Desc: Our very first spawn in the game.
|
||||
---------------------------------------------------------*/
|
||||
function GM:PlayerInitialSpawn( pl )
|
||||
|
||||
--pl:SetTeam( TEAM_UNASSIGNED )
|
||||
pl:SetTeam( TEAM_SPECTATOR )
|
||||
pl:SetPlayerClass( "Spectator" )
|
||||
pl.m_bFirstSpawn = true
|
||||
pl:UpdateNameColor()
|
||||
|
||||
GAMEMODE:CheckPlayerReconnected( pl )
|
||||
|
||||
end
|
||||
|
||||
function GM:CheckPlayerReconnected( pl )
|
||||
|
||||
if table.HasValue( GAMEMODE.ReconnectedPlayers, pl:UniqueID() ) then
|
||||
GAMEMODE:PlayerReconnected( pl )
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
/*---------------------------------------------------------
|
||||
Name: gamemode:PlayerReconnected( Player ply )
|
||||
Desc: Called if the player has appeared to have reconnected.
|
||||
---------------------------------------------------------*/
|
||||
function GM:PlayerReconnected( pl )
|
||||
|
||||
// Use this hook to do stuff when a player rejoins and has been in the server previously
|
||||
|
||||
end
|
||||
|
||||
function GM:PlayerDisconnected( pl )
|
||||
|
||||
table.insert( GAMEMODE.ReconnectedPlayers, pl:UniqueID() )
|
||||
|
||||
self.BaseClass:PlayerDisconnected( pl )
|
||||
|
||||
end
|
||||
|
||||
function GM:ShowHelp( pl )
|
||||
|
||||
pl:SendLua( "GAMEMODE:ShowHelp()" )
|
||||
|
||||
end
|
||||
|
||||
|
||||
function GM:PlayerSpawn( pl )
|
||||
|
||||
pl:UpdateNameColor()
|
||||
|
||||
// The player never spawns straight into the game in Fretta
|
||||
// They spawn as a spectator first (during the splash screen and team picking screens)
|
||||
if ( pl.m_bFirstSpawn ) then
|
||||
|
||||
pl.m_bFirstSpawn = nil
|
||||
|
||||
if ( pl:IsBot() ) then
|
||||
|
||||
GAMEMODE:AutoTeam( pl )
|
||||
|
||||
// The bot doesn't send back the 'seen splash' command, so fake it.
|
||||
if ( !GAMEMODE.TeamBased && !GAMEMODE.NoAutomaticSpawning ) then
|
||||
pl:Spawn()
|
||||
end
|
||||
|
||||
else
|
||||
|
||||
pl:StripWeapons()
|
||||
GAMEMODE:PlayerSpawnAsSpectator( pl )
|
||||
|
||||
// Follow a random player until we join a team
|
||||
--[[
|
||||
if ( #player.GetAll() > 1 ) then
|
||||
pl:Spectate( OBS_MODE_CHASE )
|
||||
pl:SpectateEntity( table.Random( player.GetAll() ) )
|
||||
end
|
||||
]]--
|
||||
|
||||
pl:Spectate( OBS_MODE_ROAMING )
|
||||
|
||||
end
|
||||
|
||||
return
|
||||
|
||||
end
|
||||
|
||||
pl:CheckPlayerClassOnSpawn()
|
||||
|
||||
if ( GAMEMODE.TeamBased && ( pl:Team() == TEAM_SPECTATOR || pl:Team() == TEAM_UNASSIGNED ) ) then
|
||||
|
||||
GAMEMODE:PlayerSpawnAsSpectator( pl )
|
||||
return
|
||||
|
||||
end
|
||||
|
||||
// Stop observer mode
|
||||
pl:UnSpectate()
|
||||
|
||||
// Call item loadout function
|
||||
hook.Call( "PlayerLoadout", GAMEMODE, pl )
|
||||
|
||||
// Set player model
|
||||
hook.Call( "PlayerSetModel", GAMEMODE, pl )
|
||||
|
||||
// Call class function
|
||||
pl:OnSpawn()
|
||||
|
||||
end
|
||||
|
||||
|
||||
function GM:PlayerLoadout( pl )
|
||||
|
||||
pl:CheckPlayerClassOnSpawn()
|
||||
|
||||
pl:OnLoadout()
|
||||
|
||||
// Switch to prefered weapon if they have it
|
||||
local cl_defaultweapon = pl:GetInfo( "cl_defaultweapon" )
|
||||
|
||||
if ( pl:HasWeapon( cl_defaultweapon ) ) then
|
||||
pl:SelectWeapon( cl_defaultweapon )
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
function GM:PlayerSetModel( pl )
|
||||
|
||||
pl:OnPlayerModel()
|
||||
|
||||
end
|
||||
|
||||
|
||||
function GM:AutoTeam( pl )
|
||||
|
||||
if ( !GAMEMODE.AllowAutoTeam ) then return end
|
||||
if ( !GAMEMODE.TeamBased ) then return end
|
||||
|
||||
GAMEMODE:PlayerRequestTeam( pl, team.BestAutoJoinTeam() )
|
||||
|
||||
end
|
||||
|
||||
concommand.Add( "autoteam", function( pl, cmd, args ) hook.Call( "AutoTeam", GAMEMODE, pl ) end )
|
||||
|
||||
|
||||
function GM:PlayerRequestClass( ply, class, disablemessage )
|
||||
|
||||
local Classes = team.GetClass( ply:Team() )
|
||||
if (!Classes) then return end
|
||||
|
||||
local RequestedClass = Classes[ class ]
|
||||
if (!RequestedClass) then return end
|
||||
|
||||
if ( ply:Alive() && SERVER ) then
|
||||
|
||||
if ( ply.m_SpawnAsClass && ply.m_SpawnAsClass == RequestedClass ) then return end
|
||||
|
||||
ply.m_SpawnAsClass = RequestedClass
|
||||
|
||||
if ( !disablemessage ) then
|
||||
ply:ChatPrint( "Your class will change to '".. player_class.GetClassName( RequestedClass ) .. "' when you respawn" )
|
||||
end
|
||||
|
||||
else
|
||||
self:PlayerJoinClass( ply, RequestedClass )
|
||||
ply.m_SpawnAsClass = nil
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
concommand.Add( "changeclass", function( pl, cmd, args ) hook.Call( "PlayerRequestClass", GAMEMODE, pl, tonumber(args[1]) ) end )
|
||||
|
||||
|
||||
local function SeenSplash( ply )
|
||||
|
||||
if ( ply.m_bSeenSplashScreen ) then return end
|
||||
ply.m_bSeenSplashScreen = true
|
||||
|
||||
if ( !GAMEMODE.TeamBased && !GAMEMODE.NoAutomaticSpawning ) then
|
||||
ply:KillSilent()
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
concommand.Add( "seensplash", SeenSplash )
|
||||
|
||||
|
||||
function GM:PlayerJoinTeam( ply, teamid )
|
||||
|
||||
local iOldTeam = ply:Team()
|
||||
|
||||
if ( ply:Alive() ) then
|
||||
if ( iOldTeam == TEAM_SPECTATOR || (iOldTeam == TEAM_UNASSIGNED && GAMEMODE.TeamBased) ) then
|
||||
ply:KillSilent()
|
||||
else
|
||||
ply:Kill()
|
||||
end
|
||||
end
|
||||
|
||||
ply:SetTeam( teamid )
|
||||
ply.LastTeamSwitch = RealTime()
|
||||
|
||||
local Classes = team.GetClass( teamid )
|
||||
|
||||
|
||||
// Needs to choose class
|
||||
if ( Classes && #Classes > 1 ) then
|
||||
|
||||
if ( ply:IsBot() || !GAMEMODE.SelectClass ) then
|
||||
|
||||
GAMEMODE:PlayerRequestClass( ply, math.random( 1, #Classes ) )
|
||||
|
||||
else
|
||||
|
||||
ply.m_fnCallAfterClassChoose = function()
|
||||
ply.DeathTime = CurTime()
|
||||
GAMEMODE:OnPlayerChangedTeam( ply, iOldTeam, teamid )
|
||||
ply:EnableRespawn()
|
||||
end
|
||||
|
||||
ply:SendLua( "GAMEMODE:ShowClassChooser( ".. teamid .." )" )
|
||||
ply:DisableRespawn()
|
||||
ply:SetRandomClass() // put the player in a VALID class in case they don't choose and get spawned
|
||||
return
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
// No class, use default
|
||||
if ( !Classes || #Classes == 0 ) then
|
||||
ply:SetPlayerClass( "Default" )
|
||||
end
|
||||
|
||||
// Only one class, use that
|
||||
if ( Classes && #Classes == 1 ) then
|
||||
GAMEMODE:PlayerRequestClass( ply, 1 )
|
||||
end
|
||||
|
||||
gamemode.Call("OnPlayerChangedTeam", ply, iOldTeam, teamid )
|
||||
|
||||
end
|
||||
|
||||
function GM:PlayerJoinClass( ply, classname )
|
||||
|
||||
ply.m_SpawnAsClass = nil
|
||||
ply:SetPlayerClass( classname )
|
||||
|
||||
if ( ply.m_fnCallAfterClassChoose ) then
|
||||
|
||||
ply.m_fnCallAfterClassChoose()
|
||||
ply.m_fnCallAfterClassChoose = nil
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
function GM:OnPlayerChangedTeam( ply, oldteam, newteam )
|
||||
|
||||
// Here's an immediate respawn thing by default. If you want to
|
||||
// re-create something more like CS or some shit you could probably
|
||||
// change to a spectator or something while dead.
|
||||
if ( newteam == TEAM_SPECTATOR ) then
|
||||
|
||||
// If we changed to spectator mode, respawn where we are
|
||||
local Pos = ply:EyePos()
|
||||
ply:Spawn()
|
||||
ply:SetPos( Pos )
|
||||
|
||||
elseif ( oldteam == TEAM_SPECTATOR ) then
|
||||
|
||||
// If we're changing from spectator, join the game
|
||||
if ( !GAMEMODE.NoAutomaticSpawning ) then
|
||||
ply:Spawn()
|
||||
end
|
||||
|
||||
elseif ( oldteam ~= TEAM_SPECTATOR ) then
|
||||
|
||||
ply.LastTeamChange = CurTime()
|
||||
|
||||
else
|
||||
|
||||
// If we're straight up changing teams just hang
|
||||
// around until we're ready to respawn onto the
|
||||
// team that we chose
|
||||
|
||||
end
|
||||
|
||||
//PrintMessage( HUD_PRINTTALK, Format( "%s joined '%s'", ply:Nick(), team.GetName( newteam ) ) )
|
||||
|
||||
// Send net for team change
|
||||
|
||||
net.Start("fretta_teamchange")
|
||||
net.WriteEntity(ply)
|
||||
net.WriteInt(oldteam, 12)
|
||||
net.WriteInt(newteam, 12)
|
||||
net.Broadcast()
|
||||
|
||||
end
|
||||
|
||||
function GM:CheckTeamBalance()
|
||||
|
||||
local highest
|
||||
|
||||
for id, tm in pairs( team.GetAllTeams() ) do
|
||||
if ( id > 0 && id < 1000 && team.Joinable( id ) ) then
|
||||
if ( !highest || team.NumPlayers( id ) > team.NumPlayers( highest ) ) then
|
||||
|
||||
highest = id
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if not highest then return end
|
||||
|
||||
for id, tm in pairs( team.GetAllTeams() ) do
|
||||
if ( id ~= highest and id > 0 && id < 1000 && team.Joinable( id ) ) then
|
||||
if team.NumPlayers( id ) < team.NumPlayers( highest ) then
|
||||
while team.NumPlayers( id ) < team.NumPlayers( highest ) - 1 do
|
||||
|
||||
local ply = GAMEMODE:FindLeastCommittedPlayerOnTeam( highest )
|
||||
|
||||
ply:Kill()
|
||||
ply:SetTeam( id )
|
||||
|
||||
// Todo: Notify player 'you have been swapped'
|
||||
// This is a placeholder
|
||||
PrintMessage(HUD_PRINTTALK, ply:Name().." has been changed to "..team.GetName( id ).." for team balance." )
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
function GM:FindLeastCommittedPlayerOnTeam( teamid )
|
||||
|
||||
local worst
|
||||
local worstteamswapper
|
||||
|
||||
for k,v in pairs( team.GetPlayers( teamid ) ) do
|
||||
|
||||
if ( v.LastTeamChange && CurTime() < v.LastTeamChange + 180 && (!worstteamswapper || worstteamswapper.LastTeamChange < v.LastTeamChange) ) then
|
||||
worstteamswapper = v
|
||||
end
|
||||
|
||||
if ( !worst || v:Frags() < worst:Frags() ) then
|
||||
worst = v
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
if worstteamswapper then
|
||||
return worstteamswapper
|
||||
end
|
||||
|
||||
return worst
|
||||
|
||||
end
|
||||
|
||||
function GM:OnEndOfGame(bGamemodeVote)
|
||||
|
||||
for k,v in pairs( player.GetAll() ) do
|
||||
|
||||
v:Freeze(true)
|
||||
v:ConCommand( "+showscores" )
|
||||
timer.Simple(GAMEMODE.VotingDelay, function()
|
||||
if (IsValid(v)) then
|
||||
v:ConCommand("-showscores")
|
||||
end
|
||||
end)
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
// Override OnEndOfGame to do any other stuff. like winning music.
|
||||
function GM:EndOfGame( bGamemodeVote )
|
||||
|
||||
if GAMEMODE.IsEndOfGame then return end
|
||||
|
||||
GAMEMODE.IsEndOfGame = true
|
||||
SetGlobalBool( "IsEndOfGame", true );
|
||||
|
||||
gamemode.Call("OnEndOfGame", bGamemodeVote);
|
||||
|
||||
if ( bGamemodeVote ) then
|
||||
|
||||
MsgN( "Starting gamemode voting..." )
|
||||
PrintMessage( HUD_PRINTTALK, "Starting gamemode voting..." );
|
||||
timer.Simple( GAMEMODE.VotingDelay, function() MapVote.Start() end )
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
function GM:GetWinningFraction()
|
||||
if ( !GAMEMODE.GMVoteResults ) then return end
|
||||
return GAMEMODE.GMVoteResults.Fraction
|
||||
end
|
||||
|
||||
function GM:PlayerShouldTakeDamage( ply, attacker )
|
||||
|
||||
if ( GAMEMODE.NoPlayerSelfDamage && IsValid( attacker ) && ply == attacker ) then return false end
|
||||
if ( GAMEMODE.NoPlayerDamage ) then return false end
|
||||
|
||||
if ( GAMEMODE.NoPlayerTeamDamage && IsValid( attacker ) ) then
|
||||
if ( attacker.Team && ply:Team() == attacker:Team() && ply != attacker ) then return false end
|
||||
end
|
||||
|
||||
if ( IsValid( attacker ) && attacker:IsPlayer() && GAMEMODE.NoPlayerPlayerDamage ) then return false end
|
||||
if ( IsValid( attacker ) && !attacker:IsPlayer() && GAMEMODE.NoNonPlayerPlayerDamage ) then return false end
|
||||
|
||||
return true
|
||||
|
||||
end
|
||||
|
||||
|
||||
function GM:PlayerDeathThink( pl )
|
||||
|
||||
pl.DeathTime = pl.DeathTime or CurTime()
|
||||
local timeDead = CurTime() - pl.DeathTime
|
||||
|
||||
// If we're in deathcam mode, promote to a generic spectator mode
|
||||
if ( GAMEMODE.DeathLingerTime > 0 && timeDead > GAMEMODE.DeathLingerTime && ( pl:GetObserverMode() == OBS_MODE_FREEZECAM || pl:GetObserverMode() == OBS_MODE_DEATHCAM ) ) then
|
||||
GAMEMODE:BecomeObserver( pl )
|
||||
end
|
||||
|
||||
// If we're in a round based game, player NEVER spawns in death think
|
||||
if ( GAMEMODE.NoAutomaticSpawning ) then return end
|
||||
|
||||
// The gamemode is holding the player from respawning.
|
||||
// Probably because they have to choose a class..
|
||||
if ( !pl:CanRespawn() ) then return end
|
||||
|
||||
// Don't respawn yet - wait for minimum time...
|
||||
if ( GAMEMODE.MinimumDeathLength ) then
|
||||
|
||||
pl:SetNWFloat( "RespawnTime", pl.DeathTime + GAMEMODE.MinimumDeathLength )
|
||||
|
||||
if ( timeDead < pl:GetRespawnTime() ) then
|
||||
return
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
// Force respawn
|
||||
if ( pl:GetRespawnTime() != 0 && GAMEMODE.MaximumDeathLength != 0 && timeDead > GAMEMODE.MaximumDeathLength ) then
|
||||
pl:Spawn()
|
||||
return
|
||||
end
|
||||
|
||||
// We're between min and max death length, player can press a key to spawn.
|
||||
if ( pl:KeyPressed( IN_ATTACK ) || pl:KeyPressed( IN_ATTACK2 ) || pl:KeyPressed( IN_JUMP ) ) then
|
||||
pl:Spawn()
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
function GM:GetFallDamage( ply, flFallSpeed )
|
||||
|
||||
if not GAMEMODE:InRound() then return 0 end
|
||||
|
||||
if ( GAMEMODE.RealisticFallDamage ) then
|
||||
return flFallSpeed / 8
|
||||
end
|
||||
|
||||
return 10
|
||||
|
||||
end
|
||||
|
||||
function GM:PostPlayerDeath( ply )
|
||||
|
||||
// Note, this gets called AFTER DoPlayerDeath.. AND it gets called
|
||||
// for KillSilent too. So if Freezecam isn't set by DoPlayerDeath, we
|
||||
// pick up the slack by setting DEATHCAM here.
|
||||
|
||||
if ( ply:GetObserverMode() == OBS_MODE_NONE ) then
|
||||
ply:Spectate( OBS_MODE_DEATHCAM )
|
||||
end
|
||||
|
||||
ply:OnDeath()
|
||||
|
||||
end
|
||||
|
||||
function GM:DoPlayerDeath( ply, attacker, dmginfo )
|
||||
|
||||
ply:CallClassFunction( "OnDeath", attacker, dmginfo )
|
||||
ply:CreateRagdoll()
|
||||
ply:AddDeaths( 1 )
|
||||
|
||||
if ( attacker:IsValid() && attacker:IsPlayer() ) then
|
||||
|
||||
if ( attacker == ply ) then
|
||||
|
||||
if ( GAMEMODE.TakeFragOnSuicide ) then
|
||||
|
||||
attacker:AddFrags( -1 )
|
||||
|
||||
if ( GAMEMODE.TeamBased && GAMEMODE.AddFragsToTeamScore ) then
|
||||
team.AddScore( attacker:Team(), -1 )
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
else
|
||||
|
||||
attacker:AddFrags( 1 )
|
||||
|
||||
if ( GAMEMODE.TeamBased && GAMEMODE.AddFragsToTeamScore ) then
|
||||
team.AddScore( attacker:Team(), 1 )
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
if ( GAMEMODE.EnableFreezeCam && IsValid( attacker ) && attacker != ply ) then
|
||||
|
||||
ply:SpectateEntity( attacker )
|
||||
ply:Spectate( OBS_MODE_FREEZECAM )
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
function GM:StartSpectating( ply )
|
||||
|
||||
if ( !GAMEMODE:PlayerCanJoinTeam( ply ) ) then return end
|
||||
|
||||
ply:StripWeapons();
|
||||
GAMEMODE:PlayerJoinTeam( ply, TEAM_SPECTATOR )
|
||||
GAMEMODE:BecomeObserver( ply )
|
||||
|
||||
end
|
||||
|
||||
|
||||
function GM:EndSpectating( ply )
|
||||
|
||||
if ( !GAMEMODE:PlayerCanJoinTeam( ply ) ) then return end
|
||||
|
||||
GAMEMODE:PlayerJoinTeam( ply, TEAM_UNASSIGNED )
|
||||
|
||||
ply:KillSilent()
|
||||
|
||||
end
|
||||
|
||||
/*---------------------------------------------------------
|
||||
Name: gamemode:PlayerRequestTeam()
|
||||
Player wants to change team
|
||||
---------------------------------------------------------*/
|
||||
function GM:PlayerRequestTeam( ply, teamid )
|
||||
|
||||
if ( !GAMEMODE.TeamBased && GAMEMODE.AllowSpectating ) then
|
||||
|
||||
if ( teamid == TEAM_SPECTATOR ) then
|
||||
GAMEMODE:StartSpectating( ply )
|
||||
else
|
||||
GAMEMODE:EndSpectating( ply )
|
||||
end
|
||||
|
||||
return
|
||||
|
||||
end
|
||||
|
||||
return self.BaseClass:PlayerRequestTeam( ply, teamid )
|
||||
|
||||
end
|
||||
|
||||
local function TimeLeft( ply )
|
||||
|
||||
local tl = GAMEMODE:GetGameTimeLeft()
|
||||
if ( tl == -1 ) then return end
|
||||
|
||||
local Time = util.ToMinutesSeconds( tl )
|
||||
|
||||
if ( IsValid( ply ) ) then
|
||||
ply:PrintMessage( HUD_PRINTCONSOLE, Time )
|
||||
else
|
||||
MsgN( Time )
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
concommand.Add( "timeleft", TimeLeft )
|
|
@ -0,0 +1,43 @@
|
|||
|
||||
module( "player_class", package.seeall )
|
||||
|
||||
local ClassTables = {}
|
||||
|
||||
|
||||
|
||||
function Register( name, classtable )
|
||||
ClassTables[ name ] = classtable
|
||||
ClassTables[ name ].m_HasBeenSetup = false
|
||||
end
|
||||
|
||||
function Get( name )
|
||||
|
||||
if ( !ClassTables[ name ] ) then return {} end
|
||||
|
||||
// Derive class here.
|
||||
// I have favoured using table.Inherit over using a meta table
|
||||
// This is to the performance hit is once, now, rather than on every usage
|
||||
if ( !ClassTables[ name ].m_HasBeenSetup ) then
|
||||
|
||||
ClassTables[ name ].m_HasBeenSetup = true
|
||||
|
||||
local Base = ClassTables[ name ].Base
|
||||
if ( ClassTables[ name ].Base && Get( Base ) ) then
|
||||
ClassTables[ name ] = table.Inherit( ClassTables[ name ], Get( Base ) )
|
||||
ClassTables[ name ].BaseClass = Get( Base )
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
return ClassTables[ name ]
|
||||
end
|
||||
|
||||
|
||||
function GetClassName( name )
|
||||
|
||||
local class = Get( name )
|
||||
if (!class) then return name end
|
||||
|
||||
return class.DisplayName
|
||||
|
||||
end
|
|
@ -0,0 +1,16 @@
|
|||
|
||||
|
||||
list.Set( "PlayerColours", "red", Color( 255, 0, 0 ) )
|
||||
list.Set( "PlayerColours", "yellow", Color( 255, 255, 0 ) )
|
||||
list.Set( "PlayerColours", "green", Color( 43, 235, 79 ) )
|
||||
list.Set( "PlayerColours", "blue", Color( 43, 158, 255 ) )
|
||||
list.Set( "PlayerColours", "orange", Color( 255, 148, 39 ) )
|
||||
list.Set( "PlayerColours", "pink", Color( 255, 148, 255 ) )
|
||||
list.Set( "PlayerColours", "lilac", Color( 120, 133, 255 ) )
|
||||
list.Set( "PlayerColours", "army", Color( 120, 158, 18 ) )
|
||||
list.Set( "PlayerColours", "grey", Color( 200, 200, 200 ) )
|
||||
|
||||
if ( CLIENT ) then
|
||||
CreateClientConVar( "cl_playercolor", "", true, true )
|
||||
end
|
||||
|
|
@ -0,0 +1,218 @@
|
|||
|
||||
local meta = FindMetaTable( "Player" )
|
||||
if (!meta) then return end
|
||||
|
||||
function meta:SetPlayerClass( strName )
|
||||
|
||||
self:SetNWString( "Class", strName )
|
||||
|
||||
local c = player_class.Get( strName )
|
||||
if ( !c ) then
|
||||
MsgN( "Warning: Player joined undefined class (", strName, ")" )
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
function meta:GetPlayerClassName()
|
||||
|
||||
return self:GetNWString( "Class", "Default" )
|
||||
|
||||
end
|
||||
|
||||
|
||||
function meta:GetPlayerClass()
|
||||
|
||||
// Class that has been set using SetClass
|
||||
local ClassName = self:GetPlayerClassName()
|
||||
local c = player_class.Get( ClassName )
|
||||
if ( c ) then return c end
|
||||
|
||||
// Class based on their Team
|
||||
local c = player_class.Get( self:Team() )
|
||||
if ( c ) then return c end
|
||||
|
||||
// If all else fails, use the default
|
||||
local c = player_class.Get( "Default" )
|
||||
if ( c ) then return c end
|
||||
|
||||
end
|
||||
|
||||
function meta:SetRandomClass()
|
||||
|
||||
local Classes = team.GetClass( self:Team() )
|
||||
if ( Classes ) then
|
||||
local Class = table.Random( Classes )
|
||||
self:SetPlayerClass( Class )
|
||||
return
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
function meta:CheckPlayerClassOnSpawn()
|
||||
|
||||
local Classes = team.GetClass( self:Team() )
|
||||
|
||||
// The player has requested to spawn as a new class
|
||||
|
||||
if ( self.m_SpawnAsClass ) then
|
||||
|
||||
self:SetPlayerClass( self.m_SpawnAsClass )
|
||||
self.m_SpawnAsClass = nil
|
||||
|
||||
end
|
||||
|
||||
// Make sure the player isn't using the wrong class
|
||||
|
||||
if ( Classes && #Classes > 0 && !table.HasValue( Classes, self:GetPlayerClassName() ) ) then
|
||||
self:SetRandomClass()
|
||||
end
|
||||
|
||||
// If the player is on a team with only one class,
|
||||
// make sure we're that one when we spawn.
|
||||
|
||||
if ( Classes && #Classes == 1 ) then
|
||||
self:SetPlayerClass( Classes[1] )
|
||||
end
|
||||
|
||||
// No defined classes, use default class
|
||||
|
||||
if ( !Classes || #Classes == 0 ) then
|
||||
self:SetPlayerClass( "Default" )
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
function meta:OnSpawn()
|
||||
|
||||
local Class = self:GetPlayerClass()
|
||||
if ( !Class ) then return end
|
||||
|
||||
if ( Class.DuckSpeed ) then self:SetDuckSpeed( Class.DuckSpeed ) end
|
||||
if ( Class.WalkSpeed ) then self:SetWalkSpeed( Class.WalkSpeed ) end
|
||||
if ( Class.RunSpeed ) then self:SetRunSpeed( Class.RunSpeed ) end
|
||||
if ( Class.CrouchedWalkSpeed ) then self:SetCrouchedWalkSpeed( Class.CrouchedWalkSpeed ) end
|
||||
if ( Class.JumpPower ) then self:SetJumpPower( Class.JumpPower ) end
|
||||
if ( Class.DrawTeamRing ) then self:SetNWBool( "DrawRing", true ) else self:SetNWBool( "DrawRing", false ) end
|
||||
if ( Class.DrawViewModel == false ) then self:DrawViewModel( false ) else self:DrawViewModel( true ) end
|
||||
if ( Class.CanUseFlashlight != nil ) then self:AllowFlashlight( Class.CanUseFlashlight ) end
|
||||
if ( Class.StartHealth ) then self:SetHealth( Class.StartHealth ) end
|
||||
if ( Class.MaxHealth ) then self:SetMaxHealth( Class.MaxHealth ) end
|
||||
if ( Class.StartArmor ) then self:SetArmor( Class.StartArmor ) end
|
||||
if ( Class.RespawnTime ) then self:SetRespawnTime( Class.RespawnTime ) end
|
||||
if ( Class.DropWeaponOnDie != nil ) then self:ShouldDropWeapon( Class.DropWeaponOnDie ) end
|
||||
if ( Class.TeammateNoCollide != nil ) then self:SetNoCollideWithTeammates( Class.TeammateNoCollide ) end
|
||||
if ( Class.AvoidPlayers != nil ) then self:SetAvoidPlayers( Class.AvoidPlayers ) end
|
||||
if ( Class.FullRotation != nil ) then self:SetAllowFullRotation( Class.FullRotation ) end
|
||||
|
||||
self:CallClassFunction( "OnSpawn" )
|
||||
|
||||
end
|
||||
|
||||
function meta:CallClassFunction( name, ... )
|
||||
|
||||
local Class = self:GetPlayerClass()
|
||||
if ( !Class ) then return end
|
||||
if ( !Class[name] ) then return end
|
||||
|
||||
//print( "Class Function: ", self:GetPlayerClassName(), name )
|
||||
|
||||
return Class[name]( Class, self, ... )
|
||||
|
||||
end
|
||||
|
||||
function meta:OnLoadout()
|
||||
|
||||
self:CallClassFunction( "Loadout" )
|
||||
|
||||
end
|
||||
|
||||
function meta:OnDeath()
|
||||
|
||||
end
|
||||
|
||||
function meta:OnPlayerModel()
|
||||
|
||||
// If the class forces a player model, use that..
|
||||
// If not, use our preferred model..
|
||||
|
||||
local Class = self:GetPlayerClass()
|
||||
if ( Class && Class.PlayerModel ) then
|
||||
|
||||
local mdl = Class.PlayerModel
|
||||
if( type( mdl ) == "table" ) then // table of models, set random
|
||||
mdl = table.Random( Class.PlayerModel );
|
||||
end
|
||||
|
||||
util.PrecacheModel( mdl );
|
||||
self:SetModel( mdl );
|
||||
return
|
||||
|
||||
end
|
||||
|
||||
local cl_playermodel = self:GetInfo( "cl_playermodel" )
|
||||
local modelname = player_manager.TranslatePlayerModel( cl_playermodel )
|
||||
util.PrecacheModel( modelname )
|
||||
self:SetModel( modelname )
|
||||
|
||||
end
|
||||
|
||||
function meta:AllowFlashlight( bAble )
|
||||
|
||||
self.m_bFlashlight = bAble
|
||||
|
||||
end
|
||||
|
||||
function meta:CanUseFlashlight()
|
||||
|
||||
if self.m_bFlashlight == nil then
|
||||
return true // Default to true unless modified by the player class
|
||||
end
|
||||
|
||||
return self.m_bFlashlight
|
||||
|
||||
end
|
||||
|
||||
function meta:SetRespawnTime( num )
|
||||
|
||||
self.m_iSpawnTime = num
|
||||
|
||||
end
|
||||
|
||||
function meta:GetRespawnTime( num )
|
||||
|
||||
if ( self.m_iSpawnTime == 0 || !self.m_iSpawnTime ) then
|
||||
return GAMEMODE.MinimumDeathLength
|
||||
end
|
||||
return self.m_iSpawnTime
|
||||
|
||||
end
|
||||
|
||||
function meta:DisableRespawn( strReason )
|
||||
|
||||
self.m_bCanRespawn = false
|
||||
|
||||
end
|
||||
|
||||
function meta:EnableRespawn()
|
||||
|
||||
self.m_bCanRespawn = true
|
||||
|
||||
end
|
||||
|
||||
function meta:CanRespawn()
|
||||
|
||||
return self.m_bCanRespawn == nil || self.m_bCanRespawn == true
|
||||
|
||||
end
|
||||
|
||||
function meta:IsObserver()
|
||||
return ( self:GetObserverMode() > OBS_MODE_NONE );
|
||||
end
|
||||
|
||||
function meta:UpdateNameColor()
|
||||
|
||||
if ( GAMEMODE.SelectColor ) then
|
||||
self:SetNWString( "NameColor", self:GetInfo( "cl_playercolor" ) )
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,408 @@
|
|||
|
||||
function GM:SetRoundWinner( ply, resulttext ) SetGlobalEntity( "RoundWinner", ply ) SetGlobalString( "RRText", tostring(resulttext) ) end
|
||||
function GM:SetRoundResult( i, resulttext ) SetGlobalInt( "RoundResult", i ) SetGlobalString( "RRText", tostring(resulttext) ) end
|
||||
function GM:ClearRoundResult() SetGlobalEntity( "RoundWinner", NULL ) SetGlobalInt( "RoundResult", 0 ) SetGlobalString( "RRText", "" ) end
|
||||
function GM:SetInRound( b ) SetGlobalBool( "InRound", b ) end
|
||||
function GM:InRound() return GetGlobalBool( "InRound", false ) end
|
||||
|
||||
--//moved to prop hunt's init.lua
|
||||
-- fretta_waitforplayers = CreateConVar( "fretta_waitforplayers", "1", { FCVAR_ARCHIVE } )
|
||||
|
||||
function GM:OnRoundStart( num )
|
||||
|
||||
UTIL_UnFreezeAllPlayers()
|
||||
|
||||
hook.Call("PH_OnRoundStart", nil, num)
|
||||
|
||||
end
|
||||
|
||||
--local bAlreadyStarted = false
|
||||
--[[moved to prop hunt's init.lua
|
||||
function GM:OnRoundEnd( num )
|
||||
|
||||
// Check if fretta_waitforplayers is true
|
||||
// This is a fast implementation for a waiting system
|
||||
// Make optimisations if needed
|
||||
if ( fretta_waitforplayers:GetBool() ) then
|
||||
|
||||
// Take away a round number quickly before it adds another when there are not enough players
|
||||
// Set to false
|
||||
if ( ( team.NumPlayers( TEAM_HUNTERS ) < 1 ) || ( team.NumPlayers( TEAM_PROPS ) < 1 ) ) then
|
||||
|
||||
bAlreadyStarted = false
|
||||
|
||||
end
|
||||
|
||||
// Check if the round was already started before so we count it as a fully played round
|
||||
if ( !bAlreadyStarted ) then
|
||||
|
||||
SetGlobalInt( "RoundNumber", GetGlobalInt( "RoundNumber" )-1 )
|
||||
|
||||
end
|
||||
|
||||
// Set to true
|
||||
if ( ( team.NumPlayers( TEAM_HUNTERS ) >= 1 ) && ( team.NumPlayers( TEAM_PROPS ) >= 1 ) ) then
|
||||
|
||||
bAlreadyStarted = true
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
]]--
|
||||
function GM:OnRoundEnd(num)
|
||||
end
|
||||
|
||||
function GM:OnRoundResult( result, resulttext )
|
||||
|
||||
// The fact that result might not be a team
|
||||
// shouldn't matter when calling this..
|
||||
team.AddScore( result, 1 )
|
||||
|
||||
end
|
||||
|
||||
function GM:OnRoundWinner( ply, resulttext )
|
||||
|
||||
// Do whatever you want to do with the winner here (this is only called in Free For All gamemodes)...
|
||||
ply:AddFrags( 1 )
|
||||
|
||||
end
|
||||
|
||||
function GM:OnPreRoundStart( num )
|
||||
|
||||
game.CleanUpMap()
|
||||
|
||||
UTIL_StripAllPlayers()
|
||||
UTIL_SpawnAllPlayers()
|
||||
UTIL_FreezeAllPlayers()
|
||||
|
||||
end
|
||||
|
||||
function GM:CanStartRound( iNum )
|
||||
return true
|
||||
end
|
||||
|
||||
function GM:StartRoundBasedGame()
|
||||
|
||||
GAMEMODE:PreRoundStart( 1 )
|
||||
|
||||
end
|
||||
|
||||
// Number of rounds
|
||||
function GM:GetRoundLimit()
|
||||
return GAMEMODE.RoundLimit;
|
||||
end
|
||||
|
||||
// Has the round limit been reached?
|
||||
function GM:HasReachedRoundLimit( iNum )
|
||||
|
||||
local iRoundLimit = GAMEMODE:GetRoundLimit();
|
||||
|
||||
if( iRoundLimit > 0 && iNum > iRoundLimit ) then
|
||||
--MapVote.Start()
|
||||
return true
|
||||
end
|
||||
|
||||
return false
|
||||
|
||||
end
|
||||
|
||||
// This is for the timer-based game end. set this to return true if you want it to end mid-round
|
||||
function GM:CanEndRoundBasedGame()
|
||||
return false
|
||||
end
|
||||
|
||||
// You can add round time by calling this (takes time in seconds)
|
||||
function GM:AddRoundTime( iAddedTime )
|
||||
|
||||
if( !GAMEMODE:InRound() ) then // don't add time if round is not in progress
|
||||
return
|
||||
end
|
||||
|
||||
SetGlobalFloat( "RoundEndTime", GetGlobalFloat( "RoundEndTime", CurTime() ) + iAddedTime );
|
||||
timer.Adjust( "RoundEndTimer", GetGlobalFloat( "RoundEndTime" ) - GetGlobalFloat( "RoundStartTime" ), 0, function() GAMEMODE:RoundTimerEnd() end );
|
||||
|
||||
local rf = RecipientFilter()
|
||||
rf:AddAllPlayers()
|
||||
|
||||
umsg.Start( "RoundAddedTime", rf ); // send a umsg so you can do something with the HUD
|
||||
umsg.Float( iAddedTime ); // time added
|
||||
umsg.End();
|
||||
|
||||
end
|
||||
|
||||
// This gets the timer for a round (you can make round number dependant round lengths, or make it cvar controlled)
|
||||
function GM:GetRoundTime( iRoundNumber )
|
||||
return GAMEMODE.RoundLength;
|
||||
end
|
||||
|
||||
//
|
||||
// Internal, override OnPreRoundStart if you want to do stuff here
|
||||
//
|
||||
function GM:PreRoundStart( iNum )
|
||||
|
||||
// Should the game end?
|
||||
if( CurTime() >= GAMEMODE.GetTimeLimit() || GAMEMODE:HasReachedRoundLimit( iNum ) ) then
|
||||
GAMEMODE:EndOfGame( true );
|
||||
return;
|
||||
end
|
||||
|
||||
if ( !GAMEMODE:CanStartRound( iNum ) ) then
|
||||
|
||||
timer.Simple( 1, function() GAMEMODE:PreRoundStart( iNum ) end ) // In a second, check to see if we can start
|
||||
return;
|
||||
|
||||
end
|
||||
|
||||
timer.Create( "RoundStartTimer", GAMEMODE.RoundPreStartTime, 1, function() GAMEMODE:RoundStart() end )
|
||||
SetGlobalInt( "RoundNumber", iNum )
|
||||
SetGlobalFloat( "RoundStartTime", CurTime() + GAMEMODE.RoundPreStartTime )
|
||||
|
||||
GAMEMODE:ClearRoundResult()
|
||||
GAMEMODE:OnPreRoundStart( GetGlobalInt( "RoundNumber" ) )
|
||||
GAMEMODE:SetInRound( true )
|
||||
|
||||
end
|
||||
|
||||
//
|
||||
// Internal, override OnRoundStart if you want to do stuff here
|
||||
//
|
||||
--[[ moved to prop hunt's init.lua
|
||||
function GM:RoundStart()
|
||||
|
||||
local roundNum = GetGlobalInt( "RoundNumber" );
|
||||
local roundDuration = GAMEMODE:GetRoundTime( roundNum )
|
||||
|
||||
GAMEMODE:OnRoundStart( roundNum )
|
||||
|
||||
timer.Create( "RoundEndTimer", roundDuration, 0, function() GAMEMODE:RoundTimerEnd() end )
|
||||
timer.Create( "CheckRoundEnd", 1, 0, function() GAMEMODE:CheckRoundEnd() end )
|
||||
|
||||
SetGlobalFloat( "RoundEndTime", CurTime() + roundDuration );
|
||||
|
||||
// Check if fretta_waitforplayers is true
|
||||
// This is a fast implementation for a waiting system
|
||||
// Make optimisations if needed
|
||||
if ( fretta_waitforplayers:GetBool() ) then
|
||||
|
||||
// Pause these timers if there are not enough players on the teams in the server
|
||||
if ( ( team.NumPlayers( TEAM_HUNTERS ) < 1 ) || ( team.NumPlayers( TEAM_PROPS ) < 1 ) ) then
|
||||
|
||||
if ( timer.Exists( "RoundEndTimer" ) && timer.Exists( "CheckRoundEnd" ) ) then
|
||||
|
||||
timer.Pause( "RoundEndTimer" )
|
||||
timer.Pause( "CheckRoundEnd" )
|
||||
|
||||
SetGlobalFloat( "RoundEndTime", -1 );
|
||||
|
||||
PrintMessage( HUD_PRINTTALK, "There's not enough players to start the game." )
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
// Send this as a global boolean
|
||||
SetGlobalBool( "RoundWaitForPlayers", fretta_waitforplayers:GetBool() )
|
||||
|
||||
end
|
||||
]]--
|
||||
-- default fretta on round start.
|
||||
function GM:RoundStart()
|
||||
|
||||
local roundNum = GetGlobalInt( "RoundNumber" );
|
||||
local roundDuration = GAMEMODE:GetRoundTime( roundNum )
|
||||
|
||||
GAMEMODE:OnRoundStart( roundNum )
|
||||
|
||||
timer.Create( "RoundEndTimer", roundDuration, 0, function() GAMEMODE:RoundTimerEnd() end )
|
||||
timer.Create( "CheckRoundEnd", 1, 0, function() GAMEMODE:CheckRoundEnd() end )
|
||||
|
||||
SetGlobalFloat( "RoundEndTime", CurTime() + roundDuration );
|
||||
|
||||
end
|
||||
//
|
||||
// Decide what text should show when a team/player wins
|
||||
//
|
||||
function GM:ProcessResultText( result, resulttext )
|
||||
|
||||
if ( resulttext == nil ) then resulttext = "" end
|
||||
|
||||
//the result could either be a number or a player!
|
||||
// for a free for all you could do... if type(result) == "Player" and IsValid( result ) then return result:Name().." is the winner" or whatever
|
||||
|
||||
return resulttext
|
||||
|
||||
end
|
||||
|
||||
//
|
||||
// Round Ended with Result
|
||||
//
|
||||
function GM:RoundEndWithResult( result, resulttext )
|
||||
|
||||
resulttext = GAMEMODE:ProcessResultText( result, resulttext )
|
||||
|
||||
if type( result ) == "number" then // the result is a team ID
|
||||
|
||||
GAMEMODE:SetRoundResult( result, resulttext )
|
||||
GAMEMODE:RoundEnd()
|
||||
GAMEMODE:OnRoundResult( result, resulttext )
|
||||
|
||||
else // the result is a player
|
||||
|
||||
GAMEMODE:SetRoundWinner( result, resulttext )
|
||||
GAMEMODE:RoundEnd()
|
||||
GAMEMODE:OnRoundWinner( result, resulttext )
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
//
|
||||
// Internal, override OnRoundEnd if you want to do stuff here
|
||||
//
|
||||
function GM:RoundEnd()
|
||||
|
||||
if ( !GAMEMODE:InRound() ) then
|
||||
// if someone uses RoundEnd incorrectly then do a trace.
|
||||
MsgN("WARNING: RoundEnd being called while gamemode not in round...")
|
||||
debug.Trace()
|
||||
return
|
||||
end
|
||||
|
||||
GAMEMODE:OnRoundEnd( GetGlobalInt( "RoundNumber" ) )
|
||||
|
||||
self:SetInRound( false )
|
||||
|
||||
timer.Destroy( "RoundEndTimer" )
|
||||
timer.Destroy( "CheckRoundEnd" )
|
||||
SetGlobalFloat( "RoundEndTime", -1 )
|
||||
|
||||
timer.Simple( GAMEMODE.RoundPostLength, function() GAMEMODE:PreRoundStart( GetGlobalInt( "RoundNumber" )+1 ) end )
|
||||
|
||||
hook.Call("PH_RoundEnd", nil)
|
||||
|
||||
end
|
||||
|
||||
function GM:GetTeamAliveCounts()
|
||||
|
||||
local TeamCounter = {}
|
||||
|
||||
for k,v in pairs( player.GetAll() ) do
|
||||
if ( v:Alive() && v:Team() > 0 && v:Team() < 1000 ) then
|
||||
TeamCounter[ v:Team() ] = TeamCounter[ v:Team() ] or 0
|
||||
TeamCounter[ v:Team() ] = TeamCounter[ v:Team() ] + 1
|
||||
end
|
||||
end
|
||||
|
||||
return TeamCounter
|
||||
|
||||
end
|
||||
|
||||
//
|
||||
// For round based games that end when a team is dead
|
||||
//
|
||||
function GM:CheckPlayerDeathRoundEnd()
|
||||
|
||||
if ( !GAMEMODE.RoundBased ) then return end
|
||||
if ( !GAMEMODE:InRound() ) then return end
|
||||
|
||||
if ( GAMEMODE.RoundEndsWhenOneTeamAlive ) then
|
||||
|
||||
local Teams = GAMEMODE:GetTeamAliveCounts()
|
||||
|
||||
if ( table.Count( Teams ) == 0 ) then
|
||||
|
||||
GAMEMODE:RoundEndWithResult( 1001, "Draw, everyone loses!" )
|
||||
return
|
||||
|
||||
end
|
||||
|
||||
if ( table.Count( Teams ) == 1 ) then
|
||||
|
||||
local TeamID = table.GetFirstKey( Teams )
|
||||
GAMEMODE:RoundEndWithResult( TeamID )
|
||||
return
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
hook.Add( "PlayerDisconnected", "RoundCheck_PlayerDisconnect", function() timer.Simple( 0.2, function() GAMEMODE:CheckPlayerDeathRoundEnd() end ) end )
|
||||
hook.Add( "PostPlayerDeath", "RoundCheck_PostPlayerDeath", function() timer.Simple( 0.2, function() GAMEMODE:CheckPlayerDeathRoundEnd() end ) end )
|
||||
|
||||
//
|
||||
// You should use this to check any round end conditions
|
||||
//
|
||||
function GM:CheckRoundEnd()
|
||||
|
||||
// Do checks..
|
||||
|
||||
// if something then call GAMEMODE:RoundEndWithResult( TEAM_BLUE, "Team Blue Ate All The Mushrooms!" )
|
||||
// OR for a free for all you could do something like... GAMEMODE:RoundEndWithResult( SomePlayer )
|
||||
|
||||
end
|
||||
|
||||
function GM:CheckRoundEndInternal()
|
||||
|
||||
if ( !GAMEMODE:InRound() ) then return end
|
||||
|
||||
GAMEMODE:CheckRoundEnd()
|
||||
|
||||
timer.Create( "CheckRoundEnd", 1, 0, function() GAMEMODE:CheckRoundEndInternal() end )
|
||||
|
||||
end
|
||||
|
||||
//
|
||||
// This is called when the round time ends.
|
||||
//
|
||||
function GM:RoundTimerEnd()
|
||||
|
||||
if ( !GAMEMODE:InRound() ) then return end
|
||||
|
||||
if ( !GAMEMODE.TeamBased ) then
|
||||
|
||||
local ply = GAMEMODE:SelectCurrentlyWinningPlayer()
|
||||
|
||||
if ply then
|
||||
GAMEMODE:RoundEndWithResult( ply, "Time Up" )
|
||||
else
|
||||
GAMEMODE:RoundEndWithResult( -1, "Time Up" )
|
||||
end
|
||||
|
||||
else
|
||||
|
||||
GAMEMODE:RoundEndWithResult( -1, "Time Up" )
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
//
|
||||
// This is called when time runs out and there is no winner chosen yet (free for all gamemodes only)
|
||||
// By default it chooses the player with the most frags but you can edit this to do what you need..
|
||||
//
|
||||
function GM:SelectCurrentlyWinningPlayer()
|
||||
|
||||
local winner
|
||||
local topscore = 0
|
||||
|
||||
for k,v in pairs( player.GetAll() ) do
|
||||
|
||||
if v:Frags() > topscore and v:Team() != TEAM_CONNECTING and v:Team() != TEAM_UNASSIGNED and v:Team() != TEAM_SPECTATOR then
|
||||
|
||||
winner = v
|
||||
topscore = v:Frags()
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
return winner
|
||||
|
||||
end
|
|
@ -0,0 +1,331 @@
|
|||
/*
|
||||
shared.lua - Shared Component
|
||||
-----------------------------------------------------
|
||||
This is the shared component of your gamemode, a lot of the game variables
|
||||
can be changed from here.
|
||||
*/
|
||||
|
||||
include( "player_class.lua" )
|
||||
include( "player_extension.lua" )
|
||||
include( "class_default.lua" )
|
||||
include( "player_colours.lua" )
|
||||
|
||||
fretta_voting = CreateConVar( "fretta_voting", "1", { FCVAR_REPLICATED, FCVAR_NOTIFY, FCVAR_ARCHIVE }, "Allow/Dissallow voting" )
|
||||
|
||||
GM.Name = "Simple Game Base"
|
||||
GM.Author = "Anonymous"
|
||||
GM.Email = ""
|
||||
GM.Website = "www.garry.tv"
|
||||
GM.Help = "No Help Available"
|
||||
|
||||
GM.TeamBased = true // Team based game or a Free For All game?
|
||||
GM.AllowAutoTeam = true // Allow auto-assign?
|
||||
GM.AllowSpectating = true // Allow people to spectate during the game?
|
||||
GM.SecondsBetweenTeamSwitches = 10 // The minimum time between each team change?
|
||||
GM.GameLength = 15 // The overall length of the game
|
||||
GM.RoundLimit = -1 // Maximum amount of rounds to be played in round based games
|
||||
GM.VotingDelay = 5 // Delay between end of game, and vote. if you want to display any extra screens before the vote pops up
|
||||
GM.ShowTeamName = true // Show the team name on the HUD
|
||||
|
||||
GM.NoPlayerSuicide = false // Set to true if players should not be allowed to commit suicide.
|
||||
GM.NoPlayerDamage = false // Set to true if players should not be able to damage each other.
|
||||
GM.NoPlayerSelfDamage = false // Allow players to hurt themselves?
|
||||
GM.NoPlayerTeamDamage = true // Allow team-members to hurt each other?
|
||||
GM.NoPlayerPlayerDamage = false // Allow players to hurt each other?
|
||||
GM.NoNonPlayerPlayerDamage = false // Allow damage from non players (physics, fire etc)
|
||||
GM.NoPlayerFootsteps = false // When true, all players have silent footsteps
|
||||
GM.PlayerCanNoClip = false // When true, players can use noclip without sv_cheats
|
||||
GM.TakeFragOnSuicide = false // -1 frag on suicide
|
||||
|
||||
GM.MaximumDeathLength = 0 // Player will repspawn if death length > this (can be 0 to disable)
|
||||
GM.MinimumDeathLength = 2 // Player has to be dead for at least this long
|
||||
GM.AutomaticTeamBalance = false // Teams will be periodically balanced
|
||||
GM.ForceJoinBalancedTeams = true // Players won't be allowed to join a team if it has more players than another team
|
||||
GM.RealisticFallDamage = false // Set to true if you want realistic fall damage instead of the fix 10 damage.
|
||||
GM.AddFragsToTeamScore = false // Adds player's individual kills to team score (must be team based)
|
||||
|
||||
GM.NoAutomaticSpawning = false // Players don't spawn automatically when they die, some other system spawns them
|
||||
GM.RoundBased = false // Round based, like CS
|
||||
GM.RoundLength = 30 // Round length, in seconds
|
||||
GM.RoundPreStartTime = 5 // Preperation time before a round starts
|
||||
GM.RoundPostLength = 8 // Seconds to show the 'x team won!' screen at the end of a round
|
||||
GM.RoundEndsWhenOneTeamAlive = true // CS Style rules
|
||||
|
||||
GM.EnableFreezeCam = true // TF2 Style Freezecam
|
||||
GM.DeathLingerTime = 7 // The time between you dying and it going into spectator mode, 0 disables
|
||||
|
||||
GM.SelectModel = false // Can players use the playermodel picker in the F1 menu?
|
||||
GM.SelectColor = false // Can players modify the colour of their name? (ie.. no teams)
|
||||
|
||||
GM.PlayerRingSize = 48 // How big are the colored rings under the player's feet (if they are enabled) ?
|
||||
GM.HudSkin = "SimpleSkin" // The Derma skin to use for the HUD components
|
||||
GM.SuicideString = "died" // The string to append to the player's name when they commit suicide.
|
||||
GM.DeathNoticeDefaultColor = Color( 255, 128, 0 ); // Default colour for entity kills
|
||||
GM.DeathNoticeTextColor = color_white; // colour for text ie. "died", "killed"
|
||||
|
||||
GM.ValidSpectatorModes = { OBS_MODE_CHASE, OBS_MODE_IN_EYE, OBS_MODE_ROAMING } // The spectator modes that are allowed
|
||||
GM.ValidSpectatorEntities = { "player" } // Entities we can spectate, players being the obvious default choice.
|
||||
GM.CanOnlySpectateOwnTeam = true; // you can only spectate players on your own team
|
||||
|
||||
DeriveGamemode( "base" )
|
||||
|
||||
TEAM_GREEN = 1
|
||||
TEAM_ORANGE = 2
|
||||
TEAM_BLUE = 3
|
||||
TEAM_RED = 4
|
||||
|
||||
/*---------------------------------------------------------
|
||||
Name: gamemode:CreateTeams()
|
||||
Desc: Set up all your teams here. Note - HAS to be shared.
|
||||
---------------------------------------------------------*/
|
||||
function GM:CreateTeams()
|
||||
|
||||
if ( !GAMEMODE.TeamBased ) then return end
|
||||
|
||||
team.SetUp( TEAM_GREEN, "Green Team", Color( 70, 230, 70 ), true )
|
||||
team.SetSpawnPoint( TEAM_GREEN, "info_player_start" ) // The list of entities can be a table
|
||||
|
||||
team.SetUp( TEAM_ORANGE, "Orange Team", Color( 255, 200, 50 ) )
|
||||
team.SetSpawnPoint( TEAM_ORANGE, "info_player_start", true )
|
||||
|
||||
team.SetUp( TEAM_BLUE, "Blue Team", Color( 80, 150, 255 ) )
|
||||
team.SetSpawnPoint( TEAM_BLUE, "info_player_start", true )
|
||||
|
||||
team.SetUp( TEAM_RED, "Red Team", Color( 255, 80, 80 ) )
|
||||
team.SetSpawnPoint( TEAM_RED, "info_player_start", true )
|
||||
|
||||
team.SetUp( TEAM_SPECTATOR, "Spectators", Color( 200, 200, 200 ), true )
|
||||
team.SetSpawnPoint( TEAM_SPECTATOR, "info_player_start" )
|
||||
team.SetClass( TEAM_SPECTATOR, { "Spectator" } )
|
||||
|
||||
end
|
||||
|
||||
function GM:InGamemodeVote()
|
||||
return GetGlobalBool( "InGamemodeVote", false )
|
||||
end
|
||||
|
||||
/*---------------------------------------------------------
|
||||
Name: gamemode:TeamHasEnoughPlayers( Number teamid )
|
||||
Desc: Return true if the team has too many players.
|
||||
Useful for when forced auto-assign is on.
|
||||
---------------------------------------------------------*/
|
||||
function GM:TeamHasEnoughPlayers( teamid )
|
||||
|
||||
local PlayerCount = team.NumPlayers( teamid )
|
||||
|
||||
// Don't let them join a team if it has more players than another team
|
||||
if ( GAMEMODE.ForceJoinBalancedTeams ) then
|
||||
|
||||
for id, tm in pairs( team.GetAllTeams() ) do
|
||||
if ( id > 0 && id < 1000 && team.NumPlayers( id ) < PlayerCount && team.Joinable(id) ) then return true end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
return false
|
||||
|
||||
end
|
||||
|
||||
/*---------------------------------------------------------
|
||||
Name: gamemode:PlayerCanJoinTeam( Player ply, Number teamid )
|
||||
Desc: Are we allowed to join a team? Return true if so.
|
||||
---------------------------------------------------------*/
|
||||
function GM:PlayerCanJoinTeam( ply, teamid )
|
||||
|
||||
if ( SERVER && !self.BaseClass:PlayerCanJoinTeam( ply, teamid ) ) then
|
||||
return false
|
||||
end
|
||||
|
||||
if ( GAMEMODE:TeamHasEnoughPlayers( teamid ) ) then
|
||||
ply:ChatPrint( "That team is full!" )
|
||||
ply:SendLua("GAMEMODE:ShowTeam()")
|
||||
return false
|
||||
end
|
||||
|
||||
return true
|
||||
|
||||
end
|
||||
|
||||
/*---------------------------------------------------------
|
||||
Name: gamemode:Move( Player ply, CMoveData mv )
|
||||
Desc: Setup Move, this also calls the player's class move
|
||||
function.
|
||||
---------------------------------------------------------*/
|
||||
function GM:Move( ply, mv )
|
||||
|
||||
if ( ply:CallClassFunction( "Move", mv ) ) then return true end
|
||||
|
||||
end
|
||||
|
||||
/*---------------------------------------------------------
|
||||
Name: gamemode:KeyPress( Player ply, Number key )
|
||||
Desc: Player presses a key, this also calls the player's class
|
||||
OnKeyPress function.
|
||||
---------------------------------------------------------*/
|
||||
function GM:KeyPress( ply, key )
|
||||
|
||||
if ( ply:CallClassFunction( "OnKeyPress", key ) ) then return true end
|
||||
|
||||
end
|
||||
|
||||
/*---------------------------------------------------------
|
||||
Name: gamemode:KeyRelease( Player ply, Number key )
|
||||
Desc: Player releases a key, this also calls the player's class
|
||||
OnKeyRelease function.
|
||||
---------------------------------------------------------*/
|
||||
function GM:KeyRelease( ply, key )
|
||||
|
||||
if ( ply:CallClassFunction( "OnKeyRelease", key ) ) then return true end
|
||||
|
||||
end
|
||||
|
||||
/*---------------------------------------------------------
|
||||
Name: gamemode:PlayerFootstep( Player ply, Vector pos, Number foot, String sound, Float volume, CReceipientFilter rf )
|
||||
Desc: Player's feet makes a sound, this also calls the player's class Footstep function.
|
||||
If you want to disable all footsteps set GM.NoPlayerFootsteps to true.
|
||||
If you want to disable footsteps on a class, set Class.DisableFootsteps to true.
|
||||
---------------------------------------------------------*/
|
||||
function GM:PlayerFootstep( ply, pos, foot, sound, volume, rf )
|
||||
|
||||
if( GAMEMODE.NoPlayerFootsteps || !ply:Alive() || ply:Team() == TEAM_SPECTATOR || ply:IsObserver() ) then
|
||||
return true;
|
||||
end
|
||||
|
||||
local Class = ply:GetPlayerClass();
|
||||
if( !Class ) then return end
|
||||
|
||||
if( Class.DisableFootsteps ) then // rather than using a hook, we can just do this to override the function instead.
|
||||
return true;
|
||||
end
|
||||
|
||||
if( Class.Footstep ) then
|
||||
return Class:Footstep( ply, pos, foot, sound, volume, rf ); // Call footstep function in class, you can use this to make custom footstep sounds
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
/*---------------------------------------------------------
|
||||
Name: gamemode:CalcView( Player ply, Vector origin, Angles angles, Number fov )
|
||||
Desc: Calculates the players view. Also calls the players class
|
||||
CalcView function, as well as GetViewModelPosition and CalcView
|
||||
on the current weapon. Returns a table.
|
||||
---------------------------------------------------------*/
|
||||
function GM:CalcView( ply, origin, angles, fov )
|
||||
|
||||
local view = ply:CallClassFunction( "CalcView", origin, angles, fov ) or { ["origin"] = origin, ["angles"] = angles, ["fov"] = fov };
|
||||
|
||||
origin = view.origin or origin
|
||||
angles = view.angles or angles
|
||||
fov = view.fov or fov
|
||||
|
||||
local wep = ply:GetActiveWeapon()
|
||||
if ( IsValid( wep ) ) then
|
||||
|
||||
local func = wep.GetViewModelPosition
|
||||
if ( func ) then view.vm_origin, view.vm_angles = func( wep, origin*1, angles*1 ) end
|
||||
|
||||
local func = wep.CalcView
|
||||
if ( func ) then view.origin, view.angles, view.fov = func( wep, ply, origin*1, angles*1, fov ) end
|
||||
|
||||
end
|
||||
|
||||
return view
|
||||
|
||||
end
|
||||
|
||||
/*---------------------------------------------------------
|
||||
Name: gamemode:GetTimeLimit()
|
||||
Desc: Returns the time limit of a game in seconds, so you could
|
||||
make it use a cvar instead. Return -1 for unlimited.
|
||||
Unlimited length games can be changed using vote for
|
||||
change.
|
||||
---------------------------------------------------------*/
|
||||
function GM:GetTimeLimit()
|
||||
|
||||
if( GAMEMODE.GameLength > 0 ) then
|
||||
return GAMEMODE.GameLength * 60;
|
||||
end
|
||||
|
||||
return -1;
|
||||
|
||||
end
|
||||
|
||||
/*---------------------------------------------------------
|
||||
Name: gamemode:GetGameTimeLeft()
|
||||
Desc: Get the remaining time in seconds.
|
||||
---------------------------------------------------------*/
|
||||
function GM:GetGameTimeLeft()
|
||||
|
||||
local EndTime = GAMEMODE:GetTimeLimit();
|
||||
if ( EndTime == -1 ) then return -1 end
|
||||
|
||||
return EndTime - CurTime()
|
||||
|
||||
end
|
||||
|
||||
/*---------------------------------------------------------
|
||||
Name: gamemode:PlayerNoClip( player, bool )
|
||||
Desc: Player pressed the noclip key, return true if
|
||||
the player is allowed to noclip, false to block
|
||||
---------------------------------------------------------*/
|
||||
function GM:PlayerNoClip( pl, on )
|
||||
|
||||
// Allow noclip if we're in single player or have cheats enabled
|
||||
if ( GAMEMODE.PlayerCanNoClip || game.SinglePlayer() || GetConVar( "sv_cheats" ):GetBool() ) then return true end
|
||||
|
||||
// Don't if it's not.
|
||||
return false
|
||||
|
||||
end
|
||||
|
||||
// This function includes /yourgamemode/player_class/*.lua
|
||||
// And AddCSLuaFile's each of those files.
|
||||
// You need to call it in your derived shared.lua IF you have files in that folder
|
||||
// and want to include them!
|
||||
|
||||
function IncludePlayerClasses()
|
||||
|
||||
local Folder = string.Replace( GM.Folder, "gamemodes/", "" );
|
||||
|
||||
for c,d in pairs(file.Find(Folder.."/gamemode/player_class/*.lua", "LUA")) do
|
||||
include( Folder.."/gamemode/player_class/"..d )
|
||||
AddCSLuaFile( Folder.."/gamemode/player_class/"..d )
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
IncludePlayerClasses()
|
||||
|
||||
function util.ToMinutesSeconds(seconds)
|
||||
local minutes = math.floor(seconds / 60)
|
||||
seconds = seconds - minutes * 60
|
||||
|
||||
return string.format("%02d:%02d", minutes, math.floor(seconds))
|
||||
end
|
||||
|
||||
function util.ToMinutesSecondsMilliseconds(seconds)
|
||||
local minutes = math.floor(seconds / 60)
|
||||
seconds = seconds - minutes * 60
|
||||
|
||||
local milliseconds = math.floor(seconds % 1 * 100)
|
||||
|
||||
return string.format("%02d:%02d.%02d", minutes, math.floor(seconds), milliseconds)
|
||||
end
|
||||
|
||||
function timer.SimpleEx(delay, action, ...)
|
||||
if ... == nil then
|
||||
timer.Simple(delay, action)
|
||||
else
|
||||
local a, b, c, d, e, f, g, h, i, j, k = ...
|
||||
timer.Simple(delay, function() action(a, b, c, d, e, f, g, h, i, j, k) end)
|
||||
end
|
||||
end
|
||||
|
||||
function timer.CreateEx(timername, delay, repeats, action, ...)
|
||||
if ... == nil then
|
||||
timer.Create(timername, delay, repeats, action)
|
||||
else
|
||||
local a, b, c, d, e, f, g, h, i, j, k = ...
|
||||
timer.Create(timername, delay, repeats, function() action(a, b, c, d, e, f, g, h, i, j, k) end)
|
||||
end
|
||||
end
|
|
@ -0,0 +1,443 @@
|
|||
/*
|
||||
skin.lua - Fretta Derma Skin
|
||||
-----------------------------------------------------
|
||||
This is the default Fretta skin for Derma. If you want to override the look of Fretta,
|
||||
base a skin of this and change GM.HudSkin.
|
||||
*/
|
||||
|
||||
local surface = surface
|
||||
local draw = draw
|
||||
local Color = Color
|
||||
|
||||
local SKIN = {}
|
||||
|
||||
SKIN.PrintName = ""
|
||||
SKIN.Author = ""
|
||||
SKIN.DermaVersion = 1
|
||||
|
||||
SKIN.bg_color = Color( 100, 100, 100, 255 )
|
||||
SKIN.bg_color_sleep = Color( 70, 70, 70, 255 )
|
||||
SKIN.bg_color_dark = Color( 50, 50, 50, 255 )
|
||||
SKIN.bg_color_bright = Color( 220, 220, 220, 255 )
|
||||
|
||||
SKIN.fontFrame = "Default"
|
||||
|
||||
SKIN.control_color = Color( 180, 180, 180, 255 )
|
||||
SKIN.control_color_highlight = Color( 220, 220, 220, 255 )
|
||||
SKIN.control_color_active = Color( 110, 150, 255, 255 )
|
||||
SKIN.control_color_bright = Color( 255, 200, 100, 255 )
|
||||
SKIN.control_color_dark = Color( 100, 100, 100, 255 )
|
||||
|
||||
SKIN.bg_alt1 = Color( 50, 50, 50, 255 )
|
||||
SKIN.bg_alt2 = Color( 55, 55, 55, 255 )
|
||||
|
||||
SKIN.listview_hover = Color( 70, 70, 70, 255 )
|
||||
SKIN.listview_selected = Color( 100, 170, 220, 255 )
|
||||
|
||||
SKIN.text_bright = Color( 255, 255, 255, 255 )
|
||||
SKIN.text_normal = Color( 180, 180, 180, 255 )
|
||||
SKIN.text_dark = Color( 20, 20, 20, 255 )
|
||||
SKIN.text_highlight = Color( 255, 20, 20, 255 )
|
||||
|
||||
SKIN.texGradientUp = Material( "gui/gradient_up" )
|
||||
SKIN.texGradientDown = Material( "gui/gradient_down" )
|
||||
|
||||
SKIN.combobox_selected = SKIN.listview_selected
|
||||
|
||||
SKIN.panel_transback = Color( 255, 255, 255, 50 )
|
||||
SKIN.tooltip = Color( 255, 245, 175, 255 )
|
||||
|
||||
SKIN.colPropertySheet = Color( 170, 170, 170, 255 )
|
||||
SKIN.colTab = SKIN.colPropertySheet
|
||||
SKIN.colTabInactive = Color( 170, 170, 170, 155 )
|
||||
SKIN.colTabShadow = Color( 60, 60, 60, 255 )
|
||||
SKIN.colTabText = Color( 255, 255, 255, 255 )
|
||||
SKIN.colTabTextInactive = Color( 0, 0, 0, 155 )
|
||||
SKIN.fontTab = "Default"
|
||||
|
||||
SKIN.colCollapsibleCategory = Color( 255, 255, 255, 20 )
|
||||
|
||||
SKIN.colCategoryText = Color( 255, 255, 255, 255 )
|
||||
SKIN.colCategoryTextInactive = Color( 200, 200, 200, 255 )
|
||||
SKIN.fontCategoryHeader = "TabLarge"
|
||||
|
||||
SKIN.colNumberWangBG = Color( 255, 240, 150, 255 )
|
||||
SKIN.colTextEntryBG = Color( 240, 240, 240, 255 )
|
||||
SKIN.colTextEntryBorder = Color( 20, 20, 20, 255 )
|
||||
SKIN.colTextEntryText = Color( 20, 20, 20, 255 )
|
||||
SKIN.colTextEntryTextHighlight = Color( 20, 200, 250, 255 )
|
||||
SKIN.colTextEntryTextHighlight = Color( 20, 200, 250, 255 )
|
||||
|
||||
SKIN.colMenuBG = Color( 255, 255, 255, 200 )
|
||||
SKIN.colMenuBorder = Color( 0, 0, 0, 200 )
|
||||
|
||||
SKIN.colButtonText = Color( 0, 0, 0, 250 )
|
||||
SKIN.colButtonTextDisabled = Color( 0, 0, 0, 100 )
|
||||
SKIN.colButtonBorder = Color( 20, 20, 20, 255 )
|
||||
SKIN.colButtonBorderHighlight = Color( 255, 255, 255, 50 )
|
||||
SKIN.colButtonBorderShadow = Color( 0, 0, 0, 100 )
|
||||
SKIN.fontButton = "Default"
|
||||
|
||||
-- enum for draw order
|
||||
DM_ORDER_LATESTATTOP = 1;
|
||||
DM_ORDER_LATESTATBOTTOM = 2;
|
||||
|
||||
-- basic deathmsg appearance settings
|
||||
SKIN.deathMessageBackgroundCol = Color( 46, 43, 42, 220 );
|
||||
SKIN.deathMessageBackgroundLocal = Color( 75, 75, 75, 200 ); -- this is the colour that the background is when the local player is involved in the deathmsg, so it stands out.
|
||||
SKIN.deathMessageActionColor = Color( 200, 200, 200 );
|
||||
|
||||
local matBlurScreen = Material( "pp/blurscreen" )
|
||||
|
||||
|
||||
/*---------------------------------------------------------
|
||||
DrawGenericBackground
|
||||
---------------------------------------------------------*/
|
||||
function SKIN:DrawGenericBackground( x, y, w, h, color )
|
||||
|
||||
draw.RoundedBox( 4, x, y, w, h, color )
|
||||
|
||||
end
|
||||
|
||||
/*---------------------------------------------------------
|
||||
DrawLinedButtonBorder
|
||||
---------------------------------------------------------*/
|
||||
function SKIN:DrawLinedButtonBorder( x, y, w, h, depressed )
|
||||
|
||||
surface.SetDrawColor( Color( 0, 0, 0, 200 ) )
|
||||
surface.DrawOutlinedRect( x+1, y+1, w-2, h-2 )
|
||||
|
||||
end
|
||||
|
||||
/*---------------------------------------------------------
|
||||
Button
|
||||
---------------------------------------------------------*/
|
||||
function SKIN:PaintCancelButton( panel )
|
||||
|
||||
local w, h = panel:GetSize()
|
||||
|
||||
if ( panel.m_bBackground ) then
|
||||
|
||||
local col = self.control_color
|
||||
|
||||
if ( panel:GetDisabled() ) then
|
||||
col = self.control_color_dark
|
||||
elseif ( panel.Depressed ) then
|
||||
col = self.control_color_active
|
||||
elseif ( panel.Hovered ) then
|
||||
col = self.control_color_highlight
|
||||
end
|
||||
|
||||
if ( panel.m_colBackground ) then
|
||||
|
||||
col = table.Copy( panel.m_colBackground )
|
||||
|
||||
if ( panel:GetDisabled() ) then
|
||||
col.r = math.Clamp( col.r * 0.7, 0, 255 )
|
||||
col.g = math.Clamp( col.g * 0.7, 0, 255 )
|
||||
col.b = math.Clamp( col.b * 0.7, 0, 255 )
|
||||
col.a = 20
|
||||
elseif ( panel.Depressed ) then
|
||||
col.r = math.Clamp( col.r + 100, 0, 255 )
|
||||
col.g = math.Clamp( col.g + 100, 0, 255 )
|
||||
col.b = math.Clamp( col.b + 100, 0, 255 )
|
||||
elseif ( panel.Hovered ) then
|
||||
col.r = math.Clamp( col.r + 30, 0, 255 )
|
||||
col.g = math.Clamp( col.g + 30, 0, 255 )
|
||||
col.b = math.Clamp( col.b + 30, 0, 255 )
|
||||
end
|
||||
end
|
||||
|
||||
surface.SetDrawColor( col.r, col.g, col.b, col.a )
|
||||
panel:DrawFilledRect()
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
SKIN.PaintSelectButton = SKIN.PaintCancelButton
|
||||
|
||||
function SKIN:PaintOverCancelButton( panel )
|
||||
|
||||
local w, h = panel:GetSize()
|
||||
|
||||
if ( panel.m_bBorder ) then
|
||||
self:DrawLinedButtonBorder( 0, 0, w, h, panel.Depressed )
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
SKIN.PaintOverSelectButton = SKIN.PaintOverCancelButton
|
||||
|
||||
function SKIN:SchemeCancelButton( panel )
|
||||
|
||||
panel:SetFontInternal( "FRETTA_SMALL" )
|
||||
|
||||
if ( panel:GetDisabled() ) then
|
||||
panel:SetTextColor( self.colButtonTextDisabled )
|
||||
else
|
||||
panel:SetTextColor( self.colButtonText )
|
||||
end
|
||||
|
||||
DLabel.ApplySchemeSettings( panel )
|
||||
|
||||
end
|
||||
|
||||
function SKIN:SchemeSelectButton( panel )
|
||||
|
||||
panel:SetFontInternal( "FRETTA_SMALL" )
|
||||
|
||||
if ( panel:GetDisabled() ) then
|
||||
panel:SetTextColor( self.colButtonTextDisabled )
|
||||
else
|
||||
panel:SetTextColor( self.colButtonText )
|
||||
end
|
||||
|
||||
DLabel.ApplySchemeSettings( panel )
|
||||
|
||||
end
|
||||
|
||||
/*---------------------------------------------------------
|
||||
ListViewLine
|
||||
---------------------------------------------------------*/
|
||||
function SKIN:PaintListViewLine( panel )
|
||||
|
||||
|
||||
end
|
||||
|
||||
/*---------------------------------------------------------
|
||||
ListViewLine
|
||||
---------------------------------------------------------*/
|
||||
function SKIN:PaintListView( panel )
|
||||
|
||||
|
||||
end
|
||||
|
||||
/*---------------------------------------------------------
|
||||
ListViewLabel
|
||||
---------------------------------------------------------*/
|
||||
function SKIN:PaintScorePanelHeader( panel )
|
||||
|
||||
//surface.SetDrawColor( panel.cTeamColor )
|
||||
//panel:DrawFilledRect()
|
||||
|
||||
end
|
||||
|
||||
/*---------------------------------------------------------
|
||||
ListViewLabel
|
||||
---------------------------------------------------------*/
|
||||
function SKIN:PaintScorePanelLine( panel )
|
||||
|
||||
local Tall = panel:GetTall()
|
||||
local BoxHeight = 21
|
||||
|
||||
if ( !IsValid( panel.pPlayer ) || !panel.pPlayer:Alive() ) then
|
||||
draw.RoundedBox( 4, 0, Tall*0.5 - BoxHeight*0.5, panel:GetWide(), BoxHeight, Color( 60, 60, 60, 255 ) )
|
||||
return
|
||||
end
|
||||
|
||||
if ( panel.pPlayer == LocalPlayer() ) then
|
||||
draw.RoundedBox( 4, 0, Tall*0.5 - BoxHeight*0.5, panel:GetWide(), BoxHeight, Color( 90, 90, 90, 255 ) )
|
||||
return
|
||||
end
|
||||
|
||||
draw.RoundedBox( 4, 0, Tall*0.5 - BoxHeight*0.5, panel:GetWide(), BoxHeight, Color( 70, 70, 70, 255 ) )
|
||||
|
||||
end
|
||||
|
||||
/*---------------------------------------------------------
|
||||
PaintScorePanel
|
||||
---------------------------------------------------------*/
|
||||
function SKIN:PaintScorePanel( panel )
|
||||
|
||||
surface.SetMaterial( matBlurScreen )
|
||||
surface.SetDrawColor( 255, 255, 255, 255 )
|
||||
|
||||
local x, y = panel:LocalToScreen( 0, 0 )
|
||||
|
||||
matBlurScreen:SetFloat( "$blur", 5 )
|
||||
render.UpdateScreenEffectTexture()
|
||||
surface.DrawTexturedRect( x*-1, y*-1, ScrW(), ScrH() )
|
||||
|
||||
//matBlurScreen:SetFloat( "$blur", 3 )
|
||||
//render.UpdateScreenEffectTexture()
|
||||
//surface.DrawTexturedRect( x*-1, y*-1, ScrW(), ScrH() )
|
||||
|
||||
draw.RoundedBox( 8, 0, 8, panel:GetWide(), panel:GetTall()-8, Color( 40, 40, 40, 150 ) )
|
||||
|
||||
end
|
||||
|
||||
|
||||
/*---------------------------------------------------------
|
||||
LayoutTeamScoreboardHeader
|
||||
---------------------------------------------------------*/
|
||||
function SKIN:LayoutTeamScoreboardHeader( panel )
|
||||
|
||||
panel.TeamName:StretchToParent( 0, 0, 0, 0 )
|
||||
panel.TeamName:SetTextInset( 8, 0 )
|
||||
panel.TeamName:SetColor( Color( 0,0,0 ) )
|
||||
panel.TeamName:SetFontInternal( "FRETTA_SMALL" )
|
||||
|
||||
panel.TeamScore:StretchToParent( 0, 0, 0, 0 )
|
||||
panel.TeamScore:SetContentAlignment( 6 )
|
||||
panel.TeamScore:SetTextInset( 8, 0 )
|
||||
panel.TeamScore:SetColor( Color( 0, 0, 0, 250 ) )
|
||||
panel.TeamScore:SetFontInternal( "FRETTA_MEDIUM" )
|
||||
|
||||
end
|
||||
|
||||
function SKIN:PaintTeamScoreboardHeader( panel )
|
||||
|
||||
local Color = team.GetColor( panel.iTeamID )
|
||||
draw.RoundedBox( 4, 0, 0, panel:GetWide(), panel:GetTall()*2, Color )
|
||||
|
||||
end
|
||||
|
||||
function SKIN:SchemeScorePanelLabel( panel )
|
||||
|
||||
panel:SetTextColor( GAMEMODE:GetTeamColor( panel.pPlayer ) )
|
||||
panel:SetFontInternal( "FRETTA_MEDIUM_SHADOW" )
|
||||
|
||||
end
|
||||
|
||||
function SKIN:PaintScorePanelLabel( panel )
|
||||
|
||||
if ( !IsValid( panel.pPlayer ) || !panel.pPlayer:Alive() ) then
|
||||
panel:SetAlpha( 125 )
|
||||
else
|
||||
panel:SetAlpha( 255 )
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
function SKIN:SchemeScorePanelHeaderLabel( panel )
|
||||
|
||||
panel:SetTextColor( Color( 180, 180, 180, 255 ) )
|
||||
panel:SetFontInternal( "Default" ) -- HudSelectionText
|
||||
end
|
||||
|
||||
function SKIN:SchemeSpectatorInfo( panel )
|
||||
|
||||
panel:SetTextColor( Color( 255, 255, 255, 255 ) )
|
||||
panel:SetFontInternal( "FRETTA_SMALL" )
|
||||
|
||||
end
|
||||
|
||||
/*---------------------------------------------------------
|
||||
ScoreHeader
|
||||
---------------------------------------------------------*/
|
||||
function SKIN:PaintScoreHeader( panel )
|
||||
|
||||
draw.RoundedBox( 8, 0, 0, panel:GetWide(), panel:GetTall()*2, Color( 60,60,60,255 ) )
|
||||
|
||||
end
|
||||
|
||||
function SKIN:LayoutScoreHeader( panel )
|
||||
|
||||
panel.HostName:SizeToContents()
|
||||
panel.HostName:SetPos( 0, 0 )
|
||||
panel.HostName:CenterHorizontal()
|
||||
|
||||
panel.GamemodeName:SizeToContents()
|
||||
panel.GamemodeName:MoveBelow( panel.HostName, 0 )
|
||||
panel.GamemodeName:CenterHorizontal()
|
||||
|
||||
panel:SetTall( panel.GamemodeName.y + panel.GamemodeName:GetTall() + 4 )
|
||||
end
|
||||
|
||||
function SKIN:SchemeScoreHeader( panel )
|
||||
|
||||
panel.HostName:SetTextColor( Color( 255, 255, 255, 255 ) )
|
||||
panel.HostName:SetFontInternal( "FRETTA_LARGE_SHADOW" )
|
||||
|
||||
panel.GamemodeName:SetTextColor( Color( 255, 255, 255, 255 ) )
|
||||
panel.GamemodeName:SetFontInternal( "FRETTA_MEDIUM_SHADOW" )
|
||||
|
||||
end
|
||||
|
||||
/*---------------------------------------------------------
|
||||
DeathMessages
|
||||
---------------------------------------------------------*/
|
||||
function SKIN:PaintGameNotice( panel )
|
||||
|
||||
if ( panel.m_bHighlight ) then
|
||||
draw.RoundedBox( 4, 0, 0, panel:GetWide(), panel:GetTall(), Color( 90, 90, 90, 200 ) )
|
||||
return
|
||||
end
|
||||
|
||||
draw.RoundedBox( 4, 0, 0, panel:GetWide(), panel:GetTall(), Color( 20, 20, 20, 190 ) )
|
||||
|
||||
end
|
||||
|
||||
function SKIN:SchemeGameNoticeLabel( panel )
|
||||
|
||||
panel:SetFontInternal( "FRETTA_NOTIFY" );
|
||||
DLabel.ApplySchemeSettings( panel )
|
||||
|
||||
end
|
||||
|
||||
/*---------------------------------------------------------
|
||||
GamemodeButton
|
||||
---------------------------------------------------------*/
|
||||
function SKIN:PaintGamemodeButton( panel )
|
||||
|
||||
local w, h = panel:GetSize()
|
||||
|
||||
local col = Color( 255, 255, 255, 10 )
|
||||
|
||||
if ( panel:GetDisabled() ) then
|
||||
col = Color( 0, 0, 0, 10 )
|
||||
elseif ( panel.Depressed ) then
|
||||
col = Color( 255, 255, 255, 50 )
|
||||
elseif ( panel.Hovered ) then
|
||||
col = Color( 255, 255, 255, 20 )
|
||||
end
|
||||
|
||||
if ( panel.bgColor != nil ) then col = panel.bgColor end
|
||||
|
||||
draw.RoundedBox( 4, 0, 0, w, h, col )
|
||||
|
||||
end
|
||||
|
||||
function SKIN:SchemeGamemodeButton( panel )
|
||||
|
||||
panel:SetTextColor( color_white )
|
||||
panel:SetFontInternal( "FRETTA_MEDIUM_SHADOW" )
|
||||
panel:SetContentAlignment( 4 )
|
||||
panel:SetTextInset( 8, 0 )
|
||||
|
||||
end
|
||||
|
||||
|
||||
/*---------------------------------------------------------
|
||||
PanelButton
|
||||
---------------------------------------------------------*/
|
||||
function SKIN:PaintPanelButton( panel )
|
||||
|
||||
local w, h = panel:GetSize()
|
||||
|
||||
local col = Color( 160, 160, 160, 255 )
|
||||
|
||||
if ( panel:GetDisabled() ) then
|
||||
col = Color( 100, 100, 100, 255 )
|
||||
elseif ( panel.Depressed ) then
|
||||
col = Color( 150, 210, 255, 255 )
|
||||
elseif ( panel.Hovered ) then
|
||||
col = Color( 200, 200, 200, 255 )
|
||||
end
|
||||
|
||||
if ( panel.bgColor != nil ) then col = panel.bgColor end
|
||||
|
||||
surface.SetDrawColor( col )
|
||||
panel:DrawFilledRect()
|
||||
|
||||
end
|
||||
|
||||
function SKIN:PaintOverPanelButton( panel )
|
||||
|
||||
local w, h = panel:GetSize()
|
||||
self:DrawLinedButtonBorder( 0, 0, w, h, panel.Depressed )
|
||||
|
||||
end
|
||||
|
||||
derma.DefineSkin( "SimpleSkin", "", SKIN )
|
|
@ -0,0 +1,358 @@
|
|||
--[[
|
||||
sv_gmchanger.lua - Gamemode Changer (server side)
|
||||
-----------------------------------------------------
|
||||
Most of the internal stuff for the votes is here and contains stuff you really don't
|
||||
want to override.
|
||||
]]
|
||||
|
||||
local g_PlayableGamemodes = {}
|
||||
|
||||
fretta_votesneeded = CreateConVar( "fretta_votesneeded", "0.75", { FCVAR_ARCHIVE } )
|
||||
fretta_votetime = CreateConVar( "fretta_votetime", "20", { FCVAR_ARCHIVE } )
|
||||
fretta_votegraceperiod = CreateConVar( "fretta_votegraceperiod", "30", { FCVAR_ARCHIVE } )
|
||||
|
||||
|
||||
local function SendAvailableGamemodes( ply )
|
||||
|
||||
net.Start("PlayableGamemodes")
|
||||
net.WriteTable(g_PlayableGamemodes)
|
||||
net.Send(ply)
|
||||
|
||||
end
|
||||
|
||||
function GetRandomGamemodeName()
|
||||
local choose = table.Random( g_PlayableGamemodes )
|
||||
if choose then return choose.key end
|
||||
|
||||
return GAMEMODE.FolderName
|
||||
end
|
||||
|
||||
function GetRandomGamemodeMap( gm )
|
||||
local gmtab = g_PlayableGamemodes[ gm or GAMEMODE.FolderName ]
|
||||
if gmtab then
|
||||
return table.Random( gmtab.maps )
|
||||
end
|
||||
|
||||
return game.GetMap()
|
||||
end
|
||||
|
||||
function GetNumberOfGamemodeMaps( gm )
|
||||
local gmtab = g_PlayableGamemodes[ gm or GAMEMODE.FolderName ]
|
||||
if gmtab then
|
||||
return table.Count( gmtab.maps )
|
||||
end
|
||||
|
||||
return 0
|
||||
end
|
||||
|
||||
hook.Add( "PlayerInitialSpawn", "SendAvailableGamemodes", SendAvailableGamemodes )
|
||||
|
||||
|
||||
local AllMaps = file.Find( "maps/*.bsp", "GAME" )
|
||||
for key, map in pairs( AllMaps ) do
|
||||
AllMaps[ key ] = string.gsub( map, ".bsp", "" )
|
||||
end
|
||||
|
||||
local GameModes = engine.GetGamemodes()
|
||||
|
||||
for _, gm in pairs( engine.GetGamemodes() ) do
|
||||
|
||||
local info = file.Read( "gamemodes/"..gm.name.."/"..gm.name..".txt", "GAME" )
|
||||
if ( info ) then
|
||||
|
||||
local info = util.KeyValuesToTable( info )
|
||||
|
||||
if ( info.selectable == 1 ) then
|
||||
|
||||
g_PlayableGamemodes[ gm.name ] = {}
|
||||
g_PlayableGamemodes[ gm.name ].key = gm.name
|
||||
g_PlayableGamemodes[ gm.name ].name = gm.title
|
||||
g_PlayableGamemodes[ gm.name ].label = info.title
|
||||
g_PlayableGamemodes[ gm.name ].description = info.description
|
||||
g_PlayableGamemodes[ gm.name ].author = info.author_name
|
||||
g_PlayableGamemodes[ gm.name ].authorurl = info.author_url
|
||||
|
||||
g_PlayableGamemodes[ gm.name ].maps = {}
|
||||
|
||||
if ( info.fretta_maps ) then
|
||||
for _, mapname in pairs( AllMaps ) do
|
||||
mapname = string.lower(mapname)
|
||||
for _, p in pairs( info.fretta_maps ) do
|
||||
if ( string.sub( mapname, 1, #p ) == p ) then
|
||||
table.insert( g_PlayableGamemodes[ gm.name ].maps, mapname )
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
g_PlayableGamemodes[ gm.name ].maps = AllMaps
|
||||
end
|
||||
|
||||
if ( info.fretta_maps_disallow ) then
|
||||
for key, mapname in pairs( g_PlayableGamemodes[ gm.name ].maps ) do
|
||||
mapname = string.lower(mapname)
|
||||
for _, p in pairs( info.fretta_maps_disallow ) do
|
||||
if ( string.sub( mapname, 1, #p ) == p ) then
|
||||
g_PlayableGamemodes[ gm.name ].maps[ key ] = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
GameModes = nil
|
||||
|
||||
function GM:IsValidGamemode( gamemode, map )
|
||||
|
||||
if ( g_PlayableGamemodes[ gamemode ] == nil ) then return false end
|
||||
|
||||
if ( map == nil ) then return true end
|
||||
|
||||
for _, mapname in pairs( g_PlayableGamemodes[ gamemode ].maps ) do
|
||||
if ( mapname == map ) then return true end
|
||||
end
|
||||
|
||||
return false
|
||||
|
||||
end
|
||||
|
||||
local gVotes = {}
|
||||
|
||||
function GM:VotePlayGamemode( ply, gamemode )
|
||||
|
||||
if ( !gamemode ) then return end
|
||||
if ( GAMEMODE.WinningGamemode ) then return end
|
||||
if ( !GAMEMODE:InGamemodeVote() ) then return end
|
||||
if ( !GAMEMODE:IsValidGamemode( gamemode ) ) then return end
|
||||
|
||||
ply:SetNWString( "Wants", gamemode )
|
||||
|
||||
end
|
||||
|
||||
concommand.Add( "votegamemode", function( pl, cmd, args ) GAMEMODE:VotePlayGamemode( pl, args[1] ) end )
|
||||
|
||||
function GM:VotePlayMap( ply, map )
|
||||
|
||||
if ( !map ) then return end
|
||||
if ( !GAMEMODE.WinningGamemode ) then return end
|
||||
if ( !GAMEMODE:InGamemodeVote() ) then return end
|
||||
if ( !GAMEMODE:IsValidGamemode( GAMEMODE.WinningGamemode, map ) ) then return end
|
||||
|
||||
ply:SetNWString( "Wants", map )
|
||||
|
||||
end
|
||||
|
||||
concommand.Add( "votemap", function( pl, cmd, args ) GAMEMODE:VotePlayMap( pl, args[1] ) end )
|
||||
|
||||
function GM:GetFractionOfPlayersThatWantChange()
|
||||
|
||||
local Humans = player.GetHumans()
|
||||
local NumHumans = #Humans
|
||||
local WantsChange = 0
|
||||
|
||||
for k, player in pairs( Humans ) do
|
||||
|
||||
if ( player:GetNWBool( "WantsVote" ) ) then
|
||||
WantsChange = WantsChange + 1
|
||||
end
|
||||
|
||||
-- Don't count players that aren't connected yet
|
||||
if ( !player:IsConnected() ) then
|
||||
NumHumans = NumHumans - 1
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
local fraction = WantsChange / NumHumans
|
||||
|
||||
return fraction, NumHumans, WantsChange
|
||||
|
||||
end
|
||||
|
||||
function GM:GetVotesNeededForChange()
|
||||
|
||||
local Fraction, NumHumans, WantsChange = GAMEMODE:GetFractionOfPlayersThatWantChange()
|
||||
local FractionNeeded = fretta_votesneeded:GetFloat()
|
||||
|
||||
local VotesNeeded = math.ceil( FractionNeeded * NumHumans )
|
||||
|
||||
return VotesNeeded - WantsChange
|
||||
|
||||
end
|
||||
|
||||
function GM:CountVotesForChange()
|
||||
|
||||
if ( CurTime() >= GetConVarNumber( "fretta_votegraceperiod" ) ) then -- can't vote too early on
|
||||
|
||||
if ( GAMEMODE:InGamemodeVote() ) then return end
|
||||
|
||||
fraction = GAMEMODE:GetFractionOfPlayersThatWantChange()
|
||||
|
||||
if ( fraction > fretta_votesneeded:GetFloat() ) then
|
||||
GAMEMODE:StartGamemodeVote()
|
||||
return false
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function GM:VoteForChange( ply )
|
||||
|
||||
if ( GetConVarNumber( "fretta_voting" ) == 0 ) then return end
|
||||
if ( ply:GetNWBool( "WantsVote" ) ) then return end
|
||||
|
||||
ply:SetNWBool( "WantsVote", true )
|
||||
|
||||
local VotesNeeded = GAMEMODE:GetVotesNeededForChange()
|
||||
local NeedTxt = ""
|
||||
if ( VotesNeeded > 0 ) then NeedTxt = ", Color( 80, 255, 50 ), [[ (need "..VotesNeeded.." more) ]] " end
|
||||
|
||||
if ( CurTime() < GetConVarNumber( "fretta_votegraceperiod" ) ) then -- can't vote too early on
|
||||
local timediff = math.Round( GetConVarNumber( "fretta_votegraceperiod" ) - CurTime() );
|
||||
BroadcastLua( "chat.AddText( Entity("..ply:EntIndex().."), Color( 255, 255, 255 ), [[ voted to change the gamemode]] )" )
|
||||
else
|
||||
BroadcastLua( "chat.AddText( Entity("..ply:EntIndex().."), Color( 255, 255, 255 ), [[ voted to change the gamemode]] "..NeedTxt.." )" )
|
||||
end
|
||||
|
||||
Msg( ply:Nick() .. " voted to change the gamemode\n" )
|
||||
|
||||
timer.Simple( 5, function() GAMEMODE:CountVotesForChange() end )
|
||||
|
||||
end
|
||||
|
||||
concommand.Add( "VoteForChange", function( pl, cmd, args ) GAMEMODE:VoteForChange( pl ) end )
|
||||
timer.Create( "VoteForChangeThink", 10, 0, function() if ( GAMEMODE ) then GAMEMODE.CountVotesForChange( GAMEMODE ) end end )
|
||||
|
||||
|
||||
function GM:ClearPlayerWants()
|
||||
|
||||
for k, ply in pairs( player.GetAll() ) do
|
||||
ply:SetNWString( "Wants", "" )
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
function GM:StartGamemodeVote()
|
||||
|
||||
if( !GAMEMODE.m_bVotingStarted ) then
|
||||
SetGlobalBool( "InGamemodeVote", true )
|
||||
|
||||
if ( fretta_voting:GetBool() ) then
|
||||
if #g_PlayableGamemodes >= 2 then
|
||||
GAMEMODE:ClearPlayerWants()
|
||||
BroadcastLua( "GAMEMODE:ShowGamemodeChooser()" )
|
||||
timer.Simple( fretta_votetime:GetFloat(), function() GAMEMODE:FinishGamemodeVote() end )
|
||||
SetGlobalFloat( "VoteEndTime", CurTime() + fretta_votetime:GetFloat() )
|
||||
else
|
||||
GAMEMODE.WinningGamemode = GAMEMODE:WorkOutWinningGamemode()
|
||||
GAMEMODE:StartMapVote()
|
||||
end
|
||||
else
|
||||
GAMEMODE.WinningGamemode = GAMEMODE.FolderName
|
||||
GAMEMODE:StartMapVote()
|
||||
end
|
||||
|
||||
GAMEMODE.m_bVotingStarted = true;
|
||||
end
|
||||
end
|
||||
|
||||
function GM:StartMapVote()
|
||||
|
||||
-- If there's only one map, let the 'random map' thing choose it
|
||||
if ( GetNumberOfGamemodeMaps( GAMEMODE.WinningGamemode ) == 1 ) then
|
||||
return GAMEMODE:FinishMapVote( true )
|
||||
end
|
||||
|
||||
BroadcastLua( "GAMEMODE:ShowMapChooserForGamemode( \""..GAMEMODE.WinningGamemode.."\" )" );
|
||||
timer.Simple( fretta_votetime:GetFloat(), function() GAMEMODE:FinishMapVote() end )
|
||||
SetGlobalFloat( "VoteEndTime", CurTime() + fretta_votetime:GetFloat() )
|
||||
|
||||
end
|
||||
|
||||
function GM:GetWinningWant()
|
||||
|
||||
local Votes = {}
|
||||
|
||||
for k, ply in pairs( player.GetAll() ) do
|
||||
|
||||
local want = ply:GetNWString( "Wants", nil )
|
||||
if ( want && want != "" ) then
|
||||
Votes[ want ] = Votes[ want ] or 0
|
||||
Votes[ want ] = Votes[ want ] + 1
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
return table.GetWinningKey( Votes )
|
||||
|
||||
end
|
||||
|
||||
function GM:WorkOutWinningGamemode()
|
||||
|
||||
if ( GAMEMODE.WinningGamemode ) then return GAMEMODE.WinningGamemode end
|
||||
|
||||
-- Gamemode Voting disabled, return current gamemode
|
||||
if ( !fretta_voting:GetBool() ) then
|
||||
return GAMEMODE.FolderName
|
||||
end
|
||||
|
||||
local winner = GAMEMODE:GetWinningWant()
|
||||
if ( !winner ) then return GetRandomGamemodeName() end
|
||||
|
||||
return winner
|
||||
|
||||
end
|
||||
|
||||
function GM:GetWinningMap( WinningGamemode )
|
||||
|
||||
if ( GAMEMODE.WinningMap ) then return GAMEMODE.WinningMap end
|
||||
|
||||
local winner = GAMEMODE:GetWinningWant()
|
||||
if ( !winner ) then return GetRandomGamemodeMap( GAMEMODE.WinningGamemode ) end
|
||||
|
||||
return winner
|
||||
|
||||
end
|
||||
|
||||
function GM:FinishGamemodeVote()
|
||||
|
||||
GAMEMODE.WinningGamemode = GAMEMODE:WorkOutWinningGamemode()
|
||||
GAMEMODE:ClearPlayerWants()
|
||||
|
||||
-- Send bink bink notification
|
||||
BroadcastLua( "GAMEMODE:GamemodeWon( '"..GAMEMODE.WinningGamemode.."' )" );
|
||||
|
||||
-- Start map vote..
|
||||
timer.Simple( 2, function() GAMEMODE:StartMapVote() end )
|
||||
|
||||
end
|
||||
|
||||
function GM:FinishMapVote()
|
||||
|
||||
GAMEMODE.WinningMap = GAMEMODE:GetWinningMap()
|
||||
GAMEMODE:ClearPlayerWants()
|
||||
|
||||
-- Send bink bink notification
|
||||
BroadcastLua( "GAMEMODE:ChangingGamemode( '"..GAMEMODE.WinningGamemode.."', '"..GAMEMODE.WinningMap.."' )" );
|
||||
|
||||
-- Start map vote?
|
||||
timer.Simple( 3, function() GAMEMODE:ChangeGamemode() end )
|
||||
|
||||
end
|
||||
|
||||
function GM:ChangeGamemode()
|
||||
|
||||
local gm = GAMEMODE:WorkOutWinningGamemode()
|
||||
local mp = GAMEMODE:GetWinningMap()
|
||||
|
||||
RunConsoleCommand( "gamemode", gm )
|
||||
RunConsoleCommand( "changelevel", mp )
|
||||
|
||||
end
|
|
@ -0,0 +1,245 @@
|
|||
|
||||
/*---------------------------------------------------------
|
||||
Name: gamemode:GetValidSpectatorModes( Player ply )
|
||||
Desc: Gets a table of the allowed spectator modes (OBS_MODE_INEYE, etc)
|
||||
Player is the player object of the spectator
|
||||
---------------------------------------------------------*/
|
||||
function GM:GetValidSpectatorModes( ply )
|
||||
|
||||
// Note: Override this and return valid modes per player/team
|
||||
|
||||
return GAMEMODE.ValidSpectatorModes
|
||||
|
||||
end
|
||||
|
||||
/*---------------------------------------------------------
|
||||
Name: gamemode:GetValidSpectatorEntityNames( Player ply )
|
||||
Desc: Returns a table of entities that can be spectated (player etc)
|
||||
---------------------------------------------------------*/
|
||||
function GM:GetValidSpectatorEntityNames( ply )
|
||||
|
||||
// Note: Override this and return valid entity names per player/team
|
||||
|
||||
return GAMEMODE.ValidSpectatorEntities
|
||||
|
||||
end
|
||||
|
||||
/*---------------------------------------------------------
|
||||
Name: gamemode:IsValidSpectator( Player ply )
|
||||
Desc: Is our player spectating - and valid?
|
||||
---------------------------------------------------------*/
|
||||
function GM:IsValidSpectator( pl )
|
||||
|
||||
if ( !IsValid( pl ) ) then return false end
|
||||
if ( pl:Team() != TEAM_SPECTATOR && !pl:IsObserver() ) then return false end
|
||||
|
||||
return true
|
||||
|
||||
end
|
||||
|
||||
/*---------------------------------------------------------
|
||||
Name: gamemode:IsValidSpectatorTarget( Player pl, Entity ent )
|
||||
Desc: Checks to make sure a spectated entity is valid.
|
||||
By default, you can change GM.CanOnlySpectate own team if you want to
|
||||
prevent players from spectating the other team.
|
||||
---------------------------------------------------------*/
|
||||
function GM:IsValidSpectatorTarget( pl, ent )
|
||||
|
||||
if ( !IsValid( ent ) ) then return false end
|
||||
if ( ent == pl ) then return false end
|
||||
if ( !table.HasValue( GAMEMODE:GetValidSpectatorEntityNames( pl ), ent:GetClass() ) ) then return false end
|
||||
if ( ent:IsPlayer() && !ent:Alive() ) then return false end
|
||||
if ( ent:IsPlayer() && ent:IsObserver() ) then return false end
|
||||
if ( pl:Team() != TEAM_SPECTATOR && ent:IsPlayer() && GAMEMODE.CanOnlySpectateOwnTeam && pl:Team() != ent:Team() ) then return false end
|
||||
|
||||
return true
|
||||
|
||||
end
|
||||
|
||||
/*---------------------------------------------------------
|
||||
Name: gamemode:GetSpectatorTargets( Player pl )
|
||||
Desc: Returns a table of entities the player can spectate.
|
||||
---------------------------------------------------------*/
|
||||
function GM:GetSpectatorTargets( pl )
|
||||
|
||||
local t = {}
|
||||
for k, v in pairs( GAMEMODE:GetValidSpectatorEntityNames( pl ) ) do
|
||||
t = table.Merge( t, ents.FindByClass( v ) )
|
||||
end
|
||||
|
||||
return t
|
||||
|
||||
end
|
||||
|
||||
/*---------------------------------------------------------
|
||||
Name: gamemode:FindRandomSpectatorTarget( Player pl )
|
||||
Desc: Finds a random player/ent we can spectate.
|
||||
This is called when a player is first put in spectate.
|
||||
---------------------------------------------------------*/
|
||||
function GM:FindRandomSpectatorTarget( pl )
|
||||
|
||||
local Targets = GAMEMODE:GetSpectatorTargets( pl )
|
||||
return table.Random( Targets )
|
||||
|
||||
end
|
||||
|
||||
/*---------------------------------------------------------
|
||||
Name: gamemode:FindNextSpectatorTarget( Player pl, Entity ent )
|
||||
Desc: Finds the next entity we can spectate.
|
||||
ent param is the current entity we are viewing.
|
||||
---------------------------------------------------------*/
|
||||
function GM:FindNextSpectatorTarget( pl, ent )
|
||||
|
||||
local Targets = GAMEMODE:GetSpectatorTargets( pl )
|
||||
return table.FindNext( Targets, ent )
|
||||
|
||||
end
|
||||
|
||||
/*---------------------------------------------------------
|
||||
Name: gamemode:FindPrevSpectatorTarget( Player pl, Entity ent )
|
||||
Desc: Finds the previous entity we can spectate.
|
||||
ent param is the current entity we are viewing.
|
||||
---------------------------------------------------------*/
|
||||
function GM:FindPrevSpectatorTarget( pl, ent )
|
||||
|
||||
local Targets = GAMEMODE:GetSpectatorTargets( pl )
|
||||
return table.FindPrev( Targets, ent )
|
||||
|
||||
end
|
||||
|
||||
/*---------------------------------------------------------
|
||||
Name: gamemode:StartEntitySpectate( Player pl )
|
||||
Desc: Called when we start spectating.
|
||||
---------------------------------------------------------*/
|
||||
function GM:StartEntitySpectate( pl )
|
||||
|
||||
local CurrentSpectateEntity = pl:GetObserverTarget()
|
||||
|
||||
for i=1, 32 do
|
||||
|
||||
if ( GAMEMODE:IsValidSpectatorTarget( pl, CurrentSpectateEntity ) ) then
|
||||
pl:SpectateEntity( CurrentSpectateEntity )
|
||||
pl:SetupHands( CurrentSpectateEntity )
|
||||
return
|
||||
end
|
||||
|
||||
CurrentSpectateEntity = GAMEMODE:FindRandomSpectatorTarget( pl )
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
/*---------------------------------------------------------
|
||||
Name: gamemode:NextEntitySpectate( Player pl )
|
||||
Desc: Called when we want to spec the next entity.
|
||||
---------------------------------------------------------*/
|
||||
function GM:NextEntitySpectate( pl )
|
||||
|
||||
local Target = pl:GetObserverTarget()
|
||||
|
||||
for i=1, 32 do
|
||||
|
||||
Target = GAMEMODE:FindNextSpectatorTarget( pl, Target )
|
||||
|
||||
if ( GAMEMODE:IsValidSpectatorTarget( pl, Target ) ) then
|
||||
pl:SpectateEntity( Target )
|
||||
pl:SetupHands( Target )
|
||||
return
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
/*---------------------------------------------------------
|
||||
Name: gamemode:PrevEntitySpectate( Player pl )
|
||||
Desc: Called when we want to spec the previous entity.
|
||||
---------------------------------------------------------*/
|
||||
function GM:PrevEntitySpectate( pl )
|
||||
|
||||
local Target = pl:GetObserverTarget()
|
||||
|
||||
for i=1, 32 do
|
||||
|
||||
Target = GAMEMODE:FindPrevSpectatorTarget( pl, Target )
|
||||
|
||||
if ( GAMEMODE:IsValidSpectatorTarget( pl, Target ) ) then
|
||||
pl:SpectateEntity( Target )
|
||||
pl:SetupHands( Target )
|
||||
return
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
/*---------------------------------------------------------
|
||||
Name: gamemode:ChangeObserverMode( Player pl, Number mode )
|
||||
Desc: Change the observer mode of a player.
|
||||
---------------------------------------------------------*/
|
||||
function GM:ChangeObserverMode( pl, mode )
|
||||
|
||||
if ( pl:GetInfoNum( "cl_spec_mode", 0) != mode ) then
|
||||
pl:ConCommand( "cl_spec_mode "..mode )
|
||||
end
|
||||
|
||||
if ( mode == OBS_MODE_IN_EYE || mode == OBS_MODE_CHASE ) then
|
||||
GAMEMODE:StartEntitySpectate( pl, mode )
|
||||
end
|
||||
|
||||
|
||||
pl:SpectateEntity( NULL )
|
||||
pl:Spectate( mode )
|
||||
|
||||
end
|
||||
|
||||
/*---------------------------------------------------------
|
||||
Name: gamemode:BecomeObserver( Player pl )
|
||||
Desc: Called when we first become a spectator.
|
||||
---------------------------------------------------------*/
|
||||
function GM:BecomeObserver( pl )
|
||||
|
||||
local mode = pl:GetInfoNum( "cl_spec_mode", OBS_MODE_CHASE )
|
||||
|
||||
if ( !table.HasValue( GAMEMODE:GetValidSpectatorModes( pl ), mode ) ) then
|
||||
mode = table.FindNext( GAMEMODE:GetValidSpectatorModes( pl ), mode )
|
||||
end
|
||||
|
||||
GAMEMODE:ChangeObserverMode( pl, mode )
|
||||
|
||||
end
|
||||
|
||||
local function spec_mode( pl, cmd, args )
|
||||
|
||||
if ( !GAMEMODE:IsValidSpectator( pl ) ) then return end
|
||||
|
||||
local mode = pl:GetObserverMode()
|
||||
local nextmode = table.FindNext( GAMEMODE:GetValidSpectatorModes( pl ), mode )
|
||||
|
||||
GAMEMODE:ChangeObserverMode( pl, nextmode )
|
||||
|
||||
end
|
||||
|
||||
concommand.Add( "spec_mode", spec_mode )
|
||||
|
||||
local function spec_next( pl, cmd, args )
|
||||
|
||||
if ( !GAMEMODE:IsValidSpectator( pl ) ) then return end
|
||||
if ( !table.HasValue( GAMEMODE:GetValidSpectatorModes( pl ), pl:GetObserverMode() ) ) then return end
|
||||
|
||||
GAMEMODE:NextEntitySpectate( pl )
|
||||
|
||||
end
|
||||
|
||||
concommand.Add( "spec_next", spec_next )
|
||||
|
||||
local function spec_prev( pl, cmd, args )
|
||||
|
||||
if ( !GAMEMODE:IsValidSpectator( pl ) ) then return end
|
||||
if ( !table.HasValue( GAMEMODE:GetValidSpectatorModes( pl ), pl:GetObserverMode() ) ) then return end
|
||||
|
||||
GAMEMODE:PrevEntitySpectate( pl )
|
||||
|
||||
end
|
||||
|
||||
concommand.Add( "spec_prev", spec_prev )
|
|
@ -0,0 +1,56 @@
|
|||
/*---------------------------------------------------------
|
||||
Name: UTIL_SpawnAllPlayers
|
||||
Desc: Respawn all non-spectators, providing they are allowed to spawn.
|
||||
---------------------------------------------------------*/
|
||||
function UTIL_SpawnAllPlayers()
|
||||
|
||||
for k,v in pairs( player.GetAll() ) do
|
||||
if ( v:CanRespawn() && v:Team() != TEAM_SPECTATOR && v:Team() != TEAM_CONNECTING ) then
|
||||
v:Spawn()
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
/*---------------------------------------------------------
|
||||
Name: UTIL_StripAllPlayers
|
||||
Desc: Clears all weapons and ammo from all players.
|
||||
---------------------------------------------------------*/
|
||||
function UTIL_StripAllPlayers()
|
||||
|
||||
for k,v in pairs( player.GetAll() ) do
|
||||
if ( v:Team() != TEAM_SPECTATOR && v:Team() != TEAM_CONNECTING ) then
|
||||
v:StripWeapons()
|
||||
v:StripAmmo()
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
/*---------------------------------------------------------
|
||||
Name: UTIL_FreezeAllPlayers
|
||||
Desc: Freeze all non-spectators.
|
||||
---------------------------------------------------------*/
|
||||
function UTIL_FreezeAllPlayers()
|
||||
|
||||
for k,v in pairs( player.GetAll() ) do
|
||||
if ( v:Team() != TEAM_SPECTATOR && v:Team() != TEAM_CONNECTING ) then
|
||||
v:Freeze( true )
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
/*---------------------------------------------------------
|
||||
Name: UTIL_UnFreezeAllPlayers
|
||||
Desc: Removes frozen flag from all players.
|
||||
---------------------------------------------------------*/
|
||||
function UTIL_UnFreezeAllPlayers()
|
||||
|
||||
for k,v in pairs( player.GetAll() ) do
|
||||
if ( v:Team() != TEAM_SPECTATOR && v:Team() != TEAM_CONNECTING ) then
|
||||
v:Freeze( false )
|
||||
end
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,111 @@
|
|||
-- client cvars to control deathmsgs
|
||||
local hud_deathnotice_time = CreateClientConVar( "hud_deathnotice_time", "6", true, false )
|
||||
local hud_deathnotice_limit = CreateClientConVar( "hud_deathnotice_limit", "5", true, false )
|
||||
|
||||
/*
|
||||
This is the player death panel. This should be parented to a DeathMessage_Panel. The DeathMessage_Panel that
|
||||
it's parented to controls aspects such as the position on screen. All this panel's job is to print the
|
||||
specific death it's been given and fade out before its RetireTime.
|
||||
*/
|
||||
|
||||
local PANEL = {}
|
||||
|
||||
Derma_Hook( PANEL, "Paint", "Paint", "GameNotice" )
|
||||
Derma_Hook( PANEL, "ApplySchemeSettings", "Scheme", "GameNotice" )
|
||||
Derma_Hook( PANEL, "PerformLayout", "Layout", "GameNotice" )
|
||||
|
||||
function PANEL:Init()
|
||||
self.m_bHighlight = false
|
||||
self.Padding = 8
|
||||
self.Spacing = 8
|
||||
self.Items = {}
|
||||
end
|
||||
|
||||
function PANEL:AddEntityText( txt )
|
||||
|
||||
if ( type( txt ) == "string" ) then return false end
|
||||
|
||||
if ( type( txt ) == "Player" ) then
|
||||
|
||||
self:AddText( txt:Nick(), GAMEMODE:GetTeamColor( txt ) )
|
||||
if ( txt == LocalPlayer() ) then self.m_bHighlight = true end
|
||||
|
||||
return true
|
||||
|
||||
end
|
||||
|
||||
if( txt:IsValid() ) then
|
||||
self:AddText( txt:GetClass(), GAMEMODE.DeathNoticeDefaultColor )
|
||||
else
|
||||
self:AddText( tostring( txt ) )
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
function PANEL:AddItem( item )
|
||||
|
||||
table.insert( self.Items, item )
|
||||
self:InvalidateLayout( true )
|
||||
|
||||
end
|
||||
|
||||
function PANEL:AddText( txt, color )
|
||||
|
||||
if ( self:AddEntityText( txt ) ) then return end
|
||||
|
||||
local txt = tostring( txt )
|
||||
|
||||
local lbl = vgui.Create( "DLabel", self )
|
||||
|
||||
Derma_Hook( lbl, "ApplySchemeSettings", "Scheme", "GameNoticeLabel" )
|
||||
lbl:ApplySchemeSettings()
|
||||
lbl:SetText( txt )
|
||||
|
||||
if( string.Left( txt , 1 ) == "#" && !color ) then color = GAMEMODE.DeathNoticeDefaultColor end // localised ent death
|
||||
if( GAMEMODE.DeathNoticeTextColor && !color ) then color = GAMEMODE.DeathNoticeTextColor end // something else
|
||||
if ( !color ) then color = color_white end
|
||||
|
||||
lbl:SetTextColor( color )
|
||||
|
||||
self:AddItem( lbl )
|
||||
|
||||
end
|
||||
|
||||
function PANEL:AddIcon( txt )
|
||||
|
||||
if ( killicon.Exists( txt ) ) then
|
||||
|
||||
local icon = vgui.Create( "DKillIcon", self )
|
||||
icon:SetName( txt )
|
||||
icon:SizeToContents()
|
||||
|
||||
self:AddItem( icon )
|
||||
|
||||
else
|
||||
|
||||
self:AddText( "killed" )
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
function PANEL:PerformLayout()
|
||||
|
||||
local x = self.Padding
|
||||
local height = self.Padding * 0.5
|
||||
|
||||
for k, v in pairs( self.Items ) do
|
||||
|
||||
v:SetPos( x, self.Padding * 0.5 )
|
||||
v:SizeToContents()
|
||||
|
||||
x = x + v:GetWide() + self.Spacing
|
||||
height = math.max( height, v:GetTall() + self.Padding )
|
||||
|
||||
end
|
||||
|
||||
self:SetSize( x + self.Padding, height )
|
||||
|
||||
end
|
||||
|
||||
derma.DefineControl( "GameNotice", "", PANEL, "DPanel" )
|
|
@ -0,0 +1,47 @@
|
|||
local PANEL = {}
|
||||
|
||||
surface.CreateLegacyFont( "Roboto", 32, 800, true, false, "FHUDElement" )
|
||||
|
||||
AccessorFunc( PANEL, "m_bPartOfBar", "PartOfBar" )
|
||||
|
||||
function PANEL:Init()
|
||||
|
||||
self:SetText( "-" )
|
||||
self:SetTextColor( self:GetDefaultTextColor() )
|
||||
self:SetFont( "FHUDElement" )
|
||||
|
||||
self:ChooseParent()
|
||||
|
||||
end
|
||||
|
||||
// This makes it so that it's behind chat & hides when you're in the menu
|
||||
// But it also removes the ability to click on it. So override it if you want to.
|
||||
function PANEL:ChooseParent()
|
||||
self:ParentToHUD()
|
||||
end
|
||||
|
||||
function PANEL:GetPadding()
|
||||
return 16
|
||||
end
|
||||
|
||||
function PANEL:GetDefaultTextColor()
|
||||
return Color( 255, 255, 255, 255 )
|
||||
end
|
||||
|
||||
function PANEL:GetTextLabelColor()
|
||||
return Color( 255, 255, 0 )
|
||||
end
|
||||
|
||||
function PANEL:GetTextLabelFont()
|
||||
return "HudSelectionText"
|
||||
end
|
||||
|
||||
function PANEL:Paint()
|
||||
|
||||
if ( !self.m_bPartOfBar ) then
|
||||
draw.RoundedBox( 4, 0, 0, self:GetWide(), self:GetTall(), Color( 0, 0, 0, 100 ) )
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
derma.DefineControl( "HudBase", "A HUD Base Element (override to change the style)", PANEL, "DLabel" )
|
|
@ -0,0 +1,107 @@
|
|||
local PANEL = {}
|
||||
AccessorFunc( PANEL, "m_Items", "Items" )
|
||||
AccessorFunc( PANEL, "m_Horizontal", "Horizontal" )
|
||||
AccessorFunc( PANEL, "m_Spacing", "Spacing" )
|
||||
|
||||
AccessorFunc( PANEL, "m_AlignBottom", "AlignBottom" )
|
||||
AccessorFunc( PANEL, "m_AlignCenter", "AlignCenter" )
|
||||
|
||||
function PANEL:Init()
|
||||
self.m_Items = {}
|
||||
self:SetHorizontal( true )
|
||||
self:SetText( "" )
|
||||
self:SetAlignCenter( true )
|
||||
self:SetSpacing( 8 )
|
||||
end
|
||||
|
||||
function PANEL:AddItem( item )
|
||||
item:SetParent( self )
|
||||
table.insert( self.m_Items, item )
|
||||
self:InvalidateLayout()
|
||||
item:SetPaintBackgroundEnabled( false )
|
||||
item.m_bPartOfBar = true
|
||||
end
|
||||
|
||||
function PANEL:PerformLayout()
|
||||
|
||||
if ( self.m_Horizontal ) then
|
||||
local x = self.m_Spacing
|
||||
local tallest = 0
|
||||
for k, v in pairs( self.m_Items ) do
|
||||
|
||||
v:SetPos( x, 0 )
|
||||
x = x + v:GetWide() + self.m_Spacing
|
||||
tallest = math.max( tallest, v:GetTall() )
|
||||
|
||||
if ( self.m_AlignBottom ) then v:AlignBottom() end
|
||||
if ( self.m_AlignCenter ) then v:CenterVertical() end
|
||||
|
||||
end
|
||||
self:SetSize( x, tallest )
|
||||
else
|
||||
// todo.
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
derma.DefineControl( "DHudBar", "", PANEL, "HudBase" )
|
||||
|
||||
local PANEL = {}
|
||||
AccessorFunc( PANEL, "m_ValueFunction", "ValueFunction" )
|
||||
AccessorFunc( PANEL, "m_ColorFunction", "ColorFunction" )
|
||||
|
||||
/*---------------------------------------------------------
|
||||
Name: Init
|
||||
---------------------------------------------------------*/
|
||||
function PANEL:Init()
|
||||
|
||||
end
|
||||
|
||||
function PANEL:GetTextValueFromFunction()
|
||||
if (!self.m_ValueFunction) then return "-" end
|
||||
return tostring( self:m_ValueFunction() )
|
||||
end
|
||||
|
||||
function PANEL:GetColorFromFunction()
|
||||
if (!self.m_ColorFunction) then return self:GetDefaultTextColor() end
|
||||
return self:m_ColorFunction()
|
||||
end
|
||||
|
||||
function PANEL:Think()
|
||||
self:SetTextColor( self:GetColorFromFunction() )
|
||||
self:SetText( self:GetTextValueFromFunction() )
|
||||
end
|
||||
|
||||
derma.DefineControl( "DHudUpdater", "A HUD Element", PANEL, "DHudElement" )
|
||||
|
||||
|
||||
local PANEL = {}
|
||||
AccessorFunc( PANEL, "m_Function", "Function" )
|
||||
|
||||
/*---------------------------------------------------------
|
||||
Name: Init
|
||||
---------------------------------------------------------*/
|
||||
function PANEL:Init()
|
||||
HudBase.Init( self )
|
||||
end
|
||||
|
||||
function PANEL:Think()
|
||||
|
||||
if ( !self.m_ValueFunction ) then return end
|
||||
|
||||
self:SetTextColor( self:GetColorFromFunction() )
|
||||
|
||||
local EndTime = self:m_ValueFunction()
|
||||
if ( EndTime == -1 ) then return end
|
||||
|
||||
if ( !EndTime || EndTime < CurTime() ) then
|
||||
self:SetText( "00:00" )
|
||||
return
|
||||
end
|
||||
|
||||
local Time = util.ToMinutesSeconds( EndTime - CurTime() )
|
||||
self:SetText( Time )
|
||||
|
||||
end
|
||||
|
||||
derma.DefineControl( "DHudCountdown", "A HUD Element", PANEL, "DHudUpdater" )
|
|
@ -0,0 +1,39 @@
|
|||
local PANEL = {}
|
||||
|
||||
/*---------------------------------------------------------
|
||||
Name: Init
|
||||
---------------------------------------------------------*/
|
||||
function PANEL:Init()
|
||||
|
||||
end
|
||||
|
||||
function PANEL:SetLabel( text )
|
||||
|
||||
self.LabelPanel = vgui.Create( "DLabel", self )
|
||||
self.LabelPanel:SetText( text )
|
||||
self.LabelPanel:SetTextColor( self:GetTextLabelColor() )
|
||||
self.LabelPanel:SetFont( self:GetTextLabelFont() )
|
||||
|
||||
end
|
||||
|
||||
/*---------------------------------------------------------
|
||||
Name: PerformLayout
|
||||
---------------------------------------------------------*/
|
||||
function PANEL:PerformLayout()
|
||||
|
||||
self:SetContentAlignment( 5 )
|
||||
|
||||
if ( self.LabelPanel ) then
|
||||
self.LabelPanel:SetPos( self:GetPadding(), self:GetPadding() )
|
||||
self.LabelPanel:SizeToContents()
|
||||
self.LabelPanel:SetSize( self.LabelPanel:GetWide() + self:GetPadding() * 0.5, self.LabelPanel:GetTall() + self:GetPadding() * 0.5 )
|
||||
self:SetTextInset( self.LabelPanel:GetWide() + self:GetPadding(), 0 )
|
||||
self:SetContentAlignment( 4 )
|
||||
end
|
||||
|
||||
self:SizeToContents( )
|
||||
self:SetSize( self:GetWide() + self:GetPadding(), self:GetTall() + self:GetPadding() )
|
||||
|
||||
end
|
||||
|
||||
derma.DefineControl( "DHudElement", "A HUD Element", PANEL, "HudBase" )
|
|
@ -0,0 +1,161 @@
|
|||
local PANEL = {}
|
||||
|
||||
AccessorFunc( PANEL, "Spacing", "Spacing" )
|
||||
|
||||
/*---------------------------------------------------------
|
||||
Name: Init
|
||||
---------------------------------------------------------*/
|
||||
function PANEL:Init()
|
||||
|
||||
self.Items = {}
|
||||
|
||||
self:SetSpacing( 8 )
|
||||
|
||||
self:SetPaintBackgroundEnabled( false )
|
||||
self:SetPaintBorderEnabled( false )
|
||||
|
||||
self:ParentToHUD()
|
||||
|
||||
end
|
||||
|
||||
// This makes it so that it's behind chat & hides when you're in the menu
|
||||
// But it also removes the ability to click on it. So override it if you want to.
|
||||
function PANEL:ChooseParent()
|
||||
self:ParentToHUD()
|
||||
end
|
||||
|
||||
/*---------------------------------------------------------
|
||||
Name: GetCanvas
|
||||
---------------------------------------------------------*/
|
||||
function PANEL:Clear( bDelete )
|
||||
|
||||
for k, panel in pairs( self.Items ) do
|
||||
|
||||
if ( panel && panel:IsValid() ) then
|
||||
|
||||
panel:SetParent( panel )
|
||||
panel:SetVisible( false )
|
||||
|
||||
if ( bDelete ) then
|
||||
panel:Remove()
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
self.Items = {}
|
||||
|
||||
end
|
||||
|
||||
/*---------------------------------------------------------
|
||||
Name: AddItem
|
||||
---------------------------------------------------------*/
|
||||
function PANEL:AddItem( item, relative, pos )
|
||||
|
||||
if (!item || !item:IsValid()) then return end
|
||||
|
||||
item.HUDPos = pos
|
||||
item.HUDrelative = relative
|
||||
|
||||
item:SetVisible( true )
|
||||
item:SetParent( self )
|
||||
table.insert( self.Items, item )
|
||||
|
||||
self:InvalidateLayout()
|
||||
|
||||
end
|
||||
|
||||
function PANEL:PositionItem( item )
|
||||
|
||||
if ( item.Positioned ) then return end
|
||||
if ( IsValid( item.HUDrelative ) && item != item.HUDrelative ) then self:PositionItem( item.HUDrelative ) end
|
||||
|
||||
local SPACING = self:GetSpacing()
|
||||
|
||||
item:InvalidateLayout( true )
|
||||
|
||||
if ( item.HUDPos == 7 || item.HUDPos == 8 || item.HUDPos == 9 ) then
|
||||
if ( IsValid( item.HUDrelative ) ) then
|
||||
item:MoveAbove( item.HUDrelative, SPACING )
|
||||
else
|
||||
item:AlignTop()
|
||||
end
|
||||
end
|
||||
|
||||
if ( item.HUDPos == 4 || item.HUDPos == 5 || item.HUDPos == 6 ) then
|
||||
if ( IsValid( item.HUDrelative ) ) then
|
||||
item.y = item.HUDrelative.y
|
||||
else
|
||||
item:CenterVertical()
|
||||
end
|
||||
end
|
||||
|
||||
if ( item.HUDPos == 1 || item.HUDPos == 2 || item.HUDPos == 3 ) then
|
||||
if ( IsValid( item.HUDrelative ) ) then
|
||||
item:MoveBelow( item.HUDrelative, SPACING )
|
||||
else
|
||||
item:AlignBottom()
|
||||
end
|
||||
end
|
||||
|
||||
if ( item.HUDPos == 7 || item.HUDPos == 4 || item.HUDPos == 1 ) then
|
||||
if ( IsValid( item.HUDrelative ) ) then
|
||||
item.x = item.HUDrelative.x
|
||||
else
|
||||
item:AlignLeft()
|
||||
end
|
||||
end
|
||||
|
||||
if ( item.HUDPos == 8 || item.HUDPos == 5 || item.HUDPos == 2 ) then
|
||||
if ( IsValid( item.HUDrelative ) ) then
|
||||
item.x = item.HUDrelative.x + ( item.HUDrelative:GetWide() - item:GetWide() ) / 2
|
||||
else
|
||||
item:CenterHorizontal()
|
||||
end
|
||||
end
|
||||
|
||||
if ( item.HUDPos == 9 || item.HUDPos == 6 || item.HUDPos == 3 ) then
|
||||
if ( IsValid( item.HUDrelative ) ) then
|
||||
item.x = item.HUDrelative.x + item.HUDrelative:GetWide() - item:GetWide()
|
||||
else
|
||||
item:AlignRight()
|
||||
end
|
||||
end
|
||||
|
||||
if ( item.HUDPos == 4 && IsValid( item.HUDrelative ) ) then
|
||||
item:MoveLeftOf( item.HUDrelative, SPACING )
|
||||
end
|
||||
|
||||
if ( item.HUDPos == 6 && IsValid( item.HUDrelative ) ) then
|
||||
item:MoveRightOf( item.HUDrelative, SPACING )
|
||||
end
|
||||
|
||||
item.Positioned = true
|
||||
|
||||
end
|
||||
|
||||
function PANEL:Think()
|
||||
self:InvalidateLayout()
|
||||
end
|
||||
|
||||
/*---------------------------------------------------------
|
||||
Name: PerformLayout
|
||||
---------------------------------------------------------*/
|
||||
function PANEL:PerformLayout()
|
||||
|
||||
self:SetPos( 32, 32 )
|
||||
self:SetWide( ScrW() - 64 )
|
||||
self:SetTall( ScrH() - 64 )
|
||||
|
||||
for k, item in pairs( self.Items ) do
|
||||
item.Positioned = false
|
||||
end
|
||||
|
||||
for k, item in pairs( self.Items ) do
|
||||
self:PositionItem( item )
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
derma.DefineControl( "DHudLayout", "A HUD Layout Base", PANEL, "Panel" )
|
|
@ -0,0 +1,219 @@
|
|||
include( "vgui_scoreboard_team.lua" )
|
||||
include( "vgui_scoreboard_small.lua" )
|
||||
|
||||
local PANEL = {}
|
||||
|
||||
Derma_Hook( PANEL, "Paint", "Paint", "ScoreHeader" )
|
||||
Derma_Hook( PANEL, "ApplySchemeSettings", "Scheme", "ScoreHeader" )
|
||||
Derma_Hook( PANEL, "PerformLayout", "Layout", "ScoreHeader" )
|
||||
|
||||
|
||||
function PANEL:Init()
|
||||
|
||||
self.Columns = {}
|
||||
self.iTeamID = 0
|
||||
|
||||
self.HostName = vgui.Create( "DLabel", self )
|
||||
self.HostName:SetText( GetHostName() )
|
||||
|
||||
self.GamemodeName = vgui.Create( "DLabel", self )
|
||||
self.GamemodeName:SetText( GAMEMODE.Name .. " | Version: ".. GAMEMODE._VERSION .. " - Rev. ".. GAMEMODE.REVISION )
|
||||
|
||||
self:SetHeight( 64 )
|
||||
|
||||
end
|
||||
|
||||
derma.DefineControl( "ScoreboardHeader", "", PANEL, "Panel" )
|
||||
|
||||
|
||||
local PANEL = {}
|
||||
|
||||
|
||||
AccessorFunc( PANEL, "m_bHorizontal", "Horizontal" )
|
||||
AccessorFunc( PANEL, "m_iPadding", "Padding" )
|
||||
AccessorFunc( PANEL, "m_iRowHeight", "RowHeight" )
|
||||
AccessorFunc( PANEL, "m_bShowScoreHeaders", "ShowScoreboardHeaders" )
|
||||
|
||||
Derma_Hook( PANEL, "Paint", "Paint", "ScorePanel" )
|
||||
Derma_Hook( PANEL, "ApplySchemeSettings", "Scheme", "ScorePanel" )
|
||||
Derma_Hook( PANEL, "PerformLayout", "Layout", "ScorePanel" )
|
||||
|
||||
function PANEL:Init()
|
||||
|
||||
self.SortDesc = true
|
||||
|
||||
self.Boards = {}
|
||||
self.SmallBoards = {}
|
||||
self.Columns = {}
|
||||
|
||||
self:SetRowHeight( 32 )
|
||||
self:SetHorizontal( false )
|
||||
self:SetPadding( 10 )
|
||||
self:SetShowScoreboardHeaders( true )
|
||||
|
||||
self.Header = vgui.Create( "ScoreboardHeader", self )
|
||||
|
||||
local teams = team.GetAllTeams()
|
||||
for k, v in pairs( teams ) do
|
||||
|
||||
local ScoreBoard = vgui.Create( "TeamScoreboard", self )
|
||||
ScoreBoard:Setup( k, self )
|
||||
self.Boards[ k ] = ScoreBoard
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
function PANEL:SetAsBullshitTeam( iTeamID )
|
||||
|
||||
if ( IsValid( self.Boards[ iTeamID ] ) ) then
|
||||
self.Boards[ iTeamID ]:Remove()
|
||||
self.Boards[ iTeamID ] = nil
|
||||
end
|
||||
|
||||
self.SmallBoards[ iTeamID ] = vgui.Create( "TeamBoardSmall", self )
|
||||
self.SmallBoards[ iTeamID ]:Setup( iTeamID, self )
|
||||
|
||||
end
|
||||
|
||||
function PANEL:SetSortColumns( ... )
|
||||
|
||||
for k, v in pairs( self.Boards ) do
|
||||
v:SetSortColumns( ... )
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
function PANEL:AddColumn( Name, iFixedSize, fncValue, UpdateRate, TeamID, HeaderAlign, ValueAlign, Font )
|
||||
|
||||
local Col = {}
|
||||
|
||||
Col.Name = Name
|
||||
Col.iFixedSize = iFixedSize
|
||||
Col.fncValue = fncValue
|
||||
Col.TeamID = TeamID
|
||||
Col.UpdateRate = UpdateRate
|
||||
Col.ValueAlign = ValueAlign
|
||||
Col.HeaderAlign = HeaderAlign
|
||||
Col.Font = Font
|
||||
|
||||
for k, v in pairs( self.Boards ) do
|
||||
v:AddColumn( Col )
|
||||
end
|
||||
|
||||
return Col
|
||||
|
||||
end
|
||||
|
||||
function PANEL:Layout4By4( y )
|
||||
|
||||
local a = self.Boards[1]
|
||||
local b = self.Boards[2]
|
||||
local c = self.Boards[3]
|
||||
local d = self.Boards[4]
|
||||
|
||||
local widtheach = (self:GetWide() - ( self.m_iPadding * 3 )) / 2
|
||||
|
||||
for k, v in pairs( self.Boards ) do
|
||||
|
||||
v:SizeToContents()
|
||||
v:SetWide( widtheach )
|
||||
|
||||
end
|
||||
|
||||
a:SetPos( self.m_iPadding, y + self.m_iPadding )
|
||||
b:SetPos( a:GetPos() + a:GetWide() + self.m_iPadding, y + self.m_iPadding )
|
||||
|
||||
local height = a:GetTall() + a.y
|
||||
height = math.max( b:GetTall() + b.y, height )
|
||||
height = height + self.m_iPadding * 2
|
||||
|
||||
c:SetPos( self.m_iPadding, height )
|
||||
d:SetPos( c:GetPos() + c:GetWide() + self.m_iPadding, height )
|
||||
|
||||
local height = d:GetTall() + d.y
|
||||
height = math.max( c:GetTall() + c.y, height )
|
||||
height = height + self.m_iPadding * 2
|
||||
|
||||
return height
|
||||
|
||||
end
|
||||
|
||||
function PANEL:LayoutHorizontal( y )
|
||||
|
||||
local cols = table.Count( self.Boards )
|
||||
|
||||
if ( cols == 4 ) then
|
||||
return self:Layout4By4( y )
|
||||
end
|
||||
|
||||
local widtheach = (self:GetWide() - ( self.m_iPadding * (cols+1) )) / cols
|
||||
|
||||
local x = self.m_iPadding
|
||||
local tallest = 0
|
||||
for k, v in pairs( self.Boards ) do
|
||||
|
||||
v:SizeToContents()
|
||||
v:SetPos( x, y )
|
||||
v:SetWide( widtheach )
|
||||
|
||||
x = x + widtheach + self.m_iPadding
|
||||
tallest = math.max( tallest, y + v:GetTall() + self.m_iPadding )
|
||||
|
||||
end
|
||||
|
||||
return tallest
|
||||
|
||||
end
|
||||
|
||||
function PANEL:LayoutVertical( y )
|
||||
|
||||
for k, v in pairs( self.Boards ) do
|
||||
|
||||
v:SizeToContents()
|
||||
v:SetPos( self.m_iPadding, y )
|
||||
v:SetWide( self:GetWide() - self.m_iPadding * 2 )
|
||||
y = y + v:GetTall() + self.m_iPadding
|
||||
|
||||
end
|
||||
|
||||
return y
|
||||
|
||||
end
|
||||
|
||||
function PANEL:PerformLayout()
|
||||
|
||||
local y = 0
|
||||
|
||||
if ( IsValid( self.Header ) ) then
|
||||
|
||||
self.Header:SetPos( 0, 0 )
|
||||
self.Header:SetWidth( self:GetWide() )
|
||||
|
||||
y = y + self.Header:GetTall() + self.m_iPadding
|
||||
|
||||
end
|
||||
|
||||
if ( self.m_bHorizontal ) then
|
||||
y = self:LayoutHorizontal( y )
|
||||
else
|
||||
y = self:LayoutVertical( y )
|
||||
end
|
||||
|
||||
for k, v in pairs( self.SmallBoards ) do
|
||||
|
||||
if ( v:ShouldShow() ) then
|
||||
|
||||
v:SizeToContents()
|
||||
|
||||
v:SetPos( self.m_iPadding, y )
|
||||
v:CenterHorizontal()
|
||||
|
||||
y = y + v:GetTall() + self.m_iPadding
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
derma.DefineControl( "FrettaScoreboard", "", PANEL, "DPanel" )
|
|
@ -0,0 +1,67 @@
|
|||
local PANEL = {}
|
||||
|
||||
Derma_Hook( PANEL, "Paint", "Paint", "SpectatorInfo" )
|
||||
Derma_Hook( PANEL, "ApplySchemeSettings", "Scheme", "SpectatorInfo" )
|
||||
Derma_Hook( PANEL, "PerformLayout", "Layout", "SpectatorInfo" )
|
||||
|
||||
function PANEL:Init()
|
||||
|
||||
self.LastThink = 0
|
||||
|
||||
end
|
||||
|
||||
function PANEL:Setup( iTeam, pMainScoreboard )
|
||||
self.iTeam = iTeam
|
||||
end
|
||||
|
||||
function PANEL:GetPlayers()
|
||||
return team.GetPlayers( self.iTeam )
|
||||
end
|
||||
|
||||
function PANEL:ShouldShow()
|
||||
|
||||
local players = team.GetPlayers( self.iTeam )
|
||||
if ( !players || #players == 0 ) then
|
||||
return false
|
||||
end
|
||||
|
||||
return true
|
||||
|
||||
end
|
||||
|
||||
function PANEL:UpdateText( NewText )
|
||||
|
||||
local OldText = self:GetValue()
|
||||
if ( OldText == NewText ) then return end
|
||||
|
||||
self:SetText( NewText )
|
||||
self:SizeToContents()
|
||||
self:InvalidateLayout()
|
||||
self:GetParent():InvalidateLayout()
|
||||
|
||||
end
|
||||
|
||||
function PANEL:Think()
|
||||
|
||||
if ( self.LastThink > RealTime() ) then return end
|
||||
self.LastThink = RealTime() + 1
|
||||
|
||||
local players = team.GetPlayers( self.iTeam )
|
||||
if ( !players || #players == 0 ) then
|
||||
local OldText = self:GetValue()
|
||||
self:UpdateText( "" )
|
||||
return
|
||||
end
|
||||
|
||||
local Str = team.GetName( self.iTeam ) .. ": "
|
||||
|
||||
for k, v in pairs( players ) do
|
||||
Str = Str .. v:Name() .. ", "
|
||||
end
|
||||
|
||||
Str = Str:sub( 0, -3 )
|
||||
self:UpdateText( Str )
|
||||
|
||||
end
|
||||
|
||||
derma.DefineControl( "TeamBoardSmall", "", PANEL, "DLabel" )
|
|
@ -0,0 +1,218 @@
|
|||
local PANEL = {}
|
||||
|
||||
Derma_Hook( PANEL, "Paint", "Paint", "TeamScoreboardHeader" )
|
||||
Derma_Hook( PANEL, "ApplySchemeSettings", "Scheme", "TeamScoreboardHeader" )
|
||||
Derma_Hook( PANEL, "PerformLayout", "Layout", "TeamScoreboardHeader" )
|
||||
|
||||
function PANEL:Init()
|
||||
|
||||
self.Columns = {}
|
||||
self.iTeamID = 0
|
||||
self.PlayerCount = 0
|
||||
|
||||
self.TeamName = vgui.Create( "DLabel", self )
|
||||
self.TeamScore = vgui.Create( "DLabel", self )
|
||||
|
||||
end
|
||||
|
||||
function PANEL:Setup( iTeam, pMainScoreboard )
|
||||
|
||||
self.TeamName:SetText( team.GetName( iTeam ) )
|
||||
self.iTeamID = iTeam
|
||||
|
||||
end
|
||||
|
||||
function PANEL:Think()
|
||||
|
||||
local Count = #team.GetPlayers( self.iTeamID )
|
||||
if ( self.PlayerCount != Count ) then
|
||||
self.PlayerCount = Count
|
||||
self.TeamName:SetText( team.GetName( self.iTeamID ) .. " (" .. self.PlayerCount .. " Players)" )
|
||||
end
|
||||
|
||||
self.TeamScore:SetText( team.GetScore( self.iTeamID ) )
|
||||
|
||||
end
|
||||
|
||||
derma.DefineControl( "TeamScoreboardHeader", "", PANEL, "Panel" )
|
||||
|
||||
|
||||
|
||||
|
||||
local PANEL = {}
|
||||
|
||||
function PANEL:Init()
|
||||
|
||||
self.Columns = {}
|
||||
|
||||
self.List = vgui.Create( "DListView", self )
|
||||
self.List:SetSortable( false )
|
||||
self.List:DisableScrollbar()
|
||||
|
||||
self.Header = vgui.Create( "TeamScoreboardHeader", self )
|
||||
|
||||
end
|
||||
|
||||
function PANEL:Setup( iTeam, pMainScoreboard )
|
||||
|
||||
self.iTeam = iTeam
|
||||
self.pMain = pMainScoreboard
|
||||
|
||||
self.Header:Setup( iTeam, pMainScoreboard )
|
||||
|
||||
end
|
||||
|
||||
function PANEL:SizeToContents()
|
||||
|
||||
self.List:SizeToContents()
|
||||
local tall = self.List:GetTall()
|
||||
|
||||
self:SetTall( tall + self.Header:GetTall() )
|
||||
|
||||
end
|
||||
|
||||
function PANEL:PerformLayout()
|
||||
|
||||
if ( self.pMain:GetShowScoreboardHeaders() ) then
|
||||
|
||||
self.Header:SetPos( 0, 0 )
|
||||
self.Header:CopyWidth( self )
|
||||
|
||||
else
|
||||
|
||||
self.Header:SetTall( 0 )
|
||||
self.Header:SetVisible( false )
|
||||
|
||||
end
|
||||
|
||||
self:SizeToContents()
|
||||
self.List:StretchToParent( 0, self.Header:GetTall(), 0, 0 )
|
||||
self.List:SetDataHeight( self.pMain:GetRowHeight() )
|
||||
self.List:SetHeaderHeight( 16 )
|
||||
|
||||
end
|
||||
|
||||
function PANEL:AddColumn( col )
|
||||
|
||||
table.insert( self.Columns, col )
|
||||
|
||||
local pnlCol = self.List:AddColumn( col.Name )
|
||||
|
||||
if (col.iFixedSize) then pnlCol:SetMinWidth( col.iFixedSize ) pnlCol:SetMaxWidth( col.iFixedSize ) end
|
||||
if (col.HeaderAlign) then
|
||||
pnlCol.Header:SetContentAlignment( col.HeaderAlign )
|
||||
end
|
||||
|
||||
-- Credits to dhantasmic on GitHub for this fix
|
||||
pnlCol:GetChildren()[1]:SetVisible( false )
|
||||
pnlCol:GetChildren()[2]:SetVisible( false )
|
||||
|
||||
Derma_Hook( pnlCol, "Paint", "Paint", "ScorePanelHeader" )
|
||||
|
||||
pnlCol.cTeamColor = team.GetColor( self.iTeam )
|
||||
|
||||
Derma_Hook( pnlCol.Header, "Paint", "Paint", "ScorePanelHeaderLabel" )
|
||||
Derma_Hook( pnlCol.Header, "ApplySchemeSettings", "Scheme", "ScorePanelHeaderLabel" )
|
||||
Derma_Hook( pnlCol.Header, "PerformLayout", "Layout", "ScorePanelHeaderLabel" )
|
||||
|
||||
pnlCol.Header:ApplySchemeSettings()
|
||||
|
||||
end
|
||||
|
||||
function PANEL:SetSortColumns( ... )
|
||||
|
||||
self.SortArgs = ...
|
||||
|
||||
end
|
||||
|
||||
function PANEL:FindPlayerLine( ply )
|
||||
|
||||
for _, line in pairs( self.List.Lines ) do
|
||||
if ( line.pPlayer == ply ) then return line end
|
||||
end
|
||||
|
||||
local line = self.List:AddLine()
|
||||
line.pPlayer = ply
|
||||
line.UpdateTime = {}
|
||||
|
||||
Derma_Hook( line, "Paint", "Paint", "ScorePanelLine" )
|
||||
Derma_Hook( line, "ApplySchemeSettings", "Scheme", "ScorePanelLine" )
|
||||
Derma_Hook( line, "PerformLayout", "Layout", "ScorePanelLine" )
|
||||
|
||||
self.pMain:InvalidateLayout()
|
||||
|
||||
return line
|
||||
|
||||
end
|
||||
|
||||
function PANEL:UpdateColumn( i, col, pLine )
|
||||
|
||||
if ( !col.fncValue ) then return end
|
||||
|
||||
pLine.UpdateTime[i] = pLine.UpdateTime[i] or 0
|
||||
if ( col.UpdateRate == 0 && pLine.UpdateTime[i] != 0 ) then return end // 0 = only update once
|
||||
if ( pLine.UpdateTime[i] > RealTime() ) then return end
|
||||
|
||||
pLine.UpdateTime[i] = RealTime() + col.UpdateRate
|
||||
|
||||
local Value = col.fncValue( pLine.pPlayer )
|
||||
if ( Value == nil ) then return end
|
||||
|
||||
local lbl = pLine:SetColumnText( i, Value )
|
||||
if ( IsValid( lbl ) && !lbl.bScorePanelHooks ) then
|
||||
|
||||
lbl.bScorePanelHooks = true
|
||||
|
||||
if ( col.ValueAlign ) then lbl:SetContentAlignment( col.ValueAlign ) end
|
||||
if ( col.Font ) then lbl:SetFont( col.Font ) end
|
||||
|
||||
lbl.pPlayer = pLine.pPlayer
|
||||
|
||||
Derma_Hook( lbl, "Paint", "Paint", "ScorePanelLabel" )
|
||||
Derma_Hook( lbl, "ApplySchemeSettings", "Scheme", "ScorePanelLabel" )
|
||||
Derma_Hook( lbl, "PerformLayout", "Layout", "ScorePanelLabel" )
|
||||
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
function PANEL:UpdateLine( pLine )
|
||||
|
||||
for i, col in pairs( self.Columns ) do
|
||||
self:UpdateColumn( i, col, pLine )
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
function PANEL:CleanLines( pLine )
|
||||
|
||||
for k, line in pairs( self.List.Lines ) do
|
||||
|
||||
if ( !IsValid( line.pPlayer ) || line.pPlayer:Team() != self.iTeam ) then
|
||||
self.List:RemoveLine( k )
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
function PANEL:Think()
|
||||
|
||||
self:CleanLines()
|
||||
|
||||
local players = team.GetPlayers( self.iTeam )
|
||||
for _, player in pairs( players ) do
|
||||
|
||||
local line = self:FindPlayerLine( player )
|
||||
self:UpdateLine( line )
|
||||
|
||||
end
|
||||
|
||||
if ( self.SortArgs ) then
|
||||
self.List:SortByColumns( unpack(self.SortArgs) )
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
derma.DefineControl( "TeamScoreboard", "", PANEL, "Panel" )
|
|
@ -0,0 +1,240 @@
|
|||
local PANEL = {}
|
||||
|
||||
function PANEL:Init()
|
||||
|
||||
self:SetSkin( GAMEMODE.HudSkin )
|
||||
self:ParentToHUD()
|
||||
|
||||
self.ControlCanvas = vgui.Create( "Panel", self )
|
||||
self.ControlCanvas:MakePopup()
|
||||
self.ControlCanvas:SetKeyboardInputEnabled( false )
|
||||
|
||||
self.lblCountDown = vgui.Create( "DLabel", self.ControlCanvas )
|
||||
self.lblCountDown:SetText( "60" )
|
||||
|
||||
self.lblActionName = vgui.Create( "DLabel", self.ControlCanvas )
|
||||
|
||||
self.ctrlList = vgui.Create( "DPanelList", self.ControlCanvas )
|
||||
self.ctrlList:SetDrawBackground( false )
|
||||
self.ctrlList:SetSpacing( 2 )
|
||||
self.ctrlList:SetPadding( 2 )
|
||||
self.ctrlList:EnableHorizontal( true )
|
||||
self.ctrlList:EnableVerticalScrollbar()
|
||||
|
||||
self.Peeps = {}
|
||||
|
||||
for i =1, game.MaxPlayers() do
|
||||
|
||||
self.Peeps[i] = vgui.Create( "DImage", self.ctrlList:GetCanvas() )
|
||||
self.Peeps[i]:SetSize( 16, 16 )
|
||||
self.Peeps[i]:SetZPos( 1000 )
|
||||
self.Peeps[i]:SetVisible( false )
|
||||
self.Peeps[i]:SetImage( "icon16/emoticon_smile.png" )
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
function PANEL:PerformLayout()
|
||||
|
||||
local cx, cy = chat.GetChatBoxPos()
|
||||
|
||||
self:SetPos( 0, 0 )
|
||||
self:SetSize( ScrW(), ScrH() )
|
||||
|
||||
self.ControlCanvas:StretchToParent( 0, 0, 0, 0 )
|
||||
self.ControlCanvas:SetWide( 550 )
|
||||
self.ControlCanvas:SetTall( cy - 30 )
|
||||
self.ControlCanvas:SetPos( 0, 30 )
|
||||
self.ControlCanvas:CenterHorizontal();
|
||||
self.ControlCanvas:SetZPos( 0 )
|
||||
|
||||
self.lblCountDown:SetFont( "FRETTA_MEDIUM_SHADOW" )
|
||||
self.lblCountDown:AlignRight()
|
||||
self.lblCountDown:SetTextColor( color_white )
|
||||
self.lblCountDown:SetContentAlignment( 6 )
|
||||
self.lblCountDown:SetWidth( 500 )
|
||||
|
||||
self.lblActionName:SetFont( "FRETTA_LARGE_SHADOW" )
|
||||
self.lblActionName:AlignLeft()
|
||||
self.lblActionName:SetTextColor( color_white )
|
||||
self.lblActionName:SizeToContents()
|
||||
self.lblActionName:SetWidth( 500 )
|
||||
|
||||
self.ctrlList:StretchToParent( 0, 60, 0, 0 )
|
||||
|
||||
end
|
||||
|
||||
function PANEL:ChooseGamemode()
|
||||
|
||||
self.lblActionName:SetText( "Which Gamemode Next?" )
|
||||
self.ctrlList:Clear()
|
||||
|
||||
for name, gamemode in RandomPairs( g_PlayableGamemodes ) do
|
||||
|
||||
local lbl = vgui.Create( "DButton", self.ctrlList )
|
||||
lbl:SetText( gamemode.label )
|
||||
|
||||
Derma_Hook( lbl, "Paint", "Paint", "GamemodeButton" )
|
||||
Derma_Hook( lbl, "ApplySchemeSettings", "Scheme", "GamemodeButton" )
|
||||
Derma_Hook( lbl, "PerformLayout", "Layout", "GamemodeButton" )
|
||||
|
||||
lbl:SetTall( 24 )
|
||||
lbl:SetWide( 240 )
|
||||
|
||||
local desc = tostring( gamemode.description );
|
||||
if ( gamemode.author ) then desc = desc .. "\n\nBy: " .. tostring( gamemode.author ) end
|
||||
if ( gamemode.authorurl ) then desc = desc .. "\n" .. tostring( gamemode.authorurl ) end
|
||||
|
||||
lbl:SetTooltip( desc )
|
||||
|
||||
lbl.WantName = name
|
||||
lbl.NumVotes = 0
|
||||
lbl.DoClick = function() if GetGlobalFloat( "VoteEndTime", 0 ) - CurTime() <= 0 then return end RunConsoleCommand( "votegamemode", name ) end
|
||||
|
||||
self.ctrlList:AddItem( lbl )
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
function PANEL:ChooseMap( gamemode )
|
||||
|
||||
self.lblActionName:SetText( "Which Map?" )
|
||||
self:ResetPeeps()
|
||||
self.ctrlList:Clear()
|
||||
|
||||
local gm = g_PlayableGamemodes[ gamemode ]
|
||||
if ( !gm ) then MsgN( "GAMEMODE MISSING, COULDN'T VOTE FOR MAP ", gamemode ) return end
|
||||
|
||||
for id, mapname in RandomPairs( gm.maps ) do
|
||||
local lbl = vgui.Create( "DButton", self.ctrlList )
|
||||
lbl:SetText( mapname )
|
||||
|
||||
Derma_Hook( lbl, "Paint", "Paint", "GamemodeButton" )
|
||||
Derma_Hook( lbl, "ApplySchemeSettings", "Scheme", "GamemodeButton" )
|
||||
Derma_Hook( lbl, "PerformLayout", "Layout", "GamemodeButton" )
|
||||
|
||||
lbl:SetTall( 24 )
|
||||
lbl:SetWide( 240 )
|
||||
|
||||
lbl.WantName = mapname
|
||||
lbl.NumVotes = 0
|
||||
lbl.DoClick = function() if GetGlobalFloat( "VoteEndTime", 0 ) - CurTime() <= 0 then return end RunConsoleCommand( "votemap", mapname ) end
|
||||
|
||||
--[[if file.Exists("maps/"..mapname..".png", "MOD") then
|
||||
lbl:SetTall(72)
|
||||
|
||||
local Image = vgui.Create("DImage", lbl)
|
||||
Image:SetImage("../maps/"..mapname..".png")
|
||||
Image:SizeToContents()
|
||||
Image:SetSize(math.min(Image:GetWide(), 64), math.min(Image:GetTall(), 64))
|
||||
Image:AlignRight(4)
|
||||
Image:CenterVertical()
|
||||
end]]
|
||||
|
||||
self.ctrlList:AddItem( lbl )
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
function PANEL:ResetPeeps()
|
||||
|
||||
for i=1, game.MaxPlayers() do
|
||||
self.Peeps[i]:SetPos( math.random( 0, 600 ), -16 )
|
||||
self.Peeps[i]:SetVisible( false )
|
||||
self.Peeps[i].strVote = nil
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
function PANEL:FindWantBar( name )
|
||||
|
||||
for k, v in pairs( self.ctrlList:GetItems() ) do
|
||||
if ( v.WantName == name ) then return v end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
function PANEL:PeepThink( peep, ent )
|
||||
|
||||
if ( !IsValid( ent ) ) then
|
||||
peep:SetVisible( false )
|
||||
return
|
||||
end
|
||||
|
||||
peep:SetTooltip( ent:Nick() )
|
||||
peep:SetMouseInputEnabled( true )
|
||||
|
||||
if ( !peep.strVote ) then
|
||||
peep:SetVisible( true )
|
||||
peep:SetPos( math.random( 0, 600 ), -16 )
|
||||
if ( ent == LocalPlayer() ) then
|
||||
peep:SetImage( "icon16/star.png" )
|
||||
end
|
||||
end
|
||||
|
||||
peep.strVote = ent:GetNWString( "Wants", "" )
|
||||
local bar = self:FindWantBar( peep.strVote )
|
||||
if ( IsValid( bar ) ) then
|
||||
|
||||
bar.NumVotes = bar.NumVotes + 1
|
||||
local vCurrentPos = Vector( peep.x, peep.y, 0 )
|
||||
local vNewPos = Vector( (bar.x + bar:GetWide()) - 15 * bar.NumVotes - 4, bar.y + ( bar:GetTall() * 0.5 - 8 ), 0 )
|
||||
|
||||
if ( !peep.CurPos || peep.CurPos != vNewPos ) then
|
||||
|
||||
peep:MoveTo( vNewPos.x, vNewPos.y, 0.2 )
|
||||
peep.CurPos = vNewPos
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
function PANEL:Think()
|
||||
|
||||
local Seconds = GetGlobalFloat( "VoteEndTime", 0 ) - CurTime()
|
||||
if ( Seconds < 0 ) then Seconds = 0 end
|
||||
|
||||
self.lblCountDown:SetText( Format( "%i", Seconds ) )
|
||||
|
||||
for k, v in pairs( self.ctrlList:GetItems() ) do
|
||||
v.NumVotes = 0
|
||||
end
|
||||
|
||||
for i=1, game.MaxPlayers() do
|
||||
self:PeepThink( self.Peeps[i], Entity(i) )
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
function PANEL:Paint()
|
||||
|
||||
Derma_DrawBackgroundBlur( self )
|
||||
|
||||
local CenterY = ScrH() / 2.0
|
||||
local CenterX = ScrW() / 2.0
|
||||
|
||||
surface.SetDrawColor( 0, 0, 0, 200 );
|
||||
surface.DrawRect( 0, 0, ScrW(), ScrH() );
|
||||
|
||||
end
|
||||
|
||||
function PANEL:FlashItem( itemname )
|
||||
|
||||
local bar = self:FindWantBar( itemname )
|
||||
if ( !IsValid( bar ) ) then return end
|
||||
|
||||
timer.Simple( 0.0, function() bar.bgColor = Color( 0, 255, 255 ) surface.PlaySound( "hl1/fvox/blip.wav" ) end )
|
||||
timer.Simple( 0.2, function() bar.bgColor = nil end )
|
||||
timer.Simple( 0.4, function() bar.bgColor = Color( 0, 255, 255 ) surface.PlaySound( "hl1/fvox/blip.wav" ) end )
|
||||
timer.Simple( 0.6, function() bar.bgColor = nil end )
|
||||
timer.Simple( 0.8, function() bar.bgColor = Color( 0, 255, 255 ) surface.PlaySound( "hl1/fvox/blip.wav" ) end )
|
||||
timer.Simple( 1.0, function() bar.bgColor = Color( 100, 100, 100 ) end )
|
||||
|
||||
end
|
||||
|
||||
derma.DefineControl( "VoteScreen", "", PANEL, "DPanel" )
|
After Width: | Height: | Size: 218 KiB |
After Width: | Height: | Size: 172 KiB |
After Width: | Height: | Size: 136 KiB |
After Width: | Height: | Size: 207 KiB |
After Width: | Height: | Size: 324 KiB |
After Width: | Height: | Size: 254 KiB |
After Width: | Height: | Size: 255 KiB |
After Width: | Height: | Size: 227 KiB |
After Width: | Height: | Size: 101 KiB |
After Width: | Height: | Size: 86 KiB |
After Width: | Height: | Size: 127 KiB |
After Width: | Height: | Size: 171 KiB |
After Width: | Height: | Size: 238 KiB |
After Width: | Height: | Size: 71 KiB |
After Width: | Height: | Size: 274 KiB |
|
@ -0,0 +1,17 @@
|
|||
"VertexLitGeneric"
|
||||
{
|
||||
"$basetexture" "models/weapons/v_models/blast_brenmk3/bren_d"
|
||||
"$bumpmap" "models/weapons/v_models/blast_brenmk3/bren_n"
|
||||
|
||||
"$phongexponenttexture" "models/weapons/v_models/blast_brenmk3/bren_m"
|
||||
"$phong" "1"
|
||||
"$phongboost" ".5"
|
||||
"$phongalbedoboost" "25"
|
||||
"$phongfresnelranges" "[.83 .83 0]"
|
||||
"$phongalbedotint" "1"
|
||||
"$phongdisablehalflambert" "1"
|
||||
|
||||
"$envmap" "env_cubemap"
|
||||
"$envmapfresnel" "1"
|
||||
"$envmaptint" "[.0025 .0025 .0025]"
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
"VertexLitGeneric"
|
||||
{
|
||||
"$baseTexture" "models\weapons\V_models\bren\tex_bren_diff"
|
||||
"$bumpmap" "models\weapons\V_models\bren\tex_bren_nrm"
|
||||
"$halflambert" 1
|
||||
"$nocull" 1
|
||||
"$phong" "1"
|
||||
"$phongexponent" "20"
|
||||
"$phongboost" "0.75"
|
||||
"$phongfresnelranges" "[.3 1 7]"
|
||||
|
||||
"$rimlight" "1"
|
||||
"$rimlightexponent" "300"
|
||||
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
"VertexLitGeneric"
|
||||
{
|
||||
"$baseTexture" "models\weapons\v_models\hands\sleeve_diffuse"
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
VertexLitGeneric
|
||||
{
|
||||
$basetexture "models\weapons\v_models\blast_brenmk3\bren_d"
|
||||
$bumpmap "models\weapons\v_models\blast_brenmk3\bren_n"
|
||||
$ambientocculusion "models\weapons\v_models\blast_brenmk3\bren_s"
|
||||
|
||||
$phongexponenttexture "models\weapons\v_models\blast_brenmk3\bren_m"
|
||||
$phong 1
|
||||
$phongboost ".5"
|
||||
$phongalbedoboost 25
|
||||
$phongfresnelranges "[.83 .83 0]"
|
||||
$phongalbedotint 1
|
||||
$phongdisablehalflambert 1
|
||||
|
||||
$envmap env_cubemap
|
||||
$envmapfresnel 1
|
||||
$envmaptint "[.0025 .0025 .0025]"
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
"UnlitGeneric"
|
||||
{
|
||||
"$basetexture" "prophunt_enhanced/box/box"
|
||||
"$translucent" "1"
|
||||
"$alphatest" "1"
|
||||
|
||||
"$nodraw" "1"
|
||||
"$no_draw" "1"
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
"VertexLitGeneric"
|
||||
{
|
||||
"$basetexture" "prophunt_enhanced/devil"
|
||||
"$surfaceprop" "Glass"
|
||||
"$envmap" "env_cubemap"
|
||||
"$envmapsaturation" "[.75 .75 .75]"
|
||||
// Don't this may get confused?
|
||||
"$translucent" "1"
|
||||
"$nocull" "1"
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
"UnlitGeneric"
|
||||
{
|
||||
"$basetexture" "prophunt_enhanced/sprites/devilball"
|
||||
"$translucent" 1
|
||||
"$vertexcolor" 1
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
"UnlitGeneric"
|
||||
{
|
||||
"$basetexture" "prophunt_enhanced/sprites/devilball_pointer"
|
||||
"$translucent" 1
|
||||
"$vertexcolor" 1
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
"UnlitGeneric"
|
||||
{
|
||||
"$basetexture" "prophunt_enhanced/sprites/luckyball"
|
||||
"$translucent" 1
|
||||
"$vertexcolor" 1
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
"UnlitGeneric"
|
||||
{
|
||||
"$basetexture" "prophunt_enhanced/sprites/luckyball_pointer"
|
||||
"$translucent" 1
|
||||
"$vertexcolor" 1
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
"UnlitGeneric"
|
||||
{
|
||||
"$basetexture" "vgui/hud/wlv_bren"
|
||||
"$additive" 1
|
||||
"$vertexalpha" 1
|
||||
"$vertexcolor" 1
|
||||
}
|
After Width: | Height: | Size: 25 KiB |
|
@ -0,0 +1,6 @@
|
|||
"UnlitGeneric"
|
||||
{
|
||||
"$basetexture" "vgui/hud_crosshair"
|
||||
"$additive" "1"
|
||||
"$vertexcolor" "1"
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
"UnlitGeneric"
|
||||
{
|
||||
"$basetexture" "vgui\phehud\btn_close"
|
||||
"$translucent" "1"
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
"UnlitGeneric"
|
||||
{
|
||||
"$basetexture" "vgui\phehud\btn_play"
|
||||
"$translucent" "1"
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
"UnlitGeneric"
|
||||
{
|
||||
"$basetexture" "vgui\phehud\btn_playpub"
|
||||
"$translucent" "1"
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
"UnlitGeneric"
|
||||
{
|
||||
"$basetexture" "vgui\phehud\btn_playx"
|
||||
"$translucent" "1"
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
"UnlitGeneric"
|
||||
{
|
||||
"$basetexture" "vgui\phehud\hud_topbar"
|
||||
"$vertexcolor" "1"
|
||||
"$translucent" "1"
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
"UnlitGeneric"
|
||||
{
|
||||
"$basetexture" "vgui\phehud\i_halo"
|
||||
"$translucent" "1"
|
||||
"$vertexcolor" "1"
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
"UnlitGeneric"
|
||||
{
|
||||
"$basetexture" "vgui\phehud\i_light"
|
||||
"$translucent" "1"
|
||||
"$vertexcolor" "1"
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
"UnlitGeneric"
|
||||
{
|
||||
"$basetexture" "vgui\phehud\i_rotate"
|
||||
"$translucent" "1"
|
||||
"$vertexcolor" "1"
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
"UnlitGeneric"
|
||||
{
|
||||
"$basetexture" "vgui\phehud\i_shield"
|
||||
"$translucent" "1"
|
||||
"$vertexcolor" "1"
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
"UnlitGeneric"
|
||||
{
|
||||
"$basetexture" "vgui\phehud\res_hp_1"
|
||||
"$vertexcolor" "1"
|
||||
"$translucent" "1"
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
"UnlitGeneric"
|
||||
{
|
||||
"$basetexture" "vgui\phehud\res_hp_2"
|
||||
"$vertexcolor" "1"
|
||||
"$translucent" "1"
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
"UnlitGeneric"
|
||||
{
|
||||
"$basetexture" "vgui\phehud\res_wep"
|
||||
"$vertexcolor" "1"
|
||||
"$translucent" "1"
|
||||
}
|