doom

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

p_plats.c (5553B)


      1 #include "i_system.h"
      2 #include "z_zone.h"
      3 #include "m_random.h"
      4 
      5 #include "doomdef.h"
      6 #include "p_local.h"
      7 
      8 #include "s_sound.h"
      9 
     10 
     11 #include "doomstat.h"
     12 #include "r_state.h"
     13 
     14 
     15 #include "sounds.h"
     16 
     17 
     18 plat_t*		activeplats[MAXPLATS];
     19 
     20 
     21 
     22 
     23 
     24 
     25 void T_PlatRaise(plat_t* plat)
     26 {
     27     result_e	res;
     28 	
     29     switch(plat->status)
     30     {
     31       case up:
     32 	res = T_MovePlane(plat->sector,
     33 			  plat->speed,
     34 			  plat->high,
     35 			  plat->crush,0,1);
     36 					
     37 	if (plat->type == raiseAndChange
     38 	    || plat->type == raiseToNearestAndChange)
     39 	{
     40 	    if (!(leveltime&7))
     41 		S_StartSound((mobj_t *)&plat->sector->soundorg,
     42 			     sfx_stnmov);
     43 	}
     44 	
     45 				
     46 	if (res == crushed && (!plat->crush))
     47 	{
     48 	    plat->count = plat->wait;
     49 	    plat->status = down;
     50 	    S_StartSound((mobj_t *)&plat->sector->soundorg,
     51 			 sfx_pstart);
     52 	}
     53 	else
     54 	{
     55 	    if (res == pastdest)
     56 	    {
     57 		plat->count = plat->wait;
     58 		plat->status = waiting;
     59 		S_StartSound((mobj_t *)&plat->sector->soundorg,
     60 			     sfx_pstop);
     61 
     62 		switch(plat->type)
     63 		{
     64 		  case blazeDWUS:
     65 		  case downWaitUpStay:
     66 		    P_RemoveActivePlat(plat);
     67 		    break;
     68 		    
     69 		  case raiseAndChange:
     70 		  case raiseToNearestAndChange:
     71 		    P_RemoveActivePlat(plat);
     72 		    break;
     73 		    
     74 		  default:
     75 		    break;
     76 		}
     77 	    }
     78 	}
     79 	break;
     80 	
     81       case	down:
     82 	res = T_MovePlane(plat->sector,plat->speed,plat->low,false,0,-1);
     83 
     84 	if (res == pastdest)
     85 	{
     86 	    plat->count = plat->wait;
     87 	    plat->status = waiting;
     88 	    S_StartSound((mobj_t *)&plat->sector->soundorg,sfx_pstop);
     89 	}
     90 	break;
     91 	
     92       case	waiting:
     93 	if (!--plat->count)
     94 	{
     95 	    if (plat->sector->floorheight == plat->low)
     96 		plat->status = up;
     97 	    else
     98 		plat->status = down;
     99 	    S_StartSound((mobj_t *)&plat->sector->soundorg,sfx_pstart);
    100 	}
    101       case	in_stasis:
    102 	break;
    103     }
    104 }
    105 
    106 
    107 
    108 
    109 
    110 
    111 int
    112 EV_DoPlat
    113 ( line_t*	line,
    114   plattype_e	type,
    115   int		amount )
    116 {
    117     plat_t*	plat;
    118     int		secnum;
    119     int		rtn;
    120     sector_t*	sec;
    121 	
    122     secnum = -1;
    123     rtn = 0;
    124 
    125     
    126     
    127     switch(type)
    128     {
    129       case perpetualRaise:
    130 	P_ActivateInStasis(line->tag);
    131 	break;
    132 	
    133       default:
    134 	break;
    135     }
    136 	
    137     while ((secnum = P_FindSectorFromLineTag(line,secnum)) >= 0)
    138     {
    139 	sec = &sectors[secnum];
    140 
    141 	if (sec->specialdata)
    142 	    continue;
    143 	
    144 	
    145 	rtn = 1;
    146 	plat = Z_Malloc( sizeof(*plat), PU_LEVSPEC, 0);
    147 	P_AddThinker(&plat->thinker);
    148 		
    149 	plat->type = type;
    150 	plat->sector = sec;
    151 	plat->sector->specialdata = plat;
    152 	plat->thinker.function.acp1 = (actionf_p1) T_PlatRaise;
    153 	plat->crush = false;
    154 	plat->tag = line->tag;
    155 	
    156 	switch(type)
    157 	{
    158 	  case raiseToNearestAndChange:
    159 	    plat->speed = PLATSPEED/2;
    160 	    sec->floorpic = sides[line->sidenum[0]].sector->floorpic;
    161 	    plat->high = P_FindNextHighestFloor(sec,sec->floorheight);
    162 	    plat->wait = 0;
    163 	    plat->status = up;
    164 	    
    165 	    sec->special = 0;		
    166 
    167 	    S_StartSound((mobj_t *)&sec->soundorg,sfx_stnmov);
    168 	    break;
    169 	    
    170 	  case raiseAndChange:
    171 	    plat->speed = PLATSPEED/2;
    172 	    sec->floorpic = sides[line->sidenum[0]].sector->floorpic;
    173 	    plat->high = sec->floorheight + amount*FRACUNIT;
    174 	    plat->wait = 0;
    175 	    plat->status = up;
    176 
    177 	    S_StartSound((mobj_t *)&sec->soundorg,sfx_stnmov);
    178 	    break;
    179 	    
    180 	  case downWaitUpStay:
    181 	    plat->speed = PLATSPEED * 4;
    182 	    plat->low = P_FindLowestFloorSurrounding(sec);
    183 
    184 	    if (plat->low > sec->floorheight)
    185 		plat->low = sec->floorheight;
    186 
    187 	    plat->high = sec->floorheight;
    188 	    plat->wait = 35*PLATWAIT;
    189 	    plat->status = down;
    190 	    S_StartSound((mobj_t *)&sec->soundorg,sfx_pstart);
    191 	    break;
    192 	    
    193 	  case blazeDWUS:
    194 	    plat->speed = PLATSPEED * 8;
    195 	    plat->low = P_FindLowestFloorSurrounding(sec);
    196 
    197 	    if (plat->low > sec->floorheight)
    198 		plat->low = sec->floorheight;
    199 
    200 	    plat->high = sec->floorheight;
    201 	    plat->wait = 35*PLATWAIT;
    202 	    plat->status = down;
    203 	    S_StartSound((mobj_t *)&sec->soundorg,sfx_pstart);
    204 	    break;
    205 	    
    206 	  case perpetualRaise:
    207 	    plat->speed = PLATSPEED;
    208 	    plat->low = P_FindLowestFloorSurrounding(sec);
    209 
    210 	    if (plat->low > sec->floorheight)
    211 		plat->low = sec->floorheight;
    212 
    213 	    plat->high = P_FindHighestFloorSurrounding(sec);
    214 
    215 	    if (plat->high < sec->floorheight)
    216 		plat->high = sec->floorheight;
    217 
    218 	    plat->wait = 35*PLATWAIT;
    219 	    plat->status = P_Random()&1;
    220 
    221 	    S_StartSound((mobj_t *)&sec->soundorg,sfx_pstart);
    222 	    break;
    223 	}
    224 	P_AddActivePlat(plat);
    225     }
    226     return rtn;
    227 }
    228 
    229 
    230 
    231 void P_ActivateInStasis(int tag)
    232 {
    233     int		i;
    234 	
    235     for (i = 0;i < MAXPLATS;i++)
    236 	if (activeplats[i]
    237 	    && (activeplats[i])->tag == tag
    238 	    && (activeplats[i])->status == in_stasis)
    239 	{
    240 	    (activeplats[i])->status = (activeplats[i])->oldstatus;
    241 	    (activeplats[i])->thinker.function.acp1
    242 	      = (actionf_p1) T_PlatRaise;
    243 	}
    244 }
    245 
    246 void EV_StopPlat(line_t* line)
    247 {
    248     int		j;
    249 	
    250     for (j = 0;j < MAXPLATS;j++)
    251 	if (activeplats[j]
    252 	    && ((activeplats[j])->status != in_stasis)
    253 	    && ((activeplats[j])->tag == line->tag))
    254 	{
    255 	    (activeplats[j])->oldstatus = (activeplats[j])->status;
    256 	    (activeplats[j])->status = in_stasis;
    257 	    (activeplats[j])->thinker.function.acv = (actionf_v)NULL;
    258 	}
    259 }
    260 
    261 void P_AddActivePlat(plat_t* plat)
    262 {
    263     int		i;
    264     
    265     for (i = 0;i < MAXPLATS;i++)
    266 	if (activeplats[i] == NULL)
    267 	{
    268 	    activeplats[i] = plat;
    269 	    return;
    270 	}
    271     I_Error ("P_AddActivePlat: no more plats!");
    272 }
    273 
    274 void P_RemoveActivePlat(plat_t* plat)
    275 {
    276     int		i;
    277     for (i = 0;i < MAXPLATS;i++)
    278 	if (plat == activeplats[i])
    279 	{
    280 	    (activeplats[i])->sector->specialdata = NULL;
    281 	    P_RemoveThinker(&(activeplats[i])->thinker);
    282 	    activeplats[i] = NULL;
    283 	    
    284 	    return;
    285 	}
    286     I_Error ("P_RemoveActivePlat: can't find plat!");
    287 }