diff --git a/docs/rh-log.txt b/docs/rh-log.txt index 038aee92fa..90cc58b197 100644 --- a/docs/rh-log.txt +++ b/docs/rh-log.txt @@ -1,3 +1,18 @@ +February 3, 2007 +- Reduced the rate at which drowning damage increases. +- Added more player water sounds: + *dive - Played when your head goes below water. + *surface - Played when your head goes back above water. + *gasp - Played when you were drowning and get your air back. + If your head surfaces and you were drowning, only *gasp plays, not both. +- Added damage-specific player death sounds, in the same fashion as the + damage-specific player pain sounds. It looks for a sound with a name like + "*death-damagetype" first and then "*death" if the first sound didn't exist. +- Removed the constraint that player sounds must be reserved before they can + be assigned. Hence, the $playerreserve command has been eliminated, because + it is no longer needed and it was never accessible from user wads, so I + don't need to worry about breaking anything by removing it. + February 2, 2007 - Added a new fixrtext tool that sets the IMAGE_SCN_MEM_WRITE flag for .rtext files in the assembly object files. Now I can avoid doing this at diff --git a/src/actor.h b/src/actor.h index b9e86a88ba..4557738836 100644 --- a/src/actor.h +++ b/src/actor.h @@ -749,7 +749,7 @@ public: int GetTics(FState * newstate); bool SetState (FState *newstate); bool SetStateNF (FState *newstate); - bool UpdateWaterLevel (fixed_t oldz, bool splash=true); + virtual bool UpdateWaterLevel (fixed_t oldz, bool splash=true); FState *FindState (FName label) const; FState *FindState (FName label, FName sublabel, bool exact = false) const; diff --git a/src/d_player.h b/src/d_player.h index 68663f8aed..9bcd399d75 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -117,6 +117,9 @@ public: int SpawnMask; FNameNoInit MorphWeapon; + bool UpdateWaterLevel (fixed_t oldz, bool splash); + bool ResetAirSupply (); + int GetMaxHealth() const; }; diff --git a/src/g_shared/a_artifacts.cpp b/src/g_shared/a_artifacts.cpp index 7f45b9611f..a921dece99 100644 --- a/src/g_shared/a_artifacts.cpp +++ b/src/g_shared/a_artifacts.cpp @@ -727,7 +727,7 @@ void APowerIronFeet::AbsorbDamage (int damage, FName damageType, int &newdamage) newdamage = 0; if (Owner->player != NULL) { - Owner->player->air_finished = level.time + level.airsupply; + Owner->player->mo->ResetAirSupply (); } } else if (Inventory != NULL) diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 5d3b7299a8..f9a76c21ca 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -3478,7 +3478,7 @@ void P_SpawnPlayer (mapthing2_t *mthing, bool tempplayer) p->multicount = 0; p->lastkilltime = 0; p->BlendR = p->BlendG = p->BlendB = p->BlendA = 0.f; - p->air_finished = level.time + level.airsupply; + p->mo->ResetAirSupply(); p->Uncrouch(); p->momx = p->momy = 0; // killough 10/98: initialize bobbing to 0. diff --git a/src/p_user.cpp b/src/p_user.cpp index 6c6cff84fd..fe2e54d8a0 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -832,6 +832,55 @@ int APlayerPawn::GetMaxHealth() const return MaxHealth > 0? MaxHealth : ((i_compatflags&COMPATF_DEHHEALTH)? 100 : deh.MaxHealth); } +//=========================================================================== +// +// APlayerPawn :: UpdateWaterLevel +// +// Plays surfacing and diving sounds, as appropriate. +// +//=========================================================================== + +bool APlayerPawn::UpdateWaterLevel (fixed_t oldz, bool splash) +{ + int oldlevel = waterlevel; + bool retval = Super::UpdateWaterLevel (oldz, splash); + if (oldlevel < 3 && waterlevel == 3) + { // Our head just went under. + S_Sound (this, CHAN_VOICE, "*dive", 1, ATTN_NORM); + } + else if (oldlevel == 3 && waterlevel < 3) + { // Our head just came up. + if (player->air_finished > level.time) + { // We hadn't run out of air yet. + S_Sound (this, CHAN_VOICE, "*surface", 1, ATTN_NORM); + } + // If we were running out of air, then ResetAirSupply() will play *gasp. + } + return retval; +} + +//=========================================================================== +// +// APlayerPawn :: ResetAirSupply +// +// Gives the player a full "tank" of air. If they had previously completely +// run out of air, also plays the *gasp sound. Returns true if the player +// was drowning. +// +//=========================================================================== + +bool APlayerPawn::ResetAirSupply () +{ + bool wasdrowning = (player->air_finished < level.time); + + if (wasdrowning) + { + S_Sound (this, CHAN_VOICE, "*gasp", 1, ATTN_NORM); + } + player->air_finished = level.time + level.airsupply; + return wasdrowning; +} + //=========================================================================== // // Animations @@ -1108,27 +1157,27 @@ void A_PlayerScream (AActor *self) if (!sound && self->special1<10) { // Wimpy death sound - sound = S_FindSkinnedSound (self, "*wimpydeath"); + sound = S_FindSkinnedSoundEx (self, "*wimpydeath", self->player->LastDamageType); } if (!sound && self->health <= -50) { if (self->health > -100) { // Crazy death sound - sound = S_FindSkinnedSound (self, "*crazydeath"); + sound = S_FindSkinnedSoundEx (self, "*crazydeath", self->player->LastDamageType); } if (!sound) { // Extreme death sound - sound = S_FindSkinnedSound (self, "*xdeath"); + sound = S_FindSkinnedSoundEx (self, "*xdeath", self->player->LastDamageType); if (!sound) { - sound = S_FindSkinnedSound (self, "*gibbed"); + sound = S_FindSkinnedSoundEx (self, "*gibbed", self->player->LastDamageType); chan = CHAN_BODY; } } } if (!sound) { // Normal death sound - sound=S_FindSkinnedSound (self, "*death"); + sound = S_FindSkinnedSoundEx (self, "*death", self->player->LastDamageType); } if (chan != CHAN_VOICE) @@ -2122,17 +2171,17 @@ void P_PlayerThink (player_t *player) } // Handle air supply - if (level.airsupply>0) + if (level.airsupply > 0) { if (player->mo->waterlevel < 3 || (player->mo->flags2 & MF2_INVULNERABLE) || (player->cheats & CF_GODMODE)) { - player->air_finished = level.time + level.airsupply; + player->mo->ResetAirSupply (); } else if (player->air_finished <= level.time && !(level.time & 31)) { - P_DamageMobj (player->mo, NULL, NULL, 2 + 2*((level.time-player->air_finished)/TICRATE), NAME_Drowning); + P_DamageMobj (player->mo, NULL, NULL, 2 + ((level.time-player->air_finished)/TICRATE), NAME_Drowning); } } } diff --git a/src/s_advsound.cpp b/src/s_advsound.cpp index 0f2fb87727..67a98e24f1 100644 --- a/src/s_advsound.cpp +++ b/src/s_advsound.cpp @@ -128,7 +128,6 @@ enum SICommands { SI_Ambient, SI_Random, - SI_PlayerReserve, SI_PlayerSound, SI_PlayerSoundDup, SI_PlayerCompat, @@ -219,7 +218,6 @@ static const char *SICommandStrings[] = { "$ambient", "$random", - "$playerreserve", "$playersound", "$playersounddup", "$playercompat", @@ -452,7 +450,12 @@ int S_AddSoundLump (const char *logicalname, int lump) int S_FindSoundTentative (const char *name) { int id = S_FindSoundNoHash (name); - return id != 0 ? id : S_AddSoundLump (name, -1); + if (id == 0) + { + id = S_AddSoundLump (name, -1); + S_sfx[id].bTentative = true; + } + return id; } //========================================================================== @@ -500,6 +503,7 @@ static int S_AddSound (const char *logicalname, int lumpnum) sfx->lumpnum = lumpnum; sfx->bRandomHeader = false; sfx->link = sfxinfo_t::NO_LINK; + sfx->bTentative = false; //sfx->PitchMask = CurrentPitchMask; } else @@ -537,9 +541,9 @@ int S_AddPlayerSound (const char *pclass, int gender, int refid, int lumpnum, bo int id; fakename = pclass; - fakename += ';'; + fakename += '"'; fakename += '0' + gender; - fakename += ';'; + fakename += '"'; fakename += S_sfx[refid].name; id = S_AddSoundLump (fakename, lumpnum); @@ -1000,16 +1004,6 @@ static void S_AddSNDINFO (int lump) SC_MustGetString (); // Unused for now break; - case SI_PlayerReserve: - // $playerreserve - { - SC_MustGetString (); - int id = S_AddSound (sc_String, -1); - S_sfx[id].link = NumPlayerReserves++; - S_sfx[id].bPlayerReserve = true; - } - break; - case SI_PlayerSound: { // $playersound char pclass[MAX_SNDNAME+1]; @@ -1269,9 +1263,20 @@ static void S_ParsePlayerSoundCommon (char pclass[MAX_SNDNAME+1], int &gender, i gender = D_GenderToInt (sc_String); SC_MustGetString (); refid = S_FindSoundNoHash (sc_String); - if (!S_sfx[refid].bPlayerReserve) + if (refid != 0 && !S_sfx[refid].bPlayerReserve && !S_sfx[refid].bTentative) { - SC_ScriptError ("%s has not been reserved for a player sound", sc_String); + SC_ScriptError ("%s has already been used for a non-player sound.", sc_String); + } + if (refid == 0) + { + refid = S_AddSound (sc_String, -1); + S_sfx[refid].bTentative = true; + } + if (S_sfx[refid].bTentative) + { + S_sfx[refid].link = NumPlayerReserves++; + S_sfx[refid].bTentative = false; + S_sfx[refid].bPlayerReserve = true; } SC_MustGetString (); } @@ -1601,6 +1606,31 @@ int S_FindSkinnedSound (AActor *actor, int refid) return S_LookupPlayerSound (pclass, gender, refid); } +//========================================================================== +// +// S_FindSkinnedSoundEx +// +// Tries looking for both "name-extendedname" and "name" in that order. +//========================================================================== + +int S_FindSkinnedSoundEx (AActor *actor, const char *name, const char *extendedname) +{ + FString fullname; + int id; + + // Look for "name-extendedname"; + fullname = name; + fullname += '-'; + fullname += extendedname; + id = S_FindSound (fullname); + + if (id == 0) + { // Look for "name" + id = S_FindSound (name); + } + return S_FindSkinnedSound (actor, id); +} + //========================================================================== // // CCMD soundlist diff --git a/src/s_sound.h b/src/s_sound.h index 908003055d..e0a5bbed0d 100644 --- a/src/s_sound.h +++ b/src/s_sound.h @@ -57,6 +57,7 @@ struct sfxinfo_t WORD b16bit:1; WORD bUsed:1; WORD bSingular:1; + WORD bTentative:1; WORD link; @@ -194,6 +195,7 @@ bool S_AreSoundsEquivalent (AActor *actor, const char *name1, const char *name2) int S_LookupPlayerSound (const char *playerclass, int gender, const char *logicalname); int S_LookupPlayerSound (const char *playerclass, int gender, int refid); int S_FindSkinnedSound (AActor *actor, const char *logicalname); +int S_FindSkinnedSoundEx (AActor *actor, const char *logicalname, const char *extendedname); int S_FindSkinnedSound (AActor *actor, int refid); int S_FindSoundByLump (int lump); int S_AddSound (const char *logicalname, const char *lumpname); // Add sound by lumpname diff --git a/wadsrc/sndinfo.txt b/wadsrc/sndinfo.txt index 420a0cb4f5..aff744df65 100644 --- a/wadsrc/sndinfo.txt +++ b/wadsrc/sndinfo.txt @@ -13,29 +13,6 @@ // //=========================================================================== -$playerreserve *death -$playerreserve *xdeath -$playerreserve *wimpydeath -$playerreserve *crazydeath -$playerreserve *burndeath -$playerreserve *gibbed -$playerreserve *splat -$playerreserve *pain100 -$playerreserve *pain75 -$playerreserve *pain50 -$playerreserve *pain25 -$playerreserve *grunt -$playerreserve *land -$playerreserve *falling -$playerreserve *jump -$playerreserve *fist -$playerreserve *fistgrunt -$playerreserve *usefail -$playerreserve *evillaugh -$playerreserve *weaponlaugh -$playerreserve *puzzfail -$playerreserve *poison - // Use *pain in a script to play any of the pain sounds $random *pain { *pain100 *pain75 *pain50 *pain25 }