Merge branch 'azerothcore:master' into Playerbot

This commit is contained in:
ZhengPeiRu21
2022-03-27 11:23:15 -06:00
committed by GitHub
52 changed files with 3865 additions and 281 deletions

View File

@@ -51,7 +51,8 @@ enum Events
enum Actions
{
ACTION_DISARMED = 0
ACTION_DEACTIVATE = 0,
ACTION_DISARMED = 1
};
class boss_broodlord : public CreatureScript
@@ -75,6 +76,18 @@ public:
events.ScheduleEvent(EVENT_CHECK, 1000);
}
void JustDied(Unit* /*killer*/) override
{
_JustDied();
std::list<GameObject*> _goList;
GetGameObjectListWithEntryInGrid(_goList, me, GO_SUPPRESSION_DEVICE, 200.0f);
for (std::list<GameObject*>::const_iterator itr = _goList.begin(); itr != _goList.end(); itr++)
{
((*itr)->AI()->DoAction(ACTION_DEACTIVATE));
}
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
@@ -183,11 +196,19 @@ class go_suppression_device : public GameObjectScript
void DoAction(int32 action) override
{
if (action == ACTION_DISARMED)
if (action == ACTION_DEACTIVATE)
{
_events.CancelEvent(EVENT_SUPPRESSION_RESET);
}
else if (action == ACTION_DISARMED)
{
Deactivate();
_events.CancelEvent(EVENT_SUPPRESSION_CAST);
_events.ScheduleEvent(EVENT_SUPPRESSION_RESET, urand(30000, 120000));
if (_instance->GetBossState(DATA_BROODLORD_LASHLAYER) != DONE)
{
_events.ScheduleEvent(EVENT_SUPPRESSION_RESET, urand(30000, 120000));
}
}
}

View File

@@ -34,6 +34,7 @@ enum Events
EVENT_CHECK_PHASE_2,
EVENT_START_EVENT,
EVENT_SHADOW_BOLT,
EVENT_SHADOW_BOLT_VOLLEY,
EVENT_FEAR,
EVENT_SILENCE,
EVENT_MIND_CONTROL,
@@ -298,7 +299,8 @@ public:
SetCombatMovement(false);
AttackStart(SelectTarget(SelectTargetMethod::Random, 0, 200.f, true));
events.ScheduleEvent(EVENT_SHADOWBLINK, 500);
events.ScheduleEvent(EVENT_SHADOW_BOLT, urand(3000, 10000));
events.ScheduleEvent(EVENT_SHADOW_BOLT, 3000);
events.ScheduleEvent(EVENT_SHADOW_BOLT_VOLLEY, urand(13000, 15000));
events.ScheduleEvent(EVENT_FEAR, urand(10000, 20000));
events.ScheduleEvent(EVENT_SILENCE, urand(20000, 25000));
events.ScheduleEvent(EVENT_MIND_CONTROL, urand(30000, 35000));
@@ -388,17 +390,12 @@ public:
switch (eventId)
{
case EVENT_SHADOW_BOLT:
switch (urand(0, 1))
{
case 0:
DoCastAOE(SPELL_SHADOWBOLT_VOLLEY);
break;
case 1:
DoCastRandomTarget(SPELL_SHADOWBOLT, 0, 150.f);
break;
}
DoResetThreat();
events.ScheduleEvent(EVENT_SHADOW_BOLT, urand(3000, 10000));
DoCastRandomTarget(SPELL_SHADOWBOLT, 0, 150.f);
events.ScheduleEvent(EVENT_SHADOW_BOLT, urand(2000, 4000));
break;
case EVENT_SHADOW_BOLT_VOLLEY:
DoCastAOE(SPELL_SHADOWBOLT_VOLLEY);
events.ScheduleEvent(EVENT_SHADOW_BOLT_VOLLEY, 19000, 25000);
break;
case EVENT_FEAR:
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 40, true))
@@ -412,7 +409,7 @@ public:
case EVENT_MIND_CONTROL:
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 40, true))
DoCast(target, SPELL_SHADOW_COMMAND);
events.ScheduleEvent(EVENT_MIND_CONTROL, urand(30000, 35000));
events.ScheduleEvent(EVENT_MIND_CONTROL, urand(24000, 30000));
break;
case EVENT_SHADOWBLINK:
DoCastSelf(SPELL_SHADOWBLINK);
@@ -436,6 +433,7 @@ public:
events.CancelEvent(EVENT_MIND_CONTROL);
events.CancelEvent(EVENT_FEAR);
events.CancelEvent(EVENT_SHADOW_BOLT);
events.CancelEvent(EVENT_SHADOW_BOLT_VOLLEY);
events.CancelEvent(EVENT_SILENCE);
DoCastSelf(SPELL_ROOT_SELF, true);
me->SetVisible(false);
@@ -470,6 +468,8 @@ public:
me->SetUInt32Value(UNIT_NPC_FLAGS, 0);
me->SetStandState(UNIT_STAND_STATE_STAND);
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_NOT_SELECTABLE);
// Due to Nefarius despawning himself on Vael, we need to update the guid on instance to prevent unwanted behaviours as encounter not resetting at all.
instance->SetGuidData(DATA_LORD_VICTOR_NEFARIUS, me->GetGUID());
}
}

View File

@@ -124,7 +124,7 @@ public:
events.ScheduleEvent(EVENT_CLEAVE, 10000);
events.ScheduleEvent(EVENT_FLAME_BREATH, 15000);
events.ScheduleEvent(EVENT_FIRE_NOVA, 20000);
events.ScheduleEvent(EVENT_FIRE_NOVA, 5000);
events.ScheduleEvent(EVENT_TAIL_SWEEP, 11000);
events.ScheduleEvent(EVENT_BURNING_ADRENALINE, 15000);
}
@@ -220,7 +220,7 @@ public:
break;
case EVENT_FIRE_NOVA:
DoCastVictim(SPELL_FIRE_NOVA);
events.ScheduleEvent(EVENT_FIRE_NOVA, 15000);
events.ScheduleEvent(EVENT_FIRE_NOVA, urand(3000, 5000));
break;
case EVENT_TAIL_SWEEP:
DoCastAOE(SPELL_TAIL_SWEEP);

View File

@@ -357,6 +357,18 @@ public:
return ObjectGuid::Empty;
}
void SetGuidData(uint32 type, ObjectGuid data) override
{
switch (type)
{
case DATA_LORD_VICTOR_NEFARIUS:
victorNefariusGUID = data;
break;
default:
break;
}
}
void OnUnitDeath(Unit* unit) override
{
switch (unit->GetEntry())

View File

@@ -1171,6 +1171,52 @@ public:
}
};
class spell_death_knight_initiate_visual : public SpellScript
{
PrepareSpellScript(spell_death_knight_initiate_visual);
void HandleScriptEffect(SpellEffIndex /* effIndex */)
{
Creature* target = GetHitCreature();
if (!target)
return;
uint32 spellId;
switch (target->GetDisplayId())
{
case 25369: spellId = 51552; break; // bloodelf female
case 25373: spellId = 51551; break; // bloodelf male
case 25363: spellId = 51542; break; // draenei female
case 25357: spellId = 51541; break; // draenei male
case 25361: spellId = 51537; break; // dwarf female
case 25356: spellId = 51538; break; // dwarf male
case 25372: spellId = 51550; break; // forsaken female
case 25367: spellId = 51549; break; // forsaken male
case 25362: spellId = 51540; break; // gnome female
case 25359: spellId = 51539; break; // gnome male
case 25355: spellId = 51534; break; // human female
case 25354: spellId = 51520; break; // human male
case 25360: spellId = 51536; break; // nightelf female
case 25358: spellId = 51535; break; // nightelf male
case 25368: spellId = 51544; break; // orc female
case 25364: spellId = 51543; break; // orc male
case 25371: spellId = 51548; break; // tauren female
case 25366: spellId = 51547; break; // tauren male
case 25370: spellId = 51545; break; // troll female
case 25365: spellId = 51546; break; // troll male
default: return;
}
target->CastSpell(target, spellId, true);
target->LoadEquipment();
}
void Register() override
{
OnEffectHitTarget += SpellEffectFn(spell_death_knight_initiate_visual::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
}
};
void AddSC_the_scarlet_enclave_c1()
{
// Ours
@@ -1191,4 +1237,6 @@ void AddSC_the_scarlet_enclave_c1()
new npc_scarlet_miner();
new npc_scarlet_miner_cart();
new go_inconspicuous_mine_car();
RegisterSpellScript(spell_death_knight_initiate_visual);
}

View File

@@ -268,6 +268,11 @@ public:
BindPlayers();
me->SetInCombatWithZone();
if (!_startTimer)
{
TurnGates(true, false);
}
}
void InitializeAI() override

View File

@@ -242,17 +242,19 @@ public:
summons.DespawnAll();
if (m_pInstance)
{
m_pInstance->SetData(TYPE_KOLOGARN, NOT_STARTED);
// Open the door inside Kologarn chamber
if (GameObject* door = m_pInstance->instance->GetGameObject(m_pInstance->GetGuidData(GO_KOLOGARN_DOORS)))
door->SetGoState(GO_STATE_ACTIVE);
}
AttachLeftArm();
AttachRightArm();
// Reset breath on pull
breathReady = false;
// Open the door inside Kologarn chamber
if (GameObject* door = me->FindNearestGameObject(GO_KOLOGARN_DOORS, 100.0f))
door->SetGoState(GO_STATE_ACTIVE);
}
void DoAction(int32 param) override
@@ -301,6 +303,13 @@ public:
Talk(SAY_DEATH);
if (m_pInstance)
{
// Open the door inside Kologarn chamber
if (GameObject* door = m_pInstance->instance->GetGameObject(m_pInstance->GetGuidData(GO_KOLOGARN_DOORS)))
door->SetGoState(GO_STATE_ACTIVE);
}
if (GameObject* bridge = me->FindNearestGameObject(GO_KOLOGARN_BRIDGE, 100))
bridge->SetGoState(GO_STATE_READY);
@@ -384,8 +393,13 @@ public:
me->setActive(true);
// Close the door inside Kologarn chamber
if (GameObject* door = me->FindNearestGameObject(GO_KOLOGARN_DOORS, 100.0f))
door->SetGoState(GO_STATE_READY);
if (m_pInstance)
{
if (GameObject* door = m_pInstance->instance->GetGameObject(m_pInstance->GetGuidData(GO_KOLOGARN_DOORS)))
{
door->SetGoState(GO_STATE_READY);
}
}
}
void UpdateAI(uint32 diff) override

View File

@@ -16,12 +16,14 @@
*/
#include "ulduar.h"
#include "CombatAI.h"
#include "Player.h"
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "ScriptedGossip.h"
#include "SpellAuraEffects.h"
#include "SpellScript.h"
#include "Vehicle.h"
class npc_ulduar_keeper : public CreatureScript
{
@@ -423,6 +425,31 @@ public:
}
};
struct npc_salvaged_siege_engine : public VehicleAI
{
npc_salvaged_siege_engine(Creature* creature) : VehicleAI(creature) { }
bool BeforeSpellClick(Unit* clicker) override
{
if (Vehicle* vehicle = me->GetVehicleKit())
{
if (vehicle->IsVehicleInUse())
{
if (Unit* turret = vehicle->GetPassenger(7))
{
if (!turret->GetVehicleKit()->IsVehicleInUse())
{
turret->HandleSpellClick(clicker);
return false;
}
}
}
}
return true;
}
};
void AddSC_ulduar()
{
new npc_ulduar_keeper();
@@ -435,4 +462,6 @@ void AddSC_ulduar()
new AreaTrigger_at_celestial_planetarium_enterance();
new go_call_tram();
RegisterCreatureAI(npc_salvaged_siege_engine);
}

View File

@@ -20,17 +20,18 @@
#include "MapMgr.h"
#include "ObjectMgr.h"
#include "OutdoorPvP.h"
#include "OutdoorPvPMgr.h"
#include "Player.h"
#include "ScriptMgr.h"
#include "World.h"
#include "WorldPacket.h"
#include "GameTime.h"
OutdoorPvPTF::OutdoorPvPTF()
{
m_TypeId = OUTDOOR_PVP_TF;
m_IsLocked = false;
m_JustLocked = false;
m_LockTimer = TF_LOCK_TIME;
m_LockTimerUpdate = 0;
@@ -105,6 +106,71 @@ void OutdoorPvPTF::SendRemoveWorldStates(Player* player)
}
}
void OutdoorPvPTF::SaveRequiredWorldStates() const
{
sWorld->setWorldState(TF_UI_TOWER_COUNT_H, m_HordeTowersControlled);
sWorld->setWorldState(TF_UI_TOWER_COUNT_A, m_AllianceTowersControlled);
sWorld->setWorldState(TF_UI_TOWERS_CONTROLLED_DISPLAY, m_IsLocked);
// Save expiry as unix
uint32 const lockExpireTime = GameTime::GetGameTime().count() + (m_LockTimer / IN_MILLISECONDS);
sWorld->setWorldState(TF_UI_LOCKED_TIME_HOURS, lockExpireTime);
}
void OutdoorPvPTF::ResetZoneToTeamControlled(TeamId team)
{
switch (team)
{
case TEAM_HORDE:
m_HordeTowersControlled = TF_TOWER_NUM;
m_AllianceTowersControlled = 0;
break;
case TEAM_ALLIANCE:
m_HordeTowersControlled = 0;
m_AllianceTowersControlled = TF_TOWER_NUM;
break;
case TEAM_NEUTRAL:
m_HordeTowersControlled = 0;
m_AllianceTowersControlled = 0;
break;
}
for (auto& [guid, tower] : m_capturePoints)
{
dynamic_cast<OPvPCapturePointTF*>(tower)->ResetToTeamControlled(team);
}
SendUpdateWorldState(TF_UI_TOWER_COUNT_H, m_HordeTowersControlled);
SendUpdateWorldState(TF_UI_TOWER_COUNT_A, m_AllianceTowersControlled);
}
void OPvPCapturePointTF::ResetToTeamControlled(TeamId team)
{
switch (team)
{
case TEAM_HORDE:
m_State = OBJECTIVESTATE_HORDE;
m_OldState = OBJECTIVESTATE_HORDE;
m_team = TEAM_HORDE;
break;
case TEAM_ALLIANCE:
m_State = OBJECTIVESTATE_ALLIANCE;
m_OldState = OBJECTIVESTATE_ALLIANCE;
m_team = TEAM_ALLIANCE;
break;
case TEAM_NEUTRAL:
m_State = OBJECTIVESTATE_NEUTRAL;
m_OldState = OBJECTIVESTATE_NEUTRAL;
m_team = TEAM_NEUTRAL;
break;
}
m_value = 0.0f;
ChangeState();
SendChangePhase();
}
void OPvPCapturePointTF::UpdateTowerState()
{
m_PvP->SendUpdateWorldState(uint32(TFTowerWorldStates[m_TowerType].n), uint32(bool(m_TowerState & TF_TOWERSTATE_N)));
@@ -141,6 +207,7 @@ bool OutdoorPvPTF::Update(uint32 diff)
{
TeamApplyBuff(TEAM_ALLIANCE, TF_CAPTURE_BUFF);
m_IsLocked = true;
m_JustLocked = true;
SendUpdateWorldState(TF_UI_LOCKED_DISPLAY_NEUTRAL, uint32(0));
SendUpdateWorldState(TF_UI_LOCKED_DISPLAY_HORDE, uint32(0));
SendUpdateWorldState(TF_UI_LOCKED_DISPLAY_ALLIANCE, uint32(1));
@@ -150,6 +217,7 @@ bool OutdoorPvPTF::Update(uint32 diff)
{
TeamApplyBuff(TEAM_HORDE, TF_CAPTURE_BUFF);
m_IsLocked = true;
m_JustLocked = true;
SendUpdateWorldState(TF_UI_LOCKED_DISPLAY_NEUTRAL, uint32(0));
SendUpdateWorldState(TF_UI_LOCKED_DISPLAY_HORDE, uint32(1));
SendUpdateWorldState(TF_UI_LOCKED_DISPLAY_ALLIANCE, uint32(0));
@@ -160,17 +228,29 @@ bool OutdoorPvPTF::Update(uint32 diff)
TeamCastSpell(TEAM_ALLIANCE, -TF_CAPTURE_BUFF);
TeamCastSpell(TEAM_HORDE, -TF_CAPTURE_BUFF);
}
SendUpdateWorldState(TF_UI_TOWER_COUNT_A, m_AllianceTowersControlled);
SendUpdateWorldState(TF_UI_TOWER_COUNT_H, m_HordeTowersControlled);
}
if (m_IsLocked)
{
if (m_JustLocked)
{
m_JustLocked = false;
SaveRequiredWorldStates();
}
// lock timer is down, release lock
if (m_LockTimer < diff)
{
m_LockTimer = TF_LOCK_TIME;
m_LockTimerUpdate = 0;
m_IsLocked = false;
ResetZoneToTeamControlled(TEAM_NEUTRAL);
SaveRequiredWorldStates();
SendUpdateWorldState(TF_UI_TOWERS_CONTROLLED_DISPLAY, uint32(1));
SendUpdateWorldState(TF_UI_LOCKED_DISPLAY_NEUTRAL, uint32(0));
SendUpdateWorldState(TF_UI_LOCKED_DISPLAY_HORDE, uint32(0));
@@ -182,20 +262,21 @@ bool OutdoorPvPTF::Update(uint32 diff)
if (m_LockTimerUpdate < diff)
{
m_LockTimerUpdate = TF_LOCK_TIME_UPDATE;
uint32 minutes_left = m_LockTimer / 60000;
hours_left = minutes_left / 60;
minutes_left -= hours_left * 60;
second_digit = minutes_left % 10;
first_digit = minutes_left / 10;
RecalculateClientUILockTime();
SendUpdateWorldState(TF_UI_LOCKED_TIME_MINUTES_FIRST_DIGIT, first_digit);
SendUpdateWorldState(TF_UI_LOCKED_TIME_MINUTES_SECOND_DIGIT, second_digit);
SendUpdateWorldState(TF_UI_LOCKED_TIME_HOURS, hours_left);
}
else m_LockTimerUpdate -= diff;
else
{
m_LockTimerUpdate -= diff;
}
m_LockTimer -= diff;
}
}
return changed;
}
@@ -251,7 +332,8 @@ bool OutdoorPvPTF::SetupOutdoorPvP()
m_AllianceTowersControlled = 0;
m_HordeTowersControlled = 0;
m_IsLocked = false;
m_IsLocked = bool(sWorld->getWorldState(TF_UI_TOWERS_CONTROLLED_DISPLAY));
m_JustLocked = false;
m_LockTimer = TF_LOCK_TIME;
m_LockTimerUpdate = 0;
hours_left = 6;
@@ -270,6 +352,30 @@ bool OutdoorPvPTF::SetupOutdoorPvP()
AddCapturePoint(new OPvPCapturePointTF(this, TF_TOWER_SE));
AddCapturePoint(new OPvPCapturePointTF(this, TF_TOWER_S));
if (m_IsLocked)
{
// Core shutdown while locked -- init from latest known data in WorldState
// Convert from unix
int32 const lockRemainingTime = int32((sWorld->getWorldState(TF_UI_LOCKED_TIME_HOURS) - GameTime::GetGameTime().count()) * IN_MILLISECONDS);
if (lockRemainingTime > 0)
{
m_LockTimer = lockRemainingTime;
RecalculateClientUILockTime();
uint32 const hordeTowers = uint32(sWorld->getWorldState(TF_UI_TOWER_COUNT_H));
uint32 const allianceTowers = uint32(sWorld->getWorldState(TF_UI_TOWER_COUNT_A));
TeamId const controllingTeam = hordeTowers > allianceTowers ? TEAM_HORDE : TEAM_ALLIANCE;
ResetZoneToTeamControlled(controllingTeam);
}
else
{
// Lock expired while core was offline
m_IsLocked = false;
SaveRequiredWorldStates();
}
}
return true;
}

View File

@@ -32,10 +32,10 @@ const uint32 OutdoorPvPTFBuffZones[OutdoorPvPTFBuffZonesNum] =
};
// locked for 6 hours after capture
const uint32 TF_LOCK_TIME = 3600 * 6 * 1000;
const uint32 TF_LOCK_TIME = 6 * HOUR * IN_MILLISECONDS;
// update lock timer every 1/4 minute (overkill, but this way it's sure the timer won't "jump" 2 minutes at once.)
const uint32 TF_LOCK_TIME_UPDATE = 15000;
const uint32 TF_LOCK_TIME_UPDATE = 15 * IN_MILLISECONDS;
// blessing of auchindoun
#define TF_CAPTURE_BUFF 33377
@@ -138,6 +138,8 @@ public:
bool HandlePlayerEnter(Player* player) override;
void HandlePlayerLeave(Player* player) override;
void ResetToTeamControlled(TeamId team);
void UpdateTowerState();
protected:
@@ -162,6 +164,19 @@ public:
void SendRemoveWorldStates(Player* player) override;
void SaveRequiredWorldStates() const;
void ResetZoneToTeamControlled(TeamId team);
void RecalculateClientUILockTime()
{
uint32 minutes_left = m_LockTimer / 60000;
hours_left = minutes_left / 60;
minutes_left -= hours_left * 60;
second_digit = minutes_left % 10;
first_digit = minutes_left / 10;
}
uint32 GetAllianceTowersControlled() const;
void SetAllianceTowersControlled(uint32 count);
@@ -172,6 +187,7 @@ public:
private:
bool m_IsLocked;
bool m_JustLocked;
uint32 m_LockTimer;
uint32 m_LockTimerUpdate;

View File

@@ -2101,6 +2101,61 @@ class spell_item_scroll_of_recall : public SpellScript
}
};
// 36890 - Dimensional Ripper - Area 52
enum DimensionalRipperArea52
{
SPELL_TRANSPORTER_MALFUNCTION = 36895,
SPELL_TRANSFORM_HORDE = 36897,
SPELL_TRANSFORM_ALLIANCE = 36899,
SPELL_SOUL_SPLIT_EVIL = 36900,
SPELL_SOUL_SPLIT_GOOD = 36901
};
class spell_item_dimensional_ripper_area52 : public SpellScript
{
PrepareSpellScript(spell_item_dimensional_ripper_area52);
bool Load() override
{
return GetCaster()->GetTypeId() == TYPEID_PLAYER;
}
void HandleScript(SpellEffIndex /* effIndex */)
{
if (!roll_chance_i(50)) // 50% success
return;
Unit* caster = GetCaster();
uint32 spellId = 0;
switch (urand(0, 3))
{
case 0:
spellId = SPELL_TRANSPORTER_MALFUNCTION;
break;
case 1:
spellId = SPELL_SOUL_SPLIT_EVIL;
break;
case 2:
spellId = SPELL_SOUL_SPLIT_GOOD;
break;
case 3:
if (caster->ToPlayer()->GetTeamId() == TEAM_ALLIANCE)
spellId = SPELL_TRANSFORM_HORDE;
else
spellId = SPELL_TRANSFORM_ALLIANCE;
break;
}
caster->CastSpell(caster, spellId, true);
}
void Register() override
{
OnEffectHitTarget += SpellEffectFn(spell_item_dimensional_ripper_area52::HandleScript, EFFECT_0, SPELL_EFFECT_TELEPORT_UNITS);
}
};
// 71169 - Shadow's Fate (Shadowmourne questline)
enum ShadowsFate
{
@@ -3184,6 +3239,28 @@ class spell_item_rocket_boots : public SpellScript
}
};
class spell_item_runic_healing_injector : public SpellScript
{
PrepareSpellScript(spell_item_runic_healing_injector);
bool Load() override
{
return GetCaster()->GetTypeId() == TYPEID_PLAYER;
}
void HandleHeal(SpellEffIndex /*effIndex*/)
{
if (Player* caster = GetCaster()->ToPlayer())
if (caster->HasSkill(SKILL_ENGINEERING))
SetHitHeal(GetHitHeal() * 1.25f);
}
void Register() override
{
OnEffectHitTarget += SpellEffectFn(spell_item_runic_healing_injector::HandleHeal, EFFECT_0, SPELL_EFFECT_HEAL);
}
};
enum PygmyOil
{
SPELL_PYGMY_OIL_PYGMY_AURA = 53806,
@@ -3585,6 +3662,7 @@ void AddSC_item_spell_scripts()
RegisterSpellScript(spell_item_piccolo_of_the_flaming_fire);
RegisterSpellScript(spell_item_savory_deviate_delight);
RegisterSpellScript(spell_item_scroll_of_recall);
RegisterSpellScript(spell_item_dimensional_ripper_area52);
RegisterSpellScript(spell_item_unsated_craving);
RegisterSpellScript(spell_item_shadows_fate);
RegisterSpellScript(spell_item_shadowmourne);
@@ -3612,6 +3690,7 @@ void AddSC_item_spell_scripts()
RegisterSpellScript(spell_item_nitro_boots);
RegisterSpellScript(spell_item_teach_language);
RegisterSpellScript(spell_item_rocket_boots);
RegisterSpellScript(spell_item_runic_healing_injector);
RegisterSpellScript(spell_item_pygmy_oil);
RegisterSpellScript(spell_item_unusual_compass);
RegisterSpellScript(spell_item_chicken_cover);

View File

@@ -27,6 +27,7 @@
#include "SpellAuraEffects.h"
#include "SpellMgr.h"
#include "SpellScript.h"
#include "TemporarySummon.h"
enum PriestSpells
{
@@ -37,6 +38,7 @@ enum PriestSpells
SPELL_PRIEST_GLYPH_OF_PRAYER_OF_HEALING_HEAL = 56161,
SPELL_PRIEST_GUARDIAN_SPIRIT_HEAL = 48153,
SPELL_PRIEST_ITEM_EFFICIENCY = 37595,
SPELL_PRIEST_LIGHTWELL_CHARGES = 59907,
SPELL_PRIEST_MANA_LEECH_PROC = 34650,
SPELL_PRIEST_PENANCE_R1 = 47540,
SPELL_PRIEST_PENANCE_R1_DAMAGE = 47758,
@@ -61,6 +63,16 @@ enum PriestSpellIcons
PRIEST_ICON_ID_PAIN_AND_SUFFERING = 2874,
};
enum Mics
{
PRIEST_LIGHTWELL_NPC_1 = 31897,
PRIEST_LIGHTWELL_NPC_2 = 31896,
PRIEST_LIGHTWELL_NPC_3 = 31895,
PRIEST_LIGHTWELL_NPC_4 = 31894,
PRIEST_LIGHTWELL_NPC_5 = 31893,
PRIEST_LIGHTWELL_NPC_6 = 31883
};
class spell_pri_shadowfiend_scaling : public AuraScript
{
PrepareAuraScript(spell_pri_shadowfiend_scaling);
@@ -359,6 +371,48 @@ class spell_pri_item_greater_heal_refund : public AuraScript
}
};
// 60123 - Lightwell
class spell_pri_lightwell : public SpellScript
{
PrepareSpellScript(spell_pri_lightwell);
bool Load() override
{
return GetCaster()->GetTypeId() == TYPEID_UNIT;
}
void HandleScriptEffect(SpellEffIndex /* effIndex */)
{
Creature* caster = GetCaster()->ToCreature();
if (!caster || !caster->IsSummon())
return;
uint32 lightwellRenew = 0;
switch (caster->GetEntry())
{
case PRIEST_LIGHTWELL_NPC_1: lightwellRenew = 7001; break;
case PRIEST_LIGHTWELL_NPC_2: lightwellRenew = 27873; break;
case PRIEST_LIGHTWELL_NPC_3: lightwellRenew = 27874; break;
case PRIEST_LIGHTWELL_NPC_4: lightwellRenew = 28276; break;
case PRIEST_LIGHTWELL_NPC_5: lightwellRenew = 48084; break;
case PRIEST_LIGHTWELL_NPC_6: lightwellRenew = 48085; break;
}
// proc a spellcast
if (Aura* chargesAura = caster->GetAura(SPELL_PRIEST_LIGHTWELL_CHARGES))
{
caster->CastSpell(GetHitUnit(), lightwellRenew, caster->ToTempSummon()->GetSummonerGUID());
if (chargesAura->ModCharges(-1))
caster->ToTempSummon()->UnSummon();
}
}
void Register() override
{
OnEffectHitTarget += SpellEffectFn(spell_pri_lightwell::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
}
};
// -7001 - Lightwell Renew
class spell_pri_lightwell_renew : public AuraScript
{
@@ -854,6 +908,7 @@ void AddSC_priest_spell_scripts()
RegisterSpellScript(spell_pri_guardian_spirit);
RegisterSpellScript(spell_pri_hymn_of_hope);
RegisterSpellScript(spell_pri_item_greater_heal_refund);
RegisterSpellScript(spell_pri_lightwell);
RegisterSpellScript(spell_pri_lightwell_renew);
RegisterSpellScript(spell_pri_mana_burn);
RegisterSpellScript(spell_pri_mana_leech);

View File

@@ -840,6 +840,33 @@ public:
}
};
enum BendingShinbone
{
SPELL_BENDING_SHINBONE1 = 8854,
SPELL_BENDING_SHINBONE2 = 8855
};
class spell_q1846_bending_shinbone : public SpellScript
{
PrepareSpellScript(spell_q1846_bending_shinbone);
void HandleScriptEffect(SpellEffIndex /* effIndex */)
{
Item* target = GetHitItem();
Unit* caster = GetCaster();
if (!target && caster->GetTypeId() != TYPEID_PLAYER)
return;
uint32 const spellId = roll_chance_i(20) ? SPELL_BENDING_SHINBONE1 : SPELL_BENDING_SHINBONE2;
caster->CastSpell(caster, spellId, true);
}
void Register() override
{
OnEffectHitTarget += SpellEffectFn(spell_q1846_bending_shinbone::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
}
};
// 9712 - Thaumaturgy Channel
enum ThaumaturgyChannel
{
@@ -2400,6 +2427,7 @@ void AddSC_quest_spell_scripts()
RegisterSpellScript(spell_q10985_light_of_the_naaru);
RegisterSpellScript(spell_q9718_crow_transform);
new spell_q55_sacred_cleansing();
RegisterSpellScript(spell_q1846_bending_shinbone);
RegisterSpellScript(spell_q2203_thaumaturgy_channel);
RegisterSpellScript(spell_q5206_test_fetid_skull);
RegisterSpellScript(spell_q6124_6129_apply_salve);