void GenerateStats (CUniverse &Universe, CXMLElement *pCmdLine) { int i; printf("STATS\n\n"); int iItemTypes = 0; for (i = 0; i < Universe.GetItemTypeCount(); i++) { CItemType *pType = Universe.GetItemType(i); // Do not count virtual items if (pType->IsVirtual()) continue; iItemTypes++; } printf("Item types:\t\t%d\n", iItemTypes); printf("Ship classes:\t\t%d\n", Universe.GetShipClassCount()); printf("Station types:\t\t%d\n", Universe.GetStationTypeCount()); }
void RunEncounterSim (CUniverse &Universe, CXMLElement *pCmdLine) { int iRuns = pCmdLine->GetAttributeIntegerBounded(COUNT_ATTRIB, 1, -1, DEFAULT_RUN_COUNT); int iTimeOut = DEFAULT_TIME_OUT; // Get the station criteria CString sCriteria = strPatternSubst(CONSTLIT("%s t"), pCmdLine->GetAttribute(DEFENDERS_ATTRIB)); CDesignTypeCriteria DefenderCriteria; if (CDesignTypeCriteria::ParseCriteria(sCriteria, &DefenderCriteria) != NOERROR) { printf("ERROR: Unable to parse defenders criteria.\n"); return; } bool bAll = pCmdLine->GetAttributeBool(CONSTLIT("all")); // Get the criteria from the command line. Always append 's' because we // want ship classes. sCriteria = strPatternSubst(CONSTLIT("%s s"), pCmdLine->GetAttribute(ATTACKERS_ATTRIB)); CDesignTypeCriteria AttackerCriteria; if (CDesignTypeCriteria::ParseCriteria(sCriteria, &AttackerCriteria) != NOERROR) { printf("ERROR: Unable to parse attackers criteria.\n"); return; } // Create a viewer, if desired CSimViewer Viewer; if (pCmdLine->GetAttributeBool(VIEWER_ATTRIB)) Viewer.Create(); // Print headers printf("Encounter\tLevel"); int iAttacker; for (iAttacker = 0; iAttacker < Universe.GetShipClassCount(); iAttacker++) { CShipClass *pAttackerClass = Universe.GetShipClass(iAttacker); if (!pAttackerClass->MatchesCriteria(AttackerCriteria)) continue; printf("\t%s", pAttackerClass->GetName().GetASCIIZPointer()); } printf("\n"); // Loop over all defenders int iDefender; for (iDefender = 0; iDefender < Universe.GetStationTypeCount(); iDefender++) { CStationType *pDefenderType = Universe.GetStationType(iDefender); if (!bAll && pDefenderType->GetLevel() == 0) continue; if (!pDefenderType->MatchesCriteria(DefenderCriteria)) continue; // Compute an enemy of the station CSovereign *pAttackerSovereign = GetAttackerSovereign(Universe, pDefenderType); if (pAttackerSovereign == NULL) { printf("ERROR: Unable to find enemy sovereign of encounter: %s [%x].\n", pDefenderType->GetNounPhrase().GetASCIIZPointer(), pDefenderType->GetUNID()); return; } printf("%s [%x]\t%d", pDefenderType->GetNounPhrase().GetASCIIZPointer(), pDefenderType->GetUNID(), pDefenderType->GetLevel()); // Loop over all attackers for (iAttacker = 0; iAttacker < Universe.GetShipClassCount(); iAttacker++) { CShipClass *pAttackerClass = Universe.GetShipClass(iAttacker); if (!pAttackerClass->MatchesCriteria(AttackerCriteria)) continue; // Do several runs so we can get some statistical data int iAttackerSurvived = 0; int iRun; for (iRun = 0; iRun < iRuns; iRun++) { EResults iResult = RunEncounter(Universe, Viewer, pDefenderType, pAttackerClass, pAttackerSovereign); if (iResult == resultError) return; // Did the attacker survive? if (iResult != resultAttackerDestroyed) iAttackerSurvived++; } // Output results for this attacker int iSurvivability = 100 * iAttackerSurvived / iRuns; printf("\t%d%%", iSurvivability); } printf("\n"); } Viewer.Destroy(); }
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 GenerateShipImageChart (CUniverse &Universe, CXMLElement *pCmdLine) { int i; enum OrderTypes { orderSmallest = 1, orderLargest = 2, orderName = 3, }; // Options bool bTextBoxesOnly = pCmdLine->GetAttributeBool(CONSTLIT("textBoxesOnly")); // 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 iOrder = orderName; // 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")); // Rotation int iRotation = pCmdLine->GetAttributeInteger(CONSTLIT("rotation")); // 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); WORD wNameColor = CG16bitImage::RGBValue(255, 255, 255); // Output file CString sFilespec = pCmdLine->GetAttribute(CONSTLIT("output")); if (!sFilespec.IsBlank()) sFilespec = pathAddExtensionIfNecessary(sFilespec, CONSTLIT(".bmp")); // Generate a table of ships CSymbolTable Table(FALSE, TRUE); for (i = 0; i < Universe.GetShipClassCount(); i++) { CShipClass *pClass = Universe.GetShipClass(i); // Skip player ship classes if (pClass->GetPlayerSettings()) continue; // Skip non-generic classes if (!pClass->HasAttribute(CONSTLIT("genericClass"))) continue; // Compute the sort key char szBuffer[1024]; switch (iOrder) { case orderLargest: wsprintf(szBuffer, "%04d%s%x", 2048 - RectWidth(pClass->GetImage().GetImageRect()), pClass->GetName().GetASCIIZPointer(), pClass); break; case orderSmallest: wsprintf(szBuffer, "%04d%s%x", RectWidth(pClass->GetImage().GetImageRect()), pClass->GetName().GetASCIIZPointer(), pClass); break; default: wsprintf(szBuffer, "%s%x", pClass->GetName().GetASCIIZPointer(), pClass); break; } // Add to list Table.AddEntry(CString(szBuffer), (CObject *)pClass); } // Allocate a map that tracks where to paint each ship CPaintMap Map(Table.GetCount()); // Arrange the ships SArrangeDesc Desc; Desc.cxDesiredWidth = Max(512, cxDesiredWidth - (2 * (cxSpacing + cxExtraMargin))); Desc.cxSpacing = cxSpacing; Desc.cxExtraMargin = cxExtraMargin; Desc.pHeader = &NameFont; ArrangeByRow(Table, Desc, Map); //ArrangeByCell(Table, cxDesiredWidth, Map); // Create a large image CG16bitImage Output; int cxWidth = Max(cxDesiredWidth, Map.GetWidth()); int cyHeight = Map.GetHeight(); Output.CreateBlank(cxWidth, cyHeight, false); printf("Creating %dx%d image.\n", cxWidth, cyHeight); // Paint the images for (i = 0; i < Table.GetCount(); i++) { CShipClass *pClass = (CShipClass *)Table.GetValue(i); int x = Map.GetX(i); int y = Map.GetY(i); if (x != -1) { if (!bTextBoxesOnly) pClass->GetImage().PaintImageUL(Output, x, y, 0, Angle2Direction(iRotation)); // Paint name int xText = Map.GetTextX(i); int yText = Map.GetTextY(i); if (xText != -1) { if (bTextBoxesOnly) Output.Fill(xText, yText, Map.GetTextWidth(i), Map.GetTextHeight(i), 0xffff); if (!bTextBoxesOnly) { Output.FillColumn(x + (Map.GetWidth(i) / 2), y + Map.GetHeight(i), yText - (y + Map.GetHeight(i)), wNameColor); NameFont.DrawText(Output, xText, yText, wNameColor, 255, pClass->GetNounPhrase(0)); } } } } // Write to file or clipboard OutputImage(Output, sFilespec); }