p_floor.c (9930B)
1 /* 2 3 T_MovePlane 4 Literally the same guy who wrote the P_ShootSpecialLine function 5 6 */ 7 #include "z_zone.h" 8 #include "doomdef.h" 9 #include "p_local.h" 10 #include "s_sound.h" 11 #include "doomstat.h" 12 #include "r_state.h" 13 #include "sounds.h" 14 15 result_e 16 T_MovePlane(sector_t* sector, fixed_t speed, fixed_t dest, boolean crush, int floorOrCeiling, int direction) 17 { 18 boolean flag; 19 fixed_t lastpos; 20 switch (floorOrCeiling) { 21 case 0: 22 switch (direction) { 23 case -1: 24 if (sector->floorheight - speed < dest) { 25 lastpos = sector->floorheight; 26 sector->floorheight = dest; 27 flag = P_ChangeSector(sector,crush); 28 if (flag == true) { 29 sector->floorheight =lastpos; 30 P_ChangeSector(sector,crush); 31 } 32 return pastdest; 33 } else { 34 lastpos = sector->floorheight; 35 sector->floorheight -= speed; 36 flag = P_ChangeSector(sector,crush); 37 if (flag == true) { 38 sector->floorheight = lastpos; 39 P_ChangeSector(sector,crush); 40 return crushed; 41 } 42 } 43 break; 44 case 1: 45 if (sector->floorheight + speed > dest) { 46 lastpos = sector->floorheight; 47 sector->floorheight = dest; 48 flag = P_ChangeSector(sector,crush); 49 if (flag == true) { 50 sector->floorheight = lastpos; 51 P_ChangeSector(sector,crush); 52 } 53 return pastdest; 54 } else { 55 lastpos = sector->floorheight; 56 sector->floorheight += speed; 57 flag = P_ChangeSector(sector,crush); 58 if (flag == true) { 59 if (crush == true) 60 return crushed; 61 sector->floorheight = lastpos; 62 P_ChangeSector(sector, crush); 63 return crushed; 64 } 65 } 66 break; 67 } 68 break; 69 case 1: 70 switch (direction) { 71 case -1: 72 if (sector->ceilingheight - speed < dest) { 73 lastpos = sector->ceilingheight; 74 sector->ceilingheight = dest; 75 flag = P_ChangeSector(sector,crush); 76 if (flag == true) { 77 sector->ceilingheight = lastpos; 78 P_ChangeSector(sector,crush); 79 } 80 return pastdest; 81 } else { 82 lastpos = sector->ceilingheight; 83 sector->ceilingheight -= speed; 84 flag = P_ChangeSector(sector,crush); 85 if (flag == true) { 86 if (crush == true) 87 return crushed; 88 sector->ceilingheight = lastpos; 89 P_ChangeSector(sector,crush); 90 return crushed; 91 } 92 } 93 break; 94 case 1: 95 if (sector->ceilingheight + speed > dest) { 96 lastpos = sector->ceilingheight; 97 sector->ceilingheight = dest; 98 flag = P_ChangeSector(sector,crush); 99 if (flag == true) { 100 sector->ceilingheight = lastpos; 101 P_ChangeSector(sector,crush); 102 } 103 return pastdest; 104 } else { 105 lastpos = sector->ceilingheight; 106 sector->ceilingheight += speed; 107 flag = P_ChangeSector(sector,crush); 108 } 109 break; 110 } 111 break; 112 } 113 return ok; 114 } 115 116 117 118 119 120 void T_MoveFloor(floormove_t* floor) 121 { 122 result_e res; 123 124 res = T_MovePlane(floor->sector, 125 floor->speed, 126 floor->floordestheight, 127 floor->crush,0,floor->direction); 128 129 if (!(leveltime&7)) 130 S_StartSound((mobj_t *)&floor->sector->soundorg, 131 sfx_stnmov); 132 133 if (res == pastdest) 134 { 135 floor->sector->specialdata = NULL; 136 137 if (floor->direction == 1) 138 { 139 switch(floor->type) 140 { 141 case donutRaise: 142 floor->sector->special = floor->newspecial; 143 floor->sector->floorpic = floor->texture; 144 default: 145 break; 146 } 147 } 148 else if (floor->direction == -1) 149 { 150 switch(floor->type) 151 { 152 case lowerAndChange: 153 floor->sector->special = floor->newspecial; 154 floor->sector->floorpic = floor->texture; 155 default: 156 break; 157 } 158 } 159 P_RemoveThinker(&floor->thinker); 160 161 S_StartSound((mobj_t *)&floor->sector->soundorg, 162 sfx_pstop); 163 } 164 165 } 166 167 168 169 170 int 171 EV_DoFloor 172 ( line_t* line, 173 floor_e floortype ) 174 { 175 int secnum; 176 int rtn; 177 int i; 178 sector_t* sec; 179 floormove_t* floor; 180 181 secnum = -1; 182 rtn = 0; 183 while ((secnum = P_FindSectorFromLineTag(line,secnum)) >= 0) 184 { 185 sec = §ors[secnum]; 186 187 188 if (sec->specialdata) 189 continue; 190 191 192 rtn = 1; 193 floor = Z_Malloc (sizeof(*floor), PU_LEVSPEC, 0); 194 P_AddThinker (&floor->thinker); 195 sec->specialdata = floor; 196 floor->thinker.function.acp1 = (actionf_p1) T_MoveFloor; 197 floor->type = floortype; 198 floor->crush = false; 199 200 switch(floortype) 201 { 202 case lowerFloor: 203 floor->direction = -1; 204 floor->sector = sec; 205 floor->speed = FLOORSPEED; 206 floor->floordestheight = 207 P_FindHighestFloorSurrounding(sec); 208 break; 209 210 case lowerFloorToLowest: 211 floor->direction = -1; 212 floor->sector = sec; 213 floor->speed = FLOORSPEED; 214 floor->floordestheight = 215 P_FindLowestFloorSurrounding(sec); 216 break; 217 218 case turboLower: 219 floor->direction = -1; 220 floor->sector = sec; 221 floor->speed = FLOORSPEED * 4; 222 floor->floordestheight = 223 P_FindHighestFloorSurrounding(sec); 224 if (floor->floordestheight != sec->floorheight) 225 floor->floordestheight += 8*FRACUNIT; 226 break; 227 228 case raiseFloorCrush: 229 floor->crush = true; 230 case raiseFloor: 231 floor->direction = 1; 232 floor->sector = sec; 233 floor->speed = FLOORSPEED; 234 floor->floordestheight = 235 P_FindLowestCeilingSurrounding(sec); 236 if (floor->floordestheight > sec->ceilingheight) 237 floor->floordestheight = sec->ceilingheight; 238 floor->floordestheight -= (8*FRACUNIT)* 239 (floortype == raiseFloorCrush); 240 break; 241 242 case raiseFloorTurbo: 243 floor->direction = 1; 244 floor->sector = sec; 245 floor->speed = FLOORSPEED*4; 246 floor->floordestheight = 247 P_FindNextHighestFloor(sec,sec->floorheight); 248 break; 249 250 case raiseFloorToNearest: 251 floor->direction = 1; 252 floor->sector = sec; 253 floor->speed = FLOORSPEED; 254 floor->floordestheight = 255 P_FindNextHighestFloor(sec,sec->floorheight); 256 break; 257 258 case raiseFloor24: 259 floor->direction = 1; 260 floor->sector = sec; 261 floor->speed = FLOORSPEED; 262 floor->floordestheight = floor->sector->floorheight + 263 24 * FRACUNIT; 264 break; 265 case raiseFloor512: 266 floor->direction = 1; 267 floor->sector = sec; 268 floor->speed = FLOORSPEED; 269 floor->floordestheight = floor->sector->floorheight + 270 512 * FRACUNIT; 271 break; 272 273 case raiseFloor24AndChange: 274 floor->direction = 1; 275 floor->sector = sec; 276 floor->speed = FLOORSPEED; 277 floor->floordestheight = floor->sector->floorheight + 278 24 * FRACUNIT; 279 sec->floorpic = line->frontsector->floorpic; 280 sec->special = line->frontsector->special; 281 break; 282 283 case raiseToTexture: 284 { 285 int minsize = INT_MAX; 286 side_t* side; 287 288 floor->direction = 1; 289 floor->sector = sec; 290 floor->speed = FLOORSPEED; 291 for (i = 0; i < sec->linecount; i++) 292 { 293 if (twoSided (secnum, i) ) 294 { 295 side = getSide(secnum,i,0); 296 if (side->bottomtexture >= 0) 297 if (textureheight_g[side->bottomtexture] < 298 minsize) 299 minsize = 300 textureheight_g[side->bottomtexture]; 301 side = getSide(secnum,i,1); 302 if (side->bottomtexture >= 0) 303 if (textureheight_g[side->bottomtexture] < 304 minsize) 305 minsize = 306 textureheight_g[side->bottomtexture]; 307 } 308 } 309 floor->floordestheight = 310 floor->sector->floorheight + minsize; 311 } 312 break; 313 314 case lowerAndChange: 315 floor->direction = -1; 316 floor->sector = sec; 317 floor->speed = FLOORSPEED; 318 floor->floordestheight = 319 P_FindLowestFloorSurrounding(sec); 320 floor->texture = sec->floorpic; 321 322 for (i = 0; i < sec->linecount; i++) 323 { 324 if ( twoSided(secnum, i) ) 325 { 326 if (getSide(secnum,i,0)->sector-sectors == secnum) 327 { 328 sec = getSector(secnum,i,1); 329 330 if (sec->floorheight == floor->floordestheight) 331 { 332 floor->texture = sec->floorpic; 333 floor->newspecial = sec->special; 334 break; 335 } 336 } 337 else 338 { 339 sec = getSector(secnum,i,0); 340 341 if (sec->floorheight == floor->floordestheight) 342 { 343 floor->texture = sec->floorpic; 344 floor->newspecial = sec->special; 345 break; 346 } 347 } 348 } 349 } 350 default: 351 break; 352 } 353 } 354 return rtn; 355 } 356 357 int 358 EV_BuildStairs(line_t* line, stair_e type) 359 { 360 int secnum, height, i, newsecnum, texture, ok, rtn; 361 sector_t* sec, *tsec; 362 floormove_t* floor; 363 fixed_t stairsize, speed; 364 365 secnum = -1; 366 rtn = 0; 367 while ((secnum = P_FindSectorFromLineTag(line,secnum)) >= 0) { 368 sec = §ors[secnum]; 369 if (sec->specialdata) 370 continue; 371 rtn = 1; 372 floor = Z_Malloc(sizeof(*floor), PU_LEVSPEC, 0); 373 P_AddThinker (&floor->thinker); 374 sec->specialdata = floor; 375 floor->thinker.function.acp1 = (actionf_p1)T_MoveFloor; 376 floor->direction = 1; 377 floor->sector = sec; 378 switch (type) { 379 case build8: 380 speed = FLOORSPEED/4; 381 stairsize = 8*FRACUNIT; 382 break; 383 case turbo16: 384 default: 385 speed = FLOORSPEED*4; 386 stairsize = 16*FRACUNIT; 387 break; 388 } 389 floor->speed = speed; 390 height = sec->floorheight + stairsize; 391 floor->floordestheight = height; 392 texture = sec->floorpic; 393 do { 394 ok = 0; 395 for (i = 0; i < sec->linecount; ++i) { 396 if (!((sec->lines[i])->flags & ML_TWOSIDED)) 397 continue; 398 tsec = (sec->lines[i])->frontsector; 399 newsecnum = tsec-sectors; 400 if (secnum != newsecnum) 401 continue; 402 tsec = (sec->lines[i])->backsector; 403 newsecnum = tsec - sectors; 404 if (tsec->floorpic != texture) 405 continue; 406 height += stairsize; 407 if (tsec->specialdata) 408 continue; 409 sec = tsec; 410 secnum = newsecnum; 411 floor = Z_Malloc(sizeof(*floor), PU_LEVSPEC, 0); 412 P_AddThinker(&floor->thinker); 413 sec->specialdata = floor; 414 floor->thinker.function.acp1 = (actionf_p1) T_MoveFloor; 415 floor->direction = 1; 416 floor->sector = sec; 417 floor->speed = speed; 418 floor->floordestheight = height; 419 ok = 1; 420 break; 421 } 422 } while (ok); 423 } 424 return rtn; 425 }