diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index 655df486a..33d255a95 100644 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -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; } } diff --git a/src/server/game/Entities/Player/PlayerStorage.cpp b/src/server/game/Entities/Player/PlayerStorage.cpp index 43517b3f8..0dd417e64 100644 --- a/src/server/game/Entities/Player/PlayerStorage.cpp +++ b/src/server/game/Entities/Player/PlayerStorage.cpp @@ -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(); diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index b5624ec5a..93d8c503b 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -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