Files
CypherCore/Source/Game/Entities/Item/ItemEnchantment.cs
T
hondacrx 49a07ebcce Core/Items: Item bonus generation improvements
* Pass ItemContext to item creation wherever possible
* Support scaling item levels with m+ keystone levels (not used currently)
* Fixed item link validation when client sends it as default uninitialized bonus list with context only
* Support scaling items depending on current active season (seasons not implemented)
* Implemented content tuning redirection
Port From (https://github.com/TrinityCore/TrinityCore/commit/0fb8765a6638fd947b59fce44d5c31251d0cdadd)
2023-06-21 09:19:40 -04:00

158 lines
5.9 KiB
C#

// Copyright (c) CypherCore <http://github.com/CypherCore> All rights reserved.
// Licensed under the GNU GENERAL PUBLIC LICENSE. See LICENSE file in the project root for full license information.
using Framework.Constants;
using Framework.Database;
using Game.DataStorage;
using System.Collections.Generic;
namespace Game.Entities
{
public class ItemEnchantmentManager
{
public static void LoadItemRandomBonusListTemplates()
{
uint oldMSTime = Time.GetMSTime();
_storage.Clear();
// 0 1 2
SQLResult result = DB.World.Query("SELECT Id, BonusListID, Chance FROM item_random_bonus_list_template");
if (result.IsEmpty())
{
Log.outInfo(LogFilter.Player, "Loaded 0 Item Enchantment definitions. DB table `item_enchantment_template` is empty.");
return;
}
uint count = 0;
do
{
uint id = result.Read<uint>(0);
uint bonusListId = result.Read<uint>(1);
float chance = result.Read<float>(2);
if (ItemBonusMgr.GetItemBonuses(bonusListId).Empty())
{
Log.outError(LogFilter.Sql, $"Bonus list {bonusListId} used in `item_random_bonus_list_template` by id {id} doesn't have exist in ItemBonus.db2");
continue;
}
if (chance < 0.000001f || chance > 100.0f)
{
Log.outError(LogFilter.Sql, $"Bonus list {bonusListId} used in `item_random_bonus_list_template` by id {id} has invalid chance {chance}");
continue;
}
if (!_storage.ContainsKey(id))
_storage[id] = new RandomBonusListIds();
RandomBonusListIds ids = _storage[id];
ids.BonusListIDs.Add(bonusListId);
ids.Chances.Add(chance);
++count;
} while (result.NextRow());
Log.outInfo(LogFilter.Player, $"Loaded {count} Random item bonus list definitions in {Time.GetMSTimeDiffToNow(oldMSTime)} ms");
}
public static uint GenerateItemRandomBonusListId(uint item_id)
{
ItemTemplate itemProto = Global.ObjectMgr.GetItemTemplate(item_id);
if (itemProto == null)
return 0;
// item must have one from this field values not null if it can have random enchantments
if (itemProto.RandomBonusListTemplateId == 0)
return 0;
var tab = _storage.LookupByKey(itemProto.RandomBonusListTemplateId);
if (tab == null)
{
Log.outError(LogFilter.Sql, $"Item RandomBonusListTemplateId id {itemProto.RandomBonusListTemplateId} used in `item_template_addon` but it does not have records in `item_random_bonus_list_template` table.");
return 0;
}
//todo fix me this is ulgy
return tab.BonusListIDs.SelectRandomElementByWeight(x => (float)tab.Chances[tab.BonusListIDs.IndexOf(x)]);
}
public static float GetRandomPropertyPoints(uint itemLevel, ItemQuality quality, InventoryType inventoryType, uint subClass)
{
uint propIndex;
switch (inventoryType)
{
case InventoryType.Head:
case InventoryType.Body:
case InventoryType.Chest:
case InventoryType.Legs:
case InventoryType.Ranged:
case InventoryType.Weapon2Hand:
case InventoryType.Robe:
case InventoryType.Thrown:
propIndex = 0;
break;
case InventoryType.RangedRight:
if ((ItemSubClassWeapon)subClass == ItemSubClassWeapon.Wand)
propIndex = 3;
else
propIndex = 0;
break;
case InventoryType.Weapon:
case InventoryType.WeaponMainhand:
case InventoryType.WeaponOffhand:
propIndex = 3;
break;
case InventoryType.Shoulders:
case InventoryType.Waist:
case InventoryType.Feet:
case InventoryType.Hands:
case InventoryType.Trinket:
propIndex = 1;
break;
case InventoryType.Neck:
case InventoryType.Wrists:
case InventoryType.Finger:
case InventoryType.Shield:
case InventoryType.Cloak:
case InventoryType.Holdable:
propIndex = 2;
break;
case InventoryType.Relic:
propIndex = 4;
break;
default:
return 0;
}
RandPropPointsRecord randPropPointsEntry = CliDB.RandPropPointsStorage.LookupByKey(itemLevel);
if (randPropPointsEntry == null)
return 0;
switch (quality)
{
case ItemQuality.Uncommon:
return randPropPointsEntry.GoodF[propIndex];
case ItemQuality.Rare:
case ItemQuality.Heirloom:
return randPropPointsEntry.SuperiorF[propIndex];
case ItemQuality.Epic:
case ItemQuality.Legendary:
case ItemQuality.Artifact:
return randPropPointsEntry.EpicF[propIndex];
}
return 0;
}
static Dictionary<uint, RandomBonusListIds> _storage = new();
}
public class RandomBonusListIds
{
public List<uint> BonusListIDs = new();
public List<double> Chances = new();
}
}