]> git.lizzy.rs Git - plan9front.git/blob - sys/src/games/doom/p_plats.c
games/doom: add /sys/games/lib/doom as default wad path
[plan9front.git] / sys / src / games / doom / p_plats.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 //      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(void *_plat, void*)
53 {
54     plat_t *plat = (plat_t*)_plat;
55     result_e    res;
56         
57     switch(plat->status)
58     {
59       case up:
60         res = T_MovePlane(plat->sector,
61                           plat->speed,
62                           plat->high,
63                           plat->crush,0,1);
64                                         
65         if (plat->type == raiseAndChange
66             || plat->type == raiseToNearestAndChange)
67         {
68             if (!(leveltime&7))
69                 S_StartSound((mobj_t *)&plat->sector->soundorg,
70                              sfx_stnmov);
71         }
72         
73                                 
74         if (res == crushed && (!plat->crush))
75         {
76             plat->count = plat->wait;
77             plat->status = down;
78             S_StartSound((mobj_t *)&plat->sector->soundorg,
79                          sfx_pstart);
80         }
81         else
82         {
83             if (res == pastdest)
84             {
85                 plat->count = plat->wait;
86                 plat->status = waiting;
87                 S_StartSound((mobj_t *)&plat->sector->soundorg,
88                              sfx_pstop);
89
90                 switch(plat->type)
91                 {
92                   case blazeDWUS:
93                   case downWaitUpStay:
94                     P_RemoveActivePlat(plat);
95                     break;
96                     
97                   case raiseAndChange:
98                   case raiseToNearestAndChange:
99                     P_RemoveActivePlat(plat);
100                     break;
101                     
102                   default:
103                     break;
104                 }
105             }
106         }
107         break;
108         
109       case      down:
110         res = T_MovePlane(plat->sector,plat->speed,plat->low,false,0,-1);
111
112         if (res == pastdest)
113         {
114             plat->count = plat->wait;
115             plat->status = waiting;
116             S_StartSound((mobj_t *)&plat->sector->soundorg,sfx_pstop);
117         }
118         break;
119         
120       case      waiting:
121         if (!--plat->count)
122         {
123             if (plat->sector->floorheight == plat->low)
124                 plat->status = up;
125             else
126                 plat->status = down;
127             S_StartSound((mobj_t *)&plat->sector->soundorg,sfx_pstart);
128         }
129       case      in_stasis:
130         break;
131     }
132 }
133
134
135 //
136 // Do Platforms
137 //  "amount" is only used for SOME platforms.
138 //
139 int
140 EV_DoPlat
141 ( line_t*       line,
142   plattype_e    type,
143   int           amount )
144 {
145     plat_t*     plat;
146     int         secnum;
147     int         rtn;
148     sector_t*   sec;
149         
150     secnum = -1;
151     rtn = 0;
152
153     
154     //  Activate all <type> plats that are in_stasis
155     switch(type)
156     {
157       case perpetualRaise:
158         P_ActivateInStasis(line->tag);
159         break;
160         
161       default:
162         break;
163     }
164         
165     while ((secnum = P_FindSectorFromLineTag(line,secnum)) >= 0)
166     {
167         sec = &sectors[secnum];
168
169         if (sec->specialdata)
170             continue;
171         
172         // Find lowest & highest floors around sector
173         rtn = 1;
174         plat = Z_Malloc( sizeof(*plat), PU_LEVSPEC, 0);
175         P_AddThinker(&plat->thinker);
176                 
177         plat->type = type;
178         plat->sector = sec;
179         plat->sector->specialdata = plat;
180         plat->thinker.function = T_PlatRaise;
181         plat->crush = false;
182         plat->tag = line->tag;
183         
184         switch(type)
185         {
186           case raiseToNearestAndChange:
187             plat->speed = PLATSPEED/2;
188             sec->floorpic = sides[line->sidenum[0]].sector->floorpic;
189             plat->high = P_FindNextHighestFloor(sec,sec->floorheight);
190             plat->wait = 0;
191             plat->status = up;
192             // NO MORE DAMAGE, IF APPLICABLE
193             sec->special = 0;           
194
195             S_StartSound((mobj_t *)&sec->soundorg,sfx_stnmov);
196             break;
197             
198           case raiseAndChange:
199             plat->speed = PLATSPEED/2;
200             sec->floorpic = sides[line->sidenum[0]].sector->floorpic;
201             plat->high = sec->floorheight + amount*FRACUNIT;
202             plat->wait = 0;
203             plat->status = up;
204
205             S_StartSound((mobj_t *)&sec->soundorg,sfx_stnmov);
206             break;
207             
208           case downWaitUpStay:
209             plat->speed = PLATSPEED * 4;
210             plat->low = P_FindLowestFloorSurrounding(sec);
211
212             if (plat->low > sec->floorheight)
213                 plat->low = sec->floorheight;
214
215             plat->high = sec->floorheight;
216             plat->wait = 35*PLATWAIT;
217             plat->status = down;
218             S_StartSound((mobj_t *)&sec->soundorg,sfx_pstart);
219             break;
220             
221           case blazeDWUS:
222             plat->speed = PLATSPEED * 8;
223             plat->low = P_FindLowestFloorSurrounding(sec);
224
225             if (plat->low > sec->floorheight)
226                 plat->low = sec->floorheight;
227
228             plat->high = sec->floorheight;
229             plat->wait = 35*PLATWAIT;
230             plat->status = down;
231             S_StartSound((mobj_t *)&sec->soundorg,sfx_pstart);
232             break;
233             
234           case perpetualRaise:
235             plat->speed = PLATSPEED;
236             plat->low = P_FindLowestFloorSurrounding(sec);
237
238             if (plat->low > sec->floorheight)
239                 plat->low = sec->floorheight;
240
241             plat->high = P_FindHighestFloorSurrounding(sec);
242
243             if (plat->high < sec->floorheight)
244                 plat->high = sec->floorheight;
245
246             plat->wait = 35*PLATWAIT;
247             plat->status = P_Random()&1;
248
249             S_StartSound((mobj_t *)&sec->soundorg,sfx_pstart);
250             break;
251         }
252         P_AddActivePlat(plat);
253     }
254     return rtn;
255 }
256
257
258
259 void P_ActivateInStasis(int tag)
260 {
261     int         i;
262         
263     for (i = 0;i < MAXPLATS;i++)
264         if (activeplats[i]
265             && (activeplats[i])->tag == tag
266             && (activeplats[i])->status == in_stasis)
267         {
268             (activeplats[i])->status = (activeplats[i])->oldstatus;
269             (activeplats[i])->thinker.function = 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 = 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 }