mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-01-22 13:16:23 +00:00
Merge branch 'master' into Playerbot
This commit is contained in:
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -302,4 +302,6 @@ inline AI* GetUlduarAI(T* obj)
|
||||
return GetInstanceAI<AI>(obj, UlduarScriptName);
|
||||
}
|
||||
|
||||
#define RegisterUlduarCreatureAI(ai_name) RegisterCreatureAIWithFactory(ai_name, GetUlduarAI)
|
||||
|
||||
#endif
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user