void OutputTable (SItemTableCtx &Ctx, const SItemTypeList &ItemList) { int i, j; if (ItemList.GetCount() == 0) return; // Output each row for (i = 0; i < ItemList.GetCount(); i++) { CItemType *pType = ItemList[i]; for (j = 0; j < Ctx.Cols.GetCount(); j++) { if (j != 0) printf("\t"); const CString &sField = Ctx.Cols[j]; // Get the field value CString sValue; CItem Item(pType, 1); CItemCtx ItemCtx(Item); CCodeChainCtx CCCtx; ICCItem *pResult = Item.GetProperty(&CCCtx, ItemCtx, sField); if (pResult->IsNil()) sValue = NULL_STR; else sValue = pResult->Print(&g_pUniverse->GetCC(), PRFLAG_NO_QUOTES | PRFLAG_ENCODE_FOR_DISPLAY); pResult->Discard(&g_pUniverse->GetCC()); // Format the value if (strEquals(sField, FIELD_AVERAGE_DAMAGE) || strEquals(sField, FIELD_POWER_PER_SHOT)) printf("%.2f", strToInt(sValue, 0, NULL) / 1000.0); else if (strEquals(sField, FIELD_POWER)) printf("%.1f", strToInt(sValue, 0, NULL) / 1000.0); else if (strEquals(sField, FIELD_TOTAL_COUNT)) { SDesignTypeInfo *pInfo = Ctx.TotalCount.GetAt(pType->GetUNID()); double rCount = (pInfo ? pInfo->rPerGameMeanCount : 0.0); printf("%.2f", rCount); } else printf(sValue.GetASCIIZPointer()); } printf("\n"); } }
void OutputTable (SItemTableCtx &Ctx, const SItemTypeList &ItemList) { int i, j; if (ItemList.GetCount() == 0) return; // Output each row for (i = 0; i < ItemList.GetCount(); i++) { CItemType *pType = ItemList[i]; CItem Item(pType, 1); CItemCtx ItemCtx(Item); for (j = 0; j < Ctx.Cols.GetCount(); j++) { if (j != 0) printf("\t"); const CString &sField = Ctx.Cols[j]; // Handle some special fields if (strEquals(sField, FIELD_BENCHMARK)) { CWeaponBenchmarkCtx::SStats Stats; if (!Ctx.WeaponBenchmarks.GetStats(pType, Stats)) { printf("\t\t\t\t"); } else { CString sBestArmor; if (Stats.pBestArmor) { CItem BestArmor(Stats.pBestArmor, 1); sBestArmor = BestArmor.GetNounPhrase(nounShort); } CString sWorstArmor; if (Stats.pWorstArmor) { CItem WorstArmor(Stats.pWorstArmor, 1); sWorstArmor = WorstArmor.GetNounPhrase(nounShort); } printf("%d\t%s\t%d\t%s\t%d", Stats.iAverageTime, (LPSTR)sBestArmor, Stats.iBestTime, (LPSTR)sWorstArmor, Stats.iWorstTime); } } else if (strEquals(sField, FIELD_BALANCE_STATS)) { CDeviceClass *pDevice = pType->GetDeviceClass(); CWeaponClass *pWeapon = NULL; if (pDevice) pWeapon = pDevice->AsWeaponClass(); else if (pType->IsMissile() && ItemCtx.ResolveVariant()) { pDevice = ItemCtx.GetVariantDevice(); pWeapon = pDevice->AsWeaponClass(); } if (pWeapon) { CWeaponClass::SBalance Balance; pWeapon->CalcBalance(ItemCtx, Balance); printf("%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f", Balance.rBalance, Balance.rBalance - Balance.rCost, Balance.rDamage, Balance.rDamageType, Balance.rAmmo, Balance.rOmni, Balance.rTracking, Balance.rRange, Balance.rSpeed, Balance.rWMD, Balance.rRadiation, Balance.rMining, Balance.rShatter, Balance.rDeviceDisrupt, Balance.rDeviceDamage, Balance.rDisintegration, Balance.rShieldPenetrate, Balance.rArmor, Balance.rShield, Balance.rProjectileHP, Balance.rPower, Balance.rCost, Balance.rSlots, Balance.rExternal, Balance.rLinkedFire, Balance.rRecoil ); } else printf("\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t"); } // Get the field value else { CString sValue; CCodeChainCtx CCCtx; ICCItem *pResult = Item.GetProperty(&CCCtx, ItemCtx, sField); if (pResult->IsNil()) sValue = NULL_STR; else sValue = pResult->Print(&g_pUniverse->GetCC(), PRFLAG_NO_QUOTES | PRFLAG_ENCODE_FOR_DISPLAY); pResult->Discard(&g_pUniverse->GetCC()); // Format the value if (strEquals(sField, FIELD_POWER_PER_SHOT)) printf("%.2f", strToInt(sValue, 0, NULL) / 1000.0); else if (strEquals(sField, FIELD_POWER)) printf("%.1f", strToInt(sValue, 0, NULL) / 1000.0); else if (strEquals(sField, FIELD_TOTAL_COUNT)) { SDesignTypeInfo *pInfo = Ctx.TotalCount.GetAt(pType->GetUNID()); double rCount = (pInfo ? pInfo->rPerGameMeanCount : 0.0); printf("%.2f", rCount); } else printf(sValue.GetASCIIZPointer()); } } printf("\n"); } }
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 GenerateItemTable (CUniverse &Universe, CXMLElement *pCmdLine) { ALERROR error; int i, j; // Compute the criteria CItemCriteria Crit; CString sCriteria; if (pCmdLine->FindAttribute(CRITERIA_ATTRIB, &sCriteria)) CItem::ParseCriteria(sCriteria, &Crit); else CItem::InitCriteriaAll(&Crit); // Generate a table CSymbolTable Table(FALSE, TRUE); // Loop over all items that match and add them to // a sorted table. for (j = 0; j < Universe.GetItemTypeCount(); j++) { CItemType *pType = Universe.GetItemType(j); CItem Item(pType, 1); if (!Item.MatchesCriteria(Crit)) continue; // Figure out the sort order char szBuffer[1024]; wsprintf(szBuffer, "%02d%s%02d%s", pType->GetLevel(), g_szTypeCode[GetItemType(pType)], GetItemFreq(pType), pType->GetNounPhrase().GetASCIIZPointer()); Table.AddEntry(CString(szBuffer), (CObject *)pType); } // If we need to output total count, then load the table CSymbolTable TotalCount(TRUE, TRUE); if (pCmdLine->GetAttributeBool(FIELD_TOTAL_COUNT)) { if (error = LoadTotalCount(TOTAL_COUNT_FILENAME, TotalCount)) return; } // If we've got any entries in the table, output now if (Table.GetCount()) { // Generate a list of columns to display CStringArray Cols; Cols.AppendString(FIELD_LEVEL); Cols.AppendString(FIELD_TYPE); Cols.AppendString(FIELD_FREQUENCY); Cols.AppendString(FIELD_NAME); // More columns from command-line if (pCmdLine->GetAttributeBool(FIELD_AVERAGE_COUNT)) Cols.AppendString(FIELD_AVERAGE_COUNT); if (pCmdLine->GetAttributeBool(FIELD_BALANCE)) Cols.AppendString(FIELD_BALANCE); if (pCmdLine->GetAttributeBool(FIELD_COST)) Cols.AppendString(FIELD_COST); if (pCmdLine->GetAttributeBool(FIELD_INSTALL_COST)) Cols.AppendString(FIELD_INSTALL_COST); if (pCmdLine->GetAttributeBool(FIELD_MASS)) Cols.AppendString(FIELD_MASS); if (pCmdLine->GetAttributeBool(FIELD_TOTAL_COUNT)) Cols.AppendString(FIELD_TOTAL_COUNT); if (pCmdLine->GetAttributeBool(FIELD_REFERENCE)) Cols.AppendString(FIELD_REFERENCE); if (pCmdLine->GetAttributeBool(FIELD_HP)) Cols.AppendString(FIELD_HP); if (pCmdLine->GetAttributeBool(FIELD_HP_BONUS)) Cols.AppendString(FIELD_HP_BONUS); if (pCmdLine->GetAttributeBool(FIELD_REGEN)) Cols.AppendString(FIELD_REGEN); if (pCmdLine->GetAttributeBool(FIELD_FIRE_DELAY)) Cols.AppendString(FIELD_FIRE_DELAY); if (pCmdLine->GetAttributeBool(FIELD_THRUST)) Cols.AppendString(FIELD_THRUST); if (pCmdLine->GetAttributeBool(FIELD_POWER)) Cols.AppendString(FIELD_POWER); if (pCmdLine->GetAttributeBool(FIELD_POWER_PER_SHOT)) Cols.AppendString(FIELD_POWER_PER_SHOT); if (pCmdLine->GetAttributeBool(FIELD_AVERAGE_DAMAGE)) Cols.AppendString(FIELD_AVERAGE_DAMAGE); if (pCmdLine->GetAttributeBool(FIELD_MAX_SPEED)) Cols.AppendString(FIELD_MAX_SPEED); // Output the header for (j = 0; j < Cols.GetCount(); j++) { if (j != 0) printf("\t"); printf(Cols.GetStringValue(j).GetASCIIZPointer()); } printf("\n"); // Output each row for (i = 0; i < Table.GetCount(); i++) { CItemType *pType = (CItemType *)Table.GetValue(i); for (j = 0; j < Cols.GetCount(); j++) { if (j != 0) printf("\t"); CString sField = Cols.GetStringValue(j); CString sValue = pType->GetDataField(sField); if (strEquals(sField, FIELD_AVERAGE_DAMAGE) || strEquals(sField, FIELD_POWER_PER_SHOT)) printf("%.2f", strToInt(sValue, 0, NULL) / 1000.0); else if (strEquals(sField, FIELD_POWER)) printf("%.1f", strToInt(sValue, 0, NULL) / 1000.0); else if (strEquals(sField, FIELD_TOTAL_COUNT)) { double rCount = 0.0; CString sKey = strFromInt(pType->GetUNID(), FALSE); EntryInfo *pEntry; if (TotalCount.Lookup(sKey, (CObject **)&pEntry) == NOERROR) rCount = pEntry->rTotalCount; printf("%.2f", rCount); } else printf(sValue.GetASCIIZPointer()); } printf("\n"); } printf("\n"); } else printf("No entries match criteria.\n"); }