diff --git a/docs/rh-log.txt b/docs/rh-log.txt index 7285ccb1f..6ad78c23f 100644 --- a/docs/rh-log.txt +++ b/docs/rh-log.txt @@ -1,4 +1,5 @@ December 20, 2007 (Changes by Graf Zahl) +- Added Karate Chris's TEAMINFO submission. - Added true color processing to FDDSTexture. This is untested so far because I don't have any DDS textures to check it with. - Fixed: FTexture::~FTexture() must destroy the associated native texture diff --git a/src/b_bot.cpp b/src/b_bot.cpp index c812ef2df..37daafa8d 100644 --- a/src/b_bot.cpp +++ b/src/b_bot.cpp @@ -10,6 +10,7 @@ #include "doomstat.h" #include "p_local.h" #include "cmdlib.h" +#include "teaminfo.h" CVAR (Int, bot_next_color, 11, 0) CVAR (Bool, bot_observer, false, 0) diff --git a/src/b_game.cpp b/src/b_game.cpp index 9183ab917..e9b750841 100644 --- a/src/b_game.cpp +++ b/src/b_game.cpp @@ -56,6 +56,7 @@ Everything that is changed is marked (maybe commented) with "Added by MC" #include "m_misc.h" #include "sbar.h" #include "p_acs.h" +#include "teaminfo.h" static FRandom pr_botspawn ("BotSpawn"); @@ -335,7 +336,7 @@ bool DCajunMaster::SpawnBot (const char *name, int color) { strcat (concat, colors[bot_next_color]); } - if (thebot->lastteam < NUM_TEAMS) + if (TEAMINFO_IsValidTeam (thebot->lastteam)) { // Keep the bot on the same team when switching levels sprintf (concat+strlen(concat), "\\team\\%d\n", thebot->lastteam); } @@ -374,7 +375,11 @@ void DCajunMaster::DoAddBot (int bnum, char *info) players[bnum].mo = NULL; players[bnum].playerstate = PST_ENTER; botingame[bnum] = true; - Printf ("%s joined the game\n", players[bnum].userinfo.netname); + + if (teamplay) + Printf ("%s joined the %s team\n", players[bnum].userinfo.netname, teams[players[bnum].userinfo.team].name); + else + Printf ("%s joined the game\n", players[bnum].userinfo.netname); G_DoReborn (bnum, true); if (StatusBar != NULL) @@ -589,7 +594,7 @@ bool DCajunMaster::LoadBots () if (IsNum (sc_String)) { teamnum = atoi (sc_String); - if (teamnum >= NUM_TEAMS) + if (!TEAMINFO_IsValidTeam (teamnum)) { teamnum = TEAM_None; } @@ -597,9 +602,9 @@ bool DCajunMaster::LoadBots () else { teamnum = TEAM_None; - for (int i = 0; i < NUM_TEAMS; ++i) + for (int i = 0; i < teams.Size (); ++i) { - if (stricmp (TeamNames[i], sc_String) == 0) + if (stricmp (teams[i].name, sc_String) == 0) { teamnum = i; break; diff --git a/src/d_main.cpp b/src/d_main.cpp index f4f4ac034..1b6705ec7 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -88,6 +88,7 @@ #include "v_text.h" #include "st_start.h" #include "templates.h" +#include "teaminfo.h" // MACROS ------------------------------------------------------------------ @@ -2326,6 +2327,10 @@ void D_DoomMain (void) Printf ("S_InitData: Load sound definitions.\n"); S_InitData (); + // [CW] Parse any TEAMINFO lumps + Printf ("TEAMINFO_Init: Load team definitions.\n"); + TEAMINFO_Init (); + FActorInfo::StaticInit (); // Now that all actors have been defined we can finally set up the weapon slots diff --git a/src/d_net.cpp b/src/d_net.cpp index f6ba0ba0c..c0ab17b32 100644 --- a/src/d_net.cpp +++ b/src/d_net.cpp @@ -52,6 +52,7 @@ #include "p_trace.h" #include "a_sharedglobal.h" #include "st_start.h" +#include "teaminfo.h" int P_StartScript (AActor *who, line_t *where, int script, char *map, bool backSide, int arg0, int arg1, int arg2, int always, bool wantResultCode, bool net); diff --git a/src/d_netinf.h b/src/d_netinf.h index 522fe0d25..4e8cac104 100644 --- a/src/d_netinf.h +++ b/src/d_netinf.h @@ -66,20 +66,6 @@ struct userinfo_s }; typedef struct userinfo_s userinfo_t; -enum ETeams -{ - TEAM_Red, - TEAM_Blue, - TEAM_Green, - TEAM_Gold, - - NUM_TEAMS, - TEAM_None = 255 -}; - -extern const char *TeamNames[NUM_TEAMS]; -extern float TeamHues[NUM_TEAMS]; - FArchive &operator<< (FArchive &arc, userinfo_t &info); void D_SetupUserInfo (void); diff --git a/src/d_netinfo.cpp b/src/d_netinfo.cpp index 6b30d48a1..0a1a81843 100644 --- a/src/d_netinfo.cpp +++ b/src/d_netinfo.cpp @@ -52,6 +52,7 @@ #include "sbar.h" #include "gi.h" #include "m_random.h" +#include "teaminfo.h" static FRandom pr_pickteam ("PickRandomTeam"); @@ -62,7 +63,7 @@ CVAR (Float, autoaim, 5000.f, CVAR_USERINFO | CVAR_ARCHIVE); CVAR (String, name, "Player", CVAR_USERINFO | CVAR_ARCHIVE); CVAR (Color, color, 0x40cf00, CVAR_USERINFO | CVAR_ARCHIVE); CVAR (String, skin, "base", CVAR_USERINFO | CVAR_ARCHIVE); -CVAR (Int, team, 255, CVAR_USERINFO | CVAR_ARCHIVE); +CVAR (Int, team, TEAM_None, CVAR_USERINFO | CVAR_ARCHIVE); CVAR (String, gender, "male", CVAR_USERINFO | CVAR_ARCHIVE); CVAR (Bool, neverswitchonpickup, false, CVAR_USERINFO | CVAR_ARCHIVE); CVAR (Float, movebob, 0.25f, CVAR_USERINFO | CVAR_ARCHIVE); @@ -83,16 +84,6 @@ enum INFO_PlayerClass, }; -const char *TeamNames[NUM_TEAMS] = -{ - "Red", "Blue", "Green", "Gold" -}; - -float TeamHues[NUM_TEAMS] = -{ - 0.f, 240.f, 120.f, 60.f -}; - const char *GenderNames[3] = { "male", "female", "other" }; static const char *UserInfoStrings[] = @@ -192,29 +183,11 @@ int D_PlayerClassToInt (const char *classname) void D_GetPlayerColor (int player, float *h, float *s, float *v) { - int color = players[player].userinfo.color; + userinfo_t *info = &players[player].userinfo; + int color = teamplay ? teams[info->team].playercolor : info->color; RGBtoHSV (RPART(color)/255.f, GPART(color)/255.f, BPART(color)/255.f, h, s, v); - - if (teamplay && players[player].userinfo.team < NUM_TEAMS) - { - // In team play, force the player to use the team's hue - // and adjust the saturation and value so that the team - // hue is visible in the final color. - *h = TeamHues[players[player].userinfo.team]; - if (gameinfo.gametype == GAME_Doom) - { - *s = *s*0.15f+0.8f; - *v = *v*0.5f+0.4f; - } - else - { - // I'm not really happy with the red team color in Heretic... - *s = team == 0 ? 0.6f : 0.8f; - *v = *v*0.4f+0.3f; - } - } } // Find out which teams are present. If there is only one, @@ -235,7 +208,12 @@ void D_PickRandomTeam (int player) int D_PickRandomTeam () { - int teamPresent[NUM_TEAMS] = { 0 }; + for (int i = 0; i < (signed)teams.Size (); i++) + { + teams[i].present = 0; + teams[i].ties = 0; + } + int numTeams = 0; int team; @@ -243,9 +221,9 @@ int D_PickRandomTeam () { if (playeringame[i]) { - if (players[i].userinfo.team < NUM_TEAMS) + if (TEAMINFO_IsValidTeam (players[i].userinfo.team)) { - if (teamPresent[players[i].userinfo.team]++ == 0) + if (teams[players[i].userinfo.team].present++ == 0) { numTeams++; } @@ -257,37 +235,36 @@ int D_PickRandomTeam () { do { - team = pr_pickteam() % NUM_TEAMS; - } while (teamPresent[team] != 0); + team = pr_pickteam() % teams.Size (); + } while (teams[team].present != 0); } else { int lowest = INT_MAX, lowestTie = 0, i; - int ties[NUM_TEAMS]; - for (i = 0; i < NUM_TEAMS; ++i) + for (i = 0; i < (signed)teams.Size (); ++i) { - if (teamPresent[i] > 0) + if (teams[i].present > 0) { - if (teamPresent[i] < lowest) + if (teams[i].present < lowest) { - lowest = teamPresent[i]; + lowest = teams[i].present; lowestTie = 0; - ties[0] = i; + teams[0].ties = i; } - else if (teamPresent[i] == lowest) + else if (teams[i].present == lowest) { - ties[++lowestTie] = i; + teams[++lowestTie].ties = i; } } } if (lowestTie == 0) { - team = ties[0]; + team = teams[0].ties; } else { - team = ties[pr_pickteam() % (lowestTie+1)]; + team = teams[pr_pickteam() % (lowestTie+1)].ties; } } @@ -299,21 +276,21 @@ static void UpdateTeam (int pnum, int team, bool update) userinfo_t *info = &players[pnum].userinfo; int oldteam; - if (team < 0) + if (team < TEAM_None) { team = TEAM_None; } oldteam = info->team; info->team = team; - if (teamplay && info->team >= NUM_TEAMS) + if (teamplay && !TEAMINFO_IsValidTeam (info->team)) { // Force players onto teams in teamplay mode info->team = D_PickRandomTeam (); } if (update && oldteam != info->team) { - if (info->team < NUM_TEAMS) - Printf ("%s joined the %s team\n", info->netname, TeamNames[info->team]); + if (TEAMINFO_IsValidTeam (info->team)) + Printf ("%s joined the %s team\n", info->netname, teams[info->team].name); else Printf ("%s is now a loner\n", info->netname); } @@ -323,13 +300,13 @@ static void UpdateTeam (int pnum, int team, bool update) { StatusBar->AttachToPlayer (&players[pnum]); } - if ((unsigned)info->team >= NUM_TEAMS) + if (!TEAMINFO_IsValidTeam (info->team)) info->team = TEAM_None; } int D_GetFragCount (player_t *player) { - if (!teamplay || player->userinfo.team >= NUM_TEAMS) + if (!teamplay || !TEAMINFO_IsValidTeam (player->userinfo.team)) { return player->fragcount; } @@ -359,7 +336,7 @@ void D_SetupUserInfo () memset (&players[i].userinfo, 0, sizeof(userinfo_t)); strncpy (coninfo->netname, name, MAXPLAYERNAME); - if (teamplay && team >= NUM_TEAMS) + if (teamplay && !TEAMINFO_IsValidTeam (team)) { coninfo->team = D_PickRandomTeam (); } diff --git a/src/hu_scores.cpp b/src/hu_scores.cpp index 26163a4c6..3e405faba 100644 --- a/src/hu_scores.cpp +++ b/src/hu_scores.cpp @@ -1,10 +1,10 @@ /* ** hu_scores.cpp -** Routines for drawing the deathmatch scoreboard. +** Routines for drawing the scoreboards. ** **--------------------------------------------------------------------------- ** Copyright 1998-2006 Randy Heit -** Copyright 2007 Chris Westley +** Copyright 2007 Christopher Westley ** All rights reserved. ** ** Redistribution and use in source and binary forms, with or without @@ -35,10 +35,11 @@ // HEADER FILES ------------------------------------------------------------ -#include "st_stuff.h" #include "c_console.h" -#include "v_video.h" +#include "st_stuff.h" +#include "teaminfo.h" #include "templates.h" +#include "v_video.h" // MACROS ------------------------------------------------------------------ @@ -50,11 +51,8 @@ // PRIVATE FUNCTION PROTOTYPES --------------------------------------------- -static void HU_DrawNonTeamScores (player_t *, player_t *[MAXPLAYERS]); -static void HU_DrawTeamScores (player_t *, player_t *[MAXPLAYERS]); - +static void HU_DoDrawScores (player_t *, player_t *[MAXPLAYERS]); static void HU_DrawTimeRemaining (int y); - static void HU_DrawPlayer (player_t *, bool, int, int, int, bool); // EXTERNAL DATA DECLARATIONS ---------------------------------------------- @@ -74,12 +72,11 @@ CVAR (Int, sb_deathmatch_yourplayercolor, CR_GREEN, CVAR_ARCHIVE) CVAR (Int, sb_deathmatch_otherplayercolor, CR_GREY, CVAR_ARCHIVE) CVAR (Bool, sb_teamdeathmatch_enable, true, CVAR_ARCHIVE) -CVAR (Int, sb_teamdeathmatch_yourplayercolor, CR_GREEN, CVAR_ARCHIVE) -CVAR (Int, sb_teamdeathmatch_otherplayercolor, CR_GREY, CVAR_ARCHIVE) +CVAR (Int, sb_teamdeathmatch_headingcolor, CR_RED, CVAR_ARCHIVE) // PRIVATE DATA DEFINITIONS ------------------------------------------------ -static int STACK_ARGS compare (const void *arg1, const void *arg2) +static int STACK_ARGS comparepoints (const void *arg1, const void *arg2) { if (deathmatch) return (*(player_t **)arg2)->fragcount - (*(player_t **)arg1)->fragcount; @@ -87,6 +84,11 @@ static int STACK_ARGS compare (const void *arg1, const void *arg2) return (*(player_t **)arg2)->killcount - (*(player_t **)arg1)->killcount; } +static int STACK_ARGS compareteams (const void *arg1, const void *arg2) +{ + return (*(player_t **)arg1)->userinfo.team - (*(player_t **)arg2)->userinfo.team; +} + // CODE -------------------------------------------------------------------- //========================================================================== @@ -97,6 +99,25 @@ static int STACK_ARGS compare (const void *arg1, const void *arg2) void HU_DrawScores (player_t *player) { + if (deathmatch) + { + if (teamplay) + { + if (!sb_teamdeathmatch_enable) + return; + } + else + { + if (!sb_deathmatch_enable) + return; + } + } + else + { + if (!sb_cooperative_enable) + return; + } + int i, j; player_t *sortedplayers[MAXPLAYERS]; @@ -111,31 +132,42 @@ void HU_DrawScores (player_t *player) sortedplayers[j] = &players[i]; } - qsort (sortedplayers, MAXPLAYERS, sizeof(player_t *), compare); - - if (deathmatch && teamplay) - HU_DrawTeamScores (player, sortedplayers); + if (teamplay) + qsort (sortedplayers, MAXPLAYERS, sizeof(player_t *), compareteams); else - HU_DrawNonTeamScores (player, sortedplayers); + qsort (sortedplayers, MAXPLAYERS, sizeof(player_t *), comparepoints); + + HU_DoDrawScores (player, sortedplayers); BorderNeedRefresh = screen->GetPageCount (); } //========================================================================== // -// HU_DrawNonTeamScores +// HU_DoDrawScores // //========================================================================== -static void HU_DrawNonTeamScores (player_t *player, player_t *sortedplayers[MAXPLAYERS]) +static void HU_DoDrawScores (player_t *player, player_t *sortedplayers[MAXPLAYERS]) { int color; int height = screen->Font->GetHeight() * CleanYfac; int i; int maxwidth = 0; + int numTeams = 0; int x ,y; - deathmatch ? color = sb_deathmatch_headingcolor : color = sb_cooperative_headingcolor; + if (deathmatch) + { + if (teamplay) + color = sb_teamdeathmatch_headingcolor; + else + color = sb_deathmatch_headingcolor; + } + else + { + color = sb_cooperative_headingcolor; + } for (i = 0; i < MAXPLAYERS; i++) { @@ -147,10 +179,49 @@ static void HU_DrawNonTeamScores (player_t *player, player_t *sortedplayers[MAXP } } - gamestate == GS_INTERMISSION ? y = SCREENHEIGHT / 4 : y = SCREENHEIGHT / 16; + gamestate == GS_INTERMISSION ? y = SCREENHEIGHT / 3.5 : y = SCREENHEIGHT / 16; HU_DrawTimeRemaining (ST_Y - height); + for (i = 0; i < teams.Size (); i++) + { + teams[i].players = 0; + teams[i].score = 0; + } + + for (i = 0; i < MAXPLAYERS; ++i) + { + if (playeringame[sortedplayers[i]-players] && TEAMINFO_IsValidTeam (sortedplayers[i]->userinfo.team)) + { + if (teams[sortedplayers[i]->userinfo.team].players++ == 0) + { + numTeams++; + } + + teams[sortedplayers[i]->userinfo.team].score += sortedplayers[i]->fragcount; + } + } + + int scorexwidth = SCREENWIDTH / 32; + for (i = 0; i < teams.Size (); i++) + { + if (teams[i].players) + { + char score[80]; + sprintf (score, "%d", teams[i].score); + + screen->SetFont (BigFont); + screen->DrawText (teams[i].GetTextColor (), scorexwidth, gamestate == GS_INTERMISSION ? y / 1.25 : y / 2, score, + DTA_CleanNoMove, true, TAG_DONE); + + scorexwidth += SCREENWIDTH / 8; + } + } + + gamestate == GS_INTERMISSION ? y += 0 : y += SCREENWIDTH / 32; + + screen->SetFont (SmallFont); + screen->DrawText (color, SCREENWIDTH / 32, y, "Color", DTA_CleanNoMove, true, TAG_DONE); @@ -163,6 +234,8 @@ static void HU_DrawNonTeamScores (player_t *player, player_t *sortedplayers[MAXP x = (SCREENWIDTH >> 1) - (((maxwidth + 32 + 32 + 16) * CleanXfac) >> 1); gamestate == GS_INTERMISSION ? y = SCREENHEIGHT / 3.5 : y = SCREENHEIGHT / 10; + y += SCREENWIDTH / 32; + for (i = 0; i < MAXPLAYERS && y < ST_Y - 12 * CleanYfac; i++) { if (playeringame[sortedplayers[i] - players]) @@ -173,86 +246,6 @@ static void HU_DrawNonTeamScores (player_t *player, player_t *sortedplayers[MAXP } } -//========================================================================== -// -// HU_DrawTeamScores -// -//========================================================================== - -static void HU_DrawTeamScores (player_t *player, player_t *sorted[MAXPLAYERS]) -{ - static const int teamColors[NUM_TEAMS] = { CR_RED, CR_BLUE, CR_GREEN, CR_GOLD }; - - char str[80]; - int height = screen->Font->GetHeight() * CleanYfac; - int teamPlayers[NUM_TEAMS] = { 0 }, teamSlot[NUM_TEAMS]; - int teamX[NUM_TEAMS], teamY[NUM_TEAMS], teamScore[NUM_TEAMS] = { 0 }; - int numTeams = 0; - int i, j, tallest; - - for (i = 0; i < MAXPLAYERS; ++i) - { - if (playeringame[sorted[i]-players] && sorted[i]->userinfo.team < NUM_TEAMS) - { - if (teamPlayers[sorted[i]->userinfo.team]++ == 0) - { - numTeams++; - } - teamScore[sorted[i]->userinfo.team] += sorted[i]->fragcount; - } - } - - if (numTeams == 0) - { - HU_DrawNonTeamScores (player, sorted); - return; - } - - HU_DrawTimeRemaining (ST_Y - height); - - screen->SetFont (BigFont); - - for (i = j = tallest = 0; i < NUM_TEAMS; ++i) - { - if (teamPlayers[i]) - { - teamPlayers[j] = teamPlayers[i]; - teamSlot[i] = j; - - if (j < 2 && teamPlayers[i] > tallest) - { - tallest = teamPlayers[i]; - } - else if (j == 2) - { - tallest = tallest * (height+CleanYfac) + 36*CleanYfac + teamY[0]; - } - - teamX[j] = (j&1) ? (SCREENWIDTH+teamX[0]) >> 1 : 10*CleanXfac; - teamY[j] = (j&2) ? tallest : (gamestate==GS_LEVEL?32*CleanYfac: - (56-100)*CleanYfac+(SCREENHEIGHT/2)); - - sprintf (str, "%s: %d", TeamNames[i], teamScore[i]); - screen->DrawText (teamColors[i], teamX[j], - teamY[j] - 20*CleanYfac, str, DTA_CleanNoMove, true, TAG_DONE); - - j++; - } - } - - screen->SetFont (SmallFont); - - for (i = 0; i < MAXPLAYERS; ++i) - { - if (playeringame[sorted[i]-players] && sorted[i]->userinfo.team < NUM_TEAMS) - { - int slot = teamSlot[sorted[i]->userinfo.team]; - HU_DrawPlayer (sorted[i], player==sorted[i], teamX[slot], teamY[slot], height, true); - teamY[slot] += height + CleanYfac; - } - } -} - //========================================================================== // // HU_DrawTimeRemaining @@ -304,50 +297,31 @@ static void HU_DrawPlayer (player_t *player, bool highlight, int x, int y, int h color = ColorMatcher.Pick (clamp (int(r*255.f),0,255), clamp (int(g*255.f),0,255), clamp (int(b*255.f),0,255)); - if (deathmatch && teamplay) + screen->Clear (SCREENWIDTH / 24, y, SCREENWIDTH / 24 + 24*CleanXfac, y + height, color); + + if (teamplay) { - screen->Clear (x, y, x + 24*CleanXfac, y + height, color); - - if (player->mo->ScoreIcon > 0) - { - screen->DrawTexture (TexMan[player->mo->ScoreIcon], x+(pack?20:32)*CleanXfac, y, - DTA_CleanNoMove, true, TAG_DONE); - } - - sprintf (str, "%d", player->fragcount); - - if (!highlight) - color = sb_teamdeathmatch_otherplayercolor; - else - color = sb_teamdeathmatch_yourplayercolor; - - screen->DrawText (color, x+(pack?28:40)*CleanXfac, y, str, - DTA_CleanNoMove, true, TAG_DONE); - - screen->DrawText (color, x + (pack?54:72)*CleanXfac, y, player->userinfo.netname, - DTA_CleanNoMove, true, TAG_DONE); + color = teams[player->userinfo.team].GetTextColor (); } else { - screen->Clear (SCREENWIDTH / 24, y, SCREENWIDTH / 24 + 24*CleanXfac, y + height, color); - if (!highlight) deathmatch ? color = sb_deathmatch_otherplayercolor : color = sb_cooperative_otherplayercolor; else deathmatch ? color = sb_deathmatch_yourplayercolor : color = sb_cooperative_yourplayercolor; + } - sprintf (str, "%d", deathmatch ? player->fragcount : player->killcount); + sprintf (str, "%d", deathmatch ? player->fragcount : player->killcount); - screen->DrawText (color, SCREENWIDTH / 4, y, str, + screen->DrawText (color, SCREENWIDTH / 4, y, str, + DTA_CleanNoMove, true, TAG_DONE); + + screen->DrawText (color, SCREENWIDTH / 2, y, player->userinfo.netname, + DTA_CleanNoMove, true, TAG_DONE); + + if (player->mo->ScoreIcon > 0) + { + screen->DrawTexture (TexMan[player->mo->ScoreIcon], SCREENWIDTH / 2.25, y, DTA_CleanNoMove, true, TAG_DONE); - - screen->DrawText (color, SCREENWIDTH / 2, y, player->userinfo.netname, - DTA_CleanNoMove, true, TAG_DONE); - - if (player->mo->ScoreIcon > 0) - { - screen->DrawTexture (TexMan[player->mo->ScoreIcon], SCREENWIDTH / 2.25, y, - DTA_CleanNoMove, true, TAG_DONE); - } } } diff --git a/src/m_menu.cpp b/src/m_menu.cpp index 620e5cdec..80b649ad3 100644 --- a/src/m_menu.cpp +++ b/src/m_menu.cpp @@ -65,6 +65,7 @@ #include "gi.h" #include "p_tick.h" #include "st_start.h" +#include "teaminfo.h" // MACROS ------------------------------------------------------------------ @@ -2078,8 +2079,8 @@ static void M_PlayerSetupDrawer () screen->DrawText (label, PSetupDef.x, PSetupDef.y + LINEHEIGHT+yo, "Team", DTA_Clean, true, TAG_DONE); screen->DrawText (value, x, PSetupDef.y + LINEHEIGHT+yo, - (unsigned)players[consoleplayer].userinfo.team >= NUM_TEAMS ? "None" : - TeamNames[players[consoleplayer].userinfo.team], + !TEAMINFO_IsValidTeam (players[consoleplayer].userinfo.team) ? "None" : + teams[players[consoleplayer].userinfo.team].name, DTA_Clean, true, TAG_DONE); // Draw player character @@ -2548,7 +2549,7 @@ static void M_ChangePlayerTeam (int choice) } else if (team == TEAM_None) { - team = NUM_TEAMS-1; + team = teams.Size () - 1; } else { @@ -2557,7 +2558,7 @@ static void M_ChangePlayerTeam (int choice) } else { - if (team == NUM_TEAMS-1) + if (team == teams.Size () - 1) { team = TEAM_None; } diff --git a/src/m_options.cpp b/src/m_options.cpp index 15ea0e829..62ab9729a 100644 --- a/src/m_options.cpp +++ b/src/m_options.cpp @@ -828,8 +828,7 @@ EXTERN_CVAR (Int, sb_deathmatch_yourplayercolor) EXTERN_CVAR (Int, sb_deathmatch_otherplayercolor) EXTERN_CVAR (Bool, sb_teamdeathmatch_enable) -EXTERN_CVAR (Int, sb_teamdeathmatch_yourplayercolor) -EXTERN_CVAR (Int, sb_teamdeathmatch_otherplayercolor) +EXTERN_CVAR (Int, sb_teamdeathmatch_headingcolor) static menuitem_t ScoreboardItems[] = { { whitetext, "Cooperative Options", {NULL}, {0.0}, {0.0}, {0.0}, {NULL} }, @@ -851,8 +850,7 @@ static menuitem_t ScoreboardItems[] = { { whitetext, "Team Deathmatch Options", {NULL}, {0.0}, {0.0}, {0.0}, {NULL} }, { redtext, " ", {NULL}, {0.0}, {0.0}, {0.0}, {NULL} }, { discrete, "Enable Scoreboard", {&sb_teamdeathmatch_enable}, {21.0}, {0.0}, {0.0}, {YesNo} }, - { cdiscrete, "Your Player Color", {&sb_teamdeathmatch_yourplayercolor}, {21.0}, {0.0}, {0.0}, {TextColors} }, - { cdiscrete, "Other Players' Color", {&sb_teamdeathmatch_otherplayercolor}, {21.0}, {0.0}, {0.0}, {TextColors} } + { cdiscrete, "Header Color", {&sb_teamdeathmatch_headingcolor}, {21.0}, {0.0}, {0.0}, {TextColors} } }; menu_t ScoreboardMenu = diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index d2b423ffc..5a9f26b97 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -54,6 +54,7 @@ #include "p_conversation.h" #include "thingdef/thingdef.h" #include "g_game.h" +#include "teaminfo.h" // MACROS ------------------------------------------------------------------ diff --git a/src/teaminfo.cpp b/src/teaminfo.cpp new file mode 100644 index 000000000..ed878745d --- /dev/null +++ b/src/teaminfo.cpp @@ -0,0 +1,180 @@ +/* +** teaminfo.cpp +** Implementation of the TEAMINFO lump. +** +**--------------------------------------------------------------------------- +** Copyright 2007 Christopher Westley +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**--------------------------------------------------------------------------- +** +*/ + +// HEADER FILES ------------------------------------------------------------ + +#include "i_system.h" +#include "sc_man.h" +#include "teaminfo.h" +#include "v_palette.h" +#include "w_wad.h" + +// MACROS ------------------------------------------------------------------ + +// TYPES ------------------------------------------------------------------- + +// EXTERNAL FUNCTION PROTOTYPES -------------------------------------------- + +// PUBLIC FUNCTION PROTOTYPES ---------------------------------------------- + +void TEAMINFO_Init (); +void TEAMINFO_ParseTeam (); + +bool TEAMINFO_IsValidTeam (int team); + +// PRIVATE FUNCTION PROTOTYPES --------------------------------------------- + +// EXTERNAL DATA DECLARATIONS ---------------------------------------------- + +// PUBLIC DATA DEFINITIONS ------------------------------------------------- + +TArray teams; + +// PRIVATE DATA DEFINITIONS ------------------------------------------------ + +static const char *keywords_teaminfo [] = { + "PLAYERCOLOR", + "TEXTCOLOR", + NULL +}; + +// CODE -------------------------------------------------------------------- + +//========================================================================== +// +// TEAMINFO_Init +// +//========================================================================== + +void TEAMINFO_Init () +{ + int lastlump = 0, lump; + + while ((lump = Wads.FindLump ("TEAMINFO", &lastlump)) != -1) + { + SC_OpenLumpNum (lump, "TEAMINFO"); + while (SC_GetString ()) + { + if (SC_Compare("CLEARTEAMS")) + teams.Clear (); + else if (SC_Compare("TEAM")) + TEAMINFO_ParseTeam (); + else + SC_ScriptError ("Unknown command %s in TEAMINFO", sc_String); + } + SC_Close(); + } + + if (teams.Size () == 0) + I_FatalError ("No teams defined in TEAMINFO"); +} + +//========================================================================== +// +// TEAMINFO_ParseTeam +// +//========================================================================== + +void TEAMINFO_ParseTeam () +{ + TEAMINFO team; + int i; + char *color; + + SC_MustGetString (); + team.name = sc_String; + + SC_MustGetStringName("{"); + while (!SC_CheckString("}")) + { + SC_MustGetString(); + switch(i = SC_MatchString (keywords_teaminfo)) + { + case 0: + SC_MustGetString (); + color = sc_String; + team.playercolor = V_GetColor (NULL, color); + break; + + case 1: + SC_MustGetString(); + team.textcolor = '['; + team.textcolor << sc_String << ']'; + break; + + default: + break; + } + } + + teams.Push (team); +} + +//========================================================================== +// +// TEAMINFO_IsValidTeam +// +//========================================================================== + +bool TEAMINFO_IsValidTeam (int team) +{ + if (team < 0 || team >= (signed)teams.Size ()) + { + return false; + } + + return true; +} + +//========================================================================== +// +// TEAMINFO :: GetTextColor +// +//========================================================================== + +int TEAMINFO::GetTextColor () const +{ + if (textcolor.IsEmpty()) + { + return CR_UNTRANSLATED; + } + const BYTE *cp = (const BYTE *)textcolor.GetChars(); + int color = V_ParseFontColor(cp, 0, 0); + if (color == CR_UNDEFINED) + { + Printf("Undefined color '%s' in definition of team %s\n", textcolor.GetChars (), name.GetChars ()); + color = CR_UNTRANSLATED; + } + return color; +} diff --git a/src/teaminfo.h b/src/teaminfo.h new file mode 100644 index 000000000..3059a3378 --- /dev/null +++ b/src/teaminfo.h @@ -0,0 +1,59 @@ +/* +** teaminfo.h +** Implementation of the TEAMINFO lump. +** +**--------------------------------------------------------------------------- +** Copyright 2007 Christopher Westley +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**--------------------------------------------------------------------------- +** +*/ + +#ifndef __TEAMINFO_H__ +#define __TEAMINFO_H__ + +#define TEAM_None -1 + +struct TEAMINFO +{ + FString name; + int playercolor; + FString textcolor; + int GetTextColor () const; + int players; + int score; + int present; + int ties; +}; + +extern TArray teams; + +extern void TEAMINFO_Init (); +extern void TEAMINFO_ParseTeam (); + +extern bool TEAMINFO_IsValidTeam (int team); + +#endif diff --git a/wadsrc/teaminfo.txt b/wadsrc/teaminfo.txt new file mode 100644 index 000000000..24cc0ee89 --- /dev/null +++ b/wadsrc/teaminfo.txt @@ -0,0 +1,49 @@ +ClearTeams + +Team "Blue" +{ + PlayerColor "00 00 FF" + TextColor "Blue" +} + +Team "Red" +{ + PlayerColor "FF 00 00" + TextColor "Red" +} + +Team "Green" +{ + PlayerColor "00 FF 00" + TextColor "Green" +} + +Team "Gold" +{ + PlayerColor "FF FF 00" + TextColor "Gold" +} + +Team "Black" +{ + PlayerColor "00 00 00" + TextColor "Black" +} + +Team "White" +{ + PlayerColor "FF FF FF" + TextColor "White" +} + +Team "Orange" +{ + PlayerColor "FF 80 00" + TextColor "Orange" +} + +Team "Purple" +{ + PlayerColor "FF 00 FF" + TextColor "Purple" +} diff --git a/wadsrc/wadsrc.vcproj b/wadsrc/wadsrc.vcproj index e3fd08afd..a07c39c5a 100644 --- a/wadsrc/wadsrc.vcproj +++ b/wadsrc/wadsrc.vcproj @@ -39,27 +39,6 @@ CompileAsManaged="" /> - - - + + + + + diff --git a/wadsrc/zdoom.lst b/wadsrc/zdoom.lst index 90df6f7fc..3d7b4fb00 100644 --- a/wadsrc/zdoom.lst +++ b/wadsrc/zdoom.lst @@ -59,6 +59,7 @@ in_htc1.txt in_htc1.txt in_htc2.txt in_htc2.txt in_htc3.txt in_htc3.txt lockdefs.txt lockdefs.txt +teaminfo.txt teaminfo.txt ======== # Support lumps diff --git a/zdoom.vcproj b/zdoom.vcproj index d44a7d771..124a060c2 100644 --- a/zdoom.vcproj +++ b/zdoom.vcproj @@ -135,6 +135,112 @@ Name="VCPostBuildEventTool" /> + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - @@ -2725,6 +2717,14 @@ GeneratePreprocessedFile="0" /> + + + @@ -2747,7 +2747,7 @@ /> + + @@ -3919,7 +3923,7 @@ /> + + @@ -4774,16 +4782,6 @@ Outputs="$(IntDir)\$(InputName).obj" /> - - - @@ -4794,6 +4792,16 @@ Outputs="$(IntDir)\$(InputName).obj" /> + + + @@ -4818,16 +4826,6 @@ Outputs="$(IntDir)\$(InputName).obj" /> - - - @@ -4838,6 +4836,16 @@ Outputs="$(IntDir)\$(InputName).obj" /> + + + @@ -4862,16 +4870,6 @@ Outputs="$(IntDir)\$(InputName).obj" /> - - - @@ -4882,6 +4880,16 @@ Outputs="$(IntDir)\$(InputName).obj" /> + + + @@ -4906,16 +4914,6 @@ Outputs="$(IntDir)\$(InputName).obj" /> - - - @@ -4926,6 +4924,16 @@ Outputs="$(IntDir)\$(InputName).obj" /> + + + @@ -4950,16 +4958,6 @@ Outputs="$(IntDir)\$(InputName).obj" /> - - - @@ -4970,6 +4968,16 @@ Outputs="$(IntDir)\$(InputName).obj" /> + + + @@ -5053,7 +5061,7 @@ /> - - - @@ -5400,6 +5400,14 @@ Outputs="$(IntDir)\$(InputName).obj" /> + + + + + + @@ -5626,14 +5642,6 @@ GeneratePreprocessedFile="0" /> - - - @@ -5655,7 +5663,7 @@ /> - - - @@ -9148,6 +9148,14 @@ AdditionalIncludeDirectories="src\win32;$(NoInherit)" /> + + + @@ -9322,7 +9330,7 @@ />