P_CEILNG.C 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. #include "DoomDef.h"
  2. #include "P_local.h"
  3. #include "soundst.h"
  4. //==================================================================
  5. //==================================================================
  6. //
  7. // CEILINGS
  8. //
  9. //==================================================================
  10. //==================================================================
  11. ceiling_t *activeceilings[MAXCEILINGS];
  12. //==================================================================
  13. //
  14. // T_MoveCeiling
  15. //
  16. //==================================================================
  17. void T_MoveCeiling (ceiling_t *ceiling)
  18. {
  19. result_e res;
  20. switch(ceiling->direction)
  21. {
  22. case 0: // IN STASIS
  23. break;
  24. case 1: // UP
  25. res = T_MovePlane(ceiling->sector,ceiling->speed,
  26. ceiling->topheight,false,1,ceiling->direction);
  27. if(!(leveltime&7))
  28. S_StartSound((mobj_t *)&ceiling->sector->soundorg, sfx_dormov);
  29. if (res == pastdest)
  30. switch(ceiling->type)
  31. {
  32. case raiseToHighest:
  33. P_RemoveActiveCeiling(ceiling);
  34. break;
  35. case fastCrushAndRaise:
  36. case crushAndRaise:
  37. ceiling->direction = -1;
  38. break;
  39. default:
  40. break;
  41. }
  42. break;
  43. case -1: // DOWN
  44. res = T_MovePlane(ceiling->sector,ceiling->speed,
  45. ceiling->bottomheight,ceiling->crush,1,ceiling->direction);
  46. if (!(leveltime&7))
  47. S_StartSound((mobj_t *)&ceiling->sector->soundorg,sfx_dormov);
  48. if (res == pastdest)
  49. switch(ceiling->type)
  50. {
  51. case crushAndRaise:
  52. ceiling->speed = CEILSPEED;
  53. case fastCrushAndRaise:
  54. ceiling->direction = 1;
  55. break;
  56. case lowerAndCrush:
  57. case lowerToFloor:
  58. P_RemoveActiveCeiling(ceiling);
  59. break;
  60. default:
  61. break;
  62. }
  63. else
  64. if (res == crushed)
  65. switch(ceiling->type)
  66. {
  67. case crushAndRaise:
  68. case lowerAndCrush:
  69. ceiling->speed = CEILSPEED / 8;
  70. break;
  71. default:
  72. break;
  73. }
  74. break;
  75. }
  76. }
  77. //==================================================================
  78. //
  79. // EV_DoCeiling
  80. // Move a ceiling up/down and all around!
  81. //
  82. //==================================================================
  83. int EV_DoCeiling (line_t *line, ceiling_e type)
  84. {
  85. int secnum,rtn;
  86. sector_t *sec;
  87. ceiling_t *ceiling;
  88. secnum = -1;
  89. rtn = 0;
  90. //
  91. // Reactivate in-stasis ceilings...for certain types.
  92. //
  93. switch(type)
  94. {
  95. case fastCrushAndRaise:
  96. case crushAndRaise:
  97. P_ActivateInStasisCeiling(line);
  98. default:
  99. break;
  100. }
  101. while ((secnum = P_FindSectorFromLineTag(line,secnum)) >= 0)
  102. {
  103. sec = &sectors[secnum];
  104. if (sec->specialdata)
  105. continue;
  106. //
  107. // new door thinker
  108. //
  109. rtn = 1;
  110. ceiling = Z_Malloc (sizeof(*ceiling), PU_LEVSPEC, 0);
  111. P_AddThinker (&ceiling->thinker);
  112. sec->specialdata = ceiling;
  113. ceiling->thinker.function = T_MoveCeiling;
  114. ceiling->sector = sec;
  115. ceiling->crush = false;
  116. switch(type)
  117. {
  118. case fastCrushAndRaise:
  119. ceiling->crush = true;
  120. ceiling->topheight = sec->ceilingheight;
  121. ceiling->bottomheight = sec->floorheight + (8*FRACUNIT);
  122. ceiling->direction = -1;
  123. ceiling->speed = CEILSPEED * 2;
  124. break;
  125. case crushAndRaise:
  126. ceiling->crush = true;
  127. ceiling->topheight = sec->ceilingheight;
  128. case lowerAndCrush:
  129. case lowerToFloor:
  130. ceiling->bottomheight = sec->floorheight;
  131. if (type != lowerToFloor)
  132. ceiling->bottomheight += 8*FRACUNIT;
  133. ceiling->direction = -1;
  134. ceiling->speed = CEILSPEED;
  135. break;
  136. case raiseToHighest:
  137. ceiling->topheight = P_FindHighestCeilingSurrounding(sec);
  138. ceiling->direction = 1;
  139. ceiling->speed = CEILSPEED;
  140. break;
  141. }
  142. ceiling->tag = sec->tag;
  143. ceiling->type = type;
  144. P_AddActiveCeiling(ceiling);
  145. }
  146. return rtn;
  147. }
  148. //==================================================================
  149. //
  150. // Add an active ceiling
  151. //
  152. //==================================================================
  153. void P_AddActiveCeiling(ceiling_t *c)
  154. {
  155. int i;
  156. for (i = 0; i < MAXCEILINGS;i++)
  157. if (activeceilings[i] == NULL)
  158. {
  159. activeceilings[i] = c;
  160. return;
  161. }
  162. }
  163. //==================================================================
  164. //
  165. // Remove a ceiling's thinker
  166. //
  167. //==================================================================
  168. void P_RemoveActiveCeiling(ceiling_t *c)
  169. {
  170. int i;
  171. for (i = 0;i < MAXCEILINGS;i++)
  172. if (activeceilings[i] == c)
  173. {
  174. activeceilings[i]->sector->specialdata = NULL;
  175. P_RemoveThinker (&activeceilings[i]->thinker);
  176. activeceilings[i] = NULL;
  177. break;
  178. }
  179. }
  180. //==================================================================
  181. //
  182. // Restart a ceiling that's in-stasis
  183. //
  184. //==================================================================
  185. void P_ActivateInStasisCeiling(line_t *line)
  186. {
  187. int i;
  188. for (i = 0;i < MAXCEILINGS;i++)
  189. if (activeceilings[i] && (activeceilings[i]->tag == line->tag) &&
  190. (activeceilings[i]->direction == 0))
  191. {
  192. activeceilings[i]->direction = activeceilings[i]->olddirection;
  193. activeceilings[i]->thinker.function = T_MoveCeiling;
  194. }
  195. }
  196. //==================================================================
  197. //
  198. // EV_CeilingCrushStop
  199. // Stop a ceiling from crushing!
  200. //
  201. //==================================================================
  202. int EV_CeilingCrushStop(line_t *line)
  203. {
  204. int i;
  205. int rtn;
  206. rtn = 0;
  207. for (i = 0;i < MAXCEILINGS;i++)
  208. if (activeceilings[i] && (activeceilings[i]->tag == line->tag) &&
  209. (activeceilings[i]->direction != 0))
  210. {
  211. activeceilings[i]->olddirection = activeceilings[i]->direction;
  212. activeceilings[i]->thinker.function = NULL;
  213. activeceilings[i]->direction = 0; // in-stasis
  214. rtn = 1;
  215. }
  216. return rtn;
  217. }