doom

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

p_floor.c (9930B)


      1 /*
      2 
      3 T_MovePlane
      4 Literally the same guy who wrote the P_ShootSpecialLine function
      5 
      6 */
      7 #include "z_zone.h"
      8 #include "doomdef.h"
      9 #include "p_local.h"
     10 #include "s_sound.h"
     11 #include "doomstat.h"
     12 #include "r_state.h"
     13 #include "sounds.h"
     14 
     15 result_e
     16 T_MovePlane(sector_t* sector, fixed_t speed, fixed_t dest, boolean crush, int floorOrCeiling, int direction)
     17 {
     18     boolean	flag;
     19     fixed_t	lastpos;
     20     switch (floorOrCeiling) {
     21 		case 0:
     22 			switch (direction) {
     23 				case -1:
     24 					if (sector->floorheight - speed < dest) {
     25 						lastpos = sector->floorheight;
     26 						sector->floorheight = dest;
     27 						flag = P_ChangeSector(sector,crush);
     28 						if (flag == true) {
     29 							sector->floorheight =lastpos;
     30 							P_ChangeSector(sector,crush);
     31 						}
     32 						return pastdest;
     33 					} else {
     34 						lastpos = sector->floorheight;
     35 						sector->floorheight -= speed;
     36 						flag = P_ChangeSector(sector,crush);
     37 						if (flag == true) {
     38 							sector->floorheight = lastpos;
     39 							P_ChangeSector(sector,crush);
     40 							return crushed;
     41 						}
     42 					}
     43 					break;
     44 				case 1:
     45 					if (sector->floorheight + speed > dest) {
     46 						lastpos = sector->floorheight;
     47 						sector->floorheight = dest;
     48 						flag = P_ChangeSector(sector,crush);
     49 						if (flag == true) {
     50 							sector->floorheight = lastpos;
     51 							P_ChangeSector(sector,crush);
     52 						}
     53 						return pastdest;
     54 					} else {
     55 						lastpos = sector->floorheight;
     56 						sector->floorheight += speed;
     57 						flag = P_ChangeSector(sector,crush);
     58 						if (flag == true) {
     59 							if (crush == true)
     60 								return crushed;
     61 							sector->floorheight = lastpos;
     62 							P_ChangeSector(sector, crush);
     63 							return crushed;
     64 						}
     65 					}
     66 					break;
     67 			}
     68 			break;
     69 		case 1:
     70 			switch (direction) {
     71 				case -1:
     72 					if (sector->ceilingheight - speed < dest) {
     73 						lastpos = sector->ceilingheight;
     74 						sector->ceilingheight = dest;
     75 						flag = P_ChangeSector(sector,crush);
     76 						if (flag == true) {
     77 							sector->ceilingheight = lastpos;
     78 							P_ChangeSector(sector,crush);
     79 						}
     80 						return pastdest;
     81 					} else {
     82 						lastpos = sector->ceilingheight;
     83 						sector->ceilingheight -= speed;
     84 						flag = P_ChangeSector(sector,crush);
     85 						if (flag == true) {
     86 							if (crush == true)
     87 								return crushed;
     88 							sector->ceilingheight = lastpos;
     89 							P_ChangeSector(sector,crush);
     90 							return crushed;
     91 						}
     92 					}
     93 					break;
     94 				case 1:
     95 					if (sector->ceilingheight + speed > dest) {
     96 						lastpos = sector->ceilingheight;
     97 						sector->ceilingheight = dest;
     98 						flag = P_ChangeSector(sector,crush);
     99 						if (flag == true) {
    100 							sector->ceilingheight = lastpos;
    101 							P_ChangeSector(sector,crush);
    102 						}
    103 						return pastdest;
    104 					} else {
    105 						lastpos = sector->ceilingheight;
    106 						sector->ceilingheight += speed;
    107 						flag = P_ChangeSector(sector,crush);
    108 					}
    109 					break;
    110 				}
    111 				break;
    112 	}
    113 	return ok;
    114 }
    115 
    116 
    117 
    118 
    119 
    120 				void T_MoveFloor(floormove_t* floor)
    121 				{
    122 				result_e	res;
    123 
    124     res = T_MovePlane(floor->sector,
    125 		      floor->speed,
    126 		      floor->floordestheight,
    127 		      floor->crush,0,floor->direction);
    128     
    129     if (!(leveltime&7))
    130 	S_StartSound((mobj_t *)&floor->sector->soundorg,
    131 		     sfx_stnmov);
    132     
    133     if (res == pastdest)
    134     {
    135 	floor->sector->specialdata = NULL;
    136 
    137 	if (floor->direction == 1)
    138 	{
    139 	    switch(floor->type)
    140 	    {
    141 	      case donutRaise:
    142 		floor->sector->special = floor->newspecial;
    143 		floor->sector->floorpic = floor->texture;
    144 	      default:
    145 		break;
    146 	    }
    147 	}
    148 	else if (floor->direction == -1)
    149 	{
    150 	    switch(floor->type)
    151 	    {
    152 	      case lowerAndChange:
    153 		floor->sector->special = floor->newspecial;
    154 		floor->sector->floorpic = floor->texture;
    155 	      default:
    156 		break;
    157 	    }
    158 	}
    159 	P_RemoveThinker(&floor->thinker);
    160 
    161 	S_StartSound((mobj_t *)&floor->sector->soundorg,
    162 		     sfx_pstop);
    163     }
    164 
    165 }
    166 
    167 
    168 
    169 
    170 int
    171 EV_DoFloor
    172 ( line_t*	line,
    173   floor_e	floortype )
    174 {
    175     int			secnum;
    176     int			rtn;
    177     int			i;
    178     sector_t*		sec;
    179     floormove_t*	floor;
    180 
    181     secnum = -1;
    182     rtn = 0;
    183     while ((secnum = P_FindSectorFromLineTag(line,secnum)) >= 0)
    184     {
    185 	sec = &sectors[secnum];
    186 		
    187 	
    188 	if (sec->specialdata)
    189 	    continue;
    190 	
    191 	
    192 	rtn = 1;
    193 	floor = Z_Malloc (sizeof(*floor), PU_LEVSPEC, 0);
    194 	P_AddThinker (&floor->thinker);
    195 	sec->specialdata = floor;
    196 	floor->thinker.function.acp1 = (actionf_p1) T_MoveFloor;
    197 	floor->type = floortype;
    198 	floor->crush = false;
    199 
    200 	switch(floortype)
    201 	{
    202 	  case lowerFloor:
    203 	    floor->direction = -1;
    204 	    floor->sector = sec;
    205 	    floor->speed = FLOORSPEED;
    206 	    floor->floordestheight = 
    207 		P_FindHighestFloorSurrounding(sec);
    208 	    break;
    209 
    210 	  case lowerFloorToLowest:
    211 	    floor->direction = -1;
    212 	    floor->sector = sec;
    213 	    floor->speed = FLOORSPEED;
    214 	    floor->floordestheight = 
    215 		P_FindLowestFloorSurrounding(sec);
    216 	    break;
    217 
    218 	  case turboLower:
    219 	    floor->direction = -1;
    220 	    floor->sector = sec;
    221 	    floor->speed = FLOORSPEED * 4;
    222 	    floor->floordestheight = 
    223 		P_FindHighestFloorSurrounding(sec);
    224 	    if (floor->floordestheight != sec->floorheight)
    225 		floor->floordestheight += 8*FRACUNIT;
    226 	    break;
    227 
    228 	  case raiseFloorCrush:
    229 	    floor->crush = true;
    230 	  case raiseFloor:
    231 	    floor->direction = 1;
    232 	    floor->sector = sec;
    233 	    floor->speed = FLOORSPEED;
    234 	    floor->floordestheight = 
    235 		P_FindLowestCeilingSurrounding(sec);
    236 	    if (floor->floordestheight > sec->ceilingheight)
    237 		floor->floordestheight = sec->ceilingheight;
    238 	    floor->floordestheight -= (8*FRACUNIT)*
    239 		(floortype == raiseFloorCrush);
    240 	    break;
    241 
    242 	  case raiseFloorTurbo:
    243 	    floor->direction = 1;
    244 	    floor->sector = sec;
    245 	    floor->speed = FLOORSPEED*4;
    246 	    floor->floordestheight = 
    247 		P_FindNextHighestFloor(sec,sec->floorheight);
    248 	    break;
    249 
    250 	  case raiseFloorToNearest:
    251 	    floor->direction = 1;
    252 	    floor->sector = sec;
    253 	    floor->speed = FLOORSPEED;
    254 	    floor->floordestheight = 
    255 		P_FindNextHighestFloor(sec,sec->floorheight);
    256 	    break;
    257 
    258 	  case raiseFloor24:
    259 	    floor->direction = 1;
    260 	    floor->sector = sec;
    261 	    floor->speed = FLOORSPEED;
    262 	    floor->floordestheight = floor->sector->floorheight +
    263 		24 * FRACUNIT;
    264 	    break;
    265 	  case raiseFloor512:
    266 	    floor->direction = 1;
    267 	    floor->sector = sec;
    268 	    floor->speed = FLOORSPEED;
    269 	    floor->floordestheight = floor->sector->floorheight +
    270 		512 * FRACUNIT;
    271 	    break;
    272 
    273 	  case raiseFloor24AndChange:
    274 	    floor->direction = 1;
    275 	    floor->sector = sec;
    276 	    floor->speed = FLOORSPEED;
    277 	    floor->floordestheight = floor->sector->floorheight +
    278 		24 * FRACUNIT;
    279 	    sec->floorpic = line->frontsector->floorpic;
    280 	    sec->special = line->frontsector->special;
    281 	    break;
    282 
    283 	  case raiseToTexture:
    284 	  {
    285 	      int	minsize = INT_MAX;
    286 	      side_t*	side;
    287 				
    288 	      floor->direction = 1;
    289 	      floor->sector = sec;
    290 	      floor->speed = FLOORSPEED;
    291 	      for (i = 0; i < sec->linecount; i++)
    292 	      {
    293 		  if (twoSided (secnum, i) )
    294 		  {
    295 		      side = getSide(secnum,i,0);
    296 		      if (side->bottomtexture >= 0)
    297 			  if (textureheight_g[side->bottomtexture] < 
    298 			      minsize)
    299 			      minsize = 
    300 				  textureheight_g[side->bottomtexture];
    301 		      side = getSide(secnum,i,1);
    302 		      if (side->bottomtexture >= 0)
    303 			  if (textureheight_g[side->bottomtexture] < 
    304 			      minsize)
    305 			      minsize = 
    306 				  textureheight_g[side->bottomtexture];
    307 		  }
    308 	      }
    309 	      floor->floordestheight =
    310 		  floor->sector->floorheight + minsize;
    311 	  }
    312 	  break;
    313 	  
    314 	  case lowerAndChange:
    315 	    floor->direction = -1;
    316 	    floor->sector = sec;
    317 	    floor->speed = FLOORSPEED;
    318 	    floor->floordestheight = 
    319 		P_FindLowestFloorSurrounding(sec);
    320 	    floor->texture = sec->floorpic;
    321 
    322 	    for (i = 0; i < sec->linecount; i++)
    323 	    {
    324 		if ( twoSided(secnum, i) )
    325 		{
    326 		    if (getSide(secnum,i,0)->sector-sectors == secnum)
    327 		    {
    328 			sec = getSector(secnum,i,1);
    329 
    330 			if (sec->floorheight == floor->floordestheight)
    331 			{
    332 			    floor->texture = sec->floorpic;
    333 			    floor->newspecial = sec->special;
    334 			    break;
    335 			}
    336 		    }
    337 		    else
    338 		    {
    339 			sec = getSector(secnum,i,0);
    340 
    341 			if (sec->floorheight == floor->floordestheight)
    342 			{
    343 			    floor->texture = sec->floorpic;
    344 			    floor->newspecial = sec->special;
    345 			    break;
    346 			}
    347 		    }
    348 		}
    349 	    }
    350 	  default:
    351 	    break;
    352 	}
    353     }
    354     return rtn;
    355 }
    356 
    357 int
    358 EV_BuildStairs(line_t* line, stair_e type)
    359 {
    360     int          secnum, height, i, newsecnum, texture, ok, rtn;
    361     sector_t*    sec, *tsec;
    362     floormove_t* floor;
    363     fixed_t      stairsize, speed;
    364 
    365     secnum = -1;
    366     rtn = 0;
    367     while ((secnum = P_FindSectorFromLineTag(line,secnum)) >= 0) {
    368 		sec = &sectors[secnum];
    369 		if (sec->specialdata)
    370 			continue;
    371 		rtn = 1;
    372 		floor = Z_Malloc(sizeof(*floor), PU_LEVSPEC, 0);
    373 		P_AddThinker (&floor->thinker);
    374 		sec->specialdata = floor;
    375 		floor->thinker.function.acp1 = (actionf_p1)T_MoveFloor;
    376 		floor->direction = 1;
    377 		floor->sector = sec;
    378 		switch (type) {
    379 			case build8:
    380 				speed = FLOORSPEED/4;
    381 				stairsize = 8*FRACUNIT;
    382 				break;
    383 			case turbo16:
    384 			default:
    385 				speed = FLOORSPEED*4;
    386 				stairsize = 16*FRACUNIT;
    387 				break;
    388 		}
    389 		floor->speed = speed;
    390 		height = sec->floorheight + stairsize;
    391 		floor->floordestheight = height;
    392 		texture = sec->floorpic;
    393 		do {
    394 			ok = 0;
    395 			for (i = 0; i < sec->linecount; ++i) {
    396 				if (!((sec->lines[i])->flags & ML_TWOSIDED))
    397 					continue;
    398 				tsec = (sec->lines[i])->frontsector;
    399 				newsecnum = tsec-sectors;
    400 				if (secnum != newsecnum)
    401 					continue;
    402 				tsec = (sec->lines[i])->backsector;
    403 				newsecnum = tsec - sectors;
    404 				if (tsec->floorpic != texture)
    405 					continue;
    406 				height += stairsize;
    407 				if (tsec->specialdata)
    408 					continue;
    409 				sec = tsec;
    410 				secnum = newsecnum;
    411 				floor = Z_Malloc(sizeof(*floor), PU_LEVSPEC, 0);
    412 				P_AddThinker(&floor->thinker);
    413 				sec->specialdata = floor;
    414 				floor->thinker.function.acp1 = (actionf_p1) T_MoveFloor;
    415 				floor->direction = 1;
    416 				floor->sector = sec;
    417 				floor->speed = speed;
    418 				floor->floordestheight = height;
    419 				ok = 1;
    420 				break;
    421 			}
    422 		} while (ok);
    423 	}
    424 	return rtn;
    425 }