2 //**************************************************************************
4 //** p_doors.c : Heretic 2 : Raven Software, Corp.
11 //**************************************************************************
17 //==================================================================
18 //==================================================================
22 //==================================================================
23 //==================================================================
25 //==================================================================
29 //==================================================================
30 void T_VerticalDoor(vldoor_t *door)
34 switch(door->direction)
37 if(!--door->topcountdown)
41 door->direction = -1; // time to go back down
42 SN_StartSequence((mobj_t *)&door->sector->soundorg,
43 SEQ_DOOR_STONE+door->sector->seqType);
45 case DREV_CLOSE30THENOPEN:
52 case 2: // INITIAL WAIT
53 if(!--door->topcountdown)
57 case DREV_RAISEIN5MINS:
59 door->type = DREV_NORMAL;
67 res = T_MovePlane(door->sector, door->speed,
68 door->sector->floorheight, false, 1, door->direction);
69 if(res == RES_PASTDEST)
71 SN_StopSequence((mobj_t *)&door->sector->soundorg);
76 door->sector->specialdata = NULL;
77 P_TagFinished(door->sector->tag);
78 P_RemoveThinker(&door->thinker); // unlink and free
80 case DREV_CLOSE30THENOPEN:
82 door->topcountdown = 35*30;
88 else if(res == RES_CRUSHED)
92 case DREV_CLOSE: // DON'T GO BACK UP!
101 res = T_MovePlane(door->sector, door->speed,
102 door->topheight, false, 1, door->direction);
103 if(res == RES_PASTDEST)
105 SN_StopSequence((mobj_t *)&door->sector->soundorg);
109 door->direction = 0; // wait at top
110 door->topcountdown = door->topwait;
112 case DREV_CLOSE30THENOPEN:
114 door->sector->specialdata = NULL;
115 P_TagFinished(door->sector->tag);
116 P_RemoveThinker (&door->thinker); // unlink and free
126 //----------------------------------------------------------------------------
130 // Move a door up/down
132 //----------------------------------------------------------------------------
134 int EV_DoDoor(line_t *line, byte *args, vldoor_e type)
142 speed = args[1]*FRACUNIT/8;
145 while((secnum = P_FindSectorFromTag(args[0], secnum)) >= 0)
147 sec = §ors[secnum];
152 // Add new door thinker
154 door = Z_Malloc(sizeof(*door), PU_LEVSPEC, 0);
155 P_AddThinker(&door->thinker);
156 sec->specialdata = door;
157 door->thinker.function = T_VerticalDoor;
162 door->topheight = P_FindLowestCeilingSurrounding(sec);
163 door->topheight -= 4*FRACUNIT;
164 door->direction = -1;
166 case DREV_CLOSE30THENOPEN:
167 door->topheight = sec->ceilingheight;
168 door->direction = -1;
173 door->topheight = P_FindLowestCeilingSurrounding(sec);
174 door->topheight -= 4*FRACUNIT;
181 door->topwait = args[2]; // line->arg3
182 SN_StartSequence((mobj_t *)&door->sector->soundorg,
183 SEQ_DOOR_STONE+door->sector->seqType);
188 //==================================================================
190 // EV_VerticalDoor : open a door manually, no tag value
192 //==================================================================
193 boolean EV_VerticalDoor(line_t *line, mobj_t *thing)
200 side = 0; // only front sides can be used
202 // if the sector has an active thinker, use it
203 sec = sides[line->sidenum[side^1]].sector;
204 secnum = sec-sectors;
209 door = sec->specialdata;
210 switch(line->special)
211 { // only for raise doors
213 if(door->direction == -1)
215 door->direction = 1; // go back up
220 { // Monsters don't close doors
223 door->direction = -1; // start going down immediately
232 door = Z_Malloc (sizeof(*door), PU_LEVSPEC, 0);
233 P_AddThinker(&door->thinker);
234 sec->specialdata = door;
235 door->thinker.function = T_VerticalDoor;
238 switch(line->special)
241 door->type = DREV_OPEN;
246 door->type = DREV_NORMAL;
249 door->type = DREV_NORMAL;
252 door->speed = line->arg2*(FRACUNIT/8);
253 door->topwait = line->arg3;
256 // find the top and bottom of the movement range
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);
265 //==================================================================
267 // Spawn a door that closes after 30 seconds
269 //==================================================================
272 void P_SpawnDoorCloseIn30(sector_t *sec)
276 door = Z_Malloc(sizeof(*door), PU_LEVSPEC, 0);
277 P_AddThinker(&door->thinker);
278 sec->specialdata = door;
280 door->thinker.function = T_VerticalDoor;
283 door->type = DREV_NORMAL;
284 door->speed = VDOORSPEED;
285 door->topcountdown = 30*35;
289 //==================================================================
291 // Spawn a door that opens after 5 minutes
293 //==================================================================
296 void P_SpawnDoorRaiseIn5Mins(sector_t *sec, int secnum)
300 door = Z_Malloc(sizeof(*door), PU_LEVSPEC, 0);
301 P_AddThinker(&door->thinker);
302 sec->specialdata = door;
304 door->thinker.function = T_VerticalDoor;
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;