Merge branch 'master' into Playerbot

This commit is contained in:
Yunfan Li
2024-12-13 18:51:37 +08:00
48 changed files with 1584 additions and 64 deletions
@@ -124,7 +124,7 @@ struct boss_nightbane : public BossAI
_triggerCountTakeOffWhileFlying = 0;
_airPhasesCompleted = 0;
me->SetSpeed(MOVE_RUN, me->GetCreatureTemplate()->speed_run);
me->SetSpeed(MOVE_RUN, 2.0f);
me->SetCanFly(true);
me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
me->SetReactState(REACT_PASSIVE);
@@ -300,7 +300,6 @@ struct boss_nightbane : public BossAI
{
me->ClearUnitState(UNIT_STATE_IGNORE_PATHFINDING);
me->GetMotionMaster()->MovePoint(POINT_INTRO_LAND, introLandPos);
me->SetSpeed(MOVE_RUN, 2.0f);
}).Schedule(3s, [this](TaskContext /*context*/)
{
me->SetDisableGravity(false);
@@ -83,6 +83,14 @@ struct boss_muru : public BossAI
}, 10min);
}
void JustSummoned(Creature* creature) override
{
if (creature->GetEntry() == NPC_ENTROPIUS)
creature->SetInCombatWithZone();
else
BossAI::JustSummoned(creature);
}
void DamageTaken(Unit*, uint32& damage, DamageEffectType, SpellSchoolMask) override
{
if (damage >= me->GetHealth())
@@ -20,6 +20,8 @@
#include "GridNotifiers.h"
#include "GridNotifiersImpl.h"
#include "ScriptedCreature.h"
#include "SpellAuras.h"
#include "SpellAuraEffects.h"
#include "SpellScript.h"
#include "SpellScriptLoader.h"
#include "Weather.h"
@@ -321,9 +323,30 @@ class spell_electrial_storm : public AuraScript
}
};
// 43657 - Electrical Storm
class spell_electrical_storm_proc : public SpellScript
{
PrepareSpellScript(spell_electrical_storm_proc);
void HandleDamageCalc(SpellEffIndex /*effIndex*/)
{
if (Aura* aura = GetCaster()->GetAura(SPELL_ELECTRICAL_STORM))
{
uint8 multiplier = aura->GetEffect(EFFECT_1)->GetTickNumber();
SetHitDamage(GetHitDamage() * multiplier);
}
}
void Register() override
{
OnEffectHitTarget += SpellEffectFn(spell_electrical_storm_proc::HandleDamageCalc, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE);
}
};
void AddSC_boss_akilzon()
{
RegisterZulAmanCreatureAI(boss_akilzon);
RegisterZulAmanCreatureAI(npc_akilzon_eagle);
RegisterSpellScript(spell_electrial_storm);
RegisterSpellScript(spell_electrical_storm_proc);
}
@@ -229,7 +229,13 @@ static PlayerAbilityStruct PlayerAbility[13][3] =
struct boss_hexlord_malacrass : public BossAI
{
boss_hexlord_malacrass(Creature* creature) : BossAI(creature, DATA_HEXLORD) { }
boss_hexlord_malacrass(Creature* creature) : BossAI(creature, DATA_HEXLORD)
{
scheduler.SetValidator([this]
{
return !me->HasUnitState(UNIT_STATE_CASTING);
});
}
void Reset() override
{
@@ -238,19 +244,28 @@ struct boss_hexlord_malacrass : public BossAI
_classAbilityTimer = 10000ms;
SpawnAdds();
ScheduleHealthCheckEvent(80, [&] {
ScheduleTimedEvent(0s, [&] {
ScheduleTimedEvent(1s, [&] {
DoCastSelf(SPELL_DRAIN_POWER, true);
Talk(SAY_DRAIN_POWER);
}, 30s, 30s);
}, 30s);
});
}
void SpawnAdds()
{
for (uint8 i = 0; i < MAX_ADD_COUNT; ++i)
if (_creatureIndex.empty())
{
uint8 flip = urand(0, 1);
me->SummonCreature(AddEntrySets[i][flip], AddPosition[i], TEMPSUMMON_DEAD_DESPAWN, 0);
for (uint8 i = 0; i < MAX_ADD_COUNT; ++i)
{
uint8 flip = urand(0, 1);
me->SummonCreature(AddEntrySets[i][flip], AddPosition[i], TEMPSUMMON_DEAD_DESPAWN, 0);
_creatureIndex.push_back(flip);
}
}
else
{
for (uint8 i = 0; i < MAX_ADD_COUNT; ++i)
me->SummonCreature(AddEntrySets[i][_creatureIndex[i]], AddPosition[i], TEMPSUMMON_DEAD_DESPAWN, 0);
}
}
@@ -339,6 +354,7 @@ struct boss_hexlord_malacrass : public BossAI
private:
uint8 _currentClass;
std::chrono::milliseconds _classAbilityTimer;
std::vector<uint8> _creatureIndex;
};
struct boss_alyson_antille : public ScriptedAI
@@ -15,6 +15,7 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "CreatureGroups.h"
#include "CreatureScript.h"
#include "Player.h"
#include "ScriptedCreature.h"
@@ -144,6 +145,9 @@ struct boss_zuljin : public BossAI
me->SetCombatMovement(true);
me->m_Events.KillAllEvents(false);
_nextPhase = 0;
if (CreatureGroup* formation = me->GetFormation())
formation->RespawnFormation(true);
}
void JustEngagedWith(Unit* /*who*/) override
@@ -198,10 +202,16 @@ struct boss_zuljin : public BossAI
me->ResumeChasingVictim();
ScheduleTimedEvent(5s, [&] {
DoCastRandomTarget(SPELL_CLAW_RAGE_CHARGE);
if (me->HasAura(SPELL_LYNX_RUSH_HASTE))
return;
DoCastRandomTarget(SPELL_CLAW_RAGE_CHARGE, 1);
}, 15s, 20s);
ScheduleTimedEvent(14s, [&] {
if (me->HasAura(SPELL_CLAW_RAGE_AURA))
return;
DoCastSelf(SPELL_LYNX_RUSH_HASTE);
for (int8 count = 0; count <= 8; ++count)
@@ -233,6 +243,21 @@ struct boss_zuljin : public BossAI
});
}
void EnterEvadeMode(EvadeReason /*why*/) override
{
if (CreatureGroup* formation = me->GetFormation())
{
for (auto const& itr : formation->GetMembers())
{
if (itr.first && itr.first != me)
itr.first->DespawnOnEvade(2min);
}
}
me->DespawnOnEvade(2min);
_EnterEvadeMode();
}
void SpellHitTarget(Unit* target, SpellInfo const* spellInfo) override
{
if (spellInfo->Id == SPELL_CLAW_RAGE_CHARGE && target != me)
@@ -53,7 +53,6 @@ DoorData const doorData[] =
{ GO_DOOR_HALAZZI, DATA_HALAZZI, DOOR_TYPE_PASSAGE },
{ GO_LYNX_TEMPLE_ENTRANCE, DATA_HALAZZI, DOOR_TYPE_ROOM },
{ GO_DOOR_AKILZON, DATA_AKILZON, DOOR_TYPE_ROOM },
{ GO_GATE_ZULJIN, DATA_HEXLORD, DOOR_TYPE_PASSAGE },
{ 0, 0, DOOR_TYPE_ROOM } // END
};
@@ -71,6 +70,7 @@ ObjectData const gameObjectData[] =
{ GO_STRANGE_GONG, DATA_STRANGE_GONG },
{ GO_MASSIVE_GATE, DATA_MASSIVE_GATE },
{ GO_GATE_HEXLORD, DATA_HEXLORD_GATE },
{ GO_GATE_ZULJIN, DATA_ZULJIN_GATE },
{ 0, 0 }
};
@@ -290,6 +290,11 @@ public:
HandleGameObject(ObjectGuid::Empty, false, GetGameObject(DATA_HEXLORD_GATE));
else if (state == NOT_STARTED)
CheckInstanceStatus();
else if (state == DONE)
{
if (GameObject* zuljinGate = GetGameObject(DATA_ZULJIN_GATE))
zuljinGate->RemoveGameObjectFlag(GO_FLAG_LOCKED);
}
break;
}
@@ -41,6 +41,7 @@ enum DataTypes
DATA_HARRISON_JONES = 13,
TYPE_AKILZON_GAUNTLET = 14,
DATA_LOOKOUT = 15,
DATA_ZULJIN_GATE = 16
};
enum CreatureIds
@@ -28,6 +28,7 @@
enum MountSpells
{
SPELL_LANCE_EQUIPPED = 62853,
SPELL_PLAYER_VEHICLE_DEFEND = 66482,
SPELL_MINIONS_DEFEND = 64100,
SPELL_BOSS_DEFEND = 62719,
@@ -152,16 +153,9 @@ public:
return GetTrialOfTheChampionAI<npc_toc5_player_vehicleAI>(pCreature);
}
struct npc_toc5_player_vehicleAI : public NullCreatureAI
struct npc_toc5_player_vehicleAI : public VehicleAI
{
npc_toc5_player_vehicleAI(Creature* pCreature) : NullCreatureAI(pCreature)
{
conditions = sConditionMgr->GetConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_CREATURE_TEMPLATE_VEHICLE, me->GetEntry());
m_ConditionsTimer = 1000;
}
ConditionList conditions;
uint16 m_ConditionsTimer;
npc_toc5_player_vehicleAI(Creature* creature) : VehicleAI(creature) { }
void Reset() override
{
@@ -203,23 +197,25 @@ public:
}
}
//void EnterEvadeMode() { CreatureAI::EnterEvadeMode(); }
void MoveInLineOfSight(Unit* /*who*/) override {}
void UpdateAI(uint32 diff) override
bool BeforeSpellClick(Unit* clicker) override
{
if (m_ConditionsTimer <= diff)
{
if (!conditions.empty())
if (Unit* passenger = me->GetVehicleKit()->GetPassenger(0))
if (!sConditionMgr->IsObjectMeetToConditions(passenger, me, conditions))
passenger->ExitVehicle();
m_ConditionsTimer = VEHICLE_CONDITION_CHECK_TIME;
}
else
m_ConditionsTimer -= diff;
if (!clicker->IsPlayer())
return true;
if (clicker->IsInDisallowedMountForm())
clicker->RemoveAurasByType(SPELL_AURA_MOD_SHAPESHIFT);
if (clicker->HasAura(SPELL_LANCE_EQUIPPED))
return true;
WorldPacket data(SMSG_CAST_FAILED, 1 + 4 + 1);
data << uint8(0); // single cast or multi 2.3 (0/1)
data << uint32(VEHICLE_SPELL_RIDE_HARDCODED);
data << uint8(SPELL_FAILED_CUSTOM_ERROR);
data << uint32(SPELL_CUSTOM_ERROR_MUST_HAVE_LANCE_EQUIPPED);
clicker->ToPlayer()->GetSession()->SendPacket(&data);
return false;
}
void AttackStart(Unit* /*who*/) override {}
void JustEngagedWith(Unit* /*who*/) override {}
};
};
@@ -912,7 +912,7 @@ public:
npc_vengeful_shadeAI(Creature* creature) : ScriptedAI(creature)
{
me->SetControlled(true, UNIT_STATE_ROOT);
unroot_timer = 500;
unroot_timer = 2000;
targetGUID.Clear();
}