/*
* This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see .
*/
#include "ItemEnchantmentMgr.h"
#include "Containers.h"
#include "DatabaseEnv.h"
#include "DB2Stores.h"
#include "ItemBonusMgr.h"
#include "ItemTemplate.h"
#include "Log.h"
#include "ObjectMgr.h"
#include "Timer.h"
#include
#include
namespace
{
struct RandomBonusListIds
{
std::vector BonusListIDs;
std::vector Chances;
};
std::unordered_map _storage;
}
void LoadItemRandomBonusListTemplates()
{
uint32 oldMSTime = getMSTime();
_storage.clear();
// 0 1 2
QueryResult result = WorldDatabase.Query("SELECT Id, BonusListID, Chance FROM item_random_bonus_list_template");
if (result)
{
uint32 count = 0;
do
{
Field* fields = result->Fetch();
uint32 id = fields[0].GetUInt32();
uint32 bonusListId = fields[1].GetUInt32();
float chance = fields[2].GetFloat();
if (ItemBonusMgr::GetItemBonuses(bonusListId).empty())
{
TC_LOG_ERROR("sql.sql", "Bonus list {} used in `item_random_bonus_list_template` by id {} doesn't have exist in ItemBonus.db2", bonusListId, id);
continue;
}
if (chance < 0.000001f || chance > 100.0f)
{
TC_LOG_ERROR("sql.sql", "Bonus list {} used in `item_random_bonus_list_template` by id {} has invalid chance {}", bonusListId, id, chance);
continue;
}
RandomBonusListIds& ids = _storage[id];
ids.BonusListIDs.push_back(bonusListId);
ids.Chances.push_back(chance);
++count;
} while (result->NextRow());
TC_LOG_INFO("server.loading", ">> Loaded {} Random item bonus list definitions in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
}
else
TC_LOG_INFO("server.loading", ">> Loaded 0 Random item bonus list definitions. DB table `item_random_bonus_list_template` is empty.");
}
ItemRandomBonusListId GenerateItemRandomBonusListId(uint32 item_id)
{
ItemTemplate const* itemProto = sObjectMgr->GetItemTemplate(item_id);
if (!itemProto)
return 0;
// item must have one from this field values not null if it can have random enchantments
if (!itemProto->RandomBonusListTemplateId)
return 0;
auto tab = _storage.find(itemProto->RandomBonusListTemplateId);
if (tab == _storage.end())
{
TC_LOG_ERROR("sql.sql", "Item RandomBonusListTemplateId id #{} used in `item_template_addon` but it does not have records in `item_random_bonus_list_template` table.", itemProto->RandomBonusListTemplateId);
return 0;
}
return *Trinity::Containers::SelectRandomWeightedContainerElement(tab->second.BonusListIDs, std::span(tab->second.Chances));
}
TC_GAME_API float GetRandomPropertyPoints(uint32 itemLevel, uint32 quality, uint32 inventoryType, uint32 subClass)
{
uint32 propIndex;
switch (inventoryType)
{
case INVTYPE_HEAD:
case INVTYPE_BODY:
case INVTYPE_CHEST:
case INVTYPE_LEGS:
case INVTYPE_RANGED:
case INVTYPE_2HWEAPON:
case INVTYPE_ROBE:
case INVTYPE_THROWN:
propIndex = 0;
break;
case INVTYPE_RANGEDRIGHT:
if (subClass == ITEM_SUBCLASS_WEAPON_WAND)
propIndex = 3;
else
propIndex = 0;
break;
case INVTYPE_WEAPON:
case INVTYPE_WEAPONMAINHAND:
case INVTYPE_WEAPONOFFHAND:
propIndex = 3;
break;
case INVTYPE_SHOULDERS:
case INVTYPE_WAIST:
case INVTYPE_FEET:
case INVTYPE_HANDS:
case INVTYPE_TRINKET:
propIndex = 1;
break;
case INVTYPE_NECK:
case INVTYPE_WRISTS:
case INVTYPE_FINGER:
case INVTYPE_SHIELD:
case INVTYPE_CLOAK:
case INVTYPE_HOLDABLE:
propIndex = 2;
break;
case INVTYPE_RELIC:
propIndex = 4;
break;
default:
return 0;
}
RandPropPointsEntry const* randPropPointsEntry = sRandPropPointsStore.LookupEntry(itemLevel);
if (!randPropPointsEntry)
return 0;
switch (quality)
{
case ITEM_QUALITY_UNCOMMON:
return randPropPointsEntry->GoodF[propIndex];
case ITEM_QUALITY_RARE:
case ITEM_QUALITY_HEIRLOOM:
return randPropPointsEntry->SuperiorF[propIndex];
case ITEM_QUALITY_EPIC:
case ITEM_QUALITY_LEGENDARY:
case ITEM_QUALITY_ARTIFACT:
return randPropPointsEntry->EpicF[propIndex];
}
return 0;
}