p_ceilng.cpp (7154B)
1 /* 2 =========================================================================== 3 4 Doom 3 BFG Edition GPL Source Code 5 Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company. 6 7 This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code"). 8 9 Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify 10 it under the terms of the GNU General Public License as published by 11 the Free Software Foundation, either version 3 of the License, or 12 (at your option) any later version. 13 14 Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful, 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 GNU General Public License for more details. 18 19 You should have received a copy of the GNU General Public License 20 along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>. 21 22 In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below. 23 24 If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA. 25 26 =========================================================================== 27 */ 28 29 #include "Precompiled.h" 30 #include "globaldata.h" 31 32 33 #include "z_zone.h" 34 #include "doomdef.h" 35 #include "p_local.h" 36 37 #include "s_sound.h" 38 39 // State. 40 #include "doomstat.h" 41 #include "r_state.h" 42 43 // Data. 44 #include "sounds.h" 45 46 // 47 // CEILINGS 48 // 49 50 51 52 53 // 54 // T_MoveCeiling 55 // 56 57 void T_MoveCeiling (ceiling_t* ceiling) 58 { 59 result_e res; 60 61 switch(ceiling->direction) 62 { 63 case 0: 64 // IN STASIS 65 break; 66 case 1: 67 // UP 68 res = T_MovePlane(ceiling->sector, 69 ceiling->speed, 70 ceiling->topheight, 71 false,1,ceiling->direction); 72 73 if (!(::g->leveltime&7)) 74 { 75 switch(ceiling->type) 76 { 77 case silentCrushAndRaise: 78 break; 79 default: 80 S_StartSound( &ceiling->sector->soundorg, 81 sfx_stnmov); 82 // ? 83 break; 84 } 85 } 86 87 if (res == pastdest) 88 { 89 switch(ceiling->type) 90 { 91 case raiseToHighest: 92 P_RemoveActiveCeiling(ceiling); 93 break; 94 95 case silentCrushAndRaise: 96 S_StartSound( &ceiling->sector->soundorg, 97 sfx_pstop); 98 case fastCrushAndRaise: 99 case crushAndRaise: 100 ceiling->direction = -1; 101 break; 102 103 default: 104 break; 105 } 106 107 } 108 break; 109 110 case -1: 111 // DOWN 112 res = T_MovePlane(ceiling->sector, 113 ceiling->speed, 114 ceiling->bottomheight, 115 ceiling->crush,1,ceiling->direction); 116 117 if (!(::g->leveltime&7)) 118 { 119 switch(ceiling->type) 120 { 121 case silentCrushAndRaise: break; 122 default: 123 S_StartSound( &ceiling->sector->soundorg, 124 sfx_stnmov); 125 } 126 } 127 128 if (res == pastdest) 129 { 130 switch(ceiling->type) 131 { 132 case silentCrushAndRaise: 133 S_StartSound( &ceiling->sector->soundorg, 134 sfx_pstop); 135 case crushAndRaise: 136 ceiling->speed = CEILSPEED; 137 case fastCrushAndRaise: 138 ceiling->direction = 1; 139 break; 140 141 case lowerAndCrush: 142 case lowerToFloor: 143 P_RemoveActiveCeiling(ceiling); 144 break; 145 146 default: 147 break; 148 } 149 } 150 else // ( res != pastdest ) 151 { 152 if (res == crushed) 153 { 154 switch(ceiling->type) 155 { 156 case silentCrushAndRaise: 157 case crushAndRaise: 158 case lowerAndCrush: 159 ceiling->speed = CEILSPEED / 8; 160 break; 161 162 default: 163 break; 164 } 165 } 166 } 167 break; 168 } 169 } 170 171 172 // 173 // EV_DoCeiling 174 // Move a ceiling up/down and all around! 175 // 176 int 177 EV_DoCeiling 178 ( line_t* line, 179 ceiling_e type ) 180 { 181 int secnum; 182 int rtn; 183 sector_t* sec; 184 ceiling_t* ceiling; 185 186 secnum = -1; 187 rtn = 0; 188 189 // Reactivate in-stasis ceilings...for certain types. 190 switch(type) 191 { 192 case fastCrushAndRaise: 193 case silentCrushAndRaise: 194 case crushAndRaise: 195 P_ActivateInStasisCeiling(line); 196 default: 197 break; 198 } 199 200 while ((secnum = P_FindSectorFromLineTag(line,secnum)) >= 0) 201 { 202 sec = &::g->sectors[secnum]; 203 if (sec->specialdata) 204 continue; 205 206 // new door thinker 207 rtn = 1; 208 ceiling = (ceiling_t*)DoomLib::Z_Malloc(sizeof(*ceiling), PU_LEVEL, 0); 209 P_AddThinker (&ceiling->thinker); 210 sec->specialdata = ceiling; 211 ceiling->thinker.function.acp1 = (actionf_p1)T_MoveCeiling; 212 ceiling->sector = sec; 213 ceiling->crush = false; 214 215 switch(type) 216 { 217 case fastCrushAndRaise: 218 ceiling->crush = true; 219 ceiling->topheight = sec->ceilingheight; 220 ceiling->bottomheight = sec->floorheight + (8*FRACUNIT); 221 ceiling->direction = -1; 222 ceiling->speed = CEILSPEED * 2; 223 break; 224 225 case silentCrushAndRaise: 226 case crushAndRaise: 227 ceiling->crush = true; 228 ceiling->topheight = sec->ceilingheight; 229 case lowerAndCrush: 230 case lowerToFloor: 231 ceiling->bottomheight = sec->floorheight; 232 if (type != lowerToFloor) 233 ceiling->bottomheight += 8*FRACUNIT; 234 ceiling->direction = -1; 235 ceiling->speed = CEILSPEED; 236 break; 237 238 case raiseToHighest: 239 ceiling->topheight = P_FindHighestCeilingSurrounding(sec); 240 ceiling->direction = 1; 241 ceiling->speed = CEILSPEED; 242 break; 243 } 244 245 ceiling->tag = sec->tag; 246 ceiling->type = type; 247 P_AddActiveCeiling(ceiling); 248 } 249 return rtn; 250 } 251 252 253 // 254 // Add an active ceiling 255 // 256 void P_AddActiveCeiling(ceiling_t* c) 257 { 258 int i; 259 260 for (i = 0; i < MAXCEILINGS;i++) 261 { 262 if (::g->activeceilings[i] == NULL) 263 { 264 ::g->activeceilings[i] = c; 265 return; 266 } 267 } 268 } 269 270 271 272 // 273 // Remove a ceiling's thinker 274 // 275 void P_RemoveActiveCeiling(ceiling_t* c) 276 { 277 int i; 278 279 for (i = 0;i < MAXCEILINGS;i++) 280 { 281 if (::g->activeceilings[i] == c) 282 { 283 ::g->activeceilings[i]->sector->specialdata = NULL; 284 P_RemoveThinker (&::g->activeceilings[i]->thinker); 285 ::g->activeceilings[i] = NULL; 286 break; 287 } 288 } 289 } 290 291 292 293 // 294 // Restart a ceiling that's in-stasis 295 // 296 void P_ActivateInStasisCeiling(line_t* line) 297 { 298 int i; 299 300 for (i = 0;i < MAXCEILINGS;i++) 301 { 302 if (::g->activeceilings[i] 303 && (::g->activeceilings[i]->tag == line->tag) 304 && (::g->activeceilings[i]->direction == 0)) 305 { 306 ::g->activeceilings[i]->direction = ::g->activeceilings[i]->olddirection; 307 ::g->activeceilings[i]->thinker.function.acp1 308 = (actionf_p1)T_MoveCeiling; 309 } 310 } 311 } 312 313 314 315 // 316 // EV_CeilingCrushStop 317 // Stop a ceiling from crushing! 318 // 319 int EV_CeilingCrushStop(line_t *line) 320 { 321 int i; 322 int rtn; 323 324 rtn = 0; 325 for (i = 0;i < MAXCEILINGS;i++) 326 { 327 if (::g->activeceilings[i] 328 && (::g->activeceilings[i]->tag == line->tag) 329 && (::g->activeceilings[i]->direction != 0)) 330 { 331 ::g->activeceilings[i]->olddirection = ::g->activeceilings[i]->direction; 332 ::g->activeceilings[i]->thinker.function.acv = (actionf_v)NULL; 333 ::g->activeceilings[i]->direction = 0; // in-stasis 334 rtn = 1; 335 } 336 } 337 338 339 return rtn; 340 } 341