p_switch.cpp (14482B)
1 /* 2 =========================================================================== 3 4 Doom 3 BFG Edition GPL Source Code 5 Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company. 6 7 This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code"). 8 9 Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify 10 it under the terms of the GNU General Public License as published by 11 the Free Software Foundation, either version 3 of the License, or 12 (at your option) any later version. 13 14 Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful, 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 GNU General Public License for more details. 18 19 You should have received a copy of the GNU General Public License 20 along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>. 21 22 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. 23 24 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. 25 26 =========================================================================== 27 */ 28 29 #include "Precompiled.h" 30 #include "globaldata.h" 31 32 33 #include "i_system.h" 34 #include "doomdef.h" 35 #include "p_local.h" 36 37 #include "g_game.h" 38 39 #include "s_sound.h" 40 41 // Data. 42 #include "sounds.h" 43 44 // State. 45 #include "doomstat.h" 46 #include "r_state.h" 47 48 49 // 50 // CHANGE THE TEXTURE OF A WALL SWITCH TO ITS OPPOSITE 51 // 52 const switchlist_t alphSwitchList[] = 53 { 54 // Doom shareware episode 1 switches 55 {"SW1BRCOM", "SW2BRCOM", 1}, 56 {"SW1BRN1", "SW2BRN1", 1}, 57 {"SW1BRN2", "SW2BRN2", 1}, 58 {"SW1BRNGN", "SW2BRNGN", 1}, 59 {"SW1BROWN", "SW2BROWN", 1}, 60 {"SW1COMM", "SW2COMM", 1}, 61 {"SW1COMP", "SW2COMP", 1}, 62 {"SW1DIRT", "SW2DIRT", 1}, 63 {"SW1EXIT", "SW2EXIT", 1}, 64 {"SW1GRAY", "SW2GRAY", 1}, 65 {"SW1GRAY1", "SW2GRAY1", 1}, 66 {"SW1METAL", "SW2METAL", 1}, 67 {"SW1PIPE", "SW2PIPE", 1}, 68 {"SW1SLAD", "SW2SLAD", 1}, 69 {"SW1STARG", "SW2STARG", 1}, 70 {"SW1STON1", "SW2STON1", 1}, 71 {"SW1STON2", "SW2STON2", 1}, 72 {"SW1STONE", "SW2STONE", 1}, 73 {"SW1STRTN", "SW2STRTN", 1}, 74 75 // Doom registered episodes 2&3 switches 76 {"SW1BLUE", "SW2BLUE", 2}, 77 {"SW1CMT", "SW2CMT", 2}, 78 {"SW1GARG", "SW2GARG", 2}, 79 {"SW1GSTON", "SW2GSTON", 2}, 80 {"SW1HOT", "SW2HOT", 2}, 81 {"SW1LION", "SW2LION", 2}, 82 {"SW1SATYR", "SW2SATYR", 2}, 83 {"SW1SKIN", "SW2SKIN", 2}, 84 {"SW1VINE", "SW2VINE", 2}, 85 {"SW1WOOD", "SW2WOOD", 2}, 86 87 // Doom II switches 88 {"SW1PANEL", "SW2PANEL", 3}, 89 {"SW1ROCK", "SW2ROCK", 3}, 90 {"SW1MET2", "SW2MET2", 3}, 91 {"SW1WDMET", "SW2WDMET", 3}, 92 {"SW1BRIK", "SW2BRIK", 3}, 93 {"SW1MOD1", "SW2MOD1", 3}, 94 {"SW1ZIM", "SW2ZIM", 3}, 95 {"SW1STON6", "SW2STON6", 3}, 96 {"SW1TEK", "SW2TEK", 3}, 97 {"SW1MARB", "SW2MARB", 3}, 98 {"SW1SKULL", "SW2SKULL", 3}, 99 100 {"\0", "\0", 0} 101 }; 102 103 104 // 105 // P_InitSwitchList 106 // Only called at game initialization. 107 // 108 void P_InitSwitchList(void) 109 { 110 int i; 111 int index; 112 int episode; 113 114 episode = 1; 115 116 if (::g->gamemode == registered || ::g->gamemode == retail) 117 episode = 2; 118 else if ( ::g->gamemode == commercial ) 119 episode = 3; 120 121 for (index = 0,i = 0;i < MAXSWITCHES;i++) 122 { 123 if (!alphSwitchList[i].episode) 124 { 125 ::g->numswitches = index/2; 126 ::g->switchlist[index] = -1; 127 break; 128 } 129 130 if (alphSwitchList[i].episode <= episode) 131 { 132 #if 0 // UNUSED - debug? 133 int value; 134 135 if (R_CheckTextureNumForName(alphSwitchList[i].name1) < 0) 136 { 137 I_Error("Can't find switch texture '%s'!", 138 alphSwitchList[i].name1); 139 continue; 140 } 141 142 value = R_TextureNumForName(alphSwitchList[i].name1); 143 #endif 144 ::g->switchlist[index++] = R_TextureNumForName(alphSwitchList[i].name1); 145 ::g->switchlist[index++] = R_TextureNumForName(alphSwitchList[i].name2); 146 } 147 } 148 } 149 150 151 // 152 // Start a button counting down till it turns off. 153 // 154 void 155 P_StartButton 156 ( line_t* line, 157 bwhere_e w, 158 int texture, 159 int time ) 160 { 161 int i; 162 163 // See if button is already pressed 164 for (i = 0;i < MAXBUTTONS;i++) 165 { 166 if (::g->buttonlist[i].btimer 167 && ::g->buttonlist[i].line == line) 168 { 169 170 return; 171 } 172 } 173 174 175 176 for (i = 0;i < MAXBUTTONS;i++) 177 { 178 if (!::g->buttonlist[i].btimer) 179 { 180 ::g->buttonlist[i].line = line; 181 ::g->buttonlist[i].where = w; 182 ::g->buttonlist[i].btexture = texture; 183 ::g->buttonlist[i].btimer = time; 184 ::g->buttonlist[i].degensoundorg = &line->frontsector->soundorg; 185 return; 186 } 187 } 188 189 I_Error("P_StartButton: no button slots left!"); 190 } 191 192 193 194 195 196 // 197 // Function that changes wall texture. 198 // Tell it if switch is ok to use again (1=yes, it's a button). 199 // 200 void 201 P_ChangeSwitchTexture 202 ( line_t* line, 203 int useAgain ) 204 { 205 int texTop; 206 int texMid; 207 int texBot; 208 int i; 209 int sound; 210 211 if (!useAgain) 212 line->special = 0; 213 214 texTop = ::g->sides[line->sidenum[0]].toptexture; 215 texMid = ::g->sides[line->sidenum[0]].midtexture; 216 texBot = ::g->sides[line->sidenum[0]].bottomtexture; 217 218 sound = sfx_swtchn; 219 220 // EXIT SWITCH? 221 if (line->special == 11) 222 sound = sfx_swtchx; 223 224 for (i = 0;i < ::g->numswitches*2;i++) 225 { 226 if (::g->switchlist[i] == texTop) 227 { 228 S_StartSound(::g->buttonlist->soundorg,sound); 229 ::g->sides[line->sidenum[0]].toptexture = ::g->switchlist[i^1]; 230 231 if (useAgain) 232 P_StartButton(line,top,::g->switchlist[i],BUTTONTIME); 233 234 return; 235 } 236 else 237 { 238 if (::g->switchlist[i] == texMid) 239 { 240 S_StartSound(::g->buttonlist->soundorg,sound); 241 ::g->sides[line->sidenum[0]].midtexture = ::g->switchlist[i^1]; 242 243 if (useAgain) 244 P_StartButton(line, middle,::g->switchlist[i],BUTTONTIME); 245 246 return; 247 } 248 else 249 { 250 if (::g->switchlist[i] == texBot) 251 { 252 S_StartSound(::g->buttonlist->soundorg,sound); 253 ::g->sides[line->sidenum[0]].bottomtexture = ::g->switchlist[i^1]; 254 255 if (useAgain) 256 P_StartButton(line, bottom,::g->switchlist[i],BUTTONTIME); 257 258 return; 259 } 260 } 261 } 262 } 263 } 264 265 266 267 268 269 270 // 271 // P_UseSpecialLine 272 // Called when a thing uses a special line. 273 // Only the front ::g->sides of ::g->lines are usable. 274 // 275 qboolean 276 P_UseSpecialLine 277 ( mobj_t* thing, 278 line_t* line, 279 int side ) 280 { 281 282 // Err... 283 // Use the back ::g->sides of VERY SPECIAL ::g->lines... 284 if (side) 285 { 286 switch(line->special) 287 { 288 case 124: 289 // Sliding door open&close 290 // UNUSED? 291 break; 292 293 default: 294 return false; 295 break; 296 } 297 } 298 299 300 // Switches that other things can activate. 301 if (!thing->player) 302 { 303 // never open secret doors 304 if (line->flags & ML_SECRET) 305 return false; 306 307 switch(line->special) 308 { 309 case 1: // MANUAL DOOR RAISE 310 case 32: // MANUAL BLUE 311 case 33: // MANUAL RED 312 case 34: // MANUAL YELLOW 313 break; 314 315 default: 316 return false; 317 break; 318 } 319 } 320 321 322 // do something 323 switch (line->special) 324 { 325 // MANUALS 326 case 1: // Vertical Door 327 case 26: // Blue Door/Locked 328 case 27: // Yellow Door /Locked 329 case 28: // Red Door /Locked 330 331 case 31: // Manual door open 332 case 32: // Blue locked door open 333 case 33: // Red locked door open 334 case 34: // Yellow locked door open 335 336 case 117: // Blazing door raise 337 case 118: // Blazing door open 338 EV_VerticalDoor (line, thing); 339 break; 340 341 //UNUSED - Door Slide Open&Close 342 // case 124: 343 // EV_SlidingDoor (line, thing); 344 // break; 345 346 // SWITCHES 347 case 7: 348 // Build Stairs 349 if (EV_BuildStairs(line,build8)) 350 P_ChangeSwitchTexture(line,0); 351 break; 352 353 case 9: 354 // Change Donut 355 if (EV_DoDonut(line)) 356 P_ChangeSwitchTexture(line,0); 357 break; 358 359 case 11: 360 // Exit level 361 // DHM - Nerve :: Not in deathmatch, stay in level until timelimit or fraglimit 362 if ( !::g->deathmatch && ::g->gameaction != ga_completed ) { 363 P_ChangeSwitchTexture(line,0); 364 G_ExitLevel (); 365 } 366 break; 367 368 case 14: 369 // Raise Floor 32 and change texture 370 if (EV_DoPlat(line,raiseAndChange,32)) 371 P_ChangeSwitchTexture(line,0); 372 break; 373 374 case 15: 375 // Raise Floor 24 and change texture 376 if (EV_DoPlat(line,raiseAndChange,24)) 377 P_ChangeSwitchTexture(line,0); 378 break; 379 380 case 18: 381 // Raise Floor to next highest floor 382 if (EV_DoFloor(line, raiseFloorToNearest)) 383 P_ChangeSwitchTexture(line,0); 384 break; 385 386 case 20: 387 // Raise Plat next highest floor and change texture 388 if (EV_DoPlat(line,raiseToNearestAndChange,0)) 389 P_ChangeSwitchTexture(line,0); 390 break; 391 392 case 21: 393 // PlatDownWaitUpStay 394 if (EV_DoPlat(line,downWaitUpStay,0)) 395 P_ChangeSwitchTexture(line,0); 396 break; 397 398 case 23: 399 // Lower Floor to Lowest 400 if (EV_DoFloor(line,lowerFloorToLowest)) 401 P_ChangeSwitchTexture(line,0); 402 break; 403 404 case 29: 405 // Raise Door 406 if (EV_DoDoor(line,normal)) 407 P_ChangeSwitchTexture(line,0); 408 break; 409 410 case 41: 411 // Lower Ceiling to Floor 412 if (EV_DoCeiling(line,lowerToFloor)) 413 P_ChangeSwitchTexture(line,0); 414 break; 415 416 case 71: 417 // Turbo Lower Floor 418 if (EV_DoFloor(line,turboLower)) 419 P_ChangeSwitchTexture(line,0); 420 break; 421 422 case 49: 423 // Ceiling Crush And Raise 424 if (EV_DoCeiling(line,crushAndRaise)) 425 P_ChangeSwitchTexture(line,0); 426 break; 427 428 case 50: 429 // Close Door 430 if (EV_DoDoor(line,closed)) 431 P_ChangeSwitchTexture(line,0); 432 break; 433 434 case 51: 435 // Secret EXIT 436 if ( !::g->deathmatch && ::g->gameaction != ga_completed ) { 437 P_ChangeSwitchTexture(line,0); 438 G_SecretExitLevel (); 439 } 440 break; 441 442 case 55: 443 // Raise Floor Crush 444 if (EV_DoFloor(line,raiseFloorCrush)) 445 P_ChangeSwitchTexture(line,0); 446 break; 447 448 case 101: 449 // Raise Floor 450 if (EV_DoFloor(line,raiseFloor)) 451 P_ChangeSwitchTexture(line,0); 452 break; 453 454 case 102: 455 // Lower Floor to Surrounding floor height 456 if (EV_DoFloor(line,lowerFloor)) 457 P_ChangeSwitchTexture(line,0); 458 break; 459 460 case 103: 461 // Open Door 462 if (EV_DoDoor(line,opened)) 463 P_ChangeSwitchTexture(line,0); 464 break; 465 466 case 111: 467 // Blazing Door Raise (faster than TURBO!) 468 if (EV_DoDoor (line,blazeRaise)) 469 P_ChangeSwitchTexture(line,0); 470 break; 471 472 case 112: 473 // Blazing Door Open (faster than TURBO!) 474 if (EV_DoDoor (line,blazeOpen)) 475 P_ChangeSwitchTexture(line,0); 476 break; 477 478 case 113: 479 // Blazing Door Close (faster than TURBO!) 480 if (EV_DoDoor (line,blazeClose)) 481 P_ChangeSwitchTexture(line,0); 482 break; 483 484 case 122: 485 // Blazing PlatDownWaitUpStay 486 if (EV_DoPlat(line,blazeDWUS,0)) 487 P_ChangeSwitchTexture(line,0); 488 break; 489 490 case 127: 491 // Build Stairs Turbo 16 492 if (EV_BuildStairs(line,turbo16)) 493 P_ChangeSwitchTexture(line,0); 494 break; 495 496 case 131: 497 // Raise Floor Turbo 498 if (EV_DoFloor(line,raiseFloorTurbo)) 499 P_ChangeSwitchTexture(line,0); 500 break; 501 502 case 133: 503 // BlzOpenDoor BLUE 504 case 135: 505 // BlzOpenDoor RED 506 case 137: 507 // BlzOpenDoor YELLOW 508 if (EV_DoLockedDoor (line,blazeOpen,thing)) 509 P_ChangeSwitchTexture(line,0); 510 break; 511 512 case 140: 513 // Raise Floor 512 514 if (EV_DoFloor(line,raiseFloor512)) 515 P_ChangeSwitchTexture(line,0); 516 break; 517 518 // BUTTONS 519 case 42: 520 // Close Door 521 if (EV_DoDoor(line,closed)) 522 P_ChangeSwitchTexture(line,1); 523 break; 524 525 case 43: 526 // Lower Ceiling to Floor 527 if (EV_DoCeiling(line,lowerToFloor)) 528 P_ChangeSwitchTexture(line,1); 529 break; 530 531 case 45: 532 // Lower Floor to Surrounding floor height 533 if (EV_DoFloor(line,lowerFloor)) 534 P_ChangeSwitchTexture(line,1); 535 break; 536 537 case 60: 538 // Lower Floor to Lowest 539 if (EV_DoFloor(line,lowerFloorToLowest)) 540 P_ChangeSwitchTexture(line,1); 541 break; 542 543 case 61: 544 // Open Door 545 if (EV_DoDoor(line,opened)) 546 P_ChangeSwitchTexture(line,1); 547 break; 548 549 case 62: 550 // PlatDownWaitUpStay 551 if (EV_DoPlat(line,downWaitUpStay,1)) 552 P_ChangeSwitchTexture(line,1); 553 break; 554 555 case 63: 556 // Raise Door 557 if (EV_DoDoor(line,normal)) 558 P_ChangeSwitchTexture(line,1); 559 break; 560 561 case 64: 562 // Raise Floor to ceiling 563 if (EV_DoFloor(line,raiseFloor)) 564 P_ChangeSwitchTexture(line,1); 565 break; 566 567 case 66: 568 // Raise Floor 24 and change texture 569 if (EV_DoPlat(line,raiseAndChange,24)) 570 P_ChangeSwitchTexture(line,1); 571 break; 572 573 case 67: 574 // Raise Floor 32 and change texture 575 if (EV_DoPlat(line,raiseAndChange,32)) 576 P_ChangeSwitchTexture(line,1); 577 break; 578 579 case 65: 580 // Raise Floor Crush 581 if (EV_DoFloor(line,raiseFloorCrush)) 582 P_ChangeSwitchTexture(line,1); 583 break; 584 585 case 68: 586 // Raise Plat to next highest floor and change texture 587 if (EV_DoPlat(line,raiseToNearestAndChange,0)) 588 P_ChangeSwitchTexture(line,1); 589 break; 590 591 case 69: 592 // Raise Floor to next highest floor 593 if (EV_DoFloor(line, raiseFloorToNearest)) 594 P_ChangeSwitchTexture(line,1); 595 break; 596 597 case 70: 598 // Turbo Lower Floor 599 if (EV_DoFloor(line,turboLower)) 600 P_ChangeSwitchTexture(line,1); 601 break; 602 603 case 114: 604 // Blazing Door Raise (faster than TURBO!) 605 if (EV_DoDoor (line,blazeRaise)) 606 P_ChangeSwitchTexture(line,1); 607 break; 608 609 case 115: 610 // Blazing Door Open (faster than TURBO!) 611 if (EV_DoDoor (line,blazeOpen)) 612 P_ChangeSwitchTexture(line,1); 613 break; 614 615 case 116: 616 // Blazing Door Close (faster than TURBO!) 617 if (EV_DoDoor (line,blazeClose)) 618 P_ChangeSwitchTexture(line,1); 619 break; 620 621 case 123: 622 // Blazing PlatDownWaitUpStay 623 if (EV_DoPlat(line,blazeDWUS,0)) 624 P_ChangeSwitchTexture(line,1); 625 break; 626 627 case 132: 628 // Raise Floor Turbo 629 if (EV_DoFloor(line,raiseFloorTurbo)) 630 P_ChangeSwitchTexture(line,1); 631 break; 632 633 case 99: 634 // BlzOpenDoor BLUE 635 case 134: 636 // BlzOpenDoor RED 637 case 136: 638 // BlzOpenDoor YELLOW 639 if (EV_DoLockedDoor (line,blazeOpen,thing)) 640 P_ChangeSwitchTexture(line,1); 641 break; 642 643 case 138: 644 // Light Turn On 645 EV_LightTurnOn(line,255); 646 P_ChangeSwitchTexture(line,1); 647 break; 648 649 case 139: 650 // Light Turn Off 651 EV_LightTurnOn(line,35); 652 P_ChangeSwitchTexture(line,1); 653 break; 654 655 } 656 657 return true; 658 } 659 660