doom

a minimalistic implementation of doom
git clone git://ssnf.xyz/doom
Log | Files | Refs

p_doors.c (8656B)


      1 #include "z_zone.h"
      2 #include "doomdef.h"
      3 #include "p_local.h"
      4 #include "s_sound.h"
      5 #include "doomstat.h"
      6 #include "r_state.h"
      7 #include "dstrings.h"
      8 #include "sounds.h"
      9 
     10 void
     11 T_VerticalDoor(vldoor_t* door)
     12 {
     13 	result_e res;
     14 	
     15 	switch (door->direction) {
     16 		case 0:
     17 			if (!--door->topcountdown) {
     18 			    switch(door->type) {
     19 					case blazeRaise:
     20 						door->direction = -1; 
     21 						S_StartSound((mobj_t *)&door->sector->soundorg, sfx_bdcls);
     22 				break;
     23 			      case normal:
     24 				door->direction = -1; 
     25 				S_StartSound((mobj_t *)&door->sector->soundorg,
     26 					     sfx_dorcls);
     27 				break;
     28 				
     29 			      case close30ThenOpen:
     30 				door->direction = 1;
     31 				S_StartSound((mobj_t *)&door->sector->soundorg,
     32 					     sfx_doropn);
     33 				break;
     34 				
     35 			      default:
     36 				break;
     37 			    }
     38 			}
     39 			break;
     40 		case 2:
     41 	if (!--door->topcountdown)
     42 	{
     43 	    switch(door->type)
     44 	    {
     45 	      case raiseIn5Mins:
     46 		door->direction = 1;
     47 		door->type = normal;
     48 		S_StartSound((mobj_t *)&door->sector->soundorg,
     49 			     sfx_doropn);
     50 		break;
     51 		
     52 	      default:
     53 		break;
     54 	    }
     55 	}
     56 	break;
     57 	
     58       case -1:
     59 	
     60 	res = T_MovePlane(door->sector,
     61 			  door->speed,
     62 			  door->sector->floorheight,
     63 			  false,1,door->direction);
     64 	if (res == pastdest)
     65 	{
     66 	    switch(door->type)
     67 	    {
     68 	      case blazeRaise:
     69 	      case blazeClose:
     70 		door->sector->specialdata = NULL;
     71 		P_RemoveThinker (&door->thinker);  
     72 		S_StartSound((mobj_t *)&door->sector->soundorg,
     73 			     sfx_bdcls);
     74 		break;
     75 		
     76 	      case normal:
     77 	      case close:
     78 		door->sector->specialdata = NULL;
     79 		P_RemoveThinker (&door->thinker);  
     80 		break;
     81 		
     82 	      case close30ThenOpen:
     83 		door->direction = 0;
     84 		door->topcountdown = 35*30;
     85 		break;
     86 		
     87 	      default:
     88 		break;
     89 	    }
     90 	}
     91 	else if (res == crushed)
     92 	{
     93 	    switch(door->type)
     94 	    {
     95 	      case blazeClose:
     96 	      case close:		
     97 		break;
     98 		
     99 	      default:
    100 		door->direction = 1;
    101 		S_StartSound((mobj_t *)&door->sector->soundorg,
    102 			     sfx_doropn);
    103 		break;
    104 	    }
    105 	}
    106 	break;
    107 	
    108       case 1:
    109 	
    110 	res = T_MovePlane(door->sector,
    111 			  door->speed,
    112 			  door->topheight,
    113 			  false,1,door->direction);
    114 	
    115 	if (res == pastdest)
    116 	{
    117 	    switch(door->type)
    118 	    {
    119 	      case blazeRaise:
    120 	      case normal:
    121 		door->direction = 0; 
    122 		door->topcountdown = door->topwait;
    123 		break;
    124 		
    125 	      case close30ThenOpen:
    126 	      case blazeOpen:
    127 	      case open:
    128 		door->sector->specialdata = NULL;
    129 		P_RemoveThinker (&door->thinker);  
    130 		break;
    131 		
    132 	      default:
    133 		break;
    134 	    }
    135 	}
    136 	break;
    137     }
    138 }
    139 
    140 int
    141 EV_DoLockedDoor
    142 ( line_t*	line,
    143   vldoor_e	type,
    144   mobj_t*	thing )
    145 {
    146     player_t*	p;
    147 	
    148     p = thing->player;
    149 	
    150     if (!p)
    151 	return 0;
    152 		
    153     switch(line->special)
    154     {
    155       case 99:	
    156       case 133:
    157 	if ( !p )
    158 	    return 0;
    159 	if (!p->cards[it_bluecard] && !p->cards[it_blueskull])
    160 	{
    161 	    p->message = lang[PD_BLUEO];
    162 	    S_StartSound(NULL,sfx_oof);
    163 	    return 0;
    164 	}
    165 	break;
    166 	
    167       case 134: 
    168       case 135:
    169 	if ( !p )
    170 	    return 0;
    171 	if (!p->cards[it_redcard] && !p->cards[it_redskull])
    172 	{
    173 	    p->message = lang[PD_REDO];
    174 	    S_StartSound(NULL,sfx_oof);
    175 	    return 0;
    176 	}
    177 	break;
    178 	
    179       case 136:	
    180       case 137:
    181 	if ( !p )
    182 	    return 0;
    183 	if (!p->cards[it_yellowcard] &&
    184 	    !p->cards[it_yellowskull])
    185 	{
    186 	    p->message = lang[PD_YELLOWO];
    187 	    S_StartSound(NULL,sfx_oof);
    188 	    return 0;
    189 	}
    190 	break;	
    191     }
    192 
    193     return EV_DoDoor(line,type);
    194 }
    195 
    196 
    197 int
    198 EV_DoDoor
    199 ( line_t*	line,
    200   vldoor_e	type )
    201 {
    202     int		secnum,rtn;
    203     sector_t*	sec;
    204     vldoor_t*	door;
    205 	
    206     secnum = -1;
    207     rtn = 0;
    208     
    209     while ((secnum = P_FindSectorFromLineTag(line,secnum)) >= 0)
    210     {
    211 	sec = &sectors[secnum];
    212 	if (sec->specialdata)
    213 	    continue;
    214 		
    215 	
    216 	
    217 	rtn = 1;
    218 	door = Z_Malloc (sizeof(*door), PU_LEVSPEC, 0);
    219 	P_AddThinker (&door->thinker);
    220 	sec->specialdata = door;
    221 
    222 	door->thinker.function.acp1 = (actionf_p1) T_VerticalDoor;
    223 	door->sector = sec;
    224 	door->type = type;
    225 	door->topwait = VDOORWAIT;
    226 	door->speed = VDOORSPEED;
    227 		
    228 	switch(type)
    229 	{
    230 	  case blazeClose:
    231 	    door->topheight = P_FindLowestCeilingSurrounding(sec);
    232 	    door->topheight -= 4*FRACUNIT;
    233 	    door->direction = -1;
    234 	    door->speed = VDOORSPEED * 4;
    235 	    S_StartSound((mobj_t *)&door->sector->soundorg,
    236 			 sfx_bdcls);
    237 	    break;
    238 	    
    239 	  case close:
    240 	    door->topheight = P_FindLowestCeilingSurrounding(sec);
    241 	    door->topheight -= 4*FRACUNIT;
    242 	    door->direction = -1;
    243 	    S_StartSound((mobj_t *)&door->sector->soundorg,
    244 			 sfx_dorcls);
    245 	    break;
    246 	    
    247 	  case close30ThenOpen:
    248 	    door->topheight = sec->ceilingheight;
    249 	    door->direction = -1;
    250 	    S_StartSound((mobj_t *)&door->sector->soundorg,
    251 			 sfx_dorcls);
    252 	    break;
    253 	    
    254 	  case blazeRaise:
    255 	  case blazeOpen:
    256 	    door->direction = 1;
    257 	    door->topheight = P_FindLowestCeilingSurrounding(sec);
    258 	    door->topheight -= 4*FRACUNIT;
    259 	    door->speed = VDOORSPEED * 4;
    260 	    if (door->topheight != sec->ceilingheight)
    261 		S_StartSound((mobj_t *)&door->sector->soundorg,
    262 			     sfx_bdopn);
    263 	    break;
    264 	    
    265 	  case normal:
    266 	  case open:
    267 	    door->direction = 1;
    268 	    door->topheight = P_FindLowestCeilingSurrounding(sec);
    269 	    door->topheight -= 4*FRACUNIT;
    270 	    if (door->topheight != sec->ceilingheight)
    271 		S_StartSound((mobj_t *)&door->sector->soundorg,
    272 			     sfx_doropn);
    273 	    break;
    274 	    
    275 	  default:
    276 	    break;
    277 	}
    278 		
    279     }
    280     return rtn;
    281 }
    282 
    283 
    284 
    285 
    286 
    287 void
    288 EV_VerticalDoor
    289 ( line_t*	line,
    290   mobj_t*	thing )
    291 {
    292     player_t*	player;
    293     sector_t*	sec;
    294     vldoor_t*	door;
    295     int		side;
    296 	
    297     side = 0;	
    298 
    299     
    300     player = thing->player;
    301 		
    302     switch(line->special)
    303     {
    304       case 26: 
    305       case 32:
    306 	if ( !player )
    307 	    return;
    308 	
    309 	if (!player->cards[it_bluecard] && !player->cards[it_blueskull])
    310 	{
    311 	    player->message = lang[PD_BLUEK];
    312 	    S_StartSound(NULL,sfx_oof);
    313 	    return;
    314 	}
    315 	break;
    316 	
    317       case 27: 
    318       case 34:
    319 	if ( !player )
    320 	    return;
    321 	
    322 	if (!player->cards[it_yellowcard] &&
    323 	    !player->cards[it_yellowskull])
    324 	{
    325 	    player->message = lang[PD_YELLOWK];
    326 	    S_StartSound(NULL,sfx_oof);
    327 	    return;
    328 	}
    329 	break;
    330 	
    331       case 28: 
    332       case 33:
    333 	if ( !player )
    334 	    return;
    335 	
    336 	if (!player->cards[it_redcard] && !player->cards[it_redskull])
    337 	{
    338 	    player->message = lang[PD_REDK];
    339 	    S_StartSound(NULL,sfx_oof);
    340 	    return;
    341 	}
    342 	break;
    343     }
    344 	
    345     
    346     sec = sides[ line->sidenum[side^1]] .sector;
    347 
    348     if (sec->specialdata)
    349     {
    350 	door = sec->specialdata;
    351 	switch(line->special)
    352 	{
    353 	  case	1: 
    354 	  case	26:
    355 	  case	27:
    356 	  case	28:
    357 	  case	117:
    358 	    if (door->direction == -1)
    359 		door->direction = 1;	
    360 	    else
    361 	    {
    362 		if (!thing->player)
    363 		    return;		
    364 		
    365 		door->direction = -1;	
    366 	    }
    367 	    return;
    368 	}
    369     }
    370 	
    371     
    372     switch(line->special)
    373     {
    374       case 117:	
    375       case 118:	
    376 	S_StartSound((mobj_t *)&sec->soundorg,sfx_bdopn);
    377 	break;
    378 	
    379       case 1:	
    380       case 31:
    381 	S_StartSound((mobj_t *)&sec->soundorg,sfx_doropn);
    382 	break;
    383 	
    384       default:	
    385 	S_StartSound((mobj_t *)&sec->soundorg,sfx_doropn);
    386 	break;
    387     }
    388 	
    389     
    390     
    391     door = Z_Malloc (sizeof(*door), PU_LEVSPEC, 0);
    392     P_AddThinker (&door->thinker);
    393     sec->specialdata = door;
    394     door->thinker.function.acp1 = (actionf_p1) T_VerticalDoor;
    395     door->sector = sec;
    396     door->direction = 1;
    397     door->speed = VDOORSPEED;
    398     door->topwait = VDOORWAIT;
    399 
    400     switch(line->special)
    401     {
    402       case 1:
    403       case 26:
    404       case 27:
    405       case 28:
    406 	door->type = normal;
    407 	break;
    408 	
    409       case 31:
    410       case 32:
    411       case 33:
    412       case 34:
    413 	door->type = open;
    414 	line->special = 0;
    415 	break;
    416 	
    417       case 117:	
    418 	door->type = blazeRaise;
    419 	door->speed = VDOORSPEED*4;
    420 	break;
    421       case 118:	
    422 	door->type = blazeOpen;
    423 	line->special = 0;
    424 	door->speed = VDOORSPEED*4;
    425 	break;
    426     }
    427     door->topheight = P_FindLowestCeilingSurrounding(sec);
    428     door->topheight -= 4*FRACUNIT;
    429 }
    430 
    431 void
    432 P_SpawnDoorCloseIn30(sector_t* sec)
    433 {
    434     vldoor_t*	door;
    435 	
    436     door = Z_Malloc ( sizeof(*door), PU_LEVSPEC, 0);
    437     P_AddThinker (&door->thinker);
    438     sec->specialdata = door;
    439     sec->special = 0;
    440     door->thinker.function.acp1 = (actionf_p1)T_VerticalDoor;
    441     door->sector = sec;
    442     door->direction = 0;
    443     door->type = normal;
    444     door->speed = VDOORSPEED;
    445     door->topcountdown = 30 * 35;
    446 }
    447 
    448 void
    449 P_SpawnDoorRaiseIn5Mins
    450 ( sector_t*	sec,
    451   int		secnum )
    452 {
    453     vldoor_t*	door;
    454 	
    455     door = Z_Malloc ( sizeof(*door), PU_LEVSPEC, 0);
    456     
    457     P_AddThinker (&door->thinker);
    458 
    459     sec->specialdata = door;
    460     sec->special = 0;
    461 
    462     door->thinker.function.acp1 = (actionf_p1)T_VerticalDoor;
    463     door->sector = sec;
    464     door->direction = 2;
    465     door->type = raiseIn5Mins;
    466     door->speed = VDOORSPEED;
    467     door->topheight = P_FindLowestCeilingSurrounding(sec);
    468     door->topheight -= 4*FRACUNIT;
    469     door->topwait = VDOORWAIT;
    470     door->topcountdown = 5 * 60 * 35;
    471 }