mirror of
https://github.com/R2Northstar/NorthstarMods
synced 2026-08-25 12:29:17 -04:00
Add replacing scoreboard columns (#988)
add replacing scoreboard columns
This commit is contained in:
parent
f664202e9d
commit
800e787f22
2 changed files with 158 additions and 33 deletions
|
|
@ -1,5 +1,3 @@
|
||||||
// Shared
|
|
||||||
|
|
||||||
// Contains data about a custom scoreboard column data.
|
// Contains data about a custom scoreboard column data.
|
||||||
global struct ScoreboardColumnData
|
global struct ScoreboardColumnData
|
||||||
{
|
{
|
||||||
|
|
@ -7,8 +5,17 @@ global struct ScoreboardColumnData
|
||||||
string title
|
string title
|
||||||
// A valid PlayerGameStat (PGS) constant value (PGS_ASSAULT_SCORE, PGS_KILLS etc.).
|
// A valid PlayerGameStat (PGS) constant value (PGS_ASSAULT_SCORE, PGS_KILLS etc.).
|
||||||
int scoreType
|
int scoreType
|
||||||
// The maximum amount of digits this column can hold. Determines the width of the column.
|
// The maximum amount of digits this column can hold. Determines the width of the column.
|
||||||
int digits
|
int digits
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stores a replacement for any scoreboard column index (base or custom).
|
||||||
|
global struct ScoreboardColumnReplacementData
|
||||||
|
{
|
||||||
|
int columnIndex
|
||||||
|
string title
|
||||||
|
int scoreType
|
||||||
|
int digits
|
||||||
}
|
}
|
||||||
|
|
||||||
global function Shared_GetCustomScoreboardColumns
|
global function Shared_GetCustomScoreboardColumns
|
||||||
|
|
@ -20,11 +27,17 @@ global function Client_CustomScoreboardColumns_Init
|
||||||
#if SERVER
|
#if SERVER
|
||||||
global function Server_CustomScoreboardColumns_Init
|
global function Server_CustomScoreboardColumns_Init
|
||||||
global function Server_AddCustomScoreboardColumn
|
global function Server_AddCustomScoreboardColumn
|
||||||
|
global function Server_ReplaceCustomScoreboardColumn
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Currently tracked custom scoreboard columns added by the server.
|
// Currently tracked custom scoreboard columns added by the server.
|
||||||
array<ScoreboardColumnData> CustomScoreboardColumns
|
array<ScoreboardColumnData> CustomScoreboardColumns
|
||||||
|
|
||||||
|
#if SERVER
|
||||||
|
// Track latest replacement per absolute scoreboard column index.
|
||||||
|
array<ScoreboardColumnReplacementData> ScoreboardColumnReplacements
|
||||||
|
#endif
|
||||||
|
|
||||||
// Returns the custom scoreboard columns defined by the server.
|
// Returns the custom scoreboard columns defined by the server.
|
||||||
array<ScoreboardColumnData> function Shared_GetCustomScoreboardColumns()
|
array<ScoreboardColumnData> function Shared_GetCustomScoreboardColumns()
|
||||||
{
|
{
|
||||||
|
|
@ -35,26 +48,43 @@ array<ScoreboardColumnData> function Shared_GetCustomScoreboardColumns()
|
||||||
void function Client_CustomScoreboardColumns_Init()
|
void function Client_CustomScoreboardColumns_Init()
|
||||||
{
|
{
|
||||||
AddServerToClientStringCommandCallback( "AddCustomScoreboardColumn", ServerCallback_AddCustomScoreboardColumn )
|
AddServerToClientStringCommandCallback( "AddCustomScoreboardColumn", ServerCallback_AddCustomScoreboardColumn )
|
||||||
|
AddServerToClientStringCommandCallback( "ReplaceCustomScoreboardColumn", ServerCallback_ReplaceCustomScoreboardColumn )
|
||||||
|
}
|
||||||
|
|
||||||
|
void function ServerCallback_ReplaceCustomScoreboardColumn( array<string> args )
|
||||||
|
{
|
||||||
|
if ( args.len() != 4 )
|
||||||
|
{
|
||||||
|
printt( format( "Warning: received invalid ReplaceCustomScoreboardColumn command with %i arguments.", args.len() ) )
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
int columnIndex = args[0].tointeger()
|
||||||
|
string title = StringReplace( args[1], "\b", " ", true )
|
||||||
|
int scoreType = args[2].tointeger()
|
||||||
|
int digits = args[3].tointeger()
|
||||||
|
|
||||||
|
GameMode_ReplaceScoreboardColumnData( GAMETYPE, columnIndex, title, scoreType, digits )
|
||||||
}
|
}
|
||||||
|
|
||||||
void function ServerCallback_AddCustomScoreboardColumn( array<string> args )
|
void function ServerCallback_AddCustomScoreboardColumn( array<string> args )
|
||||||
{
|
{
|
||||||
if (args.len() != 3)
|
if ( args.len() != 3 )
|
||||||
{
|
{
|
||||||
printt(format("Warning: received invalid AddCustomScoreboardColumn command with %i arguments.", args.len()))
|
printt( format( "Warning: received invalid AddCustomScoreboardColumn command with %i arguments.", args.len() ) )
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
ScoreboardColumnData newColumn = { ... }
|
ScoreboardColumnData newColumn = { ... }
|
||||||
newColumn.title = StringReplace(args[0], "\b", " ", true)
|
newColumn.title = StringReplace( args[0], "\b", " ", true )
|
||||||
newColumn.scoreType = args[1].tointeger()
|
newColumn.scoreType = args[1].tointeger()
|
||||||
newColumn.digits = args[2].tointeger()
|
newColumn.digits = args[2].tointeger()
|
||||||
|
|
||||||
CustomScoreboardColumns.append(newColumn)
|
CustomScoreboardColumns.append( newColumn )
|
||||||
|
|
||||||
GameMode_AddScoreboardColumnData(GAMETYPE, newColumn.title, newColumn.scoreType, newColumn.digits)
|
GameMode_AddScoreboardColumnData( GAMETYPE, newColumn.title, newColumn.scoreType, newColumn.digits )
|
||||||
}
|
}
|
||||||
#endif //CLIENT
|
#endif // CLIENT
|
||||||
|
|
||||||
#if SERVER
|
#if SERVER
|
||||||
void function Server_CustomScoreboardColumns_Init()
|
void function Server_CustomScoreboardColumns_Init()
|
||||||
|
|
@ -69,16 +99,16 @@ void function Server_CustomScoreboardColumns_Init()
|
||||||
* @param scoreType A valid PlayerGameStat (PGS) constant value (PGS_ASSAULT_SCORE, PGS_KILLS etc.).
|
* @param scoreType A valid PlayerGameStat (PGS) constant value (PGS_ASSAULT_SCORE, PGS_KILLS etc.).
|
||||||
* @param digits The maximum amount of digits this column can hold. Determines the width of the column.
|
* @param digits The maximum amount of digits this column can hold. Determines the width of the column.
|
||||||
*/
|
*/
|
||||||
void function Server_AddCustomScoreboardColumn(string title, int scoreType, int digits)
|
void function Server_AddCustomScoreboardColumn( string title, int scoreType, int digits )
|
||||||
{
|
{
|
||||||
// Limit of four scoreboard columns, else it'll break it entirely.
|
// Limit of four scoreboard columns, else it will break it entirely.
|
||||||
if (GameMode_GetScoreboardColumnTitles(GAMETYPE).len() + CustomScoreboardColumns.len() >= 4)
|
if ( GameMode_GetScoreboardColumnTitles( GAMETYPE ).len() + CustomScoreboardColumns.len() >= 4 )
|
||||||
{
|
{
|
||||||
throw "Cannot have more than 4 scoreboard columns."
|
throw "Cannot have more than 4 scoreboard columns."
|
||||||
}
|
}
|
||||||
|
|
||||||
string sanitized = strip(title)
|
string sanitized = strip( title )
|
||||||
if (sanitized.len() == 0)
|
if ( sanitized.len() == 0 )
|
||||||
{
|
{
|
||||||
throw "Cannot have an empty scoreboard column title."
|
throw "Cannot have an empty scoreboard column title."
|
||||||
}
|
}
|
||||||
|
|
@ -89,32 +119,117 @@ void function Server_AddCustomScoreboardColumn(string title, int scoreType, int
|
||||||
newColumn.scoreType = scoreType
|
newColumn.scoreType = scoreType
|
||||||
newColumn.digits = digits
|
newColumn.digits = digits
|
||||||
|
|
||||||
CustomScoreboardColumns.append(newColumn)
|
CustomScoreboardColumns.append( newColumn )
|
||||||
|
|
||||||
string cmd = BuildScoreboardStringCommand(newColumn)
|
string cmd = BuildScoreboardStringCommand( newColumn )
|
||||||
printt(cmd)
|
foreach ( entity player in GetPlayerArray() )
|
||||||
foreach(entity player in GetPlayerArray())
|
|
||||||
{
|
{
|
||||||
ServerToClientStringCommand(player, cmd)
|
ServerToClientStringCommand( player, cmd )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//adds all the registered columns when a player connects
|
/**
|
||||||
void function SendCustomScoreboardColumnsToPlayer(entity player)
|
* Replaces a scoreboard column by index.
|
||||||
|
* Replacements are tracked and replayed to late joiners.
|
||||||
|
*/
|
||||||
|
void function Server_ReplaceCustomScoreboardColumn( int columnIndex, string title, int scoreType, int digits )
|
||||||
{
|
{
|
||||||
foreach(ScoreboardColumnData data in CustomScoreboardColumns)
|
string sanitized = strip( title )
|
||||||
|
if ( sanitized.len() == 0 )
|
||||||
{
|
{
|
||||||
string cmd = BuildScoreboardStringCommand(data)
|
throw "Cannot have an empty scoreboard column title."
|
||||||
ServerToClientStringCommand(player, cmd)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int baseColumnCount = GameMode_GetScoreboardColumnTitles( GAMETYPE ).len()
|
||||||
|
int totalColumnCount = baseColumnCount + CustomScoreboardColumns.len()
|
||||||
|
|
||||||
|
if ( columnIndex < 0 || columnIndex >= totalColumnCount )
|
||||||
|
{
|
||||||
|
throw format( "Scoreboard column index %i is out of range (0..%i).", columnIndex, totalColumnCount - 1 )
|
||||||
|
}
|
||||||
|
|
||||||
|
// If replacing one of our tracked custom columns, update stored state
|
||||||
|
// so reconnecting players still receive the correct custom data.
|
||||||
|
if ( columnIndex >= baseColumnCount )
|
||||||
|
{
|
||||||
|
int customIndex = columnIndex - baseColumnCount
|
||||||
|
ScoreboardColumnData data = CustomScoreboardColumns[customIndex]
|
||||||
|
data.title = sanitized
|
||||||
|
data.scoreType = scoreType
|
||||||
|
data.digits = digits
|
||||||
|
CustomScoreboardColumns[customIndex] = data
|
||||||
|
}
|
||||||
|
|
||||||
|
RecordScoreboardColumnReplacement( columnIndex, sanitized, scoreType, digits )
|
||||||
|
|
||||||
|
ScoreboardColumnData payload = { ... }
|
||||||
|
payload.title = sanitized
|
||||||
|
payload.scoreType = scoreType
|
||||||
|
payload.digits = digits
|
||||||
|
|
||||||
|
string cmd = BuildReplaceScoreboardStringCommand( columnIndex, payload )
|
||||||
|
foreach ( entity player in GetPlayerArray() )
|
||||||
|
{
|
||||||
|
ServerToClientStringCommand( player, cmd )
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Adds all the registered columns and replacements when a player connects.
|
||||||
|
void function SendCustomScoreboardColumnsToPlayer( entity player )
|
||||||
|
{
|
||||||
|
foreach ( ScoreboardColumnData data in CustomScoreboardColumns )
|
||||||
|
{
|
||||||
|
string addCmd = BuildScoreboardStringCommand( data )
|
||||||
|
ServerToClientStringCommand( player, addCmd )
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ( ScoreboardColumnReplacementData replacement in ScoreboardColumnReplacements )
|
||||||
|
{
|
||||||
|
ScoreboardColumnData data = { ... }
|
||||||
|
data.title = replacement.title
|
||||||
|
data.scoreType = replacement.scoreType
|
||||||
|
data.digits = replacement.digits
|
||||||
|
|
||||||
|
string replaceCmd = BuildReplaceScoreboardStringCommand( replacement.columnIndex, data )
|
||||||
|
ServerToClientStringCommand( player, replaceCmd )
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void function RecordScoreboardColumnReplacement( int columnIndex, string title, int scoreType, int digits )
|
||||||
|
{
|
||||||
|
for ( int i = 0; i < ScoreboardColumnReplacements.len(); i++ )
|
||||||
|
{
|
||||||
|
if ( ScoreboardColumnReplacements[i].columnIndex == columnIndex )
|
||||||
|
{
|
||||||
|
ScoreboardColumnReplacementData existing = ScoreboardColumnReplacements[i]
|
||||||
|
existing.title = title
|
||||||
|
existing.scoreType = scoreType
|
||||||
|
existing.digits = digits
|
||||||
|
ScoreboardColumnReplacements[i] = existing
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ScoreboardColumnReplacementData replacement = { ... }
|
||||||
|
replacement.columnIndex = columnIndex
|
||||||
|
replacement.title = title
|
||||||
|
replacement.scoreType = scoreType
|
||||||
|
replacement.digits = digits
|
||||||
|
ScoreboardColumnReplacements.append( replacement )
|
||||||
|
}
|
||||||
|
|
||||||
|
string function BuildReplaceScoreboardStringCommand( int columnIndex, ScoreboardColumnData data )
|
||||||
|
{
|
||||||
|
string sanitizedName = StringReplace( data.title, " ", "\b", true )
|
||||||
|
return format( "ReplaceCustomScoreboardColumn %i %s %i %i", columnIndex, sanitizedName, data.scoreType, data.digits )
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper function to build the string command used to send a custom scoreboard column.
|
// Helper function to build the string command used to send a custom scoreboard column.
|
||||||
string function BuildScoreboardStringCommand(ScoreboardColumnData data)
|
string function BuildScoreboardStringCommand( ScoreboardColumnData data )
|
||||||
{
|
{
|
||||||
// Replace spaces with backspaces so they arrive as one argument instead of splitting.
|
// Replace spaces with backspaces so they arrive as one argument instead of splitting.
|
||||||
// Nobody's going to use those anyway, should be fine.
|
// Nobody is going to use those anyway, should be fine.
|
||||||
string sanitizedName = StringReplace(data.title, " ", "\b", true)
|
string sanitizedName = StringReplace( data.title, " ", "\b", true )
|
||||||
return format("AddCustomScoreboardColumn %s %i %i", sanitizedName, data.scoreType, data.digits)
|
return format( "AddCustomScoreboardColumn %s %i %i", sanitizedName, data.scoreType, data.digits )
|
||||||
}
|
}
|
||||||
#endif //SERVER
|
#endif // SERVER
|
||||||
|
|
@ -10,6 +10,7 @@ global function GameMode_SetDefendDesc
|
||||||
global function GameMode_SetIcon
|
global function GameMode_SetIcon
|
||||||
global function GameMode_SetDefaultScoreLimits
|
global function GameMode_SetDefaultScoreLimits
|
||||||
global function GameMode_AddScoreboardColumnData
|
global function GameMode_AddScoreboardColumnData
|
||||||
|
global function GameMode_ReplaceScoreboardColumnData
|
||||||
global function GameMode_SetGameModeAnnouncement
|
global function GameMode_SetGameModeAnnouncement
|
||||||
global function GameMode_SetDefaultTimeLimits
|
global function GameMode_SetDefaultTimeLimits
|
||||||
global function GameMode_SetDesc
|
global function GameMode_SetDesc
|
||||||
|
|
@ -560,6 +561,15 @@ void function GameMode_AddScoreboardColumnData( string gameModeName, string titl
|
||||||
file.gameModeDefs[gameModeName].scoreboardColumnNumDigits.append( numDigits )
|
file.gameModeDefs[gameModeName].scoreboardColumnNumDigits.append( numDigits )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void function GameMode_ReplaceScoreboardColumnData( string gameModeName, int columnIndex, string title, int scoreType, int numDigits )
|
||||||
|
{
|
||||||
|
Assert( gameModeName in file.gameModeDefs, "No MP Gametype specified in _settings.nut" )
|
||||||
|
Assert( columnIndex < file.gameModeDefs[gameModeName].scoreboardColumnTitles.len(), "Column index out of range" )
|
||||||
|
file.gameModeDefs[gameModeName].scoreboardColumnTitles[columnIndex] = title
|
||||||
|
file.gameModeDefs[gameModeName].scoreboardColumnScoreTypes[columnIndex] = scoreType
|
||||||
|
file.gameModeDefs[gameModeName].scoreboardColumnNumDigits[columnIndex] = numDigits
|
||||||
|
}
|
||||||
|
|
||||||
void function GameMode_SetEvacEnabled( string gameModeName, bool value )
|
void function GameMode_SetEvacEnabled( string gameModeName, bool value )
|
||||||
{
|
{
|
||||||
Assert( gameModeName in file.gameModeDefs, "No MP Gametype specified in _settings.nut" )
|
Assert( gameModeName in file.gameModeDefs, "No MP Gametype specified in _settings.nut" )
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue