fix(Scripts/Outland): Fix crash in dragonmaw_race_npc by refreshing players pointer in lambda function. (#20333)

* fix(Scripts/Outland): Fix crash in dragonmaw_race_npc by refreshing players pointer in lambda function.

* Fix typo

* Refactor dragonmaw_race_npc to replace players pointer to GUID.

* Update src/server/scripts/Outland/zone_shadowmoon_valley.cpp

---------
This commit is contained in:
Anton Popovichenko
2024-11-01 23:14:08 +01:00
committed by GitHub
parent 2daedcec8a
commit b45c41cf6e

View File

@@ -1863,7 +1863,6 @@ struct dragonmaw_race_npc : public ScriptedAI
{ {
dragonmaw_race_npc(Creature* creature) : ScriptedAI(creature) dragonmaw_race_npc(Creature* creature) : ScriptedAI(creature)
{ {
_player = nullptr;
} }
void Reset() override void Reset() override
@@ -1873,14 +1872,17 @@ struct dragonmaw_race_npc : public ScriptedAI
me->SetWalk(true); me->SetWalk(true);
me->SetDisableGravity(false); me->SetDisableGravity(false);
me->GetMotionMaster()->MoveIdle(); me->GetMotionMaster()->MoveIdle();
_playerGUID.Clear();
} }
void sQuestAccept(Player* player, Quest const* /*quest*/) override void sQuestAccept(Player* player, Quest const* /*quest*/) override
{ {
_player = player;
me->RemoveNpcFlag(UNIT_NPC_FLAG_QUESTGIVER); me->RemoveNpcFlag(UNIT_NPC_FLAG_QUESTGIVER);
if (_player) if (player)
Talk(SAY_START, _player); {
_playerGUID = player->GetGUID();
Talk(SAY_START, player);
}
switch (me->GetEntry()) switch (me->GetEntry())
{ {
@@ -1915,38 +1917,38 @@ struct dragonmaw_race_npc : public ScriptedAI
void StartRace() void StartRace()
{ {
me->SetWalk(false); me->SetWalk(false);
ScheduleTimedEvent(5s, [&] ScheduleTimedEvent(5s, [&]
{ {
if (!_player) Player *player = ObjectAccessor::GetPlayer(me->GetMap(), _playerGUID);
FailQuest(); if (!player || !me->IsWithinDist(player, 100.f))
else if (!me->IsWithinDist(_player, 100.f)) FailQuest(player);
FailQuest();
}, 5s); }, 5s);
} }
void FailQuest() void FailQuest(Player *player)
{ {
if (_player) if (player)
{ {
switch (me->GetEntry()) switch (me->GetEntry())
{ {
case NPC_MUCKJAW: case NPC_MUCKJAW:
_player->FailQuest(QUEST_MUCKJAW); player->FailQuest(QUEST_MUCKJAW);
break; break;
case NPC_TROPE: case NPC_TROPE:
_player->FailQuest(QUEST_TROPE); player->FailQuest(QUEST_TROPE);
break; break;
case NPC_CORLOK: case NPC_CORLOK:
_player->FailQuest(QUEST_CORLOK); player->FailQuest(QUEST_CORLOK);
break; break;
case NPC_ICHMAN: case NPC_ICHMAN:
_player->FailQuest(QUEST_ICHMAN); player->FailQuest(QUEST_ICHMAN);
break; break;
case NPC_MULVERICK: case NPC_MULVERICK:
_player->FailQuest(QUEST_MULVERICK); player->FailQuest(QUEST_MULVERICK);
break; break;
case NPC_SKYSHATTER: case NPC_SKYSHATTER:
_player->FailQuest(QUEST_SKYSHATTER); player->FailQuest(QUEST_SKYSHATTER);
break; break;
default: default:
break; break;
@@ -1962,7 +1964,11 @@ struct dragonmaw_race_npc : public ScriptedAI
* Timers are placeholders * Timers are placeholders
* After spawned, the rest is done via SmartAI * After spawned, the rest is done via SmartAI
*/ */
if (!_player) if (_playerGUID.IsEmpty())
return;
Player *player = ObjectAccessor::GetPlayer(me->GetMap(), _playerGUID);
if (!player)
return; return;
switch (me->GetEntry()) switch (me->GetEntry())
@@ -1970,85 +1976,79 @@ struct dragonmaw_race_npc : public ScriptedAI
case NPC_MUCKJAW: case NPC_MUCKJAW:
ScheduleTimedEvent(4s, [&] ScheduleTimedEvent(4s, [&]
{ {
if (_player) Player *player = ObjectAccessor::GetPlayer(me->GetMap(), _playerGUID);
{ if (!player)
Position summonPos;
summonPos = me->GetRandomPoint(_player->GetPosition(), 15.f);
summonPos.m_positionZ = _player->GetPositionZ(); // So they don't spawn at ground height
me->SummonCreature(NPC_TARGET_MUCKJAW, summonPos, TEMPSUMMON_TIMED_DESPAWN, 10000);
}
else
return; return;
Position summonPos;
summonPos = me->GetRandomPoint(player->GetPosition(), 15.f);
summonPos.m_positionZ = player->GetPositionZ(); // So they don't spawn at ground height
me->SummonCreature(NPC_TARGET_MUCKJAW, summonPos, TEMPSUMMON_TIMED_DESPAWN, 10000);
}, 4s, 8s); }, 4s, 8s);
break; break;
case NPC_TROPE: case NPC_TROPE:
ScheduleTimedEvent(4s, [&] ScheduleTimedEvent(4s, [&]
{ {
if (_player) Player *player = ObjectAccessor::GetPlayer(me->GetMap(), _playerGUID);
{ if (!player)
Position summonPos; return;
summonPos = me->GetRandomPoint(_player->GetPosition(), 10.f);
summonPos.m_positionZ = _player->GetPositionZ(); Position summonPos;
me->SummonCreature(NPC_TARGET_TROPE, summonPos, TEMPSUMMON_TIMED_DESPAWN, 10000); summonPos = me->GetRandomPoint(player->GetPosition(), 10.f);
} summonPos.m_positionZ = player->GetPositionZ();
else me->SummonCreature(NPC_TARGET_TROPE, summonPos, TEMPSUMMON_TIMED_DESPAWN, 10000);
return;
}, 1s, 3s); }, 1s, 3s);
break; break;
case NPC_CORLOK: case NPC_CORLOK:
ScheduleTimedEvent(4s, [&] ScheduleTimedEvent(4s, [&]
{ {
if (_player) Player *player = ObjectAccessor::GetPlayer(me->GetMap(), _playerGUID);
{ if (!player)
Position summonPos; return;
summonPos = me->GetRandomPoint(_player->GetPosition(), 10.f);
summonPos.m_positionZ = _player->GetPositionZ(); Position summonPos;
me->SummonCreature(NPC_TARGET_CORLOK, summonPos, TEMPSUMMON_TIMED_DESPAWN, 10000); summonPos = me->GetRandomPoint(player->GetPosition(), 10.f);
} summonPos.m_positionZ = player->GetPositionZ();
else me->SummonCreature(NPC_TARGET_CORLOK, summonPos, TEMPSUMMON_TIMED_DESPAWN, 10000);
return;
}, 1s, 3s); }, 1s, 3s);
break; break;
case NPC_ICHMAN: case NPC_ICHMAN:
ScheduleTimedEvent(4s, [&] ScheduleTimedEvent(4s, [&]
{ {
if (_player) Player *player = ObjectAccessor::GetPlayer(me->GetMap(), _playerGUID);
{ if (!player)
Position summonPos; return;
summonPos = me->GetRandomPoint(_player->GetPosition(), 10.f);
summonPos.m_positionZ = _player->GetPositionZ(); Position summonPos;
me->SummonCreature(NPC_TARGET_ICHMAN, summonPos, TEMPSUMMON_TIMED_DESPAWN, 10000); summonPos = me->GetRandomPoint(player->GetPosition(), 10.f);
} summonPos.m_positionZ = player->GetPositionZ();
else me->SummonCreature(NPC_TARGET_ICHMAN, summonPos, TEMPSUMMON_TIMED_DESPAWN, 10000);
return;
}, 1s, 3s); }, 1s, 3s);
break; break;
case NPC_MULVERICK: case NPC_MULVERICK:
ScheduleTimedEvent(4s, [&] ScheduleTimedEvent(4s, [&]
{ {
if (_player) Player *player = ObjectAccessor::GetPlayer(me->GetMap(), _playerGUID);
{ if (!player)
Position summonPos; return;
summonPos = me->GetRandomPoint(_player->GetPosition(), 10.f);
summonPos.m_positionZ = _player->GetPositionZ(); Position summonPos;
me->SummonCreature(NPC_TARGET_MULVERICK, summonPos, TEMPSUMMON_TIMED_DESPAWN, 10000); summonPos = me->GetRandomPoint(player->GetPosition(), 10.f);
} summonPos.m_positionZ = player->GetPositionZ();
else me->SummonCreature(NPC_TARGET_MULVERICK, summonPos, TEMPSUMMON_TIMED_DESPAWN, 10000);
return;
}, 1s, 3s); }, 1s, 3s);
break; break;
case NPC_SKYSHATTER: case NPC_SKYSHATTER:
ScheduleTimedEvent(4s, [&] ScheduleTimedEvent(4s, [&]
{ {
if (_player) Player *player = ObjectAccessor::GetPlayer(me->GetMap(), _playerGUID);
{ if (!player)
Position summonPos; return;
summonPos = me->GetRandomPoint(_player->GetPosition(), 7.f);
summonPos.m_positionZ = _player->GetPositionZ(); // So they don't spawn at ground height Position summonPos;
me->SummonCreature(NPC_TARGET_SKYSHATTER, summonPos, TEMPSUMMON_TIMED_DESPAWN, 10000); summonPos = me->GetRandomPoint(player->GetPosition(), 7.f);
} summonPos.m_positionZ = player->GetPositionZ(); // So they don't spawn at ground height
else me->SummonCreature(NPC_TARGET_SKYSHATTER, summonPos, TEMPSUMMON_TIMED_DESPAWN, 10000);
return;
}, 1s, 3s); }, 1s, 3s);
break; break;
default: default:
@@ -2063,32 +2063,33 @@ struct dragonmaw_race_npc : public ScriptedAI
me->SetDisableGravity(false); me->SetDisableGravity(false);
me->SetWalk(true); me->SetWalk(true);
if (_player) Player *player = ObjectAccessor::GetPlayer(me->GetMap(), _playerGUID);
if (!player)
return;
Talk(SAY_COMPLETE, player);
switch (me->GetEntry())
{ {
Talk(SAY_COMPLETE, _player); case NPC_MUCKJAW:
switch (me->GetEntry()) player->AreaExploredOrEventHappens(QUEST_MUCKJAW);
{ break;
case NPC_MUCKJAW: case NPC_TROPE:
_player->AreaExploredOrEventHappens(QUEST_MUCKJAW); player->AreaExploredOrEventHappens(QUEST_TROPE);
break; break;
case NPC_TROPE: case NPC_CORLOK:
_player->AreaExploredOrEventHappens(QUEST_TROPE); player->AreaExploredOrEventHappens(QUEST_CORLOK);
break; break;
case NPC_CORLOK: case NPC_ICHMAN:
_player->AreaExploredOrEventHappens(QUEST_CORLOK); player->AreaExploredOrEventHappens(QUEST_ICHMAN);
break; break;
case NPC_ICHMAN: case NPC_MULVERICK:
_player->AreaExploredOrEventHappens(QUEST_ICHMAN); player->AreaExploredOrEventHappens(QUEST_MULVERICK);
break; break;
case NPC_MULVERICK: case NPC_SKYSHATTER:
_player->AreaExploredOrEventHappens(QUEST_MULVERICK); player->AreaExploredOrEventHappens(QUEST_SKYSHATTER);
break; break;
case NPC_SKYSHATTER: default:
_player->AreaExploredOrEventHappens(QUEST_SKYSHATTER); break;
break;
default:
break;
}
} }
} }
@@ -2202,8 +2203,8 @@ struct dragonmaw_race_npc : public ScriptedAI
break; break;
case 7: case 7:
StartRace(); StartRace();
if (_player) if (Player *player = ObjectAccessor::GetPlayer(me->GetMap(), _playerGUID))
Talk(SAY_SKYSHATTER_SPECIAL, _player); Talk(SAY_SKYSHATTER_SPECIAL, player);
break; break;
case 10: case 10:
StartRaceAttacks(); StartRaceAttacks();
@@ -2232,7 +2233,7 @@ struct dragonmaw_race_npc : public ScriptedAI
} }
private: private:
Player* _player; ObjectGuid _playerGUID;
}; };
void AddSC_shadowmoon_valley() void AddSC_shadowmoon_valley()