mirror of
https://github.com/id-Software/DOOM-3-BFG.git
synced 2026-03-20 09:00:25 +01:00
Initial commit
This commit is contained in:
560
doomclassic/doom/p_doors.cpp
Normal file
560
doomclassic/doom/p_doors.cpp
Normal file
@@ -0,0 +1,560 @@
|
||||
/*
|
||||
===========================================================================
|
||||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||
|
||||
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#include "Precompiled.h"
|
||||
#include "globaldata.h"
|
||||
|
||||
|
||||
#include "z_zone.h"
|
||||
#include "doomdef.h"
|
||||
#include "p_local.h"
|
||||
|
||||
#include "s_sound.h"
|
||||
|
||||
|
||||
// State.
|
||||
#include "doomstat.h"
|
||||
#include "r_state.h"
|
||||
|
||||
// Data.
|
||||
#include "dstrings.h"
|
||||
#include "sounds.h"
|
||||
|
||||
|
||||
extern bool globalNetworking;
|
||||
|
||||
//
|
||||
// VERTICAL DOORS
|
||||
//
|
||||
|
||||
//
|
||||
// T_VerticalDoor
|
||||
//
|
||||
void T_VerticalDoor (vldoor_t* door)
|
||||
{
|
||||
result_e res;
|
||||
|
||||
switch(door->direction)
|
||||
{
|
||||
case 0:
|
||||
// WAITING
|
||||
if (!--door->topcountdown)
|
||||
{
|
||||
switch(door->type)
|
||||
{
|
||||
case blazeRaise:
|
||||
door->direction = -1; // time to go back down
|
||||
S_StartSound( &door->sector->soundorg,
|
||||
sfx_bdcls);
|
||||
break;
|
||||
|
||||
case normal:
|
||||
door->direction = -1; // time to go back down
|
||||
S_StartSound( &door->sector->soundorg,
|
||||
sfx_dorcls);
|
||||
break;
|
||||
|
||||
case close30ThenOpen:
|
||||
door->direction = 1;
|
||||
S_StartSound( &door->sector->soundorg,
|
||||
sfx_doropn);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
// INITIAL WAIT
|
||||
if (!--door->topcountdown)
|
||||
{
|
||||
switch(door->type)
|
||||
{
|
||||
case raiseIn5Mins:
|
||||
door->direction = 1;
|
||||
door->type = normal;
|
||||
S_StartSound( &door->sector->soundorg,
|
||||
sfx_doropn);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case -1:
|
||||
// DOWN
|
||||
res = T_MovePlane(door->sector,
|
||||
door->speed,
|
||||
door->sector->floorheight,
|
||||
false,1,door->direction);
|
||||
if (res == pastdest)
|
||||
{
|
||||
switch(door->type)
|
||||
{
|
||||
case blazeRaise:
|
||||
case blazeClose:
|
||||
door->sector->specialdata = NULL;
|
||||
P_RemoveThinker (&door->thinker); // unlink and free
|
||||
S_StartSound( &door->sector->soundorg,
|
||||
sfx_bdcls);
|
||||
break;
|
||||
|
||||
case normal:
|
||||
case closed:
|
||||
door->sector->specialdata = NULL;
|
||||
P_RemoveThinker (&door->thinker); // unlink and free
|
||||
break;
|
||||
|
||||
case close30ThenOpen:
|
||||
door->direction = 0;
|
||||
door->topcountdown = TICRATE*30;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (res == crushed)
|
||||
{
|
||||
switch(door->type)
|
||||
{
|
||||
case blazeClose:
|
||||
case closed: // DO NOT GO BACK UP!
|
||||
break;
|
||||
|
||||
default:
|
||||
door->direction = 1;
|
||||
S_StartSound( &door->sector->soundorg,
|
||||
sfx_doropn);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 1:
|
||||
// UP
|
||||
res = T_MovePlane(door->sector,
|
||||
door->speed,
|
||||
door->topheight,
|
||||
false,1,door->direction);
|
||||
|
||||
if (res == pastdest)
|
||||
{
|
||||
switch(door->type)
|
||||
{
|
||||
case blazeRaise:
|
||||
case normal:
|
||||
door->direction = 0; // wait at top
|
||||
door->topcountdown = door->topwait;
|
||||
break;
|
||||
|
||||
case close30ThenOpen:
|
||||
case blazeOpen:
|
||||
case opened:
|
||||
door->sector->specialdata = NULL;
|
||||
P_RemoveThinker (&door->thinker); // unlink and free
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// EV_DoLockedDoor
|
||||
// Move a locked door up/down
|
||||
//
|
||||
|
||||
int
|
||||
EV_DoLockedDoor
|
||||
( line_t* line,
|
||||
vldoor_e type,
|
||||
mobj_t* thing )
|
||||
{
|
||||
player_t* p;
|
||||
|
||||
p = thing->player;
|
||||
|
||||
if (!p)
|
||||
return 0;
|
||||
|
||||
switch(line->special)
|
||||
{
|
||||
case 99: // Blue Lock
|
||||
case 133:
|
||||
if ( !p )
|
||||
return 0;
|
||||
if (!p->cards[it_bluecard] && !p->cards[it_blueskull])
|
||||
{
|
||||
p->message = PD_BLUEO;
|
||||
if (p == &::g->players[::g->consoleplayer])
|
||||
S_StartSound(NULL,sfx_oof);
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case 134: // Red Lock
|
||||
case 135:
|
||||
if ( !p )
|
||||
return 0;
|
||||
if (!p->cards[it_redcard] && !p->cards[it_redskull])
|
||||
{
|
||||
p->message = PD_REDO;
|
||||
if (p == &::g->players[::g->consoleplayer])
|
||||
S_StartSound(NULL,sfx_oof);
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case 136: // Yellow Lock
|
||||
case 137:
|
||||
if ( !p )
|
||||
return 0;
|
||||
if (!p->cards[it_yellowcard] &&
|
||||
!p->cards[it_yellowskull])
|
||||
{
|
||||
p->message = PD_YELLOWO;
|
||||
if (p == &::g->players[::g->consoleplayer])
|
||||
S_StartSound(NULL,sfx_oof);
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return EV_DoDoor(line,type);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
EV_DoDoor
|
||||
( line_t* line,
|
||||
vldoor_e type )
|
||||
{
|
||||
int secnum,rtn;
|
||||
sector_t* sec;
|
||||
vldoor_t* door;
|
||||
|
||||
secnum = -1;
|
||||
rtn = 0;
|
||||
|
||||
while ((secnum = P_FindSectorFromLineTag(line,secnum)) >= 0)
|
||||
{
|
||||
sec = &::g->sectors[secnum];
|
||||
if (sec->specialdata)
|
||||
continue;
|
||||
|
||||
|
||||
// new door thinker
|
||||
rtn = 1;
|
||||
door = (vldoor_t*)DoomLib::Z_Malloc(sizeof(*door), PU_LEVEL, 0);
|
||||
P_AddThinker (&door->thinker);
|
||||
sec->specialdata = door;
|
||||
|
||||
door->thinker.function.acp1 = (actionf_p1) T_VerticalDoor;
|
||||
door->sector = sec;
|
||||
door->type = type;
|
||||
door->topwait = VDOORWAIT;
|
||||
door->speed = VDOORSPEED;
|
||||
|
||||
switch(type)
|
||||
{
|
||||
case blazeClose:
|
||||
door->topheight = P_FindLowestCeilingSurrounding(sec);
|
||||
door->topheight -= 4*FRACUNIT;
|
||||
door->direction = -1;
|
||||
door->speed = VDOORSPEED * 4;
|
||||
S_StartSound( &door->sector->soundorg,
|
||||
sfx_bdcls);
|
||||
break;
|
||||
|
||||
case closed:
|
||||
door->topheight = P_FindLowestCeilingSurrounding(sec);
|
||||
door->topheight -= 4*FRACUNIT;
|
||||
door->direction = -1;
|
||||
S_StartSound( &door->sector->soundorg,
|
||||
sfx_dorcls);
|
||||
break;
|
||||
|
||||
case close30ThenOpen:
|
||||
door->topheight = sec->ceilingheight;
|
||||
door->direction = -1;
|
||||
S_StartSound( &door->sector->soundorg,
|
||||
sfx_dorcls);
|
||||
break;
|
||||
|
||||
case blazeRaise:
|
||||
case blazeOpen:
|
||||
door->direction = 1;
|
||||
door->topheight = P_FindLowestCeilingSurrounding(sec);
|
||||
door->topheight -= 4*FRACUNIT;
|
||||
door->speed = VDOORSPEED * 4;
|
||||
if (door->topheight != sec->ceilingheight)
|
||||
S_StartSound( &door->sector->soundorg,
|
||||
sfx_bdopn);
|
||||
break;
|
||||
|
||||
case normal:
|
||||
case opened:
|
||||
door->direction = 1;
|
||||
door->topheight = P_FindLowestCeilingSurrounding(sec);
|
||||
door->topheight -= 4*FRACUNIT;
|
||||
if (door->topheight != sec->ceilingheight)
|
||||
S_StartSound( &door->sector->soundorg,
|
||||
sfx_doropn);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
return rtn;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// EV_VerticalDoor : open a door manually, no tag value
|
||||
//
|
||||
void
|
||||
EV_VerticalDoor
|
||||
( line_t* line,
|
||||
mobj_t* thing )
|
||||
{
|
||||
player_t* player;
|
||||
int secnum;
|
||||
sector_t* sec;
|
||||
vldoor_t* door;
|
||||
int side;
|
||||
|
||||
side = 0; // only front ::g->sides can be used
|
||||
|
||||
// Check for locks
|
||||
player = thing->player;
|
||||
|
||||
switch(line->special)
|
||||
{
|
||||
case 26: // Blue Lock
|
||||
case 32:
|
||||
if ( !player )
|
||||
return;
|
||||
|
||||
if (!player->cards[it_bluecard] && !player->cards[it_blueskull])
|
||||
{
|
||||
player->message = PD_BLUEK;
|
||||
if (globalNetworking || (player == &::g->players[::g->consoleplayer]))
|
||||
S_StartSound(player->mo,sfx_oof);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
case 27: // Yellow Lock
|
||||
case 34:
|
||||
if ( !player )
|
||||
return;
|
||||
|
||||
if (!player->cards[it_yellowcard] &&
|
||||
!player->cards[it_yellowskull])
|
||||
{
|
||||
player->message = PD_YELLOWK;
|
||||
if (globalNetworking || (player == &::g->players[::g->consoleplayer]))
|
||||
S_StartSound(player->mo,sfx_oof);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
case 28: // Red Lock
|
||||
case 33:
|
||||
if ( !player )
|
||||
return;
|
||||
|
||||
if (!player->cards[it_redcard] && !player->cards[it_redskull])
|
||||
{
|
||||
player->message = PD_REDK;
|
||||
if (globalNetworking || (player == &::g->players[::g->consoleplayer]))
|
||||
S_StartSound(player->mo,sfx_oof);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// if the sector has an active thinker, use it
|
||||
sec = ::g->sides[ line->sidenum[side^1]] .sector;
|
||||
secnum = sec-::g->sectors;
|
||||
|
||||
if (sec->specialdata)
|
||||
{
|
||||
door = (vldoor_t*)sec->specialdata;
|
||||
switch(line->special)
|
||||
{
|
||||
case 1: // ONLY FOR "RAISE" DOORS, NOT "OPEN"s
|
||||
case 26:
|
||||
case 27:
|
||||
case 28:
|
||||
case 117:
|
||||
if (door->direction == -1)
|
||||
door->direction = 1; // go back up
|
||||
else
|
||||
{
|
||||
if (!thing->player)
|
||||
return; // JDC: bad guys never close doors
|
||||
|
||||
door->direction = -1; // start going down immediately
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// for proper sound
|
||||
if (globalNetworking || (player == &::g->players[::g->consoleplayer])) {
|
||||
switch(line->special)
|
||||
{
|
||||
case 117: // BLAZING DOOR RAISE
|
||||
case 118: // BLAZING DOOR OPEN
|
||||
S_StartSound( &sec->soundorg,sfx_bdopn);
|
||||
break;
|
||||
|
||||
case 1: // NORMAL DOOR SOUND
|
||||
case 31:
|
||||
S_StartSound( &sec->soundorg,sfx_doropn);
|
||||
break;
|
||||
|
||||
default: // LOCKED DOOR SOUND
|
||||
S_StartSound( &sec->soundorg,sfx_doropn);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// new door thinker
|
||||
door = (vldoor_t*)DoomLib::Z_Malloc(sizeof(*door), PU_LEVEL, 0);
|
||||
P_AddThinker (&door->thinker);
|
||||
sec->specialdata = door;
|
||||
door->thinker.function.acp1 = (actionf_p1) T_VerticalDoor;
|
||||
door->sector = sec;
|
||||
door->direction = 1;
|
||||
door->speed = VDOORSPEED;
|
||||
door->topwait = VDOORWAIT;
|
||||
|
||||
switch(line->special)
|
||||
{
|
||||
case 1:
|
||||
case 26:
|
||||
case 27:
|
||||
case 28:
|
||||
door->type = normal;
|
||||
break;
|
||||
|
||||
case 31:
|
||||
case 32:
|
||||
case 33:
|
||||
case 34:
|
||||
door->type = opened;
|
||||
line->special = 0;
|
||||
break;
|
||||
|
||||
case 117: // blazing door raise
|
||||
door->type = blazeRaise;
|
||||
door->speed = VDOORSPEED*4;
|
||||
break;
|
||||
case 118: // blazing door open
|
||||
door->type = blazeOpen;
|
||||
line->special = 0;
|
||||
door->speed = VDOORSPEED*4;
|
||||
break;
|
||||
}
|
||||
|
||||
// find the top and bottom of the movement range
|
||||
door->topheight = P_FindLowestCeilingSurrounding(sec);
|
||||
door->topheight -= 4*FRACUNIT;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Spawn a door that closes after 30 seconds
|
||||
//
|
||||
void P_SpawnDoorCloseIn30 (sector_t* sec)
|
||||
{
|
||||
vldoor_t* door;
|
||||
|
||||
door = (vldoor_t*)DoomLib::Z_Malloc( sizeof(*door), PU_LEVEL, 0);
|
||||
|
||||
P_AddThinker (&door->thinker);
|
||||
|
||||
sec->specialdata = door;
|
||||
sec->special = 0;
|
||||
|
||||
door->thinker.function.acp1 = (actionf_p1)T_VerticalDoor;
|
||||
door->sector = sec;
|
||||
door->direction = 0;
|
||||
door->type = normal;
|
||||
door->speed = VDOORSPEED;
|
||||
door->topcountdown = 30 * TICRATE;
|
||||
}
|
||||
|
||||
//
|
||||
// Spawn a door that opens after 5 minutes
|
||||
//
|
||||
void
|
||||
P_SpawnDoorRaiseIn5Mins
|
||||
( sector_t* sec,
|
||||
int secnum )
|
||||
{
|
||||
vldoor_t* door;
|
||||
|
||||
door = (vldoor_t*)DoomLib::Z_Malloc( sizeof(*door), PU_LEVEL, 0);
|
||||
|
||||
P_AddThinker (&door->thinker);
|
||||
|
||||
sec->specialdata = door;
|
||||
sec->special = 0;
|
||||
|
||||
door->thinker.function.acp1 = (actionf_p1)T_VerticalDoor;
|
||||
door->sector = sec;
|
||||
door->direction = 2;
|
||||
door->type = raiseIn5Mins;
|
||||
door->speed = VDOORSPEED;
|
||||
door->topheight = P_FindLowestCeilingSurrounding(sec);
|
||||
door->topheight -= 4*FRACUNIT;
|
||||
door->topwait = VDOORWAIT;
|
||||
door->topcountdown = 5 * 60 * TICRATE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// UNUSED
|
||||
// Separate into p_slidoor.c?
|
||||
|
||||
|
||||
Reference in New Issue
Block a user