Ejemplo n.º 1
0
//
// EV_DoCeiling
// Move a ceiling up/down and all around!
//
// [RH] Added tag, speed, speed2, height, crush, silent, change params
BOOL EV_DoCeiling (DCeiling::ECeiling type, line_t *line,
				   int tag, fixed_t speed, fixed_t speed2, fixed_t height,
				   bool crush, int silent, int change)
{
	int 		secnum;
	BOOL 		rtn;
	sector_t*	sec;
	DCeiling*	ceiling;
	BOOL		manual = false;
	fixed_t		targheight = 0;

	rtn = false;

	// check if a manual trigger, if so do just the sector on the backside
	if (tag == 0)
	{
		if (!line || !(sec = line->backsector))
			return rtn;
		secnum = sec-sectors;
		manual = true;
		// [RH] Hack to let manual crushers be retriggerable, too
		tag ^= secnum | 0x1000000;
		P_ActivateInStasisCeiling (tag);
		goto manual_ceiling;
	}

	//	Reactivate in-stasis ceilings...for certain types.
	// This restarts a crusher after it has been stopped
	if (type == DCeiling::ceilCrushAndRaise)
	{
		P_ActivateInStasisCeiling (tag);
	}

	secnum = -1;
	// affects all sectors with the same tag as the linedef
	while ((secnum = P_FindSectorFromTag (tag, secnum)) >= 0)
	{
		sec = &sectors[secnum];
manual_ceiling:
		// if ceiling already moving, don't start a second function on it
		if (sec->ceilingdata)
			continue;

		// new door thinker
		rtn = 1;
		ceiling = new DCeiling (sec, speed, speed2, silent);

		switch (type)
		{
		case DCeiling::ceilCrushAndRaise:
		case DCeiling::ceilCrushRaiseAndStay:
			ceiling->m_TopHeight = sec->ceilingheight;
		case DCeiling::ceilLowerAndCrush:
			ceiling->m_Crush = crush;
			targheight = ceiling->m_BottomHeight = sec->floorheight + 8*FRACUNIT;
			ceiling->m_Direction = -1;
			break;

		case DCeiling::ceilRaiseToHighest:
			targheight = ceiling->m_TopHeight = P_FindHighestCeilingSurrounding (sec);
			ceiling->m_Direction = 1;
			break;

		case DCeiling::ceilLowerByValue:
			targheight = ceiling->m_BottomHeight = sec->ceilingheight - height;
			ceiling->m_Direction = -1;
			break;

		case DCeiling::ceilRaiseByValue:
			targheight = ceiling->m_TopHeight = sec->ceilingheight + height;
			ceiling->m_Direction = 1;
			break;

		case DCeiling::ceilMoveToValue:
			{
			  int diff = height - sec->ceilingheight;

			  if (diff < 0) {
				  targheight = ceiling->m_BottomHeight = height;
				  ceiling->m_Direction = -1;
			  } else {
				  targheight = ceiling->m_TopHeight = height;
				  ceiling->m_Direction = 1;
			  }
			}
			break;

		case DCeiling::ceilLowerToHighestFloor:
			targheight = ceiling->m_BottomHeight = P_FindHighestFloorSurrounding (sec);
			ceiling->m_Direction = -1;
			break;

		case DCeiling::ceilRaiseToHighestFloor:
			targheight = ceiling->m_TopHeight = P_FindHighestFloorSurrounding (sec);
			ceiling->m_Direction = 1;
			break;

		case DCeiling::ceilLowerInstant:
			targheight = ceiling->m_BottomHeight = sec->ceilingheight - height;
			ceiling->m_Direction = -1;
			ceiling->m_Speed = height;
			break;

		case DCeiling::ceilRaiseInstant:
			targheight = ceiling->m_TopHeight = sec->ceilingheight + height;
			ceiling->m_Direction = 1;
			ceiling->m_Speed = height;
			break;

		case DCeiling::ceilLowerToNearest:
			targheight = ceiling->m_BottomHeight =
				P_FindNextLowestCeiling (sec, sec->ceilingheight);
			ceiling->m_Direction = 1;
			break;

		case DCeiling::ceilRaiseToNearest:
			targheight = ceiling->m_TopHeight =
				P_FindNextHighestCeiling (sec, sec->ceilingheight);
			ceiling->m_Direction = 1;
			break;

		case DCeiling::ceilLowerToLowest:
			targheight = ceiling->m_BottomHeight = P_FindLowestCeilingSurrounding (sec);
			ceiling->m_Direction = -1;
			break;

		case DCeiling::ceilRaiseToLowest:
			targheight = ceiling->m_TopHeight = P_FindLowestCeilingSurrounding (sec);
			ceiling->m_Direction = -1;
			break;

		case DCeiling::ceilLowerToFloor:
			targheight = ceiling->m_BottomHeight = sec->floorheight;
			ceiling->m_Direction = -1;
			break;

		case DCeiling::ceilRaiseToFloor:
			targheight = ceiling->m_TopHeight = sec->floorheight;
			ceiling->m_Direction = 1;
			break;

		case DCeiling::ceilLowerToHighest:
			targheight = ceiling->m_BottomHeight = P_FindHighestCeilingSurrounding (sec);
			ceiling->m_Direction = -1;
			break;

		case DCeiling::ceilLowerByTexture:
			targheight = ceiling->m_BottomHeight =
				sec->ceilingheight - P_FindShortestUpperAround (secnum);
			ceiling->m_Direction = -1;
			break;

		case DCeiling::ceilRaiseByTexture:
			targheight = ceiling->m_TopHeight =
				sec->ceilingheight + P_FindShortestUpperAround (secnum);
			ceiling->m_Direction = 1;
			break;

		case DCeiling::genCeilingChg0: // denis - fixme - will these need code?
		case DCeiling::genCeilingChgT:
		case DCeiling::genCeilingChg:
			break;
		}

		ceiling->m_Tag = tag;
		ceiling->m_Type = type;

		// set texture/type change properties
		if (change & 3)		// if a texture change is indicated
		{
			if (change & 4)	// if a numeric model change
			{
				sector_t *sec;

				//jff 5/23/98 find model with floor at target height if target
				//is a floor type
				sec = (type == DCeiling::ceilRaiseToHighest ||
					   type == DCeiling::ceilRaiseToFloor ||
					   type == DCeiling::ceilLowerToHighest ||
					   type == DCeiling::ceilLowerToFloor) ?
					P_FindModelFloorSector (targheight, secnum) :
					P_FindModelCeilingSector (targheight, secnum);
				if (sec)
				{
					ceiling->m_Texture = sec->ceilingpic;
					switch (change & 3)
					{
						case 1:		// type is zeroed
							ceiling->m_NewSpecial = 0;
							ceiling->m_Type = DCeiling::genCeilingChg0;
							break;
						case 2:		// type is copied
							ceiling->m_NewSpecial = sec->special;
							ceiling->m_Type = DCeiling::genCeilingChgT;
							break;
						case 3:		// type is left alone
							ceiling->m_Type = DCeiling::genCeilingChg;
							break;
					}
				}
			}
			else if (line)	// else if a trigger model change
			{

				ceiling->m_Texture = line->frontsector->ceilingpic;
				switch (change & 3)
				{
					case 1:		// type is zeroed
						ceiling->m_NewSpecial = 0;
						ceiling->m_Type = DCeiling::genCeilingChg0;
						break;
					case 2:		// type is copied
						ceiling->m_NewSpecial = line->frontsector->special;
						ceiling->m_Type = DCeiling::genCeilingChgT;
						break;
					case 3:		// type is left alone
						ceiling->m_Type = DCeiling::genCeilingChg;
						break;
				}
			}
		}

		ceiling->PlayCeilingSound ();

		if (manual)
			return rtn;
	}
	return rtn;
}
Ejemplo n.º 2
0
//
// EV_DoCeiling
// Move a ceiling up/down and all around!
//
int
EV_DoCeiling
( line_t*		line,
  ceiling_e		type )
{
	int			secnum;
	int			rtn;
	sector_t*	sec;
	ceiling_t*	ceiling;
		
	secnum = -1;
	rtn = 0;
	
	//	Reactivate in-stasis ceilings...for certain types.
	switch(type)
	{
	  case fastCrushAndRaise:
	  case silentCrushAndRaise:
	  case crushAndRaise:
		P_ActivateInStasisCeiling(line);
	  default:
		break;
	}
		
	while ((secnum = P_FindSectorFromLineTag(line,secnum)) >= 0)
	{
		sec = &sectors[secnum];
		if (sec->specialdata)
			continue;
		
		// new door thinker
		rtn = 1;
		ceiling = Z_Malloc (sizeof(*ceiling), PU_LEVSPEC, 0);
		P_AddThinker (&ceiling->thinker);
		sec->specialdata = ceiling;
		ceiling->thinker.function.acp1 = (actionf_p1)T_MoveCeiling;
		ceiling->sector = sec;
		ceiling->crush = false;
		
		switch(type)
		{
		  case fastCrushAndRaise:
			ceiling->crush = true;
			ceiling->topheight = sec->ceilingheight;
			ceiling->bottomheight = sec->floorheight + (8*FRACUNIT);
			ceiling->direction = -1;
			ceiling->speed = CEILSPEED * 2;
			break;

		  case silentCrushAndRaise:
		  case crushAndRaise:
			ceiling->crush = true;
			ceiling->topheight = sec->ceilingheight;
		  case lowerAndCrush:
		  case lowerToFloor:
			ceiling->bottomheight = sec->floorheight;
			if (type != lowerToFloor)
				ceiling->bottomheight += 8*FRACUNIT;
			ceiling->direction = -1;
			ceiling->speed = CEILSPEED;
			break;

		  case raiseToHighest:
			ceiling->topheight = P_FindHighestCeilingSurrounding(sec);
			ceiling->direction = 1;
			ceiling->speed = CEILSPEED;
			break;
		}
				
		ceiling->tag = sec->tag;
		ceiling->type = type;
		P_AddActiveCeiling(ceiling);
	}
	return rtn;
}
Ejemplo n.º 3
0
//
// EV_DoCeiling
// Move a ceiling up/down and all around!
//
// haleyjd 10/04/10: [STRIFE] Changes:
// * Fast crushers were made 2x as fast.
// * lowerAndCrush was apparently "fixed" to actually crush, and was also
//   altered to lower all the way to the floor rather than remain 8 above.
// * silentCrushAndRaise and crushAndRaise no longer crush.
int
EV_DoCeiling
( line_t*       line,
  ceiling_e     type )
{
    int         secnum;
    int         rtn;
    sector_t*   sec;
    ceiling_t*  ceiling;

    secnum = -1;
    rtn = 0;

    //	Reactivate in-stasis ceilings...for certain types.
    switch(type)
    {
    case fastCrushAndRaise:
    case silentCrushAndRaise:
    case crushAndRaise:
        P_ActivateInStasisCeiling(line);
    default:
        break;
    }

    while ((secnum = P_FindSectorFromLineTag(line,secnum)) >= 0)
    {
        sec = &sectors[secnum];
        if (sec->specialdata)
            continue;

        // new door thinker
        rtn = 1;
        ceiling = Z_Malloc (sizeof(*ceiling), PU_LEVSPEC, 0);
        P_AddThinker (&ceiling->thinker);
        sec->specialdata = ceiling;
        ceiling->thinker.function.acp1 = (actionf_p1)T_MoveCeiling;
        ceiling->sector = sec;
        ceiling->crush = false;

        switch(type)
        {
        case fastCrushAndRaise:
            // [STRIFE]: Speed of fast crushers increased by 2x!
            ceiling->crush = true;
            ceiling->topheight = sec->ceilingheight;
            ceiling->bottomheight = sec->floorheight + (8*FRACUNIT);
            ceiling->direction = -1;
            ceiling->speed = CEILSPEED * 4; // [STRIFE] Was CEILSPEED * 2
            break;

        case lowerAndCrush:
            // [STRIFE] lowerAndCrush doesn't seem to have crushed in DOOM,
            // but it was certainly made to do so in Strife! It is also
            // changed to lower all the way to the floor.
            ceiling->crush = 1;
            ceiling->direction = -1;
            ceiling->speed = CEILSPEED;
            ceiling->bottomheight = sec->floorheight;
            break;

        case silentCrushAndRaise:
        case crushAndRaise:
            // [STRIFE] haleyjd 20130209: Turns out these types do NOT crush
            // in Strife... yeah, that makes a lot of sense. Thanks to Gez for
            // having detected this difference.
            //ceiling->crush = true;
            ceiling->topheight = sec->ceilingheight;

        case lowerToFloor:
            ceiling->bottomheight = sec->floorheight;
            if (type != lowerToFloor)
                ceiling->bottomheight += 8*FRACUNIT;
            ceiling->direction = -1;
            ceiling->speed = CEILSPEED;
            break;

        case raiseToHighest:
            ceiling->topheight = P_FindHighestCeilingSurrounding(sec);
            ceiling->direction = 1;
            ceiling->speed = CEILSPEED;
            break;
        }

        ceiling->tag = sec->tag;
        ceiling->type = type;
        P_AddActiveCeiling(ceiling);
    }
    return rtn;
}
Ejemplo n.º 4
0
//
// EV_DoCeiling
//
// Move a ceiling up/down or start a crusher
//
// Passed the linedef activating the function and the type of function desired
// returns true if a thinker started
//
int EV_DoCeiling
(line_t* line,
 ceiling_e type)
{
  int   secnum;
  int   rtn;
  sector_t* sec;
  ceiling_t*  ceiling;

  secnum = -1;
  rtn = 0;

  // Reactivate in-stasis ceilings...for certain types.
  // This restarts a crusher after it has been stopped
  switch (type)
  {
  case fastCrushAndRaise:
  case silentCrushAndRaise:
  case crushAndRaise:
    //jff 4/5/98 return if activated
    rtn = P_ActivateInStasisCeiling(line);
  default:
    break;
  }

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

    // if ceiling already moving, don't start a second function on it
    if (P_SectorActive(ceiling_special, sec)) //jff 2/22/98
      continue;

    // create a new ceiling thinker
    rtn = 1;
    ceiling = Z_Malloc(sizeof(*ceiling), PU_LEVSPEC, 0);
    P_AddThinker(&ceiling->thinker);
    sec->ceilingdata = ceiling;               //jff 2/22/98
    ceiling->thinker.function = T_MoveCeiling;
    ceiling->sector = sec;
    ceiling->crush = false;

    // setup ceiling structure according to type of function
    switch (type)
    {
    case fastCrushAndRaise:
      ceiling->crush = true;
      ceiling->topheight = sec->ceilingheight;
      ceiling->bottomheight = sec->floorheight + (8 * FRACUNIT);
      ceiling->direction = -1;
      ceiling->speed = CEILSPEED * 2;
      break;

    case silentCrushAndRaise:
    case crushAndRaise:
      ceiling->crush = true;
      ceiling->topheight = sec->ceilingheight;
    case lowerAndCrush:
    case lowerToFloor:
      ceiling->bottomheight = sec->floorheight;
      if (type != lowerToFloor)
        ceiling->bottomheight += 8 * FRACUNIT;
      ceiling->direction = -1;
      ceiling->speed = CEILSPEED;
      break;

    case raiseToHighest:
      ceiling->topheight = P_FindHighestCeilingSurrounding(sec);
      ceiling->direction = 1;
      ceiling->speed = CEILSPEED;
      break;

    case lowerToLowest:
      ceiling->bottomheight = P_FindLowestCeilingSurrounding(sec);
      ceiling->direction = -1;
      ceiling->speed = CEILSPEED;
      break;

    case lowerToMaxFloor:
      ceiling->bottomheight = P_FindHighestFloorSurrounding(sec);
      ceiling->direction = -1;
      ceiling->speed = CEILSPEED;
      break;

    default:
      break;
    }

    // add the ceiling to the active list
    ceiling->tag = sec->tag;
    ceiling->type = type;
    P_AddActiveCeiling(ceiling);
  }
  return rtn;
}
Ejemplo n.º 5
0
int EV_OpenPillar(line_t *line, byte *args)
{
	int secnum;
	sector_t *sec;
	pillar_t *pillar;
	int rtn;

	rtn = 0;
	secnum = -1;
	while((secnum = P_FindSectorFromTag(args[0], secnum)) >= 0)
	{
		sec = &sectors[secnum];
		if(sec->specialdata)
			continue; // already moving
		if(sec->floorheight != sec->ceilingheight)
		{ // pillar isn't closed
			continue;
		}
		rtn = 1;
		pillar = Z_Malloc(sizeof(*pillar), PU_LEVSPEC, 0);
		sec->specialdata = pillar;
		P_AddThinker(&pillar->thinker);
		pillar->thinker.function = T_BuildPillar;
		pillar->sector = sec;
		if(!args[2])
		{
			pillar->floordest = P_FindLowestFloorSurrounding(sec);
		}
		else
		{
			pillar->floordest = sec->floorheight-(args[2]<<FRACBITS);
		}
		if(!args[3])
		{
			pillar->ceilingdest = P_FindHighestCeilingSurrounding(sec);
		}
		else
		{
			pillar->ceilingdest = sec->ceilingheight+(args[3]<<FRACBITS);
		}
		if(sec->floorheight-pillar->floordest >= pillar->ceilingdest-
			sec->ceilingheight)
		{
			pillar->floorSpeed = args[1]*(FRACUNIT/8);
			pillar->ceilingSpeed = FixedMul(sec->ceilingheight-
				pillar->ceilingdest, FixedDiv(pillar->floorSpeed,
				pillar->floordest-sec->floorheight));
		}
		else
		{
			pillar->ceilingSpeed = args[1]*(FRACUNIT/8);
			pillar->floorSpeed = FixedMul(pillar->floordest-sec->floorheight,
				FixedDiv(pillar->ceilingSpeed, sec->ceilingheight-
				pillar->ceilingdest));
		}
		pillar->direction = -1; // open the pillar
		SN_StartSequence((mobj_t *)&pillar->sector->soundorg, 
			SEQ_PLATFORM+pillar->sector->seqType);
	}
	return rtn;
}
Ejemplo n.º 6
0
//
// EV_DoCeiling
//
// Move a ceiling up/down or start a crusher
//
// Passed the linedef activating the function and the type of function desired
// returns true if a thinker started
//
int EV_DoCeiling(const line_t *line, ceiling_e type)
{
   int       secnum = -1;
   int       rtn = 0;
   int       noise = CNOISE_NORMAL; // haleyjd 09/28/06
   sector_t  *sec;
   CeilingThinker *ceiling;
      
   // Reactivate in-stasis ceilings...for certain types.
   // This restarts a crusher after it has been stopped
   switch(type)
   {
   case fastCrushAndRaise:
   case silentCrushAndRaise:
   case crushAndRaise:
      //jff 4/5/98 return if activated
      rtn = P_ActivateInStasisCeiling(line, line->tag);
   default:
      break;
   }
  
   // affects all sectors with the same tag as the linedef
   while((secnum = P_FindSectorFromLineTag(line,secnum)) >= 0)
   {
      sec = &sectors[secnum];
      
      // if ceiling already moving, don't start a second function on it
      if(P_SectorActive(ceiling_special, sec))  //jff 2/22/98
         continue;
  
      // create a new ceiling thinker
      rtn = 1;
      ceiling = new CeilingThinker;
      ceiling->addThinker();
      sec->ceilingdata = ceiling;               //jff 2/22/98
      ceiling->sector = sec;
      ceiling->crush = -1;
      ceiling->crushflags = 0;   // ioanch 20160305
  
      // setup ceiling structure according to type of function
      switch(type)
      {
      case fastCrushAndRaise:
         ceiling->crush = 10;
         ceiling->topheight = sec->ceilingheight;
         ceiling->bottomheight = sec->floorheight + (8*FRACUNIT);
         ceiling->direction = plat_down;
         ceiling->speed = CEILSPEED * 2;
         break;

      case silentCrushAndRaise:
         noise = CNOISE_SEMISILENT;
      case crushAndRaise:
         ceiling->crush = 10;
         ceiling->topheight = sec->ceilingheight;
      case lowerAndCrush:
      case lowerToFloor:
         ceiling->bottomheight = sec->floorheight;
         if(type != lowerToFloor)
            ceiling->bottomheight += 8*FRACUNIT;
         ceiling->direction = plat_down;
         ceiling->speed = CEILSPEED;
         break;

      case raiseToHighest:
         ceiling->topheight = P_FindHighestCeilingSurrounding(sec);
         ceiling->direction = plat_up;
         ceiling->speed = CEILSPEED;
         break;
         
      case lowerToLowest:
         ceiling->bottomheight = P_FindLowestCeilingSurrounding(sec);
         ceiling->direction = plat_down;
         ceiling->speed = CEILSPEED;
         break;
         
      case lowerToMaxFloor:
         ceiling->bottomheight = P_FindHighestFloorSurrounding(sec);
         ceiling->direction = plat_down;
         ceiling->speed = CEILSPEED;
         break;
         
      default:
         break;
      }
    
      // add the ceiling to the active list
      ceiling->tag = sec->tag;
      ceiling->type = type;
      P_AddActiveCeiling(ceiling);

      // haleyjd 09/28/06: sound sequences
      P_CeilingSequence(ceiling->sector, noise);
   }
   return rtn;
}
Ejemplo n.º 7
0
//==================================================================
//
//              EV_DoCeiling
//              Move a ceiling up/down and all around!
//
//==================================================================
int EV_DoCeiling(line_t *line, byte *arg, ceiling_e type)
{
	int     secnum, rtn;
	sector_t *sec;
	ceiling_t *ceiling;

	secnum = -1;
	rtn = 0;

	/* Old Ceiling stasis code
	   //
	   //      Reactivate in-stasis ceilings...for certain types.
	   //
	   switch(type)
	   {
	   case CLEV_CRUSHANDRAISE:
	   P_ActivateInStasisCeiling(line);
	   default:
	   break;
	   }
	 */
	while((secnum = P_FindSectorFromTag(arg[0], secnum)) >= 0)
	{
		sec = &sectors[secnum];
		if(sec->specialdata)
			continue;

		//
		// new door thinker
		//
		rtn = 1;
		ceiling = Z_Malloc(sizeof(*ceiling), PU_LEVSPEC, 0);
		P_AddThinker(&ceiling->thinker);
		sec->specialdata = ceiling;
		ceiling->thinker.function = T_MoveCeiling;
		ceiling->sector = sec;
		ceiling->crush = 0;
		ceiling->speed = arg[1] * (FRACUNIT / 8);
		switch (type)
		{
		case CLEV_CRUSHRAISEANDSTAY:
			ceiling->crush = arg[2];	// arg[2] = crushing value
			ceiling->topheight = sec->ceilingheight;
			ceiling->bottomheight = sec->floorheight + (8 * FRACUNIT);
			ceiling->direction = -1;
			break;
		case CLEV_CRUSHANDRAISE:
			ceiling->topheight = sec->ceilingheight;
		case CLEV_LOWERANDCRUSH:
			ceiling->crush = arg[2];	// arg[2] = crushing value
		case CLEV_LOWERTOFLOOR:
			ceiling->bottomheight = sec->floorheight;
			if(type != CLEV_LOWERTOFLOOR)
			{
				ceiling->bottomheight += 8 * FRACUNIT;
			}
			ceiling->direction = -1;
			break;
		case CLEV_RAISETOHIGHEST:
			ceiling->topheight = P_FindHighestCeilingSurrounding(sec);
			ceiling->direction = 1;
			break;
		case CLEV_LOWERBYVALUE:
			ceiling->bottomheight = sec->ceilingheight - arg[2] * FRACUNIT;
			ceiling->direction = -1;
			break;
		case CLEV_RAISEBYVALUE:
			ceiling->topheight = sec->ceilingheight + arg[2] * FRACUNIT;
			ceiling->direction = 1;
			break;
		case CLEV_MOVETOVALUETIMES8:
			{
				int     destHeight = arg[2] * FRACUNIT * 8;

				if(arg[3])
				{
					destHeight = -destHeight;
				}
				if(sec->ceilingheight <= destHeight)
				{
					ceiling->direction = 1;
					ceiling->topheight = destHeight;
					if(sec->ceilingheight == destHeight)
					{
						rtn = 0;
					}
				}
				else if(sec->ceilingheight > destHeight)
				{
					ceiling->direction = -1;
					ceiling->bottomheight = destHeight;
				}
				break;
			}
		default:
			rtn = 0;
			break;
		}
		ceiling->tag = sec->tag;
		ceiling->type = type;
		P_AddActiveCeiling(ceiling);
		if(rtn)
		{
			SN_StartSequence((mobj_t *) &ceiling->sector->soundorg,
							 SEQ_PLATFORM + ceiling->sector->seqType);
		}
	}
	return rtn;
}
Ejemplo n.º 8
0
//
// EV_DoCeiling
// Move a ceiling up/down and all around!
//
dboolean EV_DoCeiling(line_t *line, ceiling_e type)
{
    int         secnum = -1;
    dboolean    rtn = false;
    sector_t    *sec;
    ceiling_t   *ceiling;


    // Reactivate in-stasis ceilings...for certain types.
    switch (type)
    {
        case fastCrushAndRaise:
        case silentCrushAndRaise:
        case crushAndRaise:
            rtn = P_ActivateInStasisCeiling(line);

        default:
            break;
    }

    while ((secnum = P_FindSectorFromLineTag(line, secnum)) >= 0)
    {
        sec = &sectors[secnum];
        if (P_SectorActive(ceiling_special, sec))
            continue;

        // new door thinker
        rtn = true;
        ceiling = Z_Malloc(sizeof(*ceiling), PU_LEVSPEC, 0);
        memset(ceiling, 0, sizeof(*ceiling));
        P_AddThinker(&ceiling->thinker);
        sec->ceilingdata = ceiling;
        ceiling->thinker.function = T_MoveCeiling;
        ceiling->sector = sec;
        ceiling->crush = false;

        switch (type)
        {
            case fastCrushAndRaise:
                ceiling->crush = true;
                ceiling->topheight = sec->ceilingheight;
                ceiling->bottomheight = sec->floorheight + 8 * FRACUNIT;
                ceiling->direction = -1;
                ceiling->speed = CEILSPEED * 2;
                break;

            case silentCrushAndRaise:
            case crushAndRaise:
                ceiling->crush = true;
                ceiling->topheight = sec->ceilingheight;

            case lowerAndCrush:
            case lowerToFloor:
                ceiling->bottomheight = sec->floorheight;
                if (type != lowerToFloor && !(gamemission == doom2 && gamemap == 4 && canmodify))
                    ceiling->bottomheight += 8 * FRACUNIT;
                ceiling->direction = -1;
                ceiling->speed = CEILSPEED;
                break;

            case raiseToHighest:
                ceiling->topheight = P_FindHighestCeilingSurrounding(sec);
                ceiling->direction = 1;
                ceiling->speed = CEILSPEED;
                break;

            case lowerToLowest:
                ceiling->bottomheight = P_FindLowestCeilingSurrounding(sec);
                ceiling->direction = -1;
                ceiling->speed = CEILSPEED;
                break;

            case lowerToMaxFloor:
                ceiling->bottomheight = P_FindHighestFloorSurrounding(sec);
                ceiling->direction = -1;
                ceiling->speed = CEILSPEED;
                break;
        }

        ceiling->tag = sec->tag;
        ceiling->type = type;
        P_AddActiveCeiling(ceiling);
    }
    return rtn;
}
Ejemplo n.º 9
0
DPillar::DPillar (sector_t *sector, EPillar type, fixed_t speed,
				  fixed_t height, fixed_t height2, bool crush)
	: DMover (sector), m_Status(init)
{
	fixed_t	ceilingdist, floordist;

	sector->floordata = sector->ceilingdata = this;

	fixed_t floorheight = P_FloorHeight(sector);
	fixed_t ceilingheight = P_CeilingHeight(sector);

	m_Type = type;
	m_Crush = crush;

	if (type == pillarBuild)
	{
		// If the pillar height is 0, have the floor and ceiling meet halfway
		if (height == 0)
		{
			m_FloorTarget = m_CeilingTarget =
				 (ceilingheight - floorheight) / 2 + floorheight;
			floordist = m_FloorTarget - floorheight;
		}
		else
		{
			m_FloorTarget = m_CeilingTarget = floorheight + height;
			floordist = height;
		}
		ceilingdist = ceilingheight - m_CeilingTarget;
	}
	else
	{
		// If one of the heights is 0, figure it out based on the
		// surrounding sectors
		if (height == 0)
		{
			m_FloorTarget = P_FindLowestFloorSurrounding (sector);
			floordist = floorheight - m_FloorTarget;
		}
		else
		{
			floordist = height;
			m_FloorTarget = floorheight - height;
		}
		if (height2 == 0)
		{
			m_CeilingTarget = P_FindHighestCeilingSurrounding (sector);
			ceilingdist = m_CeilingTarget - ceilingheight;
		}
		else
		{
			m_CeilingTarget = ceilingheight + height2;
			ceilingdist = height2;
		}
	}

	// The speed parameter applies to whichever part of the pillar
	// travels the farthest. The other part's speed is then set so
	// that it arrives at its destination at the same time.
	if (floordist > ceilingdist)
	{
		m_FloorSpeed = speed;
		m_CeilingSpeed = FixedDiv (FixedMul (speed, ceilingdist), floordist);
	}
	else
	{
		m_CeilingSpeed = speed;
		m_FloorSpeed = FixedDiv (FixedMul (speed, floordist), ceilingdist);
	}

	PlayPillarSound();
}