P_DOORS.C 7.2 KB

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