]> icculus.org git repositories - theoddone33/hheretic.git/blob - base/p_doors.c
Initial revision
[theoddone33/hheretic.git] / base / p_doors.c
1
2 // P_doors.c
3
4 #include "doomdef.h"
5 #include "p_local.h"
6 #include "soundst.h"
7
8 //==================================================================
9 //==================================================================
10 //
11 //                                                      VERTICAL DOORS
12 //
13 //==================================================================
14 //==================================================================
15
16 //==================================================================
17 //
18 //      T_VerticalDoor
19 //
20 //==================================================================
21 void T_VerticalDoor(vldoor_t *door)
22 {
23         result_e res;
24
25         switch(door->direction)
26         {
27                 case 0: // WAITING
28                         if(!--door->topcountdown)
29                                 switch(door->type)
30                                 {
31                                         case normal:
32                                                 door->direction = -1; // time to go back down
33                                                 S_StartSound((mobj_t *)
34                                                         &door->sector->soundorg, sfx_doropn);
35                                                 break;
36                                         case close30ThenOpen:
37                                                 door->direction = 1;
38                                                 S_StartSound((mobj_t *)
39                                                         &door->sector->soundorg, sfx_doropn);
40                                                 break;
41                                         default:
42                                                 break;
43                                 }
44                         break;
45                 case 2: // INITIAL WAIT
46                         if(!--door->topcountdown)
47                         {
48                                 switch(door->type)
49                                 {
50                                         case raiseIn5Mins:
51                                                 door->direction = 1;
52                                                 door->type = normal;
53                                                 S_StartSound((mobj_t *)
54                                                         &door->sector->soundorg, sfx_doropn);
55                                                 break;
56                                         default:
57                                                 break;
58                                 }
59                         }
60                         break;
61                 case -1: // DOWN
62                         res = T_MovePlane(door->sector, door->speed,
63                                 door->sector->floorheight, false, 1, door->direction);
64                         if(res == pastdest)
65                         {
66                                 switch(door->type)
67                                 {
68                                         case normal:
69                                         case close:
70                                                 door->sector->specialdata = NULL;
71                                                 P_RemoveThinker(&door->thinker);  // unlink and free
72                                                 S_StartSound((mobj_t *)
73                                                         &door->sector->soundorg, sfx_dorcls);
74                                                 break;
75                                         case close30ThenOpen:
76                                                 door->direction = 0;
77                                                 door->topcountdown = 35*30;
78                                                 break;
79                                         default:
80                                                 break;
81                                 }
82                         }
83                         else if(res == crushed)
84                         {
85                                 switch(door->type)
86                                 {
87                                         case close: // DON'T GO BACK UP!
88                                                 break;
89                                         default:
90                                                 door->direction = 1;
91                                                 S_StartSound((mobj_t *)
92                                                         &door->sector->soundorg,sfx_doropn);
93                                                 break;
94                                 }
95                         }
96                         break;
97                 case 1: // UP
98                         res = T_MovePlane(door->sector, door->speed,
99                                 door->topheight, false, 1, door->direction);
100                         if(res == pastdest)
101                         {
102                                 switch(door->type)
103                                 {
104                                         case normal:
105                                                 door->direction = 0; // wait at top
106                                                 door->topcountdown = door->topwait;
107                                                 break;
108                                         case close30ThenOpen:
109                                         case open:
110                                                 door->sector->specialdata = NULL;
111                                                 P_RemoveThinker (&door->thinker); // unlink and free
112                                                 S_StopSound((mobj_t *)&door->sector->soundorg);
113                                                 break;
114                                         default:
115                                                 break;
116                                 }
117                         }
118                         break;
119         }
120 }
121
122 //----------------------------------------------------------------------------
123 //
124 // EV_DoDoor
125 //
126 // Move a door up/down
127 //
128 //----------------------------------------------------------------------------
129
130 int EV_DoDoor(line_t *line, vldoor_e type, fixed_t speed)
131 {
132         int secnum;
133         int retcode;
134         sector_t *sec;
135         vldoor_t *door;
136
137         secnum = -1;
138         retcode = 0;
139         while((secnum = P_FindSectorFromLineTag(line, secnum)) >= 0)
140         {
141                 sec = &sectors[secnum];
142                 if(sec->specialdata)
143                 {
144                         continue;
145                 }
146                 // Add new door thinker
147                 retcode = 1;
148                 door = Z_Malloc(sizeof(*door), PU_LEVSPEC, 0);
149                 P_AddThinker(&door->thinker);
150                 sec->specialdata = door;
151                 door->thinker.function = T_VerticalDoor;
152                 door->sector = sec;
153                 switch(type)
154                 {
155                         case close:
156                                 door->topheight = P_FindLowestCeilingSurrounding(sec);
157                                 door->topheight -= 4*FRACUNIT;
158                                 door->direction = -1;
159                                 S_StartSound((mobj_t *)&door->sector->soundorg, sfx_doropn);
160                                 break;
161                         case close30ThenOpen:
162                                 door->topheight = sec->ceilingheight;
163                                 door->direction = -1;
164                                 S_StartSound((mobj_t *)&door->sector->soundorg, sfx_doropn);
165                                 break;
166                         case normal:
167                         case open:
168                                 door->direction = 1;
169                                 door->topheight = P_FindLowestCeilingSurrounding(sec);
170                                 door->topheight -= 4*FRACUNIT;
171                                 if(door->topheight != sec->ceilingheight)
172                                 {
173                                         S_StartSound((mobj_t *)&door->sector->soundorg,
174                                                 sfx_doropn);
175                                 }
176                                 break;
177                         default:
178                                 break;
179                 }
180                 door->type = type;
181                 door->speed = speed;
182                 door->topwait = VDOORWAIT;
183         }
184         return(retcode);
185 }
186
187 //==================================================================
188 //
189 //      EV_VerticalDoor : open a door manually, no tag value
190 //
191 //==================================================================
192 void EV_VerticalDoor(line_t *line, mobj_t *thing)
193 {
194         player_t                *player;
195         int                             secnum;
196         sector_t                *sec;
197         vldoor_t                *door;
198         int                             side;
199         
200         side = 0; // only front sides can be used
201 //
202 //      Check for locks
203 //
204         player = thing->player;
205         switch(line->special)
206         {
207                 case 26: // Blue Lock
208                 case 32:
209                         if(!player)
210                         {
211                                 return;
212                         }
213                         if(!player->keys[key_blue])
214                         {
215                                 P_SetMessage(player, TXT_NEEDBLUEKEY, false);
216                                 S_StartSound(NULL, sfx_plroof);
217                                 return;
218                         }
219                         break;
220                 case 27: // Yellow Lock
221                 case 34:
222                         if(!player)
223                         {
224                                 return;
225                         }
226                         if(!player->keys[key_yellow])
227                         {
228                                 P_SetMessage(player, TXT_NEEDYELLOWKEY, false);
229                                 S_StartSound(NULL, sfx_plroof);
230                                 return;
231                         }
232                         break;
233                 case 28: // Green Lock
234                 case 33:
235                         if(!player)
236                         {
237                                 return;
238                         }
239                         if(!player->keys[key_green])
240                         {
241                                 P_SetMessage(player, TXT_NEEDGREENKEY, false);
242                                 S_StartSound(NULL, sfx_plroof);
243                                 return;
244                         }
245                         break;
246         }
247
248         // if the sector has an active thinker, use it
249         sec = sides[line->sidenum[side^1]].sector;
250         secnum = sec-sectors;
251         if(sec->specialdata)
252         {
253                 door = sec->specialdata;
254                 switch(line->special)
255                 {
256                         case 1: // ONLY FOR "RAISE" DOORS, NOT "OPEN"s
257                         case 26:
258                         case 27:
259                         case 28:
260                                 if(door->direction == -1)
261                                 {
262                                         door->direction = 1; // go back up
263                                 }
264                                 else
265                                 {
266                                         if(!thing->player)
267                                         { // Monsters don't close doors
268                                                 return;
269                                         }
270                                         door->direction = -1; // start going down immediately
271                                 }
272                                 return;
273                 }
274         }
275
276         // for proper sound
277         switch(line->special)
278         {
279                 case 1: // NORMAL DOOR SOUND
280                 case 31:
281                         S_StartSound((mobj_t *)&sec->soundorg, sfx_doropn);
282                         //S_StartSound((mobj_t *)&sec->soundorg, sfx_dormov);
283                         break;
284                 default: // LOCKED DOOR SOUND
285                         S_StartSound((mobj_t *)&sec->soundorg, sfx_doropn);
286                         //S_StartSound((mobj_t *)&sec->soundorg, sfx_dormov);
287                         break;
288         }
289
290         //
291         // new door thinker
292         //
293         door = Z_Malloc (sizeof(*door), PU_LEVSPEC, 0);
294         P_AddThinker(&door->thinker);
295         sec->specialdata = door;
296         door->thinker.function = T_VerticalDoor;
297         door->sector = sec;
298         door->direction = 1;
299         switch(line->special)
300         {
301                 case 1:
302                 case 26:
303                 case 27:
304                 case 28:
305                         door->type = normal;
306                         break;
307                 case 31:
308                 case 32:
309                 case 33:
310                 case 34:
311                         door->type = open;
312                         line->special = 0;
313                         break;
314         }
315         door->speed = VDOORSPEED;
316         door->topwait = VDOORWAIT;
317         
318         //
319         // find the top and bottom of the movement range
320         //
321         door->topheight = P_FindLowestCeilingSurrounding(sec);
322         door->topheight -= 4*FRACUNIT;
323 }
324
325 //==================================================================
326 //
327 //      Spawn a door that closes after 30 seconds
328 //
329 //==================================================================
330 void P_SpawnDoorCloseIn30(sector_t *sec)
331 {
332         vldoor_t *door;
333
334         door = Z_Malloc(sizeof(*door), PU_LEVSPEC, 0);
335         P_AddThinker(&door->thinker);
336         sec->specialdata = door;
337         sec->special = 0;
338         door->thinker.function = T_VerticalDoor;
339         door->sector = sec;
340         door->direction = 0;
341         door->type = normal;
342         door->speed = VDOORSPEED;
343         door->topcountdown = 30*35;
344 }
345
346 //==================================================================
347 //
348 //      Spawn a door that opens after 5 minutes
349 //
350 //==================================================================
351 void P_SpawnDoorRaiseIn5Mins(sector_t *sec, int secnum)
352 {
353         vldoor_t *door;
354
355         door = Z_Malloc(sizeof(*door), PU_LEVSPEC, 0);
356         P_AddThinker(&door->thinker);
357         sec->specialdata = door;
358         sec->special = 0;
359         door->thinker.function = T_VerticalDoor;
360         door->sector = sec;
361         door->direction = 2;
362         door->type = raiseIn5Mins;
363         door->speed = VDOORSPEED;
364         door->topheight = P_FindLowestCeilingSurrounding(sec);
365         door->topheight -= 4*FRACUNIT;
366         door->topwait = VDOORWAIT;
367         door->topcountdown = 5*60*35;
368 }