Core/Loot: Increased allowed loot range and updated SendLootError

Closes #18685
This commit is contained in:
Shauren
2016-12-31 20:50:39 +01:00
parent ca306c6019
commit dc704efe45
4 changed files with 49 additions and 47 deletions

View File

@@ -8308,7 +8308,7 @@ void Player::SendLoot(ObjectGuid guid, LootType loot_type, bool aeLooting/* = fa
}
else
{
SendLootError(guid, LOOT_ERROR_ALREADY_PICKPOCKETED);
SendLootError(loot->GetGUID(), guid, LOOT_ERROR_ALREADY_PICKPOCKETED);
return;
}
} // else - still has pickpocket loot generated & not fully taken
@@ -8429,19 +8429,20 @@ void Player::SendLoot(ObjectGuid guid, LootType loot_type, bool aeLooting/* = fa
m_AELootView[loot->GetGUID()] = guid;
}
else
SendLootError(GetLootGUID(), LOOT_ERROR_DIDNT_KILL);
SendLootError(loot->GetGUID(), guid, LOOT_ERROR_DIDNT_KILL);
if (loot_type == LOOT_CORPSE && !guid.IsItem())
SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_LOOTING);
}
void Player::SendLootError(ObjectGuid guid, LootError error) const
void Player::SendLootError(ObjectGuid const& lootObj, ObjectGuid const& owner, LootError error) const
{
WorldPacket data(SMSG_LOOT_RESPONSE, 10);
data << guid;
data << uint8(LOOT_NONE);
data << uint8(error);
SendDirectMessage(&data);
WorldPackets::Loot::LootResponse lootResponse;
lootResponse.LootObj = lootObj;
lootResponse.Owner = GetLootWorldObjectGUID(lootObj);
lootResponse.Acquired = false;
lootResponse.FailureReason = error;
SendDirectMessage(lootResponse.Write());
}
void Player::SendNotifyLootMoneyRemoved(ObjectGuid lootObj) const

View File

@@ -2198,7 +2198,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
std::vector<ItemSetEffect*> ItemSetEff;
void SendLoot(ObjectGuid guid, LootType loot_type, bool aeLooting = false);
void SendLootError(ObjectGuid guid, LootError error) const;
void SendLootError(ObjectGuid const& lootObj, ObjectGuid const& owner, LootError error) const;
void SendLootRelease(ObjectGuid guid) const;
void SendLootReleaseAll() const;
void SendNotifyLootItemRemoved(ObjectGuid lootObj, uint8 lootSlot) const;

View File

@@ -33,6 +33,31 @@
#include "LootPackets.h"
#include "WorldSession.h"
class AELootCreatureCheck
{
public:
static float constexpr LootDistance = 30.0f;
AELootCreatureCheck(Player* looter, ObjectGuid mainLootTarget) : _looter(looter), _mainLootTarget(mainLootTarget) { }
bool operator()(Creature* creature) const
{
if (creature->IsAlive())
return false;
if (creature->GetGUID() == _mainLootTarget)
return false;
if (!_looter->IsWithinDist(creature, LootDistance))
return false;
return _looter->isAllowedToLoot(creature);
}
Player* _looter;
ObjectGuid _mainLootTarget;
};
void WorldSession::HandleAutostoreLootItemOpcode(WorldPackets::Loot::LootItem& packet)
{
Player* player = GetPlayer();
@@ -86,9 +111,9 @@ void WorldSession::HandleAutostoreLootItemOpcode(WorldPackets::Loot::LootItem& p
Creature* creature = GetPlayer()->GetMap()->GetCreature(lguid);
bool lootAllowed = creature && creature->IsAlive() == (player->getClass() == CLASS_ROGUE && creature->loot.loot_type == LOOT_PICKPOCKETING);
if (!lootAllowed || !creature->IsWithinDistInMap(_player, INTERACTION_DISTANCE))
if (!lootAllowed || !creature->IsWithinDistInMap(_player, AELootCreatureCheck::LootDistance))
{
player->SendLootError(lguid, lootAllowed ? LOOT_ERROR_TOO_FAR : LOOT_ERROR_DIDNT_KILL);
player->SendLootError(req.Object, lguid, lootAllowed ? LOOT_ERROR_TOO_FAR : LOOT_ERROR_DIDNT_KILL);
continue;
}
@@ -161,14 +186,14 @@ void WorldSession::HandleLootMoneyOpcode(WorldPackets::Loot::LootMoney& /*packet
{
Creature* creature = player->GetMap()->GetCreature(guid);
bool lootAllowed = creature && creature->IsAlive() == (player->getClass() == CLASS_ROGUE && creature->loot.loot_type == LOOT_PICKPOCKETING);
if (lootAllowed && creature->IsWithinDistInMap(player, INTERACTION_DISTANCE))
if (lootAllowed && creature->IsWithinDistInMap(player, AELootCreatureCheck::LootDistance))
{
loot = &creature->loot;
if (creature->IsAlive())
shareMoney = false;
}
else
player->SendLootError(guid, lootAllowed ? LOOT_ERROR_TOO_FAR : LOOT_ERROR_DIDNT_KILL);
player->SendLootError(lootView.first, lootView.second, lootAllowed ? LOOT_ERROR_TOO_FAR : LOOT_ERROR_DIDNT_KILL);
break;
}
default:
@@ -238,31 +263,6 @@ void WorldSession::HandleLootMoneyOpcode(WorldPackets::Loot::LootMoney& /*packet
}
}
class AELootCreatureCheck
{
public:
static float constexpr LootDistance = 30.0f;
AELootCreatureCheck(Player* looter, ObjectGuid mainLootTarget) : _looter(looter), _mainLootTarget(mainLootTarget) { }
bool operator()(Creature* creature) const
{
if (creature->IsAlive())
return false;
if (creature->GetGUID() == _mainLootTarget)
return false;
if (!_looter->IsWithinDist(creature, LootDistance))
return false;
return _looter->isAllowedToLoot(creature);
}
Player* _looter;
ObjectGuid _mainLootTarget;
};
void WorldSession::HandleLootOpcode(WorldPackets::Loot::LootUnit& packet)
{
// Check possible cheat
@@ -407,7 +407,7 @@ void WorldSession::DoLootRelease(ObjectGuid lguid)
Creature* creature = GetPlayer()->GetMap()->GetCreature(lguid);
bool lootAllowed = creature && creature->IsAlive() == (player->getClass() == CLASS_ROGUE && creature->loot.loot_type == LOOT_PICKPOCKETING);
if (!lootAllowed || !creature->IsWithinDistInMap(_player, INTERACTION_DISTANCE))
if (!lootAllowed || !creature->IsWithinDistInMap(_player, AELootCreatureCheck::LootDistance))
return;
loot = &creature->loot;
@@ -460,14 +460,14 @@ void WorldSession::HandleLootMasterGiveOpcode(WorldPacket& recvData)
if (!_player->GetGroup() || _player->GetGroup()->GetMasterLooterGuid() != _player->GetGUID() || _player->GetGroup()->GetLootMethod() != MASTER_LOOT)
{
_player->SendLootError(lootguid, LOOT_ERROR_DIDNT_KILL);
_player->SendLootError(lootguid, ObjectGuid::Empty, LOOT_ERROR_DIDNT_KILL);
return;
}
Player* target = ObjectAccessor::FindPlayer(target_playerguid);
if (!target)
{
_player->SendLootError(lootguid, LOOT_ERROR_PLAYER_NOT_FOUND);
_player->SendLootError(lootguid, ObjectGuid::Empty, LOOT_ERROR_PLAYER_NOT_FOUND);
return;
}
@@ -475,13 +475,13 @@ void WorldSession::HandleLootMasterGiveOpcode(WorldPacket& recvData)
if (_player->GetLootGUID() != lootguid)
{
_player->SendLootError(lootguid, LOOT_ERROR_DIDNT_KILL);
_player->SendLootError(lootguid, ObjectGuid::Empty, LOOT_ERROR_DIDNT_KILL);
return;
}
if (!_player->IsInRaidWith(target) || !_player->IsInMap(target))
{
_player->SendLootError(lootguid, LOOT_ERROR_MASTER_OTHER);
_player->SendLootError(lootguid, ObjectGuid::Empty, LOOT_ERROR_MASTER_OTHER);
TC_LOG_INFO("loot", "MasterLootItem: Player %s tried to give an item to ineligible player %s !", GetPlayer()->GetName().c_str(), target->GetName().c_str());
return;
}
@@ -524,11 +524,11 @@ void WorldSession::HandleLootMasterGiveOpcode(WorldPacket& recvData)
if (msg != EQUIP_ERR_OK)
{
if (msg == EQUIP_ERR_ITEM_MAX_COUNT)
_player->SendLootError(lootguid, LOOT_ERROR_MASTER_UNIQUE_ITEM);
_player->SendLootError(lootguid, ObjectGuid::Empty, LOOT_ERROR_MASTER_UNIQUE_ITEM);
else if (msg == EQUIP_ERR_INV_FULL)
_player->SendLootError(lootguid, LOOT_ERROR_MASTER_INV_FULL);
_player->SendLootError(lootguid, ObjectGuid::Empty, LOOT_ERROR_MASTER_INV_FULL);
else
_player->SendLootError(lootguid, LOOT_ERROR_MASTER_OTHER);
_player->SendLootError(lootguid, ObjectGuid::Empty, LOOT_ERROR_MASTER_OTHER);
target->SendEquipError(msg, NULL, NULL, item.itemid);
return;

View File

@@ -114,7 +114,8 @@ enum LootError
LOOT_ERROR_MASTER_UNIQUE_ITEM = 13, // Player has too many of that item already
LOOT_ERROR_MASTER_OTHER = 14, // Can't assign item to that player
LOOT_ERROR_ALREADY_PICKPOCKETED = 15, // Your target has already had its pockets picked
LOOT_ERROR_NOT_WHILE_SHAPESHIFTED = 16 // You can't do that while shapeshifted.
LOOT_ERROR_NOT_WHILE_SHAPESHIFTED = 16, // You can't do that while shapeshifted.
LOOT_ERROR_NO_LOOT = 17 // There is no loot.
};
// type of Loot Item in Loot View