Example #1
0
        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());
        }
Example #2
0
        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());
        }
Example #3
0
        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());
        }
Example #4
0
        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());
        }
Example #5
0
        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());
        }
Example #6
0
        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());
        }
Example #7
0
        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());
        }
Example #8
0
        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());
        }
Example #9
0
        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());
        }
Example #10
0
        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());
        }
Example #11
0
        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());
        }
Example #12
0
        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());
        }
Example #13
0
        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);
        }
Example #14
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);
        }