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; } } } }
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"); }
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"); }
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; } } } }
void GenerateTopology (CUniverse &Universe, CXMLElement *pCmdLine) { int i, j, k; int iCount = pCmdLine->GetAttributeIntegerBounded(COUNT_SWITCH, 1, -1, 1); STopologyStats Stats; for (k = 0; k < iCount; k++) { if (iCount > 1) printf("sample %d", k+1); TSortMap<CString, SNodeInfo> NodeData; TSortMap<CString, int> AttribCount; // Initialize the topology CString sError; Universe.GetFirstTopologyNode(); // Loop over all nodes for (i = 0; i < Universe.GetTopologyNodeCount(); i++) { CTopologyNode *pNode = Universe.GetTopologyNode(i); SNodeInfo *pNewNode = NodeData.Insert(pNode->GetID()); pNewNode->sID = pNode->GetID(); pNewNode->sName = pNode->GetSystemName(); pNewNode->dwSystemUNID = pNode->GetSystemDescUNID(); pNewNode->sAttribs = pNode->GetAttributes(); // Add the attributes in this node to the list of // attributes for this try. TArray<CString> Attribs; ParseAttributes(pNewNode->sAttribs, &Attribs); for (j = 0; j < Attribs.GetCount(); j++) { int *pCount = AttribCount.GetAt(Attribs[j]); if (pCount == NULL) { pCount = AttribCount.Insert(Attribs[j]); *pCount = 0; } *pCount = (*pCount) + 1; } } // Compute topology stats // Add the node count for this try Stats.NodeCount.Insert(NodeData.GetCount()); // Loop over all attributes that we know about. If one doesn't // exist in this try, then we set its min to 0 if (k > 0) { for (i = 0; i < Stats.Attribs.GetCount(); i++) { if (AttribCount.GetAt(Stats.Attribs.GetKey(i)) == NULL) Stats.Attribs[i].SetMin(0); } } // Loop over all attributes in this try and add them to the stats SStat *pAttribStat; for (i = 0; i < AttribCount.GetCount(); i++) { // If we have some attributes that no other try had, then // that means that the minimum value is 0. if (pAttribStat = Stats.Attribs.GetAt(AttribCount.GetKey(i))) pAttribStat->Insert(AttribCount[i]); else { pAttribStat = Stats.Attribs.Insert(AttribCount.GetKey(i)); pAttribStat->Insert(AttribCount[i]); if (k > 0) pAttribStat->SetMin(0); } } // Output all the nodes if (iCount == 1) { printf("Node\tSystemType\tName\tStargates\tAttributes\n"); for (i = 0; i < NodeData.GetCount(); i++) { SNodeInfo *pNode = &NodeData.GetValue(i); printf("%s\t%08x\t%s\t%d\t%s\n", pNode->sID.GetASCIIZPointer(), pNode->dwSystemUNID, pNode->sName.GetASCIIZPointer(), pNode->Stargates.GetCount(), pNode->sAttribs.GetASCIIZPointer()); } } else { Universe.Reinit(); printf("\n"); } } // Output stats if (iCount > 0) { printf("\n"); printf("STATS\n\n"); Stats.NodeCount.Print(CONSTLIT("Nodes"), iCount, Stats.NodeCount.GetAverage(iCount)); printf("\n"); printf("ATTRIBS\n\n"); for (i = 0; i < Stats.Attribs.GetCount(); i++) Stats.Attribs[i].Print(Stats.Attribs.GetKey(i), iCount, Stats.NodeCount.GetAverage(iCount)); printf("\n"); } }
void GenerateTopologyMap (CUniverse &Universe, CXMLElement *pCmdLine) { int i; // Some parameters int iScale = pCmdLine->GetAttributeIntegerBounded(CONSTLIT("scale"), 100, -1, -1); // We need to create all systems so that the global object table is // initialized. for (i = 0; i < Universe.GetTopologyNodeCount(); i++) { CTopologyNode *pNode = Universe.GetTopologyNode(i); // Do not try to create end game nodes if (pNode->IsEndGame()) continue; // Node is known pNode->SetKnown(); // Create this system CSystem *pNewSystem; CString sError; if (Universe.CreateStarSystem(pNode, &pNewSystem, &sError) != NOERROR) { printf("ERROR: creating system %s: %s\n", (LPSTR)pNode->GetSystemName(), (LPSTR)sError); continue; } // Delete the system Universe.FlushStarSystem(pNode); } // Initialize the output COutputChart Output; Output.SetStyleFont(STYLE_NAME, pCmdLine->GetAttribute(CONSTLIT("font"))); Output.SetStyleColor(STYLE_NAME, CG32bitPixel(0xFF, 0xFF, 0xFF)); Output.SetOutputFilespec(pCmdLine->GetAttribute(CONSTLIT("output"))); // Get the topology node CTopologyNode *pFirstNode = Universe.GetFirstTopologyNode(); if (pFirstNode == NULL) { printf("ERROR: Unable to find topology node.\n"); return; } // Get the system map for the node CSystemMap *pMap = pFirstNode->GetDisplayPos(); if (pMap == NULL) { printf("ERROR: No system map for node %s.\n", pFirstNode->GetID().GetASCIIZPointer()); return; } // If we didn't set a scale, use the map's initial scale if (iScale == -1) pMap->GetScale(&iScale); // Initialize painting structures CSystemMapThumbnails Thumbs; Thumbs.Init(Universe.GetGlobalObjects()); CGalacticMapPainter Painter(Universe, pMap, Thumbs); int cxMap = Painter.GetWidth() * iScale / 100; int cyMap = Painter.GetHeight() * iScale / 100; // Compute the size of the map RECT rcView; rcView.left = 0; rcView.top = 0; rcView.right = cxMap; rcView.bottom = cyMap; // Create the output Output.SetContentSize(cxMap, cyMap); CG32bitImage &Dest = Output.GetOutputImage(); // Paint Painter.SetViewport(rcView); Painter.SetScale(iScale); Painter.SetPos(0, 0); Painter.Paint(Dest); // Done Output.Output(); }