- Fixed: Prematurely closing a Door_Raise-type door now properly examines the actual sound

sequence to determine if it should start the closing sequence.

SVN r3476 (trunk)
This commit is contained in:
Randy Heit 2012-03-23 22:21:33 +00:00
parent 49ea87f8bc
commit f82024efbf
4 changed files with 120 additions and 29 deletions

View file

@ -232,9 +232,13 @@ void DDoor::Tick ()
// //
// [RH] DoorSound: Plays door sound depending on direction and speed // [RH] DoorSound: Plays door sound depending on direction and speed
// //
// If curseq is non-NULL, then it will check if the desired sound sequence
// will result in a different command stream than the current one. If not,
// then it does nothing.
//
//============================================================================ //============================================================================
void DDoor::DoorSound (bool raise) const void DDoor::DoorSound(bool raise, DSeqNode *curseq) const
{ {
int choice; int choice;
@ -253,11 +257,17 @@ void DDoor::DoorSound (bool raise) const
if (m_Sector->seqType >= 0) if (m_Sector->seqType >= 0)
{ {
SN_StartSequence (m_Sector, CHAN_CEILING, m_Sector->seqType, SEQ_DOOR, choice); if (curseq == NULL || !SN_AreModesSame(m_Sector->seqType, SEQ_DOOR, choice, curseq->GetModeNum()))
{
SN_StartSequence(m_Sector, CHAN_CEILING, m_Sector->seqType, SEQ_DOOR, choice);
}
} }
else if (m_Sector->SeqName != NAME_None) else if (m_Sector->SeqName != NAME_None)
{ {
SN_StartSequence (m_Sector, CHAN_CEILING, m_Sector->SeqName, choice); if (curseq == NULL || !SN_AreModesSame(m_Sector->SeqName, choice, curseq->GetModeNum()))
{
SN_StartSequence(m_Sector, CHAN_CEILING, m_Sector->SeqName, choice);
}
} }
else else
{ {
@ -318,7 +328,10 @@ void DDoor::DoorSound (bool raise) const
} }
break; break;
} }
SN_StartSequence (m_Sector, CHAN_CEILING, snd, choice); if (curseq == NULL || !SN_AreModesSame(snd, choice, curseq->GetModeNum()))
{
SN_StartSequence(m_Sector, CHAN_CEILING, snd, choice);
}
} }
} }
@ -450,15 +463,8 @@ bool EV_DoDoor (DDoor::EVlDoor type, line_t *line, AActor *thing,
door->m_Direction = -1; // start going down immediately door->m_Direction = -1; // start going down immediately
// [RH] If this sector doesn't have a specific sound // Start the door close sequence.
// attached to it, start the door close sequence. door->DoorSound(false, SN_CheckSequence(sec, CHAN_CEILING));
// Otherwise, just let the current one continue.
// FIXME: This should be check if the sound sequence has separate up/down
// paths, not if it was manually set.
if ((sec->seqType < 0 && sec->SeqName == NAME_None) || SN_CheckSequence(sec, CHAN_CEILING) == NULL)
{
door->DoorSound (false);
}
return true; return true;
} }
else else

View file

@ -531,7 +531,7 @@ protected:
int m_LightTag; int m_LightTag;
void DoorSound (bool raise) const; void DoorSound (bool raise, class DSeqNode *curseq=NULL) const;
friend bool EV_DoDoor (DDoor::EVlDoor type, line_t *line, AActor *thing, friend bool EV_DoDoor (DDoor::EVlDoor type, line_t *line, AActor *thing,
int tag, int speed, int delay, int lock, int tag, int speed, int delay, int lock,

View file

@ -839,10 +839,7 @@ static bool TwiddleSeqNum (int &sequence, seqtype_t type)
} }
} }
if (sequence == -1 || Sequences[sequence] == NULL) return ((size_t)sequence < Sequences.Size() && Sequences[sequence] != NULL);
return false;
else
return true;
} }
DSeqNode *SN_StartSequence (AActor *actor, int sequence, seqtype_t type, int modenum, bool nostop) DSeqNode *SN_StartSequence (AActor *actor, int sequence, seqtype_t type, int modenum, bool nostop)
@ -892,7 +889,7 @@ DSeqNode *SN_StartSequence (FPolyObj *poly, int sequence, seqtype_t type, int mo
DSeqNode *SN_StartSequence (AActor *actor, const char *seqname, int modenum) DSeqNode *SN_StartSequence (AActor *actor, const char *seqname, int modenum)
{ {
int seqnum = FindSequence (seqname); int seqnum = FindSequence(seqname);
if (seqnum >= 0) if (seqnum >= 0)
{ {
return SN_StartSequence (actor, seqnum, SEQ_NOTRANS, modenum); return SN_StartSequence (actor, seqnum, SEQ_NOTRANS, modenum);
@ -902,7 +899,7 @@ DSeqNode *SN_StartSequence (AActor *actor, const char *seqname, int modenum)
DSeqNode *SN_StartSequence (AActor *actor, FName seqname, int modenum) DSeqNode *SN_StartSequence (AActor *actor, FName seqname, int modenum)
{ {
int seqnum = FindSequence (seqname); int seqnum = FindSequence(seqname);
if (seqnum >= 0) if (seqnum >= 0)
{ {
return SN_StartSequence (actor, seqnum, SEQ_NOTRANS, modenum); return SN_StartSequence (actor, seqnum, SEQ_NOTRANS, modenum);
@ -912,7 +909,7 @@ DSeqNode *SN_StartSequence (AActor *actor, FName seqname, int modenum)
DSeqNode *SN_StartSequence (sector_t *sec, int chan, const char *seqname, int modenum) DSeqNode *SN_StartSequence (sector_t *sec, int chan, const char *seqname, int modenum)
{ {
int seqnum = FindSequence (seqname); int seqnum = FindSequence(seqname);
if (seqnum >= 0) if (seqnum >= 0)
{ {
return SN_StartSequence (sec, chan, seqnum, SEQ_NOTRANS, modenum); return SN_StartSequence (sec, chan, seqnum, SEQ_NOTRANS, modenum);
@ -922,7 +919,7 @@ DSeqNode *SN_StartSequence (sector_t *sec, int chan, const char *seqname, int mo
DSeqNode *SN_StartSequence (sector_t *sec, int chan, FName seqname, int modenum) DSeqNode *SN_StartSequence (sector_t *sec, int chan, FName seqname, int modenum)
{ {
int seqnum = FindSequence (seqname); int seqnum = FindSequence(seqname);
if (seqnum >= 0) if (seqnum >= 0)
{ {
return SN_StartSequence (sec, chan, seqnum, SEQ_NOTRANS, modenum); return SN_StartSequence (sec, chan, seqnum, SEQ_NOTRANS, modenum);
@ -932,7 +929,7 @@ DSeqNode *SN_StartSequence (sector_t *sec, int chan, FName seqname, int modenum)
DSeqNode *SN_StartSequence (FPolyObj *poly, const char *seqname, int modenum) DSeqNode *SN_StartSequence (FPolyObj *poly, const char *seqname, int modenum)
{ {
int seqnum = FindSequence (seqname); int seqnum = FindSequence(seqname);
if (seqnum >= 0) if (seqnum >= 0)
{ {
return SN_StartSequence (poly, seqnum, SEQ_NOTRANS, modenum); return SN_StartSequence (poly, seqnum, SEQ_NOTRANS, modenum);
@ -942,20 +939,18 @@ DSeqNode *SN_StartSequence (FPolyObj *poly, const char *seqname, int modenum)
static int FindSequence (const char *searchname) static int FindSequence (const char *searchname)
{ {
FName seqname (searchname, true); FName seqname(searchname, true);
if (seqname != NAME_None) if (seqname != NAME_None)
{ {
return FindSequence (seqname); return FindSequence(seqname);
} }
return -1; return -1;
} }
static int FindSequence (FName seqname) static int FindSequence (FName seqname)
{ {
int i; for (int i = Sequences.Size(); i-- > 0; )
for (i = Sequences.Size(); i-- > 0; )
{ {
if (Sequences[i] != NULL && seqname == Sequences[i]->SeqName) if (Sequences[i] != NULL && seqname == Sequences[i]->SeqName)
{ {
@ -1351,6 +1346,93 @@ void DSeqNode::ChangeData (int seqOffset, int delayTics, float volume, FSoundID
m_CurrentSoundID = currentSoundID; m_CurrentSoundID = currentSoundID;
} }
//==========================================================================
//
// FindMode
//
// Finds the sequence this sequence and mode combination selects.
//
//==========================================================================
static int FindMode(int seqnum, int mode)
{
if (seqnum <= 0)
{ // Sequence does not exist.
return seqnum;
}
FSoundSequence *seq = Sequences[seqnum];
if (GetCommand(seq->Script[0]) != SS_CMD_SELECT)
{ // This sequence doesn't select any others.
return seqnum;
}
// Search for the desired mode amongst the selections
int nummodes = GetData(seq->Script[0]);
for (int i = 0; i < nummodes; ++i)
{
if (seq->Script[1 + i*2] == mode)
{
return FindSequence(ENamedName(seq->Script[1 + i*2 + 1]));
}
}
// The mode isn't selected, which means it stays on this sequence.
return seqnum;
}
//==========================================================================
//
// FindModeDeep
//
// Finds the final sequence this sequence and mode combination selects.
//
//==========================================================================
static int FindModeDeep(int seqnum, int mode)
{
int newseqnum = FindMode(seqnum, mode);
while (newseqnum != seqnum)
{
seqnum = newseqnum;
newseqnum = FindMode(seqnum, mode);
}
return seqnum;
}
//==========================================================================
//
// SN_AreModesSame
//
// Returns true if mode1 and mode2 represent the same sequence.
//
//==========================================================================
bool SN_AreModesSame(int seqnum, seqtype_t type, int mode1, int mode2)
{
if (mode1 == mode2)
{ // Obviously they're the same.
return true;
}
if (TwiddleSeqNum(seqnum, type))
{
int mode1seq = FindModeDeep(seqnum, mode1);
int mode2seq = FindModeDeep(seqnum, mode2);
return mode1seq == mode2seq;
}
// The sequence doesn't exist, so that makes both modes equally nonexistant.
return true;
}
bool SN_AreModesSame(const char *name, int mode1, int mode2)
{
int seqnum = FindSequence(name);
if (seqnum >= 0)
{
return SN_AreModesSame(seqnum, SEQ_NOTRANS, mode1, mode2);
}
// The sequence doesn't exist, so that makes both modes equally nonexistant.
return true;
}
//========================================================================== //==========================================================================
// //
// CCMD playsequence // CCMD playsequence

View file

@ -26,6 +26,7 @@ public:
void Tick (); void Tick ();
void ChangeData (int seqOffset, int delayTics, float volume, FSoundID currentSoundID); void ChangeData (int seqOffset, int delayTics, float volume, FSoundID currentSoundID);
void AddChoice (int seqnum, seqtype_t type); void AddChoice (int seqnum, seqtype_t type);
int GetModeNum() const { return m_ModeNum; }
FName GetSequenceName() const; FName GetSequenceName() const;
static void StaticMarkHead() { GC::Mark(SequenceListHead); } static void StaticMarkHead() { GC::Mark(SequenceListHead); }
@ -89,6 +90,8 @@ DSeqNode *SN_CheckSequence (sector_t *sector, int chan);
void SN_StopSequence (AActor *mobj); void SN_StopSequence (AActor *mobj);
void SN_StopSequence (sector_t *sector, int chan); void SN_StopSequence (sector_t *sector, int chan);
void SN_StopSequence (FPolyObj *poly); void SN_StopSequence (FPolyObj *poly);
bool SN_AreModesSame(int sequence, seqtype_t type, int mode1, int mode2);
bool SN_AreModesSame(const char *name, int mode1, int mode2);
void SN_UpdateActiveSequences (void); void SN_UpdateActiveSequences (void);
ptrdiff_t SN_GetSequenceOffset (int sequence, SDWORD *sequencePtr); ptrdiff_t SN_GetSequenceOffset (int sequence, SDWORD *sequencePtr);
void SN_DoStop (void *); void SN_DoStop (void *);