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