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 = &sectors[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 = &sectors[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