diff --git a/polymer/eduke32/source/gamedef.c b/polymer/eduke32/source/gamedef.c index 72111458a..2431b4e1c 100644 --- a/polymer/eduke32/source/gamedef.c +++ b/polymer/eduke32/source/gamedef.c @@ -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 "" }; #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)"); diff --git a/polymer/eduke32/source/gamedef.h b/polymer/eduke32/source/gamedef.h index bc9336635..5879ed9b2 100644 --- a/polymer/eduke32/source/gamedef.h +++ b/polymer/eduke32/source/gamedef.h @@ -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 diff --git a/polymer/eduke32/source/gameexec.c b/polymer/eduke32/source/gameexec.c index b8535209e..45fc51b2c 100644 --- a/polymer/eduke32/source/gameexec.c +++ b/polymer/eduke32/source/gameexec.c @@ -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 diff --git a/polymer/eduke32/source/lunatic/con_lang.lua b/polymer/eduke32/source/lunatic/con_lang.lua index 1fc807d7a..3f0f12282 100644 --- a/polymer/eduke32/source/lunatic/con_lang.lua +++ b/polymer/eduke32/source/lunatic/con_lang.lua @@ -1288,6 +1288,7 @@ lpeg.P(false) + "cactor" + "break" + "betaname" + +"appendevent" + "angoffvar" + "angoff" + "andvarvar" + diff --git a/polymer/eduke32/source/lunatic/lunacon.lua b/polymer/eduke32/source/lunatic/lunacon.lua index ea1c9f8e7..52795c681 100644 --- a/polymer/eduke32/source/lunatic/lunacon.lua +++ b/polymer/eduke32/source/lunatic/lunacon.lua @@ -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