]> git.lizzy.rs Git - plan9front.git/blob - sys/src/games/doom/p_floor.c
games/doom: fix unterminated comment causing sound bugs (from qu7uux)
[plan9front.git] / sys / src / games / doom / p_floor.c
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                 sector->ceilingheight += speed;
185                 P_ChangeSector(sector,crush);
186             }
187             break;
188         }
189         break;
190                 
191     }
192     return ok;
193 }
194
195
196 //
197 // MOVE A FLOOR TO IT'S DESTINATION (UP OR DOWN)
198 //
199 void T_MoveFloor(void* _floor, void*)
200 {
201     floormove_t *floor = (floormove_t*)_floor;
202     result_e    res;
203         
204     res = T_MovePlane(floor->sector,
205                       floor->speed,
206                       floor->floordestheight,
207                       floor->crush,0,floor->direction);
208     
209     if (!(leveltime&7))
210         S_StartSound((mobj_t *)&floor->sector->soundorg,
211                      sfx_stnmov);
212     
213     if (res == pastdest)
214     {
215         floor->sector->specialdata = NULL;
216
217         if (floor->direction == 1)
218         {
219             switch(floor->type)
220             {
221               case donutRaise:
222                 floor->sector->special = floor->newspecial;
223                 floor->sector->floorpic = floor->texture;
224               default:
225                 break;
226             }
227         }
228         else if (floor->direction == -1)
229         {
230             switch(floor->type)
231             {
232               case lowerAndChange:
233                 floor->sector->special = floor->newspecial;
234                 floor->sector->floorpic = floor->texture;
235               default:
236                 break;
237             }
238         }
239         P_RemoveThinker(&floor->thinker);
240
241         S_StartSound((mobj_t *)&floor->sector->soundorg,
242                      sfx_pstop);
243     }
244
245 }
246
247 //
248 // HANDLE FLOOR TYPES
249 //
250 int
251 EV_DoFloor
252 ( line_t*       line,
253   floor_e       floortype )
254 {
255     int                 secnum;
256     int                 rtn;
257     int                 i;
258     sector_t*           sec;
259     floormove_t*        floor;
260
261     secnum = -1;
262     rtn = 0;
263     while ((secnum = P_FindSectorFromLineTag(line,secnum)) >= 0)
264     {
265         sec = &sectors[secnum];
266                 
267         // ALREADY MOVING?  IF SO, KEEP GOING...
268         if (sec->specialdata)
269             continue;
270         
271         // new floor thinker
272         rtn = 1;
273         floor = Z_Malloc (sizeof(*floor), PU_LEVSPEC, 0);
274         P_AddThinker (&floor->thinker);
275         sec->specialdata = floor;
276         floor->thinker.function = T_MoveFloor;
277         floor->type = floortype;
278         floor->crush = false;
279
280         switch(floortype)
281         {
282           case lowerFloor:
283             floor->direction = -1;
284             floor->sector = sec;
285             floor->speed = FLOORSPEED;
286             floor->floordestheight = 
287                 P_FindHighestFloorSurrounding(sec);
288             break;
289
290           case lowerFloorToLowest:
291             floor->direction = -1;
292             floor->sector = sec;
293             floor->speed = FLOORSPEED;
294             floor->floordestheight = 
295                 P_FindLowestFloorSurrounding(sec);
296             break;
297
298           case turboLower:
299             floor->direction = -1;
300             floor->sector = sec;
301             floor->speed = FLOORSPEED * 4;
302             floor->floordestheight = 
303                 P_FindHighestFloorSurrounding(sec);
304             if (floor->floordestheight != sec->floorheight)
305                 floor->floordestheight += 8*FRACUNIT;
306             break;
307
308           case raiseFloorCrush:
309             floor->crush = true;
310           case raiseFloor:
311             floor->direction = 1;
312             floor->sector = sec;
313             floor->speed = FLOORSPEED;
314             floor->floordestheight = 
315                 P_FindLowestCeilingSurrounding(sec);
316             if (floor->floordestheight > sec->ceilingheight)
317                 floor->floordestheight = sec->ceilingheight;
318             floor->floordestheight -= (8*FRACUNIT)*
319                 (floortype == raiseFloorCrush);
320             break;
321
322           case raiseFloorTurbo:
323             floor->direction = 1;
324             floor->sector = sec;
325             floor->speed = FLOORSPEED*4;
326             floor->floordestheight = 
327                 P_FindNextHighestFloor(sec,sec->floorheight);
328             break;
329
330           case raiseFloorToNearest:
331             floor->direction = 1;
332             floor->sector = sec;
333             floor->speed = FLOORSPEED;
334             floor->floordestheight = 
335                 P_FindNextHighestFloor(sec,sec->floorheight);
336             break;
337
338           case raiseFloor24:
339             floor->direction = 1;
340             floor->sector = sec;
341             floor->speed = FLOORSPEED;
342             floor->floordestheight = floor->sector->floorheight +
343                 24 * FRACUNIT;
344             break;
345           case raiseFloor512:
346             floor->direction = 1;
347             floor->sector = sec;
348             floor->speed = FLOORSPEED;
349             floor->floordestheight = floor->sector->floorheight +
350                 512 * FRACUNIT;
351             break;
352
353           case raiseFloor24AndChange:
354             floor->direction = 1;
355             floor->sector = sec;
356             floor->speed = FLOORSPEED;
357             floor->floordestheight = floor->sector->floorheight +
358                 24 * FRACUNIT;
359             sec->floorpic = line->frontsector->floorpic;
360             sec->special = line->frontsector->special;
361             break;
362
363           case raiseToTexture:
364           {
365               int       minsize = MAXINT;
366               side_t*   side;
367                                 
368               floor->direction = 1;
369               floor->sector = sec;
370               floor->speed = FLOORSPEED;
371               for (i = 0; i < sec->linecount; i++)
372               {
373                   if (twoSided (secnum, i) )
374                   {
375                       side = getSide(secnum,i,0);
376                       if (side->bottomtexture >= 0)
377                           if (textureheight[side->bottomtexture] < 
378                               minsize)
379                               minsize = 
380                                   textureheight[side->bottomtexture];
381                       side = getSide(secnum,i,1);
382                       if (side->bottomtexture >= 0)
383                           if (textureheight[side->bottomtexture] < 
384                               minsize)
385                               minsize = 
386                                   textureheight[side->bottomtexture];
387                   }
388               }
389               floor->floordestheight =
390                   floor->sector->floorheight + minsize;
391           }
392           break;
393           
394           case lowerAndChange:
395             floor->direction = -1;
396             floor->sector = sec;
397             floor->speed = FLOORSPEED;
398             floor->floordestheight = 
399                 P_FindLowestFloorSurrounding(sec);
400             floor->texture = sec->floorpic;
401
402             for (i = 0; i < sec->linecount; i++)
403             {
404                 if ( twoSided(secnum, i) )
405                 {
406                     if (getSide(secnum,i,0)->sector-sectors == secnum)
407                     {
408                         sec = getSector(secnum,i,1);
409
410                         if (sec->floorheight == floor->floordestheight)
411                         {
412                             floor->texture = sec->floorpic;
413                             floor->newspecial = sec->special;
414                             break;
415                         }
416                     }
417                     else
418                     {
419                         sec = getSector(secnum,i,0);
420
421                         if (sec->floorheight == floor->floordestheight)
422                         {
423                             floor->texture = sec->floorpic;
424                             floor->newspecial = sec->special;
425                             break;
426                         }
427                     }
428                 }
429             }
430           default:
431             break;
432         }
433     }
434     return rtn;
435 }
436
437
438
439
440 //
441 // BUILD A STAIRCASE!
442 //
443 int
444 EV_BuildStairs
445 ( line_t*       line,
446   stair_e       type )
447 {
448     int                 secnum;
449     int                 height;
450     int                 i;
451     int                 newsecnum;
452     int                 texture;
453     int                 ok;
454     int                 rtn;
455     
456     sector_t*           sec;
457     sector_t*           tsec;
458
459     floormove_t*        floor;
460     
461     fixed_t             stairsize;
462     fixed_t             speed;
463
464     secnum = -1;
465     rtn = 0;
466     while ((secnum = P_FindSectorFromLineTag(line,secnum)) >= 0)
467     {
468         sec = &sectors[secnum];
469                 
470         // ALREADY MOVING?  IF SO, KEEP GOING...
471         if (sec->specialdata)
472             continue;
473         
474         // new floor thinker
475         rtn = 1;
476         floor = Z_Malloc (sizeof(*floor), PU_LEVSPEC, 0);
477         P_AddThinker (&floor->thinker);
478         sec->specialdata = floor;
479         floor->thinker.function = T_MoveFloor;
480         floor->direction = 1;
481         floor->sector = sec;
482         switch(type)
483         {
484           default:
485           case build8:
486             speed = FLOORSPEED/4;
487             stairsize = 8*FRACUNIT;
488             break;
489           case turbo16:
490             speed = FLOORSPEED*4;
491             stairsize = 16*FRACUNIT;
492             break;
493         }
494         floor->speed = speed;
495         height = sec->floorheight + stairsize;
496         floor->floordestheight = height;
497                 
498         texture = sec->floorpic;
499         
500         // Find next sector to raise
501         // 1.   Find 2-sided line with same sector side[0]
502         // 2.   Other side is the next sector to raise
503         do
504         {
505             ok = 0;
506             for (i = 0;i < sec->linecount;i++)
507             {
508                 if ( !((sec->lines[i])->flags & ML_TWOSIDED) )
509                     continue;
510                                         
511                 tsec = (sec->lines[i])->frontsector;
512                 newsecnum = tsec-sectors;
513                 
514                 if (secnum != newsecnum)
515                     continue;
516
517                 tsec = (sec->lines[i])->backsector;
518                 newsecnum = tsec - sectors;
519
520                 if (tsec->floorpic != texture)
521                     continue;
522                                         
523                 height += stairsize;
524
525                 if (tsec->specialdata)
526                     continue;
527                                         
528                 sec = tsec;
529                 secnum = newsecnum;
530                 floor = Z_Malloc (sizeof(*floor), PU_LEVSPEC, 0);
531
532                 P_AddThinker (&floor->thinker);
533
534                 sec->specialdata = floor;
535                 floor->thinker.function = T_MoveFloor;
536                 floor->direction = 1;
537                 floor->sector = sec;
538                 floor->speed = speed;
539                 floor->floordestheight = height;
540                 ok = 1;
541                 break;
542             }
543         } while(ok);
544     }
545     return rtn;
546 }
547