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