mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-01-22 13:16:23 +00:00
Improved OnItemRoll hook
Now you can change the chance temporary and dinamically
This commit is contained in:
@@ -84,7 +84,7 @@ class LootTemplate::LootGroup // A set of loot def
|
|||||||
bool HasQuestDrop() const; // True if group includes at least 1 quest drop entry
|
bool HasQuestDrop() const; // True if group includes at least 1 quest drop entry
|
||||||
bool HasQuestDropForPlayer(Player const* player) const;
|
bool HasQuestDropForPlayer(Player const* player) const;
|
||||||
// The same for active quests of the player
|
// The same for active quests of the player
|
||||||
void Process(Loot& loot, uint16 lootMode) const; // Rolls an item from the group (if any) and adds the item to the loot
|
void Process(Loot& loot, Player const *player, LootStore const& lootstore, uint16 lootMode) const; // Rolls an item from the group (if any) and adds the item to the loot
|
||||||
float RawTotalChance() const; // Overall chance for the group (without equal chanced items)
|
float RawTotalChance() const; // Overall chance for the group (without equal chanced items)
|
||||||
float TotalChance() const; // Overall chance for the group
|
float TotalChance() const; // Overall chance for the group
|
||||||
|
|
||||||
@@ -98,7 +98,7 @@ class LootTemplate::LootGroup // A set of loot def
|
|||||||
LootStoreItemList ExplicitlyChanced; // Entries with chances defined in DB
|
LootStoreItemList ExplicitlyChanced; // Entries with chances defined in DB
|
||||||
LootStoreItemList EqualChanced; // Zero chances - every entry takes the same chance
|
LootStoreItemList EqualChanced; // Zero chances - every entry takes the same chance
|
||||||
|
|
||||||
LootStoreItem const* Roll(Loot& loot, uint16 lootMode) const; // Rolls an item from the group, returns NULL if all miss their chances
|
LootStoreItem const* Roll(Loot& loot, Player const *player, LootStore const& store, uint16 lootMode) const; // Rolls an item from the group, returns NULL if all miss their chances
|
||||||
|
|
||||||
// This class must never be copied - storing pointers
|
// This class must never be copied - storing pointers
|
||||||
LootGroup(LootGroup const&);
|
LootGroup(LootGroup const&);
|
||||||
@@ -279,19 +279,23 @@ void LootStore::ReportNotExistedId(uint32 id) const
|
|||||||
|
|
||||||
// Checks if the entry (quest, non-quest, reference) takes it's chance (at loot generation)
|
// Checks if the entry (quest, non-quest, reference) takes it's chance (at loot generation)
|
||||||
// RATE_DROP_ITEMS is no longer used for all types of entries
|
// RATE_DROP_ITEMS is no longer used for all types of entries
|
||||||
bool LootStoreItem::Roll(bool rate) const
|
bool LootStoreItem::Roll(bool rate, Player const *player, Loot& loot, LootStore const& store) const
|
||||||
{
|
{
|
||||||
if (chance >= 100.0f)
|
float _chance = chance;
|
||||||
|
|
||||||
|
sScriptMgr->OnItemRoll(player, this, _chance, loot, store);
|
||||||
|
|
||||||
|
if (_chance >= 100.0f)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (mincountOrRef < 0) // reference case
|
if (mincountOrRef < 0) // reference case
|
||||||
return roll_chance_f(chance* (rate ? sWorld->getRate(RATE_DROP_ITEM_REFERENCED) : 1.0f));
|
return roll_chance_f(_chance* (rate ? sWorld->getRate(RATE_DROP_ITEM_REFERENCED) : 1.0f));
|
||||||
|
|
||||||
ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(itemid);
|
ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(itemid);
|
||||||
|
|
||||||
float qualityModifier = pProto && rate ? sWorld->getRate(qualityToRate[pProto->Quality]) : 1.0f;
|
float qualityModifier = pProto && rate ? sWorld->getRate(qualityToRate[pProto->Quality]) : 1.0f;
|
||||||
|
|
||||||
return roll_chance_f(chance*qualityModifier);
|
return roll_chance_f(_chance*qualityModifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Checks correctness of values
|
// Checks correctness of values
|
||||||
@@ -1102,7 +1106,7 @@ void LootTemplate::LootGroup::AddEntry(LootStoreItem* item)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Rolls an item from the group, returns NULL if all miss their chances
|
// Rolls an item from the group, returns NULL if all miss their chances
|
||||||
LootStoreItem const* LootTemplate::LootGroup::Roll(Loot& loot, uint16 lootMode) const
|
LootStoreItem const* LootTemplate::LootGroup::Roll(Loot& loot, Player const *player, LootStore const& store, uint16 lootMode) const
|
||||||
{
|
{
|
||||||
LootStoreItemList possibleLoot = ExplicitlyChanced;
|
LootStoreItemList possibleLoot = ExplicitlyChanced;
|
||||||
possibleLoot.remove_if(LootGroupInvalidSelector(loot, lootMode));
|
possibleLoot.remove_if(LootGroupInvalidSelector(loot, lootMode));
|
||||||
@@ -1114,10 +1118,14 @@ LootStoreItem const* LootTemplate::LootGroup::Roll(Loot& loot, uint16 lootMode)
|
|||||||
for (LootStoreItemList::const_iterator itr = possibleLoot.begin(); itr != possibleLoot.end(); ++itr) // check each explicitly chanced entry in the template and modify its chance based on quality.
|
for (LootStoreItemList::const_iterator itr = possibleLoot.begin(); itr != possibleLoot.end(); ++itr) // check each explicitly chanced entry in the template and modify its chance based on quality.
|
||||||
{
|
{
|
||||||
LootStoreItem* item = *itr;
|
LootStoreItem* item = *itr;
|
||||||
if (item->chance >= 100.0f)
|
float chance = item->chance;
|
||||||
|
|
||||||
|
sScriptMgr->OnItemRoll(player, item, chance, loot, store);
|
||||||
|
|
||||||
|
if (chance >= 100.0f)
|
||||||
return item;
|
return item;
|
||||||
|
|
||||||
roll -= item->chance;
|
roll -= chance;
|
||||||
if (roll < 0)
|
if (roll < 0)
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
@@ -1169,9 +1177,9 @@ void LootTemplate::LootGroup::CopyConditions(ConditionList /*conditions*/)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Rolls an item from the group (if any takes its chance) and adds the item to the loot
|
// Rolls an item from the group (if any takes its chance) and adds the item to the loot
|
||||||
void LootTemplate::LootGroup::Process(Loot& loot, uint16 lootMode) const
|
void LootTemplate::LootGroup::Process(Loot& loot, Player const *player, LootStore const& store, uint16 lootMode) const
|
||||||
{
|
{
|
||||||
if (LootStoreItem const* item = Roll(loot, lootMode))
|
if (LootStoreItem const* item = Roll(loot, player, store, lootMode))
|
||||||
loot.AddItem(*item);
|
loot.AddItem(*item);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1309,7 +1317,7 @@ void LootTemplate::Process(Loot& loot, LootStore const& store, uint16 lootMode,
|
|||||||
if (!Groups[groupId - 1])
|
if (!Groups[groupId - 1])
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Groups[groupId-1]->Process(loot, lootMode);
|
Groups[groupId-1]->Process(loot, player, store, lootMode);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1319,10 +1327,8 @@ void LootTemplate::Process(Loot& loot, LootStore const& store, uint16 lootMode,
|
|||||||
LootStoreItem* item = *i;
|
LootStoreItem* item = *i;
|
||||||
if (!(item->lootmode & lootMode)) // Do not add if mode mismatch
|
if (!(item->lootmode & lootMode)) // Do not add if mode mismatch
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
sScriptMgr->OnBeforeItemRoll(player, loot, rate, lootMode, item, store);
|
|
||||||
|
|
||||||
if (!item->Roll(rate))
|
if (!item->Roll(rate, player, loot, store))
|
||||||
continue; // Bad luck for the entry
|
continue; // Bad luck for the entry
|
||||||
|
|
||||||
if (item->mincountOrRef < 0) // References processing
|
if (item->mincountOrRef < 0) // References processing
|
||||||
@@ -1345,7 +1351,7 @@ void LootTemplate::Process(Loot& loot, LootStore const& store, uint16 lootMode,
|
|||||||
// Now processing groups
|
// Now processing groups
|
||||||
for (LootGroups::const_iterator i = Groups.begin(); i != Groups.end(); ++i)
|
for (LootGroups::const_iterator i = Groups.begin(); i != Groups.end(); ++i)
|
||||||
if (LootGroup* group = *i)
|
if (LootGroup* group = *i)
|
||||||
group->Process(loot, lootMode);
|
group->Process(loot, player, store, lootMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
// True if template includes at least 1 quest drop entry
|
// True if template includes at least 1 quest drop entry
|
||||||
|
|||||||
@@ -110,6 +110,7 @@ enum LootSlotType
|
|||||||
class Player;
|
class Player;
|
||||||
class LootStore;
|
class LootStore;
|
||||||
class ConditionMgr;
|
class ConditionMgr;
|
||||||
|
struct Loot;
|
||||||
|
|
||||||
struct LootStoreItem
|
struct LootStoreItem
|
||||||
{
|
{
|
||||||
@@ -129,7 +130,7 @@ struct LootStoreItem
|
|||||||
group(_group), needs_quest(_chanceOrQuestChance < 0), maxcount(_maxcount)
|
group(_group), needs_quest(_chanceOrQuestChance < 0), maxcount(_maxcount)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
bool Roll(bool rate) const; // Checks if the entry takes it's chance (at loot generation)
|
bool Roll(bool rate, Player const *player, Loot& loot, LootStore const& store) const; // Checks if the entry takes it's chance (at loot generation)
|
||||||
bool IsValid(LootStore const& store, uint32 entry) const;
|
bool IsValid(LootStore const& store, uint32 entry) const;
|
||||||
// Checks correctness of values
|
// Checks correctness of values
|
||||||
};
|
};
|
||||||
@@ -178,7 +179,6 @@ struct QuestItem
|
|||||||
: index(_index), is_looted(_islooted) {}
|
: index(_index), is_looted(_islooted) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Loot;
|
|
||||||
class LootTemplate;
|
class LootTemplate;
|
||||||
|
|
||||||
typedef std::vector<QuestItem> QuestItemList;
|
typedef std::vector<QuestItem> QuestItemList;
|
||||||
|
|||||||
@@ -1519,8 +1519,8 @@ void ScriptMgr::OnBeforeDropAddItem(Player const* player, Loot& loot, bool canRa
|
|||||||
FOREACH_SCRIPT(GlobalScript)->OnBeforeDropAddItem(player, loot, canRate, lootMode, LootStoreItem, store);
|
FOREACH_SCRIPT(GlobalScript)->OnBeforeDropAddItem(player, loot, canRate, lootMode, LootStoreItem, store);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScriptMgr::OnBeforeItemRoll(Player const* player, Loot& loot, bool canRate, uint16 lootMode, LootStoreItem* LootStoreItem, LootStore const& store) {
|
void ScriptMgr::OnItemRoll(Player const* player, LootStoreItem const* LootStoreItem, float &chance, Loot& loot, LootStore const& store) {
|
||||||
FOREACH_SCRIPT(GlobalScript)->OnBeforeItemRoll(player, loot, canRate, lootMode, LootStoreItem, store);
|
FOREACH_SCRIPT(GlobalScript)->OnItemRoll(player, LootStoreItem, chance, loot, store);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScriptMgr::OnInitializeLockedDungeons(Player* player, uint8& level, uint32& lockData)
|
void ScriptMgr::OnInitializeLockedDungeons(Player* player, uint8& level, uint32& lockData)
|
||||||
|
|||||||
@@ -1008,7 +1008,7 @@ class GlobalScript : public ScriptObject
|
|||||||
// loot
|
// loot
|
||||||
virtual void OnAfterRefCount(Player const* /*player*/, LootStoreItem* /*LootStoreItem*/, Loot& /*loot*/, bool /*canRate*/, uint16 /*lootMode*/, uint32& /*maxcount*/, LootStore const& /*store*/) { }
|
virtual void OnAfterRefCount(Player const* /*player*/, LootStoreItem* /*LootStoreItem*/, Loot& /*loot*/, bool /*canRate*/, uint16 /*lootMode*/, uint32& /*maxcount*/, LootStore const& /*store*/) { }
|
||||||
virtual void OnBeforeDropAddItem(Player const* /*player*/, Loot& /*loot*/, bool /*canRate*/, uint16 /*lootMode*/, LootStoreItem* /*LootStoreItem*/, LootStore const& /*store*/) { }
|
virtual void OnBeforeDropAddItem(Player const* /*player*/, Loot& /*loot*/, bool /*canRate*/, uint16 /*lootMode*/, LootStoreItem* /*LootStoreItem*/, LootStore const& /*store*/) { }
|
||||||
virtual void OnBeforeItemRoll(Player const* /*player*/, Loot& /*loot*/, bool /*canRate*/, uint16 /*lootMode*/, LootStoreItem* /*LootStoreItem*/, LootStore const& /*store*/) { };
|
virtual void OnItemRoll(Player const* /*player*/, LootStoreItem const* /*LootStoreItem*/, float& /*chance*/, Loot& /*loot*/, LootStore const& /*store*/) { };
|
||||||
|
|
||||||
virtual void OnInitializeLockedDungeons(Player* /*player*/, uint8& /*level*/, uint32& /*lockData*/) { }
|
virtual void OnInitializeLockedDungeons(Player* /*player*/, uint8& /*level*/, uint32& /*lockData*/) { }
|
||||||
virtual void OnAfterInitializeLockedDungeons(Player* /*player*/) { }
|
virtual void OnAfterInitializeLockedDungeons(Player* /*player*/) { }
|
||||||
@@ -1281,7 +1281,7 @@ class ScriptMgr
|
|||||||
void OnBeforeUpdateArenaPoints(ArenaTeam* at, std::map<uint32, uint32> &ap);
|
void OnBeforeUpdateArenaPoints(ArenaTeam* at, std::map<uint32, uint32> &ap);
|
||||||
void OnAfterRefCount(Player const* player, Loot& loot, bool canRate, uint16 lootMode, LootStoreItem* LootStoreItem, uint32 &maxcount, LootStore const& store);
|
void OnAfterRefCount(Player const* player, Loot& loot, bool canRate, uint16 lootMode, LootStoreItem* LootStoreItem, uint32 &maxcount, LootStore const& store);
|
||||||
void OnBeforeDropAddItem(Player const* player, Loot& loot, bool canRate, uint16 lootMode, LootStoreItem* LootStoreItem, LootStore const& store);
|
void OnBeforeDropAddItem(Player const* player, Loot& loot, bool canRate, uint16 lootMode, LootStoreItem* LootStoreItem, LootStore const& store);
|
||||||
void OnBeforeItemRoll(Player const* player, Loot& loot, bool canRate, uint16 lootMode, LootStoreItem* LootStoreItem, LootStore const& store);
|
void OnItemRoll(Player const* player, LootStoreItem const* LootStoreItem, float &chance, Loot& loot, LootStore const& store);
|
||||||
void OnInitializeLockedDungeons(Player* player, uint8& level, uint32& lockData);
|
void OnInitializeLockedDungeons(Player* player, uint8& level, uint32& lockData);
|
||||||
void OnAfterInitializeLockedDungeons(Player* player);
|
void OnAfterInitializeLockedDungeons(Player* player);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user