DOOM64-RE

DOOM 64 Reverse Engineering
Log | Files | Refs | README | LICENSE

p_floor.c (15041B)


      1 #include "doomdef.h"
      2 #include "p_local.h"
      3 
      4 /*================================================================== */
      5 /*================================================================== */
      6 /* */
      7 /*								FLOORS */
      8 /* */
      9 /*================================================================== */
     10 /*================================================================== */
     11 
     12 
     13 
     14 /*================================================================== */
     15 /* */
     16 /*	Move a plane (floor or ceiling) and check for crushing */
     17 /* */
     18 /*================================================================== */
     19 result_e	T_MovePlane(sector_t *sector,fixed_t speed,
     20 			fixed_t dest,boolean crush,int floorOrCeiling,int direction) // 800136C0
     21 {
     22 	boolean	flag;
     23 	fixed_t	lastpos;
     24 	result_e result;
     25 
     26 	result = ok;
     27 
     28 	switch(floorOrCeiling)
     29 	{
     30 		case 0:		/* FLOOR */
     31 			switch(direction)
     32 			{
     33 				case -1:	/* DOWN */
     34                     lastpos = sector->floorheight;
     35                     sector->floorheight -= speed;
     36                     if (sector->floorheight <= dest)
     37                     {
     38                         sector->floorheight = dest;
     39                         result = pastdest;
     40                     }
     41 
     42                     flag = P_ChangeSector(sector,crush);
     43                     if (flag != 0)
     44                     {
     45                         sector->floorheight = lastpos;
     46                         P_ChangeSector(sector,crush);
     47                         if (!crush)
     48                             result = stop;
     49                         else
     50                             result = crushed;
     51                     }
     52 					break;
     53 
     54 				case 1:		/* UP */
     55                     lastpos = sector->floorheight;
     56                     sector->floorheight += speed;
     57                     if (dest <= sector->floorheight)
     58                     {
     59                         sector->floorheight = dest;
     60                         result = pastdest;
     61                     }
     62 
     63                     flag = P_ChangeSector(sector,crush);
     64                     if (flag != 0)
     65                     {
     66                         sector->floorheight = lastpos;
     67                         P_ChangeSector(sector,crush);
     68                         if(!crush)
     69                             result = stop;
     70                         else
     71                             result = crushed;
     72                     }
     73 					break;
     74 			}
     75 			break;
     76 
     77 		case 1:		/* CEILING */
     78 			switch(direction)
     79 			{
     80 				case -1:	/* DOWN */
     81 
     82                     lastpos = sector->ceilingheight;
     83                     sector->ceilingheight -= speed;
     84                     if (sector->ceilingheight <= dest)
     85                     {
     86                         sector->ceilingheight = dest;
     87                         result = pastdest;
     88                     }
     89 
     90                     flag  = P_ChangeSector(sector,crush);
     91                     if (flag != 0)
     92                     {
     93                         if(crush == true && result == ok)
     94                         {
     95                             result = crushed;
     96                         }
     97                         else
     98                         {
     99                             sector->ceilingheight = lastpos;
    100                             P_ChangeSector(sector,crush);
    101                             if (result == ok)
    102                                 result = crushed;
    103                         }
    104                     }
    105 					break;
    106 
    107 				case 1:		/* UP */
    108 
    109                     lastpos = sector->ceilingheight;
    110                     sector->ceilingheight += speed;
    111                     if (dest <= sector->ceilingheight)
    112                     {
    113                         sector->ceilingheight = dest;
    114                         result = pastdest;
    115                     }
    116 
    117                     flag = P_ChangeSector(sector,false);
    118                     if ((flag != 0) && (result != 0))
    119                     {
    120                         sector->ceilingheight = lastpos;
    121                         P_ChangeSector(sector,false);
    122                     }
    123 					break;
    124 			}
    125 			break;
    126 
    127 	}
    128 
    129 	return result;
    130 }
    131 
    132 /*================================================================== */
    133 /* */
    134 /*	MOVE A FLOOR TO IT'S DESTINATION (UP OR DOWN) */
    135 /* */
    136 /*================================================================== */
    137 void T_MoveFloor(floormove_t *floor) // 80013920
    138 {
    139 	result_e	res;
    140 
    141 	res = T_MovePlane(floor->sector,floor->speed,
    142 			floor->floordestheight,floor->crush,0,floor->direction);
    143 
    144 	if (!floor->instant)
    145     {
    146         if (!(gametic&3))
    147         {
    148             S_StartSound((mobj_t *)&floor->sector->soundorg,sfx_secmove);//sfx_stnmov
    149         }
    150     }
    151 
    152 	if (res == pastdest)
    153 	{
    154 		floor->sector->specialdata = NULL;
    155 		if (floor->direction == -1)
    156         {
    157 			switch(floor->type)
    158 			{
    159 				case lowerAndChange:
    160 					floor->sector->special = floor->newspecial;
    161 					floor->sector->floorpic = floor->texture;
    162 				default:
    163 					break;
    164 			}
    165         }
    166 		P_RemoveThinker(&floor->thinker);
    167 	}
    168 
    169 }
    170 
    171 /*================================================================== */
    172 /* */
    173 /*	HANDLE FLOOR TYPES */
    174 /* */
    175 /*================================================================== */
    176 int EV_DoFloor(line_t *line,floor_e floortype,fixed_t speed) // 800139FC
    177 {
    178 	int			secnum;
    179 	int			rtn;
    180 	int			i;
    181 	sector_t	*sec;
    182 	floormove_t	*floor;
    183 
    184 	secnum = -1;
    185 	rtn = 0;
    186 	while ((secnum = P_FindSectorFromLineTag(line->tag,secnum)) >= 0)
    187 	{
    188 		sec = &sectors[secnum];
    189 
    190 		/*	ALREADY MOVING?  IF SO, KEEP GOING... */
    191 		if (sec->specialdata)
    192 			continue;
    193 
    194 		/* */
    195 		/*	new floor thinker */
    196 		/* */
    197 		rtn = 1;
    198 		floor = Z_Malloc (sizeof(*floor), PU_LEVSPEC, 0);
    199 		P_AddThinker (&floor->thinker);
    200 		sec->specialdata = floor;
    201 		floor->thinker.function = T_MoveFloor;
    202 		floor->type = floortype;
    203 		floor->crush = false;
    204 		floor->sector = sec;
    205 
    206 		if (speed == (4096 * FRACUNIT))
    207             floor->instant = true;
    208         else
    209             floor->instant = false;
    210 
    211 		switch(floortype)
    212 		{
    213 			case lowerFloor:
    214 				floor->direction = -1;
    215 				floor->speed = speed;
    216 				floor->floordestheight = P_FindHighestFloorSurrounding(sec);
    217 				break;
    218 			case lowerFloorToLowest:
    219 				floor->direction = -1;
    220 				floor->speed = speed;
    221 				floor->floordestheight = P_FindLowestFloorSurrounding(sec);
    222 				break;
    223 			case turboLower:
    224 				floor->direction = -1;
    225 				floor->speed = speed;
    226 				floor->floordestheight = P_FindHighestFloorSurrounding(sec);
    227 				if (floor->floordestheight != sec->floorheight)
    228 					floor->floordestheight += 8 * FRACUNIT;
    229 				break;
    230 			case raiseFloorCrush:
    231 				floor->crush = true;
    232 			case raiseFloor:
    233 				floor->direction = 1;
    234 				floor->speed = speed;
    235 				floor->floordestheight = P_FindLowestCeilingSurrounding(sec);
    236 				if (floor->floordestheight > sec->ceilingheight)
    237 					floor->floordestheight = sec->ceilingheight;
    238 
    239 				if (floortype == raiseFloorCrush)
    240 					floor->floordestheight -= (8 * FRACUNIT);
    241 				break;
    242 			case raiseFloorToNearest:
    243 				floor->direction = 1;
    244 				floor->speed = speed;
    245 				floor->floordestheight = P_FindNextHighestFloor(sec,sec->floorheight);
    246 				break;
    247 			case raiseFloor24:
    248 				floor->direction = 1;
    249 				floor->speed = speed;
    250 				floor->floordestheight = floor->sector->floorheight + 24 * FRACUNIT;
    251 				break;
    252 			case raiseFloor24AndChange:
    253 				floor->direction = 1;
    254 				floor->speed = speed;
    255 				floor->floordestheight = floor->sector->floorheight + 24 * FRACUNIT;
    256 				sec->floorpic = line->frontsector->floorpic;
    257 				sec->special = line->frontsector->special;
    258 				break;
    259             case customFloor:
    260                 floor->direction = (macrointeger > 0) ? 1 : -1;
    261                 floor->speed = speed;
    262                 floor->floordestheight = floor->sector->floorheight + (macrointeger * FRACUNIT);
    263                 break;
    264             case customFloorToHeight:
    265                 floor->direction = ((macrointeger*FRACUNIT) > (floor->sector->floorheight)) ? 1 : -1;
    266                 floor->speed = speed;
    267                 floor->floordestheight = (macrointeger * FRACUNIT);
    268                 break;
    269 #if 0 //Missing on D64
    270 			case raiseToTexture:
    271 				{
    272 					int	minsize = MAXINT;
    273 					side_t	*side;
    274 
    275 					floor->direction = 1;
    276 					floor->speed = speed;
    277 					for (i = 0; i < sec->linecount; i++)
    278                     {
    279 						if (twoSided (secnum, i) )
    280 						{
    281 							side = getSide(secnum,i,0);
    282 							if (side->bottomtexture >= 0)
    283 							{
    284 								if ((textures[side->bottomtexture].h << FRACBITS) < minsize)
    285 									minsize = (textures[side->bottomtexture].h << FRACBITS);
    286 							}
    287 							side = getSide(secnum,i,1);
    288 							if (side->bottomtexture >= 0)
    289 							{
    290 								if ((textures[side->bottomtexture].h << FRACBITS) < minsize)
    291 									minsize = (textures[side->bottomtexture].h << FRACBITS);
    292 							}
    293 						}
    294                     }
    295 					floor->floordestheight = floor->sector->floorheight + minsize;
    296 				}
    297 				break;
    298 #endif // 0
    299 			case lowerAndChange:
    300 				floor->direction = -1;
    301 				floor->speed = speed;
    302 				floor->floordestheight = P_FindLowestFloorSurrounding(sec);
    303 				floor->texture = sec->floorpic;
    304 				for (i = 0; i < sec->linecount; i++)
    305                 {
    306 					if ( twoSided(secnum, i) )
    307 					{
    308 						if (getSide(secnum,i,0)->sector-sectors == secnum)
    309 						{
    310 							sec = getSector(secnum,i,1);
    311 							floor->texture = sec->floorpic;
    312 							floor->newspecial = sec->special;
    313 							break;
    314 						}
    315 						else
    316 						{
    317 							sec = getSector(secnum,i,0);
    318 							floor->texture = sec->floorpic;
    319 							floor->newspecial = sec->special;
    320 							break;
    321 						}
    322 					}
    323                 }
    324 			default:
    325 				break;
    326 		}
    327 	}
    328 	return rtn;
    329 }
    330 
    331 /*================================================================== */
    332 /* */
    333 /*	BUILD A STAIRCASE! */
    334 /* */
    335 /*================================================================== */
    336 int EV_BuildStairs(line_t *line, stair_e type) // 80013DB0
    337 {
    338 	int		secnum;
    339 	int		height;
    340 	int		i;
    341 	int		newsecnum;
    342 	int		texture;
    343 	int		ok;
    344 	int		rtn;
    345 	fixed_t	stairsize;
    346     fixed_t	speed;
    347 	sector_t	*sec, *tsec;
    348 	floormove_t	*floor;
    349 
    350 
    351 	secnum = -1;
    352 	rtn = 0;
    353 	while ((secnum = P_FindSectorFromLineTag(line->tag,secnum)) >= 0)
    354 	{
    355 		sec = &sectors[secnum];
    356 
    357 		/* ALREADY MOVING?  IF SO, KEEP GOING... */
    358 		if (sec->specialdata)
    359 			continue;
    360 
    361 		/* */
    362 		/* new floor thinker */
    363 		/* */
    364 		rtn = 1;
    365 		floor = Z_Malloc (sizeof(*floor), PU_LEVSPEC, 0);
    366 		P_AddThinker (&floor->thinker);
    367 		sec->specialdata = floor;
    368 		floor->thinker.function = T_MoveFloor;
    369 		floor->direction = 1;
    370 		floor->sector = sec;
    371 		floor->instant = false;
    372 
    373 		switch (type)
    374 		{
    375 		case build8:
    376 			speed = FLOORSPEED / 2;
    377 			stairsize = 8 * FRACUNIT;
    378 			break;
    379 		case turbo16:
    380 			speed = FLOORSPEED * 2;
    381 			stairsize = 16 * FRACUNIT;
    382 			break;
    383 		}
    384 
    385 		floor->speed = speed;
    386 		height = sec->floorheight + stairsize;
    387 		floor->floordestheight = height;
    388 
    389 		texture = sec->floorpic;
    390 
    391 		/* */
    392 		/* Find next sector to raise */
    393 		/* 1.	Find 2-sided line with same sector side[0] */
    394 		/* 2.	Other side is the next sector to raise */
    395 		/* */
    396 		do
    397 		{
    398 			ok = 0;
    399 			for (i = 0;i < sec->linecount;i++)
    400 			{
    401 				if ( !((sec->lines[i])->flags & ML_TWOSIDED) )
    402 					continue;
    403 
    404 				tsec = (sec->lines[i])->frontsector;
    405 				newsecnum = tsec-sectors;
    406 				if (secnum != newsecnum)
    407 					continue;
    408 
    409 				tsec = (sec->lines[i])->backsector;
    410 				newsecnum = tsec - sectors;
    411 				if (tsec->floorpic != texture)
    412 					continue;
    413 
    414 				height += stairsize;
    415 				if (tsec->specialdata)
    416 					continue;
    417 
    418 				sec = tsec;
    419 				secnum = newsecnum;
    420 				floor = Z_Malloc (sizeof(*floor), PU_LEVSPEC, 0);
    421 				P_AddThinker (&floor->thinker);
    422 				sec->specialdata = floor;
    423 				floor->thinker.function = T_MoveFloor;
    424 				floor->direction = 1;
    425 				floor->sector = sec;
    426 				floor->speed = speed;
    427 				floor->floordestheight = height;
    428                 floor->instant = false;
    429 				ok = 1;
    430 				break;
    431 			}
    432 		} while(ok);
    433 		secnum = -1;
    434 	}
    435 	return rtn;
    436 }
    437 
    438 /*================================================================== */
    439 /* */
    440 /* T_MoveSplitPlane */
    441 /* */
    442 /*================================================================== */
    443 
    444 void T_MoveSplitPlane(splitmove_t *split) // 80014098
    445 {
    446     sector_t *sector;
    447     fixed_t lastceilpos;
    448     fixed_t lastflrpos;
    449     boolean cdone;
    450     boolean fdone;
    451 
    452     sector = split->sector;
    453     lastceilpos = sector->ceilingheight;
    454     lastflrpos = sector->floorheight;
    455     cdone = false;
    456     fdone = false;
    457 
    458     if (split->ceildir == -1)
    459     {
    460         sector->ceilingheight -= (2*FRACUNIT);
    461         if (sector->ceilingheight <= split->ceildest)
    462         {
    463             sector->ceilingheight = split->ceildest;
    464             cdone = true;
    465         }
    466     }
    467     else if (split->ceildir == 1)
    468     {
    469         sector->ceilingheight += (2*FRACUNIT);
    470         if(sector->ceilingheight >= split->ceildest)
    471         {
    472             sector->ceilingheight = split->ceildest;
    473             cdone = true;
    474         }
    475     }
    476 
    477     if (split->flrdir == -1)
    478     {
    479         sector->floorheight -= (2*FRACUNIT);
    480         if(sector->floorheight <= split->flrdest)
    481         {
    482             sector->floorheight = split->flrdest;
    483             fdone = true;
    484         }
    485     }
    486     else if (split->flrdir == 1)
    487     {
    488         sector->floorheight += (2*FRACUNIT);
    489         if(sector->floorheight >= split->flrdest)
    490         {
    491             sector->floorheight = split->flrdest;
    492             fdone = true;
    493         }
    494     }
    495 
    496     if(!P_ChangeSector(sector, false))
    497     {
    498         if(!cdone || !fdone)
    499             return;
    500 
    501         P_RemoveThinker(&split->thinker);
    502         split->sector->specialdata = NULL;
    503     }
    504     else
    505     {
    506         sector->floorheight = lastflrpos;
    507         sector->ceilingheight = lastceilpos;
    508         P_ChangeSector(sector,false);
    509     }
    510 }
    511 
    512 /*================================================================== */
    513 /* */
    514 /* EV_SplitSector */
    515 /* */
    516 /*================================================================== */
    517 
    518 int EV_SplitSector(line_t *line, boolean sync) // 80014234
    519 {
    520     int secnum;
    521     int rtn;
    522     sector_t *sec;
    523     splitmove_t *split;
    524 
    525     secnum = -1;
    526     rtn = 0;
    527 
    528     while((secnum = P_FindSectorFromLineTag(line->tag, secnum)) >= 0)
    529     {
    530         sec = &sectors[secnum];
    531 
    532         /* ALREADY MOVING?  IF SO, KEEP GOING... */
    533         if (sec->specialdata)
    534 			continue;
    535 
    536         /* */
    537 		/* new split thinker */
    538 		/* */
    539 		rtn = 1;
    540 		split = Z_Malloc (sizeof(*split), PU_LEVSPEC, 0);
    541 		P_AddThinker (&split->thinker);
    542 		sec->specialdata = split;
    543 		split->thinker.function = T_MoveSplitPlane;
    544         split->sector = sec;
    545 
    546         split->ceildest = sec->ceilingheight + (macrointeger * FRACUNIT);
    547 
    548         if(sync)
    549         {
    550             split->flrdest = sec->floorheight + (macrointeger * FRACUNIT);
    551 
    552             if (macrointeger >= 0)
    553             {
    554                 split->ceildir = 1;
    555                 split->flrdir = 1;
    556             }
    557             else
    558             {
    559                 split->ceildir = -1;
    560                 split->flrdir = -1;
    561             }
    562         }
    563         else
    564         {
    565             split->flrdest = sec->floorheight - (macrointeger * FRACUNIT);
    566 
    567             if (macrointeger >= 0)
    568             {
    569                 split->ceildir = 1;
    570                 split->flrdir = -1;
    571             }
    572             else
    573             {
    574                 split->ceildir = -1;
    575                 split->flrdir = 1;
    576             }
    577         }
    578     }
    579 
    580     return rtn;
    581 }