mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-01-16 10:30:27 +00:00
fix(Core/Loot): Set skinnable flag only after all loot was taken. Source: TrinityCore. (#9573)
Fixes #9318
This commit is contained in:
@@ -1793,11 +1793,6 @@ void Creature::setDeathState(DeathState s, bool despawn)
|
||||
|
||||
setActive(false);
|
||||
|
||||
if (!IsPet() && GetCreatureTemplate()->SkinLootId)
|
||||
if (LootTemplates_Skinning.HaveLootFor(GetCreatureTemplate()->SkinLootId))
|
||||
if (hasLootRecipient())
|
||||
SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE);
|
||||
|
||||
if (HasSearchedAssistance())
|
||||
{
|
||||
SetNoSearchAssistance(false);
|
||||
@@ -1869,6 +1864,7 @@ void Creature::Respawn(bool force)
|
||||
LOG_DEBUG("entities.unit", "Respawning creature %s (SpawnId: %u, %s)", GetName().c_str(), GetSpawnId(), GetGUID().ToString().c_str());
|
||||
m_respawnTime = 0;
|
||||
ResetPickPocketLootTime();
|
||||
loot.clear();
|
||||
|
||||
if (m_originalEntry != GetEntry())
|
||||
UpdateEntry(m_originalEntry);
|
||||
@@ -2710,25 +2706,33 @@ void Creature::GetRespawnPosition(float& x, float& y, float& z, float* ori, floa
|
||||
|
||||
void Creature::AllLootRemovedFromCorpse()
|
||||
{
|
||||
if (!HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE))
|
||||
if (loot.loot_type != LOOT_SKINNING && !IsPet() && GetCreatureTemplate()->SkinLootId && hasLootRecipient())
|
||||
{
|
||||
time_t now = time(nullptr);
|
||||
if (m_corpseRemoveTime <= now)
|
||||
return;
|
||||
if (LootTemplates_Skinning.HaveLootFor(GetCreatureTemplate()->SkinLootId))
|
||||
{
|
||||
SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE);
|
||||
}
|
||||
}
|
||||
|
||||
float decayRate;
|
||||
CreatureTemplate const* cinfo = GetCreatureTemplate();
|
||||
time_t now = time(nullptr);
|
||||
if (m_corpseRemoveTime <= now)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
decayRate = sWorld->getRate(RATE_CORPSE_DECAY_LOOTED);
|
||||
uint32 diff = uint32((m_corpseRemoveTime - now) * decayRate);
|
||||
float decayRate = sWorld->getRate(RATE_CORPSE_DECAY_LOOTED);
|
||||
uint32 diff = uint32((m_corpseRemoveTime - now) * decayRate);
|
||||
|
||||
m_respawnTime -= diff;
|
||||
m_respawnTime -= diff;
|
||||
|
||||
// corpse skinnable, but without skinning flag, and then skinned, corpse will despawn next update
|
||||
if (cinfo && cinfo->SkinLootId)
|
||||
m_corpseRemoveTime = time(nullptr);
|
||||
else
|
||||
m_corpseRemoveTime -= diff;
|
||||
// corpse skinnable, but without skinning flag, and then skinned, corpse will despawn next update
|
||||
if (loot.loot_type == LOOT_SKINNING)
|
||||
{
|
||||
m_corpseRemoveTime = time(nullptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_corpseRemoveTime -= diff;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5667,6 +5667,9 @@ bool Player::isAllowedToLoot(const Creature* creature)
|
||||
if (!loot->hasItemForAll() && !loot->hasItemFor(this)) // no loot in creature for this player
|
||||
return false;
|
||||
|
||||
if (loot->loot_type == LOOT_SKINNING)
|
||||
return creature->GetLootRecipientGUID() == GetGUID();
|
||||
|
||||
Group* thisGroup = GetGroup();
|
||||
if (!thisGroup)
|
||||
return this == creature->GetLootRecipient();
|
||||
|
||||
@@ -17116,9 +17116,16 @@ void Unit::Kill(Unit* killer, Unit* victim, bool durabilityLoss, WeaponAttackTyp
|
||||
if (!creature->IsPet() && creature->GetLootMode() > 0)
|
||||
{
|
||||
creature->DeleteThreatList();
|
||||
CreatureTemplate const* cInfo = creature->GetCreatureTemplate();
|
||||
if (cInfo && (cInfo->lootid || cInfo->maxgold > 0))
|
||||
|
||||
// must be after setDeathState which resets dynamic flags
|
||||
if (!creature->loot.empty())
|
||||
{
|
||||
creature->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
|
||||
}
|
||||
else
|
||||
{
|
||||
creature->AllLootRemovedFromCorpse();
|
||||
}
|
||||
}
|
||||
|
||||
// Call KilledUnit for creatures, this needs to be called after the lootable flag is set
|
||||
|
||||
Reference in New Issue
Block a user