diff options
author | Trazom62 <none@none> | 2010-03-11 22:55:02 +0100 |
---|---|---|
committer | Trazom62 <none@none> | 2010-03-11 22:55:02 +0100 |
commit | ed8c5ef6ffdbeadb600990fe683f5e20e8f31759 (patch) | |
tree | a9628a30089fae19083326d8f38aa2b45f11b8cd /src/game/LootHandler.cpp | |
parent | d9f257a18c8e7984168d52b2d89b8e1582e27925 (diff) |
Implement group loot for chest having GroupLootRules (go type=3, data15=1).
Implement round robin loot.
Implement round robin for underthreshold items (group loot and need befor greed).
Fix "all players pass" bug on creature.
Add SMSG_LOOT_LIST message to indicate looter (round robin or master).
And some other minor loot bugs.
Fixes issue #167.
Fixes issue #247.
--HG--
branch : trunk
Diffstat (limited to 'src/game/LootHandler.cpp')
-rw-r--r-- | src/game/LootHandler.cpp | 64 |
1 files changed, 47 insertions, 17 deletions
diff --git a/src/game/LootHandler.cpp b/src/game/LootHandler.cpp index 9ee41f05fb8..89d5679e751 100644 --- a/src/game/LootHandler.cpp +++ b/src/game/LootHandler.cpp @@ -274,7 +274,7 @@ void WorldSession::HandleLootReleaseOpcode( WorldPacket & recv_data ) DoLootRelease(lguid); } -void WorldSession::DoLootRelease( uint64 lguid ) +void WorldSession::DoLootRelease(uint64 lguid) { Player *player = GetPlayer(); Loot *loot; @@ -284,7 +284,7 @@ void WorldSession::DoLootRelease( uint64 lguid ) player->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_LOOTING); - if(!player->IsInWorld()) + if (!player->IsInWorld()) return; if (IS_GAMEOBJECT_GUID(lguid)) @@ -364,13 +364,29 @@ void WorldSession::DoLootRelease( uint64 lguid ) loot->clear(); } else + { // not fully looted object go->SetLootState(GO_ACTIVATED); + + // if the round robin player release, reset it. + if (player->GetGUID() == loot->roundRobinPlayer) + { + if (Group* pGroup = player->GetGroup()) + { + if (pGroup->GetLootMethod() != MASTER_LOOT) + { + loot->roundRobinPlayer = 0; + } + } + else + loot->roundRobinPlayer = 0; + } + } } else if (IS_CORPSE_GUID(lguid)) // ONLY remove insignia at BG { Corpse *corpse = ObjectAccessor::GetCorpse(*player, lguid); - if (!corpse || !corpse->IsWithinDistInMap(_player,INTERACTION_DISTANCE) ) + if (!corpse || !corpse->IsWithinDistInMap(_player,INTERACTION_DISTANCE)) return; loot = &corpse->loot; @@ -384,13 +400,13 @@ void WorldSession::DoLootRelease( uint64 lguid ) else if (IS_ITEM_GUID(lguid)) { Item *pItem = player->GetItemByGuid(lguid ); - if(!pItem) + if (!pItem) return; ItemPrototype const* proto = pItem->GetProto(); // destroy only 5 items from stack in case prospecting and milling - if( (proto->BagFamily & (BAG_FAMILY_MASK_MINING_SUPP|BAG_FAMILY_MASK_HERBS)) && + if ((proto->BagFamily & (BAG_FAMILY_MASK_MINING_SUPP|BAG_FAMILY_MASK_HERBS)) && proto->Class == ITEM_CLASS_TRADE_GOODS) { pItem->m_lootGenerated = false; @@ -399,14 +415,14 @@ void WorldSession::DoLootRelease( uint64 lguid ) uint32 count = pItem->GetCount(); // >=5 checked in spell code, but will work for cheating cases also with removing from another stacks. - if(count > 5) + if (count > 5) count = 5; player->DestroyItemCount(pItem, count, true); } else - // FIXME: item don't must be deleted in case not fully looted state. But this pre-request implement loot saving in DB at item save. Or checting possible. - player->DestroyItem( pItem->GetBagSlot(),pItem->GetSlot(), true); + // FIXME: item must not be deleted in case not fully looted state. But this pre-request implement loot saving in DB at item save. Or cheating possible. + player->DestroyItem(pItem->GetBagSlot(),pItem->GetSlot(), true); return; // item can be looted only single player } else @@ -414,26 +430,40 @@ void WorldSession::DoLootRelease( uint64 lguid ) Creature* pCreature = GetPlayer()->GetMap()->GetCreature(lguid); bool ok_loot = pCreature && pCreature->isAlive() == (player->getClass()==CLASS_ROGUE && pCreature->lootForPickPocketed); - if ( !ok_loot || !pCreature->IsWithinDistInMap(_player,INTERACTION_DISTANCE) ) + if (!ok_loot || !pCreature->IsWithinDistInMap(_player,INTERACTION_DISTANCE)) return; loot = &pCreature->loot; - - // update next looter - if(Player *recipient = pCreature->GetLootRecipient()) - if(Group* group = recipient->GetGroup()) - if (group->GetLooterGuid() == player->GetGUID()) - group->UpdateLooterGuid(pCreature); - if (loot->isLooted()) { // skip pickpocketing loot for speed, skinning timer redunction is no-op in fact - if(!pCreature->isAlive()) + if (!pCreature->isAlive()) pCreature->AllLootRemovedFromCorpse(); pCreature->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE); + pCreature->SetLootRecipient(NULL); loot->clear(); } + else + { + // if the round robin player release, reset it. + if (player->GetGUID() == loot->roundRobinPlayer) + { + if (Group* pGroup = player->GetGroup()) + { + if (pGroup->GetLootMethod() != MASTER_LOOT) + { + loot->roundRobinPlayer = 0; + pGroup->SendLooter(pCreature, NULL); + + // force update of dynamic flags, otherwise other group's players still not able to loot. + pCreature->ForceValuesUpdateAtIndex(UNIT_DYNAMIC_FLAGS); + } + } + else + loot->roundRobinPlayer = 0; + } + } } //Player is not looking at loot list, he doesn't need to see updates on the loot list |