2010-10-07 15:35:36 +02:00
/*
2012-01-01 00:32:13 +01:00
* Copyright (C) 2008-2012 TrinityCore <http://www.trinitycore.org/>
2010-10-07 15:35:36 +02:00
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
* 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 <http://www.gnu.org/licenses/>.
2008-10-02 16:23:55 -05:00
*/
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
#include <stdlib.h>
#include <functional>
#include "ItemEnchantmentMgr.h"
2010-06-08 16:13:55 -06:00
#include "DatabaseEnv.h"
2008-10-02 16:23:55 -05:00
#include "Log.h"
#include "ObjectMgr.h"
#include <list>
#include <vector>
#include "Util.h"
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
struct EnchStoreItem
{
uint32 ench ;
float chance ;
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
EnchStoreItem ()
: ench ( 0 ), chance ( 0 ) {}
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
EnchStoreItem ( uint32 _ench , float _chance )
: ench ( _ench ), chance ( _chance ) {}
};
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
typedef std :: vector < EnchStoreItem > EnchStoreList ;
2008-11-10 06:53:00 -06:00
typedef UNORDERED_MAP < uint32 , EnchStoreList > EnchantmentStore ;
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
static EnchantmentStore RandomItemEnch ;
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
void LoadRandomEnchantmentsTable ()
{
2010-12-19 17:06:33 +01:00
uint32 oldMSTime = getMSTime ();
2008-10-02 16:23:55 -05:00
RandomItemEnch . clear (); // for reload case
2009-10-17 15:51:44 -07:00
2012-03-27 19:26:58 +01:00
// 0 1 2
2010-09-11 21:10:54 +02:00
QueryResult result = WorldDatabase . Query ( "SELECT entry, ench, chance FROM item_enchantment_template" );
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
if ( result )
{
2010-12-06 02:07:53 +01:00
uint32 count = 0 ;
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
do
{
2011-09-15 14:08:17 +02:00
Field * fields = result -> Fetch ();
2009-10-17 15:51:44 -07:00
2010-12-06 02:07:53 +01:00
uint32 entry = fields [ 0 ]. GetUInt32 ();
uint32 ench = fields [ 1 ]. GetUInt32 ();
float chance = fields [ 2 ]. GetFloat ();
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
if ( chance > 0.000001f && chance <= 100.0f )
2010-04-07 22:59:46 +02:00
RandomItemEnch [ entry ]. push_back ( EnchStoreItem ( ench , chance ));
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
++ count ;
} while ( result -> NextRow ());
2009-10-17 15:51:44 -07:00
2012-08-03 14:20:18 +02:00
sLog -> outInfo ( LOG_FILTER_PLAYER_ITEMS , ">> Loaded %u Item Enchantment definitions in %u ms" , count , GetMSTimeDiffToNow ( oldMSTime ));
2008-10-02 16:23:55 -05:00
}
else
{
2012-08-03 14:20:18 +02:00
sLog -> outError ( LOG_FILTER_SQL , ">> Loaded 0 Item Enchantment definitions. DB table `item_enchantment_template` is empty." );
2008-10-02 16:23:55 -05:00
}
}
2009-10-17 15:51:44 -07:00
2010-05-04 17:51:11 +02:00
uint32 GetItemEnchantMod ( int32 entry )
2008-10-02 16:23:55 -05:00
{
2010-05-04 17:51:11 +02:00
if ( ! entry )
return 0 ;
2009-10-17 15:51:44 -07:00
2010-05-04 17:51:11 +02:00
if ( entry == - 1 )
2010-06-27 19:46:25 +02:00
return 0 ;
2010-08-08 19:45:53 +02:00
EnchantmentStore :: const_iterator tab = RandomItemEnch . find ( entry );
2008-10-02 16:23:55 -05:00
if ( tab == RandomItemEnch . end ())
{
2012-08-03 14:20:18 +02:00
sLog -> outError ( LOG_FILTER_SQL , "Item RandomProperty / RandomSuffix id #%u used in `item_template` but it does not have records in `item_enchantment_template` table." , entry );
2008-10-02 16:23:55 -05:00
return 0 ;
}
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
double dRoll = rand_chance ();
float fCount = 0 ;
2009-10-17 15:51:44 -07:00
2009-10-17 16:20:24 -07:00
for ( EnchStoreList :: const_iterator ench_iter = tab -> second . begin (); ench_iter != tab -> second . end (); ++ ench_iter )
2008-10-02 16:23:55 -05:00
{
fCount += ench_iter -> chance ;
2009-10-17 15:51:44 -07:00
2012-03-28 20:00:29 +08:00
if ( fCount > dRoll )
return ench_iter -> ench ;
2008-10-02 16:23:55 -05:00
}
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
//we could get here only if sum of all enchantment chances is lower than 100%
2012-03-29 13:42:04 +08:00
dRoll = ( irand ( 0 , ( int ) floor ( fCount * 100 ) + 1 )) / 100 ;
2008-10-02 16:23:55 -05:00
fCount = 0 ;
2009-10-17 15:51:44 -07:00
2009-10-17 16:20:24 -07:00
for ( EnchStoreList :: const_iterator ench_iter = tab -> second . begin (); ench_iter != tab -> second . end (); ++ ench_iter )
2008-10-02 16:23:55 -05:00
{
fCount += ench_iter -> chance ;
2009-10-17 15:51:44 -07:00
2012-03-28 20:00:29 +08:00
if ( fCount > dRoll )
return ench_iter -> ench ;
2008-10-02 16:23:55 -05:00
}
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
return 0 ;
}
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
uint32 GenerateEnchSuffixFactor ( uint32 item_id )
{
2011-09-15 14:08:17 +02:00
ItemTemplate const * itemProto = sObjectMgr -> GetItemTemplate ( item_id );
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( ! itemProto )
2008-10-02 16:23:55 -05:00
return 0 ;
2010-04-07 19:14:10 +02:00
if ( ! itemProto -> RandomSuffix )
2008-10-02 16:23:55 -05:00
return 0 ;
2009-10-17 15:51:44 -07:00
2011-09-15 14:08:17 +02:00
RandomPropertiesPointsEntry const * randomProperty = sRandomPropertiesPointsStore . LookupEntry ( itemProto -> ItemLevel );
2010-04-07 19:14:10 +02:00
if ( ! randomProperty )
2008-10-02 16:23:55 -05:00
return 0 ;
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
uint32 suffixFactor ;
2011-09-29 12:43:05 +02:00
switch ( itemProto -> InventoryType )
2008-10-02 16:23:55 -05:00
{
// Items of that type don`t have points
case INVTYPE_NON_EQUIP :
case INVTYPE_BAG :
case INVTYPE_TABARD :
case INVTYPE_AMMO :
case INVTYPE_QUIVER :
case INVTYPE_RELIC :
return 0 ;
// Select point coefficient
case INVTYPE_HEAD :
case INVTYPE_BODY :
case INVTYPE_CHEST :
case INVTYPE_LEGS :
case INVTYPE_2HWEAPON :
case INVTYPE_ROBE :
suffixFactor = 0 ;
break ;
case INVTYPE_SHOULDERS :
case INVTYPE_WAIST :
case INVTYPE_FEET :
case INVTYPE_HANDS :
case INVTYPE_TRINKET :
suffixFactor = 1 ;
break ;
case INVTYPE_NECK :
case INVTYPE_WRISTS :
case INVTYPE_FINGER :
case INVTYPE_SHIELD :
case INVTYPE_CLOAK :
case INVTYPE_HOLDABLE :
suffixFactor = 2 ;
break ;
case INVTYPE_WEAPON :
case INVTYPE_WEAPONMAINHAND :
case INVTYPE_WEAPONOFFHAND :
suffixFactor = 3 ;
break ;
case INVTYPE_RANGED :
case INVTYPE_THROWN :
case INVTYPE_RANGEDRIGHT :
suffixFactor = 4 ;
break ;
default :
return 0 ;
}
// Select rare/epic modifier
switch ( itemProto -> Quality )
{
case ITEM_QUALITY_UNCOMMON :
return randomProperty -> UncommonPropertiesPoints [ suffixFactor ];
case ITEM_QUALITY_RARE :
return randomProperty -> RarePropertiesPoints [ suffixFactor ];
case ITEM_QUALITY_EPIC :
return randomProperty -> EpicPropertiesPoints [ suffixFactor ];
case ITEM_QUALITY_LEGENDARY :
case ITEM_QUALITY_ARTIFACT :
return 0 ; // not have random properties
default :
break ;
}
return 0 ;
}
2009-02-17 20:07:49 -06:00