Advertisement
Serverlands

Loud21's "Better Reload" Item/Creature

May 22nd, 2021
519
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 36.67 KB | None | 0 0
  1. /*
  2.  
  3. Created by Loud21
  4. Updated by Zeraax
  5. https://www.ac-web.org/forums/showthread.php?233198-Better-Item-Reload-(Includes-full-Item-and-Creature-Template-reloads)
  6.  
  7. */
  8.  
  9.  
  10. #include "Chat.h"
  11. #include "Player.h"
  12. #include "ObjectMgr.h"
  13. #include "DisableMgr.h"
  14. #include "DatabaseWorker.h"
  15. #include "DatabaseEnv.h"
  16. #include "Log.h"
  17. #include "ItemTemplate.h"
  18. #include "World.h"
  19. #include "Totem.h"
  20. #include "DBCStores.h"
  21. #include "SpellMgr.h"
  22. #include "RBAC.h"
  23. #include "WorldSession.h"
  24. #include "Bag.h"
  25.  
  26. // Sending cache data for reloaded items
  27. static const void SendCachePackets(Player* player, ItemTemplate* proto)
  28. {
  29.     if (!player || !proto)
  30.         return;
  31.  
  32.     std::string Name = proto->Name1;
  33.     std::string Description = proto->Description;
  34.  
  35.     LocaleConstant loc_idx = player->GetSession()->GetSessionDbLocaleIndex();
  36.  
  37.     if (loc_idx >= 0)
  38.     {
  39.         if (ItemLocale const* il = sObjectMgr->GetItemLocale(proto->ItemId))
  40.         {
  41.             ObjectMgr::GetLocaleString(il->Name, loc_idx, Name);
  42.             ObjectMgr::GetLocaleString(il->Description, loc_idx, Description);
  43.         }
  44.     }
  45.     WorldPacket data(SMSG_ITEM_QUERY_SINGLE_RESPONSE, 600);
  46.     data << proto->ItemId;
  47.     data << proto->Class;
  48.     data << proto->SubClass;
  49.     data << int32(proto->SoundOverrideSubclass);
  50.     data << Name;
  51.     data << uint8(0x00);
  52.     data << uint8(0x00);
  53.     data << uint8(0x00);
  54.     data << proto->DisplayInfoID;
  55.     data << proto->Quality;
  56.     data << proto->Flags;
  57.     data << proto->Flags2;
  58.     data << proto->BuyPrice;
  59.     data << proto->SellPrice;
  60.     data << proto->InventoryType;
  61.     data << proto->AllowableClass;
  62.     data << proto->AllowableRace;
  63.     data << proto->ItemLevel;
  64.     data << proto->RequiredLevel;
  65.     data << proto->RequiredSkill;
  66.     data << proto->RequiredSkillRank;
  67.     data << proto->RequiredSpell;
  68.     data << proto->RequiredHonorRank;
  69.     data << proto->RequiredCityRank;
  70.     data << proto->RequiredReputationFaction;
  71.     data << proto->RequiredReputationRank;
  72.     data << int32(proto->MaxCount);
  73.     data << int32(proto->Stackable);
  74.     data << proto->ContainerSlots;
  75.     data << proto->StatsCount;
  76.     for (uint32 i = 0; i < proto->StatsCount; ++i)
  77.     {
  78.         data << proto->ItemStat[i].ItemStatType;
  79.         data << proto->ItemStat[i].ItemStatValue;
  80.     }
  81.     data << proto->ScalingStatDistribution;
  82.     data << proto->ScalingStatValue;
  83.     for (int i = 0; i < MAX_ITEM_PROTO_DAMAGES; ++i)
  84.     {
  85.         data << proto->Damage[i].DamageMin;
  86.         data << proto->Damage[i].DamageMax;
  87.         data << proto->Damage[i].DamageType;
  88.     }
  89.     data << proto->Armor;
  90.     data << proto->HolyRes;
  91.     data << proto->FireRes;
  92.     data << proto->NatureRes;
  93.     data << proto->FrostRes;
  94.     data << proto->ShadowRes;
  95.     data << proto->ArcaneRes;
  96.     data << proto->Delay;
  97.     data << proto->AmmoType;
  98.     data << proto->RangedModRange;
  99.     for (int s = 0; s < MAX_ITEM_PROTO_SPELLS; ++s)
  100.     {
  101.         SpellInfo const* spell = sSpellMgr->GetSpellInfo(proto->Spells[s].SpellId);
  102.         if (spell)
  103.         {
  104.             bool db_data = proto->Spells[s].SpellCooldown >= 0 || proto->Spells[s].SpellCategoryCooldown >= 0;
  105.             data << proto->Spells[s].SpellId;
  106.             data << proto->Spells[s].SpellTrigger;
  107.             data << uint32(-abs(proto->Spells[s].SpellCharges));
  108.             if (db_data)
  109.             {
  110.                 data << uint32(proto->Spells[s].SpellCooldown);
  111.                 data << uint32(proto->Spells[s].SpellCategory);
  112.                 data << uint32(proto->Spells[s].SpellCategoryCooldown);
  113.             }
  114.             else
  115.             {
  116.                 data << uint32(spell->RecoveryTime);
  117.                 data << uint32(spell->GetCategory());
  118.                 data << uint32(spell->CategoryRecoveryTime);
  119.             }
  120.         }
  121.         else
  122.         {
  123.             data << uint32(0);
  124.             data << uint32(0);
  125.             data << uint32(0);
  126.             data << uint32(-1);
  127.             data << uint32(0);
  128.             data << uint32(-1);
  129.         }
  130.     }
  131.     data << proto->Bonding;
  132.     data << Description;
  133.     data << proto->PageText;
  134.     data << proto->LanguageID;
  135.     data << proto->PageMaterial;
  136.     data << proto->StartQuest;
  137.     data << proto->LockID;
  138.     data << int32(proto->Material);
  139.     data << proto->Sheath;
  140.     data << proto->RandomProperty;
  141.     data << proto->RandomSuffix;
  142.     data << proto->Block;
  143.     data << proto->ItemSet;
  144.     data << proto->MaxDurability;
  145.     data << proto->Area;
  146.     data << proto->Map;
  147.     data << proto->BagFamily;
  148.     data << proto->TotemCategory;
  149.     for (int s = 0; s < MAX_ITEM_PROTO_SOCKETS; ++s)
  150.     {
  151.         data << proto->Socket[s].Color;
  152.         data << proto->Socket[s].Content;
  153.     }
  154.     data << proto->socketBonus;
  155.     data << proto->GemProperties;
  156.     data << proto->RequiredDisenchantSkill;
  157.     data << proto->ArmorDamageModifier;
  158.     data << proto->Duration;
  159.     data << proto->ItemLimitCategory;
  160.     data << proto->HolidayId;
  161.  
  162.     player->GetSession()->SendPacket(&data);
  163.  
  164.     if (Item* item = player->GetItemByEntry(proto->ItemId))
  165.         player->_ApplyItemMods(item, item->GetSlot(), true);
  166. }
  167.  
  168. // Loading data from the database and inserting it into the ItemTemplate map
  169. void BetterLoadItem(Player* player, std::vector<uint32> itemID)
  170. {
  171.     if (!player)
  172.         return;
  173.  
  174.     std::stringstream ss;
  175.     for (uint32 i = 0; i < itemID.size(); i++)
  176.         ss << itemID[i] << ", ";
  177.     std::string str = ss.str();
  178.     str.erase(str.length()-2, 2);
  179.  
  180.     uint32 oldMSTime = getMSTime();
  181.  
  182.     //                                                 0      1       2               3              4        5        6       7          8         9        10        11           12
  183.     QueryResult result = WorldDatabase.PQuery("SELECT entry, class, subclass, SoundOverrideSubclass, name, displayid, Quality, Flags, FlagsExtra, BuyCount, BuyPrice, SellPrice, InventoryType, "
  184.         //                                              13              14           15          16             17               18                19              20
  185.         "AllowableClass, AllowableRace, ItemLevel, RequiredLevel, RequiredSkill, RequiredSkillRank, requiredspell, requiredhonorrank, "
  186.         //                                              21                      22                       23               24        25          26             27           28
  187.         "RequiredCityRank, RequiredReputationFaction, RequiredReputationRank, maxcount, stackable, ContainerSlots, StatsCount, stat_type1, "
  188.         //                                            29           30          31           32          33           34          35           36          37           38
  189.         "stat_value1, stat_type2, stat_value2, stat_type3, stat_value3, stat_type4, stat_value4, stat_type5, stat_value5, stat_type6, "
  190.         //                                            39           40          41           42           43          44           45           46           47
  191.         "stat_value6, stat_type7, stat_value7, stat_type8, stat_value8, stat_type9, stat_value9, stat_type10, stat_value10, "
  192.         //                                                   48                    49           50        51        52         53        54         55      56      57        58
  193.         "ScalingStatDistribution, ScalingStatValue, dmg_min1, dmg_max1, dmg_type1, dmg_min2, dmg_max2, dmg_type2, armor, holy_res, fire_res, "
  194.         //                                            59          60         61          62       63       64            65            66          67               68
  195.         "nature_res, frost_res, shadow_res, arcane_res, delay, ammo_type, RangedModRange, spellid_1, spelltrigger_1, spellcharges_1, "
  196.         //                                              69              70                71                 72                 73           74               75
  197.         "spellppmRate_1, spellcooldown_1, spellcategory_1, spellcategorycooldown_1, spellid_2, spelltrigger_2, spellcharges_2, "
  198.         //                                              76               77              78                  79                 80           81               82
  199.         "spellppmRate_2, spellcooldown_2, spellcategory_2, spellcategorycooldown_2, spellid_3, spelltrigger_3, spellcharges_3, "
  200.         //                                              83               84              85                  86                 87           88               89
  201.         "spellppmRate_3, spellcooldown_3, spellcategory_3, spellcategorycooldown_3, spellid_4, spelltrigger_4, spellcharges_4, "
  202.         //                                              90               91              92                  93                  94          95               96
  203.         "spellppmRate_4, spellcooldown_4, spellcategory_4, spellcategorycooldown_4, spellid_5, spelltrigger_5, spellcharges_5, "
  204.         //                                              97               98              99                  100                 101        102         103       104          105
  205.         "spellppmRate_5, spellcooldown_5, spellcategory_5, spellcategorycooldown_5, bonding, description, PageText, LanguageID, PageMaterial, "
  206.         //                                            106       107     108      109          110            111       112     113         114       115   116     117
  207.         "startquest, lockid, Material, sheath, RandomProperty, RandomSuffix, block, itemset, MaxDurability, area, Map, BagFamily, "
  208.         //                                            118             119             120             121             122            123              124            125
  209.         "TotemCategory, socketColor_1, socketContent_1, socketColor_2, socketContent_2, socketColor_3, socketContent_3, socketBonus, "
  210.         //                                            126                 127                     128            129            130            131         132         133
  211.         "GemProperties, RequiredDisenchantSkill, ArmorDamageModifier, duration, ItemLimitCategory, HolidayId, ScriptName, DisenchantID, "
  212.         //                                           134        135            136
  213.         "FoodType, minMoneyLoot, maxMoneyLoot, flagsCustom FROM item_template WHERE entry in (%s)", str);
  214.  
  215.     if (!result)
  216.     {
  217.         TC_LOG_INFO("server.loading", ">> Loaded 0 item templates. DB table `item_template` is empty.");
  218.         return;
  219.     }
  220.  
  221.     bool enforceDBCAttributes = sWorld->getBoolConfig(CONFIG_DBC_ENFORCE_ITEM_ATTRIBUTES);
  222.  
  223.     do
  224.     {
  225.         Field* fields = result->Fetch();
  226.  
  227.         uint32 entry = fields[0].GetUInt32();
  228.  
  229.         if (sObjectMgr->GetItemTemplateStore().find(entry) == sObjectMgr->GetItemTemplateStore().end())
  230.         {
  231.             ChatHandler(player->GetSession()).PSendSysMessage("Item not in Item Template store, please use the .reload item_template command first, or restart your server");
  232.             return;
  233.         }
  234.  
  235.         ItemTemplate* itemTemplate = const_cast<ItemTemplate*>(&sObjectMgr->GetItemTemplateStore().at(entry));
  236.  
  237.         itemTemplate->ItemId = entry;
  238.         itemTemplate->Class = uint32(fields[1].GetUInt8());
  239.         itemTemplate->SubClass = uint32(fields[2].GetUInt8());
  240.         itemTemplate->SoundOverrideSubclass = int32(fields[3].GetInt8());
  241.         itemTemplate->Name1 = fields[4].GetString();
  242.         itemTemplate->DisplayInfoID = fields[5].GetUInt32();
  243.         itemTemplate->Quality = uint32(fields[6].GetUInt8());
  244.         itemTemplate->Flags = fields[7].GetUInt32();
  245.         itemTemplate->Flags2 = fields[8].GetUInt32();
  246.         itemTemplate->BuyCount = uint32(fields[9].GetUInt8());
  247.         itemTemplate->BuyPrice = int32(fields[10].GetInt64());
  248.         itemTemplate->SellPrice = fields[11].GetUInt32();
  249.         itemTemplate->InventoryType = uint32(fields[12].GetUInt8());
  250.         itemTemplate->AllowableClass = fields[13].GetInt32();
  251.         itemTemplate->AllowableRace = fields[14].GetInt32();
  252.         itemTemplate->ItemLevel = uint32(fields[15].GetUInt16());
  253.         itemTemplate->RequiredLevel = uint32(fields[16].GetUInt8());
  254.         itemTemplate->RequiredSkill = uint32(fields[17].GetUInt16());
  255.         itemTemplate->RequiredSkillRank = uint32(fields[18].GetUInt16());
  256.         itemTemplate->RequiredSpell = fields[19].GetUInt32();
  257.         itemTemplate->RequiredHonorRank = fields[20].GetUInt32();
  258.         itemTemplate->RequiredCityRank = fields[21].GetUInt32();
  259.         itemTemplate->RequiredReputationFaction = uint32(fields[22].GetUInt16());
  260.         itemTemplate->RequiredReputationRank = uint32(fields[23].GetUInt16());
  261.         itemTemplate->MaxCount = fields[24].GetInt32();
  262.         itemTemplate->Stackable = fields[25].GetInt32();
  263.         itemTemplate->ContainerSlots = uint32(fields[26].GetUInt8());
  264.         itemTemplate->StatsCount = uint32(fields[27].GetUInt8());
  265.  
  266.         if (itemTemplate->StatsCount > MAX_ITEM_PROTO_STATS)
  267.         {
  268.             TC_LOG_ERROR("sql.sql", "Item (Entry: %u) has too large value in statscount (%u), replace by hardcoded limit (%u).", entry, itemTemplate->StatsCount, MAX_ITEM_PROTO_STATS);
  269.             itemTemplate->StatsCount = MAX_ITEM_PROTO_STATS;
  270.         }
  271.  
  272.         for (uint8 i = 0; i < itemTemplate->StatsCount; ++i)
  273.         {
  274.             itemTemplate->ItemStat[i].ItemStatType = uint32(fields[28 + i * 2].GetUInt8());
  275.             itemTemplate->ItemStat[i].ItemStatValue = int32(fields[29 + i * 2].GetInt32());
  276.         }
  277.  
  278.         itemTemplate->ScalingStatDistribution = uint32(fields[48].GetUInt16());
  279.         itemTemplate->ScalingStatValue = fields[49].GetInt32();
  280.  
  281.         for (uint8 i = 0; i < MAX_ITEM_PROTO_DAMAGES; ++i)
  282.         {
  283.             itemTemplate->Damage[i].DamageMin = fields[50 + i * 3].GetFloat();
  284.             itemTemplate->Damage[i].DamageMax = fields[51 + i * 3].GetFloat();
  285.             itemTemplate->Damage[i].DamageType = uint32(fields[52 + i * 3].GetUInt8());
  286.         }
  287.  
  288.         itemTemplate->Armor = uint32(fields[56].GetUInt16());
  289.         itemTemplate->HolyRes = uint32(fields[57].GetUInt8());
  290.         itemTemplate->FireRes = uint32(fields[58].GetUInt8());
  291.         itemTemplate->NatureRes = uint32(fields[59].GetUInt8());
  292.         itemTemplate->FrostRes = uint32(fields[60].GetUInt8());
  293.         itemTemplate->ShadowRes = uint32(fields[61].GetUInt8());
  294.         itemTemplate->ArcaneRes = uint32(fields[62].GetUInt8());
  295.         itemTemplate->Delay = uint32(fields[63].GetUInt16());
  296.         itemTemplate->AmmoType = uint32(fields[64].GetUInt8());
  297.         itemTemplate->RangedModRange = fields[65].GetFloat();
  298.  
  299.         for (uint8 i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i)
  300.         {
  301.             itemTemplate->Spells[i].SpellId = fields[66 + i * 7].GetInt32();
  302.             itemTemplate->Spells[i].SpellTrigger = uint32(fields[67 + i * 7].GetUInt8());
  303.             itemTemplate->Spells[i].SpellCharges = int32(fields[68 + i * 7].GetInt16());
  304.             itemTemplate->Spells[i].SpellPPMRate = fields[69 + i * 7].GetFloat();
  305.             itemTemplate->Spells[i].SpellCooldown = fields[70 + i * 7].GetInt32();
  306.             itemTemplate->Spells[i].SpellCategory = uint32(fields[71 + i * 7].GetUInt16());
  307.             itemTemplate->Spells[i].SpellCategoryCooldown = fields[72 + i * 7].GetInt32();
  308.         }
  309.  
  310.         itemTemplate->Bonding = uint32(fields[101].GetUInt8());
  311.         itemTemplate->Description = fields[102].GetString();
  312.         itemTemplate->PageText = fields[103].GetUInt32();
  313.         itemTemplate->LanguageID = uint32(fields[104].GetUInt8());
  314.         itemTemplate->PageMaterial = uint32(fields[105].GetUInt8());
  315.         itemTemplate->StartQuest = fields[106].GetUInt32();
  316.         itemTemplate->LockID = fields[107].GetUInt32();
  317.         itemTemplate->Material = int32(fields[108].GetInt8());
  318.         itemTemplate->Sheath = uint32(fields[109].GetUInt8());
  319.         itemTemplate->RandomProperty = fields[110].GetUInt32();
  320.         itemTemplate->RandomSuffix = fields[111].GetInt32();
  321.         itemTemplate->Block = fields[112].GetUInt32();
  322.         itemTemplate->ItemSet = fields[113].GetUInt32();
  323.         itemTemplate->MaxDurability = uint32(fields[114].GetUInt16());
  324.         itemTemplate->Area = fields[115].GetUInt32();
  325.         itemTemplate->Map = uint32(fields[116].GetUInt16());
  326.         itemTemplate->BagFamily = fields[117].GetUInt32();
  327.         itemTemplate->TotemCategory = fields[118].GetUInt32();
  328.  
  329.         for (uint8 i = 0; i < MAX_ITEM_PROTO_SOCKETS; ++i)
  330.         {
  331.             itemTemplate->Socket[i].Color = uint32(fields[119 + i * 2].GetUInt8());
  332.             itemTemplate->Socket[i].Content = fields[120 + i * 2].GetUInt32();
  333.         }
  334.  
  335.         itemTemplate->socketBonus = fields[125].GetUInt32();
  336.         itemTemplate->GemProperties = fields[126].GetUInt32();
  337.         itemTemplate->RequiredDisenchantSkill = uint32(fields[127].GetInt16());
  338.         itemTemplate->ArmorDamageModifier = fields[128].GetFloat();
  339.         itemTemplate->Duration = fields[129].GetUInt32();
  340.         itemTemplate->ItemLimitCategory = uint32(fields[130].GetInt16());
  341.         itemTemplate->HolidayId = fields[131].GetUInt32();
  342.         itemTemplate->ScriptId = sObjectMgr->GetScriptId(fields[132].GetString());
  343.         itemTemplate->DisenchantID = fields[133].GetUInt32();
  344.         itemTemplate->FoodType = uint32(fields[134].GetUInt8());
  345.         itemTemplate->MinMoneyLoot = fields[135].GetUInt32();
  346.         itemTemplate->MaxMoneyLoot = fields[136].GetUInt32();
  347.         itemTemplate->FlagsCu = fields[137].GetUInt32();
  348.  
  349.         // Checks
  350.  
  351.         ItemEntry const* dbcitem = sItemStore.LookupEntry(entry);
  352.  
  353.         if (dbcitem)
  354.         {
  355.  
  356.             if (itemTemplate->SoundOverrideSubclass != dbcitem->SoundOverrideSubclassID)
  357.             {
  358.                 TC_LOG_ERROR("sql.sql", "Item (Entry: %u) does not have a correct SoundOverrideSubclassID (%i), must be %i .", entry, itemTemplate->SoundOverrideSubclass, dbcitem->SoundOverrideSubclassID);
  359.                 if (enforceDBCAttributes)
  360.                     itemTemplate->SoundOverrideSubclass = dbcitem->SoundOverrideSubclassID;
  361.             }
  362.             if (itemTemplate->InventoryType != dbcitem->InventoryType)
  363.             {
  364.                 TC_LOG_ERROR("sql.sql", "Item (Entry: %u) does not have a correct inventory type (%u), must be %u .", entry, itemTemplate->InventoryType, dbcitem->InventoryType);
  365.                 if (enforceDBCAttributes)
  366.                     itemTemplate->InventoryType = dbcitem->InventoryType;
  367.             }
  368.  
  369.         }
  370.         else
  371.             TC_LOG_ERROR("sql.sql", "Item (Entry: %u) does not exist in item.dbc! (not correct id?).", entry);
  372.  
  373.         if (itemTemplate->Class >= MAX_ITEM_CLASS)
  374.         {
  375.             TC_LOG_ERROR("sql.sql", "Item (Entry: %u) has wrong Class value (%u)", entry, itemTemplate->Class);
  376.             itemTemplate->Class = ITEM_CLASS_MISC;
  377.         }
  378.  
  379.         if (itemTemplate->SubClass >= MaxItemSubclassValues[itemTemplate->Class])
  380.         {
  381.             TC_LOG_ERROR("sql.sql", "Item (Entry: %u) has wrong Subclass value (%u) for class %u", entry, itemTemplate->SubClass, itemTemplate->Class);
  382.             itemTemplate->SubClass = 0;// exist for all item classes
  383.         }
  384.  
  385.         if (itemTemplate->Quality >= MAX_ITEM_QUALITY)
  386.         {
  387.             TC_LOG_ERROR("sql.sql", "Item (Entry: %u) has wrong Quality value (%u)", entry, itemTemplate->Quality);
  388.             itemTemplate->Quality = ITEM_QUALITY_NORMAL;
  389.         }
  390.  
  391.         if (itemTemplate->Flags2 & ITEM_FLAG2_FACTION_HORDE)
  392.         {
  393.             if (FactionEntry const* faction = sFactionStore.LookupEntry(HORDE))
  394.                 if ((itemTemplate->AllowableRace & faction->ReputationBase[0]) == 0)
  395.                     TC_LOG_ERROR("sql.sql", "Item (Entry: %u) has value (%u) in `AllowableRace` races, not compatible with ITEM_FLAG2_FACTION_HORDE (%u) in Flags field, item cannot be equipped or used by these races.",
  396.                         entry, itemTemplate->AllowableRace, ITEM_FLAG2_FACTION_HORDE);
  397.  
  398.             if (itemTemplate->Flags2 & ITEM_FLAG2_FACTION_ALLIANCE)
  399.                 TC_LOG_ERROR("sql.sql", "Item (Entry: %u) has value (%u) in `Flags2` flags (ITEM_FLAG2_FACTION_ALLIANCE) and ITEM_FLAG2_FACTION_HORDE (%u) in Flags field, this is a wrong combination.",
  400.                     entry, ITEM_FLAG2_FACTION_ALLIANCE, ITEM_FLAG2_FACTION_HORDE);
  401.         }
  402.         else if (itemTemplate->Flags2 & ITEM_FLAG2_FACTION_ALLIANCE)
  403.         {
  404.             if (FactionEntry const* faction = sFactionStore.LookupEntry(ALLIANCE))
  405.                 if ((itemTemplate->AllowableRace & faction->ReputationBase[0]) == 0)
  406.                     TC_LOG_ERROR("sql.sql", "Item (Entry: %u) has value (%u) in `AllowableRace` races, not compatible with ITEM_FLAG2_FACTION_ALLIANCE (%u) in Flags field, item cannot be equipped or used by these races.",
  407.                         entry, itemTemplate->AllowableRace, ITEM_FLAG2_FACTION_ALLIANCE);
  408.         }
  409.  
  410.         if (itemTemplate->BuyCount <= 0)
  411.         {
  412.             TC_LOG_ERROR("sql.sql", "Item (Entry: %u) has wrong BuyCount value (%u), set to default(1).", entry, itemTemplate->BuyCount);
  413.             itemTemplate->BuyCount = 1;
  414.         }
  415.  
  416.         if (itemTemplate->InventoryType >= MAX_INVTYPE)
  417.         {
  418.             TC_LOG_ERROR("sql.sql", "Item (Entry: %u) has wrong InventoryType value (%u)", entry, itemTemplate->InventoryType);
  419.             itemTemplate->InventoryType = INVTYPE_NON_EQUIP;
  420.         }
  421.  
  422.         if (itemTemplate->RequiredSkill >= MAX_SKILL_TYPE)
  423.         {
  424.             TC_LOG_ERROR("sql.sql", "Item (Entry: %u) has wrong RequiredSkill value (%u)", entry, itemTemplate->RequiredSkill);
  425.             itemTemplate->RequiredSkill = 0;
  426.         }
  427.  
  428.         {
  429.             // can be used in equip slot, as page read use in inventory, or spell casting at use
  430.             bool req = itemTemplate->InventoryType != INVTYPE_NON_EQUIP || itemTemplate->PageText;
  431.             if (!req)
  432.                 for (uint8 j = 0; j < MAX_ITEM_PROTO_SPELLS; ++j)
  433.                 {
  434.                     if (itemTemplate->Spells[j].SpellId > 0)
  435.                     {
  436.                         req = true;
  437.                         break;
  438.                     }
  439.                 }
  440.  
  441.             if (req)
  442.             {
  443.                 if (!(itemTemplate->AllowableClass & CLASSMASK_ALL_PLAYABLE))
  444.                     TC_LOG_ERROR("sql.sql", "Item (Entry: %u) does not have any playable classes (%u) in `AllowableClass` and can't be equipped or used.", entry, itemTemplate->AllowableClass);
  445.  
  446.                 if (!(itemTemplate->AllowableRace & RACEMASK_ALL_PLAYABLE))
  447.                     TC_LOG_ERROR("sql.sql", "Item (Entry: %u) does not have any playable races (%u) in `AllowableRace` and can't be equipped or used.", entry, itemTemplate->AllowableRace);
  448.             }
  449.         }
  450.  
  451.         if (itemTemplate->RequiredSpell && !sSpellMgr->GetSpellInfo(itemTemplate->RequiredSpell))
  452.         {
  453.             TC_LOG_ERROR("sql.sql", "Item (Entry: %u) has a wrong (non-existing) spell in RequiredSpell (%u)", entry, itemTemplate->RequiredSpell);
  454.             itemTemplate->RequiredSpell = 0;
  455.         }
  456.  
  457.         if (itemTemplate->RequiredReputationRank >= MAX_REPUTATION_RANK)
  458.             TC_LOG_ERROR("sql.sql", "Item (Entry: %u) has wrong reputation rank in RequiredReputationRank (%u), item can't be used.", entry, itemTemplate->RequiredReputationRank);
  459.  
  460.         if (itemTemplate->RequiredReputationFaction)
  461.         {
  462.             if (!sFactionStore.LookupEntry(itemTemplate->RequiredReputationFaction))
  463.             {
  464.                 TC_LOG_ERROR("sql.sql", "Item (Entry: %u) has wrong (not existing) faction in RequiredReputationFaction (%u)", entry, itemTemplate->RequiredReputationFaction);
  465.                 itemTemplate->RequiredReputationFaction = 0;
  466.             }
  467.  
  468.             if (itemTemplate->RequiredReputationRank == MIN_REPUTATION_RANK)
  469.                 TC_LOG_ERROR("sql.sql", "Item (Entry: %u) has min. reputation rank in RequiredReputationRank (0) but RequiredReputationFaction > 0, faction setting is useless.", entry);
  470.         }
  471.  
  472.         if (itemTemplate->MaxCount < -1)
  473.         {
  474.             TC_LOG_ERROR("sql.sql", "Item (Entry: %u) has too large negative in maxcount (%i), replace by value (-1) no storing limits.", entry, itemTemplate->MaxCount);
  475.             itemTemplate->MaxCount = -1;
  476.         }
  477.  
  478.         if (itemTemplate->Stackable == 0)
  479.         {
  480.             TC_LOG_ERROR("sql.sql", "Item (Entry: %u) has wrong value in stackable (%i), replace by default 1.", entry, itemTemplate->Stackable);
  481.             itemTemplate->Stackable = 1;
  482.         }
  483.         else if (itemTemplate->Stackable < -1)
  484.         {
  485.             TC_LOG_ERROR("sql.sql", "Item (Entry: %u) has too large negative in stackable (%i), replace by value (-1) no stacking limits.", entry, itemTemplate->Stackable);
  486.             itemTemplate->Stackable = -1;
  487.         }
  488.  
  489.         if (itemTemplate->ContainerSlots > MAX_BAG_SIZE)
  490.         {
  491.             TC_LOG_ERROR("sql.sql", "Item (Entry: %u) has too large value in ContainerSlots (%u), replace by hardcoded limit (%u).", entry, itemTemplate->ContainerSlots, MAX_BAG_SIZE);
  492.             itemTemplate->ContainerSlots = MAX_BAG_SIZE;
  493.         }
  494.  
  495.         for (uint8 j = 0; j < itemTemplate->StatsCount; ++j)
  496.         {
  497.             // for ItemStatValue != 0
  498.             if (itemTemplate->ItemStat[j].ItemStatValue && itemTemplate->ItemStat[j].ItemStatType >= MAX_ITEM_MOD)
  499.             {
  500.                 TC_LOG_ERROR("sql.sql", "Item (Entry: %u) has wrong (non-existing?) stat_type%d (%u)", entry, j + 1, itemTemplate->ItemStat[j].ItemStatType);
  501.                 itemTemplate->ItemStat[j].ItemStatType = 0;
  502.             }
  503.  
  504.             switch (itemTemplate->ItemStat[j].ItemStatType)
  505.             {
  506.             case ITEM_MOD_SPELL_HEALING_DONE:
  507.             case ITEM_MOD_SPELL_DAMAGE_DONE:
  508.                 TC_LOG_ERROR("sql.sql", "Item (Entry: %u) has deprecated stat_type%d (%u)", entry, j + 1, itemTemplate->ItemStat[j].ItemStatType);
  509.                 break;
  510.             default:
  511.                 break;
  512.             }
  513.         }
  514.  
  515.         for (uint8 j = 0; j < MAX_ITEM_PROTO_DAMAGES; ++j)
  516.         {
  517.             if (itemTemplate->Damage[j].DamageType >= MAX_SPELL_SCHOOL)
  518.             {
  519.                 TC_LOG_ERROR("sql.sql", "Item (Entry: %u) has wrong dmg_type%d (%u)", entry, j + 1, itemTemplate->Damage[j].DamageType);
  520.                 itemTemplate->Damage[j].DamageType = 0;
  521.             }
  522.         }
  523.  
  524.         // special format
  525.         if ((itemTemplate->Spells[0].SpellId == 483) || (itemTemplate->Spells[0].SpellId == 55884))
  526.         {
  527.             // spell_1
  528.             if (itemTemplate->Spells[0].SpellTrigger != ITEM_SPELLTRIGGER_ON_USE)
  529.             {
  530.                 TC_LOG_ERROR("sql.sql", "Item (Entry: %u) has wrong item spell trigger value in spelltrigger_%d (%u) for special learning format", entry, 0 + 1, itemTemplate->Spells[0].SpellTrigger);
  531.                 itemTemplate->Spells[0].SpellId = 0;
  532.                 itemTemplate->Spells[0].SpellTrigger = ITEM_SPELLTRIGGER_ON_USE;
  533.                 itemTemplate->Spells[1].SpellId = 0;
  534.                 itemTemplate->Spells[1].SpellTrigger = ITEM_SPELLTRIGGER_ON_USE;
  535.             }
  536.  
  537.             // spell_2 have learning spell
  538.             if (itemTemplate->Spells[1].SpellTrigger != ITEM_SPELLTRIGGER_LEARN_SPELL_ID)
  539.             {
  540.                 TC_LOG_ERROR("sql.sql", "Item (Entry: %u) has wrong item spell trigger value in spelltrigger_%d (%u) for special learning format.", entry, 1 + 1, itemTemplate->Spells[1].SpellTrigger);
  541.                 itemTemplate->Spells[0].SpellId = 0;
  542.                 itemTemplate->Spells[1].SpellId = 0;
  543.                 itemTemplate->Spells[1].SpellTrigger = ITEM_SPELLTRIGGER_ON_USE;
  544.             }
  545.             else if (!itemTemplate->Spells[1].SpellId)
  546.             {
  547.                 TC_LOG_ERROR("sql.sql", "Item (Entry: %u) does not have an expected spell in spellid_%d in special learning format.", entry, 1 + 1);
  548.                 itemTemplate->Spells[0].SpellId = 0;
  549.                 itemTemplate->Spells[1].SpellTrigger = ITEM_SPELLTRIGGER_ON_USE;
  550.             }
  551.             else if (itemTemplate->Spells[1].SpellId != -1)
  552.             {
  553.                 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(itemTemplate->Spells[1].SpellId);
  554.                 if (!spellInfo && !DisableMgr::IsDisabledFor(DISABLE_TYPE_SPELL, itemTemplate->Spells[1].SpellId, nullptr))
  555.                 {
  556.                     TC_LOG_ERROR("sql.sql", "Item (Entry: %u) has wrong (not existing) spell in spellid_%d (%d)", entry, 1 + 1, itemTemplate->Spells[1].SpellId);
  557.                     itemTemplate->Spells[0].SpellId = 0;
  558.                     itemTemplate->Spells[1].SpellId = 0;
  559.                     itemTemplate->Spells[1].SpellTrigger = ITEM_SPELLTRIGGER_ON_USE;
  560.                 }
  561.                 // allowed only in special format
  562.                 else if ((itemTemplate->Spells[1].SpellId == 483) || (itemTemplate->Spells[1].SpellId == 55884))
  563.                 {
  564.                     TC_LOG_ERROR("sql.sql", "Item (Entry: %u) has broken spell in spellid_%d (%d)", entry, 1 + 1, itemTemplate->Spells[1].SpellId);
  565.                     itemTemplate->Spells[0].SpellId = 0;
  566.                     itemTemplate->Spells[1].SpellId = 0;
  567.                     itemTemplate->Spells[1].SpellTrigger = ITEM_SPELLTRIGGER_ON_USE;
  568.                 }
  569.             }
  570.  
  571.             // spell_3*, spell_4*, spell_5* is empty
  572.             for (uint8 j = 2; j < MAX_ITEM_PROTO_SPELLS; ++j)
  573.             {
  574.                 if (itemTemplate->Spells[j].SpellTrigger != ITEM_SPELLTRIGGER_ON_USE)
  575.                 {
  576.                     TC_LOG_ERROR("sql.sql", "Item (Entry: %u) has wrong item spell trigger value in spelltrigger_%d (%u)", entry, j + 1, itemTemplate->Spells[j].SpellTrigger);
  577.                     itemTemplate->Spells[j].SpellId = 0;
  578.                     itemTemplate->Spells[j].SpellTrigger = ITEM_SPELLTRIGGER_ON_USE;
  579.                 }
  580.                 else if (itemTemplate->Spells[j].SpellId != 0)
  581.                 {
  582.                     TC_LOG_ERROR("sql.sql", "Item (Entry: %u) has wrong spell in spellid_%d (%d) for learning special format", entry, j + 1, itemTemplate->Spells[j].SpellId);
  583.                     itemTemplate->Spells[j].SpellId = 0;
  584.                 }
  585.             }
  586.         }
  587.         // normal spell list
  588.         else
  589.         {
  590.             for (uint8 j = 0; j < MAX_ITEM_PROTO_SPELLS; ++j)
  591.             {
  592.                 if (itemTemplate->Spells[j].SpellTrigger >= MAX_ITEM_SPELLTRIGGER || itemTemplate->Spells[j].SpellTrigger == ITEM_SPELLTRIGGER_LEARN_SPELL_ID)
  593.                 {
  594.                     TC_LOG_ERROR("sql.sql", "Item (Entry: %u) has wrong item spell trigger value in spelltrigger_%d (%u)", entry, j + 1, itemTemplate->Spells[j].SpellTrigger);
  595.                     itemTemplate->Spells[j].SpellId = 0;
  596.                     itemTemplate->Spells[j].SpellTrigger = ITEM_SPELLTRIGGER_ON_USE;
  597.                 }
  598.  
  599.                 if (itemTemplate->Spells[j].SpellId && itemTemplate->Spells[j].SpellId != -1)
  600.                 {
  601.                     SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(itemTemplate->Spells[j].SpellId);
  602.                     if (!spellInfo && !DisableMgr::IsDisabledFor(DISABLE_TYPE_SPELL, itemTemplate->Spells[j].SpellId, nullptr))
  603.                     {
  604.                         TC_LOG_ERROR("sql.sql", "Item (Entry: %u) has wrong (not existing) spell in spellid_%d (%d)", entry, j + 1, itemTemplate->Spells[j].SpellId);
  605.                         itemTemplate->Spells[j].SpellId = 0;
  606.                     }
  607.                     // allowed only in special format
  608.                     else if ((itemTemplate->Spells[j].SpellId == 483) || (itemTemplate->Spells[j].SpellId == 55884))
  609.                     {
  610.                         TC_LOG_ERROR("sql.sql", "Item (Entry: %u) has broken spell in spellid_%d (%d)", entry, j + 1, itemTemplate->Spells[j].SpellId);
  611.                         itemTemplate->Spells[j].SpellId = 0;
  612.                     }
  613.                 }
  614.             }
  615.         }
  616.  
  617.         if (itemTemplate->Bonding >= MAX_BIND_TYPE)
  618.             TC_LOG_ERROR("sql.sql", "Item (Entry: %u) has wrong Bonding value (%u)", entry, itemTemplate->Bonding);
  619.  
  620.         if (itemTemplate->PageText && !sObjectMgr->GetPageText(itemTemplate->PageText))
  621.             TC_LOG_ERROR("sql.sql", "Item (Entry: %u) has non existing first page (Id:%u)", entry, itemTemplate->PageText);
  622.  
  623.         if (itemTemplate->LockID && !sLockStore.LookupEntry(itemTemplate->LockID))
  624.             TC_LOG_ERROR("sql.sql", "Item (Entry: %u) has wrong LockID (%u)", entry, itemTemplate->LockID);
  625.  
  626.         if (itemTemplate->Sheath >= MAX_SHEATHETYPE)
  627.         {
  628.             TC_LOG_ERROR("sql.sql", "Item (Entry: %u) has wrong Sheath (%u)", entry, itemTemplate->Sheath);
  629.             itemTemplate->Sheath = SHEATHETYPE_NONE;
  630.         }
  631.  
  632.         if (itemTemplate->RandomProperty)
  633.         {
  634.             // To be implemented later
  635.             if (itemTemplate->RandomProperty == -1)
  636.                 itemTemplate->RandomProperty = 0;
  637.  
  638.             else if (!sItemRandomPropertiesStore.LookupEntry(GetItemEnchantMod(itemTemplate->RandomProperty)))
  639.             {
  640.                 TC_LOG_ERROR("sql.sql", "Item (Entry: %u) has unknown (wrong or not listed in `item_enchantment_template`) RandomProperty (%u)", entry, itemTemplate->RandomProperty);
  641.                 itemTemplate->RandomProperty = 0;
  642.             }
  643.         }
  644.  
  645.         if (itemTemplate->RandomSuffix && !sItemRandomSuffixStore.LookupEntry(GetItemEnchantMod(itemTemplate->RandomSuffix)))
  646.         {
  647.             TC_LOG_ERROR("sql.sql", "Item (Entry: %u) has wrong RandomSuffix (%u)", entry, itemTemplate->RandomSuffix);
  648.             itemTemplate->RandomSuffix = 0;
  649.         }
  650.  
  651.         if (itemTemplate->ItemSet && !sItemSetStore.LookupEntry(itemTemplate->ItemSet))
  652.         {
  653.             TC_LOG_ERROR("sql.sql", "Item (Entry: %u) have wrong ItemSet (%u)", entry, itemTemplate->ItemSet);
  654.             itemTemplate->ItemSet = 0;
  655.         }
  656.  
  657.         if (itemTemplate->Area && !sAreaTableStore.LookupEntry(itemTemplate->Area))
  658.             TC_LOG_ERROR("sql.sql", "Item (Entry: %u) has wrong Area (%u)", entry, itemTemplate->Area);
  659.  
  660.         if (itemTemplate->Map && !sMapStore.LookupEntry(itemTemplate->Map))
  661.             TC_LOG_ERROR("sql.sql", "Item (Entry: %u) has wrong Map (%u)", entry, itemTemplate->Map);
  662.  
  663.         if (itemTemplate->BagFamily)
  664.         {
  665.             // check bits
  666.             for (uint32 j = 0; j < sizeof(itemTemplate->BagFamily) * 8; ++j)
  667.             {
  668.                 uint32 mask = 1 << j;
  669.                 if ((itemTemplate->BagFamily & mask) == 0)
  670.                     continue;
  671.  
  672.                 ItemBagFamilyEntry const* bf = sItemBagFamilyStore.LookupEntry(j + 1);
  673.                 if (!bf)
  674.                 {
  675.                     TC_LOG_ERROR("sql.sql", "Item (Entry: %u) has bag family bit set not listed in ItemBagFamily.dbc, remove bit", entry);
  676.                     itemTemplate->BagFamily &= ~mask;
  677.                     continue;
  678.                 }
  679.  
  680.                 if (BAG_FAMILY_MASK_CURRENCY_TOKENS & mask)
  681.                 {
  682.                     CurrencyTypesEntry const* ctEntry = sCurrencyTypesStore.LookupEntry(itemTemplate->ItemId);
  683.                     if (!ctEntry)
  684.                     {
  685.                         TC_LOG_ERROR("sql.sql", "Item (Entry: %u) has currency bag family bit set in BagFamily but not listed in CurrencyTypes.dbc, remove bit", entry);
  686.                         itemTemplate->BagFamily &= ~mask;
  687.                     }
  688.                 }
  689.             }
  690.         }
  691.  
  692.         if (itemTemplate->TotemCategory && !sTotemCategoryStore.LookupEntry(itemTemplate->TotemCategory))
  693.             TC_LOG_ERROR("sql.sql", "Item (Entry: %u) has wrong TotemCategory (%u)", entry, itemTemplate->TotemCategory);
  694.  
  695.         for (uint8 j = 0; j < MAX_ITEM_PROTO_SOCKETS; ++j)
  696.         {
  697.             if (itemTemplate->Socket[j].Color && (itemTemplate->Socket[j].Color & SOCKET_COLOR_ALL) != itemTemplate->Socket[j].Color)
  698.             {
  699.                 TC_LOG_ERROR("sql.sql", "Item (Entry: %u) has wrong socketColor_%d (%u)", entry, j + 1, itemTemplate->Socket[j].Color);
  700.                 itemTemplate->Socket[j].Color = 0;
  701.             }
  702.         }
  703.  
  704.         if (itemTemplate->GemProperties && !sGemPropertiesStore.LookupEntry(itemTemplate->GemProperties))
  705.             TC_LOG_ERROR("sql.sql", "Item (Entry: %u) has wrong GemProperties (%u)", entry, itemTemplate->GemProperties);
  706.  
  707.         if (itemTemplate->FoodType >= MAX_PET_DIET)
  708.         {
  709.             TC_LOG_ERROR("sql.sql", "Item (Entry: %u) has wrong FoodType value (%u)", entry, itemTemplate->FoodType);
  710.             itemTemplate->FoodType = 0;
  711.         }
  712.  
  713.         if (itemTemplate->ItemLimitCategory && !sItemLimitCategoryStore.LookupEntry(itemTemplate->ItemLimitCategory))
  714.         {
  715.             TC_LOG_ERROR("sql.sql", "Item (Entry: %u) has wrong LimitCategory value (%u)", entry, itemTemplate->ItemLimitCategory);
  716.             itemTemplate->ItemLimitCategory = 0;
  717.         }
  718.  
  719.         if (itemTemplate->HolidayId && !sHolidaysStore.LookupEntry(itemTemplate->HolidayId))
  720.         {
  721.             TC_LOG_ERROR("sql.sql", "Item (Entry: %u) has wrong HolidayId value (%u)", entry, itemTemplate->HolidayId);
  722.             itemTemplate->HolidayId = 0;
  723.         }
  724.  
  725.         if (itemTemplate->FlagsCu & ITEM_FLAGS_CU_DURATION_REAL_TIME && !itemTemplate->Duration)
  726.         {
  727.             TC_LOG_ERROR("sql.sql", "Item (Entry %u) has flag ITEM_FLAGS_CU_DURATION_REAL_TIME but it does not have duration limit", entry);
  728.             itemTemplate->FlagsCu &= ~ITEM_FLAGS_CU_DURATION_REAL_TIME;
  729.         }
  730.  
  731.         SendCachePackets(player, itemTemplate);
  732.  
  733.     } while (result->NextRow());
  734.  
  735.     // Check if item templates for DBC referenced character start outfit are present
  736.     std::set<uint32> notFoundOutfit;
  737.     for (uint32 i = 1; i < sCharStartOutfitStore.GetNumRows(); ++i)
  738.     {
  739.         CharStartOutfitEntry const* entry = sCharStartOutfitStore.LookupEntry(i);
  740.         if (!entry)
  741.             continue;
  742.  
  743.         for (uint8 j = 0; j < MAX_OUTFIT_ITEMS; ++j)
  744.         {
  745.             if (entry->ItemID[j] <= 0)
  746.                 continue;
  747.  
  748.             uint32 item_id = entry->ItemID[j];
  749.  
  750.             if (!sObjectMgr->GetItemTemplate(item_id))
  751.                 notFoundOutfit.insert(item_id);
  752.         }
  753.     }
  754.     for (std::set<uint32>::const_iterator itr = notFoundOutfit.begin(); itr != notFoundOutfit.end(); ++itr)
  755.         TC_LOG_ERROR("sql.sql", "Item (Entry: %u) does not exist in `item_template` but is referenced in `CharStartOutfit.dbc`", *itr);
  756. }
  757.  
  758.  
  759. // Comand stuff
  760. class custom_reload_commands : public CommandScript
  761. {
  762. public:
  763.     custom_reload_commands() : CommandScript("custom_reload_commands") { }
  764.  
  765.     std::vector<ChatCommand> GetCommands() const
  766.     {
  767.         static std::vector<ChatCommand> customCommandTable =
  768.         {
  769.             { "reload_better_reload",          rbac::RBAC_PERM_COMMAND_RELOAD, true, &HandleBetterItemReload,   "" },
  770.         { "reload_item_template",          rbac::RBAC_PERM_COMMAND_RELOAD, true, &HandleReloadItemTemplate, "" },
  771.         { "reload_full_creature_template", rbac::RBAC_PERM_COMMAND_RELOAD, true, &HandleReloadFullCreatureTemplate, "" },
  772.         };
  773.         return customCommandTable;
  774.     }
  775.  
  776.     static bool HandleReloadItemTemplate(ChatHandler * handler, const char * args)
  777.     {
  778.         bool itemTemplateReloadEnabled = true;
  779.         if (itemTemplateReloadEnabled)
  780.         {
  781.             TC_LOG_INFO("misc", "Reloading item_template...");
  782.             sObjectMgr->LoadItemTemplates();
  783.             //No need to add checks here because InitializeQueriesData checks if the config setting is enabled or disabled
  784.             sObjectMgr->InitializeQueriesData(QUERY_DATA_ITEMS);
  785.             handler->SendGlobalGMSysMessage("Item Template has been reloaded");
  786.         }
  787.         else
  788.             handler->SendGlobalGMSysMessage("The item_template reload command is currently disabled.");
  789.         return true;
  790.     }
  791.  
  792.     static bool HandleReloadFullCreatureTemplate(ChatHandler * handler, const char * args)
  793.     {
  794.         bool creatureTemplateReloadEnabled = true;
  795.         if (creatureTemplateReloadEnabled)
  796.         {
  797.             TC_LOG_INFO("misc", "Reloading Creature Template...");
  798.             sObjectMgr->LoadCreatureTemplates();
  799.             //No need to add checks here because InitializeQueriesData checks if the config setting is enabled or disabled
  800.             sObjectMgr->InitializeQueriesData(QUERY_DATA_CREATURES);
  801.             handler->SendGlobalGMSysMessage("Creature Template has been reloaded");
  802.         }
  803.         else
  804.             handler->SendGlobalGMSysMessage("The creature_template reload command is currently disabled");
  805.  
  806.         return true;
  807.     }
  808.  
  809.     static bool HandleBetterItemReload(ChatHandler * handler, const char * args)
  810.     {
  811.         if (!*args)
  812.             return false;
  813.  
  814.         std::vector<uint32> ids;
  815.         Player* player = handler->GetSession()->GetPlayer();
  816.  
  817.         /*
  818.         *
  819.         OLD DATA - Ignore
  820.         Tokenizer entries(std::string(args), ' ');
  821.         for (Tokenizer::const_iterator it = entries.begin(); it != entries.end(); ++it)
  822.         {
  823.             uint32 itemID = uint32(atoi(*it));
  824.  
  825.             if (player)
  826.                 if (Item* item = player->GetItemByEntry(itemID))
  827.                     player->_ApplyItemMods(item, item->GetSlot(), false);
  828.  
  829.             ids.push_back(itemID);
  830.         }
  831.         */
  832.  
  833.         char* itemID = strtok((char*)args, " ");
  834.         if (!itemID)
  835.             return false;
  836.  
  837.         if (!sObjectMgr->GetItemTemplate(atoi(itemID))) //if an item is not found in the database
  838.         {
  839.             handler->PSendSysMessage("[|cffFF0000Item Reloader|r]: item ID %u was not found in the database", atoi(itemID));
  840.             return true;
  841.         }
  842.  
  843.         Item* item = player->GetItemByEntry(atoi(itemID));
  844.         player->_ApplyItemMods(item, item->GetSlot(), false);
  845.  
  846.         ids.push_back(atoi(itemID));
  847.  
  848.  
  849.         BetterLoadItem(player, ids);
  850.         handler->SendGlobalGMSysMessage("[|cffFF0000Item Reloader|r]: better reloading system used");
  851.  
  852.         return true;
  853.     }
  854. };
  855.  
  856.  
  857. void AddSC_custom_reload_commands()
  858. {
  859.     new custom_reload_commands();
  860. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement