shithub: choc

Download patch

ref: 496bd0cfca29fdcb7b6de72fac85d6d6fa62e2af
parent: b335b29a98bf2f86fb66a385e913d5e013317e2a
author: James Haley <haleyjd@hotmail.com>
date: Sat Sep 18 03:29:09 EDT 2010

Revisions to objective macro and addition of voice with objective for
super-shortcut. Implemented A_BossDeath - needs moar testing! Resolved
conflict with p_inter.c.

Subversion-branch: /branches/strife-branch
Subversion-revision: 2107

--- a/src/strife/doomdef.h
+++ b/src/strife/doomdef.h
@@ -201,39 +201,39 @@
 // villsa [STRIFE]
 // quest numbers
 typedef enum
-{
-    tk_quest1,
-    tk_quest2,
-    tk_quest3,
-    tk_quest4,
-    tk_quest5,
-    tk_quest6,
-    tk_quest7,
-    tk_quest8,
-    tk_quest9,
-    tk_quest10,
-    tk_quest11,
-    tk_quest12,
-    tk_quest13,
-    tk_quest14,
-    tk_quest15,
-    tk_quest16,
-    tk_quest17,
-    tk_quest18,
-    tk_quest19,
-    tk_quest20,
-    tk_quest21,
-    tk_quest22,
-    tk_quest23,
-    tk_quest24,
-    tk_quest25,
-    tk_quest26,
-    tk_quest27,
-    tk_quest28,
-    tk_quest29,
-    tk_quest30,
-    tk_quest31,
-    tk_quest32,   // most likely unused
+{               // Hex          Watcom Name   
+    tk_quest1,  // 0x00000001   questflags & 1
+    tk_quest2,  // 0x00000002   questflags & 2
+    tk_quest3,  // 0x00000004   questflags & 4
+    tk_quest4,  // 0x00000008   questflags & 8
+    tk_quest5,  // 0x00000010   questflags & 10h
+    tk_quest6,  // 0x00000020   questflags & 20h
+    tk_quest7,  // 0x00000040   questflags & 40h
+    tk_quest8,  // 0x00000080   questflags & 80h
+    tk_quest9,  // 0x00000100   BYTE1(questflags) & 1
+    tk_quest10, // 0x00000200   BYTE1(questflags) & 2
+    tk_quest11, // 0x00000400   BYTE1(questflags) & 4
+    tk_quest12, // 0x00000800   BYTE1(questflags) & 8
+    tk_quest13, // 0x00001000   BYTE1(questflags) & 10h
+    tk_quest14, // 0x00002000   BYTE1(questflags) & 20h
+    tk_quest15, // 0x00004000   BYTE1(questflags) & 40h
+    tk_quest16, // 0x00008000   BYTE1(questflags) & 80h
+    tk_quest17, // 0x00010000   BYTE2(questflags) & 1
+    tk_quest18, // 0x00020000   BYTE2(questflags) & 2
+    tk_quest19, // 0x00040000   BYTE2(questflags) & 4
+    tk_quest20, // 0x00080000   BYTE2(questflags) & 8
+    tk_quest21, // 0x00100000   BYTE2(questflags) & 10h
+    tk_quest22, // 0x00200000   BYTE2(questflags) & 20h
+    tk_quest23, // 0x00400000   BYTE2(questflags) & 40h
+    tk_quest24, // 0x00800000   BYTE2(questflags) & 80h
+    tk_quest25, // 0x01000000   BYTE3(questflags) & 1
+    tk_quest26, // 0x02000000   BYTE3(questflags) & 2
+    tk_quest27, // 0x04000000   BYTE3(questflags) & 4
+    tk_quest28, // 0x08000000   BYTE3(questflags) & 8
+    tk_quest29, // 0x10000000   BYTE3(questflags) & 10h
+    tk_quest30, // 0x20000000   BYTE3(questflags) & 20h
+    tk_quest31, // 0x40000000   BYTE3(questflags) & 40h
+    tk_quest32, // most likely unused
     tk_numquests
 } questtype_t;
 
@@ -261,12 +261,12 @@
     QF_QUEST18 = (1 << tk_quest18), // Obtained Oracle Pass
     QF_QUEST19 = (1 << tk_quest19),
     QF_QUEST20 = (1 << tk_quest20),
-    QF_QUEST21 = (1 << tk_quest21),
-    QF_QUEST22 = (1 << tk_quest22),
-    QF_QUEST23 = (1 << tk_quest23),
-    QF_QUEST24 = (1 << tk_quest24),
+    QF_QUEST21 = (1 << tk_quest21), // Killed Bishop - TODO: verify!
+    QF_QUEST22 = (1 << tk_quest22), // Killed Oracle with QUEST21 set
+    QF_QUEST23 = (1 << tk_quest23), // Killed Oracle (always given)
+    QF_QUEST24 = (1 << tk_quest24), // Killed Macil
     QF_QUEST25 = (1 << tk_quest25), // Destroyed the Converter
-    QF_QUEST26 = (1 << tk_quest26),
+    QF_QUEST26 = (1 << tk_quest26), // Killed Loremaster
     QF_QUEST27 = (1 << tk_quest27),
     QF_QUEST28 = (1 << tk_quest28),
     QF_QUEST29 = (1 << tk_quest29), // Destroyed the Mines Transmitter
--- a/src/strife/p_dialog.h
+++ b/src/strife/p_dialog.h
@@ -46,9 +46,21 @@
 extern char mission_objective[OBJECTIVE_LEN];
 
 // villsa - convenient macro for giving objective logs to player
-#define GiveObjective(x) \
-    if(W_CheckNumForName(DEH_String(x)) != -1)\
-{ strncpy(mission_objective, W_CacheLumpName(DEH_String(x), PU_CACHE), OBJECTIVE_LEN); }
+#define GiveObjective(x, minlumpnum) \
+do { \
+  int obj_ln  = W_CheckNumForName(DEH_String(x)); \
+  if(obj_ln > minlumpnum) \
+    strncpy(mission_objective, W_CacheLumpNum(obj_ln, PU_CACHE), OBJECTIVE_LEN);\
+} while(0)
+
+// haleyjd - voice and objective in one
+#define GiveVoiceObjective(voice, log, minlumpnum) \
+do { \
+  int obj_ln = W_CheckNumForName(DEH_String(log)); \
+  I_StartVoice(DEH_String(voice)); \
+  if(obj_ln > minlumpnum) \
+    strncpy(mission_objective, W_CacheLumpNum(obj_ln, PU_CACHE), OBJECTIVE_LEN);\
+} while(0)
 
 typedef struct mapdlgchoice_s
 {
--- a/src/strife/p_enemy.c
+++ b/src/strife/p_enemy.c
@@ -46,6 +46,7 @@
 
 // [STRIFE] Dialog / Inventory
 #include "p_dialog.h"
+#include "deh_str.h"
 
 // Forward Declarations:
 void A_RandomWalk(mobj_t *);
@@ -2514,7 +2515,7 @@
 {
     angle_t an = angle >> ANGLETOFINESHIFT;
     actor->momx += FixedMul(finecosine[an], force);
-    actor->momy += FixedMul(finesine[an], force);
+    actor->momy += FixedMul(finesine[an],   force);
 }
 
 //
@@ -2527,7 +2528,39 @@
 //
 void A_EntityDeath(mobj_t* actor)
 {
-    // STRIFE-TODO
+    mobj_t *subentity;
+    angle_t an;
+    fixed_t dist;
+    fixed_t momx, momy;
+
+    dist = 2 * mobjinfo[MT_SUBENTITY].radius;
+
+    // Subentity One
+    an = actor->angle >> ANGLETOFINESHIFT;
+    subentity = P_SpawnMobj(FixedMul(finecosine[an], dist) + entity_pos_x,
+                            FixedMul(finesine[an],   dist) + entity_pos_y,
+                            entity_pos_z, MT_SUBENTITY);
+    subentity->target = actor->target;
+    A_FaceTarget(subentity);
+    P_ThrustMobj(subentity, subentity->angle, 625 << 13);
+
+    // Subentity Two
+    an = (actor->angle + ANG90) >> ANGLETOFINESHIFT;
+    subentity = P_SpawnMobj(FixedMul(finecosine[an], dist) + entity_pos_x, 
+                            FixedMul(finesine[an],   dist) + entity_pos_y,
+                            entity_pos_z, MT_SUBENTITY);
+    subentity->target = actor->target;
+    P_ThrustMobj(subentity, actor->angle + ANG90, 4);
+    A_FaceTarget(subentity);
+
+    // Subentity Three
+    an = (actor->angle - ANG90) >> ANGLETOFINESHIFT;
+    subentity = P_SpawnMobj(FixedMul(finecosine[an], dist) + entity_pos_x, 
+                            FixedMul(finesine[an],   dist) + entity_pos_y,
+                            entity_pos_z, MT_SUBENTITY);
+    subentity->target = actor->target;
+    P_ThrustMobj(subentity, actor->angle - ANG90, 4);
+    A_FaceTarget(subentity);
 }
 
 //
@@ -2610,7 +2643,7 @@
 {
     int i;
 
-    sprintf(pmsgbuffer, "You've freed the prisoners!");
+    DEH_snprintf(pmsgbuffer, sizeof(pmsgbuffer), "You've freed the prisoners!");
 
     for(i = 0; i < MAXPLAYERS; i++)
     {
@@ -2630,7 +2663,7 @@
 {
     int i;
 
-    sprintf(pmsgbuffer, "You've destroyed the Converter!");
+    DEH_snprintf(pmsgbuffer, sizeof(pmsgbuffer), "You've destroyed the Converter!");
 
     for(i = 0; i < MAXPLAYERS; i++)
     {
@@ -2655,7 +2688,7 @@
     int i;
 
     // get name
-    name = mobjinfo[(MT_TOKEN_QUEST1 - 1) + actor->info->speed].name;
+    name = DEH_String(mobjinfo[(MT_TOKEN_QUEST1 - 1) + actor->info->speed].name);
     strcpy(pmsgbuffer, name);   // inlined in asm
 
     // give quest and display message to players
@@ -2860,12 +2893,159 @@
 
 //
 // A_BossDeath
+//
 // Possibly trigger special effects
 // if on first boss level
 //
-void A_BossDeath (mobj_t* mo)
+// haleyjd 09/17/10: [STRIFE]
+// * Modified to handle all Strife bosses.
+//
+void A_BossDeath (mobj_t* actor)
 {
-    // villsa [STRIFE] TODO - update to strife version
+    int i;
+    thinker_t *th;
+    line_t junk;
+
+    // only the following types can be a boss:
+    switch(actor->type)
+    {
+    case MT_CRUSADER:
+    case MT_SPECTRE_A:
+    case MT_SPECTRE_B:
+    case MT_SPECTRE_C:
+    case MT_SPECTRE_D:
+    case MT_SPECTRE_E:
+    case MT_SUBENTITY:
+    case MT_PROGRAMMER:
+        break;
+    default:
+        return;
+    }
+
+    // check for a living player
+    for(i = 0; i < MAXPLAYERS; i++)
+    {
+        if(playeringame[i] && players[i].health > 0)
+            break;
+    }
+    if(i == MAXPLAYERS)
+        return; // everybody's dead.
+
+    // check for a still living boss
+    for(th = thinkercap.next; th != &thinkercap; th = th->next)
+    {
+        if(th->function.acp1 == P_MobjThinker)
+        {
+            mobj_t *mo = (mobj_t *)th;
+
+            if(mo != actor && mo->type == actor->type && mo->health > 0)
+                return; // one is still alive.
+        }
+    }
+
+    // Victory!
+    switch(actor->type)
+    {
+    case MT_CRUSADER:
+        junk.tag = 667;
+        EV_DoFloor(&junk, lowerFloorToLowest);
+        break;
+
+    case MT_SPECTRE_A:
+        GiveVoiceObjective("VOC95", "LOG95", 0);
+        junk.tag = 999;
+        EV_DoFloor(&junk, lowerFloorToLowest);
+        break;
+
+    case MT_SPECTRE_B:
+        P_GiveItemToPlayer(&players[0], SPR_TOKN, MT_TOKEN_BISHOP);
+        GiveVoiceObjective("VOC74", "LOG74", 0);
+        break;
+
+    case MT_SPECTRE_C:
+        // Look for an MT_ORACLE - this is for in case the player awakened the 
+        // Oracle's spectre without killing the Oracle, which is possible by 
+        // looking up to max and firing the Sigil at it. If this were not done,
+        // a serious sequence break possibility would arise where one could 
+        // kill both the Oracle AND Macil, possibly throwing the game out of
+        // sorts entirely. Too bad they thought of it ;)  However this also
+        // causes a bug sometimes! The Oracle, in its death state, sets the
+        // Spectre C back to its seestate. If the Spectre C is already dead,
+        // it becomes an undead ghost monster. Then it's a REAL spectre ;)
+        for(th = thinkercap.next; th != &thinkercap; th = th->next)
+        {
+            if(th->function.acp1 == P_MobjThinker)
+            {
+                mobj_t *mo = (mobj_t *)th;
+
+                // KILL ALL ORACLES! RAWWR!
+                if(mo != actor && mo->type == MT_ORACLE && mo->health > 0)
+                    P_KillMobj(actor, mo);
+            }
+        }
+        P_GiveItemToPlayer(&players[0], SPR_TOKN, MT_TOKEN_ORACLE);
+        
+        // Bishop is dead? - verify.
+        if(players[0].questflags & QF_QUEST21) 
+            P_GiveItemToPlayer(&players[0], SPR_TOKN, MT_TOKEN_QUEST22);
+
+        // Macil is dead?
+        if(players[0].questflags & QF_QUEST24)
+        {
+            // Loremaster is dead?
+            if(players[0].questflags & QF_QUEST26)
+            {
+                // We wield the complete sigil, blahblah
+                GiveVoiceObjective("VOC85", "LOG85", 0);
+            }
+        }
+        else
+        {
+            // So much for prognostication.
+            GiveVoiceObjective("VOC87", "LOG87", 0);
+        }
+        junk.tag = 222;         // Open the exit door again;
+        EV_DoDoor(&junk, open); // Note this is NOT the Loremaster door...
+        break;
+
+    case MT_SPECTRE_D:
+        P_GiveItemToPlayer(&players[0], SPR_TOKN, MT_TOKEN_MACIL);
+        if(players[0].questflags & QF_QUEST25) // Destroyed converter?
+            GiveVoiceObjective("VOC106", "LOG106", 0);
+        else
+            GiveVoiceObjective("VOC79", "LOG79", 0);
+        break;
+
+    case MT_SPECTRE_E:
+        P_GiveItemToPlayer(&players[0], SPR_TOKN, MT_TOKEN_LOREMASTER);
+        if(!netgame)
+        {
+            P_GiveItemToPlayer(&players[0], SPR_TOKN, MT_TOKEN_STAMINA);
+            P_GiveItemToPlayer(&players[0], SPR_TOKN, MT_TOKEN_NEW_ACCURACY);
+        }
+        if(players[0].sigiltype == 4)
+            GiveVoiceObjective("VOC85", "LOG85", 0);
+        else
+            GiveVoiceObjective("VOC83", "LOG83", 0);
+        junk.tag = 666;
+        EV_DoFloor(&junk, lowerFloorToLowest);
+        break;
+
+    case MT_SUBENTITY:
+        F_StartFinale();
+        break;
+
+    case MT_PROGRAMMER:
+        F_StartFinale();
+        G_ExitLevel(0);
+        break;
+
+    default:
+        // Real classy, Rogue.
+        if(actor->type)
+            I_Error("Error: Unconnected BossDeath id %d", actor->type);
+        break;
+    }
 }
 
 //
@@ -2909,7 +3089,7 @@
             I_StartVoice(DEH_String("VOC14"));
 
             // give objective
-            GiveObjective("LOG14");
+            GiveObjective("LOG14", 0);
         }
     }
 }
--- a/src/strife/p_inter.c
+++ b/src/strife/p_inter.c
@@ -839,7 +839,7 @@
             EV_DoFloor(&junk, lowerFloor);
 
             I_StartVoice(DEH_String("VOC13"));
-            GiveObjective("LOG13");
+            GiveObjective("LOG13", 0);
 
             item = MT_COUPLING_BROKEN;
             players[0].questflags |= (1 << (mobjinfo[MT_COUPLING].speed - 1));