DOOM-3-BFG

DOOM 3 BFG Edition
Log | Files | Refs

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