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/Player.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/Player.cpp')
-rw-r--r-- | src/game/Player.cpp | 169 |
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) |