//============================================================================
//----------------------------------------------------------------------------
//									Objects.c
//----------------------------------------------------------------------------
//============================================================================


#include "Externs.h"
#include "ObjectEdit.h"


#define kMaxTempManholes			8


short GetObjectLinked (objectType *);
void ListOneRoomsObjects (short);


Rect		blowerSrcRect;									// Blowers
DrawSurface	*blowerSrcMap;
DrawSurface	*blowerMaskMap;
Rect		flame[kNumCandleFlames], tikiFlame[kNumTikiFlames];
Rect		coals[kNumBBQCoals];
Rect		furnitureSrcRect;								// Furniture
DrawSurface	*furnitureSrcMap;
DrawSurface	*furnitureMaskMap;
Rect		tableSrc, shelfSrc, hingeSrc, handleSrc, knobSrc;
Rect		leftFootSrc, rightFootSrc, deckSrc;
Rect		bonusSrcRect;									// Bonuses
DrawSurface	*bonusSrcMap;
DrawSurface	*bonusMaskMap;
Rect		pointsSrcRect;
DrawSurface	*pointsSrcMap;
DrawSurface	*pointsMaskMap;
Rect		starSrc[6], sparkleSrc[kNumSparkleModes];
Rect		digits[11], pendulumSrc[3], greaseSrcRt[4], greaseSrcLf[4];
Rect		transSrcRect;									// Transport
DrawSurface	*transSrcMap;
DrawSurface	*transMaskMap;
Rect		switchSrcRect;									// Switches
DrawSurface	*switchSrcMap;
Rect		lightSwitchSrc[2], machineSwitchSrc[2], thermostatSrc[2];
Rect		powerSrc[2], knifeSwitchSrc[2];
Rect		lightSrcRect;									// Lights
DrawSurface	*lightSrcMap;
DrawSurface	*lightMaskMap;
Rect		flourescentSrc1, flourescentSrc2, trackLightSrc[kNumTrackLights];
Rect		applianceSrcRect, toastSrcRect, shredSrcRect;	// Appliances
DrawSurface	*applianceSrcMap, *toastSrcMap, *shredSrcMap;
DrawSurface	*applianceMaskMap, *toastMaskMap, *shredMaskMap;
Rect		plusScreen1, plusScreen2, tvScreen1, tvScreen2;
Rect		coffeeLight1, coffeeLight2, vcrTime1, vcrTime2;
Rect		stereoLight1, stereoLight2, microOn, microOff;
Rect		outletSrc[kNumOutletPicts];
Rect		balloonSrcRect, copterSrcRect, dartSrcRect;		// Enemies
Rect		ballSrcRect, dripSrcRect, enemySrcRect;
Rect		fishSrcRect;
DrawSurface	*balloonSrcMap, *copterSrcMap, *dartSrcMap;
DrawSurface	*ballSrcMap, *dripSrcMap, *enemySrcMap;
DrawSurface	*fishSrcMap;
DrawSurface	*balloonMaskMap, *copterMaskMap, *dartMaskMap;
DrawSurface	*ballMaskMap, *dripMaskMap, *enemyMaskMap;
DrawSurface	*fishMaskMap;
Rect		balloonSrc[kNumBalloonFrames], copterSrc[kNumCopterFrames];
Rect		dartSrc[kNumDartFrames], ballSrc[kNumBallFrames];
Rect		dripSrc[kNumDripFrames], fishSrc[kNumFishFrames];
DrawSurface	*clutterSrcMap;									// Clutter
DrawSurface	*clutterMaskMap;
Rect		clutterSrcRect;
Rect		flowerSrc[kNumFlowers];
Rect		*srcRects;
Rect		tempManholes[kMaxTempManholes];
savedType	savedMaps[kMaxSavedMaps];
objDataPtr	masterObjects;
hotPtr		hotSpots;
short		nLocalObj, nHotSpots, numMasterObjects, numLocalMasterObjects;
short		numTempManholes, tvWithMovieNumber;
Boolean		newState;

extern	linksPtr	linksList;
extern	short		srcLocations[], destLocations[];
extern	short		localNumbers[];
extern	short		numNeighbors;


//==============================================================  Functions
//--------------------------------------------------------------  IsThisValid

Boolean IsThisValid (short where, short who)
{
	char		wasState;
	Boolean		itsGood;
	
	itsGood = true;
	
	switch ((*thisHouse)->rooms[where].objects[who].what)
	{
		case kObjectIsEmpty:
		itsGood = false;
		break;
		
		case kRedClock:
		case kBlueClock:
		case kYellowClock:
		case kCuckoo:
		case kPaper:
		case kBattery:
		case kBands:
		case kFoil:
		case kInvisBonus:
		case kStar:
		case kSparkle:
		case kHelium:
		itsGood = (*thisHouse)->rooms[where].objects[who].data.c.state;
		break;
	}
	
	return (itsGood);
}

//--------------------------------------------------------------  GetRoomLinked

short GetRoomLinked (objectType *who)
{
	short		compoundRoomNumber, whereLinked;
	short		floor, suite;
	
	switch (who->what)
	{
		case kMailboxLf:
		case kMailboxRt:
		case kFloorTrans:
		case kCeilingTrans:
		case kInvisTrans:
		case kDeluxeTrans:
		compoundRoomNumber = who->data.d.where;
		if (compoundRoomNumber != -1)	// is object linked
		{
			ExtractFloorSuite(compoundRoomNumber, &floor, &suite);
			whereLinked = GetRoomNumber(floor, suite);
		}
		else
			whereLinked = -1;			// not linked
		break;
		
		case kLightSwitch:
		case kMachineSwitch:
		case kThermostat:
		case kPowerSwitch:
		case kKnifeSwitch:
		case kInvisSwitch:
		case kTrigger:
		case kLgTrigger:
		compoundRoomNumber = who->data.e.where;
		if (compoundRoomNumber != -1)	// is object linked
		{
			ExtractFloorSuite(compoundRoomNumber, &floor, &suite);
			whereLinked = GetRoomNumber(floor, suite);
		}
		else
			whereLinked = -1;			// not linked
		break;
		
		default:
		whereLinked = -1;
		break;
	}
	
	return (whereLinked);
}

//--------------------------------------------------------------  GetObjectLinked

short GetObjectLinked (objectType *who)
{
	short		whoLinked;
	
	switch (who->what)
	{
		case kMailboxLf:
		case kMailboxRt:
		case kFloorTrans:
		case kCeilingTrans:
		case kInvisTrans:
		case kDeluxeTrans:
		if (who->data.d.who != 255)		// is it linked?
			whoLinked = (short)who->data.d.who;
		else
			whoLinked = -1;				// object not linked
		break;
		
		case kLightSwitch:
		case kMachineSwitch:
		case kThermostat:
		case kPowerSwitch:
		case kKnifeSwitch:
		case kInvisSwitch:
		case kTrigger:
		case kLgTrigger:
		if (who->data.e.who != 255)		// is it linked?
			whoLinked = (short)who->data.e.who;
		else
			whoLinked = -1;				// object not linked
		break;
		
		default:
		whoLinked = -1;
		break;
	}
	
	return (whoLinked);
}

//--------------------------------------------------------------  ObjectIsLinkTransport

Boolean ObjectIsLinkTransport (objectType *who)
{
	Boolean		itIs;
	
	itIs = false;
	if ((who->what == kMailboxLf) || (who->what == kMailboxRt) || 
			(who->what == kFloorTrans) || (who->what == kCeilingTrans) || 
			(who->what == kInvisTrans) || (who->what == kDeluxeTrans))
	{
		itIs = true;
	}
	
	return (itIs);
}

//--------------------------------------------------------------  ObjectIsLinkSwitch

Boolean ObjectIsLinkSwitch (objectType *who)
{
	Boolean		itIs;
	
	itIs = false;
	if ((who->what == kLightSwitch) || (who->what == kMachineSwitch) || 
			(who->what == kThermostat) || (who->what == kPowerSwitch) || 
			(who->what == kKnifeSwitch) || (who->what == kInvisSwitch) || 
			(who->what == kTrigger) || (who->what == kLgTrigger))
	{
		itIs = true;
	}
	
	return (itIs);
}

//--------------------------------------------------------------  ListOneRoomsObjects

void ListOneRoomsObjects (short where)
{
	objectType	thisObject;
	short		roomNum, n;
	char		wasState;
	
	roomNum = localNumbers[where];
	if (roomNum == kRoomIsEmpty)
		return;
	
	for (n = 0; n < kMaxRoomObs; n++)
	{
		if (numMasterObjects < kMaxMasterObjects)
		{
			thisObject = (*thisHouse)->rooms[roomNum].objects[n];
			
			masterObjects[numMasterObjects].roomNum = roomNum;
			masterObjects[numMasterObjects].objectNum = n;
			masterObjects[numMasterObjects].roomLink = 
					GetRoomLinked(&thisObject);
			masterObjects[numMasterObjects].objectLink = 
					GetObjectLinked(&thisObject);
			masterObjects[numMasterObjects].localLink = -1;
			
			masterObjects[numMasterObjects].theObject = 
					(*thisHouse)->rooms[roomNum].objects[n];
			
			if ((where == kCentralRoom) && (IsThisValid(roomNum, n)))
				masterObjects[numMasterObjects].hotNum = CreateActiveRects(n);
			else
				masterObjects[numMasterObjects].hotNum = -1;
			masterObjects[numMasterObjects].dynaNum = -1;
			
			numMasterObjects++;
			
			if (where == kCentralRoom)
				numLocalMasterObjects++;
		}
	}
}

//--------------------------------------------------------------  ListAllLocalObjects

void ListAllLocalObjects (void)
{
	short		i, n;
	char		wasState;
	
	numMasterObjects = 0;
	numLocalMasterObjects = 0;
	nHotSpots = 0;
	
	ListOneRoomsObjects(kCentralRoom);
	
	if (numNeighbors > 1)
	{
		ListOneRoomsObjects(kEastRoom);
		ListOneRoomsObjects(kWestRoom);
	}
	
	if (numNeighbors > 3)
	{
		ListOneRoomsObjects(kNorthRoom);
		ListOneRoomsObjects(kNorthEastRoom);
		ListOneRoomsObjects(kSouthEastRoom);
		ListOneRoomsObjects(kSouthRoom);
		ListOneRoomsObjects(kSouthWestRoom);
		ListOneRoomsObjects(kNorthWestRoom);
	}
	
	for (i = 0; i < numMasterObjects; i++)				// correlate links withÉ
	{													// index into this list
		if ((masterObjects[i].roomLink != -1) && 		// if object has a link
				(masterObjects[i].objectLink != -1))
		{
			for (n = 0; n < numMasterObjects; n++)		// search for the objectÉ
			{											// linked to in this list
				if ((masterObjects[i].roomLink == masterObjects[n].roomNum) && 
						(masterObjects[i].objectLink == masterObjects[n].objectNum))
				{
					masterObjects[i].localLink = n;		// log the index
				}
			}
		}
	}
}

//--------------------------------------------------------------  AddTempManholeRect

void AddTempManholeRect (Rect *manHole)
{
	Rect		tempRect;
	
	if (numTempManholes < kMaxTempManholes)
	{
		tempRect = *manHole;
		tempRect.bottom = tempRect.top + kFloorSupportTall;
		tempManholes[numTempManholes] = tempRect;
		numTempManholes++;
	}
}

//--------------------------------------------------------------  SetObjectState

Boolean SetObjectState (short room, short object, short action, short local)
{
	char		wasState;
	Boolean		changed = false;
	
	switch ((*thisHouse)->rooms[room].objects[object].what)
	{
		case kFloorVent:
		case kCeilingVent:
		case kFloorBlower:
		case kCeilingBlower:
		case kLeftFan:
		case kRightFan:
		case kSewerGrate:
		case kInvisBlower:
		case kGrecoVent:
		case kSewerBlower:
		case kLiftArea:
		switch (action)
		{
			case kToggle:
			newState = !(*thisHouse)->rooms[room].objects[object].data.a.state;
			(*thisHouse)->rooms[room].objects[object].data.a.state = newState;
			changed = true;
			break;
			
			case kForceOn:
			changed = ((*thisHouse)->rooms[room].objects[object].data.a.state == false);
			newState = true;
			(*thisHouse)->rooms[room].objects[object].data.a.state = newState;
			break;
			
			case kForceOff:
			changed = ((*thisHouse)->rooms[room].objects[object].data.a.state == PL_TRUE);
			newState = false;
			(*thisHouse)->rooms[room].objects[object].data.a.state = newState;
			break;
		}
		if ((changed) && (local != -1))
		{
			masterObjects[local].theObject.data.a.state = newState;
			if (room == thisRoomNumber)
				thisRoom->objects[object].data.a.state = newState;
			if (newState)
				PlayPrioritySound(kBlowerOn, kBlowerOnPriority);
			else
				PlayPrioritySound(kBlowerOff, kBlowerOffPriority);
			if (masterObjects[local].hotNum != -1)
				hotSpots[masterObjects[local].hotNum].isOn = newState;
		}
		break;
		
		case kTaper:
		case kCandle:
		case kStubby:
		case kTiki:
		case kBBQ:
		changed = false;	// Cannot switch on/off these
		break;
		
		case kTable:
		case kShelf:
		case kCabinet:
		case kFilingCabinet:
		case kWasteBasket:
		case kMilkCrate:
		case kCounter:
		case kDresser:
		case kStool:
		case kTrunk:
		case kDeckTable:
		case kInvisObstacle:
		case kManhole:
		case kBooks:
		case kInvisBounce:
		changed = false;	// Cannot switch on/off these
		break;
		
		case kRedClock:
		case kBlueClock:
		case kYellowClock:
		case kCuckoo:
		case kPaper:
		case kBattery:
		case kBands:
		case kGreaseRt:
		case kGreaseLf:
		case kFoil:
		case kInvisBonus:
		case kStar:
		case kSparkle:
		case kHelium:
		changed = ((*thisHouse)->rooms[room].objects[object].data.c.state == PL_TRUE);
		newState = false;
		(*thisHouse)->rooms[room].objects[object].data.c.state = newState;
		if ((changed) && (local != -1))
		{
			masterObjects[local].theObject.data.a.state = false;
			if (room == thisRoomNumber)
			{
				thisRoom->objects[object].data.c.state = false;
				if (masterObjects[local].hotNum != -1)
					hotSpots[masterObjects[local].hotNum].isOn = false;
			}
		}
		break;
		
		case kSlider:
		break;
		
		case kUpStairs:
		case kDownStairs:
		case kMailboxLf:
		case kMailboxRt:
		case kFloorTrans:
		case kCeilingTrans:
		case kDoorInLf:
		case kDoorInRt:
		case kDoorExRt:
		case kDoorExLf:
		case kWindowInLf:
		case kWindowInRt:
		case kWindowExRt:
		case kWindowExLf:
		case kInvisTrans:
		changed = false;
		break;
		
		case kDeluxeTrans:
		switch (action)
		{
			case kToggle:
			newState = (*thisHouse)->rooms[room].objects[object].data.d.wide & 0x0F;
			newState = !newState;
			(*thisHouse)->rooms[room].objects[object].data.d.wide &= 0xF0;
			(*thisHouse)->rooms[room].objects[object].data.d.wide += newState;
			changed = true;
			break;
			
			case kForceOn:
			changed = (((*thisHouse)->rooms[room].objects[object].data.d.wide & 0x0F) == 0x00);
			newState = true;
			(*thisHouse)->rooms[room].objects[object].data.d.wide &= 0xF0;
			(*thisHouse)->rooms[room].objects[object].data.d.wide += newState;
			break;
			
			case kForceOff:
			changed = (((*thisHouse)->rooms[room].objects[object].data.d.wide & 0x0F) != 0x00);
			newState = false;
			(*thisHouse)->rooms[room].objects[object].data.d.wide &= 0xF0;
			(*thisHouse)->rooms[room].objects[object].data.d.wide += newState;
			break;
		}
		if ((changed) && (local != -1))
		{
			masterObjects[local].theObject.data.d.wide = 
					(*thisHouse)->rooms[room].objects[object].data.d.wide;
			if (room == thisRoomNumber)
				thisRoom->objects[object].data.d.wide = 
						(*thisHouse)->rooms[room].objects[object].data.d.wide;
			if (masterObjects[local].hotNum != -1)
				hotSpots[masterObjects[local].hotNum].isOn = newState;
		}
		break;
		
		case kLightSwitch:
		case kMachineSwitch:
		case kThermostat:
		case kPowerSwitch:
		case kInvisSwitch:
		case kTrigger:
		case kLgTrigger:
		case kSoundTrigger:
		changed = false;
		break;
		
		case kCeilingLight:
		case kLightBulb:
		case kTableLamp:
		case kHipLamp:
		case kDecoLamp:
		case kFlourescent:
		case kTrackLight:
		case kInvisLight:
		switch (action)
		{
			case kToggle:
			newState = !(*thisHouse)->rooms[room].objects[object].data.f.state;
			(*thisHouse)->rooms[room].objects[object].data.f.state = newState;
			changed = true;
			break;
			
			case kForceOn:
			changed = ((*thisHouse)->rooms[room].objects[object].data.f.state == false);
			newState = true;
			(*thisHouse)->rooms[room].objects[object].data.f.state = newState;
			break;
			
			case kForceOff:
			changed = ((*thisHouse)->rooms[room].objects[object].data.f.state == PL_TRUE);
			newState = false;
			(*thisHouse)->rooms[room].objects[object].data.f.state = newState;
			break;
		}
		if ((changed) && (local != -1))
		{
			masterObjects[local].theObject.data.f.state = newState;
			if (room == thisRoomNumber)
				thisRoom->objects[object].data.f.state = newState;
		}
		break;
		
		case kGuitar:		// really no point to change this state
		changed = false;
		break;
		
		case kStereo:
		newState = !isPlayMusicGame;
		isPlayMusicGame = newState;
		changed = true;
		break;
		
		case kShredder:
		case kToaster:
		case kMacPlus:
		case kTV:
		case kCoffee:
		case kOutlet:
		case kVCR:
		case kMicrowave:
		switch (action)
		{
			case kToggle:
			newState = !(*thisHouse)->rooms[room].objects[object].data.g.state;
			(*thisHouse)->rooms[room].objects[object].data.g.state = newState;
			changed = true;
			break;
			
			case kForceOn:
			changed = ((*thisHouse)->rooms[room].objects[object].data.g.state == false);
			newState = true;
			(*thisHouse)->rooms[room].objects[object].data.g.state = newState;
			break;
			
			case kForceOff:
			changed = ((*thisHouse)->rooms[room].objects[object].data.g.state == PL_TRUE);
			newState = false;
			(*thisHouse)->rooms[room].objects[object].data.g.state = newState;
			break;
		}
		if ((changed) && (local != -1))
		{
			masterObjects[local].theObject.data.g.state = newState;
			if (room == thisRoomNumber)
			{
				thisRoom->objects[object].data.g.state = newState;
				if ((*thisHouse)->rooms[room].objects[object].what == kShredder)
					hotSpots[masterObjects[local].hotNum].isOn = newState;
			}
		}
		break;
		
		case kCinderBlock:
		case kFlowerBox:
		case kCDs:
		case kCustomPict:
		changed = false;
		break;
				
		case kBalloon:
		case kCopterLf:
		case kCopterRt:
		case kDartLf:
		case kDartRt:
		case kBall:
		case kDrip:
		case kFish:
		switch (action)
		{
			case kToggle:
			newState = !(*thisHouse)->rooms[room].objects[object].data.h.state;
			(*thisHouse)->rooms[room].objects[object].data.h.state = newState;
			changed = true;
			break;
			
			case kForceOn:
			changed = ((*thisHouse)->rooms[room].objects[object].data.h.state == false);
			newState = true;
			(*thisHouse)->rooms[room].objects[object].data.h.state = newState;
			break;
			
			case kForceOff:
			changed = ((*thisHouse)->rooms[room].objects[object].data.h.state == PL_TRUE);
			newState = false;
			(*thisHouse)->rooms[room].objects[object].data.h.state = newState;
			break;
		}
		if ((changed) && (local != -1))
		{
			masterObjects[local].theObject.data.h.state = newState;
			if (room == thisRoomNumber)
				thisRoom->objects[object].data.h.state = newState;
		}
		break;
		
		case kCobweb:
		changed = false;
		break;
		
		case kOzma:
		case kMirror:
		case kMousehole:
		case kFireplace:
		case kFlower:
		case kWallWindow:
		case kBear:
		case kCalendar:
		case kVase1:
		case kVase2:
		case kBulletin:
		case kCloud:
		case kFaucet:
		case kRug:
		case kChimes:
		changed = false;
		break;
		
	}
	
	return (changed);
}

//--------------------------------------------------------------  GetObjectState

Boolean GetObjectState (short room, short object)
{
	char		wasState;
	Boolean		theState;
	
	theState = true;
	
	switch ((*thisHouse)->rooms[room].objects[object].what)
	{
		case kFloorVent:
		case kCeilingVent:
		case kFloorBlower:
		case kCeilingBlower:
		case kLeftFan:
		case kRightFan:
		case kSewerGrate:
		case kInvisBlower:
		case kGrecoVent:
		case kSewerBlower:
		case kLiftArea:
		theState = (*thisHouse)->rooms[room].objects[object].data.a.state;
		break;
		
		case kTaper:
		case kCandle:
		case kStubby:
		case kTiki:
		case kBBQ:
		break;
		
		case kTable:
		case kShelf:
		case kCabinet:
		case kFilingCabinet:
		case kWasteBasket:
		case kMilkCrate:
		case kCounter:
		case kDresser:
		case kDeckTable:
		case kStool:
		case kTrunk:
		case kInvisObstacle:
		case kManhole:
		case kBooks:
		case kInvisBounce:
		break;
		
		case kRedClock:
		case kBlueClock:
		case kYellowClock:
		case kCuckoo:
		case kPaper:
		case kBattery:
		case kBands:
		case kGreaseRt:
		case kGreaseLf:
		case kFoil:
		case kInvisBonus:
		case kStar:
		case kSparkle:
		case kHelium:
		theState = (*thisHouse)->rooms[room].objects[object].data.c.state;
		break;
		
		case kSlider:
		break;
		
		case kUpStairs:
		case kDownStairs:
		case kMailboxLf:
		case kMailboxRt:
		case kFloorTrans:
		case kCeilingTrans:
		case kDoorInLf:
		case kDoorInRt:
		case kDoorExRt:
		case kDoorExLf:
		case kWindowInLf:
		case kWindowInRt:
		case kWindowExRt:
		case kWindowExLf:
		case kInvisTrans:
		break;
		
		case kDeluxeTrans:
		theState = (*thisHouse)->rooms[room].objects[object].data.d.wide & 0x0F;
		break;
		
		case kLightSwitch:
		case kMachineSwitch:
		case kThermostat:
		case kPowerSwitch:
		case kInvisSwitch:
		case kTrigger:
		case kLgTrigger:
		case kSoundTrigger:
		break;
		
		case kCeilingLight:
		case kLightBulb:
		case kTableLamp:
		case kHipLamp:
		case kDecoLamp:
		case kFlourescent:
		case kTrackLight:
		case kInvisLight:
		theState = (*thisHouse)->rooms[room].objects[object].data.f.state;
		break;
		
		case kStereo:
		theState = isPlayMusicGame;
		break;
		
		case kShredder:
		case kToaster:
		case kMacPlus:
		case kGuitar:
		case kTV:
		case kCoffee:
		case kOutlet:
		case kVCR:
		case kMicrowave:
		theState = (*thisHouse)->rooms[room].objects[object].data.g.state;
		break;
		
		case kCinderBlock:
		case kFlowerBox:
		case kCDs:
		case kCustomPict:
		break;
		
		case kBalloon:
		case kCopterLf:
		case kCopterRt:
		case kDartLf:
		case kDartRt:
		case kBall:
		case kDrip:
		case kFish:
		theState = (*thisHouse)->rooms[room].objects[object].data.h.state;
		break;
		
		case kCobweb:
		break;
		
		case kOzma:
		case kMirror:
		case kMousehole:
		case kFireplace:
		case kFlower:
		case kWallWindow:
		case kBear:
		case kCalendar:
		case kVase1:
		case kVase2:
		case kBulletin:
		case kCloud:
		case kFaucet:
		case kRug:
		case kChimes:
		break;
	}
	
	return (theState);
}

//--------------------------------------------------------------  SendObjectToBack

#ifndef COMPILEDEMO
void BringSendFrontBack (Boolean bringFront)
{
	houseType	*thisHousePtr;
	objectType	savedObject;
	short		numLinks, i;
	short		srcRoom, srcObj;
	short		sorting[kMaxRoomObs];
	short		sorted[kMaxRoomObs];
	char		wasState;
	
	if (bringFront)							// No need to bring to frontÉ
	{										// or send to back if the objectÉ
		if (objActive == (kMaxRoomObs - 1))	// in question is already front-
			return;							// most or backmost.
	}
	else
	{
		if (objActive == 0)
			return;
	}
	
	CopyThisRoomToRoom();					// Any changes to room writtenÉ
											// back to the house handle.
	numLinks = CountHouseLinks();			// Determine space needed for all links.
	if (numLinks != 0)						// Create links list of ALL house links.
	{
		linksList = nil;
		linksList = (linksPtr)NewPtr(sizeof(linksType) * numLinks);
		if (linksList == nil)
		{
			YellowAlert(kYellowCantOrderLinks, PLErrors::kOutOfMemory);
			return;
		}
		GenerateLinksList();				// Fill in links list with src/destÉ
	}										// data on objects and room numbers.
	
	thisHousePtr = *thisHouse;				// Get a pointer to house structure.
	
	for (i = 0; i < kMaxRoomObs; i++)		// Set up an ordered array.
		sorting[i] = i;
	
	savedObject = (*thisHouse)->rooms[thisRoomNumber].objects[objActive];
	
	if (bringFront)
	{
		for (i = objActive; i < kMaxRoomObs - 1; i++)
		{									// Pull all objects down to fill hole.
			(*thisHouse)->rooms[thisRoomNumber].objects[i] = 
					(*thisHouse)->rooms[thisRoomNumber].objects[i + 1];
			sorting[i] = sorting[i + 1];
			SpinCursor(2);
		}
											// Insert object at end of array.
		(*thisHouse)->rooms[thisRoomNumber].objects[kMaxRoomObs - 1] = savedObject;
		sorting[kMaxRoomObs - 1] = objActive;
	}
	else
	{
		for (i = objActive; i > 0; i--)
		{									// Move all objects up to fill hole.
			(*thisHouse)->rooms[thisRoomNumber].objects[i] = 
					(*thisHouse)->rooms[thisRoomNumber].objects[i - 1];
			sorting[i] = sorting[i - 1];
			SpinCursor(2);
		}
											// Insert object at beginning of array.
		(*thisHouse)->rooms[thisRoomNumber].objects[0] = savedObject;
		sorting[0] = objActive;
	}
	
	for (i = 0; i < kMaxRoomObs; i++)		// Set up retro-ordered array.
		sorted[sorting[i]] = i;
	
	for (i = 0; i < numLinks; i++)			// Walk links list in order to assignÉ
	{										// corrected links to objects moved.
		if (linksList[i].destRoom == thisRoomNumber)
		{									// Does link point to room we re-ordered?
			srcRoom = linksList[i].srcRoom;	// Room where-which an object is linked from.
			if (srcRoom == thisRoomNumber)	// Handle special case for local links.
				srcObj = sorted[linksList[i].srcObj];
			else
				srcObj = linksList[i].srcObj;
			
			switch ((*thisHouse)->rooms[srcRoom].objects[srcObj].what)
			{
				case kLightSwitch:
				case kMachineSwitch:
				case kThermostat:
				case kPowerSwitch:
				case kKnifeSwitch:
				case kInvisSwitch:
				case kTrigger:
				case kLgTrigger:
				(*thisHouse)->rooms[srcRoom].objects[srcObj].data.d.who = 
						sorted[linksList[i].destObj];
				break;
				
				default:
				(*thisHouse)->rooms[srcRoom].objects[srcObj].data.e.who = 
						sorted[linksList[i].destObj];
				break;
			}
		}
	}
	
	if (linksList != nil)
		DisposePtr((Ptr)linksList);
	
	ForceThisRoom(thisRoomNumber);
	
	fileDirty = true;
	UpdateMenus(false);
	DeselectObject();
	GetThisRoomsObjRects();
	ReadyBackground(thisRoom->background, thisRoom->tiles);
	DrawThisRoomsObjects();
	GenerateRetroLinks();
	
	InitCursor();

	UpdateMainWindow();
}
#endif

