Merge branch 'master' into Playerbot

This commit is contained in:
Yunfan Li
2025-02-11 22:35:57 +08:00
62 changed files with 1532 additions and 1969 deletions
+12 -12
View File
@@ -68,9 +68,9 @@ public:
GameEventData const& eventData = events[eventId];
if (handler->GetSession())
handler->PSendSysMessage(LANG_EVENT_ENTRY_LIST_CHAT, eventId, eventId, eventData.description, active);
handler->PSendSysMessage(LANG_EVENT_ENTRY_LIST_CHAT, eventId, eventId, eventData.Description, active);
else
handler->PSendSysMessage(LANG_EVENT_ENTRY_LIST_CONSOLE, eventId, eventData.description, active);
handler->PSendSysMessage(LANG_EVENT_ENTRY_LIST_CONSOLE, eventId, eventData.Description, active);
++counter;
}
@@ -104,17 +104,17 @@ public:
bool active = activeEvents.find(eventId) != activeEvents.end();
std::string activeStr = active ? handler->GetAcoreString(LANG_ACTIVE) : "";
std::string startTimeStr = Acore::Time::TimeToTimestampStr(Seconds(eventData.start));
std::string endTimeStr = Acore::Time::TimeToTimestampStr(Seconds(eventData.end));
std::string startTimeStr = Acore::Time::TimeToTimestampStr(Seconds(eventData.Start));
std::string endTimeStr = Acore::Time::TimeToTimestampStr(Seconds(eventData.End));
uint32 delay = sGameEventMgr->NextCheck(eventId);
time_t nextTime = GameTime::GetGameTime().count() + delay;
std::string nextStr = nextTime >= eventData.start && nextTime < eventData.end ? Acore::Time::TimeToTimestampStr(Seconds(nextTime)) : "-";
std::string nextStr = nextTime >= eventData.Start && nextTime < eventData.End ? Acore::Time::TimeToTimestampStr(Seconds(nextTime)) : "-";
std::string occurenceStr = secsToTimeString(eventData.occurence * MINUTE, true);
std::string lengthStr = secsToTimeString(eventData.length * MINUTE, true);
std::string occurenceStr = secsToTimeString(eventData.Occurence * MINUTE, true);
std::string lengthStr = secsToTimeString(eventData.Length * MINUTE, true);
handler->PSendSysMessage(LANG_EVENT_INFO, uint16(eventId), eventData.description, activeStr,
handler->PSendSysMessage(LANG_EVENT_INFO, uint16(eventId), eventData.Description, activeStr,
startTimeStr, endTimeStr, occurenceStr, lengthStr,
nextStr);
@@ -141,11 +141,11 @@ public:
GameEventMgr::ActiveEvents const& activeEvents = sGameEventMgr->GetActiveEventList();
if (activeEvents.find(eventId) != activeEvents.end())
{
handler->SendErrorMessage(LANG_EVENT_ALREADY_ACTIVE, uint16(eventId), eventData.description);
handler->SendErrorMessage(LANG_EVENT_ALREADY_ACTIVE, uint16(eventId), eventData.Description);
return false;
}
handler->PSendSysMessage(LANG_EVENT_STARTED, uint16(eventId), eventData.description);
handler->PSendSysMessage(LANG_EVENT_STARTED, uint16(eventId), eventData.Description);
sGameEventMgr->StartEvent(eventId, true);
return true;
}
@@ -171,11 +171,11 @@ public:
if (activeEvents.find(eventId) == activeEvents.end())
{
handler->SendErrorMessage(LANG_EVENT_NOT_ACTIVE, uint16(eventId), eventData.description);
handler->SendErrorMessage(LANG_EVENT_NOT_ACTIVE, uint16(eventId), eventData.Description);
return false;
}
handler->PSendSysMessage(LANG_EVENT_STOPPED, uint16(eventId), eventData.description);
handler->PSendSysMessage(LANG_EVENT_STOPPED, uint16(eventId), eventData.Description);
sGameEventMgr->StopEvent(eventId, true);
return true;
}
+3 -17
View File
@@ -269,17 +269,13 @@ public:
static bool HandleLookupEventCommand(ChatHandler* handler, Tail namePart)
{
if (namePart.empty())
{
return false;
}
std::wstring wNamePart;
// converting string that we try to find to lower case
if (!Utf8toWStr(namePart, wNamePart))
{
return false;
}
wstrToLower(wNamePart);
@@ -294,11 +290,9 @@ public:
{
GameEventData const& eventData = events[id];
std::string descr = eventData.description;
std::string descr = eventData.Description;
if (descr.empty())
{
continue;
}
if (Utf8FitTo(descr, wNamePart))
{
@@ -311,25 +305,17 @@ public:
std::string active = activeEvents.find(id) != activeEvents.end() ? handler->GetAcoreString(LANG_ACTIVE) : "";
if (handler->GetSession())
{
handler->PSendSysMessage(LANG_EVENT_ENTRY_LIST_CHAT, id, id, eventData.description, active);
}
handler->PSendSysMessage(LANG_EVENT_ENTRY_LIST_CHAT, id, id, eventData.Description, active);
else
{
handler->PSendSysMessage(LANG_EVENT_ENTRY_LIST_CONSOLE, id, eventData.description, active);
}
handler->PSendSysMessage(LANG_EVENT_ENTRY_LIST_CONSOLE, id, eventData.Description, active);
if (!found)
{
found = true;
}
}
}
if (!found)
{
handler->SendSysMessage(LANG_NOEVENTFOUND);
}
return true;
}
@@ -83,7 +83,7 @@ public:
handler->PSendSysMessage("Invalid subphase, see \".worldstate sunsreach subphase\" for usage");
return false;
}
sWorldState->HandleSunsReachSubPhaseTransition(subphase);;
sWorldState->HandleSunsReachSubPhaseTransition(subphase);
handler->PSendSysMessage(sWorldState->GetSunsReachPrintout());
return true;
}
@@ -354,9 +354,8 @@ struct npc_madrigosa : public NullCreatureAI
}
break;
case EVENT_SPAWN_FELMYST:
DoCastAOE(SPELL_SUMMON_FELBLAZE, true);
me->DespawnOrUnsummon(1);
if (Creature* felmyst = instance->GetCreature(DATA_FELMYST))
felmyst->AI()->DoAction(ACTION_START_EVENT);
break;
}
}
@@ -100,30 +100,30 @@ private:
struct boss_felmyst : public BossAI
{
boss_felmyst(Creature* creature) : BossAI(creature, DATA_FELMYST)
{
bool appear = instance->GetBossState(DATA_BRUTALLUS) == DONE;
creature->SetVisible(appear);
creature->SetStandState(UNIT_STAND_STATE_SLEEP);
creature->SetReactState(REACT_PASSIVE);
}
boss_felmyst(Creature* creature) : BossAI(creature, DATA_FELMYST) { }
void DoAction(int32 param) override
void InitializeAI() override
{
if (param == ACTION_START_EVENT)
me->SetReactState(REACT_PASSIVE);
if (instance->GetBossState(DATA_FELMYST) == TO_BE_DECIDED)
{
me->SetVisible(true);
me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
me->SetStandState(UNIT_STAND_STATE_SLEEP);
me->SetImmuneToPC(true);
StartIntro();
}
else
{
me->SetCanFly(true);
me->SetDisableGravity(true);
me->SendMovementFlagUpdate();
me->GetMotionMaster()->MovePath(me->GetEntry() * 10, true);
}
}
void Reset() override
{
BossAI::Reset();
me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
me->SetReactState(REACT_PASSIVE);
me->SetDisableGravity(false);
me->m_Events.KillAllEvents(false);
instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_FOG_OF_CORRUPTION_CHARM);
}
@@ -131,10 +131,18 @@ struct boss_felmyst : public BossAI
void JustEngagedWith(Unit* who) override
{
BossAI::JustEngagedWith(who);
me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
me->CastSpell(me, SPELL_NOXIOUS_FUMES, true);
me->m_Events.AddEventAtOffset([&] {
Talk(YELL_BERSERK);
DoCastSelf(SPELL_BERSERK, true);
}, 10min);
if (!scheduler.IsGroupScheduled(GROUP_START_INTRO))
StartIntro();
me->GetMotionMaster()->Clear();
Position landPos = who->GetPosition();
me->m_Events.AddEventAtOffset([&, landPos] {
me->GetMotionMaster()->MovePoint(POINT_GROUND, landPos, false, true);
}, 2s);
}
void KilledUnit(Unit* victim) override
@@ -146,6 +154,7 @@ struct boss_felmyst : public BossAI
void JustDied(Unit* killer) override
{
BossAI::JustDied(killer);
me->m_Events.KillAllEvents(false);
Talk(YELL_DEATH);
instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_FOG_OF_CORRUPTION_CHARM);
@@ -161,8 +170,10 @@ struct boss_felmyst : public BossAI
if (point == POINT_GROUND)
{
me->HandleEmoteCommand(EMOTE_ONESHOT_LAND);
me->SetCanFly(false);
me->SetDisableGravity(false);
me->SendMovementFlagUpdate();
SetInvincibility(false);
me->m_Events.AddEventAtOffset([&] {
me->SetReactState(REACT_AGGRESSIVE);
@@ -171,7 +182,7 @@ struct boss_felmyst : public BossAI
me->SetTarget(me->GetVictim()->GetGUID());
me->ResumeChasingVictim();
}, 1s);
}, 2s);
ScheduleTimedEvent(7500ms, [&] {
DoCastVictim(SPELL_CLEAVE);
@@ -238,6 +249,7 @@ struct boss_felmyst : public BossAI
me->HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF);
me->SetDisableGravity(true);
me->SendMovementFlagUpdate();
SetInvincibility(true);
me->m_Events.AddEventAtOffset([&] {
me->GetMotionMaster()->MovePoint(POINT_AIR, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ() + 15.0f, false, true);
@@ -304,30 +316,16 @@ struct boss_felmyst : public BossAI
me->m_Events.AddEventAtOffset([&] {
Talk(YELL_BIRTH);
me->SetCanFly(true);
me->SetDisableGravity(true);
me->HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF);
me->SendMovementFlagUpdate();
me->HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF);
}, 7s);
me->m_Events.AddEventAtOffset([&] {
me->GetMotionMaster()->MovePoint(POINT_AIR, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ() + 10.0f, false, true);
me->SetImmuneToPC(false);
me->GetMotionMaster()->MovePath(me->GetEntry() * 10, true);
}, 8500ms);
me->m_Events.AddEventAtOffset([&] {
me->SetInCombatWithZone();
me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
me->CastSpell(me, SPELL_NOXIOUS_FUMES, true);
me->GetMotionMaster()->MovePoint(POINT_MISC, 1472.18f, 603.38f, 34.0f, false, true);
me->m_Events.AddEventAtOffset([&] {
me->GetMotionMaster()->MovePoint(POINT_GROUND, me->GetPositionX(), me->GetPositionY(), me->GetMapHeight(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ()), false, true);
}, 3s);
me->m_Events.AddEventAtOffset([&] {
Talk(YELL_BERSERK);
DoCastSelf(SPELL_BERSERK, true);
}, 10min);
}, 10500ms);
});
}
@@ -106,12 +106,6 @@ struct boss_kalecgos : public BossAI
return true;
}
void JustReachedHome() override
{
BossAI::JustReachedHome();
me->SetVisible(true);
}
void Reset() override
{
BossAI::Reset();
@@ -175,7 +169,6 @@ struct boss_kalecgos : public BossAI
}, 4s);
me->m_Events.AddEventAtOffset([&] {
me->SetVisible(false);
EnterEvadeMode();
}, 9s);
@@ -251,10 +244,11 @@ struct boss_kalecgos : public BossAI
DoCastAOE(SPELL_SPECTRAL_BLAST);
}, 15s, 25s);
me->m_Events.AddEventAtOffset([&] {
scheduler.Schedule(16s, [this](TaskContext)
{
me->SummonCreature(NPC_KALEC, 1702.21f, 931.7f, -74.56f, 5.07f, TEMPSUMMON_MANUAL_DESPAWN);
me->SummonCreature(NPC_SATHROVARR, 1704.62f, 927.78f, -73.9f, 2.0f, TEMPSUMMON_MANUAL_DESPAWN);
}, 16s);
});
me->SetStandState(UNIT_STAND_STATE_STAND);
Talk(SAY_EVIL_AGGRO);
@@ -282,10 +276,7 @@ enum Kalec
struct boss_kalec : public ScriptedAI
{
boss_kalec(Creature* creature) : ScriptedAI(creature)
{
SetInvincibility(true);
}
boss_kalec(Creature* creature) : ScriptedAI(creature) { }
void Reset() override
{
@@ -89,6 +89,18 @@ public:
LoadSummonData(summonData);
}
void Load(char const* data) override
{
InstanceScript::Load(data);
scheduler.Schedule(3s, [this](TaskContext /*context*/)
{
if (IsBossDone(DATA_BRUTALLUS) && !IsBossDone(DATA_FELMYST))
if (Creature* madrigosa = GetCreature(DATA_MADRIGOSA))
madrigosa->CastSpell((Unit*)nullptr, SPELL_SUMMON_FELBLAZE, true);
});
}
void OnPlayerEnter(Player* player) override
{
instance->LoadGrid(1477.94f, 643.22f);
@@ -106,6 +106,11 @@ enum GameObjectIds
GO_ORB_OF_THE_BLUE_DRAGONFLIGHT4 = 188116
};
enum SpellIds
{
SPELL_SUMMON_FELBLAZE = 45069 // Felblaze? Summons Felmyst
};
template <class AI, class T>
inline AI* GetSunwellPlateauAI(T* obj)
{
@@ -1114,10 +1114,9 @@ public:
return !_caster->IsWithinLOSInMap(unit);
// for players and pets check only dynamic los (ice block gameobjects)
float ox, oy, oz;
_caster->GetPosition(ox, oy, oz);
DynamicMapTree const& dTree = unit->GetMap()->GetDynamicMapTree();
return !dTree.isInLineOfSight(unit->GetPositionX(), unit->GetPositionY(), unit->GetPositionZ() + 2.f, ox, oy, oz + 2.f, unit->GetPhaseMask(), VMAP::ModelIgnoreFlags::Nothing);
if (unit->IsUnit() && unit->ToUnit()->HasUnitState(UNIT_STATE_MELEE_ATTACKING) && unit->ToUnit()->IsWithinMeleeRange(_caster))
return false;
return !_caster->IsWithinLOSInMap(unit, VMAP::ModelIgnoreFlags::Nothing, LINEOFSIGHT_CHECK_GOBJECT_M2, 0, _caster->GetCombatReach() * 0.7);
}
private:
@@ -1161,17 +1161,6 @@ public:
{
IsSindragosaIntroDone = true;
HandleDropAttempt();
if (instance->IsHeroic())
{
if (HeroicAttempts)
{
Events.ScheduleEvent(EVENT_RESPAWN_SINDRAGOSA, 30s);
}
}
else
{
Events.ScheduleEvent(EVENT_RESPAWN_SINDRAGOSA, 30s);
}
}
if (state == DONE && !instance->IsHeroic() && LichKingHeroicAvailable)
{
@@ -369,6 +369,9 @@ public:
break;
case NPC_ALGALON:
m_uiAlgalonGUID = creature->GetGUID();
if (!m_algalonTimer)
creature->DespawnOrUnsummon();
break;
case NPC_HARPOON_FIRE_STATE:
{
@@ -811,17 +814,6 @@ public:
go->EnableCollision(false);
}
if (data == FAIL)
{
scheduler.Schedule(5s, [this](TaskContext)
{
if (m_algalonTimer && (m_algalonTimer <= 60 || m_algalonTimer == TIMER_ALGALON_TO_SUMMON))
{
instance->SummonCreature(NPC_ALGALON, AlgalonLandPos);
}
});
}
break;
// Achievement
@@ -444,7 +444,9 @@ public:
void MoveInLineOfSight(Unit* who) override
{
if (!who || !who->IsInWorld() || who->GetZoneId() != 4395)
// 4395 Dalaran
// 4569 Sewer Exit Pipe
if (!who || !who->IsInWorld()|| who->GetZoneId() != 4395 || who->GetAreaId() == 4569)
return;
if (!me->IsWithinDist(who, 5.0f, false))
@@ -5400,6 +5400,38 @@ class spell_gen_proc_on_victim : public AuraScript
}
};
enum TranslocateSpells
{
SPELL_TRANSLOCATION_DOWN = 45368,
SPELL_TRANSLOCATION_UP = 45371
};
class spell_gen_translocate : public SpellScript
{
PrepareSpellScript(spell_gen_translocate);
public:
spell_gen_translocate(uint32 spellId) : SpellScript(), _spellId(spellId) {}
bool Validate(SpellInfo const* /*spellInfo*/) override
{
return ValidateSpellInfo({ _spellId });
}
void HandleScript()
{
GetCaster()->CastSpell(GetCaster(), _spellId);
}
void Register() override
{
AfterCast += SpellCastFn(spell_gen_translocate::HandleScript);
}
private:
uint32 _spellId;
};
void AddSC_generic_spell_scripts()
{
RegisterSpellScript(spell_silithyst);
@@ -5560,4 +5592,6 @@ void AddSC_generic_spell_scripts()
RegisterSpellScript(spell_gen_set_health);
RegisterSpellScript(spell_pet_spellhit_expertise_spellpen_scaling);
RegisterSpellScript(spell_gen_proc_on_victim);
RegisterSpellScriptWithArgs(spell_gen_translocate, "spell_gen_translocate_down", SPELL_TRANSLOCATION_DOWN);
RegisterSpellScriptWithArgs(spell_gen_translocate, "spell_gen_translocate_up", SPELL_TRANSLOCATION_UP);
}