]> icculus.org git repositories - theoddone33/hhexen.git/blob - base/p_doors.c
change email address
[theoddone33/hhexen.git] / base / p_doors.c
1
2 //**************************************************************************
3 //**
4 //** p_doors.c : Heretic 2 : Raven Software, Corp.
5 //**
6 //** $RCSfile$
7 //** $Revision$
8 //** $Date$
9 //** $Author$
10 //**
11 //**************************************************************************
12
13 #include "h2def.h"
14 #include "p_local.h"
15 #include "soundst.h"
16
17 //==================================================================
18 //==================================================================
19 //
20 //                                                      VERTICAL DOORS
21 //
22 //==================================================================
23 //==================================================================
24
25 //==================================================================
26 //
27 //      T_VerticalDoor
28 //
29 //==================================================================
30 void T_VerticalDoor(vldoor_t *door)
31 {
32         result_e res;
33
34         switch(door->direction)
35         {
36                 case 0: // WAITING
37                         if(!--door->topcountdown)
38                                 switch(door->type)
39                                 {
40                                         case DREV_NORMAL:
41                                                 door->direction = -1; // time to go back down
42                                                 SN_StartSequence((mobj_t *)&door->sector->soundorg,
43                                                         SEQ_DOOR_STONE+door->sector->seqType);
44                                                 break;
45                                         case DREV_CLOSE30THENOPEN:
46                                                 door->direction = 1;
47                                                 break;
48                                         default:
49                                                 break;
50                                 }
51                         break;
52                 case 2: // INITIAL WAIT
53                         if(!--door->topcountdown)
54                         {
55                                 switch(door->type)
56                                 {
57                                         case DREV_RAISEIN5MINS:
58                                                 door->direction = 1;
59                                                 door->type = DREV_NORMAL;
60                                                 break;
61                                         default:
62                                                 break;
63                                 }
64                         }
65                         break;
66                 case -1: // DOWN
67                         res = T_MovePlane(door->sector, door->speed,
68                                 door->sector->floorheight, false, 1, door->direction);          
69                         if(res == RES_PASTDEST)
70                         {
71                                 SN_StopSequence((mobj_t *)&door->sector->soundorg);
72                                 switch(door->type)
73                                 {
74                                         case DREV_NORMAL:
75                                         case DREV_CLOSE:
76                                                 door->sector->specialdata = NULL;
77                                                 P_TagFinished(door->sector->tag);
78                                                 P_RemoveThinker(&door->thinker);  // unlink and free
79                                                 break;
80                                         case DREV_CLOSE30THENOPEN:
81                                                 door->direction = 0;
82                                                 door->topcountdown = 35*30;
83                                                 break;
84                                         default:
85                                                 break;
86                                 }
87                         }
88                         else if(res == RES_CRUSHED)
89                         {
90                                 switch(door->type)
91                                 {
92                                         case DREV_CLOSE: // DON'T GO BACK UP!
93                                                 break;
94                                         default:
95                                                 door->direction = 1;
96                                                 break;
97                                 }
98                         }
99                         break;
100                 case 1: // UP
101                         res = T_MovePlane(door->sector, door->speed,
102                                 door->topheight, false, 1, door->direction);
103                         if(res == RES_PASTDEST)
104                         {
105                                 SN_StopSequence((mobj_t *)&door->sector->soundorg);
106                                 switch(door->type)
107                                 {
108                                         case DREV_NORMAL:
109                                                 door->direction = 0; // wait at top
110                                                 door->topcountdown = door->topwait;
111                                                 break;
112                                         case DREV_CLOSE30THENOPEN:
113                                         case DREV_OPEN:
114                                                 door->sector->specialdata = NULL;
115                                                 P_TagFinished(door->sector->tag);
116                                                 P_RemoveThinker (&door->thinker); // unlink and free
117                                                 break;
118                                         default:
119                                                 break;
120                                 }
121                         }
122                         break;
123         }
124 }
125
126 //----------------------------------------------------------------------------
127 //
128 // EV_DoDoor
129 //
130 // Move a door up/down
131 //
132 //----------------------------------------------------------------------------
133
134 int EV_DoDoor(line_t *line, byte *args, vldoor_e type)
135 {
136         int secnum;
137         int retcode;
138         sector_t *sec;
139         vldoor_t *door;
140         fixed_t speed;
141
142         speed = args[1]*FRACUNIT/8;
143         secnum = -1;
144         retcode = 0;
145         while((secnum = P_FindSectorFromTag(args[0], secnum)) >= 0)
146         {
147                 sec = &sectors[secnum];
148                 if(sec->specialdata)
149                 {
150                         continue;
151                 }
152                 // Add new door thinker
153                 retcode = 1;
154                 door = Z_Malloc(sizeof(*door), PU_LEVSPEC, 0);
155                 P_AddThinker(&door->thinker);
156                 sec->specialdata = door;
157                 door->thinker.function = T_VerticalDoor;
158                 door->sector = sec;
159                 switch(type)
160                 {
161                         case DREV_CLOSE:
162                                 door->topheight = P_FindLowestCeilingSurrounding(sec);
163                                 door->topheight -= 4*FRACUNIT;
164                                 door->direction = -1;
165                                 break;
166                         case DREV_CLOSE30THENOPEN:
167                                 door->topheight = sec->ceilingheight;
168                                 door->direction = -1;
169                                 break;
170                         case DREV_NORMAL:
171                         case DREV_OPEN:
172                                 door->direction = 1;
173                                 door->topheight = P_FindLowestCeilingSurrounding(sec);
174                                 door->topheight -= 4*FRACUNIT;
175                                 break;
176                         default:
177                                 break;
178                 }
179                 door->type = type;
180                 door->speed = speed;
181                 door->topwait = args[2]; // line->arg3
182                 SN_StartSequence((mobj_t *)&door->sector->soundorg,
183                         SEQ_DOOR_STONE+door->sector->seqType);
184         }
185         return(retcode);
186 }
187
188 //==================================================================
189 //
190 //      EV_VerticalDoor : open a door manually, no tag value
191 //
192 //==================================================================
193 boolean EV_VerticalDoor(line_t *line, mobj_t *thing)
194 {
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         // if the sector has an active thinker, use it
203         sec = sides[line->sidenum[side^1]].sector;
204         secnum = sec-sectors;
205         if(sec->specialdata)
206         {
207                 return false;
208 /*
209                 door = sec->specialdata;
210                 switch(line->special)
211                 {       // only for raise doors
212                         case 12:
213                                 if(door->direction == -1)
214                                 {
215                                         door->direction = 1; // go back up
216                                 }
217                                 else
218                                 {
219                                         if(!thing->player)
220                                         { // Monsters don't close doors
221                                                 return;
222                                         }
223                                         door->direction = -1; // start going down immediately
224                                 }
225                                 return;
226                 }
227 */
228         }
229         //
230         // new door thinker
231         //
232         door = Z_Malloc (sizeof(*door), PU_LEVSPEC, 0);
233         P_AddThinker(&door->thinker);
234         sec->specialdata = door;
235         door->thinker.function = T_VerticalDoor;
236         door->sector = sec;
237         door->direction = 1;
238         switch(line->special)
239         {
240                 case 11:
241                         door->type = DREV_OPEN;
242                         line->special = 0;
243                         break;
244                 case 12:
245                 case 13:
246                         door->type = DREV_NORMAL;
247                         break;
248                 default:
249                         door->type = DREV_NORMAL;
250                         break;
251         }
252         door->speed = line->arg2*(FRACUNIT/8);
253         door->topwait = line->arg3;
254
255         //
256         // find the top and bottom of the movement range
257         //
258         door->topheight = P_FindLowestCeilingSurrounding(sec);
259         door->topheight -= 4*FRACUNIT;
260         SN_StartSequence((mobj_t *)&door->sector->soundorg,
261                 SEQ_DOOR_STONE+door->sector->seqType);
262         return true;
263 }
264
265 //==================================================================
266 //
267 //      Spawn a door that closes after 30 seconds
268 //
269 //==================================================================
270
271 /*
272 void P_SpawnDoorCloseIn30(sector_t *sec)
273 {
274         vldoor_t *door;
275
276         door = Z_Malloc(sizeof(*door), PU_LEVSPEC, 0);
277         P_AddThinker(&door->thinker);
278         sec->specialdata = door;
279         sec->special = 0;
280         door->thinker.function = T_VerticalDoor;
281         door->sector = sec;
282         door->direction = 0;
283         door->type = DREV_NORMAL;
284         door->speed = VDOORSPEED;
285         door->topcountdown = 30*35;
286 }
287 */
288
289 //==================================================================
290 //
291 //      Spawn a door that opens after 5 minutes
292 //
293 //==================================================================
294
295 /*
296 void P_SpawnDoorRaiseIn5Mins(sector_t *sec, int secnum)
297 {
298         vldoor_t *door;
299
300         door = Z_Malloc(sizeof(*door), PU_LEVSPEC, 0);
301         P_AddThinker(&door->thinker);
302         sec->specialdata = door;
303         sec->special = 0;
304         door->thinker.function = T_VerticalDoor;
305         door->sector = sec;
306         door->direction = 2;
307         door->type = DREV_RAISEIN5MINS;
308         door->speed = VDOORSPEED;
309         door->topheight = P_FindLowestCeilingSurrounding(sec);
310         door->topheight -= 4*FRACUNIT;
311         door->topwait = VDOORWAIT;
312         door->topcountdown = 5*60*35;
313 }
314 */
315