コード例 #1
0
        public async Task <IActionResult> GetItemTooltip(int itemID, string build)
        {
            var result = new TTItem();

            // Basic Item information -- generally always available
            using (var query = new SQLiteCommand("SELECT IconFileDataID, ClassID, SubclassID, InventoryType FROM Item WHERE ID = :id"))
            {
                query.Connection = db;
                query.Parameters.AddWithValue(":id", itemID);
                await query.ExecuteNonQueryAsync();

                var reader = await query.ExecuteReaderAsync();

                if (!reader.HasRows)
                {
                    return(NotFound());
                }

                while (reader.Read())
                {
                    result.IconFileDataID = reader.GetInt32(0);
                    result.ClassID        = reader.GetInt32(1);
                    result.SubClassID     = reader.GetInt32(2);
                    result.InventoryType  = reader.GetInt32(3);
                }
            }

            // Icons in Item.db2 can be 0. Look up the proper one in ItemModifiedAppearance => ItemAppearance
            if (result.IconFileDataID == 0)
            {
                using var query  = new SQLiteCommand("SELECT DefaultIconFileDataID FROM ItemAppearance WHERE ID IN (SELECT ItemAppearanceID FROM ItemModifiedAppearance WHERE ItemID = :id)");
                query.Connection = db;
                query.Parameters.AddWithValue(":id", itemID);
                query.ExecuteNonQuery();

                var reader = query.ExecuteReader();
                while (reader.Read())
                {
                    result.IconFileDataID = reader.GetInt32(0);
                }
            }

            using (var query = new SQLiteCommand("SELECT * FROM ItemSparse WHERE ID = :id"))
            {
                query.Connection = db;
                query.Parameters.AddWithValue(":id", itemID);
                await query.ExecuteNonQueryAsync();

                var reader = await query.ExecuteReaderAsync();

                if (!reader.HasRows)
                {
                    result.HasSparse = false;
                }

                while (reader.Read())
                {
                    result.HasSparse        = true;
                    result.ItemLevel        = reader.GetInt32(reader.GetOrdinal("ItemLevel"));
                    result.OverallQualityID = reader.GetInt32(reader.GetOrdinal("OverallQualityID"));
                    result.Name             = reader.GetString(reader.GetOrdinal("Display_lang"));
                    result.FlavorText       = reader.GetString(reader.GetOrdinal("Description_lang"));
                    result.ExpansionID      = reader.GetInt32(reader.GetOrdinal("ExpansionID"));
                    result.RequiredLevel    = reader.GetInt32(reader.GetOrdinal("RequiredLevel"));

                    var itemDelay  = reader.GetInt32(reader.GetOrdinal("ItemDelay")) / 1000f;
                    var itemFlags1 = reader.GetInt32(reader.GetOrdinal("Flags_1"));

                    var targetDamageDB = GetDamageDBByItemSubClass(result.SubClassID, (itemFlags1 & 0x200) == 0x200);

                    var statTypes = new List <int>();
                    for (int i = 0; i < 10; i++)
                    {
                        statTypes.Add(reader.GetInt32(reader.GetOrdinal("StatModifier_bonusStat_" + i)));
                    }

                    if (statTypes.Count > 0 && statTypes.Any(x => x != -1) && statTypes.Any(x => x != 0))
                    {
                        var(RandomPropField, RandomPropIndex) = TooltipUtils.GetRandomPropertyByInventoryType(result.OverallQualityID, result.InventoryType, result.SubClassID);

                        using var rpropQuery  = new SQLiteCommand("SELECT " + RandomPropField + "F_" + RandomPropIndex + " FROM RandPropPoints WHERE ID = :id");
                        rpropQuery.Connection = db;
                        rpropQuery.Parameters.AddWithValue(":id", result.ItemLevel);
                        rpropQuery.ExecuteNonQuery();

                        var   rpropReader = rpropQuery.ExecuteReader();
                        float randProp    = 0.0f;

                        while (rpropReader.Read())
                        {
                            randProp = rpropReader.GetFloat(0);
                        }

                        var statPercentEditor = new List <int>();
                        for (int i = 0; i < 10; i++)
                        {
                            statPercentEditor.Add(reader.GetInt32(reader.GetOrdinal("StatPercentEditor_" + i)));
                        }

                        var statList = new Dictionary <int, TTItemStat>();
                        for (var statIndex = 0; statIndex < statTypes.Count; 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 quality = result.OverallQualityID;
                    if (quality == 7) // Heirloom == Rare
                    {
                        quality = 3;
                    }

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

                    using var damageQuery  = new SQLiteCommand("SELECT Quality_" + quality + " FROM " + targetDamageDB + " WHERE ItemLevel = :ilvl");
                    damageQuery.Connection = db;
                    damageQuery.Parameters.AddWithValue(":ilvl", result.ItemLevel);
                    damageQuery.ExecuteNonQuery();

                    var   damageReader = damageQuery.ExecuteReader();
                    float itemDamage   = 0.0f;

                    while (damageReader.Read())
                    {
                        itemDamage = damageReader.GetFloat(0);
                    }

                    var dmgVariance = reader.GetFloat(reader.GetOrdinal("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);
                }
            }

            if (!result.HasSparse)
            {
                using (var query = new SQLiteCommand("SELECT * FROM ItemSearchName WHERE ID = :id"))
                {
                    query.Connection = db;
                    query.Parameters.AddWithValue(":id", itemID);
                    await query.ExecuteNonQueryAsync();

                    var reader = await query.ExecuteReaderAsync();

                    if (!reader.HasRows)
                    {
                        result.Name = "Unknown Item";
                    }

                    while (reader.Read())
                    {
                        result.Name             = reader.GetString(reader.GetOrdinal("Display_lang"));
                        result.RequiredLevel    = reader.GetInt32(reader.GetOrdinal("RequiredLevel"));
                        result.ExpansionID      = reader.GetInt32(reader.GetOrdinal("ExpansionID"));
                        result.ItemLevel        = reader.GetInt32(reader.GetOrdinal("ItemLevel"));
                        result.OverallQualityID = reader.GetInt32(reader.GetOrdinal("OverallQualityID"));
                    }
                }
            }

            using (var query = new SQLiteCommand("SELECT ItemEffectID FROM ItemXItemEffect WHERE ItemID = :id"))
            {
                query.Connection = db;
                query.Parameters.AddWithValue(":id", itemID);
                await query.ExecuteNonQueryAsync();

                var reader = await query.ExecuteReaderAsync();

                var itemEffects = new List <TTItemEffect>();

                if (reader.HasRows)
                {
                    while (reader.Read())
                    {
                        var itemEffectID = reader.GetInt32(reader.GetOrdinal("ItemEffectID"));
                        using (var subquery = new SQLiteCommand("SELECT * FROM ItemEffect WHERE ID = :id"))
                        {
                            subquery.Connection = db;
                            subquery.Parameters.AddWithValue(":id", itemEffectID);
                            await subquery.ExecuteNonQueryAsync();

                            var subreader = await subquery.ExecuteReaderAsync();

                            if (subreader.HasRows)
                            {
                                while (subreader.Read())
                                {
                                    var triggerType = subreader.GetInt32(subreader.GetOrdinal("TriggerType"));
                                    var spellID     = subreader.GetInt32(subreader.GetOrdinal("SpellID"));

                                    itemEffects.Add(new TTItemEffect()
                                    {
                                        Spell = new TTSpell()
                                        {
                                            SpellID = spellID, Description = "Loading.."
                                        }, TriggerType = triggerType
                                    });
                                }
                            }
                        }
                    }
                }

                result.ItemEffects = itemEffects.ToArray();
            }

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

            return(Ok(result));
        }
コード例 #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));
        }
コード例 #3
0
        // Stat/Effect Point parsing based on work done by simc & https://github.com/TrinityCore/SpellWork
        public double?SupplyEffectPoint(int spellID, uint?effectIndex)
        {
            var points = 0.0f;

            using (var query = new SQLiteCommand("SELECT * FROM SpellEffect WHERE SpellID = :id AND EffectIndex = :effectIndex"))
            {
                query.Connection = db;
                query.Parameters.AddWithValue(":id", spellID);
                query.Parameters.AddWithValue(":effectIndex", effectIndex - 1);
                query.ExecuteNonQuery();

                var reader = query.ExecuteReader();
                if (!reader.HasRows)
                {
                    return(points);
                }

                while (reader.Read())
                {
                    var effectPoints    = reader.GetFloat(reader.GetOrdinal("EffectBasePointsF"));
                    var spellAttributes = new int[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };

                    using (var subQuery = new SQLiteCommand("SELECT * FROM SpellMisc WHERE ID = :id"))
                    {
                        subQuery.Connection = db;
                        subQuery.Parameters.AddWithValue(":id", spellID);
                        subQuery.ExecuteNonQuery();

                        var subReader = subQuery.ExecuteReader();
                        if (subReader.HasRows)
                        {
                            while (subReader.Read())
                            {
                                var spellAttrs = new List <int>();
                                for (int i = 0; i < 14; i++)
                                {
                                    spellAttrs.Add(subReader.GetInt32(subReader.GetOrdinal("Attributes_" + i)));
                                }
                                spellAttributes = spellAttrs.ToArray();
                            }
                        }
                    }

                    var coefficient = reader.GetFloat(reader.GetOrdinal("Coefficient"));

                    var scalingClass = reader.GetInt32(reader.GetOrdinal("ScalingClass"));

                    if (coefficient >= 0.0f)
                    {
                        // TODO: Not yet implemented

                        //SpellScaling? ItemLevel based scaling?
                        // TODO ScalingClass -1, -2, -3, -4, -5, -6, -7, -8, -9

                        // -6 - Sta
                        // -7 RandProp ?
                        // -8 RandProp DamageReplaceStatF
                        // -9 RandProp DamageReplaceStatF
                        // ItemLevel based scaling
                        if (itemID == 0)
                        {
                            return(effectPoints);
                        }

                        var itemLevel   = 0;
                        var itemSlot    = 0;
                        var itemQuality = 0;

                        using (var subquery = new SQLiteCommand("SELECT ItemLevel, InventoryType, OverallQualityID FROM ItemSparse WHERE ID = :id"))
                        {
                            subquery.Connection = db;
                            subquery.Parameters.AddWithValue(":id", itemID);
                            subquery.ExecuteNonQuery();

                            var subreader = subquery.ExecuteReader();
                            if (!subreader.HasRows)
                            {
                                return(effectPoints);
                            }

                            while (subreader.Read())
                            {
                                itemLevel   = subreader.GetInt32(subreader.GetOrdinal("ItemLevel"));
                                itemSlot    = subreader.GetInt32(subreader.GetOrdinal("InventoryType"));
                                itemQuality = subreader.GetInt32(subreader.GetOrdinal("OverallQualityID"));
                            }
                        }

                        var multiplier = GetItemMultiplier(itemSlot, itemLevel, build);

                        if (scalingClass == -7)
                        {
                            var(RandomPropField, RandomPropIndex) = TooltipUtils.GetRandomPropertyByInventoryType(itemQuality, itemSlot, 0);

                            using var rpropQuery  = new SQLiteCommand("SELECT " + RandomPropField + "F_0" + " FROM RandPropPoints WHERE ID = :id");
                            rpropQuery.Connection = db;
                            rpropQuery.Parameters.AddWithValue(":id", itemLevel);
                            rpropQuery.ExecuteNonQuery();

                            var   rpropReader = rpropQuery.ExecuteReader();
                            float randProp    = 0.0f;

                            while (rpropReader.Read())
                            {
                                randProp = rpropReader.GetFloat(0);
                            }

                            points = randProp * (float)multiplier;
                        }
                        else if (scalingClass == -8 || scalingClass == -9)
                        {
                            var randomPropField = "DamageReplaceStatF";
                            if (scalingClass == -9)
                            {
                                randomPropField = "DamageSecondaryF";
                            }

                            using var rpropQuery  = new SQLiteCommand("SELECT " + randomPropField + " FROM RandPropPoints WHERE ID = :id");
                            rpropQuery.Connection = db;
                            rpropQuery.Parameters.AddWithValue(":id", itemLevel);
                            rpropQuery.ExecuteNonQuery();

                            var   rpropReader = rpropQuery.ExecuteReader();
                            float randProp    = 0.0f;

                            while (rpropReader.Read())
                            {
                                randProp = rpropReader.GetFloat(0);
                            }

                            points = randProp;
                        }

                        return(points * coefficient);
                    }
                    else
                    {
                        //using (var subQuery = new SQLiteCommand("SELECT * FROM ExpectedStat WHERE Lvl = :id AND ExpansionID = :expansionID"))
                        //{
                        //    subQuery.Connection = db;
                        //    subQuery.Parameters.AddWithValue(":id", level);
                        //    subQuery.Parameters.AddWithValue(":expansionID", this.expansion);
                        //    subQuery.ExecuteNonQuery();

                        //    var subReader = subQuery.ExecuteReader();
                        //    if (subReader.HasRows)
                        //    {
                        //    }
                        //}

                        var expectedStatType =
                            TooltipUtils.GetExpectedStatTypeBySpellEffect(reader.GetInt32(reader.GetOrdinal("Effect")), reader.GetInt16(reader.GetOrdinal("EffectAura")), reader.GetInt32(reader.GetOrdinal("EffectMiscValue_0")));
                        if (expectedStatType != TooltipUtils.ExpectedStatType.None)
                        {
                            if ((spellAttributes[0] & 0x80000) == 0x80000)
                            {
                                expectedStatType = TooltipUtils.ExpectedStatType.CreatureAutoAttackDps;
                            }
                        }

                        return(effectPoints);
                    }
                }
            }

            return(points);
        }