Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
8547 maxcodehac 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
//	Plats (i.e. elevator platforms) code, raising/lowering.
21
//
22
//-----------------------------------------------------------------------------
23
 
24
static const char
25
rcsid[] = "$Id: p_plats.c,v 1.5 1997/02/03 22:45:12 b1 Exp $";
26
 
27
 
28
#include "i_system.h"
29
#include "z_zone.h"
30
#include "m_random.h"
31
 
32
#include "doomdef.h"
33
#include "p_local.h"
34
 
35
#include "s_sound.h"
36
 
37
// State.
38
#include "doomstat.h"
39
#include "r_state.h"
40
 
41
// Data.
42
#include "sounds.h"
43
 
44
 
45
plat_t*		activeplats[MAXPLATS];
46
 
47
 
48
 
49
//
50
// Move a plat up and down
51
//
52
void T_PlatRaise(plat_t* plat)
53
{
54
    result_e	res;
55
 
56
    switch(plat->status)
57
    {
58
      case up:
59
	res = T_MovePlane(plat->sector,
60
			  plat->speed,
61
			  plat->high,
62
			  plat->crush,0,1);
63
 
64
	if (plat->type == raiseAndChange
65
	    || plat->type == raiseToNearestAndChange)
66
	{
67
	    if (!(leveltime&7))
68
		S_StartSound((mobj_t *)&plat->sector->soundorg,
69
			     sfx_stnmov);
70
	}
71
 
72
 
73
	if (res == crushed && (!plat->crush))
74
	{
75
	    plat->count = plat->wait;
76
	    plat->status = down;
77
	    S_StartSound((mobj_t *)&plat->sector->soundorg,
78
			 sfx_pstart);
79
	}
80
	else
81
	{
82
	    if (res == pastdest)
83
	    {
84
		plat->count = plat->wait;
85
		plat->status = waiting;
86
		S_StartSound((mobj_t *)&plat->sector->soundorg,
87
			     sfx_pstop);
88
 
89
		switch(plat->type)
90
		{
91
		  case blazeDWUS:
92
		  case downWaitUpStay:
93
		    P_RemoveActivePlat(plat);
94
		    break;
95
 
96
		  case raiseAndChange:
97
		  case raiseToNearestAndChange:
98
		    P_RemoveActivePlat(plat);
99
		    break;
100
 
101
		  default:
102
		    break;
103
		}
104
	    }
105
	}
106
	break;
107
 
108
      case	down:
109
	res = T_MovePlane(plat->sector,plat->speed,plat->low,false,0,-1);
110
 
111
	if (res == pastdest)
112
	{
113
	    plat->count = plat->wait;
114
	    plat->status = waiting;
115
	    S_StartSound((mobj_t *)&plat->sector->soundorg,sfx_pstop);
116
	}
117
	break;
118
 
119
      case	waiting:
120
	if (!--plat->count)
121
	{
122
	    if (plat->sector->floorheight == plat->low)
123
		plat->status = up;
124
	    else
125
		plat->status = down;
126
	    S_StartSound((mobj_t *)&plat->sector->soundorg,sfx_pstart);
127
	}
128
      case	in_stasis:
129
	break;
130
    }
131
}
132
 
133
 
134
//
135
// Do Platforms
136
//  "amount" is only used for SOME platforms.
137
//
138
int
139
EV_DoPlat
140
( line_t*	line,
141
  plattype_e	type,
142
  int		amount )
143
{
144
    plat_t*	plat;
145
    int		secnum;
146
    int		rtn;
147
    sector_t*	sec;
148
 
149
    secnum = -1;
150
    rtn = 0;
151
 
152
 
153
    //	Activate all  plats that are in_stasis
154
    switch(type)
155
    {
156
      case perpetualRaise:
157
	P_ActivateInStasis(line->tag);
158
	break;
159
 
160
      default:
161
	break;
162
    }
163
 
164
    while ((secnum = P_FindSectorFromLineTag(line,secnum)) >= 0)
165
    {
166
	sec = §ors[secnum];
167
 
168
	if (sec->specialdata)
169
	    continue;
170
 
171
	// Find lowest & highest floors around sector
172
	rtn = 1;
173
	plat = Z_Malloc( sizeof(*plat), PU_LEVSPEC, 0);
174
	P_AddThinker(&plat->thinker);
175
 
176
	plat->type = type;
177
	plat->sector = sec;
178
	plat->sector->specialdata = plat;
179
	plat->thinker.function.acp1 = (actionf_p1) T_PlatRaise;
180
	plat->crush = false;
181
	plat->tag = line->tag;
182
 
183
	switch(type)
184
	{
185
	  case raiseToNearestAndChange:
186
	    plat->speed = PLATSPEED/2;
187
	    sec->floorpic = sides[line->sidenum[0]].sector->floorpic;
188
	    plat->high = P_FindNextHighestFloor(sec,sec->floorheight);
189
	    plat->wait = 0;
190
	    plat->status = up;
191
	    // NO MORE DAMAGE, IF APPLICABLE
192
	    sec->special = 0;
193
 
194
	    S_StartSound((mobj_t *)&sec->soundorg,sfx_stnmov);
195
	    break;
196
 
197
	  case raiseAndChange:
198
	    plat->speed = PLATSPEED/2;
199
	    sec->floorpic = sides[line->sidenum[0]].sector->floorpic;
200
	    plat->high = sec->floorheight + amount*FRACUNIT;
201
	    plat->wait = 0;
202
	    plat->status = up;
203
 
204
	    S_StartSound((mobj_t *)&sec->soundorg,sfx_stnmov);
205
	    break;
206
 
207
	  case downWaitUpStay:
208
	    plat->speed = PLATSPEED * 4;
209
	    plat->low = P_FindLowestFloorSurrounding(sec);
210
 
211
	    if (plat->low > sec->floorheight)
212
		plat->low = sec->floorheight;
213
 
214
	    plat->high = sec->floorheight;
215
	    plat->wait = 35*PLATWAIT;
216
	    plat->status = down;
217
	    S_StartSound((mobj_t *)&sec->soundorg,sfx_pstart);
218
	    break;
219
 
220
	  case blazeDWUS:
221
	    plat->speed = PLATSPEED * 8;
222
	    plat->low = P_FindLowestFloorSurrounding(sec);
223
 
224
	    if (plat->low > sec->floorheight)
225
		plat->low = sec->floorheight;
226
 
227
	    plat->high = sec->floorheight;
228
	    plat->wait = 35*PLATWAIT;
229
	    plat->status = down;
230
	    S_StartSound((mobj_t *)&sec->soundorg,sfx_pstart);
231
	    break;
232
 
233
	  case perpetualRaise:
234
	    plat->speed = PLATSPEED;
235
	    plat->low = P_FindLowestFloorSurrounding(sec);
236
 
237
	    if (plat->low > sec->floorheight)
238
		plat->low = sec->floorheight;
239
 
240
	    plat->high = P_FindHighestFloorSurrounding(sec);
241
 
242
	    if (plat->high < sec->floorheight)
243
		plat->high = sec->floorheight;
244
 
245
	    plat->wait = 35*PLATWAIT;
246
	    plat->status = P_Random()&1;
247
 
248
	    S_StartSound((mobj_t *)&sec->soundorg,sfx_pstart);
249
	    break;
250
	}
251
	P_AddActivePlat(plat);
252
    }
253
    return rtn;
254
}
255
 
256
 
257
 
258
void P_ActivateInStasis(int tag)
259
{
260
    int		i;
261
 
262
    for (i = 0;i < MAXPLATS;i++)
263
	if (activeplats[i]
264
	    && (activeplats[i])->tag == tag
265
	    && (activeplats[i])->status == in_stasis)
266
	{
267
	    (activeplats[i])->status = (activeplats[i])->oldstatus;
268
	    (activeplats[i])->thinker.function.acp1
269
	      = (actionf_p1) T_PlatRaise;
270
	}
271
}
272
 
273
void EV_StopPlat(line_t* line)
274
{
275
    int		j;
276
 
277
    for (j = 0;j < MAXPLATS;j++)
278
	if (activeplats[j]
279
	    && ((activeplats[j])->status != in_stasis)
280
	    && ((activeplats[j])->tag == line->tag))
281
	{
282
	    (activeplats[j])->oldstatus = (activeplats[j])->status;
283
	    (activeplats[j])->status = in_stasis;
284
	    (activeplats[j])->thinker.function.acv = (actionf_v)NULL;
285
	}
286
}
287
 
288
void P_AddActivePlat(plat_t* plat)
289
{
290
    int		i;
291
 
292
    for (i = 0;i < MAXPLATS;i++)
293
	if (activeplats[i] == NULL)
294
	{
295
	    activeplats[i] = plat;
296
	    return;
297
	}
298
    I_Error ("P_AddActivePlat: no more plats!");
299
}
300
 
301
void P_RemoveActivePlat(plat_t* plat)
302
{
303
    int		i;
304
    for (i = 0;i < MAXPLATS;i++)
305
	if (plat == activeplats[i])
306
	{
307
	    (activeplats[i])->sector->specialdata = NULL;
308
	    P_RemoveThinker(&(activeplats[i])->thinker);
309
	    activeplats[i] = NULL;
310
 
311
	    return;
312
	}
313
    I_Error ("P_RemoveActivePlat: can't find plat!");
314
}