Skip to content

Commit

Permalink
Creature: Implement CreatureStaticFlags3::CAN_BE_MULTITAPPED
Browse files Browse the repository at this point in the history
  • Loading branch information
killerwife committed Dec 27, 2024
1 parent 54f6bf2 commit c83f2b8
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 13 deletions.
17 changes: 12 additions & 5 deletions src/game/Entities/Creature.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -416,7 +416,7 @@ bool Creature::InitEntry(uint32 Entry, CreatureData const* data /*=nullptr*/, Ga

if (GetSettings().HasFlag(CreatureStaticFlags::CAN_WIELD_LOOT)) // override from loot if any
{
PrepareBodyLootState();
PrepareBodyLootState(nullptr);
if (m_loot != nullptr)
{
auto [mh, oh, ranged] = m_loot->GetQualifiedWeapons();
Expand Down Expand Up @@ -1095,7 +1095,7 @@ bool Creature::CanTrainAndResetTalentsOf(Player* pPlayer) const
&& pPlayer->getClass() == GetCreatureInfo()->TrainerClass;
}

void Creature::PrepareBodyLootState()
void Creature::PrepareBodyLootState(Unit* killer)
{
// if can weild loot - already generated on spawn
if (GetSettings().HasFlag(CreatureStaticFlags::CAN_WIELD_LOOT) && m_loot != nullptr && m_loot->GetLootType() == LOOT_CORPSE)
Expand All @@ -1109,10 +1109,14 @@ void Creature::PrepareBodyLootState()
SetLootStatus(CREATURE_LOOT_STATUS_LOOTED);
else
{
Player* killer = GetLootRecipient();
Player* looter = nullptr;
if (GetSettings().HasFlag(CreatureStaticFlags3::CAN_BE_MULTITAPPED))
looter = dynamic_cast<Player*>(killer);
else
looter = GetLootRecipient();

if (killer)
m_loot = new Loot(killer, this, LOOT_CORPSE);
if (looter || GetSettings().HasFlag(CreatureStaticFlags::CAN_WIELD_LOOT))
m_loot = new Loot(looter, this, LOOT_CORPSE);
}

if (m_lootStatus == CREATURE_LOOT_STATUS_LOOTED && !HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE))
Expand Down Expand Up @@ -1189,6 +1193,9 @@ void Creature::SetLootRecipient(Unit* unit)
return;
}

if (GetSettings().HasFlag(CreatureStaticFlags3::CAN_BE_MULTITAPPED))
return;

Player* player = unit->GetBeneficiaryPlayer();
if (!player) // normal creature, no player involved
return;
Expand Down
2 changes: 1 addition & 1 deletion src/game/Entities/Creature.h
Original file line number Diff line number Diff line change
Expand Up @@ -723,7 +723,7 @@ class Creature : public Unit
virtual void DeleteFromDB(); // overwrited in Pet
static void DeleteFromDB(uint32 lowguid, CreatureData const* data);

void PrepareBodyLootState();
void PrepareBodyLootState(Unit* killer);
CreatureLootStatus GetLootStatus() const { return m_lootStatus; }
virtual void InspectingLoot() override;
void SetLootStatus(CreatureLootStatus status, bool forced = false);
Expand Down
9 changes: 5 additions & 4 deletions src/game/Entities/Unit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1476,6 +1476,11 @@ void Unit::JustKilledCreature(Unit* killer, Creature* victim, Player* responsibl

bool isPet = victim->IsPet();

/* ******************************** Prepare loot if can ************************************ */
// only lootable if it has loot or can drop gold, must be done before threat list is cleared
if (!isPet || !victim->GetSettings().HasFlag(CreatureStaticFlags::DESPAWN_INSTANTLY))

This comment has been minimized.

Copy link
@Exxenoz

Exxenoz Dec 27, 2024

Member

Pets that don't have the CreatureStaticFlags::DESPAWN_INSTANTLY flag set are lootable? If this behaviour is not intended, then the condition should be && instead of ||

This comment has been minimized.

Copy link
@insunaa

insunaa Dec 27, 2024

Contributor

Do target dummies count as pets?

victim->PrepareBodyLootState(killer);

/* ********************************* Set Death finally ************************************* */
DEBUG_FILTER_LOG(LOG_FILTER_DAMAGE, "SET JUST_DIED");
victim->SetDeathState(JUST_DIED); // if !spiritOfRedemtionTalentReady always true for unit
Expand All @@ -1491,11 +1496,7 @@ void Unit::JustKilledCreature(Unit* killer, Creature* victim, Player* responsibl
if (isPet)
return; // Pets might have been unsummoned at this place, do not handle them further!

/* ******************************** Prepare loot if can ************************************ */
victim->DeleteThreatList();

// only lootable if it has loot or can drop gold
victim->PrepareBodyLootState();
}

void Unit::PetOwnerKilledUnit(Unit* pVictim)
Expand Down
13 changes: 10 additions & 3 deletions src/game/Loot/LootMgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1687,8 +1687,15 @@ Loot::Loot(Player* player, Creature* creature, LootType type) :
{
case LOOT_CORPSE:
{
// setting loot right
SetGroupLootRight(player);
if (creature->GetSettings().HasFlag(CreatureStaticFlags3::CAN_BE_MULTITAPPED))
{
for (auto& threatEntry : creature->getThreatManager().getThreatList())
if (threatEntry->getTarget()->IsPlayer())
m_ownerSet.insert(threatEntry->getTarget()->GetObjectGuid());
}
else
// setting loot right
SetGroupLootRight(player);
m_clientLootType = CLIENT_LOOT_CORPSE;

if ((creatureInfo->LootId && FillLoot(creatureInfo->LootId, LootTemplates_Creature, player, false)) || creatureInfo->MaxLootGold > 0)
Expand Down Expand Up @@ -2097,7 +2104,7 @@ InventoryResult Loot::SendItem(Player* target, LootItem* lootItem, bool sendErro

std::tuple<uint32, uint32, uint32> Loot::GetQualifiedWeapons()
{
uint32 mh, oh, ranged;
uint32 mh = 0, oh = 0, ranged = 0;
uint32 mhType = 0;
for (auto const& itr : m_lootItems)
{
Expand Down

0 comments on commit c83f2b8

Please sign in to comment.