aboutsummaryrefslogtreecommitdiff
path: root/src/game/Player.cpp
diff options
context:
space:
mode:
authorTrazom62 <none@none>2010-03-11 22:55:02 +0100
committerTrazom62 <none@none>2010-03-11 22:55:02 +0100
commited8c5ef6ffdbeadb600990fe683f5e20e8f31759 (patch)
treea9628a30089fae19083326d8f38aa2b45f11b8cd /src/game/Player.cpp
parentd9f257a18c8e7984168d52b2d89b8e1582e27925 (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/Player.cpp')
-rw-r--r--src/game/Player.cpp169
1 files changed, 122 insertions, 47 deletions
diff --git a/src/game/Player.cpp b/src/game/Player.cpp
index 69475ff46ac..7305a2ac3f4 100644
--- a/src/game/Player.cpp
+++ b/src/game/Player.cpp
@@ -7917,10 +7917,10 @@ void Player::SendLoot(uint64 guid, LootType loot_type)
uint32 lootid = go->GetGOInfo()->GetLootId();
//TODO: fix this big hack
- 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())))
+ 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;
@@ -7928,16 +7928,71 @@ void Player::SendLoot(uint64 guid, LootType loot_type)
if (lootid)
{
- sLog.outDebug(" if(lootid)");
loot->clear();
- loot->FillLoot(lootid, LootTemplates_Gameobject, this, false, false, go->GetLootMode());
+
+ Group* group = GetGroup();
+ bool groupRules = (group && go->GetGOInfo()->type == GAMEOBJECT_TYPE_CHEST && go->GetGOInfo()->chest.groupLootRules);
+
+ // check current RR player and get next if necessary
+ if (groupRules)
+ group->UpdateLooterGuid(go, true);
+
+ loot->FillLoot(lootid, LootTemplates_Gameobject, this, !groupRules, false, go->GetLootMode());
+
+ // get next RR player (for next loot)
+ if (groupRules)
+ group->UpdateLooterGuid(go);
}
if (loot_type == LOOT_FISHING)
go->getFishLoot(loot,this);
+ if (go->GetGOInfo()->type == GAMEOBJECT_TYPE_CHEST && go->GetGOInfo()->chest.groupLootRules)
+ {
+ if (Group* group = GetGroup())
+ {
+ switch (group->GetLootMethod())
+ {
+ case GROUP_LOOT:
+ // GroupLoot: rolls items over threshold. Items with quality < threshold, round robin
+ group->GroupLoot(loot, go);
+ break;
+ case NEED_BEFORE_GREED:
+ group->NeedBeforeGreed(loot, go);
+ break;
+ case MASTER_LOOT:
+ group->MasterLoot(loot, go);
+ break;
+ }
+ }
+ }
+
go->SetLootState(GO_ACTIVATED);
}
+
+ if (go->getLootState() == GO_ACTIVATED)
+ {
+ if (Group* group = GetGroup())
+ {
+ switch (group->GetLootMethod())
+ {
+ case MASTER_LOOT:
+ permission = MASTER_PERMISSION;
+ break;
+ case FREE_FOR_ALL:
+ permission = ALL_PERMISSION;
+ break;
+ case ROUND_ROBIN:
+ permission = ROUND_ROBIN_PERMISSION;
+ break;
+ default:
+ permission = GROUP_PERMISSION;
+ break;
+ }
+ }
+ else
+ permission = ALL_PERMISSION;
+ }
}
else if (IS_ITEM_GUID(guid))
{
@@ -8019,7 +8074,7 @@ void Player::SendLoot(uint64 guid, LootType loot_type)
return;
}
- loot = &creature->loot;
+ loot = &creature->loot;
if (loot_type == LOOT_PICKPOCKETING)
{
@@ -8029,7 +8084,7 @@ void Player::SendLoot(uint64 guid, LootType loot_type)
loot->clear();
if (uint32 lootid = creature->GetCreatureInfo()->pickpocketLootId)
- loot->FillLoot(lootid, LootTemplates_Pickpocketing, this, false);
+ loot->FillLoot(lootid, LootTemplates_Pickpocketing, this, true);
// Generate extra money for pick pocket loot
const uint32 a = urand(0, creature->getLevel()/2);
@@ -8047,37 +8102,25 @@ void Player::SendLoot(uint64 guid, LootType loot_type)
recipient = this;
}
- if (creature->lootForPickPocketed)
- {
- creature->lootForPickPocketed = false;
- loot->clear();
- }
-
if (!creature->lootForBody)
{
creature->lootForBody = true;
- loot->clear();
-
- if (uint32 lootid = creature->GetCreatureInfo()->lootid)
- loot->FillLoot(lootid, LootTemplates_Creature, recipient, false, false, creature->GetLootMode());
- loot->generateMoneyLoot(creature->GetCreatureInfo()->mingold,creature->GetCreatureInfo()->maxgold);
+ // for creature, loot is filled when creature is killed.
if (Group* group = recipient->GetGroup())
{
- group->UpdateLooterGuid(creature,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(recipient->GetGUID(), loot, creature);
+ // GroupLoot: rolls items over threshold. Items with quality < threshold, round robin
+ group->GroupLoot(loot, creature);
break;
case NEED_BEFORE_GREED:
- group->NeedBeforeGreed(recipient->GetGUID(), loot, creature);
+ group->NeedBeforeGreed(loot, creature);
break;
case MASTER_LOOT:
- group->MasterLoot(recipient->GetGUID(), loot, creature);
+ group->MasterLoot(loot, creature);
break;
default:
break;
@@ -8089,26 +8132,30 @@ void Player::SendLoot(uint64 guid, LootType loot_type)
if (loot_type == LOOT_SKINNING)
{
loot->clear();
- loot->FillLoot(creature->GetCreatureInfo()->SkinLootId, LootTemplates_Skinning, this, false);
+ loot->FillLoot(creature->GetCreatureInfo()->SkinLootId, LootTemplates_Skinning, this, true);
}
// set group rights only for loot_type != LOOT_SKINNING
else
{
- if(Group* group = GetGroup())
+ if (Group* group = GetGroup())
{
if (group == recipient->GetGroup())
{
- if (group->GetLootMethod() == FREE_FOR_ALL)
- permission = ALL_PERMISSION;
- else if (group->GetLooterGuid() == GetGUID())
+ switch (group->GetLootMethod())
{
- if (group->GetLootMethod() == MASTER_LOOT)
+ case MASTER_LOOT:
permission = MASTER_PERMISSION;
- else
+ break;
+ case FREE_FOR_ALL:
permission = ALL_PERMISSION;
+ break;
+ case ROUND_ROBIN:
+ permission = ROUND_ROBIN_PERMISSION;
+ break;
+ default:
+ permission = GROUP_PERMISSION;
+ break;
}
- else
- permission = GROUP_PERMISSION;
}
else
permission = NONE_PERMISSION;
@@ -16077,22 +16124,50 @@ bool Player::isAllowedToLoot(Creature* creature)
if (creature->isDead() && !creature->IsDamageEnoughForLootingAndReward())
return false;
- if (Player* recipient = creature->GetLootRecipient())
- {
- if (recipient == this)
- return true;
- if (Group* otherGroup = recipient->GetGroup())
- {
- Group* thisGroup = GetGroup();
- if (!thisGroup)
- return false;
- return thisGroup == otherGroup;
- }
+ Loot* loot = &creature->loot;
+ if (loot->items.size() == 0)
return false;
- }
- else
+
+ Player* recipient = creature->GetLootRecipient();
+ if (!recipient)
// prevent other players from looting if the recipient got disconnected
return !creature->hasLootRecipient();
+
+ Group* recipientGroup = recipient->GetGroup();
+ if (!recipientGroup)
+ return (this == recipient);
+
+ Group* thisGroup = GetGroup();
+ if (!thisGroup || thisGroup != recipientGroup)
+ return false;
+
+ switch(thisGroup->GetLootMethod())
+ {
+ case FREE_FOR_ALL:
+ return true;
+ case ROUND_ROBIN:
+ case MASTER_LOOT:
+ // may only loot if the player is the loot roundrobin player
+ // or if there are free/quest/conditional item for the player
+ if (loot->roundRobinPlayer == 0 || loot->roundRobinPlayer == GetGUID())
+ return true;
+
+ return loot->hasItemFor(this);
+ case GROUP_LOOT:
+ case NEED_BEFORE_GREED:
+ // may only loot if the player is the loot roundrobin player
+ // or item over threshold (so roll(s) can be launched)
+ // or if there are free/quest/conditional item for the player
+ if (loot->roundRobinPlayer == 0 || loot->roundRobinPlayer == GetGUID())
+ return true;
+
+ if (loot->hasOverThresholdItem())
+ return true;
+
+ return loot->hasItemFor(this);
+ }
+
+ return false;
}
void Player::_LoadActions(QueryResult_AutoPtr result, bool startup)