diff options
author | James Haley | 2010-09-05 23:28:16 +0000 |
---|---|---|
committer | James Haley | 2010-09-05 23:28:16 +0000 |
commit | f7768ad7dcfbefce525d846ce2f565dacf99f546 (patch) | |
tree | 8e5e071d261338984f90d901ff63cb10cf684f4e | |
parent | cb79caae119fe361d0c5835ae91a9a1f0bf8147f (diff) | |
download | chocolate-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
-rw-r--r-- | src/strife/d_main.c | 2 | ||||
-rw-r--r-- | src/strife/d_net.c | 1 | ||||
-rw-r--r-- | src/strife/doomdef.h | 14 | ||||
-rw-r--r-- | src/strife/doomstat.h | 2 | ||||
-rw-r--r-- | src/strife/g_game.c | 11 | ||||
-rw-r--r-- | src/strife/info.c | 14 | ||||
-rw-r--r-- | src/strife/m_menu.c | 202 | ||||
-rw-r--r-- | src/strife/m_menu.h | 39 | ||||
-rw-r--r-- | src/strife/p_dialog.c | 579 | ||||
-rw-r--r-- | src/strife/p_dialog.h | 32 | ||||
-rw-r--r-- | src/strife/p_enemy.c | 911 | ||||
-rw-r--r-- | src/strife/p_map.c | 10 | ||||
-rw-r--r-- | src/strife/p_mobj.c | 80 | ||||
-rw-r--r-- | src/strife/p_mobj.h | 82 | ||||
-rw-r--r-- | src/strife/p_pspr.c | 2 | ||||
-rw-r--r-- | src/strife/p_setup.c | 2 | ||||
-rw-r--r-- | src/strife/p_tick.c | 4 | ||||
-rw-r--r-- | src/strife/r_draw.c | 62 |
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; } } |