summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJames Haley2010-09-05 23:28:16 +0000
committerJames Haley2010-09-05 23:28:16 +0000
commitf7768ad7dcfbefce525d846ce2f565dacf99f546 (patch)
tree8e5e071d261338984f90d901ff63cb10cf684f4e /src
parentcb79caae119fe361d0c5835ae91a9a1f0bf8147f (diff)
downloadchocolate-doom-f7768ad7dcfbefce525d846ce2f565dacf99f546.tar.gz
chocolate-doom-f7768ad7dcfbefce525d846ce2f565dacf99f546.tar.bz2
chocolate-doom-f7768ad7dcfbefce525d846ce2f565dacf99f546.zip
Corrections to some of Kaiser's previous commits. Also, significant work
on dialog engine, p_enemy code, and support for all new mapthing_t flag values in P_SpawnMapThing. Subversion-branch: /branches/strife-branch Subversion-revision: 2015
Diffstat (limited to 'src')
-rw-r--r--src/strife/d_main.c2
-rw-r--r--src/strife/d_net.c1
-rw-r--r--src/strife/doomdef.h14
-rw-r--r--src/strife/doomstat.h2
-rw-r--r--src/strife/g_game.c11
-rw-r--r--src/strife/info.c14
-rw-r--r--src/strife/m_menu.c202
-rw-r--r--src/strife/m_menu.h39
-rw-r--r--src/strife/p_dialog.c579
-rw-r--r--src/strife/p_dialog.h32
-rw-r--r--src/strife/p_enemy.c911
-rw-r--r--src/strife/p_map.c10
-rw-r--r--src/strife/p_mobj.c80
-rw-r--r--src/strife/p_mobj.h82
-rw-r--r--src/strife/p_pspr.c2
-rw-r--r--src/strife/p_setup.c2
-rw-r--r--src/strife/p_tick.c4
-rw-r--r--src/strife/r_draw.c62
18 files changed, 1465 insertions, 584 deletions
diff --git a/src/strife/d_main.c b/src/strife/d_main.c
index a203ef3d..ba0d8145 100644
--- a/src/strife/d_main.c
+++ b/src/strife/d_main.c
@@ -498,7 +498,7 @@ void D_DoomLoop (void)
{
TryRunTics (); // will run at least one tic
}
-
+
S_UpdateSounds (players[consoleplayer].mo);// move positional sounds
// Update display, next frame, with current state.
diff --git a/src/strife/d_net.c b/src/strife/d_net.c
index e30ead83..c8742c71 100644
--- a/src/strife/d_net.c
+++ b/src/strife/d_net.c
@@ -604,6 +604,7 @@ void TryRunTics (void)
G_Ticker ();
gametic++;
+
// modify command for duplicated tics
if (i != ticdup-1)
{
diff --git a/src/strife/doomdef.h b/src/strife/doomdef.h
index 50db2fc8..c73a0b78 100644
--- a/src/strife/doomdef.h
+++ b/src/strife/doomdef.h
@@ -79,9 +79,9 @@ typedef enum
//
// Skill flags.
-#define MTF_EASY 1
-#define MTF_NORMAL 2
-#define MTF_HARD 4
+#define MTF_EASY 1
+#define MTF_NORMAL 2
+#define MTF_HARD 4
// villsa [STRIFE] standing monsters
#define MTF_STAND 8
// villsa [STRIFE] don't spawn in single player
@@ -91,13 +91,13 @@ typedef enum
// villsa [STRIFE] friendly to players
#define MTF_FRIEND 64
// villsa [STRIFE] TODO - identify
-#define MTF_UNKNOWN 128
-// villsa [STRIFE] thing is translucent
+#define MTF_UNKNOWN1 128
+// villsa [STRIFE] thing is translucent - STRIFE-TODO: But how much?
#define MTF_TRANSLUCENT 256
-// villsa [STRIFE] TODO - identify
+// villsa [STRIFE] thing is more - or less? - translucent - STRIFE-TODO
#define MTF_MVIS 512
// villsa [STRIFE] TODO - identify
-#define MTF_RESERVED 1024
+#define MTF_UNKNOWN2 1024
diff --git a/src/strife/doomstat.h b/src/strife/doomstat.h
index 6aaaf976..81095ed4 100644
--- a/src/strife/doomstat.h
+++ b/src/strife/doomstat.h
@@ -141,6 +141,8 @@ extern boolean statusbaractive;
extern boolean automapactive; // In AutoMap mode?
extern boolean menuactive; // Menu overlayed?
extern boolean menupause; // haleyjd 08/29/10: [STRIFE]
+extern int menupausetime; // haleyjd 09/04/10: [STRIFE]
+extern boolean menuindialog; // haleyjd: ditto
extern boolean paused; // Game Pause?
diff --git a/src/strife/g_game.c b/src/strife/g_game.c
index 2b7c2cb0..49c4ef24 100644
--- a/src/strife/g_game.c
+++ b/src/strife/g_game.c
@@ -493,7 +493,6 @@ void G_BuildTiccmd (ticcmd_t* cmd)
cmd->buttons |= BT_ATTACK;
else
--mouse_fire_countdown;
-
}
if (gamekeydown[key_use]
@@ -816,9 +815,7 @@ boolean G_Responder (event_t* ev)
return false;
}
-
-
-
+
//
// G_Ticker
// Make ticcmd_ts for the players.
@@ -828,7 +825,7 @@ void G_Ticker (void)
int i;
int buf;
ticcmd_t* cmd;
-
+
// do player reborns if needed
for (i=0 ; i<MAXPLAYERS ; i++)
if (playeringame[i] && players[i].playerstate == PST_REBORN)
@@ -885,9 +882,9 @@ void G_Ticker (void)
memcpy (cmd, &netcmds[i][buf], sizeof(ticcmd_t));
- if (demoplayback)
+ if (demoplayback)
G_ReadDemoTiccmd (cmd);
- if (demorecording)
+ if (demorecording)
G_WriteDemoTiccmd (cmd);
// check for turbo cheats
diff --git a/src/strife/info.c b/src/strife/info.c
index d1decf6d..f5eccaaf 100644
--- a/src/strife/info.c
+++ b/src/strife/info.c
@@ -3570,7 +3570,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
sfx_alnact, //activesound
MF_SPECIAL|MF_SOLID|MF_SHOOTABLE|MF_NOGRAVITY|MF_GIVEQUEST
|MF_FLOAT|MF_INCOMBAT|MF_SHADOW|MF_COUNTKILL|MF_NOTDMATCH
- |MF_MOREVISIBLE|MF_SPECTRAL, //flags
+ |MF_MVIS|MF_SPECTRAL, //flags
NULL, //namepointer
},
@@ -3653,7 +3653,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
sfx_alnact, //activesound
MF_SPECIAL|MF_SOLID|MF_SHOOTABLE|MF_NOGRAVITY|MF_GIVEQUEST
|MF_FLOAT|MF_INCOMBAT|MF_SHADOW|MF_COUNTKILL|MF_NOTDMATCH
- |MF_MOREVISIBLE|MF_SPECTRAL, //flags
+ |MF_MVIS|MF_SPECTRAL, //flags
NULL, //namepointer
},
@@ -3682,7 +3682,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
sfx_alnact, //activesound
MF_SPECIAL|MF_SOLID|MF_SHOOTABLE|MF_NOGRAVITY|MF_GIVEQUEST
|MF_FLOAT|MF_INCOMBAT|MF_SHADOW|MF_COUNTKILL|MF_NOTDMATCH
- |MF_MOREVISIBLE|MF_SPECTRAL, //flags
+ |MF_MVIS|MF_SPECTRAL, //flags
NULL, //namepointer
},
@@ -3711,7 +3711,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
sfx_alnact, //activesound
MF_SPECIAL|MF_SOLID|MF_SHOOTABLE|MF_NOGRAVITY|MF_GIVEQUEST
|MF_FLOAT|MF_INCOMBAT|MF_SHADOW|MF_COUNTKILL|MF_NOTDMATCH
- |MF_MOREVISIBLE|MF_SPECTRAL, //flags
+ |MF_MVIS|MF_SPECTRAL, //flags
NULL, //namepointer
},
@@ -3740,7 +3740,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
sfx_alnact, //activesound
MF_SPECIAL|MF_SOLID|MF_SHOOTABLE|MF_NOGRAVITY|MF_GIVEQUEST
|MF_FLOAT|MF_INCOMBAT|MF_SHADOW|MF_COUNTKILL|MF_NOTDMATCH
- |MF_MOREVISIBLE|MF_SPECTRAL, //flags
+ |MF_MVIS|MF_SPECTRAL, //flags
NULL, //namepointer
},
@@ -3769,7 +3769,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
sfx_alnact, //activesound
MF_SPECIAL|MF_SOLID|MF_SHOOTABLE|MF_NOGRAVITY|MF_GIVEQUEST
|MF_FLOAT|MF_INCOMBAT|MF_SHADOW|MF_COUNTKILL|MF_NOTDMATCH
- |MF_MOREVISIBLE|MF_SPECTRAL, //flags
+ |MF_MVIS|MF_SPECTRAL, //flags
NULL, //namepointer
},
@@ -3798,7 +3798,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
sfx_alnact, //activesound
MF_SPECIAL|MF_SOLID|MF_SHOOTABLE|MF_NOGRAVITY|MF_GIVEQUEST
|MF_FLOAT|MF_INCOMBAT|MF_SHADOW|MF_COUNTKILL|MF_NOTDMATCH
- |MF_MOREVISIBLE|MF_SPECTRAL, //flags
+ |MF_MVIS|MF_SPECTRAL, //flags
NULL, //namepointer
},
diff --git a/src/strife/m_menu.c b/src/strife/m_menu.c
index 5800aefc..8516d446 100644
--- a/src/strife/m_menu.c
+++ b/src/strife/m_menu.c
@@ -125,7 +125,9 @@ char saveOldString[SAVESTRINGSIZE];
boolean inhelpscreens;
boolean menuactive;
-boolean menupause; // haleyjd 08/29/10: [STRIFE] New global
+boolean menupause; // haleyjd 08/29/10: [STRIFE] New global
+int menupausetime; // haleyjd 09/04/10: [STRIFE] New global
+boolean menuindialog; // haleyjd 09/04/10: ditto
// haleyjd 08/27/10: [STRIFE] SKULLXOFF == -28, LINEHEIGHT == 19
#define CURSORXOFF -28
@@ -136,38 +138,8 @@ char savegamestrings[10][SAVESTRINGSIZE];
char endstring[160];
-
-//
-// MENU TYPEDEFS
-//
-typedef struct
-{
- // 0 = no cursor here, 1 = ok, 2 = arrows ok
- short status;
-
- char name[10];
-
- // choice = menu item #.
- // if status = 2,
- // choice=0:leftarrow,1:rightarrow
- void (*routine)(int choice);
-
- // hotkey in menu
- char alphaKey;
-} menuitem_t;
-
-
-
-typedef struct menu_s
-{
- short numitems; // # of menu items
- struct menu_s* prevMenu; // previous menu
- menuitem_t* menuitems; // menu items
- void (*routine)(); // draw routine
- short x;
- short y; // x,y of menu
- short lastOn; // last item user was on in menu
-} menu_t;
+// haleyjd 09/04/10: [STRIFE] Moved menuitem / menu structures into header
+// because they are needed externally by the dialog engine.
// haleyjd 08/27/10: [STRIFE] skull* stuff changed to cursor* stuff
short itemOn; // menu item skull is on
@@ -230,7 +202,6 @@ void M_SetupNextMenu(menu_t *menudef);
void M_DrawThermo(int x,int y,int thermWidth,int thermDot);
void M_DrawEmptyCell(menu_t *menu,int item);
void M_DrawSelCell(menu_t *menu,int item);
-void M_WriteText(int x, int y, char *string);
int M_StringWidth(char *string);
int M_StringHeight(char *string);
void M_StartControlPanel(void);
@@ -1391,9 +1362,13 @@ int M_StringHeight(char* string)
//
-// Write a string using the hu_font
+// M_WriteText
//
-void
+// Write a string using the hu_font
+// haleyjd 09/04/10: [STRIFE]
+// * Rogue made a lot of changes to this for the dialog system.
+//
+int
M_WriteText
( int x,
int y,
@@ -1404,39 +1379,142 @@ M_WriteText
int c;
int cx;
int cy;
-
ch = string;
cx = x;
cy = y;
-
+
while(1)
{
- c = *ch++;
- if (!c)
- break;
- if (c == '\n')
- {
- cx = x;
- cy += 12;
- continue;
- }
-
- c = toupper(c) - HU_FONTSTART;
- if (c < 0 || c>= HU_FONTSIZE)
- {
- cx += 4;
- continue;
- }
-
- w = SHORT (hu_font[c]->width);
- if (cx+w > SCREENWIDTH)
- break;
- V_DrawPatchDirect(cx, cy, hu_font[c]);
- cx+=w;
+ c = *ch++;
+ if (!c)
+ break;
+
+ // haleyjd 09/04/10: [STRIFE] Don't draw spaces at the start of lines.
+ if(c == ' ' && cx == x)
+ continue;
+
+ if (c == '\n')
+ {
+ cx = x;
+ cy += 11; // haleyjd 09/04/10: [STRIFE]: Changed 12 -> 11
+ continue;
+ }
+
+ c = toupper(c) - HU_FONTSTART;
+ if (c < 0 || c>= HU_FONTSIZE)
+ {
+ cx += 4;
+ continue;
+ }
+
+ w = SHORT (hu_font[c]->width);
+
+ // haleyjd 09/04/10: [STRIFE] Different linebreak handling
+ if (cx + w > SCREENWIDTH - 20)
+ {
+ cx = x;
+ cy += 11;
+ --ch;
+ }
+ else
+ {
+ V_DrawPatchDirect(cx, cy, hu_font[c]);
+ cx += w;
+ }
}
+
+ // [STRIFE] Return final y coordinate.
+ return cy + 12;
}
+//
+// M_DialogDimMsg
+//
+// [STRIFE] New function
+// haleyjd 09/04/10: Painstakingly transformed from the assembly code, as the
+// decompiler could not touch it. Redimensions a string to fit on screen, leaving
+// at least a 20 pixel margin on the right side. The string passed in must be
+// writable.
+//
+void M_DialogDimMsg(int x, int y, char *str, boolean useyfont)
+{
+ int rightbound = (SCREENWIDTH - 20) - x;
+ patch_t **fontarray; // ebp
+ int linewidth = 0; // esi
+ int i = 0; // edx
+ char *message = str; // edi
+ char bl; // bl
+
+ /*
+ STRIFE-TODO:
+ if(useyfont)
+ fontarray = yfont;
+ else
+ fontarray = hu_font;
+ */
+ fontarray = hu_font;
+
+ bl = toupper(*message);
+
+ if(!bl)
+ return;
+
+ // outer loop - run to end of string
+ do
+ {
+ if(bl != '\n')
+ {
+ int charwidth; // eax
+ int tempwidth; // ecx
+
+ if(bl < HU_FONTSTART || bl > HU_FONTEND)
+ charwidth = 4;
+ else
+ charwidth = SHORT(fontarray[bl - HU_FONTSTART]->width);
+
+ tempwidth = linewidth + charwidth;
+
+ // Test if the line still fits within the boundary...
+ if(tempwidth >= rightbound)
+ {
+ // Doesn't fit...
+ char *tempptr = &message[i]; // ebx
+ char al; // al
+
+ // inner loop - run backward til a space (or the start of the
+ // string) is found, subtracting width off the current line.
+ // BUG: shouldn't we stop at a previous '\n' too?
+ while(*tempptr != ' ' && i > 0)
+ {
+ tempptr--;
+ // BUG: they didn't add the first char to linewidth yet...
+ linewidth -= charwidth;
+ i--;
+ al = toupper(*tempptr);
+ if(al < HU_FONTSTART || al > HU_FONTEND)
+ charwidth = 4;
+ else
+ charwidth = SHORT(fontarray[al - HU_FONTSTART]->width);
+ }
+ // Replace the space with a linebreak.
+ // BUG: what if i is zero? ... infinite loop time!
+ message[i] = '\n';
+ linewidth = 0;
+ }
+ else
+ {
+ // The line does fit.
+ // Spaces at the start of a line don't count though.
+ if(!(bl == ' ' && linewidth == 0))
+ linewidth += charwidth;
+ }
+ }
+ else
+ linewidth = 0; // '\n' seen, so reset the line width
+ }
+ while((bl = toupper(message[++i])) != 0); // step to the next character
+}
//
@@ -1461,7 +1539,7 @@ boolean M_Responder (event_t* ev)
// "close" button pressed on window?
if (ev->type == ev_quit)
{
- S_StartSound(NULL,sfx_swtchn);
+ S_StartSound(NULL, sfx_swtchn);
M_QuitDOOM(0);
return true;
}
@@ -1899,7 +1977,7 @@ void M_StartControlPanel (void)
{
// intro might call this repeatedly
if (menuactive)
- return;
+ return;
menuactive = 1;
currentMenu = &MainDef; // JDC
diff --git a/src/strife/m_menu.h b/src/strife/m_menu.h
index c06fe981..82848126 100644
--- a/src/strife/m_menu.h
+++ b/src/strife/m_menu.h
@@ -28,9 +28,40 @@
#ifndef __M_MENU__
#define __M_MENU__
+#include "d_event.h"
+//
+// MENU TYPEDEFS
+//
-#include "d_event.h"
+// haleyjd 09/04/10: [STRIFE] Made external
+
+typedef struct
+{
+ // 0 = no cursor here, 1 = ok, 2 = arrows ok
+ short status;
+
+ char name[10];
+
+ // choice = menu item #.
+ // if status = 2,
+ // choice=0:leftarrow,1:rightarrow
+ void (*routine)(int choice);
+
+ // hotkey in menu
+ char alphaKey;
+} menuitem_t;
+
+typedef struct menu_s
+{
+ short numitems; // # of menu items
+ struct menu_s* prevMenu; // previous menu
+ menuitem_t* menuitems; // menu items
+ void (*routine)(); // draw routine
+ short x;
+ short y; // x,y of menu
+ short lastOn; // last item user was on in menu
+} menu_t;
//
// MENUS
@@ -59,11 +90,13 @@ void M_Init (void);
// does nothing if menu is already up.
void M_StartControlPanel (void);
+// haleyjd 09/04/10: Externalized. Draws menu text.
+int M_WriteText(int x, int y, char *string);
+// haleyjd 09/04/10: [STRIFE] New function.
+void M_DialogDimMsg(int x, int y, char *str, boolean useyfont);
extern int detailLevel;
extern int screenblocks;
-
-
#endif
diff --git a/src/strife/p_dialog.c b/src/strife/p_dialog.c
index 2b20f55d..853fe15b 100644
--- a/src/strife/p_dialog.c
+++ b/src/strife/p_dialog.c
@@ -33,6 +33,10 @@
#include "deh_str.h"
#include "d_player.h"
#include "doomstat.h"
+#include "m_random.h"
+#include "m_menu.h"
+#include "r_main.h"
+#include "v_video.h"
#include "p_dialog.h"
@@ -43,6 +47,25 @@
// haleyjd: size of the original Strife mapdialog_t structure.
#define ORIG_MAPDIALOG_SIZE 0x5EC
+#define DIALOG_INT(field, ptr) \
+ field = ((int)ptr[0] | \
+ ((int)ptr[1] << 8) | \
+ ((int)ptr[2] << 16) | \
+ ((int)ptr[3] << 24)); \
+ ptr += 4;
+
+#define DIALOG_STR(field, ptr, len) \
+ memcpy(field, ptr, len); \
+ ptr += len;
+
+//
+// Globals
+//
+
+// This can be toggled at runtime to determine if the full dialog messages
+// are subtitled on screen or not. Defaults to off.
+boolean dialogshowtext = false;
+
//
// Static Globals
//
@@ -64,27 +87,291 @@ static mapdialog_t *script0dialogs;
// Number of dialogs defined in the SCRIPT00 lump.
static int numscript0dialogs;
+// The player engaged in dialog. This is always player 1, though, since Rogue
+// never completed the ability to use dialog outside of single-player mode.
+player_t *dialogplayer;
+
+// The object to which the player is speaking.
+mobj_t *dialogtalker;
+
+// The currently active mapdialog object.
+static mapdialog_t *currentdialog;
+
+//=============================================================================
//
-// Routines
+// Dialog State Sets
+//
+// These are used to animate certain actors in response to what happens in
+// their dialog sequences.
//
-#define DIALOG_INT(field, ptr) \
- field = ((int)ptr[0] | \
- ((int)ptr[1] << 8) | \
- ((int)ptr[2] << 16) | \
- ((int)ptr[3] << 24)); \
- ptr += 4;
+typedef struct dialogstateset_s
+{
+ mobjtype_t type; // the type of object
+ statenum_t greet; // greeting state, for start of dialog
+ statenum_t yes; // "yes" state, for an affirmative response
+ statenum_t no; // "no" state, when you don't have the right items
+} dialogstateset_t;
-#define DIALOG_STR(field, ptr, len) \
- memcpy(field, ptr, len); \
- ptr += len;
+static dialogstateset_t dialogstatesets[] =
+{
+ { MT_PLAYER, S_NULL, S_NULL, S_NULL },
+ { MT_SHOPKEEPER_W, S_MRGT_00, S_MRYS_00, S_MRNO_00 },
+ { MT_SHOPKEEPER_B, S_MRGT_00, S_MRYS_00, S_MRNO_00 },
+ { MT_SHOPKEEPER_A, S_MRGT_00, S_MRYS_00, S_MRNO_00 },
+ { MT_SHOPKEEPER_M, S_MRGT_00, S_MRYS_00, S_MRNO_00 }
+};
+
+// Rogue stored this in a static global rather than making it a define...
+static int numdialogstatesets = arrlen(dialogstatesets);
+
+//=============================================================================
+//
+// Random Messages
+//
+// Rogue hard-coded these so they wouldn't have to repeat them several times
+// in the SCRIPT00 lump, apparently.
+//
+
+#define MAXRNDMESSAGES 10
+
+typedef struct rndmessage_s
+{
+ const char *type_name;
+ int nummessages;
+ const char *messages[MAXRNDMESSAGES];
+} rndmessage_t;
+
+static rndmessage_t rndMessages[] =
+{
+ // Peasants
+ {
+ "PEASANT",
+ 10,
+ {
+ "PLEASE DON'T HURT ME.",
+
+ "IF YOU'RE LOOKING TO HURT ME, I'M \n"
+ "NOT REALLY WORTH THE EFFORT.",
+
+ "I DON'T KNOW ANYTHING.",
+
+ "GO AWAY OR I'LL CALL THE GUARDS!",
+
+ "I WISH SOMETIMES THAT ALL THESE \n"
+ "REBELS WOULD JUST LEARN THEIR \n"
+ "PLACE AND STOP THIS NONSENSE.",
+
+ "JUST LEAVE ME ALONE, OK?",
+
+ "I'M NOT SURE, BUT SOMETIMES I THINK \n"
+ "THAT I KNOW SOME OF THE ACOLYTES.",
+
+ "THE ORDER'S GOT EVERYTHING AROUND HERE PRETTY WELL LOCKED UP TIGHT.",
+
+ "THERE'S NO WAY THAT THIS IS JUST A \n"
+ "SECURITY FORCE.",
+
+ "I'VE HEARD THAT THE ORDER IS REALLY \n"
+ "NERVOUS ABOUT THE FRONT'S \n"
+ "ACTIONS AROUND HERE."
+ }
+ },
+ // Rebel
+ {
+ "REBEL",
+ 10,
+ {
+ "THERE'S NO WAY THE ORDER WILL \n"
+ "STAND AGAINST US.",
+
+ "WE'RE ALMOST READY TO STRIKE. \n"
+ "MACIL'S PLANES ARE FALLING IN PLACE.",
+
+ "WE'RE ALL BEHIND YOU, DON'T WORRY.",
+
+ "DON'T GET TOO CLOSE TO ANY OF THOSE BIG ROBOTS. THEY'LL MELT YOU DOWN \n"
+ "FOR SCRAP!",
+
+ "THE DAY OF OUR GLORY WILL SOON \n"
+ "COME, AND THOSE WHO OPPOSE US WILL \n"
+ "BE CRUSHED!",
+
+ "DON'T GET TOO COMFORTABLE. WE'VE \n"
+ "STILL GOT OUR WORK CUT OUT FOR US.",
+
+ "MACIL SAYS THAT YOU'RE THE NEW \n"
+ "HOPE. BEAR THAT IN MIND.",
+
+ "ONCE WE'VE TAKEN THESE CHARLATANS DOWN, WE'LL BE ABLE TO REBUILD THIS "
+ "WORLD AS IT SHOULD BE.",
+
+ "REMEMBER THAT YOU AREN'T FIGHTING \n"
+ "JUST FOR YOURSELF, BUT FOR \n"
+ "EVERYONE HERE AND OUTSIDE.",
+
+ "AS LONG AS ONE OF US STILL STANDS, \n"
+ "WE WILL WIN."
+ }
+ },
+ // Acolyte
+ {
+ "AGUARD",
+ 10,
+ {
+ "MOVE ALONG, PEASANT.",
+
+ "FOLLOW THE TRUE FAITH, ONLY THEN \n"
+ "WILL YOU BEGIN TO UNDERSTAND.",
+
+ "ONLY THROUGH DEATH CAN ONE BE \n"
+ "TRULY REBORN.",
+
+ "I'M NOT INTERESTED IN YOUR USELESS \n"
+ "DRIVEL.",
+
+ "IF I HAD WANTED TO TALK YOU I \n"
+ "WOULD HAVE TOLD YOU SO.",
+
+ "GO AND ANNOY SOMEONE ELSE!",
+
+ "KEEP MOVING!",
+
+ "IF THE ALARM GOES OFF, JUST STAY OUT OF OUR WAY!",
+
+ "THE ORDER WILL CLEANSE THE WORLD \n"
+ "AND USHER IT INTO THE NEW ERA.",
+
+ "PROBLEM? NO, I THOUGHT NOT.",
+ }
+ },
+ // Beggar
+ {
+ "BEGGAR",
+ 10,
+ {
+ "ALMS FOR THE POOR?",
+
+ "WHAT ARE YOU LOOKING AT, SURFACER?",
+
+ "YOU WOULDN'T HAVE ANY EXTRA FOOD, WOULD YOU?",
+
+ "YOU SURFACE PEOPLE WILL NEVER \n"
+ " "
+ " UNDERSTAND US.",
+
+ "HA, THE GUARDS CAN'T FIND US. THOSE \n"
+ "IDIOTS DON'T EVEN KNOW WE EXIST.",
+
+ "ONE DAY EVERYONE BUT THOSE WHO SERVE THE ORDER WILL BE FORCED TO "
+ " JOIN US.",
+
+ "STARE NOW, BUT YOU KNOW THAT THIS WILL BE YOUR OWN FACE ONE DAY.",
+
+ "THERE'S NOTHING THING MORE \n"
+ "ANNOYING THAN A SURFACER WITH AN ATTITUDE!",
+
+ "THE ORDER WILL MAKE SHORT WORK OF YOUR PATHETIC FRONT.",
+
+ "WATCH YOURSELF SURFACER. WE KNOW OUR ENEMIES!"
+ }
+ },
+ // Templar
+ {
+ "PGUARD",
+ 10,
+ {
+ "WE ARE THE HANDS OF FATE. TO EARN \n"
+ "OUR WRATH IS TO FIND OBLIVION!",
+
+ "THE ORDER WILL CLEANSE THE WORLD \n"
+ "OF THE WEAK AND CORRUPT!",
+
+ "OBEY THE WILL OF THE MASTERS!",
+
+ "LONG LIFE TO THE BROTHERS OF THE \n"
+ "ORDER!",
+
+ "FREE WILL IS AN ILLUSION THAT BINDS \n"
+ "THE WEAK MINDED.",
+
+ "POWER IS THE PATH TO GLORY. TO \n"
+ "FOLLOW THE ORDER IS TO WALK THAT \n"
+ "PATH!",
+
+ "TAKE YOUR PLACE AMONG THE \n"
+ "RIGHTEOUS, JOIN US!",
+
+ "THE ORDER PROTECTS ITS OWN.",
+
+ "ACOLYTES? THEY HAVE YET TO SEE THE FULL GLORY OF THE ORDER.",
+
+ "IF THERE IS ANY HONOR INSIDE THAT \n"
+ "PATHETIC SHELL OF A BODY, \n"
+ "YOU'LL ENTER INTO THE ARMS OF THE \n"
+ "ORDER."
+ }
+ }
+};
+
+// And again, this could have been a define, but was a variable.
+static int numrndmessages = arrlen(rndMessages);
+
+//=============================================================================
+//
+// Dialog Menu Structure
+//
+// The Strife dialog system is actually just a serious abuse of the DOOM menu
+// engine. Hence why it doesn't work in multiplayer games or during demo
+// recording.
+//
+
+#define NUMDIALOGMENUITEMS 6
+
+static void P_DialogDrawer(void);
+static void P_DialogDoChoice(int choice);
+
+static menuitem_t dialogmenuitems[] =
+{
+ { 1, "", P_DialogDoChoice, '1' }, // These items are loaded dynamically
+ { 1, "", P_DialogDoChoice, '2' },
+ { 1, "", P_DialogDoChoice, '3' },
+ { 1, "", P_DialogDoChoice, '4' },
+ { 1, "", P_DialogDoChoice, '5' },
+ { 1, "", P_DialogDoChoice, '6' } // Item 6 is always the dismissal item
+};
+
+static menu_t dialogmenu =
+{
+ NUMDIALOGMENUITEMS,
+ NULL,
+ dialogmenuitems,
+ P_DialogDrawer,
+ 42,
+ 75,
+ 0
+};
+
+// Lump number of the dialog background picture, if any.
+static int dialogbgpiclumpnum;
+
+// Name of current speaking character.
+static char *dialogname;
+
+// Current dialog text.
+static char *dialogtext;
+
+//=============================================================================
+//
+// Routines
+//
//
// P_ParseDialogLump
//
-// haleyjd 09/02/10: This is a new function added to parse out the dialogs
-// from the dialog lump rather than reading them raw from the lump pointer.
-// This avoids problems with structure packing.
+// haleyjd 09/02/10: This is an original function added to parse out the
+// dialogs from the dialog lump rather than reading them raw from the lump
+// pointer. This avoids problems with structure packing.
//
static void P_ParseDialogLump(byte *lump, mapdialog_t **dialogs,
int numdialogs, int tag)
@@ -114,10 +401,10 @@ static void P_ParseDialogLump(byte *lump, mapdialog_t **dialogs,
for(j = 0; j < 5; j++)
{
mapdlgchoice_t *curchoice = &(curdialog->choices[j]);
- DIALOG_INT(curchoice->giveitem, rover);
- DIALOG_INT(curchoice->needitem1, rover);
- DIALOG_INT(curchoice->needitem2, rover);
- DIALOG_INT(curchoice->needitem3, rover);
+ DIALOG_INT(curchoice->giveitem, rover);
+ DIALOG_INT(curchoice->needitem1, rover);
+ DIALOG_INT(curchoice->needitem2, rover);
+ DIALOG_INT(curchoice->needitem3, rover);
DIALOG_INT(curchoice->needamount1, rover);
DIALOG_INT(curchoice->needamount2, rover);
DIALOG_INT(curchoice->needamount3, rover);
@@ -137,7 +424,7 @@ static void P_ParseDialogLump(byte *lump, mapdialog_t **dialogs,
// haleyjd 09/02/10: Loads the dialog script for the current map. Also loads
// SCRIPT00 if it has not yet been loaded.
//
-void P_DialogLoad(int eax0, int a2, int a3, int a4)
+void P_DialogLoad(void)
{
char lumpname[9];
int lumpnum;
@@ -206,3 +493,259 @@ int P_PlayerHasItem(player_t *player, mobjtype_t type)
return 0;
}
+//
+// P_DialogFind
+//
+// [STRIFE] New function
+// haleyjd 09/03/10: Looks for a dialog definition matching the given
+// Script ID # for an mobj.
+//
+mapdialog_t *P_DialogFind(int type)
+{
+ int i;
+
+ // check the map-specific dialogs first
+ for(i = 0; i < numleveldialogs; i++)
+ {
+ if(type == leveldialogs[i].speakerid)
+ return &leveldialogs[i];
+ }
+
+ // check SCRIPT00 dialogs next
+ for(i = 0; i < numscript0dialogs; i++)
+ {
+ if(type == script0dialogs[i].speakerid)
+ return &script0dialogs[i];
+ }
+
+ // the default dialog is script 0 in the SCRIPT00 lump.
+ return &script0dialogs[0];
+}
+
+//
+// P_DialogGetStates
+//
+// [STRIFE] New function
+// haleyjd 09/03/10: Find the set of special dialog states (greetings, yes, no)
+// for a particular thing type.
+// STRIFE-TODO: Or is it a conversation ID?
+//
+static dialogstateset_t *P_DialogGetStates(mobjtype_t type)
+{
+ int i;
+
+ // look for a match by type
+ for(i = 0; i < numdialogstatesets; i++)
+ {
+ if(type == dialogstatesets[i].type)
+ return &dialogstatesets[i];
+ }
+
+ // return the default 0 record if no match.
+ return &dialogstatesets[0];
+}
+
+//
+// P_DialogGetMsg
+//
+// [STRIFE] New function
+// haleyjd 09/03/10: Redirects dialog messages when the script indicates that
+// the actor should use a random message stored in the executable instead.
+//
+static const char *P_DialogGetMsg(const char *message)
+{
+ // if the message starts with "RANDOM"...
+ if(!strncasecmp(message, "RANDOM", 6))
+ {
+ int i;
+ const char *nameloc = message + 7;
+
+ // look for a match in rndMessages for the string starting
+ // 7 chars after "RANDOM_"
+ for(i = 0; i < numrndmessages; i++)
+ {
+ if(!strncasecmp(nameloc, rndMessages[i].type_name, 4))
+ {
+ // found a match, so return a random message
+ int rnd = M_Random();
+ int nummessages = rndMessages[i].nummessages;
+ return rndMessages[i].messages[rnd % nummessages];
+ }
+ }
+ }
+
+ // otherwise, just return the message passed in.
+ return message;
+}
+
+//
+// P_GiveInventoryItem
+//
+// [STRIFE] New function
+// haleyjd 09/03/10: Give an inventory item to the player, if possible.
+//
+boolean P_GiveInventoryItem(player_t *player, int a2, int a3)
+{
+ int v3 = 0;
+ int v15 = a2;
+ int v4 = a3;
+
+ // repaint the status bar due to inventory changing
+ player->st_update = true;
+
+ // STRIFE-TODO: do an insertion sort on the inventory...
+ // Too bad the code is nearly impossible to understand!!!
+
+ return true;
+}
+
+//
+// P_GiveItemToPlayer
+//
+// [STRIFE] New function
+// haleyjd 09/03/10: Sorts out how to give something to the player.
+// Not strictly just for inventory items.
+//
+boolean P_GiveItemToPlayer(player_t *player, int sprnum, mobjtype_t type)
+{
+ // haleyjd: STRIFE-TODO
+ return true;
+}
+
+//
+// P_TakeDialogItem
+//
+// [STRIFE] New function
+// haleyjd 09/03/10: Removes needed items from the player's inventory.
+//
+static void P_TakeDialogItem(player_t *player, int type, int amount)
+{
+ int i;
+
+ if(amount <= 0)
+ return;
+
+ for(i = 0; i < player->numinventory; i++)
+ {
+ // find a matching item
+ if(type != player->inventory[i].type)
+ continue;
+
+ // if there is none left...
+ if((player->inventory[i].amount -= amount) < 1)
+ {
+ // ...shift everything above it down
+ int j;
+
+ // BUG: They should have stopped at j < numinventory. This
+ // seems to implicitly assume that numinventory is always at
+ // least one less than the max # of slots, otherwise it
+ // pulls in data from the following player_t fields:
+ // st_update, numinventory, inventorycursor, accuracy, stamina
+ for(j = i + 1; j <= player->numinventory; j++)
+ {
+ inventory_t *item1 = &(player->inventory[j - 1]);
+ inventory_t *item2 = &(player->inventory[j]);
+
+ *item1 = *item2;
+ }
+
+ // blank the topmost slot
+ // BUG: This will overwrite the aforementioned fields if
+ // numinventory is equal to the number of slots!
+ // STRIFE-TODO: Overflow emulation?
+ player->inventory[player->numinventory].type = NUMMOBJTYPES;
+ player->inventory[player->numinventory].sprite = -1;
+ player->numinventory--;
+
+ // update cursor position
+ if(player->inventorycursor >= player->numinventory)
+ {
+ if(player->inventorycursor)
+ player->inventorycursor--;
+ }
+ } // end if
+
+ return; // done!
+
+ } // end for
+}
+
+//
+// P_DialogDrawer
+//
+// This function is set as the drawer callback for the dialog menu.
+//
+static void P_DialogDrawer(void)
+{
+ angle_t angle;
+ int y;
+ int height;
+ int finaly;
+
+ // Run down bonuscount faster than usual so that flashes from being given
+ // items are less obvious.
+ if(dialogplayer->bonuscount)
+ {
+ dialogplayer->bonuscount -= 3;
+ if(dialogplayer->bonuscount < 0)
+ dialogplayer->bonuscount = 0;
+ }
+
+ angle = R_PointToAngle2(dialogplayer->mo->x,
+ dialogplayer->mo->y,
+ dialogtalker->x,
+ dialogtalker->y);
+ angle -= dialogplayer->mo->angle;
+
+ // Dismiss the dialog if the player is out of alignment, or the thing he was
+ // talking to is now engaged in battle.
+ if(angle > 0x20000000 && angle < 0xE0000000 || dialogtalker->flags & MF_INCOMBAT)
+ P_DialogDoChoice(dialogmenu.numitems - 1);
+
+ dialogtalker->reactiontime = 2;
+
+ if(dialogbgpiclumpnum != -1)
+ {
+ patch_t *patch = W_CacheLumpNum(dialogbgpiclumpnum, PU_CACHE);
+ V_DrawPatchDirect(0, 0, patch);
+ }
+
+ if(menupausetime <= gametic)
+ {
+ if(menuindialog)
+ {
+ if(menupausetime + 3 < gametic)
+ menupause = true;
+ }
+ M_WriteText(12, 18, dialogname);
+ y = 28;
+
+ if(dialogshowtext || currentdialog->voice[0] == '\0')
+ y = M_WriteText(20, 28, dialogtext);
+
+ height = 20 * dialogmenu.numitems;
+
+ finaly = 175 - height; // preferred height
+ if(y > finaly)
+ finaly = 199 - height; // height it will bump down to if necessary.
+
+ M_WriteText(42, finaly - 6, "______________________________");
+
+ /*
+ dialogmenu
+ */
+ }
+}
+
+//
+// P_DialogDoChoice
+//
+// [STRIFE] New function
+// haleyjd 09/05/10: Handles making a choice in a dialog. Installed as the
+// callback for all items in the dialogmenu structure.
+//
+static void P_DialogDoChoice(int choice)
+{
+ // STRIFE-TODO
+}
diff --git a/src/strife/p_dialog.h b/src/strife/p_dialog.h
index 17ff46ca..3da79ba8 100644
--- a/src/strife/p_dialog.h
+++ b/src/strife/p_dialog.h
@@ -40,28 +40,28 @@
typedef struct mapdlgchoice_s
{
- int giveitem; // item given when successful
- int needitem1; // first item needed for success
- int needitem2; // second item needed for success, if any
- int needitem3; // third item needed for success, if any
- int needamount1; // amount of first item needed
- int needamount2; // amount of second item needed
- int needamount3; // amount of third item needed
+ int giveitem; // item given when successful
+ int needitem1; // first item needed for success
+ int needitem2; // second item needed for success, if any
+ int needitem3; // third item needed for success, if any
+ int needamount1; // amount of first item needed
+ int needamount2; // amount of second item needed
+ int needamount3; // amount of third item needed
char text[MDLG_CHOICELEN]; // normal text
char textok[MDLG_MSGLEN]; // message given on success
- int next; // next dialog?
- int objective; // ???
- char textno[MDLG_MSGLEN]; // message given on failure
+ int next; // next dialog?
+ int objective; // ???
+ char textno[MDLG_MSGLEN]; // message given on failure
} mapdlgchoice_t;
typedef struct mapdialog_s
{
- int speakerid; // script ID# for thingtype that will use this dialog
- int dropitem; // item to drop if that thingtype is killed
- int checkitem1; // first item needed to see this dialog
- int checkitem2; // second item needed to see this dialog, if any
- int checkitem3; // third item needed to see this dialog, if any
- int jumptoconv; // conversation to jump to when... ?
+ int speakerid; // script ID# for mobjtype that will use this dialog
+ int dropitem; // item to drop if that thingtype is killed
+ int checkitem1; // first item needed to see this dialog
+ int checkitem2; // second item needed to see this dialog, if any
+ int checkitem3; // third item needed to see this dialog, if any
+ int jumptoconv; // conversation to jump to when... ?
char name[MDLG_NAMELEN]; // name of speaker
char voice[MDLG_LUMPLEN]; // voice file to play
char backpic[MDLG_LUMPLEN]; // backdrop pic for character, if any
diff --git a/src/strife/p_enemy.c b/src/strife/p_enemy.c
index 9f3fb7a6..46a31881 100644
--- a/src/strife/p_enemy.c
+++ b/src/strife/p_enemy.c
@@ -47,6 +47,8 @@
#include "sounds.h"
+// Forward Declarations:
+void A_RandomWalk(mobj_t *);
typedef enum
@@ -100,6 +102,8 @@ void A_Fall (mobj_t *actor);
// Recursively traverse adjacent sectors,
// sound blocking lines cut off traversal.
//
+// haleyjd 09/05/10: [STRIFE] Verified unmodified
+//
mobj_t* soundtarget;
@@ -156,6 +160,8 @@ P_RecursiveSound
// If a monster yells at a player,
// it will alert other monsters to the player.
//
+// haleyjd 09/05/10: [STRIFE] Verified unmodified
+//
void
P_NoiseAlert
( mobj_t* target,
@@ -168,23 +174,25 @@ P_NoiseAlert
//
// P_WakeUpThing
-// villsa [STRIFE] new function
//
-
-static void P_WakeUpThing(mobj_t* puncher, mobj_t* rover)
+// villsa [STRIFE] New function
+// Wakes up an mobj.nearby when somebody has been punched.
+//
+static void P_WakeUpThing(mobj_t* puncher, mobj_t* bystander)
{
- if(!(rover->flags & MF_INCOMBAT))
+ if(!(bystander->flags & MF_INCOMBAT))
{
- rover->target = puncher;
- if(rover->info->seesound)
- S_StartSound(rover, rover->info->seesound);
- P_SetMobjState(rover, rover->info->seestate);
+ bystander->target = puncher;
+ if(bystander->info->seesound)
+ S_StartSound(bystander, bystander->info->seesound);
+ P_SetMobjState(bystander, bystander->info->seestate);
}
}
//
// P_DoPunchAlert
-// villsa [STRIFE] - new function
+//
+// villsa [STRIFE] New function (by Quasar ;)
// Wake up buddies nearby when the player thinks he's gotten too clever
// with the punch dagger. Walks sector links.
//
@@ -204,9 +212,9 @@ void P_DoPunchAlert(mobj_t *puncher, mobj_t *punchee)
if(!(punchee->flags & MF_COUNTKILL) || punchee->flags & MF_INCOMBAT)
return;
- // wake up punchee
+ // make the punchee hurt - haleyjd 09/05/10: Fixed to use painstate.
punchee->target = puncher;
- P_SetMobjState(punchee, punchee->info->seestate);
+ P_SetMobjState(punchee, punchee->info->painstate);
// wake up everybody nearby
@@ -218,7 +226,7 @@ void P_DoPunchAlert(mobj_t *puncher, mobj_t *punchee)
(P_CheckSight(rover, puncher) || P_CheckSight(rover, punchee)))
{
P_WakeUpThing(puncher, rover);
- rover->flags |= MF_INCOMBAT; // huh? why?
+ rover->flags |= MF_INCOMBAT;
}
}
@@ -230,7 +238,7 @@ void P_DoPunchAlert(mobj_t *puncher, mobj_t *punchee)
(P_CheckSight(rover, puncher) || P_CheckSight(rover, punchee)))
{
P_WakeUpThing(puncher, rover);
- rover->flags |= MF_INCOMBAT; // huh? why?
+ rover->flags |= MF_INCOMBAT;
}
}
}
@@ -241,14 +249,16 @@ void P_DoPunchAlert(mobj_t *puncher, mobj_t *punchee)
//
// P_CheckMeleeRange
//
+// [STRIFE] Minor change to meleerange.
+//
boolean P_CheckMeleeRange(mobj_t* actor)
{
mobj_t* pl;
fixed_t dist;
-
+
if(!actor->target)
- return false;
-
+ return false;
+
pl = actor->target;
if(actor->z + 3 * actor->height / 2 < pl->z) // villsa [STRIFE]
return false;
@@ -257,81 +267,101 @@ boolean P_CheckMeleeRange(mobj_t* actor)
// villsa [STRIFE] change to 36
if(dist >= MELEERANGE - 36*FRACUNIT + pl->info->radius)
- return false;
-
+ return false;
+
if(!P_CheckSight (actor, actor->target))
- return false;
-
- return true;
+ return false;
+
+ return true;
}
//
// P_CheckMissileRange
//
+// [STRIFE]
+// Changes to eliminate DOOM-specific code and to allow for
+// varying attack ranges for Strife monsters, as well as a general tweak
+// to considered distance for all monsters.
+//
boolean P_CheckMissileRange(mobj_t* actor)
{
fixed_t dist;
-
+
if(!P_CheckSight(actor, actor->target))
- return false;
-
+ return false;
+
if(actor->flags & MF_JUSTHIT)
{
- // the target just hit the enemy,
- // so fight back!
- actor->flags &= ~MF_JUSTHIT;
- return true;
+ // the target just hit the enemy,
+ // so fight back!
+ actor->flags &= ~MF_JUSTHIT;
+ return true;
}
-
+
if(actor->reactiontime)
- return false; // do not attack yet
-
+ return false; // do not attack yet
+
// OPTIMIZE: get this from a global checksight
dist = P_AproxDistance(actor->x-actor->target->x,
- actor->y-actor->target->y) - 64*FRACUNIT;
+ actor->y-actor->target->y) - 64*FRACUNIT;
if (!actor->info->meleestate)
- dist -= 128*FRACUNIT; // no melee attack, so fire more
+ dist -= 128*FRACUNIT; // no melee attack, so fire more
dist >>= 16;
// villsa [STRIFE] checks for acolytes
- if(actor->type == MT_SHADOWGUARD ||
- (actor->type >= MT_GUARD1 && actor->type <= MT_GUARD6))
+ // haleyjd 09/05/10: Repaired to match disassembly: Was including
+ // SHADOWGUARD in the wrong case, was missing MT_SENTINEL entirely.
+ // Structure of ASM also indicates this was probably a switch
+ // statement turned into a cascading if/else by the compiler.
+ switch(actor->type)
{
+ case MT_GUARD1:
+ case MT_GUARD2:
+ case MT_GUARD3:
+ case MT_GUARD4:
+ case MT_GUARD5:
+ case MT_GUARD6:
+ // oddly, not all Acolytes are included here...
dist >>= 4;
- }
- // villsa [STRIFE] check for Crusader
- else if(actor->type == MT_CRUSADER)
+ break;
+ case MT_SHADOWGUARD:
+ case MT_CRUSADER:
+ case MT_SENTINEL:
dist >>= 1;
+ break;
+ default:
+ break;
+ }
// villsa [STRIFE] changed to 150
if (dist > 150)
- dist = 150;
-
+ dist = 150;
+
if (P_Random () < dist)
- return false;
-
+ return false;
+
return true;
}
//
// P_CheckRobotRange
-// villsa [STRIFE] new function
//
-
+// villsa [STRIFE] New function
+//
boolean P_CheckRobotRange(mobj_t *actor)
{
fixed_t dist;
if(!P_CheckSight(actor, actor->target))
- return false;
+ return false;
if(actor->reactiontime)
- return false; // do not attack yet
+ return false; // do not attack yet
dist = (P_AproxDistance(actor->x-actor->target->x,
- actor->y-actor->target->y) - 64*FRACUNIT) >> FRACBITS;
+ actor->y-actor->target->y) - 64*FRACUNIT) >> FRACBITS;
return (dist < 200);
}
@@ -342,6 +372,10 @@ boolean P_CheckRobotRange(mobj_t *actor)
// Move in the current direction,
// returns false if the move is blocked.
//
+// [STRIFE]
+// villsa/haleyjd 09/05/10: Modified for terrain types and 3D object
+// clipping. Below constants are verified to be unmodified:
+//
fixed_t xspeed[8] = {FRACUNIT,47000,0,-47000,-FRACUNIT,-47000,0,47000};
fixed_t yspeed[8] = {0,47000,FRACUNIT,47000,0,-47000,-FRACUNIT,-47000};
@@ -354,20 +388,20 @@ boolean P_Move (mobj_t* actor)
{
fixed_t tryx;
fixed_t tryy;
-
+
line_t* ld;
-
+
// warning: 'catch', 'throw', and 'try'
// are all C++ reserved words
boolean try_ok;
boolean good;
-
+
if (actor->movedir == DI_NODIR)
- return false;
-
+ return false;
+
if ((unsigned)actor->movedir >= 8)
- I_Error ("Weird actor->movedir!");
-
+ I_Error ("Weird actor->movedir!");
+
tryx = actor->x + actor->info->speed*xspeed[actor->movedir];
tryy = actor->y + actor->info->speed*yspeed[actor->movedir];
@@ -375,48 +409,49 @@ boolean P_Move (mobj_t* actor)
if (!try_ok)
{
- // open any specials
- if (actor->flags & MF_FLOAT && floatok)
- {
- // must adjust height
- if (actor->z < tmfloorz)
- actor->z += FLOATSPEED;
- else
- actor->z -= FLOATSPEED;
-
- actor->flags |= MF_INFLOAT;
- return true;
- }
-
- if (!numspechit)
- return false;
-
- actor->movedir = DI_NODIR;
- good = false;
- while (numspechit--)
- {
- ld = spechit[numspechit];
- // if the special is not a door
- // that can be opened,
- // return false
- if (P_UseSpecialLine (actor, ld,0))
- good = true;
- }
- return good;
+ // open any specials
+ if (actor->flags & MF_FLOAT && floatok)
+ {
+ // must adjust height
+ if (actor->z < tmfloorz)
+ actor->z += FLOATSPEED; // [STRIFE] Note FLOATSPEED == 5*FRACUNIT
+ else
+ actor->z -= FLOATSPEED;
+
+ actor->flags |= MF_INFLOAT;
+ return true;
+ }
+
+ if (!numspechit)
+ return false;
+
+ actor->movedir = DI_NODIR;
+ good = false;
+ while (numspechit--)
+ {
+ ld = spechit[numspechit];
+ // if the special is not a door
+ // that can be opened,
+ // return false
+ if (P_UseSpecialLine (actor, ld,0))
+ good = true;
+ }
+ return good;
}
else
{
- actor->flags &= ~(MF_INFLOAT|MF_FEETCLIPPED); // villsa [STRIFE]
+ actor->flags &= ~(MF_INFLOAT|MF_FEETCLIPPED); // villsa [STRIFE]
// villsa [STRIFE]
if(P_GetTerrainType(actor) != FLOOR_SOLID)
actor->flags |= MF_FEETCLIPPED;
}
-
- // villsa [STRIFE] TODO - verify
+
+ // villsa [STRIFE] Removed pulling non-floating actors down to the ground.
+ // (haleyjd 09/05/10: Verified)
/*if (! (actor->flags & MF_FLOAT) )
- actor->z = actor->floorz;*/
+ actor->z = actor->floorz;*/
return true;
}
@@ -433,11 +468,13 @@ boolean P_Move (mobj_t* actor)
// If a door is in the way,
// an OpenDoor call is made to start it opening.
//
+// haleyjd 09/05/10: [STRIFE] Verified unmodified.
+//
boolean P_TryWalk (mobj_t* actor)
-{
+{
if (!P_Move (actor))
{
- return false;
+ return false;
}
actor->movecount = P_Random()&15;
@@ -469,7 +506,7 @@ void P_NewChaseDir(mobj_t* actor)
P_SetMobjState(actor, actor->info->spawnstate);
return;
}
-
+
olddir = actor->movedir;
turnaround=opposite[olddir];
@@ -477,107 +514,107 @@ void P_NewChaseDir(mobj_t* actor)
deltay = actor->target->y - actor->y;
if (deltax>10*FRACUNIT)
- d[1]= DI_EAST;
+ d[1]= DI_EAST;
else if (deltax<-10*FRACUNIT)
- d[1]= DI_WEST;
+ d[1]= DI_WEST;
else
- d[1]=DI_NODIR;
+ d[1]=DI_NODIR;
if (deltay<-10*FRACUNIT)
- d[2]= DI_SOUTH;
+ d[2]= DI_SOUTH;
else if (deltay>10*FRACUNIT)
- d[2]= DI_NORTH;
+ d[2]= DI_NORTH;
else
- d[2]=DI_NODIR;
+ d[2]=DI_NODIR;
// try direct route
if (d[1] != DI_NODIR
- && d[2] != DI_NODIR)
+ && d[2] != DI_NODIR)
{
- actor->movedir = diags[((deltay<0)<<1)+(deltax>0)];
- if (actor->movedir != (int) turnaround && P_TryWalk(actor))
- return;
+ actor->movedir = diags[((deltay<0)<<1)+(deltax>0)];
+ if (actor->movedir != (int) turnaround && P_TryWalk(actor))
+ return;
}
// try other directions
if (P_Random() > 200
- || abs(deltay)>abs(deltax))
+ || abs(deltay)>abs(deltax))
{
- tdir=d[1];
- d[1]=d[2];
- d[2]=tdir;
+ tdir=d[1];
+ d[1]=d[2];
+ d[2]=tdir;
}
if (d[1]==turnaround)
- d[1]=DI_NODIR;
+ d[1]=DI_NODIR;
if (d[2]==turnaround)
- d[2]=DI_NODIR;
-
+ d[2]=DI_NODIR;
+
if (d[1]!=DI_NODIR)
{
- actor->movedir = d[1];
- if (P_TryWalk(actor))
- {
- // either moved forward or attacked
- return;
- }
+ actor->movedir = d[1];
+ if (P_TryWalk(actor))
+ {
+ // either moved forward or attacked
+ return;
+ }
}
if (d[2]!=DI_NODIR)
{
- actor->movedir =d[2];
+ actor->movedir =d[2];
- if (P_TryWalk(actor))
- return;
+ if (P_TryWalk(actor))
+ return;
}
// there is no direct path to the player,
// so pick another direction.
if (olddir!=DI_NODIR)
{
- actor->movedir =olddir;
+ actor->movedir =olddir;
- if (P_TryWalk(actor))
- return;
+ if (P_TryWalk(actor))
+ return;
}
// randomly determine direction of search
if (P_Random()&1)
{
- for ( tdir=DI_EAST;
- tdir<=DI_SOUTHEAST;
- tdir++ )
- {
- if (tdir != (int) turnaround)
- {
- actor->movedir =tdir;
-
- if ( P_TryWalk(actor) )
- return;
- }
- }
+ for ( tdir=DI_EAST;
+ tdir<=DI_SOUTHEAST;
+ tdir++ )
+ {
+ if (tdir != (int) turnaround)
+ {
+ actor->movedir =tdir;
+
+ if ( P_TryWalk(actor) )
+ return;
+ }
+ }
}
else
{
- for ( tdir=DI_SOUTHEAST;
- tdir != (DI_EAST-1);
- tdir-- )
- {
- if (tdir != (int) turnaround)
- {
- actor->movedir = tdir;
-
- if ( P_TryWalk(actor) )
- return;
- }
- }
+ for ( tdir=DI_SOUTHEAST;
+ tdir != (DI_EAST-1);
+ tdir-- )
+ {
+ if (tdir != (int) turnaround)
+ {
+ actor->movedir = tdir;
+
+ if ( P_TryWalk(actor) )
+ return;
+ }
+ }
}
if (turnaround != DI_NODIR)
{
- actor->movedir =turnaround;
- if ( P_TryWalk(actor) )
- return;
+ actor->movedir =turnaround;
+ if ( P_TryWalk(actor) )
+ return;
}
actor->movedir = DI_NODIR; // can not move
@@ -585,13 +622,20 @@ void P_NewChaseDir(mobj_t* actor)
//
// P_NewRandomDir
+//
// villsa [STRIFE] new function
//
-
+// haleyjd: Almost identical to the tail-end of P_NewChaseDir, this function
+// finds a purely random direction for an object to walk. Called from
+// A_RandomWalk.
+//
+// Shockingly similar to the RandomWalk pointer in Eternity :)
+//
void P_NewRandomDir(mobj_t* actor)
{
int dir = 0;
+ // randomly determine direction of search
if(P_Random() & 1)
{
for(dir = 0; dir < DI_NODIR; dir++)
@@ -612,11 +656,16 @@ void P_NewRandomDir(mobj_t* actor)
dir = DI_SOUTHEAST;
while(1)
{
+ // haleyjd 09/05/10: P_TryWalk -> P_Move, missing random code.
if(dir != opposite[actor->movedir])
{
actor->movedir = dir;
- if(P_TryWalk(actor))
- break;
+
+ if(P_Move(actor))
+ {
+ actor->movecount = P_Random() & 15;
+ return;
+ }
}
if(--dir == -1)
@@ -628,120 +677,150 @@ void P_NewRandomDir(mobj_t* actor)
}
actor->movedir = opposite[actor->movedir];
- if(!P_TryWalk(actor))
+ if(P_Move(actor))
+ {
+ actor->movecount = P_Random() & 15;
+ return;
+ }
+ else
{
actor->movedir = DI_NODIR;
return;
}
- }
- }
- }
+ } // end if(--dir == -1)
+ } // end while(1)
+ } // end else
}
+// haleyjd 09/05/10: Needed below.
+extern void P_BulletSlope (mobj_t *mo);
+#define LOCAL_MELEERANGE 64*FRACUNIT
//
// P_LookForPlayers
+//
// If allaround is false, only look 180 degrees in front.
// Returns true if a player is targeted.
//
+// [STRIFE]
+// haleyjd 09/05/10: Modifications to support friendly units.
+//
boolean
P_LookForPlayers
( mobj_t* actor,
boolean allaround )
{
- int c;
- int stop;
- player_t* player;
- sector_t* sector;
- angle_t an;
- fixed_t dist;
-
+ int c;
+ int stop;
+ player_t* player;
+ sector_t* sector;
+ angle_t an;
+ fixed_t dist;
+ mobj_t * master = players[actor->allegiance].mo;
+
+ // haleyjd 09/05/10: handle Allies
+ if(actor->flags & MF_ALLY)
+ {
+ // Deathmatch: support team behavior for Rebels.
+ if(netgame)
+ {
+ // Rebels adopt the allied player's target if it is not of the same
+ // allegiance. Other allies do it unconditionally.
+ if(master && master->target &&
+ (master->target->type != MT_REBEL1 ||
+ master->target->allegiance != actor->allegiance))
+ {
+ actor->target = master->target;
+ }
+ else
+ {
+ P_BulletSlope(actor);
+
+ // Clear target if nothing is visible, or if the target is a
+ // friendly Rebel or the allied player.
+ if(!linetarget ||
+ actor->target->target == MT_REBEL1 &&
+ actor->target->allegiance == actor->allegiance ||
+ actor->target == master)
+ {
+ actor->target = NULL;
+ return false;
+ }
+ }
+ }
+ else
+ {
+ // Single-player: Adopt any non-allied player target.
+ if(master && master->target && !(master->target->flags & MF_ALLY))
+ {
+ actor->target = master->target;
+ return true;
+ }
+
+ P_BulletSlope(actor);
+
+ // Clear target if nothing is visible, or if the target is an ally.
+ if(!linetarget || actor->target->flags & MF_ALLY)
+ {
+ actor->target = NULL;
+ return false;
+ }
+ }
+
+ return true;
+ }
+
sector = actor->subsector->sector;
-
+
c = 0;
stop = (actor->lastlook-1)&3;
-
+
for ( ; ; actor->lastlook = (actor->lastlook+1)&3 )
{
- if (!playeringame[actor->lastlook])
- continue;
-
- if (c++ == 2
- || actor->lastlook == stop)
- {
- // done looking
- return false;
- }
-
- player = &players[actor->lastlook];
+ if (!playeringame[actor->lastlook])
+ continue;
- if (player->health <= 0)
- continue; // dead
+ if (c++ == 2
+ || actor->lastlook == stop)
+ {
+ // done looking
+ return false;
+ }
- if (!P_CheckSight (actor, player->mo))
- continue; // out of sight
-
- if (!allaround)
- {
- an = R_PointToAngle2 (actor->x,
- actor->y,
- player->mo->x,
- player->mo->y)
- - actor->angle;
-
- if (an > ANG90 && an < ANG270)
- {
- dist = P_AproxDistance (player->mo->x - actor->x,
- player->mo->y - actor->y);
- // if real close, react anyway
- if (dist > MELEERANGE)
- continue; // behind back
- }
- }
-
- actor->target = player->mo;
- return true;
- }
+ player = &players[actor->lastlook];
- return false;
-}
+ if (player->health <= 0)
+ continue; // dead
+ if (!P_CheckSight (actor, player->mo))
+ continue; // out of sight
-//
-// A_KeenDie
-// DOOM II special, map 32.
-// Uses special tag 666.
-//
-void A_KeenDie (mobj_t* mo)
-{
- thinker_t* th;
- mobj_t* mo2;
- line_t junk;
+ if (!allaround)
+ {
+ an = R_PointToAngle2(actor->x,
+ actor->y,
+ player->mo->x,
+ player->mo->y) - actor->angle;
- A_Fall (mo);
-
- // scan the remaining thinkers
- // to see if all Keens are dead
- for (th = thinkercap.next ; th != &thinkercap ; th=th->next)
- {
- if (th->function.acp1 != (actionf_p1)P_MobjThinker)
- continue;
+ if (an > ANG90 && an < ANG270)
+ {
+ dist = P_AproxDistance (player->mo->x - actor->x,
+ player->mo->y - actor->y);
+ // if real close, react anyway
+ if (dist > LOCAL_MELEERANGE) // haleyjd: ......
+ continue; // behind back
+ }
+ }
- mo2 = (mobj_t *)th;
- if (mo2 != mo
- && mo2->type == mo->type
- && mo2->health > 0)
- {
- // other Keen not dead
- return;
- }
+ actor->target = player->mo;
+ return true;
}
- junk.tag = 666;
- EV_DoDoor(&junk,open);
+ return false;
}
+// haleyjd 09/05/10: [STRIFE] Removed A_KeenDie
//
// ACTION ROUTINES
@@ -751,178 +830,308 @@ void A_KeenDie (mobj_t* mo)
// A_Look
// Stay in state until a player is sighted.
//
+// [STRIFE]
+// haleyjd 09/05/10: Adjusted for allies, Inquisitors, etc.
+//
void A_Look (mobj_t* actor)
{
- mobj_t* targ;
-
- actor->threshold = 0; // any shot will wake up
+ mobj_t* targ;
+
+ actor->threshold = 0; // any shot will wake up
targ = actor->subsector->sector->soundtarget;
if (targ
- && (targ->flags & MF_SHOOTABLE) )
+ && (targ->flags & MF_SHOOTABLE) )
{
- actor->target = targ;
+ // [STRIFE] Allies wander when they call this.
+ if(actor->flags & MF_ALLY)
+ A_RandomWalk(actor);
+ else
+ {
+ actor->target = targ;
- if ( actor->flags & MF_AMBUSH )
- {
- if (P_CheckSight (actor, actor->target))
- goto seeyou;
- }
- else
- goto seeyou;
+ if ( actor->flags & MF_AMBUSH )
+ {
+ if (P_CheckSight (actor, actor->target))
+ goto seeyou;
+ }
+ else
+ goto seeyou;
+ }
}
-
-
- if (!P_LookForPlayers (actor, false) )
- return;
-
+
+ // haleyjd 09/05/10: This is bizarre, as Rogue keeps using the GIVEQUEST flag
+ // as a parameter to control allaround look behavior. Did they just run out of
+ // flags, or what?
+ // STRIFE-TODO: Needs serious verification.
+ if (!P_LookForPlayers (actor, actor->flags & MF_GIVEQUEST) )
+ return;
+
// go into chase state
- seeyou:
+seeyou:
if (actor->info->seesound)
{
- int sound;
-
- switch (actor->info->seesound)
- {
- case sfx_pespna: // villsa [STRIFE] TODO - fix sounds
- case sfx_pespnb: // villsa [STRIFE] TODO - fix sounds
- case sfx_pespnc: // villsa [STRIFE] TODO - fix sounds
- sound = sfx_pespna+P_Random()%3; // villsa [STRIFE] TODO - fix sounds
- break;
+ int sound = actor->info->seesound;
+ mobj_t * emitter = actor;
- case sfx_agrac1: // villsa [STRIFE] TODO - fix sounds
- case sfx_agrac2: // villsa [STRIFE] TODO - fix sounds
- sound = sfx_agrac1+P_Random()%2; // villsa [STRIFE] TODO - fix sounds
- break;
+ // [STRIFE] Removed DOOM random sounds.
- default:
- sound = actor->info->seesound;
- break;
- }
+ // [STRIFE] Only Inquisitors roar loudly here.
+ if (actor->type == MT_INQUISITOR)
+ emitter = NULL;
- // villsa [STRIFE] TODO replace with proper strife bosses
- /*if (actor->type==MT_SPIDER
- || actor->type == MT_CYBORG)
- {
- // full volume
- S_StartSound (NULL, sound);
- }
- else*/
- S_StartSound (actor, sound);
+ S_StartSound (emitter, sound);
}
+ // [STRIFE] Set threshold (kinda odd as it's still set to 0 above...)
+ actor->threshold = 20;
+
P_SetMobjState (actor, actor->info->seestate);
}
+//
+// A_RandomWalk
+//
+// [STRIFE] New function.
+// haleyjd 09/05/10: Action routine used to meander about.
+//
+void A_RandomWalk(mobj_t* actor)
+{
+ // Standing actors do not wander.
+ if(actor->flags & MF_STAND)
+ return;
+
+ if(actor->reactiontime)
+ actor->reactiontime--; // count down reaction time
+ else
+ {
+ // turn to a new angle
+ if(actor->movedir < DI_NODIR)
+ {
+ int delta;
+
+ actor->angle &= (7 << 29);
+ delta = actor->angle - (actor->movedir << 29);
+
+ if(delta < 0)
+ actor->angle += ANG90/2;
+ else if(delta > 0)
+ actor->angle -= ANG90/2;
+ }
+
+ // try moving
+ if(--actor->movecount < 0 || !P_Move(actor))
+ {
+ P_NewRandomDir(actor);
+ actor->movecount += 5;
+ }
+ }
+}
+
+//
+// A_FriendLook
+//
+// [STRIFE] New function
+// haleyjd 09/05/10: Action function used mostly by mundane characters such as
+// peasants.
+//
+void A_FriendLook(mobj_t* actor)
+{
+ mobj_t *soundtarget = actor->subsector->sector->soundtarget;
+
+ actor->threshold = 0;
+
+ if(soundtarget && soundtarget->flags & MF_SHOOTABLE)
+ {
+ // Handle allies, except on maps 3 and 34 (Front Base/Movement Base)
+ if((actor->flags & MF_ALLY) == (soundtarget->flags & MF_ALLY) &&
+ gamemap != 3 && gamemap != 34)
+ {
+ // STRIFE-TODO: Needs serious verification.
+ if(P_LookForPlayers(actor, actor->flags & MF_GIVEQUEST))
+ {
+ P_SetMobjState(actor, actor->info->seestate);
+ actor->flags |= MF_INCOMBAT;
+ return;
+ }
+ }
+ else
+ {
+ actor->target = soundtarget;
+
+ if(!(actor->flags & MF_AMBUSH) || P_CheckSight(actor, actor->target))
+ {
+ actor->threshold = 10;
+ P_SetMobjState(actor, actor->info->seestate);
+ return;
+ }
+ }
+ }
+
+ // do some idle animation
+ if(P_Random() < 30)
+ P_SetMobjState(actor, actor->info->spawnstate + 1 + (P_Random() & 1));
+
+ // wander around a bit
+ if(!(actor->flags & MF_STAND) && P_Random() < 40)
+ P_SetMobjState(actor, actor->info->spawnstate + 3);
+}
+
+//
+// A_Listen
+//
+// [STRIFE] New function
+// haleyjd 09/05/10: Action routine used to strictly listen for a target.
+//
+void A_Listen(mobj_t* actor)
+{
+ mobj_t *soundtarget;
+
+ actor->threshold = 0;
+
+ soundtarget = actor->subsector->sector->soundtarget;
+
+ if(soundtarget && soundtarget->flags & MF_SHOOTABLE)
+ {
+ if(actor->flags & MF_ALLY != soundtarget->flags & MF_ALLY)
+ {
+ actor->target = soundtarget;
+
+ if(!(actor->flags & MF_AMBUSH) || P_CheckSight(actor, actor->target))
+ {
+ if(actor->info->seesound)
+ S_StartSound(actor, actor->info->seesound);
+
+ actor->threshold = 10;
+
+ P_SetMobjState(actor, actor->info->seestate);
+ }
+ }
+ }
+}
+
//
// A_Chase
// Actor has a melee attack,
// so it tries to close as fast as possible
//
+// haleyjd 09/05/10: [STRIFE] Various minor changes
+//
void A_Chase (mobj_t* actor)
{
- int delta;
+ int delta;
if (actor->reactiontime)
- actor->reactiontime--;
-
+ actor->reactiontime--;
// modify target threshold
if (actor->threshold)
{
- if (!actor->target
- || actor->target->health <= 0)
- {
- actor->threshold = 0;
- }
- else
- actor->threshold--;
+ if (!actor->target
+ || actor->target->health <= 0)
+ {
+ actor->threshold = 0;
+ }
+ else
+ actor->threshold--;
}
// turn towards movement direction if not there yet
if (actor->movedir < 8)
{
- actor->angle &= (7<<29);
- delta = actor->angle - (actor->movedir << 29);
-
- if (delta > 0)
- actor->angle -= ANG90/2;
- else if (delta < 0)
- actor->angle += ANG90/2;
+ actor->angle &= (7<<29);
+ delta = actor->angle - (actor->movedir << 29);
+
+ if (delta > 0)
+ actor->angle -= ANG90/2;
+ else if (delta < 0)
+ actor->angle += ANG90/2;
}
if (!actor->target
- || !(actor->target->flags&MF_SHOOTABLE))
+ || !(actor->target->flags&MF_SHOOTABLE))
{
- // look for a new target
- if (P_LookForPlayers(actor,true))
- return; // got a new target
-
- P_SetMobjState (actor, actor->info->spawnstate);
- return;
+ // look for a new target
+ if (P_LookForPlayers(actor,true))
+ return; // got a new target
+
+ P_SetMobjState (actor, actor->info->spawnstate);
+ return;
}
// do not attack twice in a row
if (actor->flags & MF_JUSTATTACKED)
{
- actor->flags &= ~MF_JUSTATTACKED;
- if (gameskill != sk_nightmare && !fastparm)
- P_NewChaseDir (actor);
- return;
+ actor->flags &= ~MF_JUSTATTACKED;
+ // [STRIFE] Checks only against fastparm, not gameskill == 5
+ if (!fastparm)
+ P_NewChaseDir (actor);
+ return;
}
// check for melee attack
if (actor->info->meleestate
- && P_CheckMeleeRange (actor))
+ && P_CheckMeleeRange (actor))
{
- if (actor->info->attacksound)
- S_StartSound (actor, actor->info->attacksound);
+ if (actor->info->attacksound)
+ S_StartSound (actor, actor->info->attacksound);
- P_SetMobjState (actor, actor->info->meleestate);
- return;
+ P_SetMobjState (actor, actor->info->meleestate);
+ return;
}
// check for missile attack
if (actor->info->missilestate)
{
- if (gameskill < sk_nightmare
- && !fastparm && actor->movecount)
- {
- goto nomissile;
- }
-
- if (!P_CheckMissileRange (actor))
- goto nomissile;
-
- P_SetMobjState (actor, actor->info->missilestate);
- actor->flags |= MF_JUSTATTACKED;
- return;
+ // [STRIFE] Checks only fastparm.
+ if (!fastparm && actor->movecount)
+ {
+ goto nomissile;
+ }
+
+ if (!P_CheckMissileRange (actor))
+ goto nomissile;
+
+ P_SetMobjState (actor, actor->info->missilestate);
+
+ // [STRIFE] Add INCOMBAT flag to disable dialog
+ actor->flags |= (MF_INCOMBAT|MF_JUSTATTACKED);
+ return;
}
// ?
- nomissile:
+nomissile:
// possibly choose another target
if (netgame
- && !actor->threshold
- && !P_CheckSight (actor, actor->target) )
+ && !actor->threshold
+ && !P_CheckSight (actor, actor->target) )
{
- if (P_LookForPlayers(actor,true))
- return; // got a new target
+ if (P_LookForPlayers(actor,true))
+ return; // got a new target
}
// chase towards player
if (--actor->movecount<0
- || !P_Move (actor))
+ || !P_Move (actor))
{
- P_NewChaseDir (actor);
+ P_NewChaseDir (actor);
}
-
+
+ // [STRIFE] Changes to active sound behavior:
+ // * Significantly more frequent
+ // * Acolytes have randomized wandering sounds
+
// make active sound
- if (actor->info->activesound
- && P_Random () < 3)
+ if (actor->info->activesound && P_Random () < 38)
{
- S_StartSound (actor, actor->info->activesound);
+ if(actor->info->activesound >= sfx_agrac1 &&
+ actor->info->activesound <= sfx_agrac4)
+ {
+ S_StartSound(actor, sfx_agrac1 + P_Random() % 4);
+ }
+ else
+ S_StartSound (actor, actor->info->activesound);
}
}
@@ -930,20 +1139,34 @@ void A_Chase (mobj_t* actor)
//
// A_FaceTarget
//
+// [STRIFE]
+// haleyjd 09/05/10: Modified handling for various visibility
+// modifying flags.
+//
void A_FaceTarget (mobj_t* actor)
{
if (!actor->target)
- return;
-
+ return;
+
actor->flags &= ~MF_AMBUSH;
-
+
actor->angle = R_PointToAngle2 (actor->x,
- actor->y,
- actor->target->x,
- actor->target->y);
-
- if (actor->target->flags & MF_SHADOW)
- actor->angle += (P_Random()-P_Random())<<21;
+ actor->y,
+ actor->target->x,
+ actor->target->y);
+
+ if(actor->target->flags & MF_SHADOW)
+ {
+ // [STRIFE] increased SHADOW inaccuracy by a power of 2
+ int t = P_Random();
+ actor->angle += (t - P_Random()) << 22;
+ }
+ else if(actor->target->flags & MF_MVIS)
+ {
+ // [STRIFE] MVIS gives even worse aiming!
+ int t = P_Random();
+ actor->angle += (t - P_Random()) << 23;
+ }
}
@@ -2189,20 +2412,6 @@ void A_PlayerScream (mobj_t* mo)
S_StartSound (mo, sound);
}
-void A_RandomWalk(mobj_t* actor)
-{
-
-}
-
-void A_FriendLook(mobj_t* actor)
-{
-
-}
-
-void A_Listen(mobj_t* actor)
-{
-
-}
void A_PeasantPunch(mobj_t* actor)
{
diff --git a/src/strife/p_map.c b/src/strife/p_map.c
index 4897d164..f83851cf 100644
--- a/src/strife/p_map.c
+++ b/src/strife/p_map.c
@@ -1234,11 +1234,11 @@ P_LineAttack
shootz = t1->z + (t1->height>>1) + 8*FRACUNIT;
attackrange = distance;
aimslope = slope;
-
- P_PathTraverse ( t1->x, t1->y,
- x2, y2,
- PT_ADDLINES|PT_ADDTHINGS,
- PTR_ShootTraverse );
+
+ P_PathTraverse(t1->x, t1->y,
+ x2, y2,
+ PT_ADDLINES|PT_ADDTHINGS,
+ PTR_ShootTraverse);
}
diff --git a/src/strife/p_mobj.c b/src/strife/p_mobj.c
index 5f7e258a..d2c2e5de 100644
--- a/src/strife/p_mobj.c
+++ b/src/strife/p_mobj.c
@@ -836,16 +836,16 @@ void P_SpawnMapThing (mapthing_t* mthing)
fixed_t x;
fixed_t y;
fixed_t z;
-
+
// count deathmatch start positions
if (mthing->type == 11)
{
- if (deathmatch_p < &deathmatchstarts[10])
- {
- memcpy (deathmatch_p, mthing, sizeof(*mthing));
- deathmatch_p++;
- }
- return;
+ if (deathmatch_p < &deathmatchstarts[10])
+ {
+ memcpy (deathmatch_p, mthing, sizeof(*mthing));
+ deathmatch_p++;
+ }
+ return;
}
if (mthing->type <= 0)
@@ -855,36 +855,37 @@ void P_SpawnMapThing (mapthing_t* mthing)
return;
}
-
+
// check for players specially
+ // STRIFE-TODO: Need 8 player starts
if (mthing->type <= 4)
{
- // save spots for respawning in network games
- playerstarts[mthing->type-1] = *mthing;
- if (!deathmatch)
- P_SpawnPlayer (mthing);
+ // save spots for respawning in network games
+ playerstarts[mthing->type-1] = *mthing;
+ if (!deathmatch)
+ P_SpawnPlayer (mthing);
- return;
+ return;
}
// check for apropriate skill level
if (!netgame && (mthing->options & 16) )
- return;
-
+ return;
+
if (gameskill == sk_baby)
- bit = 1;
+ bit = 1;
else if (gameskill == sk_nightmare)
- bit = 4;
+ bit = 4;
else
- bit = 1<<(gameskill-1);
+ bit = 1<<(gameskill-1);
if (!(mthing->options & bit) )
return;
// find which type to spawn
for (i=0 ; i< NUMMOBJTYPES ; i++)
- if (mthing->type == mobjinfo[i].doomednum)
- break;
+ if (mthing->type == mobjinfo[i].doomednum)
+ break;
/*
if (i==NUMMOBJTYPES)
@@ -895,43 +896,48 @@ void P_SpawnMapThing (mapthing_t* mthing)
// haleyjd 08/29/10: STRIFE-FIXME: Temporarily disabled I_Error for testing purposes
if (i == NUMMOBJTYPES)
return;
-
+
// don't spawn keycards and players in deathmatch
if (deathmatch && mobjinfo[i].flags & MF_NOTDMATCH)
- return;
+ return;
// don't spawn any monsters if -nomonsters
- if (nomonsters
- && ( /*i == MT_SKULL // villsa [STRIFE] unused
- ||*/ (mobjinfo[i].flags & MF_COUNTKILL)) )
- {
- return;
- }
+ // villsa [STRIFE] Removed MT_SKULL
+ if (nomonsters && (mobjinfo[i].flags & MF_COUNTKILL))
+ return;
// spawn it
x = mthing->x << FRACBITS;
y = mthing->y << FRACBITS;
if (mobjinfo[i].flags & MF_SPAWNCEILING)
- z = ONCEILINGZ;
+ z = ONCEILINGZ;
else
- z = ONFLOORZ;
+ z = ONFLOORZ;
mobj = P_SpawnMobj (x,y,z, i);
mobj->spawnpoint = *mthing;
if (mobj->tics > 0)
- mobj->tics = 1 + (P_Random () % mobj->tics);
+ mobj->tics = 1 + (P_Random () % mobj->tics);
if (mobj->flags & MF_COUNTKILL)
- totalkills++;
+ totalkills++;
// villsa [STRIFE] unused
/*if (mobj->flags & MF_COUNTITEM)
- totalitems++;*/
-
+ totalitems++;*/
+
mobj->angle = ANG45 * (mthing->angle/45);
if (mthing->options & MTF_AMBUSH)
- mobj->flags |= MF_AMBUSH;
+ mobj->flags |= MF_AMBUSH;
+ if (mthing->options & MTF_STAND) // [STRIFE] Standing mode, for NPCs
+ mobj->flags |= MF_STAND;
+ if (mthing->options & MTF_FRIEND) // [STRIFE] Allies
+ mobj->flags |= MF_ALLY;
+ if (mthing->options & MTF_TRANSLUCENT) // [STRIFE] Translucent object
+ mobj->flags |= MF_SHADOW;
+ if (mthing->options & MTF_MVIS) // [STRIFE] Alt. Translucency
+ mobj->flags |= MF_MVIS;
}
@@ -1090,7 +1096,7 @@ P_SpawnMissile
if (dest->flags & MF_SHADOW)
an += (P_Random()-P_Random())<<21;
// villsa [STRIFE] check for heavily transparent things
- else if(dest->flags & MF_MOREVISIBLE)
+ else if(dest->flags & MF_MVIS)
an += (P_Random()-P_Random())<<22;
th->angle = an;
@@ -1134,7 +1140,7 @@ mobj_t* P_SpawnFacingMissile(mobj_t* source, mobj_t* target, mobjtype_t type)
if (target->flags & MF_SHADOW)
an += (P_Random()-P_Random())<<21;
// villsa [STRIFE] check for heavily transparent things
- else if(target->flags & MF_MOREVISIBLE)
+ else if(target->flags & MF_MVIS)
an += (P_Random()-P_Random())<<22;
th->angle = an;
diff --git a/src/strife/p_mobj.h b/src/strife/p_mobj.h
index 38c04075..67c1c35d 100644
--- a/src/strife/p_mobj.h
+++ b/src/strife/p_mobj.h
@@ -213,8 +213,8 @@ typedef enum
// villsa [STRIFE] friendly towards player with matching flag
MF_ALLY = 0x4000000,
- // villsa [STRIFE] 75% transparency?
- MF_MOREVISIBLE = 0x8000000,
+ // villsa [STRIFE] 75% transparency? -- NEEDS VERIFICATION
+ MF_MVIS = 0x8000000,
// villsa [STRIFE] color translation
MF_COLORSWAP1 = 0x10000000,
@@ -242,84 +242,92 @@ typedef enum
// Map Object definition.
+//
+// [STRIFE]: Amazingly, only one modification was made to mobj_t over DOOM
+// 1.666, and that was the addition of the single-byte allegiance field for
+// tracking with which player friendly monsters are allied.
+//
typedef struct mobj_s
{
// List: thinker links.
- thinker_t thinker;
+ thinker_t thinker;
// Info for drawing: position.
- fixed_t x;
- fixed_t y;
- fixed_t z;
+ fixed_t x;
+ fixed_t y;
+ fixed_t z;
// More list: links in sector (if needed)
- struct mobj_s* snext;
- struct mobj_s* sprev;
+ struct mobj_s* snext;
+ struct mobj_s* sprev;
//More drawing info: to determine current sprite.
- angle_t angle; // orientation
- spritenum_t sprite; // used to find patch_t and flip value
- int frame; // might be ORed with FF_FULLBRIGHT
+ angle_t angle; // orientation
+ spritenum_t sprite; // used to find patch_t and flip value
+ int frame; // might be ORed with FF_FULLBRIGHT
// Interaction info, by BLOCKMAP.
// Links in blocks (if needed).
- struct mobj_s* bnext;
- struct mobj_s* bprev;
+ struct mobj_s* bnext;
+ struct mobj_s* bprev;
- struct subsector_s* subsector;
+ struct subsector_s* subsector;
// The closest interval over all contacted Sectors.
- fixed_t floorz;
- fixed_t ceilingz;
+ fixed_t floorz;
+ fixed_t ceilingz;
// For movement checking.
- fixed_t radius;
- fixed_t height;
+ fixed_t radius;
+ fixed_t height;
// Momentums, used to update position.
- fixed_t momx;
- fixed_t momy;
- fixed_t momz;
+ fixed_t momx;
+ fixed_t momy;
+ fixed_t momz;
// If == validcount, already checked.
- int validcount;
+ int validcount;
- mobjtype_t type;
- mobjinfo_t* info; // &mobjinfo[mobj->type]
+ mobjtype_t type;
+ mobjinfo_t* info; // &mobjinfo[mobj->type]
- int tics; // state tic counter
- state_t* state;
- int flags;
- int health;
+ int tics; // state tic counter
+ state_t* state;
+ int flags;
+ int health;
// Movement direction, movement generation (zig-zagging).
- int movedir; // 0-7
- int movecount; // when 0, select a new dir
+ int movedir; // 0-7
+ int movecount; // when 0, select a new dir
// Thing being chased/attacked (or NULL),
// also the originator for missiles.
- struct mobj_s* target;
+ struct mobj_s* target;
// Reaction time: if non 0, don't attack yet.
// Used by player to freeze a bit after teleporting.
- int reactiontime;
+ int reactiontime;
// If >0, the target will be chased
// no matter what (even if shot)
- int threshold;
+ int threshold;
// Additional info record for player avatars only.
// Only valid if type == MT_PLAYER
- struct player_s* player;
+ struct player_s* player;
// Player number last looked for.
- int lastlook;
+ int lastlook;
// For nightmare respawn.
- mapthing_t spawnpoint;
+ mapthing_t spawnpoint;
// Thing being chased/attacked for tracers.
- struct mobj_s* tracer;
+ struct mobj_s* tracer;
+
+ // [STRIFE] haleyjd 09/05/10: allegiance, for friends and teleport beacons
+ byte allegiance;
} mobj_t;
diff --git a/src/strife/p_pspr.c b/src/strife/p_pspr.c
index 6696e153..55264a20 100644
--- a/src/strife/p_pspr.c
+++ b/src/strife/p_pspr.c
@@ -644,7 +644,7 @@ void A_FirePoisonBolt(player_t* player, pspdef_t* pspr)
fixed_t bulletslope;
-void P_BulletSlope (mobj_t* mo)
+void P_BulletSlope (mobj_t *mo)
{
angle_t an;
diff --git a/src/strife/p_setup.c b/src/strife/p_setup.c
index eeefe2dc..652d86df 100644
--- a/src/strife/p_setup.c
+++ b/src/strife/p_setup.c
@@ -342,6 +342,7 @@ void P_LoadThings (int lump)
// Do not spawn cool, new monsters if !commercial
// STRIFE-TODO: replace with isregistered stuff
+ /*
if (gamemode != commercial)
{
switch (SHORT(mt->type))
@@ -362,6 +363,7 @@ void P_LoadThings (int lump)
}
if (spawn == false)
break;
+ */
// Do spawn all other stuff.
spawnthing.x = SHORT(mt->x);
diff --git a/src/strife/p_tick.c b/src/strife/p_tick.c
index 9429cf20..55e893ab 100644
--- a/src/strife/p_tick.c
+++ b/src/strife/p_tick.c
@@ -94,8 +94,6 @@ void P_AllocateThinker (thinker_t* thinker)
{
}
-
-
//
// P_RunThinkers
//
@@ -122,8 +120,6 @@ void P_RunThinkers (void)
}
}
-
-
//
// P_Ticker
//
diff --git a/src/strife/r_draw.c b/src/strife/r_draw.c
index 9d0882d9..b8adbf9b 100644
--- a/src/strife/r_draw.c
+++ b/src/strife/r_draw.c
@@ -547,7 +547,7 @@ byte *xlatab;
void R_InitTranslationTables (void)
{
int i;
- int j;
+ byte col1, col2;
// [STRIFE] Load xlatab. Here's how Rogue did it:
// v7 = W_CacheLumpName("XLATAB", PU_CACHE); // note potential cache bug...
@@ -567,18 +567,21 @@ void R_InitTranslationTables (void)
// villsa [STRIFE] allocate a larger size for translation tables
translationtables = Z_Malloc (256*8, PU_STATIC, 0);
+ col1 = 0xFA;
+ col2 = 0xE0;
+
// villsa [STRIFE] setup all translation tables
- for(i = 0, j = -6; i < 256; i++, j++)
+ for(i = 0; i < 256; i++)
{
- if(i >= 0x80 && i<= 0x8f)
+ if(i >= 0x80 && i <= 0x8f)
{
- translationtables [i ] = (i & 0xf) + 64;
- translationtables [i+ 256] = (i & 0xf) - 80;
- translationtables [i+2*256] = (i & 0xf) + 16;
- translationtables [i+3*256] = (i & 0xf) + 48;
- translationtables [i+4*256] = (i & 0xf) + 80;
- translationtables [i+5*256] = (i & 0xf) + 96;
- translationtables [i+6*256] = (i & 0xf) - 112;
+ translationtables [i ] = (i & 0x0f) + 64;
+ translationtables [i+ 256] = (i & 0x0f) - 80;
+ translationtables [i+2*256] = (i & 0x0f) + 16;
+ translationtables [i+3*256] = (i & 0x0f) + 48;
+ translationtables [i+4*256] = (i & 0x0f) + 80;
+ translationtables [i+5*256] = (i & 0x0f) + 96;
+ translationtables [i+6*256] = (i & 0x0f) - 112;
}
else if(i >= 0x50 && i<= 0x5f)
@@ -587,9 +590,9 @@ void R_InitTranslationTables (void)
translationtables [i+ 256] = i;
translationtables [i+2*256] = i;
translationtables [i+3*256] = i;
- translationtables [i+4*256] = (i & 0xf) + -128;
- translationtables [i+5*256] = (i & 0xf) + 16;
- translationtables [i+6*256] = (i & 0xf) + 64;
+ translationtables [i+4*256] = (i & 0x0f) + -128;
+ translationtables [i+5*256] = (i & 0x0f) + 16;
+ translationtables [i+6*256] = (i & 0x0f) + 64;
}
else if(i >= 0xd0 && i<= 0xdf)
{
@@ -597,9 +600,9 @@ void R_InitTranslationTables (void)
translationtables [i+ 256] = i;
translationtables [i+2*256] = i;
translationtables [i+3*256] = i;
- translationtables [i+4*256] = (i & 0xf) - 80;
- translationtables [i+5*256] = (i & 0xf) + 48;
- translationtables [i+6*256] = (i & 0xf) + 16;
+ translationtables [i+4*256] = (i & 0x0f) - 80;
+ translationtables [i+5*256] = (i & 0x0f) + 48;
+ translationtables [i+6*256] = (i & 0x0f) + 16;
}
else if(i >= 0xc0 && i<= 0xcf)
{
@@ -607,13 +610,13 @@ void R_InitTranslationTables (void)
translationtables [i+ 256] = i;
translationtables [i+2*256] = i;
translationtables [i+3*256] = i;
- translationtables [i+4*256] = (i & 0xf) - 96;
- translationtables [i+5*256] = (i & 0xf) + 32;
- translationtables [i+6*256] = (i & 0xf);
+ translationtables [i+4*256] = (i & 0x0f) - 96;
+ translationtables [i+5*256] = (i & 0x0f) + 32;
+ translationtables [i+6*256] = (i & 0x0f);
}
else if(i >= 0xf7 && i<= 0xfb)
{
- translationtables [i ] = j;
+ translationtables [i ] = col1;
translationtables [i+ 256] = i;
translationtables [i+2*256] = i;
translationtables [i+3*256] = i;
@@ -623,7 +626,7 @@ void R_InitTranslationTables (void)
}
else if(i >= 0xf1 && i<= 0xf6)
{
- translationtables [i ] = (i & 0xf) - 33;
+ translationtables [i ] = (i & 0x0f) - 33;
translationtables [i+ 256] = i;
translationtables [i+2*256] = i;
translationtables [i+3*256] = i;
@@ -633,13 +636,13 @@ void R_InitTranslationTables (void)
}
else if(i >= 0x20 && i<= 0x40)
{
- translationtables [i ] = i;
- translationtables [i+ 256] = i;
- translationtables [i+2*256] = (i & 0xf) - 48;
- translationtables [i+3*256] = (i & 0xf) - 48;
- translationtables [i+4*256] = i;
- translationtables [i+5*256] = i;
- translationtables [i+6*256] = i;
+ translationtables [i ] = col2;
+ translationtables [i+ 256] = col2;
+ translationtables [i+2*256] = (i & 0x0f) - 48;
+ translationtables [i+3*256] = (i & 0x0f) - 48;
+ translationtables [i+4*256] = col2;
+ translationtables [i+5*256] = col2;
+ translationtables [i+6*256] = col2;
}
else // Keep all other colors as is.
{
@@ -651,6 +654,9 @@ void R_InitTranslationTables (void)
translationtables[i+5*256]=
translationtables[i+6*256]=i;
}
+
+ ++col1;
+ ++col2;
}
}