mirror of
https://github.com/mangosfour/server.git
synced 2025-12-14 07:37:01 +00:00
Fixes and cleanups in loot code.
* Move not-normal loot tables generation in single place (Loot::FillLoot function) for group and non group case. * Simplify LootView code.
This commit is contained in:
parent
fb432a0f36
commit
7d63f4ce02
6 changed files with 86 additions and 99 deletions
|
|
@ -480,7 +480,7 @@ void GameObject::Delete()
|
|||
AddObjectToRemoveList();
|
||||
}
|
||||
|
||||
void GameObject::getFishLoot(Loot *fishloot)
|
||||
void GameObject::getFishLoot(Loot *fishloot, Player* loot_owner)
|
||||
{
|
||||
fishloot->clear();
|
||||
|
||||
|
|
@ -488,10 +488,10 @@ void GameObject::getFishLoot(Loot *fishloot)
|
|||
|
||||
// if subzone loot exist use it
|
||||
if(LootTemplates_Fishing.HaveLootFor(subzone))
|
||||
fishloot->FillLoot(subzone, LootTemplates_Fishing, NULL);
|
||||
fishloot->FillLoot(subzone, LootTemplates_Fishing, loot_owner,true);
|
||||
// else use zone loot
|
||||
else
|
||||
fishloot->FillLoot(GetZoneId(), LootTemplates_Fishing, NULL);
|
||||
fishloot->FillLoot(GetZoneId(), LootTemplates_Fishing, loot_owner,true);
|
||||
}
|
||||
|
||||
void GameObject::SaveToDB()
|
||||
|
|
|
|||
|
|
@ -507,7 +507,7 @@ class MANGOS_DLL_SPEC GameObject : public WorldObject
|
|||
void Delete();
|
||||
void SetSpellId(uint32 id) { m_spellId = id;}
|
||||
uint32 GetSpellId() const { return m_spellId;}
|
||||
void getFishLoot(Loot *loot);
|
||||
void getFishLoot(Loot *loot, Player* loot_owner);
|
||||
GameobjectTypes GetGoType() const { return GameobjectTypes(GetByteValue(GAMEOBJECT_BYTES_1, 1)); }
|
||||
void SetGoType(GameobjectTypes type) { SetByteValue(GAMEOBJECT_BYTES_1, 1, type); }
|
||||
uint8 GetGoState() const { return GetByteValue(GAMEOBJECT_BYTES_1, 0); }
|
||||
|
|
|
|||
|
|
@ -366,8 +366,12 @@ void Loot::AddItem(LootStoreItem const & item)
|
|||
}
|
||||
|
||||
// Calls processor of corresponding LootTemplate (which handles everything including references)
|
||||
void Loot::FillLoot(uint32 loot_id, LootStore const& store, Player* loot_owner)
|
||||
void Loot::FillLoot(uint32 loot_id, LootStore const& store, Player* loot_owner, bool personal)
|
||||
{
|
||||
// Must be provided
|
||||
if(!loot_owner)
|
||||
return;
|
||||
|
||||
LootTemplate const* tab = store.GetLootFor(loot_id);
|
||||
|
||||
if (!tab)
|
||||
|
|
@ -381,35 +385,34 @@ void Loot::FillLoot(uint32 loot_id, LootStore const& store, Player* loot_owner)
|
|||
|
||||
tab->Process(*this, store,store.IsRatesAllowed ()); // Processing is done there, callback via Loot::AddItem()
|
||||
|
||||
// Setting access rights fow group-looting case
|
||||
if(!loot_owner)
|
||||
return;
|
||||
// Setting access rights for group loot case
|
||||
Group * pGroup=loot_owner->GetGroup();
|
||||
if(!pGroup)
|
||||
return;
|
||||
for(GroupReference *itr = pGroup->GetFirstMember(); itr != NULL; itr = itr->next())
|
||||
if(!personal && pGroup)
|
||||
{
|
||||
//fill the quest item map for every player in the recipient's group
|
||||
Player* pl = itr->getSource();
|
||||
if(!pl)
|
||||
continue;
|
||||
uint32 plguid = pl->GetGUIDLow();
|
||||
QuestItemMap::iterator qmapitr = PlayerQuestItems.find(plguid);
|
||||
if (qmapitr == PlayerQuestItems.end())
|
||||
{
|
||||
FillQuestLoot(pl);
|
||||
}
|
||||
qmapitr = PlayerFFAItems.find(plguid);
|
||||
if (qmapitr == PlayerFFAItems.end())
|
||||
{
|
||||
FillFFALoot(pl);
|
||||
}
|
||||
qmapitr = PlayerNonQuestNonFFAConditionalItems.find(plguid);
|
||||
if (qmapitr == PlayerNonQuestNonFFAConditionalItems.end())
|
||||
{
|
||||
FillNonQuestNonFFAConditionalLoot(pl);
|
||||
}
|
||||
for(GroupReference *itr = pGroup->GetFirstMember(); itr != NULL; itr = itr->next())
|
||||
if(Player* pl = itr->getSource())
|
||||
FillNotNormalLootFor(pl);
|
||||
}
|
||||
// ... for personal loot
|
||||
else
|
||||
FillNotNormalLootFor(loot_owner);
|
||||
}
|
||||
|
||||
void Loot::FillNotNormalLootFor(Player* pl)
|
||||
{
|
||||
uint32 plguid = pl->GetGUIDLow();
|
||||
|
||||
QuestItemMap::iterator qmapitr = PlayerQuestItems.find(plguid);
|
||||
if (qmapitr == PlayerQuestItems.end())
|
||||
FillQuestLoot(pl);
|
||||
|
||||
qmapitr = PlayerFFAItems.find(plguid);
|
||||
if (qmapitr == PlayerFFAItems.end())
|
||||
FillFFALoot(pl);
|
||||
|
||||
qmapitr = PlayerNonQuestNonFFAConditionalItems.find(plguid);
|
||||
if (qmapitr == PlayerNonQuestNonFFAConditionalItems.end())
|
||||
FillNonQuestNonFFAConditionalLoot(pl);
|
||||
}
|
||||
|
||||
QuestItemList* Loot::FillFFALoot(Player* player)
|
||||
|
|
@ -653,12 +656,19 @@ ByteBuffer& operator<<(ByteBuffer& b, LootItem const& li)
|
|||
|
||||
ByteBuffer& operator<<(ByteBuffer& b, LootView const& lv)
|
||||
{
|
||||
if (lv.permission == NONE_PERMISSION)
|
||||
{
|
||||
b << uint32(0); //gold
|
||||
b << uint8(0); // item count
|
||||
return b; // nothing output more
|
||||
}
|
||||
|
||||
Loot &l = lv.loot;
|
||||
|
||||
uint8 itemsShown = 0;
|
||||
|
||||
//gold
|
||||
b << uint32(lv.permission!=NONE_PERMISSION ? l.gold : 0);
|
||||
b << uint32(l.gold);
|
||||
|
||||
size_t count_pos = b.wpos(); // pos of item count byte
|
||||
b << uint8(0); // item count placeholder
|
||||
|
|
@ -697,19 +707,21 @@ ByteBuffer& operator<<(ByteBuffer& b, LootView const& lv)
|
|||
}
|
||||
break;
|
||||
}
|
||||
case NONE_PERMISSION:
|
||||
default:
|
||||
return b; // nothing output more
|
||||
}
|
||||
|
||||
if (lv.qlist)
|
||||
QuestItemMap const& lootPlayerQuestItems = l.GetPlayerQuestItems();
|
||||
QuestItemMap::const_iterator q_itr = lootPlayerQuestItems.find(lv.viewer->GetGUIDLow());
|
||||
if (q_itr != lootPlayerQuestItems.end())
|
||||
{
|
||||
for (QuestItemList::iterator qi = lv.qlist->begin() ; qi != lv.qlist->end(); ++qi)
|
||||
QuestItemList *q_list = q_itr->second;
|
||||
for (QuestItemList::iterator qi = q_list->begin() ; qi != q_list->end(); ++qi)
|
||||
{
|
||||
LootItem &item = l.quest_items[qi->index];
|
||||
if (!qi->is_looted && !item.is_looted)
|
||||
{
|
||||
b << uint8(l.items.size() + (qi - lv.qlist->begin()));
|
||||
b << uint8(l.items.size() + (qi - q_list->begin()));
|
||||
b << item;
|
||||
b << uint8(0); // allow loot
|
||||
++itemsShown;
|
||||
|
|
@ -717,9 +729,12 @@ ByteBuffer& operator<<(ByteBuffer& b, LootView const& lv)
|
|||
}
|
||||
}
|
||||
|
||||
if (lv.ffalist)
|
||||
QuestItemMap const& lootPlayerFFAItems = l.GetPlayerFFAItems();
|
||||
QuestItemMap::const_iterator ffa_itr = lootPlayerFFAItems.find(lv.viewer->GetGUIDLow());
|
||||
if (ffa_itr != lootPlayerFFAItems.end())
|
||||
{
|
||||
for (QuestItemList::iterator fi = lv.ffalist->begin() ; fi != lv.ffalist->end(); ++fi)
|
||||
QuestItemList *ffa_list = ffa_itr->second;
|
||||
for (QuestItemList::iterator fi = ffa_list->begin() ; fi != ffa_list->end(); ++fi)
|
||||
{
|
||||
LootItem &item = l.items[fi->index];
|
||||
if (!fi->is_looted && !item.is_looted)
|
||||
|
|
@ -731,9 +746,12 @@ ByteBuffer& operator<<(ByteBuffer& b, LootView const& lv)
|
|||
}
|
||||
}
|
||||
|
||||
if (lv.conditionallist)
|
||||
QuestItemMap const& lootPlayerNonQuestNonFFAConditionalItems = l.GetPlayerNonQuestNonFFAConditionalItems();
|
||||
QuestItemMap::const_iterator nn_itr = lootPlayerNonQuestNonFFAConditionalItems.find(lv.viewer->GetGUIDLow());
|
||||
if (nn_itr != lootPlayerNonQuestNonFFAConditionalItems.end())
|
||||
{
|
||||
for (QuestItemList::iterator ci = lv.conditionallist->begin() ; ci != lv.conditionallist->end(); ++ci)
|
||||
QuestItemList *conditional_list = nn_itr->second;
|
||||
for (QuestItemList::iterator ci = conditional_list->begin() ; ci != conditional_list->end(); ++ci)
|
||||
{
|
||||
LootItem &item = l.items[ci->index];
|
||||
if (!ci->is_looted && !item.is_looted)
|
||||
|
|
|
|||
|
|
@ -208,17 +208,19 @@ class LootValidatorRefManager : public RefManager<Loot, LootValidatorRef>
|
|||
};
|
||||
|
||||
//=====================================================
|
||||
struct LootView;
|
||||
|
||||
ByteBuffer& operator<<(ByteBuffer& b, LootItem const& li);
|
||||
ByteBuffer& operator<<(ByteBuffer& b, LootView const& lv);
|
||||
|
||||
struct Loot
|
||||
{
|
||||
friend ByteBuffer& operator<<(ByteBuffer& b, LootView const& lv);
|
||||
|
||||
QuestItemMap const& GetPlayerQuestItems() const { return PlayerQuestItems; }
|
||||
QuestItemMap const& GetPlayerFFAItems() const { return PlayerFFAItems; }
|
||||
QuestItemMap const& GetPlayerNonQuestNonFFAConditionalItems() const { return PlayerNonQuestNonFFAConditionalItems; }
|
||||
|
||||
QuestItemList* FillFFALoot(Player* player);
|
||||
QuestItemList* FillQuestLoot(Player* player);
|
||||
QuestItemList* FillNonQuestNonFFAConditionalLoot(Player* player);
|
||||
|
||||
std::vector<LootItem> items;
|
||||
std::vector<LootItem> quest_items;
|
||||
uint32 gold;
|
||||
|
|
@ -265,13 +267,19 @@ struct Loot
|
|||
void RemoveLooter(uint64 GUID) { PlayersLooting.erase(GUID); }
|
||||
|
||||
void generateMoneyLoot(uint32 minAmount, uint32 maxAmount);
|
||||
void FillLoot(uint32 loot_id, LootStore const& store, Player* loot_owner);
|
||||
void FillLoot(uint32 loot_id, LootStore const& store, Player* loot_owner, bool personal);
|
||||
|
||||
// Inserts the item into the loot (called by LootTemplate processors)
|
||||
void AddItem(LootStoreItem const & item);
|
||||
|
||||
LootItem* LootItemInSlot(uint32 lootslot, Player* player, QuestItem** qitem = NULL, QuestItem** ffaitem = NULL, QuestItem** conditem = NULL);
|
||||
|
||||
private:
|
||||
void FillNotNormalLootFor(Player* player);
|
||||
QuestItemList* FillFFALoot(Player* player);
|
||||
QuestItemList* FillQuestLoot(Player* player);
|
||||
QuestItemList* FillNonQuestNonFFAConditionalLoot(Player* player);
|
||||
|
||||
std::set<uint64> PlayersLooting;
|
||||
QuestItemMap PlayerQuestItems;
|
||||
QuestItemMap PlayerFFAItems;
|
||||
|
|
@ -279,19 +287,15 @@ struct Loot
|
|||
|
||||
// All rolls are registered here. They need to know, when the loot is not valid anymore
|
||||
LootValidatorRefManager i_LootValidatorRefManager;
|
||||
|
||||
};
|
||||
|
||||
struct LootView
|
||||
{
|
||||
Loot &loot;
|
||||
QuestItemList *qlist;
|
||||
QuestItemList *ffalist;
|
||||
QuestItemList *conditionallist;
|
||||
Player *viewer;
|
||||
PermissionTypes permission;
|
||||
LootView(Loot &_loot, QuestItemList *_qlist, QuestItemList *_ffalist, QuestItemList *_conditionallist, Player *_viewer,PermissionTypes _permission = ALL_PERMISSION)
|
||||
: loot(_loot), qlist(_qlist), ffalist(_ffalist), conditionallist(_conditionallist), viewer(_viewer), permission(_permission) {}
|
||||
LootView(Loot &_loot, Player *_viewer,PermissionTypes _permission = ALL_PERMISSION)
|
||||
: loot(_loot), viewer(_viewer), permission(_permission) {}
|
||||
};
|
||||
|
||||
extern LootStore LootTemplates_Creature;
|
||||
|
|
@ -337,6 +341,4 @@ inline void LoadLootTables()
|
|||
LoadLootTemplates_Reference();
|
||||
}
|
||||
|
||||
ByteBuffer& operator<<(ByteBuffer& b, LootItem const& li);
|
||||
ByteBuffer& operator<<(ByteBuffer& b, LootView const& lv);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -7401,11 +7401,11 @@ void Player::SendLoot(uint64 guid, LootType loot_type)
|
|||
{
|
||||
sLog.outDebug(" if(lootid)");
|
||||
loot->clear();
|
||||
loot->FillLoot(lootid, LootTemplates_Gameobject, this);
|
||||
loot->FillLoot(lootid, LootTemplates_Gameobject, this, false);
|
||||
}
|
||||
|
||||
if(loot_type == LOOT_FISHING)
|
||||
go->getFishLoot(loot);
|
||||
go->getFishLoot(loot,this);
|
||||
|
||||
go->SetLootState(GO_ACTIVATED);
|
||||
}
|
||||
|
|
@ -7428,7 +7428,7 @@ void Player::SendLoot(uint64 guid, LootType loot_type)
|
|||
{
|
||||
item->m_lootGenerated = true;
|
||||
loot->clear();
|
||||
loot->FillLoot(item->GetProto()->DisenchantID, LootTemplates_Disenchant, this);
|
||||
loot->FillLoot(item->GetProto()->DisenchantID, LootTemplates_Disenchant, this,true);
|
||||
}
|
||||
}
|
||||
else if(loot_type == LOOT_PROSPECTING)
|
||||
|
|
@ -7439,7 +7439,7 @@ void Player::SendLoot(uint64 guid, LootType loot_type)
|
|||
{
|
||||
item->m_lootGenerated = true;
|
||||
loot->clear();
|
||||
loot->FillLoot(item->GetEntry(), LootTemplates_Prospecting, this);
|
||||
loot->FillLoot(item->GetEntry(), LootTemplates_Prospecting, this,true);
|
||||
}
|
||||
}
|
||||
else if(loot_type == LOOT_MILLING)
|
||||
|
|
@ -7450,7 +7450,7 @@ void Player::SendLoot(uint64 guid, LootType loot_type)
|
|||
{
|
||||
item->m_lootGenerated = true;
|
||||
loot->clear();
|
||||
loot->FillLoot(item->GetEntry(), LootTemplates_Milling, this);
|
||||
loot->FillLoot(item->GetEntry(), LootTemplates_Milling, this,true);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -7461,7 +7461,7 @@ void Player::SendLoot(uint64 guid, LootType loot_type)
|
|||
{
|
||||
item->m_lootGenerated = true;
|
||||
loot->clear();
|
||||
loot->FillLoot(item->GetEntry(), LootTemplates_Item, this);
|
||||
loot->FillLoot(item->GetEntry(), LootTemplates_Item, this,true);
|
||||
|
||||
loot->generateMoneyLoot(item->GetProto()->MinMoneyLoot,item->GetProto()->MaxMoneyLoot);
|
||||
}
|
||||
|
|
@ -7519,7 +7519,7 @@ void Player::SendLoot(uint64 guid, LootType loot_type)
|
|||
loot->clear();
|
||||
|
||||
if (uint32 lootid = creature->GetCreatureInfo()->pickpocketLootId)
|
||||
loot->FillLoot(lootid, LootTemplates_Pickpocketing, this);
|
||||
loot->FillLoot(lootid, LootTemplates_Pickpocketing, this, false);
|
||||
|
||||
// Generate extra money for pick pocket loot
|
||||
const uint32 a = urand(0, creature->getLevel()/2);
|
||||
|
|
@ -7549,7 +7549,7 @@ void Player::SendLoot(uint64 guid, LootType loot_type)
|
|||
loot->clear();
|
||||
|
||||
if (uint32 lootid = creature->GetCreatureInfo()->lootid)
|
||||
loot->FillLoot(lootid, LootTemplates_Creature, recipient);
|
||||
loot->FillLoot(lootid, LootTemplates_Creature, recipient, false);
|
||||
|
||||
loot->generateMoneyLoot(creature->GetCreatureInfo()->mingold,creature->GetCreatureInfo()->maxgold);
|
||||
|
||||
|
|
@ -7579,7 +7579,7 @@ void Player::SendLoot(uint64 guid, LootType loot_type)
|
|||
if (loot_type == LOOT_SKINNING)
|
||||
{
|
||||
loot->clear();
|
||||
loot->FillLoot(creature->GetCreatureInfo()->SkinLootId, LootTemplates_Skinning, this);
|
||||
loot->FillLoot(creature->GetCreatureInfo()->SkinLootId, LootTemplates_Skinning, this, false);
|
||||
}
|
||||
// set group rights only for loot_type != LOOT_SKINNING
|
||||
else
|
||||
|
|
@ -7613,39 +7613,6 @@ void Player::SendLoot(uint64 guid, LootType loot_type)
|
|||
|
||||
SetLootGUID(guid);
|
||||
|
||||
QuestItemList *q_list = 0;
|
||||
if (permission != NONE_PERMISSION)
|
||||
{
|
||||
QuestItemMap const& lootPlayerQuestItems = loot->GetPlayerQuestItems();
|
||||
QuestItemMap::const_iterator itr = lootPlayerQuestItems.find(GetGUIDLow());
|
||||
if (itr == lootPlayerQuestItems.end())
|
||||
q_list = loot->FillQuestLoot(this);
|
||||
else
|
||||
q_list = itr->second;
|
||||
}
|
||||
|
||||
QuestItemList *ffa_list = 0;
|
||||
if (permission != NONE_PERMISSION)
|
||||
{
|
||||
QuestItemMap const& lootPlayerFFAItems = loot->GetPlayerFFAItems();
|
||||
QuestItemMap::const_iterator itr = lootPlayerFFAItems.find(GetGUIDLow());
|
||||
if (itr == lootPlayerFFAItems.end())
|
||||
ffa_list = loot->FillFFALoot(this);
|
||||
else
|
||||
ffa_list = itr->second;
|
||||
}
|
||||
|
||||
QuestItemList *conditional_list = 0;
|
||||
if (permission != NONE_PERMISSION)
|
||||
{
|
||||
QuestItemMap const& lootPlayerNonQuestNonFFAConditionalItems = loot->GetPlayerNonQuestNonFFAConditionalItems();
|
||||
QuestItemMap::const_iterator itr = lootPlayerNonQuestNonFFAConditionalItems.find(GetGUIDLow());
|
||||
if (itr == lootPlayerNonQuestNonFFAConditionalItems.end())
|
||||
conditional_list = loot->FillNonQuestNonFFAConditionalLoot(this);
|
||||
else
|
||||
conditional_list = itr->second;
|
||||
}
|
||||
|
||||
// LOOT_PICKPOCKETING, LOOT_PROSPECTING, LOOT_DISENCHANTING, LOOT_INSIGNIA and LOOT_MILLING unsupported by client, sending LOOT_SKINNING instead
|
||||
if(loot_type == LOOT_PICKPOCKETING || loot_type == LOOT_DISENCHANTING || loot_type == LOOT_PROSPECTING || loot_type == LOOT_INSIGNIA || loot_type == LOOT_MILLING)
|
||||
loot_type = LOOT_SKINNING;
|
||||
|
|
@ -7657,7 +7624,7 @@ void Player::SendLoot(uint64 guid, LootType loot_type)
|
|||
|
||||
data << uint64(guid);
|
||||
data << uint8(loot_type);
|
||||
data << LootView(*loot, q_list, ffa_list, conditional_list, this, permission);
|
||||
data << LootView(*loot, this, permission);
|
||||
|
||||
SendDirectMessage(&data);
|
||||
|
||||
|
|
@ -12799,7 +12766,7 @@ void Player::RewardQuest( Quest const *pQuest, uint32 reward, Object* questGiver
|
|||
|
||||
Loot questMailLoot;
|
||||
|
||||
questMailLoot.FillLoot(pQuest->GetQuestId(), LootTemplates_QuestMail, this);
|
||||
questMailLoot.FillLoot(pQuest->GetQuestId(), LootTemplates_QuestMail, this,true);
|
||||
|
||||
// fill mail
|
||||
MailItemsInfo mi; // item list preparing
|
||||
|
|
@ -19412,7 +19379,7 @@ void Player::InitRunes()
|
|||
void Player::AutoStoreLootItem(uint8 bag, uint8 slot, uint32 loot_id, LootStore const& store)
|
||||
{
|
||||
Loot loot;
|
||||
loot.FillLoot (loot_id,store,this);
|
||||
loot.FillLoot (loot_id,store,this,true);
|
||||
if(loot.items.empty ())
|
||||
return;
|
||||
LootItem const* lootItem = &loot.items[0];
|
||||
|
|
|
|||
|
|
@ -1523,7 +1523,7 @@ void Aura::TriggerSpell()
|
|||
}
|
||||
Loot *loot = &creature->loot;
|
||||
loot->clear();
|
||||
loot->FillLoot(creature->GetCreatureInfo()->SkinLootId, LootTemplates_Skinning, NULL);
|
||||
loot->FillLoot(creature->GetCreatureInfo()->SkinLootId, LootTemplates_Skinning, player, true);
|
||||
for(uint8 i=0;i<loot->items.size();i++)
|
||||
{
|
||||
LootItem *item = loot->LootItemInSlot(i,player);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue