diff --git a/docs/rh-log.txt b/docs/rh-log.txt index e2a2143929..f14ae98541 100644 --- a/docs/rh-log.txt +++ b/docs/rh-log.txt @@ -1,4 +1,9 @@ October 26, 2008 (Changes by Graf Zahl) +- Added read and write barriers to the actor pointer in the sound channel + structure. +- Fixed: Items which should stay but had an IF_ALWAYSPICKUP flag were removed. +- Fixed: The pickup flash must only play when an item is picked up so the + correct place to spawn it is in AInventory::Touch, not in AInventory::GoAway. - Fixed: A_Jump didn't properly determine a state's owner anymore when called from weapons. diff --git a/src/dobjgc.cpp b/src/dobjgc.cpp index b17fcc2aad..8ab5fc81b3 100644 --- a/src/dobjgc.cpp +++ b/src/dobjgc.cpp @@ -300,6 +300,7 @@ static void MarkRoot() DThinker::MarkRoots(); FCanvasTextureInfo::Mark(); Mark(DACSThinker::ActiveThinker); + S_MarkSoundChannels(); // Mark dead bodies. for (i = 0; i < BODYQUESIZE; ++i) { diff --git a/src/g_shared/a_pickups.cpp b/src/g_shared/a_pickups.cpp index e652a0a7ba..e3309fc874 100644 --- a/src/g_shared/a_pickups.cpp +++ b/src/g_shared/a_pickups.cpp @@ -553,19 +553,11 @@ bool AInventory::GoAway () // Dropped items never stick around if (flags & MF_DROPPED) { - if (PickupFlash != NULL) - { - Spawn(PickupFlash, x, y, z, ALLOW_REPLACE); - } return false; } if (!ShouldStay ()) { - if (PickupFlash != NULL) - { - Spawn(PickupFlash, x, y, z, ALLOW_REPLACE); - } Hide (); if (ShouldRespawn ()) { @@ -893,8 +885,13 @@ void AInventory::Touch (AActor *toucher) toucher = toucher->player->mo; } - if (!CallTryPickup (toucher)) - return; + // This is the only situation when a pickup flash should ever play. + if (!CallTryPickup (toucher)) return; + + if (PickupFlash != NULL && !ShouldStay()) + { + Spawn(PickupFlash, x, y, z, ALLOW_REPLACE); + } if (!(ItemFlags & IF_QUIET)) { @@ -1264,7 +1261,7 @@ bool AInventory::CallTryPickup (AActor *toucher) { bool res = TryPickup(toucher); - if (!res && (ItemFlags & IF_ALWAYSPICKUP)) + if (!res && (ItemFlags & IF_ALWAYSPICKUP) && !ShouldStay()) { res = true; GoAwayAndDie(); diff --git a/src/m_menu.cpp b/src/m_menu.cpp index a6f2411aff..1da41e4d8b 100644 --- a/src/m_menu.cpp +++ b/src/m_menu.cpp @@ -1637,9 +1637,13 @@ void M_NewGame(int choice) } else if (EpiDef.numitems <= 1) { - if (EpisodeNoSkill[0]) + if (AllSkills.Size() == 1) { - M_ChooseSkill(2); + M_ChooseSkill(0); + } + else if (EpisodeNoSkill[0]) + { + M_ChooseSkill(AllSkills.Size() == 2? 1:2); } else { @@ -1823,12 +1827,16 @@ void M_Episode (int choice) epi = choice; - if (EpisodeNoSkill[choice]) + if (AllSkills.Size() == 1) { - M_ChooseSkill(2); + M_ChooseSkill(0); + return; + } + else if (EpisodeNoSkill[choice]) + { + M_ChooseSkill(AllSkills.Size() == 2? 1:2); return; } - M_StartupSkillMenu(NULL); } @@ -1858,13 +1866,17 @@ static void SCClass (int option) { M_SetupNextMenu (&EpiDef); } + else if (AllSkills.Size() == 1) + { + M_ChooseSkill(0); + } else if (!EpisodeNoSkill[0]) { M_StartupSkillMenu(playerclass); } else { - M_ChooseSkill(2); + M_ChooseSkill(AllSkills.Size() == 2? 1:2); } } @@ -1886,9 +1898,13 @@ static void M_ChooseClass (int choice) { M_SetupNextMenu (&EpiDef); } + else if (AllSkills.Size() == 1) + { + M_ChooseSkill(0); + } else if (EpisodeNoSkill[0]) { - M_ChooseSkill(2); + M_ChooseSkill(AllSkills.Size() == 2? 1:2); } else { diff --git a/src/s_sound.cpp b/src/s_sound.cpp index 6799119b51..106b549811 100644 --- a/src/s_sound.cpp +++ b/src/s_sound.cpp @@ -101,7 +101,7 @@ extern float S_GetMusicVolume (const char *music); static bool S_CheckSoundLimit(sfxinfo_t *sfx, const FVector3 &pos, int near_limit); static void S_ActivatePlayList(bool goBack); -static void CalcPosVel(const FSoundChan *chan, FVector3 *pos, FVector3 *vel); +static void CalcPosVel(FSoundChan *chan, FVector3 *pos, FVector3 *vel); static void CalcPosVel(int type, const AActor *actor, const sector_t *sector, const FPolyObj *poly, const float pt[3], int channel, int chanflags, FVector3 *pos, FVector3 *vel); static void CalcSectorSoundOrg(const sector_t *sec, int channum, fixed_t *x, fixed_t *y, fixed_t *z); @@ -625,7 +625,7 @@ void S_LinkChannel(FSoundChan *chan, FSoundChan **head) // //========================================================================= -static void CalcPosVel(const FSoundChan *chan, FVector3 *pos, FVector3 *vel) +static void CalcPosVel(FSoundChan *chan, FVector3 *pos, FVector3 *vel) { CalcPosVel(chan->SourceType, chan->Actor, chan->Sector, chan->Poly, chan->Point, chan->EntChannel, chan->ChanFlags, pos, vel); @@ -1057,7 +1057,7 @@ static FSoundChan *S_StartSound(AActor *actor, const sector_t *sec, const FPolyO chan->SourceType = type; switch (type) { - case SOURCE_Actor: chan->Actor = actor; actor->SoundChans |= 1 << channel; break; + case SOURCE_Actor: chan->Actor = actor; actor->SoundChans |= 1 << channel; GC::WriteBarrier(actor); break; case SOURCE_Sector: chan->Sector = sec; break; case SOURCE_Polyobj: chan->Poly = poly; break; case SOURCE_Unattached: chan->Point[0] = pt->X; chan->Point[1] = pt->Y; chan->Point[2] = pt->Z; break; @@ -1436,6 +1436,27 @@ void S_StopSound (const FPolyObj *poly, int channel) } } +//========================================================================== +// +// S_MarkSoundChannels +// +//========================================================================== + +void S_MarkSoundChannels() +{ + for (FSoundChan *chan = Channels; chan != NULL; chan = chan->NextChan) + { + if (chan->SourceType == SOURCE_Actor) + { + GC::Mark(chan->Actor); + } + else + { + chan->Actor = NULL; + } + } +} + //========================================================================== // // S_StopAllChannels @@ -1476,9 +1497,11 @@ void S_RelinkSound (AActor *from, AActor *to) if (to != NULL) { chan->Actor = to; + GC::WriteBarrier(to); } else if (!(chan->ChanFlags & CHAN_LOOP)) { + chan->Actor = NULL; chan->SourceType = SOURCE_Unattached; chan->Point[0] = FIXED2FLOAT(from->x); chan->Point[1] = FIXED2FLOAT(from->z); diff --git a/src/s_sound.h b/src/s_sound.h index bf7b67baf3..2aa9e58397 100644 --- a/src/s_sound.h +++ b/src/s_sound.h @@ -23,6 +23,7 @@ #include "doomtype.h" #include "i_soundinternal.h" +#include "dobject.h" class AActor; class FScanner; @@ -177,9 +178,10 @@ struct FSoundChan : public FISoundChannel SBYTE Priority; SWORD NearLimit; BYTE SourceType; + TObjPtr Actor; union { - AActor *Actor; // Used for position and velocity. + //AActor *Actor; // Used for position and velocity. const sector_t *Sector; // Sector for area sounds. const FPolyObj *Poly; // Polyobject sound source. float Point[3]; // Sound is not attached to any source. @@ -276,6 +278,7 @@ bool S_CheckSingular (int sound_id); void S_StopSound (AActor *ent, int channel); void S_StopSound (const sector_t *sec, int channel); void S_StopSound (const FPolyObj *poly, int channel); +void S_MarkSoundChannels(); // Stops an origin-less sound from playing from this channel. void S_StopSound (int channel); diff --git a/src/thingdef/thingdef_data.cpp b/src/thingdef/thingdef_data.cpp index 4a67990f1c..3f610276e2 100644 --- a/src/thingdef/thingdef_data.cpp +++ b/src/thingdef/thingdef_data.cpp @@ -224,6 +224,7 @@ static FFlagDef ActorFlags[]= DEFINE_DEPRECATED_FLAG(FIRERESIST), DEFINE_DUMMY_FLAG(NONETID), DEFINE_DUMMY_FLAG(ALLOWCLIENTSPAWN), + DEFINE_DUMMY_FLAG(CLIENTSIDEONLY), }; static FFlagDef InventoryFlags[] =