379 lines
10 KiB
Lua
379 lines
10 KiB
Lua
|
|
BennyGame = BennyGame or {}
|
|
|
|
|
|
BG_GTYPE_CAMPAIGN = 0
|
|
BG_GTYPE_MP = 1
|
|
|
|
local cGametype = CreateConVar("b-gametype", 1, nil, "0 for Campaign, 1 for MP")
|
|
local cGamemode = CreateConVar("b-gamemode", "dom", nil, "")
|
|
|
|
local cMinplayers = CreateConVar("b-g_minplayers", 2)
|
|
local cPregame = CreateConVar("b-g_pregame", 15)
|
|
local cPostgame = CreateConVar("b-g_postgame", 15)
|
|
local cIntermission = CreateConVar("b-g_intermission", 10)
|
|
|
|
function BennyGame:GetType()
|
|
return cGametype:GetBool() and BG_GTYPE_MP or BG_GTYPE_CAMPAIGN
|
|
end
|
|
|
|
GM.TeamBased = BennyGame:GetType() == BG_GTYPE_MP
|
|
|
|
function BennyGame:GetMode()
|
|
return cGamemode:GetString()
|
|
end
|
|
|
|
function BennyGame:GetModeData()
|
|
return BennyGame.Gamemodes[ BennyGame:GetMode() ]
|
|
end
|
|
|
|
BennyGame.TeamsInPlay = {
|
|
4,
|
|
3,
|
|
}
|
|
BennyGame.TeamCount = #BennyGame.TeamsInPlay
|
|
|
|
BennyGame.Gamemodes = {
|
|
["free"] = {
|
|
name = "#Gamemode.free.Name",
|
|
description = "#Gamemode.free.Description",
|
|
},
|
|
["tdm"] = {
|
|
name = "#Gamemode.tdm.Name",
|
|
description = "#Gamemode.tdm.Description",
|
|
|
|
scorelimit = CreateConVar("b-g_tdm_scorelimit", 75 ),
|
|
timelimit = CreateConVar("b-g_tdm_timelimit", 10*60 ),
|
|
},
|
|
["ffa"] = {
|
|
name = "#Gamemode.ffa.Name",
|
|
description = "#Gamemode.ffa.Description",
|
|
|
|
scorelimit = CreateConVar("b-g_ffa_scorelimit", 30 ),
|
|
timelimit = CreateConVar("b-g_ffa_timelimit", 10*60 ),
|
|
},
|
|
["snd"] = {
|
|
name = "#Gamemode.snd.Name",
|
|
description = "#Gamemode.snd.Description",
|
|
|
|
scorelimit = CreateConVar("b-g_snd_scorelimit", 6 ),
|
|
timelimit = CreateConVar("b-g_snd_timelimit", 2.5*60 ),
|
|
},
|
|
["ctf"] = {
|
|
name = "#Gamemode.ctf.Name",
|
|
description = "#Gamemode.ctf.Description",
|
|
|
|
scorelimit = CreateConVar("b-g_ctf_scorelimit", 3 ),
|
|
timelimit = CreateConVar("b-g_ctf_timelimit", 10*60 ),
|
|
},
|
|
["dom"] = {
|
|
name = "#Gamemode.dom.Name",
|
|
description = "#Gamemode.dom.Description",
|
|
|
|
scorelimit = CreateConVar("b-g_dom_scorelimit", 1000 ),
|
|
timelimit = CreateConVar("b-g_dom_timelimit", 10*60 ),
|
|
roundlimit = CreateConVar("b-g_dom_roundlimit", 1 ),
|
|
},
|
|
["dem"] = {
|
|
name = "#Gamemode.dem.Name",
|
|
description = "#Gamemode.dem.Description",
|
|
|
|
scorelimit = CreateConVar("b-g_dem_scorelimit", 3 ),
|
|
timelimit = CreateConVar("b-g_dem_timelimit", 5*60 ),
|
|
roundlimit = CreateConVar("b-g_dom_roundlimit", 2 ),
|
|
},
|
|
["hp"] = {
|
|
name = "#Gamemode.hp.Name",
|
|
description = "#Gamemode.hp.Description",
|
|
|
|
scorelimit = CreateConVar("b-g_hp_scorelimit", 300 ),
|
|
timelimit = CreateConVar("b-g_hp_timelimit", 10*60 ),
|
|
},
|
|
}
|
|
|
|
local thetypes = {
|
|
"Float",
|
|
"Int",
|
|
"Bool",
|
|
"Entity",
|
|
}
|
|
|
|
function BennyGame:Accessor( name, typey, default )
|
|
local World = game.GetWorld()
|
|
|
|
if typey == "Float" then
|
|
BennyGame["Get" .. name] = function( self )
|
|
return World:GetNW2Float( name, default )
|
|
end
|
|
BennyGame["Set" .. name] = function( self, val )
|
|
World:SetNW2Float( name, val )
|
|
end
|
|
return
|
|
end
|
|
|
|
if typey == "Int" then
|
|
BennyGame["Get" .. name] = function( self )
|
|
return World:GetNW2Int( name, default )
|
|
end
|
|
BennyGame["Set" .. name] = function( self, val )
|
|
World:SetNW2Int( name, val )
|
|
end
|
|
return
|
|
end
|
|
|
|
if typey == "Bool" then
|
|
BennyGame["Get" .. name] = function( self )
|
|
return World:GetNW2Bool( name, default )
|
|
end
|
|
BennyGame["Set" .. name] = function( self, val )
|
|
World:SetNW2Bool( name, val )
|
|
end
|
|
return
|
|
end
|
|
|
|
if typey == "Entity" then
|
|
BennyGame["Get" .. name] = function( self )
|
|
return World:GetNW2Entity( name, default )
|
|
end
|
|
BennyGame["Set" .. name] = function( self, val )
|
|
World:SetNW2Entity( name, val )
|
|
end
|
|
return
|
|
end
|
|
end
|
|
|
|
BG_STATE_WAITINGFORPLAYERS = 0
|
|
BG_STATE_PRE = 1
|
|
BG_STATE_ACTIVE = 2
|
|
BG_STATE_POST = 3
|
|
|
|
hook.Add("InitPostEntity", "Benny_Gamestate_InitPostEntity", function()
|
|
BennyGame:Accessor( "RoundStartedAt", "Float", 0 )
|
|
BennyGame:Accessor( "PregameStartedAt", "Float", 0 )
|
|
BennyGame:Accessor( "RoundFinishedAt", "Float", 0 )
|
|
|
|
BennyGame:Accessor( "State", "Int", 0 )
|
|
BennyGame:Accessor( "Round", "Int", 1 )
|
|
BennyGame:Accessor( "SwappedAtRound", "Int", 1 )
|
|
BennyGame:Accessor( "TimeExtension", "Int", 0 )
|
|
|
|
BennyGame:Accessor( "Team1_Score", "Int", 0 )
|
|
BennyGame:Accessor( "Team2_Score", "Int", 0 )
|
|
BennyGame:Accessor( "Team3_Score", "Int", 0 )
|
|
BennyGame:Accessor( "Team4_Score", "Int", 0 )
|
|
BennyGame:Accessor( "Team5_Score", "Int", 0 )
|
|
BennyGame:Accessor( "Team6_Score", "Int", 0 )
|
|
|
|
BennyGame:Accessor( "TeamsSwapped", "Bool", false )
|
|
end)
|
|
|
|
function BennyGame:GetScoreLimit()
|
|
if !BennyGame.Gamemodes[BennyGame:GetMode()].scorelimit then return false end
|
|
return BennyGame.Gamemodes[BennyGame:GetMode()].scorelimit:GetInt()
|
|
end
|
|
|
|
function BennyGame:GetTimeLimit()
|
|
if !BennyGame.Gamemodes[BennyGame:GetMode()].timelimit then return false end
|
|
return BennyGame.Gamemodes[BennyGame:GetMode()].timelimit:GetInt() + BennyGame:GetTimeExtension()
|
|
end
|
|
|
|
function BennyGame:GetRoundLimit()
|
|
if !BennyGame.Gamemodes[BennyGame:GetMode()].roundlimit then return false end
|
|
return BennyGame.Gamemodes[BennyGame:GetMode()].roundlimit:GetInt()
|
|
end
|
|
|
|
|
|
function BennyGame:GetPregameTime()
|
|
return cPregame:GetInt()
|
|
end
|
|
|
|
function BennyGame:GetPostgameTime()
|
|
return cPostgame:GetInt()
|
|
end
|
|
|
|
function BennyGame:GetIntermissionTime()
|
|
return cIntermission:GetInt()
|
|
end
|
|
|
|
function BennyGame:GetScoreForTeam( teamid )
|
|
return BennyGame["GetTeam" .. teamid .. "_Score"]( self )
|
|
end
|
|
|
|
function BennyGame:SetScoreForTeam( teamid, var )
|
|
return BennyGame["SetTeam" .. teamid .. "_Score"]( self, var )
|
|
end
|
|
|
|
function BennyGame:AddScoreForTeam( teamid, var )
|
|
if Nuke then return end
|
|
if BennyGame:GetState() != BG_STATE_ACTIVE then return end
|
|
self:SetScoreForTeam( teamid, self:GetScoreForTeam( teamid ) + (var or 1) )
|
|
|
|
if self:GetScoreForTeam( teamid ) >= BennyGame:GetScoreLimit() then
|
|
BennyGame:EndRound( BG_ER_SCORELIMIT, teamid )
|
|
end
|
|
end
|
|
|
|
BG_ER_TIMELIMIT = 0
|
|
BG_ER_SCORELIMIT = 1
|
|
BG_ER_NUKE = 2
|
|
BG_ER_FORCE = 3
|
|
|
|
function BennyGame:StartRound()
|
|
PrintMessage(HUD_PRINTCENTER, "Round start!")
|
|
BennyGame:SetState( BG_STATE_ACTIVE )
|
|
BennyGame:SetRoundStartedAt( CurTime() )
|
|
game.CleanUpMap()
|
|
for _, ply in player.Iterator() do
|
|
ply:Spawn()
|
|
end
|
|
end
|
|
|
|
function BennyGame:EndRound( reason, forceteam )
|
|
local winningteam = forceteam
|
|
BennyGame:SetState( BG_STATE_POST )
|
|
BennyGame:SetRoundFinishedAt( CurTime() )
|
|
|
|
if !winningteam then
|
|
-- who has the most score
|
|
|
|
local HighestScore, HighestTeam = 0, 0
|
|
for TeamID, RealTeamID in ipairs( BennyGame.TeamsInPlay ) do
|
|
local ThisScore = BennyGame:GetScoreForTeam( RealTeamID )
|
|
if HighestScore < ThisScore then
|
|
HighestScore = ThisScore
|
|
HighestTeam = RealTeamID
|
|
print("highest score to do it to em", HighestScore, TEAMS[HighestTeam].name)
|
|
winningteam = HighestTeam
|
|
end
|
|
end
|
|
|
|
for TeamID, RealTeamID in ipairs( BennyGame.TeamsInPlay ) do
|
|
local ThisScore = BennyGame:GetScoreForTeam( RealTeamID )
|
|
if RealTeamID == HighestTeam then continue end
|
|
if HighestScore < ThisScore then
|
|
print("clearly there's been a failure", RealTeamID, ThisScore, HighestTeam, HighestScore)
|
|
elseif HighestScore == ThisScore then
|
|
print("this looks like a tie", RealTeamID, HighestTeam)
|
|
winningteam = 0
|
|
break
|
|
end
|
|
end
|
|
|
|
end
|
|
|
|
local TheFull = "["
|
|
TheFull = TheFull .. ((reason==0 and "TIME END!] ") or (reason==1 and "SCORE END!] ") or ("MISSING END!] "))
|
|
if winningteam == 0 then
|
|
TheFull = "It's a tie! "
|
|
else
|
|
TheFull = TheFull .. l8(TEAMS[winningteam].name) .. " wins! "
|
|
end
|
|
TheFull = TheFull .. cPostgame:GetInt() .. "s until the next round."
|
|
PrintMessage(HUD_PRINTCENTER, TheFull)
|
|
|
|
local roundtime = CurTime() - BennyGame:GetRoundStartedAt()
|
|
print( "That round lasted " .. math.ceil(roundtime) .. " seconds." )
|
|
end
|
|
|
|
concommand.Add("b-cheat_scoreset", function( ply, cmd, args )
|
|
if !args[1] then
|
|
print( "Needs a team ID." )
|
|
for index, data in ipairs( TEAMS ) do
|
|
print( index .. " - " .. data.id )
|
|
end
|
|
elseif !args[2] then
|
|
print( "Needs an integer." )
|
|
else
|
|
BennyGame:SetScoreForTeam( TEAMS_IDorName( args[1] ), args[2] )
|
|
print( "Team " .. args[1] .. " score now " .. BennyGame:GetScoreForTeam( TEAMS_IDorName( args[1] ) ) )
|
|
end
|
|
end, function( cmd, args )
|
|
return BENNY.SimpleAutoComplete( cmd, args, TEAMS_IDs )
|
|
end )
|
|
|
|
concommand.Add("b-cheat_scoreadd", function( ply, cmd, args )
|
|
if !args[1] then
|
|
print( "Needs a team ID." )
|
|
for index, data in ipairs( TEAMS ) do
|
|
print( index .. " - " .. data.id )
|
|
end
|
|
else
|
|
BennyGame:AddScoreForTeam( TEAMS_IDorName( args[1] ), args[2] )
|
|
print( "Team " .. args[1] .. " score now " .. BennyGame:GetScoreForTeam( TEAMS_IDorName( args[1] ) ) )
|
|
end
|
|
end, function( cmd, args )
|
|
return BENNY.SimpleAutoComplete( cmd, args, TEAMS_IDs )
|
|
end )
|
|
|
|
concommand.Add("b-cheat_setstate", function( ply, cmd, args )
|
|
if !args[1] then
|
|
print( "Needs an integer 0 waiting for palyers 1 pre 2 active 3 post" )
|
|
else
|
|
BennyGame:SetState( args[1] )
|
|
end
|
|
end, function( cmd, args )
|
|
return BENNY.SimpleAutoComplete( cmd, args, TEAMS_IDs )
|
|
end )
|
|
|
|
concommand.Add("b-cheat_endround", function( ply, cmd, args )
|
|
BennyGame:EndRound( args[1] or BG_ER_FORCE, args[2] )
|
|
end, function( cmd, args )
|
|
return BENNY.SimpleAutoComplete( cmd, args, TEAMS_IDs )
|
|
end )
|
|
|
|
hook.Add("Think", "Benny_Gamestate_Think", function()
|
|
if SERVER then
|
|
local World = Entity(0)
|
|
if BennyGame:GetType() == BG_GTYPE_MP then
|
|
local roundstate = BennyGame:GetState()
|
|
|
|
if roundstate == BG_STATE_WAITINGFORPLAYERS then
|
|
-- Waiting for players
|
|
|
|
local count = 0
|
|
for index, ply in player.Iterator() do
|
|
if ply:Team() == TEAM_CONNECTING then continue end
|
|
if ply:Team() == TEAM_UNASSIGNED then continue end
|
|
if ply:Team() == TEAM_SPECTATOR then continue end
|
|
|
|
count = count + 1
|
|
end
|
|
if count >= cMinplayers:GetInt() then
|
|
roundstate = BG_STATE_PRE
|
|
BennyGame:SetState( roundstate )
|
|
BennyGame:SetPregameStartedAt( CurTime() )
|
|
PrintMessage(HUD_PRINTCENTER, "Pregame. " .. cPregame:GetInt() .. "s until the round starts")
|
|
end
|
|
end
|
|
|
|
if roundstate == BG_STATE_PRE then
|
|
-- Pregame
|
|
|
|
if BennyGame:GetPregameStartedAt() + BennyGame:GetPregameTime() <= CurTime() then
|
|
BennyGame:StartRound()
|
|
end
|
|
|
|
elseif roundstate == BG_STATE_POST then
|
|
-- Postgame
|
|
|
|
|
|
if BennyGame:GetRoundFinishedAt() + BennyGame:GetPostgameTime() <= CurTime() then
|
|
for TeamID, RealTeamID in ipairs( BennyGame.TeamsInPlay ) do
|
|
BennyGame:SetScoreForTeam( RealTeamID, 0 )
|
|
end
|
|
BennyGame:SetState( BG_STATE_WAITINGFORPLAYERS )
|
|
end
|
|
|
|
elseif roundstate == BG_STATE_ACTIVE then
|
|
-- Active round
|
|
|
|
if (BennyGame:GetRoundStartedAt()+BennyGame:GetTimeLimit()) <= CurTime() then
|
|
-- Round time expired
|
|
BennyGame:EndRound( BG_ER_TIMELIMIT )
|
|
end
|
|
end
|
|
|
|
|
|
end
|
|
end
|
|
end) |