foxygit / doom Log in
commit 46d461a5ae15d081b743f9293aa10ac838884254
Author:     Jonathan Dowland <jon+github@alcopop.org>
AuthorDate: Sat Jul 23 20:01:43 2016 +0100
Commit:     Jonathan Dowland <jon+github@alcopop.org>
CommitDate: Sat Jul 23 20:01:43 2016 +0100

    Add CheckACSPresent and gracefully exit

    Avoid a segfault if Korax is included in a PWAD without the proper
    ACS/MAPINFO/etc stuff, instead exit via I_Error.

    Fixes #761
---
 src/hexen/p_acs.c   | 19 +++++++++++++++++++
 src/hexen/p_enemy.c |  7 +++++++
 src/hexen/p_spec.h  |  1 +
 3 files changed, 27 insertions(+)

diff --git a/src/hexen/p_acs.c b/src/hexen/p_acs.c
index b7a63fe9..d3a3619f 100644
--- a/src/hexen/p_acs.c
+++ b/src/hexen/p_acs.c
@@ -56,6 +56,8 @@ typedef struct

 // PUBLIC FUNCTION PROTOTYPES ----------------------------------------------

+void CheckACSPresent(int number);
+
 // PRIVATE FUNCTION PROTOTYPES ---------------------------------------------

 static void StartOpenACS(int number, int infoIndex, int *address);
@@ -785,6 +787,23 @@ static int GetACSIndex(int number)
     return -1;
 }

+//==========================================================================
+//
+// CheckACSPresent
+//
+// Placing Korax in a PWAD without extra steps will result in a crash in
+// Vanilla because the relevant ACS scripts are not initialised
+//
+//==========================================================================
+
+void CheckACSPresent(int number)
+{
+    if (GetACSIndex(number) == -1)
+    {
+        I_Error("Required ACS script %d not initialised", number);
+    }
+}
+
 //==========================================================================
 //
 // Push
diff --git a/src/hexen/p_enemy.c b/src/hexen/p_enemy.c
index 38f3a2b5..afdf1381 100644
--- a/src/hexen/p_enemy.c
+++ b/src/hexen/p_enemy.c
@@ -4946,6 +4946,7 @@ void A_KoraxChase(mobj_t * actor)
             P_Teleport(actor, spot->x, spot->y, spot->angle, true);
         }

+        CheckACSPresent(249);
         P_StartACS(249, 0, args, actor, NULL, 0);
         actor->special2.i = 1;    // Don't run again

@@ -5023,6 +5024,7 @@ void A_KoraxBonePop(mobj_t * actor)
     if (mo)
         KSpiritInit(mo, actor);

+    CheckACSPresent(255);
     P_StartACS(255, 0, args, actor, NULL, 0);   // Death script
 }

@@ -5140,18 +5142,23 @@ void A_KoraxCommand(mobj_t * actor)
     switch (P_Random() % numcommands)
     {
         case 0:
+            CheckACSPresent(250);
             P_StartACS(250, 0, args, actor, NULL, 0);
             break;
         case 1:
+            CheckACSPresent(251);
             P_StartACS(251, 0, args, actor, NULL, 0);
             break;
         case 2:
+            CheckACSPresent(252);
             P_StartACS(252, 0, args, actor, NULL, 0);
             break;
         case 3:
+            CheckACSPresent(253);
             P_StartACS(253, 0, args, actor, NULL, 0);
             break;
         case 4:
+            CheckACSPresent(254);
             P_StartACS(254, 0, args, actor, NULL, 0);
             break;
     }
diff --git a/src/hexen/p_spec.h b/src/hexen/p_spec.h
index 879b21a8..750e9187 100644
--- a/src/hexen/p_spec.h
+++ b/src/hexen/p_spec.h
@@ -546,6 +546,7 @@ void P_TagFinished(int tag);
 void P_PolyobjFinished(int po);
 void P_ACSInitNewGame(void);
 void P_CheckACSStore(void);
+void CheckACSPresent(int number);

 extern int ACScriptCount;
 extern byte *ActionCodeBase;