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_IFCUTSCENE, 20150210 },
{ CON_DEFINEVOLUMEFLAGS, 20150222 }, { CON_DEFINEVOLUMEFLAGS, 20150222 },
{ CON_RESETPLAYERFLAGS, 20150303 }, { CON_RESETPLAYERFLAGS, 20150303 },
{ CON_APPENDEVENT, 20150325 },
}; };
#endif #endif
@ -563,6 +564,7 @@ const char *keyw[] =
"ifcutscene", // 379 "ifcutscene", // 379
"definevolumeflags", // 380 "definevolumeflags", // 380
"resetplayerflags", // 381 "resetplayerflags", // 381
"appendevent", // 382
"<null>" "<null>"
}; };
#endif #endif
@ -3422,6 +3424,7 @@ static int32_t C_ParseCommand(int32_t loop)
continue; continue;
case CON_ONEVENT: case CON_ONEVENT:
case CON_APPENDEVENT:
if (EDUKE32_PREDICT_FALSE(g_processingState || g_parsingActorPtr)) if (EDUKE32_PREDICT_FALSE(g_processingState || g_parsingActorPtr))
{ {
C_ReportError(ERROR_FOUNDWITHIN); C_ReportError(ERROR_FOUNDWITHIN);
@ -3456,11 +3459,22 @@ static int32_t C_ParseCommand(int32_t loop)
continue; continue;
} }
// if event has already been declared then store previous script location // 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; g_checkingIfElse = 0;
@ -6073,6 +6087,14 @@ repeatcase:
*(g_scriptPtr++) = CON_ENDEVENT; *(g_scriptPtr++) = CON_ENDEVENT;
previous_event = NULL; 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_parsingEventPtr = g_parsingActorPtr = NULL;
g_currentEvent = -1; g_currentEvent = -1;
Bsprintf(g_szCurrentBlockName,"(none)"); Bsprintf(g_szCurrentBlockName,"(none)");

View file

@ -75,6 +75,7 @@ enum QuickStructureAccess_t {
extern int32_t g_iStructVarIDs; extern int32_t g_iStructVarIDs;
extern intptr_t *apScriptGameEvent[MAXGAMEEVENTS]; extern intptr_t *apScriptGameEvent[MAXGAMEEVENTS];
extern intptr_t *apScriptGameEventEnd[MAXGAMEEVENTS];
#endif #endif
extern int32_t otherp; extern int32_t otherp;
@ -1027,6 +1028,7 @@ enum ScriptKeywords_t
CON_IFCUTSCENE, // 379 CON_IFCUTSCENE, // 379
CON_DEFINEVOLUMEFLAGS, // 380 CON_DEFINEVOLUMEFLAGS, // 380
CON_RESETPLAYERFLAGS, // 381 CON_RESETPLAYERFLAGS, // 381
CON_APPENDEVENT, // 382
CON_END CON_END
}; };
// KEEPINSYNC with the keyword list in lunatic/con_lang.lua // 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 *apScriptGameEvent[MAXGAMEEVENTS];
intptr_t *apScriptGameEventEnd[MAXGAMEEVENTS];
// May recurse, e.g. through EVENT_XXX -> ... -> EVENT_KILLIT // May recurse, e.g. through EVENT_XXX -> ... -> EVENT_KILLIT
#ifdef LUNATIC #ifdef LUNATIC

View file

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

View file

@ -657,6 +657,18 @@ function on.event_end(pos, eventidx, codetab)
g_code.event[eventidx] = codetab g_code.event[eventidx] = codetab
end 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) function on.eventloadactor_end(pos, tilenum, codetab)
if (on.fnames_tilenum_label(tilenum)) then if (on.fnames_tilenum_label(tilenum)) then
return return
@ -3413,6 +3425,8 @@ local Cblock = {
onevent = POS() * sp1 * tok.define * sp1 * stmt_list_or_eps * "endevent" onevent = POS() * sp1 * tok.define * sp1 * stmt_list_or_eps * "endevent"
/ on.event_end, / 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)) state = POS() * sp1 * (lpeg.Cmt(tok.identifier, on.state_begin_Cmt))
* sp1 * stmt_list_or_eps * tok.state_ends * sp1 * stmt_list_or_eps * tok.state_ends