fix(Scripts/BlackrockSpire): Urok Doomhowl - improvements: (#9067)

The mobs should attack the pike if there is no players around
The boss should not despawning after summon
Urok's Tribute Pile with Pike and Head should disapear after Urok appear
Fixes #9023
This commit is contained in:
UltraNix
2021-11-12 13:46:07 +01:00
committed by GitHub
parent 4a69d1fc07
commit 7201d8840f
10 changed files with 68 additions and 22 deletions

View File

@@ -0,0 +1,31 @@
INSERT INTO `version_db_world` (`sql_rev`) VALUES ('1636407148113092900');
UPDATE `smart_scripts` SET `action_param2`=7, `action_param3`=0 WHERE `entryorguid`=17558400 AND `id`=17;
DELETE FROM `smart_scripts` WHERE `entryorguid`=17558400 AND `id`=18;
DELETE FROM `smart_scripts` WHERE `entryorguid` IN (10601) AND `id`>2;
INSERT INTO `smart_scripts` VALUES
(10601,0,3,4,54,0,100,0,0,0,0,0,0,11,12980,0,0,0,0,0,1,0,0,0,0,0,0,0,0,'Urok Enforcer - on just summoned - cast Simple Teleport'),
(10601,0,4,0,61,0,100,0,0,0,0,0,0,69,1,0,0,2,0,0,20,175621,50,1,0,0,0,0,0,'Urok Enforcer - on summoned - move to Urok Pike'),
(10601,0,5,0,34,0,100,0,8,1,0,0,0,22,2,0,0,0,0,0,1,0,0,0,0,0,0,0,0,'Urok Enforcer - on pos 1 - set event phase to 2'),
(10601,0,6,7,1,2,100,0,1500,1500,2500,3500,0,5,37,0,0,0,0,0,1,0,0,0,0,0,0,0,0,'Urok Enforcer - OOC (phase 2) - play emote 37'),
(10601,0,7,0,61,2,100,0,0,0,0,0,0,63,1,1,0,0,0,0,20,175621,10,0,0,0,0,0,0,'Urok Enforcer - OOC (phase 2) - set counter 1 Urok Pike'),
(10601,0,8,0,4,0,100,0,0,0,0,0,0,22,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,'Urok Enforcer - on aggro - set phase to 0'),
(10601,0,9,0,21,0,100,0,0,0,0,0,0,22,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,'Urok Enforcer - on just reached home - set event phase to 1'),
(10601,0,10,0,1,1,100,1,500,500,0,0,0,69,1,0,0,2,0,0,20,175621,50,1,0,0,0,0,0,'Urok Enforcer - OOC (phase 1) - move to Urok Pike');
DELETE FROM `smart_scripts` WHERE `entryorguid` IN (10602) AND `id`>4;
INSERT INTO `smart_scripts` VALUES
(10602,0,5,6,54,0,100,0,0,0,0,0,0,11,12980,0,0,0,0,0,1,0,0,0,0,0,0,0,0,'Urok Ogre Magus - on just summoned - cast Simple Teleport'),
(10602,0,6,0,61,0,100,0,0,0,0,0,0,69,1,0,0,2,0,0,20,175621,50,1,0,0,0,0,0,'Urok Ogre Magus - on just summoned - move to Urok Pike'),
(10602,0,7,0,34,0,100,0,8,1,0,0,0,22,2,0,0,0,0,0,1,0,0,0,0,0,0,0,0,'Urok Ogre Magus - on pos 1 - set event phase to 2'),
(10602,0,8,9,1,2,100,0,1500,1500,2500,3500,0,5,37,0,0,0,0,0,1,0,0,0,0,0,0,0,0,'Urok Ogre Magus - OOC (phase 2) - play emote 37'),
(10602,0,9,0,61,2,100,0,0,0,0,0,0,63,1,1,0,0,0,0,20,175621,10,0,0,0,0,0,0,'Urok Ogre Magus - OOC (phase 2) - set counter 1 Urok Pike'),
(10602,0,10,0,4,0,100,0,0,0,0,0,0,22,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,'Urok Ogre Magus - on aggro - set phase to 0'),
(10602,0,11,0,21,0,100,0,0,0,0,0,0,22,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,'Urok Ogre Magus - on just reached home - set event phase to 1'),
(10602,0,12,0,1,1,100,1,500,500,0,0,0,69,1,0,0,2,0,0,20,175621,50,1,0,0,0,0,0,'Urok Ogre Magus - OOC (phase 1) - move to Urok Pike');
DELETE FROM `smart_scripts` WHERE `entryorguid` IN (175621) AND `id`>1;
INSERT INTO `smart_scripts` VALUES
(175621,1,2,3,77,0,100,0,1,20,5000,5000,0,34,4,2,0,0,0,0,1,0,0,0,0,0,0,0,0, 'Ur\'s Tribute Pile - on 20 count - fail event'),
(175621,1,3,0,61,0,100,0,0,0,0,0,0,41,0,180,0,0,0,0,1,0,0,0,0,0,0,0,0, 'Ur\'s Tribute Pile - on 20 count - despawn');

View File

@@ -742,9 +742,9 @@ Creature* GetClosestCreatureWithEntry(WorldObject* source, uint32 entry, float m
return source->FindNearestCreature(entry, maxSearchRange, alive);
}
GameObject* GetClosestGameObjectWithEntry(WorldObject* source, uint32 entry, float maxSearchRange)
GameObject* GetClosestGameObjectWithEntry(WorldObject* source, uint32 entry, float maxSearchRange, bool onlySpawned /*= false*/)
{
return source->FindNearestGameObject(entry, maxSearchRange);
return source->FindNearestGameObject(entry, maxSearchRange, onlySpawned);
}
void GetCreatureListWithEntryInGrid(std::list<Creature*>& list, WorldObject* source, uint32 entry, float maxSearchRange)

View File

@@ -504,7 +504,7 @@ protected:
// SD2 grid searchers.
Creature* GetClosestCreatureWithEntry(WorldObject* source, uint32 entry, float maxSearchRange, bool alive = true);
GameObject* GetClosestGameObjectWithEntry(WorldObject* source, uint32 entry, float maxSearchRange);
GameObject* GetClosestGameObjectWithEntry(WorldObject* source, uint32 entry, float maxSearchRange, bool onlySpawned = false);
void GetCreatureListWithEntryInGrid(std::list<Creature*>& list, WorldObject* source, uint32 entry, float maxSearchRange);
void GetGameObjectListWithEntryInGrid(std::list<GameObject*>& list, WorldObject* source, uint32 entry, float maxSearchRange);
void GetDeadCreatureListInGrid(std::list<Creature*>& list, WorldObject* source, float maxSearchRange, bool alive = false);

View File

@@ -3681,7 +3681,7 @@ ObjectList* SmartScript::GetTargets(SmartScriptHolder const& e, Unit* invoker /*
}
case SMART_TARGET_CLOSEST_GAMEOBJECT:
{
GameObject* target = GetClosestGameObjectWithEntry(GetBaseObject(), e.target.closest.entry, (float)(e.target.closest.dist ? e.target.closest.dist : 100));
GameObject* target = GetClosestGameObjectWithEntry(GetBaseObject(), e.target.closestGameobject.entry, (float)(e.target.closestGameobject.dist ? e.target.closestGameobject.dist : 100), e.target.closestGameobject.onlySpawned);
if (target)
l->push_back(target);
break;

View File

@@ -1460,6 +1460,13 @@ struct SmartTarget
uint32 dead;
} closest;
struct
{
uint32 entry;
uint32 dist;
uint32 onlySpawned;
} closestGameobject;
struct
{
uint32 maxDist;

View File

@@ -2533,10 +2533,10 @@ Creature* WorldObject::FindNearestCreature(uint32 entry, float range, bool alive
return creature;
}
GameObject* WorldObject::FindNearestGameObject(uint32 entry, float range) const
GameObject* WorldObject::FindNearestGameObject(uint32 entry, float range, bool onlySpawned /*= false*/) const
{
GameObject* go = nullptr;
Acore::NearestGameObjectEntryInObjectRangeCheck checker(*this, entry, range);
Acore::NearestGameObjectEntryInObjectRangeCheck checker(*this, entry, range, onlySpawned);
Acore::GameObjectLastSearcher<Acore::NearestGameObjectEntryInObjectRangeCheck> searcher(this, go, checker);
Cell::VisitGridObjects(this, searcher, range);
return go;
@@ -2816,7 +2816,8 @@ void WorldObject::GetContactPoint(const WorldObject* obj, float& x, float& y, fl
// angle to face `obj` to `this` using distance includes size of `obj`
GetNearPoint(obj, x, y, z, obj->GetObjectSize(), distance2d, GetAngle(obj));
if (fabs(this->GetPositionZ() - z) > 3.0f || !IsWithinLOS(x, y, z))
// Exclude gameobjects from LoS calculations
if (fabs(this->GetPositionZ() - z) > 3.0f || (GetTypeId() != TYPEID_GAMEOBJECT && !IsWithinLOS(x, y, z)))
{
x = this->GetPositionX();
y = this->GetPositionY();

View File

@@ -812,7 +812,7 @@ public:
void SummonCreatureGroup(uint8 group, std::list<TempSummon*>* list = nullptr);
[[nodiscard]] Creature* FindNearestCreature(uint32 entry, float range, bool alive = true) const;
[[nodiscard]] GameObject* FindNearestGameObject(uint32 entry, float range) const;
[[nodiscard]] GameObject* FindNearestGameObject(uint32 entry, float range, bool onlySpawned = false) const;
[[nodiscard]] GameObject* FindNearestGameObjectOfType(GameobjectTypes type, float range) const;
[[nodiscard]] Player* SelectNearestPlayer(float distance = 0) const;

View File

@@ -690,10 +690,12 @@ namespace Acore
class NearestGameObjectEntryInObjectRangeCheck
{
public:
NearestGameObjectEntryInObjectRangeCheck(WorldObject const& obj, uint32 entry, float range) : i_obj(obj), i_entry(entry), i_range(range) {}
NearestGameObjectEntryInObjectRangeCheck(WorldObject const& obj, uint32 entry, float range, bool onlySpawned = false) :
i_obj(obj), i_entry(entry), i_range(range), i_onlySpawned(onlySpawned) { }
bool operator()(GameObject* go)
{
if (go->GetEntry() == i_entry && i_obj.IsWithinDistInMap(go, i_range))
if (go->GetEntry() == i_entry && i_obj.IsWithinDistInMap(go, i_range) && (!i_onlySpawned || go->isSpawned()))
{
i_range = i_obj.GetDistance(go); // use found GO range as new range limit for next check
return true;
@@ -704,6 +706,7 @@ namespace Acore
WorldObject const& i_obj;
uint32 i_entry;
float i_range;
bool i_onlySpawned;
// prevent clone this object
NearestGameObjectEntryInObjectRangeCheck(NearestGameObjectEntryInObjectRangeCheck const&);

View File

@@ -49,17 +49,22 @@ public:
{
boss_urok_doomhowlAI(Creature* creature) : BossAI(creature, DATA_UROK_DOOMHOWL) {}
void Reset() override
{
_Reset();
}
void InitializeAI() override
{
me->CastSpell(me, SPELL_UROK_SPAWN, true);
BossAI::InitializeAI();
Talk(SAY_SUMMON);
DoZoneInCombat(nullptr, 100.0f);
if (GameObject* challenge = instance->instance->GetGameObject(instance->GetGuidData(GO_UROK_CHALLENGE)))
{
challenge->Delete();
}
if (GameObject* pile = instance->instance->GetGameObject(instance->GetGuidData(GO_UROK_PILE)))
{
pile->DespawnOrUnsummon(0ms, Seconds(MONTH));
}
}
void EnterCombat(Unit* /*who*/) override
@@ -70,11 +75,6 @@ public:
events.ScheduleEvent(SPELL_INTIMIDATING_ROAR, urand(25000, 30000));
}
void JustDied(Unit* /*killer*/) override
{
_JustDied();
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())

View File

@@ -376,7 +376,7 @@ public:
case DATA_UROK_DOOMHOWL:
if (data == FAIL)
{
if (!(GetBossState(DATA_UROK_DOOMHOWL) == NOT_STARTED))
if (GetBossState(DATA_UROK_DOOMHOWL) != NOT_STARTED)
{
SetBossState(DATA_UROK_DOOMHOWL, NOT_STARTED);
if (GameObject* challenge = instance->GetGameObject(go_urokChallenge))
@@ -395,7 +395,7 @@ public:
circle->Delete();
}
}
for (const auto& mobGUID: UrokMobs)
for (const auto& mobGUID : UrokMobs)
{
if (Creature* mob = instance->GetCreature(mobGUID))
{
@@ -510,6 +510,10 @@ public:
return go_emberseerrunes[6];
case GO_PORTCULLIS_ACTIVE:
return go_portcullis_active;
case GO_UROK_PILE:
return go_urokPile;
case GO_UROK_CHALLENGE:
return go_urokChallenge;
default:
break;
}