Implement adding new teams

This commit is contained in:
Lactozilla 2023-08-05 20:14:44 -03:00
parent d497be795e
commit bd5542c182
14 changed files with 628 additions and 65 deletions

View file

@ -131,6 +131,22 @@ static inline int lib_freeslot(lua_State *L)
if (i == NUMCOLORFREESLOTS) if (i == NUMCOLORFREESLOTS)
CONS_Alert(CONS_WARNING, "Ran out of free skincolor slots!\n"); CONS_Alert(CONS_WARNING, "Ran out of free skincolor slots!\n");
} }
else if (fastcmp(type, "TEAM"))
{
UINT8 i;
for (i = 0; i < MAXTEAMS; i++)
if (!teamnames[i]) {
CONS_Printf("Team TEAM_%s allocated.\n",word);
teamnames[i] = Z_Malloc(strlen(word)+1, PU_STATIC, NULL);
strcpy(teamnames[i],word);
lua_pushinteger(L, i);
numteams++;
r++;
break;
}
if (i == MAXTEAMS)
CONS_Alert(CONS_WARNING, "Ran out of free team slots!\n");
}
else if (fastcmp(type, "SPR2")) else if (fastcmp(type, "SPR2"))
{ {
// Search if we already have an SPR2 by that name... // Search if we already have an SPR2 by that name...
@ -561,6 +577,19 @@ static int ScanConstants(lua_State *L, boolean mathlib, const char *word)
} }
return luaL_error(L, "skincolor '%s' could not be found.\n", word); return luaL_error(L, "skincolor '%s' could not be found.\n", word);
} }
else if (fastncmp("TEAM_",word,5)) {
p = word+5;
for (i = 0; i < MAXTEAMS; i++)
{
if (!teamnames[i])
break;
if (fastcmp(p, teamnames[i])) {
CacheAndPushConstant(L, word, i);
return 1;
}
}
return luaL_error(L, "team '%s' could not be found.\n", word);
}
else if (fastncmp("GRADE_",word,6)) else if (fastncmp("GRADE_",word,6))
{ {
p = word+6; p = word+6;

View file

@ -473,6 +473,16 @@ void readfreeslots(MYFILE *f)
break; break;
} }
} }
else if (fastcmp(type, "TEAM"))
{
for (i = 0; i < MAXTEAMS; i++)
if (!teamnames[i]) {
teamnames[i] = Z_Malloc(strlen(word)+1, PU_STATIC, NULL);
strcpy(teamnames[i],word);
numteams++;
break;
}
}
else if (fastcmp(type, "SPR2")) else if (fastcmp(type, "SPR2"))
{ {
// Search if we already have an SPR2 by that name... // Search if we already have an SPR2 by that name...
@ -1139,15 +1149,20 @@ void readgametype(MYFILE *f, INT32 num)
INT32 i, j; INT32 i, j;
char *gtname = gametypes[num].name; char *gtname = gametypes[num].name;
char gtconst[32]; char gtconst[MAXLINELEN];
char gtdescription[441]; char gtdescription[441];
UINT8 teamcount = 0;
UINT8 teamlist[MAXTEAMS];
UINT8 newgtleftcolor, newgtrightcolor; UINT8 newgtleftcolor, newgtrightcolor;
boolean has_desc_colors[2] = { false, false }; boolean has_desc_colors[2] = { false, false };
memset(gtconst, 0, sizeof(gtconst)); memset(gtconst, 0, sizeof(gtconst));
memset(gtdescription, 0, sizeof(gtconst)); memset(gtdescription, 0, sizeof(gtconst));
strcpy(gtdescription, "???");
do do
{ {
if (myfgets(s, MAXLINELEN, f)) if (myfgets(s, MAXLINELEN, f))
@ -1307,6 +1322,35 @@ void readgametype(MYFILE *f, INT32 num)
gametypes[num].typeoflevel = tol; gametypes[num].typeoflevel = tol;
} }
} }
// Teams
else if (fastcmp(word, "TEAMLIST"))
{
tmp = strtok(word2,",");
do {
if (teamcount == MAXTEAMS)
{
deh_warning("readgametype %s: too many teams\n", gtname);
break;
}
UINT8 team_id = TEAM_NONE;
for (i = 1; i < MAXTEAMS; i++)
{
if (!teamnames[i])
break;
if (fasticmp(tmp, teamnames[i]))
{
team_id = i;
break;
}
}
if (team_id == TEAM_NONE)
deh_warning("readgametype %s: unknown team %s\n", gtname, tmp);
else
{
teamlist[teamcount++] = team_id;
}
} while((tmp = strtok(NULL,",")) != NULL);
}
// This SOC probably provided gametype rules as words, instead of using the RULES keyword. // This SOC probably provided gametype rules as words, instead of using the RULES keyword.
// (For example, "NOSPECTATORSPAWN = TRUE") // (For example, "NOSPECTATORSPAWN = TRUE")
else else
@ -1339,6 +1383,11 @@ void readgametype(MYFILE *f, INT32 num)
if (has_desc_colors[1]) if (has_desc_colors[1])
G_SetGametypeDescriptionRightColor(num, newgtrightcolor); G_SetGametypeDescriptionRightColor(num, newgtrightcolor);
// Copy the teams
gametypes[num].teams.num = teamcount;
if (teamcount)
memcpy(gametypes[num].teams.list, teamlist, sizeof(teamlist[0]) * teamcount);
// Write the constant name. // Write the constant name.
if (gametypes[num].constant_name == NULL) if (gametypes[num].constant_name == NULL)
{ {

View file

@ -407,7 +407,7 @@ typedef struct
{ {
char *name; char *name;
char *flag_name; char *flag_name;
UINT8 flag; UINT16 flag;
UINT32 flag_mobj_type; UINT32 flag_mobj_type;
UINT16 color; UINT16 color;
UINT16 weapon_color; UINT16 weapon_color;
@ -418,6 +418,8 @@ typedef struct
extern team_t teams[MAXTEAMS]; extern team_t teams[MAXTEAMS];
extern UINT8 numteams; extern UINT8 numteams;
extern char *teamnames[MAXTEAMS];
#define NUMGAMETYPEFREESLOTS 128 #define NUMGAMETYPEFREESLOTS 128
// Gametypes // Gametypes
@ -485,6 +487,12 @@ enum
RANKINGS_RACE RANKINGS_RACE
}; };
typedef struct
{
UINT8 num;
UINT8 list[MAXTEAMS];
} teamlist_t;
typedef struct typedef struct
{ {
char *name; char *name;
@ -495,8 +503,7 @@ typedef struct
INT16 rankings_type; INT16 rankings_type;
INT32 pointlimit; INT32 pointlimit;
INT32 timelimit; INT32 timelimit;
UINT8 numteams; teamlist_t teams;
UINT8 teams[MAXTEAMS];
} gametype_t; } gametype_t;
extern gametype_t gametypes[NUMGAMETYPES]; extern gametype_t gametypes[NUMGAMETYPES];

View file

@ -3460,8 +3460,10 @@ gametype_t gametypes[NUMGAMETYPES] = {
// default settings for match: timelimit 10 mins, no pointlimit // default settings for match: timelimit 10 mins, no pointlimit
.timelimit = 10, .timelimit = 10,
.pointlimit = 0, .pointlimit = 0,
.numteams = 2, .teams = {
.teams = { TEAM_RED, TEAM_BLUE } .num = 2,
.list = { TEAM_RED, TEAM_BLUE }
}
}, },
// GT_TAG // GT_TAG
{ {
@ -3494,8 +3496,10 @@ gametype_t gametypes[NUMGAMETYPES] = {
// default settings for CTF: no timelimit, pointlimit 5 // default settings for CTF: no timelimit, pointlimit 5
.timelimit = 0, .timelimit = 0,
.pointlimit = 5, .pointlimit = 5,
.numteams = 2, .teams = {
.teams = { TEAM_RED, TEAM_BLUE } .num = 2,
.list = { TEAM_RED, TEAM_BLUE }
}
}, },
}; };
@ -3520,6 +3524,8 @@ team_t teams[MAXTEAMS] = {
} }
}; };
char *teamnames[MAXTEAMS];
static void G_InitTeams(void) static void G_InitTeams(void)
{ {
numteams = 3; numteams = 3;
@ -3527,6 +3533,7 @@ static void G_InitTeams(void)
teams[TEAM_NONE].name = Z_StrDup("None"); teams[TEAM_NONE].name = Z_StrDup("None");
teams[TEAM_NONE].flag_name = Z_StrDup("Thingmabob"); teams[TEAM_NONE].flag_name = Z_StrDup("Thingmabob");
teamnames[TEAM_NONE] = Z_StrDup("NONE");
teams[TEAM_RED].name = Z_StrDup("Red"); teams[TEAM_RED].name = Z_StrDup("Red");
teams[TEAM_RED].flag_name = Z_StrDup("Red Flag"); teams[TEAM_RED].flag_name = Z_StrDup("Red Flag");
@ -3534,6 +3541,7 @@ static void G_InitTeams(void)
teams[TEAM_RED].icons[TEAM_ICON_FLAG] = Z_StrDup("RFLAGICO"); teams[TEAM_RED].icons[TEAM_ICON_FLAG] = Z_StrDup("RFLAGICO");
teams[TEAM_RED].icons[TEAM_ICON_GOT_FLAG] = Z_StrDup("GOTRFLAG"); teams[TEAM_RED].icons[TEAM_ICON_GOT_FLAG] = Z_StrDup("GOTRFLAG");
teams[TEAM_RED].icons[TEAM_ICON_MISSING_FLAG] = Z_StrDup("NONICON2"); teams[TEAM_RED].icons[TEAM_ICON_MISSING_FLAG] = Z_StrDup("NONICON2");
teamnames[TEAM_RED] = Z_StrDup("RED");
teams[TEAM_BLUE].name = Z_StrDup("Blue"); teams[TEAM_BLUE].name = Z_StrDup("Blue");
teams[TEAM_BLUE].flag_name = Z_StrDup("Blue Flag"); teams[TEAM_BLUE].flag_name = Z_StrDup("Blue Flag");
@ -3541,6 +3549,7 @@ static void G_InitTeams(void)
teams[TEAM_BLUE].icons[TEAM_ICON_FLAG] = Z_StrDup("BFLAGICO"); teams[TEAM_BLUE].icons[TEAM_ICON_FLAG] = Z_StrDup("BFLAGICO");
teams[TEAM_BLUE].icons[TEAM_ICON_GOT_FLAG] = Z_StrDup("GOTBFLAG"); teams[TEAM_BLUE].icons[TEAM_ICON_GOT_FLAG] = Z_StrDup("GOTBFLAG");
teams[TEAM_BLUE].icons[TEAM_ICON_MISSING_FLAG] = Z_StrDup("NONICON"); teams[TEAM_BLUE].icons[TEAM_ICON_MISSING_FLAG] = Z_StrDup("NONICON");
teamnames[TEAM_BLUE] = Z_StrDup("BLUE");
G_UpdateTeamSelection(); G_UpdateTeamSelection();
} }
@ -3567,11 +3576,20 @@ void G_UpdateTeamSelection(void)
i++; i++;
} }
for (UINT8 j = 1; j < teamsingame; j++, i++) if (G_GametypeHasTeams())
{ {
UINT8 team = G_GetTeam(j); for (UINT8 j = 1; j < teamsingame; j++, i++)
dummyteam_cons_t[i].value = team; {
dummyteam_cons_t[i].strvalue = teams[team].name; UINT8 team = G_GetTeam(j);
dummyteam_cons_t[i].value = team;
dummyteam_cons_t[i].strvalue = teams[team].name;
}
}
else
{
dummyteam_cons_t[i].value = 1;
dummyteam_cons_t[i].strvalue = "Playing";
i++;
} }
dummyteam_cons_t[i].value = 0; dummyteam_cons_t[i].value = 0;
@ -3579,6 +3597,7 @@ void G_UpdateTeamSelection(void)
cv_dummyteam.defaultvalue = dummyteam_cons_t[0].strvalue; cv_dummyteam.defaultvalue = dummyteam_cons_t[0].strvalue;
cv_dummyteam.value = 0; cv_dummyteam.value = 0;
cv_dummyteam.string = cv_dummyteam.defaultvalue;
} }
// //
@ -3590,9 +3609,9 @@ void G_SetGametype(INT16 gtype)
gametyperules = gametypes[gametype].rules; gametyperules = gametypes[gametype].rules;
if (G_GametypeHasTeams()) if (G_GametypeHasTeams())
teamsingame = gametypes[gametype].numteams + 1; teamsingame = gametypes[gametype].teams.num + 1;
else else
teamsingame = 3; teamsingame = 0;
G_UpdateTeamSelection(); G_UpdateTeamSelection();
} }
@ -3803,7 +3822,10 @@ boolean G_GametypeUsesCoopStarposts(void)
// //
boolean G_GametypeHasTeams(void) boolean G_GametypeHasTeams(void)
{ {
return (gametyperules & GTR_TEAMS); if (gametyperules & GTR_TEAMS)
return gametypes[gametype].teams.num > 0;
return false;
} }
// //
@ -3884,10 +3906,10 @@ UINT32 G_TOLFlag(INT32 pgametype)
UINT8 G_GetGametypeTeam(UINT8 gtype, UINT8 team) UINT8 G_GetGametypeTeam(UINT8 gtype, UINT8 team)
{ {
if (team == TEAM_NONE || team >= gametypes[gtype].numteams + 1) if (team == TEAM_NONE || team >= gametypes[gtype].teams.num + 1)
return TEAM_NONE; return TEAM_NONE;
return gametypes[gtype].teams[team - 1] % MAXTEAMS; return gametypes[gtype].teams.list[team - 1] % MAXTEAMS;
} }
UINT8 G_GetTeam(UINT8 team) UINT8 G_GetTeam(UINT8 team)
@ -3981,6 +4003,39 @@ boolean G_HasTeamIcon(UINT8 team, UINT8 icon_type)
return true; return true;
} }
void G_SetTeamIcon(UINT8 team, UINT8 icon_type, const char *icon)
{
if (team >= numteams || icon_type >= TEAM_ICON_MAX)
return;
Z_Free(teams[team].icons[icon_type]);
teams[team].icons[icon_type] = NULL;
if (icon)
teams[team].icons[icon_type] = Z_StrDup(icon);
}
void G_FreeTeamData(UINT8 team)
{
if (team >= numteams)
return;
team_t *team_ptr = &teams[team];
if (team_ptr->name)
Z_Free(team_ptr->name);
if (team_ptr->flag_name)
Z_Free(team_ptr->flag_name);
for (UINT8 i = 0; i < TEAM_ICON_MAX; i++)
{
Z_Free(team_ptr->icons[i]);
team_ptr->icons[i] = NULL;
}
team_ptr->name = NULL;
team_ptr->flag_name = NULL;
}
/** Select a random map with the given typeoflevel flags. /** Select a random map with the given typeoflevel flags.
* If no map has those flags, this arbitrarily gives you map 1. * If no map has those flags, this arbitrarily gives you map 1.
* \param tolflags The typeoflevel flags to insist on. Other bits may * \param tolflags The typeoflevel flags to insist on. Other bits may

View file

@ -234,6 +234,8 @@ UINT16 G_GetTeamWeaponColor(UINT8 team);
UINT16 G_GetTeamMissileColor(UINT8 team); UINT16 G_GetTeamMissileColor(UINT8 team);
const char *G_GetTeamIcon(UINT8 team, UINT8 icon_type); const char *G_GetTeamIcon(UINT8 team, UINT8 icon_type);
boolean G_HasTeamIcon(UINT8 team, UINT8 icon_type); boolean G_HasTeamIcon(UINT8 team, UINT8 icon_type);
void G_SetTeamIcon(UINT8 team, UINT8 icon_type, const char *icon);
void G_FreeTeamData(UINT8 team);
void G_Ticker(boolean run); void G_Ticker(boolean run);
boolean G_Responder(event_t *ev); boolean G_Responder(event_t *ev);

View file

@ -2294,13 +2294,13 @@ static void HU_Draw32TeamTabRankings(playersort_t *tab, INT32 whiteplayer)
greycheck = greycheckdef; greycheck = greycheckdef;
supercheck = supercheckdef; supercheck = supercheckdef;
if (tab[i].team == TEAM_RED) //red if (tab[i].team == G_GetTeam(1)) //red
{ {
redplayers++; redplayers++;
x = 14 + (BASEVIDWIDTH/2); x = 14 + (BASEVIDWIDTH/2);
y = (redplayers * 9) + 20; y = (redplayers * 9) + 20;
} }
else if (tab[i].team == TEAM_BLUE) //blue else if (tab[i].team == G_GetTeam(2)) //blue
{ {
blueplayers++; blueplayers++;
x = 14; x = 14;
@ -2380,7 +2380,7 @@ void HU_DrawTeamTabRankings(playersort_t *tab, INT32 whiteplayer)
if (players[tab[i].num].spectator) if (players[tab[i].num].spectator)
continue; //ignore them. continue; //ignore them.
if (tab[i].team == TEAM_RED) //red if (tab[i].team == G_GetTeam(1)) //red
{ {
if (redplayers++ > 8) if (redplayers++ > 8)
{ {
@ -2388,7 +2388,7 @@ void HU_DrawTeamTabRankings(playersort_t *tab, INT32 whiteplayer)
break; // don't make more loops than we need to. break; // don't make more loops than we need to.
} }
} }
else if (tab[i].team == TEAM_BLUE) //blue else if (tab[i].team == G_GetTeam(2)) //blue
{ {
if (blueplayers++ > 8) if (blueplayers++ > 8)
{ {
@ -2419,14 +2419,14 @@ void HU_DrawTeamTabRankings(playersort_t *tab, INT32 whiteplayer)
if (players[tab[i].num].spectator) if (players[tab[i].num].spectator)
continue; //ignore them. continue; //ignore them.
if (tab[i].team == TEAM_RED) //red if (tab[i].team == G_GetTeam(1)) //red
{ {
if (redplayers++ > 8) if (redplayers++ > 8)
continue; continue;
x = 32 + (BASEVIDWIDTH/2); x = 32 + (BASEVIDWIDTH/2);
y = (redplayers * 16) + 16; y = (redplayers * 16) + 16;
} }
else if (tab[i].team == TEAM_BLUE) //blue else if (tab[i].team == G_GetTeam(2)) //blue
{ {
if (blueplayers++ > 8) if (blueplayers++ > 8)
continue; continue;

View file

@ -156,6 +156,8 @@ static const struct {
{META_SKINCOLOR, "skincolor_t"}, {META_SKINCOLOR, "skincolor_t"},
{META_COLORRAMP, "skincolor_t.ramp"}, {META_COLORRAMP, "skincolor_t.ramp"},
{META_GAMETYPE, "gametype_t"}, {META_GAMETYPE, "gametype_t"},
{META_TEAM, "team_t"},
{META_TEAMLIST, "teamlist_t"},
{META_SPRITEINFO, "spriteinfo_t"}, {META_SPRITEINFO, "spriteinfo_t"},
{META_PIVOTLIST, "spriteframepivot_t[]"}, {META_PIVOTLIST, "spriteframepivot_t[]"},
{META_FRAMEPIVOT, "spriteframepivot_t"}, {META_FRAMEPIVOT, "spriteframepivot_t"},
@ -3545,7 +3547,6 @@ static int lib_sResumeMusic(lua_State *L)
// G_GAME // G_GAME
//////////// ////////////
// Copypasted from lib_cvRegisterVar :]
static int lib_gAddGametype(lua_State *L) static int lib_gAddGametype(lua_State *L)
{ {
const char *k; const char *k;
@ -3562,6 +3563,8 @@ static int lib_gAddGametype(lua_State *L)
UINT8 newgtrightcolor = 54; UINT8 newgtrightcolor = 54;
INT16 newgtrankingstype = RANKINGS_DEFAULT; INT16 newgtrankingstype = RANKINGS_DEFAULT;
int newgtinttype = 0; int newgtinttype = 0;
UINT8 teamcount = 0;
UINT8 teamlist[MAXTEAMS];
luaL_checktype(L, 1, LUA_TTABLE); luaL_checktype(L, 1, LUA_TTABLE);
lua_settop(L, 1); // Clear out all other possible arguments, leaving only the first one. lua_settop(L, 1); // Clear out all other possible arguments, leaving only the first one.
@ -3587,7 +3590,6 @@ static int lib_gAddGametype(lua_State *L)
else if (lua_isstring(L, 2)) else if (lua_isstring(L, 2))
k = lua_tostring(L, 2); k = lua_tostring(L, 2);
// Sorry, no gametype rules as key names.
if (i == 1 || (k && fasticmp(k, "name"))) { if (i == 1 || (k && fasticmp(k, "name"))) {
if (!lua_isstring(L, 3)) if (!lua_isstring(L, 3))
TYPEERROR("name", LUA_TSTRING) TYPEERROR("name", LUA_TSTRING)
@ -3632,6 +3634,36 @@ static int lib_gAddGametype(lua_State *L)
if (!lua_isnumber(L, 3)) if (!lua_isnumber(L, 3))
TYPEERROR("headerrightcolor", LUA_TNUMBER) TYPEERROR("headerrightcolor", LUA_TNUMBER)
newgtrightcolor = (UINT8)lua_tointeger(L, 3); newgtrightcolor = (UINT8)lua_tointeger(L, 3);
} else if (i == 12 || (k && fasticmp(k, "teams"))) {
if (lua_istable(L, 3))
{
lua_pushnil(L);
while (lua_next(L, 3)) {
lua_Integer idx = luaL_checkinteger(L, -2) - 1;
if (idx >= 0 && idx < MAXTEAMS)
{
int team_index = luaL_checkinteger(L, -1);
if (team_index < 0 || team_index >= numteams)
luaL_error(L, "team index %d out of range (0 - %d)", team_index, numteams-1);
teamlist[idx] = (UINT8)team_index;
if ((lua_Integer)teamcount < idx + 1)
teamcount = (UINT8)idx + 1;
}
lua_pop(L, 1);
}
}
else if (lua_isuserdata(L, 3))
{
teamlist_t *tl = *((teamlist_t **)luaL_checkudata(L, 3, META_TEAMLIST));
teamcount = tl->num;
memcpy(teamlist, tl->list, sizeof(teamlist[0]) * teamcount);
}
else
TYPEERROR("teams", LUA_TTABLE)
// Key name specified // Key name specified
} else if ((!i) && (k && fasticmp(k, "headercolor"))) { } else if ((!i) && (k && fasticmp(k, "headercolor"))) {
if (!lua_isnumber(L, 3)) if (!lua_isnumber(L, 3))
@ -3667,6 +3699,11 @@ static int lib_gAddGametype(lua_State *L)
gt->name = gtname; gt->name = gtname;
// Copy the teams
gt->teams.num = teamcount;
if (teamcount)
memcpy(gt->teams.list, teamlist, sizeof(teamlist[0]) * teamcount);
if (gtconst) if (gtconst)
G_AddGametypeConstant(gtype, gtconst); G_AddGametypeConstant(gtype, gtconst);
else else

View file

@ -1933,7 +1933,8 @@ enum gametype_e
gametype_intermission_type, gametype_intermission_type,
gametype_rankings_type, gametype_rankings_type,
gametype_pointlimit, gametype_pointlimit,
gametype_timelimit gametype_timelimit,
gametype_teams
}; };
const char *const gametype_opt[] = { const char *const gametype_opt[] = {
@ -1944,6 +1945,7 @@ const char *const gametype_opt[] = {
"rankings_type", "rankings_type",
"point_limit", "point_limit",
"time_limit", "time_limit",
"teams",
NULL, NULL,
}; };
@ -1980,6 +1982,11 @@ static int gametype_get(lua_State *L)
case gametype_timelimit: case gametype_timelimit:
lua_pushinteger(L, gt->timelimit); lua_pushinteger(L, gt->timelimit);
break; break;
case gametype_teams:
LUA_PushUserdata(L, &gt->teams, META_TEAMLIST);
break;
default:
return luaL_error(L, LUA_QL("gametype_t") " has no field named " LUA_QS, gametype_opt[field]);
} }
return 1; return 1;
} }
@ -1989,6 +1996,8 @@ static int gametype_set(lua_State *L)
gametype_t *gt = *((gametype_t **)luaL_checkudata(L, 1, META_GAMETYPE)); gametype_t *gt = *((gametype_t **)luaL_checkudata(L, 1, META_GAMETYPE));
enum gametype_e field = Lua_optoption(L, 2, -1, gametype_fields_ref); enum gametype_e field = Lua_optoption(L, 2, -1, gametype_fields_ref);
if (!lua_lumploading)
return luaL_error(L, "Do not alter gametype data from within a hook or coroutine!");
if (hud_running) if (hud_running)
return luaL_error(L, "Do not alter gametype data in HUD rendering code!"); return luaL_error(L, "Do not alter gametype data in HUD rendering code!");
if (hook_cmd_running) if (hook_cmd_running)
@ -1997,6 +2006,8 @@ static int gametype_set(lua_State *L)
I_Assert(gt != NULL); I_Assert(gt != NULL);
I_Assert(gt >= gametypes); I_Assert(gt >= gametypes);
INT16 gametype_id = gt - gametypes;
switch (field) switch (field)
{ {
case gametype_name: case gametype_name:
@ -2022,6 +2033,52 @@ static int gametype_set(lua_State *L)
case gametype_timelimit: case gametype_timelimit:
gt->timelimit = luaL_checkinteger(L, 3); gt->timelimit = luaL_checkinteger(L, 3);
break; break;
case gametype_teams:
if (lua_istable(L, 3))
{
gt->teams.num = 0;
memset(gt->teams.list, TEAM_NONE, sizeof(gt->teams.list));
lua_pushnil(L);
while (lua_next(L, 3)) {
lua_Integer i = luaL_checkinteger(L, -2) - 1;
if (i >= 0 && i < MAXTEAMS)
{
int team_index = luaL_checkinteger(L, -1);
if (team_index < 0 || team_index >= numteams)
luaL_error(L, "team index %d out of range (0 - %d)", team_index, numteams-1);
gt->teams.list[i] = (UINT8)team_index;
if ((lua_Integer)gt->teams.num < i + 1)
gt->teams.num = (UINT8)i + 1;
}
lua_pop(L, 1);
}
if (gametype == gametype_id)
{
teamsingame = gt->teams.num;
G_UpdateTeamSelection();
}
}
else
{
teamlist_t *teamlist = *((teamlist_t **)luaL_checkudata(L, 3, META_TEAMLIST));
memcpy(&gt->teams, teamlist, sizeof(teamlist_t));
if (gametype == gametype_id)
{
teamsingame = gt->teams.num;
G_UpdateTeamSelection();
}
}
break;
default:
return luaL_error(L, LUA_QL("gametype_t") " has no field named " LUA_QS, gametype_opt[field]);
} }
return 0; return 0;
} }
@ -2037,6 +2094,313 @@ static int gametype_num(lua_State *L)
return 1; return 1;
} }
///////////
// TEAMS //
///////////
enum team_e
{
team_name,
team_flag_name,
team_flag,
team_flag_mobj_type,
team_color,
team_weapon_color,
team_missile_color,
team_icon,
team_icon_flag,
team_icon_got_flag,
team_icon_missing_flag
};
const char *const team_opt[] = {
"name",
"flag_name",
"flag",
"flag_mobj_type",
"color",
"weapon_color",
"missile_color",
"icon",
"flag_icon",
"captured_flag_icon",
"missing_flag_icon",
NULL,
};
static int team_fields_ref = LUA_NOREF;
static int lib_getTeams(lua_State *L)
{
INT16 i;
lua_remove(L, 1);
i = luaL_checkinteger(L, 1);
if (i < 0 || i >= numteams)
return luaL_error(L, "teams[] index %d out of range (0 - %d)", i, numteams-1);
LUA_PushUserdata(L, &teams[i], META_GAMETYPE);
return 1;
}
static int set_team_field(lua_State *L, team_t *team, enum team_e field)
{
switch (field)
{
case team_name:
Z_Free(team->name);
team->name = Z_StrDup(luaL_checkstring(L, 3));
G_UpdateTeamSelection();
break;
case team_flag_name:
Z_Free(team->flag_name);
team->flag_name = Z_StrDup(luaL_checkstring(L, 3));
break;
case team_flag:
team->flag = (UINT16)luaL_checkinteger(L, 3);
break;
case team_flag_mobj_type:
{
mobjtype_t type = luaL_checkinteger(L, 3);
if (type >= NUMMOBJTYPES)
{
luaL_error(L, "mobj type %d out of range (0 - %d)", type, NUMMOBJTYPES-1);
return 0;
}
team->flag_mobj_type = type;
break;
}
case team_color:
{
UINT16 newcolor = (UINT16)luaL_checkinteger(L, 3);
if (newcolor >= numskincolors)
{
luaL_error(L, "skincolor %d out of range (0 - %d).", newcolor, numskincolors-1);
return 0;
}
team->color = newcolor;
break;
}
case team_weapon_color:
{
UINT16 newcolor = (UINT16)luaL_checkinteger(L, 3);
if (newcolor >= numskincolors)
{
luaL_error(L, "skincolor %d out of range (0 - %d).", newcolor, numskincolors-1);
return 0;
}
team->weapon_color = newcolor;
break;
}
case team_missile_color:
{
UINT16 newcolor = (UINT16)luaL_checkinteger(L, 3);
if (newcolor >= numskincolors)
{
luaL_error(L, "skincolor %d out of range (0 - %d).", newcolor, numskincolors-1);
return 0;
}
team->missile_color = newcolor;
break;
}
case team_icon:
G_SetTeamIcon(team - teams, TEAM_ICON, luaL_checkstring(L, 3));
ST_LoadTeamIcons();
break;
case team_icon_flag:
G_SetTeamIcon(team - teams, TEAM_ICON_FLAG, luaL_checkstring(L, 3));
ST_LoadTeamIcons();
break;
case team_icon_got_flag:
G_SetTeamIcon(team - teams, TEAM_ICON_GOT_FLAG, luaL_checkstring(L, 3));
ST_LoadTeamIcons();
break;
case team_icon_missing_flag:
G_SetTeamIcon(team - teams, TEAM_ICON_MISSING_FLAG, luaL_checkstring(L, 3));
ST_LoadTeamIcons();
break;
default:
return -1;
}
return 1;
}
static int lib_setTeams(lua_State *L)
{
UINT32 teamnum;
team_t *team;
lua_remove(L, 1);
{
teamnum = luaL_checkinteger(L, 1);
if (teamnum >= numteams)
return luaL_error(L, "teams[] index %d out of range (0 - %d)", teamnum, numteams-1);
team = &teams[teamnum];
}
luaL_checktype(L, 2, LUA_TTABLE);
lua_remove(L, 1);
lua_settop(L, 1);
if (hud_running)
return luaL_error(L, "Do not alter team data in HUD rendering code!");
if (hook_cmd_running)
return luaL_error(L, "Do not alter team data in CMD building code!");
G_FreeTeamData(teamnum);
memset(team, 0, sizeof(team_t));
lua_pushnil(L);
while (lua_next(L, 1)) {
const char *str = luaL_checkstring(L, 2);
int field = -1;
for (int i = 0; team_opt[i]; i++) {
if (fastcmp(str, team_opt[i]))
{
field = i;
break;
}
}
if (field != -1)
set_team_field(L, team, field);
else
luaL_error(L, LUA_QL("team_t") " has no field named " LUA_QS, str);
lua_pop(L, 1);
}
return 0;
}
// #teams -> numteams
static int lib_teamslen(lua_State *L)
{
lua_pushinteger(L, numteams);
return 1;
}
static int team_get(lua_State *L)
{
team_t *team = *((team_t **)luaL_checkudata(L, 1, META_GAMETYPE));
enum team_e field = Lua_optoption(L, 2, team_name, team_fields_ref);
I_Assert(team != NULL);
I_Assert(team >= teams);
switch (field)
{
case team_name:
lua_pushstring(L, team->name);
break;
case team_flag_name:
lua_pushstring(L, team->flag_name);
break;
case team_flag:
lua_pushinteger(L, team->flag);
break;
case team_flag_mobj_type:
lua_pushinteger(L, team->flag_mobj_type);
break;
case team_color:
lua_pushinteger(L, team->color);
break;
case team_weapon_color:
lua_pushinteger(L, team->weapon_color);
break;
case team_missile_color:
lua_pushinteger(L, team->missile_color);
break;
case team_icon:
if (G_HasTeamIcon(team - teams, TEAM_ICON))
lua_pushstring(L, G_GetTeamIcon(team - teams, TEAM_ICON));
else
lua_pushnil(L);
break;
case team_icon_flag:
if (G_HasTeamIcon(team - teams, TEAM_ICON_FLAG))
lua_pushstring(L, G_GetTeamIcon(team - teams, TEAM_ICON_FLAG));
else
lua_pushnil(L);
break;
case team_icon_got_flag:
if (G_HasTeamIcon(team - teams, TEAM_ICON_GOT_FLAG))
lua_pushstring(L, G_GetTeamIcon(team - teams, TEAM_ICON_GOT_FLAG));
else
lua_pushnil(L);
break;
case team_icon_missing_flag:
if (G_HasTeamIcon(team - teams, TEAM_ICON_MISSING_FLAG))
lua_pushstring(L, G_GetTeamIcon(team - teams, TEAM_ICON_MISSING_FLAG));
else
lua_pushnil(L);
break;
default:
return luaL_error(L, LUA_QL("team_t") " has no field named " LUA_QS, lua_tostring(L, 2));
}
return 1;
}
static int team_set(lua_State *L)
{
team_t *team = *((team_t **)luaL_checkudata(L, 1, META_GAMETYPE));
enum team_e field = Lua_optoption(L, 2, -1, team_fields_ref);
if (!lua_lumploading)
return luaL_error(L, "Do not alter team data from within a hook or coroutine!");
if (hud_running)
return luaL_error(L, "Do not alter team data in HUD rendering code!");
if (hook_cmd_running)
return luaL_error(L, "Do not alter team data in CMD building code!");
I_Assert(team != NULL);
I_Assert(team >= teams);
if (set_team_field(L, team, field) < 0)
return luaL_error(L, LUA_QL("team_t") " has no field named " LUA_QS, lua_tostring(L, 2));
return 0;
}
static int team_num(lua_State *L)
{
team_t *team = *((team_t **)luaL_checkudata(L, 1, META_GAMETYPE));
I_Assert(team != NULL);
I_Assert(team >= teams);
lua_pushinteger(L, team-teams);
return 1;
}
static int teamlist_len(lua_State *L)
{
teamlist_t *teamlist = *((teamlist_t **)luaL_checkudata(L, 1, META_TEAMLIST));
lua_pushinteger(L, teamlist->num);
return 1;
}
static int teamlist_get(lua_State *L)
{
teamlist_t *teamlist = *((teamlist_t **)luaL_checkudata(L, 1, META_TEAMLIST));
int i = luaL_checkinteger(L, 2);
if (i < 0 || i > teamlist->num)
return luaL_error(L, "list index %d out of range (1 - %d)", i, teamlist->num);
lua_pushinteger(L, teamlist->list[i - 1]);
return 1;
}
static int teamlist_set(lua_State *L)
{
teamlist_t *teamlist = *((teamlist_t **)luaL_checkudata(L, 1, META_TEAMLIST));
int i = luaL_checkinteger(L, 2);
if (i < 0 || i > teamlist->num)
return luaL_error(L, "list index %d out of range (1 - %d)", i, teamlist->num);
int team = luaL_checkinteger(L, 3);
if (team < 0 || team >= numteams)
return luaL_error(L, "team index %d out of range (0 - %d)", i, numteams - 1);
teamlist->list[i - 1] = (UINT8)team;
return 0;
}
////////////////////////////// //////////////////////////////
// //
// Now push all these functions into the Lua state! // Now push all these functions into the Lua state!
@ -2055,6 +2419,8 @@ int LUA_InfoLib(lua_State *L)
LUA_RegisterUserdataMetatable(L, META_STATE, state_get, state_set, state_num); LUA_RegisterUserdataMetatable(L, META_STATE, state_get, state_set, state_num);
LUA_RegisterUserdataMetatable(L, META_MOBJINFO, mobjinfo_get, mobjinfo_set, mobjinfo_num); LUA_RegisterUserdataMetatable(L, META_MOBJINFO, mobjinfo_get, mobjinfo_set, mobjinfo_num);
LUA_RegisterUserdataMetatable(L, META_GAMETYPE, gametype_get, gametype_set, gametype_num); LUA_RegisterUserdataMetatable(L, META_GAMETYPE, gametype_get, gametype_set, gametype_num);
LUA_RegisterUserdataMetatable(L, META_TEAM, team_get, team_set, team_num);
LUA_RegisterUserdataMetatable(L, META_TEAMLIST, teamlist_get, teamlist_set, teamlist_len);
LUA_RegisterUserdataMetatable(L, META_SKINCOLOR, skincolor_get, skincolor_set, skincolor_num); LUA_RegisterUserdataMetatable(L, META_SKINCOLOR, skincolor_get, skincolor_set, skincolor_num);
LUA_RegisterUserdataMetatable(L, META_COLORRAMP, colorramp_get, colorramp_set, colorramp_len); LUA_RegisterUserdataMetatable(L, META_COLORRAMP, colorramp_get, colorramp_set, colorramp_len);
LUA_RegisterUserdataMetatable(L, META_SFXINFO, sfxinfo_get, sfxinfo_set, sfxinfo_num); LUA_RegisterUserdataMetatable(L, META_SFXINFO, sfxinfo_get, sfxinfo_set, sfxinfo_num);
@ -2064,6 +2430,7 @@ int LUA_InfoLib(lua_State *L)
LUA_RegisterUserdataMetatable(L, META_LUABANKS, lib_getluabanks, lib_setluabanks, lib_luabankslen); LUA_RegisterUserdataMetatable(L, META_LUABANKS, lib_getluabanks, lib_setluabanks, lib_luabankslen);
mobjinfo_fields_ref = Lua_CreateFieldTable(L, mobjinfo_opt); mobjinfo_fields_ref = Lua_CreateFieldTable(L, mobjinfo_opt);
team_fields_ref = Lua_CreateFieldTable(L, team_opt);
LUA_RegisterGlobalUserdata(L, "sprnames", lib_getSprname, NULL, lib_sprnamelen); LUA_RegisterGlobalUserdata(L, "sprnames", lib_getSprname, NULL, lib_sprnamelen);
LUA_RegisterGlobalUserdata(L, "spr2names", lib_getSpr2name, NULL, lib_spr2namelen); LUA_RegisterGlobalUserdata(L, "spr2names", lib_getSpr2name, NULL, lib_spr2namelen);
@ -2071,6 +2438,8 @@ int LUA_InfoLib(lua_State *L)
LUA_RegisterGlobalUserdata(L, "states", lib_getState, lib_setState, lib_statelen); LUA_RegisterGlobalUserdata(L, "states", lib_getState, lib_setState, lib_statelen);
LUA_RegisterGlobalUserdata(L, "mobjinfo", lib_getMobjInfo, lib_setMobjInfo, lib_mobjinfolen); LUA_RegisterGlobalUserdata(L, "mobjinfo", lib_getMobjInfo, lib_setMobjInfo, lib_mobjinfolen);
LUA_RegisterGlobalUserdata(L, "gametypes", lib_getGametypes, NULL, lib_gametypeslen); LUA_RegisterGlobalUserdata(L, "gametypes", lib_getGametypes, NULL, lib_gametypeslen);
LUA_RegisterGlobalUserdata(L, "teams", lib_getTeams, lib_setTeams, lib_teamslen);
// LUA_RegisterGlobalUserdata(L, "gametypes", lib_getGametypes, NULL, lib_gametypeslen);
LUA_RegisterGlobalUserdata(L, "skincolors", lib_getSkinColor, lib_setSkinColor, lib_skincolorslen); LUA_RegisterGlobalUserdata(L, "skincolors", lib_getSkinColor, lib_setSkinColor, lib_skincolorslen);
LUA_RegisterGlobalUserdata(L, "spriteinfo", lib_getSpriteInfo, lib_setSpriteInfo, lib_spriteinfolen); LUA_RegisterGlobalUserdata(L, "spriteinfo", lib_getSpriteInfo, lib_setSpriteInfo, lib_spriteinfolen);
LUA_RegisterGlobalUserdata(L, "sfxinfo", lib_getSfxInfo, lib_setSfxInfo, lib_sfxlen); LUA_RegisterGlobalUserdata(L, "sfxinfo", lib_getSfxInfo, lib_setSfxInfo, lib_sfxlen);

View file

@ -30,6 +30,8 @@ extern boolean ignoregameinputs;
#define META_COLORRAMP "SKINCOLOR_T*RAMP" #define META_COLORRAMP "SKINCOLOR_T*RAMP"
#define META_SPRITEINFO "SPRITEINFO_T*" #define META_SPRITEINFO "SPRITEINFO_T*"
#define META_GAMETYPE "GAMETYPE_T*" #define META_GAMETYPE "GAMETYPE_T*"
#define META_TEAM "TEAM_T*"
#define META_TEAMLIST "TEAMLIST_T*"
#define META_PIVOTLIST "SPRITEFRAMEPIVOT_T[]" #define META_PIVOTLIST "SPRITEFRAMEPIVOT_T[]"
#define META_FRAMEPIVOT "SPRITEFRAMEPIVOT_T*" #define META_FRAMEPIVOT "SPRITEFRAMEPIVOT_T*"

View file

@ -214,10 +214,10 @@ int LUA_PushGlobals(lua_State *L, const char *word)
lua_pushboolean(L, paused); lua_pushboolean(L, paused);
return 1; return 1;
} else if (fastcmp(word,"bluescore")) { } else if (fastcmp(word,"bluescore")) {
lua_pushinteger(L, teamscores[TEAM_BLUE]); lua_pushinteger(L, teamscores[G_GetTeam(2)]);
return 1; return 1;
} else if (fastcmp(word,"redscore")) { } else if (fastcmp(word,"redscore")) {
lua_pushinteger(L, teamscores[TEAM_RED]); lua_pushinteger(L, teamscores[G_GetTeam(1)]);
return 1; return 1;
} else if (fastcmp(word,"timelimit")) { } else if (fastcmp(word,"timelimit")) {
lua_pushinteger(L, cv_timelimit.value); lua_pushinteger(L, cv_timelimit.value);
@ -226,16 +226,16 @@ int LUA_PushGlobals(lua_State *L, const char *word)
lua_pushinteger(L, cv_pointlimit.value); lua_pushinteger(L, cv_pointlimit.value);
return 1; return 1;
} else if (fastcmp(word, "redflag")) { } else if (fastcmp(word, "redflag")) {
LUA_PushUserdata(L, flagmobjs[TEAM_RED], META_MOBJ); LUA_PushUserdata(L, flagmobjs[G_GetTeam(1)], META_MOBJ);
return 1; return 1;
} else if (fastcmp(word, "blueflag")) { } else if (fastcmp(word, "blueflag")) {
LUA_PushUserdata(L, flagmobjs[TEAM_BLUE], META_MOBJ); LUA_PushUserdata(L, flagmobjs[G_GetTeam(2)], META_MOBJ);
return 1; return 1;
} else if (fastcmp(word, "rflagpoint")) { } else if (fastcmp(word, "rflagpoint")) {
LUA_PushUserdata(L, flagpoints[TEAM_RED], META_MAPTHING); LUA_PushUserdata(L, flagpoints[G_GetTeam(1)], META_MAPTHING);
return 1; return 1;
} else if (fastcmp(word, "bflagpoint")) { } else if (fastcmp(word, "bflagpoint")) {
LUA_PushUserdata(L, flagpoints[TEAM_BLUE], META_MAPTHING); LUA_PushUserdata(L, flagpoints[G_GetTeam(2)], META_MAPTHING);
return 1; return 1;
// begin map vars // begin map vars
} else if (fastcmp(word,"spstage_start")) { } else if (fastcmp(word,"spstage_start")) {
@ -271,6 +271,12 @@ int LUA_PushGlobals(lua_State *L, const char *word)
} else if (fastcmp(word,"tutorialmode")) { } else if (fastcmp(word,"tutorialmode")) {
lua_pushboolean(L, tutorialmode); lua_pushboolean(L, tutorialmode);
return 1; return 1;
} else if (fastcmp(word,"numteams")) {
lua_pushinteger(L, max(numteams - 1, 0));
return 1;
} else if (fastcmp(word,"teamsingame")) {
lua_pushinteger(L, max(teamsingame - 1, 0));
return 1;
// end map vars // end map vars
// begin CTF colors // begin CTF colors
} else if (fastcmp(word,"skincolor_redteam")) { } else if (fastcmp(word,"skincolor_redteam")) {
@ -992,6 +998,7 @@ enum
ARCH_MOUSE, ARCH_MOUSE,
ARCH_SKIN, ARCH_SKIN,
ARCH_GAMETYPE, ARCH_GAMETYPE,
ARCH_TEAM,
ARCH_TEND=0xFF, ARCH_TEND=0xFF,
}; };
@ -1022,6 +1029,7 @@ static const struct {
{META_MOUSE, ARCH_MOUSE}, {META_MOUSE, ARCH_MOUSE},
{META_SKIN, ARCH_SKIN}, {META_SKIN, ARCH_SKIN},
{META_GAMETYPE, ARCH_GAMETYPE}, {META_GAMETYPE, ARCH_GAMETYPE},
{META_TEAM, ARCH_TEAM},
{NULL, ARCH_NULL} {NULL, ARCH_NULL}
}; };
@ -1357,6 +1365,13 @@ static UINT8 ArchiveValue(int TABLESINDEX, int myindex)
WRITEUINT8(save_p, gt - gametypes); WRITEUINT8(save_p, gt - gametypes);
break; break;
} }
case ARCH_TEAM:
{
team_t *team = *((team_t **)lua_touserdata(gL, myindex));
WRITEUINT8(save_p, ARCH_TEAM);
WRITEUINT8(save_p, team - teams);
break;
}
default: default:
WRITEUINT8(save_p, ARCH_NULL); WRITEUINT8(save_p, ARCH_NULL);
return 2; return 2;
@ -1609,6 +1624,9 @@ static UINT8 UnArchiveValue(int TABLESINDEX)
case ARCH_GAMETYPE: case ARCH_GAMETYPE:
LUA_PushUserdata(gL, &gametypes[READUINT8(save_p)], META_GAMETYPE); LUA_PushUserdata(gL, &gametypes[READUINT8(save_p)], META_GAMETYPE);
break; break;
case ARCH_TEAM:
LUA_PushUserdata(gL, &teams[READUINT8(save_p)], META_TEAM);
break;
case ARCH_TEND: case ARCH_TEND:
return 1; return 1;
} }

View file

@ -465,7 +465,7 @@ static CV_PossibleValue_t dummymares_cons_t[] = {
{-1, "END"}, {0,"Overall"}, {1,"Mare 1"}, {2,"Mare 2"}, {3,"Mare 3"}, {4,"Mare 4"}, {5,"Mare 5"}, {6,"Mare 6"}, {7,"Mare 7"}, {8,"Mare 8"}, {0,NULL} {-1, "END"}, {0,"Overall"}, {1,"Mare 1"}, {2,"Mare 2"}, {3,"Mare 3"}, {4,"Mare 4"}, {5,"Mare 5"}, {6,"Mare 6"}, {7,"Mare 7"}, {8,"Mare 8"}, {0,NULL}
}; };
CV_PossibleValue_t dummyteam_cons_t[MAXTEAMS + 1]; CV_PossibleValue_t dummyteam_cons_t[MAXTEAMS + 2];
consvar_t cv_dummyteam = CVAR_INIT ("dummyteam", "Spectator", CV_HIDEN, dummyteam_cons_t, NULL); consvar_t cv_dummyteam = CVAR_INIT ("dummyteam", "Spectator", CV_HIDEN, dummyteam_cons_t, NULL);
@ -6954,18 +6954,7 @@ static void M_ConfirmTeamChange(INT32 choice)
M_ClearMenus(true); M_ClearMenus(true);
switch (cv_dummyteam.value) COM_ImmedExecute(va("changeteam %d", cv_dummyteam.value));
{
case 0:
COM_ImmedExecute("changeteam spectator");
break;
case 1:
COM_ImmedExecute("changeteam red");
break;
case 2:
COM_ImmedExecute("changeteam blue");
break;
}
} }
static void M_Options(INT32 choice) static void M_Options(INT32 choice)

View file

@ -4208,7 +4208,7 @@ void D_GameTypeChanged(INT32 lastgametype)
// When swapping to a gametype that supports spectators, // When swapping to a gametype that supports spectators,
// make everyone a spectator initially. // make everyone a spectator initially.
// Averted with GTR_NOSPECTATORSPAWN. // Averted with GTR_NOSPECTATORSPAWN.
if (!splitscreen && (G_GametypeHasSpectators())) if (!splitscreen && G_GametypeHasSpectators())
{ {
INT32 i; INT32 i;
for (i = 0; i < MAXPLAYERS; i++) for (i = 0; i < MAXPLAYERS; i++)

View file

@ -2283,8 +2283,20 @@ void P_CheckTimeLimit(void)
} }
else else
{ {
//In team match and CTF, determining a tie is much simpler. =P boolean is_tied = true;
if (teamscores[TEAM_RED] == teamscores[TEAM_BLUE]) UINT32 lastscore = teamscores[G_GetTeam(1)];
for (UINT8 j = 2; j < teamsingame; j++)
{
if (teamscores[G_GetTeam(j)] != lastscore)
{
is_tied = false;
break;
}
lastscore = teamscores[G_GetTeam(j)];
}
if (is_tied)
return; return;
} }
} }
@ -2304,7 +2316,8 @@ void P_CheckTimeLimit(void)
*/ */
void P_CheckPointLimit(void) void P_CheckPointLimit(void)
{ {
INT32 i; if (!server)
return;
if (!cv_pointlimit.value) if (!cv_pointlimit.value)
return; return;
@ -2315,19 +2328,22 @@ void P_CheckPointLimit(void)
if (!(gametyperules & GTR_POINTLIMIT)) if (!(gametyperules & GTR_POINTLIMIT))
return; return;
// pointlimit is nonzero, check if it's been reached by this player
if (G_GametypeHasTeams()) if (G_GametypeHasTeams())
{ {
// Just check both teams for (UINT8 i = 1; i < teamsingame; i++)
if ((UINT32)cv_pointlimit.value <= teamscores[TEAM_RED] || (UINT32)cv_pointlimit.value <= teamscores[TEAM_BLUE])
{ {
if (server) if (teamscores[G_GetTeam(i)] >= (UINT32)cv_pointlimit.value)
D_SendExitLevel(false); {
if (server)
D_SendExitLevel(false);
return;
}
} }
} }
else else
{ {
for (i = 0; i < MAXPLAYERS; i++) // pointlimit is nonzero, check if it's been reached by this player
for (INT32 i = 0; i < MAXPLAYERS; i++)
{ {
if (!playeringame[i] || players[i].spectator) if (!playeringame[i] || players[i].spectator)
continue; continue;

View file

@ -4340,12 +4340,7 @@ static void P_NetArchiveMisc(boolean resending)
WRITEUINT8(save_p, teamsingame); WRITEUINT8(save_p, teamsingame);
for (i = 0; i < MAXTEAMS; i++) for (i = 0; i < MAXTEAMS; i++)
{
WRITEUINT32(save_p, teamscores[i]); WRITEUINT32(save_p, teamscores[i]);
WRITEUINT16(save_p, teams[i].color);
WRITEUINT16(save_p, teams[i].weapon_color);
WRITEUINT16(save_p, teams[i].missile_color);
}
WRITEINT32(save_p, modulothing); WRITEINT32(save_p, modulothing);
@ -4440,12 +4435,7 @@ static inline boolean P_NetUnArchiveMisc(boolean reloading)
teamsingame = READUINT8(save_p); teamsingame = READUINT8(save_p);
for (i = 0; i < MAXTEAMS; i++) for (i = 0; i < MAXTEAMS; i++)
{
teamscores[i] = READUINT32(save_p); teamscores[i] = READUINT32(save_p);
teams[i].color = READUINT16(save_p);
teams[i].weapon_color = READUINT16(save_p);
teams[i].missile_color = READUINT16(save_p);
}
modulothing = READINT32(save_p); modulothing = READINT32(save_p);