예제 #1
0
bool CDockingPorts::ShipsNearPort (CSpaceObject *pOwner, CSpaceObject *pRequestingObj, const CVector &vPortPos)

//	ShipsNearPort
//
//	Returns TRUE if there are ships near the given port

	{
	int i;
	CSystem *pSystem = pOwner->GetSystem();

	for (i = 0; i < pSystem->GetObjectCount(); i++)
		{
		CSpaceObject *pObj = pSystem->GetObject(i);
		if (pObj
				&& pObj->GetCategory() == CSpaceObject::catShip
				&& !pObj->IsInactive()
				&& pObj != pRequestingObj)
			{
			Metric rDist2 = (pObj->GetPos() - vPortPos).Length2();
			if (rDist2 < MIN_PORT_DISTANCE2 && !IsDockedOrDocking(pObj))
				return true;
			}
		}

	return false;
	}
예제 #2
0
void CTranscendenceWnd::DestroyIntroShips (void)

//	DestroyIntroShips
//
//	Destroys all ships of the same class as the POV

	{
	int i;

	CShip *pShip = g_pUniverse->GetPOV()->AsShip();
	if (pShip == NULL)
		return;

	//	Destroy all ships of the current class

	CSystem *pSystem = pShip->GetSystem();
	CShipClass *pClassToDestroy = pShip->GetClass();
	TArray<CSpaceObject *> ShipsToDestroy;
	CSpaceObject *pOtherShip = NULL;
	for (i = 0; i < pSystem->GetObjectCount(); i++)
		{
		CSpaceObject *pObj = pSystem->GetObject(i);
		CShip *pShip;
		if (pObj 
				&& !pObj->IsInactive()
				&& !pObj->IsVirtual()
				&& (pShip = pObj->AsShip()))
			{
			if (pShip->GetClass() == pClassToDestroy)
				ShipsToDestroy.Insert(pObj);
			else if (pOtherShip == NULL)
				pOtherShip = pObj;
			}
		}

	//	Destroy ships

	for (i = 0; i < ShipsToDestroy.GetCount(); i++)
		ShipsToDestroy[i]->Destroy(removedFromSystem, CDamageSource());
	}
예제 #3
0
void DoTradeSim (CUniverse &Universe, CXMLElement *pCmdLine)
	{
	ALERROR error;
	int i, j;
	CSovereign *pPlayer = Universe.FindSovereign(g_PlayerSovereignUNID);

	int iSystemSample = pCmdLine->GetAttributeIntegerBounded(CONSTLIT("count"), 1, -1, 1);
	bool bLogo = !pCmdLine->GetAttributeBool(NO_LOGO_SWITCH);

	//	For each station type we keep track of the items that it sells and the
	//	various prices that each instances charges.

	SStationData AllStations;

	//	For each item type we keep track of the stations that sell and/or
	//	buy it.

	SItemData AllItems;

	//	Generate systems for multiple games

	for (i = 0; i < iSystemSample; i++)
		{
		if (bLogo)
			printf("pass %d...\n", i+1);

		CTopologyNode *pNode = Universe.GetFirstTopologyNode();

		while (true)
			{
			//	Create the system

			CSystem *pSystem;
			if (error = Universe.CreateStarSystem(pNode, &pSystem))
				{
				printf("ERROR: Unable to create star system.\n");
				return;
				}

			//	For all active stations in the system, get their trading information

			for (j = 0; j < pSystem->GetObjectCount(); j++)
				{
				CSpaceObject *pObj = pSystem->GetObject(j);

				if (pObj && pObj->GetCategory() == CSpaceObject::catStation)
					CompileTradeData(pObj, &AllStations, &AllItems);
				}

			//	Get the next node

			CString sEntryPoint;
			pNode = pSystem->GetStargateDestination(CONSTLIT("Outbound"), &sEntryPoint);
			if (pNode == NULL || pNode->IsEndGame())
				break;

			//	Done with old system

			Universe.DestroySystem(pSystem);
			}

		Universe.Reinit();
		}

	if (bLogo)
		printf("FINAL STATISTICS\n\n");

	//	Loop over each item and output the best trading strategy

	printf("Item\tSeller\tSell Price\tBuyer\tBuy Price\tProfit\n");
	for (i = 0; i < AllItems.GetCount(); i++)
		{
		ComputeAverages(&AllItems[i]);
		OutputTradingStrategy(AllItems[i]);
		}
	}
예제 #4
0
void GenerateSnapshot (CUniverse &Universe, CXMLElement *pCmdLine)
	{
	ALERROR error;
	int i;

	//	Get some parameters

	int iInitialUpdateTime = 10;
	int iUpdateTime = pCmdLine->GetAttributeInteger(CONSTLIT("wait"));

	//	Criteria

	CString sNode = pCmdLine->GetAttribute(CONSTLIT("node"));
	CString sCriteria = pCmdLine->GetAttribute(CONSTLIT("criteria"));

	//	Output

	int cxWidth;
	int cyHeight;
	if (pCmdLine->FindAttributeInteger(CONSTLIT("size"), &cxWidth))
		{
		cyHeight = cxWidth;
		}
	else
		{
		cxWidth = 1024;
		cyHeight = 1024;
		}

	//	Paint flags

	DWORD dwPaintFlags = 0;
	if (pCmdLine->GetAttributeBool(CONSTLIT("noStars")))
		dwPaintFlags |= CSystem::VWP_NO_STAR_FIELD;

	//	Output file

	CString sFilespec = pCmdLine->GetAttribute(CONSTLIT("output"));
	if (!sFilespec.IsBlank())
		sFilespec = pathAddExtensionIfNecessary(sFilespec, CONSTLIT(".bmp"));

	//	Update context

	SSystemUpdateCtx Ctx;
	Ctx.bForceEventFiring = true;
	Ctx.bForcePainted = true;

	//	Loop over all systems until we find what we're looking for

	int iLoops = 20;
	int iNodeIndex = 0;
	CTopologyNode *pNode = Universe.GetTopologyNode(iNodeIndex);
	while (true)
		{
		//	Create the system

		CSystem *pSystem;
		if (error = Universe.CreateStarSystem(pNode, &pSystem))
			{
			printf("ERROR: Unable to create star system.\n");
			return;
			}

		//	If this is the node we want, then search

		CSpaceObject *pTarget;
		if (sNode.IsBlank() || strEquals(sNode, pNode->GetID()))
			{
			printf("Searching %s...\n", pNode->GetSystemName().GetASCIIZPointer());

			//	Set the POV

			CSpaceObject *pPOV = pSystem->GetObject(0);
			Universe.SetPOV(pPOV);
			pSystem->SetPOVLRS(pPOV);

			//	Prepare system

			Universe.UpdateExtended();
			Universe.GarbageCollectLibraryBitmaps();

			//	Update for a while

			for (i = 0; i < iInitialUpdateTime; i++)
				Universe.Update(Ctx);

			//	Compose the criteria

			CSpaceObject::Criteria Criteria;
			CSpaceObject::ParseCriteria(pPOV, sCriteria, &Criteria);

			//	Get the list of all objects in the system that match the criteria

			CSpaceObject::SCriteriaMatchCtx Ctx(Criteria);
			TArray<CSpaceObject *> Results;
			for (i = 0; i < pSystem->GetObjectCount(); i++)
				{
				CSpaceObject *pObj = pSystem->GetObject(i);
				if (pObj && pObj->MatchesCriteria(Ctx, Criteria))
					Results.Insert(pObj);
				}

			//	Pick the appropriate object from the list

			if (Results.GetCount() == 0)
				pTarget = NULL;
			else if (Criteria.bNearestOnly || Criteria.bFarthestOnly)
				pTarget = Ctx.pBestObj;
			else
				pTarget = Results[mathRandom(0, Results.GetCount() - 1)];
			}
		else
			pTarget = NULL;

		//	If we found the target, then output

		if (pTarget)
			{
			//	If we found the target, take a snapshot

			printf("Found %s.\n", pTarget->GetNounPhrase(0).GetASCIIZPointer());

			//	Wait a bit

			for (i = 0; i < iUpdateTime; i++)
				{
				if ((i % 100) == 99)
					printf(".");

				Universe.Update(Ctx);
				}

			if (iUpdateTime >= 99)
				printf("\n");

			//	Paint

			CG16bitImage Output;
			Output.CreateBlank(cxWidth, cyHeight, false);
			RECT rcViewport;
			rcViewport.left = 0;
			rcViewport.top = 0;
			rcViewport.right = cxWidth;
			rcViewport.bottom = cyHeight;
			
			pSystem->PaintViewport(Output, rcViewport, pTarget, dwPaintFlags);

			//	Write to file

			if (!sFilespec.IsBlank())
				{
				CFileWriteStream OutputFile(sFilespec);
				if (OutputFile.Create() != NOERROR)
					{
					printf("ERROR: Unable to create '%s'\n", sFilespec.GetASCIIZPointer());
					return;
					}

				Output.WriteToWindowsBMP(&OutputFile);
				OutputFile.Close();
				printf("%s\n", sFilespec.GetASCIIZPointer());
				}

			//	Otherwise, clipboard

			else
				{
				if (error = Output.CopyToClipboard())
					{
					printf("ERROR: Unable to copy image to clipboard.\n");
					return;
					}

				printf("Image copied to clipboard.\n");
				}

			//	Done

			break;
			}

		//	Done with old system

		Universe.DestroySystem(pSystem);

		//	Loop to the next node

		do
			{
			iNodeIndex = ((iNodeIndex + 1) % Universe.GetTopologyNodeCount());
			pNode = Universe.GetTopologyNode(iNodeIndex);
			}
		while (pNode == NULL || pNode->IsEndGame());

		//	If we're back to the first node again, restart

		if (iNodeIndex == 0)
			{
			if (--iLoops > 0)
				{
				Universe.Reinit();

				iNodeIndex = 0;
				pNode = Universe.GetTopologyNode(iNodeIndex);
				}
			else
				{
				printf("ERROR: Specified target could not be found.\n");
				return;
				}
			}
		}
	}
예제 #5
0
void GenerateSimTables (CUniverse &Universe, CXMLElement *pCmdLine)
	{
	ALERROR error;
	int i, j;

	int iSystemSample = pCmdLine->GetAttributeInteger(CONSTLIT("count"));
	if (iSystemSample == 0)
		iSystemSample = DEFAULT_SYSTEM_SAMPLE;

	//	Generate systems for multiple games

	CSymbolTable AllSystems(TRUE, TRUE);
	for (i = 0; i < iSystemSample; i++)
		{
		printf("sample %d...\n", i+1);

		CTopologyNode *pNode = Universe.GetFirstTopologyNode();

		while (true)
			{
			//	Create the system

			CSystem *pSystem;
			if (error = Universe.CreateStarSystem(pNode, &pSystem))
				{
				printf("ERROR: Unable to create star system.\n");
				return;
				}

			//	Find this system in the table.

			SystemInfo *pSystemEntry;
			if (error = AllSystems.Lookup(pNode->GetSystemName(), (CObject **)&pSystemEntry))
				{
				pSystemEntry = new SystemInfo;
				pSystemEntry->sName = pNode->GetSystemName();
				pSystemEntry->iLevel = pNode->GetLevel();
				pSystemEntry->dwSystemType = pNode->GetSystemDescUNID();
				pSystemEntry->iCount = 1;

				AllSystems.AddEntry(pSystemEntry->sName, pSystemEntry);
				}
			else
				pSystemEntry->iCount++;

			//	Add the encounters to the appropriate tables

			for (j = 0; j < pSystem->GetObjectCount(); j++)
				{
				CSpaceObject *pObj = pSystem->GetObject(j);

				if (pObj)
					{
					//	Add this encounter to the table

					CStationType *pType;
					if (pType = pObj->GetEncounterInfo())
						{
						CString sKey = strFromInt(pType->GetUNID(), false);

						//	See if we have this type in the table

						StationInfo *pEntry;
						if (error = pSystemEntry->Stations.Lookup(sKey, (CObject **)&pEntry))
							{
							pEntry = new StationInfo;
							pEntry->pType = pType;
							pEntry->iSystemCount = 0;
							pEntry->iTotalCount = 1;

							pSystemEntry->Stations.AddEntry(sKey, pEntry);
							}
						else
							pEntry->iTotalCount++;
						}

					//	Enumerate the items in this object

					CItemListManipulator ItemList(pObj->GetItemList());
					ItemList.ResetCursor();
					while (ItemList.MoveCursorForward())
						{
						const CItem &Item(ItemList.GetItemAtCursor());

						if (!Item.IsInstalled() && !Item.IsDamaged())
							{
							CString sKey = strFromInt(Item.GetType()->GetUNID(), false);

							//	Find the item type in the table

							ItemInfo *pEntry;
							if (error = pSystemEntry->Items.Lookup(sKey, (CObject **)&pEntry))
								{
								pEntry = new ItemInfo;
								pEntry->pType = Item.GetType();
								pEntry->iTotalCount = Item.GetCount();

								pSystemEntry->Items.AddEntry(sKey, pEntry);
								}
							else
								pEntry->iTotalCount += Item.GetCount();
							}
						}
					}
				}

			//	Get the next node

			CString sEntryPoint;
			pNode = pSystem->GetStargateDestination(CONSTLIT("Outbound"), &sEntryPoint);
			if (pNode == NULL || pNode->IsEndGame())
				break;

			//	Done with old system

			Universe.DestroySystem(pSystem);
			}

		Universe.Reinit();
		}

	//	Output

	if (error = OutputItemTable(AllSystems, iSystemSample))
		return;

	if (error = OutputEncounterTable(AllSystems, iSystemSample))
		return;

	//	Create a table with the sum of all items for the game

	printf("Total count statistic computed.\n");
	}
예제 #6
0
void Run (CUniverse &Universe, CXMLElement *pCmdLine)
	{
	ALERROR error;
	int i;
	CCodeChain &CC = g_pUniverse->GetCC();
	bool bNoLogo = pCmdLine->GetAttributeBool(NO_LOGO_SWITCH);

	//	Prepare the universe

	CTopologyNode *pNode = g_pUniverse->GetFirstTopologyNode();
	if (pNode == NULL)
		{
		printf("ERROR: No topology node found.\n");
		return;
		}

	CSystem *pSystem;
	if (error = g_pUniverse->CreateStarSystem(pNode, &pSystem))
		{
		printf("ERROR: Unable to create star system.\n");
		return;
		}

	//	Set the POV

	CSpaceObject *pPOV = pSystem->GetObject(0);
	g_pUniverse->SetPOV(pPOV);
	pSystem->SetPOVLRS(pPOV);

	//	Prepare system

	g_pUniverse->UpdateExtended();
	g_pUniverse->GarbageCollectLibraryBitmaps();

	CString sCommand = pCmdLine->GetAttribute(RUN_SWITCH);
	CString sRunFile = pCmdLine->GetAttribute(RUN_FILE_SWITCH);

	//	If this is a run file, then we parse it and run it

	if (!sRunFile.IsBlank() && !strEquals(sRunFile, CONSTLIT("true")))
		{
		TArray<CString> Files;
		ParseStringList(sRunFile, PSL_FLAG_ALLOW_WHITESPACE, &Files);
		for (i = 0; i < Files.GetCount(); i++)
			RunFile(Files[i], bNoLogo);
		}

	//	If we have a command, invoke it

	else if (!sCommand.IsBlank() && !strEquals(sCommand, CONSTLIT("True")))
		{
		CCodeChainCtx Ctx;
		ICCItem *pCode = Ctx.Link(sCommand, 0, NULL);
		ICCItem *pResult = Ctx.Run(pCode);

		CString sOutput;
		if (pResult->IsIdentifier())
			sOutput = pResult->Print(&CC, PRFLAG_NO_QUOTES | PRFLAG_ENCODE_FOR_DISPLAY);
		else
			sOutput = CC.Unlink(pResult);

		Ctx.Discard(pResult);
		Ctx.Discard(pCode);

		//	Output result

		printf("%s\n", sOutput.GetASCIIZPointer());
		}

	//	Otherwise, we enter a command loop

	else
		{
		//	Welcome

		if (!bNoLogo)
			{
			printf("(help) for function help.\n");
			printf("\\q to quit.\n\n");
			}

		//	Loop

		while (true)
			{
			char szBuffer[1024];
			if (!bNoLogo)
				printf(": ");
			gets_s(szBuffer, sizeof(szBuffer)-1);
			CString sCommand(szBuffer);

			//	Escape codes

			if (*sCommand.GetASCIIZPointer() == '\\')
				{
				//	Quit command

				if (strStartsWith(sCommand, CONSTLIT("\\q")))
					break;
				else if (strStartsWith(sCommand, CONSTLIT("\\?"))
						|| strStartsWith(sCommand, CONSTLIT("\\h")))
					{
					printf("TLisp Shell\n\n");
					printf("\\h      Show this help\n");
					printf("\\q      Quit\n");

					printf("\n(help) for function help.\n");
					}
				}

			//	Null command

			else if (sCommand.IsBlank())
				NULL;

			//	Command

			else
				{
				CCodeChainCtx Ctx;
				ICCItem *pCode = Ctx.Link(sCommand, 0, NULL);
				ICCItem *pResult = Ctx.Run(pCode);

				CString sOutput;
				if (pResult->IsIdentifier())
					sOutput = pResult->Print(&CC, PRFLAG_NO_QUOTES | PRFLAG_ENCODE_FOR_DISPLAY);
				else
					sOutput = CC.Unlink(pResult);

				Ctx.Discard(pResult);
				Ctx.Discard(pCode);

				//	Output result

				printf("%s\n", sOutput.GetASCIIZPointer());
				}
			}
		}
	}
예제 #7
0
void GenerateStationPlaceSim (CUniverse &Universe, CXMLElement *pCmdLine)
	{
	ALERROR error;
	int i, j, k;
	CSovereign *pPlayer = Universe.FindSovereign(g_PlayerSovereignUNID);

	int iSystemSample = pCmdLine->GetAttributeIntegerBounded(CONSTLIT("count"), 1, -1, 1);
	bool bLogo = !pCmdLine->GetAttributeBool(NO_LOGO_SWITCH);

	//	Generate systems for multiple games

	CSymbolTable AllSystems(TRUE, TRUE);
	for (i = 0; i < iSystemSample; i++)
		{
		if (bLogo)
			printf("pass %d...\n", i+1);

		CTopologyNode *pNode = Universe.GetFirstTopologyNode();

		while (true)
			{
			//	Create the system

			CSystem *pSystem;
			if (error = Universe.CreateStarSystem(pNode, &pSystem))
				{
				printf("ERROR: Unable to create star system.\n");
				return;
				}

			//	Find this system in the table.

			SPSimSystemInfo *pSystemEntry;
			if (error = AllSystems.Lookup(pNode->GetSystemName(), (CObject **)&pSystemEntry))
				{
				pSystemEntry = new SPSimSystemInfo;
				pSystemEntry->sName = pNode->GetSystemName();
				pSystemEntry->iLevel = pNode->GetLevel();
				pSystemEntry->dwSystemType = pNode->GetSystemTypeUNID();
				pSystemEntry->iCount = 1;

				for (j = 0; j < DIST_BUCKET_COUNT; j++)
					pSystemEntry->iEnemies[j] = 0;

				AllSystems.AddEntry(pSystemEntry->sName, pSystemEntry);
				}
			else
				pSystemEntry->iCount++;

			//	For all active stations in the system, count the number of enemy stations
			//	within certain distance buckets

			for (j = 0; j < pSystem->GetObjectCount(); j++)
				{
				CSpaceObject *pObj = pSystem->GetObject(j);

				//	Find any objects that are lootable by the player

				if (pObj
						&& pObj->GetCategory() == CSpaceObject::catStation
						&& pObj->CanAttack())
					{
					//	Count to see how many enemy stations are in range

					for (k = 0; k < pSystem->GetObjectCount(); k++)
						{
						CSpaceObject *pEnemy = pSystem->GetObject(k);
						if (pEnemy
								&& pEnemy->GetCategory() == CSpaceObject::catStation
								&& pEnemy->CanAttack()
								&& (pEnemy->IsEnemy(pObj) || pObj->IsEnemy(pEnemy)))
							{
							Metric rDist = pObj->GetDistance(pEnemy);
							int iDist = DistToBucketIndex(rDist);
							if (iDist != -1)
								{
								ASSERT(iDist < DIST_BUCKET_COUNT && iDist >= 0);
								pSystemEntry->iEnemies[iDist]++;

								int iLSDist = (int)((rDist / LIGHT_SECOND) + 0.5);
								if (iLSDist < 30)
									{
									printf("%s: %s (%x) and %s (%x) within %d ls\n",
											pSystem->GetName().GetASCIIZPointer(),
											pObj->GetNounPhrase().GetASCIIZPointer(),
											pObj->GetID(),
											pEnemy->GetNounPhrase().GetASCIIZPointer(),
											pEnemy->GetID(),
											iLSDist);
									}
								}
							}
						}
					}
				}

			//	Get the next node

			CString sEntryPoint;
			pNode = pSystem->GetStargateDestination(CONSTLIT("Outbound"), &sEntryPoint);
			if (pNode == NULL || pNode->IsEndGame())
				break;

			//	Done with old system

			Universe.DestroySystem(pSystem);
			}

		Universe.Reinit();
		}

	if (bLogo)
		printf("FINAL SYSTEM STATISTICS\n\n");

	//	Output total value stats

	printf("Level\tSystem\t<10 ls\t<25 ls\t<50ls\t<100 ls\n");

	int iTotals[DIST_BUCKET_COUNT];
	for (i = 0; i < DIST_BUCKET_COUNT; i++)
		iTotals[i] = 0;

	for (i = 0; i < AllSystems.GetCount(); i++)
		{
		SPSimSystemInfo *pSystemEntry = (SPSimSystemInfo *)AllSystems.GetValue(i);

		printf("%d\t%s",
				pSystemEntry->iLevel,
				pSystemEntry->sName.GetASCIIZPointer());

		for (j = 0; j < DIST_BUCKET_COUNT; j++)
			{
			printf("\t%.2f", (double)pSystemEntry->iEnemies[j] / (double)pSystemEntry->iCount);
			iTotals[j] += pSystemEntry->iEnemies[j];
			}

		printf("\n");
		}

	//	Totals

	printf("\n");
	printf("Within  10 ls: %.2f\n", iTotals[0] / (double)iSystemSample);
	printf("Within  25 ls: %.2f\n", iTotals[1] / (double)iSystemSample);
	printf("Within  50 ls: %.2f\n", iTotals[2] / (double)iSystemSample);
	printf("Within 100 ls: %.2f\n", iTotals[3] / (double)iSystemSample);

	printf("\n");
	}
예제 #8
0
void GenerateSnapshot (CUniverse &Universe, CXMLElement *pCmdLine)
	{
	ALERROR error;
	int i;

	//	Get some parameters

	int iInitialUpdateTime = pCmdLine->GetAttributeIntegerBounded(CONSTLIT("initialUpdate"), 0, -1, 10);
	int iUpdateTime = pCmdLine->GetAttributeInteger(CONSTLIT("wait"));
	bool bObjOnly = pCmdLine->GetAttributeBool(CONSTLIT("objOnly"));

	//	Criteria

	CString sNode = pCmdLine->GetAttribute(CONSTLIT("node"));
	CString sCriteria = pCmdLine->GetAttribute(CONSTLIT("criteria"));

	//	Number of snapshots

	int iTotalCount = pCmdLine->GetAttributeIntegerBounded(CONSTLIT("count"), 1, -1, 1);

	//	Output

	int cxWidth;
	int cyHeight;
	if (pCmdLine->FindAttributeInteger(CONSTLIT("size"), &cxWidth))
		{
		cyHeight = cxWidth;
		}
	else
		{
		cxWidth = 1024;
		cyHeight = 1024;
		}

	//	Paint flags

	DWORD dwPaintFlags = 0;
	if (pCmdLine->GetAttributeBool(CONSTLIT("noStars")))
		dwPaintFlags |= CSystem::VWP_NO_STAR_FIELD;

	//	Output file

	CString sFilespec = pCmdLine->GetAttribute(CONSTLIT("output"));
	if (!sFilespec.IsBlank())
		sFilespec = pathStripExtension(sFilespec);

	//	Output image

	CG32bitImage Output;
	Output.Create(cxWidth, cyHeight);

	//	Update context

	SSystemUpdateCtx Ctx;
	Ctx.bForceEventFiring = true;
	Ctx.bForcePainted = true;

	RECT rcViewport;
	rcViewport.left = 0;
	rcViewport.top = 0;
	rcViewport.right = cxWidth;
	rcViewport.bottom = cyHeight;

	//	Loop over all systems until we find what we're looking for

	int iLoops = 20;
	int iNodeIndex = 0;
	int iSnapshotIndex = 0;
	CTopologyNode *pNode = Universe.GetTopologyNode(iNodeIndex);
	while (true)
		{
		//	Create the system

		CSystem *pSystem;
		if (error = Universe.CreateStarSystem(pNode, &pSystem))
			{
			printf("ERROR: Unable to create star system.\n");
			return;
			}

		//	If this is the node we want, then search

		CSpaceObject *pTarget;
		if (sNode.IsBlank() || strEquals(sNode, pNode->GetID()))
			{
			printf("Searching %s...\n", pNode->GetSystemName().GetASCIIZPointer());

			//	Set the POV

			CSpaceObject *pPOV = pSystem->GetObject(0);
			Universe.SetPOV(pPOV);
			pSystem->SetPOVLRS(pPOV);

			//	Prepare system

			Universe.UpdateExtended();
			Universe.GarbageCollectLibraryBitmaps();

			//	Update for a while

			for (i = 0; i < iInitialUpdateTime; i++)
				{
				Universe.Update(Ctx);
				Universe.PaintPOV(Output, rcViewport, 0);
				}

			//	Compose the criteria

			CSpaceObject::Criteria Criteria;
			CSpaceObject::ParseCriteria(pPOV, sCriteria, &Criteria);

			//	Get the list of all objects in the system that match the criteria

			CSpaceObject::SCriteriaMatchCtx Ctx(Criteria);
			TArray<CSpaceObject *> Results;
			for (i = 0; i < pSystem->GetObjectCount(); i++)
				{
				CSpaceObject *pObj = pSystem->GetObject(i);
				if (pObj && pObj->MatchesCriteria(Ctx, Criteria))
					Results.Insert(pObj);
				}

			//	Pick the appropriate object from the list

			if (Results.GetCount() == 0)
				pTarget = NULL;
			else if (Criteria.bNearestOnly || Criteria.bFarthestOnly)
				pTarget = Ctx.pBestObj;
			else
				pTarget = Results[mathRandom(0, Results.GetCount() - 1)];
			}
		else
			pTarget = NULL;

		//	If we found the target, then output

		if (pTarget)
			{
			Universe.SetPOV(pTarget);

			//	Wait a bit
			//
			//	NOTE: After we update, pTarget could be invalid (i.e., destroyed)
			//	so we can't use it again.

			CString sTargetName = pTarget->GetNounPhrase(0);

			for (i = 0; i < iUpdateTime; i++)
				{
				if ((i % 100) == 99)
					printf(".");

				Universe.Update(Ctx);
				Universe.PaintPOV(Output, rcViewport, 0);
				}

			if (iUpdateTime >= 99)
				printf("\n");

			//	Paint

			if (bObjOnly)
				{
				SViewportPaintCtx Ctx;
				Ctx.pObj = Universe.GetPOV();
				Ctx.XForm = ViewportTransform(Universe.GetPOV()->GetPos(), 
						g_KlicksPerPixel, 
						cxWidth / 2, 
						cyHeight / 2);
				Ctx.XFormRel = Ctx.XForm;
				Ctx.fNoRecon = true;
				Ctx.fNoDockedShips = true;
				Ctx.fNoSelection = true;
				Ctx.fNoStarfield = true;

				CSpaceObject *pPOV = pSystem->GetObject(0);
				CSpaceObject::Criteria Criteria;
				CSpaceObject::ParseCriteria(pPOV, sCriteria, &Criteria);

				//	Paint all objects that match the criteria

				CSpaceObject::SCriteriaMatchCtx CriteriaCtx(Criteria);
				for (i = 0; i < pSystem->GetObjectCount(); i++)
					{
					CSpaceObject *pObj = pSystem->GetObject(i);
					if (pObj && pObj->MatchesCriteria(CriteriaCtx, Criteria))
						{
						Ctx.pObj = pObj;
						int xObj;
						int yObj;
						Ctx.XForm.Transform(pObj->GetPos(), &xObj, &yObj);

						pObj->Paint(Output, xObj, yObj, Ctx);
						}
					}
				}
			else
				{
			
				Universe.PaintPOV(Output, rcViewport, 0);
				}

			//	Write to file

			if (!sFilespec.IsBlank())
				{
				CString sBmpFilespec;
				if (iTotalCount > 100)
					sBmpFilespec = pathAddExtensionIfNecessary(strPatternSubst(CONSTLIT("%s%03d"), sFilespec, iSnapshotIndex + 1), CONSTLIT(".bmp"));
				else if (iTotalCount > 1)
					sBmpFilespec = pathAddExtensionIfNecessary(strPatternSubst(CONSTLIT("%s%02d"), sFilespec, iSnapshotIndex + 1), CONSTLIT(".bmp"));
				else
					sBmpFilespec = pathAddExtensionIfNecessary(sFilespec, CONSTLIT(".bmp"));

				CFileWriteStream OutputFile(sBmpFilespec);
				if (OutputFile.Create() != NOERROR)
					{
					printf("ERROR: Unable to create '%s'\n", sBmpFilespec.GetASCIIZPointer());
					return;
					}

				Output.WriteToWindowsBMP(&OutputFile);
				OutputFile.Close();
				printf("Found %s: Saved to %s\n", sTargetName.GetASCIIZPointer(), sBmpFilespec.GetASCIIZPointer());
				}

			//	Otherwise, clipboard

			else
				{
				if (error = Output.CopyToClipboard())
					{
					printf("ERROR: Unable to copy image to clipboard.\n");
					return;
					}

				printf("Found %s: Copied to clipboard.\n", sTargetName.GetASCIIZPointer());
				}

			//	Reset maximum loops

			iLoops = 20;

			//	Done

			iSnapshotIndex++;
			if (iSnapshotIndex >= iTotalCount)
				break;
			}

		//	Done with old system

		Universe.DestroySystem(pSystem);

		//	Loop to the next node

		do
			{
			iNodeIndex = ((iNodeIndex + 1) % Universe.GetTopologyNodeCount());
			pNode = Universe.GetTopologyNode(iNodeIndex);
			}
		while (pNode == NULL || pNode->IsEndGame());

		//	If we're back to the first node again, restart

		if (iNodeIndex == 0)
			{
			if (--iLoops > 0)
				{
				//	Reinitialize

				Universe.Reinit();
				CString sError;
				if (Universe.InitGame(0, &sError) != NOERROR)
					{
					printf("ERROR: %s\n", sError.GetASCIIZPointer());
					return;
					}

				iNodeIndex = 0;
				pNode = Universe.GetTopologyNode(iNodeIndex);
				}
			else
				{
				printf("ERROR: Specified target could not be found.\n");
				return;
				}
			}
		}
	}
예제 #9
0
CString CNavigationPath::DebugDescribe (CSpaceObject *pObj, CNavigationPath *pNavPath)

//	DebugDescribe
//
//	Outputs debug info about the path

	{
	if (pNavPath == NULL)
		return CONSTLIT("none");

	//	Get the system

	CSystem *pSystem;
	try
		{
		pSystem = pObj->GetSystem();
		}
	catch (...)
		{
		return strPatternSubst(CONSTLIT("invalid system"));
		}

	//	Get the indeces for the objects

	int iFrom;
	int iTo;
	try
		{
		iFrom = pNavPath->m_iStartIndex;
		iTo = pNavPath->m_iEndIndex;
		}
	catch (...)
		{
		return strPatternSubst(CONSTLIT("%x [invalid]"), (DWORD)pNavPath);
		}

	//	Get the objects

	CSpaceObject *pFrom;
	CSpaceObject *pTo;
	try
		{
		pFrom = pSystem->GetObject(iFrom);
		pTo = pSystem->GetObject(iTo);
		}
	catch (...)
		{
		return strPatternSubst(CONSTLIT("invalid objects: %d, %d"), iFrom, iTo);
		}

	//	Return the object names

	try
		{
		return strPatternSubst(CONSTLIT("FROM: %s TO: %s"),
				CSpaceObject::DebugDescribe(pFrom).GetASCIIZPointer(),
				CSpaceObject::DebugDescribe(pTo).GetASCIIZPointer());
		}
	catch (...)
		{
		return strPatternSubst(CONSTLIT("CObject::DebugDescribe failed"));
		}
	}
예제 #10
0
void TestUpdate (CUniverse &Universe, CXMLElement *pCmdLine)
{
    int i;
    int iTrial;

    TArray<DWORD> Trials;
    DWORD dwLastAverage;

    //	How many tests

    int iCount = pCmdLine->GetAttributeInteger(CONSTLIT("count"));
    if (iCount == 0)
        iCount = 1;

    //	How long do we update

    int iUpdateCount = pCmdLine->GetAttributeInteger(CONSTLIT("updateCount"));
    if (iUpdateCount == 0)
        iUpdateCount = DEFAULT_UPDATE;

    //	Create the fist system

    for (iTrial = 0; iTrial < iCount; iTrial++)
    {
        TArray<SSample> Timings;

        printf("Trial: %d\n", iTrial + 1);

        //	Initialize the universe

        CString sError;
        if (Universe.InitGame(0, &sError) != NOERROR)
        {
            printf("ERROR: %s", sError.GetASCIIZPointer());
            return;
        }

        //	Create the first system

        CTopologyNode *pNode = Universe.GetFirstTopologyNode();
        if (pNode == NULL)
        {
            printf("ERROR: Cannot find first node.\n");
            return;
        }

        CSystem *pSystem;
        if (Universe.CreateStarSystem(pNode, &pSystem) != NOERROR)
        {
            printf("ERROR: Unable to create star system.\n");
            return;
        }

        //	Set the POV

        CSpaceObject *pPOV = pSystem->GetObject(0);
        Universe.SetPOV(pPOV);
        pSystem->SetPOVLRS(pPOV);

        //	Prepare system

        Universe.UpdateExtended();
        Universe.GarbageCollectLibraryBitmaps();
        Universe.StartGame(true);

        //	Update context

        SSystemUpdateCtx Ctx;
        Ctx.bForceEventFiring = true;
        Ctx.bForcePainted = true;

        //	Update for a while

        DWORD dwStart = ::GetTickCount();
        for (i = 0; i < iUpdateCount; i++)
        {
            Universe.Update(Ctx);

            if (i > 0 && (i % SAMPLE_SIZE) == 0)
            {
                DWORD dwEnd = ::GetTickCount();
                DWORD dwTime = dwEnd - dwStart;
                SSample *pSample = Timings.Insert();
                pSample->dwTime = dwTime;
                pSample->iObjCount = GetValidObjCount(pSystem);

                CString sTime = strFormatMilliseconds(dwTime);
                CString sObjTime = strFormatMicroseconds(1000 * dwTime / pSample->iObjCount);
                printf("Objs: %d  Total time: %s  Per obj: %s\n",
                       pSample->iObjCount,
                       sTime.GetASCIIZPointer(),
                       sObjTime.GetASCIIZPointer());

                dwStart = ::GetTickCount();
            }
        }

        //	Compute trial average

        DWORD dwTotal = 0;
        DWORD dwAverage = 0;
        for (i = 0; i < Timings.GetCount(); i++)
            dwTotal += Timings[i].dwTime;

        if (Timings.GetCount() > 0)
        {
            dwAverage = dwTotal / Timings.GetCount();
            CString sTime = strFormatMilliseconds(dwAverage);
            printf("Trial average: %s\n", sTime.GetASCIIZPointer());
        }

        Trials.Insert(dwAverage);

        //	Compute total average

        dwTotal = 0;
        for (i = 0; i < Trials.GetCount(); i++)
            dwTotal += Trials[i];

        dwLastAverage = dwTotal / Trials.GetCount();
        CString sTime = strFormatMilliseconds(dwLastAverage);
        printf("\n");
        printf("Running average: %s\n", sTime.GetASCIIZPointer());
        printf("\n");
    }

    //	Final tally

    CString sTime = strFormatMilliseconds(dwLastAverage);
    CString sTime2 = strFormatMicroseconds(1000 * dwLastAverage / SAMPLE_SIZE);

    printf("Total updates: %d\n", iUpdateCount * iCount);
    printf("Average time for %d updates: %s\n", SAMPLE_SIZE, sTime.GetASCIIZPointer());
    printf("Average time per update: %s\n", sTime2.GetASCIIZPointer());
}
예제 #11
0
void CDockingPorts::UpdateAll (CSpaceObject *pOwner)

//	UpdateAll
//
//	UpdateAll 

	{
	int i, j;

	for (i = 0; i < m_iPortCount; i++)
		{
		if (m_pPort[i].iStatus == psDocking)
			{
			CShip *pShip = m_pPort[i].pObj->AsShip();

			ASSERT(pShip);
			if (pShip == NULL)
				continue;

			CVector vDest = pOwner->GetPos() + m_pPort[i].vPos;
			CVector vDestVel = pOwner->GetVel();

			//	Figure out how far we are from where we want to be

			CVector vDelta = vDest - pShip->GetPos();

			//	Figure out if we're aligned

			int iFinalRotation = pShip->AlignToRotationAngle(m_pPort[i].iRotation);

			//	If the docking object is within the appropriate threshold 
			//	of the port, then complete the docking sequence.

			Metric rDelta2 = vDelta.Length2();
			if (rDelta2 < DOCKING_THRESHOLD2 
					&& (pShip == g_pUniverse->GetPlayer() || iFinalRotation == pShip->GetRotation()))
				{
				pShip->Place(vDest);
				pShip->UnfreezeControls();
				IShipController *pController = pShip->GetController();
				pController->SetManeuver(IShipController::NoRotation);

				m_pPort[i].iStatus = psInUse;

				//	Tell the owner that somone has docked with it first
				//	(We do this because sometimes we want to handle stuff
				//	in OnObjDocked before we show the player a dock screen)

				if (pOwner && pOwner->HasOnObjDockedEvent() && pOwner != pShip)
					pOwner->OnObjDocked(pShip, pOwner);

				//	Dock

				pShip->OnDocked(pOwner);

				//	Tell all objects in the system that a ship has docked

				CSystem *pSystem = pShip->GetSystem();
				for (j = 0; j < pSystem->GetObjectCount(); j++)
					{
					CSpaceObject *pObj = pSystem->GetObject(j);

					if (pObj && pObj->HasOnObjDockedEvent() && pObj != pShip && pObj != pOwner)
						pObj->OnObjDocked(pShip, pOwner);
					}
				}

			//	Otherwise accelerate the ship towards the docking port

			else
				{
				Metric rMaxSpeed = pShip->GetMaxSpeed();
				Metric rMinSpeed = rMaxSpeed / 10.0;

				//	We slow down as we get closer

				Metric rSpeed;
				if (rDelta2 < FINAL_DOCKING2)
					rSpeed = rMinSpeed;
				else if (rDelta2 < FINAL_APPROACH2)
					{
					Metric rSpeedRange = rMaxSpeed - rMinSpeed;
					Metric rDelta = sqrt(rDelta2);
					rSpeed = rMinSpeed + (rSpeedRange * (rDelta - FINAL_DOCKING) / (FINAL_APPROACH - FINAL_DOCKING));
					}
				else
					rSpeed = rMaxSpeed;

				//	Figure out the ideal velocity vector that we want to
				//	be following.

				CVector vIdealVel = vDelta.Normal() * rSpeed;

				//	Calculate the delta v that we need

				CVector vDeltaV = vIdealVel - pShip->GetVel();

				//	Rotate

				if (pShip != g_pUniverse->GetPlayer())
					{
					IShipController *pController = pShip->GetController();

					//	If we're close enough, align to rotation angle

					if (rDelta2 < FINAL_APPROACH2)
						pController->SetManeuver(CalcTurnManeuver(iFinalRotation, pShip->GetRotation(), pShip->GetRotationAngle()));

					//	Otherwise, align along delta v

					else
						pController->SetManeuver(CalcTurnManeuver(VectorToPolar(vDeltaV), pShip->GetRotation(), pShip->GetRotationAngle()));
					}

				//	Accelerate

				pShip->Accelerate(vDeltaV * pShip->GetMass() / 10000.0, g_SecondsPerUpdate);

				pShip->ClipSpeed(rSpeed);
				}
			}
		}
	}
예제 #12
0
void DoSmokeTest (CUniverse &Universe, CXMLElement *pCmdLine)
	{
	ALERROR error;
	int i, j;

	int iSystemSample = pCmdLine->GetAttributeInteger(CONSTLIT("count"));
	if (iSystemSample == 0)
		iSystemSample = DEFAULT_SYSTEM_SAMPLE;

	int iSystemUpdateTime = 100;

	//	Generate systems for multiple games

	CSymbolTable AllSystems(TRUE, TRUE);
	for (i = 0; i < iSystemSample; i++)
		{
		printf("sample %d", i+1);

		CTopologyNode *pNode = Universe.GetFirstTopologyNode();

		while (true)
			{
			//	Create the system

			CSystem *pSystem;
			if (error = Universe.CreateStarSystem(pNode, &pSystem))
				{
				printf("ERROR: Unable to create star system.\n");
				return;
				}

			//	Set the POV

			CSpaceObject *pPOV = pSystem->GetObject(0);
			Universe.SetPOV(pPOV);
			pSystem->SetPOVLRS(pPOV);

			//	Prepare system

			Universe.UpdateExtended();
			Universe.GarbageCollectLibraryBitmaps();
			Universe.LoadLibraryBitmaps();

			//	Update for a while

			for (j = 0; j < iSystemUpdateTime; j++)
				Universe.Update(g_SecondsPerUpdate, true);

			//	Get the next node

			CString sEntryPoint;
			pNode = pSystem->GetStargateDestination(CONSTLIT("Outbound"), &sEntryPoint);
			if (pNode == NULL || pNode->IsEndGame())
				break;

			//	Done with old system

			Universe.DestroySystem(pSystem);

			printf(".");
			}

		Universe.Reinit();
		printf("\n");
		}

	//	Done

	printf("Test successful.\n");
	}