diff --git a/src/modules/PlayerbotV2/playerbotv2_core_hooks.thordekk.patch b/src/modules/PlayerbotV2/playerbotv2_core_hooks.thordekk.patch index d74eaff818..1c981228fc 100644 --- a/src/modules/PlayerbotV2/playerbotv2_core_hooks.thordekk.patch +++ b/src/modules/PlayerbotV2/playerbotv2_core_hooks.thordekk.patch @@ -1305,15 +1305,17 @@ index b82bd78f34..d58f648db8 100644 setCompoundState.StateChanges.emplace_back(SMSG_MOVE_ROOT, m_movementCounter++); if (HasAuraType(SPELL_AURA_FEATHER_FALL)) -@@ -27740,6 +27836,13 @@ void Player::StoreLootItem(ObjectGuid lootWorldObjectGuid, uint8 lootSlot, Loot* +@@ -27740,6 +27836,15 @@ void Player::StoreLootItem(ObjectGuid lootWorldObjectGuid, uint8 lootSlot, Loot* Item* newitem = StoreNewItem(dest, item->itemid, true, item->randomBonusListId, item->GetAllowedLooters(), item->context); +#if TRINITY_PLAYERBOT_V2 + // Quest-item propagation: when the owner loots a quest item, + // give a copy to all owned bots who still need it. (f47eaa0740) -+ if (newitem) -+ Playerbot::Hooks::OnPlayerLootItem(this, item->itemid, item->count); ++ // Fire regardless of whether StoreNewItem created a physical item — ++ // quest-BOUND items return nullptr from StoreNewItem (objective ++ // guard) but must still propagate to owned bots. ++ Playerbot::Hooks::OnPlayerLootItem(this, item->itemid, item->count); +#endif + if (newitem && (newitem->GetQuality() > ITEM_QUALITY_EPIC || (newitem->GetQuality() == ITEM_QUALITY_EPIC && newitem->GetItemLevel(this) >= MinNewsItemLevel))) @@ -1360,7 +1362,7 @@ index 4577fffa77..1126d89a09 100644 void RemoveLootRoll(LootRoll* roll); diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp -index 1f376653f2..971fb43af8 100644 +index 43e3ba2..ac73ca7 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -91,6 +91,7 @@ @@ -1371,7 +1373,7 @@ index 1f376653f2..971fb43af8 100644 #include #include #include -@@ -870,6 +871,13 @@ bool Unit::HasBreakableByDamageCrowdControlAura(Unit const* excludeCasterChannel +@@ -884,6 +885,13 @@ bool Unit::HasBreakableByDamageCrowdControlAura(Unit const* excludeCasterChannel // Hook for OnDamage Event sScriptMgr->OnDamage(attacker, victim, tmpDamage); @@ -1385,7 +1387,7 @@ index 1f376653f2..971fb43af8 100644 // if any script modified damage, we need to also apply the same modification to unscaled damage value if (tmpDamage != damageTaken) { -@@ -6041,6 +6049,10 @@ bool Unit::Attack(Unit* victim, bool meleeAttack) +@@ -6055,6 +6063,10 @@ bool Unit::Attack(Unit* victim, bool meleeAttack) if (Creature* cControlled = controlled->ToCreature()) if (CreatureAI* controlledAI = cControlled->AI()) controlledAI->OwnerAttacked(victim); @@ -1396,7 +1398,7 @@ index 1f376653f2..971fb43af8 100644 } return true; -@@ -6624,6 +6636,13 @@ void Unit::SetCharm(Unit* charm, bool apply) +@@ -6636,6 +6648,13 @@ void Unit::SetCharm(Unit* charm, bool apply) // Hook for OnHeal Event sScriptMgr->OnHeal(healer, victim, (uint32&)gain); @@ -1410,7 +1412,7 @@ index 1f376653f2..971fb43af8 100644 Unit* unit = healer; if (healer && healer->GetTypeId() == TYPEID_UNIT && healer->IsTotem()) unit = healer->GetOwner(); -@@ -8430,6 +8431,15 @@ void Unit::Mount(uint32 mount, uint32 VehicleId, uint32 creatureEntry) +@@ -8443,6 +8462,15 @@ void Unit::Mount(uint32 mount, uint32 VehicleId, uint32 creatureEntry) SetUnitFlag(UNIT_FLAG_MOUNT); @@ -1426,7 +1428,7 @@ index 1f376653f2..971fb43af8 100644 CalculateHoverHeight(); if (Player* player = ToPlayer()) -@@ -8460,6 +8470,13 @@ void Unit::Dismount() +@@ -8473,6 +8501,13 @@ void Unit::Dismount() if (!IsMounted()) return; @@ -1440,7 +1442,7 @@ index 1f376653f2..971fb43af8 100644 SetMountDisplayId(0); RemoveUnitFlag(UNIT_FLAG_MOUNT); -@@ -11459,6 +11478,13 @@ void Unit::SetMeleeAnimKitId(uint16 animKitId) +@@ -11489,6 +11524,13 @@ void Unit::SetMeleeAnimKitId(uint16 animKitId) if (attacker && !attacker->IsInMap(victim)) attacker = nullptr; @@ -1451,11 +1453,10 @@ index 1f376653f2..971fb43af8 100644 + Playerbot::Hooks::OnDeath(victim, attacker); +#endif + - // find player: owner of controlled `this` or `this` itself maybe - Player* player = nullptr; - if (attacker) -@@ -13071,5 +13113,13 @@ void Unit::_ExitVehicle(Position const* exitPosition) - // If the player is on mounted duel and exits the mount, he should immediatly lose the duel + // find player: owner of controlled `this` or `this` itself maybe + Player* player = nullptr; + if (attacker) +@@ -13682,6 +13724,14 @@ void Unit::_ExitVehicle(Position const* exitPosition) if (player && player->duel && player->duel->IsMounted) player->DuelComplete(DUEL_FLED); @@ -1468,6 +1469,11 @@ index 1f376653f2..971fb43af8 100644 +#endif + SetControlled(false, UNIT_STATE_ROOT); // SMSG_MOVE_FORCE_UNROOT, ~MOVEMENTFLAG_ROOT + + AddUnitState(UNIT_STATE_MOVE); +diff --git a/src/server/game/Entities/Unit/Unit.cpp.rej b/src/server/game/Entities/Unit/Unit.cpp.rej +new file mode 100644 +index 0000000..e69de29 diff --git a/src/server/game/Groups/GroupMgr.h b/src/server/game/Groups/GroupMgr.h index 58951339b2..7ce860e770 100644 --- a/src/server/game/Groups/GroupMgr.h