CON: Add token "appendevent", which functions identically to "onevent" except that the event's code is chained to the end of any previous events, instead of the beginning.

git-svn-id: https://svn.eduke32.com/eduke32@5093 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
hendricks266 2015-03-25 21:31:11 +00:00
parent a90f47c1ea
commit 0805a0ed45
5 changed files with 43 additions and 3 deletions

View file

@ -100,6 +100,7 @@ static struct { uint32_t keyw; uint32_t date; } g_keywdate[] =
{ CON_IFCUTSCENE, 20150210 },
{ CON_DEFINEVOLUMEFLAGS, 20150222 },
{ CON_RESETPLAYERFLAGS, 20150303 },
{ CON_APPENDEVENT, 20150325 },
};
#endif
@ -563,6 +564,7 @@ const char *keyw[] =
"ifcutscene", // 379
"definevolumeflags", // 380
"resetplayerflags", // 381
"appendevent", // 382
"<null>"
};
#endif
@ -3422,6 +3424,7 @@ static int32_t C_ParseCommand(int32_t loop)
continue;
case CON_ONEVENT:
case CON_APPENDEVENT:
if (EDUKE32_PREDICT_FALSE(g_processingState || g_parsingActorPtr))
{
C_ReportError(ERROR_FOUNDWITHIN);
@ -3456,11 +3459,22 @@ static int32_t C_ParseCommand(int32_t loop)
continue;
}
// if event has already been declared then store previous script location
if (apScriptGameEvent[j])
if (!apScriptGameEvent[j])
{
previous_event =apScriptGameEvent[j];
apScriptGameEvent[j] = g_parsingEventPtr;
}
else if (tw == CON_ONEVENT)
{
previous_event = apScriptGameEvent[j];
apScriptGameEvent[j] = g_parsingEventPtr;
}
else // if (tw == CON_APPENDEVENT)
{
intptr_t *previous_event_end = apScriptGameEventEnd[j];
*(previous_event_end++) = CON_JUMP;
*(previous_event_end++) = MAXGAMEVARS;
*(previous_event_end++) = g_parsingEventPtr-script;
}
apScriptGameEvent[j]=g_parsingEventPtr;
g_checkingIfElse = 0;
@ -6073,6 +6087,14 @@ repeatcase:
*(g_scriptPtr++) = CON_ENDEVENT;
previous_event = NULL;
}
else
{
// pad space for the next potential appendevent
apScriptGameEventEnd[g_currentEvent] = g_scriptPtr-1;
*(g_scriptPtr++) = CON_ENDEVENT;
*(g_scriptPtr++) = CON_ENDEVENT;
*(g_scriptPtr++) = CON_ENDEVENT;
}
g_parsingEventPtr = g_parsingActorPtr = NULL;
g_currentEvent = -1;
Bsprintf(g_szCurrentBlockName,"(none)");

View file

@ -75,6 +75,7 @@ enum QuickStructureAccess_t {
extern int32_t g_iStructVarIDs;
extern intptr_t *apScriptGameEvent[MAXGAMEEVENTS];
extern intptr_t *apScriptGameEventEnd[MAXGAMEEVENTS];
#endif
extern int32_t otherp;
@ -1027,6 +1028,7 @@ enum ScriptKeywords_t
CON_IFCUTSCENE, // 379
CON_DEFINEVOLUMEFLAGS, // 380
CON_RESETPLAYERFLAGS, // 381
CON_APPENDEVENT, // 382
CON_END
};
// KEEPINSYNC with the keyword list in lunatic/con_lang.lua

View file

@ -140,6 +140,7 @@ static void VM_DeleteSprite(int32_t iActor, int32_t iPlayer)
}
intptr_t *apScriptGameEvent[MAXGAMEEVENTS];
intptr_t *apScriptGameEventEnd[MAXGAMEEVENTS];
// May recurse, e.g. through EVENT_XXX -> ... -> EVENT_KILLIT
#ifdef LUNATIC

View file

@ -1288,6 +1288,7 @@ lpeg.P(false) +
"cactor" +
"break" +
"betaname" +
"appendevent" +
"angoffvar" +
"angoff" +
"andvarvar" +

View file

@ -657,6 +657,18 @@ function on.event_end(pos, eventidx, codetab)
g_code.event[eventidx] = codetab
end
function on.appendevent_end(pos, eventidx, codetab)
assert(type(codetab)=="table")
-- 0x40000000: actor.FLAGS.chain_end
paddcodef(pos, "gameevent{%d,0x40000000,function(_aci,_pli,_dist)", eventidx)
addcode(get_cache_sap_code())
addcode(codetab)
addcode("end}")
-- XXX: appendevent needs different behavior? g_code.event doesn't appear to be used anywhere, for now.
g_code.event[eventidx] = codetab
end
function on.eventloadactor_end(pos, tilenum, codetab)
if (on.fnames_tilenum_label(tilenum)) then
return
@ -3413,6 +3425,8 @@ local Cblock = {
onevent = POS() * sp1 * tok.define * sp1 * stmt_list_or_eps * "endevent"
/ on.event_end,
appendevent = POS() * sp1 * tok.define * sp1 * stmt_list_or_eps * "endevent"
/ on.appendevent_end,
state = POS() * sp1 * (lpeg.Cmt(tok.identifier, on.state_begin_Cmt))
* sp1 * stmt_list_or_eps * tok.state_ends