0
0
Fork 0
mirror of https://github.com/id-Software/DOOM-3-BFG.git synced 2025-03-16 15:41:16 +00:00
doom3-bfg/doomclassic/doom/p_switch.cpp
2022-09-05 22:25:33 +02:00

768 lines
15 KiB
C++

/*
===========================================================================
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 "i_system.h"
#include "doomdef.h"
#include "p_local.h"
#include "g_game.h"
#include "s_sound.h"
// Data.
#include "sounds.h"
// State.
#include "doomstat.h"
#include "r_state.h"
//
// CHANGE THE TEXTURE OF A WALL SWITCH TO ITS OPPOSITE
//
const switchlist_t alphSwitchList[] =
{
// Doom shareware episode 1 switches
{"SW1BRCOM", "SW2BRCOM", 1},
{"SW1BRN1", "SW2BRN1", 1},
{"SW1BRN2", "SW2BRN2", 1},
{"SW1BRNGN", "SW2BRNGN", 1},
{"SW1BROWN", "SW2BROWN", 1},
{"SW1COMM", "SW2COMM", 1},
{"SW1COMP", "SW2COMP", 1},
{"SW1DIRT", "SW2DIRT", 1},
{"SW1EXIT", "SW2EXIT", 1},
{"SW1GRAY", "SW2GRAY", 1},
{"SW1GRAY1", "SW2GRAY1", 1},
{"SW1METAL", "SW2METAL", 1},
{"SW1PIPE", "SW2PIPE", 1},
{"SW1SLAD", "SW2SLAD", 1},
{"SW1STARG", "SW2STARG", 1},
{"SW1STON1", "SW2STON1", 1},
{"SW1STON2", "SW2STON2", 1},
{"SW1STONE", "SW2STONE", 1},
{"SW1STRTN", "SW2STRTN", 1},
// Doom registered episodes 2&3 switches
{"SW1BLUE", "SW2BLUE", 2},
{"SW1CMT", "SW2CMT", 2},
{"SW1GARG", "SW2GARG", 2},
{"SW1GSTON", "SW2GSTON", 2},
{"SW1HOT", "SW2HOT", 2},
{"SW1LION", "SW2LION", 2},
{"SW1SATYR", "SW2SATYR", 2},
{"SW1SKIN", "SW2SKIN", 2},
{"SW1VINE", "SW2VINE", 2},
{"SW1WOOD", "SW2WOOD", 2},
// Doom II switches
{"SW1PANEL", "SW2PANEL", 3},
{"SW1ROCK", "SW2ROCK", 3},
{"SW1MET2", "SW2MET2", 3},
{"SW1WDMET", "SW2WDMET", 3},
{"SW1BRIK", "SW2BRIK", 3},
{"SW1MOD1", "SW2MOD1", 3},
{"SW1ZIM", "SW2ZIM", 3},
{"SW1STON6", "SW2STON6", 3},
{"SW1TEK", "SW2TEK", 3},
{"SW1MARB", "SW2MARB", 3},
{"SW1SKULL", "SW2SKULL", 3},
{"\0", "\0", 0}
};
//
// P_InitSwitchList
// Only called at game initialization.
//
void P_InitSwitchList( void )
{
int i;
int index;
int episode;
episode = 1;
if( ::g->gamemode == registered || ::g->gamemode == retail )
{
episode = 2;
}
else if( ::g->gamemode == commercial )
{
episode = 3;
}
for( index = 0, i = 0; i < MAXSWITCHES; i++ )
{
if( !alphSwitchList[i].episode )
{
::g->numswitches = index / 2;
::g->switchlist[index] = -1;
break;
}
if( alphSwitchList[i].episode <= episode )
{
#if 0 // UNUSED - debug?
int value;
if( R_CheckTextureNumForName( alphSwitchList[i].name1 ) < 0 )
{
I_Error( "Can't find switch texture '%s'!",
alphSwitchList[i].name1 );
continue;
}
value = R_TextureNumForName( alphSwitchList[i].name1 );
#endif
::g->switchlist[index++] = R_TextureNumForName( alphSwitchList[i].name1 );
::g->switchlist[index++] = R_TextureNumForName( alphSwitchList[i].name2 );
}
}
}
//
// Start a button counting down till it turns off.
//
void
P_StartButton
( line_t* line,
bwhere_e w,
int texture,
int time )
{
int i;
// See if button is already pressed
for( i = 0; i < MAXBUTTONS; i++ )
{
if( ::g->buttonlist[i].btimer
&& ::g->buttonlist[i].line == line )
{
return;
}
}
for( i = 0; i < MAXBUTTONS; i++ )
{
if( !::g->buttonlist[i].btimer )
{
::g->buttonlist[i].line = line;
::g->buttonlist[i].where = w;
::g->buttonlist[i].btexture = texture;
::g->buttonlist[i].btimer = time;
::g->buttonlist[i].degensoundorg = &line->frontsector->soundorg;
return;
}
}
I_Error( "P_StartButton: no button slots left!" );
}
//
// Function that changes wall texture.
// Tell it if switch is ok to use again (1=yes, it's a button).
//
void
P_ChangeSwitchTexture
( line_t* line,
int useAgain )
{
int texTop;
int texMid;
int texBot;
int i;
int sound;
if( !useAgain )
{
line->special = 0;
}
texTop = ::g->sides[line->sidenum[0]].toptexture;
texMid = ::g->sides[line->sidenum[0]].midtexture;
texBot = ::g->sides[line->sidenum[0]].bottomtexture;
sound = sfx_swtchn;
// EXIT SWITCH?
if( line->special == 11 )
{
sound = sfx_swtchx;
}
for( i = 0; i < ::g->numswitches * 2; i++ )
{
if( ::g->switchlist[i] == texTop )
{
S_StartSound( ::g->buttonlist->soundorg, sound );
::g->sides[line->sidenum[0]].toptexture = ::g->switchlist[i ^ 1];
if( useAgain )
{
P_StartButton( line, top, ::g->switchlist[i], BUTTONTIME );
}
return;
}
else
{
if( ::g->switchlist[i] == texMid )
{
S_StartSound( ::g->buttonlist->soundorg, sound );
::g->sides[line->sidenum[0]].midtexture = ::g->switchlist[i ^ 1];
if( useAgain )
{
P_StartButton( line, middle, ::g->switchlist[i], BUTTONTIME );
}
return;
}
else
{
if( ::g->switchlist[i] == texBot )
{
S_StartSound( ::g->buttonlist->soundorg, sound );
::g->sides[line->sidenum[0]].bottomtexture = ::g->switchlist[i ^ 1];
if( useAgain )
{
P_StartButton( line, bottom, ::g->switchlist[i], BUTTONTIME );
}
return;
}
}
}
}
}
//
// P_UseSpecialLine
// Called when a thing uses a special line.
// Only the front ::g->sides of ::g->lines are usable.
//
qboolean
P_UseSpecialLine
( mobj_t* thing,
line_t* line,
int side )
{
// Err...
// Use the back ::g->sides of VERY SPECIAL ::g->lines...
if( side )
{
switch( line->special )
{
case 124:
// Sliding door open&close
// UNUSED?
break;
default:
return false;
break;
}
}
// Switches that other things can activate.
if( !thing->player )
{
// never open secret doors
if( line->flags & ML_SECRET )
{
return false;
}
switch( line->special )
{
case 1: // MANUAL DOOR RAISE
case 32: // MANUAL BLUE
case 33: // MANUAL RED
case 34: // MANUAL YELLOW
break;
default:
return false;
break;
}
}
// do something
switch( line->special )
{
// MANUALS
case 1: // Vertical Door
case 26: // Blue Door/Locked
case 27: // Yellow Door /Locked
case 28: // Red Door /Locked
case 31: // Manual door open
case 32: // Blue locked door open
case 33: // Red locked door open
case 34: // Yellow locked door open
case 117: // Blazing door raise
case 118: // Blazing door open
EV_VerticalDoor( line, thing );
break;
//UNUSED - Door Slide Open&Close
// case 124:
// EV_SlidingDoor (line, thing);
// break;
// SWITCHES
case 7:
// Build Stairs
if( EV_BuildStairs( line, build8 ) )
{
P_ChangeSwitchTexture( line, 0 );
}
break;
case 9:
// Change Donut
if( EV_DoDonut( line ) )
{
P_ChangeSwitchTexture( line, 0 );
}
break;
case 11:
// Exit level
// DHM - Nerve :: Not in deathmatch, stay in level until timelimit or fraglimit
if( !::g->deathmatch && ::g->gameaction != ga_completed )
{
P_ChangeSwitchTexture( line, 0 );
G_ExitLevel();
}
break;
case 14:
// Raise Floor 32 and change texture
if( EV_DoPlat( line, raiseAndChange, 32 ) )
{
P_ChangeSwitchTexture( line, 0 );
}
break;
case 15:
// Raise Floor 24 and change texture
if( EV_DoPlat( line, raiseAndChange, 24 ) )
{
P_ChangeSwitchTexture( line, 0 );
}
break;
case 18:
// Raise Floor to next highest floor
if( EV_DoFloor( line, raiseFloorToNearest ) )
{
P_ChangeSwitchTexture( line, 0 );
}
break;
case 20:
// Raise Plat next highest floor and change texture
if( EV_DoPlat( line, raiseToNearestAndChange, 0 ) )
{
P_ChangeSwitchTexture( line, 0 );
}
break;
case 21:
// PlatDownWaitUpStay
if( EV_DoPlat( line, downWaitUpStay, 0 ) )
{
P_ChangeSwitchTexture( line, 0 );
}
break;
case 23:
// Lower Floor to Lowest
if( EV_DoFloor( line, lowerFloorToLowest ) )
{
P_ChangeSwitchTexture( line, 0 );
}
break;
case 29:
// Raise Door
if( EV_DoDoor( line, normal ) )
{
P_ChangeSwitchTexture( line, 0 );
}
break;
case 41:
// Lower Ceiling to Floor
if( EV_DoCeiling( line, lowerToFloor ) )
{
P_ChangeSwitchTexture( line, 0 );
}
break;
case 71:
// Turbo Lower Floor
if( EV_DoFloor( line, turboLower ) )
{
P_ChangeSwitchTexture( line, 0 );
}
break;
case 49:
// Ceiling Crush And Raise
if( EV_DoCeiling( line, crushAndRaise ) )
{
P_ChangeSwitchTexture( line, 0 );
}
break;
case 50:
// Close Door
if( EV_DoDoor( line, closed ) )
{
P_ChangeSwitchTexture( line, 0 );
}
break;
case 51:
// Secret EXIT
if( !::g->deathmatch && ::g->gameaction != ga_completed )
{
P_ChangeSwitchTexture( line, 0 );
G_SecretExitLevel();
}
break;
case 55:
// Raise Floor Crush
if( EV_DoFloor( line, raiseFloorCrush ) )
{
P_ChangeSwitchTexture( line, 0 );
}
break;
case 101:
// Raise Floor
if( EV_DoFloor( line, raiseFloor ) )
{
P_ChangeSwitchTexture( line, 0 );
}
break;
case 102:
// Lower Floor to Surrounding floor height
if( EV_DoFloor( line, lowerFloor ) )
{
P_ChangeSwitchTexture( line, 0 );
}
break;
case 103:
// Open Door
if( EV_DoDoor( line, opened ) )
{
P_ChangeSwitchTexture( line, 0 );
}
break;
case 111:
// Blazing Door Raise (faster than TURBO!)
if( EV_DoDoor( line, blazeRaise ) )
{
P_ChangeSwitchTexture( line, 0 );
}
break;
case 112:
// Blazing Door Open (faster than TURBO!)
if( EV_DoDoor( line, blazeOpen ) )
{
P_ChangeSwitchTexture( line, 0 );
}
break;
case 113:
// Blazing Door Close (faster than TURBO!)
if( EV_DoDoor( line, blazeClose ) )
{
P_ChangeSwitchTexture( line, 0 );
}
break;
case 122:
// Blazing PlatDownWaitUpStay
if( EV_DoPlat( line, blazeDWUS, 0 ) )
{
P_ChangeSwitchTexture( line, 0 );
}
break;
case 127:
// Build Stairs Turbo 16
if( EV_BuildStairs( line, turbo16 ) )
{
P_ChangeSwitchTexture( line, 0 );
}
break;
case 131:
// Raise Floor Turbo
if( EV_DoFloor( line, raiseFloorTurbo ) )
{
P_ChangeSwitchTexture( line, 0 );
}
break;
case 133:
// BlzOpenDoor BLUE
case 135:
// BlzOpenDoor RED
case 137:
// BlzOpenDoor YELLOW
if( EV_DoLockedDoor( line, blazeOpen, thing ) )
{
P_ChangeSwitchTexture( line, 0 );
}
break;
case 140:
// Raise Floor 512
if( EV_DoFloor( line, raiseFloor512 ) )
{
P_ChangeSwitchTexture( line, 0 );
}
break;
// BUTTONS
case 42:
// Close Door
if( EV_DoDoor( line, closed ) )
{
P_ChangeSwitchTexture( line, 1 );
}
break;
case 43:
// Lower Ceiling to Floor
if( EV_DoCeiling( line, lowerToFloor ) )
{
P_ChangeSwitchTexture( line, 1 );
}
break;
case 45:
// Lower Floor to Surrounding floor height
if( EV_DoFloor( line, lowerFloor ) )
{
P_ChangeSwitchTexture( line, 1 );
}
break;
case 60:
// Lower Floor to Lowest
if( EV_DoFloor( line, lowerFloorToLowest ) )
{
P_ChangeSwitchTexture( line, 1 );
}
break;
case 61:
// Open Door
if( EV_DoDoor( line, opened ) )
{
P_ChangeSwitchTexture( line, 1 );
}
break;
case 62:
// PlatDownWaitUpStay
if( EV_DoPlat( line, downWaitUpStay, 1 ) )
{
P_ChangeSwitchTexture( line, 1 );
}
break;
case 63:
// Raise Door
if( EV_DoDoor( line, normal ) )
{
P_ChangeSwitchTexture( line, 1 );
}
break;
case 64:
// Raise Floor to ceiling
if( EV_DoFloor( line, raiseFloor ) )
{
P_ChangeSwitchTexture( line, 1 );
}
break;
case 66:
// Raise Floor 24 and change texture
if( EV_DoPlat( line, raiseAndChange, 24 ) )
{
P_ChangeSwitchTexture( line, 1 );
}
break;
case 67:
// Raise Floor 32 and change texture
if( EV_DoPlat( line, raiseAndChange, 32 ) )
{
P_ChangeSwitchTexture( line, 1 );
}
break;
case 65:
// Raise Floor Crush
if( EV_DoFloor( line, raiseFloorCrush ) )
{
P_ChangeSwitchTexture( line, 1 );
}
break;
case 68:
// Raise Plat to next highest floor and change texture
if( EV_DoPlat( line, raiseToNearestAndChange, 0 ) )
{
P_ChangeSwitchTexture( line, 1 );
}
break;
case 69:
// Raise Floor to next highest floor
if( EV_DoFloor( line, raiseFloorToNearest ) )
{
P_ChangeSwitchTexture( line, 1 );
}
break;
case 70:
// Turbo Lower Floor
if( EV_DoFloor( line, turboLower ) )
{
P_ChangeSwitchTexture( line, 1 );
}
break;
case 114:
// Blazing Door Raise (faster than TURBO!)
if( EV_DoDoor( line, blazeRaise ) )
{
P_ChangeSwitchTexture( line, 1 );
}
break;
case 115:
// Blazing Door Open (faster than TURBO!)
if( EV_DoDoor( line, blazeOpen ) )
{
P_ChangeSwitchTexture( line, 1 );
}
break;
case 116:
// Blazing Door Close (faster than TURBO!)
if( EV_DoDoor( line, blazeClose ) )
{
P_ChangeSwitchTexture( line, 1 );
}
break;
case 123:
// Blazing PlatDownWaitUpStay
if( EV_DoPlat( line, blazeDWUS, 0 ) )
{
P_ChangeSwitchTexture( line, 1 );
}
break;
case 132:
// Raise Floor Turbo
if( EV_DoFloor( line, raiseFloorTurbo ) )
{
P_ChangeSwitchTexture( line, 1 );
}
break;
case 99:
// BlzOpenDoor BLUE
case 134:
// BlzOpenDoor RED
case 136:
// BlzOpenDoor YELLOW
if( EV_DoLockedDoor( line, blazeOpen, thing ) )
{
P_ChangeSwitchTexture( line, 1 );
}
break;
case 138:
// Light Turn On
EV_LightTurnOn( line, 255 );
P_ChangeSwitchTexture( line, 1 );
break;
case 139:
// Light Turn Off
EV_LightTurnOn( line, 35 );
P_ChangeSwitchTexture( line, 1 );
break;
}
return true;
}