Beispiel #1
0
        public async Task <IActionResult> GetSpellTooltip(int spellID, string build)
        {
            var result = new TTSpell();

            result.SpellID = spellID;

            var spellNameDB = await dbcManager.GetOrLoad("SpellName", build);

            if (spellNameDB.TryGetValue(spellID, out DBCDRow spellNameRow))
            {
                var spellName = (string)spellNameRow["Name_lang"];
                if (!string.IsNullOrWhiteSpace(spellName))
                {
                    result.Name = spellName;
                }
            }

            var spellDB = await dbcManager.GetOrLoad("Spell", build);

            if (spellDB.TryGetValue(spellID, out var spellRow))
            {
                var dataSupplier = new SpellDataSupplier(dbcManager, build);

                if ((string)spellRow["Description_lang"] != string.Empty)
                {
                    var spellDescParser = new SpellDescParser((string)spellRow["Description_lang"]);
                    spellDescParser.Parse();

                    var sb = new StringBuilder();
                    spellDescParser.root.Format(sb, spellID, dataSupplier);

                    result.Description = sb.ToString();
                }
            }

            var spellMiscRow = dbcManager.FindRecords("spellMisc", build, "SpellID", spellID, true).Result;

            if (spellMiscRow.Count == 0)
            {
                result.IconFileDataID = 134400;
            }
            else
            {
                result.IconFileDataID = (int)spellMiscRow[0]["SpellIconFileDataID"];
            }

            return(Ok(result));
        }
Beispiel #2
0
        public async Task <IActionResult> GetItemTooltip(int itemID, string build)
        {
            var result = new TTItem();

            var itemDB = await dbcManager.GetOrLoad("Item", build);

            if (!itemDB.TryGetValue(itemID, out DBCDRow itemEntry))
            {
                return(NotFound());
            }

            result.IconFileDataID = (int)itemEntry["IconFileDataID"];
            result.ClassID        = (byte)itemEntry["ClassID"];
            result.SubClassID     = (byte)itemEntry["SubclassID"];
            result.InventoryType  = (sbyte)itemEntry["InventoryType"];

            // Icons in Item.db2 can be 0. Look up the proper one in ItemModifiedAppearance => ItemAppearance
            if (result.IconFileDataID == 0)
            {
                var itemModifiedAppearances = await dbcManager.FindRecords("ItemModifiedAppearance", build, "ItemID", itemID);

                if (itemModifiedAppearances.Count > 0)
                {
                    var itemAppearanceDB = await dbcManager.GetOrLoad("ItemAppearance", build);

                    if (itemAppearanceDB.TryGetValue((ushort)itemModifiedAppearances[0]["ItemAppearanceID"], out DBCDRow itemAppearanceRow))
                    {
                        result.IconFileDataID = (int)itemAppearanceRow["DefaultIconFileDataID"];
                    }
                }
            }

            var itemSparseDB = await dbcManager.GetOrLoad("ItemSparse", build);

            if (!itemSparseDB.TryGetValue(itemID, out DBCDRow itemSparseEntry))
            {
                var itemSearchNameDB = await dbcManager.GetOrLoad("ItemSearchName", build);

                if (!itemSearchNameDB.TryGetValue(itemID, out DBCDRow itemSearchNameEntry))
                {
                    result.Name = "Unknown Item";
                }
                else
                {
                    result.Name             = (string)itemSearchNameEntry["Display_lang"];
                    result.RequiredLevel    = (sbyte)itemSearchNameEntry["RequiredLevel"];
                    result.ExpansionID      = (byte)itemSearchNameEntry["ExpansionID"];
                    result.ItemLevel        = (ushort)itemSearchNameEntry["ItemLevel"];
                    result.OverallQualityID = (byte)itemSearchNameEntry["OverallQualityID"];
                }

                result.HasSparse = false;
            }
            else
            {
                result.HasSparse        = true;
                result.ItemLevel        = (ushort)itemSparseEntry["ItemLevel"];
                result.OverallQualityID = (byte)itemSparseEntry["OverallQualityID"];
                result.Name             = (string)itemSparseEntry["Display_lang"];
                result.FlavorText       = (string)itemSparseEntry["Description_lang"];
                result.ExpansionID      = (byte)itemSparseEntry["ExpansionID"];
                result.RequiredLevel    = (sbyte)itemSparseEntry["RequiredLevel"];

                var itemDelay      = (ushort)itemSparseEntry["ItemDelay"] / 1000f;
                var targetDamageDB = GetDamageDBByItemSubClass((byte)itemEntry["SubclassID"], (itemSparseEntry.FieldAs <int[]>("Flags")[1] & 0x200) == 0x200);

                var statTypes = itemSparseEntry.FieldAs <sbyte[]>("StatModifier_bonusStat");
                if (statTypes.Length > 0 && statTypes.Any(x => x != -1) && statTypes.Any(x => x != 0))
                {
                    var(RandomPropField, RandomPropIndex) = TooltipUtils.GetRandomPropertyByInventoryType(result.OverallQualityID, result.InventoryType, result.SubClassID, build);

                    var randomPropDB = await dbcManager.GetOrLoad("RandPropPoints", build);

                    int randProp;
                    if (randomPropDB.TryGetValue(result.ItemLevel, out DBCDRow randPropEntry))
                    {
                        randProp = (int)randPropEntry.FieldAs <uint[]>(RandomPropField)[RandomPropIndex];
                    }
                    else
                    {
                        throw new Exception("Item Level " + result.ItemLevel + " not found in RandPropPoints");
                    }

                    var statPercentEditor = itemSparseEntry.FieldAs <int[]>("StatPercentEditor");

                    var statList = new Dictionary <sbyte, TTItemStat>();
                    for (var statIndex = 0; statIndex < statTypes.Length; statIndex++)
                    {
                        if (statTypes[statIndex] == -1 || statTypes[statIndex] == 0)
                        {
                            continue;
                        }

                        var stat = TooltipUtils.CalculateItemStat(statTypes[statIndex], randProp, result.ItemLevel, statPercentEditor[statIndex], 0.0f, result.OverallQualityID, result.InventoryType, result.SubClassID, build);

                        if (stat.Value == 0)
                        {
                            continue;
                        }

                        if (statList.TryGetValue(statTypes[statIndex], out var currStat))
                        {
                            currStat.Value += stat.Value;
                        }
                        else
                        {
                            statList.Add(statTypes[statIndex], stat);
                        }
                    }

                    result.Stats = statList.Values.ToArray();
                }

                var damageRecord = await dbcManager.FindRecords(targetDamageDB, build, "ItemLevel", result.ItemLevel);

                var quality = result.OverallQualityID;
                if (quality == 7) // Heirloom == Rare
                {
                    quality = 3;
                }

                if (quality == 5) // Legendary = Epic
                {
                    quality = 4;
                }

                var itemDamage  = damageRecord[0].FieldAs <float[]>("Quality")[quality];
                var dmgVariance = (float)itemSparseEntry["DmgVariance"];


                // Use . as decimal separator
                NumberFormatInfo nfi = new NumberFormatInfo();
                nfi.NumberDecimalSeparator = ".";
                result.MinDamage           = Math.Floor(itemDamage * itemDelay * (1 - dmgVariance * 0.5)).ToString(nfi);
                result.MaxDamage           = Math.Floor(itemDamage * itemDelay * (1 + dmgVariance * 0.5)).ToString(nfi);
                result.Speed = itemDelay.ToString("F2", nfi);
                result.DPS   = itemDamage.ToString("F2", nfi);
            }

            var itemEffectEntries = await dbcManager.FindRecords("ItemEffect", build, "ParentItemID", itemID);

            if (itemEffectEntries.Count > 0)
            {
                var spellDB = await dbcManager.GetOrLoad("Spell", build);

                var spellNameDB = await dbcManager.GetOrLoad("SpellName", build);

                result.ItemEffects = new TTItemEffect[itemEffectEntries.Count];
                for (var i = 0; i < itemEffectEntries.Count; i++)
                {
                    result.ItemEffects[i].TriggerType = (sbyte)itemEffectEntries[i]["TriggerType"];

                    var ttSpell = new TTSpell {
                        SpellID = (int)itemEffectEntries[i]["SpellID"]
                    };
                    if (spellDB.TryGetValue((int)itemEffectEntries[i]["SpellID"], out DBCDRow spellRow))
                    {
                        var spellDescription = (string)spellRow["Description_lang"];
                        if (!string.IsNullOrWhiteSpace(spellDescription))
                        {
                            ttSpell.Description = spellDescription;
                        }
                    }

                    if (spellNameDB.TryGetValue((int)itemEffectEntries[i]["SpellID"], out DBCDRow spellNameRow))
                    {
                        var spellName = (string)spellNameRow["Name_lang"];
                        if (!string.IsNullOrWhiteSpace(spellName))
                        {
                            ttSpell.Name = spellName;
                        }
                    }

                    result.ItemEffects[i].Spell = ttSpell;
                }
            }

            /* Fixups */
            // Classic ExpansionID column has 254, make 0. ¯\_(ツ)_/¯
            if (result.ExpansionID == 254)
            {
                result.ExpansionID = 0;
            }

            return(Ok(result));
        }
Beispiel #3
0
        public async Task <IActionResult> GetSpellTooltip(int spellID, string build, byte level = 60, sbyte difficulty = -1, short mapID = -1)
        {
            // If difficulty is -1 fall back to Normal

            var result = new TTSpell();

            result.SpellID = spellID;

            var spellNameDB = await dbcManager.GetOrLoad("SpellName", build);

            if (spellNameDB.TryGetValue(spellID, out DBCDRow spellNameRow))
            {
                var spellName = (string)spellNameRow["Name_lang"];
                if (!string.IsNullOrWhiteSpace(spellName))
                {
                    result.Name = spellName;
                }
            }

            var spellDB = await dbcManager.GetOrLoad("Spell", build);

            if (spellDB.TryGetValue(spellID, out var spellRow))
            {
                var dataSupplier = new SpellDataSupplier(dbcManager, build, level, difficulty, mapID);

                if ((string)spellRow["Description_lang"] != string.Empty)
                {
                    var spellDescParser = new SpellDescParser((string)spellRow["Description_lang"]);
                    spellDescParser.Parse();

                    var sb = new StringBuilder();
                    spellDescParser.root.Format(sb, spellID, dataSupplier);

                    result.Description = sb.ToString();

                    // Check for PropertyType.SpellDescription nodes and feed those into separate parsers (make sure to add a recursion limit :) )
                    foreach (var node in spellDescParser.root.nodes)
                    {
                        if (node is Property property && property.propertyType == PropertyType.SpellDescription && property.overrideSpellID != null)
                        {
                            if (spellDB.TryGetValue((int)property.overrideSpellID, out var externalSpellRow))
                            {
                                var externalSpellDescParser = new SpellDescParser((string)externalSpellRow["Description_lang"]);
                                externalSpellDescParser.Parse();

                                var externalSB = new StringBuilder();
                                externalSpellDescParser.root.Format(externalSB, (int)property.overrideSpellID, dataSupplier);

                                result.Description = result.Description.Replace("$@spelldesc" + property.overrideSpellID, externalSB.ToString());
                            }
                        }
                    }
                }

                if ((string)spellRow["NameSubtext_lang"] != string.Empty)
                {
                    result.SubText = (string)spellRow["NameSubtext_lang"];
                }
            }

            var spellMiscRow = dbcManager.FindRecords("spellMisc", build, "SpellID", spellID, true).Result;

            if (spellMiscRow.Count == 0)
            {
                result.IconFileDataID = 134400;
            }
            else
            {
                result.IconFileDataID = (int)spellMiscRow[0]["SpellIconFileDataID"];
            }

            return(Ok(result));
        }