summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/hexen/p_acs.c25
-rw-r--r--src/hexen/p_enemy.c5
-rw-r--r--src/hexen/p_inter.c5
-rw-r--r--src/hexen/p_map.c12
-rw-r--r--src/hexen/p_spec.c14
5 files changed, 48 insertions, 13 deletions
diff --git a/src/hexen/p_acs.c b/src/hexen/p_acs.c
index f76fa167..b9fd8f08 100644
--- a/src/hexen/p_acs.c
+++ b/src/hexen/p_acs.c
@@ -27,6 +27,7 @@
// MACROS ------------------------------------------------------------------
+#define MAX_SCRIPT_ARGS 3
#define SCRIPT_CONTINUE 0
#define SCRIPT_STOP 1
#define SCRIPT_TERMINATE 2
@@ -195,7 +196,7 @@ static acs_t *NewScript;
static int (*PCodeCmds[]) (void) =
{
-CmdNOP,
+ CmdNOP,
CmdTerminate,
CmdSuspend,
CmdPushNumber,
@@ -294,7 +295,10 @@ CmdNOP,
CmdSoundSequence,
CmdSetLineTexture,
CmdSetLineBlocking,
- CmdSetLineSpecial, CmdThingSound, CmdEndPrintBold};
+ CmdSetLineSpecial,
+ CmdThingSound,
+ CmdEndPrintBold,
+};
// CODE --------------------------------------------------------------------
@@ -336,6 +340,16 @@ void P_LoadACScripts(int lump)
info->argCount = LONG(*buffer);
++buffer;
+ if (info->argCount > MAX_SCRIPT_ARGS)
+ {
+ fprintf(stderr, "Warning: ACS script #%i has %i arguments, more "
+ "than the maximum of %i. Enforcing limit.\n"
+ "If you are seeing this message, please report "
+ "the name of the WAD where you saw it.\n",
+ i, info->argCount, MAX_SCRIPT_ARGS);
+ info->argCount = MAX_SCRIPT_ARGS;
+ }
+
if (info->number >= OPEN_SCRIPTS_BASE)
{ // Auto-activate
info->number -= OPEN_SCRIPTS_BASE;
@@ -414,6 +428,9 @@ void P_CheckACSStore(void)
//
// P_StartACS
//
+// Start an ACS script. The 'args' array should be at least MAX_SCRIPT_ARGS
+// elements in length.
+//
//==========================================================================
static char ErrorMsg[128];
@@ -458,7 +475,7 @@ boolean P_StartACS(int number, int map, byte * args, mobj_t * activator,
script->side = side;
script->ip = ACSInfo[infoIndex].address;
script->thinker.function = T_InterpretACS;
- for (i = 0; i < ACSInfo[infoIndex].argCount; i++)
+ for (i = 0; i < MAX_SCRIPT_ARGS && i < ACSInfo[infoIndex].argCount; i++)
{
script->vars[i] = args[i];
}
@@ -503,7 +520,7 @@ static boolean AddToACSStore(int map, int number, byte * args)
}
ACSStore[index].map = map;
ACSStore[index].script = number;
- memcpy(ACSStore[index].args, args, sizeof(int));
+ memcpy(ACSStore[index].args, args, MAX_SCRIPT_ARGS);
return true;
}
diff --git a/src/hexen/p_enemy.c b/src/hexen/p_enemy.c
index 1ad87032..18cc79eb 100644
--- a/src/hexen/p_enemy.c
+++ b/src/hexen/p_enemy.c
@@ -4781,7 +4781,8 @@ void A_FreezeDeath(mobj_t * actor)
}
}
else if (actor->flags & MF_COUNTKILL && actor->special)
- { // Initiate monster death actions
+ {
+ // Initiate monster death actions.
P_ExecuteLineSpecial(actor->special, actor->args, NULL, 0, actor);
}
}
@@ -4933,7 +4934,7 @@ void A_KoraxChase(mobj_t * actor)
{
mobj_t *spot;
int lastfound;
- byte args[3] = { 0, 0, 0 };
+ byte args[3] = {0, 0, 0};
if ((!actor->special2.i) &&
(actor->health <= (actor->info->spawnhealth / 2)))
diff --git a/src/hexen/p_inter.c b/src/hexen/p_inter.c
index 15dfa5f8..587614ff 100644
--- a/src/hexen/p_inter.c
+++ b/src/hexen/p_inter.c
@@ -1280,7 +1280,7 @@ mobj_t *ActiveMinotaur(player_t * master)
void P_KillMobj(mobj_t * source, mobj_t * target)
{
- int dummy;
+ byte dummyArgs[3] = {0, 0, 0};
mobj_t *master;
target->flags &= ~(MF_SHOOTABLE | MF_FLOAT | MF_SKULLFLY | MF_NOGRAVITY);
@@ -1292,8 +1292,7 @@ void P_KillMobj(mobj_t * source, mobj_t * target)
{ // Initiate monster death actions
if (target->type == MT_SORCBOSS)
{
- dummy = 0;
- P_StartACS(target->special, 0, (byte *) & dummy, target, NULL, 0);
+ P_StartACS(target->special, 0, dummyArgs, target, NULL, 0);
}
else
{
diff --git a/src/hexen/p_map.c b/src/hexen/p_map.c
index c8172555..11aa23e0 100644
--- a/src/hexen/p_map.c
+++ b/src/hexen/p_map.c
@@ -2003,6 +2003,7 @@ static boolean PuzzleActivated;
boolean PTR_PuzzleItemTraverse(intercept_t * in)
{
mobj_t *mobj;
+ byte args[3];
int sound;
if (in->isaline)
@@ -2045,8 +2046,14 @@ boolean PTR_PuzzleItemTraverse(intercept_t * in)
{ // Item type doesn't match
return false;
}
- P_StartACS(in->d.line->arg2, 0, &in->d.line->arg3,
- PuzzleItemUser, in->d.line, 0);
+
+ // Construct an args[] array that would contain the values from
+ // the line that would be passed by Vanilla Hexen.
+ args[0] = in->d.line->arg3;
+ args[1] = in->d.line->arg4;
+ args[2] = in->d.line->arg5;
+
+ P_StartACS(in->d.line->arg2, 0, args, PuzzleItemUser, in->d.line, 0);
in->d.line->special = 0;
PuzzleActivated = true;
return false; // Stop searching
@@ -2061,6 +2068,7 @@ boolean PTR_PuzzleItemTraverse(intercept_t * in)
{ // Item type doesn't match
return true;
}
+
P_StartACS(mobj->args[1], 0, &mobj->args[2], PuzzleItemUser, NULL, 0);
mobj->special = 0;
PuzzleActivated = true;
diff --git a/src/hexen/p_spec.c b/src/hexen/p_spec.c
index f9d69367..e2069fb9 100644
--- a/src/hexen/p_spec.c
+++ b/src/hexen/p_spec.c
@@ -498,6 +498,9 @@ Events are operations triggered by using, crossing, or shooting special lines, o
//
// P_ExecuteLineSpecial
//
+// Invoked when crossing a linedef. The args[] array should be at least
+// 5 elements in length.
+//
//============================================================================
boolean P_ExecuteLineSpecial(int special, byte * args, line_t * line,
@@ -842,6 +845,7 @@ boolean P_ExecuteLineSpecial(int special, byte * args, line_t * line,
boolean P_ActivateLine(line_t * line, mobj_t * mo, int side,
int activationType)
{
+ byte args[5];
int lineActivation;
boolean repeat;
boolean buttonSuccess;
@@ -863,8 +867,14 @@ boolean P_ActivateLine(line_t * line, mobj_t * mo, int side,
repeat = line->flags & ML_REPEAT_SPECIAL;
buttonSuccess = false;
- buttonSuccess = P_ExecuteLineSpecial(line->special, &line->arg1, line,
- side, mo);
+ // Construct args[] array to contain the arguments from the line, as we
+ // cannot rely on struct field ordering and layout.
+ args[0] = line->arg1;
+ args[1] = line->arg2;
+ args[2] = line->arg3;
+ args[3] = line->arg4;
+ args[4] = line->arg5;
+ buttonSuccess = P_ExecuteLineSpecial(line->special, args, line, side, mo);
if (!repeat && buttonSuccess)
{ // clear the special on non-retriggerable lines
line->special = 0;