mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-11 15:22:16 +00:00
- 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:
parent
49ea87f8bc
commit
f82024efbf
4 changed files with 120 additions and 29 deletions
|
@ -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
|
||||||
|
|
|
@ -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,
|
||||||
|
|
110
src/s_sndseq.cpp
110
src/s_sndseq.cpp
|
@ -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
|
||||||
|
|
|
@ -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 *);
|
||||||
|
|
Loading…
Reference in a new issue