Skip to content

Commit

Permalink
[12308] Use non-player conditions within the loot system
Browse files Browse the repository at this point in the history
Also remove no more required special handling for go fishing loot
  • Loading branch information
Schmoozerd committed Dec 13, 2012
1 parent ebc4672 commit 7992aff
Show file tree
Hide file tree
Showing 14 changed files with 82 additions and 73 deletions.
3 changes: 2 additions & 1 deletion src/game/Corpse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@
#include "World.h"
#include "ObjectMgr.h"

Corpse::Corpse(CorpseType type) : WorldObject()
Corpse::Corpse(CorpseType type) : WorldObject(),
loot(this)
{
m_objectType |= TYPEMASK_CORPSE;
m_objectTypeId = TYPEID_CORPSE;
Expand Down
1 change: 1 addition & 0 deletions src/game/Creature.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ bool CreatureCreatePos::Relocate(Creature* cr) const

Creature::Creature(CreatureSubtype subtype) : Unit(),
i_AI(NULL),
loot(this),
lootForPickPocketed(false), lootForBody(false), lootForSkin(false),
m_groupLootTimer(0), m_groupLootId(0),
m_lootMoney(0), m_lootGroupRecipientId(0),
Expand Down
14 changes: 1 addition & 13 deletions src/game/GameObject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
GameObject::GameObject() : WorldObject(),
m_goInfo(NULL),
m_displayInfo(NULL),
loot(this),
m_model(NULL)
{
m_objectType |= TYPEMASK_GAMEOBJECT;
Expand Down Expand Up @@ -526,19 +527,6 @@ void GameObject::Delete()
AddObjectToRemoveList();
}

void GameObject::getFishLoot(Loot* fishloot, Player* loot_owner)
{
fishloot->clear();

uint32 zone, subzone;
GetZoneAndAreaId(zone, subzone);

// if subzone loot exist use it
if (!fishloot->FillLoot(subzone, LootTemplates_Fishing, loot_owner, true, (subzone != zone)) && subzone != zone)
// else use zone loot (if zone diff. from subzone, must exist in like case)
fishloot->FillLoot(zone, LootTemplates_Fishing, loot_owner, true);
}

void GameObject::SaveToDB()
{
// this should only be used when the gameobject has already been loaded
Expand Down
1 change: 0 additions & 1 deletion src/game/GameObject.h
Original file line number Diff line number Diff line change
Expand Up @@ -729,7 +729,6 @@ class MANGOS_DLL_SPEC GameObject : public WorldObject

// Loot System
Loot loot;
void getFishLoot(Loot* loot, Player* loot_owner);
void StartGroupLoot(Group* group, uint32 timer) override;

ObjectGuid GetLootRecipientGuid() const { return m_lootRecipientGuid; }
Expand Down
4 changes: 2 additions & 2 deletions src/game/Group.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -759,7 +759,7 @@ void Group::StartLootRoll(WorldObject* lootTarget, LootMethod method, Loot* loot
if (!playerToRoll || !playerToRoll->GetSession())
continue;

if (lootItem.AllowedForPlayer(playerToRoll))
if (lootItem.AllowedForPlayer(playerToRoll, lootTarget))
{
if (playerToRoll->IsWithinDistInMap(lootTarget, sWorld.getConfig(CONFIG_FLOAT_GROUP_XP_DISTANCE), false))
{
Expand Down Expand Up @@ -926,7 +926,7 @@ void Group::CountTheRoll(Rolls::iterator& rollI)
--roll->getLoot()->unlootedCount;

ItemPrototype const* pProto = ObjectMgr::GetItemPrototype(roll->itemid);
player->AutoStoreLoot(pProto->DisenchantID, LootTemplates_Disenchant, true);
player->AutoStoreLoot(roll->getLoot()->GetLootTarget(), pProto->DisenchantID, LootTemplates_Disenchant, true);
}
}
}
Expand Down
3 changes: 2 additions & 1 deletion src/game/Item.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,8 @@ bool ItemCanGoIntoBag(ItemPrototype const* pProto, ItemPrototype const* pBagProt
return false;
}

Item::Item()
Item::Item() :
loot(NULL)
{
m_objectType |= TYPEMASK_ITEM;
m_objectTypeId = TYPEID_ITEM;
Expand Down
20 changes: 10 additions & 10 deletions src/game/LootMgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -361,10 +361,10 @@ LootItem::LootItem(uint32 itemid_, uint32 count_, uint32 randomSuffix_, int32 ra
}

// Basic checks for player/item compatibility - if false no chance to see the item in the loot
bool LootItem::AllowedForPlayer(Player const* player) const
bool LootItem::AllowedForPlayer(Player const* player, WorldObject const* lootTarget) const
{
// DB conditions check
if (conditionId && !sObjectMgr.IsPlayerMeetToCondition(conditionId, player, NULL, NULL, CONDITION_FROM_LOOT))
if (conditionId && !sObjectMgr.IsPlayerMeetToCondition(conditionId, player, player->GetMap(), lootTarget, CONDITION_FROM_LOOT))
return false;

ItemPrototype const* pProto = ObjectMgr::GetItemPrototype(itemid);
Expand Down Expand Up @@ -394,10 +394,10 @@ bool LootItem::AllowedForPlayer(Player const* player) const
return true;
}

LootSlotType LootItem::GetSlotTypeForSharedLoot(PermissionTypes permission, Player* viewer, bool condition_ok /*= false*/) const
LootSlotType LootItem::GetSlotTypeForSharedLoot(PermissionTypes permission, Player* viewer, WorldObject const* lootTarget, bool condition_ok /*= false*/) const
{
// ignore looted, FFA (each player get own copy) and not allowed items
if (is_looted || freeforall || (conditionId && !condition_ok) || !AllowedForPlayer(viewer))
if (is_looted || freeforall || (conditionId && !condition_ok) || !AllowedForPlayer(viewer, lootTarget))
return MAX_LOOT_SLOT_TYPE;

switch (permission)
Expand Down Expand Up @@ -503,7 +503,7 @@ QuestItemList* Loot::FillFFALoot(Player* player)
for (uint8 i = 0; i < items.size(); ++i)
{
LootItem& item = items[i];
if (!item.is_looted && item.freeforall && item.AllowedForPlayer(player))
if (!item.is_looted && item.freeforall && item.AllowedForPlayer(player, m_lootTarget))
{
ql->push_back(QuestItem(i));
++unlootedCount;
Expand All @@ -527,7 +527,7 @@ QuestItemList* Loot::FillQuestLoot(Player* player)
for (uint8 i = 0; i < m_questItems.size(); ++i)
{
LootItem& item = m_questItems[i];
if (!item.is_looted && item.AllowedForPlayer(player))
if (!item.is_looted && item.AllowedForPlayer(player, m_lootTarget))
{
ql->push_back(QuestItem(i));

Expand Down Expand Up @@ -561,7 +561,7 @@ QuestItemList* Loot::FillNonQuestNonFFAConditionalLoot(Player* player)
for (uint8 i = 0; i < items.size(); ++i)
{
LootItem& item = items[i];
if (!item.is_looted && !item.freeforall && item.conditionId && item.AllowedForPlayer(player))
if (!item.is_looted && !item.freeforall && item.conditionId && item.AllowedForPlayer(player, m_lootTarget))
{
ql->push_back(QuestItem(i));
if (!item.is_counted)
Expand Down Expand Up @@ -765,7 +765,7 @@ ByteBuffer& operator<<(ByteBuffer& b, LootView const& lv)

for (uint8 i = 0; i < l.items.size(); ++i)
{
LootSlotType slot_type = l.items[i].GetSlotTypeForSharedLoot(lv.permission, lv.viewer);
LootSlotType slot_type = l.items[i].GetSlotTypeForSharedLoot(lv.permission, lv.viewer, l.GetLootTarget());
if (slot_type >= MAX_LOOT_SLOT_TYPE)
continue;

Expand All @@ -783,7 +783,7 @@ ByteBuffer& operator<<(ByteBuffer& b, LootView const& lv)
{
LootItem& item = l.items[ci->index];

LootSlotType slot_type = item.GetSlotTypeForSharedLoot(lv.permission, lv.viewer, !ci->is_looted);
LootSlotType slot_type = item.GetSlotTypeForSharedLoot(lv.permission, lv.viewer, l.GetLootTarget(), !ci->is_looted);
if (slot_type >= MAX_LOOT_SLOT_TYPE)
continue;

Expand Down Expand Up @@ -1010,7 +1010,7 @@ void LootTemplate::Process(Loot& loot, LootStore const& store, bool rate, uint8
continue; // Error message already printed at loading stage

// Check condition
if (i->conditionId && !sObjectMgr.IsPlayerMeetToCondition(i->conditionId, NULL, NULL, NULL, CONDITION_FROM_REFERING_LOOT))
if (i->conditionId && !sObjectMgr.IsPlayerMeetToCondition(i->conditionId, NULL, NULL, loot.GetLootTarget(), CONDITION_FROM_REFERING_LOOT))
continue;

for (uint32 loop = 0; loop < i->maxcount; ++loop) // Ref multiplicator
Expand Down
11 changes: 8 additions & 3 deletions src/game/LootMgr.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,8 @@ struct LootItem
LootItem(uint32 itemid_, uint32 count_, uint32 randomSuffix_ = 0, int32 randomPropertyId_ = 0);

// Basic checks for player/item compatibility - if false no chance to see the item in the loot
bool AllowedForPlayer(Player const* player) const;
LootSlotType GetSlotTypeForSharedLoot(PermissionTypes permission, Player* viewer, bool condition_ok = false) const;
bool AllowedForPlayer(Player const* player, WorldObject const* lootTarget) const;
LootSlotType GetSlotTypeForSharedLoot(PermissionTypes permission, Player* viewer, WorldObject const* lootTarget, bool condition_ok = false) const;
};

typedef std::vector<LootItem> LootItemList;
Expand Down Expand Up @@ -243,7 +243,7 @@ struct Loot
uint8 unlootedCount;
LootType loot_type; // required for achievement system

Loot(uint32 _gold = 0) : gold(_gold), unlootedCount(0), loot_type(LOOT_CORPSE) {}
Loot(WorldObject const* lootTarget, uint32 _gold = 0) : m_lootTarget(lootTarget), gold(_gold), unlootedCount(0), loot_type(LOOT_CORPSE) {}
~Loot() { clear(); }

// if loot becomes invalid this reference is used to inform the listener
Expand Down Expand Up @@ -293,6 +293,8 @@ struct Loot
LootItem* LootItemInSlot(uint32 lootslot, Player* player, QuestItem** qitem = NULL, QuestItem** ffaitem = NULL, QuestItem** conditem = NULL);
uint32 GetMaxSlotInLootFor(Player* player) const;

WorldObject const* GetLootTarget() const { return m_lootTarget; }

private:
void FillNotNormalLootFor(Player* player);
QuestItemList* FillFFALoot(Player* player);
Expand All @@ -309,6 +311,9 @@ struct Loot

// All rolls are registered here. They need to know, when the loot is not valid anymore
LootValidatorRefManager m_LootValidatorRefManager;

// What is looted
WorldObject const* m_lootTarget;
};

struct LootView
Expand Down
4 changes: 2 additions & 2 deletions src/game/Mail.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ bool MailDraft::prepareItems(Player* receiver)

m_mailTemplateItemsNeed = false;

Loot mailLoot;
Loot mailLoot(NULL);

// can be empty
mailLoot.FillLoot(m_mailTemplateId, LootTemplates_Mail, receiver, true, true);
Expand Down Expand Up @@ -347,7 +347,7 @@ void Mail::prepareTemplateItems(Player* receiver)

has_items = true;

Loot mailLoot;
Loot mailLoot(NULL);

// can be empty
mailLoot.FillLoot(mailTemplateId, LootTemplates_Mail, receiver, true, true);
Expand Down
84 changes: 49 additions & 35 deletions src/game/Player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8052,54 +8052,68 @@ void Player::SendLoot(ObjectGuid guid, LootType loot_type)
{
uint32 lootid = go->GetGOInfo()->GetLootId();
if ((go->GetEntry() == BG_AV_OBJECTID_MINE_N || go->GetEntry() == BG_AV_OBJECTID_MINE_S))
{
if (BattleGround* bg = GetBattleGround())
if (bg->GetTypeID() == BATTLEGROUND_AV)
if (!(((BattleGroundAV*)bg)->PlayerCanDoMineQuest(go->GetEntry(), GetTeam())))
{
SendLootRelease(guid);
return;
}
}

// Entry 0 in fishing loot template used for store junk fish loot at fishing fail it junk allowed by config option
// this is overwrite fishinghole loot for example
if (loot_type == LOOT_FISHING_FAIL)
loot->FillLoot(0, LootTemplates_Fishing, this, true);
else if (lootid)
loot->clear();
switch (loot_type)
{
DEBUG_LOG(" if(lootid)");
loot->clear();
loot->FillLoot(lootid, LootTemplates_Gameobject, this, false);
loot->generateMoneyLoot(go->GetGOInfo()->MinMoneyLoot, go->GetGOInfo()->MaxMoneyLoot);
// Entry 0 in fishing loot template used for store junk fish loot at fishing fail it junk allowed by config option
// this is overwrite fishinghole loot for example
case LOOT_FISHING_FAIL:
loot->FillLoot(0, LootTemplates_Fishing, this, true);
break;
case LOOT_FISHING:
uint32 zone, subzone;
go->GetZoneAndAreaId(zone, subzone);
// if subzone loot exist use it
if (!loot->FillLoot(subzone, LootTemplates_Fishing, this, true, (subzone != zone)) && subzone != zone)
// else use zone loot (if zone diff. from subzone, must exist in like case)
loot->FillLoot(zone, LootTemplates_Fishing, this, true);
break;
default:
if (!lootid)
break;
DEBUG_LOG(" send normal GO loot");

if (go->GetGoType() == GAMEOBJECT_TYPE_CHEST && go->GetGOInfo()->chest.groupLootRules)
{
if (Group* group = go->GetGroupLootRecipient())
{
group->UpdateLooterGuid(go, true);
loot->FillLoot(lootid, LootTemplates_Gameobject, this, false);
loot->generateMoneyLoot(go->GetGOInfo()->MinMoneyLoot, go->GetGOInfo()->MaxMoneyLoot);

switch (group->GetLootMethod())
if (go->GetGoType() == GAMEOBJECT_TYPE_CHEST && go->GetGOInfo()->chest.groupLootRules)
{
if (Group* group = go->GetGroupLootRecipient())
{
case GROUP_LOOT:
// GroupLoot delete items over threshold (threshold even not implemented), and roll them. Items with quality<threshold, round robin
group->GroupLoot(go, loot);
permission = GROUP_PERMISSION;
break;
case NEED_BEFORE_GREED:
group->NeedBeforeGreed(go, loot);
permission = GROUP_PERMISSION;
break;
case MASTER_LOOT:
group->MasterLoot(go, loot);
permission = MASTER_PERMISSION;
break;
default:
break;
group->UpdateLooterGuid(go, true);

switch (group->GetLootMethod())
{
case GROUP_LOOT:
// GroupLoot delete items over threshold (threshold even not implemented), and roll them. Items with quality<threshold, round robin
group->GroupLoot(go, loot);
permission = GROUP_PERMISSION;
break;
case NEED_BEFORE_GREED:
group->NeedBeforeGreed(go, loot);
permission = GROUP_PERMISSION;
break;
case MASTER_LOOT:
group->MasterLoot(go, loot);
permission = MASTER_PERMISSION;
break;
default:
break;
}
}
}
}
break;
}
else if (loot_type == LOOT_FISHING)
go->getFishLoot(loot, this);

go->SetLootState(GO_ACTIVATED);
}
Expand Down Expand Up @@ -21832,9 +21846,9 @@ bool Player::IsBaseRuneSlotsOnCooldown(RuneType runeType) const
return true;
}

void Player::AutoStoreLoot(uint32 loot_id, LootStore const& store, bool broadcast, uint8 bag, uint8 slot)
void Player::AutoStoreLoot(WorldObject const* lootTarget, uint32 loot_id, LootStore const& store, bool broadcast, uint8 bag, uint8 slot)
{
Loot loot;
Loot loot(lootTarget);
loot.FillLoot(loot_id, store, this, true);

AutoStoreLoot(loot, broadcast, bag, slot);
Expand Down
2 changes: 1 addition & 1 deletion src/game/Player.h
Original file line number Diff line number Diff line change
Expand Up @@ -1201,7 +1201,7 @@ class MANGOS_DLL_SPEC Player : public Unit
bool StoreNewItemInBestSlots(uint32 item_id, uint32 item_count);
Item* StoreNewItemInInventorySlot(uint32 itemEntry, uint32 amount);

void AutoStoreLoot(uint32 loot_id, LootStore const& store, bool broadcast = false, uint8 bag = NULL_BAG, uint8 slot = NULL_SLOT);
void AutoStoreLoot(WorldObject const* lootTarget, uint32 loot_id, LootStore const& store, bool broadcast = false, uint8 bag = NULL_BAG, uint8 slot = NULL_SLOT);
void AutoStoreLoot(Loot& loot, bool broadcast = false, uint8 bag = NULL_BAG, uint8 slot = NULL_SLOT);

Item* ConvertItem(Item* item, uint32 newItemId);
Expand Down
2 changes: 1 addition & 1 deletion src/game/SpellAuras.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1390,7 +1390,7 @@ void Aura::TriggerSpell()
if (!creature->GetCreatureInfo()->SkinLootId)
return;

player->AutoStoreLoot(creature->GetCreatureInfo()->SkinLootId, LootTemplates_Skinning, true);
player->AutoStoreLoot(creature, creature->GetCreatureInfo()->SkinLootId, LootTemplates_Skinning, true);

creature->ForcedDespawn();
}
Expand Down
4 changes: 2 additions & 2 deletions src/game/SpellEffects.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4509,7 +4509,7 @@ void Spell::EffectCreateItem2(SpellEffectIndex eff_idx)
}

// create some random items
player->AutoStoreLoot(m_spellInfo->Id, LootTemplates_Spell);
player->AutoStoreLoot(NULL, m_spellInfo->Id, LootTemplates_Spell);
}
}

Expand All @@ -4520,7 +4520,7 @@ void Spell::EffectCreateRandomItem(SpellEffectIndex /*eff_idx*/)
Player* player = (Player*)m_caster;

// create some random items
player->AutoStoreLoot(m_spellInfo->Id, LootTemplates_Spell);
player->AutoStoreLoot(NULL, m_spellInfo->Id, LootTemplates_Spell);
}

void Spell::EffectPersistentAA(SpellEffectIndex eff_idx)
Expand Down
2 changes: 1 addition & 1 deletion src/shared/revision_nr.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__
#define __REVISION_NR_H__
#define REVISION_NR "12307"
#define REVISION_NR "12308"
#endif // __REVISION_NR_H__

0 comments on commit 7992aff

Please sign in to comment.