mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2025-01-18 07:22:28 +00:00
Implement adding new teams
This commit is contained in:
parent
4a2f3a2b18
commit
f2bbc445a0
14 changed files with 660 additions and 71 deletions
|
@ -4262,7 +4262,7 @@ void D_GameTypeChanged(INT32 lastgametype)
|
|||
// When swapping to a gametype that supports spectators,
|
||||
// make everyone a spectator initially.
|
||||
// Averted with GTR_NOSPECTATORSPAWN.
|
||||
if (!splitscreen && (G_GametypeHasSpectators()))
|
||||
if (!splitscreen && G_GametypeHasSpectators())
|
||||
{
|
||||
INT32 i;
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
|
|
|
@ -131,6 +131,22 @@ static inline int lib_freeslot(lua_State *L)
|
|||
if (i == NUMCOLORFREESLOTS)
|
||||
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"))
|
||||
{
|
||||
// Search if we already have an SPR2 by that name...
|
||||
|
@ -560,6 +576,19 @@ static int ScanConstants(lua_State *L, boolean mathlib, const char *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))
|
||||
{
|
||||
p = word+6;
|
||||
|
|
|
@ -473,6 +473,16 @@ void readfreeslots(MYFILE *f)
|
|||
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"))
|
||||
{
|
||||
// Search if we already have an SPR2 by that name...
|
||||
|
@ -1149,11 +1159,15 @@ void readgametype(MYFILE *f, char *gtname)
|
|||
int newgtinttype = 0;
|
||||
char gtdescription[441];
|
||||
char gtconst[MAXLINELEN];
|
||||
UINT8 teamcount = 0;
|
||||
UINT8 teamlist[MAXTEAMS];
|
||||
|
||||
// Empty strings.
|
||||
gtdescription[0] = '\0';
|
||||
gtconst[0] = '\0';
|
||||
|
||||
strcpy(gtdescription, "???");
|
||||
|
||||
do
|
||||
{
|
||||
if (myfgets(s, MAXLINELEN, f))
|
||||
|
@ -1278,10 +1292,37 @@ void readgametype(MYFILE *f, char *gtname)
|
|||
newgttol = tol;
|
||||
}
|
||||
}
|
||||
// The SOC probably provided gametype rules as words,
|
||||
// instead of using the RULES keyword.
|
||||
// Like for example "NOSPECTATORSPAWN = TRUE".
|
||||
// This is completely valid, and looks better anyway.
|
||||
// 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.
|
||||
// (For example, "NOSPECTATORSPAWN = TRUE")
|
||||
else
|
||||
{
|
||||
UINT32 wordgt = 0;
|
||||
|
@ -1323,6 +1364,11 @@ void readgametype(MYFILE *f, char *gtname)
|
|||
gametypes[newgtidx].pointlimit = newgtpointlimit;
|
||||
gametypes[newgtidx].timelimit = newgttimelimit;
|
||||
|
||||
// Copy the teams
|
||||
gametypes[newgtidx].teams.num = teamcount;
|
||||
if (teamcount)
|
||||
memcpy(gametypes[newgtidx].teams.list, teamlist, sizeof(teamlist[0]) * teamcount);
|
||||
|
||||
// Write the new gametype name.
|
||||
gametypes[newgtidx].name = Z_StrDup(gtname);
|
||||
|
||||
|
|
|
@ -406,7 +406,7 @@ typedef struct
|
|||
{
|
||||
char *name;
|
||||
char *flag_name;
|
||||
UINT8 flag;
|
||||
UINT16 flag;
|
||||
UINT32 flag_mobj_type;
|
||||
UINT16 color;
|
||||
UINT16 weapon_color;
|
||||
|
@ -417,6 +417,8 @@ typedef struct
|
|||
extern team_t teams[MAXTEAMS];
|
||||
extern UINT8 numteams;
|
||||
|
||||
extern char *teamnames[MAXTEAMS];
|
||||
|
||||
#define NUMGAMETYPEFREESLOTS 128
|
||||
|
||||
// Gametypes
|
||||
|
@ -484,6 +486,12 @@ enum
|
|||
RANKINGS_RACE
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
UINT8 num;
|
||||
UINT8 list[MAXTEAMS];
|
||||
} teamlist_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char *name;
|
||||
|
@ -494,8 +502,7 @@ typedef struct
|
|||
INT16 rankings_type;
|
||||
INT32 pointlimit;
|
||||
INT32 timelimit;
|
||||
UINT8 numteams;
|
||||
UINT8 teams[MAXTEAMS];
|
||||
teamlist_t teams;
|
||||
} gametype_t;
|
||||
|
||||
extern gametype_t gametypes[NUMGAMETYPES];
|
||||
|
|
81
src/g_game.c
81
src/g_game.c
|
@ -3465,8 +3465,10 @@ gametype_t gametypes[NUMGAMETYPES] = {
|
|||
// default settings for match: timelimit 10 mins, no pointlimit
|
||||
.timelimit = 10,
|
||||
.pointlimit = 0,
|
||||
.numteams = 2,
|
||||
.teams = { TEAM_RED, TEAM_BLUE }
|
||||
.teams = {
|
||||
.num = 2,
|
||||
.list = { TEAM_RED, TEAM_BLUE }
|
||||
}
|
||||
},
|
||||
// GT_TAG
|
||||
{
|
||||
|
@ -3499,8 +3501,10 @@ gametype_t gametypes[NUMGAMETYPES] = {
|
|||
// default settings for CTF: no timelimit, pointlimit 5
|
||||
.timelimit = 0,
|
||||
.pointlimit = 5,
|
||||
.numteams = 2,
|
||||
.teams = { TEAM_RED, TEAM_BLUE }
|
||||
.teams = {
|
||||
.num = 2,
|
||||
.list = { TEAM_RED, TEAM_BLUE }
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -3525,6 +3529,8 @@ team_t teams[MAXTEAMS] = {
|
|||
}
|
||||
};
|
||||
|
||||
char *teamnames[MAXTEAMS];
|
||||
|
||||
static void G_InitTeams(void)
|
||||
{
|
||||
numteams = 3;
|
||||
|
@ -3532,6 +3538,7 @@ static void G_InitTeams(void)
|
|||
|
||||
teams[TEAM_NONE].name = Z_StrDup("None");
|
||||
teams[TEAM_NONE].flag_name = Z_StrDup("Thingmabob");
|
||||
teamnames[TEAM_NONE] = Z_StrDup("NONE");
|
||||
|
||||
teams[TEAM_RED].name = Z_StrDup("Red");
|
||||
teams[TEAM_RED].flag_name = Z_StrDup("Red Flag");
|
||||
|
@ -3539,6 +3546,7 @@ static void G_InitTeams(void)
|
|||
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_MISSING_FLAG] = Z_StrDup("NONICON2");
|
||||
teamnames[TEAM_RED] = Z_StrDup("RED");
|
||||
|
||||
teams[TEAM_BLUE].name = Z_StrDup("Blue");
|
||||
teams[TEAM_BLUE].flag_name = Z_StrDup("Blue Flag");
|
||||
|
@ -3546,6 +3554,7 @@ static void G_InitTeams(void)
|
|||
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_MISSING_FLAG] = Z_StrDup("NONICON");
|
||||
teamnames[TEAM_BLUE] = Z_StrDup("BLUE");
|
||||
|
||||
G_UpdateTeamSelection();
|
||||
}
|
||||
|
@ -3572,11 +3581,20 @@ void G_UpdateTeamSelection(void)
|
|||
i++;
|
||||
}
|
||||
|
||||
for (UINT8 j = 1; j < teamsingame; j++, i++)
|
||||
if (G_GametypeHasTeams())
|
||||
{
|
||||
UINT8 team = G_GetTeam(j);
|
||||
dummyteam_cons_t[i].value = team;
|
||||
dummyteam_cons_t[i].strvalue = teams[team].name;
|
||||
for (UINT8 j = 1; j < teamsingame; j++, i++)
|
||||
{
|
||||
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;
|
||||
|
@ -3584,6 +3602,7 @@ void G_UpdateTeamSelection(void)
|
|||
|
||||
cv_dummyteam.defaultvalue = dummyteam_cons_t[0].strvalue;
|
||||
cv_dummyteam.value = 0;
|
||||
cv_dummyteam.string = cv_dummyteam.defaultvalue;
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -3595,9 +3614,9 @@ void G_SetGametype(INT16 gtype)
|
|||
gametyperules = gametypes[gametype].rules;
|
||||
|
||||
if (G_GametypeHasTeams())
|
||||
teamsingame = gametypes[gametype].numteams + 1;
|
||||
teamsingame = gametypes[gametype].teams.num + 1;
|
||||
else
|
||||
teamsingame = 3;
|
||||
teamsingame = 0;
|
||||
|
||||
G_UpdateTeamSelection();
|
||||
}
|
||||
|
@ -3804,7 +3823,10 @@ boolean G_GametypeUsesCoopStarposts(void)
|
|||
//
|
||||
boolean G_GametypeHasTeams(void)
|
||||
{
|
||||
return (gametyperules & GTR_TEAMS);
|
||||
if (gametyperules & GTR_TEAMS)
|
||||
return gametypes[gametype].teams.num > 0;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -3885,10 +3907,10 @@ UINT32 G_TOLFlag(INT32 pgametype)
|
|||
|
||||
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 gametypes[gtype].teams[team - 1] % MAXTEAMS;
|
||||
return gametypes[gtype].teams.list[team - 1] % MAXTEAMS;
|
||||
}
|
||||
|
||||
UINT8 G_GetTeam(UINT8 team)
|
||||
|
@ -3982,6 +4004,39 @@ boolean G_HasTeamIcon(UINT8 team, UINT8 icon_type)
|
|||
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.
|
||||
* If no map has those flags, this arbitrarily gives you map 1.
|
||||
* \param tolflags The typeoflevel flags to insist on. Other bits may
|
||||
|
|
|
@ -231,6 +231,8 @@ UINT16 G_GetTeamWeaponColor(UINT8 team);
|
|||
UINT16 G_GetTeamMissileColor(UINT8 team);
|
||||
const char *G_GetTeamIcon(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);
|
||||
boolean G_Responder(event_t *ev);
|
||||
|
|
|
@ -2323,13 +2323,13 @@ static void HU_Draw32TeamTabRankings(playersort_t *tab, INT32 whiteplayer)
|
|||
greycheck = greycheckdef;
|
||||
supercheck = supercheckdef;
|
||||
|
||||
if (tab[i].team == TEAM_RED) //red
|
||||
if (tab[i].team == G_GetTeam(1)) //red
|
||||
{
|
||||
redplayers++;
|
||||
x = 14 + (BASEVIDWIDTH/2);
|
||||
y = (redplayers * 9) + 20;
|
||||
}
|
||||
else if (tab[i].team == TEAM_BLUE) //blue
|
||||
else if (tab[i].team == G_GetTeam(2)) //blue
|
||||
{
|
||||
blueplayers++;
|
||||
x = 14;
|
||||
|
@ -2409,7 +2409,7 @@ void HU_DrawTeamTabRankings(playersort_t *tab, INT32 whiteplayer)
|
|||
if (players[tab[i].num].spectator)
|
||||
continue; //ignore them.
|
||||
|
||||
if (tab[i].team == TEAM_RED) //red
|
||||
if (tab[i].team == G_GetTeam(1)) //red
|
||||
{
|
||||
if (redplayers++ > 8)
|
||||
{
|
||||
|
@ -2417,7 +2417,7 @@ void HU_DrawTeamTabRankings(playersort_t *tab, INT32 whiteplayer)
|
|||
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)
|
||||
{
|
||||
|
@ -2448,14 +2448,14 @@ void HU_DrawTeamTabRankings(playersort_t *tab, INT32 whiteplayer)
|
|||
if (players[tab[i].num].spectator)
|
||||
continue; //ignore them.
|
||||
|
||||
if (tab[i].team == TEAM_RED) //red
|
||||
if (tab[i].team == G_GetTeam(1)) //red
|
||||
{
|
||||
if (redplayers++ > 8)
|
||||
continue;
|
||||
x = 32 + (BASEVIDWIDTH/2);
|
||||
y = (redplayers * 16) + 16;
|
||||
}
|
||||
else if (tab[i].team == TEAM_BLUE) //blue
|
||||
else if (tab[i].team == G_GetTeam(2)) //blue
|
||||
{
|
||||
if (blueplayers++ > 8)
|
||||
continue;
|
||||
|
|
|
@ -156,6 +156,8 @@ static const struct {
|
|||
{META_SKINCOLOR, "skincolor_t"},
|
||||
{META_COLORRAMP, "skincolor_t.ramp"},
|
||||
{META_GAMETYPE, "gametype_t"},
|
||||
{META_TEAM, "team_t"},
|
||||
{META_TEAMLIST, "teamlist_t"},
|
||||
{META_SPRITEINFO, "spriteinfo_t"},
|
||||
{META_PIVOTLIST, "spriteframepivot_t[]"},
|
||||
{META_FRAMEPIVOT, "spriteframepivot_t"},
|
||||
|
@ -3402,7 +3404,6 @@ static int lib_sResumeMusic(lua_State *L)
|
|||
// G_GAME
|
||||
////////////
|
||||
|
||||
// Copypasted from lib_cvRegisterVar :]
|
||||
static int lib_gAddGametype(lua_State *L)
|
||||
{
|
||||
const char *k;
|
||||
|
@ -3420,6 +3421,8 @@ static int lib_gAddGametype(lua_State *L)
|
|||
UINT8 newgtrightcolor = 0;
|
||||
INT16 newgtrankingstype = -1;
|
||||
int newgtinttype = 0;
|
||||
UINT8 teamcount = 0;
|
||||
UINT8 teamlist[MAXTEAMS];
|
||||
|
||||
luaL_checktype(L, 1, LUA_TTABLE);
|
||||
lua_settop(L, 1); // Clear out all other possible arguments, leaving only the first one.
|
||||
|
@ -3445,7 +3448,6 @@ static int lib_gAddGametype(lua_State *L)
|
|||
else if (lua_isstring(L, 2))
|
||||
k = lua_tostring(L, 2);
|
||||
|
||||
// Sorry, no gametype rules as key names.
|
||||
if (i == 1 || (k && fasticmp(k, "name"))) {
|
||||
if (!lua_isstring(L, 3))
|
||||
TYPEERROR("name", LUA_TSTRING)
|
||||
|
@ -3490,6 +3492,36 @@ static int lib_gAddGametype(lua_State *L)
|
|||
if (!lua_isnumber(L, 3))
|
||||
TYPEERROR("headerrightcolor", LUA_TNUMBER)
|
||||
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
|
||||
} else if ((!i) && (k && fasticmp(k, "headercolor"))) {
|
||||
if (!lua_isnumber(L, 3))
|
||||
|
@ -3514,8 +3546,7 @@ static int lib_gAddGametype(lua_State *L)
|
|||
// Add the new gametype
|
||||
newgtidx = G_AddGametype(newgtrules);
|
||||
G_AddGametypeTOL(newgtidx, newgttol);
|
||||
G_SetGametypeDescription(newgtidx, NULL, newgtleftcolor, newgtrightcolor);
|
||||
strncpy(gametypedesc[newgtidx].notes, gtdescription, 441);
|
||||
G_SetGametypeDescription(newgtidx, gtdescription, newgtleftcolor, newgtrightcolor);
|
||||
|
||||
// Not covered by G_AddGametype alone.
|
||||
if (newgtrankingstype == -1)
|
||||
|
@ -3525,6 +3556,11 @@ static int lib_gAddGametype(lua_State *L)
|
|||
gametypes[newgtidx].pointlimit = newgtpointlimit;
|
||||
gametypes[newgtidx].timelimit = newgttimelimit;
|
||||
|
||||
// Copy the teams
|
||||
gametypes[newgtidx].teams.num = teamcount;
|
||||
if (teamcount)
|
||||
memcpy(gametypes[newgtidx].teams.list, teamlist, sizeof(teamlist[0]) * teamcount);
|
||||
|
||||
// Write the new gametype name.
|
||||
gametypes[newgtidx].name = gtname;
|
||||
|
||||
|
|
|
@ -1930,7 +1930,8 @@ enum gametype_e
|
|||
gametype_intermission_type,
|
||||
gametype_rankings_type,
|
||||
gametype_pointlimit,
|
||||
gametype_timelimit
|
||||
gametype_timelimit,
|
||||
gametype_teams
|
||||
};
|
||||
|
||||
const char *const gametype_opt[] = {
|
||||
|
@ -1941,6 +1942,7 @@ const char *const gametype_opt[] = {
|
|||
"rankings_type",
|
||||
"point_limit",
|
||||
"time_limit",
|
||||
"teams",
|
||||
NULL,
|
||||
};
|
||||
|
||||
|
@ -1977,6 +1979,11 @@ static int gametype_get(lua_State *L)
|
|||
case gametype_timelimit:
|
||||
lua_pushinteger(L, gt->timelimit);
|
||||
break;
|
||||
case gametype_teams:
|
||||
LUA_PushUserdata(L, >->teams, META_TEAMLIST);
|
||||
break;
|
||||
default:
|
||||
return luaL_error(L, LUA_QL("gametype_t") " has no field named " LUA_QS, gametype_opt[field]);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
@ -1986,6 +1993,8 @@ static int gametype_set(lua_State *L)
|
|||
gametype_t *gt = *((gametype_t **)luaL_checkudata(L, 1, META_GAMETYPE));
|
||||
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)
|
||||
return luaL_error(L, "Do not alter gametype data in HUD rendering code!");
|
||||
if (hook_cmd_running)
|
||||
|
@ -1994,6 +2003,8 @@ static int gametype_set(lua_State *L)
|
|||
I_Assert(gt != NULL);
|
||||
I_Assert(gt >= gametypes);
|
||||
|
||||
INT16 gametype_id = gt - gametypes;
|
||||
|
||||
switch (field)
|
||||
{
|
||||
case gametype_name:
|
||||
|
@ -2019,6 +2030,52 @@ static int gametype_set(lua_State *L)
|
|||
case gametype_timelimit:
|
||||
gt->timelimit = luaL_checkinteger(L, 3);
|
||||
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(>->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;
|
||||
}
|
||||
|
@ -2034,6 +2091,313 @@ static int gametype_num(lua_State *L)
|
|||
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!
|
||||
|
@ -2086,6 +2450,30 @@ int LUA_InfoLib(lua_State *L)
|
|||
|
||||
gametype_fields_ref = Lua_CreateFieldTable(L, gametype_opt);
|
||||
|
||||
luaL_newmetatable(L, META_TEAM);
|
||||
lua_pushcfunction(L, team_get);
|
||||
lua_setfield(L, -2, "__index");
|
||||
|
||||
lua_pushcfunction(L, team_set);
|
||||
lua_setfield(L, -2, "__newindex");
|
||||
|
||||
lua_pushcfunction(L, team_num);
|
||||
lua_setfield(L, -2, "__len");
|
||||
lua_pop(L, 1);
|
||||
|
||||
team_fields_ref = Lua_CreateFieldTable(L, team_opt);
|
||||
|
||||
luaL_newmetatable(L, META_TEAMLIST);
|
||||
lua_pushcfunction(L, teamlist_get);
|
||||
lua_setfield(L, -2, "__index");
|
||||
|
||||
lua_pushcfunction(L, teamlist_set);
|
||||
lua_setfield(L, -2, "__newindex");
|
||||
|
||||
lua_pushcfunction(L, teamlist_len);
|
||||
lua_setfield(L, -2, "__len");
|
||||
lua_pop(L, 1);
|
||||
|
||||
luaL_newmetatable(L, META_SKINCOLOR);
|
||||
lua_pushcfunction(L, skincolor_get);
|
||||
lua_setfield(L, -2, "__index");
|
||||
|
@ -2262,6 +2650,19 @@ int LUA_InfoLib(lua_State *L)
|
|||
lua_setmetatable(L, -2);
|
||||
lua_setglobal(L, "gametypes");
|
||||
|
||||
lua_newuserdata(L, 0);
|
||||
lua_createtable(L, 0, 2);
|
||||
lua_pushcfunction(L, lib_getTeams);
|
||||
lua_setfield(L, -2, "__index");
|
||||
|
||||
lua_pushcfunction(L, lib_setTeams);
|
||||
lua_setfield(L, -2, "__newindex");
|
||||
|
||||
lua_pushcfunction(L, lib_teamslen);
|
||||
lua_setfield(L, -2, "__len");
|
||||
lua_setmetatable(L, -2);
|
||||
lua_setglobal(L, "teams");
|
||||
|
||||
luaL_newmetatable(L, META_LUABANKS);
|
||||
lua_pushcfunction(L, lib_getluabanks);
|
||||
lua_setfield(L, -2, "__index");
|
||||
|
|
|
@ -29,6 +29,8 @@ extern boolean mousegrabbedbylua;
|
|||
#define META_COLORRAMP "SKINCOLOR_T*RAMP"
|
||||
#define META_SPRITEINFO "SPRITEINFO_T*"
|
||||
#define META_GAMETYPE "GAMETYPE_T*"
|
||||
#define META_TEAM "TEAM_T*"
|
||||
#define META_TEAMLIST "TEAMLIST_T*"
|
||||
#define META_PIVOTLIST "SPRITEFRAMEPIVOT_T[]"
|
||||
#define META_FRAMEPIVOT "SPRITEFRAMEPIVOT_T*"
|
||||
|
||||
|
|
|
@ -214,10 +214,10 @@ int LUA_PushGlobals(lua_State *L, const char *word)
|
|||
lua_pushboolean(L, paused);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"bluescore")) {
|
||||
lua_pushinteger(L, teamscores[TEAM_BLUE]);
|
||||
lua_pushinteger(L, teamscores[G_GetTeam(2)]);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"redscore")) {
|
||||
lua_pushinteger(L, teamscores[TEAM_RED]);
|
||||
lua_pushinteger(L, teamscores[G_GetTeam(1)]);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"timelimit")) {
|
||||
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);
|
||||
return 1;
|
||||
} else if (fastcmp(word, "redflag")) {
|
||||
LUA_PushUserdata(L, flagmobjs[TEAM_RED], META_MOBJ);
|
||||
LUA_PushUserdata(L, flagmobjs[G_GetTeam(1)], META_MOBJ);
|
||||
return 1;
|
||||
} else if (fastcmp(word, "blueflag")) {
|
||||
LUA_PushUserdata(L, flagmobjs[TEAM_BLUE], META_MOBJ);
|
||||
LUA_PushUserdata(L, flagmobjs[G_GetTeam(2)], META_MOBJ);
|
||||
return 1;
|
||||
} else if (fastcmp(word, "rflagpoint")) {
|
||||
LUA_PushUserdata(L, flagpoints[TEAM_RED], META_MAPTHING);
|
||||
LUA_PushUserdata(L, flagpoints[G_GetTeam(1)], META_MAPTHING);
|
||||
return 1;
|
||||
} else if (fastcmp(word, "bflagpoint")) {
|
||||
LUA_PushUserdata(L, flagpoints[TEAM_BLUE], META_MAPTHING);
|
||||
LUA_PushUserdata(L, flagpoints[G_GetTeam(2)], META_MAPTHING);
|
||||
return 1;
|
||||
// begin map vars
|
||||
} else if (fastcmp(word,"spstage_start")) {
|
||||
|
@ -271,6 +271,12 @@ int LUA_PushGlobals(lua_State *L, const char *word)
|
|||
} else if (fastcmp(word,"tutorialmode")) {
|
||||
lua_pushboolean(L, tutorialmode);
|
||||
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
|
||||
// begin CTF colors
|
||||
} else if (fastcmp(word,"skincolor_redteam")) {
|
||||
|
@ -991,6 +997,7 @@ enum
|
|||
ARCH_MOUSE,
|
||||
ARCH_SKIN,
|
||||
ARCH_GAMETYPE,
|
||||
ARCH_TEAM,
|
||||
|
||||
ARCH_TEND=0xFF,
|
||||
};
|
||||
|
@ -1021,6 +1028,7 @@ static const struct {
|
|||
{META_MOUSE, ARCH_MOUSE},
|
||||
{META_SKIN, ARCH_SKIN},
|
||||
{META_GAMETYPE, ARCH_GAMETYPE},
|
||||
{META_TEAM, ARCH_TEAM},
|
||||
{NULL, ARCH_NULL}
|
||||
};
|
||||
|
||||
|
@ -1356,6 +1364,13 @@ static UINT8 ArchiveValue(int TABLESINDEX, int myindex)
|
|||
WRITEUINT8(save_p, gt - gametypes);
|
||||
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:
|
||||
WRITEUINT8(save_p, ARCH_NULL);
|
||||
return 2;
|
||||
|
@ -1608,6 +1623,9 @@ static UINT8 UnArchiveValue(int TABLESINDEX)
|
|||
case ARCH_GAMETYPE:
|
||||
LUA_PushUserdata(gL, &gametypes[READUINT8(save_p)], META_GAMETYPE);
|
||||
break;
|
||||
case ARCH_TEAM:
|
||||
LUA_PushUserdata(gL, &teams[READUINT8(save_p)], META_TEAM);
|
||||
break;
|
||||
case ARCH_TEND:
|
||||
return 1;
|
||||
}
|
||||
|
|
15
src/m_menu.c
15
src/m_menu.c
|
@ -473,7 +473,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}
|
||||
};
|
||||
|
||||
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);
|
||||
|
||||
|
@ -6992,18 +6992,7 @@ static void M_ConfirmTeamChange(INT32 choice)
|
|||
|
||||
M_ClearMenus(true);
|
||||
|
||||
switch (cv_dummyteam.value)
|
||||
{
|
||||
case 0:
|
||||
COM_ImmedExecute("changeteam spectator");
|
||||
break;
|
||||
case 1:
|
||||
COM_ImmedExecute("changeteam red");
|
||||
break;
|
||||
case 2:
|
||||
COM_ImmedExecute("changeteam blue");
|
||||
break;
|
||||
}
|
||||
COM_ImmedExecute(va("changeteam %d", cv_dummyteam.value));
|
||||
}
|
||||
|
||||
static void M_Options(INT32 choice)
|
||||
|
|
|
@ -2282,8 +2282,20 @@ void P_CheckTimeLimit(void)
|
|||
}
|
||||
else
|
||||
{
|
||||
//In team match and CTF, determining a tie is much simpler. =P
|
||||
if (teamscores[TEAM_RED] == teamscores[TEAM_BLUE])
|
||||
boolean is_tied = true;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -2303,7 +2315,8 @@ void P_CheckTimeLimit(void)
|
|||
*/
|
||||
void P_CheckPointLimit(void)
|
||||
{
|
||||
INT32 i;
|
||||
if (!server)
|
||||
return;
|
||||
|
||||
if (!cv_pointlimit.value)
|
||||
return;
|
||||
|
@ -2314,27 +2327,28 @@ void P_CheckPointLimit(void)
|
|||
if (!(gametyperules & GTR_POINTLIMIT))
|
||||
return;
|
||||
|
||||
// pointlimit is nonzero, check if it's been reached by this player
|
||||
if (G_GametypeHasTeams())
|
||||
{
|
||||
// Just check both teams
|
||||
if ((UINT32)cv_pointlimit.value <= teamscores[TEAM_RED] || (UINT32)cv_pointlimit.value <= teamscores[TEAM_BLUE])
|
||||
for (UINT8 i = 1; i < teamsingame; i++)
|
||||
{
|
||||
if (server)
|
||||
if (teamscores[G_GetTeam(i)] >= (UINT32)cv_pointlimit.value)
|
||||
{
|
||||
SendNetXCmd(XD_EXITLEVEL, NULL, 0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
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)
|
||||
continue;
|
||||
|
||||
if ((UINT32)cv_pointlimit.value <= players[i].score)
|
||||
{
|
||||
if (server)
|
||||
SendNetXCmd(XD_EXITLEVEL, NULL, 0);
|
||||
SendNetXCmd(XD_EXITLEVEL, NULL, 0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4340,12 +4340,7 @@ static void P_NetArchiveMisc(boolean resending)
|
|||
|
||||
WRITEUINT8(save_p, teamsingame);
|
||||
for (i = 0; i < MAXTEAMS; 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);
|
||||
|
||||
|
@ -4440,12 +4435,7 @@ static inline boolean P_NetUnArchiveMisc(boolean reloading)
|
|||
|
||||
teamsingame = READUINT8(save_p);
|
||||
for (i = 0; i < MAXTEAMS; i++)
|
||||
{
|
||||
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);
|
||||
|
||||
|
|
Loading…
Reference in a new issue