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 OutputByAttribute (SItemTableCtx &Ctx, const SItemTypeList &ItemList) { int i, j; // Make a categorized list by attribute SByAttributeTypeList ByAttributeTable; for (i = 0; i < ItemList.GetCount(); i++) { const CString &sKey = ItemList.GetKey(i); CItemType *pType = ItemList[i]; // Loop over all attributes TArray<CString> Attribs; ParseAttributes(pType->GetAttributes(), &Attribs); for (j = 0; j < Attribs.GetCount(); j++) { bool bNew; SAttributeEntry *pEntry = ByAttributeTable.SetAt(Attribs[j], &bNew); if (bNew) pEntry->sAttribute = Attribs[j]; pEntry->ItemTable.Insert(sKey, pType); } // If no attribute if (Attribs.GetCount() == 0) { bool bNew; SAttributeEntry *pEntry = ByAttributeTable.SetAt(CONSTLIT("(none)"), &bNew); if (bNew) pEntry->sAttribute = CONSTLIT("(none)"); pEntry->ItemTable.Insert(sKey, pType); } } // Now loop over all attributes for (i = 0; i < ByAttributeTable.GetCount(); i++) { const SAttributeEntry &Entry = ByAttributeTable[i]; printf("%s\n\n", Entry.sAttribute.GetASCIIZPointer()); OutputHeader(Ctx); OutputTable(Ctx, Entry.ItemTable); 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 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"); } }