コード例 #1
0
ファイル: p_ceiling.cpp プロジェクト: nashmuhandes/GZDoom-GPL
bool EV_CeilingCrushStop (int tag, bool remove)
{
	bool rtn = false;
	DCeiling *scan;
	TThinkerIterator<DCeiling> iterator;

	scan = iterator.Next();
	while (scan != nullptr)
	{
		DCeiling *next = iterator.Next();
		if (scan->m_Tag == tag && scan->m_Direction != 0)
		{
			if (!remove)
			{
				SN_StopSequence(scan->m_Sector, CHAN_CEILING);
				scan->m_OldDirection = scan->m_Direction;
				scan->m_Direction = 0;		// in-stasis;
			}
			else
			{
				scan->Destroy();
			}
			rtn = true;
		}
		scan = next;
	}

	return rtn;
}
コード例 #2
0
ファイル: p_ceiling.cpp プロジェクト: JohnnyonFlame/odamex
//
// Restart a ceiling that's in-stasis
// [RH] Passed a tag instead of a line and rewritten to use list
//
void P_ActivateInStasisCeiling (int tag)
{
	DCeiling *scan;
	TThinkerIterator<DCeiling> iterator;

	while ( (scan = iterator.Next ()) )
	{
		if (scan->m_Tag == tag && scan->m_Direction == 0)
		{
			scan->m_Direction = scan->m_OldDirection;
			scan->PlayCeilingSound ();
		}
	}
}
コード例 #3
0
//*****************************************************************************
//
DCeiling *P_GetCeilingByID( LONG lID )
{
	DCeiling	*pCeiling;

	TThinkerIterator<DCeiling>		Iterator;

	while (( pCeiling = Iterator.Next( )))
	{
		if ( pCeiling->GetID( ) == lID )
			return ( pCeiling );
	}

	return ( NULL );
}
コード例 #4
0
//
// Restart a ceiling that's in-stasis
// [RH] Passed a tag instead of a line and rewritten to use a list
//
void P_ActivateInStasisCeiling (int tag)
{
	DCeiling *scan;
	TThinkerIterator<DCeiling> iterator;

	while ( (scan = iterator.Next ()) )
	{
		if (scan->m_Tag == tag && scan->m_Direction == 0)
		{
			scan->m_Direction = scan->m_OldDirection;
			scan->PlayCeilingSound ();

			// [BC] If we're the server, tell clients to change the ceiling direction, and
			// play the ceiling sound.
			if ( NETWORK_GetState( ) == NETSTATE_SERVER )
			{
				SERVERCOMMANDS_ChangeCeilingDirection( scan->GetID( ), scan->GetDirection( ));
				SERVERCOMMANDS_PlayCeilingSound( scan->GetID( ));
			}
		}
	}
}
コード例 #5
0
//
// EV_CeilingCrushStop
// Stop a ceiling from crushing!
// [RH] Passed a tag instead of a line and rewritten to use a list
//
bool EV_CeilingCrushStop (int tag)
{
	bool rtn = false;
	DCeiling *scan;
	TThinkerIterator<DCeiling> iterator;

	while ( (scan = iterator.Next ()) )
	{
		if (scan->m_Tag == tag && scan->m_Direction != 0)
		{
			// [BC] If we're stopping, this is probably a good time to verify all the clients
			// have the correct floor/ceiling height for this sector.
			if ( NETWORK_GetState( ) == NETSTATE_SERVER )
			{
				if ( scan->m_Sector->floorOrCeiling == 0 )
					SERVERCOMMANDS_SetSectorFloorPlane( ULONG( scan->m_Sector - sectors ));
				else
					SERVERCOMMANDS_SetSectorCeilingPlane( ULONG( scan->m_Sector - sectors ));

				// Tell clients to stop the floor's sound sequence.
				SERVERCOMMANDS_StopSectorSequence( scan->m_Sector );
			}

			SN_StopSequence (scan->m_Sector);
			scan->m_OldDirection = scan->m_Direction;
			scan->m_Direction = 0;		// in-stasis;
			rtn = true;

			// [BB] Also tell the updated direction to the clients.
			if ( NETWORK_GetState( ) == NETSTATE_SERVER )
				SERVERCOMMANDS_ChangeCeilingDirection( scan->GetID( ), scan->GetDirection( ));
		}
	}

	return rtn;
}
コード例 #6
0
ファイル: p_ceiling.cpp プロジェクト: JohnnyonFlame/odamex
//
// 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;
}
コード例 #7
0
ファイル: p_ceiling.cpp プロジェクト: CarlKenner/gz3doom
DCeiling *DCeiling::Create(sector_t *sec, 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)
{
	fixed_t		targheight = 0;	// Silence, GCC

	// if ceiling already moving, don't start a second function on it
	if (sec->PlaneMoving(sector_t::ceiling))
	{
		return NULL;
	}
	
	// new door thinker
	DCeiling *ceiling = new DCeiling (sec, speed, speed2, silent);
	vertex_t *spot = sec->lines[0]->v1;

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

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

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

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

	case 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 ceilLowerToHighestFloor:
		targheight = sec->FindHighestFloorSurrounding (&spot);
		ceiling->m_BottomHeight = sec->ceilingplane.PointToDist (spot, targheight);
		ceiling->m_Direction = -1;
		break;

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

	case 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 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 ceilLowerToNearest:
		targheight = sec->FindNextLowestCeiling (&spot);
		ceiling->m_BottomHeight = sec->ceilingplane.PointToDist (spot, targheight);
		ceiling->m_Direction = -1;
		break;

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

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

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

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

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

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

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

	case 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();
	}

	// 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 == ceilRaiseToHighest ||*/
				   type == ceilRaiseToFloor ||
				   /*type == ceilLowerToHighest ||*/
				   type == 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 = genCeilingChg0;
						break;
					case 2:		// type is copied
						ceiling->m_NewSpecial = sec->special;
						ceiling->m_Type = genCeilingChgT;
						break;
					case 3:		// type is left alone
						ceiling->m_Type = 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 = genCeilingChg0;
					break;
				case 2:		// type is copied
					ceiling->m_NewSpecial = line->frontsector->special;
					ceiling->m_Type = genCeilingChgT;
					break;
				case 3:		// type is left alone
					ceiling->m_Type = genCeilingChg;
					break;
			}
		}
	}

	ceiling->PlayCeilingSound ();
	return ceiling;
}
コード例 #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;
}