Subversion Repositories Kolibri OS

Rev

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