p_floor.c (15041B)
1 #include "doomdef.h" 2 #include "p_local.h" 3 4 /*================================================================== */ 5 /*================================================================== */ 6 /* */ 7 /* FLOORS */ 8 /* */ 9 /*================================================================== */ 10 /*================================================================== */ 11 12 13 14 /*================================================================== */ 15 /* */ 16 /* Move a plane (floor or ceiling) and check for crushing */ 17 /* */ 18 /*================================================================== */ 19 result_e T_MovePlane(sector_t *sector,fixed_t speed, 20 fixed_t dest,boolean crush,int floorOrCeiling,int direction) // 800136C0 21 { 22 boolean flag; 23 fixed_t lastpos; 24 result_e result; 25 26 result = ok; 27 28 switch(floorOrCeiling) 29 { 30 case 0: /* FLOOR */ 31 switch(direction) 32 { 33 case -1: /* DOWN */ 34 lastpos = sector->floorheight; 35 sector->floorheight -= speed; 36 if (sector->floorheight <= dest) 37 { 38 sector->floorheight = dest; 39 result = pastdest; 40 } 41 42 flag = P_ChangeSector(sector,crush); 43 if (flag != 0) 44 { 45 sector->floorheight = lastpos; 46 P_ChangeSector(sector,crush); 47 if (!crush) 48 result = stop; 49 else 50 result = crushed; 51 } 52 break; 53 54 case 1: /* UP */ 55 lastpos = sector->floorheight; 56 sector->floorheight += speed; 57 if (dest <= sector->floorheight) 58 { 59 sector->floorheight = dest; 60 result = pastdest; 61 } 62 63 flag = P_ChangeSector(sector,crush); 64 if (flag != 0) 65 { 66 sector->floorheight = lastpos; 67 P_ChangeSector(sector,crush); 68 if(!crush) 69 result = stop; 70 else 71 result = crushed; 72 } 73 break; 74 } 75 break; 76 77 case 1: /* CEILING */ 78 switch(direction) 79 { 80 case -1: /* DOWN */ 81 82 lastpos = sector->ceilingheight; 83 sector->ceilingheight -= speed; 84 if (sector->ceilingheight <= dest) 85 { 86 sector->ceilingheight = dest; 87 result = pastdest; 88 } 89 90 flag = P_ChangeSector(sector,crush); 91 if (flag != 0) 92 { 93 if(crush == true && result == ok) 94 { 95 result = crushed; 96 } 97 else 98 { 99 sector->ceilingheight = lastpos; 100 P_ChangeSector(sector,crush); 101 if (result == ok) 102 result = crushed; 103 } 104 } 105 break; 106 107 case 1: /* UP */ 108 109 lastpos = sector->ceilingheight; 110 sector->ceilingheight += speed; 111 if (dest <= sector->ceilingheight) 112 { 113 sector->ceilingheight = dest; 114 result = pastdest; 115 } 116 117 flag = P_ChangeSector(sector,false); 118 if ((flag != 0) && (result != 0)) 119 { 120 sector->ceilingheight = lastpos; 121 P_ChangeSector(sector,false); 122 } 123 break; 124 } 125 break; 126 127 } 128 129 return result; 130 } 131 132 /*================================================================== */ 133 /* */ 134 /* MOVE A FLOOR TO IT'S DESTINATION (UP OR DOWN) */ 135 /* */ 136 /*================================================================== */ 137 void T_MoveFloor(floormove_t *floor) // 80013920 138 { 139 result_e res; 140 141 res = T_MovePlane(floor->sector,floor->speed, 142 floor->floordestheight,floor->crush,0,floor->direction); 143 144 if (!floor->instant) 145 { 146 if (!(gametic&3)) 147 { 148 S_StartSound((mobj_t *)&floor->sector->soundorg,sfx_secmove);//sfx_stnmov 149 } 150 } 151 152 if (res == pastdest) 153 { 154 floor->sector->specialdata = NULL; 155 if (floor->direction == -1) 156 { 157 switch(floor->type) 158 { 159 case lowerAndChange: 160 floor->sector->special = floor->newspecial; 161 floor->sector->floorpic = floor->texture; 162 default: 163 break; 164 } 165 } 166 P_RemoveThinker(&floor->thinker); 167 } 168 169 } 170 171 /*================================================================== */ 172 /* */ 173 /* HANDLE FLOOR TYPES */ 174 /* */ 175 /*================================================================== */ 176 int EV_DoFloor(line_t *line,floor_e floortype,fixed_t speed) // 800139FC 177 { 178 int secnum; 179 int rtn; 180 int i; 181 sector_t *sec; 182 floormove_t *floor; 183 184 secnum = -1; 185 rtn = 0; 186 while ((secnum = P_FindSectorFromLineTag(line->tag,secnum)) >= 0) 187 { 188 sec = §ors[secnum]; 189 190 /* ALREADY MOVING? IF SO, KEEP GOING... */ 191 if (sec->specialdata) 192 continue; 193 194 /* */ 195 /* new floor thinker */ 196 /* */ 197 rtn = 1; 198 floor = Z_Malloc (sizeof(*floor), PU_LEVSPEC, 0); 199 P_AddThinker (&floor->thinker); 200 sec->specialdata = floor; 201 floor->thinker.function = T_MoveFloor; 202 floor->type = floortype; 203 floor->crush = false; 204 floor->sector = sec; 205 206 if (speed == (4096 * FRACUNIT)) 207 floor->instant = true; 208 else 209 floor->instant = false; 210 211 switch(floortype) 212 { 213 case lowerFloor: 214 floor->direction = -1; 215 floor->speed = speed; 216 floor->floordestheight = P_FindHighestFloorSurrounding(sec); 217 break; 218 case lowerFloorToLowest: 219 floor->direction = -1; 220 floor->speed = speed; 221 floor->floordestheight = P_FindLowestFloorSurrounding(sec); 222 break; 223 case turboLower: 224 floor->direction = -1; 225 floor->speed = speed; 226 floor->floordestheight = P_FindHighestFloorSurrounding(sec); 227 if (floor->floordestheight != sec->floorheight) 228 floor->floordestheight += 8 * FRACUNIT; 229 break; 230 case raiseFloorCrush: 231 floor->crush = true; 232 case raiseFloor: 233 floor->direction = 1; 234 floor->speed = speed; 235 floor->floordestheight = P_FindLowestCeilingSurrounding(sec); 236 if (floor->floordestheight > sec->ceilingheight) 237 floor->floordestheight = sec->ceilingheight; 238 239 if (floortype == raiseFloorCrush) 240 floor->floordestheight -= (8 * FRACUNIT); 241 break; 242 case raiseFloorToNearest: 243 floor->direction = 1; 244 floor->speed = speed; 245 floor->floordestheight = P_FindNextHighestFloor(sec,sec->floorheight); 246 break; 247 case raiseFloor24: 248 floor->direction = 1; 249 floor->speed = speed; 250 floor->floordestheight = floor->sector->floorheight + 24 * FRACUNIT; 251 break; 252 case raiseFloor24AndChange: 253 floor->direction = 1; 254 floor->speed = speed; 255 floor->floordestheight = floor->sector->floorheight + 24 * FRACUNIT; 256 sec->floorpic = line->frontsector->floorpic; 257 sec->special = line->frontsector->special; 258 break; 259 case customFloor: 260 floor->direction = (macrointeger > 0) ? 1 : -1; 261 floor->speed = speed; 262 floor->floordestheight = floor->sector->floorheight + (macrointeger * FRACUNIT); 263 break; 264 case customFloorToHeight: 265 floor->direction = ((macrointeger*FRACUNIT) > (floor->sector->floorheight)) ? 1 : -1; 266 floor->speed = speed; 267 floor->floordestheight = (macrointeger * FRACUNIT); 268 break; 269 #if 0 //Missing on D64 270 case raiseToTexture: 271 { 272 int minsize = MAXINT; 273 side_t *side; 274 275 floor->direction = 1; 276 floor->speed = speed; 277 for (i = 0; i < sec->linecount; i++) 278 { 279 if (twoSided (secnum, i) ) 280 { 281 side = getSide(secnum,i,0); 282 if (side->bottomtexture >= 0) 283 { 284 if ((textures[side->bottomtexture].h << FRACBITS) < minsize) 285 minsize = (textures[side->bottomtexture].h << FRACBITS); 286 } 287 side = getSide(secnum,i,1); 288 if (side->bottomtexture >= 0) 289 { 290 if ((textures[side->bottomtexture].h << FRACBITS) < minsize) 291 minsize = (textures[side->bottomtexture].h << FRACBITS); 292 } 293 } 294 } 295 floor->floordestheight = floor->sector->floorheight + minsize; 296 } 297 break; 298 #endif // 0 299 case lowerAndChange: 300 floor->direction = -1; 301 floor->speed = speed; 302 floor->floordestheight = P_FindLowestFloorSurrounding(sec); 303 floor->texture = sec->floorpic; 304 for (i = 0; i < sec->linecount; i++) 305 { 306 if ( twoSided(secnum, i) ) 307 { 308 if (getSide(secnum,i,0)->sector-sectors == secnum) 309 { 310 sec = getSector(secnum,i,1); 311 floor->texture = sec->floorpic; 312 floor->newspecial = sec->special; 313 break; 314 } 315 else 316 { 317 sec = getSector(secnum,i,0); 318 floor->texture = sec->floorpic; 319 floor->newspecial = sec->special; 320 break; 321 } 322 } 323 } 324 default: 325 break; 326 } 327 } 328 return rtn; 329 } 330 331 /*================================================================== */ 332 /* */ 333 /* BUILD A STAIRCASE! */ 334 /* */ 335 /*================================================================== */ 336 int EV_BuildStairs(line_t *line, stair_e type) // 80013DB0 337 { 338 int secnum; 339 int height; 340 int i; 341 int newsecnum; 342 int texture; 343 int ok; 344 int rtn; 345 fixed_t stairsize; 346 fixed_t speed; 347 sector_t *sec, *tsec; 348 floormove_t *floor; 349 350 351 secnum = -1; 352 rtn = 0; 353 while ((secnum = P_FindSectorFromLineTag(line->tag,secnum)) >= 0) 354 { 355 sec = §ors[secnum]; 356 357 /* ALREADY MOVING? IF SO, KEEP GOING... */ 358 if (sec->specialdata) 359 continue; 360 361 /* */ 362 /* new floor thinker */ 363 /* */ 364 rtn = 1; 365 floor = Z_Malloc (sizeof(*floor), PU_LEVSPEC, 0); 366 P_AddThinker (&floor->thinker); 367 sec->specialdata = floor; 368 floor->thinker.function = T_MoveFloor; 369 floor->direction = 1; 370 floor->sector = sec; 371 floor->instant = false; 372 373 switch (type) 374 { 375 case build8: 376 speed = FLOORSPEED / 2; 377 stairsize = 8 * FRACUNIT; 378 break; 379 case turbo16: 380 speed = FLOORSPEED * 2; 381 stairsize = 16 * FRACUNIT; 382 break; 383 } 384 385 floor->speed = speed; 386 height = sec->floorheight + stairsize; 387 floor->floordestheight = height; 388 389 texture = sec->floorpic; 390 391 /* */ 392 /* Find next sector to raise */ 393 /* 1. Find 2-sided line with same sector side[0] */ 394 /* 2. Other side is the next sector to raise */ 395 /* */ 396 do 397 { 398 ok = 0; 399 for (i = 0;i < sec->linecount;i++) 400 { 401 if ( !((sec->lines[i])->flags & ML_TWOSIDED) ) 402 continue; 403 404 tsec = (sec->lines[i])->frontsector; 405 newsecnum = tsec-sectors; 406 if (secnum != newsecnum) 407 continue; 408 409 tsec = (sec->lines[i])->backsector; 410 newsecnum = tsec - sectors; 411 if (tsec->floorpic != texture) 412 continue; 413 414 height += stairsize; 415 if (tsec->specialdata) 416 continue; 417 418 sec = tsec; 419 secnum = newsecnum; 420 floor = Z_Malloc (sizeof(*floor), PU_LEVSPEC, 0); 421 P_AddThinker (&floor->thinker); 422 sec->specialdata = floor; 423 floor->thinker.function = T_MoveFloor; 424 floor->direction = 1; 425 floor->sector = sec; 426 floor->speed = speed; 427 floor->floordestheight = height; 428 floor->instant = false; 429 ok = 1; 430 break; 431 } 432 } while(ok); 433 secnum = -1; 434 } 435 return rtn; 436 } 437 438 /*================================================================== */ 439 /* */ 440 /* T_MoveSplitPlane */ 441 /* */ 442 /*================================================================== */ 443 444 void T_MoveSplitPlane(splitmove_t *split) // 80014098 445 { 446 sector_t *sector; 447 fixed_t lastceilpos; 448 fixed_t lastflrpos; 449 boolean cdone; 450 boolean fdone; 451 452 sector = split->sector; 453 lastceilpos = sector->ceilingheight; 454 lastflrpos = sector->floorheight; 455 cdone = false; 456 fdone = false; 457 458 if (split->ceildir == -1) 459 { 460 sector->ceilingheight -= (2*FRACUNIT); 461 if (sector->ceilingheight <= split->ceildest) 462 { 463 sector->ceilingheight = split->ceildest; 464 cdone = true; 465 } 466 } 467 else if (split->ceildir == 1) 468 { 469 sector->ceilingheight += (2*FRACUNIT); 470 if(sector->ceilingheight >= split->ceildest) 471 { 472 sector->ceilingheight = split->ceildest; 473 cdone = true; 474 } 475 } 476 477 if (split->flrdir == -1) 478 { 479 sector->floorheight -= (2*FRACUNIT); 480 if(sector->floorheight <= split->flrdest) 481 { 482 sector->floorheight = split->flrdest; 483 fdone = true; 484 } 485 } 486 else if (split->flrdir == 1) 487 { 488 sector->floorheight += (2*FRACUNIT); 489 if(sector->floorheight >= split->flrdest) 490 { 491 sector->floorheight = split->flrdest; 492 fdone = true; 493 } 494 } 495 496 if(!P_ChangeSector(sector, false)) 497 { 498 if(!cdone || !fdone) 499 return; 500 501 P_RemoveThinker(&split->thinker); 502 split->sector->specialdata = NULL; 503 } 504 else 505 { 506 sector->floorheight = lastflrpos; 507 sector->ceilingheight = lastceilpos; 508 P_ChangeSector(sector,false); 509 } 510 } 511 512 /*================================================================== */ 513 /* */ 514 /* EV_SplitSector */ 515 /* */ 516 /*================================================================== */ 517 518 int EV_SplitSector(line_t *line, boolean sync) // 80014234 519 { 520 int secnum; 521 int rtn; 522 sector_t *sec; 523 splitmove_t *split; 524 525 secnum = -1; 526 rtn = 0; 527 528 while((secnum = P_FindSectorFromLineTag(line->tag, secnum)) >= 0) 529 { 530 sec = §ors[secnum]; 531 532 /* ALREADY MOVING? IF SO, KEEP GOING... */ 533 if (sec->specialdata) 534 continue; 535 536 /* */ 537 /* new split thinker */ 538 /* */ 539 rtn = 1; 540 split = Z_Malloc (sizeof(*split), PU_LEVSPEC, 0); 541 P_AddThinker (&split->thinker); 542 sec->specialdata = split; 543 split->thinker.function = T_MoveSplitPlane; 544 split->sector = sec; 545 546 split->ceildest = sec->ceilingheight + (macrointeger * FRACUNIT); 547 548 if(sync) 549 { 550 split->flrdest = sec->floorheight + (macrointeger * FRACUNIT); 551 552 if (macrointeger >= 0) 553 { 554 split->ceildir = 1; 555 split->flrdir = 1; 556 } 557 else 558 { 559 split->ceildir = -1; 560 split->flrdir = -1; 561 } 562 } 563 else 564 { 565 split->flrdest = sec->floorheight - (macrointeger * FRACUNIT); 566 567 if (macrointeger >= 0) 568 { 569 split->ceildir = 1; 570 split->flrdir = -1; 571 } 572 else 573 { 574 split->ceildir = -1; 575 split->flrdir = 1; 576 } 577 } 578 } 579 580 return rtn; 581 }