fixed gold dupping, empty corpses now reliably show as empty once opened
This commit is contained in:
parent
48a8d0c620
commit
9715afee68
3 changed files with 139 additions and 29 deletions
|
|
@ -41,6 +41,7 @@
|
|||
#include "Config.h"
|
||||
#include "CreatureAI.h"
|
||||
#include "DatabaseEnv.h"
|
||||
#include "DatabaseEnvFwd.h"
|
||||
#include "DisableMgr.h"
|
||||
#include "Formulas.h"
|
||||
#include "GameEventMgr.h"
|
||||
|
|
@ -60,6 +61,7 @@
|
|||
#include "MapMgr.h"
|
||||
#include "MiscPackets.h"
|
||||
#include "ObjectAccessor.h"
|
||||
#include "ObjectGuid.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "OutdoorPvP.h"
|
||||
#include "OutdoorPvPMgr.h"
|
||||
|
|
@ -8079,6 +8081,9 @@ void Player::SendLoot(ObjectGuid guid, LootType loot_type)
|
|||
|
||||
permission = NONE_PERMISSION;
|
||||
|
||||
ObjectGuid corpseGUID = bones->GetGUID();
|
||||
CheckCorpseByGUID(corpseGUID);
|
||||
|
||||
if (Corpse* bones = ObjectAccessor::GetCorpse(*this, guid))
|
||||
{
|
||||
if (bones->GetOwnerGUID() != GetGUID())
|
||||
|
|
@ -8304,11 +8309,16 @@ void Player::LoadLostCorpseLoot(ObjectGuid playerGuid, Loot& loot)
|
|||
return;
|
||||
|
||||
QueryResult corpseResult = CharacterDatabase.Query(
|
||||
"SELECT lost_corpse_id, money "
|
||||
"SELECT lost_corpse_id, money, money_collected "
|
||||
"FROM lost_corpses "
|
||||
"WHERE player_guid = {} "
|
||||
"AND SQRT(POW(position_x - {}, 2) + POW(position_y - {}, 2) + POW(position_z - {}, 2)) <= 5 "
|
||||
"AND active = 1 "
|
||||
"ORDER BY lost_corpse_id DESC LIMIT 1",
|
||||
playerGuid.GetCounter()
|
||||
playerGuid.GetCounter(),
|
||||
GetPositionX(),
|
||||
GetPositionY(),
|
||||
GetPositionZ()
|
||||
);
|
||||
|
||||
if (!corpseResult)
|
||||
|
|
@ -8318,8 +8328,12 @@ void Player::LoadLostCorpseLoot(ObjectGuid playerGuid, Loot& loot)
|
|||
|
||||
uint32 lostCorpseId = corpseFields[0].Get<uint32>();
|
||||
uint32 money = corpseFields[1].Get<uint32>();
|
||||
bool moneyCollected = corpseFields[2].Get<uint8>();
|
||||
|
||||
loot.gold = money;
|
||||
if (!moneyCollected)
|
||||
{
|
||||
loot.gold = money;
|
||||
}
|
||||
|
||||
QueryResult result = CharacterDatabase.Query(
|
||||
"SELECT id, lost_corpse_id, item_entry, count, durability "
|
||||
|
|
@ -8360,6 +8374,80 @@ void Player::LoadLostCorpseLoot(ObjectGuid playerGuid, Loot& loot)
|
|||
} while (result->NextRow());
|
||||
}
|
||||
|
||||
void Player::CheckCorpse(uint32 lostCorpseId, ObjectGuid corpseGuid)
|
||||
{
|
||||
// Check if any items remain unlooted
|
||||
QueryResult remaining = CharacterDatabase.Query(
|
||||
"SELECT COUNT(*) FROM lost_corpse_items "
|
||||
"WHERE lost_corpse_id = {} AND looted = 0",
|
||||
lostCorpseId
|
||||
);
|
||||
|
||||
if (remaining)
|
||||
{
|
||||
uint32 count = remaining->Fetch()[0].Get<uint32>();
|
||||
|
||||
if (count == 0)
|
||||
{
|
||||
QueryResult moneyCheck = CharacterDatabase.Query(
|
||||
"SELECT money_collected, money FROM lost_corpses "
|
||||
"WHERE lost_corpse_id = {} OR money = 0",
|
||||
lostCorpseId
|
||||
);
|
||||
|
||||
if (moneyCheck)
|
||||
{
|
||||
bool moneyCollected = moneyCheck->Fetch()[0].Get<uint8>();
|
||||
uint32 money = moneyCheck->Fetch()[1].Get<uint32>();
|
||||
|
||||
if (moneyCollected || money == 0)
|
||||
{
|
||||
// No items left, deactivate corpse
|
||||
CharacterDatabase.Execute(
|
||||
"UPDATE lost_corpses SET active = 0 WHERE lost_corpse_id = {}",
|
||||
lostCorpseId
|
||||
);
|
||||
|
||||
ObjectGuid guidToUse = corpseGuid.IsEmpty() ? GetLootGUID() : corpseGuid;
|
||||
|
||||
// Remove lootability in-game
|
||||
if (Corpse* corpse = ObjectAccessor::GetCorpse(*this, guidToUse))
|
||||
{
|
||||
corpse->RemoveFlag(CORPSE_FIELD_DYNAMIC_FLAGS, CORPSE_DYNFLAG_LOOTABLE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Player::CheckCorpseByGUID(ObjectGuid corpseGuid)
|
||||
{
|
||||
uint32 guid = corpseGuid.GetCounter();
|
||||
uint32 playerGUID = GetGUID().GetCounter();
|
||||
float player_x = GetPositionX();
|
||||
float player_y = GetPositionY();
|
||||
float player_z = GetPositionZ();
|
||||
|
||||
QueryResult result = CharacterDatabase.Query(
|
||||
"SELECT lost_corpse_id "
|
||||
"FROM lost_corpses "
|
||||
"WHERE corpse_guid = {} AND player_guid = {} "
|
||||
"AND SQRT(POW(position_x - {}, 2) + POW(position_y - {}, 2) + POW(position_z - {}, 2)) <= 5",
|
||||
guid,
|
||||
playerGUID,
|
||||
player_x,
|
||||
player_y,
|
||||
player_z
|
||||
);
|
||||
|
||||
if (result)
|
||||
{
|
||||
uint32 lostCorpseId = result->Fetch()[0].Get<uint32>();
|
||||
CheckCorpse(lostCorpseId, corpseGuid);
|
||||
}
|
||||
}
|
||||
|
||||
void Player::SendLootError(ObjectGuid guid, LootError error)
|
||||
{
|
||||
WorldPacket data(SMSG_LOOT_RESPONSE, 10);
|
||||
|
|
@ -13801,32 +13889,7 @@ LootItem* Player::StoreLootItem(uint8 lootSlot, Loot* loot, InventoryResult& msg
|
|||
dbId
|
||||
);
|
||||
|
||||
// Check if any items remain unlooted
|
||||
QueryResult remaining = CharacterDatabase.Query(
|
||||
"SELECT COUNT(*) FROM lost_corpse_items "
|
||||
"WHERE lost_corpse_id = {} AND looted = 0",
|
||||
corpseId
|
||||
);
|
||||
|
||||
if (remaining)
|
||||
{
|
||||
uint32 count = remaining->Fetch()[0].Get<uint32>();
|
||||
|
||||
if (count == 0)
|
||||
{
|
||||
// No items left, deactivate corpse
|
||||
CharacterDatabase.Execute(
|
||||
"UPDATE lost_corpses SET active = 0 WHERE lost_corpse_id = {}",
|
||||
corpseId
|
||||
);
|
||||
|
||||
// Remove lootability in-game
|
||||
if (Corpse* corpse = ObjectAccessor::GetCorpse(*this, GetLootGUID()))
|
||||
{
|
||||
corpse->RemoveFlag(CORPSE_FIELD_DYNAMIC_FLAGS, CORPSE_DYNFLAG_LOOTABLE);
|
||||
}
|
||||
}
|
||||
}
|
||||
CheckCorpse(corpseId);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1101,6 +1101,9 @@ public:
|
|||
explicit Player(WorldSession* session);
|
||||
~Player() override;
|
||||
|
||||
void CheckCorpse(uint32 lostCorpseId, ObjectGuid corpseGuid = ObjectGuid::Empty);
|
||||
void CheckCorpseByGUID(ObjectGuid corpseGuid);
|
||||
|
||||
void CleanupsBeforeDelete(bool finalCleanup = true) override;
|
||||
|
||||
void AddToWorld() override;
|
||||
|
|
|
|||
|
|
@ -17,12 +17,14 @@
|
|||
|
||||
#include "Corpse.h"
|
||||
#include "Creature.h"
|
||||
#include "DatabaseEnvFwd.h"
|
||||
#include "GameObject.h"
|
||||
#include "Group.h"
|
||||
#include "LootItemStorage.h"
|
||||
#include "LootMgr.h"
|
||||
#include "Object.h"
|
||||
#include "ObjectAccessor.h"
|
||||
#include "ObjectGuid.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "Opcodes.h"
|
||||
#include "Player.h"
|
||||
|
|
@ -146,7 +148,46 @@ void WorldSession::HandleLootMoneyOpcode(WorldPacket& /*recvData*/)
|
|||
loot = &bones->loot;
|
||||
shareMoney = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
player->SendLootError(guid, LOOT_ERROR_DIDNT_KILL);
|
||||
break;
|
||||
}
|
||||
|
||||
QueryResult result = CharacterDatabase.Query(
|
||||
"SELECT lost_corpse_id, money "
|
||||
"FROM lost_corpses "
|
||||
"WHERE corpse_guid = {} AND player_guid = {} "
|
||||
"AND active = 1 AND money_collected = 0 "
|
||||
"AND SQRT(POW(position_x - {}, 2) + POW(position_y - {}, 2) + POW(position_z - {}, 2)) <= 5",
|
||||
bones->GetGUID().GetCounter(),
|
||||
player->GetGUID().GetCounter(),
|
||||
player->GetPositionX(),
|
||||
player->GetPositionY(),
|
||||
player->GetPositionZ()
|
||||
);
|
||||
|
||||
if (result)
|
||||
{
|
||||
Field* fields = result->Fetch();
|
||||
|
||||
uint32 lostCorpseId = fields[0].Get<uint32>();
|
||||
uint32 totalMoney = fields[1].Get<uint32>();
|
||||
|
||||
loot->gold = totalMoney;
|
||||
|
||||
CharacterDatabase.Execute(
|
||||
"UPDATE lost_corpses SET money_collected = 1 "
|
||||
"WHERE lost_corpse_id = {}",
|
||||
lostCorpseId
|
||||
);
|
||||
|
||||
player->CheckCorpse(lostCorpseId);
|
||||
}
|
||||
else
|
||||
{
|
||||
loot->gold = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case HighGuid::Item:
|
||||
|
|
@ -342,6 +383,9 @@ void WorldSession::DoLootRelease(ObjectGuid lguid)
|
|||
|
||||
loot = &corpse->loot;
|
||||
|
||||
ObjectGuid corpseGUID = corpse->GetGUID();
|
||||
player->CheckCorpseByGUID(corpseGUID);
|
||||
|
||||
// Xinef: Buggs client? (Opening loot after closing)
|
||||
//if (loot->isLooted())
|
||||
//{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue