Ejemplo n.º 1
0
bool EV_DoCeiling (DCeiling::ECeiling type, line_t *line,
				   int tag, fixed_t speed, fixed_t speed2, fixed_t height,
				   int crush, int silent, int change, bool hexencrush)
{
	int 		secnum;
	bool 		rtn;
	sector_t*	sec;
		
	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 = (int)(sec-sectors);
		// [RH] Hack to let manual crushers be retriggerable, too
		tag ^= secnum | 0x1000000;
		P_ActivateInStasisCeiling (tag);
		return !!DCeiling::Create(sec, type, line, tag, speed, speed2, height, crush, silent, change, hexencrush);
	}
	
	//	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)
	{
		rtn |= !!DCeiling::Create(&sectors[secnum], type, line, tag, speed, speed2, height, crush, silent, change, hexencrush);
	}
	return rtn;
}
Ejemplo n.º 2
0
bool EV_DoCeiling (DCeiling::ECeiling type, line_t *line,
				   int tag, double speed, double speed2, double height,
				   int crush, int silent, int change, DCeiling::ECrushMode hexencrush)
{
	int 		secnum;
	bool 		rtn;
	sector_t*	sec;
		
	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->sectornum;
		// [RH] Hack to let manual crushers be retriggerable, too
		tag ^= secnum | 0x1000000;
		P_ActivateInStasisCeiling (tag);
		return P_CreateCeiling(sec, type, line, tag, speed, speed2, height, crush, silent, change, hexencrush);
	}
	
	//	Reactivate in-stasis ceilings...for certain types.
	// This restarts a crusher after it has been stopped
	if (type == DCeiling::ceilCrushAndRaise)
	{
		P_ActivateInStasisCeiling (tag);
	}

	// affects all sectors with the same tag as the linedef
	FSectorTagIterator it(tag);
	while ((secnum = it.Next()) >= 0)
	{
		rtn |= P_CreateCeiling(&level.sectors[secnum], type, line, tag, speed, speed2, height, crush, silent, change, hexencrush);
	}
	return rtn;
}
Ejemplo n.º 3
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.º 4
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.º 5
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.º 6
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.º 7
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.º 8
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,
				   int crush, int silent, int change, bool hexencrush)
{
	int 		secnum;
	bool 		rtn;
	sector_t*	sec;
	DCeiling*	ceiling;
	bool		manual = false;
	fixed_t		targheight = 0;	// Silence, GCC
	vertex_t*	spot;
		
	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 = (int)(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)
		{
			if (!manual)
				continue;
			else
				return false;
		}
		
		// new door thinker
		rtn = 1;
		ceiling = new DCeiling (sec, speed, speed2, silent);
		spot = sec->lines[0]->v1;

		// [BC] If we're not a client, assign a network ID to the ceiling.
		if (( NETWORK_GetState( ) != NETSTATE_CLIENT ) && !( CLIENTDEMO_IsPlaying( )))
			ceiling->m_lCeilingID = P_GetFirstFreeCeilingID( );

		switch (type)
		{
		case DCeiling::ceilCrushAndRaise:
		case DCeiling::ceilCrushRaiseAndStay:
			ceiling->m_TopHeight = sec->ceilingplane.d;
		case DCeiling::ceilLowerAndCrush:
			targheight = sec->FindHighestFloorPoint (&spot);
			if (type != DCeiling::ceilLowerAndCrush || gameinfo.gametype != GAME_Strife)
			{
				targheight += 8*FRACUNIT;
			}
			ceiling->m_BottomHeight = sec->ceilingplane.PointToDist (spot, targheight);
			ceiling->m_Direction = -1;
			break;

		case DCeiling::ceilRaiseToHighest:
			targheight = sec->FindHighestCeilingSurrounding (&spot);
			ceiling->m_TopHeight = sec->ceilingplane.PointToDist (spot, targheight);
			ceiling->m_Direction = 1;
			break;

		case DCeiling::ceilLowerByValue:
			targheight = sec->ceilingplane.ZatPoint (spot) - height;
			ceiling->m_BottomHeight = sec->ceilingplane.PointToDist (spot, targheight);
			ceiling->m_Direction = -1;
			break;

		case DCeiling::ceilRaiseByValue:
			targheight = sec->ceilingplane.ZatPoint (spot) + height;
			ceiling->m_TopHeight = sec->ceilingplane.PointToDist (spot, targheight);
			ceiling->m_Direction = 1;
			break;

		case DCeiling::ceilMoveToValue:
			{
				int diff = height - sec->ceilingplane.ZatPoint (spot);

				targheight = height;
				if (diff < 0)
				{
					ceiling->m_BottomHeight = sec->ceilingplane.PointToDist (spot, height);
					ceiling->m_Direction = -1;
				}
				else
				{
					ceiling->m_TopHeight = sec->ceilingplane.PointToDist (spot, height);
					ceiling->m_Direction = 1;
				}
			}
			break;

		case DCeiling::ceilLowerToHighestFloor:
			targheight = sec->FindHighestFloorSurrounding (&spot);
			ceiling->m_BottomHeight = sec->ceilingplane.PointToDist (spot, targheight);
			ceiling->m_Direction = -1;
			break;

		case DCeiling::ceilRaiseToHighestFloor:
			targheight = sec->FindHighestFloorSurrounding (&spot);
			ceiling->m_TopHeight = sec->ceilingplane.PointToDist (spot, targheight);
			ceiling->m_Direction = 1;
			break;

		case DCeiling::ceilLowerInstant:
			targheight = sec->ceilingplane.ZatPoint (spot) - height;
			ceiling->m_BottomHeight = sec->ceilingplane.PointToDist (spot, targheight);
			ceiling->m_Direction = -1;
			ceiling->m_Speed = height;
			break;

		case DCeiling::ceilRaiseInstant:
			targheight = sec->ceilingplane.ZatPoint (spot) + height;
			ceiling->m_TopHeight = sec->ceilingplane.PointToDist (spot, targheight);
			ceiling->m_Direction = 1;
			ceiling->m_Speed = height;
			break;

		case DCeiling::ceilLowerToNearest:
			targheight = sec->FindNextLowestCeiling (&spot);
			ceiling->m_BottomHeight = sec->ceilingplane.PointToDist (spot, targheight);
			ceiling->m_Direction = -1;
			break;

		case DCeiling::ceilRaiseToNearest:
			targheight = sec->FindNextHighestCeiling (&spot);
			ceiling->m_TopHeight = sec->ceilingplane.PointToDist (spot, targheight);
			ceiling->m_Direction = 1;
			break;

		case DCeiling::ceilLowerToLowest:
			targheight = sec->FindLowestCeilingSurrounding (&spot);
			ceiling->m_BottomHeight = sec->ceilingplane.PointToDist (spot, targheight);
			ceiling->m_Direction = -1;
			break;

		case DCeiling::ceilRaiseToLowest:
			targheight = sec->FindLowestCeilingSurrounding (&spot);
			ceiling->m_TopHeight = sec->ceilingplane.PointToDist (spot, targheight);
			ceiling->m_Direction = 1;
			break;

		case DCeiling::ceilLowerToFloor:
			targheight = sec->FindHighestFloorPoint (&spot);
			ceiling->m_BottomHeight = sec->ceilingplane.PointToDist (spot, targheight);
			ceiling->m_Direction = -1;
			break;

		case DCeiling::ceilRaiseToFloor:	// [RH] What's this for?
			targheight = sec->FindHighestFloorPoint (&spot);
			ceiling->m_TopHeight = sec->ceilingplane.PointToDist (spot, targheight);
			ceiling->m_Direction = 1;
			break;

		case DCeiling::ceilLowerToHighest:
			targheight = sec->FindHighestCeilingSurrounding (&spot);
			ceiling->m_BottomHeight = sec->ceilingplane.PointToDist (spot, targheight);
			ceiling->m_Direction = -1;
			break;

		case DCeiling::ceilLowerByTexture:
			targheight = sec->ceilingplane.ZatPoint (spot) - sec->FindShortestUpperAround ();
			ceiling->m_BottomHeight = sec->ceilingplane.PointToDist (spot, targheight);
			ceiling->m_Direction = -1;
			break;

		case DCeiling::ceilRaiseByTexture:
			targheight = sec->ceilingplane.ZatPoint (spot) + sec->FindShortestUpperAround ();
			ceiling->m_TopHeight = sec->ceilingplane.PointToDist (spot, targheight);
			ceiling->m_Direction = 1;
			break;

		default:
			break;	// Silence GCC
		}
				
		ceiling->m_Tag = tag;
		ceiling->m_Type = type;
		ceiling->m_Crush = crush;
		ceiling->m_Hexencrush = hexencrush;

		// Do not interpolate instant movement ceilings.
		// Note for ZDoomGL: Check to make sure that you update the sector
		// after the ceiling moves, because it hasn't actually moved yet.
		fixed_t movedist;

		if (ceiling->m_Direction < 0)
		{
			movedist = sec->ceilingplane.d - ceiling->m_BottomHeight;
		}
		else
		{
			movedist = ceiling->m_TopHeight - sec->ceilingplane.d;
		}
		if (ceiling->m_Speed >= movedist)
		{
			ceiling->StopInterpolation();
		}

		// [BC] If we're the server, tell clients to create a ceiling.
		if ( NETWORK_GetState( ) == NETSTATE_SERVER )
			SERVERCOMMANDS_DoCeiling( type, &sectors[secnum], ceiling->m_Direction, ceiling->m_BottomHeight, ceiling->m_TopHeight, ceiling->m_Speed, ceiling->m_Crush, ceiling->m_Silent, ceiling->m_lCeilingID );

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

				//jff 5/23/98 find model with floor at target height if target
				//is a floor type
				modelsec = (/*type == DCeiling::ceilRaiseToHighest ||*/
					   type == DCeiling::ceilRaiseToFloor ||
					   /*type == DCeiling::ceilLowerToHighest ||*/
					   type == DCeiling::ceilLowerToFloor) ?
					sec->FindModelFloorSector (targheight) :
					sec->FindModelCeilingSector (targheight);
				if (modelsec != NULL)
				{
					ceiling->m_Texture = modelsec->GetTexture(sector_t::ceiling);
					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->GetTexture(sector_t::ceiling);
				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 ();

		// [BC] If we're the server, tell clients to play the ceiling sound.
		if ( NETWORK_GetState( ) == NETSTATE_SERVER )
			SERVERCOMMANDS_PlayCeilingSound( ceiling->m_lCeilingID );

		if (manual)
			return rtn;
	}
	return rtn;
}
Ejemplo n.º 9
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;
}