public string GetDataAsHtml(GameVersion version, ItemDat.ItemDat items, TSSFile stringDic, Dictionary <uint, TSSEntry> inGameIdDict, List <SearchPointContent> searchPointContents, List <SearchPointItem> searchPointItems, int index, bool phpLinks = false) { StringBuilder sb = new StringBuilder(); sb.Append("<tr id=\"searchpoint").Append(Index).Append("\">"); sb.Append("<td colspan=\"5\">"); sb.Append("[#").Append(index).Append("] "); switch (SearchPointType) { case 0: sb.Append("Tree Stump"); break; case 1: sb.Append("Shell"); break; case 2: sb.Append("Bones"); break; case 3: sb.Append("Seagulls"); break; default: sb.Append(SearchPointType); break; } if (CoordY < 0) { sb.Append(" (Underwater)"); } if (ScenarioBegin > 1000999) { switch (ScenarioBegin) { case 3000000: sb.Append(" (Chapter 3 only)"); break; case 3590000: sb.Append(" (once Erealumen Crystallands accessible)"); break; default: sb.Append(" (Appears after scenario ").Append(ScenarioBegin).Append(")"); break; } } //sb.Append( "<br>" ) //sb.Append( "9: " ).Append( Unknown9 ).Append( "<br>" ); //sb.Append( "11: " ).Append( Unknown11 ).Append( "<br>" ); //sb.Append( "14a: " ).Append( Unknown14a ).Append( "<br>" ); sb.Append("</td>"); sb.Append("</tr>"); sb.Append("<tr>"); for (uint i = 0; i < SearchPointContentCount; ++i) { sb.Append("<td>"); sb.Append(searchPointContents[(int)(SearchPointContentIndex + i)].GetDataAsHtml(version, items, stringDic, inGameIdDict, searchPointItems, phpLinks: phpLinks)); sb.Append("</td>"); } for (uint i = SearchPointContentCount; i < 5; ++i) { sb.Append("<td>"); sb.Append("</td>"); } sb.Append("</tr>"); return(sb.ToString()); }
public string GetDataAsHtml(GameVersion version, ItemDat.ItemDat items, TSSFile stringDic, Dictionary <uint, TSSEntry> inGameIdDict, bool phpLinks = false) { StringBuilder sb = new StringBuilder(); var item = items.itemIdDict[Item]; sb.Append("<img src=\"item-icons/ICON" + item.Data[(int)ItemData.Icon] + ".png\" height=\"16\" width=\"16\"> "); sb.Append("<a href=\"" + Website.GenerateWebsite.GetUrl(Website.WebsiteSection.Item, version, phpLinks, id: (int)item.Data[(int)ItemData.ID], icon: (int)item.Data[(int)ItemData.Icon]) + "\">"); sb.Append(inGameIdDict[item.NamePointer].StringEngOrJpnHtml(version) + "</a> x" + Count); return(sb.ToString()); }
public string GetDataAsHtml(GameVersion version, ItemDat.ItemDat items, TSSFile stringDic, Dictionary <uint, TSSEntry> inGameIdDict, List <SearchPointItem> searchPointItems, bool phpLinks = false) { StringBuilder sb = new StringBuilder(); //sb.Append( "Percentage: " ).Append( Percentage ).Append( "%" ).Append( "<br>" ); for (uint i = 0; i < SearchPointItemCount; ++i) { //sb.Append( "Item #" ).Append( i ).Append( ":" ); sb.Append(searchPointItems[(int)(SearchPointItemIndex + i)].GetDataAsHtml(version, items, stringDic, inGameIdDict, phpLinks: phpLinks)); sb.Append("<br>"); } return(sb.ToString()); }
public string GetDataAsHtml(ItemDat.ItemDat items, Dictionary <uint, TSS.TSSEntry> inGameIdDict, GameVersion version, string versionPostfix, GameLocale locale, WebsiteLanguage websiteLanguage) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < Items.Length; ++i) { if (Items[i] > 0) { var item = items.itemIdDict[this.Items[i]]; sb.Append(inGameIdDict[item.NamePointer].StringEngOrJpnHtml(version, inGameIdDict, websiteLanguage)); sb.Append(" / "); sb.Append(Chances[i]); } sb.Append((i % 3 == 2) ? "<br>" : " -- "); } return(sb.ToString()); }
public string GetDataAsHtml(ItemDat.ItemDat items, Dictionary <uint, TSS.TSSEntry> inGameIdDict) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < Items.Length; ++i) { if (Items[i] > 0) { var item = items.itemIdDict[this.Items[i]]; sb.Append(inGameIdDict[item.NamePointer].StringEngOrJpnHtml(GameVersion.PS3)); sb.Append(" / "); sb.Append(Chances[i]); } sb.Append((i % 3 == 2) ? "<br>" : " -- "); } return(sb.ToString()); }
public string GetDataAsHtml(GameVersion version, ItemDat.ItemDat items, ShopData shops, Dictionary <uint, TSS.TSSEntry> inGameIdDict, bool phpLinks = false) { StringBuilder sb = new StringBuilder(); sb.AppendLine("<tr id=\"shop" + InGameID + "\">"); sb.AppendLine("<td class=\"synopsistitle\" colspan=\"3\">"); sb.AppendLine(inGameIdDict[StringDicID].StringJpnHtml(version)); sb.AppendLine("</td>"); sb.AppendLine("<td class=\"synopsistitle\" colspan=\"3\">"); sb.AppendLine(inGameIdDict[StringDicID].StringEngHtml(version)); sb.AppendLine("</td>"); sb.AppendLine("</tr>"); sb.AppendLine("<tr>"); for (int i = 2; i < 9; ++i) { if (i == 4) { continue; } sb.AppendLine("<td>"); foreach (var item in ShopItems) { if (items.itemIdDict[item.ItemID].Data[(int)ItemDat.ItemData.Category] == i) { sb.Append(item.GetDataAsHtml(version, items, inGameIdDict, phpLinks: phpLinks)); sb.Append("<br>"); } } sb.AppendLine("</td>"); } sb.AppendLine("</tr>"); if (OnTrigger > 0) { sb.Append("<tr>"); sb.Append("<td class=\"strategychar\" colspan=\"6\">"); sb.Append("Changes to <a href=\"#shop" + ChangeToShop + "\">"); sb.Append(inGameIdDict[shops.ShopDictionary[ChangeToShop].StringDicID].StringEngOrJpnHtml(version)); sb.Append("</a>"); sb.Append("</td>"); sb.Append("</tr>"); } return(sb.ToString()); }
public string GetDataAsHtml(GameVersion version, string versionPostfix, GameLocale locale, WebsiteLanguage websiteLanguage, ItemDat.ItemDat items, ShopData shops, Dictionary <uint, TSS.TSSEntry> inGameIdDict, bool phpLinks = false) { StringBuilder sb = new StringBuilder(); int colspan = websiteLanguage.WantsBoth() ? 3 : 6; sb.Append("<tr id=\"shop" + InGameID + "\">"); if (websiteLanguage.WantsJp()) { sb.Append("<td class=\"synopsistitle\" colspan=\"" + colspan + "\">"); sb.Append(inGameIdDict[StringDicID].StringJpnHtml(version, inGameIdDict)); sb.Append("</td>"); } if (websiteLanguage.WantsEn()) { sb.Append("<td class=\"synopsistitle\" colspan=\"" + colspan + "\">"); sb.Append(inGameIdDict[StringDicID].StringEngHtml(version, inGameIdDict)); sb.Append("</td>"); } sb.Append("</tr>"); sb.Append("<tr>"); for (int i = 2; i < 9; ++i) { if (i == 4) { continue; } sb.Append("<td>"); foreach (var item in ShopItems) { if (items.itemIdDict[item.ItemID].Data[(int)ItemDat.ItemData.Category] == i) { sb.Append(item.GetDataAsHtml(version, versionPostfix, locale, websiteLanguage, items, inGameIdDict, phpLinks: phpLinks)); sb.Append("<br>"); } } sb.Append("</td>"); } sb.Append("</tr>"); if (OnTrigger > 0) { sb.Append("<tr>"); sb.Append("<td class=\"strategychar\" colspan=\"6\">"); sb.Append("Changes to <a href=\"" + Vesperia.Website.WebsiteGenerator.GetUrl(Website.WebsiteSection.Shop, version, versionPostfix, locale, websiteLanguage, phpLinks, id: (int)ChangeToShop) + "\">"); sb.Append(inGameIdDict[shops.ShopDictionary[ChangeToShop].StringDicID].StringEngOrJpnHtml(version, inGameIdDict, websiteLanguage)); sb.Append("</a>"); sb.Append("</td>"); sb.Append("</tr>"); } return(sb.ToString()); }
public string GetDataAsHtml(string stratum, int floor, T8BTEMST.T8BTEMST Enemies, T8BTEMGP.T8BTEMGP EnemyGroups, T8BTEMEG.T8BTEMEG EncounterGroups, GameVersion version, string versionPostfix, GameLocale locale, WebsiteLanguage websiteLanguage, T8BTXTMT treasures, ItemDat.ItemDat items, Dictionary <uint, TSS.TSSEntry> inGameIdDict, bool phpLinks = false) { StringBuilder sb = new StringBuilder(); bool printEnemies = Enemies != null && EnemyGroups != null && EncounterGroups != null; sb.Append("<td class=\"necropolistile" + RoomType + "\">"); if (RoomType != 0) { sb.Append("<div class=\"necropolis-arrow-up\">"); if (MoveUpAllowed > 0) { sb.Append("<img src=\"etc/up.png\" width=\"16\" height=\"16\">"); } sb.Append("</div>"); sb.Append("<div class=\"necropolis-arrow-side\">"); if (MoveLeftAllowed > 0) { sb.Append("<img src=\"etc/left.png\" width=\"16\" height=\"16\">"); } sb.Append("</div>"); sb.Append("<div class=\"necropolis-data\">"); if (printEnemies) { foreach (uint groupId in EncounterGroups.EncounterGroupIdDict[EnemyGroup].EnemyGroupIDs) { if (groupId == 0xFFFFFFFFu) { continue; } foreach (int enemyId in EnemyGroups.EnemyGroupIdDict[groupId].EnemyIDs) { if (enemyId < 0) { continue; } var enemy = Enemies.EnemyIdDict[(uint)enemyId]; sb.Append("<a href=\"" + Website.WebsiteGenerator.GetUrl(Website.WebsiteSection.Enemy, version, versionPostfix, locale, websiteLanguage, phpLinks, category: (int)enemy.Category, id: (int)enemy.InGameID) + "\">"); sb.Append("<img src=\"monster-icons/46px/monster-" + enemy.IconID.ToString("D3") + ".png\" title=\"" + inGameIdDict[enemy.NameStringDicID].StringEngOrJpnHtml(version, inGameIdDict, websiteLanguage) + "\" width=\"23\" height=\"23\">"); sb.Append("</a>"); } sb.Append("<br>"); } } else { sb.Append("<img src=\"item-icons/ICON60.png\" width=\"16\" height=\"16\"> " + (FramesToMove / 60) + " sec<br>"); switch (RoomType) { case 1: sb.Append("Entrance<br>"); break; case 2: case 5: { int targetFloor; string targetLinkId; string targetStratum; if (RoomType == 5) { targetFloor = (floor + FloorExitDiff); } else { targetFloor = (floor + 1); } if (targetFloor == 11) { targetStratum = ((char)(((int)stratum[0]) + 1)).ToString(); targetLinkId = targetStratum + "1"; } else { targetStratum = stratum; targetLinkId = targetStratum + targetFloor; } string targetHumanReadable; if (targetFloor == 11) { targetHumanReadable = stratum + " Bottom"; } else { targetHumanReadable = stratum + "-" + targetFloor; } string nextHumanReadable = ""; if (targetFloor == 11) { nextHumanReadable = targetStratum + "-1"; } string linkStart = "<a href=\"" + (phpLinks ? Website.WebsiteGenerator.GetUrl(Website.WebsiteSection.NecropolisMap, version, versionPostfix, locale, websiteLanguage, true, extra: targetLinkId) : ("#" + targetLinkId)) + "\">"; string linkEnd = "</a>"; string finalText; if (targetFloor == 11) { if (stratum == "F") { finalText = $"Exit to {targetHumanReadable}"; } else { finalText = $"Exit to {targetHumanReadable}<br>(Go to {linkStart}{nextHumanReadable}{linkEnd})"; } } else { finalText = $"Exit to {linkStart}{targetHumanReadable}{linkStart}"; } sb.Append(finalText); sb.Append("<br>"); break; } case 3: //sb.Append( "Regular Room<br>" ); break; case 4: //sb.Append( "Treasure Room<br>" ); break; } if (RegularTreasure > 0) { // not a generic solution, but the unmodified game has all four slots identical for regular treasures var treasureInfo = treasures.TreasureInfoList[(int)RegularTreasure]; sb.Append("<table>"); sb.Append("<tr>"); for (int i = 0; i < 3; ++i) { var item = items.itemIdDict[treasureInfo.Items[i]]; sb.Append("<td>"); sb.Append("<a href=\"" + Website.WebsiteGenerator.GetUrl(Website.WebsiteSection.Item, version, versionPostfix, locale, websiteLanguage, phpLinks, id: (int)item.Data[(int)ItemData.ID], icon: (int)item.Data[(int)ItemData.Icon]) + "\">"); sb.Append("<img src=\"items/U_" + item.ItemString.TrimNull() + ".png\" height=\"32\" width=\"32\" title=\"" + inGameIdDict[item.NamePointer].StringEngOrJpnHtml(version, inGameIdDict, websiteLanguage) + "\">"); sb.Append("</a>"); sb.Append("</td>"); } sb.Append("</tr>"); sb.Append("<tr>"); for (int i = 0; i < 3; ++i) { sb.Append("<td>"); sb.Append(treasureInfo.Chances[i] + "%"); sb.Append("</td>"); } sb.Append("</tr>"); sb.Append("</table>"); } if (SpecialTreasure > 0) { // unmodified game always has special treasures as one in the first slot with 100% chance var treasureInfo = treasures.TreasureInfoList[(int)SpecialTreasure]; var item = items.itemIdDict[treasureInfo.Items[0]]; sb.Append("<img src=\"item-icons/ICON" + item.Data[(int)ItemDat.ItemData.Icon] + ".png\" height=\"16\" width=\"16\"> "); sb.Append("<a href=\"" + Website.WebsiteGenerator.GetUrl(Website.WebsiteSection.Item, version, versionPostfix, locale, websiteLanguage, phpLinks, id: (int)item.Data[(int)ItemData.ID], icon: (int)item.Data[(int)ItemData.Icon]) + "\">"); sb.Append(inGameIdDict[item.NamePointer].StringEngOrJpnHtml(version, inGameIdDict, websiteLanguage) + "</a><br>"); } } sb.Append("</div>"); sb.Append("<div class=\"necropolis-arrow-side\">"); if (MoveRightAllowed > 0) { sb.Append("<img src=\"etc/right.png\" width=\"16\" height=\"16\">"); } sb.Append("</div>"); sb.Append("<div class=\"necropolis-arrow-down\">"); if (MoveDownAllowed > 0) { sb.Append("<img src=\"etc/down.png\" width=\"16\" height=\"16\">"); } sb.Append("</div>"); } sb.Append("</td>"); return(sb.ToString()); }
public string GetDataAsHtml(string stratum, int floor, T8BTEMST.T8BTEMST Enemies, T8BTEMGP.T8BTEMGP EnemyGroups, T8BTEMEG.T8BTEMEG EncounterGroups, GameVersion version, string versionPostfix, GameLocale locale, WebsiteLanguage websiteLanguage, T8BTXTMT treasures, ItemDat.ItemDat items, Dictionary <uint, TSS.TSSEntry> inGameIdDict, bool surroundingTable = true, bool phpLinks = false) { StringBuilder sb = new StringBuilder(); if (surroundingTable) { sb.Append("<div id=\"" + stratum + floor + "\">"); sb.Append("<table class=\"necropolisfloor\">"); sb.Append("<tr>"); sb.Append("<th colspan=\"6\">"); sb.Append("<div class=\"itemname\" style=\"text-align: center;\">"); sb.Append(stratum + "-" + floor); sb.Append("</div>"); sb.Append("</td>"); sb.Append("</tr>"); } for (int y = 0; y < VerticalTiles; y++) { sb.Append("<tr>"); for (int x = 0; x < HorizontalTiles; x++) { sb.Append(TileList[(int)(y * HorizontalTiles + x)].GetDataAsHtml(stratum, floor, Enemies, EnemyGroups, EncounterGroups, version, versionPostfix, locale, websiteLanguage, treasures, items, inGameIdDict, phpLinks: phpLinks)); } sb.Append("</tr>"); //sb.Append( "<tr><td colspan=\"" + HorizontalTiles + "\"><hr></td></tr>" ); } if (surroundingTable) { sb.Append("</table>"); sb.Append("</div>"); } return(sb.ToString()); }
public string GetDataAsHtml(GameVersion version, ItemDat.ItemDat items, WRLDDAT.WRLDDAT locations, TSS.TSSFile stringDic, Dictionary <uint, TSS.TSSEntry> inGameIdDict, bool phpLinks = false) { var sb = new StringBuilder(); sb.Append("<tr id=\"enemy" + InGameID + "\">"); sb.Append("<td style=\"height: 46px;\">"); var enemyNameEntry = inGameIdDict[NameStringDicID]; sb.Append("<img src=\"monster-icons/44px/monster-" + IconID.ToString("D3") + ".png\" title=\"" + RefString + "\">"); sb.Append("</td>"); sb.Append("<td style=\"height: 46px;\">"); sb.Append("<span class=\"itemname\">" + enemyNameEntry.StringJpnHtml(version) + "</span><br>"); sb.Append("<span class=\"itemname\">" + enemyNameEntry.StringEngHtml(version) + "</span><br>"); //sb.Append( RefString2 + "<br>" ); //sb.Append( RefString3 + "<br>" ); //sb.Append( RefString4 + "<br>" ); //sb.Append( RefString5 + "<br>" ); sb.Append("</td>"); //sb.Append( " / Category: " + Category + "<br>" ); AppendStats(sb, "Easy", 0); AppendStats(sb, "Normal", 1); AppendStats(sb, "Hard", 2); AppendStats(sb, "Unknown", 3); sb.Append("<td rowspan=\"2\">"); sb.Append("EXP: " + EXP + ", "); Website.GenerateWebsite.AppendFatalStrikeIcon(sb, FatalTypeExp); sb.Append(" +" + EXPModifier + "<br>"); sb.Append("LP: " + LP + ", "); Website.GenerateWebsite.AppendFatalStrikeIcon(sb, FatalTypeLP); sb.Append(" +" + LPModifier + "<br>"); sb.Append("Gald: " + Gald + "<br>"); sb.Append("Fatal Strike Resistances:<br>"); Website.GenerateWebsite.AppendFatalStrikeIcon(sb, 0); sb.Append(FatalBlue); sb.Append(" "); Website.GenerateWebsite.AppendFatalStrikeIcon(sb, 1); sb.Append(FatalRed); sb.Append(" "); Website.GenerateWebsite.AppendFatalStrikeIcon(sb, 2); sb.Append(FatalGreen); sb.Append("<br>"); int weakCount = 0; int strongCount = 0; int immuneCount = 0; int absorbCount = 0; for (int i = 0; i < Attributes.Length; ++i) { if (Attributes[i] > 100) { weakCount++; } if (Attributes[i] > 0 && Attributes[i] < 100) { strongCount++; } if (Attributes[i] == 0) { immuneCount++; } if (Attributes[i] < 0) { absorbCount++; } } if (weakCount > 0) { sb.Append("Weak: "); for (int i = 0; i < Attributes.Length; ++i) { if (Attributes[i] > 100) { Website.GenerateWebsite.AppendElementIcon(sb, (Element)i); sb.Append(Attributes[i] - 100); sb.Append("% "); } } sb.Append("<br>"); } if (strongCount > 0) { sb.Append("Strong: "); for (int i = 0; i < Attributes.Length; ++i) { if (Attributes[i] > 0 && Attributes[i] < 100) { Website.GenerateWebsite.AppendElementIcon(sb, (Element)i); sb.Append(Attributes[i]); sb.Append("% "); } } sb.Append("<br>"); } if (immuneCount > 0) { sb.Append("Immune: "); for (int i = 0; i < Attributes.Length; ++i) { if (Attributes[i] == 0) { Website.GenerateWebsite.AppendElementIcon(sb, (Element)i); } } sb.Append("<br>"); } if (absorbCount > 0) { sb.Append("Absorb: "); for (int i = 0; i < Attributes.Length; ++i) { if (Attributes[i] < 0) { Website.GenerateWebsite.AppendElementIcon(sb, (Element)i); sb.Append(-Attributes[i]); sb.Append("% "); } } sb.Append("<br>"); } if (KillableWithFS == 0) { sb.AppendLine("Immune to Fatal Strike.<br>"); } sb.Append("</td>"); /* * sb.Append( "<td rowspan=\"2\">" ); * sb.AppendLine(); * for ( int i = 0; i < 62; ++i ) { * if ( !KnownValues.Contains( i ) ) { * sb.Append( "~" + i + ": " + Data[i] ); * sb.Append( " [" + Category + "/" + enemyNameEntry.StringEngOrJpn + "]" ); * sb.AppendLine( "<br>" ); * } * } * for ( int i = 62; i < Data.Length; ++i ) { * if ( !KnownValues.Contains( i ) ) { * sb.Append( "~" + i + ": " + DataFloat[i] ); * sb.Append( " [" + Category + "/" + enemyNameEntry.StringEngOrJpn + "]" ); * sb.AppendLine( "<br>" ); * } * } * sb.Append( "</td>" ); * //*/ sb.Append("</tr>"); sb.Append("<tr>"); sb.Append("<td colspan=\"2\">"); if (InMonsterBook == 0) { sb.AppendLine("Not in Monster Book.<br>"); } if (Location != 0) { var loc = locations.LocationIdDict[Location]; sb.Append("<a href=\"" + Website.GenerateWebsite.GetUrl(Website.WebsiteSection.Location, version, phpLinks, id: (int)loc.LocationID) + "\">"); if (LocationWeather > -1) { sb.AppendLine("<img src=\"menu-icons/weather-" + LocationWeather + ".png\" width=\"16\" height=\"16\">"); } sb.AppendLine(loc.GetLastValidName(inGameIdDict).StringEngOrJpnHtml(version) + "</a><br>"); } for (int i = 0; i < DropItems.Length; ++i) { if (DropItems[i] != 0) { sb.Append("Drops:<br>"); break; } } for (int i = 0; i < DropItems.Length; ++i) { if (DropItems[i] != 0) { var item = items.itemIdDict[DropItems[i]]; sb.Append("<img src=\"item-icons/ICON" + item.Data[(int)ItemData.Icon] + ".png\" height=\"16\" width=\"16\"> "); sb.Append("<a href=\"" + Website.GenerateWebsite.GetUrl(Website.WebsiteSection.Item, version, phpLinks, id: (int)item.Data[(int)ItemData.ID], icon: (int)item.Data[(int)ItemData.Icon]) + "\">"); sb.Append(inGameIdDict[item.NamePointer].StringEngOrJpnHtml(version) + "</a>"); sb.Append(", " + DropChances[i] + "%"); if (DropChances[i] < 100) { sb.Append(", "); Website.GenerateWebsite.AppendFatalStrikeIcon(sb, FatalTypeDrop); sb.Append(" +" + DropModifier[i] + "%"); } sb.Append("<br>"); } } if (SecretMissionDrop != 0 && SecretMissionDropChance > 0) { sb.Append("Secret Mission Reward:<br>"); var item = items.itemIdDict[SecretMissionDrop]; sb.Append("<img src=\"item-icons/ICON" + item.Data[(int)ItemData.Icon] + ".png\" height=\"16\" width=\"16\"> "); sb.Append("<a href=\"" + Website.GenerateWebsite.GetUrl(Website.WebsiteSection.Item, version, phpLinks, id: (int)item.Data[(int)ItemData.ID], icon: (int)item.Data[(int)ItemData.Icon]) + "\">"); sb.Append(inGameIdDict[item.NamePointer].StringEngOrJpnHtml(version) + "</a>, " + SecretMissionDropChance + "%<br>"); } if (StealItem != 0) { sb.Append("Steal:<br>"); var item = items.itemIdDict[StealItem]; sb.Append("<img src=\"item-icons/ICON" + item.Data[(int)ItemData.Icon] + ".png\" height=\"16\" width=\"16\"> "); sb.Append("<a href=\"" + Website.GenerateWebsite.GetUrl(Website.WebsiteSection.Item, version, phpLinks, id: (int)item.Data[(int)ItemData.ID], icon: (int)item.Data[(int)ItemData.Icon]) + "\">"); sb.Append(inGameIdDict[item.NamePointer].StringEngOrJpnHtml(version) + "</a>, " + StealChance + "%<br>"); } sb.Append("</td>"); sb.AppendLine("</tr>"); return(sb.ToString()); }
public string GetDataAsHtml(GameVersion version, COOKDAT recipes, ItemDat.ItemDat items, TSS.TSSFile stringDic, Dictionary <uint, TSS.TSSEntry> inGameIdDict, bool phpLinks = false) { StringBuilder sb = new StringBuilder(); sb.Append("<tr id=\"recipe" + ID + "\"><td>"); sb.Append("<img src=\"recipes/U_" + RefString + ".png\">"); sb.Append("</td><td>"); sb.Append("<span class=\"itemname\">" + inGameIdDict[NameStringDicID].StringJpnHtml(version) + "</span><br>"); sb.Append(inGameIdDict[DescriptionStringDicID].StringJpnHtml(version) + "<br>"); sb.Append(inGameIdDict[EffectStringDicID].StringJpnHtml(version) + "<br>"); sb.Append("<br>"); sb.Append("<span class=\"itemname\">" + inGameIdDict[NameStringDicID].StringEngHtml(version) + "</span><br>"); sb.Append(inGameIdDict[DescriptionStringDicID].StringEngHtml(version) + "<br>"); sb.Append(inGameIdDict[EffectStringDicID].StringEngHtml(version) + "<br>"); sb.Append("</td><td>"); for (int i = 0; i < IngredientGroups.Length; ++i) { if (IngredientGroups[i] != 0) { uint stringDicId; stringDicId = IngredientGroupDict[IngredientGroups[i]]; var entry = inGameIdDict[stringDicId]; sb.Append("<img src=\"item-icons/ICON" + IngredientGroups[i] + ".png\" height=\"16\" width=\"16\"> "); sb.Append(entry.StringEngOrJpnHtml(version) + " x" + IngredientGroupCount[i] + "<br>"); } } for (int i = 0; i < Ingredients.Length; ++i) { if (Ingredients[i] != 0) { var item = items.itemIdDict[Ingredients[i]]; sb.Append("<img src=\"item-icons/ICON" + item.Data[(int)ItemData.Icon] + ".png\" height=\"16\" width=\"16\"> "); sb.Append("<a href=\"" + Website.GenerateWebsite.GetUrl(Website.WebsiteSection.Item, version, phpLinks, id: (int)item.Data[(int)ItemData.ID], icon: (int)item.Data[(int)ItemData.Icon]) + "\">"); sb.Append(inGameIdDict[item.NamePointer].StringEngOrJpnHtml(version) + "</a> x" + IngredientCount[i] + "<br>"); } } sb.Append("</td><td>"); if (HP > 0) { sb.Append("HP Heal: " + HP + "%<br>"); } if (TP > 0) { sb.Append("TP Heal: " + TP + "%<br>"); } if (PhysicalAilmentHeal > 0 || DeathHeal > 0) { sb.Append("Cures Ailments: "); if (DeathHeal > 0) { sb.Append("<img src=\"text-icons/icon-status-13.png\" height=\"16\" width=\"16\" title=\"Death\">"); } if ((PhysicalAilmentHeal & 1) == 1) { sb.Append("<img src=\"text-icons/icon-status-01.png\" height=\"16\" width=\"16\" title=\"Poison\">"); } if ((PhysicalAilmentHeal & 2) == 2) { sb.Append("<img src=\"text-icons/icon-status-07.png\" height=\"16\" width=\"16\" title=\"Contamination\">"); } if ((PhysicalAilmentHeal & 4) == 4) { sb.Append("<img src=\"text-icons/icon-status-02.png\" height=\"16\" width=\"16\" title=\"Paralysis\">"); } if ((PhysicalAilmentHeal & 8) == 8) { sb.Append("<img src=\"text-icons/icon-status-03.png\" height=\"16\" width=\"16\" title=\"Petrification\">"); } if ((PhysicalAilmentHeal & 16) == 16) { sb.Append("<img src=\"text-icons/icon-status-04.png\" height=\"16\" width=\"16\" title=\"Weakness\">"); } if ((PhysicalAilmentHeal & 32) == 32) { sb.Append("<img src=\"text-icons/icon-status-05.png\" height=\"16\" width=\"16\" title=\"Sealed Artes\">"); } if ((PhysicalAilmentHeal & 64) == 64) { sb.Append("<img src=\"text-icons/icon-status-06.png\" height=\"16\" width=\"16\" title=\"Sealed Skills\">"); } sb.Append("<br>"); } if (StatValue > 0) { //sb.Append( "Stat Type: " + StatType + "<br>" ); switch (StatType) { case 1: sb.Append("P. ATK"); break; case 2: sb.Append("P. DEF"); break; case 3: sb.Append("M. ATK"); break; case 4: sb.Append("M. DEF"); break; case 5: sb.Append("AGL"); break; case 11: sb.Append("Over Limit gauge increases<br>"); break; } if (StatType != 11) { sb.Append(" +" + StatValue + (StatType < 5 ? "%" : "") + "<br>"); sb.Append("Duration: " + StatTime + " seconds<br>"); } } if (RecipeCreationCharacter.Count(x => x != 0) > 0) { sb.Append("Recipe Evolutions:<br>"); for (int i = 0; i < RecipeCreationCharacter.Length; ++i) { if (RecipeCreationCharacter[i] != 0) { var otherRecipe = recipes.RecipeList[(int)RecipeCreationRecipe[i]]; Website.GenerateWebsite.AppendCharacterBitfieldAsImageString(sb, version, (uint)(1 << (int)(RecipeCreationCharacter[i] - 1))); sb.Append(" <a href=\"#recipe" + otherRecipe.ID + "\">"); sb.Append(inGameIdDict[otherRecipe.NameStringDicID].StringEngOrJpnHtml(version)); sb.Append("</a>"); sb.Append("<br>"); } } } sb.Append("<table class=\"element\">"); sb.Append("<tr>"); sb.Append("<td>Likes</td>"); sb.Append("<td>Dislikes</td>"); sb.Append("</tr>"); sb.Append("<tr>"); sb.Append("<td>"); Website.GenerateWebsite.AppendCharacterBitfieldAsImageString(sb, version, CharactersLike); sb.Append("</td>"); sb.Append("<td>"); Website.GenerateWebsite.AppendCharacterBitfieldAsImageString(sb, version, CharactersDislike); sb.Append("</td>"); sb.Append("</tr>"); sb.Append("<tr>"); sb.Append("<td>Good at</td>"); sb.Append("<td>Bad at</td>"); sb.Append("</tr>"); sb.Append("<tr>"); sb.Append("<td>"); Website.GenerateWebsite.AppendCharacterBitfieldAsImageString(sb, version, CharactersGoodAtMaking); sb.Append("</td>"); sb.Append("<td>"); Website.GenerateWebsite.AppendCharacterBitfieldAsImageString(sb, version, CharactersBadAtMaking); sb.Append("</td>"); sb.Append("</tr>"); sb.Append("</table>"); sb.Append("</td></tr>"); return(sb.ToString()); }
public string GetDataAsHtml(GameVersion version, string versionPostfix, GameLocale locale, WebsiteLanguage websiteLanguage, ItemDat.ItemDat items, Dictionary <uint, TSS.TSSEntry> inGameIdDict, bool phpLinks = false) { StringBuilder sb = new StringBuilder(); var item = items.itemIdDict[ItemID]; sb.Append("<img src=\"item-icons/ICON" + item.Data[(int)ItemData.Icon] + ".png\" height=\"16\" width=\"16\"> "); sb.Append("<a href=\"" + Website.WebsiteGenerator.GetUrl(Website.WebsiteSection.Item, version, versionPostfix, locale, websiteLanguage, phpLinks, id: (int)item.Data[(int)ItemData.ID], icon: (int)item.Data[(int)ItemData.Icon]) + "\">"); sb.Append(inGameIdDict[item.NamePointer].StringEngOrJpnHtml(version, inGameIdDict, websiteLanguage) + "</a>"); return(sb.ToString()); }
public static int Parse(List <string> args) { if (args.Count < 2) { Console.WriteLine("Usage: SaveDataParser savefile gamedatapath"); Console.WriteLine("Save must be decrypted."); Console.WriteLine("Game data path should point to a directory or other container with the game files, which is needed to parse things like item, title, and enemy data correctly."); return(-1); } IContainer gameContainer = Website.GenerateWebsite.ContainerFromPath(args[1]); if (gameContainer == null) { Console.WriteLine("Invalid game data path given."); return(-1); } GameVersion?maybeVersion = Website.GenerateWebsite.GuessGameVersionFromContainer(gameContainer); if (!maybeVersion.HasValue) { Console.WriteLine("Failed to determine game version from given data path."); return(-1); } GameVersion version = maybeVersion.Value; IContainer gameDir = Website.GenerateWebsite.FindGameDataDirectory(gameContainer, version); if (gameDir == null) { Console.WriteLine("Failed to find correct file container -- is your game dump incomplete?"); return(-1); } GameLocale locale = VesperiaUtil.GetValidLocales(version).First(); EndianUtils.Endianness endian = VesperiaUtil.GetEndian(version); TextUtils.GameTextEncoding encoding = VesperiaUtil.GetEncoding(version); BitUtils.Bitness bits = VesperiaUtil.GetBitness(version); TSS.TSSFile stringDic = new TSS.TSSFile(Website.GenerateWebsite.TryGetStringDic(gameDir, locale, version), encoding, endian); Dictionary <uint, TSS.TSSEntry> inGameDic = stringDic.GenerateInGameIdDictionary(); ItemDat.ItemDat itemData = new ItemDat.ItemDat(Website.GenerateWebsite.TryGetItemDat(gameDir, locale, version), Website.GenerateWebsite.TryGetItemSortDat(gameDir, locale, version), EndianUtils.Endianness.BigEndian); List <ItemDat.ItemDatSingle> itemDataSorted = itemData.GetSortedByInGameSorting(); FAMEDAT.FAMEDAT titles = new FAMEDAT.FAMEDAT(Website.GenerateWebsite.TryGetTitles(gameDir, locale, version), endian); T8BTEMST.T8BTEMST enemies = new T8BTEMST.T8BTEMST(Website.GenerateWebsite.TryGetEnemies(gameDir, locale, version), endian, bits); using (DuplicatableFileStream file = new DuplicatableFileStream(args[0])) { var savedata = new SaveData(file, endian); savedata.SavePoint.PrintData(); savedata.PartyData.PrintData(endian, inGameDic, itemDataSorted, enemies); foreach (var characterBlock in savedata.CharacterData) { characterBlock.PrintData(endian, version, inGameDic, titles); Console.WriteLine("====="); } //savedata.ExportTo( args[0] + ".ext" ); } return(0); }
public static int Parse(List <string> args) { if (args.Count < 1) { Console.WriteLine("Usage: SaveDataParser SAVE"); Console.WriteLine("Save must be decrypted."); return(-1); } Util.Endianness endian = Util.Endianness.BigEndian; var stringDic = new TSS.TSSFile(@"c:\Dropbox\ToV\PS3\mod\string.svo.ext\STRING_DIC.SO", Util.GameTextEncoding.ShiftJIS, Util.Endianness.BigEndian); var inGameDic = stringDic.GenerateInGameIdDictionary(); var itemData = new ItemDat.ItemDat(@"c:\Dropbox\ToV\PS3\orig\item.svo.ext\ITEM.DAT", endian); var itemDataSorted = itemData.GetSortedByInGameSorting(); var titles = new FAMEDAT.FAMEDAT(@"c:\Dropbox\ToV\PS3\orig\menu.svo.ext\FAMEDATA.BIN", endian); var enemies = new T8BTEMST.T8BTEMST(@"c:\Dropbox\ToV\PS3\orig\btl.svo.ext\BTL_PACK.DAT.ext\0005.ext\ALL.0000", endian, Util.Bitness.B32); using (Stream file = new FileStream(args[0], FileMode.Open, FileAccess.Read)) { file.DiscardBytes(0x228); // short header, used for save menu on 360 version to display basic info about save string magic = file.ReadAscii(8); if (magic != "TO8SAVE\0") { throw new Exception("Invalid magic byte sequence for ToV save: " + magic); } uint saveFileSize = file.ReadUInt32().FromEndian(endian); if (saveFileSize != 0xCCAA0) { throw new Exception("Unexpected filesize for ToV save: " + saveFileSize); } file.DiscardBytes(0x3AC8 - 0x234); // no idea what all this is // save point flags, one byte each, 0x00 not visted 0x01 visited byte[] savePointFlags = file.ReadUInt8Array(0x59); { PrintSavePoint(savePointFlags, 0x00, "Fiertia Deck (Docked at Atherum)"); PrintSavePoint(savePointFlags, 0x01, "Atherum"); PrintSavePoint(savePointFlags, 0x02, "Fiertia Hold"); // same flag for both opportunities? PrintSavePoint(savePointFlags, 0x03, "Keiv Moc (Middle)"); PrintSavePoint(savePointFlags, 0x04, "Keiv Moc (Boss)"); PrintSavePoint(savePointFlags, 0x05, "Zaphias (Lower Quarter)"); PrintSavePoint(savePointFlags, 0x06, "Zaphias (Royal Quarter)"); PrintSavePoint(savePointFlags, 0x07, "Zaphias Castle (Prison)"); PrintSavePoint(savePointFlags, 0x08, "Zaphias Castle (Kitchen)"); // 2nd visit only PrintSavePoint(savePointFlags, 0x09, "Zaphias Castle (Hallways)"); // before zagi fight PrintSavePoint(savePointFlags, 0x0A, "Zaphias Castle (Sword Stair)"); PrintSavePoint(savePointFlags, 0x0B, "Zaphias Castle (Big Hall)"); // 2nd visit only, that big room that leads to the sword stair PrintSavePoint(savePointFlags, 0x0C, "Weasand of Cados (Middle)"); PrintSavePoint(savePointFlags, 0x0D, "Weasand of Cados (Exit)"); PrintSavePoint(savePointFlags, 0x0E, "Halure (Inn)"); PrintSavePoint(savePointFlags, 0x0F, "Ghasfarost (Bottom)"); PrintSavePoint(savePointFlags, 0x10, "Ghasfarost (Top)"); PrintSavePoint(savePointFlags, 0x11, "Myorzo (Vacant House)"); PrintSavePoint(savePointFlags, 0x12, "Mt. Temza (Middle)"); PrintSavePoint(savePointFlags, 0x13, "Mt. Temza (Boss)"); PrintSavePoint(savePointFlags, 0x14, "Deidon Hold"); PrintSavePoint(savePointFlags, 0x15, "Northeastern Hypionia"); // aurnion before it's built PrintSavePoint(savePointFlags, 0x16, "Aurnion (Developing)"); PrintSavePoint(savePointFlags, 0x17, "Aurnion (Developed)"); PrintSavePoint(savePointFlags, 0x18, "Caer Bocram"); PrintSavePoint(savePointFlags, 0x19, "Quoi Woods"); PrintSavePoint(savePointFlags, 0x1A, "Dahngrest (Inn)"); PrintSavePoint(savePointFlags, 0x1B, "Ehmead Hill"); PrintSavePoint(savePointFlags, 0x1C, "Erealumen (Middle)"); PrintSavePoint(savePointFlags, 0x1D, "Erealumen (Boss)"); PrintSavePoint(savePointFlags, 0x1E, "Heracles (Near Engine Room)"); PrintSavePoint(savePointFlags, 0x1F, "Heracles (Near Control Room)"); // zagi fight PrintSavePoint(savePointFlags, 0x20, "Zopheir (Boss)"); // 1st visit only PrintSavePoint(savePointFlags, 0x21, "Zopheir (Near Aer Krene)"); // 2nd visit only PrintSavePoint(savePointFlags, 0x22, "Manor of the Wicked"); PrintSavePoint(savePointFlags, 0x23, "Tarqaron (Middle)"); PrintSavePoint(savePointFlags, 0x24, "Tarqaron (Top)"); PrintSavePoint(savePointFlags, 0x25, "Baction B1F"); PrintSavePoint(savePointFlags, 0x26, "Baction B2F"); // both save points on B2F share this flag...? PrintSavePoint(savePointFlags, 0x27, "Mantaic (Inn)"); PrintSavePoint(savePointFlags, 0x28, "Relewiese (Middle)"); PrintSavePoint(savePointFlags, 0x29, "Relewiese (Boss)"); PrintSavePoint(savePointFlags, 0x2A, "Capua Nor (Outside Ragou's Mansion)"); PrintSavePoint(savePointFlags, 0x2B, "Capua Nor (Inn)"); PrintSavePoint(savePointFlags, 0x2C, "Capua Torim (Inn)"); PrintSavePoint(savePointFlags, 0x2D, "Shaikos Ruins"); PrintSavePoint(savePointFlags, 0x2E, "Zaude (Side Entrance)"); PrintSavePoint(savePointFlags, 0x2F, "Zaude (Alexei)"); PrintSavePoint(savePointFlags, 0x30, "Zaude (Yeager)"); PrintSavePoint(savePointFlags, 0x31, "Aspio (Inn)"); PrintSavePoint(savePointFlags, 0x32, "Nordopolica (Inn)"); PrintSavePoint(savePointFlags, 0x33, "Heliord (Inn)"); PrintSavePoint(savePointFlags, 0x34, "Yormgen (Inn)"); PrintSavePoint(savePointFlags, 0x35, "Weasand of Kogorh (Oasis)"); PrintSavePoint(savePointFlags, 0x36, "Weasand of Kogorh (Exit)"); PrintSavePoint(savePointFlags, 0x37, "Egothor Forest"); PrintSavePoint(savePointFlags, 0x38, "Dahngrest Underpass (Oath)"); PrintSavePoint(savePointFlags, 0x39, "Ragou's Mansion"); // basement dungeon midpoint PrintSavePoint(savePointFlags, 0x3A, "Dahngrest Underpass (Exit)"); PrintSavePoint(savePointFlags, 0x3B, "Abysmal Hollow (Aer Krene near Yumanju)"); PrintSavePoint(savePointFlags, 0x3C, "? Abysmal Hollow (Aer Krene near Zaphias)"); PrintSavePoint(savePointFlags, 0x3D, "Abysmal Hollow (Aer Krene near Heliord)"); PrintSavePoint(savePointFlags, 0x3E, "Abysmal Hollow (Aer Krene near Nordopolica)"); PrintSavePoint(savePointFlags, 0x3F, "? Abysmal Hollow (Center)"); PrintSavePoint(savePointFlags, 0x40, "City of the Waning Moon"); PrintSavePoint(savePointFlags, 0x41, "Necropolis of Nostalgia A3"); PrintSavePoint(savePointFlags, 0x42, "Necropolis of Nostalgia A6"); PrintSavePoint(savePointFlags, 0x43, "Necropolis of Nostalgia A9"); PrintSavePoint(savePointFlags, 0x44, "Necropolis of Nostalgia A Bottom"); PrintSavePoint(savePointFlags, 0x45, "Necropolis of Nostalgia B2"); PrintSavePoint(savePointFlags, 0x46, "Necropolis of Nostalgia B5"); PrintSavePoint(savePointFlags, 0x47, "Necropolis of Nostalgia B8"); PrintSavePoint(savePointFlags, 0x48, "Necropolis of Nostalgia B Bottom"); PrintSavePoint(savePointFlags, 0x49, "Necropolis of Nostalgia C3"); PrintSavePoint(savePointFlags, 0x4A, "Necropolis of Nostalgia C6"); PrintSavePoint(savePointFlags, 0x4B, "Necropolis of Nostalgia C9"); PrintSavePoint(savePointFlags, 0x4C, "Necropolis of Nostalgia C Bottom"); PrintSavePoint(savePointFlags, 0x4D, "Necropolis of Nostalgia D3"); PrintSavePoint(savePointFlags, 0x4E, "Necropolis of Nostalgia D6"); PrintSavePoint(savePointFlags, 0x4F, "Necropolis of Nostalgia D9"); PrintSavePoint(savePointFlags, 0x50, "Necropolis of Nostalgia D Bottom"); PrintSavePoint(savePointFlags, 0x51, "Necropolis of Nostalgia E3"); PrintSavePoint(savePointFlags, 0x52, "Necropolis of Nostalgia E6"); PrintSavePoint(savePointFlags, 0x53, "Necropolis of Nostalgia E9"); PrintSavePoint(savePointFlags, 0x54, "Necropolis of Nostalgia E Bottom"); PrintSavePoint(savePointFlags, 0x55, "Necropolis of Nostalgia F3"); PrintSavePoint(savePointFlags, 0x56, "Necropolis of Nostalgia F6"); PrintSavePoint(savePointFlags, 0x57, "Necropolis of Nostalgia F9"); PrintSavePoint(savePointFlags, 0x58, "Necropolis of Nostalgia F Bottom"); } file.DiscardBytes(0xA3F48 - 0x3B21); // no idea what all this is file.ReadUInt32().FromEndian(endian); // ? file.ReadUInt32().FromEndian(endian); // ? file.ReadUInt32Array(9, endian); file.ReadUInt32().FromEndian(endian); // play time in frames, assuming 60 frames = 1 second file.ReadUInt32().FromEndian(endian); // gald file.DiscardBytes(4); // ? uint[] itemCounts = file.ReadUInt32Array(3072, endian); uint[] itemBookBitfields = file.ReadUInt32Array(3072 / 32, endian); file.DiscardBytes(4); // ? file.ReadUInt32Array(4, endian); // control modes for the four active party slots file.ReadUInt32Array(3, endian); // strategies assigned to dpad directions file.DiscardBytes(0x40); // ?? for (int i = 0; i < 8; ++i) { // custom strategy names // game seems to read these till null byte so this could totally be abused to buffer overflow... file.ReadAscii(0x40); } file.DiscardBytes(0xA84D0 - 0xA7360); // ? uint[] monsterBookBitfieldsScanned = file.ReadUInt32Array(0x48 / 4, endian); file.DiscardBytes(0xA8680 - 0xA8518); // ? uint[] monsterBookBitfieldsSeen = file.ReadUInt32Array(0x48 / 4, endian); file.DiscardBytes(0xA8928 - 0xA86C8); // ? // 9 character blocks, each 0x4010 bytes for (int character = 0; character < 9; ++character) { file.ReadUInt32().FromEndian(endian); // ? file.ReadAscii(0x40); // custom character name file.ReadUInt32().FromEndian(endian); // character ID file.ReadUInt32().FromEndian(endian); // level file.ReadUInt32().FromEndian(endian); // current HP file.ReadUInt32().FromEndian(endian); // current TP file.ReadUInt32().FromEndian(endian); // max HP file.ReadUInt32().FromEndian(endian); // max TP file.ReadUInt32().FromEndian(endian); // ? file.ReadUInt32().FromEndian(endian); // EXP file.ReadUInt32().FromEndian(endian); // ? file.ReadUInt32().FromEndian(endian); // ? file.ReadUInt32().FromEndian(endian); // base attack file.ReadUInt32().FromEndian(endian); // base magic attack file.ReadUInt32().FromEndian(endian); // base def file.ReadUInt32().FromEndian(endian); // base mdef file.ReadUInt32().FromEndian(endian); // ? file.ReadUInt32().FromEndian(endian); // base agility file.ReadUInt32().FromEndian(endian); // luck file.ReadUInt32().FromEndian(endian); // ? file.ReadUInt32().FromEndian(endian); // ? file.ReadUInt32().FromEndian(endian); // base attack attribute fire file.ReadUInt32().FromEndian(endian); // base attack attribute earth file.ReadUInt32().FromEndian(endian); // base attack attribute wind file.ReadUInt32().FromEndian(endian); // base attack attribute water file.ReadUInt32().FromEndian(endian); // base attack attribute light file.ReadUInt32().FromEndian(endian); // base attack attribute dark file.ReadUInt32().FromEndian(endian); // base attack attribute physical...? file.ReadUInt32().FromEndian(endian); // base damage multiplier fire file.ReadUInt32().FromEndian(endian); // base damage multiplier earth file.ReadUInt32().FromEndian(endian); // base damage multiplier wind file.ReadUInt32().FromEndian(endian); // base damage multiplier water file.ReadUInt32().FromEndian(endian); // base damage multiplier light file.ReadUInt32().FromEndian(endian); // base damage multiplier dark file.ReadUInt32().FromEndian(endian); // base damage multiplier physical? file.DiscardBytes(0xA8A60 - 0xA89F0); // ? file.ReadUInt32().FromEndian(endian); // modified attack (base + from equipment) file.ReadUInt32().FromEndian(endian); // mod def file.ReadUInt32().FromEndian(endian); // mod matk file.ReadUInt32().FromEndian(endian); // mod mdef file.ReadUInt32().FromEndian(endian); // ? file.ReadUInt32().FromEndian(endian); // mod agility file.ReadUInt32().FromEndian(endian); // mod luck file.ReadUInt32().FromEndian(endian); // ? file.ReadUInt32().FromEndian(endian); // ? file.ReadUInt32().FromEndian(endian); // mod attack attribute fire file.ReadUInt32().FromEndian(endian); // mod attack attribute earth file.ReadUInt32().FromEndian(endian); // mod attack attribute wind file.ReadUInt32().FromEndian(endian); // mod attack attribute water file.ReadUInt32().FromEndian(endian); // mod attack attribute light file.ReadUInt32().FromEndian(endian); // mod attack attribute dark file.ReadUInt32().FromEndian(endian); // mod attack attribute physical...? file.ReadUInt32().FromEndian(endian); // mod damage multiplier fire file.ReadUInt32().FromEndian(endian); // mod damage multiplier earth file.ReadUInt32().FromEndian(endian); // mod damage multiplier wind file.ReadUInt32().FromEndian(endian); // mod damage multiplier water file.ReadUInt32().FromEndian(endian); // mod damage multiplier light file.ReadUInt32().FromEndian(endian); // mod damage multiplier dark file.ReadUInt32().FromEndian(endian); // mod damage multiplier physical? file.DiscardBytes(0xA8E04 - 0xA8ABC); // ? file.ReadUInt32().FromEndian(endian); // enemy kill counter (?) file.DiscardBytes(0xAAE28 - 0xA8E08); // ? // skill equipment is stored around here file.DiscardBytes(0xAC5B8 - 0xAAE28); // ? uint[] titlesUnlockedBitfield = file.ReadUInt32Array(15, endian); foreach (var title in titles.TitleList) { bool haveTitle = ((titlesUnlockedBitfield[title.ID / 32] >> (int)(title.ID % 32)) & 1) > 0; if (haveTitle || ((title.BunnyGuildPointsMaybe > 0 || title.ID == 67) && title.Character == (character + 1))) { Console.WriteLine((haveTitle ? "Y" : "N") + ": " + inGameDic[title.NameStringDicID].StringEngOrJpn); } } Console.WriteLine("==="); file.DiscardBytes(0xAC938 - 0xAC5F4); // ? } uint collectorsBookIndex = 0; foreach (var item in itemDataSorted) { uint i = item.Data[(int)ItemDat.ItemData.ID]; if (item.Data[(int)ItemDat.ItemData.InCollectorsBook] > 0) { bool haveItem = ((itemBookBitfields[i / 32] >> (int)(i % 32)) & 1) > 0; Console.WriteLine((haveItem ? "Y" : "N") + (collectorsBookIndex) + ": " + inGameDic[item.NamePointer].StringEngOrJpn); ++collectorsBookIndex; } } uint monsterBookIndex = 0; foreach (var enemy in enemies.EnemyList) { uint i = enemy.InGameID; if (enemy.InMonsterBook > 0) { bool haveSeen = ((monsterBookBitfieldsSeen[i / 32] >> (int)(i % 32)) & 1) > 0; bool haveScanned = ((monsterBookBitfieldsScanned[i / 32] >> (int)(i % 32)) & 1) > 0; Console.WriteLine((haveSeen ? "Y" : "N") + (haveScanned ? "Y" : "N") + (monsterBookIndex) + ": " + inGameDic[enemy.NameStringDicID].StringEngOrJpn); ++monsterBookIndex; } } } return(0); }