Beispiel #1
0
//
// Do Platforms
//	[RH] Changed amount to height and added delay,
//		 lip, change, tag, and speed parameters.
//
BOOL EV_DoPlat (int tag, line_t *line, DPlat::EPlatType type, int height,
				int speed, int delay, int lip, int change)
{
	DPlat *plat;
	int secnum;
	sector_t *sec;
	int rtn = false;
	BOOL manual = false;

	// [RH] If tag is zero, use the sector on the back side
	//		of the activating line (if any).
	if (!tag)
	{
		if (!line || !(sec = line->backsector))
			return false;
		secnum = sec - sectors;
		manual = true;
		goto manual_plat;
	}

	//	Activate all <type> plats that are in_stasis
	switch (type)
	{
	case DPlat::platToggle:
		rtn = true;
	case DPlat::platPerpetualRaise:
		P_ActivateInStasis (tag);
		break;
	
	default:
		break;
	}
		
	secnum = -1;
	while ((secnum = P_FindSectorFromTag (tag, secnum)) >= 0)
	{
		sec = &sectors[secnum];

manual_plat:
		if (sec->floordata)
			continue;
		
		// Find lowest & highest floors around sector
		rtn = true;
		plat = new DPlat (sec);

		plat->m_Type = type;
		plat->m_Crush = false;
		plat->m_Tag = tag;
		plat->m_Speed = speed;
		plat->m_Wait = delay;

		//jff 1/26/98 Avoid raise plat bouncing a head off a ceiling and then
		//going down forever -- default lower to plat height when triggered
		plat->m_Low = sec->floorheight;

		if (change)
		{
			if (line)
				sec->floorpic = sides[line->sidenum[0]].sector->floorpic;
			if (change == 1)
				sec->special = 0;	// Stop damage and other stuff, if any
		}

		switch (type)
		{
		case DPlat::platRaiseAndStay:
			plat->m_High = P_FindNextHighestFloor (sec, sec->floorheight);
			plat->m_Status = DPlat::midup;
			plat->PlayPlatSound();
			break;

		case DPlat::platUpByValue:
		case DPlat::platUpByValueStay:
			plat->m_High = sec->floorheight + height;
			plat->m_Status = DPlat::midup;
			plat->PlayPlatSound();
			break;
		
		case DPlat::platDownByValue:
			plat->m_Low = sec->floorheight - height;
			plat->m_Status = DPlat::middown;
			plat->PlayPlatSound();
			break;

		case DPlat::platDownWaitUpStay:
			plat->m_Low = P_FindLowestFloorSurrounding (sec) + lip*FRACUNIT;

			if (plat->m_Low > sec->floorheight)
				plat->m_Low = sec->floorheight;

			plat->m_High = sec->floorheight;
			plat->m_Status = DPlat::down;
			plat->PlayPlatSound();
			break;
		
		case DPlat::platUpWaitDownStay:
			plat->m_High = P_FindHighestFloorSurrounding (sec);

			if (plat->m_High < sec->floorheight)
				plat->m_High = sec->floorheight;

			plat->m_Status = DPlat::up;
			plat->PlayPlatSound();
			break;

		case DPlat::platPerpetualRaise:
			plat->m_Low = P_FindLowestFloorSurrounding (sec) + lip*FRACUNIT;

			if (plat->m_Low > sec->floorheight)
				plat->m_Low = sec->floorheight;

			plat->m_High = P_FindHighestFloorSurrounding (sec);

			if (plat->m_High < sec->floorheight)
				plat->m_High = sec->floorheight;

			plat->m_Status = P_Random () & 1 ? DPlat::down : DPlat::up;

			plat->PlayPlatSound();
			break;

		case DPlat::platToggle:	//jff 3/14/98 add new type to support instant toggle
			plat->m_Crush = false;	//jff 3/14/98 crush anything in the way

			// set up toggling between ceiling, floor inclusive
			plat->m_Low = sec->ceilingheight;
			plat->m_High = sec->floorheight;
			plat->m_Status = DPlat::down;
// 			SN_StartSequence (sec, "Silence");
			break;

		case DPlat::platDownToNearestFloor:
			plat->m_Low = P_FindNextLowestFloor (sec, sec->floorheight) + lip*FRACUNIT;
			plat->m_Status = DPlat::down;
			plat->m_High = sec->floorheight;
			plat->PlayPlatSound();
			break;

		case DPlat::platDownToLowestCeiling:
		    plat->m_Low = P_FindLowestCeilingSurrounding (sec);
			plat->m_High = sec->floorheight;

			if (plat->m_Low > sec->floorheight)
				plat->m_Low = sec->floorheight;

			plat->m_Status = DPlat::down;
			plat->PlayPlatSound();
			break;

		default:
			break;
		}
		if (manual)
			return rtn;
	}
	return rtn;
}
Beispiel #2
0
//
// Handle elevator linedef types, can move floor and ceiling in parallel.
// This is from Boom.
//
int EV_DoElevator(line_t *line, elevator_e elevtype)
{
    int		secnum;
    int		rtn;
    sector_t	*sec;
    elevator_t	*elevator;

    secnum = -1;
    rtn = 0;

    // act on all sectors with the same tag as the triggering linedef
    while ((secnum = P_FindSectorFromLineTag(line, secnum)) >= 0)
    {
	sec = &sectors[secnum];

	// if either floor or ceiling is already activated, skip it
	if (sec->floordata || sec->ceilingdata)
	    continue;

	// create and initialize new elevator thinker
	rtn = 1;
	elevator = Z_Malloc(sizeof(*elevator), PU_LEVSPEC, (void *)0);
	P_AddThinker(&elevator->thinker);
	sec->floordata = elevator;
	sec->ceilingdata = elevator;
	elevator->thinker.function.acp1 = (actionf_p1)T_MoveElevator;
	elevator->type = elevtype;

	// set up the fields according to the type of elevator action
	switch (elevtype)
	{
	    // elevator down to next floor
	    case elevateDown:
		elevator->direction = -1;
		elevator->sector = sec;
		elevator->speed = ELEVATORSPEED;
		elevator->floordestheight =
		    P_FindNextLowestFloor(sec, sec->floorheight);
		elevator->ceilingdestheight =
		    elevator->floordestheight + sec->ceilingheight
		    - sec->floorheight;
		break;

	    // elevator up to next floor
	    case elevateUp:
		elevator->direction = 1;
		elevator->sector = sec;
		elevator->speed = ELEVATORSPEED;
		elevator->floordestheight =
		    P_FindNextHighestFloor(sec, sec->floorheight);
		elevator->ceilingdestheight =
		    elevator->floordestheight + sec->ceilingheight
		    - sec->floorheight;
		break;

	    // elevator to floor height of activating switch's front sector
	    case elevateCurrent:
		elevator->sector = sec;
		elevator->speed = ELEVATORSPEED;
		elevator->floordestheight = line->frontsector->floorheight;
		elevator->ceilingdestheight =
		    elevator->floordestheight + sec->ceilingheight
		    - sec->floorheight;
		elevator->direction =
		    elevator->floordestheight > sec->floorheight ? 1 : -1;
		break;
	}
    }
    return rtn;
}
DPlat::DPlat(sector_t *sec, DPlat::EPlatType type, fixed_t height,
			 int speed, int delay, fixed_t lip)
	: DMovingFloor(sec), m_Status(init)
{
	m_Type = type;
	m_Crush = false;
	m_Speed = speed;
	m_Wait = delay;
	m_Height = height;
	m_Lip = lip;

	//jff 1/26/98 Avoid raise plat bouncing a head off a ceiling and then
	//going down forever -- default lower to plat height when triggered
	m_Low = P_FloorHeight(sec);

	switch (type)
	{
	case DPlat::platRaiseAndStay:
		m_High = P_FindNextHighestFloor(sec);
		m_Status = DPlat::midup;
		PlayPlatSound();
		break;

	case DPlat::platUpByValue:
	case DPlat::platUpByValueStay:
		m_High = P_FloorHeight(sec) + height;
		m_Status = DPlat::midup;
		PlayPlatSound();
		break;
	
	case DPlat::platDownByValue:
		m_Low = P_FloorHeight(sec) - height;
		m_Status = DPlat::middown;
		PlayPlatSound();
		break;

	case DPlat::platDownWaitUpStay:
		m_Low = P_FindLowestFloorSurrounding(sec) + lip;

		if (m_Low > P_FloorHeight(sec))
			m_Low = P_FloorHeight(sec);

		m_High = P_FloorHeight(sec);
		m_Status = DPlat::down;
		PlayPlatSound();
		break;
	
	case DPlat::platUpWaitDownStay:
		m_High = P_FindHighestFloorSurrounding(sec);

		if (m_High < P_FloorHeight(sec))
			m_High = P_FloorHeight(sec);

		m_Status = DPlat::up;
		PlayPlatSound();
		break;

	case DPlat::platPerpetualRaise:
		m_Low = P_FindLowestFloorSurrounding(sec) + lip;

		if (m_Low > P_FloorHeight(sec))
			m_Low = P_FloorHeight(sec);

		m_High = P_FindHighestFloorSurrounding (sec);

		if (m_High < P_FloorHeight(sec))
			m_High = P_FloorHeight(sec);

		m_Status = P_Random () & 1 ? DPlat::down : DPlat::up;

		PlayPlatSound();
		break;

	case DPlat::platToggle:	//jff 3/14/98 add new type to support instant toggle
		m_Crush = false;	//jff 3/14/98 crush anything in the way

		// set up toggling between ceiling, floor inclusive
		m_Low = P_CeilingHeight(sec);
		m_High = P_FloorHeight(sec);
		m_Status = DPlat::down;
// 			SN_StartSequence (sec, "Silence");
		break;

	case DPlat::platDownToNearestFloor:
		m_Low = P_FindNextLowestFloor(sec) + lip;
		m_Status = DPlat::down;
		m_High = P_FloorHeight(sec);
		PlayPlatSound();
		break;

	case DPlat::platDownToLowestCeiling:
	    m_Low = P_FindLowestCeilingSurrounding (sec);
		m_High = P_FloorHeight(sec);

		if (m_Low > P_FloorHeight(sec))
			m_Low = P_FloorHeight(sec);

		m_Status = DPlat::down;
		PlayPlatSound();
		break;

	default:
		break;
	}	
}
Beispiel #4
0
//
// HANDLE FLOOR TYPES
//
int EV_DoFloor(line_t *line, floor_e floortype)
{
    int			secnum;
    int			rtn;
    int			i;
    sector_t		*sec;
    floormove_t		*floor;

    secnum = -1;
    rtn = 0;
    while ((secnum = P_FindSectorFromLineTag(line, secnum)) >= 0)
    {
	sec = &sectors[secnum];

	// ALREADY MOVING?  IF SO, KEEP GOING...
	if (sec->floordata)
	    continue;

	// new floor thinker
	rtn = 1;
	floor = Z_Malloc(sizeof(*floor), PU_LEVSPEC, (void *)0);
	P_AddThinker(&floor->thinker);
	sec->floordata = floor;
	floor->thinker.function.acp1 = (actionf_p1)T_MoveFloor;
	floor->type = floortype;
	floor->crush = false;

	switch(floortype)
	{
	  case lowerFloor:
	    floor->direction = -1;
	    floor->sector = sec;
	    floor->speed = FLOORSPEED;
	    floor->floordestheight =
		P_FindHighestFloorSurrounding(sec);
	    break;

	  case lowerFloorToLowest:
	    floor->direction = -1;
	    floor->sector = sec;
	    floor->speed = FLOORSPEED;
	    floor->floordestheight =
		P_FindLowestFloorSurrounding(sec);
	    break;

	  case lowerFloorToNearest:
	    floor->direction = -1;
	    floor->sector = sec;
	    floor->speed = FLOORSPEED;
	    floor->floordestheight =
		P_FindNextLowestFloor(sec, floor->sector->floorheight);
	    break;

	  case turboLower:
	    floor->direction = -1;
	    floor->sector = sec;
	    floor->speed = FLOORSPEED * 4;
	    floor->floordestheight =
		P_FindHighestFloorSurrounding(sec);
	    if (floor->floordestheight != sec->floorheight)
		floor->floordestheight += 8 * FRACUNIT;
	    break;

	  case raiseFloorCrush:
	    floor->crush = true;
	  case raiseFloor:
	    floor->direction = 1;
	    floor->sector = sec;
	    floor->speed = FLOORSPEED;
	    floor->floordestheight =
		P_FindLowestCeilingSurrounding(sec);
	    if (floor->floordestheight > sec->ceilingheight)
		floor->floordestheight = sec->ceilingheight;
	    floor->floordestheight -= (8 * FRACUNIT) *
		(floortype == raiseFloorCrush);
	    break;

	  case raiseFloorTurbo:
	    floor->direction = 1;
	    floor->sector = sec;
	    floor->speed = FLOORSPEED * 4;
	    floor->floordestheight =
		P_FindNextHighestFloor(sec, sec->floorheight);
	    break;

	  case raiseFloorToNearest:
	    floor->direction = 1;
	    floor->sector = sec;
	    floor->speed = FLOORSPEED;
	    floor->floordestheight =
		P_FindNextHighestFloor(sec, sec->floorheight);
	    break;

	  case raiseFloor24:
	    floor->direction = 1;
	    floor->sector = sec;
	    floor->speed = FLOORSPEED;
	    floor->floordestheight = floor->sector->floorheight +
		24 * FRACUNIT;
	    break;

	  case raiseFloor512:
	    floor->direction = 1;
	    floor->sector = sec;
	    floor->speed = FLOORSPEED;
	    floor->floordestheight = floor->sector->floorheight +
		512 * FRACUNIT;
	    break;

	  case raiseFloor24AndChange:
	    floor->direction = 1;
	    floor->sector = sec;
	    floor->speed = FLOORSPEED;
	    floor->floordestheight = floor->sector->floorheight +
		24 * FRACUNIT;
	    sec->floorpic = line->frontsector->floorpic;
	    sec->special = line->frontsector->special;
	    break;

	  case raiseToTexture:
	  {
	      int	minsize = MAXINT;
	      side_t	*side;

	      floor->direction = 1;
	      floor->sector = sec;
	      floor->speed = FLOORSPEED;
	      for (i = 0; i < sec->linecount; i++)
	      {
		  if (twoSided (secnum, i) )
		  {
		      side = getSide(secnum, i, 0);
		      if (side->bottomtexture >= 0)
			  if (textureheight[side->bottomtexture] <
			      minsize)
			      minsize =
				  textureheight[side->bottomtexture];
		      side = getSide(secnum, i, 1);
		      if (side->bottomtexture >= 0)
			  if (textureheight[side->bottomtexture] <
			      minsize)
			      minsize =
				  textureheight[side->bottomtexture];
		  }
	      }
	      floor->floordestheight =
		  floor->sector->floorheight + minsize;
	  }
	  break;

	  case lowerAndChange:
	    floor->direction = -1;
	    floor->sector = sec;
	    floor->speed = FLOORSPEED;
	    floor->floordestheight =
		P_FindLowestFloorSurrounding(sec);
	    floor->texture = sec->floorpic;

	    for (i = 0; i < sec->linecount; i++)
	    {
		if ( twoSided(secnum, i) )
		{
		    if (getSide(secnum, i, 0)->sector-sectors == secnum)
		    {
			sec = getSector(secnum, i, 1);

			if (sec->floorheight == floor->floordestheight)
			{
			    floor->texture = sec->floorpic;
			    floor->newspecial = sec->special;
			    break;
			}
		    }
		    else
		    {
			sec = getSector(secnum, i, 0);

			if (sec->floorheight == floor->floordestheight)
			{
			    floor->texture = sec->floorpic;
			    floor->newspecial = sec->special;
			    break;
			}
		    }
		}
	    }
	  default:
	    break;
	}
    }
    return rtn;
}