From 18a6e7b3530a6e956115ef17d3c2ffa5f19ad6ae Mon Sep 17 00:00:00 2001 From: trickerer Date: Sun, 10 Nov 2024 21:22:35 +0700 Subject: [PATCH] NPCBots: Fix a crash happening if Death Knight bot casts Dancing Rune Weapon. Make non-pet summons created by bots ignore faction hostility rules and attack whatever bot can (cherry picked from commit 196070de249cd6179ceedca5afcd1219da763681) # Conflicts: # src/server/game/AI/NpcBots/bot_death_knight_ai.cpp # src/server/game/Entities/Object/Object.cpp # src/server/game/Spells/SpellEffects.cpp --- .../game/AI/NpcBots/bot_death_knight_ai.cpp | 17 ++++------- src/server/game/Entities/Unit/Unit.cpp | 6 +++- src/server/scripts/Spells/spell_dk.cpp | 29 +++++++++++++++++++ 3 files changed, 39 insertions(+), 13 deletions(-) diff --git a/src/server/game/AI/NpcBots/bot_death_knight_ai.cpp b/src/server/game/AI/NpcBots/bot_death_knight_ai.cpp index 635e03ad5eda93..75bda623aff5a1 100644 --- a/src/server/game/AI/NpcBots/bot_death_knight_ai.cpp +++ b/src/server/game/AI/NpcBots/bot_death_knight_ai.cpp @@ -1698,18 +1698,6 @@ class death_knight_bot : public CreatureScript botPet = myPet; } - void UnsummonAll(bool savePets = true) override - { - UnsummonPet(savePets); - } - - void SummonedCreatureDies(Creature* /*summon*/, Unit* /*killer*/) override - { - //BOT_LOG_ERROR("entities.unit", "SummonedCreatureDies: %s's %s", me->GetName().c_str(), summon->GetName().c_str()); - //if (summon == botPet) - // botPet = nullptr; - } - void SummonedCreatureDespawn(Creature* summon) override { //all hunter bot pets despawn at death or manually (gossip, teleport, etc.) @@ -1721,6 +1709,11 @@ class death_knight_bot : public CreatureScript } } + void UnsummonAll(bool savePets = true) override + { + UnsummonPet(savePets); + } + uint32 GetAIMiscValue(uint32 data) const override { switch (data) diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 3f678e06f1cd68..2e51efbd6ad8c6 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -14834,9 +14834,13 @@ bool Unit::_IsValidAttackTarget(Unit const* target, SpellInfo const* bySpell, Wo } //end npcbot - //npcbot + //npcbot: allow bots and their summons to ignore this rule if (IsNPCBotOrPet() || target->IsNPCBotOrPet()) {} + else if (GetOwnerGUID() && GetOwnerGUID().IsCreature() && sObjectMgr->GetCreatureTemplate(GetOwnerGUID().GetEntry())->IsNPCBotOrPet()) + {} + else if (target->GetOwnerGUID() && target->GetOwnerGUID().IsCreature() && sObjectMgr->GetCreatureTemplate(target->GetOwnerGUID().GetEntry())->IsNPCBotOrPet()) + {} else //end npcbot // CvC case - can attack each other only when one of them is hostile diff --git a/src/server/scripts/Spells/spell_dk.cpp b/src/server/scripts/Spells/spell_dk.cpp index ae42954d1bb5e7..60c0a9afbc8fe1 100644 --- a/src/server/scripts/Spells/spell_dk.cpp +++ b/src/server/scripts/Spells/spell_dk.cpp @@ -615,6 +615,23 @@ class spell_dk_dancing_rune_weapon : public AuraScript bool CheckProc(ProcEventInfo& eventInfo) { + //npcbot + if (eventInfo.GetActor() && eventInfo.GetActor()->IsNPCBot()) + { + if (!eventInfo.GetActor() || !eventInfo.GetActionTarget() || !eventInfo.GetActionTarget()->IsAlive()) + return false; + + if (SpellInfo const* spellInfo = eventInfo.GetSpellInfo()) + { + if (spellInfo->SpellFamilyFlags.HasFlag(0x20A1220, 0x10000000, 0x0) || spellInfo->IsTargetingArea() && eventInfo.GetActor() != eventInfo.GetActionTarget() || + spellInfo->HasEffect(SPELL_EFFECT_SUMMON) || spellInfo->IsPositive()) + return false; + } + + return true; + } + //end npcbot + if (!eventInfo.GetActor() || !eventInfo.GetActionTarget() || !eventInfo.GetActionTarget()->IsAlive() || !eventInfo.GetActor()->IsPlayer()) return false; @@ -702,6 +719,18 @@ class spell_dk_dancing_rune_weapon_visual : public AuraScript void HandleEffectApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) { PreventDefaultAction(); + //npcbot + if (GetUnitOwner()->ToTempSummon()->GetSummonerGUID().IsCreature()) + { + if (Unit* owner = GetUnitOwner()->ToTempSummon()->GetSummonerUnit()) + { + GetUnitOwner()->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, owner->GetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 0)); + GetUnitOwner()->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1, owner->GetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1)); + GetUnitOwner()->SetFloatValue(UNIT_FIELD_COMBATREACH, 0.01f); + } + } + else + //end npcbot if (Unit* owner = GetUnitOwner()->ToTempSummon()->GetSummonerUnit()) { GetUnitOwner()->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, owner->GetUInt32Value(PLAYER_VISIBLE_ITEM_16_ENTRYID));