- migrated fully away from EDuke's script compiler

# Conflicts:
#	source/games/duke/src/zz_gamedef.cpp
This commit is contained in:
Christoph Oelckers 2020-05-13 16:16:27 +02:00
parent 6d066d4b7b
commit e625f94e84
6 changed files with 96 additions and 532 deletions

View file

@ -40,6 +40,7 @@ into many sub-files.
#include "mapinfo.h"
#include "menu.h"
#include "global.h"
#include "m_argv.h"
BEGIN_DUKE_NS
@ -384,12 +385,6 @@ int scriptpos()
return script.Size();
}
// store addresses as offsets
static void setscriptaddress(int offset, int* address)
{
setscriptvalue(offset, int(address - script.Data()));
}
static void appendscriptvalue(int value)
{
script.Push(value);
@ -414,24 +409,18 @@ void reservescriptspace(int space)
#else
// Helpers to write to the old script buffer while using the new interface. Allows to test the parser before implementing the rest.
// TRANSITIONAL Helpers to write to the old script buffer while using the new interface. Allows to test the parser before implementing the rest.
void scriptWriteValue(int32_t const value);
void scriptWriteAtOffset(int32_t const value, intptr_t addr);
void scriptWritePointer(intptr_t const value, intptr_t addr);
static void setscriptvalue(int offset, int value)
{
scriptWriteAtOffset(value, offset);
}
// store addresses as offsets
static void setscriptaddress(int offset, int* address)
{
scriptWritePointer((intptr_t)address, offset);
apScript[offset] = value;
}
static void appendscriptvalue(int value)
{
scriptWriteValue(value);
*scriptptr++ = value;
}
static int popscriptvalue()
@ -627,13 +616,7 @@ void checkforkeyword()
static TArray<char> parsebuffer; // global so that the storage is persistent across calls.
int C_ParseCommand(int);
void parsecommand() // TRANSITIONAL
{
C_ParseCommand(0);
}
int parsecommand(int tw) // for now just run an externally parsed command.
int parsecommand()
{
const char* fn = fileSystem.GetFileFullName(g_currentSourceFile);
int i, j, k;
@ -643,18 +626,15 @@ int parsecommand(int tw) // for now just run an externally parsed command.
int temp_current_file;
int lnum;
#if FOR_LATER // for now this should just parse a single instruction
if ((errorcount + warningcount) > 12 || (*textptr == '\0') || (*(textptr + 1) == '\0')) return 1;
tw = transword();
#endif
// Do not count warnings here and allow more errors before bailing out.
if ((errorcount) > 64 || (*textptr == '\0') || (*(textptr + 1) == '\0')) return 1;
int tw = transword();
switch (tw)
{
default:
case -1:
return 1; //End
return 0; //End
case concmd_state:
if (parsing_actor == 0 && parsing_state == 0)
@ -883,13 +863,9 @@ int parsecommand(int tw) // for now just run an externally parsed command.
auto origtptr = textptr;
textptr = (char*)data.Data();
#if 0
do
done = parsecommand();
while (done == 0);
#else // TRANSITIONAL
C_ParseCommand(1);
#endif
textptr = origtptr;
line_number = temp_line_number;
@ -1408,13 +1384,9 @@ int parsecommand(int tw) // for now just run an externally parsed command.
case concmd_leftbrace:
num_squigilly_brackets++;
#if 0
do
done = parsecommand();
while (done == 0);
#else // TRANSITIONAL
C_ParseCommand(1);
#endif
return 0;
case concmd_rightbrace:
num_squigilly_brackets--;
@ -1699,19 +1671,85 @@ int parsecommand(int tw) // for now just run an externally parsed command.
return 0;
}
// I think this should go away.
void initquotes()
{
for (int i = 0; i < 48; i++)
{
quoteMgr.FormatQuote(i + OBITQUOTEINDEX, "$TXT_OBITUARY%d", i + 1);
}
//---------------------------------------------------------------------------
//
// split in two to allow multiple CON files.
//
//---------------------------------------------------------------------------
for (int i = 0; i < 6; i++)
void compilecon(const char *filenam)
{
g_currentSourceFile = fileSystem.FindFile(filenam);
if (g_currentSourceFile < 0)
{
quoteMgr.FormatQuote(i + SUICIDEQUOTEINDEX, "$TXT_SELFOBIT%d", i + 1);
I_FatalError("%s: Missing con file(s).", filenam);
}
Printf("Compiling: '%s'.\n", filenam);
auto data = fileSystem.GetFileData(g_currentSourceFile, 1);
textptr = (char*)data.Data();
line_number = 1;
errorcount = warningcount = 0;
while (parsecommand() == 0);
if ((errorcount) > 64)
Printf(TEXTCOLOR_RED " * ERROR! Too many errors.");
else if (warningcount || errorcount)
Printf(TEXTCOLOR_ORANGE "Found %d warning(s), %d error(s).\n", warningcount, errorcount);
if (errorcount > 0) I_FatalError("Failed to compile %s", filenam);
}
//---------------------------------------------------------------------------
//
// why was this called loadefs?
//
//---------------------------------------------------------------------------
void loadcons(const char* filenam)
{
labelcnt = 0;
#if 0
ClearGameEvents();
ClearGameVars();
AddSystemVars();
InitGameVarPointers();
ResetSystemDefaults();
#endif
//memset(actorscrptr, 0, MAXSPRITES);
//memset(actortype, 0, MAXSPRITES);
auto before = I_nsTime();
scriptptr = apScript + 1;
compilecon(filenam); //Tokenize
if (userConfig.AddCons) for (FString& m : *userConfig.AddCons.get())
{
compilecon(filenam);
}
userConfig.AddCons.reset();
setscriptvalue(0, scriptpos());
if (errorcount)
{
I_FatalError("\nError in %s.", filenam);
}
else
{
auto after = I_nsTime();
Printf("Compilation time:%.2f ms, Code Size:%d bytes. %d labels. %d/%d Variables.\n", (after-before) / 1000000.,
((scriptptr - apScript) << 2) - 4,
labelcnt,
0,//iGameVarCount,
MAXGAMEVARS
);
}
}
END_DUKE_NS

View file

@ -53,22 +53,6 @@ enum
#define VM_INSTMASK 0xfff
#define VM_DECODE_LINE_NUMBER(xxx) ((int)((xxx) >> 12))
#define C_CUSTOMERROR(Text, ...) \
do \
{ \
C_ReportError(-1); \
Printf("%s:%d: error: " Text "\n", g_scriptFileName, line_number, ##__VA_ARGS__); \
errorcount++; \
} while (0)
#define C_CUSTOMWARNING(Text, ...) \
do \
{ \
C_ReportError(-1); \
Printf("%s:%d: warning: " Text "\n", g_scriptFileName, line_number, ##__VA_ARGS__); \
warningcount++; \
} while (0)
extern intptr_t const * insptr;
extern void VM_ScriptInfo(intptr_t const *ptr, int range);
@ -96,27 +80,10 @@ extern int32_t line_number;
extern int32_t g_scriptVersion;
extern int32_t g_totalLines;
extern int warningcount;
extern uint32_t g_scriptcrc;
extern int32_t otherp;
extern intptr_t *scriptptr;
typedef struct
{
const char *name;
int lId, flags, maxParm2;
} memberlabel_t;
extern const memberlabel_t ActorLabels[];
extern const memberlabel_t InputLabels[];
extern const memberlabel_t PalDataLabels[];
extern const memberlabel_t PlayerLabels[];
extern const memberlabel_t ProjectileLabels[];
extern const memberlabel_t SectorLabels[];
extern const memberlabel_t TileDataLabels[];
extern const memberlabel_t TsprLabels[];
extern const memberlabel_t UserdefsLabels[];
extern const memberlabel_t WallLabels[];
int32_t C_AllocQuote(int32_t qnum);
void C_InitQuotes(void);
@ -145,10 +112,7 @@ void G_DoGameStartup(const int32_t *params);
void C_DefineMusic(int volumeNum, int levelNum, const char *fileName);
void C_DefineVolumeFlags(int32_t vol, int32_t flags);
void C_UndefineVolume(int32_t vol);
void C_UndefineSkill(int32_t skill);
void C_UndefineLevel(int32_t vol, int32_t lev);
void C_ReportError(int32_t iError);
void ReportError(int32_t iError);
void C_Compile(const char *filenam);
extern int32_t g_errorLineNum;

View file

@ -60,7 +60,6 @@ int32_t g_scriptVersion = 14; // 13 = 1.3D-style CON files, 14 = 1.4/1.5 style C
char g_scriptFileName[BMAX_PATH] = "(none)"; // file we're currently compiling
int32_t g_totalLines;
uint32_t g_scriptcrc;
char g_szBuf[1024];
static char g_szCurrentBlockName[256] = "(none)", g_szLastBlockName[256] = "NULL";
@ -77,10 +76,6 @@ extern int num_squigilly_brackets;
int32_t C_ParseCommand(int32_t loop);
static int32_t C_SetScriptSize(int32_t size);
static intptr_t apScriptGameEventEnd[MAXEVENTS];
extern intptr_t parsing_actor;
extern intptr_t parsing_event;
extern char *textptr;
char const * VM_GetKeywordForID(int32_t id)
@ -89,10 +84,6 @@ char const * VM_GetKeywordForID(int32_t id)
return "<invalid keyword>";
}
#define BITPTR_SET(x)
#define BITPTR_CLEAR(x)
#define BITPTR_IS_POINTER(x)
hashtable_t h_gamevars = { MAXGAMEVARS >> 1, NULL };
static hashtable_t * const tables[] = {
@ -106,285 +97,14 @@ void C_InitHashes()
hash_init(table);
}
// "magic" number for { and }, overrides line number in compiled code for later detection
#define IFELSE_MAGIC 31337
static int32_t g_skipBranch;
static int32_t C_SetScriptSize(int32_t newsize)
{
return 0;
}
extern bool ispecial(const char c);
static inline void C_SkipSpace(void)
{
while (*textptr == ' ' || *textptr == '\t')
textptr++;
}
static int32_t g_gotComment = 0;
static int32_t C_SkipComments(void)
{
g_gotComment = 0;
do
{
switch (*textptr)
{
case '\n':
line_number++;
fallthrough__;
case ' ':
case '\t':
case '\r':
case 0x1a:
textptr++;
break;
case '/':
switch (textptr[1])
{
case '/': // C++ style comment
if (!(errorcount || warningcount) && g_scriptDebug > 1)
Printf("%s:%d: debug: got comment.\n",g_scriptFileName,line_number);
skiptoendofline();
g_gotComment = 1;
continue;
case '*': // beginning of a C style comment
if (!(errorcount || warningcount) && g_scriptDebug > 1)
Printf("%s:%d: debug: got start of comment block.\n",g_scriptFileName,line_number);
do
{
if (*textptr == '\n')
line_number++;
textptr++;
}
while (*textptr && (textptr[0] != '*' || textptr[1] != '/'));
if (EDUKE32_PREDICT_FALSE(!*textptr))
{
if (!(errorcount || warningcount) && g_scriptDebug)
Printf("%s:%d: debug: EOF in comment!\n",g_scriptFileName,line_number);
C_ReportError(-1);
Printf("%s:%d: error: found `/*' with no `*/'.\n",g_scriptFileName,line_number);
parsing_actor = parsing_state = num_squigilly_brackets = 0;
errorcount++;
continue;
}
if (!(errorcount || warningcount) && g_scriptDebug > 1)
Printf("%s:%d: debug: got end of comment block.\n",g_scriptFileName,line_number);
textptr+=2;
g_gotComment = 1;
continue;
default:
C_ReportError(-1);
Printf("%s:%d: error: malformed comment.\n", g_scriptFileName, line_number);
skiptoendofline();
errorcount++;
continue;
}
break;
default:
if (ispecial(*textptr))
{
textptr++;
continue;
}
fallthrough__;
case 0: // EOF
return ((scriptptr-apScript) > (g_scriptSize-32)) ? C_SetScriptSize(g_scriptSize<<1) : 0;
}
}
while (1);
}
int GetDefID(char const *label) { return hash_find(&h_gamevars, label); }
#define LAST_LABEL (label+(labelcnt<<6))
bool isaltok(const char c);
void scriptWriteValue(int32_t const value)
{
BITPTR_CLEAR(scriptptr-apScript);
*scriptptr++ = value;
}
// addresses passed to these functions must be within the block of memory pointed to by apScript
void scriptWriteAtOffset(int32_t const value, intptr_t * const addr)
{
BITPTR_CLEAR(addr-apScript);
*(addr) = value;
}
void scriptWritePointer(intptr_t const value, intptr_t * const addr)
{
BITPTR_SET(addr-apScript);
*(addr) = value;
}
// addresses passed to these functions must be within the block of memory pointed to by apScript
void scriptWriteAtOffset(int32_t const value, intptr_t addr)
{
BITPTR_CLEAR(addr);
apScript[addr] = value;
}
void scriptWritePointer(intptr_t const value, intptr_t addr)
{
BITPTR_SET(addr);
apScript[addr] = value;
}
static int32_t C_GetNextKeyword(void) //Returns its code #
{
int32_t i, l;
C_SkipComments();
if (*textptr == 0) // EOF
return -1;
l = 0;
while (isaltok(*(textptr+l)))
{
tempbuf[l] = textptr[l];
l++;
}
tempbuf[l] = 0;
if ((i=getkeyword(tempbuf)) >= 0)
{
if (i == concmd_leftbrace || i == concmd_rightbrace || i == concmd_nullop)
scriptWriteValue(i | (VM_IFELSE_MAGIC<<12));
else scriptWriteValue(i | LINE_NUMBER);
textptr += l;
if (!(errorcount || warningcount) && g_scriptDebug)
Printf("%s:%d: debug: keyword `%s'.\n", g_scriptFileName, line_number, tempbuf);
return i;
}
textptr += l;
errorcount++;
if (EDUKE32_PREDICT_FALSE((tempbuf[0] == '{' || tempbuf[0] == '}') && tempbuf[1] != 0))
{
C_ReportError(-1);
Printf("%s:%d: error: expected whitespace between `%c' and `%s'.\n",g_scriptFileName,line_number,tempbuf[0],tempbuf+1);
}
else C_ReportError(ERROR_EXPECTEDKEYWORD);
return -1;
}
extern int g_currentSourceFile;
static void C_Include(const char *confile)
{
auto fp = fileSystem.OpenFileReader(confile);
if (!fp.isOpen())
{
errorcount++;
Printf("%s:%d: error: could not find file `%s'.\n",g_scriptFileName,line_number,confile);
return;
}
g_currentSourceFile = fileSystem.FindFile(confile);
int32_t j = fp.GetLength();
char *mptr = (char *)Xmalloc(j+1);
Printf("Including: %s (%d bytes)\n",confile, j);
fp.Read(mptr, j);
fp.Close();
g_scriptcrc = Bcrc32(mptr, j, g_scriptcrc);
mptr[j] = 0;
if (*textptr == '"') // skip past the closing quote if it's there so we don't screw up the next line
textptr++;
char *origtptr = textptr;
char parentScriptFileName[255];
Bstrcpy(parentScriptFileName, g_scriptFileName);
Bstrcpy(g_scriptFileName, confile);
int32_t temp_ScriptLineNumber = line_number;
line_number = 1;
int32_t temp_ifelse_check = checking_ifelse;
checking_ifelse = 0;
textptr = mptr;
C_SkipComments();
C_ParseCommand(1);
Bstrcpy(g_scriptFileName, parentScriptFileName);
g_totalLines += line_number;
line_number = temp_ScriptLineNumber;
checking_ifelse = temp_ifelse_check;
textptr = origtptr;
Xfree(mptr);
}
int parsecommand(int tw); // for now just run an externally parsed command.
int32_t C_ParseCommand(int32_t loop)
{
int32_t j=0, k=0, tw;
TArray<char> buffer;
do
{
if (EDUKE32_PREDICT_FALSE(errorcount > 63 || (*textptr == '\0') || (*(textptr+1) == '\0') || C_SkipComments()))
return 1;
if (EDUKE32_PREDICT_FALSE(g_scriptDebug))
C_ReportError(-1);
g_lastKeyword = tw = C_GetNextKeyword();
if (parsecommand(g_lastKeyword)) return 1;
continue;
}
while (loop);
return 0;
}
static char const * C_ScriptVersionString(int32_t version)
{
switch (version)
{
case 9:
return ", v0.99 compatibility mode";
case 10:
return ", v1.0 compatibility mode";
case 11:
return ", v1.1 compatibility mode";
case 13:
return ", v1.3D compatibility mode";
default:
return "";
}
}
void loadcons(const char* filenam);
void C_Compile(const char *fileName)
{
Bmemset(apScriptGameEvent, 0, sizeof(apScriptGameEvent));
Bmemset(apScriptGameEventEnd, 0, sizeof(apScriptGameEventEnd));
for (int i=0; i<MAXTILES; i++)
{
@ -395,135 +115,9 @@ void C_Compile(const char *fileName)
C_InitHashes();
Gv_Init();
auto kFile = fileSystem.OpenFileReader(fileName);
if (!kFile.isOpen())
{
if (!kFile.isOpen())
{
I_Error(tempbuf, "CON file `%s' missing.", fileName);
}
}
int const kFileLen = kFile.GetLength();
Printf("Compiling: %s (%d bytes)\n", fileName, kFileLen);
uint32_t const startcompiletime = timerGetTicks();
char * mptr = (char *)Xmalloc(kFileLen+1);
mptr[kFileLen] = 0;
textptr = (char *) mptr;
kFile.Read((char *)textptr,kFileLen);
kFile.Close();
g_scriptcrc = Bcrc32(NULL, 0, 0L);
g_scriptcrc = Bcrc32(textptr, kFileLen, g_scriptcrc);
Xfree(apScript);
apScript = (intptr_t *)Xcalloc(1, g_scriptSize * sizeof(intptr_t));
labelcnt = 0;
g_defaultLabelCnt = 0;
scriptptr = apScript + 3; // move permits constants 0 and 1; moveptr[1] would be script[2] (reachable?)
warningcount = 0;
errorcount = 0;
line_number = 1;
g_totalLines = 0;
Bstrcpy(g_scriptFileName, fileName);
C_ParseCommand(1);
if (userConfig.AddCons) for (FString & m : *userConfig.AddCons.get())
{
C_Include(m);
}
userConfig.AddCons.reset();
if (errorcount > 63)
Printf("fatal error: too many errors: Aborted\n");
//*script = (intptr_t) scriptptr;
DO_FREE_AND_NULL(mptr);
if (warningcount || errorcount)
Printf("Found %d warning(s), %d error(s).\n", warningcount, errorcount);
if (errorcount)
{
Bsprintf(buf, "Error compiling CON files.");
G_GameExit(buf);
}
g_totalLines += line_number;
C_SetScriptSize(scriptptr-apScript+8);
Printf("Script compiled in %dms, %ld bytes%s\n", timerGetTicks() - startcompiletime,
(unsigned long)(scriptptr-apScript), C_ScriptVersionString(g_scriptVersion));
loadcons(fileName);
}
void C_ReportError(int32_t iError)
{
if (Bstrcmp(g_szCurrentBlockName,g_szLastBlockName))
{
if (parsing_event || parsing_state || parsing_actor)
Printf("%s: In %s `%s':\n",g_scriptFileName,parsing_event?"event":parsing_actor?"actor":"state",g_szCurrentBlockName);
else Printf("%s: At top level:\n",g_scriptFileName);
Bstrcpy(g_szLastBlockName,g_szCurrentBlockName);
}
switch (iError)
{
case ERROR_CLOSEBRACKET:
Printf("%s:%d: error: found more `}' than `{' before `%s'.\n",g_scriptFileName,line_number,tempbuf);
break;
case ERROR_EXCEEDSMAXTILES:
Printf("%s:%d: error: `%s' value exceeds MAXTILES. Maximum is %d.\n",g_scriptFileName,line_number,tempbuf,MAXTILES-1);
break;
case ERROR_EXPECTEDKEYWORD:
Printf("%s:%d: error: expected a keyword but found `%s'.\n",g_scriptFileName,line_number,tempbuf);
break;
case ERROR_FOUNDWITHIN:
Printf("%s:%d: error: found `%s' within %s.\n",g_scriptFileName,line_number,tempbuf,parsing_actor?"an actor":"a state");
break;
case ERROR_ISAKEYWORD:
Printf("%s:%d: error: symbol `%s' is a keyword.\n",g_scriptFileName,line_number,label+(labelcnt<<6));
break;
case ERROR_OPENBRACKET:
Printf("%s:%d: error: found more `{' than `}' before `%s'.\n",g_scriptFileName,line_number,tempbuf);
break;
case ERROR_NOTAGAMEVAR:
Printf("%s:%d: error: symbol `%s' is not a variable.\n",g_scriptFileName,line_number,LAST_LABEL);
break;
case ERROR_PARAMUNDEFINED:
Printf("%s:%d: error: parameter `%s' is undefined.\n",g_scriptFileName,line_number,tempbuf);
break;
case ERROR_SYNTAXERROR:
Printf("%s:%d: error: syntax error.\n",g_scriptFileName,line_number);
break;
case ERROR_VARREADONLY:
Printf("%s:%d: error: variable `%s' is read-only.\n",g_scriptFileName,line_number,LAST_LABEL);
break;
case ERROR_VARTYPEMISMATCH:
Printf("%s:%d: error: variable `%s' is of the wrong type.\n",g_scriptFileName,line_number,LAST_LABEL);
break;
case WARNING_BADGAMEVAR:
Printf("%s:%d: warning: variable `%s' should be either per-player OR per-actor, not both.\n",g_scriptFileName,line_number,LAST_LABEL);
break;
case WARNING_DUPLICATEDEFINITION:
Printf("%s:%d: warning: duplicate definition `%s' ignored.\n",g_scriptFileName,line_number,LAST_LABEL);
break;
case WARNING_LABELSONLY:
Printf("%s:%d: warning: expected a label, found a constant.\n",g_scriptFileName,line_number);
break;
case WARNING_VARMASKSKEYWORD:
Printf("%s:%d: warning: variable `%s' masks keyword.\n", g_scriptFileName, line_number, LAST_LABEL);
break;
}
}
END_DUKE_NS

View file

@ -274,7 +274,7 @@ void Gv_NewVar(const char *pszLabel, intptr_t lValue, uint32_t dwFlags)
if (EDUKE32_PREDICT_FALSE(g_gameVarCount >= MAXGAMEVARS))
{
errorcount++;
C_ReportError(-1);
ReportError(-1);
Printf("%s:%d: error: too many gamevars!\n",g_scriptFileName,line_number);
return;
}
@ -282,7 +282,7 @@ void Gv_NewVar(const char *pszLabel, intptr_t lValue, uint32_t dwFlags)
if (EDUKE32_PREDICT_FALSE(Bstrlen(pszLabel) > (MAXVARLABEL-1)))
{
errorcount++;
C_ReportError(-1);
ReportError(-1);
Printf("%s:%d: error: variable name `%s' exceeds limit of %d characters.\n",g_scriptFileName,line_number,pszLabel, MAXVARLABEL);
return;
}
@ -294,7 +294,7 @@ void Gv_NewVar(const char *pszLabel, intptr_t lValue, uint32_t dwFlags)
// found it...
if (EDUKE32_PREDICT_FALSE(aGameVars[gV].flags & (GAMEVAR_PTR_MASK)))
{
C_ReportError(-1);
ReportError(-1);
Printf("%s:%d: warning: cannot redefine internal gamevar `%s'.\n",g_scriptFileName,line_number,label+(labelcnt<<6));
return;
}
@ -302,7 +302,7 @@ void Gv_NewVar(const char *pszLabel, intptr_t lValue, uint32_t dwFlags)
{
// it's a duplicate in error
warningcount++;
C_ReportError(WARNING_DUPLICATEDEFINITION);
ReportError(WARNING_DUPLICATEDEFINITION);
return;
}
}

View file

@ -4933,38 +4933,6 @@ void P_FragPlayer(int playerNum)
quoteMgr.InitializeQuote(QUOTE_RESERVED2, "Killed %s", &g_player[playerNum].user_name[0]);
P_DoQuote(QUOTE_RESERVED2, g_player[pPlayer->frag_ps].ps);
}
if (cl_obituaries)
{
Bsprintf(tempbuf, quoteMgr.GetQuote(OBITQUOTEINDEX + (krand2() % g_numObituaries)),
&g_player[pPlayer->frag_ps].user_name[0], &g_player[playerNum].user_name[0]);
G_AddUserQuote(tempbuf);
}
else
krand2();
}
else
{
if (actor[pPlayer->i].picnum != TILE_APLAYERTOP)
{
pPlayer->fraggedself++;
if ((unsigned)pPlayer->wackedbyactor < MAXTILES && A_CheckEnemyTile(sprite[pPlayer->wackedbyactor].picnum))
Bsprintf(tempbuf, quoteMgr.GetQuote(OBITQUOTEINDEX + (krand2() % g_numObituaries)), "A monster",
&g_player[playerNum].user_name[0]);
else if (actor[pPlayer->i].picnum == TILE_NUKEBUTTON)
Bsprintf(tempbuf, "^02%s^02 tried to leave", &g_player[playerNum].user_name[0]);
else
{
// random suicide death string
Bsprintf(tempbuf, quoteMgr.GetQuote(SUICIDEQUOTEINDEX + (krand2() % g_numSelfObituaries)),
&g_player[playerNum].user_name[0]);
}
}
else
Bsprintf(tempbuf, "^02%s^02 switched to team %d", &g_player[playerNum].user_name[0], pPlayer->team + 1);
if (cl_obituaries)
G_AddUserQuote(tempbuf);
}
pPlayer->frag_ps = playerNum;
pus = NUMPAGES;

View file

@ -1013,7 +1013,7 @@ int32_t sv_saveandmakesnapshot(FileWriter &fil, int8_t spot, bool isAutoSave)
h.bytever = BYTEVERSION;
h.userbytever = ud.userbytever;
h.scriptcrc = g_scriptcrc;
h.scriptcrc = 0;
h.reccnt = 0;
h.snapsiz = svsnapsiz;
@ -1109,13 +1109,13 @@ int32_t sv_loadheader(FileReader &fill, int32_t spot, savehead_t *h)
return -2;
}
if (h->majorver != SV_MAJOR_VER || h->minorver != SV_MINOR_VER || h->bytever != BYTEVERSION || h->userbytever != ud.userbytever || (apScript != NULL && h->scriptcrc != g_scriptcrc))
if (h->majorver != SV_MAJOR_VER || h->minorver != SV_MINOR_VER || h->bytever != BYTEVERSION || h->userbytever != ud.userbytever || (apScript != NULL))
{
#ifndef DEBUGGINGAIDS
if (havedemo)
#endif
Printf("Incompatible savegame. Expected version %d.%d.%d.%d.%0x, found %d.%d.%d.%d.%0x\n", SV_MAJOR_VER, SV_MINOR_VER, BYTEVERSION,
ud.userbytever, g_scriptcrc, h->majorver, h->minorver, h->bytever, h->userbytever, h->scriptcrc);
Printf("Incompatible savegame. Expected version %d.%d.%d.%d, found %d.%d.%d.%d\n", SV_MAJOR_VER, SV_MINOR_VER, BYTEVERSION,
ud.userbytever, h->majorver, h->minorver, h->bytever, h->userbytever);
if (h->majorver == SV_MAJOR_VER && h->minorver == SV_MINOR_VER)
{