📄 p_acs.c
字号:
//**************************************************************************//**//** p_acs.c : Heretic 2 : Raven Software, Corp.//**//** $RCSfile: p_acs.c,v $//** $Revision: 1.31 $//** $Date: 95/10/09 16:25:17 $//** $Author: cjr $//**//**************************************************************************// HEADER FILES ------------------------------------------------------------#include "h2def.h"#include "p_local.h"// MACROS ------------------------------------------------------------------#define SCRIPT_CONTINUE 0#define SCRIPT_STOP 1#define SCRIPT_TERMINATE 2#define OPEN_SCRIPTS_BASE 1000#define PRINT_BUFFER_SIZE 256#define GAME_SINGLE_PLAYER 0#define GAME_NET_COOPERATIVE 1#define GAME_NET_DEATHMATCH 2#define TEXTURE_TOP 0#define TEXTURE_MIDDLE 1#define TEXTURE_BOTTOM 2#define S_DROP ACScript->stackPtr--#define S_POP ACScript->stack[--ACScript->stackPtr]#define S_PUSH(x) ACScript->stack[ACScript->stackPtr++] = x// TYPES -------------------------------------------------------------------typedef struct{ int marker; int infoOffset; int code;} acsHeader_t;// EXTERNAL FUNCTION PROTOTYPES --------------------------------------------// PUBLIC FUNCTION PROTOTYPES ----------------------------------------------// PRIVATE FUNCTION PROTOTYPES ---------------------------------------------static void StartOpenACS(int number, int infoIndex, int *address);static void ScriptFinished(int number);static boolean TagBusy(int tag);static boolean AddToACSStore(int map, int number, byte *args);static int GetACSIndex(int number);static void Push(int value);static int Pop(void);static int Top(void);static void Drop(void);static int CmdNOP(void);static int CmdTerminate(void);static int CmdSuspend(void);static int CmdPushNumber(void);static int CmdLSpec1(void);static int CmdLSpec2(void);static int CmdLSpec3(void);static int CmdLSpec4(void);static int CmdLSpec5(void);static int CmdLSpec1Direct(void);static int CmdLSpec2Direct(void);static int CmdLSpec3Direct(void);static int CmdLSpec4Direct(void);static int CmdLSpec5Direct(void);static int CmdAdd(void);static int CmdSubtract(void);static int CmdMultiply(void);static int CmdDivide(void);static int CmdModulus(void);static int CmdEQ(void);static int CmdNE(void);static int CmdLT(void);static int CmdGT(void);static int CmdLE(void);static int CmdGE(void);static int CmdAssignScriptVar(void);static int CmdAssignMapVar(void);static int CmdAssignWorldVar(void);static int CmdPushScriptVar(void);static int CmdPushMapVar(void);static int CmdPushWorldVar(void);static int CmdAddScriptVar(void);static int CmdAddMapVar(void);static int CmdAddWorldVar(void);static int CmdSubScriptVar(void);static int CmdSubMapVar(void);static int CmdSubWorldVar(void);static int CmdMulScriptVar(void);static int CmdMulMapVar(void);static int CmdMulWorldVar(void);static int CmdDivScriptVar(void);static int CmdDivMapVar(void);static int CmdDivWorldVar(void);static int CmdModScriptVar(void);static int CmdModMapVar(void);static int CmdModWorldVar(void);static int CmdIncScriptVar(void);static int CmdIncMapVar(void);static int CmdIncWorldVar(void);static int CmdDecScriptVar(void);static int CmdDecMapVar(void);static int CmdDecWorldVar(void);static int CmdGoto(void);static int CmdIfGoto(void);static int CmdDrop(void);static int CmdDelay(void);static int CmdDelayDirect(void);static int CmdRandom(void);static int CmdRandomDirect(void);static int CmdThingCount(void);static int CmdThingCountDirect(void);static int CmdTagWait(void);static int CmdTagWaitDirect(void);static int CmdPolyWait(void);static int CmdPolyWaitDirect(void);static int CmdChangeFloor(void);static int CmdChangeFloorDirect(void);static int CmdChangeCeiling(void);static int CmdChangeCeilingDirect(void);static int CmdRestart(void);static int CmdAndLogical(void);static int CmdOrLogical(void);static int CmdAndBitwise(void);static int CmdOrBitwise(void);static int CmdEorBitwise(void);static int CmdNegateLogical(void);static int CmdLShift(void);static int CmdRShift(void);static int CmdUnaryMinus(void);static int CmdIfNotGoto(void);static int CmdLineSide(void);static int CmdScriptWait(void);static int CmdScriptWaitDirect(void);static int CmdClearLineSpecial(void);static int CmdCaseGoto(void);static int CmdBeginPrint(void);static int CmdEndPrint(void);static int CmdPrintString(void);static int CmdPrintNumber(void);static int CmdPrintCharacter(void);static int CmdPlayerCount(void);static int CmdGameType(void);static int CmdGameSkill(void);static int CmdTimer(void);static int CmdSectorSound(void);static int CmdAmbientSound(void);static int CmdSoundSequence(void);static int CmdSetLineTexture(void);static int CmdSetLineBlocking(void);static int CmdSetLineSpecial(void);static int CmdThingSound(void);static int CmdEndPrintBold(void);static void ThingCount(int type, int tid);// EXTERNAL DATA DECLARATIONS ----------------------------------------------// PUBLIC DATA DEFINITIONS -------------------------------------------------int ACScriptCount;byte *ActionCodeBase;acsInfo_t *ACSInfo;int MapVars[MAX_ACS_MAP_VARS];int WorldVars[MAX_ACS_WORLD_VARS];acsstore_t ACSStore[MAX_ACS_STORE+1]; // +1 for termination marker// PRIVATE DATA DEFINITIONS ------------------------------------------------static acs_t *ACScript;static int *PCodePtr;static byte SpecArgs[8];static int ACStringCount;static char **ACStrings;static char PrintBuffer[PRINT_BUFFER_SIZE];static acs_t *NewScript;static int (*PCodeCmds[])(void) ={ CmdNOP, CmdTerminate, CmdSuspend, CmdPushNumber, CmdLSpec1, CmdLSpec2, CmdLSpec3, CmdLSpec4, CmdLSpec5, CmdLSpec1Direct, CmdLSpec2Direct, CmdLSpec3Direct, CmdLSpec4Direct, CmdLSpec5Direct, CmdAdd, CmdSubtract, CmdMultiply, CmdDivide, CmdModulus, CmdEQ, CmdNE, CmdLT, CmdGT, CmdLE, CmdGE, CmdAssignScriptVar, CmdAssignMapVar, CmdAssignWorldVar, CmdPushScriptVar, CmdPushMapVar, CmdPushWorldVar, CmdAddScriptVar, CmdAddMapVar, CmdAddWorldVar, CmdSubScriptVar, CmdSubMapVar, CmdSubWorldVar, CmdMulScriptVar, CmdMulMapVar, CmdMulWorldVar, CmdDivScriptVar, CmdDivMapVar, CmdDivWorldVar, CmdModScriptVar, CmdModMapVar, CmdModWorldVar, CmdIncScriptVar, CmdIncMapVar, CmdIncWorldVar, CmdDecScriptVar, CmdDecMapVar, CmdDecWorldVar, CmdGoto, CmdIfGoto, CmdDrop, CmdDelay, CmdDelayDirect, CmdRandom, CmdRandomDirect, CmdThingCount, CmdThingCountDirect, CmdTagWait, CmdTagWaitDirect, CmdPolyWait, CmdPolyWaitDirect, CmdChangeFloor, CmdChangeFloorDirect, CmdChangeCeiling, CmdChangeCeilingDirect, CmdRestart, CmdAndLogical, CmdOrLogical, CmdAndBitwise, CmdOrBitwise, CmdEorBitwise, CmdNegateLogical, CmdLShift, CmdRShift, CmdUnaryMinus, CmdIfNotGoto, CmdLineSide, CmdScriptWait, CmdScriptWaitDirect, CmdClearLineSpecial, CmdCaseGoto, CmdBeginPrint, CmdEndPrint, CmdPrintString, CmdPrintNumber, CmdPrintCharacter, CmdPlayerCount, CmdGameType, CmdGameSkill, CmdTimer, CmdSectorSound, CmdAmbientSound, CmdSoundSequence, CmdSetLineTexture, CmdSetLineBlocking, CmdSetLineSpecial, CmdThingSound, CmdEndPrintBold};// CODE --------------------------------------------------------------------//==========================================================================//// P_LoadACScripts////==========================================================================void P_LoadACScripts(int lump){ int i; int *buffer; acsHeader_t *header; acsInfo_t *info; header = W_CacheLumpNum(lump, PU_LEVEL); ActionCodeBase = (byte *)header; buffer = (int *)((byte *)header+header->infoOffset); ACScriptCount = *buffer++; if(ACScriptCount == 0) { // Empty behavior lump return; } ACSInfo = Z_Malloc(ACScriptCount*sizeof(acsInfo_t), PU_LEVEL, 0); memset(ACSInfo, 0, ACScriptCount*sizeof(acsInfo_t)); for(i = 0, info = ACSInfo; i < ACScriptCount; i++, info++) { info->number = *buffer++; info->address = (int *)((byte *)ActionCodeBase+*buffer++); info->argCount = *buffer++; if(info->number >= OPEN_SCRIPTS_BASE) { // Auto-activate info->number -= OPEN_SCRIPTS_BASE; StartOpenACS(info->number, i, info->address); info->state = ASTE_RUNNING; } else { info->state = ASTE_INACTIVE; } } ACStringCount = *buffer++; ACStrings = (char **)buffer; for(i = 0; i < ACStringCount; i++) { ACStrings[i] += (int)ActionCodeBase; } memset(MapVars, 0, sizeof(MapVars));}//==========================================================================//// StartOpenACS////==========================================================================static void StartOpenACS(int number, int infoIndex, int *address){ acs_t *script; script = Z_Malloc(sizeof(acs_t), PU_LEVSPEC, 0); memset(script, 0, sizeof(acs_t)); script->number = number; // World objects are allotted 1 second for initialization script->delayCount = 35; script->infoIndex = infoIndex; script->ip = address; script->thinker.function = T_InterpretACS; P_AddThinker(&script->thinker);}//==========================================================================//// P_CheckACSStore//// Scans the ACS store and executes all scripts belonging to the current// map.////==========================================================================void P_CheckACSStore(void){ acsstore_t *store; for(store = ACSStore; store->map != 0; store++) { if(store->map == gamemap) { P_StartACS(store->script, 0, store->args, NULL, NULL, 0); if(NewScript) { NewScript->delayCount = 35; } store->map = -1; } }}//==========================================================================//// P_StartACS////==========================================================================static char ErrorMsg[128];boolean P_StartACS(int number, int map, byte *args, mobj_t *activator, line_t *line, int side){ int i; acs_t *script; int infoIndex; aste_t *statePtr; NewScript = NULL; if(map && map != gamemap) { // Add to the script store return AddToACSStore(map, number, args); } infoIndex = GetACSIndex(number); if(infoIndex == -1) { // Script not found //I_Error("P_StartACS: Unknown script number %d", number); sprintf(ErrorMsg, "P_STARTACS ERROR: UNKNOWN SCRIPT %d", number); P_SetMessage(&players[consoleplayer], ErrorMsg, true); } statePtr = &ACSInfo[infoIndex].state; if(*statePtr == ASTE_SUSPENDED) { // Resume a suspended script *statePtr = ASTE_RUNNING; return true; } if(*statePtr != ASTE_INACTIVE) { // Script is already executing return false; } script = Z_Malloc(sizeof(acs_t), PU_LEVSPEC, 0); memset(script, 0, sizeof(acs_t)); script->number = number; script->infoIndex = infoIndex; script->activator = activator; script->line = line; script->side = side; script->ip = ACSInfo[infoIndex].address; script->thinker.function = T_InterpretACS; for(i = 0; i < ACSInfo[infoIndex].argCount; i++) { script->vars[i] = args[i]; } *statePtr = ASTE_RUNNING; P_AddThinker(&script->thinker); NewScript = script; return true;}//==========================================================================//// AddToACSStore////==========================================================================static boolean AddToACSStore(int map, int number, byte *args){ int i; int index; index = -1; for(i = 0; ACSStore[i].map != 0; i++) { if(ACSStore[i].script == number && ACSStore[i].map == map) { // Don't allow duplicates return false; } if(index == -1 && ACSStore[i].map == -1) { // Remember first empty slot index = i; } } if(index == -1) { // Append required if(i == MAX_ACS_STORE) { I_Error("AddToACSStore: MAX_ACS_STORE (%d) exceeded.", MAX_ACS_STORE); } index = i; ACSStore[index+1].map = 0; } ACSStore[index].map = map; ACSStore[index].script = number; *((int *)ACSStore[index].args) = *((int *)args); return true;}//==========================================================================//// P_StartLockedACS////==========================================================================boolean P_StartLockedACS(line_t *line, byte *args, mobj_t *mo, int side){ int i; int lock; byte newArgs[5]; char LockedBuffer[80]; extern char *TextKeyMessages[11]; lock = args[4]; if(!mo->player) { return false; } if(lock) { if(!(mo->player->keys&(1<<(lock-1)))) { sprintf(LockedBuffer, "YOU NEED THE %s\n", TextKeyMessages[lock-1]); P_SetMessage(mo->player, LockedBuffer, true); S_StartSound(mo, SFX_DOOR_LOCKED); return false; } } for(i = 0; i < 4; i++) { newArgs[i] = args[i]; } newArgs[4] = 0; return P_StartACS(newArgs[0], newArgs[1], &newArgs[2], mo, line, side);}//==========================================================================//// P_TerminateACS////==========================================================================boolean P_TerminateACS(int number, int map){ int infoIndex; infoIndex = GetACSIndex(number); if(infoIndex == -1) { // Script not found return false; } if(ACSInfo[infoIndex].state == ASTE_INACTIVE || ACSInfo[infoIndex].state == ASTE_TERMINATING) { // States that disallow termination return false; } ACSInfo[infoIndex].state = ASTE_TERMINATING; return true;}//==========================================================================//// P_SuspendACS////==========================================================================boolean P_SuspendACS(int number, int map){ int infoIndex; infoIndex = GetACSIndex(number); if(infoIndex == -1) { // Script not found return false; } if(ACSInfo[infoIndex].state == ASTE_INACTIVE || ACSInfo[infoIndex].state == ASTE_SUSPENDED || ACSInfo[infoIndex].state == ASTE_TERMINATING) { // States that disallow suspension return false; } ACSInfo[infoIndex].state = ASTE_SUSPENDED; return true;}//==========================================================================//// P_Init////==========================================================================void P_ACSInitNewGame(void){ memset(WorldVars, 0, sizeof(WorldVars)); memset(ACSStore, 0, sizeof(ACSStore));}//==========================================================================//// T_InterpretACS////==========================================================================
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -