Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision

Target

Select target project
  • STJr/SRB2
  • Sryder/SRB2
  • wolfy852/SRB2
  • Alpha2244/SRB2
  • Inuyasha/SRB2
  • yoshibot/SRB2
  • TehRealSalt/SRB2
  • PrisimaTF/SRB2
  • Hatninja/SRB2
  • SteelT/SRB2
  • james/SRB2
  • ShaderWraith/SRB2
  • SinnamonLat/SRB2
  • mazmazz_/SRB2
  • filpAM/SRB2
  • chaoloveicemdboy/SRB2
  • Whooa21/SRB2
  • Machturne/SRB2
  • Golden/SRB2
  • Tatsuru/SRB2
  • Snu/SRB2
  • Zwip-Zwap_Zapony/SRB2
  • fickleheart/SRB2
  • alphaRexJames/SRB2
  • JJK/SRB2
  • diskpoppy/SRB2
  • Hannu_Hanhi/SRB2
  • ZipperQR/SRB2
  • kays/SRB2
  • spherallic/SRB2
  • Zippy_Zolton/SRB2
  • namiishere/SRB2
  • Ors/SRB2
  • SMS_Alfredo/SRB2
  • sonic_edge/SRB2
  • lavla/SRB2
  • ashi/SRB2
  • X.organic/SRB2
  • Fafabis/SRB2
  • Meziu/SRB2
  • v-rob/SRB2
  • tertu/SRB2
  • bitten2up/SRB2
  • flarn2006/SRB2
  • Krabs/SRB2
  • clairebun/SRB2
  • Lactozilla/SRB2
  • thehackstack/SRB2
  • Spice/SRB2
  • win8linux/SRB2
  • JohnFrostFox/SRB2
  • talktoneon726/SRB2
  • Wane/SRB2
  • Lamibe/SRB2
  • spectrumuk2/srb-2
  • nerdyminer18/srb-2
  • 256nil/SRB2
  • ARJr/SRB2
  • Alam/SRB2
  • Zenya/srb-2-marathon-demos
  • Acelite/srb-2-archivedmodifications
  • MIDIMan/SRB2
  • Lach/SRB2
  • Frostiikin/bounce-tweaks
  • Jaden/SRB2
  • Tyron/SRB2
  • Astronight/SRB2
  • Mari0shi06/SRB2
  • aiire/SRB2
  • Galactice/SRB2
  • srb2-ports/srb2-dreamcast
  • sdasdas/SRB2
  • chreas/srb-2-vr
  • StarManiaKG/the-story-of-sinically-rocketing-and-botching-the-2nd
  • LoganAir/SRB2
  • NepDisk/srb-2
  • alufolie91/SRB2
  • Felicia.iso/SRB2
  • twi/SRB2
  • BarrelsOFun/SRB2
  • Speed2411/SRB2
  • Leather_Realms/SRB2
  • Ayemar/SRB2
  • Acelite/SRB2
  • VladDoc/SRB2
  • kaldrum/model-features
  • strawberryfox417/SRB2
  • Lugent/SRB2
  • Rem/SRB2
  • Refrag/SRB2
  • Henry_3230/srb-3230
  • TehPuertoRicanSpartan2/tprs-srb2
  • Leminn/srb-2-marathon-stuff
  • chromaticpipe2/SRB2
  • MiguelGustavo15/SRB2
  • Maru/srb-2-tests
  • SilicDev/SRB2
  • UnmatchedBracket/SRB2
  • HybridDog/SRB2
  • xordspar0/SRB2
  • jsjhbewfhh/SRB2
  • Fancy2209/SRB2
  • Lorsoen/SRB2
  • shindoukin/SRB2
  • GamerOfDays/SRB2
  • Craftyawesome/SRB2
  • tenshi-tensai-tennoji/SRB2
  • Scarfdudebalder/SRB2
  • luigi-budd/srb-2-fix-interplag-lockon
  • mskluesner/SRB2
  • johnpetersa19/SRB2
  • Pheazant/SRB2
  • chromaticpipe2/srb2classic
  • romoney5/SRB2
  • PAS/SRB2Classic
  • BlueStaggo/SRB2
  • Jisk/srb-2-beef-jerky
117 results
Select Git revision
  • 21-installer-nodd
  • 2210-pre1
  • 2210-pre2
  • 2210-rc1
  • 2210-rc2
  • 2210-rc3
  • 2211-pre1
  • 2211-pre2
  • 2211-rc1
  • 2212-pre1
  • 2212-pre2
  • 2212-pre3
  • 2212-rc1
  • 2213
  • 2214-pre1
  • 2214-pre2
  • 2214-pre3
  • 2214-pre4
  • 2_2_12
  • 64-gl-log
  • COM_ImmedExecute-lua
  • DJGPP
  • accel-momentum
  • acs
  • action-args
  • alpha-fixes
  • any-resolution
  • appveyor
  • blend-locking
  • blentran
  • blua-unary-not-fix
  • boost-tickrate
  • bustablesoundz
  • cleanup-opengl
  • cleanupmusic
  • clipmidtex
  • cmake-valgrind
  • crawlacommander-sprites
  • custom-map-names
  • custom-teams
  • cutscene-cleanup
  • dd-music-bypass
  • dd-music-fix
  • delfile2
  • deprecate-lua-dedicated-server
  • dpl-2
  • dropshadows-spawning
  • dynabsp
  • emblem-drawing
  • exchndl-xp-fix
  • extra-textures
  • few-kart-lua-changes
  • ffloorclip
  • fix-167
  • fix-cvar-conflicts
  • fix-opengl-parameter-crash
  • fix-opengl-shear-roll
  • flipfuncpointers
  • fof-lightlist-fixes
  • font-FUCK
  • frictionrefactor
  • fuck-macros-1
  • gamepad-luakeydown
  • gamepad-morefixes
  • gamepad_experiments
  • gametype-refactor
  • gametype-refactor-1
  • gametype-refactor-player-spawns
  • ghost-networking
  • gif-splitting
  • grr-lj
  • hitboxviewer
  • hwr-texture-cache-refactor
  • hwrender2
  • improve-439
  • increase-maxconditionsets
  • increase-packet-tics
  • input-display
  • input-display-translucency
  • io
  • joystick-juggling-maz
  • just-in-case
  • keycodes-only
  • ksf-wadfiles
  • ld413-mp-fix
  • levelstruct
  • libpng-version-support
  • linedef-actions
  • lj-test
  • lol-states
  • loopedsounds
  • lower-unpegged-fix
  • lua-change-gametype
  • lua-command-netids
  • lua-gfx-2
  • lua-gfx-sprites
  • lua-local
  • makefile-auto-mingw-gcc
  • makefile-tinkering
  • map-components-signedness-fixes
  • SRB2_release_2.1
  • SRB2_release_2.1.1
  • SRB2_release_2.1.10
  • SRB2_release_2.1.11
  • SRB2_release_2.1.12
  • SRB2_release_2.1.14
  • SRB2_release_2.1.15
  • SRB2_release_2.1.16
  • SRB2_release_2.1.16a
  • SRB2_release_2.1.17
  • SRB2_release_2.1.18
  • SRB2_release_2.1.19
  • SRB2_release_2.1.2
  • SRB2_release_2.1.20
  • SRB2_release_2.1.21
  • SRB2_release_2.1.22
  • SRB2_release_2.1.23
  • SRB2_release_2.1.24
  • SRB2_release_2.1.25
  • SRB2_release_2.1.3
  • SRB2_release_2.1.4
  • SRB2_release_2.1.5
  • SRB2_release_2.1.6
  • SRB2_release_2.1.7
  • SRB2_release_2.1.8
  • SRB2_release_2.1.9
  • SRB2_release_2.2.0
  • SRB2_release_2.2.1
  • SRB2_release_2.2.10
  • SRB2_release_2.2.11
  • SRB2_release_2.2.12
  • SRB2_release_2.2.13
  • SRB2_release_2.2.15
  • SRB2_release_2.2.2
  • SRB2_release_2.2.3
  • SRB2_release_2.2.4
  • SRB2_release_2.2.5
  • SRB2_release_2.2.6
  • SRB2_release_2.2.7
  • SRB2_release_2.2.8
  • SRB2_release_2.2.9
  • td-release-v1.0.0
142 results
Show changes
Commits on Source (47)
...@@ -1365,6 +1365,8 @@ void D_SRB2Main(void) ...@@ -1365,6 +1365,8 @@ void D_SRB2Main(void)
CONS_Printf("Z_Init(): Init zone memory allocation daemon. \n"); CONS_Printf("Z_Init(): Init zone memory allocation daemon. \n");
Z_Init(); Z_Init();
G_InitGametypes();
clientGamedata = M_NewGameDataStruct(); clientGamedata = M_NewGameDataStruct();
serverGamedata = M_NewGameDataStruct(); serverGamedata = M_NewGameDataStruct();
......
...@@ -131,6 +131,16 @@ static inline int lib_freeslot(lua_State *L) ...@@ -131,6 +131,16 @@ 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 = G_AddTeam(word);
if (i == MAXTEAMS)
CONS_Alert(CONS_WARNING, "Ran out of free team slots!\n");
CONS_Printf("Team TEAM_%s allocated.\n",word);
lua_pushinteger(L, i);
r++;
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...
...@@ -308,8 +318,8 @@ static int ScanConstants(lua_State *L, boolean mathlib, const char *word) ...@@ -308,8 +318,8 @@ static int ScanConstants(lua_State *L, boolean mathlib, const char *word)
} }
else if (fastncmp("GT_", word, 3)) { else if (fastncmp("GT_", word, 3)) {
p = word; p = word;
for (i = 0; Gametype_ConstantNames[i]; i++) for (i = 0; i < gametypecount; i++)
if (fastcmp(p, Gametype_ConstantNames[i])) { if (fastcmp(p, gametypes[i].constant_name)) {
CacheAndPushConstant(L, word, i); CacheAndPushConstant(L, word, i);
return 1; return 1;
} }
...@@ -561,6 +571,17 @@ static int ScanConstants(lua_State *L, boolean mathlib, const char *word) ...@@ -561,6 +571,17 @@ 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 < numteams; i++)
{
if (fastcmp(p, teamnames[i][0])) {
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;
......
...@@ -485,6 +485,10 @@ void readfreeslots(MYFILE *f) ...@@ -485,6 +485,10 @@ void readfreeslots(MYFILE *f)
break; break;
} }
} }
else if (fastcmp(type, "TEAM"))
{
G_AddTeam(word);
}
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...
...@@ -1145,7 +1149,7 @@ void readsprite2(MYFILE *f, INT32 num) ...@@ -1145,7 +1149,7 @@ void readsprite2(MYFILE *f, INT32 num)
Z_Free(s); Z_Free(s);
} }
void readgametype(MYFILE *f, char *gtname) void readgametype(MYFILE *f, INT32 num)
{ {
char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL); char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL);
char *word; char *word;
...@@ -1153,20 +1157,17 @@ void readgametype(MYFILE *f, char *gtname) ...@@ -1153,20 +1157,17 @@ void readgametype(MYFILE *f, char *gtname)
char *tmp; char *tmp;
INT32 i, j; INT32 i, j;
INT16 newgtidx = 0; char *gtname = gametypes[num].name;
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 gtdescription[441];
char gtconst[MAXLINELEN]; char gtconst[MAXLINELEN];
char gtdescription[441];
UINT8 teamcount = gametypes[num].teams.num;
UINT8 teamlist[MAXTEAMS];
boolean has_teams = false;
UINT8 newgtleftcolor, newgtrightcolor;
boolean has_desc_colors[2] = { false, false };
// Empty strings.
gtdescription[0] = '\0';
gtconst[0] = '\0'; gtconst[0] = '\0';
do do
...@@ -1226,8 +1227,8 @@ void readgametype(MYFILE *f, char *gtname) ...@@ -1226,8 +1227,8 @@ void readgametype(MYFILE *f, char *gtname)
if (word2) if (word2)
{ {
if (!word2lwr) if (!word2lwr)
word2lwr = Z_Malloc(MAXLINELEN, PU_STATIC, NULL); word2lwr = Z_Calloc(MAXLINELEN, PU_STATIC, NULL);
strcpy(word2lwr, word2); strlcpy(word2lwr, word2, MAXLINELEN);
strupr(word2); strupr(word2);
} }
else else
...@@ -1235,49 +1236,84 @@ void readgametype(MYFILE *f, char *gtname) ...@@ -1235,49 +1236,84 @@ void readgametype(MYFILE *f, char *gtname)
if (word2[strlen(word2)-1] == '\n') if (word2[strlen(word2)-1] == '\n')
word2[strlen(word2)-1] = '\0'; word2[strlen(word2)-1] = '\0';
if (word2lwr[strlen(word2lwr)-1] == '\n')
word2lwr[strlen(word2lwr)-1] = '\0';
i = atoi(word2); i = atoi(word2);
// Name
if (fastcmp(word, "NAME"))
{
Z_Free(gametypes[num].name);
gametypes[num].name = Z_StrDup(word2lwr);
}
// Game type rules // Game type rules
if (fastcmp(word, "RULES")) else if (fastcmp(word, "RULES"))
{ {
// GTR_ // GTR_
newgtrules = (UINT32)get_number(word2); gametypes[num].rules = (UINT32)get_number(word2);
} }
// Identifier // Identifier
else if (fastcmp(word, "IDENTIFIER")) else if (fastcmp(word, "IDENTIFIER"))
{ {
// GT_ // GT_
strncpy(gtconst, word2, MAXLINELEN); strlcpy(gtconst, word2, sizeof(gtconst));
} }
// Point and time limits // Point and time limits
else if (fastcmp(word, "DEFAULTPOINTLIMIT")) else if (fastcmp(word, "DEFAULTPOINTLIMIT"))
newgtpointlimit = (INT32)i; gametypes[num].pointlimit = (INT32)i;
else if (fastcmp(word, "DEFAULTTIMELIMIT")) else if (fastcmp(word, "DEFAULTTIMELIMIT"))
newgttimelimit = (INT32)i; gametypes[num].timelimit = (INT32)i;
// Level platter // Level platter
else if (fastcmp(word, "HEADERCOLOR") || fastcmp(word, "HEADERCOLOUR")) 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")) 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")) 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 // Rankings type
else if (fastcmp(word, "RANKINGTYPE")) else if (fastcmp(word, "RANKINGTYPE"))
{ {
// Case insensitive // Case insensitive
newgtrankingstype = (int)get_number(word2); gametypes[num].rankings_type = (int)get_number(word2);
} }
// Intermission type // Intermission type
else if (fastcmp(word, "INTERMISSIONTYPE")) else if (fastcmp(word, "INTERMISSIONTYPE"))
{ {
// Case sensitive // Case sensitive
newgtinttype = (int)get_number(word2lwr); gametypes[num].intermission_type = (int)get_number(word2lwr);
} }
// Type of level // Type of level
else if (fastcmp(word, "TYPEOFLEVEL")) else if (fastcmp(word, "TYPEOFLEVEL"))
{ {
if (i) // it's just a number if (i) // it's just a number
newgttol = (UINT32)i; gametypes[num].typeoflevel = (UINT32)i;
else else
{ {
UINT32 tol = 0; UINT32 tol = 0;
...@@ -1287,28 +1323,51 @@ void readgametype(MYFILE *f, char *gtname) ...@@ -1287,28 +1323,51 @@ void readgametype(MYFILE *f, char *gtname)
if (fasticmp(tmp, TYPEOFLEVEL[i].name)) if (fasticmp(tmp, TYPEOFLEVEL[i].name))
break; break;
if (!TYPEOFLEVEL[i].name) 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; tol |= TYPEOFLEVEL[i].flag;
} while((tmp = strtok(NULL,",")) != NULL); } while((tmp = strtok(NULL,",")) != NULL);
newgttol = tol; gametypes[num].typeoflevel = tol;
} }
} }
// The SOC probably provided gametype rules as words, // Teams
// instead of using the RULES keyword. else if (fastcmp(word, "TEAMLIST"))
// Like for example "NOSPECTATORSPAWN = TRUE". {
// This is completely valid, and looks better anyway. tmp = strtok(word2,",");
do {
if (teamcount == MAXTEAMS)
{
deh_warning("readgametype %d: too many teams\n", num);
break;
}
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.
// (For example, "NOSPECTATORSPAWN = TRUE")
else else
{ {
UINT32 wordgt = 0; UINT32 wordgt = 0;
for (j = 0; GAMETYPERULE_LIST[j]; j++) for (j = 0; GAMETYPERULE_LIST[j]; j++)
if (fastcmp(word, GAMETYPERULE_LIST[j])) { if (fastcmp(word, GAMETYPERULE_LIST[j])) {
wordgt |= (1<<j); wordgt |= (1<<j);
if (i || word2[0] == 'T' || word2[0] == 'Y') if (word2[0] == 'T' || word2[0] == 'Y')
newgtrules |= wordgt; gametypes[num].rules |= wordgt;
else if (word2[0] == 'F' || word2[0] == 'N')
gametypes[num].rules &= ~wordgt;
break; break;
} }
if (!wordgt) 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 } while (!myfeof(f)); // finish when the line is empty
...@@ -1318,38 +1377,183 @@ void readgametype(MYFILE *f, char *gtname) ...@@ -1318,38 +1377,183 @@ void readgametype(MYFILE *f, char *gtname)
if (word2lwr) if (word2lwr)
Z_Free(word2lwr); Z_Free(word2lwr);
// Ran out of gametype slots if (gtdescription[0])
if (gametypecount == NUMGAMETYPEFREESLOTS) 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"); gametypes[num].teams.num = teamcount;
return; 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);
// Not covered by G_AddGametype alone.
if (newgtrankingstype == -1)
newgtrankingstype = newgtidx;
gametyperankings[newgtidx] = newgtrankingstype;
intermissiontypes[newgtidx] = newgtinttype;
pointlimits[newgtidx] = newgtpointlimit;
timelimits[newgtidx] = newgttimelimit;
// Write the new gametype name.
Gametype_Names[newgtidx] = Z_StrDup((const char *)gtname);
// Write the constant name. // Write the constant name.
if (gtconst[0] == '\0') if (gametypes[num].constant_name == NULL)
strncpy(gtconst, gtname, MAXLINELEN); {
G_AddGametypeConstant(newgtidx, (const char *)gtconst); if (gtconst[0] == '\0')
G_AddGametypeConstant(num, gtname);
else
G_AddGametypeConstant(num, gtconst);
}
else if (gtconst[0] != '\0')
G_AddGametypeConstant(num, gtconst);
// Update gametype_cons_t accordingly. // Update gametype_cons_t accordingly.
G_UpdateGametypeSelections(); G_UpdateGametypeSelections();
}
void readteam(MYFILE *f, INT32 num)
{
char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL);
char *word;
char *word2, *word2lwr = NULL;
INT32 i;
team_t *team = &teams[num];
do
{
if (myfgets(s, MAXLINELEN, f))
{
if (s[0] == '\n')
break;
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);
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, "WEAPON"))
{
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->weapon_mobj_type = i;
else
{
deh_warning("readteam %d: Thing %d out of range (1 - %d)", num, i, NUMMOBJTYPES-1);
}
}
else if (fastcmp(word, "MISSILE"))
{
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->missile_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
CONS_Printf("Added gametype %s\n", Gametype_Names[newgtidx]); // Free strings.
Z_Free(s);
if (word2lwr)
Z_Free(word2lwr);
ST_LoadTeamIcons();
G_UpdateTeamSelection();
} }
void readlevelheader(MYFILE *f, INT32 num) void readlevelheader(MYFILE *f, INT32 num)
...@@ -3653,19 +3857,19 @@ void readmaincfg(MYFILE *f) ...@@ -3653,19 +3857,19 @@ void readmaincfg(MYFILE *f)
} }
else if (fastcmp(word, "REDTEAM")) else if (fastcmp(word, "REDTEAM"))
{ {
skincolor_redteam = (UINT16)get_number(word2); teams[TEAM_RED].color = (UINT16)get_number(word2);
} }
else if (fastcmp(word, "BLUETEAM")) else if (fastcmp(word, "BLUETEAM"))
{ {
skincolor_blueteam = (UINT16)get_number(word2); teams[TEAM_BLUE].color = (UINT16)get_number(word2);
} }
else if (fastcmp(word, "REDRING")) else if (fastcmp(word, "REDRING"))
{ {
skincolor_redring = (UINT16)get_number(word2); teams[TEAM_RED].missile_color = (UINT16)get_number(word2);
} }
else if (fastcmp(word, "BLUERING")) else if (fastcmp(word, "BLUERING"))
{ {
skincolor_bluering = (UINT16)get_number(word2); teams[TEAM_BLUE].missile_color = (UINT16)get_number(word2);
} }
else if (fastcmp(word, "INVULNTICS")) else if (fastcmp(word, "INVULNTICS"))
{ {
...@@ -4165,6 +4369,38 @@ skincolornum_t get_skincolor(const char *word) ...@@ -4165,6 +4369,38 @@ skincolornum_t get_skincolor(const char *word)
return SKINCOLOR_GREEN; 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][0]))
return i;
}
deh_warning("Couldn't find team named 'TEAM_%s'",word);
return TEAM_NONE;
}
spritenum_t get_sprite(const char *word) spritenum_t get_sprite(const char *word)
{ // Returns the value of SPR_ enumerations { // Returns the value of SPR_ enumerations
spritenum_t i; spritenum_t i;
...@@ -4237,34 +4473,6 @@ menutype_t get_menutype(const char *word) ...@@ -4237,34 +4473,6 @@ menutype_t get_menutype(const char *word)
return MN_NONE; return MN_NONE;
} }
/*static INT16 get_gametype(const char *word)
{ // Returns the value of GT_ enumerations
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 < NUMGAMETYPES; i++)
if (fastcmp(word, Gametype_ConstantNames[i]+3))
return i;
deh_warning("Couldn't find gametype named 'GT_%s'",word);
return GT_COOP;
}
static powertype_t get_power(const char *word)
{ // Returns the value of pw_ enumerations
powertype_t i;
if (*word >= '0' && *word <= '9')
return atoi(word);
if (fastncmp("PW_",word,3))
word += 3; // take off the pw_
for (i = 0; i < NUMPOWERS; i++)
if (fastcmp(word, POWERS_LIST[i]))
return i;
deh_warning("Couldn't find power named 'pw_%s'",word);
return pw_invulnerability;
}*/
/// \todo Make ANY of this completely over-the-top math craziness obey the order of operations. /// \todo Make ANY of this completely over-the-top math craziness obey the order of operations.
static fixed_t op_mul(fixed_t a, fixed_t b) { return a*b; } static fixed_t op_mul(fixed_t a, fixed_t b) { return a*b; }
static fixed_t op_div(fixed_t a, fixed_t b) { return a/b; } static fixed_t op_div(fixed_t a, fixed_t b) { return a/b; }
......
...@@ -54,9 +54,9 @@ playersprite_t get_sprite2(const char *word); ...@@ -54,9 +54,9 @@ playersprite_t get_sprite2(const char *word);
sfxenum_t get_sfx(const char *word); sfxenum_t get_sfx(const char *word);
hudnum_t get_huditem(const char *word); hudnum_t get_huditem(const char *word);
menutype_t get_menutype(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); skincolornum_t get_skincolor(const char *word);
INT16 get_gametype(const char *word);
UINT8 get_team(const char *word);
void readwipes(MYFILE *f); void readwipes(MYFILE *f);
void readmaincfg(MYFILE *f); void readmaincfg(MYFILE *f);
...@@ -71,7 +71,8 @@ void readmenu(MYFILE *f, INT32 num); ...@@ -71,7 +71,8 @@ void readmenu(MYFILE *f, INT32 num);
void readtextprompt(MYFILE *f, INT32 num); void readtextprompt(MYFILE *f, INT32 num);
void readcutscene(MYFILE *f, INT32 num); void readcutscene(MYFILE *f, INT32 num);
void readlevelheader(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 readsprite2(MYFILE *f, INT32 num);
void readspriteinfo(MYFILE *f, INT32 num, boolean sprite2); void readspriteinfo(MYFILE *f, INT32 num, boolean sprite2);
#ifdef HWRENDER #ifdef HWRENDER
......
...@@ -4416,6 +4416,8 @@ const char *const MOBJEFLAG_LIST[] = { ...@@ -4416,6 +4416,8 @@ const char *const MOBJEFLAG_LIST[] = {
"TRACERANGLE", // Compute and trigger on mobj angle relative to tracer "TRACERANGLE", // Compute and trigger on mobj angle relative to tracer
"FORCESUPER", // Forces an object to use super sprites with SPR_PLAY. "FORCESUPER", // Forces an object to use super sprites with SPR_PLAY.
"FORCENOSUPER", // Forces an object to NOT use super sprites with SPR_PLAY. "FORCENOSUPER", // Forces an object to NOT use super sprites with SPR_PLAY.
"TEAMITEM", // Object is a team item
"TEAMFLAG", // Object is a team flag
NULL NULL
}; };
...@@ -5328,6 +5330,11 @@ struct int_const_s const INT_CONST[] = { ...@@ -5328,6 +5330,11 @@ struct int_const_s const INT_CONST[] = {
{"int_race",int_race}, {"int_race",int_race},
{"int_comp",int_comp}, {"int_comp",int_comp},
// Ranking types
{"RANKINGS_DEFAULT",RANKINGS_DEFAULT},
{"RANKINGS_COMPETITION",RANKINGS_COMPETITION},
{"RANKINGS_RACE",RANKINGS_RACE},
// Jingles (jingletype_t) // Jingles (jingletype_t)
{"JT_NONE",JT_NONE}, {"JT_NONE",JT_NONE},
{"JT_OTHER",JT_OTHER}, {"JT_OTHER",JT_OTHER},
......
...@@ -186,9 +186,9 @@ void ignorelinesuntilhash(MYFILE *f) ...@@ -186,9 +186,9 @@ void ignorelinesuntilhash(MYFILE *f)
static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile) static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile)
{ {
char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL); char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL);
char textline[MAXLINELEN];
char *word; char *word;
char *word2; char *word2;
char word2lwr[MAXLINELEN];
INT32 i; INT32 i;
if (!deh_loaded) if (!deh_loaded)
...@@ -203,7 +203,6 @@ static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile) ...@@ -203,7 +203,6 @@ static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile)
while (!myfeof(f)) while (!myfeof(f))
{ {
myfgets(s, MAXLINELEN, f); myfgets(s, MAXLINELEN, f);
memcpy(textline, s, MAXLINELEN);
if (s[0] == '\n' || s[0] == '#') if (s[0] == '\n' || s[0] == '#')
continue; continue;
...@@ -230,10 +229,14 @@ static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile) ...@@ -230,10 +229,14 @@ static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile)
continue; continue;
} }
word2 = strtok(NULL, " "); word2 = strtok(NULL, " ");
word2lwr[0] = '\0';
if (word2) { if (word2) {
strcpy(word2lwr, word2);
strupr(word2); strupr(word2);
if (word2[strlen(word2) - 1] == '\n') if (word2[strlen(word2) - 1] == '\n')
word2[strlen(word2) - 1] = '\0'; word2[strlen(word2) - 1] = '\0';
if (word2lwr[strlen(word2lwr) - 1] == '\n')
word2lwr[strlen(word2lwr) - 1] = '\0';
i = atoi(word2); i = atoi(word2);
} }
else else
...@@ -389,32 +392,60 @@ static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile) ...@@ -389,32 +392,60 @@ static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile)
} }
else if (fastcmp(word, "GAMETYPE")) else if (fastcmp(word, "GAMETYPE"))
{ {
// Get the gametype name from textline char *gtname = NULL;
// instead of word2, so that gametype names if (word2lwr[0])
// aren't allcaps
INT32 c;
for (c = 0; c < MAXLINELEN; c++)
{ {
if (textline[c] == '\0') gtname = word2lwr;
break;
if (textline[c] == ' ') 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 (!strncmp(gtname, "GT_", 3))
if (gtname) gametype_id = get_gametype(gtname + 3);
else if (gametypecount != NUMGAMETYPEFREESLOTS)
{ {
// remove funny characters gametype_id = G_AddGametype();
INT32 j; CONS_Printf("Added gametype %s\n", gtname);
for (j = 0; j < (MAXLINELEN - c); j++)
{
if (gtname[j] == '\0')
break;
if (gtname[j] < 32)
gtname[j] = '\0';
}
readgametype(f, 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")) else if (fastcmp(word, "CUTSCENE"))
......
...@@ -221,6 +221,8 @@ typedef struct ...@@ -221,6 +221,8 @@ typedef struct
struct mobj_s *mobj; struct mobj_s *mobj;
} mapthing_t; } mapthing_t;
#define THING_TYPE_CTF_TEAM_FLAG 324
#define ZSHIFT 4 #define ZSHIFT 4
#define NUMMAPS 1035 #define NUMMAPS 1035
......
...@@ -98,7 +98,6 @@ extern boolean multiplayer; ...@@ -98,7 +98,6 @@ extern boolean multiplayer;
extern INT16 gametype; extern INT16 gametype;
extern UINT32 gametyperules; extern UINT32 gametyperules;
extern INT16 gametypecount;
extern boolean splitscreen; extern boolean splitscreen;
extern boolean circuitmap; // Does this level have 'circuit mode'? extern boolean circuitmap; // Does this level have 'circuit mode'?
...@@ -155,9 +154,6 @@ extern INT32 tutorialanalog; // store cv_analog[0] user value ...@@ -155,9 +154,6 @@ extern INT32 tutorialanalog; // store cv_analog[0] user value
extern boolean looptitle; extern boolean looptitle;
// CTF colors.
extern UINT16 skincolor_redteam, skincolor_blueteam, skincolor_redring, skincolor_bluering;
extern tic_t countdowntimer; extern tic_t countdowntimer;
extern boolean countdowntimeup; extern boolean countdowntimeup;
extern boolean exitfadestarted; extern boolean exitfadestarted;
...@@ -255,10 +251,11 @@ extern UINT32 ssspheres; // Total # of spheres in a level ...@@ -255,10 +251,11 @@ extern UINT32 ssspheres; // Total # of spheres in a level
// Fun extra stuff // Fun extra stuff
extern INT16 lastmap; // Last level you were at (returning from special stages). extern INT16 lastmap; // Last level you were at (returning from special stages).
extern mobj_t *redflag, *blueflag; // Pointers to physical flags
extern mapthing_t *rflagpoint, *bflagpoint; // Pointers to the flag spawn locations enum {
#define GF_REDFLAG 1 GF_REDFLAG = 1,
#define GF_BLUEFLAG 2 GF_BLUEFLAG = 2
};
// A single point in space. // A single point in space.
typedef struct typedef struct
...@@ -390,8 +387,44 @@ typedef struct ...@@ -390,8 +387,44 @@ typedef struct
extern mapheader_t* mapheaderinfo[NUMMAPS]; extern mapheader_t* mapheaderinfo[NUMMAPS];
// Gametypes enum {
TEAM_NONE,
TEAM_RED,
TEAM_BLUE,
TEAM_PLAYING = 1,
MAXTEAMS = 16
};
enum {
TEAM_ICON,
TEAM_ICON_FLAG,
TEAM_ICON_GOT_FLAG,
TEAM_ICON_MISSING_FLAG,
TEAM_ICON_MAX
};
typedef struct
{
char *name;
UINT16 color;
UINT32 weapon_mobj_type;
UINT32 missile_mobj_type;
UINT16 weapon_color;
UINT16 missile_color;
char *flag_name;
UINT16 flag;
UINT32 flag_mobj_type;
char *icons[TEAM_ICON_MAX];
} team_t;
extern team_t teams[MAXTEAMS];
extern UINT8 numteams;
extern char *teamnames[MAXTEAMS][2];
#define NUMGAMETYPEFREESLOTS 128 #define NUMGAMETYPEFREESLOTS 128
// Gametypes
enum GameType enum GameType
{ {
GT_COOP = 0, // also used in single player GT_COOP = 0, // also used in single player
...@@ -410,7 +443,7 @@ enum GameType ...@@ -410,7 +443,7 @@ enum GameType
GT_LASTFREESLOT = GT_FIRSTFREESLOT + NUMGAMETYPEFREESLOTS - 1, GT_LASTFREESLOT = GT_FIRSTFREESLOT + NUMGAMETYPEFREESLOTS - 1,
NUMGAMETYPES NUMGAMETYPES
}; };
// If you alter this list, update deh_tables.c, MISC_ChangeGameTypeMenu in m_menu.c, and Gametype_Names in g_game.c // If you alter this list, update deh_tables.c, MISC_ChangeGameTypeMenu in m_menu.c, and gametypes in g_game.c
// Gametype rules // Gametype rules
enum GameTypeRules enum GameTypeRules
...@@ -449,13 +482,34 @@ enum GameTypeRules ...@@ -449,13 +482,34 @@ enum GameTypeRules
GTR_CUTSCENES = 1<<31, // Play cutscenes, ending, credits, and evaluation GTR_CUTSCENES = 1<<31, // Play cutscenes, ending, credits, and evaluation
}; };
// String names for gametypes enum
extern const char *Gametype_Names[NUMGAMETYPES]; {
extern const char *Gametype_ConstantNames[NUMGAMETYPES]; RANKINGS_DEFAULT,
RANKINGS_COMPETITION,
RANKINGS_RACE
};
// Point and time limits for every gametype typedef struct
extern INT32 pointlimits[NUMGAMETYPES]; {
extern INT32 timelimits[NUMGAMETYPES]; UINT8 num;
UINT8 list[MAXTEAMS];
} teamlist_t;
typedef struct
{
char *name;
char *constant_name;
UINT32 rules;
UINT32 typeoflevel;
UINT8 intermission_type;
INT16 rankings_type;
INT32 pointlimit;
INT32 timelimit;
teamlist_t teams;
} gametype_t;
extern gametype_t gametypes[NUMGAMETYPES];
extern INT16 gametypecount;
// TypeOfLevel things // TypeOfLevel things
enum TypeOfLevel enum TypeOfLevel
...@@ -517,8 +571,10 @@ extern UINT32 tokenlist; ///< List of tokens collected ...@@ -517,8 +571,10 @@ extern UINT32 tokenlist; ///< List of tokens collected
extern boolean gottoken; ///< Did you get a token? Used for end of act extern boolean gottoken; ///< Did you get a token? Used for end of act
extern INT32 tokenbits; ///< Used for setting token bits extern INT32 tokenbits; ///< Used for setting token bits
extern INT32 sstimer; ///< Time allotted in the special stage extern INT32 sstimer; ///< Time allotted in the special stage
extern UINT32 bluescore; ///< Blue Team Scores extern UINT8 teamsingame; ///< Current teams in game
extern UINT32 redscore; ///< Red Team Scores extern UINT32 teamscores[MAXTEAMS]; ///< Team scores
extern mobj_t *flagmobjs[MAXTEAMS]; // Pointers to physical flags
extern mapthing_t *flagpoints[MAXTEAMS]; // Pointers to the flag spawn locations
// Eliminates unnecessary searching. // Eliminates unnecessary searching.
extern boolean CheckForBustableBlocks; extern boolean CheckForBustableBlocks;
......
This diff is collapsed.
...@@ -191,17 +191,17 @@ void G_SaveGame(UINT32 slot, INT16 mapnum); ...@@ -191,17 +191,17 @@ void G_SaveGame(UINT32 slot, INT16 mapnum);
void G_SaveGameOver(UINT32 slot, boolean modifylives); void G_SaveGameOver(UINT32 slot, boolean modifylives);
extern UINT32 gametypedefaultrules[NUMGAMETYPES];
extern UINT32 gametypetol[NUMGAMETYPES];
extern INT16 gametyperankings[NUMGAMETYPES];
void G_SetGametype(INT16 gametype); void G_SetGametype(INT16 gametype);
INT16 G_AddGametype(UINT32 rules); void G_InitGametypes(void);
INT16 G_AddGametype(void);
void G_UpdateTeamSelection(void);
void G_AddGametypeConstant(INT16 gtype, const char *newgtconst); void G_AddGametypeConstant(INT16 gtype, const char *newgtconst);
void G_UpdateGametypeSelections(void); void G_UpdateGametypeSelections(void);
void G_AddTOL(UINT32 newtol, const char *tolname); 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); INT32 G_GetGametypeByName(const char *gametypestr);
boolean G_IsSpecialStage(INT32 mapnum); boolean G_IsSpecialStage(INT32 mapnum);
...@@ -224,6 +224,30 @@ void G_UseContinue(void); ...@@ -224,6 +224,30 @@ void G_UseContinue(void);
void G_AfterIntermission(void); void G_AfterIntermission(void);
void G_EndGame(void); // moved from y_inter.c/h and renamed void G_EndGame(void); // moved from y_inter.c/h and renamed
void G_InitTeam(UINT8 team);
UINT8 G_AddTeam(const char *name);
UINT8 G_GetGametypeTeam(UINT8 gtype, UINT8 team);
UINT8 G_GetTeam(UINT8 team);
UINT8 G_GetTeamFromTeamFlag(UINT32 flag);
UINT8 G_GetTeamListFromTeamFlags(UINT8 *teamlist, UINT32 flags);
UINT8 G_GetTeamByName(const char *name);
const char *G_GetTeamName(UINT8 team);
const char *G_GetTeamFlagName(UINT8 team);
UINT32 G_GetTeamWeaponMobjtype(UINT8 team);
UINT32 G_GetTeamMissileMobjtype(UINT8 team);
UINT16 G_GetTeamColor(UINT8 team);
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);
UINT8 G_GetBestPerformingTeam(void);
UINT8 G_GetWorstPerformingTeam(void);
UINT8 G_GetMostAdvantagedTeam(void);
UINT8 G_GetMostDisadvantagedTeam(void);
void G_Ticker(boolean run); void G_Ticker(boolean run);
boolean G_Responder(event_t *ev); boolean G_Responder(event_t *ev);
boolean G_LuaResponder(event_t *ev); boolean G_LuaResponder(event_t *ev);
......
...@@ -86,10 +86,7 @@ static boolean headsupactive = false; ...@@ -86,10 +86,7 @@ static boolean headsupactive = false;
boolean hu_showscores; // draw rankings boolean hu_showscores; // draw rankings
static char hu_tick; static char hu_tick;
patch_t *rflagico; patch_t *teamicons[MAXTEAMS][TEAM_ICON_MAX];
patch_t *bflagico;
patch_t *rmatcico;
patch_t *bmatcico;
patch_t *tagico; patch_t *tagico;
patch_t *tallminus; patch_t *tallminus;
patch_t *tallinfin; patch_t *tallinfin;
...@@ -626,6 +623,46 @@ static void Command_CSay_f(void) ...@@ -626,6 +623,46 @@ static void Command_CSay_f(void)
static tic_t spam_tokens[MAXPLAYERS] = { 1 }; // fill the buffer with 1 so the motd can be sent. static tic_t spam_tokens[MAXPLAYERS] = { 1 }; // fill the buffer with 1 so the motd can be sent.
static tic_t spam_tics[MAXPLAYERS]; static tic_t spam_tics[MAXPLAYERS];
const char *GetChatColorForSkincolor(UINT16 skincolor)
{
UINT16 chatcolor = skincolors[skincolor].chatcolor;
if (!chatcolor || chatcolor%0x1000 || chatcolor>V_INVERTMAP)
return "\x80";
else if (chatcolor == V_MAGENTAMAP)
return "\x81";
else if (chatcolor == V_YELLOWMAP)
return "\x82";
else if (chatcolor == V_GREENMAP)
return "\x83";
else if (chatcolor == V_BLUEMAP)
return "\x84";
else if (chatcolor == V_REDMAP)
return "\x85";
else if (chatcolor == V_GRAYMAP)
return "\x86";
else if (chatcolor == V_ORANGEMAP)
return "\x87";
else if (chatcolor == V_SKYMAP)
return "\x88";
else if (chatcolor == V_PURPLEMAP)
return "\x89";
else if (chatcolor == V_AQUAMAP)
return "\x8a";
else if (chatcolor == V_PERIDOTMAP)
return "\x8b";
else if (chatcolor == V_AZUREMAP)
return "\x8c";
else if (chatcolor == V_BROWNMAP)
return "\x8d";
else if (chatcolor == V_ROSYMAP)
return "\x8e";
else if (chatcolor == V_INVERTMAP)
return "\x8f";
return "\x80";
}
/** Receives a message, processing an ::XD_SAY command. /** Receives a message, processing an ::XD_SAY command.
* \sa DoSayCommand * \sa DoSayCommand
* \author Graue <graue@oceanbase.org> * \author Graue <graue@oceanbase.org>
...@@ -736,6 +773,7 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum) ...@@ -736,6 +773,7 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum)
{ {
const char *prefix = "", *cstart = "", *cend = "", *adminchar = "\x82~\x83", *remotechar = "\x82@\x83", *fmt2, *textcolor = "\x80"; const char *prefix = "", *cstart = "", *cend = "", *adminchar = "\x82~\x83", *remotechar = "\x82@\x83", *fmt2, *textcolor = "\x80";
char *tempchar = NULL; char *tempchar = NULL;
char *tempteam = NULL;
// player is a spectator? // player is a spectator?
if (players[playernum].spectator) if (players[playernum].spectator)
...@@ -745,54 +783,13 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum) ...@@ -745,54 +783,13 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum)
} }
else if (target == -1) // say team else if (target == -1) // say team
{ {
if (players[playernum].ctfteam == 1) // red cstart = GetChatColorForSkincolor(G_GetTeamColor(players[playernum].ctfteam));
{ textcolor = cstart;
cstart = "\x85";
textcolor = "\x85";
}
else // blue
{
cstart = "\x84";
textcolor = "\x84";
}
} }
else else
{ {
UINT16 chatcolor = skincolors[players[playernum].skincolor].chatcolor; cstart = GetChatColorForSkincolor(players[playernum].skincolor);
}
if (!chatcolor || chatcolor%0x1000 || chatcolor>V_INVERTMAP)
cstart = "\x80";
else if (chatcolor == V_MAGENTAMAP)
cstart = "\x81";
else if (chatcolor == V_YELLOWMAP)
cstart = "\x82";
else if (chatcolor == V_GREENMAP)
cstart = "\x83";
else if (chatcolor == V_BLUEMAP)
cstart = "\x84";
else if (chatcolor == V_REDMAP)
cstart = "\x85";
else if (chatcolor == V_GRAYMAP)
cstart = "\x86";
else if (chatcolor == V_ORANGEMAP)
cstart = "\x87";
else if (chatcolor == V_SKYMAP)
cstart = "\x88";
else if (chatcolor == V_PURPLEMAP)
cstart = "\x89";
else if (chatcolor == V_AQUAMAP)
cstart = "\x8a";
else if (chatcolor == V_PERIDOTMAP)
cstart = "\x8b";
else if (chatcolor == V_AZUREMAP)
cstart = "\x8c";
else if (chatcolor == V_BROWNMAP)
cstart = "\x8d";
else if (chatcolor == V_ROSYMAP)
cstart = "\x8e";
else if (chatcolor == V_INVERTMAP)
cstart = "\x8f";
}
prefix = cstart; prefix = cstart;
// Give admins and remote admins their symbols. // Give admins and remote admins their symbols.
...@@ -836,10 +833,11 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum) ...@@ -836,10 +833,11 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum)
fmt2 = "%s<%s%s%s>\x80 %s%s"; fmt2 = "%s<%s%s%s>\x80 %s%s";
else // To your team else // To your team
{ {
if (players[playernum].ctfteam == 1) // red if (players[playernum].ctfteam != 0)
prefix = "\x85[TEAM]"; {
else if (players[playernum].ctfteam == 2) // blue tempteam = Z_StrDup(va("%s[TEAM]", GetChatColorForSkincolor(G_GetTeamColor(players[playernum].ctfteam))));
prefix = "\x84[TEAM]"; prefix = tempteam;
}
else else
prefix = "\x83"; // makes sure this doesn't implode if you sayteam on non-team gamemodes prefix = "\x83"; // makes sure this doesn't implode if you sayteam on non-team gamemodes
...@@ -850,6 +848,8 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum) ...@@ -850,6 +848,8 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum)
if (tempchar) if (tempchar)
Z_Free(tempchar); Z_Free(tempchar);
if (tempteam)
Z_Free(tempteam);
} }
#ifdef _DEBUG #ifdef _DEBUG
// I just want to point out while I'm here that because the data is still // I just want to point out while I'm here that because the data is still
...@@ -1589,12 +1589,6 @@ static void HU_DrawChat(void) ...@@ -1589,12 +1589,6 @@ static void HU_DrawChat(void)
if (teamtalk) if (teamtalk)
{ {
talk = ttalk; talk = ttalk;
#if 0
if (players[consoleplayer].ctfteam == 1)
t = 0x500; // Red
else if (players[consoleplayer].ctfteam == 2)
t = 0x400; // Blue
#endif
} }
if (CHAT_MUTE) if (CHAT_MUTE)
...@@ -1757,12 +1751,6 @@ static void HU_DrawChat_Old(void) ...@@ -1757,12 +1751,6 @@ static void HU_DrawChat_Old(void)
if (teamtalk) if (teamtalk)
{ {
talk = ttalk; talk = ttalk;
#if 0
if (players[consoleplayer].ctfteam == 1)
t = 0x500; // Red
else if (players[consoleplayer].ctfteam == 2)
t = 0x400; // Blue
#endif
} }
while (talk[i]) while (talk[i])
...@@ -1908,7 +1896,7 @@ static void HU_drawGametype(void) ...@@ -1908,7 +1896,7 @@ static void HU_drawGametype(void)
if (gametype < 0 || gametype >= gametypecount) if (gametype < 0 || gametype >= gametypecount)
return; // not a valid gametype??? return; // not a valid gametype???
strvalue = Gametype_Names[gametype]; strvalue = gametypes[gametype].name;
if (splitscreen) if (splitscreen)
V_DrawString(4, 184, 0, strvalue); V_DrawString(4, 184, 0, strvalue);
...@@ -2119,7 +2107,7 @@ void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, I ...@@ -2119,7 +2107,7 @@ void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, I
for (i = 0; i < scorelines; i++) for (i = 0; i < scorelines; i++)
{ {
if (players[tab[i].num].spectator && gametyperankings[gametype] != GT_COOP) if (players[tab[i].num].spectator && !G_GametypeUsesCoopLives())
continue; //ignore them. continue; //ignore them.
greycheck = greycheckdef; greycheck = greycheckdef;
...@@ -2196,7 +2184,7 @@ void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, I ...@@ -2196,7 +2184,7 @@ void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, I
if (players[tab[i].num].exiting || (players[tab[i].num].pflags & PF_FINISHED)) if (players[tab[i].num].exiting || (players[tab[i].num].pflags & PF_FINISHED))
V_DrawSmallScaledPatch(x - exiticon->width/2 - 1, y-3, 0, exiticon); V_DrawSmallScaledPatch(x - exiticon->width/2 - 1, y-3, 0, exiticon);
if (gametyperankings[gametype] == GT_RACE) if (gametypes[gametype].rankings_type == RANKINGS_RACE)
{ {
if (circuitmap) if (circuitmap)
{ {
...@@ -2266,13 +2254,13 @@ static void HU_Draw32TeamTabRankings(playersort_t *tab, INT32 whiteplayer) ...@@ -2266,13 +2254,13 @@ static void HU_Draw32TeamTabRankings(playersort_t *tab, INT32 whiteplayer)
greycheck = greycheckdef; greycheck = greycheckdef;
supercheck = supercheckdef; supercheck = supercheckdef;
if (tab[i].color == skincolor_redteam) //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].color == skincolor_blueteam) //blue else if (tab[i].team == G_GetTeam(2)) //blue
{ {
blueplayers++; blueplayers++;
x = 14; x = 14;
...@@ -2293,23 +2281,21 @@ static void HU_Draw32TeamTabRankings(playersort_t *tab, INT32 whiteplayer) ...@@ -2293,23 +2281,21 @@ static void HU_Draw32TeamTabRankings(playersort_t *tab, INT32 whiteplayer)
if (gametyperules & GTR_TEAMFLAGS) if (gametyperules & GTR_TEAMFLAGS)
{ {
if (players[tab[i].num].gotflag & GF_REDFLAG) // Red UINT8 teamlist[MAXTEAMS];
V_DrawFixedPatch((x-10)*FRACUNIT, (y)*FRACUNIT, FRACUNIT/4, 0, rflagico, 0); UINT8 teamcount = G_GetTeamListFromTeamFlags(teamlist, players[tab[i].num].gotflag);
else if (players[tab[i].num].gotflag & GF_BLUEFLAG) // Blue if (teamcount > 0)
V_DrawFixedPatch((x-10)*FRACUNIT, (y)*FRACUNIT, FRACUNIT/4, 0, bflagico, 0); V_DrawFixedPatch((x-10)*FRACUNIT, (y)*FRACUNIT, FRACUNIT/4, 0, ST_GetTeamIconImage(teamlist[0], TEAM_ICON_FLAG), 0);
} }
// Draw emeralds // Draw emeralds
if (players[tab[i].num].powers[pw_invulnerability] && (players[tab[i].num].powers[pw_invulnerability] == players[tab[i].num].powers[pw_sneakers]) && ((leveltime/7) & 1)) if (players[tab[i].num].powers[pw_invulnerability] && (players[tab[i].num].powers[pw_invulnerability] == players[tab[i].num].powers[pw_sneakers]) && ((leveltime/7) & 1))
{ {
HU_Draw32Emeralds(x+60, y+2, 255); HU_Draw32Emeralds(x+60, y+2, 255);
//HU_DrawEmeralds(x-12,y+2,255);
} }
else if (!players[tab[i].num].powers[pw_super] else if (!players[tab[i].num].powers[pw_super]
|| ((leveltime/7) & 1)) || ((leveltime/7) & 1))
{ {
HU_Draw32Emeralds(x+60, y+2, tab[i].emeralds); HU_Draw32Emeralds(x+60, y+2, tab[i].emeralds);
//HU_DrawEmeralds(x-12,y+2,tab[i].emeralds);
} }
if (supercheck) if (supercheck)
...@@ -2354,7 +2340,7 @@ void HU_DrawTeamTabRankings(playersort_t *tab, INT32 whiteplayer) ...@@ -2354,7 +2340,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].color == skincolor_redteam) //red if (tab[i].team == G_GetTeam(1)) //red
{ {
if (redplayers++ > 8) if (redplayers++ > 8)
{ {
...@@ -2362,7 +2348,7 @@ void HU_DrawTeamTabRankings(playersort_t *tab, INT32 whiteplayer) ...@@ -2362,7 +2348,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].color == skincolor_blueteam) //blue else if (tab[i].team == G_GetTeam(2)) //blue
{ {
if (blueplayers++ > 8) if (blueplayers++ > 8)
{ {
...@@ -2393,14 +2379,14 @@ void HU_DrawTeamTabRankings(playersort_t *tab, INT32 whiteplayer) ...@@ -2393,14 +2379,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].color == skincolor_redteam) //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].color == skincolor_blueteam) //blue else if (tab[i].team == G_GetTeam(2)) //blue
{ {
if (blueplayers++ > 8) if (blueplayers++ > 8)
continue; continue;
...@@ -2422,10 +2408,10 @@ void HU_DrawTeamTabRankings(playersort_t *tab, INT32 whiteplayer) ...@@ -2422,10 +2408,10 @@ void HU_DrawTeamTabRankings(playersort_t *tab, INT32 whiteplayer)
if (gametyperules & GTR_TEAMFLAGS) if (gametyperules & GTR_TEAMFLAGS)
{ {
if (players[tab[i].num].gotflag & GF_REDFLAG) // Red UINT8 teamlist[MAXTEAMS];
V_DrawSmallScaledPatch(x-28, y-4, 0, rflagico); UINT8 teamcount = G_GetTeamListFromTeamFlags(teamlist, players[tab[i].num].gotflag);
else if (players[tab[i].num].gotflag & GF_BLUEFLAG) // Blue if (teamcount > 0)
V_DrawSmallScaledPatch(x-28, y-4, 0, bflagico); V_DrawSmallScaledPatch(x-28, y-4, 0, ST_GetTeamIconImage(teamlist[0], TEAM_ICON_FLAG));
} }
// Draw emeralds // Draw emeralds
...@@ -2455,8 +2441,6 @@ void HU_DrawTeamTabRankings(playersort_t *tab, INT32 whiteplayer) ...@@ -2455,8 +2441,6 @@ void HU_DrawTeamTabRankings(playersort_t *tab, INT32 whiteplayer)
{ {
if (tab[i].num != serverplayer) if (tab[i].num != serverplayer)
HU_drawPing(x+ 113, y, players[tab[i].num].quittime ? UINT32_MAX : playerpingtable[tab[i].num], false, 0); HU_drawPing(x+ 113, y, players[tab[i].num].quittime ? UINT32_MAX : playerpingtable[tab[i].num], false, 0);
//else
// V_DrawSmallString(x+ 94, y+4, V_YELLOWMAP, "SERVER");
} }
} }
} }
...@@ -2477,7 +2461,7 @@ void HU_DrawDualTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scoreline ...@@ -2477,7 +2461,7 @@ void HU_DrawDualTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scoreline
for (i = 0; i < scorelines; i++) for (i = 0; i < scorelines; i++)
{ {
if (players[tab[i].num].spectator && gametyperankings[gametype] != GT_COOP) if (players[tab[i].num].spectator && !G_GametypeUsesCoopLives())
continue; //ignore them. continue; //ignore them.
greycheck = greycheckdef; greycheck = greycheckdef;
...@@ -2544,7 +2528,7 @@ void HU_DrawDualTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scoreline ...@@ -2544,7 +2528,7 @@ void HU_DrawDualTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scoreline
} }
// All data drawn with thin string for space. // All data drawn with thin string for space.
if (gametyperankings[gametype] == GT_RACE) if (gametypes[gametype].rankings_type == RANKINGS_RACE)
{ {
if (circuitmap) if (circuitmap)
{ {
...@@ -2584,7 +2568,7 @@ static void HU_Draw32TabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scor ...@@ -2584,7 +2568,7 @@ static void HU_Draw32TabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scor
for (i = 0; i < scorelines; i++) for (i = 0; i < scorelines; i++)
{ {
if (players[tab[i].num].spectator && gametyperankings[gametype] != GT_COOP) if (players[tab[i].num].spectator && !G_GametypeUsesCoopLives())
continue; //ignore them. continue; //ignore them.
greycheck = greycheckdef; greycheck = greycheckdef;
...@@ -2655,7 +2639,7 @@ static void HU_Draw32TabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scor ...@@ -2655,7 +2639,7 @@ static void HU_Draw32TabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scor
} }
// All data drawn with thin string for space. // All data drawn with thin string for space.
if (gametyperankings[gametype] == GT_RACE) if (gametypes[gametype].rankings_type == RANKINGS_RACE)
{ {
if (circuitmap) if (circuitmap)
{ {
...@@ -2815,7 +2799,7 @@ static void HU_DrawRankings(void) ...@@ -2815,7 +2799,7 @@ static void HU_DrawRankings(void)
tab[i].num = -1; tab[i].num = -1;
tab[i].name = 0; tab[i].name = 0;
if (gametyperankings[gametype] == GT_RACE && !circuitmap) if (gametypes[gametype].rankings_type == RANKINGS_RACE && !circuitmap)
tab[i].count = INT32_MAX; tab[i].count = INT32_MAX;
} }
...@@ -2835,7 +2819,7 @@ static void HU_DrawRankings(void) ...@@ -2835,7 +2819,7 @@ static void HU_DrawRankings(void)
if (!G_PlatformGametype() && players[i].spectator) if (!G_PlatformGametype() && players[i].spectator)
continue; continue;
if (gametyperankings[gametype] == GT_RACE) if (gametypes[gametype].rankings_type == RANKINGS_RACE)
{ {
if (circuitmap) if (circuitmap)
{ {
...@@ -2844,6 +2828,7 @@ static void HU_DrawRankings(void) ...@@ -2844,6 +2828,7 @@ static void HU_DrawRankings(void)
tab[scorelines].count = players[i].laps+1; tab[scorelines].count = players[i].laps+1;
tab[scorelines].num = i; tab[scorelines].num = i;
tab[scorelines].color = players[i].skincolor; tab[scorelines].color = players[i].skincolor;
tab[scorelines].team = players[i].ctfteam;
tab[scorelines].name = player_names[i]; tab[scorelines].name = player_names[i];
} }
} }
...@@ -2854,11 +2839,12 @@ static void HU_DrawRankings(void) ...@@ -2854,11 +2839,12 @@ static void HU_DrawRankings(void)
tab[scorelines].count = players[i].realtime; tab[scorelines].count = players[i].realtime;
tab[scorelines].num = i; tab[scorelines].num = i;
tab[scorelines].color = players[i].skincolor; tab[scorelines].color = players[i].skincolor;
tab[scorelines].team = players[i].ctfteam;
tab[scorelines].name = player_names[i]; tab[scorelines].name = player_names[i];
} }
} }
} }
else if (gametyperankings[gametype] == GT_COMPETITION) else if (gametypes[gametype].rankings_type == RANKINGS_COMPETITION)
{ {
// todo put something more fitting for the gametype here, such as current // todo put something more fitting for the gametype here, such as current
// number of categories led // number of categories led
...@@ -2868,6 +2854,7 @@ static void HU_DrawRankings(void) ...@@ -2868,6 +2854,7 @@ static void HU_DrawRankings(void)
tab[scorelines].num = i; tab[scorelines].num = i;
tab[scorelines].color = players[i].skincolor; tab[scorelines].color = players[i].skincolor;
tab[scorelines].name = player_names[i]; tab[scorelines].name = player_names[i];
tab[scorelines].team = players[i].ctfteam;
tab[scorelines].emeralds = players[i].powers[pw_emeralds]; tab[scorelines].emeralds = players[i].powers[pw_emeralds];
} }
} }
...@@ -2879,6 +2866,7 @@ static void HU_DrawRankings(void) ...@@ -2879,6 +2866,7 @@ static void HU_DrawRankings(void)
tab[scorelines].num = i; tab[scorelines].num = i;
tab[scorelines].color = players[i].skincolor; tab[scorelines].color = players[i].skincolor;
tab[scorelines].name = player_names[i]; tab[scorelines].name = player_names[i];
tab[scorelines].team = players[i].ctfteam;
tab[scorelines].emeralds = players[i].powers[pw_emeralds]; tab[scorelines].emeralds = players[i].powers[pw_emeralds];
} }
} }
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#ifndef __HU_STUFF_H__ #ifndef __HU_STUFF_H__
#define __HU_STUFF_H__ #define __HU_STUFF_H__
#include "doomstat.h"
#include "d_event.h" #include "d_event.h"
#include "w_wad.h" #include "w_wad.h"
#include "r_defs.h" #include "r_defs.h"
...@@ -56,6 +57,7 @@ typedef struct ...@@ -56,6 +57,7 @@ typedef struct
INT32 num; INT32 num;
INT32 color; INT32 color;
INT32 emeralds; INT32 emeralds;
UINT8 team;
const char *name; const char *name;
} playersort_t; } playersort_t;
...@@ -87,10 +89,7 @@ extern patch_t *ntb_font[NT_FONTSIZE]; ...@@ -87,10 +89,7 @@ extern patch_t *ntb_font[NT_FONTSIZE];
extern patch_t *nto_font[NT_FONTSIZE]; extern patch_t *nto_font[NT_FONTSIZE];
extern patch_t *ttlnum[10]; extern patch_t *ttlnum[10];
extern patch_t *emeraldpics[3][8]; extern patch_t *emeraldpics[3][8];
extern patch_t *rflagico; extern patch_t *teamicons[MAXTEAMS][TEAM_ICON_MAX];
extern patch_t *bflagico;
extern patch_t *rmatcico;
extern patch_t *bmatcico;
extern patch_t *tagico; extern patch_t *tagico;
extern patch_t *tallminus; extern patch_t *tallminus;
extern patch_t *tallinfin; extern patch_t *tallinfin;
...@@ -120,6 +119,8 @@ void HU_DrawEmeralds(INT32 x, INT32 y, INT32 pemeralds); ...@@ -120,6 +119,8 @@ void HU_DrawEmeralds(INT32 x, INT32 y, INT32 pemeralds);
INT32 HU_CreateTeamScoresTbl(playersort_t *tab, UINT32 dmtotals[]); INT32 HU_CreateTeamScoresTbl(playersort_t *tab, UINT32 dmtotals[]);
const char *GetChatColorForSkincolor(UINT16 skincolor);
// CECHO interface. // CECHO interface.
void HU_ClearCEcho(void); void HU_ClearCEcho(void);
void HU_SetCEchoDuration(INT32 seconds); void HU_SetCEchoDuration(INT32 seconds);
......
...@@ -7123,7 +7123,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = ...@@ -7123,7 +7123,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
24*FRACUNIT, // radius 24*FRACUNIT, // radius
64*FRACUNIT, // height 64*FRACUNIT, // height
0, // display offset 0, // display offset
16, // mass TEAM_RED, // mass
0, // damage 0, // damage
sfx_None, // activesound sfx_None, // activesound
MF_SPECIAL, // flags MF_SPECIAL, // flags
...@@ -7150,7 +7150,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = ...@@ -7150,7 +7150,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
24*FRACUNIT, // radius 24*FRACUNIT, // radius
64*FRACUNIT, // height 64*FRACUNIT, // height
0, // display offset 0, // display offset
16, // mass TEAM_BLUE, // mass
0, // damage 0, // damage
sfx_None, // activesound sfx_None, // activesound
MF_SPECIAL, // flags MF_SPECIAL, // flags
......
...@@ -155,6 +155,9 @@ static const struct { ...@@ -155,6 +155,9 @@ static const struct {
{META_SFXINFO, "sfxinfo_t"}, {META_SFXINFO, "sfxinfo_t"},
{META_SKINCOLOR, "skincolor_t"}, {META_SKINCOLOR, "skincolor_t"},
{META_COLORRAMP, "skincolor_t.ramp"}, {META_COLORRAMP, "skincolor_t.ramp"},
{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"},
...@@ -843,13 +846,32 @@ static int lib_pGetMobjGravity(lua_State *L) ...@@ -843,13 +846,32 @@ static int lib_pGetMobjGravity(lua_State *L)
static int lib_pWeaponOrPanel(lua_State *L) static int lib_pWeaponOrPanel(lua_State *L)
{ {
mobjtype_t type = luaL_checkinteger(L, 1); mobjtype_t type = luaL_checkinteger(L, 1);
//HUDSAFE
if (type >= NUMMOBJTYPES) if (type >= NUMMOBJTYPES)
return luaL_error(L, "mobj type %d out of range (0 - %d)", type, NUMMOBJTYPES-1); return luaL_error(L, "mobj type %d out of range (0 - %d)", type, NUMMOBJTYPES-1);
lua_pushboolean(L, P_WeaponOrPanel(type)); lua_pushboolean(L, P_WeaponOrPanel(type));
return 1; return 1;
} }
static int lib_pGetTeamFlag(lua_State *L)
{
int team = luaL_checkinteger(L, 1);
if (team <= 0 || team >= numteams)
return luaL_error(L, "team index %d out of range (1 - %d)", team, numteams - 1);
INLEVEL
LUA_PushUserdata(L, P_GetTeamFlag(team), META_MOBJ);
return 1;
}
static int lib_pGetTeamFlagMapthing(lua_State *L)
{
int team = luaL_checkinteger(L, 1);
if (team <= 0 || team >= numteams)
return luaL_error(L, "team index %d out of range (1 - %d)", team, numteams - 1);
INLEVEL
LUA_PushUserdata(L, P_GetTeamFlagMapthing(team), META_MAPTHING);
return 1;
}
static int lib_pFlashPal(lua_State *L) static int lib_pFlashPal(lua_State *L)
{ {
player_t *pl = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); player_t *pl = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
...@@ -1857,6 +1879,19 @@ static int lib_pPlayerShouldUseSpinHeight(lua_State *L) ...@@ -1857,6 +1879,19 @@ static int lib_pPlayerShouldUseSpinHeight(lua_State *L)
return 1; return 1;
} }
static int lib_pPlayerHasTeamFlag(lua_State *L)
{
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
INT32 team = (INT32)luaL_checkinteger(L, 2);
INLEVEL
if (!player)
return LUA_ErrInvalid(L, "player_t");
if (team <= 0 || team >= numteams)
luaL_error(L, "team index %d out of range (1 - %d)", team, numteams-1);
lua_pushboolean(L, P_PlayerHasTeamFlag(player, team));
return 1;
}
// P_MAP // P_MAP
/////////// ///////////
...@@ -2571,6 +2606,19 @@ static int lib_pPlayerTouchingSectorSpecialFlag(lua_State *L) ...@@ -2571,6 +2606,19 @@ static int lib_pPlayerTouchingSectorSpecialFlag(lua_State *L)
return 1; return 1;
} }
static int lib_pMobjTouchingTeamBase(lua_State *L)
{
mobj_t *mo = *((mobj_t**)luaL_checkudata(L, 1, META_MOBJ));
INT32 team = (INT32)luaL_checkinteger(L, 2);
INLEVEL
if (!mo)
return LUA_ErrInvalid(L, "mobj_t");
if (team <= 0 || team >= numteams)
luaL_error(L, "team index %d out of range (1 - %d)", team, numteams-1);
LUA_PushUserdata(L, P_MobjTouchingTeamBase(mo, team), META_SECTOR);
return 1;
}
static int lib_pFindLowestFloorSurrounding(lua_State *L) static int lib_pFindLowestFloorSurrounding(lua_State *L)
{ {
sector_t *sector = *((sector_t **)luaL_checkudata(L, 1, META_SECTOR)); sector_t *sector = *((sector_t **)luaL_checkudata(L, 1, META_SECTOR));
...@@ -2712,11 +2760,29 @@ static int lib_pFadeLight(lua_State *L) ...@@ -2712,11 +2760,29 @@ static int lib_pFadeLight(lua_State *L)
static int lib_pIsFlagAtBase(lua_State *L) static int lib_pIsFlagAtBase(lua_State *L)
{ {
mobjtype_t flag = luaL_checkinteger(L, 1); mobjtype_t flag = luaL_checkinteger(L, 1);
//HUDSAFE
INLEVEL INLEVEL
if (flag >= NUMMOBJTYPES) if (flag >= NUMMOBJTYPES)
return luaL_error(L, "mobj type %d out of range (0 - %d)", flag, NUMMOBJTYPES-1); return luaL_error(L, "mobj type %d out of range (0 - %d)", flag, NUMMOBJTYPES-1);
lua_pushboolean(L, P_IsFlagAtBase(flag)); for (UINT8 i = 1; i < teamsingame; i++)
{
UINT8 team = G_GetTeam(i);
if (teams[team].flag_mobj_type == flag)
{
lua_pushboolean(L, P_TeamHasFlagAtBase(team));
return 1;
}
}
lua_pushboolean(L, false);
return 1;
}
static int lib_pTeamHasFlagAtBase(lua_State *L)
{
INT32 team = luaL_checkinteger(L, 1);
INLEVEL
if (team <= 0 || team >= numteams)
luaL_error(L, "team index %d out of range (1 - %d)", team, numteams-1);
lua_pushboolean(L, P_TeamHasFlagAtBase(team));
return 1; return 1;
} }
...@@ -3657,24 +3723,24 @@ static int lib_sResumeMusic(lua_State *L) ...@@ -3657,24 +3723,24 @@ 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;
lua_Integer i; lua_Integer i;
const char *gtname = NULL; char *gtname = NULL;
const char *gtconst = NULL; char *gtconst = NULL;
const char *gtdescription = NULL; char *gtdescription = NULL;
INT16 newgtidx = 0;
UINT32 newgtrules = 0; UINT32 newgtrules = 0;
UINT32 newgttol = 0; UINT32 newgttol = 0;
INT32 newgtpointlimit = 0; INT32 newgtpointlimit = 0;
INT32 newgttimelimit = 0; INT32 newgttimelimit = 0;
UINT8 newgtleftcolor = 0; UINT8 newgtleftcolor = 54;
UINT8 newgtrightcolor = 0; UINT8 newgtrightcolor = 54;
INT16 newgtrankingstype = -1; 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.
...@@ -3700,7 +3766,6 @@ static int lib_gAddGametype(lua_State *L) ...@@ -3700,7 +3766,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)
...@@ -3745,6 +3810,36 @@ static int lib_gAddGametype(lua_State *L) ...@@ -3745,6 +3810,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 (1 - %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))
...@@ -3763,36 +3858,52 @@ static int lib_gAddGametype(lua_State *L) ...@@ -3763,36 +3858,52 @@ static int lib_gAddGametype(lua_State *L)
// Set defaults // Set defaults
if (gtname == NULL) if (gtname == NULL)
gtname = Z_StrDup("Unnamed gametype"); 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 // Add the new gametype
newgtidx = G_AddGametype(newgtrules); INT16 gtype = G_AddGametype();
G_AddGametypeTOL(newgtidx, newgttol);
G_SetGametypeDescription(newgtidx, NULL, newgtleftcolor, newgtrightcolor); gametype_t *gt = &gametypes[gtype];
strncpy(gametypedesc[newgtidx].notes, gtdescription, 441);
gt->name = gtname;
// Not covered by G_AddGametype alone.
if (newgtrankingstype == -1) // Copy the teams
newgtrankingstype = newgtidx; gt->teams.num = teamcount;
gametyperankings[newgtidx] = newgtrankingstype; if (teamcount)
intermissiontypes[newgtidx] = newgtinttype; memcpy(gt->teams.list, teamlist, sizeof(teamlist[0]) * teamcount);
pointlimits[newgtidx] = newgtpointlimit;
timelimits[newgtidx] = newgttimelimit; if (gtconst)
G_AddGametypeConstant(gtype, gtconst);
// Write the new gametype name. else
Gametype_Names[newgtidx] = gtname; G_AddGametypeConstant(gtype, gtname);
// Write the constant name. if (gtdescription)
if (gtconst == NULL) G_SetGametypeDescription(gtype, gtdescription);
gtconst = gtname; G_SetGametypeDescriptionLeftColor(gtype, newgtleftcolor);
G_AddGametypeConstant(newgtidx, gtconst); G_SetGametypeDescriptionRightColor(gtype, newgtrightcolor);
// Update gametype_cons_t accordingly. gt->rules = newgtrules;
gt->typeoflevel = newgttol;
gt->rankings_type = newgtrankingstype;
gt->intermission_type = newgtinttype;
gt->pointlimit = newgtpointlimit;
gt->timelimit = newgttimelimit;
G_UpdateGametypeSelections(); G_UpdateGametypeSelections();
// done CONS_Printf("Added gametype %s\n", gt->name);
CONS_Printf("Added gametype %s\n", Gametype_Names[newgtidx]);
Z_Free(gtconst);
Z_Free(gtdescription);
return 0; return 0;
} }
...@@ -4217,6 +4328,30 @@ static int lib_gCompetitionGametype(lua_State *L) ...@@ -4217,6 +4328,30 @@ static int lib_gCompetitionGametype(lua_State *L)
return 1; return 1;
} }
static int lib_gGetBestPerformingTeam(lua_State *L)
{
lua_pushinteger(L, G_GetBestPerformingTeam());
return 1;
}
static int lib_gGetWorstPerformingTeam(lua_State *L)
{
lua_pushinteger(L, G_GetWorstPerformingTeam());
return 1;
}
static int lib_gGetMostAdvantagedTeam(lua_State *L)
{
lua_pushinteger(L, G_GetMostAdvantagedTeam());
return 1;
}
static int lib_gGetMostDisadvantagedTeam(lua_State *L)
{
lua_pushinteger(L, G_GetMostDisadvantagedTeam());
return 1;
}
static int lib_gTicsToHours(lua_State *L) static int lib_gTicsToHours(lua_State *L)
{ {
tic_t rtic = luaL_checkinteger(L, 1); tic_t rtic = luaL_checkinteger(L, 1);
...@@ -4322,6 +4457,8 @@ static luaL_Reg lib[] = { ...@@ -4322,6 +4457,8 @@ static luaL_Reg lib[] = {
{"P_MobjFlip",lib_pMobjFlip}, {"P_MobjFlip",lib_pMobjFlip},
{"P_GetMobjGravity",lib_pGetMobjGravity}, {"P_GetMobjGravity",lib_pGetMobjGravity},
{"P_WeaponOrPanel",lib_pWeaponOrPanel}, {"P_WeaponOrPanel",lib_pWeaponOrPanel},
{"P_GetTeamFlag",lib_pGetTeamFlag},
{"P_GetTeamFlagMapthing",lib_pGetTeamFlagMapthing},
{"P_FlashPal",lib_pFlashPal}, {"P_FlashPal",lib_pFlashPal},
{"P_GetClosestAxis",lib_pGetClosestAxis}, {"P_GetClosestAxis",lib_pGetClosestAxis},
{"P_SpawnParaloop",lib_pSpawnParaloop}, {"P_SpawnParaloop",lib_pSpawnParaloop},
...@@ -4403,6 +4540,7 @@ static luaL_Reg lib[] = { ...@@ -4403,6 +4540,7 @@ static luaL_Reg lib[] = {
{"P_DoFollowMobj",lib_pDoFollowMobj}, {"P_DoFollowMobj",lib_pDoFollowMobj},
{"P_PlayerCanEnterSpinGaps",lib_pPlayerCanEnterSpinGaps}, {"P_PlayerCanEnterSpinGaps",lib_pPlayerCanEnterSpinGaps},
{"P_PlayerShouldUseSpinHeight",lib_pPlayerShouldUseSpinHeight}, {"P_PlayerShouldUseSpinHeight",lib_pPlayerShouldUseSpinHeight},
{"P_PlayerHasTeamFlag",lib_pPlayerHasTeamFlag},
// p_map // p_map
{"P_CheckPosition",lib_pCheckPosition}, {"P_CheckPosition",lib_pCheckPosition},
...@@ -4456,6 +4594,7 @@ static luaL_Reg lib[] = { ...@@ -4456,6 +4594,7 @@ static luaL_Reg lib[] = {
{"P_MobjTouchingSectorSpecialFlag",lib_pMobjTouchingSectorSpecialFlag}, {"P_MobjTouchingSectorSpecialFlag",lib_pMobjTouchingSectorSpecialFlag},
{"P_PlayerTouchingSectorSpecial",lib_pPlayerTouchingSectorSpecial}, {"P_PlayerTouchingSectorSpecial",lib_pPlayerTouchingSectorSpecial},
{"P_PlayerTouchingSectorSpecialFlag",lib_pPlayerTouchingSectorSpecialFlag}, {"P_PlayerTouchingSectorSpecialFlag",lib_pPlayerTouchingSectorSpecialFlag},
{"P_MobjTouchingTeamBase",lib_pMobjTouchingTeamBase},
{"P_FindLowestFloorSurrounding",lib_pFindLowestFloorSurrounding}, {"P_FindLowestFloorSurrounding",lib_pFindLowestFloorSurrounding},
{"P_FindHighestFloorSurrounding",lib_pFindHighestFloorSurrounding}, {"P_FindHighestFloorSurrounding",lib_pFindHighestFloorSurrounding},
{"P_FindNextHighestFloor",lib_pFindNextHighestFloor}, {"P_FindNextHighestFloor",lib_pFindNextHighestFloor},
...@@ -4468,6 +4607,7 @@ static luaL_Reg lib[] = { ...@@ -4468,6 +4607,7 @@ static luaL_Reg lib[] = {
{"P_SpawnLightningFlash",lib_pSpawnLightningFlash}, {"P_SpawnLightningFlash",lib_pSpawnLightningFlash},
{"P_FadeLight",lib_pFadeLight}, {"P_FadeLight",lib_pFadeLight},
{"P_IsFlagAtBase",lib_pIsFlagAtBase}, {"P_IsFlagAtBase",lib_pIsFlagAtBase},
{"P_TeamHasFlagAtBase",lib_pTeamHasFlagAtBase},
{"P_SetupLevelSky",lib_pSetupLevelSky}, {"P_SetupLevelSky",lib_pSetupLevelSky},
{"P_SetSkyboxMobj",lib_pSetSkyboxMobj}, {"P_SetSkyboxMobj",lib_pSetSkyboxMobj},
{"P_StartQuake",lib_pStartQuake}, {"P_StartQuake",lib_pStartQuake},
...@@ -4556,6 +4696,10 @@ static luaL_Reg lib[] = { ...@@ -4556,6 +4696,10 @@ static luaL_Reg lib[] = {
{"G_CoopGametype",lib_gCoopGametype}, {"G_CoopGametype",lib_gCoopGametype},
{"G_TagGametype",lib_gTagGametype}, {"G_TagGametype",lib_gTagGametype},
{"G_CompetitionGametype",lib_gCompetitionGametype}, {"G_CompetitionGametype",lib_gCompetitionGametype},
{"G_GetBestPerformingTeam",lib_gGetBestPerformingTeam},
{"G_GetWorstPerformingTeam",lib_gGetWorstPerformingTeam},
{"G_GetMostAdvantagedTeam",lib_gGetMostAdvantagedTeam},
{"G_GetMostDisadvantagedTeam",lib_gGetMostDisadvantagedTeam},
{"G_TicsToHours",lib_gTicsToHours}, {"G_TicsToHours",lib_gTicsToHours},
{"G_TicsToMinutes",lib_gTicsToMinutes}, {"G_TicsToMinutes",lib_gTicsToMinutes},
{"G_TicsToSeconds",lib_gTicsToSeconds}, {"G_TicsToSeconds",lib_gTicsToSeconds},
......
...@@ -1900,6 +1900,562 @@ static int colorramp_len(lua_State *L) ...@@ -1900,6 +1900,562 @@ static int colorramp_len(lua_State *L)
return 1; return 1;
} }
///////////////
// GAMETYPES //
///////////////
static int lib_getGametypes(lua_State *L)
{
INT16 i;
lua_remove(L, 1);
i = luaL_checkinteger(L, 1);
if (i < 0 || i >= gametypecount)
return luaL_error(L, "gametypes[] index %d out of range (0 - %d)", i, gametypecount-1);
LUA_PushUserdata(L, &gametypes[i], META_GAMETYPE);
return 1;
}
// #gametypes -> gametypecount
static int lib_gametypeslen(lua_State *L)
{
lua_pushinteger(L, gametypecount);
return 1;
}
enum gametype_e
{
gametype_name,
gametype_rules,
gametype_typeoflevel,
gametype_intermission_type,
gametype_rankings_type,
gametype_pointlimit,
gametype_timelimit,
gametype_teams
};
const char *const gametype_opt[] = {
"name",
"rules",
"type_of_level",
"intermission_type",
"rankings_type",
"point_limit",
"time_limit",
"teams",
NULL,
};
static int gametype_fields_ref = LUA_NOREF;
static int gametype_get(lua_State *L)
{
gametype_t *gt = *((gametype_t **)luaL_checkudata(L, 1, META_GAMETYPE));
enum gametype_e field = Lua_optoption(L, 2, gametype_name, gametype_fields_ref);
I_Assert(gt != NULL);
I_Assert(gt >= gametypes);
switch (field)
{
case gametype_name:
lua_pushstring(L, gt->name);
break;
case gametype_rules:
lua_pushinteger(L, gt->rules);
break;
case gametype_typeoflevel:
lua_pushinteger(L, gt->typeoflevel);
break;
case gametype_intermission_type:
lua_pushinteger(L, gt->intermission_type);
break;
case gametype_rankings_type:
lua_pushinteger(L, gt->rankings_type);
break;
case gametype_pointlimit:
lua_pushinteger(L, gt->pointlimit);
break;
case gametype_timelimit:
lua_pushinteger(L, gt->timelimit);
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;
}
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)
return luaL_error(L, "Do not alter gametype data in CMD building code!");
I_Assert(gt != NULL);
I_Assert(gt >= gametypes);
INT16 gametype_id = gt - gametypes;
switch (field)
{
case gametype_name:
Z_Free(gt->name);
gt->name = Z_StrDup(luaL_checkstring(L, 3));
G_UpdateGametypeSelections();
break;
case gametype_rules:
gt->rules = luaL_checkinteger(L, 3);
break;
case gametype_typeoflevel:
gt->typeoflevel = luaL_checkinteger(L, 3);
break;
case gametype_intermission_type:
gt->intermission_type = luaL_checkinteger(L, 3);
break;
case gametype_rankings_type:
gt->rankings_type = luaL_checkinteger(L, 3);
break;
case gametype_pointlimit:
gt->pointlimit = luaL_checkinteger(L, 3);
break;
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 (1 - %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;
}
static int gametype_num(lua_State *L)
{
gametype_t *gt = *((gametype_t **)luaL_checkudata(L, 1, META_GAMETYPE));
I_Assert(gt != NULL);
I_Assert(gt >= gametypes);
lua_pushinteger(L, gt-gametypes);
return 1;
}
///////////
// TEAMS //
///////////
enum team_e
{
team_name,
team_flag_name,
team_flag,
team_flag_mobj_type,
team_weapon_mobj_type,
team_missile_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",
"weapon_mobj_type",
"missile_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_weapon_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->weapon_mobj_type = type;
break;
}
case team_missile_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->missile_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_InitTeam(teamnum);
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_weapon_mobj_type:
lua_pushinteger(L, team->weapon_mobj_type);
break;
case team_missile_mobj_type:
lua_pushinteger(L, team->missile_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_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, "array 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);
int team = luaL_checkinteger(L, 3);
if (i <= 0 || i > teamlist->num)
return luaL_error(L, "array index %d out of range (1 - %d)", i, teamlist->num);
if (team <= 0 || team >= numteams)
return luaL_error(L, "team index %d out of range (1 - %d)", team, numteams - 1);
teamlist->list[i - 1] = (UINT8)team;
return 0;
}
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 teamscores_get(lua_State *L)
{
UINT32 *scoreslist = *((UINT32 **)luaL_checkudata(L, 1, META_TEAMSCORES));
int team = luaL_checkinteger(L, 2);
if (team <= 0 || team >= numteams)
return luaL_error(L, "team index %d out of range (1 - %d)", team, max(0, (int)numteams - 1));
lua_pushinteger(L, scoreslist[team]);
return 1;
}
static int teamscores_set(lua_State *L)
{
UINT32 *scoreslist = *((UINT32 **)luaL_checkudata(L, 1, META_TEAMSCORES));
int team = luaL_checkinteger(L, 2);
UINT32 score = (UINT32)luaL_checkinteger(L, 3);
if (team <= 0 || team >= numteams)
return luaL_error(L, "array index %d out of range (1 - %d)", team, max(0, (int)numteams - 1));
scoreslist[team] = score;
return 0;
}
static int teamscores_len(lua_State *L)
{
lua_pushinteger(L, max(0, numteams - 1));
return 1;
}
////////////////////////////// //////////////////////////////
// //
// Now push all these functions into the Lua state! // Now push all these functions into the Lua state!
...@@ -1917,6 +2473,10 @@ int LUA_InfoLib(lua_State *L) ...@@ -1917,6 +2473,10 @@ 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_TEAM, team_get, team_set, team_num);
LUA_RegisterUserdataMetatable(L, META_TEAMLIST, teamlist_get, teamlist_set, teamlist_len);
LUA_RegisterUserdataMetatable(L, META_TEAMSCORES, teamscores_get, teamscores_set, teamscores_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);
...@@ -1926,12 +2486,15 @@ int LUA_InfoLib(lua_State *L) ...@@ -1926,12 +2486,15 @@ 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);
LUA_RegisterGlobalUserdata(L, "spr2defaults", lib_getSpr2default, lib_setSpr2default, lib_spr2namelen); LUA_RegisterGlobalUserdata(L, "spr2defaults", lib_getSpr2default, lib_setSpr2default, lib_spr2namelen);
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, "teams", lib_getTeams, lib_setTeams, lib_teamslen);
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);
......
...@@ -29,6 +29,10 @@ extern boolean ignoregameinputs; ...@@ -29,6 +29,10 @@ extern boolean ignoregameinputs;
#define META_SKINCOLOR "SKINCOLOR_T*" #define META_SKINCOLOR "SKINCOLOR_T*"
#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_TEAM "TEAM_T*"
#define META_TEAMLIST "TEAMLIST_T*"
#define META_TEAMSCORES "TEAMSCORES"
#define META_PIVOTLIST "SPRITEFRAMEPIVOT_T[]" #define META_PIVOTLIST "SPRITEFRAMEPIVOT_T[]"
#define META_FRAMEPIVOT "SPRITEFRAMEPIVOT_T*" #define META_FRAMEPIVOT "SPRITEFRAMEPIVOT_T*"
......
...@@ -65,6 +65,7 @@ enum sector_e { ...@@ -65,6 +65,7 @@ enum sector_e {
sector_flags, sector_flags,
sector_specialflags, sector_specialflags,
sector_damagetype, sector_damagetype,
sector_teambase,
sector_triggertag, sector_triggertag,
sector_triggerer, sector_triggerer,
sector_friction, sector_friction,
...@@ -108,6 +109,7 @@ static const char *const sector_opt[] = { ...@@ -108,6 +109,7 @@ static const char *const sector_opt[] = {
"flags", "flags",
"specialflags", "specialflags",
"damagetype", "damagetype",
"teambase",
"triggertag", "triggertag",
"triggerer", "triggerer",
"friction", "friction",
...@@ -807,6 +809,9 @@ static int sector_get(lua_State *L) ...@@ -807,6 +809,9 @@ static int sector_get(lua_State *L)
case sector_damagetype: // damagetype case sector_damagetype: // damagetype
lua_pushinteger(L, (UINT8)sector->damagetype); lua_pushinteger(L, (UINT8)sector->damagetype);
return 1; return 1;
case sector_teambase: // teambase
lua_pushinteger(L, (UINT8)sector->teambase);
return 1;
case sector_triggertag: // triggertag case sector_triggertag: // triggertag
lua_pushinteger(L, (INT16)sector->triggertag); lua_pushinteger(L, (INT16)sector->triggertag);
return 1; return 1;
...@@ -953,6 +958,9 @@ static int sector_set(lua_State *L) ...@@ -953,6 +958,9 @@ static int sector_set(lua_State *L)
case sector_damagetype: case sector_damagetype:
sector->damagetype = (UINT8)luaL_checkinteger(L, 3); sector->damagetype = (UINT8)luaL_checkinteger(L, 3);
break; break;
case sector_teambase:
sector->teambase = (UINT8)luaL_checkinteger(L, 3);
break;
case sector_triggertag: case sector_triggertag:
sector->triggertag = (INT16)luaL_checkinteger(L, 3); sector->triggertag = (INT16)luaL_checkinteger(L, 3);
break; break;
......
...@@ -1104,7 +1104,7 @@ static int player_set(lua_State *L) ...@@ -1104,7 +1104,7 @@ static int player_set(lua_State *L)
plr->laps = (UINT8)luaL_checkinteger(L, 3); plr->laps = (UINT8)luaL_checkinteger(L, 3);
break; break;
case player_ctfteam: case player_ctfteam:
plr->ctfteam = (INT32)luaL_checkinteger(L, 3); plr->ctfteam = (INT32)luaL_checkinteger(L, 3) % MAXTEAMS;
break; break;
case player_gotflag: case player_gotflag:
plr->gotflag = (UINT16)luaL_checkinteger(L, 3); plr->gotflag = (UINT16)luaL_checkinteger(L, 3);
......
...@@ -217,10 +217,13 @@ int LUA_PushGlobals(lua_State *L, const char *word) ...@@ -217,10 +217,13 @@ 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, bluescore); lua_pushinteger(L, teamscores[G_GetTeam(2)]);
return 1; return 1;
} else if (fastcmp(word,"redscore")) { } else if (fastcmp(word,"redscore")) {
lua_pushinteger(L, redscore); lua_pushinteger(L, teamscores[G_GetTeam(1)]);
return 1;
} else if (fastcmp(word,"teamscores")) {
LUA_PushUserdata(L, teamscores, META_TEAMSCORES);
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);
...@@ -229,16 +232,16 @@ int LUA_PushGlobals(lua_State *L, const char *word) ...@@ -229,16 +232,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, redflag, 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, blueflag, 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, rflagpoint, 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, bflagpoint, 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")) {
...@@ -274,19 +277,25 @@ int LUA_PushGlobals(lua_State *L, const char *word) ...@@ -274,19 +277,25 @@ 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")) {
lua_pushinteger(L, skincolor_redteam); lua_pushinteger(L, G_GetTeamColor(TEAM_RED));
return 1; return 1;
} else if (fastcmp(word,"skincolor_blueteam")) { } else if (fastcmp(word,"skincolor_blueteam")) {
lua_pushinteger(L, skincolor_blueteam); lua_pushinteger(L, G_GetTeamColor(TEAM_BLUE));
return 1; return 1;
} else if (fastcmp(word,"skincolor_redring")) { } else if (fastcmp(word,"skincolor_redring")) {
lua_pushinteger(L, skincolor_redring); lua_pushinteger(L, G_GetTeamMissileColor(TEAM_RED));
return 1; return 1;
} else if (fastcmp(word,"skincolor_bluering")) { } else if (fastcmp(word,"skincolor_bluering")) {
lua_pushinteger(L, skincolor_bluering); lua_pushinteger(L, G_GetTeamMissileColor(TEAM_BLUE));
return 1; return 1;
// end CTF colors // end CTF colors
// begin timers // begin timers
...@@ -445,17 +454,17 @@ int LUA_PushGlobals(lua_State *L, const char *word) ...@@ -445,17 +454,17 @@ int LUA_PushGlobals(lua_State *L, const char *word)
int LUA_CheckGlobals(lua_State *L, const char *word) int LUA_CheckGlobals(lua_State *L, const char *word)
{ {
if (fastcmp(word, "redscore")) if (fastcmp(word, "redscore"))
redscore = (UINT32)luaL_checkinteger(L, 2); teamscores[TEAM_RED] = (UINT32)luaL_checkinteger(L, 2);
else if (fastcmp(word, "bluescore")) else if (fastcmp(word, "bluescore"))
bluescore = (UINT32)luaL_checkinteger(L, 2); teamscores[TEAM_BLUE] = (UINT32)luaL_checkinteger(L, 2);
else if (fastcmp(word, "skincolor_redteam")) else if (fastcmp(word, "skincolor_redteam"))
skincolor_redteam = (UINT16)luaL_checkinteger(L, 2); teams[TEAM_RED].color = (UINT16)luaL_checkinteger(L, 2);
else if (fastcmp(word, "skincolor_blueteam")) else if (fastcmp(word, "skincolor_blueteam"))
skincolor_blueteam = (UINT16)luaL_checkinteger(L, 2); teams[TEAM_BLUE].color = (UINT16)luaL_checkinteger(L, 2);
else if (fastcmp(word, "skincolor_redring")) else if (fastcmp(word, "skincolor_redring"))
skincolor_redring = (UINT16)luaL_checkinteger(L, 2); teams[TEAM_RED].missile_color = (UINT16)luaL_checkinteger(L, 2);
else if (fastcmp(word, "skincolor_bluering")) else if (fastcmp(word, "skincolor_bluering"))
skincolor_bluering = (UINT16)luaL_checkinteger(L, 2); teams[TEAM_BLUE].missile_color = (UINT16)luaL_checkinteger(L, 2);
else if (fastcmp(word, "emeralds")) else if (fastcmp(word, "emeralds"))
emeralds = (UINT16)luaL_checkinteger(L, 2); emeralds = (UINT16)luaL_checkinteger(L, 2);
else if (fastcmp(word, "token")) else if (fastcmp(word, "token"))
...@@ -1049,6 +1058,9 @@ enum ...@@ -1049,6 +1058,9 @@ enum
ARCH_SKINCOLOR, ARCH_SKINCOLOR,
ARCH_MOUSE, ARCH_MOUSE,
ARCH_SKIN, ARCH_SKIN,
ARCH_GAMETYPE,
ARCH_TEAM,
ARCH_TEAMSCORES,
ARCH_TEND=0xFF, ARCH_TEND=0xFF,
}; };
...@@ -1078,6 +1090,9 @@ static const struct { ...@@ -1078,6 +1090,9 @@ static const struct {
{META_SKINCOLOR, ARCH_SKINCOLOR}, {META_SKINCOLOR, ARCH_SKINCOLOR},
{META_MOUSE, ARCH_MOUSE}, {META_MOUSE, ARCH_MOUSE},
{META_SKIN, ARCH_SKIN}, {META_SKIN, ARCH_SKIN},
{META_GAMETYPE, ARCH_GAMETYPE},
{META_TEAM, ARCH_TEAM},
{META_TEAMSCORES, ARCH_TEAMSCORES},
{NULL, ARCH_NULL} {NULL, ARCH_NULL}
}; };
...@@ -1406,6 +1421,25 @@ static UINT8 ArchiveValue(int TABLESINDEX, int myindex) ...@@ -1406,6 +1421,25 @@ static UINT8 ArchiveValue(int TABLESINDEX, int myindex)
WRITEUINT8(save_p, skin->skinnum); // UINT8 because MAXSKINS must be <= 256 WRITEUINT8(save_p, skin->skinnum); // UINT8 because MAXSKINS must be <= 256
break; break;
} }
case ARCH_GAMETYPE:
{
gametype_t *gt = *((gametype_t **)lua_touserdata(gL, myindex));
WRITEUINT8(save_p, ARCH_GAMETYPE);
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;
}
case ARCH_TEAMSCORES:
{
WRITEUINT8(save_p, ARCH_TEAMSCORES);
break;
}
default: default:
WRITEUINT8(save_p, ARCH_NULL); WRITEUINT8(save_p, ARCH_NULL);
return 2; return 2;
...@@ -1658,6 +1692,15 @@ static UINT8 UnArchiveValue(int TABLESINDEX) ...@@ -1658,6 +1692,15 @@ static UINT8 UnArchiveValue(int TABLESINDEX)
case ARCH_SKIN: case ARCH_SKIN:
LUA_PushUserdata(gL, skins[READUINT8(save_p)], META_SKIN); LUA_PushUserdata(gL, skins[READUINT8(save_p)], META_SKIN);
break; break;
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_TEAMSCORES:
LUA_PushUserdata(gL, teamscores, META_TEAMSCORES);
break;
case ARCH_TEND: case ARCH_TEND:
return 1; return 1;
} }
......
...@@ -773,15 +773,15 @@ void Command_CauseCfail_f(void) ...@@ -773,15 +773,15 @@ void Command_CauseCfail_f(void)
// CTF consistency test // CTF consistency test
if (gametyperules & GTR_TEAMFLAGS) if (gametyperules & GTR_TEAMFLAGS)
{ {
if (blueflag) { if (flagmobjs[TEAM_BLUE]) {
P_RemoveMobj(blueflag); P_RemoveMobj(flagmobjs[TEAM_BLUE]);
blueflag = NULL; flagmobjs[TEAM_BLUE] = NULL;
} }
if (redflag) if (flagmobjs[TEAM_RED])
{ {
redflag->x = 423423; flagmobjs[TEAM_RED]->x = 423423;
redflag->y = 666; flagmobjs[TEAM_RED]->y = 666;
redflag->z = 123311; flagmobjs[TEAM_RED]->z = 123311;
} }
} }
} }
......