332 lines
12 KiB
Lua
332 lines
12 KiB
Lua
|
/*
|
||
|
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
|