p_spec.c (36278B)
1 /* P_Spec.c */ 2 #include "doomdef.h" 3 #include "r_local.h" 4 #include "p_local.h" 5 #include "st_main.h" 6 7 extern mapthing_t *spawnlist; // 800A5D74 8 extern int spawncount; // 800A5D78 9 10 line_t **linespeciallist; // 800A5F60 11 int numlinespecials; // 800A5F64 12 13 sector_t **sectorspeciallist;// 800A5F68 14 int numsectorspecials; // 800A5F6C 15 16 animdef_t animdefs[MAXANIMS] = // 8005AE80 17 { 18 { 15, "SMONAA", 4, 7, false, false }, 19 { 0, "SMONBA", 4, 1, false, false }, 20 { 0, "SMONCA", 4, 7, false, false }, 21 { 90, "CFACEA", 3, 3, true, false }, 22 { 0, "SMONDA", 4, 3, false, false }, 23 { 10, "SMONEA", 4, 7, false, false }, 24 { 0, "SPORTA", 9, 3, false, true }, 25 { 10, "SMONF", 5, 1, true, true }, 26 { 10, "STRAKR", 5, 1, true, true }, 27 { 10, "STRAKB", 5, 1, true, true }, 28 { 10, "STRAKY", 5, 1, true, true }, 29 { 50, "C307B", 5, 1, true, true }, 30 { 0, "CTEL", 8, 3, false, true }, 31 { 0,"CASFL98", 5, 7, true, true }, 32 { 0, "HTELA", 4, 1, true, false } 33 }; 34 35 /*---------- 36 / anims[8] -> anims[MAXANIMS = 15] 37 / For some reason Doom 64 is 8, 38 / I will leave it at 15 to avoid problems loading data into this pointer. 39 /---------*/ 40 anim_t anims[MAXANIMS], *lastanim; // 800A5F70, 800A6090 41 42 card_t MapBlueKeyType; //0x80077E9C 43 card_t MapRedKeyType; //0x8007821C 44 card_t MapYellowKeyType; //0x800780A0 45 46 void P_AddSectorSpecial(sector_t *sec); 47 48 /* 49 ================= 50 = 51 = P_Init 52 = 53 ================= 54 */ 55 56 void P_Init (void) // 8001F340 57 { 58 int i; 59 sector_t *sector; 60 side_t *side; 61 62 side = sides; 63 for (i = 0; i < numsides; i++, side++) 64 { 65 W_CacheLumpNum(side->toptexture + firsttex , PU_LEVEL, dec_d64); 66 W_CacheLumpNum(side->bottomtexture + firsttex , PU_LEVEL, dec_d64); 67 W_CacheLumpNum(side->midtexture + firsttex , PU_LEVEL, dec_d64); 68 } 69 70 sector = sectors; 71 for (i = 0; i < numsectors; i++, sector++) 72 { 73 if (sector->ceilingpic >= 0) 74 W_CacheLumpNum(sector->ceilingpic + firsttex, PU_LEVEL, dec_d64); 75 76 if (sector->floorpic >= 0) 77 W_CacheLumpNum(sector->floorpic + firsttex, PU_LEVEL, dec_d64); 78 79 if (sector->flags & MS_LIQUIDFLOOR) 80 W_CacheLumpNum(sector->floorpic + firsttex + 1, PU_LEVEL,dec_d64); 81 } 82 } 83 84 /* 85 ============================================================================== 86 87 SPECIAL SPAWNING 88 89 ============================================================================== 90 */ 91 /* 92 ================================================================================ 93 = P_SpawnSpecials 94 = 95 = After the map has been loaded, scan for specials that 96 = spawn thinkers 97 = 98 =============================================================================== 99 */ 100 101 void P_SpawnSpecials (void) // 8001F490 102 { 103 mobj_t *mo; 104 sector_t *sector; 105 line_t *line; 106 int i, j; 107 int lump; 108 109 /* */ 110 /* Init animation aka (P_InitPicAnims) */ 111 /* */ 112 lastanim = anims; 113 for (i=0 ; i < MAXANIMS ; i++) 114 { 115 lump = W_GetNumForName(animdefs[i].startname); 116 117 lastanim->basepic = (lump - firsttex); 118 lastanim->tics = animdefs[i].speed; 119 lastanim->delay = animdefs[i].delay; 120 lastanim->delaycnt = lastanim->delay; 121 lastanim->isreverse = animdefs[i].isreverse; 122 123 if (animdefs[i].ispalcycle == false) 124 { 125 lastanim->current = (lump << 4); 126 lastanim->picstart = (lump << 4); 127 lastanim->picend = (animdefs[i].frames + lump - 1) << 4; 128 lastanim->frame = 16; 129 130 /* Load the following graphics for animation */ 131 for (j=0 ; j < animdefs[i].frames ; j++) 132 { 133 W_CacheLumpNum(lump, PU_LEVEL, dec_d64); 134 lump++; 135 } 136 } 137 else 138 { 139 lastanim->current = (lump << 4); 140 lastanim->picstart = (lump << 4); 141 lastanim->picend = (lump << 4) | (animdefs[i].frames - 1); 142 lastanim->frame = 1; 143 } 144 145 lastanim++; 146 } 147 148 /* */ 149 /* Init Macro Variables */ 150 /* */ 151 activemacro = NULL; 152 macrocounter = 0; 153 macroidx1 = 0; 154 macroidx2 = 0; 155 156 /* */ 157 /* Init special SECTORs */ 158 /* */ 159 scrollfrac = 0; 160 numsectorspecials = 0; // Restart count 161 sector = sectors; 162 for(i = 0; i < numsectors; i++, sector++) 163 { 164 P_AddSectorSpecial(sector); 165 if(sector->flags & MS_SECRET) 166 { 167 totalsecret++; 168 } 169 170 if(sector->flags & (MS_SCROLLCEILING | MS_SCROLLFLOOR| 171 MS_SCROLLLEFT | MS_SCROLLRIGHT| MS_SCROLLUP| MS_SCROLLDOWN)) 172 { 173 numsectorspecials++; 174 } 175 } 176 177 sectorspeciallist = (sector_t**)Z_Malloc(numsectorspecials*sizeof(void*), PU_LEVEL, NULL); 178 sector = sectors; 179 for(i = 0, j = 0; i < numsectors; i++, sector++) 180 { 181 if(sector->flags & (MS_SCROLLCEILING | MS_SCROLLFLOOR| 182 MS_SCROLLLEFT | MS_SCROLLRIGHT| MS_SCROLLUP| MS_SCROLLDOWN)) 183 { 184 sectorspeciallist[j] = sector; 185 j++; 186 } 187 } 188 189 /* */ 190 /* Init line EFFECTs */ 191 /* */ 192 numlinespecials = 0; 193 line = lines; 194 for (i = 0;i < numlines; i++, line++) 195 { 196 if(line->flags & (ML_SCROLLRIGHT|ML_SCROLLLEFT|ML_SCROLLUP|ML_SCROLLDOWN)) 197 { 198 numlinespecials++; 199 } 200 } 201 202 linespeciallist = (line_t**)Z_Malloc(numlinespecials*sizeof(void*), PU_LEVEL, NULL); 203 line = lines; 204 for (i = 0, j = 0; i < numlines; i++, line++) 205 { 206 if(line->flags & (ML_SCROLLRIGHT|ML_SCROLLLEFT|ML_SCROLLUP|ML_SCROLLDOWN)) 207 { 208 linespeciallist[j] = line; 209 j++; 210 } 211 } 212 213 /* */ 214 /* Init Keys */ 215 /* */ 216 217 MapBlueKeyType = it_bluecard; 218 MapYellowKeyType = it_yellowcard; 219 MapRedKeyType = it_redcard; 220 for (mo = mobjhead.next ; mo != &mobjhead ; mo = mo->next) 221 { 222 if((mo->type == MT_ITEM_BLUESKULLKEY) || 223 (mo->type == MT_ITEM_YELLOWSKULLKEY) || 224 (mo->type == MT_ITEM_REDSKULLKEY)) 225 { 226 MapBlueKeyType = it_blueskull; 227 MapYellowKeyType = it_yellowskull; 228 MapRedKeyType = it_redskull; 229 break; 230 } 231 232 /*switch (mo->type) 233 { 234 case MT_ITEM_BLUESKULLKEY: MapBlueKeyType = it_blueskull; break; 235 case MT_ITEM_YELLOWSKULLKEY: MapYellowKeyType = it_yellowskull; break; 236 case MT_ITEM_REDSKULLKEY: MapRedKeyType = it_redskull; break; 237 }*/ 238 } 239 240 for (i = 0; i < spawncount; i++) 241 { 242 if((spawnlist[i].type == 40) || 243 (spawnlist[i].type == 39) || 244 (spawnlist[i].type == 38)) 245 { 246 MapBlueKeyType = it_blueskull; 247 MapYellowKeyType = it_yellowskull; 248 MapRedKeyType = it_redskull; 249 break; 250 } 251 252 /*if(spawnlist[i].type == 40)//mobjinfo[MT_ITEM_BLUESKULLKEY].doomednum 253 MapBlueKeyType = it_blueskull; 254 if(spawnlist[i].type == 39)//mobjinfo[MT_ITEM_YELLOWSKULLKEY].doomednum 255 MapYellowKeyType = it_yellowskull; 256 if(spawnlist[i].type == 38)//mobjinfo[MT_ITEM_REDSKULLKEY].doomednum 257 MapRedKeyType = it_redskull;*/ 258 } 259 260 /* */ 261 /* Init other misc stuff */ 262 /* */ 263 D_memset(activeceilings, 0, MAXCEILINGS * sizeof(ceiling_t*)); 264 D_memset(activeplats, 0, MAXPLATS * sizeof(plat_t*)); 265 D_memset(buttonlist, 0, MAXBUTTONS * sizeof(button_t)); 266 } 267 268 /* 269 ============================================================================== 270 271 UTILITIES 272 273 ============================================================================== 274 */ 275 276 /*================================================================== */ 277 /* */ 278 /* Return sector_t * of sector next to current. NULL if not two-sided line */ 279 /* */ 280 /*================================================================== */ 281 sector_t *getNextSector(line_t *line,sector_t *sec) // 8001F96C 282 { 283 if (!(line->flags & ML_TWOSIDED)) 284 return NULL; 285 286 if (line->frontsector == sec) 287 return line->backsector; 288 289 return line->frontsector; 290 } 291 292 /*================================================================== */ 293 /* */ 294 /* FIND LOWEST FLOOR HEIGHT IN SURROUNDING SECTORS */ 295 /* */ 296 /*================================================================== */ 297 fixed_t P_FindLowestFloorSurrounding(sector_t *sec) // 8001F9AC 298 { 299 int i; 300 line_t *check; 301 sector_t *other; 302 fixed_t floor = sec->floorheight; 303 304 for (i=0 ;i < sec->linecount ; i++) 305 { 306 check = sec->lines[i]; 307 other = getNextSector(check,sec); 308 if (!other) 309 continue; 310 if (other->floorheight < floor) 311 floor = other->floorheight; 312 } 313 return floor; 314 } 315 316 /*================================================================== */ 317 /* */ 318 /* FIND HIGHEST FLOOR HEIGHT IN SURROUNDING SECTORS */ 319 /* */ 320 /*================================================================== */ 321 fixed_t P_FindHighestFloorSurrounding(sector_t *sec) // 8001FA48 322 { 323 int i; 324 line_t *check; 325 sector_t *other; 326 fixed_t floor = -500*FRACUNIT; 327 328 for (i=0 ;i < sec->linecount ; i++) 329 { 330 check = sec->lines[i]; 331 other = getNextSector(check,sec); 332 if (!other) 333 continue; 334 if (other->floorheight > floor) 335 floor = other->floorheight; 336 } 337 return floor; 338 } 339 340 /*================================================================== */ 341 /* */ 342 /* FIND NEXT HIGHEST FLOOR IN SURROUNDING SECTORS */ 343 /* */ 344 /*================================================================== */ 345 fixed_t P_FindNextHighestFloor(sector_t *sec,int currentheight) // 8001FAE4 346 { 347 int i; 348 int h; 349 int min; 350 line_t *check; 351 sector_t *other; 352 fixed_t height = currentheight; 353 fixed_t heightlist[20]; /* 20 adjoining sectors max! */ 354 355 for (i =0,h = 0 ;i < sec->linecount ; i++) 356 { 357 check = sec->lines[i]; 358 other = getNextSector(check,sec); 359 if (!other) 360 continue; 361 if (other->floorheight > height) 362 heightlist[h++] = other->floorheight; 363 } 364 365 /* */ 366 /* Find lowest height in list */ 367 /* */ 368 min = heightlist[0]; 369 for (i = 1;i < h;i++) 370 if (heightlist[i] < min) 371 min = heightlist[i]; 372 373 return min; 374 } 375 376 /*================================================================== */ 377 /* */ 378 /* FIND LOWEST CEILING IN THE SURROUNDING SECTORS */ 379 /* */ 380 /*================================================================== */ 381 fixed_t P_FindLowestCeilingSurrounding(sector_t *sec) // 8001FC68 382 { 383 int i; 384 line_t *check; 385 sector_t *other; 386 fixed_t height = MAXINT; 387 388 for (i=0 ;i < sec->linecount ; i++) 389 { 390 check = sec->lines[i]; 391 other = getNextSector(check,sec); 392 if (!other) 393 continue; 394 if (other->ceilingheight < height) 395 height = other->ceilingheight; 396 } 397 return height; 398 } 399 400 /*================================================================== */ 401 /* */ 402 /* FIND HIGHEST CEILING IN THE SURROUNDING SECTORS */ 403 /* */ 404 /*================================================================== */ 405 fixed_t P_FindHighestCeilingSurrounding(sector_t *sec) // 8001FD08 406 { 407 int i; 408 line_t *check; 409 sector_t *other; 410 fixed_t height = 0; 411 412 for (i=0 ;i < sec->linecount ; i++) 413 { 414 check = sec->lines[i]; 415 other = getNextSector(check,sec); 416 if (!other) 417 continue; 418 if (other->ceilingheight > height) 419 height = other->ceilingheight; 420 } 421 return height; 422 } 423 424 /*================================================================== */ 425 /* */ 426 /* RETURN NEXT SECTOR # THAT LINE TAG REFERS TO */ 427 /* */ 428 /*================================================================== */ 429 int P_FindSectorFromLineTag(int tag,int start) // 8001FDA4 430 { 431 int i; 432 433 for (i=start+1;i<numsectors;i++) 434 if (sectors[i].tag == tag) 435 return i; 436 return -1; 437 } 438 439 /*================================================================== */ 440 /* */ 441 /* RETURN NEXT LIGHT # THAT LINE TAG REFERS TO */ 442 /* Exclusive Doom 64 */ 443 /* */ 444 /*================================================================== */ 445 int P_FindLightFromLightTag(int tag,int start) // 8001FE08 446 { 447 int i; 448 449 for (i=(start+256+1);i<numlights;i++) 450 if (lights[i].tag == tag) 451 return i; 452 return -1; 453 } 454 455 /*================================================================== */ 456 /* */ 457 /* RETURN TRUE OR FALSE */ 458 /* Exclusive Doom 64 */ 459 /* */ 460 /*================================================================== */ 461 boolean P_ActivateLineByTag(int tag,mobj_t *thing) // 8001FE64 462 { 463 int i; 464 line_t *li; 465 466 li = lines; 467 for (i=0;i<numlines;i++,li++) 468 { 469 if (li->tag == tag) 470 return P_UseSpecialLine(li, thing); 471 } 472 return false; 473 } 474 475 #if 0 476 /*================================================================== */ 477 /* */ 478 /* Find minimum light from an adjacent sector */ 479 /* */ 480 /*================================================================== */ 481 int P_FindMinSurroundingLight(sector_t *sector,int max)//L80026C10() 482 { 483 int i; 484 int min; 485 line_t *line; 486 sector_t *check; 487 488 min = max; 489 for (i=0 ; i < sector->linecount ; i++) 490 { 491 line = sector->lines[i]; 492 check = getNextSector(line,sector); 493 if (!check) 494 continue; 495 if (check->lightlevel < min) 496 min = check->lightlevel; 497 } 498 return min; 499 } 500 #endif // 0 501 502 /* 503 ============================================================================== 504 505 EVENTS 506 507 Events are operations triggered by using, crossing, or shooting special lines, or by timed thinkers 508 509 ============================================================================== 510 */ 511 512 /* 513 =============================================================================== 514 = 515 = P_UpdateSpecials 516 = 517 = Animate planes, scroll walls, etc 518 =============================================================================== 519 */ 520 521 #define SCROLLLIMIT (FRACUNIT*127) 522 523 void P_UpdateSpecials (void) // 8001FEC0 524 { 525 anim_t *anim; 526 line_t *line; 527 sector_t *sector; 528 fixed_t speed; 529 int i; 530 int neg; 531 532 /* */ 533 /* ANIMATE FLATS AND TEXTURES GLOBALY */ 534 /* */ 535 for (anim = anims ; anim < lastanim ; anim++) 536 { 537 anim->delaycnt--; 538 if ((anim->delaycnt <= 0) && !(gametic & anim->tics)) 539 { 540 anim->current += anim->frame; 541 542 if ((anim->current < anim->picstart) || (anim->picend < anim->current)) 543 { 544 neg = -anim->frame; 545 546 if (anim->isreverse) 547 { 548 anim->frame = neg; 549 anim->current += neg; 550 551 if (anim->delay == 0) 552 anim->current += neg + neg; 553 } 554 else 555 { 556 anim->current = anim->picstart; 557 } 558 559 anim->delaycnt = anim->delay; 560 } 561 562 textures[anim->basepic] = anim->current; 563 } 564 } 565 566 /* */ 567 /* ANIMATE LINE SPECIALS */ 568 /* */ 569 for (i = 0; i < numlinespecials; i++) 570 { 571 line = linespeciallist[i]; 572 573 if(line->flags & ML_SCROLLRIGHT) 574 { 575 sides[line->sidenum[0]].textureoffset += FRACUNIT; 576 sides[line->sidenum[0]].textureoffset &= SCROLLLIMIT; 577 } 578 else if(line->flags & ML_SCROLLLEFT) 579 { 580 sides[line->sidenum[0]].textureoffset -= FRACUNIT; 581 sides[line->sidenum[0]].textureoffset &= SCROLLLIMIT; 582 } 583 584 if(line->flags & ML_SCROLLUP) 585 { 586 sides[line->sidenum[0]].rowoffset += FRACUNIT; 587 sides[line->sidenum[0]].rowoffset &= SCROLLLIMIT; 588 } 589 else if(line->flags & ML_SCROLLDOWN) 590 { 591 sides[line->sidenum[0]].rowoffset -= FRACUNIT; 592 sides[line->sidenum[0]].rowoffset &= SCROLLLIMIT; 593 } 594 } 595 596 /* */ 597 /* ANIMATE SECTOR SPECIALS */ 598 /* */ 599 600 scrollfrac = (scrollfrac + (FRACUNIT / 2)); 601 602 for (i = 0; i < numsectorspecials; i++) 603 { 604 sector = sectorspeciallist[i]; 605 606 if(sector->flags & MS_SCROLLFAST) 607 speed = 3*FRACUNIT; 608 else 609 speed = FRACUNIT; 610 611 if(sector->flags & MS_SCROLLLEFT) 612 { 613 sector->xoffset += speed; 614 } 615 else if(sector->flags & MS_SCROLLRIGHT) 616 { 617 sector->xoffset -= speed; 618 } 619 620 if(sector->flags & MS_SCROLLUP) 621 { 622 sector->yoffset -= speed; 623 } 624 else if(sector->flags & MS_SCROLLDOWN) 625 { 626 sector->yoffset += speed; 627 } 628 } 629 630 /* */ 631 /* DO BUTTONS */ 632 /* */ 633 for (i = 0; i < MAXBUTTONS; i++) 634 { 635 if (buttonlist[i].btimer > 0) 636 { 637 buttonlist[i].btimer -= vblsinframe[0]; 638 639 if (buttonlist[i].btimer <= 0) 640 { 641 switch (buttonlist[i].where) 642 { 643 case top: 644 buttonlist[i].side->toptexture = buttonlist[i].btexture; 645 break; 646 case middle: 647 buttonlist[i].side->midtexture = buttonlist[i].btexture; 648 break; 649 case bottom: 650 buttonlist[i].side->bottomtexture = buttonlist[i].btexture; 651 break; 652 } 653 S_StartSound((mobj_t *)buttonlist[i].soundorg, sfx_switch1); 654 D_memset(&buttonlist[i], 0, sizeof(button_t)); // ? Doom 64 elimina esta linea 655 } 656 } 657 } 658 } 659 660 /* 661 ============================================================================== 662 663 UTILITIES 664 665 ============================================================================== 666 */ 667 668 /* */ 669 /* Will return a side_t* given the number of the current sector, */ 670 /* the line number, and the side (0/1) that you want. */ 671 /* */ 672 side_t *getSide(int currentSector,int line, int side) // 8002026C 673 { 674 return &sides[ (sectors[currentSector].lines[line])->sidenum[side] ]; 675 } 676 677 /* */ 678 /* Will return a sector_t* given the number of the current sector, */ 679 /* the line number and the side (0/1) that you want. */ 680 /* */ 681 sector_t *getSector(int currentSector,int line,int side) // 800202BC 682 { 683 return sides[ (sectors[currentSector].lines[line])->sidenum[side] ].sector; 684 } 685 686 /* */ 687 /* Given the sector number and the line number, will tell you whether */ 688 /* the line is two-sided or not. */ 689 /* */ 690 int twoSided(int sector,int line) // 80020314 691 { 692 return (sectors[sector].lines[line])->flags & ML_TWOSIDED; 693 } 694 695 /* 696 ============================================================================== 697 698 EVENTS 699 700 Events are operations triggered by using, crossing, or shooting special lines, or by timed thinkers 701 702 ============================================================================== 703 */ 704 705 void P_AddSectorSpecial(sector_t* sector) // 80020354 706 { 707 708 if((sector->flags & MS_SYNCSPECIALS) && (sector->special)) 709 { 710 P_CombineLightSpecials(sector); 711 return; 712 } 713 714 switch(sector->special) 715 { 716 case 0: 717 sector->lightlevel = 0; 718 break; 719 720 case 1: 721 /* FLICKERING LIGHTS */ 722 P_SpawnLightFlash(sector); 723 break; 724 725 case 2: 726 /* STROBE FAST */ 727 P_SpawnStrobeFlash(sector, FASTDARK); 728 break; 729 730 case 3: 731 /* STROBE SLOW */ 732 P_SpawnStrobeFlash(sector, SLOWDARK); 733 break; 734 735 case 8: 736 /* GLOWING LIGHT */ 737 P_SpawnGlowingLight(sector, PULSENORMAL); 738 break; 739 740 case 9: 741 P_SpawnGlowingLight(sector, PULSESLOW); 742 break; 743 744 case 11: 745 P_SpawnGlowingLight(sector, PULSERANDOM); 746 break; 747 748 case 17: 749 P_SpawnFireFlicker(sector); 750 break; 751 752 case 202: 753 P_SpawnStrobeAltFlash(sector, 3); 754 break; 755 756 case 204: 757 P_SpawnStrobeFlash(sector, 7); 758 break; 759 760 case 205: 761 P_SpawnSequenceLight(sector, true); 762 break; 763 764 case 206: 765 P_SpawnStrobeFlash(sector, 90); 766 break; 767 768 case 208: 769 P_SpawnStrobeAltFlash(sector, 6); 770 break; 771 772 case 666: 773 break; 774 } 775 } 776 777 /* 778 ============================================================================== 779 = 780 = P_UseSpecialLine 781 = 782 = Called when a thing uses a special line 783 = Only the front sides of lines are usable 784 =============================================================================== 785 */ 786 787 boolean P_UseSpecialLine (line_t *line, mobj_t *thing) // 800204BC 788 { 789 player_t *player; 790 boolean ok; 791 int actionType; 792 793 actionType = SPECIALMASK(line->special); 794 795 if(actionType == 0) 796 return false; 797 798 799 player = thing->player; 800 801 /* */ 802 /* Switches that other things can activate */ 803 /* */ 804 if (!player) 805 { 806 /* Missiles should NOT trigger specials... */ 807 if(thing->flags & MF_MISSILE) 808 return false; 809 810 if(!(line->flags & ML_THINGTRIGGER)) 811 { 812 /* never open secret doors */ 813 if (line->flags & ML_SECRET) 814 return false; 815 816 /* never allow a non-player mobj to use lines with these useflags */ 817 if (line->special & (MLU_BLUE|MLU_YELLOW|MLU_RED)) 818 return false; 819 820 /* 821 actionType == 1 // MANUAL DOOR RAISE 822 actionType == 2 // OPEN DOOR IMPACT 823 actionType == 4 // RAISE DOOR 824 actionType == 10 // PLAT DOWN-WAIT-UP-STAY TRIGGER 825 actionType == 39 // TELEPORT TRIGGER 826 actionType == 125 // TELEPORT MONSTERONLY TRIGGER 827 */ 828 829 if (!((line->special & MLU_USE && actionType == 1) || 830 (line->special & MLU_CROSS &&(actionType == 4 || actionType == 10 || actionType == 39 || actionType == 125)) || 831 (line->special & MLU_SHOOT && actionType == 2))) 832 return false; 833 } 834 } 835 else 836 { 837 if(line->special & MLU_BLUE) /* Blue Card Lock */ 838 { 839 if(!player->cards[it_bluecard] && !player->cards[it_blueskull]) 840 { 841 player->message = "You need a blue key."; 842 player->messagetic = MSGTICS; 843 S_StartSound(thing, sfx_oof); 844 845 if (player == &players[0]) 846 tryopen[MapBlueKeyType] = true; 847 848 return true; 849 } 850 } 851 852 if(line->special & MLU_YELLOW) /* Yellow Card Lock */ 853 { 854 if(!player->cards[it_yellowcard] && !player->cards[it_yellowskull]) 855 { 856 player->message = "You need a yellow key."; 857 player->messagetic = MSGTICS; 858 S_StartSound(thing, sfx_oof); 859 860 if (player == &players[0]) 861 tryopen[MapYellowKeyType] = true; 862 863 return true; 864 } 865 } 866 867 if(line->special & MLU_RED) /* Red Card Lock */ 868 { 869 if(!player->cards[it_redcard] && !player->cards[it_redskull]) 870 { 871 player->message = "You need a red key."; 872 player->messagetic = MSGTICS; 873 S_StartSound(thing, sfx_oof); // ?? line missing on Doom64 874 875 if (player == &players[0]) 876 tryopen[MapRedKeyType] = true; 877 878 return true; 879 } 880 } 881 882 /* 883 actionType == 90 // ARTIFACT SWITCH 1 884 actionType == 91 // ARTIFACT SWITCH 2 885 actionType == 92 // ARTIFACT SWITCH 3 886 */ 887 888 if ((actionType == 90 || actionType == 91 || actionType == 92) && 889 !((player->artifacts & 1) << ((actionType + 6) & 0x1f))) 890 { 891 player->message = "You lack the ability to activate it."; 892 player->messagetic = MSGTICS; 893 S_StartSound(thing, sfx_oof); 894 895 return false; 896 } 897 } 898 899 if(actionType >= 256) 900 return P_StartMacro(actionType, line, thing); 901 902 ok = false; 903 904 /* */ 905 /* do something */ 906 /* */ 907 switch(SPECIALMASK(line->special)) 908 { 909 case 1: /* Vertical Door */ 910 case 31: /* Manual Door Open */ 911 case 117: /* Blazing Door Raise */ 912 case 118: /* Blazing Door Open */ 913 EV_VerticalDoor(line, thing); 914 ok = true; 915 break; 916 case 2: /* Open Door */ 917 ok = EV_DoDoor(line, DoorOpen); 918 break; 919 case 3: /* Close Door */ 920 ok = EV_DoDoor(line, DoorClose); 921 break; 922 case 4: /* Raise Door */ 923 ok = EV_DoDoor(line, Normal); 924 break; 925 case 5: /* Raise Floor */ 926 ok = EV_DoFloor(line, raiseFloor, FLOORSPEED); 927 break; 928 case 6: /* Fast Ceiling Crush & Raise */ 929 ok = EV_DoCeiling(line, fastCrushAndRaise, CEILSPEED*2); 930 break; 931 case 8: /* Build Stairs */ 932 ok = EV_BuildStairs(line, build8); 933 break; 934 case 10: /* PlatDownWaitUp */ 935 ok = EV_DoPlat(line, downWaitUpStay, 0); 936 break; 937 case 16: /* Close Door 30 */ 938 ok = EV_DoDoor(line, Close30ThenOpen); 939 break; 940 case 17: /* Start Light Strobing */ 941 ok = EV_StartLightStrobing(line); 942 break; 943 case 19: /* Lower Floor */ 944 ok = EV_DoFloor(line, lowerFloor, FLOORSPEED); 945 break; 946 case 22: /* Raise floor to nearest height and change texture */ 947 ok = EV_DoPlat(line, raiseToNearestAndChange, 0); 948 break; 949 case 25: /* Ceiling Crush and Raise */ 950 ok = EV_DoCeiling(line, crushAndRaise, CEILSPEED); 951 break; 952 case 30: /* Raise floor to shortest texture height on either side of lines */ 953 ok = EV_DoFloor(line, raiseToTexture, FLOORSPEED); 954 break; 955 case 36: /* Lower Floor (TURBO) */ 956 ok = EV_DoFloor(line, turboLower, FLOORSPEED * 4); 957 break; 958 case 37: /* LowerAndChange */ 959 ok = EV_DoFloor(line, lowerAndChange, FLOORSPEED); 960 break; 961 case 38: /* Lower Floor To Lowest */ 962 ok = EV_DoFloor(line, lowerFloorToLowest, FLOORSPEED); 963 break; 964 case 39: /* TELEPORT! */ 965 EV_Teleport(line, thing); 966 ok = false; 967 break; 968 case 43: /* Lower Ceiling to Floor */ 969 ok = EV_DoCeiling(line, lowerToFloor, CEILSPEED); 970 break; 971 case 44: /* Ceiling Crush */ 972 ok = EV_DoCeiling(line, lowerAndCrush, CEILSPEED); 973 break; 974 case 52: /* EXIT! */ 975 P_ExitLevel();//G_ExitLevel 976 ok = true; 977 break; 978 case 53: /* Perpetual Platform Raise */ 979 ok = EV_DoPlat(line, perpetualRaise, 0); 980 break; 981 case 54: /* Platform Stop */ 982 ok = EV_StopPlat(line); 983 break; 984 case 56: /* Raise Floor Crush */ 985 ok = EV_DoFloor(line, raiseFloorCrush, FLOORSPEED); 986 break; 987 case 57: /* Ceiling Crush Stop */ 988 ok = EV_CeilingCrushStop(line); 989 break; 990 case 58: /* Raise Floor 24 */ 991 ok = EV_DoFloor(line, raiseFloor24, FLOORSPEED); 992 break; 993 case 59: /* Raise Floor 24 And Change */ 994 ok = EV_DoFloor(line, raiseFloor24AndChange, FLOORSPEED); 995 break; 996 case 66: /* Raise Floor 24 and change texture */ 997 ok = EV_DoPlat(line, raiseAndChange, 24); 998 break; 999 case 67: /* Raise Floor 32 and change texture */ 1000 ok = EV_DoPlat(line, raiseAndChange, 32); 1001 break; 1002 case 90: /* Artifact Switch 1 */ 1003 case 91: /* Artifact Switch 2 */ 1004 case 92: /* Artifact Switch 3 */ 1005 ok = P_ActivateLineByTag(line->tag + 1, thing); 1006 break; 1007 case 93: /* Modify mobj flags */ 1008 ok = P_ModifyMobjFlags(line->tag, MF_NOINFIGHTING); 1009 break; 1010 case 94: /* Noise Alert */ 1011 ok = P_AlertTaggedMobj(line->tag, thing); 1012 break; 1013 case 100: /* Build Stairs Turbo 16 */ 1014 ok = EV_BuildStairs(line, turbo16); 1015 break; 1016 case 108: /* Blazing Door Raise (faster than TURBO!) */ 1017 ok = EV_DoDoor(line, BlazeRaise); 1018 break; 1019 case 109: /* Blazing Door Open (faster than TURBO!) */ 1020 ok = EV_DoDoor(line, BlazeOpen); 1021 break; 1022 case 110: /* Blazing Door Close (faster than TURBO!) */ 1023 ok = EV_DoDoor(line, BlazeClose); 1024 break; 1025 case 119: /* Raise floor to nearest surr. floor */ 1026 ok = EV_DoFloor(line, raiseFloorToNearest, FLOORSPEED); 1027 break; 1028 case 121: /* Blazing PlatDownWaitUpStay */ 1029 ok = EV_DoPlat(line, blazeDWUS, 0); 1030 break; 1031 case 122: /* PlatDownWaitUpStay */ 1032 ok = EV_DoPlat(line, upWaitDownStay, 0); 1033 break; 1034 case 123: /* Blazing PlatUpWaitDownStay */ 1035 ok = EV_DoPlat(line, blazeUWDS, 0); 1036 break; 1037 case 124: /* Secret EXIT */ 1038 P_SecretExitLevel(line->tag);//(G_SecretExitLevel) 1039 ok = true; 1040 break; 1041 case 125: /* TELEPORT MonsterONLY */ 1042 if (!thing->player) 1043 { 1044 EV_Teleport(line, thing); 1045 ok = false; 1046 } 1047 break; 1048 case 141: /* Silent Ceiling Crush & Raise (Demon Disposer)*/ 1049 ok = EV_DoCeiling(line, silentCrushAndRaise, CEILSPEED*2); 1050 break; 1051 case 200: /* Set Lookat Camera */ 1052 ok = P_SetAimCamera(line, true); 1053 break; 1054 case 201: /* Set Camera */ 1055 ok = P_SetAimCamera(line, false); 1056 break; 1057 case 202: /* Invoke Dart */ 1058 ok = EV_SpawnTrapMissile(line, thing, MT_PROJ_DART); 1059 break; 1060 case 203: /* Delay Thinker */ 1061 P_SpawnDelayTimer(line->tag, NULL); 1062 ok = true; 1063 break; 1064 case 204: /* Set global integer */ 1065 macrointeger = line->tag; 1066 ok = true; 1067 break; 1068 case 205: /* Modify sector color */ 1069 P_ModifySectorColor(line, LIGHT_FLOOR, macrointeger); 1070 ok = true; 1071 break; 1072 case 206: /* Modify sector color */ 1073 ok = P_ModifySectorColor(line, LIGHT_CEILING, macrointeger); 1074 break; 1075 case 207: /* Modify sector color */ 1076 ok = P_ModifySectorColor(line, LIGHT_THING, macrointeger); 1077 break; 1078 case 208: /* Modify sector color */ 1079 ok = P_ModifySectorColor(line, LIGHT_UPRWALL, macrointeger); 1080 break; 1081 case 209: /* Modify sector color */ 1082 ok = P_ModifySectorColor(line, LIGHT_LWRWALL, macrointeger); 1083 break; 1084 case 210: /* Modify sector ceiling height */ 1085 ok = EV_DoCeiling(line, customCeiling, CEILSPEED); 1086 break; 1087 case 212: /* Modify sector floor height */ 1088 ok = EV_DoFloor(line, customFloor, FLOORSPEED); 1089 break; 1090 case 214: /* Elevator Sector */ 1091 ok = EV_SplitSector(line, true); 1092 break; 1093 case 218: /* Modify Line Flags */ 1094 ok = P_ModifyLineFlags(line, macrointeger); 1095 break; 1096 case 219: /* Modify Line Texture */ 1097 ok = P_ModifyLineTexture(line, macrointeger); 1098 break; 1099 case 220: /* Modify Sector Flags */ 1100 ok = P_ModifySector(line, macrointeger, mods_flags); 1101 break; 1102 case 221: /* Modify Sector Specials */ 1103 ok = P_ModifySector(line, macrointeger, mods_special); 1104 break; 1105 case 222: /* Modify Sector Lights */ 1106 ok = P_ModifySector(line, macrointeger, mods_lights); 1107 break; 1108 case 223: /* Modify Sector Flats */ 1109 ok = P_ModifySector(line, macrointeger, mods_flats); 1110 break; 1111 case 224: /* Spawn Thing */ 1112 ok = EV_SpawnMobjTemplate(line->tag); 1113 break; 1114 case 225: /* Quake Effect */ 1115 P_SpawnQuake(line->tag); 1116 ok = true; 1117 break; 1118 case 226: /* Modify sector ceiling height */ 1119 ok = EV_DoCeiling(line, customCeiling, CEILSPEED * 4); 1120 break; 1121 case 227: /* Modify sector ceiling height */ 1122 ok = EV_DoCeiling(line, customCeiling, 4096 * FRACUNIT); 1123 break; 1124 case 228: /* Modify sector floor height */ 1125 ok = EV_DoFloor(line, customFloor, FLOORSPEED * 4); 1126 break; 1127 case 229: /* Modify sector floor height */ 1128 ok = EV_DoFloor(line, customFloor, 4096 * FRACUNIT); 1129 break; 1130 case 230: /* Modify Line Special */ 1131 ok = P_ModifyLineData(line, macrointeger); 1132 break; 1133 case 231: /* Invoke Revenant Missile */ 1134 ok = EV_SpawnTrapMissile(line, thing, MT_PROJ_TRACER); 1135 break; 1136 case 232: /* Fast Ceiling Crush & Raise */ 1137 ok = EV_DoCeiling(line, crushAndRaiseOnce, CEILSPEED * 4); 1138 break; 1139 case 233: /* Freeze Player */ 1140 thing->reactiontime = line->tag; 1141 ok = true; 1142 break; 1143 case 234: /* Change light by light tag */ 1144 ok = P_ChangeLightByTag(macrointeger, line->tag); 1145 break; 1146 case 235: /* Modify Light Data */ 1147 ok = P_DoSectorLightChange(macrointeger, line->tag); 1148 break; 1149 case 236: /* Modify platform */ 1150 ok = EV_DoPlat(line, customDownUp, 0); 1151 break; 1152 case 237: /* Modify platform */ 1153 ok = EV_DoPlat(line, customDownUpFast,0); 1154 break; 1155 case 238: /* Modify platform */ 1156 ok = EV_DoPlat(line,customUpDown,0); 1157 break; 1158 case 239: /* Modify platform */ 1159 ok = EV_DoPlat(line,customUpDownFast,0); 1160 break; 1161 case 240: /* Execute random line trigger */ 1162 ok = P_RandomLineTrigger(line, thing); 1163 break; 1164 case 241: /* Split Open Sector */ 1165 ok = EV_SplitSector(line, false); 1166 break; 1167 case 242: /* Fade Out Thing */ 1168 ok = EV_FadeOutMobj(line->tag); 1169 break; 1170 case 243: /* Move and Aim Camera */ 1171 P_SetMovingCamera(line); 1172 ok = false; 1173 break; 1174 case 244: /* Modify Sector Floor */ 1175 ok = EV_DoFloor(line, customFloorToHeight, 4096 * FRACUNIT); 1176 break; 1177 case 245: /* Modify Sector Ceiling */ 1178 ok = EV_DoCeiling(line, customCeilingToHeight, 4096 * FRACUNIT); 1179 break; 1180 case 246: /* Restart Macro at ID */ 1181 P_RestartMacro(line, macrointeger); 1182 ok = false; 1183 break; 1184 case 247: /* Modify Sector Floor */ 1185 ok = EV_DoFloor(line, customFloorToHeight, FLOORSPEED); 1186 break; 1187 case 248: /* Suspend a macro script */ 1188 ok = P_SuspendMacro(); 1189 break; 1190 case 249: /* Silent Teleport */ 1191 ok = EV_SilentTeleport(line, thing); 1192 break; 1193 case 250: /* Toggle macros on */ 1194 P_ToggleMacros(line->tag, true); 1195 ok = true; 1196 break; 1197 case 251: /* Toggle macros off */ 1198 P_ToggleMacros(line->tag, false); 1199 ok = true; 1200 break; 1201 case 252: /* Modify Sector Ceiling */ 1202 ok = EV_DoCeiling(line, customCeilingToHeight, CEILSPEED); 1203 break; 1204 case 253: /* Unlock Cheat Menu */ 1205 if(!demoplayback) { 1206 FeaturesUnlocked = true; 1207 } 1208 ok = true; 1209 break; 1210 case 254: /* D64 Map33 Logo */ 1211 Skyfadeback = true; 1212 break; 1213 1214 default: 1215 return false; 1216 } 1217 1218 if (ok) 1219 { 1220 if (line == ¯otempline) 1221 return true; 1222 1223 P_ChangeSwitchTexture(line, line->special & MLU_REPEAT); 1224 1225 if (line->special & MLU_REPEAT) 1226 return true; 1227 1228 line->special = 0; 1229 } 1230 1231 return true; 1232 } 1233 1234 #if 0 1235 1236 /*============================================================ */ 1237 /* */ 1238 /* Special Stuff that can't be categorized */ 1239 /* */ 1240 /*============================================================ */ 1241 int EV_DoDonut(line_t *line)//L8002796C() 1242 { 1243 sector_t *s1; 1244 sector_t *s2; 1245 sector_t *s3; 1246 int secnum; 1247 int rtn; 1248 int i; 1249 floormove_t *floor; 1250 1251 secnum = -1; 1252 rtn = 0; 1253 while ((secnum = P_FindSectorFromLineTag(line->tag,secnum)) >= 0) 1254 { 1255 s1 = §ors[secnum]; 1256 1257 /* ALREADY MOVING? IF SO, KEEP GOING... */ 1258 if (s1->specialdata) 1259 continue; 1260 1261 rtn = 1; 1262 s2 = getNextSector(s1->lines[0],s1); 1263 for (i = 0;i < s2->linecount;i++) 1264 { 1265 if (//(!s2->lines[i]->flags & ML_TWOSIDED) || 1266 (s2->lines[i]->backsector == s1)) 1267 continue; 1268 s3 = s2->lines[i]->backsector; 1269 1270 /* */ 1271 /* Spawn rising slime */ 1272 /* */ 1273 floor = Z_Malloc (sizeof(*floor), PU_LEVSPEC, 0); 1274 P_AddThinker (&floor->thinker); 1275 s2->specialdata = floor; 1276 floor->thinker.function = T_MoveFloor; 1277 floor->type = donutRaise; 1278 floor->crush = false; 1279 floor->direction = 1; 1280 floor->sector = s2; 1281 floor->speed = FLOORSPEED / 2; 1282 floor->texture = s3->floorpic; 1283 floor->newspecial = 0; 1284 floor->floordestheight = s3->floorheight; 1285 1286 /* */ 1287 /* Spawn lowering donut-hole */ 1288 /* */ 1289 floor = Z_Malloc (sizeof(*floor), PU_LEVSPEC, 0); 1290 P_AddThinker (&floor->thinker); 1291 s1->specialdata = floor; 1292 floor->thinker.function = T_MoveFloor; 1293 floor->type = lowerFloor; 1294 floor->crush = false; 1295 floor->direction = -1; 1296 floor->sector = s1; 1297 floor->speed = FLOORSPEED / 2; 1298 floor->floordestheight = s3->floorheight; 1299 break; 1300 } 1301 } 1302 return rtn; 1303 } 1304 1305 #endif // 0