diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 4d6679559814ff07b792b049183cb08fa26c5620..b16781504169a1efbc78f874d35296586b866c72 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -2360,7 +2360,12 @@ static void Command_Teamchange_f(void) if (COM_Argc() <= 1) { if (G_GametypeHasTeams()) - CONS_Printf(M_GetText("changeteam <team>: switch to a new team (%s)\n"), "team name or spectator"); + { + if (G_GametypeHasSpectators()) + CONS_Printf(M_GetText("changeteam <team>: switch to a new team (%s)\n"), "team name or spectator"); + else + CONS_Printf(M_GetText("changeteam <team>: switch to a new team (%s)\n"), "team name"); + } else if (G_GametypeHasSpectators()) CONS_Printf(M_GetText("changeteam <team>: switch to a new team (%s)\n"), "spectator or playing"); else @@ -2370,7 +2375,7 @@ static void Command_Teamchange_f(void) if (G_GametypeHasTeams()) { - if (!strcasecmp(COM_Argv(1), "spectator") || !strcasecmp(COM_Argv(1), "0")) + if (G_GametypeHasSpectators() && (!strcasecmp(COM_Argv(1), "spectator") || !strcasecmp(COM_Argv(1), "0"))) NetPacket.packet.newteam = 0; else { @@ -2378,7 +2383,7 @@ static void Command_Teamchange_f(void) if (M_StringOnlyHasDigits(COM_Argv(1))) { newteam = atoi(COM_Argv(1)); - if (newteam >= teamsingame) + if (newteam == TEAM_NONE || newteam >= teamsingame) newteam = MAXTEAMS; } else @@ -2407,7 +2412,12 @@ static void Command_Teamchange_f(void) if (error) { if (G_GametypeHasTeams()) - CONS_Printf(M_GetText("changeteam <team>: switch to a new team (%s)\n"), "team name or spectator"); + { + if (G_GametypeHasSpectators()) + CONS_Printf(M_GetText("changeteam <team>: switch to a new team (%s)\n"), "team name or spectator"); + else + CONS_Printf(M_GetText("changeteam <team>: switch to a new team (%s)\n"), "team name"); + } else if (G_GametypeHasSpectators()) CONS_Printf(M_GetText("changeteam <team>: switch to a new team (%s)\n"), "spectator or playing"); return; @@ -2466,9 +2476,14 @@ static void Command_Teamchange2_f(void) if (COM_Argc() <= 1) { if (G_GametypeHasTeams()) - CONS_Printf(M_GetText("changeteam <team>: switch to a new team (%s)\n"), "team name or spectator"); + { + if (G_GametypeHasSpectators()) + CONS_Printf(M_GetText("changeteam2 <team>: switch to a new team (%s)\n"), "team name or spectator"); + else + CONS_Printf(M_GetText("changeteam2 <team>: switch to a new team (%s)\n"), "team name"); + } else if (G_GametypeHasSpectators()) - CONS_Printf(M_GetText("changeteam <team>: switch to a new team (%s)\n"), "spectator or playing"); + CONS_Printf(M_GetText("changeteam2 <team>: switch to a new team (%s)\n"), "spectator or playing"); else CONS_Alert(CONS_NOTICE, M_GetText("This command cannot be used in this gametype.\n")); return; @@ -2476,7 +2491,7 @@ static void Command_Teamchange2_f(void) if (G_GametypeHasTeams()) { - if (!strcasecmp(COM_Argv(1), "spectator") || !strcasecmp(COM_Argv(1), "0")) + if (G_GametypeHasSpectators() && (!strcasecmp(COM_Argv(1), "spectator") || !strcasecmp(COM_Argv(1), "0"))) NetPacket.packet.newteam = 0; else { @@ -2484,7 +2499,7 @@ static void Command_Teamchange2_f(void) if (M_StringOnlyHasDigits(COM_Argv(1))) { newteam = atoi(COM_Argv(1)); - if (newteam >= teamsingame) + if (newteam == TEAM_NONE || newteam >= teamsingame) newteam = MAXTEAMS; } else @@ -2514,7 +2529,12 @@ static void Command_Teamchange2_f(void) if (error) { if (G_GametypeHasTeams()) - CONS_Printf(M_GetText("changeteam2 <team>: switch to a new team (%s)\n"), "team name or spectator"); + { + if (G_GametypeHasSpectators()) + CONS_Printf(M_GetText("changeteam2 <team>: switch to a new team (%s)\n"), "team name or spectator"); + else + CONS_Printf(M_GetText("changeteam2 <team>: switch to a new team (%s)\n"), "team name"); + } else if (G_GametypeHasSpectators()) CONS_Printf(M_GetText("changeteam2 <team>: switch to a new team (%s)\n"), "spectator or playing"); return; @@ -2581,7 +2601,12 @@ static void Command_ServerTeamChange_f(void) if (G_TagGametype()) CONS_Printf(M_GetText("serverchangeteam <playernum> <team>: switch player to a new team (%s)\n"), "it, notit, playing, or spectator"); else if (G_GametypeHasTeams()) - CONS_Printf(M_GetText("serverchangeteam <playernum> <team>: switch player to a new team (%s)\n"), "team name or spectator"); + { + if (G_GametypeHasSpectators()) + CONS_Printf(M_GetText("serverchangeteam <playernum> <team>: switch player to a new team (%s)\n"), "team name or spectator"); + else + CONS_Printf(M_GetText("serverchangeteam <playernum> <team>: switch player to a new team (%s)\n"), "team name"); + } else if (G_GametypeHasSpectators()) CONS_Printf(M_GetText("serverchangeteam <playernum> <team>: switch player to a new team (%s)\n"), "spectator or playing"); else @@ -2604,7 +2629,7 @@ static void Command_ServerTeamChange_f(void) } else if (G_GametypeHasTeams()) { - if (!strcasecmp(COM_Argv(1), "spectator") || !strcasecmp(COM_Argv(1), "0")) + if (G_GametypeHasSpectators() && (!strcasecmp(COM_Argv(1), "spectator") || !strcasecmp(COM_Argv(1), "0"))) NetPacket.packet.newteam = 0; else { @@ -2612,7 +2637,7 @@ static void Command_ServerTeamChange_f(void) if (M_StringOnlyHasDigits(COM_Argv(1))) { newteam = atoi(COM_Argv(1)); - if (newteam >= teamsingame) + if (newteam == TEAM_NONE || newteam >= teamsingame) newteam = MAXTEAMS; } else @@ -2643,7 +2668,12 @@ static void Command_ServerTeamChange_f(void) if (G_TagGametype()) CONS_Printf(M_GetText("serverchangeteam <playernum> <team>: switch player to a new team (%s)\n"), "it, notit, playing, or spectator"); else if (G_GametypeHasTeams()) - CONS_Printf(M_GetText("serverchangeteam <playernum> <team>: switch player to a new team (%s)\n"), "team name or spectator"); + { + if (G_GametypeHasSpectators()) + CONS_Printf(M_GetText("serverchangeteam <playernum> <team>: switch player to a new team (%s)\n"), "team name or spectator"); + else + CONS_Printf(M_GetText("serverchangeteam <playernum> <team>: switch player to a new team (%s)\n"), "team name"); + } else if (G_GametypeHasSpectators()) CONS_Printf(M_GetText("serverchangeteam <playernum> <team>: switch player to a new team (%s)\n"), "spectator or playing"); return; diff --git a/src/deh_lua.c b/src/deh_lua.c index f43eacb43d2da2ccec77ca2311928ed19e66083d..ea94c32a9d604336d72edb1389b52dc742e3ec3e 100644 --- a/src/deh_lua.c +++ b/src/deh_lua.c @@ -133,19 +133,16 @@ static inline int lib_freeslot(lua_State *L) } 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) + if (numteams == MAXTEAMS) CONS_Alert(CONS_WARNING, "Ran out of free team slots!\n"); + UINT8 i = numteams; + 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; } else if (fastcmp(type, "SPR2")) { @@ -578,10 +575,8 @@ static int ScanConstants(lua_State *L, boolean mathlib, const char *word) } else if (fastncmp("TEAM_",word,5)) { p = word+5; - for (i = 0; i < MAXTEAMS; i++) + for (i = 0; i < numteams; i++) { - if (!teamnames[i]) - break; if (fastcmp(p, teamnames[i])) { CacheAndPushConstant(L, word, i); return 1; diff --git a/src/deh_soc.c b/src/deh_soc.c index dee24b37cee9636b4ed328c93aa341d82b5d347b..61d3d558a870b8211cd0107da8b283183ebdaa3f 100644 --- a/src/deh_soc.c +++ b/src/deh_soc.c @@ -475,13 +475,12 @@ void readfreeslots(MYFILE *f) } 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; - } + if (numteams < MAXTEAMS) + { + teamnames[numteams] = Z_Malloc(strlen(word)+1, PU_STATIC, NULL); + strcpy(teamnames[numteams],word); + numteams++; + } } else if (fastcmp(type, "SPR2")) { @@ -1139,8 +1138,7 @@ void readsprite2(MYFILE *f, INT32 num) Z_Free(s); } -// copypasted from readPlayer :] -void readgametype(MYFILE *f, char *gtname) +void readgametype(MYFILE *f, INT32 num) { char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL); char *word; @@ -1148,25 +1146,20 @@ void readgametype(MYFILE *f, char *gtname) char *tmp; INT32 i, j; - INT16 newgtidx = 0; - UINT32 newgtrules = 0; - UINT32 newgttol = 0; - INT32 newgtpointlimit = 0; - INT32 newgttimelimit = 0; - UINT8 newgtleftcolor = 0; - UINT8 newgtrightcolor = 0; - INT16 newgtrankingstype = -1; - int newgtinttype = 0; + char *gtname = gametypes[num].name; + char gtconst[32]; char gtdescription[441]; - char gtconst[MAXLINELEN]; - UINT8 teamcount = 0; - UINT8 teamlist[MAXTEAMS]; - // Empty strings. - gtdescription[0] = '\0'; - gtconst[0] = '\0'; + UINT8 newgtleftcolor, newgtrightcolor; + boolean has_desc_colors[2] = { false, false }; - strcpy(gtdescription, "???"); + UINT8 teamcount = gametypes[num].teams.num; + UINT8 teamlist[MAXTEAMS]; + boolean has_teams = false; + + memset(gtconst, 0, sizeof(gtconst)); + memset(gtdescription, 0, sizeof(gtconst)); + memcpy(teamlist, gametypes[num].teams.list, sizeof(teamlist[0]) * teamcount); do { @@ -1225,8 +1218,8 @@ void readgametype(MYFILE *f, char *gtname) if (word2) { if (!word2lwr) - word2lwr = Z_Malloc(MAXLINELEN, PU_STATIC, NULL); - strcpy(word2lwr, word2); + word2lwr = Z_Calloc(MAXLINELEN, PU_STATIC, NULL); + strlcpy(word2lwr, word2, MAXLINELEN); strupr(word2); } else @@ -1234,13 +1227,21 @@ void readgametype(MYFILE *f, char *gtname) if (word2[strlen(word2)-1] == '\n') word2[strlen(word2)-1] = '\0'; + if (word2lwr[strlen(word2lwr)-1] == '\n') + word2lwr[strlen(word2lwr)-1] = '\0'; i = atoi(word2); + // Name + if (fastcmp(word, "NAME")) + { + Z_Free(gametypes[num].name); + gametypes[num].name = Z_StrDup(word2lwr); + } // Game type rules - if (fastcmp(word, "RULES")) + else if (fastcmp(word, "RULES")) { // GTR_ - newgtrules = (UINT32)get_number(word2); + gametypes[num].rules = (UINT32)get_number(word2); } // Identifier else if (fastcmp(word, "IDENTIFIER")) @@ -1250,33 +1251,60 @@ void readgametype(MYFILE *f, char *gtname) } // Point and time limits else if (fastcmp(word, "DEFAULTPOINTLIMIT")) - newgtpointlimit = (INT32)i; + gametypes[num].pointlimit = (INT32)i; else if (fastcmp(word, "DEFAULTTIMELIMIT")) - newgttimelimit = (INT32)i; + gametypes[num].timelimit = (INT32)i; // Level platter else if (fastcmp(word, "HEADERCOLOR") || fastcmp(word, "HEADERCOLOUR")) - newgtleftcolor = newgtrightcolor = (UINT8)get_number(word2); + { + INT32 color = (INT32)i; + if (color >= 0 && color <= 255) + { + newgtleftcolor = newgtrightcolor = (UINT8)color; + has_desc_colors[0] = has_desc_colors[1] = true; + } + else + deh_warning("readgametype %d: Level platter header color %d out of range (0 - 255)", num, i); + } else if (fastcmp(word, "HEADERLEFTCOLOR") || fastcmp(word, "HEADERLEFTCOLOUR")) - newgtleftcolor = (UINT8)get_number(word2); + { + INT32 color = (INT32)i; + if (color >= 0 && color <= 255) + { + newgtleftcolor = (UINT8)color; + has_desc_colors[0] = true; + } + else + deh_warning("readgametype %d: Level platter header left color %d out of range (0 - 255)", num, i); + } else if (fastcmp(word, "HEADERRIGHTCOLOR") || fastcmp(word, "HEADERRIGHTCOLOUR")) - newgtrightcolor = (UINT8)get_number(word2); + { + INT32 color = (INT32)i; + if (color >= 0 && color < 255) + { + newgtrightcolor = (UINT8)color; + has_desc_colors[1] = true; + } + else + deh_warning("readgametype %d: Level platter header right color %d out of range (0 - 255)", num, i); + } // Rankings type else if (fastcmp(word, "RANKINGTYPE")) { // Case insensitive - newgtrankingstype = (int)get_number(word2); + gametypes[num].rankings_type = (int)get_number(word2); } // Intermission type else if (fastcmp(word, "INTERMISSIONTYPE")) { // Case sensitive - newgtinttype = (int)get_number(word2lwr); + gametypes[num].intermission_type = (int)get_number(word2lwr); } // Type of level else if (fastcmp(word, "TYPEOFLEVEL")) { if (i) // it's just a number - newgttol = (UINT32)i; + gametypes[num].typeoflevel = (UINT32)i; else { UINT32 tol = 0; @@ -1286,10 +1314,10 @@ void readgametype(MYFILE *f, char *gtname) if (fasticmp(tmp, TYPEOFLEVEL[i].name)) break; if (!TYPEOFLEVEL[i].name) - deh_warning("readgametype %s: unknown typeoflevel flag %s\n", gtname, tmp); + deh_warning("readgametype %d: unknown typeoflevel flag %s\n", num, tmp); tol |= TYPEOFLEVEL[i].flag; } while((tmp = strtok(NULL,",")) != NULL); - newgttol = tol; + gametypes[num].typeoflevel = tol; } } // Teams @@ -1299,26 +1327,20 @@ void readgametype(MYFILE *f, char *gtname) do { if (teamcount == MAXTEAMS) { - deh_warning("readgametype %s: too many teams\n", gtname); + deh_warning("readgametype %d: too many teams\n", num); 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 + char *tmp2 = Z_StrDup(tmp); + strupr(tmp2); + UINT8 team_id = get_team(tmp2); + if (team_id != TEAM_NONE) { teamlist[teamcount++] = team_id; + has_teams = true; } + else + deh_warning("readgametype %d: unknown team %s\n", num, tmp); + Z_Free(tmp2); } while((tmp = strtok(NULL,",")) != NULL); } // This SOC probably provided gametype rules as words, instead of using the RULES keyword. @@ -1329,12 +1351,14 @@ void readgametype(MYFILE *f, char *gtname) for (j = 0; GAMETYPERULE_LIST[j]; j++) if (fastcmp(word, GAMETYPERULE_LIST[j])) { wordgt |= (1<<j); - if (i || word2[0] == 'T' || word2[0] == 'Y') - newgtrules |= wordgt; + if (word2[0] == 'T' || word2[0] == 'Y') + gametypes[num].rules |= wordgt; + else if (word2[0] == 'F' || word2[0] == 'N') + gametypes[num].rules &= ~wordgt; break; } if (!wordgt) - deh_warning("readgametype %s: unknown word '%s'", gtname, word); + deh_warning("readgametype %d: unknown word '%s'", num, word); } } } while (!myfeof(f)); // finish when the line is empty @@ -1344,43 +1368,161 @@ void readgametype(MYFILE *f, char *gtname) if (word2lwr) Z_Free(word2lwr); - // Ran out of gametype slots - if (gametypecount == NUMGAMETYPEFREESLOTS) + if (gtdescription[0]) + G_SetGametypeDescription(num, gtdescription); + if (has_desc_colors[0]) + G_SetGametypeDescriptionLeftColor(num, newgtleftcolor); + if (has_desc_colors[1]) + G_SetGametypeDescriptionRightColor(num, newgtrightcolor); + + // Copy the teams + if (has_teams) { - CONS_Alert(CONS_WARNING, "Ran out of free gametype slots!\n"); - return; + gametypes[num].teams.num = teamcount; + if (teamcount) + memcpy(gametypes[num].teams.list, teamlist, sizeof(teamlist[0]) * teamcount); } - // Add the new gametype - newgtidx = G_AddGametype(newgtrules); - G_AddGametypeTOL(newgtidx, newgttol); - G_SetGametypeDescription(newgtidx, gtdescription, newgtleftcolor, newgtrightcolor); + // Write the constant name. + if (gametypes[num].constant_name == NULL) + { + if (gtconst[0] == '\0') + G_AddGametypeConstant(num, gtname); + else + G_AddGametypeConstant(num, gtconst); + } + else if (gtconst[0] != '\0') + G_AddGametypeConstant(num, gtconst); - // Not covered by G_AddGametype alone. - if (newgtrankingstype == -1) - newgtrankingstype = newgtidx; - gametypes[newgtidx].rankings_type = newgtrankingstype; - gametypes[newgtidx].intermission_type = newgtinttype; - gametypes[newgtidx].pointlimit = newgtpointlimit; - gametypes[newgtidx].timelimit = newgttimelimit; + // Update gametype_cons_t accordingly. + G_UpdateGametypeSelections(); +} - // Copy the teams - gametypes[newgtidx].teams.num = teamcount; - if (teamcount) - memcpy(gametypes[newgtidx].teams.list, teamlist, sizeof(teamlist[0]) * teamcount); +void readteam(MYFILE *f, INT32 num) +{ + char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL); + char *word; + char *word2, *word2lwr = NULL; + INT32 i; - // Write the new gametype name. - gametypes[newgtidx].name = Z_StrDup(gtname); + team_t *team = &teams[num]; - // Write the constant name. - if (gtconst[0] == '\0') - strncpy(gtconst, gtname, MAXLINELEN); - G_AddGametypeConstant(newgtidx, gtconst); + do + { + if (myfgets(s, MAXLINELEN, f)) + { + if (s[0] == '\n') + break; - // Update gametype_cons_t accordingly. - G_UpdateGametypeSelections(); + word = strtok(s, " "); + if (word) + strupr(word); + else + break; + + word2 = strtok(NULL, " = "); + if (word2) + { + if (!word2lwr) + word2lwr = Z_Malloc(MAXLINELEN, PU_STATIC, NULL); + strcpy(word2lwr, word2); + strupr(word2); + } + else + break; + + if (word2[strlen(word2)-1] == '\n') + word2[strlen(word2)-1] = '\0'; + i = atoi(word2); - CONS_Printf("Added gametype %s\n", gametypes[newgtidx].name); + if (fastcmp(word, "NAME")) + { + Z_Free(team->name); + team->name = Z_StrDup(word2lwr); + } + else if (fastcmp(word, "FLAGNAME")) + { + Z_Free(team->flag_name); + team->flag_name = Z_StrDup(word2lwr); + } + else if (fastcmp(word, "FLAG")) + { + team->flag = (UINT16)get_number(word2); + } + else if (fastcmp(word, "FLAGTYPE")) + { + if (i == 0 && word2[0] != '0') // If word2 isn't a number + i = get_mobjtype(word2); // find a thing by name + if (i < NUMMOBJTYPES && i > 0) + team->flag_mobj_type = i; + else + { + deh_warning("readteam %d: Thing %d out of range (1 - %d)", num, i, NUMMOBJTYPES-1); + } + } + else if (fastcmp(word, "COLOR")) + { + if (i == 0 && word2[0] != '0') // If word2 isn't a number + i = get_skincolor(word2); // find a skincolor by name + if (i && i < numskincolors) + team->color = i; + else + { + deh_warning("readteam %d: Color %d out of range (1 - %d)", num, i, numskincolors-1); + } + } + else if (fastcmp(word, "WEAPONCOLOR")) + { + if (i == 0 && word2[0] != '0') // If word2 isn't a number + i = get_skincolor(word2); // find a skincolor by name + if (i && i < numskincolors) + team->weapon_color = i; + else + { + deh_warning("readteam %d: Weapon color %d out of range (1 - %d)", num, i, numskincolors-1); + } + } + else if (fastcmp(word, "MISSILECOLOR")) + { + if (i == 0 && word2[0] != '0') // If word2 isn't a number + i = get_skincolor(word2); // find a skincolor by name + if (i && i < numskincolors) + team->missile_color = i; + else + { + deh_warning("readteam %d: Missile color %d out of range (1 - %d)", num, i, numskincolors-1); + } + } + else if (fastcmp(word, "ICON")) + { + G_SetTeamIcon(num, TEAM_ICON, word2lwr); + } + else if (fastcmp(word, "FLAGICON")) + { + G_SetTeamIcon(num, TEAM_ICON_FLAG, word2lwr); + } + else if (fastcmp(word, "GOTFLAGICON")) + { + G_SetTeamIcon(num, TEAM_ICON_GOT_FLAG, word2lwr); + } + else if (fastcmp(word, "MISSINGFLAGICON")) + { + G_SetTeamIcon(num, TEAM_ICON_MISSING_FLAG, word2lwr); + } + else + { + deh_warning("readteam %d: unknown word '%s'", num, word); + } + } + } while (!myfeof(f)); // finish when the line is empty + + // Free strings. + Z_Free(s); + if (word2lwr) + Z_Free(word2lwr); + + ST_LoadTeamIcons(); + G_UpdateTeamSelection(); } void readlevelheader(MYFILE *f, INT32 num) @@ -4195,6 +4337,38 @@ skincolornum_t get_skincolor(const char *word) return SKINCOLOR_GREEN; } +INT16 get_gametype(const char *word) +{ + INT16 i; + if (*word >= '0' && *word <= '9') + return atoi(word); + if (fastncmp("GT_",word,3)) + word += 3; // take off the GT_ + for (i = 0; i < gametypecount; i++) + { + if (fastcmp(word, gametypes[i].constant_name + 3)) + return i; + } + deh_warning("Couldn't find gametype named 'GT_%s'",word); + return GT_COOP; +} + +UINT8 get_team(const char *word) +{ + UINT8 i; + if (*word >= '0' && *word <= '9') + return atoi(word); + if (fastncmp("TEAM_",word,5)) + word += 5; // take off the TEAM_ + for (i = 0; i < numteams; i++) + { + if (fastcmp(word, teamnames[i])) + return i; + } + deh_warning("Couldn't find team named 'TEAM_%s'",word); + return TEAM_NONE; +} + spritenum_t get_sprite(const char *word) { // Returns the value of SPR_ enumerations spritenum_t i; diff --git a/src/deh_soc.h b/src/deh_soc.h index 0cab545f680d6ec86d6e4707b53c2a16291439ba..1ac2199af1b2d3fa3610a5e22e02c16a73ea05e4 100644 --- a/src/deh_soc.h +++ b/src/deh_soc.h @@ -54,9 +54,9 @@ playersprite_t get_sprite2(const char *word); sfxenum_t get_sfx(const char *word); hudnum_t get_huditem(const char *word); menutype_t get_menutype(const char *word); -//INT16 get_gametype(const char *word); -//powertype_t get_power(const char *word); skincolornum_t get_skincolor(const char *word); +INT16 get_gametype(const char *word); +UINT8 get_team(const char *word); void readwipes(MYFILE *f); void readmaincfg(MYFILE *f); @@ -71,7 +71,8 @@ void readmenu(MYFILE *f, INT32 num); void readtextprompt(MYFILE *f, INT32 num); void readcutscene(MYFILE *f, INT32 num); void readlevelheader(MYFILE *f, INT32 num); -void readgametype(MYFILE *f, char *gtname); +void readgametype(MYFILE *f, INT32 num); +void readteam(MYFILE *f, INT32 num); void readsprite2(MYFILE *f, INT32 num); void readspriteinfo(MYFILE *f, INT32 num, boolean sprite2); #ifdef HWRENDER diff --git a/src/dehacked.c b/src/dehacked.c index fd2a701715e17ce7dab0b6c829147113844972fe..2c00ff133067899d86599f3edffcdbb152824d95 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -172,9 +172,9 @@ static void ignorelines(MYFILE *f) static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile) { char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL); - char textline[MAXLINELEN]; char *word; char *word2; + char word2lwr[MAXLINELEN]; INT32 i; if (!deh_loaded) @@ -189,7 +189,6 @@ static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile) while (!myfeof(f)) { myfgets(s, MAXLINELEN, f); - memcpy(textline, s, MAXLINELEN); if (s[0] == '\n' || s[0] == '#') continue; @@ -216,10 +215,14 @@ static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile) continue; } word2 = strtok(NULL, " "); + word2lwr[0] = '\0'; if (word2) { + strcpy(word2lwr, word2); strupr(word2); if (word2[strlen(word2) - 1] == '\n') word2[strlen(word2) - 1] = '\0'; + if (word2lwr[strlen(word2lwr) - 1] == '\n') + word2lwr[strlen(word2lwr) - 1] = '\0'; i = atoi(word2); } else @@ -381,32 +384,60 @@ static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile) } else if (fastcmp(word, "GAMETYPE")) { - // Get the gametype name from textline - // instead of word2, so that gametype names - // aren't allcaps - INT32 c; - for (c = 0; c < MAXLINELEN; c++) + char *gtname = NULL; + if (word2lwr[0]) { - if (textline[c] == '\0') - break; - if (textline[c] == ' ') + gtname = word2lwr; + + for (size_t j = 0; j < strlen(gtname); j++) + { + if (gtname[j] == '\0') + break; + if (gtname[j] < 32 || gtname[j] == '\n') + { + gtname[j] = '\0'; + break; + } + } + } + + if (!gtname || !strlen(gtname)) + { + deh_warning("Invalid gametype name"); + ignorelines(f); + } + else + { + INT32 gametype_id = G_GetGametypeByName(gtname); + if (gametype_id == -1) { - char *gtname = (textline+c+1); - if (gtname) + if (!strncmp(gtname, "GT_", 3)) + gametype_id = get_gametype(gtname + 3); + else if (gametypecount != NUMGAMETYPEFREESLOTS) { - // remove funny characters - INT32 j; - for (j = 0; j < (MAXLINELEN - c); j++) - { - if (gtname[j] == '\0') - break; - if (gtname[j] < 32) - gtname[j] = '\0'; - } - readgametype(f, gtname); + gametype_id = G_AddGametype(); + CONS_Printf("Added gametype %s\n", gtname); } - break; + else + deh_warning("Ran out of free gametype slots"); } + + if (gametype_id != -1) + readgametype(f, gametype_id); + else + ignorelines(f); + } + } + else if (fastcmp(word, "TEAM")) + { + if (i == 0 && word2[0] != '0') // If word2 isn't a number + i = get_team(word2); // find a team by name + if (i >= 0 && i < MAXTEAMS) + readteam(f, i); + else + { + deh_warning("Team %d out of range (0 - %d)", i, MAXTEAMS); + ignorelines(f); } } else if (fastcmp(word, "CUTSCENE")) diff --git a/src/g_game.c b/src/g_game.c index 584d84972ceb60b986013250fba1ab6c2a30ddef..429dfbc061652b9b0deee8a7d39459e5cbaf4807 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -3597,11 +3597,23 @@ void G_UpdateTeamSelection(void) i++; } + // If no selections were added, somehow, we add at least two fallbacks. + if (i == 0) + { + dummyteam_cons_t[i].value = 0; + dummyteam_cons_t[i].strvalue = "Spectator"; + i++; + + dummyteam_cons_t[i].value = 1; + dummyteam_cons_t[i].strvalue = "Playing"; + i++; + } + dummyteam_cons_t[i].value = 0; dummyteam_cons_t[i].strvalue = NULL; cv_dummyteam.defaultvalue = dummyteam_cons_t[0].strvalue; - cv_dummyteam.value = 0; + cv_dummyteam.value = dummyteam_cons_t[0].value; cv_dummyteam.string = cv_dummyteam.defaultvalue; } @@ -3624,15 +3636,17 @@ void G_SetGametype(INT16 gtype) // // Adds a gametype. Returns the new gametype number. // -INT16 G_AddGametype(UINT32 rules) +INT16 G_AddGametype(void) { INT16 newgtype = gametypecount; gametypecount++; gametypes[newgtype].name = Z_StrDup("???"); - gametypes[newgtype].rules = rules; + gametypes[newgtype].rules = 0; - G_UpdateGametypeSelections(); + G_SetGametypeDescription(newgtype, "???"); + G_SetGametypeDescriptionLeftColor(newgtype, 54); + G_SetGametypeDescriptionRightColor(newgtype, 54); return newgtype; } @@ -3670,20 +3684,32 @@ void G_UpdateGametypeSelections(void) } gametype_cons_t[NUMGAMETYPES].value = 0; gametype_cons_t[NUMGAMETYPES].strvalue = NULL; + + cv_newgametype.defaultvalue = gametype_cons_t[0].strvalue; + + if (cv_newgametype.string && G_GetGametypeByName(cv_newgametype.string) == -1) + { + cv_newgametype.value = 0; + cv_newgametype.string = gametype_cons_t[0].strvalue; + } } -// -// G_SetGametypeDescription -// -// Set a description for the specified gametype. -// (Level platter) -// -void G_SetGametypeDescription(INT16 gtype, char *descriptiontext, UINT8 leftcolor, UINT8 rightcolor) +void G_SetGametypeDescription(INT16 gtype, const char *descriptiontext) +{ + if (descriptiontext) + strlcpy(gametypedesc[gtype].notes, descriptiontext, sizeof gametypedesc[gtype].notes); + else + memset(gametypedesc[gtype].notes, 0, sizeof gametypedesc[gtype].notes); +} + +void G_SetGametypeDescriptionLeftColor(INT16 gtype, UINT8 color) +{ + gametypedesc[gtype].col[0] = color; +} + +void G_SetGametypeDescriptionRightColor(INT16 gtype, UINT8 color) { - if (descriptiontext != NULL) - strncpy(gametypedesc[gtype].notes, descriptiontext, 441); - gametypedesc[gtype].col[0] = leftcolor; - gametypedesc[gtype].col[1] = rightcolor; + gametypedesc[gtype].col[1] = color; } tolinfo_t TYPEOFLEVEL[NUMTOLNAMES] = { @@ -3732,16 +3758,6 @@ void G_AddTOL(UINT32 newtol, const char *tolname) TYPEOFLEVEL[i].flag = newtol; } -// -// G_AddGametypeTOL -// -// Assigns a type of level to a gametype. -// -void G_AddGametypeTOL(INT16 gtype, UINT32 newtol) -{ - gametypes[gtype].typeoflevel = newtol; -} - // // G_GetGametypeByName // diff --git a/src/g_game.h b/src/g_game.h index 9bde7a9ee7bd52399e83c0ebc65a580f480b7c2f..035b4541e310e6d9ae11b49bef0f29aa1c0293e2 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -193,12 +193,14 @@ void G_SaveGameOver(UINT32 slot, boolean modifylives); void G_SetGametype(INT16 gametype); void G_InitGametypes(void); void G_UpdateTeamSelection(void); -INT16 G_AddGametype(UINT32 rules); +INT16 G_AddGametype(void); void G_AddGametypeConstant(INT16 gtype, const char *newgtconst); void G_UpdateGametypeSelections(void); void G_AddTOL(UINT32 newtol, const char *tolname); -void G_AddGametypeTOL(INT16 gtype, UINT32 newtol); -void G_SetGametypeDescription(INT16 gtype, char *descriptiontext, UINT8 leftcolor, UINT8 rightcolor); + +void G_SetGametypeDescription(INT16 gtype, const char *descriptiontext); +void G_SetGametypeDescriptionLeftColor(INT16 gtype, UINT8 color); +void G_SetGametypeDescriptionRightColor(INT16 gtype, UINT8 color); INT32 G_GetGametypeByName(const char *gametypestr); boolean G_IsSpecialStage(INT32 mapnum); diff --git a/src/lua_baselib.c b/src/lua_baselib.c index c8e342975f5b5f3c6c0b846eb8905e2d0ff925bc..dbd7c8e4ffda4d654228dbd5138727fe692ac74b 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -3411,15 +3411,14 @@ static int lib_gAddGametype(lua_State *L) char *gtname = NULL; char *gtconst = NULL; - const char *gtdescription = NULL; - INT16 newgtidx = 0; + char *gtdescription = NULL; UINT32 newgtrules = 0; UINT32 newgttol = 0; INT32 newgtpointlimit = 0; INT32 newgttimelimit = 0; - UINT8 newgtleftcolor = 0; - UINT8 newgtrightcolor = 0; - INT16 newgtrankingstype = -1; + UINT8 newgtleftcolor = 54; + UINT8 newgtrightcolor = 54; + INT16 newgtrankingstype = RANKINGS_DEFAULT; int newgtinttype = 0; UINT8 teamcount = 0; UINT8 teamlist[MAXTEAMS]; @@ -3540,40 +3539,52 @@ static int lib_gAddGametype(lua_State *L) // Set defaults if (gtname == NULL) gtname = Z_StrDup("Unnamed gametype"); - if (gtdescription == NULL) - gtdescription = Z_StrDup("???"); + + if (G_GetGametypeByName(gtname) != -1) + { + luaL_error(L, "gametype %s already exists", gtname); + Z_Free(gtname); + Z_Free(gtconst); + Z_Free(gtdescription); + return 0; + } // Add the new gametype - newgtidx = G_AddGametype(newgtrules); - G_AddGametypeTOL(newgtidx, newgttol); - G_SetGametypeDescription(newgtidx, gtdescription, newgtleftcolor, newgtrightcolor); - - // Not covered by G_AddGametype alone. - if (newgtrankingstype == -1) - newgtrankingstype = newgtidx; - gametypes[newgtidx].rankings_type = newgtrankingstype; - gametypes[newgtidx].intermission_type = newgtinttype; - gametypes[newgtidx].pointlimit = newgtpointlimit; - gametypes[newgtidx].timelimit = newgttimelimit; + INT16 gtype = G_AddGametype(); + + gametype_t *gt = &gametypes[gtype]; + + gt->name = gtname; + + if (gtconst) + G_AddGametypeConstant(gtype, gtconst); + else + G_AddGametypeConstant(gtype, gtname); + + if (gtdescription) + G_SetGametypeDescription(gtype, gtdescription); + G_SetGametypeDescriptionLeftColor(gtype, newgtleftcolor); + G_SetGametypeDescriptionRightColor(gtype, newgtrightcolor); + + gt->rules = newgtrules; + gt->typeoflevel = newgttol; + gt->rankings_type = newgtrankingstype; + gt->intermission_type = newgtinttype; + gt->pointlimit = newgtpointlimit; + gt->timelimit = newgttimelimit; // Copy the teams - gametypes[newgtidx].teams.num = teamcount; + gt->teams.num = teamcount; if (teamcount) - memcpy(gametypes[newgtidx].teams.list, teamlist, sizeof(teamlist[0]) * teamcount); + memcpy(gt->teams.list, teamlist, sizeof(teamlist[0]) * teamcount); - // Write the new gametype name. - gametypes[newgtidx].name = gtname; + G_UpdateGametypeSelections(); - // Write the constant name. - if (gtconst == NULL) - gtconst = gtname; - G_AddGametypeConstant(newgtidx, gtconst); + CONS_Printf("Added gametype %s\n", gt->name); - // Update gametype_cons_t accordingly. - G_UpdateGametypeSelections(); + Z_Free(gtconst); + Z_Free(gtdescription); - // done - CONS_Printf("Added gametype %s\n", gametypes[newgtidx].name); return 0; } diff --git a/src/p_mobj.c b/src/p_mobj.c index b755f64825a931cac8ba56ef419598b2838e672e..5532bb34b89c470507e919ae26627517dad1f84b 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -11573,7 +11573,12 @@ void P_SpawnPlayer(INT32 playernum) { // Fix stupid non spectator spectators. if (!p->spectator && !p->ctfteam) - p->spectator = true; + { + if (G_GametypeHasSpectators()) + p->spectator = true; + else + p->ctfteam = 1; + } // Fix team colors. // This code isn't being done right somewhere else. Oh well.