Merge branch 'master' into Playerbot

This commit is contained in:
Yunfan Li
2023-09-05 19:24:48 +08:00
13 changed files with 257 additions and 81 deletions

View File

@@ -944,9 +944,6 @@ InventoryResult Player::CanStoreItem_InSpecificSlot(uint8 bag, uint8 slot, ItemP
uint32 need_space;
if (pSrcItem && pSrcItem->IsNotEmptyBag() && !IsBagPos(uint16(bag) << 8 | slot))
return EQUIP_ERR_CAN_ONLY_DO_WITH_EMPTY_BAGS;
// empty specific slot - check item fit to slot
if (!pItem2 || swap)
{

View File

@@ -3040,7 +3040,10 @@ void InstanceMap::RemovePlayerFromMap(Player* player, bool remove)
//if (!m_unloadTimer && m_mapRefMgr.getSize() == 1)
// m_unloadTimer = m_unloadWhenEmpty ? MIN_UNLOAD_DELAY : std::max(sWorld->getIntConfig(CONFIG_INSTANCE_UNLOAD_DELAY), (uint32)MIN_UNLOAD_DELAY);
Map::RemovePlayerFromMap(player, remove);
player->SetPendingBind(0, 0);
// If remove == true - player already deleted.
if (!remove)
player->SetPendingBind(0, 0);
}
void InstanceMap::AfterPlayerUnlinkFromMap()

View File

@@ -114,7 +114,7 @@ struct boss_moroes : public BossAI
scheduler.Schedule(10s, GROUP_PRECOMBAT_TALK, [this](TaskContext context)
{
if(Creature* guest = GetRandomGuest())
if (Creature* guest = GetRandomGuest())
{
guest->AI()->Talk(SAY_GUEST);
}
@@ -156,7 +156,6 @@ struct boss_moroes : public BossAI
scheduler.Schedule(5s, 7s, [this](TaskContext)
{
me->SetImmuneToAll(false);
DoCastRandomTarget(SPELL_GARROTE, 0, 100.0f, true, true);
DoCastSelf(SPELL_VANISH_TELEPORT);
_vanished = false;
});
@@ -178,7 +177,7 @@ struct boss_moroes : public BossAI
void KilledUnit(Unit* victim) override
{
if(!_recentlySpoken && victim->GetTypeId() == TYPEID_PLAYER)
if (!_recentlySpoken && victim->GetTypeId() == TYPEID_PLAYER)
{
Talk(SAY_KILL);
_recentlySpoken = true;
@@ -206,6 +205,7 @@ struct boss_moroes : public BossAI
guestList.push_back(summon);
}
}
return Acore::Containers::SelectRandomContainerElement(guestList);
}
@@ -234,7 +234,7 @@ struct boss_moroes : public BossAI
EnterEvadeMode();
summons.DoForAllSummons([](WorldObject* summon)
{
summon->ToCreature()->AI()->EnterEvadeMode();
summon->ToCreature()->DespawnOnEvade(5s);
});
return;
}

View File

@@ -122,7 +122,7 @@ struct boss_nightbane : public BossAI
MovePhase = 0;
}
ScheduleHealthCheckEvent({25, 50, 70}, [&]{
ScheduleHealthCheckEvent({ 75, 50, 25 }, [&]{
TakeOff();
});
}
@@ -219,9 +219,7 @@ struct boss_nightbane : public BossAI
void JustDied(Unit* /*killer*/) override
{
if (instance)
instance->SetData(DATA_NIGHTBANE, DONE);
_JustDied();
HandleTerraceDoors(true);
}
@@ -398,6 +396,7 @@ private:
uint8 _skeletonCount;
uint8 _skeletonSpawnCounter;
};
class go_blackened_urn : public GameObjectScript
{
public:
@@ -405,13 +404,17 @@ public:
//if we summon an entity instead of using a sort of invisible entity, we could unsummon boss on reset
//right now that doesn't work because of how the urn works
bool OnGossipHello(Player* player, GameObject* go) override
bool OnGossipHello(Player* /*player*/, GameObject* go) override
{
if (InstanceScript* pInstance = go->GetInstanceScript())
if (InstanceScript* instance = go->GetInstanceScript())
{
if (pInstance->GetData(DATA_NIGHTBANE) != DONE && !go->FindNearestCreature(NPC_NIGHTBANE, 40.0f))
if (Creature* cr = ObjectAccessor::GetCreature(*player, pInstance->GetGuidData(DATA_NIGHTBANE)))
if (instance->GetData(DATA_NIGHTBANE) != DONE && !go->FindNearestCreature(NPC_NIGHTBANE, 40.0f))
{
if (Creature* cr = instance->GetCreature(DATA_NIGHTBANE))
{
cr->GetMotionMaster()->MovePoint(0, IntroWay[0][0], IntroWay[0][1], IntroWay[0][2]);
}
}
}
return false;

View File

@@ -305,7 +305,6 @@ struct boss_shade_of_aran : public BossAI
if (unit && !unit->IsWithinDist2d(FWTargPosX[i], FWTargPosY[i], 3))
{
unit->CastSpell(unit, 20476, true, 0, 0, me->GetGUID());
unit->CastSpell(unit, 11027, true);
FlameWreathTarget[i].Clear();
}
}

View File

@@ -34,16 +34,17 @@ const Position OptionalSpawn[] =
ObjectData const creatureData[] =
{
{ NPC_ATTUMEN_THE_HUNTSMAN, DATA_ATTUMEN },
{ NPC_MIDNIGHT, DATA_MIDNIGHT },
{ NPC_DOROTHEE, DATA_DOROTHEE },
{ NPC_TITO, DATA_TITO },
{ NPC_ROAR, DATA_ROAR },
{ NPC_STRAWMAN, DATA_STRAWMAN },
{ NPC_TINHEAD, DATA_TINHEAD },
{ NPC_ROMULO, DATA_ROMULO },
{ NPC_JULIANNE, DATA_JULIANNE },
{ 0, 0 }
{ NPC_ATTUMEN_THE_HUNTSMAN, DATA_ATTUMEN },
{ NPC_MIDNIGHT, DATA_MIDNIGHT },
{ NPC_DOROTHEE, DATA_DOROTHEE },
{ NPC_TITO, DATA_TITO },
{ NPC_ROAR, DATA_ROAR },
{ NPC_STRAWMAN, DATA_STRAWMAN },
{ NPC_TINHEAD, DATA_TINHEAD },
{ NPC_ROMULO, DATA_ROMULO },
{ NPC_JULIANNE, DATA_JULIANNE },
{ NPC_NIGHTBANE, DATA_NIGHTBANE },
{ 0, 0 }
};
class instance_karazhan : public InstanceMapScript

View File

@@ -24,30 +24,49 @@
#include "SpellAuraEffects.h"
#include "SpellScript.h"
#include "Vehicle.h"
#include "TaskScheduler.h"
enum Texts
{
// Freya
GOSSIP_MENU_FREYA = 10324,
NPC_TEXT_FREYA = 14332,
GOSSIP_MENU_FREYA = 10324,
NPC_TEXT_FREYA = 14332,
// Hodir
GOSSIP_MENU_HODIR = 10335,
NPC_TEXT_HODIR = 14326,
GOSSIP_MENU_HODIR = 10335,
NPC_TEXT_HODIR = 14326,
// Mimiron
GOSSIP_MENU_MIMIRON = 10336,
NPC_TEXT_MIMIRON = 14334,
GOSSIP_MENU_MIMIRON = 10336,
NPC_TEXT_MIMIRON = 14334,
// Thorim
GOSSIP_MENU_THORIM = 10337,
NPC_TEXT_THORIM = 14333,
GOSSIP_MENU_THORIM = 10337,
NPC_TEXT_THORIM = 14333,
// Confirm assistance
GOSSIP_MENU_CONFIRM = 10333,
NPC_TEXT_CONFIRM = 14325,
GOSSIP_MENU_CONFIRM = 10333,
NPC_TEXT_CONFIRM = 14325,
SAY_KEEPER_SELECTED = 1,
SAY_KEEPER_SELECTED = 1,
};
enum UldNPCs
{
NPC_WINTER_JORMUNGAR = 34137,
NPC_SNOW_MOUND_4 = 34146,
NPC_SNOW_MOUND_6 = 34150,
NPC_SNOW_MOUND_8 = 34151
};
enum UldGameObjects
{
GOBJ_SNOW_MOUND = 194907
};
enum UldSpells
{
SPELL_SNOW_MOUND_PARTICLES = 64615
};
class npc_ulduar_keeper : public CreatureScript
@@ -157,52 +176,72 @@ public:
}
};
class npc_ulduar_snow_mound : public CreatureScript
struct npc_ulduar_snow_mound : public ScriptedAI
{
public:
npc_ulduar_snow_mound() : CreatureScript("npc_ulduar_snow_mound") { }
CreatureAI* GetAI(Creature* creature) const override
npc_ulduar_snow_mound(Creature* creature) : ScriptedAI(creature)
{
return GetUlduarAI<npc_ulduar_snow_moundAI>(creature);
_activated = false;
_count = 0;
_counter = 0;
}
struct npc_ulduar_snow_moundAI : public ScriptedAI
void MoveInLineOfSight(Unit* who) override
{
npc_ulduar_snow_moundAI(Creature* creature) : ScriptedAI(creature)
if (!_activated && who->GetTypeId() == TYPEID_PLAYER)
{
activated = false;
me->CastSpell(me, 64615, true);
}
bool activated;
void MoveInLineOfSight(Unit* who) override
{
if (!activated && who->GetTypeId() == TYPEID_PLAYER)
if (me->GetExactDist2d(who) <= 25.0f && me->GetMap()->isInLineOfSight(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ() + 5.0f,
who->GetPositionX(), who->GetPositionY(), who->GetPositionZ() + 5.0f, 2, LINEOFSIGHT_ALL_CHECKS, VMAP::ModelIgnoreFlags::Nothing))
if (me->GetExactDist2d(who) <= 10.0f && me->GetMap()->isInLineOfSight(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ() + 5.0f,
who->GetPositionX(), who->GetPositionY(), who->GetPositionZ() + 5.0f, 2, LINEOFSIGHT_ALL_CHECKS, VMAP::ModelIgnoreFlags::Nothing))
{
_activated = true;
me->RemoveAura(SPELL_SNOW_MOUND_PARTICLES);
if (GameObject* go = me->FindNearestGameObject(GOBJ_SNOW_MOUND, 5.0f))
{
activated = true;
me->RemoveAura(64615);
if (GameObject* go = me->FindNearestGameObject(194907, 5.0f))
go->Delete();
uint8 count;
if (me->GetEntry() == 34146) count = 4;
else if (me->GetEntry() == 34150) count = 6;
else count = 8;
for (uint8 i = 0; i < count; ++i)
{
float a = rand_norm() * 2 * M_PI;
float d = rand_norm() * 4.0f;
if (Creature* c = me->SummonCreature(34137, me->GetPositionX() + cos(a) * d, me->GetPositionY() + std::sin(a) * d, me->GetPositionZ() + 1.0f, 0.0f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 300000))
c->AI()->AttackStart(who);
}
go->Delete();
}
}
void UpdateAI(uint32 /*diff*/) override {}
};
switch (me->GetEntry())
{
case NPC_SNOW_MOUND_4:
_count = 4;
break;
case NPC_SNOW_MOUND_6:
_count = 6;
break;
case NPC_SNOW_MOUND_8:
_count = 8;
break;
default:
return;
}
_scheduler.Schedule(0s, [this](TaskContext context)
{
_counter++;
float a = rand_norm() * 2 * M_PI; //needs verification from sniffs
float d = rand_norm() * 4.0f;
if (Creature* jormungar = me->SummonCreature(NPC_WINTER_JORMUNGAR, me->GetPositionX() + cos(a) * d, me->GetPositionY() + std::sin(a) * d, me->GetPositionZ() + 1.0f, 0.0f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 300000))
{
jormungar->SetInCombatWithZone();
}
if (_counter < _count)
{
context.Repeat(2s);
}
});
}
}
}
void UpdateAI(uint32 diff) override
{
_scheduler.Update(diff);
}
private:
bool _activated;
TaskScheduler _scheduler;
uint8 _count;
uint8 _counter;
};
class npc_ulduar_storm_tempered_keeper : public CreatureScript
@@ -512,13 +551,11 @@ struct npc_salvaged_siege_engine : public VehicleAI
void AddSC_ulduar()
{
new npc_ulduar_keeper();
new spell_ulduar_energy_sap();
new npc_ulduar_snow_mound();
RegisterUlduarCreatureAI(npc_ulduar_snow_mound);
new npc_ulduar_storm_tempered_keeper();
new npc_ulduar_arachnopod_destroyer();
new spell_ulduar_arachnopod_damaged();
new AreaTrigger_at_celestial_planetarium_enterance();
new go_call_tram();

View File

@@ -302,4 +302,6 @@ inline AI* GetUlduarAI(T* obj)
return GetInstanceAI<AI>(obj, UlduarScriptName);
}
#define RegisterUlduarCreatureAI(ai_name) RegisterCreatureAIWithFactory(ai_name, GetUlduarAI)
#endif

View File

@@ -102,12 +102,16 @@ struct boss_magtheridon : public BossAI
BossAI::Reset();
_channelersKilled = 0;
_currentPhase = 0;
_castingQuake = false;
_recentlySpoken = false;
_magReleased = false;
_interruptScheduler.CancelAll();
scheduler.Schedule(90s, [this](TaskContext context)
{
Talk(SAY_TAUNT);
if (!me->IsEngaged())
{
Talk(SAY_TAUNT);
}
context.Repeat(90s);
});
DoCastSelf(SPELL_SHADOW_CAGE, true);
@@ -166,6 +170,7 @@ struct boss_magtheridon : public BossAI
void ScheduleCombatEvents()
{
me->GetThreatMgr().ClearAllThreat();
me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
me->SetImmuneToPC(false);
me->SetReactState(REACT_AGGRESSIVE);
@@ -182,9 +187,18 @@ struct boss_magtheridon : public BossAI
context.Repeat(11s, 39s);
}).Schedule(40s, [this](TaskContext context)
{
DoCastSelf(SPELL_QUAKE); //needs fixes with custom spell
DoCastSelf(SPELL_QUAKE);
_castingQuake = true;
me->GetMotionMaster()->Clear();
me->SetReactState(REACT_PASSIVE);
me->SetOrientation(me->GetAngle(me->GetVictim()));
me->SetTarget(ObjectGuid::Empty);
scheduler.DelayAll(6999ms);
scheduler.Schedule(7s, [this](TaskContext /*context*/)
{
_castingQuake = false;
me->SetReactState(REACT_AGGRESSIVE);
me->GetMotionMaster()->MoveChase(me->GetVictim());
DoCastSelf(SPELL_BLAST_NOVA);
_interruptScheduler.Schedule(50ms, GROUP_INTERRUPT_CHECK, [this](TaskContext context)
@@ -234,6 +248,10 @@ struct boss_magtheridon : public BossAI
BossAI::JustEngagedWith(who);
Talk(SAY_EMOTE_BEGIN);
instance->DoForAllMinions(TYPE_MAGTHERIDON, [&](Creature* creature) {
creature->SetInCombatWithZone();
});
scheduler.Schedule(60s, GROUP_EARLY_RELEASE_CHECK, [this](TaskContext /*context*/)
{
Talk(SAY_EMOTE_NEARLY);
@@ -256,13 +274,14 @@ struct boss_magtheridon : public BossAI
scheduler.Update(diff);
_interruptScheduler.Update(diff);
if (_currentPhase != 1)
if (_currentPhase != 1 && !_castingQuake)
{
DoMeleeAttackIfReady();
}
}
private:
bool _castingQuake;
bool _recentlySpoken;
bool _magReleased;
uint8 _currentPhase;