bool CAeonEngine::OpenTableDefinitions (void) // OpenTableDefinitions // // Opens and reads all tables in all volumes. Note that we have no idea what // could have happened since our last boot--someone could have copied files // all over the place. We make almost no assumptions. { CSmartLock Lock(m_cs); int i, j; CString sError; // Loop over all volumes and end up with a list of tables and volumes TSortMap<CString, TArray<CString>> Tables; for (i = 0; i < m_LocalVolumes.GetCount(); i++) { CString sVolume = m_LocalVolumes.GetVolume(i); TArray<CString> Dirs; fileGetFileList(fileAppend(m_LocalVolumes.GetPath(i), FILESPEC_TABLE_DIR_FILTER), FFL_FLAG_DIRECTORIES_ONLY | FFL_FLAG_RELATIVE_FILESPEC, &Dirs); for (j = 0; j < Dirs.GetCount(); j++) { TArray<CString> *pList = Tables.SetAt(Dirs[j]); pList->Insert(sVolume); } } // Open all tables for (i = 0; i < Tables.GetCount(); i++) { CString sName = Tables.GetKey(i); CAeonTable *pTable = new CAeonTable; if (!pTable->Open(GetProcessCtx(), &m_LocalVolumes, sName, Tables[i], &sError)) { Log(MSG_LOG_ERROR, strPattern("Unable to load %s: %s", sName, sError)); delete pTable; continue; } m_Tables.Insert(sName, pTable); } // Done return true; }
CComplexStruct::CComplexStruct (const TSortMap<CString, CString> &Src) // CComplexStruct construtor { int i; for (i = 0; i < Src.GetCount(); i++) { const CString &sKey = Src.GetKey(i); if (!sKey.IsEmpty()) SetElement(sKey, Src.GetValue(i)); } }
void CDesignCollection::CacheGlobalEvents (CDesignType *pType) // CacheGlobalEvents // // Caches global events for the given type { DEBUG_TRY int i, j; const CEventHandler *pEvents; TSortMap<CString, SEventHandlerDesc> FullEvents; pType->GetEventHandlers(&pEvents, &FullEvents); if (pEvents) { SEventHandlerDesc Event; Event.pExtension = pType->GetExtension(); for (i = 0; i < pEvents->GetCount(); i++) { CString sEvent = pEvents->GetEvent(i, &Event.pCode); for (j = 0; j < evtCount; j++) if (m_EventsCache[j]->Insert(pType, sEvent, Event)) break; } } else { for (i = 0; i < FullEvents.GetCount(); i++) { CString sEvent = FullEvents.GetKey(i); const SEventHandlerDesc &Event = FullEvents[i]; for (j = 0; j < evtCount; j++) if (m_EventsCache[j]->Insert(pType, sEvent, Event)) break; } } DEBUG_CATCH }
void AccumulateSystem (CTopologyNode *pNode, CSystem *pSystem, TSortMap<DWORD, STypeInfo> &AllTypes) { int j; int iSystemLevel = pSystem->GetLevel(); // 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 CDesignType *pType; if ((pType = pObj->GetEncounterInfo()) || (pType = pObj->GetType())) { STypeInfo *pInfo = AllTypes.SetAt(pType->GetUNID()); pInfo->iTotalCount++; pInfo->PerLevel[iSystemLevel]++; } // 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()) { STypeInfo *pInfo = AllTypes.SetAt(Item.GetType()->GetUNID()); pInfo->iTotalCount += Item.GetCount(); pInfo->PerLevel[iSystemLevel] += Item.GetCount(); } } } } }
ALERROR OutputTypeTable (TSortMap<DWORD, STypeStats> &AllStats, int iSystemSample) { ALERROR error; int i, j; // Output all items to a well-known file CTextFileLog Output(TYPE_COUNT_FILENAME); if (error = Output.Create(FALSE)) { printf("ERROR: Unable to create output file: %s\n", TYPE_COUNT_FILENAME.GetASCIIZPointer()); return error; } for (i = 0; i < AllStats.GetCount(); i++) { DWORD dwUNID = AllStats.GetKey(i); const STypeStats &Stats = AllStats[i]; TArray<TNumberSeries<double>::SHistogramPoint> Histogram; Stats.PerGame.CalcHistogram(&Histogram); CString sLine; sLine = strPatternSubst("0x%x\t%d\t%d", dwUNID, (int)((Stats.PerGame.GetMean() * 1000.0) + 0.5), Histogram.GetCount()); for (j = 0; j < Histogram.GetCount(); j++) sLine.Append(strPatternSubst("\t%d\t%d", Histogram[j].iValue, (int)(Histogram[j].rPercent * 100.0 + 0.5))); Output.LogOutput(0, sLine); } if (error = Output.Close()) { printf("ERROR: Unable to create output file: %s\n", TYPE_COUNT_FILENAME.GetASCIIZPointer()); return error; } return NOERROR; }
void AddTypesUsedRecursive (CUniverse &Universe, DWORD dwUNID, TSortMap<DWORD, bool> *retTypesUsed) { int i; // If already added, don't bother if (retTypesUsed->Find(dwUNID)) return; CDesignType *pType = Universe.FindDesignType(dwUNID); if (pType == NULL) return; retTypesUsed->SetAt(dwUNID, true); // Recurse TSortMap<DWORD, bool> TypesUsed; pType->AddTypesUsed(&TypesUsed); for (i = 0; i < TypesUsed.GetCount(); i++) AddTypesUsedRecursive(Universe, TypesUsed.GetKey(i), retTypesUsed); }
CString ParserCtx::LookupEntity (const CString &sName, bool *retbFound) { CString *pValue = EntityTable.GetAt(sName); if (pValue == NULL) { if (m_pParentCtx) return m_pParentCtx->LookupEntity(sName, retbFound); else if (m_pController) return m_pController->ResolveExternalEntity(sName, retbFound); else { if (retbFound) *retbFound = false; return sName; } } if (retbFound) *retbFound = true; return *pValue; }
void ParserCtx::DefineEntity (const CString &sName, const CString &sValue) { EntityTable.Insert(sName, sValue); }
void GenerateTypeTable (CUniverse &Universe, CXMLElement *pCmdLine) { int i, j; // Get the criteria from the command line. CString sCriteria = pCmdLine->GetAttribute(CRITERIA_ATTRIB); // Parse it CDesignTypeCriteria Criteria; if (CDesignTypeCriteria::ParseCriteria(sCriteria, &Criteria) != NOERROR) { printf("ERROR: Unable to parse criteria.\n"); return; } // Generate a table of all matching types TSortMap<CString, CDesignType *> Table; // Loop over all items for this level and add them to // a sorted table. for (i = 0; i < Universe.GetDesignTypeCount(); i++) { CDesignType *pType = Universe.GetDesignType(i); int iLevel = pType->GetLevel(); if (!pType->MatchesCriteria(Criteria)) continue; // Get the name CString sName = pType->GetDataField(FIELD_NAME); if (*sName.GetASCIIZPointer() == '(') sName = strSubString(sName, 1, -1); // Figure out the sort order char szBuffer[1024]; wsprintf(szBuffer, "%02d%s%08x", iLevel, sName.GetASCIIZPointer(), pType->GetUNID()); Table.Insert(CString(szBuffer), pType); } // Generate a list of columns to display TArray<CString> Cols; Cols.Insert(FIELD_LEVEL); Cols.Insert(FIELD_NAME); for (i = 0; i < pCmdLine->GetAttributeCount(); i++) { CString sAttrib = pCmdLine->GetAttributeName(i); if (!IsMainCommandParam(sAttrib) && !strEquals(sAttrib, CONSTLIT("typetable"))) { CString sValue = pCmdLine->GetAttribute(i); if (!strEquals(sValue, CONSTLIT("true"))) Cols.Insert(strPatternSubst(CONSTLIT("%s:%s"), sAttrib, sValue)); else Cols.Insert(sAttrib); } } // If we need to output total count, then load the table CDesignTypeStats TotalCount; if (pCmdLine->GetAttributeBool(FIELD_TOTAL_COUNT) || pCmdLine->GetAttributeBool(FIELD_COUNT_DISTRIBUTION)) { if (LoadDesignTypeStats(Universe.GetDesignCollection().GetAdventureUNID(), &TotalCount) != NOERROR) { printf("ERROR: Unable to load type count table.\n"); return; } } // If we've got any entries in the table, output now if (Table.GetCount()) { // Output the header for (j = 0; j < Cols.GetCount(); j++) { if (j != 0) printf("\t"); printf(Cols[j].GetASCIIZPointer()); } printf("\n"); // Output each row CCodeChainCtx CCCtx; for (i = 0; i < Table.GetCount(); i++) { CDesignType *pType = Table[i]; for (j = 0; j < Cols.GetCount(); j++) { if (j != 0) printf("\t"); const CString &sField = Cols[j]; // Format and output if (strEquals(sField, FIELD_TOTAL_COUNT)) { SDesignTypeInfo *pInfo = TotalCount.GetAt(pType->GetUNID()); double rCount = (pInfo ? pInfo->rPerGameMeanCount : 0.0); printf("%.2f", rCount); } else if (strEquals(sField, FIELD_COUNT_DISTRIBUTION)) { SDesignTypeInfo *pInfo = TotalCount.GetAt(pType->GetUNID()); printf("%s", (pInfo ? pInfo->sDistribution : NULL_STR).GetASCIIZPointer()); } else { ICCItem *pResult = pType->GetProperty(CCCtx, sField); CString sValue = pResult->Print(&g_pUniverse->GetCC(), PRFLAG_NO_QUOTES | PRFLAG_ENCODE_FOR_DISPLAY); pResult->Discard(&g_pUniverse->GetCC()); printf(sValue.GetASCIIZPointer()); } } printf("\n"); } printf("\n"); } else printf("No entries match criteria.\n"); }
void GenerateTypeIslands (CUniverse &Universe, CXMLElement *pCmdLine) { int i, j; bool bExcludeImages = true; printf("TYPE ISLANDS\n"); printf("------------\n\n"); // Make a list of default types #if 0 g_DefaultTypes.SetAt(0x00001001, true); // independent sovereign g_DefaultTypes.SetAt(0x00001002, true); // Commonwealth sovereign g_DefaultTypes.SetAt(0x00001003, true); // independent sovereign g_DefaultTypes.SetAt(0x00001007, true); // ares sovereign g_DefaultTypes.SetAt(0x0000100c, true); // sung slavers sovereign g_DefaultTypes.SetAt(0x0000100f, true); // auton sovereign g_DefaultTypes.SetAt(0x00001011, true); // corporate hierarchy g_DefaultTypes.SetAt(0x00004027, true); // container of frozen supplies g_DefaultTypes.SetAt(0x0000402c, true); // pteracnium ore g_DefaultTypes.SetAt(0x000040ae, true); // helium3 reactor assembly g_DefaultTypes.SetAt(0x000040af, true); // pteracnium fuel g_DefaultTypes.SetAt(0x000040ca, true); // lancer cannon g_DefaultTypes.SetAt(0x000040e2, true); // worldship armor g_DefaultTypes.SetAt(0x00004100, true); // xenotite ore g_DefaultTypes.SetAt(0x00004109, true); // SN2500 reactor g_DefaultTypes.SetAt(0x00004167, true); // tetramite ore g_DefaultTypes.SetAt(0x00005004, true); // wreck ejecta g_DefaultTypes.SetAt(0x0000500c, true); // blast explosion 2 g_DefaultTypes.SetAt(0x0000500d, true); // blast explosion 3 g_DefaultTypes.SetAt(0x0000500e, true); // blast explosion 4 g_DefaultTypes.SetAt(0x0000500f, true); // thermo explosion 1 g_DefaultTypes.SetAt(0x00005011, true); // thermo explosion 3 g_DefaultTypes.SetAt(0x00005012, true); // thermo explosion 4 g_DefaultTypes.SetAt(0x00009004, true); // shield effect g_DefaultTypes.SetAt(0x00009007, true); // explosion effect g_DefaultTypes.SetAt(0x0000900a, true); // fire effect g_DefaultTypes.SetAt(0x0000A003, true); // dsAbandonedStation g_DefaultTypes.SetAt(0x0000a017, true); // dock screen? g_DefaultTypes.SetAt(0x001a200c, true); // wreck of the CSC Europa g_DefaultTypes.SetAt(0x001a200e, true); // sandstorm wreck g_DefaultTypes.SetAt(0x001c1002, true); // ares sect in Heretic g_DefaultTypes.SetAt(0x08020102, true); // huari empire sovereign g_DefaultTypes.SetAt(0x08040140, true); // gaian processor station #endif // Create a reverse index of all type dependencies ReverseIndexMap ReverseIndex; for (i = 0; i < Universe.GetDesignTypeCount(); i++) { CDesignType *pType = Universe.GetDesignType(i); // Get the list of UNIDs that this type uses TSortMap<DWORD, bool> TypesUsed; pType->AddTypesUsed(&TypesUsed); for (j = 0; j < TypesUsed.GetCount(); j++) { CDesignType *pRequired = Universe.FindDesignType(TypesUsed.GetKey(j)); if (pRequired == NULL) continue; // Add to reverse index TArray<DWORD> *pList = ReverseIndex.SetAt(pRequired->GetUNID()); pList->Insert(pType->GetUNID()); } } // We create a list of islands. In each island, all the types refer to // each other and don't refer to types on any other island. TArray<IslandMap> AllIslands; // Loop over all types and add them to an island. for (i = 0; i < Universe.GetDesignTypeCount(); i++) { CDesignType *pType = Universe.GetDesignType(i); // Exclude images if (bExcludeImages && pType->GetType() == designImage) continue; if (pType->GetType() == designShipTable) continue; // Exclude default types if (g_DefaultTypes.Find(pType->GetUNID())) continue; // If this type is already on one of the islands, then we skip it. #if 0 bool bFound = false; for (j = 0; j < AllIslands.GetCount(); j++) if (AllIslands[j].Find(pType->GetUNID())) { bFound = true; break; } if (bFound) continue; #endif // Since this type is not on any island, we add start a new island and // add all related types to it. IslandMap *pIsland = AllIslands.Insert(); AddTypeToIsland(Universe, ReverseIndex, pIsland, pType); // Print printf("ISLAND %s\n", (char *)GetTypeDesc(pType)); for (j = 0; j < pIsland->GetCount(); j++) { CDesignType *pType = Universe.FindDesignType(pIsland->GetKey(j)); if (pType == NULL) continue; printf("%s\n", (char *)GetTypeDesc(pType)); } printf("\n"); } }
void GenerateImageChart (CUniverse &Universe, CXMLElement *pCmdLine) { int i; enum OrderTypes { orderSmallest = 1, orderLargest = 2, orderName = 3, orderLevel = 4, orderSovereign = 5, orderManufacturer = 6, }; // Item criteria bool bHasItemCriteria; CString sCriteria; CItemCriteria ItemCriteria; if (bHasItemCriteria = pCmdLine->FindAttribute(CONSTLIT("itemCriteria"), &sCriteria)) CItem::ParseCriteria(sCriteria, &ItemCriteria); else CItem::InitCriteriaAll(&ItemCriteria); // Get the criteria from the command line. CDesignTypeCriteria Criteria; if (pCmdLine->FindAttribute(CONSTLIT("criteria"), &sCriteria)) { if (CDesignTypeCriteria::ParseCriteria(sCriteria, &Criteria) != NOERROR) { printf("ERROR: Unable to parse criteria.\n"); return; } } else if (bHasItemCriteria) { if (CDesignTypeCriteria::ParseCriteria(CONSTLIT("i"), &Criteria) != NOERROR) { printf("ERROR: Unable to parse criteria.\n"); return; } } else { printf("ERROR: Expected criteria.\n"); return; } bool bAll = pCmdLine->GetAttributeBool(CONSTLIT("all")); // Options bool bTextBoxesOnly = pCmdLine->GetAttributeBool(CONSTLIT("textBoxesOnly")); bool bFieldUNID = pCmdLine->GetAttributeBool(CONSTLIT("unid")); // Figure out what order we want CString sOrder = pCmdLine->GetAttribute(CONSTLIT("sort")); int iOrder; if (strEquals(sOrder, CONSTLIT("smallest"))) iOrder = orderSmallest; else if (strEquals(sOrder, CONSTLIT("largest"))) iOrder = orderLargest; else if (strEquals(sOrder, CONSTLIT("level"))) iOrder = orderLevel; else if (strEquals(sOrder, CONSTLIT("sovereign"))) iOrder = orderSovereign; else if (strEquals(sOrder, CONSTLIT("manufacturer"))) iOrder = orderManufacturer; else iOrder = orderName; bool b3DGrid = pCmdLine->GetAttributeBool(CONSTLIT("3DGrid")); bool bDockingPorts = pCmdLine->GetAttributeBool(CONSTLIT("portPos")); bool bDevicePos = pCmdLine->GetAttributeBool(CONSTLIT("devicePos")); // Image size int cxDesiredWidth; if (pCmdLine->FindAttributeInteger(CONSTLIT("width"), &cxDesiredWidth)) cxDesiredWidth = Max(512, cxDesiredWidth); else cxDesiredWidth = 1280; // Spacing int cxSpacing = pCmdLine->GetAttributeInteger(CONSTLIT("xSpacing")); int cxExtraMargin = pCmdLine->GetAttributeInteger(CONSTLIT("xMargin")); int cxImageMargin = 2 * pCmdLine->GetAttributeInteger(CONSTLIT("xImageMargin")); // Font for text CString sTypeface; int iSize; bool bBold; bool bItalic; if (!CG16bitFont::ParseFontDesc(pCmdLine->GetAttribute(CONSTLIT("font")), &sTypeface, &iSize, &bBold, &bItalic)) { sTypeface = CONSTLIT("Arial"); iSize = 10; bBold = false; bItalic = false; } CG16bitFont NameFont; NameFont.Create(sTypeface, -PointsToPixels(iSize), bBold, bItalic); CG32bitPixel rgbNameColor = CG32bitPixel(255, 255, 255); // Rotation int iRotation = pCmdLine->GetAttributeInteger(CONSTLIT("rotation")); // Output file CString sFilespec = pCmdLine->GetAttribute(CONSTLIT("output")); if (!sFilespec.IsBlank()) sFilespec = pathAddExtensionIfNecessary(sFilespec, CONSTLIT(".bmp")); // Generate a sorted table of types TSortMap<CString, SEntryDesc> Table; for (i = 0; i < Universe.GetDesignTypeCount(); i++) { CDesignType *pType = Universe.GetDesignType(i); SEntryDesc NewEntry; // Make sure we match the criteria if (!pType->MatchesCriteria(Criteria)) continue; // Figure stuff stuff out based on the specific design type switch (pType->GetType()) { case designItemType: { CItemType *pItemType = CItemType::AsType(pType); CItem Item(pItemType, 1); // Skip if not in item criteria if (!Item.MatchesCriteria(ItemCriteria)) continue; // Skip virtual classes if (pItemType->IsVirtual()) continue; // Initialize the entry NewEntry.pType = pType; NewEntry.sName = pItemType->GetNounPhrase(0); NewEntry.pImage = &pItemType->GetImage(); NewEntry.iSize = RectWidth(NewEntry.pImage->GetImageRect()); break; } case designShipClass: { CShipClass *pClass = CShipClass::AsType(pType); // Skip non-generic classess if (!bAll && !pClass->HasLiteralAttribute(CONSTLIT("genericClass"))) continue; // Initialize the entry NewEntry.pType = pType; NewEntry.sName = pClass->GetNounPhrase(0); NewEntry.iSize = RectWidth(pClass->GetImage().GetImageRect()); NewEntry.pImage = &pClass->GetImage(); NewEntry.iRotation = pClass->Angle2Direction(iRotation); NewEntry.sSovereignName = (pClass->GetDefaultSovereign() ? pClass->GetDefaultSovereign()->GetTypeNounPhrase() : NULL_STR); break; } case designStationType: { CStationType *pStationType = CStationType::AsType(pType); // Skip generic classes if (!bAll && !pStationType->HasLiteralAttribute(CONSTLIT("generic"))) continue; NewEntry.pType = pType; NewEntry.sName = pStationType->GetNounPhrase(0); NewEntry.iSize = pStationType->GetSize(); NewEntry.sSovereignName = (pStationType->GetSovereign() ? pStationType->GetSovereign()->GetTypeNounPhrase() : NULL_STR); InitStationTypeImage(NewEntry, pStationType); break; } default: // Don't know how to handle this type continue; break; } // Adjust name if (bFieldUNID) NewEntry.sName = strPatternSubst(CONSTLIT("%s (%x)"), NewEntry.sName, NewEntry.pType->GetUNID()); // Compute the sort key char szBuffer[1024]; switch (iOrder) { case orderLargest: wsprintf(szBuffer, "%09d%s%x", 1000000 - NewEntry.iSize, NewEntry.sName.GetASCIIZPointer(), pType->GetUNID()); break; case orderLevel: wsprintf(szBuffer, "%09d%s%x", pType->GetLevel(), NewEntry.sName.GetASCIIZPointer(), pType->GetUNID()); break; case orderSmallest: wsprintf(szBuffer, "%09d%s%x", NewEntry.iSize, NewEntry.sName.GetASCIIZPointer(), pType->GetUNID()); break; case orderSovereign: wsprintf(szBuffer, "%s|%s|%x", NewEntry.sSovereignName.GetASCIIZPointer(), NewEntry.sName.GetASCIIZPointer(), pType->GetUNID()); NewEntry.sCategorize = NewEntry.sSovereignName; break; case orderManufacturer: { CString sManufacturer = NewEntry.pType->GetPropertyString(CONSTLIT("manufacturer")); wsprintf(szBuffer, "%s|%s|%x", sManufacturer.GetASCIIZPointer(), NewEntry.sName.GetASCIIZPointer(), pType->GetUNID()); NewEntry.sCategorize = sManufacturer; break; } default: wsprintf(szBuffer, "%s%x", NewEntry.sName.GetASCIIZPointer(), pType->GetUNID()); break; } // Add to list Table.Insert(CString(szBuffer), NewEntry); } // Allocate an arranger that tracks where to paint each world. CImageArranger Arranger; // Settings for the overall arrangement CImageArranger::SArrangeDesc Desc; Desc.cxDesiredWidth = Max(512, cxDesiredWidth - (2 * (cxSpacing + cxExtraMargin))); Desc.cxSpacing = cxSpacing; Desc.cxExtraMargin = cxExtraMargin; Desc.pHeader = &NameFont; // Generate a table of cells for the arranger TArray<CCompositeImageSelector> Selectors; Selectors.InsertEmpty(Table.GetCount()); CString sLastCategory; TArray<CImageArranger::SCellDesc> Cells; for (i = 0; i < Table.GetCount(); i++) { SEntryDesc &Entry = Table[i]; CImageArranger::SCellDesc *pNewCell = Cells.Insert(); pNewCell->cxWidth = (Entry.pImage ? RectWidth(Entry.pImage->GetImageRect()) : 0) + cxImageMargin; pNewCell->cyHeight = (Entry.pImage ? RectHeight(Entry.pImage->GetImageRect()) : 0) + cxImageMargin; pNewCell->sText = Entry.sName; if (!strEquals(sLastCategory, Entry.sCategorize)) { sLastCategory = Entry.sCategorize; pNewCell->bStartNewRow = true; } } // Arrange Arranger.ArrangeByRow(Desc, Cells); // Create a large image CG32bitImage Output; int cxWidth = Max(cxDesiredWidth, Arranger.GetWidth()); int cyHeight = Arranger.GetHeight(); Output.Create(cxWidth, cyHeight); printf("Creating %dx%d image.\n", cxWidth, cyHeight); // Paint the images for (i = 0; i < Table.GetCount(); i++) { SEntryDesc &Entry = Table[i]; int x = Arranger.GetX(i); int y = Arranger.GetY(i); // Paint if (x != -1) { int xCenter = x + (Arranger.GetWidth(i) / 2); int yCenter = y + (Arranger.GetHeight(i) / 2); int xOffset; int yOffset; Entry.pImage->GetImageOffset(0, Entry.iRotation, &xOffset, &yOffset); int cxImage = RectWidth(Entry.pImage->GetImageRect()); int cyImage = RectHeight(Entry.pImage->GetImageRect()); // Paint image if (!bTextBoxesOnly && Entry.pImage) { Entry.pImage->PaintImageUL(Output, x + (Arranger.GetWidth(i) - cxImage) / 2, y + (Arranger.GetHeight(i) - cyImage) / 2, 0, Entry.iRotation); } // Paint type specific stuff switch (Entry.pType->GetType()) { case designStationType: { CStationType *pStationType = CStationType::AsType(Entry.pType); int xStationCenter = xCenter - xOffset; int yStationCenter = yCenter - yOffset; if (bDockingPorts) pStationType->PaintDockPortPositions(Output, xStationCenter, yStationCenter); if (bDevicePos) pStationType->PaintDevicePositions(Output, xStationCenter, yStationCenter); // If we have docking or device positions, mark the center of the station if (bDockingPorts || bDevicePos) { const int LINE_HALF_LENGTH = 24; const CG32bitPixel RGB_CENTER_CROSS(255, 255, 0); Output.DrawLine(xStationCenter - LINE_HALF_LENGTH, yStationCenter, xStationCenter + LINE_HALF_LENGTH, yStationCenter, 1, RGB_CENTER_CROSS); Output.DrawLine(xStationCenter, yStationCenter - LINE_HALF_LENGTH, xStationCenter, yStationCenter + LINE_HALF_LENGTH, 1, RGB_CENTER_CROSS); } break; } } // Paint the 3D grid, if necessary if (b3DGrid) { int iScale = Entry.pImage->GetImageViewportSize(); Metric rMaxRadius = g_KlicksPerPixel * cxImage * 0.5; const Metric rGridSize = LIGHT_SECOND; Metric rRadius; for (rRadius = rGridSize; rRadius <= rMaxRadius; rRadius += rGridSize) { int iRadius = (int)((rRadius / g_KlicksPerPixel) + 0.5); const int iGridAngle = 8; int iPrevAngle = 0; int iAngle; for (iAngle = iGridAngle; iAngle <= 360; iAngle += iGridAngle) { int xFrom, yFrom; C3DConversion::CalcCoord(iScale, iPrevAngle, iRadius, 0, &xFrom, &yFrom); int xTo, yTo; C3DConversion::CalcCoord(iScale, iAngle, iRadius, 0, &xTo, &yTo); Output.DrawLine(xFrom + xCenter, yFrom + yCenter, xTo + xCenter, yTo + yCenter, 1, CG32bitPixel(255, 255, 0)); iPrevAngle = iAngle; } } } // Paint name int xText = Arranger.GetTextX(i); int yText = Arranger.GetTextY(i); if (xText != -1) { if (bTextBoxesOnly) Output.Fill(xText, yText, Arranger.GetTextWidth(i), Arranger.GetTextHeight(i), 0xffff); if (!bTextBoxesOnly) { Output.FillColumn(xCenter, y + Arranger.GetHeight(i), yText - (y + Arranger.GetHeight(i)), rgbNameColor); NameFont.DrawText(Output, xText, yText, rgbNameColor, Entry.sName); } } } } // Write to file or clipboard OutputImage(Output, sFilespec); }
void CNewGameSession::SetShipClass (CShipClass *pClass, int x, int y, int cxWidth) // SetShipClass // // Sets the ship class { int i; const CPlayerSettings *pPlayerSettings = pClass->GetPlayerSettings(); const CVisualPalette &VI = m_HI.GetVisuals(); const CG16bitFont &MediumBoldFont = VI.GetFont(fontMediumBold); const CG16bitFont &SubTitleFont = VI.GetFont(fontSubTitle); // Ship class name SetShipClassName(pClass->GetName(), x, y, cxWidth); SetShipClassDesc(pPlayerSettings->GetDesc(), x, y, cxWidth); // Offset int yOffset = SMALL_BUTTON_HEIGHT + SMALL_SPACING_VERT + MediumBoldFont.GetHeight() + 2 * SubTitleFont.GetHeight(); // Ship class image SetShipClassImage(pClass, x, y + yOffset, cxWidth); // Delete previous info DeleteElement(ID_SHIP_CLASS_INFO); // Create a sequencer for all class info components CAniSequencer *pClassInfo; CAniSequencer::Create(CVector(x, y + yOffset + SubTitleFont.GetHeight()), &pClassInfo); pClassInfo->SetID(ID_SHIP_CLASS_INFO); // Generate default devices for the ship class CDeviceDescList Devices; pClass->GenerateDevices(1, Devices); // Generate list of all weapons, sorted by level and name TSortMap<CString, CItem> RightSide; for (i = 0; i < Devices.GetCount(); i++) { CDeviceClass *pDevice = Devices.GetDeviceClass(i); if (pDevice->GetCategory() == itemcatWeapon || pDevice->GetCategory() == itemcatLauncher) RightSide.Insert(strPatternSubst(CONSTLIT("%02d_%02d_%s"), 1, pDevice->GetLevel(), pDevice->GetName()), CItem(pDevice->GetItemType(), 1)); } // Add shields TSortMap<CString, CItem> LeftSide; CDeviceClass *pShields = Devices.GetNamedDevice(devShields); if (pShields) RightSide.Insert(strPatternSubst(CONSTLIT("%02d_%02d_%s"), 2, pShields->GetLevel(), pShields->GetName()), CItem(pShields->GetItemType(), 1)); // Add armor RightSide.Insert(CONSTLIT("03"), CItem(g_pUniverse->GetItemType(0), SPECIAL_ARMOR)); // Add reactor LeftSide.Insert(CONSTLIT("01"), CItem(g_pUniverse->GetItemType(0), SPECIAL_REACTOR)); // Add engines LeftSide.Insert(CONSTLIT("02"), CItem(g_pUniverse->GetItemType(0), SPECIAL_DRIVE)); // Add cargo LeftSide.Insert(CONSTLIT("03"), CItem(g_pUniverse->GetItemType(0), SPECIAL_CARGO)); // Add misc devices for (i = 0; i < Devices.GetCount(); i++) { CDeviceClass *pDevice = Devices.GetDeviceClass(i); if (pDevice->GetCategory() == itemcatMiscDevice) LeftSide.Insert(strPatternSubst(CONSTLIT("%02d_%02d_%s"), 4, pDevice->GetLevel(), pDevice->GetName()), CItem(pDevice->GetItemType(), 1)); } // Add device slots LeftSide.Insert(CONSTLIT("05"), CItem(g_pUniverse->GetItemType(0), SPECIAL_DEVICE_SLOTS)); // Set the ship class info. All weapons go to the right of the ship image int xPos = (cxWidth / 2) + (SHIP_IMAGE_RECT_WIDTH / 2); int yPos = 0; int cxInfo = (cxWidth - xPos); for (i = 0; i < RightSide.GetCount(); i++) { int cyInfo; IAnimatron *pInfo; AddClassInfo(pClass, Devices, RightSide[i], xPos, yPos, cxInfo, 0, &cyInfo, &pInfo); pClassInfo->AddTrack(pInfo, 0); yPos += cyInfo + ITEM_INFO_PADDING_VERT; } // Misc devices go on the left xPos = (cxWidth / 2) - (SHIP_IMAGE_RECT_WIDTH / 2); yPos = 0; cxInfo = xPos; for (i = 0; i < LeftSide.GetCount(); i++) { int cyInfo; IAnimatron *pInfo; AddClassInfo(pClass, Devices, LeftSide[i], xPos, yPos, cxInfo, CUIHelper::OPTION_ITEM_RIGHT_ALIGN, &cyInfo, &pInfo); pClassInfo->AddTrack(pInfo, 0); yPos += cyInfo + ITEM_INFO_PADDING_VERT; } m_pRoot->AddLine(pClassInfo); }
void GenerateTypeDependencies (CUniverse &Universe, CXMLElement *pCmdLine) { int i, j; bool bRecursive = pCmdLine->GetAttributeBool(CONSTLIT("recursive")); bool bReverse = pCmdLine->GetAttributeBool(CONSTLIT("reverse")); // Create a reverse index of all type dependencies TSortMap<DWORD, TArray<DWORD> > ReverseIndex; // Types and what they use if (!bReverse) { printf("TYPES AND WHAT THEY USE\n"); printf("-----------------------\n\n"); } for (i = 0; i < Universe.GetDesignTypeCount(); i++) { CDesignType *pType = Universe.GetDesignType(i); if (!bReverse) printf("%s\n", (char *)GetTypeDesc(pType)); // Get the list of UNIDs that this type uses TSortMap<DWORD, bool> TypesUsed; if (bRecursive) AddTypesUsedRecursive(Universe, pType->GetUNID(), &TypesUsed); else pType->AddTypesUsed(&TypesUsed); // Output the list for (j = 0; j < TypesUsed.GetCount(); j++) { CDesignType *pRequired = Universe.FindDesignType(TypesUsed.GetKey(j)); if (pRequired == NULL) continue; if (!bReverse) printf("\t%s\n", (char *)GetTypeDesc(pRequired)); // Add to reverse index TArray<DWORD> *pList = ReverseIndex.SetAt(pRequired->GetUNID()); pList->Insert(pType->GetUNID()); } } // Types and what depends on them if (bReverse) { printf("\nTYPES AND WHAT USES THEM\n"); printf( "------------------------\n\n"); for (i = 0; i < ReverseIndex.GetCount(); i++) { CDesignType *pType = Universe.FindDesignType(ReverseIndex.GetKey(i)); if (pType == NULL) continue; printf("%s\n", (char *)GetTypeDesc(pType)); TArray<DWORD> &List = ReverseIndex.GetValue(i); for (j = 0; j < List.GetCount(); j++) { CDesignType *pRequiredBy = Universe.FindDesignType(List[j]); if (pRequiredBy) printf("\t%s\n", (char *)GetTypeDesc(pRequiredBy)); } } } }
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 GenerateEncounterFrequency (CUniverse &Universe, CXMLElement *pCmdLine) { enum ETypes { outputFreq, outputFillLocations, }; int i, j; // Options int iSystemSample = pCmdLine->GetAttributeIntegerBounded(CONSTLIT("count"), 1, -1, 1); bool bLogo = !pCmdLine->GetAttributeBool(CONSTLIT("noLogo")); bool bAll = pCmdLine->GetAttributeBool(CONSTLIT("all")); bool bRawData = pCmdLine->GetAttributeBool(CONSTLIT("rawData")); ETypes iType; if (pCmdLine->GetAttributeBool(CONSTLIT("fillLocations"))) iType = outputFillLocations; else iType = outputFreq; // Additional columns TArray<CString> Cols; for (i = 0; i < pCmdLine->GetAttributeCount(); i++) { CString sAttrib = pCmdLine->GetAttributeName(i); if (!IsMainCommandParam(sAttrib) && !strEquals(sAttrib, CONSTLIT("count")) && !strEquals(sAttrib, CONSTLIT("fillLocations")) && !strEquals(sAttrib, CONSTLIT("rawData")) && !strEquals(sAttrib, CONSTLIT("encounterfreq"))) { CString sValue = pCmdLine->GetAttribute(i); if (!strEquals(sValue, CONSTLIT("true"))) Cols.Insert(strPatternSubst(CONSTLIT("%s:%s"), sAttrib, sValue)); else Cols.Insert(sAttrib); } } // Generate systems for multiple games CSystemCreateStats Stats; for (i = 0; i < iSystemSample; i++) { if (bLogo) printf("pass %d...\n", i+1); // Initialize the game CString sError; if (Universe.InitGame(0, &sError) != NOERROR) { printf("%s\n", sError.GetASCIIZPointer()); return; } for (j = 0; j < Universe.GetTopologyNodeCount(); j++) { CTopologyNode *pNode = Universe.GetTopologyNode(j); if (pNode->IsEndGame()) continue; // Create the system CSystem *pSystem; if (Universe.CreateStarSystem(pNode, &pSystem, NULL, &Stats) != NOERROR) { printf("ERROR: Unable to create star system.\n"); return; } // Done with old system Universe.DestroySystem(pSystem); } Universe.Reinit(); } // Output based on type if (iType == outputFreq) { // Generate a table for each encounter TSortMap<CStationType *, SEncounterFreqEntry> EncounterFreq; for (i = 0; i < Stats.GetEncounterTableCount(); i++) { const CSystemCreateStats::SEncounterTable &Table = Stats.GetEncounterTable(i); // Skip if only planets and asteroids if (!Table.bHasStation && !bAll) continue; // For each entry in the table, add to the frequency table for (j = 0; j < Table.Table.GetCount(); j++) { CStationType *pEncounterType = Table.Table.GetAt(j); int iChance = Table.Table.GetChance(j); SEncounterFreqEntry *pEntry = EncounterFreq.SetAt(pEncounterType); pEntry->iCount += Table.iCount; pEntry->iTotalChance += Table.iCount * iChance; if (pEntry->pMaxTable == NULL || iChance > pEntry->iMaxChance) { pEntry->pMaxTable = &Table; pEntry->iMaxChance = iChance; } if (pEntry->pMinTable == NULL || iChance < pEntry->iMinChance) { pEntry->pMinTable = &Table; pEntry->iMinChance = iChance; } } } // Output encounter frequency distribution printf("Level\tCategory\tEncounter\tTotal Chances\tAverage Chance\tMin Chance\tMax Chance"); for (i = 0; i < Cols.GetCount(); i++) printf("\t%s", Cols[i].GetASCIIZPointer()); printf("\n"); for (i = 0; i < EncounterFreq.GetCount(); i++) { CStationType *pEncounterType = EncounterFreq.GetKey(i); int iAveWhole = EncounterFreq[i].iTotalChance / EncounterFreq[i].iCount; int iAveFrac = 1000 * (EncounterFreq[i].iTotalChance % EncounterFreq[i].iCount) / EncounterFreq[i].iCount; printf("%d\t%s\t%s\t%d\t%d.%03d\t%d\t%d", pEncounterType->GetLevel(), pEncounterType->GetDataField(CONSTLIT("category")).GetASCIIZPointer(), pEncounterType->GetName().GetASCIIZPointer(), EncounterFreq[i].iCount, iAveWhole, iAveFrac, EncounterFreq[i].iMinChance, EncounterFreq[i].iMaxChance); for (j = 0; j < Cols.GetCount(); j++) { CString sValue = pEncounterType->GetDataField(Cols[j]); printf("\t%s", sValue.GetASCIIZPointer()); } printf("\n"); } // Output raw data if (bRawData) { // Loop over stats and output tables for (i = 0; i < Stats.GetEncounterTableCount(); i++) { const CSystemCreateStats::SEncounterTable &Table = Stats.GetEncounterTable(i); // Skip if only planets and asteroids if (!Table.bHasStation && !bAll) continue; // Header printf("LEVEL %d (%d location%s)\nSystem Type: %08x\nStations: %s\n", Table.iLevel, Table.iCount, (Table.iCount == 1 ? "" : "s"), Table.pSystemType->GetUNID(), Table.sStationCriteria.GetASCIIZPointer()); // Location attributes printf("Location: "); for (j = 0; j < Table.LabelAttribs.GetCount(); j++) { if (j != 0) printf(", "); printf(Table.LabelAttribs[j].GetASCIIZPointer()); } printf("\n"); // Entries for (j = 0; j < Table.Table.GetCount(); j++) printf("%s\t%d\n", Table.Table.GetAt(j)->GetName().GetASCIIZPointer(), Table.Table.GetChance(j)); printf("\n"); } } } else if (iType == outputFillLocations) { printf("Level\tSystem\tEncounter\tChance\n"); for (i = 0; i < Stats.GetFillLocationsTableCount(); i++) { const CSystemCreateStats::SFillLocationsTable &Entry = Stats.GetFillLocationsTable(i); for (j = 0; j < Entry.Table.GetCount(); j++) { int iPercent = (int)(1000.0 * Entry.Table.GetChance(j) / (Metric)Entry.Table.GetTotalChance()); printf("%d\t%s\t%s\t%d.%d\n", Entry.iLevel, Entry.sSystemName.GetASCIIZPointer(), Entry.Table[j]->GetName().GetASCIIZPointer(), iPercent / 10, iPercent % 10); } } } }
void OutputByShipClass (SItemTableCtx &Ctx, const SItemTypeList &ItemList, bool bShowUsage) { int i, j; // Make a map of ship classes for each item TSortMap<DWORD, TArray<CShipClass *>> ItemToShipClass; for (i = 0; i < g_pUniverse->GetShipClassCount(); i++) { CShipClass *pClass = g_pUniverse->GetShipClass(i); // Skip non-generic ones if (!pClass->HasLiteralAttribute(CONSTLIT("genericClass"))) continue; // Add the list of types used by the ship TSortMap<DWORD, bool> TypesUsed; pClass->AddTypesUsed(&TypesUsed); // For each item type, add it to the map for (j = 0; j < TypesUsed.GetCount(); j++) { CDesignType *pType = g_pUniverse->FindDesignType(TypesUsed.GetKey(j)); if (pType && pType->GetType() == designItemType) { TArray<CShipClass *> *pList = ItemToShipClass.SetAt(pType->GetUNID()); pList->Insert(pClass); } } } // If we want to show usage, then we print each item along with the // ship classes using each item. if (bShowUsage) { for (i = 0; i < ItemList.GetCount(); i++) { CItemType *pType = ItemList[i]; printf("%s\n", (LPSTR)pType->GetNounPhrase()); TArray<CShipClass *> *pList = ItemToShipClass.SetAt(pType->GetUNID()); for (j = 0; j < pList->GetCount(); j++) printf("\t%s\n", (LPSTR)pList->GetAt(j)->GetName()); if (pList->GetCount() == 0) printf("\t(none)\n"); printf("\n"); } } // Otherwise we categorize by ship class else { // Now make a list of all ship classes that have our items SByShipClassTypeList ByShipClassTable; for (i = 0; i < ItemList.GetCount(); i++) { const CString &sKey = ItemList.GetKey(i); CItemType *pType = ItemList[i]; // Loop over all ship classes TArray<CShipClass *> *pList = ItemToShipClass.SetAt(pType->GetUNID()); for (j = 0; j < pList->GetCount(); j++) { CString sClassName = pList->GetAt(j)->GetName(); bool bNew; SShipClassEntry *pEntry = ByShipClassTable.SetAt(sClassName, &bNew); if (bNew) pEntry->sShipClassName = sClassName; pEntry->ItemTable.Insert(sKey, pType); } // If no ship class if (pList->GetCount() == 0) { bool bNew; SShipClassEntry *pEntry = ByShipClassTable.SetAt(CONSTLIT("(none)"), &bNew); if (bNew) pEntry->sShipClassName = CONSTLIT("(none)"); pEntry->ItemTable.Insert(sKey, pType); } } // Now loop over all attributes for (i = 0; i < ByShipClassTable.GetCount(); i++) { const SShipClassEntry &Entry = ByShipClassTable[i]; printf("%s\n\n", Entry.sShipClassName.GetASCIIZPointer()); OutputHeader(Ctx); OutputTable(Ctx, Entry.ItemTable); printf("\n"); } } }
void GenerateSimTables (CUniverse &Universe, CXMLElement *pCmdLine) { ALERROR error; int i, j, k; int iSystemSample = pCmdLine->GetAttributeInteger(CONSTLIT("count")); if (iSystemSample == 0) iSystemSample = DEFAULT_SYSTEM_SAMPLE; // Keep track of stats for each type TSortMap<DWORD, STypeStats> AllStats; for (i = 0; i < iSystemSample; i++) { TSortMap<DWORD, STypeInfo> AllTypes; printf("sample %d...\n", i+1); // Initialize the game CString sError; if (error = Universe.InitGame(0, &sError)) { printf("%s\n", sError.GetASCIIZPointer()); return; } // Loop over all nodes for (j = 0; j < Universe.GetTopologyNodeCount(); j++) { CTopologyNode *pNode = Universe.GetTopologyNode(j); // Skip end game nodes if (pNode->IsEndGame()) continue; // Create the system CSystem *pSystem; if (error = Universe.CreateStarSystem(pNode, &pSystem, &sError)) { printf("ERROR: Unable to create star system: %s\n", sError.GetASCIIZPointer()); return; } // Accumulate AccumulateSystem(pNode, pSystem, AllTypes); // Done with old system Universe.DestroySystem(pSystem); } // Now accumulate all stats for (j = 0; j < Universe.GetDesignTypeCount(); j++) { CDesignType *pType = Universe.GetDesignType(j); STypeStats *pStats = AllStats.SetAt(pType->GetUNID()); STypeInfo *pTypeInfo = AllTypes.GetAt(pType->GetUNID()); if (pTypeInfo) { pStats->PerGame.Insert(pTypeInfo->iTotalCount); for (k = 0; k < MAX_TECH_LEVEL; k++) pStats->PerLevel[k].Insert(pTypeInfo->PerLevel[k]); } else { pStats->PerGame.Insert(0); for (k = 0; k < MAX_TECH_LEVEL; k++) pStats->PerLevel[k].Insert(0); } } Universe.Reinit(); } // Output if (error = OutputTypeTable(AllStats, iSystemSample)) return; // Create a table with the sum of all items for the game printf("Total count statistic computed.\n"); }
void CPlayerGameStats::GenerateGameStats (CGameStats &Stats, CSpaceObject *pPlayerShip, bool bGameOver) const // GenerateGameStats // // Generates a stats for everything we track { int j; CShip *pShip = (pPlayerShip ? pPlayerShip->AsShip() : NULL); if (pShip == NULL) return; CPlayerShipController *pPlayer = (CPlayerShipController *)pShip->GetController(); if (pPlayer == NULL) return; CSovereign *pPlayerSovereign = g_pUniverse->FindSovereign(g_PlayerSovereignUNID); if (pPlayerSovereign == NULL) return; // Base stats Stats.Insert(CONSTLIT("Genome"), strCapitalize(GetGenomeName(pPlayer->GetPlayerGenome()))); Stats.Insert(CONSTLIT("Score"), strFormatInteger(CalcEndGameScore(), -1, FORMAT_THOUSAND_SEPARATOR | FORMAT_UNSIGNED)); Stats.Insert(CONSTLIT("Ship class"), pShip->GetNounPhrase(0)); CTimeSpan Time = GetPlayTime(); if (!Time.IsBlank()) Stats.Insert(CONSTLIT("Time played"), Time.Format(NULL_STR)); #ifdef REAL_TIME Time = GetGameTime(); if (!Time.IsBlank()) Stats.Insert(CONSTLIT("Time elapsed in game"), Time.Format(NULL_STR)); #endif // Some combat stats CString sDestroyed = GetStat(ENEMY_SHIPS_DESTROYED_STAT); if (!sDestroyed.IsBlank()) Stats.Insert(CONSTLIT("Enemy ships destroyed"), sDestroyed, CONSTLIT("combat")); sDestroyed = GetStat(FRIENDLY_SHIPS_DESTROYED_STAT); if (!sDestroyed.IsBlank()) Stats.Insert(CONSTLIT("Friendly ships destroyed"), sDestroyed, CONSTLIT("combat")); sDestroyed = GetStat(ENEMY_STATIONS_DESTROYED_STAT); if (!sDestroyed.IsBlank()) Stats.Insert(CONSTLIT("Enemy stations destroyed"), sDestroyed, CONSTLIT("combat")); sDestroyed = GetStat(FRIENDLY_STATIONS_DESTROYED_STAT); if (!sDestroyed.IsBlank()) Stats.Insert(CONSTLIT("Friendly stations destroyed"), sDestroyed, CONSTLIT("combat")); // Add stat for every station destroyed CStatCounterArray CounterArray; CMapIterator i; m_StationStats.Reset(i); while (m_StationStats.HasMore(i)) { SStationTypeStats *pStats; DWORD dwUNID = m_StationStats.GetNext(i, &pStats); CStationType *pType = g_pUniverse->FindStationType(dwUNID); if (pType == NULL) continue; CString sName = pType->GetNounPhrase(0); CString sSort = strPatternSubst(CONSTLIT("%03d%s"), 100 - pType->GetLevel(), sName); if (pType->GetSovereign()->IsEnemy(pPlayerSovereign)) CounterArray.Insert(sName, pStats->iDestroyed, CONSTLIT("Enemy stations destroyed"), sSort); else CounterArray.Insert(sName, pStats->iDestroyed, CONSTLIT("Friendly stations destroyed"), sSort); } CounterArray.GenerateGameStats(Stats); // Add stat for every ship class destroyed CounterArray.DeleteAll(); m_ShipStats.Reset(i); while (m_ShipStats.HasMore(i)) { SShipClassStats *pStats; DWORD dwUNID = m_ShipStats.GetNext(i, &pStats); CShipClass *pClass = g_pUniverse->FindShipClass(dwUNID); if (pClass == NULL) continue; CString sName = pClass->GetNounPhrase(0); CString sSort = strPatternSubst(CONSTLIT("%09d%s"), 100000000 - pClass->GetScore(), sName); if (pStats->iEnemyDestroyed > 0) CounterArray.Insert(sName, pStats->iEnemyDestroyed, CONSTLIT("Enemy ships destroyed"), sSort); if (pStats->iFriendDestroyed > 0) CounterArray.Insert(sName, pStats->iFriendDestroyed, CONSTLIT("Friendly ships destroyed"), sSort); } CounterArray.GenerateGameStats(Stats); // Add stat for every weapon fired m_ItemStats.Reset(i); while (m_ItemStats.HasMore(i)) { SItemTypeStats *pStats; DWORD dwUNID = m_ItemStats.GetNext(i, &pStats); CItemType *pItemType = g_pUniverse->FindItemType(dwUNID); if (pItemType == NULL) continue; CString sName = pItemType->GetNounPhrase(nounShort); CString sSort = strPatternSubst(CONSTLIT("%03d%s"), 100 - pItemType->GetLevel(), sName); // Installed items if (pStats->dwFirstInstalled != INVALID_TIME) Stats.Insert(sName, NULL_STR, CONSTLIT("Items installed"), sSort); if (pStats->iCountFired > 0) Stats.Insert(sName, strFormatInteger(pStats->iCountFired, -1, FORMAT_THOUSAND_SEPARATOR | FORMAT_UNSIGNED), CONSTLIT("Weapons fired"), sSort); } // Stats for player equipment (but only if the game is done) if (bGameOver) { TSortMap<CString, CItem> InstalledItems; // First we generate a sorted list of installed items // (We do this in case there are multiple of the same device/armor so that // we can coalesce them together into a single line). CItemListManipulator ItemList(pShip->GetItemList()); ItemList.ResetCursor(); while (ItemList.MoveCursorForward()) { const CItem &Item(ItemList.GetItemAtCursor()); if (Item.IsInstalled()) { CString sEnhancement = Item.GetEnhancedDesc(pShip); CString sItemName = Item.GetNounPhrase(nounActual | nounCountOnly | nounShort); CString sLine = (sEnhancement.IsBlank() ? sItemName : strPatternSubst(CONSTLIT("%s [%s]"), sItemName, sEnhancement)); bool bInserted; CItem *pEntry = InstalledItems.SetAt(sLine, &bInserted); if (bInserted) { *pEntry = Item; pEntry->SetCount(1); } else pEntry->SetCount(pEntry->GetCount() + 1); } } // Now add all the installed items to the stats for (j = 0; j < InstalledItems.GetCount(); j++) { // Redo the line now that we know the proper count CString sEnhancement = InstalledItems[j].GetEnhancedDesc(pShip); CString sItemName = InstalledItems[j].GetNounPhrase(nounActual | nounCountOnly); CString sLine = (sEnhancement.IsBlank() ? sItemName : strPatternSubst(CONSTLIT("%s [%s]"), sItemName, sEnhancement)); // Compute the sort order int iOrder; switch (InstalledItems[j].GetType()->GetCategory()) { case itemcatWeapon: iOrder = 0; break; case itemcatLauncher: iOrder = 1; break; case itemcatShields: iOrder = 2; break; case itemcatArmor: iOrder = 3; break; case itemcatReactor: iOrder = 4; break; case itemcatDrive: iOrder = 5; break; default: iOrder = 6; break; } CString sSort = strPatternSubst(CONSTLIT("%d%03d%s"), iOrder, 100 - InstalledItems[j].GetType()->GetLevel(), sLine); Stats.Insert(sLine, NULL_STR, CONSTLIT("Final equipment"), sSort); } // Add the remaining items ItemList.ResetCursor(); while (ItemList.MoveCursorForward()) { const CItem &Item(ItemList.GetItemAtCursor()); if (!Item.IsInstalled()) { CString sEnhancement = Item.GetEnhancedDesc(pShip); CString sItemName = Item.GetNounPhrase(nounActual | nounCountOnly); CString sLine = (sEnhancement.IsBlank() ? sItemName : strPatternSubst(CONSTLIT("%s [%s]"), sItemName, sEnhancement)); CString sSort = strPatternSubst(CONSTLIT("%03d%s"), 100 - Item.GetType()->GetLevel(), sLine); Stats.Insert(sLine, NULL_STR, CONSTLIT("Final items"), sSort); } } } }
void GenerateEncounterCount (CUniverse &Universe, CXMLElement *pCmdLine) { int i, j, k, l; // Options int iSystemSample = pCmdLine->GetAttributeIntegerBounded(CONSTLIT("count"), 1, -1, 1); bool bLogo = !pCmdLine->GetAttributeBool(CONSTLIT("noLogo")); bool bAll = pCmdLine->GetAttributeBool(CONSTLIT("all")); // Additional columns TArray<CString> Cols; for (i = 0; i < pCmdLine->GetAttributeCount(); i++) { CString sAttrib = pCmdLine->GetAttributeName(i); if (!IsMainCommandParam(sAttrib) && !strEquals(sAttrib, CONSTLIT("count")) && !strEquals(sAttrib, CONSTLIT("encountercount"))) { CString sValue = pCmdLine->GetAttribute(i); if (!strEquals(sValue, CONSTLIT("true"))) Cols.Insert(strPatternSubst(CONSTLIT("%s:%s"), sAttrib, sValue)); else Cols.Insert(sAttrib); } } // Generate systems for multiple games TSortMap<CString, SNodeDesc> NodeTable; for (i = 0; i < iSystemSample; i++) { if (bLogo) printf("pass %d...\n", i+1); // Initialize the game CString sError; if (Universe.InitGame(0, &sError) != NOERROR) { printf("%s\n", sError.GetASCIIZPointer()); return; } for (j = 0; j < Universe.GetTopologyNodeCount(); j++) { CTopologyNode *pNode = Universe.GetTopologyNode(j); if (pNode->IsEndGame()) continue; // Create the system CSystem *pSystem; if (Universe.CreateStarSystem(pNode, &pSystem) != NOERROR) { printf("ERROR: Unable to create star system.\n"); return; } // Create a sort string for this system CString sSort = strPatternSubst(CONSTLIT("%02d-%s"), pSystem->GetLevel(), pNode->GetID()); // Get the table bool bNew; SNodeDesc *pResult = NodeTable.SetAt(sSort, &bNew); if (bNew) { pResult->iLevel = pNode->GetLevel(); pResult->sNodeID = pNode->GetID(); } // Accumulate data AddSystemData(pSystem, bAll, pResult); // Done with old system Universe.DestroySystem(pSystem); } Universe.Reinit(); } // Header printf("Level\tNode\tSystemType\tCategory\tSovereign\tEncounter\tCount"); for (i = 0; i < Cols.GetCount(); i++) printf("\t%s", Cols[i].GetASCIIZPointer()); printf("\n"); // Output all rows for (i = 0; i < NodeTable.GetCount(); i++) { for (j = 0; j < NodeTable[i].Table.GetCount(); j++) { CCountTable &Encounters = NodeTable[i].Table[j]; for (k = 0; k < Encounters.GetCount(); k++) { int iCount = Encounters[k] / iSystemSample; int iCountFrac = 1000 * (Encounters[k] % iSystemSample) / iSystemSample; CStationType *pEncounterType = Universe.FindStationType(Encounters.GetKey(k)); if (pEncounterType == NULL) continue; CSovereign *pSovereign = pEncounterType->GetControllingSovereign(); CString sSovereign = (pSovereign ? pSovereign->GetTypeName() : CONSTLIT("(Unknown)")); printf("%d\t%s\t0x%08x\t%s\t%s\t%s\t%d.%03d", NodeTable[i].iLevel, NodeTable[i].sNodeID.GetASCIIZPointer(), NodeTable[i].Table.GetKey(j), pEncounterType->GetDataField(CONSTLIT("category")).GetASCIIZPointer(), sSovereign.GetASCIIZPointer(), pEncounterType->GetName().GetASCIIZPointer(), iCount, iCountFrac); for (l = 0; l < Cols.GetCount(); l++) { CString sValue = pEncounterType->GetDataField(Cols[l]); printf("\t%s", sValue.GetASCIIZPointer()); } printf("\n"); } } } }
bool CSteamCtx::GetOrCreateItem (DWORD dwUNID, PublishedFileId_t *retFileId, bool *retbCreated, CString *retsError) // GetOrCreateItem // // Looks for the given item by the current user and returns a fileId for it. // If necessary, we create it. { if (!ValidateConnected(retsError)) return false; CString sUNID = ComposeUNID(dwUNID); // Get a list of all items with the given UNID (there should only be one). TSortMap<CString, CString> Tags; Tags.Insert(FIELD_UNID, sUNID); TArray<SteamUGCDetails_t> List; if (!GetUserContent(Tags, List, retsError)) return false; // If we found some content, get the FileID PublishedFileId_t FileId; if (List.GetCount() > 0) { FileId = List[0].m_nPublishedFileId; if (retbCreated) *retbCreated = false; } // Otherwise, we need to create a new item else { // Create the item bool bAgreementRequired; if (!CreateItem(&FileId, &bAgreementRequired, retsError)) return false; // Associate an UNID with this item UGCUpdateHandle_t Update = SteamUGC()->StartItemUpdate(TRANSCENDENCE_APP_ID, FileId); if (!SteamUGC()->AddItemKeyValueTag(Update, (LPSTR)FIELD_UNID, (LPSTR)sUNID)) return false; if (!UpdateItem(Update, CONSTLIT("Extension created."), retsError)) return false; if (retbCreated) *retbCreated = true; } // Done if (retFileId) *retFileId = FileId; return true; }