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