diff --git a/docs/rh-log.txt b/docs/rh-log.txt index 885381f14d..4acef4d092 100644 --- a/docs/rh-log.txt +++ b/docs/rh-log.txt @@ -1,3 +1,14 @@ +February 11, 2008 +- Fixed: Turning off follow mode with automap rotating enabled did not + function in an easy-to-understand manner. +- Fixed: D_AddWildFile() blindly assumed that all matches were files. +- Added back the dead player check to CheckIfExitIsGood(), but now it + applies only if the next map is part of the same hub. Otherwise, you can + still exit the map while dead. +- Removed the SpawnedPuff global variable and made it a return value from + P_LineAttack(). +- Fixed: P_SpawnPuff() played sounds for temporary puffs. + February 9, 2008 - Fixed: G_StartTravel() inadvertantly removed players' TIDs. - Modified FLAC/share/alloc.h to define SIZE_T_MAX if it isn't defined diff --git a/src/am_map.cpp b/src/am_map.cpp index 24e2a31c37..55b3424254 100644 --- a/src/am_map.cpp +++ b/src/am_map.cpp @@ -307,6 +307,8 @@ static fixed_t ftom_zoommul; // how far the window zooms in each tic (fb coords) static fixed_t m_x, m_y; // LL x,y where the window is on the map (map coords) static fixed_t m_x2, m_y2; // UR x,y where the window is on the map (map coords) +static fixed_t m_rotateoffsx, m_rotateoffsy; // Offset for rotated map. + // // width/height of window on map (map coords) // @@ -359,6 +361,8 @@ static BYTE antialias[NUMALIASES][NUMWEIGHTS]; void AM_rotatePoint (fixed_t *x, fixed_t *y); void AM_rotate (fixed_t *x, fixed_t *y, angle_t an); +void AM_doFollowPlayer (); +void AM_ToggleFollowPlayer(); // Calculates the slope and slope according to the x-axis of a line // segment in map coordinates (with the upright y-axis n' all) so @@ -564,19 +568,28 @@ static void AM_ScrollParchment (fixed_t dmapx, fixed_t dmapy) // void AM_changeWindowLoc () { - if (0 != (m_paninc.x | m_paninc.y)) + if (am_rotate) { - followplayer = 0; - f_oldloc.x = FIXED_MAX; + m_rotateoffsx -= Scale(m_paninc.x, SCREENWIDTH, 320); + m_rotateoffsy -= Scale(m_paninc.y, SCREENHEIGHT, 200); + AM_doFollowPlayer(); } + else + { + if (0 != (m_paninc.x | m_paninc.y)) + { + followplayer = 0; + f_oldloc.x = FIXED_MAX; + } - int oldmx = m_x, oldmy = m_y; + int oldmx = m_x, oldmy = m_y; - m_x += Scale (m_paninc.x, SCREENWIDTH, 320); - m_y += Scale (m_paninc.y, SCREENHEIGHT, 200); + m_x += Scale (m_paninc.x, SCREENWIDTH, 320); + m_y += Scale (m_paninc.y, SCREENHEIGHT, 200); - AM_ClipRotatedExtents (); - AM_ScrollParchment (m_x-oldmx, oldmy-m_y); + AM_ClipRotatedExtents (); + AM_ScrollParchment (m_x-oldmx, oldmy-m_y); + } } @@ -971,9 +984,7 @@ bool AM_Responder (event_t *ev) switch (ev->data2) { case AM_FOLLOWKEY: - followplayer = !followplayer; - f_oldloc.x = FIXED_MAX; - Printf ("%s\n", GStrings(followplayer ? "AMSTR_FOLLOWON" : "AMSTR_FOLLOWOFF")); + AM_ToggleFollowPlayer(); break; case AM_GRIDKEY: grid = !grid; @@ -1063,8 +1074,8 @@ void AM_doFollowPlayer () (f_oldloc.x != players[consoleplayer].camera->x || f_oldloc.y != players[consoleplayer].camera->y)) { - m_x = (players[consoleplayer].camera->x >> FRACTOMAPBITS) - m_w/2; - m_y = (players[consoleplayer].camera->y >> FRACTOMAPBITS) - m_h/2; + m_x = ((players[consoleplayer].camera->x >> FRACTOMAPBITS) + m_rotateoffsx) - m_w/2; + m_y = ((players[consoleplayer].camera->y >> FRACTOMAPBITS) + m_rotateoffsy) - m_h/2; m_x2 = m_x + m_w; m_y2 = m_y + m_h; @@ -1082,6 +1093,15 @@ void AM_doFollowPlayer () } } +static void AM_ToggleFollowPlayer() +{ + followplayer = !followplayer; + f_oldloc.x = FIXED_MAX; + m_rotateoffsx = 0; + m_rotateoffsy = 0; + Printf ("%s\n", GStrings(followplayer ? "AMSTR_FOLLOWON" : "AMSTR_FOLLOWOFF")); +} + // // Updates on Game Tick // @@ -1474,8 +1494,8 @@ void AM_rotatePoint (fixed_t *x, fixed_t *y) *x -= players[consoleplayer].camera->x >> FRACTOMAPBITS; *y -= players[consoleplayer].camera->y >> FRACTOMAPBITS; AM_rotate (x, y, ANG90 - players[consoleplayer].camera->angle); - *x += players[consoleplayer].camera->x >> FRACTOMAPBITS; - *y += players[consoleplayer].camera->y >> FRACTOMAPBITS; + *x += (players[consoleplayer].camera->x >> FRACTOMAPBITS) + m_rotateoffsx; + *y += (players[consoleplayer].camera->y >> FRACTOMAPBITS) + m_rotateoffsy; } void @@ -1539,11 +1559,13 @@ void AM_drawPlayers () if (am_cheat != 0) AM_drawLineCharacter (cheat_player_arrow, NUMCHEATPLYRLINES, 0, - angle, YourColor, players[consoleplayer].camera->x >> FRACTOMAPBITS, players[consoleplayer].camera->y >> FRACTOMAPBITS); + angle, YourColor, (players[consoleplayer].camera->x >> FRACTOMAPBITS) + m_rotateoffsx, + (players[consoleplayer].camera->y >> FRACTOMAPBITS) + m_rotateoffsy); else AM_drawLineCharacter (player_arrow, NUMPLYRLINES, 0, angle, - YourColor, players[consoleplayer].camera->x >> FRACTOMAPBITS, players[consoleplayer].camera->y >> FRACTOMAPBITS); + YourColor, (players[consoleplayer].camera->x >> FRACTOMAPBITS) + m_rotateoffsx, + (players[consoleplayer].camera->y >> FRACTOMAPBITS) + m_rotateoffsy); return; } diff --git a/src/d_main.cpp b/src/d_main.cpp index b63bf691b0..dae6892d6e 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -1178,14 +1178,17 @@ void D_AddWildFile (const char *value) { do { - if (sep == NULL) + if (!(I_FindAttr(&findstate) & FA_DIREC)) { - D_AddFile (I_FindName (&findstate)); - } - else - { - strcpy (sep+1, I_FindName (&findstate)); - D_AddFile (path); + if (sep == NULL) + { + D_AddFile (I_FindName (&findstate)); + } + else + { + strcpy (sep+1, I_FindName (&findstate)); + D_AddFile (path); + } } } while (I_FindNext (handle, &findstate) == 0); } diff --git a/src/g_hexen/a_fighterhammer.cpp b/src/g_hexen/a_fighterhammer.cpp index 84f4ea4235..b6ea2097f7 100644 --- a/src/g_hexen/a_fighterhammer.cpp +++ b/src/g_hexen/a_fighterhammer.cpp @@ -218,11 +218,9 @@ void A_FHammerAttack (AActor *actor) } } // didn't find any targets in meleerange, so set to throw out a hammer - PuffSpawned = NULL; angle = pmo->angle; slope = P_AimLineAttack (pmo, angle, HAMMER_RANGE); - P_LineAttack (pmo, angle, HAMMER_RANGE, slope, damage, NAME_Melee, RUNTIME_CLASS(AHammerPuff)); - if (PuffSpawned) + if (P_LineAttack (pmo, angle, HAMMER_RANGE, slope, damage, NAME_Melee, RUNTIME_CLASS(AHammerPuff)) != NULL) { pmo->special1 = false; } diff --git a/src/g_hexen/a_pig.cpp b/src/g_hexen/a_pig.cpp index e3b4d8b55d..095d6a62b1 100644 --- a/src/g_hexen/a_pig.cpp +++ b/src/g_hexen/a_pig.cpp @@ -259,6 +259,7 @@ void A_SnoutAttack (AActor *actor) int damage; int slope; player_t *player; + AActor *puff; if (NULL == (player = actor->player)) { @@ -268,13 +269,12 @@ void A_SnoutAttack (AActor *actor) damage = 3+(pr_snoutattack()&3); angle = player->mo->angle; slope = P_AimLineAttack(player->mo, angle, MELEERANGE); - PuffSpawned = NULL; - P_LineAttack(player->mo, angle, MELEERANGE, slope, damage, NAME_Melee, RUNTIME_CLASS(ASnoutPuff)); + puff = P_LineAttack(player->mo, angle, MELEERANGE, slope, damage, NAME_Melee, RUNTIME_CLASS(ASnoutPuff)); S_Sound(player->mo, CHAN_VOICE, "PigActive", 1, ATTN_NORM); if(linetarget) { AdjustPlayerAngle(player->mo); - if(PuffSpawned) + if(puff != NULL) { // Bit something S_Sound(player->mo, CHAN_VOICE, "PigAttack", 1, ATTN_NORM); } diff --git a/src/g_level.cpp b/src/g_level.cpp index 28abe37f1d..7e9f367aa5 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -494,7 +494,7 @@ static void ParseMapInfoLower (FScanner &sc, cluster_info_t *clusterinfo, QWORD levelflags); -static int FindWadLevelInfo (char *name) +static int FindWadLevelInfo (const char *name) { for (unsigned int i = 0; i < wadlevelinfos.Size(); i++) if (!strnicmp (name, wadlevelinfos[i].mapname, 8)) @@ -1771,26 +1771,35 @@ void G_ChangeLevel(const char * levelname, int position, bool keepFacing, int ne } } -void G_ExitLevel (int position, bool keepFacing) +const char *G_GetExitMap() { - G_ChangeLevel(level.nextmap, position, keepFacing); + return level.nextmap; } -void G_SecretExitLevel (int position) +const char *G_GetSecretExitMap() { const char *nextmap = level.nextmap; if (level.secretmap[0] != 0) { - MapData * map = P_OpenMapData(level.secretmap); + MapData *map = P_OpenMapData(level.secretmap); if (map != NULL) { delete map; nextmap = level.secretmap; } } + return nextmap; +} - G_ChangeLevel(nextmap, position, false); +void G_ExitLevel (int position, bool keepFacing) +{ + G_ChangeLevel(G_GetExitMap(), position, keepFacing); +} + +void G_SecretExitLevel (int position) +{ + G_ChangeLevel(G_GetSecretExitMap(), position, false); } void G_DoCompleted (void) @@ -2455,7 +2464,7 @@ char *CalcMapName (int episode, int level) return lumpname; } -level_info_t *FindLevelInfo (char *mapname) +level_info_t *FindLevelInfo (const char *mapname) { int i; diff --git a/src/g_level.h b/src/g_level.h index 9e401bcb2d..f3d77fd905 100644 --- a/src/g_level.h +++ b/src/g_level.h @@ -338,6 +338,8 @@ void G_DeferedInitNew (const char *mapname, int skill = -1); void G_ExitLevel (int position, bool keepFacing); void G_SecretExitLevel (int position); +const char *G_GetExitMap(); +const char *G_GetSecretExitMap(); void G_ChangeLevel(const char * levelname, int position, bool keepFacing, int nextSkill=-1, bool nointermission=false, bool resetinventory=false, bool nomonsters=false); @@ -357,7 +359,7 @@ void G_MakeEpisodes (void); const char *G_MaybeLookupLevelName (level_info_t *level); cluster_info_t *FindClusterInfo (int cluster); -level_info_t *FindLevelInfo (char *mapname); +level_info_t *FindLevelInfo (const char *mapname); level_info_t *FindLevelByNum (int num); level_info_t *CheckLevelRedirect (level_info_t *info); diff --git a/src/p_lnspec.cpp b/src/p_lnspec.cpp index 49b9c8332c..002ba7b8a6 100644 --- a/src/p_lnspec.cpp +++ b/src/p_lnspec.cpp @@ -733,7 +733,7 @@ FUNC(LS_Generic_Lift) FUNC(LS_Exit_Normal) // Exit_Normal (position) { - if (CheckIfExitIsGood (it)) + if (CheckIfExitIsGood (it, FindLevelInfo(G_GetExitMap()))) { G_ExitLevel (arg0, false); return true; @@ -744,7 +744,7 @@ FUNC(LS_Exit_Normal) FUNC(LS_Exit_Secret) // Exit_Secret (position) { - if (CheckIfExitIsGood (it)) + if (CheckIfExitIsGood (it, FindLevelInfo(G_GetSecretExitMap()))) { G_SecretExitLevel (arg0); return true; @@ -759,7 +759,7 @@ FUNC(LS_Teleport_NewMap) { level_info_t *info = FindLevelByNum (arg0); - if (info && CheckIfExitIsGood (it)) + if (info && CheckIfExitIsGood (it, info)) { G_ChangeLevel(info->mapname, arg1, !!arg2); return true; @@ -814,7 +814,7 @@ FUNC(LS_TeleportInSector) FUNC(LS_Teleport_EndGame) // Teleport_EndGame () { - if (!backSide && CheckIfExitIsGood (it)) + if (!backSide && CheckIfExitIsGood (it, NULL)) { G_SetForEndGame (level.nextmap); G_ExitLevel (0, false); diff --git a/src/p_local.h b/src/p_local.h index 4d98114936..e11f7fdf0b 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -297,11 +297,10 @@ void P_FindFloorCeiling (AActor *actor); bool P_ChangeSector (sector_t* sector, int crunch, int amt, int floorOrCeil); extern AActor* linetarget; // who got hit (or NULL) -extern AActor *PuffSpawned; // points to last puff spawned fixed_t P_AimLineAttack (AActor *t1, angle_t angle, fixed_t distance, fixed_t vrange=0, bool forcenosmart=false); -void P_LineAttack (AActor *t1, angle_t angle, fixed_t distance, int pitch, int damage, FName damageType, const PClass *pufftype); -void P_LineAttack (AActor *t1, angle_t angle, fixed_t distance, int pitch, int damage, FName damageType, FName pufftype); +AActor *P_LineAttack (AActor *t1, angle_t angle, fixed_t distance, int pitch, int damage, FName damageType, const PClass *pufftype); +AActor *P_LineAttack (AActor *t1, angle_t angle, fixed_t distance, int pitch, int damage, FName damageType, FName pufftype); void P_TraceBleed (int damage, fixed_t x, fixed_t y, fixed_t z, AActor *target, angle_t angle, int pitch); void P_TraceBleed (int damage, AActor *target, angle_t angle, int pitch); void P_TraceBleed (int damage, AActor *target, AActor *missile); // missile version diff --git a/src/p_map.cpp b/src/p_map.cpp index 3869ad0058..4453c5cd67 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -2781,7 +2781,7 @@ static bool CheckForSpectral (FTraceResults &res) return false; } -void P_LineAttack (AActor *t1, angle_t angle, fixed_t distance, +AActor *P_LineAttack (AActor *t1, angle_t angle, fixed_t distance, int pitch, int damage, FName damageType, const PClass *pufftype) { fixed_t vx, vy, vz, shootz; @@ -2826,11 +2826,11 @@ void P_LineAttack (AActor *t1, angle_t angle, fixed_t distance, } if (puffDefaults->flags3 & MF3_ALWAYSPUFF) { // Spawn the puff anyway - P_SpawnPuff (pufftype, trace.X, trace.Y, trace.Z, angle - ANG180, 2); + puff = P_SpawnPuff (pufftype, trace.X, trace.Y, trace.Z, angle - ANG180, 2); } else { - return; + return NULL; } } else @@ -2949,10 +2949,12 @@ void P_LineAttack (AActor *t1, angle_t angle, fixed_t distance, if (killPuff && puff != NULL) { puff->Destroy(); + puff = NULL; } + return puff; } -void P_LineAttack (AActor *t1, angle_t angle, fixed_t distance, +AActor *P_LineAttack (AActor *t1, angle_t angle, fixed_t distance, int pitch, int damage, FName damageType, FName pufftype) { const PClass * type = PClass::FindClass(pufftype); @@ -2962,8 +2964,9 @@ void P_LineAttack (AActor *t1, angle_t angle, fixed_t distance, } else { - P_LineAttack(t1, angle, distance, pitch, damage, damageType, type); + return P_LineAttack(t1, angle, distance, pitch, damage, damageType, type); } + return NULL; } void P_TraceBleed (int damage, fixed_t x, fixed_t y, fixed_t z, AActor *actor, angle_t angle, int pitch) diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 4304b54d08..f3f63cd16a 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -159,7 +159,6 @@ CVAR (Int, cl_pufftype, 0, CVAR_ARCHIVE); CVAR (Int, cl_bloodtype, 0, CVAR_ARCHIVE); AActor *MissileActor; -AActor *PuffSpawned; // CODE -------------------------------------------------------------------- @@ -4014,16 +4013,18 @@ AActor *P_SpawnPuff (const PClass *pufftype, fixed_t x, fixed_t y, fixed_t z, an puff->renderflags |= RF_INVISIBLE; } - if (hitthing && puff->SeeSound) - { // Hit thing sound - S_SoundID (puff, CHAN_BODY, puff->SeeSound, 1, ATTN_NORM); - } - else if (puff->AttackSound) + if (!temporary) { - S_SoundID (puff, CHAN_BODY, puff->AttackSound, 1, ATTN_NORM); + if (hitthing && puff->SeeSound) + { // Hit thing sound + S_SoundID (puff, CHAN_BODY, puff->SeeSound, 1, ATTN_NORM); + } + else if (puff->AttackSound) + { + S_SoundID (puff, CHAN_BODY, puff->AttackSound, 1, ATTN_NORM); + } } - PuffSpawned = puff; return puff; } diff --git a/src/p_spec.cpp b/src/p_spec.cpp index e02ef0d2bd..f1aba3c710 100644 --- a/src/p_spec.cpp +++ b/src/p_spec.cpp @@ -119,17 +119,30 @@ static void P_SpawnPushers (); // phares 3/20/98 // [RH] Check dmflags for noexit and respond accordingly -bool CheckIfExitIsGood (AActor *self) +bool CheckIfExitIsGood (AActor *self, level_info_t *info) { + cluster_info_t *cluster; + // The world can always exit itself. if (self == NULL) return true; + // Is this a deathmatch game and we're not allowed to exit? if ((deathmatch || alwaysapplydmflags) && (dmflags & DF_NO_EXIT)) { P_DamageMobj (self, self, self, 1000000, NAME_Exit); return false; } + // Is this a singleplayer game and the next map is part of the same hub and we're dead? + if (self->health <= 0 && + !multiplayer && + info != NULL && + info->cluster == level.cluster && + (cluster = FindClusterInfo(level.cluster)) != NULL && + cluster->flags & CLUSTER_HUB) + { + return false; + } if (deathmatch) { Printf ("%s exited the level.\n", self->player->userinfo.netname); diff --git a/src/p_spec.h b/src/p_spec.h index f3a3b73dd6..9bc860ff13 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -157,7 +157,7 @@ inline FArchive &operator<< (FArchive &arc, DPusher::EPusher &type) // [RH] If a deathmatch game, checks to see if noexit is enabled. // If so, it kills the player and returns false. Otherwise, // it returns true, and the player is allowed to live. -bool CheckIfExitIsGood (AActor *self); +bool CheckIfExitIsGood (AActor *self, level_info_t *info); // at map load void P_SpawnSpecials (void);