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));