bool CalcColumns (SItemTableCtx &Ctx, CXMLElement *pCmdLine) { int i; Ctx.Cols.DeleteAll(); // Generate a list of columns to display Ctx.Cols.Insert(FIELD_LEVEL); Ctx.Cols.Insert(FIELD_TYPE); Ctx.Cols.Insert(FIELD_FREQUENCY); Ctx.Cols.Insert(FIELD_NAME); // Add fields as columns for (i = 0; i < pCmdLine->GetAttributeCount(); i++) { CString sAttrib = pCmdLine->GetAttributeName(i); if (!IsMainCommandParam(sAttrib) && !strEquals(sAttrib, BY_ATTRIBUTE_ATTRIB) && !strEquals(sAttrib, BY_SHIP_CLASS_ATTRIB) && !strEquals(sAttrib, BY_SHIP_CLASS_USAGE_ATTRIB) && !strEquals(sAttrib, CONSTLIT("itemtable"))) { CString sValue = pCmdLine->GetAttribute(i); if (!strEquals(sValue, CONSTLIT("true"))) Ctx.Cols.Insert(strPatternSubst(CONSTLIT("%s:%s"), sAttrib, sValue)); else Ctx.Cols.Insert(sAttrib); } } // If we need to output total count, then load the table if (pCmdLine->GetAttributeBool(FIELD_TOTAL_COUNT)) { if (LoadDesignTypeStats(&Ctx.TotalCount) != NOERROR) return false; } return true; }
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"); } } } }
void GenerateShipTable (CUniverse &Universe, CXMLElement *pCmdLine, CIDTable &EntityTable) { int i, j; // Some options bool bAllClasses = (pCmdLine->GetAttributeBool(CONSTLIT("allClasses")) || pCmdLine->GetAttributeBool(CONSTLIT("all"))); // Get the criteria from the command line. Always append 's' because we // want ship classes. CString sCriteria = strPatternSubst(CONSTLIT("%s s"), pCmdLine->GetAttribute(CONSTLIT("criteria"))); CDesignTypeCriteria Criteria; if (CDesignTypeCriteria::ParseCriteria(sCriteria, &Criteria) != NOERROR) { printf("ERROR: Unable to parse criteria.\n"); return; } // 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 (strEquals(sAttrib, FIELD_BALANCE)) { Cols.Insert(CONSTLIT("balanceType")); Cols.Insert(CONSTLIT("combatStrength")); Cols.Insert(CONSTLIT("damage")); Cols.Insert(CONSTLIT("defenseStrength")); } else if (!IsMainCommandParam(sAttrib) && !strEquals(sAttrib, CONSTLIT("shiptable"))) { CString sValue = pCmdLine->GetAttribute(i); if (!strEquals(sValue, CONSTLIT("true"))) Cols.Insert(strPatternSubst(CONSTLIT("%s:%s"), sAttrib, sValue)); else Cols.Insert(sAttrib); } } // Output the header for (j = 0; j < Cols.GetCount(); j++) { if (j != 0) printf("\t"); printf(Cols[j].GetASCIIZPointer()); } printf("\n"); // Generate a table CSymbolTable Table(FALSE, TRUE); // Loop over all items that match and add them to // a sorted table. for (i = 0; i < Universe.GetShipClassCount(); i++) { CShipClass *pClass = Universe.GetShipClass(i); // Only include generic classes unless otherwise specified if (!bAllClasses && !pClass->HasLiteralAttribute(CONSTLIT("genericClass"))) continue; if (!pClass->MatchesCriteria(Criteria)) continue; // Figure out the sort order char szBuffer[1024]; wsprintf(szBuffer, "%04d%s%d", pClass->GetLevel(), pClass->GetNounPhrase(0).GetASCIIZPointer(), pClass->GetUNID()); Table.AddEntry(CString(szBuffer), (CObject *)pClass); } // Output table for (i = 0; i < Table.GetCount(); i++) { CShipClass *pClass = (CShipClass *)Table.GetValue(i); // Output each row for (j = 0; j < Cols.GetCount(); j++) { if (j != 0) printf("\t"); const CString &sField = Cols[j]; CString sValue; if (strEquals(sField, FIELD_ENTITY)) { CString *pValue; if (EntityTable.Lookup(pClass->GetUNID(), (CObject **)&pValue) == NOERROR) sValue = *pValue; else sValue = CONSTLIT("?"); } else sValue = pClass->GetDataField(sField); if (strEquals(sField, FIELD_MANEUVER) || strEquals(sField, FIELD_THRUST_TO_WEIGHT)) printf("%.1f", strToInt(sValue, 0, NULL) / 1000.0); else if (strEquals(sField, FIELD_SCORE_CALC)) printf("%d", pClass->CalcScore()); else printf(sValue.GetASCIIZPointer()); } printf("\n"); } printf("\n"); }
void GenerateEncounterTable (CUniverse &Universe, CXMLElement *pCmdLine, CIDTable &EntityTable) { ALERROR error; int i, j; // Get the criteria from the command line. Always append 't' because we // want station types. CString sCriteria = strPatternSubst(CONSTLIT("%s t"), pCmdLine->GetAttribute(CRITERIA_ATTRIB)); // Parse it CDesignTypeCriteria Criteria; if (CDesignTypeCriteria::ParseCriteria(sCriteria, &Criteria) != NOERROR) { printf("ERROR: Unable to parse criteria.\n"); return; } bool bAll = pCmdLine->GetAttributeBool(ALL_ATTRIB); bool bOnlyNotRandom = pCmdLine->GetAttributeBool(ONLY_NOT_RANDOM_ATTRIB); // Generate a table of all matching encounters CSymbolTable Table(FALSE, TRUE); // Loop over all items for this level and add them to // a sorted table. for (i = 0; i < Universe.GetStationTypeCount(); i++) { CStationType *pType = Universe.GetStationType(i); int iLevel = pType->GetLevel(); // If we're selecting all types, then do it if (bAll) ; // If we only want non-random types, then skip any random encounters. else if (bOnlyNotRandom) { if (pType->CanBeEncounteredRandomly()) continue; } // Otherwise we skip anything except random encounters. else { if (!pType->CanBeEncounteredRandomly()) continue; } // If we don't match the criteria, then continue if (!pType->MatchesCriteria(Criteria)) continue; // Get the category and name CString sCategory = pType->GetDataField(FIELD_CATEGORY); 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%s%08x", iLevel, sCategory.GetASCIIZPointer(), sName.GetASCIIZPointer(), pType->GetUNID()); Table.AddEntry(CString(szBuffer), (CObject *)pType); } // Generate a list of columns to display TArray<CString> Cols; Cols.Insert(FIELD_LEVEL); Cols.Insert(FIELD_CATEGORY); Cols.Insert(FIELD_NAME); for (i = 0; i < pCmdLine->GetAttributeCount(); i++) { CString sAttrib = pCmdLine->GetAttributeName(i); if (!IsMainCommandParam(sAttrib) && !strEquals(sAttrib, ONLY_NOT_RANDOM_ATTRIB) && !strEquals(sAttrib, CONSTLIT("encountertable"))) { 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 (error = LoadDesignTypeStats(&TotalCount)) 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 for (i = 0; i < Table.GetCount(); i++) { CStationType *pType = (CStationType *)Table.GetValue(i); for (j = 0; j < Cols.GetCount(); j++) { if (j != 0) printf("\t"); const CString &sField = Cols[j]; // Get the value CString sValue; if (strEquals(sField, FIELD_ENTITY)) { CString *pValue; if (EntityTable.Lookup(pType->GetUNID(), (CObject **)&pValue) == NOERROR) sValue = *pValue; else sValue = CONSTLIT("?"); } else sValue = pType->GetDataField(sField); // Format and output if (strEquals(sField, FIELD_FIRE_RATE_ADJ)) printf("%.2f", strToInt(sValue, 0, NULL) / 1000.0); else 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 printf(sValue.GetASCIIZPointer()); } printf("\n"); } printf("\n"); } else printf("No entries match criteria.\n"); }
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 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); } } } }