2006-02-24 04:48:15 +00:00
|
|
|
// Emacs style mode select -*- C++ -*-
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
//
|
|
|
|
// $Id:$
|
|
|
|
//
|
|
|
|
// Copyright (C) 1993-1996 by id Software, Inc.
|
|
|
|
//
|
|
|
|
// This source is available for distribution and/or modification
|
|
|
|
// only under the terms of the DOOM Source Code License as
|
|
|
|
// published by id Software. All rights reserved.
|
|
|
|
//
|
|
|
|
// The source is distributed in the hope that it will be useful,
|
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
|
|
|
|
// for more details.
|
|
|
|
//
|
|
|
|
// $Log:$
|
|
|
|
//
|
|
|
|
// DESCRIPTION: Door animation code (opening/closing)
|
|
|
|
// [RH] Removed sliding door code and simplified for Hexen-ish specials
|
|
|
|
//
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include "doomdef.h"
|
|
|
|
#include "p_local.h"
|
|
|
|
#include "s_sound.h"
|
|
|
|
#include "s_sndseq.h"
|
|
|
|
#include "doomstat.h"
|
|
|
|
#include "r_state.h"
|
|
|
|
#include "c_console.h"
|
|
|
|
#include "gi.h"
|
|
|
|
#include "a_keys.h"
|
|
|
|
#include "i_system.h"
|
|
|
|
#include "sc_man.h"
|
2008-09-14 23:54:38 +00:00
|
|
|
#include "cmdlib.h"
|
2011-07-06 14:20:54 +00:00
|
|
|
#include "farchive.h"
|
2006-02-24 04:48:15 +00:00
|
|
|
|
2010-12-27 16:14:26 +00:00
|
|
|
//============================================================================
|
|
|
|
//
|
|
|
|
// VERTICAL DOORS
|
|
|
|
//
|
|
|
|
//============================================================================
|
|
|
|
|
2006-02-24 04:48:15 +00:00
|
|
|
IMPLEMENT_CLASS (DDoor)
|
|
|
|
|
2011-07-06 14:20:54 +00:00
|
|
|
inline FArchive &operator<< (FArchive &arc, DDoor::EVlDoor &type)
|
|
|
|
{
|
|
|
|
BYTE val = (BYTE)type;
|
|
|
|
arc << val;
|
|
|
|
type = (DDoor::EVlDoor)val;
|
|
|
|
return arc;
|
|
|
|
}
|
|
|
|
|
2006-02-24 04:48:15 +00:00
|
|
|
DDoor::DDoor ()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void DDoor::Serialize (FArchive &arc)
|
|
|
|
{
|
|
|
|
Super::Serialize (arc);
|
|
|
|
arc << m_Type
|
|
|
|
<< m_TopDist
|
|
|
|
<< m_BotSpot << m_BotDist << m_OldFloorDist
|
|
|
|
<< m_Speed
|
|
|
|
<< m_Direction
|
|
|
|
<< m_TopWait
|
|
|
|
<< m_TopCountdown
|
|
|
|
<< m_LightTag;
|
|
|
|
}
|
|
|
|
|
2010-12-27 16:14:26 +00:00
|
|
|
//============================================================================
|
2006-02-24 04:48:15 +00:00
|
|
|
//
|
|
|
|
// T_VerticalDoor
|
|
|
|
//
|
2010-12-27 16:14:26 +00:00
|
|
|
//============================================================================
|
|
|
|
|
2006-02-24 04:48:15 +00:00
|
|
|
void DDoor::Tick ()
|
|
|
|
{
|
|
|
|
EResult res;
|
|
|
|
|
|
|
|
if (m_Sector->floorplane.d != m_OldFloorDist)
|
|
|
|
{
|
|
|
|
if (!m_Sector->floordata || !m_Sector->floordata->IsKindOf(RUNTIME_CLASS(DPlat)) ||
|
2008-03-12 02:56:11 +00:00
|
|
|
!(barrier_cast<DPlat*>(m_Sector->floordata))->IsLift())
|
2006-02-24 04:48:15 +00:00
|
|
|
{
|
|
|
|
m_OldFloorDist = m_Sector->floorplane.d;
|
|
|
|
m_BotDist = m_Sector->ceilingplane.PointToDist (m_BotSpot,
|
|
|
|
m_Sector->floorplane.ZatPoint (m_BotSpot));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (m_Direction)
|
|
|
|
{
|
|
|
|
case 0:
|
|
|
|
// WAITING
|
|
|
|
if (!--m_TopCountdown)
|
|
|
|
{
|
|
|
|
switch (m_Type)
|
|
|
|
{
|
|
|
|
case doorRaise:
|
|
|
|
m_Direction = -1; // time to go back down
|
|
|
|
DoorSound (false);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case doorCloseWaitOpen:
|
|
|
|
m_Direction = 1;
|
|
|
|
DoorSound (true);
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 2:
|
|
|
|
// INITIAL WAIT
|
|
|
|
if (!--m_TopCountdown)
|
|
|
|
{
|
|
|
|
switch (m_Type)
|
|
|
|
{
|
|
|
|
case doorRaiseIn5Mins:
|
|
|
|
m_Direction = 1;
|
|
|
|
m_Type = doorRaise;
|
|
|
|
DoorSound (true);
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case -1:
|
|
|
|
// DOWN
|
2008-03-19 22:47:04 +00:00
|
|
|
res = MoveCeiling (m_Speed, m_BotDist, -1, m_Direction, false);
|
2006-02-24 04:48:15 +00:00
|
|
|
|
|
|
|
// killough 10/98: implement gradual lighting effects
|
|
|
|
if (m_LightTag != 0 && m_TopDist != -m_Sector->floorplane.d)
|
|
|
|
{
|
|
|
|
EV_LightTurnOnPartway (m_LightTag, FixedDiv (m_Sector->ceilingplane.d + m_Sector->floorplane.d,
|
|
|
|
m_TopDist + m_Sector->floorplane.d));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (res == pastdest)
|
|
|
|
{
|
2009-12-25 02:19:50 +00:00
|
|
|
SN_StopSequence (m_Sector, CHAN_CEILING);
|
2006-02-24 04:48:15 +00:00
|
|
|
switch (m_Type)
|
|
|
|
{
|
|
|
|
case doorRaise:
|
|
|
|
case doorClose:
|
|
|
|
m_Sector->ceilingdata = NULL; //jff 2/22/98
|
|
|
|
Destroy (); // unlink and free
|
|
|
|
break;
|
|
|
|
|
|
|
|
case doorCloseWaitOpen:
|
|
|
|
m_Direction = 0;
|
|
|
|
m_TopCountdown = m_TopWait;
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (res == crushed)
|
|
|
|
{
|
|
|
|
switch (m_Type)
|
|
|
|
{
|
|
|
|
case doorClose: // DO NOT GO BACK UP!
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
m_Direction = 1;
|
|
|
|
DoorSound (true);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 1:
|
|
|
|
// UP
|
2008-03-19 22:47:04 +00:00
|
|
|
res = MoveCeiling (m_Speed, m_TopDist, -1, m_Direction, false);
|
2006-02-24 04:48:15 +00:00
|
|
|
|
|
|
|
// killough 10/98: implement gradual lighting effects
|
|
|
|
if (m_LightTag != 0 && m_TopDist != -m_Sector->floorplane.d)
|
|
|
|
{
|
|
|
|
EV_LightTurnOnPartway (m_LightTag, FixedDiv (m_Sector->ceilingplane.d + m_Sector->floorplane.d,
|
|
|
|
m_TopDist + m_Sector->floorplane.d));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (res == pastdest)
|
|
|
|
{
|
2009-12-25 02:19:50 +00:00
|
|
|
SN_StopSequence (m_Sector, CHAN_CEILING);
|
2006-02-24 04:48:15 +00:00
|
|
|
switch (m_Type)
|
|
|
|
{
|
|
|
|
case doorRaise:
|
|
|
|
m_Direction = 0; // wait at top
|
|
|
|
m_TopCountdown = m_TopWait;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case doorCloseWaitOpen:
|
|
|
|
case doorOpen:
|
|
|
|
m_Sector->ceilingdata = NULL; //jff 2/22/98
|
|
|
|
Destroy (); // unlink and free
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2008-03-18 18:18:18 +00:00
|
|
|
else if (res == crushed)
|
|
|
|
{
|
|
|
|
switch (m_Type)
|
|
|
|
{
|
|
|
|
case doorRaise:
|
|
|
|
case doorRaiseIn5Mins:
|
|
|
|
m_Direction = -1;
|
|
|
|
DoorSound(false);
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2006-02-24 04:48:15 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-12-27 16:14:26 +00:00
|
|
|
//============================================================================
|
|
|
|
//
|
2006-02-24 04:48:15 +00:00
|
|
|
// [RH] DoorSound: Plays door sound depending on direction and speed
|
2010-12-27 16:14:26 +00:00
|
|
|
//
|
2012-03-23 22:21:33 +00:00
|
|
|
// 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.
|
|
|
|
//
|
2010-12-27 16:14:26 +00:00
|
|
|
//============================================================================
|
|
|
|
|
2012-03-23 22:21:33 +00:00
|
|
|
void DDoor::DoorSound(bool raise, DSeqNode *curseq) const
|
2006-02-24 04:48:15 +00:00
|
|
|
{
|
- Fixed compilation with mingw again.
- Added multiple-choice sound sequences. These overcome one of the major
deficiences of the Hexen-inherited SNDSEQ system while still being Hexen
compatible: Custom door sounds can now use different opening and closing
sequences, for both normal and blazing speeds.
- Added a serializer for TArray.
- Added a countof macro to doomtype.h. See the1's blog to find out why
it's implemented the way it is.
<http://blogs.msdn.com/the1/articles/210011.aspx>
- Added a new method to FRandom for getting random numbers larger than 255,
which lets me:
- Fixed: SNDSEQ delayrand commands could delay for no more than 255 tics.
- Fixed: If you're going to have sector_t.SoundTarget, then they need to
be included in the pointer cleanup scans.
- Ported back newer name code from 2.1.
- Fixed: Using -warp with only one parameter in Doom and Heretic to
select a map on episode 1 no longer worked.
- New: Loading a multiplayer save now restores the players based on
their names rather than on their connection order. Using connection
order was sensible when -net was the only way to start a network game,
but with -host/-join, it's not so nice. Also, if there aren't enough
players in the save, then the extra players will be spawned normally,
so you can continue a saved game with more players than you started it
with.
- Added some new SNDSEQ commands to make it possible to define Heretic's
ambient sounds in SNDSEQ: volumerel, volumerand, slot, randomsequence,
delayonce, and restart. With these, it is basically possible to obsolete
all of the $ambient SNDINFO commands.
- Fixed: Sound sequences would only execute one command each time they were
ticked.
- Fixed: No bounds checking was done on the volume sound sequences played at.
- Fixed: The tic parameter to playloop was useless and caused it to
act like a redundant playrepeat. I have removed all the logic that
caused playloop to play repeating sounds, and now it acts like an
infinite sequence of play/delay commands until the sequence is
stopped.
- Fixed: Sound sequences were ticked every frame, not every tic, so all
the delay commands were timed incorrectly and varied depending on your
framerate. Since this is useful for restarting looping sounds that got
cut off, I have not changed this. Instead, the delay commands now
record the tic when execution should resume, not the number of tics
left to delay.
SVN r57 (trunk)
2006-04-21 01:22:55 +00:00
|
|
|
int choice;
|
|
|
|
|
|
|
|
// For multiple-selection sound sequences, the following choices are used:
|
|
|
|
// 0 Opening
|
|
|
|
// 1 Closing
|
|
|
|
// 2 Opening fast
|
|
|
|
// 3 Closing fast
|
|
|
|
|
|
|
|
choice = !raise;
|
|
|
|
|
|
|
|
if (m_Speed >= FRACUNIT*8)
|
|
|
|
{
|
|
|
|
choice += 2;
|
|
|
|
}
|
2006-02-24 04:48:15 +00:00
|
|
|
|
|
|
|
if (m_Sector->seqType >= 0)
|
|
|
|
{
|
2012-03-23 22:21:33 +00:00
|
|
|
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);
|
|
|
|
}
|
2006-02-24 04:48:15 +00:00
|
|
|
}
|
2010-08-07 04:32:18 +00:00
|
|
|
else if (m_Sector->SeqName != NAME_None)
|
|
|
|
{
|
2012-03-23 22:21:33 +00:00
|
|
|
if (curseq == NULL || !SN_AreModesSame(m_Sector->SeqName, choice, curseq->GetModeNum()))
|
|
|
|
{
|
|
|
|
SN_StartSequence(m_Sector, CHAN_CEILING, m_Sector->SeqName, choice);
|
|
|
|
}
|
2010-08-07 04:32:18 +00:00
|
|
|
}
|
2006-02-24 04:48:15 +00:00
|
|
|
else
|
|
|
|
{
|
- Fixed compilation with mingw again.
- Added multiple-choice sound sequences. These overcome one of the major
deficiences of the Hexen-inherited SNDSEQ system while still being Hexen
compatible: Custom door sounds can now use different opening and closing
sequences, for both normal and blazing speeds.
- Added a serializer for TArray.
- Added a countof macro to doomtype.h. See the1's blog to find out why
it's implemented the way it is.
<http://blogs.msdn.com/the1/articles/210011.aspx>
- Added a new method to FRandom for getting random numbers larger than 255,
which lets me:
- Fixed: SNDSEQ delayrand commands could delay for no more than 255 tics.
- Fixed: If you're going to have sector_t.SoundTarget, then they need to
be included in the pointer cleanup scans.
- Ported back newer name code from 2.1.
- Fixed: Using -warp with only one parameter in Doom and Heretic to
select a map on episode 1 no longer worked.
- New: Loading a multiplayer save now restores the players based on
their names rather than on their connection order. Using connection
order was sensible when -net was the only way to start a network game,
but with -host/-join, it's not so nice. Also, if there aren't enough
players in the save, then the extra players will be spawned normally,
so you can continue a saved game with more players than you started it
with.
- Added some new SNDSEQ commands to make it possible to define Heretic's
ambient sounds in SNDSEQ: volumerel, volumerand, slot, randomsequence,
delayonce, and restart. With these, it is basically possible to obsolete
all of the $ambient SNDINFO commands.
- Fixed: Sound sequences would only execute one command each time they were
ticked.
- Fixed: No bounds checking was done on the volume sound sequences played at.
- Fixed: The tic parameter to playloop was useless and caused it to
act like a redundant playrepeat. I have removed all the logic that
caused playloop to play repeating sounds, and now it acts like an
infinite sequence of play/delay commands until the sequence is
stopped.
- Fixed: Sound sequences were ticked every frame, not every tic, so all
the delay commands were timed incorrectly and varied depending on your
framerate. Since this is useful for restarting looping sounds that got
cut off, I have not changed this. Instead, the delay commands now
record the tic when execution should resume, not the number of tics
left to delay.
SVN r57 (trunk)
2006-04-21 01:22:55 +00:00
|
|
|
const char *snd;
|
2006-02-24 04:48:15 +00:00
|
|
|
|
- Fixed compilation with mingw again.
- Added multiple-choice sound sequences. These overcome one of the major
deficiences of the Hexen-inherited SNDSEQ system while still being Hexen
compatible: Custom door sounds can now use different opening and closing
sequences, for both normal and blazing speeds.
- Added a serializer for TArray.
- Added a countof macro to doomtype.h. See the1's blog to find out why
it's implemented the way it is.
<http://blogs.msdn.com/the1/articles/210011.aspx>
- Added a new method to FRandom for getting random numbers larger than 255,
which lets me:
- Fixed: SNDSEQ delayrand commands could delay for no more than 255 tics.
- Fixed: If you're going to have sector_t.SoundTarget, then they need to
be included in the pointer cleanup scans.
- Ported back newer name code from 2.1.
- Fixed: Using -warp with only one parameter in Doom and Heretic to
select a map on episode 1 no longer worked.
- New: Loading a multiplayer save now restores the players based on
their names rather than on their connection order. Using connection
order was sensible when -net was the only way to start a network game,
but with -host/-join, it's not so nice. Also, if there aren't enough
players in the save, then the extra players will be spawned normally,
so you can continue a saved game with more players than you started it
with.
- Added some new SNDSEQ commands to make it possible to define Heretic's
ambient sounds in SNDSEQ: volumerel, volumerand, slot, randomsequence,
delayonce, and restart. With these, it is basically possible to obsolete
all of the $ambient SNDINFO commands.
- Fixed: Sound sequences would only execute one command each time they were
ticked.
- Fixed: No bounds checking was done on the volume sound sequences played at.
- Fixed: The tic parameter to playloop was useless and caused it to
act like a redundant playrepeat. I have removed all the logic that
caused playloop to play repeating sounds, and now it acts like an
infinite sequence of play/delay commands until the sequence is
stopped.
- Fixed: Sound sequences were ticked every frame, not every tic, so all
the delay commands were timed incorrectly and varied depending on your
framerate. Since this is useful for restarting looping sounds that got
cut off, I have not changed this. Instead, the delay commands now
record the tic when execution should resume, not the number of tics
left to delay.
SVN r57 (trunk)
2006-04-21 01:22:55 +00:00
|
|
|
switch (gameinfo.gametype)
|
|
|
|
{
|
|
|
|
default: /* Doom and Hexen */
|
2006-04-20 00:25:30 +00:00
|
|
|
snd = "DoorNormal";
|
|
|
|
break;
|
|
|
|
|
2006-02-24 04:48:15 +00:00
|
|
|
case GAME_Heretic:
|
- Fixed compilation with mingw again.
- Added multiple-choice sound sequences. These overcome one of the major
deficiences of the Hexen-inherited SNDSEQ system while still being Hexen
compatible: Custom door sounds can now use different opening and closing
sequences, for both normal and blazing speeds.
- Added a serializer for TArray.
- Added a countof macro to doomtype.h. See the1's blog to find out why
it's implemented the way it is.
<http://blogs.msdn.com/the1/articles/210011.aspx>
- Added a new method to FRandom for getting random numbers larger than 255,
which lets me:
- Fixed: SNDSEQ delayrand commands could delay for no more than 255 tics.
- Fixed: If you're going to have sector_t.SoundTarget, then they need to
be included in the pointer cleanup scans.
- Ported back newer name code from 2.1.
- Fixed: Using -warp with only one parameter in Doom and Heretic to
select a map on episode 1 no longer worked.
- New: Loading a multiplayer save now restores the players based on
their names rather than on their connection order. Using connection
order was sensible when -net was the only way to start a network game,
but with -host/-join, it's not so nice. Also, if there aren't enough
players in the save, then the extra players will be spawned normally,
so you can continue a saved game with more players than you started it
with.
- Added some new SNDSEQ commands to make it possible to define Heretic's
ambient sounds in SNDSEQ: volumerel, volumerand, slot, randomsequence,
delayonce, and restart. With these, it is basically possible to obsolete
all of the $ambient SNDINFO commands.
- Fixed: Sound sequences would only execute one command each time they were
ticked.
- Fixed: No bounds checking was done on the volume sound sequences played at.
- Fixed: The tic parameter to playloop was useless and caused it to
act like a redundant playrepeat. I have removed all the logic that
caused playloop to play repeating sounds, and now it acts like an
infinite sequence of play/delay commands until the sequence is
stopped.
- Fixed: Sound sequences were ticked every frame, not every tic, so all
the delay commands were timed incorrectly and varied depending on your
framerate. Since this is useful for restarting looping sounds that got
cut off, I have not changed this. Instead, the delay commands now
record the tic when execution should resume, not the number of tics
left to delay.
SVN r57 (trunk)
2006-04-21 01:22:55 +00:00
|
|
|
snd = "HereticDoor";
|
2006-02-24 04:48:15 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case GAME_Strife:
|
- Fixed compilation with mingw again.
- Added multiple-choice sound sequences. These overcome one of the major
deficiences of the Hexen-inherited SNDSEQ system while still being Hexen
compatible: Custom door sounds can now use different opening and closing
sequences, for both normal and blazing speeds.
- Added a serializer for TArray.
- Added a countof macro to doomtype.h. See the1's blog to find out why
it's implemented the way it is.
<http://blogs.msdn.com/the1/articles/210011.aspx>
- Added a new method to FRandom for getting random numbers larger than 255,
which lets me:
- Fixed: SNDSEQ delayrand commands could delay for no more than 255 tics.
- Fixed: If you're going to have sector_t.SoundTarget, then they need to
be included in the pointer cleanup scans.
- Ported back newer name code from 2.1.
- Fixed: Using -warp with only one parameter in Doom and Heretic to
select a map on episode 1 no longer worked.
- New: Loading a multiplayer save now restores the players based on
their names rather than on their connection order. Using connection
order was sensible when -net was the only way to start a network game,
but with -host/-join, it's not so nice. Also, if there aren't enough
players in the save, then the extra players will be spawned normally,
so you can continue a saved game with more players than you started it
with.
- Added some new SNDSEQ commands to make it possible to define Heretic's
ambient sounds in SNDSEQ: volumerel, volumerand, slot, randomsequence,
delayonce, and restart. With these, it is basically possible to obsolete
all of the $ambient SNDINFO commands.
- Fixed: Sound sequences would only execute one command each time they were
ticked.
- Fixed: No bounds checking was done on the volume sound sequences played at.
- Fixed: The tic parameter to playloop was useless and caused it to
act like a redundant playrepeat. I have removed all the logic that
caused playloop to play repeating sounds, and now it acts like an
infinite sequence of play/delay commands until the sequence is
stopped.
- Fixed: Sound sequences were ticked every frame, not every tic, so all
the delay commands were timed incorrectly and varied depending on your
framerate. Since this is useful for restarting looping sounds that got
cut off, I have not changed this. Instead, the delay commands now
record the tic when execution should resume, not the number of tics
left to delay.
SVN r57 (trunk)
2006-04-21 01:22:55 +00:00
|
|
|
snd = "DoorSmallMetal";
|
|
|
|
|
|
|
|
// Search the front top textures of 2-sided lines on the door sector
|
|
|
|
// for a door sound to use.
|
|
|
|
for (int i = 0; i < m_Sector->linecount; ++i)
|
2006-02-24 04:48:15 +00:00
|
|
|
{
|
- Fixed compilation with mingw again.
- Added multiple-choice sound sequences. These overcome one of the major
deficiences of the Hexen-inherited SNDSEQ system while still being Hexen
compatible: Custom door sounds can now use different opening and closing
sequences, for both normal and blazing speeds.
- Added a serializer for TArray.
- Added a countof macro to doomtype.h. See the1's blog to find out why
it's implemented the way it is.
<http://blogs.msdn.com/the1/articles/210011.aspx>
- Added a new method to FRandom for getting random numbers larger than 255,
which lets me:
- Fixed: SNDSEQ delayrand commands could delay for no more than 255 tics.
- Fixed: If you're going to have sector_t.SoundTarget, then they need to
be included in the pointer cleanup scans.
- Ported back newer name code from 2.1.
- Fixed: Using -warp with only one parameter in Doom and Heretic to
select a map on episode 1 no longer worked.
- New: Loading a multiplayer save now restores the players based on
their names rather than on their connection order. Using connection
order was sensible when -net was the only way to start a network game,
but with -host/-join, it's not so nice. Also, if there aren't enough
players in the save, then the extra players will be spawned normally,
so you can continue a saved game with more players than you started it
with.
- Added some new SNDSEQ commands to make it possible to define Heretic's
ambient sounds in SNDSEQ: volumerel, volumerand, slot, randomsequence,
delayonce, and restart. With these, it is basically possible to obsolete
all of the $ambient SNDINFO commands.
- Fixed: Sound sequences would only execute one command each time they were
ticked.
- Fixed: No bounds checking was done on the volume sound sequences played at.
- Fixed: The tic parameter to playloop was useless and caused it to
act like a redundant playrepeat. I have removed all the logic that
caused playloop to play repeating sounds, and now it acts like an
infinite sequence of play/delay commands until the sequence is
stopped.
- Fixed: Sound sequences were ticked every frame, not every tic, so all
the delay commands were timed incorrectly and varied depending on your
framerate. Since this is useful for restarting looping sounds that got
cut off, I have not changed this. Instead, the delay commands now
record the tic when execution should resume, not the number of tics
left to delay.
SVN r57 (trunk)
2006-04-21 01:22:55 +00:00
|
|
|
const char *texname;
|
|
|
|
line_t *line = m_Sector->lines[i];
|
|
|
|
|
|
|
|
if (line->backsector == NULL)
|
|
|
|
continue;
|
2006-02-24 04:48:15 +00:00
|
|
|
|
2009-09-06 20:45:56 +00:00
|
|
|
FTexture *tex = TexMan[line->sidedef[0]->GetTexture(side_t::top)];
|
2014-05-18 22:38:46 +00:00
|
|
|
texname = tex ? tex->Name.GetChars() : NULL;
|
2008-03-21 17:35:49 +00:00
|
|
|
if (texname != NULL && texname[0] == 'D' && texname[1] == 'O' && texname[2] == 'R')
|
2006-02-24 04:48:15 +00:00
|
|
|
{
|
- Fixed compilation with mingw again.
- Added multiple-choice sound sequences. These overcome one of the major
deficiences of the Hexen-inherited SNDSEQ system while still being Hexen
compatible: Custom door sounds can now use different opening and closing
sequences, for both normal and blazing speeds.
- Added a serializer for TArray.
- Added a countof macro to doomtype.h. See the1's blog to find out why
it's implemented the way it is.
<http://blogs.msdn.com/the1/articles/210011.aspx>
- Added a new method to FRandom for getting random numbers larger than 255,
which lets me:
- Fixed: SNDSEQ delayrand commands could delay for no more than 255 tics.
- Fixed: If you're going to have sector_t.SoundTarget, then they need to
be included in the pointer cleanup scans.
- Ported back newer name code from 2.1.
- Fixed: Using -warp with only one parameter in Doom and Heretic to
select a map on episode 1 no longer worked.
- New: Loading a multiplayer save now restores the players based on
their names rather than on their connection order. Using connection
order was sensible when -net was the only way to start a network game,
but with -host/-join, it's not so nice. Also, if there aren't enough
players in the save, then the extra players will be spawned normally,
so you can continue a saved game with more players than you started it
with.
- Added some new SNDSEQ commands to make it possible to define Heretic's
ambient sounds in SNDSEQ: volumerel, volumerand, slot, randomsequence,
delayonce, and restart. With these, it is basically possible to obsolete
all of the $ambient SNDINFO commands.
- Fixed: Sound sequences would only execute one command each time they were
ticked.
- Fixed: No bounds checking was done on the volume sound sequences played at.
- Fixed: The tic parameter to playloop was useless and caused it to
act like a redundant playrepeat. I have removed all the logic that
caused playloop to play repeating sounds, and now it acts like an
infinite sequence of play/delay commands until the sequence is
stopped.
- Fixed: Sound sequences were ticked every frame, not every tic, so all
the delay commands were timed incorrectly and varied depending on your
framerate. Since this is useful for restarting looping sounds that got
cut off, I have not changed this. Instead, the delay commands now
record the tic when execution should resume, not the number of tics
left to delay.
SVN r57 (trunk)
2006-04-21 01:22:55 +00:00
|
|
|
switch (texname[3])
|
|
|
|
{
|
|
|
|
case 'S':
|
|
|
|
snd = "DoorStone";
|
|
|
|
break;
|
2006-02-24 04:48:15 +00:00
|
|
|
|
- Fixed compilation with mingw again.
- Added multiple-choice sound sequences. These overcome one of the major
deficiences of the Hexen-inherited SNDSEQ system while still being Hexen
compatible: Custom door sounds can now use different opening and closing
sequences, for both normal and blazing speeds.
- Added a serializer for TArray.
- Added a countof macro to doomtype.h. See the1's blog to find out why
it's implemented the way it is.
<http://blogs.msdn.com/the1/articles/210011.aspx>
- Added a new method to FRandom for getting random numbers larger than 255,
which lets me:
- Fixed: SNDSEQ delayrand commands could delay for no more than 255 tics.
- Fixed: If you're going to have sector_t.SoundTarget, then they need to
be included in the pointer cleanup scans.
- Ported back newer name code from 2.1.
- Fixed: Using -warp with only one parameter in Doom and Heretic to
select a map on episode 1 no longer worked.
- New: Loading a multiplayer save now restores the players based on
their names rather than on their connection order. Using connection
order was sensible when -net was the only way to start a network game,
but with -host/-join, it's not so nice. Also, if there aren't enough
players in the save, then the extra players will be spawned normally,
so you can continue a saved game with more players than you started it
with.
- Added some new SNDSEQ commands to make it possible to define Heretic's
ambient sounds in SNDSEQ: volumerel, volumerand, slot, randomsequence,
delayonce, and restart. With these, it is basically possible to obsolete
all of the $ambient SNDINFO commands.
- Fixed: Sound sequences would only execute one command each time they were
ticked.
- Fixed: No bounds checking was done on the volume sound sequences played at.
- Fixed: The tic parameter to playloop was useless and caused it to
act like a redundant playrepeat. I have removed all the logic that
caused playloop to play repeating sounds, and now it acts like an
infinite sequence of play/delay commands until the sequence is
stopped.
- Fixed: Sound sequences were ticked every frame, not every tic, so all
the delay commands were timed incorrectly and varied depending on your
framerate. Since this is useful for restarting looping sounds that got
cut off, I have not changed this. Instead, the delay commands now
record the tic when execution should resume, not the number of tics
left to delay.
SVN r57 (trunk)
2006-04-21 01:22:55 +00:00
|
|
|
case 'M':
|
|
|
|
if (texname[4] == 'L')
|
|
|
|
{
|
|
|
|
snd = "DoorLargeMetal";
|
|
|
|
}
|
|
|
|
break;
|
2006-02-24 04:48:15 +00:00
|
|
|
|
- Fixed compilation with mingw again.
- Added multiple-choice sound sequences. These overcome one of the major
deficiences of the Hexen-inherited SNDSEQ system while still being Hexen
compatible: Custom door sounds can now use different opening and closing
sequences, for both normal and blazing speeds.
- Added a serializer for TArray.
- Added a countof macro to doomtype.h. See the1's blog to find out why
it's implemented the way it is.
<http://blogs.msdn.com/the1/articles/210011.aspx>
- Added a new method to FRandom for getting random numbers larger than 255,
which lets me:
- Fixed: SNDSEQ delayrand commands could delay for no more than 255 tics.
- Fixed: If you're going to have sector_t.SoundTarget, then they need to
be included in the pointer cleanup scans.
- Ported back newer name code from 2.1.
- Fixed: Using -warp with only one parameter in Doom and Heretic to
select a map on episode 1 no longer worked.
- New: Loading a multiplayer save now restores the players based on
their names rather than on their connection order. Using connection
order was sensible when -net was the only way to start a network game,
but with -host/-join, it's not so nice. Also, if there aren't enough
players in the save, then the extra players will be spawned normally,
so you can continue a saved game with more players than you started it
with.
- Added some new SNDSEQ commands to make it possible to define Heretic's
ambient sounds in SNDSEQ: volumerel, volumerand, slot, randomsequence,
delayonce, and restart. With these, it is basically possible to obsolete
all of the $ambient SNDINFO commands.
- Fixed: Sound sequences would only execute one command each time they were
ticked.
- Fixed: No bounds checking was done on the volume sound sequences played at.
- Fixed: The tic parameter to playloop was useless and caused it to
act like a redundant playrepeat. I have removed all the logic that
caused playloop to play repeating sounds, and now it acts like an
infinite sequence of play/delay commands until the sequence is
stopped.
- Fixed: Sound sequences were ticked every frame, not every tic, so all
the delay commands were timed incorrectly and varied depending on your
framerate. Since this is useful for restarting looping sounds that got
cut off, I have not changed this. Instead, the delay commands now
record the tic when execution should resume, not the number of tics
left to delay.
SVN r57 (trunk)
2006-04-21 01:22:55 +00:00
|
|
|
case 'W':
|
|
|
|
if (texname[4] == 'L')
|
2006-02-24 04:48:15 +00:00
|
|
|
{
|
- Fixed compilation with mingw again.
- Added multiple-choice sound sequences. These overcome one of the major
deficiences of the Hexen-inherited SNDSEQ system while still being Hexen
compatible: Custom door sounds can now use different opening and closing
sequences, for both normal and blazing speeds.
- Added a serializer for TArray.
- Added a countof macro to doomtype.h. See the1's blog to find out why
it's implemented the way it is.
<http://blogs.msdn.com/the1/articles/210011.aspx>
- Added a new method to FRandom for getting random numbers larger than 255,
which lets me:
- Fixed: SNDSEQ delayrand commands could delay for no more than 255 tics.
- Fixed: If you're going to have sector_t.SoundTarget, then they need to
be included in the pointer cleanup scans.
- Ported back newer name code from 2.1.
- Fixed: Using -warp with only one parameter in Doom and Heretic to
select a map on episode 1 no longer worked.
- New: Loading a multiplayer save now restores the players based on
their names rather than on their connection order. Using connection
order was sensible when -net was the only way to start a network game,
but with -host/-join, it's not so nice. Also, if there aren't enough
players in the save, then the extra players will be spawned normally,
so you can continue a saved game with more players than you started it
with.
- Added some new SNDSEQ commands to make it possible to define Heretic's
ambient sounds in SNDSEQ: volumerel, volumerand, slot, randomsequence,
delayonce, and restart. With these, it is basically possible to obsolete
all of the $ambient SNDINFO commands.
- Fixed: Sound sequences would only execute one command each time they were
ticked.
- Fixed: No bounds checking was done on the volume sound sequences played at.
- Fixed: The tic parameter to playloop was useless and caused it to
act like a redundant playrepeat. I have removed all the logic that
caused playloop to play repeating sounds, and now it acts like an
infinite sequence of play/delay commands until the sequence is
stopped.
- Fixed: Sound sequences were ticked every frame, not every tic, so all
the delay commands were timed incorrectly and varied depending on your
framerate. Since this is useful for restarting looping sounds that got
cut off, I have not changed this. Instead, the delay commands now
record the tic when execution should resume, not the number of tics
left to delay.
SVN r57 (trunk)
2006-04-21 01:22:55 +00:00
|
|
|
snd = "DoorLargeWood";
|
2006-02-24 04:48:15 +00:00
|
|
|
}
|
- Fixed compilation with mingw again.
- Added multiple-choice sound sequences. These overcome one of the major
deficiences of the Hexen-inherited SNDSEQ system while still being Hexen
compatible: Custom door sounds can now use different opening and closing
sequences, for both normal and blazing speeds.
- Added a serializer for TArray.
- Added a countof macro to doomtype.h. See the1's blog to find out why
it's implemented the way it is.
<http://blogs.msdn.com/the1/articles/210011.aspx>
- Added a new method to FRandom for getting random numbers larger than 255,
which lets me:
- Fixed: SNDSEQ delayrand commands could delay for no more than 255 tics.
- Fixed: If you're going to have sector_t.SoundTarget, then they need to
be included in the pointer cleanup scans.
- Ported back newer name code from 2.1.
- Fixed: Using -warp with only one parameter in Doom and Heretic to
select a map on episode 1 no longer worked.
- New: Loading a multiplayer save now restores the players based on
their names rather than on their connection order. Using connection
order was sensible when -net was the only way to start a network game,
but with -host/-join, it's not so nice. Also, if there aren't enough
players in the save, then the extra players will be spawned normally,
so you can continue a saved game with more players than you started it
with.
- Added some new SNDSEQ commands to make it possible to define Heretic's
ambient sounds in SNDSEQ: volumerel, volumerand, slot, randomsequence,
delayonce, and restart. With these, it is basically possible to obsolete
all of the $ambient SNDINFO commands.
- Fixed: Sound sequences would only execute one command each time they were
ticked.
- Fixed: No bounds checking was done on the volume sound sequences played at.
- Fixed: The tic parameter to playloop was useless and caused it to
act like a redundant playrepeat. I have removed all the logic that
caused playloop to play repeating sounds, and now it acts like an
infinite sequence of play/delay commands until the sequence is
stopped.
- Fixed: Sound sequences were ticked every frame, not every tic, so all
the delay commands were timed incorrectly and varied depending on your
framerate. Since this is useful for restarting looping sounds that got
cut off, I have not changed this. Instead, the delay commands now
record the tic when execution should resume, not the number of tics
left to delay.
SVN r57 (trunk)
2006-04-21 01:22:55 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
snd = "DoorSmallWood";
|
|
|
|
}
|
|
|
|
break;
|
2006-02-24 04:48:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2012-03-23 22:21:33 +00:00
|
|
|
if (curseq == NULL || !SN_AreModesSame(snd, choice, curseq->GetModeNum()))
|
|
|
|
{
|
|
|
|
SN_StartSequence(m_Sector, CHAN_CEILING, snd, choice);
|
|
|
|
}
|
2006-02-24 04:48:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
DDoor::DDoor (sector_t *sector)
|
|
|
|
: DMovingCeiling (sector)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2010-12-27 16:14:26 +00:00
|
|
|
//============================================================================
|
|
|
|
//
|
2006-02-24 04:48:15 +00:00
|
|
|
// [RH] SpawnDoor: Helper function for EV_DoDoor
|
2010-12-27 16:14:26 +00:00
|
|
|
//
|
|
|
|
//============================================================================
|
|
|
|
|
2006-02-24 04:48:15 +00:00
|
|
|
DDoor::DDoor (sector_t *sec, EVlDoor type, fixed_t speed, int delay, int lightTag)
|
|
|
|
: DMovingCeiling (sec),
|
|
|
|
m_Type (type), m_Speed (speed), m_TopWait (delay), m_LightTag (lightTag)
|
|
|
|
{
|
|
|
|
vertex_t *spot;
|
|
|
|
fixed_t height;
|
|
|
|
|
2006-06-03 12:30:11 +00:00
|
|
|
if (i_compatflags & COMPATF_NODOORLIGHT)
|
2006-02-24 04:48:15 +00:00
|
|
|
{
|
|
|
|
m_LightTag = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (type)
|
|
|
|
{
|
|
|
|
case doorClose:
|
|
|
|
m_Direction = -1;
|
|
|
|
height = sec->FindLowestCeilingSurrounding (&spot);
|
|
|
|
m_TopDist = sec->ceilingplane.PointToDist (spot, height - 4*FRACUNIT);
|
|
|
|
DoorSound (false);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case doorOpen:
|
|
|
|
case doorRaise:
|
|
|
|
m_Direction = 1;
|
|
|
|
height = sec->FindLowestCeilingSurrounding (&spot);
|
|
|
|
m_TopDist = sec->ceilingplane.PointToDist (spot, height - 4*FRACUNIT);
|
|
|
|
if (m_TopDist != sec->ceilingplane.d)
|
|
|
|
DoorSound (true);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case doorCloseWaitOpen:
|
|
|
|
m_TopDist = sec->ceilingplane.d;
|
|
|
|
m_Direction = -1;
|
|
|
|
DoorSound (false);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case doorRaiseIn5Mins:
|
|
|
|
m_Direction = 2;
|
|
|
|
height = sec->FindLowestCeilingSurrounding (&spot);
|
|
|
|
m_TopDist = sec->ceilingplane.PointToDist (spot, height - 4*FRACUNIT);
|
|
|
|
m_TopCountdown = 5 * 60 * TICRATE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!m_Sector->floordata || !m_Sector->floordata->IsKindOf(RUNTIME_CLASS(DPlat)) ||
|
2008-03-12 02:56:11 +00:00
|
|
|
!(barrier_cast<DPlat*>(m_Sector->floordata))->IsLift())
|
2006-02-24 04:48:15 +00:00
|
|
|
{
|
|
|
|
height = sec->FindHighestFloorPoint (&m_BotSpot);
|
|
|
|
m_BotDist = sec->ceilingplane.PointToDist (m_BotSpot, height);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
height = sec->FindLowestCeilingPoint(&m_BotSpot);
|
|
|
|
m_BotDist = sec->ceilingplane.PointToDist (m_BotSpot, height);
|
|
|
|
}
|
|
|
|
m_OldFloorDist = sec->floorplane.d;
|
|
|
|
}
|
|
|
|
|
2010-12-27 16:14:26 +00:00
|
|
|
//============================================================================
|
|
|
|
//
|
|
|
|
// [RH] Merged EV_VerticalDoor and EV_DoLockedDoor into EV_DoDoor
|
|
|
|
// and made them more general to support the new specials.
|
|
|
|
//
|
|
|
|
//============================================================================
|
|
|
|
|
2006-02-24 04:48:15 +00:00
|
|
|
bool EV_DoDoor (DDoor::EVlDoor type, line_t *line, AActor *thing,
|
2012-04-12 12:42:00 +00:00
|
|
|
int tag, int speed, int delay, int lock, int lightTag, bool boomgen)
|
2006-02-24 04:48:15 +00:00
|
|
|
{
|
|
|
|
bool rtn = false;
|
|
|
|
int secnum;
|
|
|
|
sector_t* sec;
|
|
|
|
|
|
|
|
if (lock != 0 && !P_CheckKeys (thing, lock, tag != 0))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if (tag == 0)
|
|
|
|
{ // [RH] manual door
|
|
|
|
if (!line)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
// if the wrong side of door is pushed, give oof sound
|
2009-09-06 20:45:56 +00:00
|
|
|
if (line->sidedef[1] == NULL) // killough
|
2006-02-24 04:48:15 +00:00
|
|
|
{
|
|
|
|
S_Sound (thing, CHAN_VOICE, "*usefail", 1, ATTN_NORM);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// get the sector on the second side of activating linedef
|
2009-09-06 20:45:56 +00:00
|
|
|
sec = line->sidedef[1]->sector;
|
2009-05-15 10:39:40 +00:00
|
|
|
secnum = int(sec-sectors);
|
2006-02-24 04:48:15 +00:00
|
|
|
|
|
|
|
// if door already has a thinker, use it
|
2009-09-17 10:40:38 +00:00
|
|
|
if (sec->PlaneMoving(sector_t::ceiling))
|
2006-02-24 04:48:15 +00:00
|
|
|
{
|
2012-04-12 12:42:00 +00:00
|
|
|
// Boom used remote door logic for generalized doors, even if they are manual
|
|
|
|
if (boomgen)
|
|
|
|
return false;
|
2006-02-24 04:48:15 +00:00
|
|
|
if (sec->ceilingdata->IsKindOf (RUNTIME_CLASS(DDoor)))
|
|
|
|
{
|
2008-03-12 02:56:11 +00:00
|
|
|
DDoor *door = barrier_cast<DDoor *>(sec->ceilingdata);
|
2006-02-24 04:48:15 +00:00
|
|
|
|
|
|
|
// ONLY FOR "RAISE" DOORS, NOT "OPEN"s
|
|
|
|
if (door->m_Type == DDoor::doorRaise && type == DDoor::doorRaise)
|
|
|
|
{
|
|
|
|
if (door->m_Direction == -1)
|
|
|
|
{
|
|
|
|
door->m_Direction = 1; // go back up
|
|
|
|
door->DoorSound (true); // [RH] Make noise
|
|
|
|
}
|
2008-05-12 08:31:29 +00:00
|
|
|
else if (!(line->activation & (SPAC_Push|SPAC_MPush)))
|
2006-02-24 04:48:15 +00:00
|
|
|
// [RH] activate push doors don't go back down when you
|
|
|
|
// run into them (otherwise opening them would be
|
|
|
|
// a real pain).
|
|
|
|
{
|
2014-10-14 18:57:11 +00:00
|
|
|
if (!thing->player || thing->player->Bot != NULL)
|
2006-02-24 04:48:15 +00:00
|
|
|
return false; // JDC: bad guys never close doors
|
|
|
|
//Added by MC: Neither do bots.
|
|
|
|
|
|
|
|
door->m_Direction = -1; // start going down immediately
|
|
|
|
|
2012-03-23 22:21:33 +00:00
|
|
|
// Start the door close sequence.
|
|
|
|
door->DoorSound(false, SN_CheckSequence(sec, CHAN_CEILING));
|
2006-02-24 04:48:15 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (new DDoor (sec, type, speed, delay, lightTag))
|
|
|
|
rtn = true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{ // [RH] Remote door
|
|
|
|
|
2015-04-14 20:39:57 +00:00
|
|
|
FSectorTagIterator it(tag);
|
|
|
|
while ((secnum = it.Next()) >= 0)
|
2006-02-24 04:48:15 +00:00
|
|
|
{
|
|
|
|
sec = §ors[secnum];
|
2012-04-12 12:42:00 +00:00
|
|
|
// if the ceiling is already moving, don't start the door action
|
2009-09-17 10:40:38 +00:00
|
|
|
if (sec->PlaneMoving(sector_t::ceiling))
|
2006-02-24 04:48:15 +00:00
|
|
|
continue;
|
|
|
|
|
|
|
|
if (new DDoor (sec, type, speed, delay, lightTag))
|
|
|
|
rtn = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
return rtn;
|
|
|
|
}
|
|
|
|
|
2010-12-27 16:14:26 +00:00
|
|
|
//============================================================================
|
2006-02-24 04:48:15 +00:00
|
|
|
//
|
|
|
|
// Spawn a door that closes after 30 seconds
|
|
|
|
//
|
2010-12-27 16:14:26 +00:00
|
|
|
//============================================================================
|
|
|
|
|
2006-02-24 04:48:15 +00:00
|
|
|
void P_SpawnDoorCloseIn30 (sector_t *sec)
|
|
|
|
{
|
|
|
|
fixed_t height;
|
|
|
|
DDoor *door = new DDoor (sec);
|
|
|
|
|
|
|
|
sec->special = 0;
|
|
|
|
|
|
|
|
door->m_Sector = sec;
|
|
|
|
door->m_Direction = 0;
|
|
|
|
door->m_Type = DDoor::doorRaise;
|
|
|
|
door->m_Speed = FRACUNIT*2;
|
|
|
|
door->m_TopCountdown = 30 * TICRATE;
|
|
|
|
height = sec->FindHighestFloorPoint (&door->m_BotSpot);
|
|
|
|
door->m_BotDist = sec->ceilingplane.PointToDist (door->m_BotSpot, height);
|
|
|
|
door->m_OldFloorDist = sec->floorplane.d;
|
|
|
|
door->m_TopDist = sec->ceilingplane.d;
|
|
|
|
door->m_LightTag = 0;
|
|
|
|
}
|
|
|
|
|
2010-12-27 16:14:26 +00:00
|
|
|
//============================================================================
|
2006-02-24 04:48:15 +00:00
|
|
|
//
|
|
|
|
// Spawn a door that opens after 5 minutes
|
|
|
|
//
|
2010-12-27 16:14:26 +00:00
|
|
|
//============================================================================
|
|
|
|
|
2006-02-24 04:48:15 +00:00
|
|
|
void P_SpawnDoorRaiseIn5Mins (sector_t *sec)
|
|
|
|
{
|
|
|
|
sec->special = 0;
|
|
|
|
new DDoor (sec, DDoor::doorRaiseIn5Mins, 2*FRACUNIT, TICRATE*30/7, 0);
|
|
|
|
}
|
|
|
|
|
2010-12-27 16:14:26 +00:00
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
//
|
|
|
|
// animated doors
|
|
|
|
//
|
|
|
|
//============================================================================
|
|
|
|
|
|
|
|
IMPLEMENT_CLASS (DAnimatedDoor)
|
|
|
|
|
|
|
|
DAnimatedDoor::DAnimatedDoor ()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
DAnimatedDoor::DAnimatedDoor (sector_t *sec)
|
|
|
|
: DMovingCeiling (sec)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void DAnimatedDoor::Serialize (FArchive &arc)
|
|
|
|
{
|
|
|
|
Super::Serialize (arc);
|
|
|
|
|
|
|
|
arc << m_Line1 << m_Line2
|
|
|
|
<< m_Frame
|
|
|
|
<< m_Timer
|
|
|
|
<< m_BotDist
|
|
|
|
<< m_Status
|
|
|
|
<< m_Speed
|
|
|
|
<< m_Delay
|
|
|
|
<< m_DoorAnim
|
|
|
|
<< m_SetBlocking1 << m_SetBlocking2;
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
//
|
|
|
|
// Starts a closing action on an animated door
|
2006-02-24 04:48:15 +00:00
|
|
|
//
|
2010-12-27 16:14:26 +00:00
|
|
|
//============================================================================
|
2006-02-24 04:48:15 +00:00
|
|
|
|
|
|
|
bool DAnimatedDoor::StartClosing ()
|
|
|
|
{
|
|
|
|
// CAN DOOR CLOSE?
|
|
|
|
if (m_Sector->touching_thinglist != NULL)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
fixed_t topdist = m_Sector->ceilingplane.d;
|
2008-03-19 22:47:04 +00:00
|
|
|
if (MoveCeiling (2048*FRACUNIT, m_BotDist, 0, -1, false) == crushed)
|
2006-02-24 04:48:15 +00:00
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
MoveCeiling (2048*FRACUNIT, topdist, 1);
|
|
|
|
|
|
|
|
m_Line1->flags |= ML_BLOCKING;
|
|
|
|
m_Line2->flags |= ML_BLOCKING;
|
2010-12-12 08:30:12 +00:00
|
|
|
if (m_DoorAnim->CloseSound != NAME_None)
|
2006-02-24 04:48:15 +00:00
|
|
|
{
|
2010-12-12 08:30:12 +00:00
|
|
|
SN_StartSequence (m_Sector, CHAN_CEILING, m_DoorAnim->CloseSound, 1);
|
2006-02-24 04:48:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
m_Status = Closing;
|
|
|
|
m_Timer = m_Speed;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2010-12-27 16:14:26 +00:00
|
|
|
//============================================================================
|
|
|
|
//
|
|
|
|
//
|
|
|
|
//
|
|
|
|
//============================================================================
|
|
|
|
|
2006-02-24 04:48:15 +00:00
|
|
|
void DAnimatedDoor::Tick ()
|
|
|
|
{
|
2010-12-12 08:30:12 +00:00
|
|
|
if (m_DoorAnim == NULL)
|
|
|
|
{
|
|
|
|
// can only happen when a bad savegame is loaded.
|
|
|
|
Destroy();
|
|
|
|
return;
|
|
|
|
}
|
2006-02-24 04:48:15 +00:00
|
|
|
|
|
|
|
switch (m_Status)
|
|
|
|
{
|
|
|
|
case Dead:
|
|
|
|
m_Sector->ceilingdata = NULL;
|
|
|
|
Destroy ();
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Opening:
|
|
|
|
if (!m_Timer--)
|
|
|
|
{
|
2010-12-12 08:30:12 +00:00
|
|
|
if (++m_Frame >= m_DoorAnim->NumTextureFrames)
|
2006-02-24 04:48:15 +00:00
|
|
|
{
|
|
|
|
// IF DOOR IS DONE OPENING...
|
|
|
|
m_Line1->flags &= ~ML_BLOCKING;
|
|
|
|
m_Line2->flags &= ~ML_BLOCKING;
|
|
|
|
|
|
|
|
if (m_Delay == 0)
|
|
|
|
{
|
|
|
|
m_Sector->ceilingdata = NULL;
|
|
|
|
Destroy ();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
m_Timer = m_Delay;
|
|
|
|
m_Status = Waiting;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// IF DOOR NEEDS TO ANIMATE TO NEXT FRAME...
|
|
|
|
m_Timer = m_Speed;
|
|
|
|
|
2010-12-12 08:30:12 +00:00
|
|
|
m_Line1->sidedef[0]->SetTexture(side_t::mid, m_DoorAnim->TextureFrames[m_Frame]);
|
|
|
|
m_Line1->sidedef[1]->SetTexture(side_t::mid, m_DoorAnim->TextureFrames[m_Frame]);
|
|
|
|
m_Line2->sidedef[0]->SetTexture(side_t::mid, m_DoorAnim->TextureFrames[m_Frame]);
|
|
|
|
m_Line2->sidedef[1]->SetTexture(side_t::mid, m_DoorAnim->TextureFrames[m_Frame]);
|
2006-02-24 04:48:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Waiting:
|
|
|
|
// IF DOOR IS DONE WAITING...
|
|
|
|
if (!m_Timer--)
|
|
|
|
{
|
|
|
|
if (!StartClosing())
|
|
|
|
{
|
|
|
|
m_Timer = m_Delay;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Closing:
|
|
|
|
if (!m_Timer--)
|
|
|
|
{
|
|
|
|
if (--m_Frame < 0)
|
|
|
|
{
|
|
|
|
// IF DOOR IS DONE CLOSING...
|
|
|
|
MoveCeiling (2048*FRACUNIT, m_BotDist, -1);
|
|
|
|
m_Sector->ceilingdata = NULL;
|
|
|
|
Destroy ();
|
2010-05-25 03:40:37 +00:00
|
|
|
// Unset blocking flags on lines that didn't start with them. Since the
|
|
|
|
// ceiling is down now, we shouldn't need this flag anymore to keep things
|
|
|
|
// from getting through.
|
|
|
|
if (!m_SetBlocking1)
|
|
|
|
{
|
|
|
|
m_Line1->flags &= ~ML_BLOCKING;
|
|
|
|
}
|
|
|
|
if (!m_SetBlocking2)
|
|
|
|
{
|
|
|
|
m_Line2->flags &= ~ML_BLOCKING;
|
|
|
|
}
|
2006-02-24 04:48:15 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// IF DOOR NEEDS TO ANIMATE TO NEXT FRAME...
|
|
|
|
m_Timer = m_Speed;
|
|
|
|
|
2010-12-12 08:30:12 +00:00
|
|
|
m_Line1->sidedef[0]->SetTexture(side_t::mid, m_DoorAnim->TextureFrames[m_Frame]);
|
|
|
|
m_Line1->sidedef[1]->SetTexture(side_t::mid, m_DoorAnim->TextureFrames[m_Frame]);
|
|
|
|
m_Line2->sidedef[0]->SetTexture(side_t::mid, m_DoorAnim->TextureFrames[m_Frame]);
|
|
|
|
m_Line2->sidedef[1]->SetTexture(side_t::mid, m_DoorAnim->TextureFrames[m_Frame]);
|
2006-02-24 04:48:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-12-27 16:14:26 +00:00
|
|
|
//============================================================================
|
|
|
|
//
|
|
|
|
//
|
|
|
|
//
|
|
|
|
//============================================================================
|
2006-02-24 04:48:15 +00:00
|
|
|
|
2010-12-12 08:30:12 +00:00
|
|
|
DAnimatedDoor::DAnimatedDoor (sector_t *sec, line_t *line, int speed, int delay, FDoorAnimation *anim)
|
2006-02-24 04:48:15 +00:00
|
|
|
: DMovingCeiling (sec)
|
|
|
|
{
|
|
|
|
fixed_t topdist;
|
2008-06-15 18:36:26 +00:00
|
|
|
FTextureID picnum;
|
2006-02-24 04:48:15 +00:00
|
|
|
|
|
|
|
// The DMovingCeiling constructor automatically sets up an interpolation for us.
|
|
|
|
// Stop it, since the ceiling is moving instantly here.
|
2008-06-04 17:53:15 +00:00
|
|
|
StopInterpolation();
|
2010-12-12 08:30:12 +00:00
|
|
|
m_DoorAnim = anim;
|
2006-02-24 04:48:15 +00:00
|
|
|
|
|
|
|
m_Line1 = line;
|
|
|
|
m_Line2 = line;
|
|
|
|
|
|
|
|
for (int i = 0; i < sec->linecount; ++i)
|
|
|
|
{
|
|
|
|
if (sec->lines[i] == line)
|
|
|
|
continue;
|
|
|
|
|
2009-09-06 20:45:56 +00:00
|
|
|
if (sec->lines[i]->sidedef[0]->GetTexture(side_t::top) == line->sidedef[0]->GetTexture(side_t::top))
|
2006-02-24 04:48:15 +00:00
|
|
|
{
|
|
|
|
m_Line2 = sec->lines[i];
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-09-06 20:45:56 +00:00
|
|
|
|
|
|
|
picnum = m_Line1->sidedef[0]->GetTexture(side_t::top);
|
|
|
|
m_Line1->sidedef[0]->SetTexture(side_t::mid, picnum);
|
|
|
|
m_Line2->sidedef[0]->SetTexture(side_t::mid, picnum);
|
2006-02-24 04:48:15 +00:00
|
|
|
|
|
|
|
// don't forget texture scaling here!
|
|
|
|
FTexture *tex = TexMan[picnum];
|
2007-04-29 12:07:27 +00:00
|
|
|
topdist = tex ? tex->GetScaledHeight() : 64;
|
2006-02-24 04:48:15 +00:00
|
|
|
|
|
|
|
topdist = m_Sector->ceilingplane.d - topdist * m_Sector->ceilingplane.c;
|
|
|
|
|
|
|
|
m_Status = Opening;
|
|
|
|
m_Speed = speed;
|
|
|
|
m_Delay = delay;
|
|
|
|
m_Timer = m_Speed;
|
|
|
|
m_Frame = 0;
|
2010-05-25 03:40:37 +00:00
|
|
|
m_SetBlocking1 = !!(m_Line1->flags & ML_BLOCKING);
|
|
|
|
m_SetBlocking2 = !!(m_Line2->flags & ML_BLOCKING);
|
2006-02-24 04:48:15 +00:00
|
|
|
m_Line1->flags |= ML_BLOCKING;
|
|
|
|
m_Line2->flags |= ML_BLOCKING;
|
|
|
|
m_BotDist = m_Sector->ceilingplane.d;
|
|
|
|
MoveCeiling (2048*FRACUNIT, topdist, 1);
|
2010-12-12 08:30:12 +00:00
|
|
|
if (m_DoorAnim->OpenSound != NAME_None)
|
2006-02-24 04:48:15 +00:00
|
|
|
{
|
2010-12-12 08:30:12 +00:00
|
|
|
SN_StartSequence (m_Sector, CHAN_INTERIOR, m_DoorAnim->OpenSound, 1);
|
2006-02-24 04:48:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
//
|
2010-12-27 16:14:26 +00:00
|
|
|
// EV_SlidingDoor : slide a door horizontally
|
|
|
|
// (animate midtexture, then set noblocking line)
|
2006-02-24 04:48:15 +00:00
|
|
|
//
|
|
|
|
//============================================================================
|
|
|
|
|
|
|
|
bool EV_SlidingDoor (line_t *line, AActor *actor, int tag, int speed, int delay)
|
|
|
|
{
|
|
|
|
sector_t *sec;
|
|
|
|
int secnum;
|
|
|
|
bool rtn;
|
|
|
|
|
|
|
|
secnum = -1;
|
|
|
|
rtn = false;
|
|
|
|
|
|
|
|
if (tag == 0)
|
|
|
|
{
|
|
|
|
// Manual sliding door
|
|
|
|
sec = line->backsector;
|
|
|
|
|
|
|
|
// Make sure door isn't already being animated
|
|
|
|
if (sec->ceilingdata != NULL)
|
|
|
|
{
|
|
|
|
if (actor->player == NULL)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if (sec->ceilingdata->IsA (RUNTIME_CLASS(DAnimatedDoor)))
|
|
|
|
{
|
2008-03-12 02:56:11 +00:00
|
|
|
DAnimatedDoor *door = barrier_cast<DAnimatedDoor *>(sec->ceilingdata);
|
2006-02-24 04:48:15 +00:00
|
|
|
if (door->m_Status == DAnimatedDoor::Waiting)
|
|
|
|
{
|
|
|
|
return door->StartClosing();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
2010-12-12 08:30:12 +00:00
|
|
|
FDoorAnimation *anim = TexMan.FindAnimatedDoor (line->sidedef[0]->GetTexture(side_t::top));
|
|
|
|
if (anim != NULL)
|
2006-02-24 04:48:15 +00:00
|
|
|
{
|
2010-12-12 08:30:12 +00:00
|
|
|
new DAnimatedDoor (sec, line, speed, delay, anim);
|
2006-02-24 04:48:15 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2015-04-14 20:39:57 +00:00
|
|
|
FSectorTagIterator it(tag);
|
|
|
|
while ((secnum = it.Next()) >= 0)
|
2006-06-03 12:30:11 +00:00
|
|
|
{
|
2006-02-24 04:48:15 +00:00
|
|
|
sec = §ors[secnum];
|
|
|
|
if (sec->ceilingdata != NULL)
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (int i = 0; tag != 0 && i < sec->linecount; ++i)
|
|
|
|
{
|
|
|
|
line = sec->lines[i];
|
|
|
|
if (line->backsector == NULL)
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
2010-12-12 08:30:12 +00:00
|
|
|
FDoorAnimation *anim = TexMan.FindAnimatedDoor (line->sidedef[0]->GetTexture(side_t::top));
|
|
|
|
if (anim != NULL)
|
2006-02-24 04:48:15 +00:00
|
|
|
{
|
|
|
|
rtn = true;
|
2010-12-12 08:30:12 +00:00
|
|
|
new DAnimatedDoor (sec, line, speed, delay, anim);
|
2008-12-06 10:22:37 +00:00
|
|
|
break;
|
2006-02-24 04:48:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return rtn;
|
|
|
|
}
|
|
|
|
|