Merge branch 'azerothcore:master' into Playerbot

This commit is contained in:
ZhengPeiRu21
2023-03-29 06:29:03 -06:00
committed by GitHub
17 changed files with 572 additions and 138 deletions

View File

@@ -12568,15 +12568,18 @@ bool Player::isHonorOrXPTarget(Unit* victim) const
// Victim level less gray level
if (v_level <= k_grey)
{
return false;
}
if (victim->GetTypeId() == TYPEID_UNIT)
{
if (victim->IsTotem() ||
victim->IsPet() ||
victim->ToCreature()->GetCreatureTemplate()->flags_extra & CREATURE_FLAG_EXTRA_NO_XP)
if (victim->IsTotem() || victim->IsCritter() || victim->IsPet() || (victim->ToCreature()->GetCreatureTemplate()->flags_extra & CREATURE_FLAG_EXTRA_NO_XP))
{
return false;
}
}
return true;
}

View File

@@ -8318,6 +8318,12 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
if (procEx & PROC_EX_CRITICAL_HIT)
damage /= 2;
// do not proc off from itself
if (procSpell->Id == 45297 || procSpell->Id == 45284)
{
return false;
}
do
{
uint32 spell = 0;
@@ -17997,8 +18003,10 @@ void Unit::Kill(Unit* killer, Unit* victim, bool durabilityLoss, WeaponAttackTyp
sScriptMgr->OnCreatureKilledByPet( killer->GetCharmerOrOwnerPlayerOrPlayerItself(), victim->ToCreature());
}
if (killer != victim && !victim->IsCritter())
if (killer != victim)
{
Unit::ProcDamageAndSpell(killer, victim, killer ? PROC_FLAG_KILL : 0, PROC_FLAG_KILLED, PROC_EX_NONE, 0, attackType, spellProto, nullptr, -1, spell);
}
// Proc auras on death - must be before aura/combat remove
Unit::ProcDamageAndSpell(victim, nullptr, PROC_FLAG_DEATH, PROC_FLAG_NONE, PROC_EX_NONE, 0, attackType, spellProto, nullptr, -1, spell);

View File

@@ -4501,6 +4501,12 @@ void SpellMgr::LoadSpellInfoCorrections()
spellInfo->AttributesEx |= SPELL_ATTR1_NO_REFLECTION;
});
// Turn the Tables
ApplySpellFix({ 51627, 51628, 51629 }, [](SpellInfo* spellInfo)
{
spellInfo->AttributesEx3 |= SPELL_ATTR3_DOT_STACKING_RULE;
});
for (uint32 i = 0; i < GetSpellInfoStoreSize(); ++i)
{
SpellInfo* spellInfo = mSpellInfoMap[i];

View File

@@ -3347,13 +3347,19 @@ public:
EventMap events;
bool _didWebBeam;
void InitializeAI() override
{
me->SetDisableGravity(true);
me->SetImmuneToAll(true);
me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_CUSTOM_SPELL_03);
}
void Reset() override
{
events.Reset();
events.ScheduleEvent(1, 3s, 10s); // Crypt Scarabs
events.ScheduleEvent(2, 15s, 25s); // Dark Mending
events.ScheduleEvent(3, 8s, 15s); // Web Wrap
me->AddUnitState(UNIT_STATE_NO_ENVIRONMENT_UPD);
}
void MoveInLineOfSight(Unit* who) override
@@ -3364,9 +3370,10 @@ public:
float nx = me->GetPositionX();
float ny = me->GetPositionY();
float nz = me->GetFloorZ();
DoCastSelf(SPELL_WEB_BEAM);
me->SetHomePosition(nx, ny, nz, me->GetOrientation());
me->CastSpell(me, SPELL_WEB_BEAM, false);
me->GetMotionMaster()->MovePoint(1, nx, ny, nz, false);
me->GetMotionMaster()->MoveLand(1, nx, ny, nz, false);
me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_NONE);
return;
}
@@ -3386,20 +3393,19 @@ public:
if (me->IsLevitating())
{
me->SetDisableGravity(false);
me->SetImmuneToAll(false);
me->NearTeleportTo(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation());
}
}
void MovementInform(uint32 type, uint32 id) override
void MovementInform(uint32 /*type*/, uint32 id) override
{
if (type == POINT_MOTION_TYPE && id == 1)
if (id == 1)
{
if (me->IsLevitating())
{
me->SetDisableGravity(false);
me->SetOrientation(0.0f);
me->NearTeleportTo(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation());
me->ClearUnitState(UNIT_STATE_NO_ENVIRONMENT_UPD);
}
}
}
@@ -3516,7 +3522,7 @@ public:
if (spider->GetPositionZ() > 220.0f)
{
spider->CastSpell(spider, SPELL_WEB_BEAM2, false);
spider->GetMotionMaster()->MovePoint(POINT_ENTER_COMBAT, spider->GetPositionX(), spider->GetPositionY(), 213.03f, false);
spider->GetMotionMaster()->MoveLand(POINT_ENTER_COMBAT, spider->GetPositionX(), spider->GetPositionY(), 213.03f, false);
}
}

View File

@@ -56,6 +56,7 @@ struct boss_talon_king_ikiss : public BossAI
_Reset();
_spoken = false;
_manaShield = false;
_comboHealthStages.fill(false);
}
void MoveInLineOfSight(Unit* who) override
@@ -74,25 +75,13 @@ struct boss_talon_king_ikiss : public BossAI
_JustEngagedWith();
Talk(SAY_AGGRO);
scheduler.Schedule(35s, [this](TaskContext context)
{
me->InterruptNonMeleeSpells(false);
DoCastAOE(SPELL_BLINK);
Talk(EMOTE_ARCANE_EXP);
context.Repeat(35s, 40s);
scheduler.Schedule(1s, [this](TaskContext)
{
DoCastAOE(SPELL_ARCANE_EXPLOSION);
DoCastSelf(SPELL_ARCANE_BUBBLE, true);
});
}).Schedule(5s, [this](TaskContext context)
scheduler.Schedule(5s, [this](TaskContext context)
{
DoCastAOE(SPELL_ARCANE_VOLLEY);
context.Repeat(7s, 12s);
}).Schedule(8s, [this](TaskContext context)
{
IsHeroic() ? DoCastRandomTarget(SPELL_POLYMORPH) : DoCastMaxThreat(SPELL_POLYMORPH);
DoCastRandomTarget(SPELL_POLYMORPH);
context.Repeat(15s, 17500ms);
});
@@ -119,6 +108,60 @@ struct boss_talon_king_ikiss : public BossAI
void DamageTaken(Unit* /*attacker*/, uint32& damage, DamageEffectType /*damagetype*/, SpellSchoolMask /*damageSchoolMask*/) override
{
if (!_comboHealthStages[0] && me->HealthBelowPctDamaged(80, damage))
{
_comboHealthStages[0] = true;
me->InterruptNonMeleeSpells(false);
DoCastSelf(SPELL_ARCANE_BUBBLE, true);
DoCastAOE(SPELL_BLINK);
Talk(EMOTE_ARCANE_EXP);
scheduler.Schedule(1s, [this](TaskContext)
{
DoCastAOE(SPELL_ARCANE_EXPLOSION);
}).Schedule(6500ms, [this](TaskContext /*context*/)
{
me->GetThreatMgr().ResetAllThreat();
});
}
if (!_comboHealthStages[1] && me->HealthBelowPctDamaged(50, damage))
{
_comboHealthStages[1] = true;
me->InterruptNonMeleeSpells(false);
DoCastSelf(SPELL_ARCANE_BUBBLE, true);
DoCastAOE(SPELL_BLINK);
Talk(EMOTE_ARCANE_EXP);
scheduler.Schedule(1s, [this](TaskContext)
{
DoCastAOE(SPELL_ARCANE_EXPLOSION);
}).Schedule(6500ms, [this](TaskContext /*context*/)
{
me->GetThreatMgr().ResetAllThreat();
});
}
if (!_comboHealthStages[2] && me->HealthBelowPctDamaged(25, damage))
{
_comboHealthStages[2] = true;
me->InterruptNonMeleeSpells(false);
DoCastSelf(SPELL_ARCANE_BUBBLE, true);
DoCastAOE(SPELL_BLINK);
Talk(EMOTE_ARCANE_EXP);
scheduler.Schedule(1s, [this](TaskContext)
{
DoCastAOE(SPELL_ARCANE_EXPLOSION);
}).Schedule(6500ms, [this](TaskContext /*context*/)
{
me->GetThreatMgr().ResetAllThreat();
});
}
if (!_manaShield && me->HealthBelowPctDamaged(20, damage))
{
DoCast(me, SPELL_MANA_SHIELD);
@@ -132,9 +175,10 @@ struct boss_talon_king_ikiss : public BossAI
Talk(SAY_SLAY);
}
private:
bool _spoken;
bool _manaShield;
private:
bool _spoken;
bool _manaShield;
std::array<bool, 3> _comboHealthStages;
};
// 38194 - Blink

View File

@@ -21,10 +21,11 @@
enum HydromancerThespia
{
SAY_SUMMON = 0,
SAY_SUMMON = 0, // Unused or Unknown Use
SAY_AGGRO = 1,
SAY_SLAY = 2,
SAY_DEAD = 3,
SAY_SPELL = 4,
SPELL_LIGHTNING_CLOUD = 25033,
SPELL_LUNG_BURST = 31481,
@@ -55,9 +56,9 @@ struct boss_hydromancer_thespia : public BossAI
{
Talk(SAY_AGGRO);
_JustEngagedWith();
events.ScheduleEvent(EVENT_SPELL_LIGHTNING, 15000);
events.ScheduleEvent(EVENT_SPELL_LUNG, 7000);
events.ScheduleEvent(EVENT_SPELL_ENVELOPING, 9000);
events.ScheduleEvent(EVENT_SPELL_LIGHTNING, 9800);
events.ScheduleEvent(EVENT_SPELL_LUNG, 13300);
events.ScheduleEvent(EVENT_SPELL_ENVELOPING, 14500);
}
void UpdateAI(uint32 diff) override
@@ -69,21 +70,17 @@ struct boss_hydromancer_thespia : public BossAI
switch (events.ExecuteEvent())
{
case EVENT_SPELL_LIGHTNING:
for (uint8 i = 0; i < DUNGEON_MODE(1, 2); ++i)
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0))
me->CastSpell(target, SPELL_LIGHTNING_CLOUD, false);
events.RepeatEvent(urand(15000, 25000));
Talk(SAY_SPELL);
DoCastRandomTarget(SPELL_LIGHTNING_CLOUD);
events.RepeatEvent(urand(12100, 14500));
break;
case EVENT_SPELL_LUNG:
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0))
DoCast(target, SPELL_LUNG_BURST);
events.RepeatEvent(urand(7000, 12000));
DoCastRandomTarget(SPELL_LUNG_BURST);
events.RepeatEvent(urand(21800, 25400));
break;
case EVENT_SPELL_ENVELOPING:
for (uint8 i = 0; i < DUNGEON_MODE(1, 2); ++i)
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0))
me->CastSpell(target, SPELL_ENVELOPING_WINDS, false);
events.RepeatEvent(urand(10000, 15000));
DoCastRandomTarget(SPELL_ENVELOPING_WINDS);
events.RepeatEvent(urand(30000, 40000));
break;
}

View File

@@ -19,6 +19,12 @@
#include "ScriptMgr.h"
#include "steam_vault.h"
enum MainChambersAccessPanelSays
{
SAY_FAINT_ECHO = 0,
SAY_LOUD_RUMBLE = 1
};
class go_main_chambers_access_panel : public GameObjectScript
{
public:
@@ -28,11 +34,16 @@ public:
{
if (InstanceScript* instance = go->GetInstanceScript())
{
Creature* doorController = instance->GetCreature(DATA_DOOR_CONTROLLER);
if (go->GetEntry() == GO_ACCESS_PANEL_HYDRO)
{
if (instance->GetBossState(DATA_HYDROMANCER_THESPIA) == DONE)
{
go->SetGameObjectFlag(GO_FLAG_NOT_SELECTABLE);
if (doorController && doorController->IsAIEnabled)
{
doorController->AI()->Talk(SAY_FAINT_ECHO);
}
}
}
else
@@ -40,12 +51,31 @@ public:
if (instance->GetBossState(DATA_MEKGINEER_STEAMRIGGER) == DONE)
{
go->SetGameObjectFlag(GO_FLAG_NOT_SELECTABLE);
if (doorController && doorController->IsAIEnabled)
{
doorController->AI()->Talk(SAY_FAINT_ECHO);
}
}
}
if (instance->GetBossState(DATA_HYDROMANCER_THESPIA) == DONE && instance->GetBossState(DATA_MEKGINEER_STEAMRIGGER) == DONE)
{
if (GameObject* mainGate = instance->GetGameObject(DATA_MAIN_CHAMBERS_DOOR))
if (doorController)
{
if (doorController->IsAIEnabled)
{
doorController->AI()->Talk(SAY_LOUD_RUMBLE);
}
doorController->m_Events.AddEventAtOffset([instance]()
{
if (GameObject* mainGate = instance->GetGameObject(DATA_MAIN_CHAMBERS_DOOR))
{
instance->HandleGameObject(ObjectGuid::Empty, true, mainGate);
}
}, 4s);
}
else if (GameObject* mainGate = instance->GetGameObject(DATA_MAIN_CHAMBERS_DOOR))
{
instance->HandleGameObject(ObjectGuid::Empty, true, mainGate);
}
@@ -60,7 +90,8 @@ public:
ObjectData const creatureData[] =
{
{ NPC_MEKGINEER_STEAMRIGGER, DATA_MEKGINEER_STEAMRIGGER }
{ NPC_MEKGINEER_STEAMRIGGER, DATA_MEKGINEER_STEAMRIGGER },
{ NPC_DOOR_CONTROLLER, DATA_DOOR_CONTROLLER }
};
ObjectData const objectData[] =

View File

@@ -36,7 +36,8 @@ enum steamVault
DATA_ACCESS_PANEL_HYDROMANCER = 4,
DATA_ACCESS_PANEL_MEKGINEER = 5,
DATA_MAIN_CHAMBERS_DOOR = 6
DATA_MAIN_CHAMBERS_DOOR = 6,
DATA_DOOR_CONTROLLER = 7
};
enum steamVaultNPCGO
@@ -47,6 +48,7 @@ enum steamVaultNPCGO
NPC_MEKGINEER_STEAMRIGGER = 17796,
NPC_WARLORD_KALITHRESH = 17798,
NPC_DOOR_CONTROLLER = 20926
};
template <class AI, class T>

View File

@@ -67,8 +67,7 @@ enum MillhouseEvents
EVENT_MILL_CHECK_HEALTH = 20,
EVENT_MILL_PYROBLAST = 21,
EVENT_MILL_BASE_SPELL = 22,
EVENT_MILL_ICEBLOCK = 23
EVENT_MILL_BASE_SPELL = 22
};
class npc_millhouse_manastorm : public CreatureScript
@@ -81,6 +80,7 @@ public:
npc_millhouse_manastormAI(Creature* creature) : ScriptedAI(creature)
{
instance = creature->GetInstanceScript();
_usedIceblock = false;
}
InstanceScript* instance;
@@ -101,6 +101,7 @@ public:
void Reset() override
{
events.Reset();
_usedIceblock = false;
}
void AttackStart(Unit* who) override
@@ -124,7 +125,16 @@ public:
events.ScheduleEvent(EVENT_MILL_CHECK_HEALTH, 1000);
events.ScheduleEvent(EVENT_MILL_PYROBLAST, 30000);
events.ScheduleEvent(EVENT_MILL_BASE_SPELL, 2000);
events.ScheduleEvent(EVENT_MILL_ICEBLOCK, 1000);
}
void DamageTaken(Unit* /*attacker*/, uint32& damage, DamageEffectType /*type*/, SpellSchoolMask /*school*/) override
{
if (me->HealthBelowPctDamaged(50, damage) && !_usedIceblock)
{
_usedIceblock = true;
Talk(SAY_ICEBLOCK);
DoCastSelf(SPELL_ICEBLOCK, true);
}
}
void UpdateAI(uint32 diff) override
@@ -208,15 +218,6 @@ public:
me->CastSpell(me->GetVictim(), SPELL_PYROBLAST, false);
events.ScheduleEvent(EVENT_MILL_PYROBLAST, 30000);
break;
case EVENT_MILL_ICEBLOCK:
if (me->GetDistance(me->GetVictim()) < 5.0f)
{
Talk(SAY_ICEBLOCK);
me->CastSpell(me, SPELL_ICEBLOCK, true);
break;
}
events.ScheduleEvent(EVENT_MILL_ICEBLOCK, 1000);
break;
case EVENT_MILL_BASE_SPELL:
switch (RAND(SPELL_FIREBALL, SPELL_ARCANE_MISSILES, SPELL_FROSTBOLT))
{
@@ -240,6 +241,9 @@ public:
DoMeleeAttackIfReady();
}
private:
bool _usedIceblock;
};
CreatureAI* GetAI(Creature* creature) const override

View File

@@ -44,23 +44,24 @@ enum Spells
struct boss_dalliah_the_doomsayer : public BossAI
{
boss_dalliah_the_doomsayer(Creature* creature) : BossAI(creature, DATA_DALLIAH), _percentHealthCheck(false) { }
boss_dalliah_the_doomsayer(Creature* creature) : BossAI(creature, DATA_DALLIAH) { }
void Reset() override
{
_Reset();
_percentHealthCheck = false;
me->SetImmuneToAll(false);
ScheduleHealthCheckEvent(25, [&]
{
if (Creature* soccothrates = instance->GetCreature(DATA_SOCCOTHRATES))
{
soccothrates->AI()->Talk(SAY_DALLIAH_25_PERCENT);
}
});
}
void InitializeAI() override
{
BossAI::InitializeAI();
if (instance->GetBossState(DATA_SOCCOTHRATES) != DONE)
{
me->SetImmuneToAll(true);
}
}
void JustDied(Unit* /*killer*/) override
@@ -117,19 +118,6 @@ struct boss_dalliah_the_doomsayer : public BossAI
}
}
void DamageTaken(Unit* /*attacker*/, uint32& damage, DamageEffectType /*damageType*/, SpellSchoolMask /*damageSchoolMask*/) override
{
if (me->HealthBelowPctDamaged(25, damage) && !_percentHealthCheck)
{
if (Creature* soccothrates = instance->GetCreature(DATA_SOCCOTHRATES))
{
soccothrates->AI()->Talk(SAY_DALLIAH_25_PERCENT);
}
_percentHealthCheck = true;
}
}
void KilledUnit(Unit* victim) override
{
if (victim->IsPlayer())
@@ -137,9 +125,6 @@ struct boss_dalliah_the_doomsayer : public BossAI
Talk(SAY_SLAY);
}
}
private:
bool _percentHealthCheck;
};
void AddSC_boss_dalliah_the_doomsayer()

View File

@@ -79,7 +79,6 @@ struct boss_wrath_scryer_soccothrates : public BossAI
_Reset();
events2.Reset();
me->CastSpell(me, SPELL_FEL_IMMOLATION, true);
me->SetImmuneToAll(false);
ScheduleHealthCheckEvent(25, [&]
{
@@ -96,8 +95,6 @@ struct boss_wrath_scryer_soccothrates : public BossAI
void InitializeAI() override
{
BossAI::InitializeAI();
if (!preFight)
me->SetImmuneToAll(true);
}
void JustDied(Unit* /*killer*/) override
@@ -129,9 +126,10 @@ struct boss_wrath_scryer_soccothrates : public BossAI
}
}
scheduler.Schedule(11s, 12s, [this](TaskContext context)
scheduler.Schedule(30s, 35s, [this](TaskContext context)
{
me->CastSpell(me, SPELL_KNOCK_AWAY, false);
me->HandleEmoteCommand(EMOTE_ONESHOT_POINT);
Talk(SAY_KNOCK_AWAY);
scheduler.Schedule(4600ms, [this](TaskContext)
@@ -141,10 +139,7 @@ struct boss_wrath_scryer_soccothrates : public BossAI
scheduler.Schedule(300ms, [this](TaskContext context2)
{
if (me->GetVictim() && !me->IsWithinMeleeRange(me->GetVictim()))
{
DoCastAOE(SPELL_FELFIRE, true);
}
DoCastAOE(SPELL_FELFIRE, true);
if (context2.GetRepeatCounter() <= 6)
{
@@ -153,7 +148,7 @@ struct boss_wrath_scryer_soccothrates : public BossAI
});
});
context.Repeat();
context.Repeat(20s, 35s);
}).Schedule(12s, 14s, [this](TaskContext context)
{
DoCastVictim(SPELL_FELFIRE_SHOCK);

View File

@@ -1450,39 +1450,6 @@ public:
{
go_soulwellAI(GameObject* go) : GameObjectAI(go)
{
_stoneSpell = 0;
_stoneId = 0;
switch (go->GetEntry())
{
case GO_SOUL_WELL_R1:
_stoneSpell = SPELL_CREATE_MASTER_HEALTH_STONE_R0;
if (Unit* owner = go->GetOwner())
{
if (owner->HasAura(SPELL_IMPROVED_HEALTH_STONE_R1))
_stoneSpell = SPELL_CREATE_MASTER_HEALTH_STONE_R1;
else if (owner->HasAura(SPELL_CREATE_MASTER_HEALTH_STONE_R2))
_stoneSpell = SPELL_CREATE_MASTER_HEALTH_STONE_R2;
}
break;
case GO_SOUL_WELL_R2:
_stoneSpell = SPELL_CREATE_FEL_HEALTH_STONE_R0;
if (Unit* owner = go->GetOwner())
{
if (owner->HasAura(SPELL_IMPROVED_HEALTH_STONE_R1))
_stoneSpell = SPELL_CREATE_FEL_HEALTH_STONE_R1;
else if (owner->HasAura(SPELL_CREATE_MASTER_HEALTH_STONE_R2))
_stoneSpell = SPELL_CREATE_FEL_HEALTH_STONE_R2;
}
break;
}
if (_stoneSpell == 0) // Should never happen
return;
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(_stoneSpell);
if (!spellInfo)
return;
_stoneId = spellInfo->Effects[EFFECT_0].ItemType;
}
/// Due to the fact that this GameObject triggers CMSG_GAMEOBJECT_USE
@@ -1495,40 +1462,93 @@ public:
return false;
Unit* owner = me->GetOwner();
if (_stoneSpell == 0 || _stoneId == 0)
if (!owner)
return true;
uint32 stoneId = 0;
uint32 stoneSpell = 0;
switch (me->GetEntry())
{
case GO_SOUL_WELL_R1:
stoneSpell = SPELL_CREATE_MASTER_HEALTH_STONE_R0;
if (Unit* owner = me->GetOwner())
{
if (owner->HasAura(SPELL_IMPROVED_HEALTH_STONE_R1))
{
stoneSpell = SPELL_CREATE_MASTER_HEALTH_STONE_R1;
}
else if (owner->HasAura(SPELL_CREATE_MASTER_HEALTH_STONE_R2))
{
stoneSpell = SPELL_CREATE_MASTER_HEALTH_STONE_R2;
}
}
break;
case GO_SOUL_WELL_R2:
stoneSpell = SPELL_CREATE_FEL_HEALTH_STONE_R0;
if (Unit* owner = me->GetOwner())
{
if (owner->HasAura(SPELL_IMPROVED_HEALTH_STONE_R1))
{
stoneSpell = SPELL_CREATE_FEL_HEALTH_STONE_R1;
}
else if (owner->HasAura(SPELL_CREATE_MASTER_HEALTH_STONE_R2))
{
stoneSpell = SPELL_CREATE_FEL_HEALTH_STONE_R2;
}
}
break;
}
if (!stoneSpell)
{
if (SpellInfo const* spell = sSpellMgr->GetSpellInfo(_stoneSpell))
Spell::SendCastResult(player, spell, 0, SPELL_FAILED_ERROR);
return true;
}
if (!owner || owner->GetTypeId() != TYPEID_PLAYER || !player->IsInSameRaidWith(owner->ToPlayer()))
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(stoneSpell);
if (!spellInfo)
{
if (SpellInfo const* spell = sSpellMgr->GetSpellInfo(_stoneSpell))
return true;
}
stoneId = spellInfo->Effects[EFFECT_0].ItemType;
if (!stoneId)
{
if (SpellInfo const* spell = sSpellMgr->GetSpellInfo(stoneSpell))
{
Spell::SendCastResult(player, spell, 0, SPELL_FAILED_ERROR);
}
return true;
}
if (owner->GetTypeId() != TYPEID_PLAYER || !player->IsInSameRaidWith(owner->ToPlayer()))
{
if (SpellInfo const* spell = sSpellMgr->GetSpellInfo(stoneSpell))
{
Spell::SendCastResult(player, spell, 0, SPELL_FAILED_TARGET_NOT_IN_RAID);
}
return true;
}
// Don't try to add a stone if we already have one.
if (player->HasItemCount(_stoneId))
if (player->HasItemCount(stoneId))
{
if (SpellInfo const* spell = sSpellMgr->GetSpellInfo(_stoneSpell))
if (SpellInfo const* spell = sSpellMgr->GetSpellInfo(stoneSpell))
{
Spell::SendCastResult(player, spell, 0, SPELL_FAILED_TOO_MANY_OF_ITEM);
}
return true;
}
player->CastSpell(player, _stoneSpell, false);
player->CastSpell(player, stoneSpell, false);
// Item has to actually be created to remove a charge on the well.
if (player->HasItemCount(_stoneId))
if (player->HasItemCount(stoneId))
{
me->AddUse();
}
return true;
}
private:
uint32 _stoneSpell;
uint32 _stoneId;
};
GameObjectAI* GetAI(GameObject* go) const override