mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-01-23 21:56:22 +00:00
Merge branch 'master' into Playerbot
This commit is contained in:
@@ -42,7 +42,9 @@ public:
|
||||
static ChatCommandTable ticketResponseCommandTable =
|
||||
{
|
||||
{ "append", HandleGMTicketResponseAppendCommand, SEC_GAMEMASTER, Console::Yes },
|
||||
{ "appendln", HandleGMTicketResponseAppendLnCommand, SEC_GAMEMASTER, Console::Yes }
|
||||
{ "appendln", HandleGMTicketResponseAppendLnCommand, SEC_GAMEMASTER, Console::Yes },
|
||||
{ "delete", HandleGMTicketResponseDeleteCommand, SEC_GAMEMASTER, Console::Yes },
|
||||
{ "show", HandleGMTicketResponseShowCommand, SEC_GAMEMASTER, Console::Yes }
|
||||
};
|
||||
static ChatCommandTable ticketCommandTable =
|
||||
{
|
||||
@@ -436,10 +438,9 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool _HandleGMTicketResponseAppendCommand(uint32 ticketId, bool newLine, ChatHandler* handler)
|
||||
static bool TicketResponseAppend(uint32 ticketId, bool newLine, ChatHandler* handler, std::string response)
|
||||
{
|
||||
char* response = strtok(nullptr, "\n");
|
||||
if (!response)
|
||||
if (response.empty())
|
||||
return false;
|
||||
|
||||
GmTicket* ticket = sTicketMgr->GetTicket(ticketId);
|
||||
@@ -459,22 +460,74 @@ public:
|
||||
}
|
||||
|
||||
CharacterDatabaseTransaction trans = CharacterDatabaseTransaction(nullptr);
|
||||
ticket->AppendResponse(response);
|
||||
if (newLine)
|
||||
ticket->AppendResponse("\n");
|
||||
ticket->AppendResponse(response);
|
||||
ticket->SaveToDB(trans);
|
||||
sTicketMgr->UpdateLastChange();
|
||||
|
||||
std::string msg = ticket->FormatMessageString(*handler, nullptr, nullptr, nullptr, nullptr);
|
||||
msg += handler->PGetParseString(LANG_COMMAND_TICKETRESPONSEAPPENDED, response);
|
||||
|
||||
handler->PSendSysMessage(msg.c_str());
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool HandleGMTicketResponseAppendCommand(ChatHandler* handler, uint32 ticketId)
|
||||
static bool HandleGMTicketResponseAppendCommand(ChatHandler* handler, uint32 ticketId, Tail res)
|
||||
{
|
||||
return _HandleGMTicketResponseAppendCommand(ticketId, false, handler);
|
||||
return TicketResponseAppend(ticketId, false, handler, res.data());
|
||||
}
|
||||
|
||||
static bool HandleGMTicketResponseAppendLnCommand(ChatHandler* handler, uint32 ticketId)
|
||||
static bool HandleGMTicketResponseAppendLnCommand(ChatHandler* handler, uint32 ticketId, Tail res)
|
||||
{
|
||||
return _HandleGMTicketResponseAppendCommand(ticketId, true, handler);
|
||||
return TicketResponseAppend(ticketId, true, handler, res.data());
|
||||
}
|
||||
|
||||
static bool HandleGMTicketResponseDeleteCommand(ChatHandler* handler, uint32 ticketId)
|
||||
{
|
||||
GmTicket* ticket = sTicketMgr->GetTicket(ticketId);
|
||||
// Don't allow deleting response for a closed ticket.
|
||||
if (!ticket || ticket->IsClosed())
|
||||
{
|
||||
handler->SendSysMessage(LANG_COMMAND_TICKETNOTEXIST);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Cannot delete response for a ticket that is assigned to someone else.
|
||||
//! Console excluded
|
||||
Player* player = handler->GetSession() ? handler->GetSession()->GetPlayer() : nullptr;
|
||||
if (player && ticket->IsAssignedNotTo(player->GetGUID()))
|
||||
{
|
||||
handler->PSendSysMessage(LANG_COMMAND_TICKETALREADYASSIGNED, ticket->GetId());
|
||||
return true;
|
||||
}
|
||||
|
||||
CharacterDatabaseTransaction trans = CharacterDatabaseTransaction(nullptr);
|
||||
ticket->DeleteResponse();
|
||||
ticket->SaveToDB(trans);
|
||||
sTicketMgr->UpdateLastChange();
|
||||
|
||||
std::string msg = ticket->FormatMessageString(*handler, nullptr, nullptr, nullptr, nullptr);
|
||||
msg += handler->PGetParseString(LANG_COMMAND_TICKETRESPONSEDELETED, player ? player->GetName() : "Console");
|
||||
|
||||
handler->SendGlobalGMSysMessage(msg.c_str());
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool HandleGMTicketResponseShowCommand(ChatHandler* handler, uint32 ticketId)
|
||||
{
|
||||
GmTicket* ticket = sTicketMgr->GetTicket(ticketId);
|
||||
if (!ticket)
|
||||
{
|
||||
handler->SendSysMessage(LANG_COMMAND_TICKETNOTEXIST);
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string msg = ticket->FormatMessageString(*handler, nullptr, nullptr, nullptr, nullptr);
|
||||
msg += handler->PGetParseString(LANG_COMMAND_TICKETLISTRESPONSE, ticket->GetResponse());
|
||||
|
||||
handler->PSendSysMessage(msg.c_str());
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -81,6 +81,8 @@ enum Says
|
||||
SAY_RAISE_SKELETONS = 1,
|
||||
SAY_SLAY = 2,
|
||||
SAY_DEATH = 3,
|
||||
SAY_XHEALTH = 14,
|
||||
SAY_SHADOWFLAME = 15,
|
||||
|
||||
SAY_MAGE = 4,
|
||||
SAY_WARRIOR = 5,
|
||||
@@ -109,6 +111,7 @@ enum Paths
|
||||
|
||||
enum GameObjects
|
||||
{
|
||||
GO_DRAKONID_BONES = 179804,
|
||||
GO_PORTCULLIS_ACTIVE = 164726,
|
||||
GO_PORTCULLIS_TOBOSSROOMS = 175186
|
||||
};
|
||||
@@ -136,6 +139,8 @@ enum Spells
|
||||
SPELL_SHADOW_COMMAND = 22667,
|
||||
SPELL_FEAR = 22678,
|
||||
SPELL_SHADOWBLINK = 22664,
|
||||
SPELL_RAISE_DRAKONID = 23362,
|
||||
SPELL_SUMMON_DRAKONID_CORPSE = 23363,
|
||||
|
||||
SPELL_NEFARIANS_BARRIER = 22663,
|
||||
|
||||
@@ -273,6 +278,12 @@ public:
|
||||
{
|
||||
nefarian->DespawnOrUnsummon();
|
||||
}
|
||||
std::list<GameObject*> drakonidBones;
|
||||
me->GetGameObjectListWithEntryInGrid(drakonidBones, GO_DRAKONID_BONES, DEFAULT_VISIBILITY_INSTANCE);
|
||||
for (auto const& bones : drakonidBones)
|
||||
{
|
||||
bones->DespawnOrUnsummon();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -521,19 +532,10 @@ public:
|
||||
|
||||
struct boss_nefarian : public BossAI
|
||||
{
|
||||
boss_nefarian(Creature* creature) : BossAI(creature, DATA_NEFARIAN), _introDone(false)
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
Phase3 = false;
|
||||
}
|
||||
boss_nefarian(Creature* creature) : BossAI(creature, DATA_NEFARIAN), _introDone(false) { }
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
Initialize();
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
me->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
|
||||
me->SetCanFly(true);
|
||||
@@ -552,6 +554,16 @@ struct boss_nefarian : public BossAI
|
||||
}
|
||||
|
||||
classesPresent.clear();
|
||||
|
||||
ScheduleHealthCheckEvent(20, [&]
|
||||
{
|
||||
DoCastSelf(SPELL_RAISE_DRAKONID, true);
|
||||
Talk(SAY_RAISE_SKELETONS);
|
||||
});
|
||||
ScheduleHealthCheckEvent(5, [&]
|
||||
{
|
||||
Talk(SAY_XHEALTH);
|
||||
});
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit* /*who*/) override {}
|
||||
@@ -587,6 +599,7 @@ struct boss_nefarian : public BossAI
|
||||
if (id == 5)
|
||||
{
|
||||
DoCastAOE(SPELL_SHADOWFLAME_INITIAL);
|
||||
Talk(SAY_SHADOWFLAME);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -616,29 +629,6 @@ struct boss_nefarian : public BossAI
|
||||
_introDone = true;
|
||||
}
|
||||
|
||||
void DamageTaken(Unit* /*unit*/, uint32& damage, DamageEffectType, SpellSchoolMask) override
|
||||
{
|
||||
if (me->HealthBelowPctDamaged(20, damage) && !Phase3)
|
||||
{
|
||||
std::list<Creature*> constructList;
|
||||
me->GetCreatureListWithEntryInGrid(constructList, NPC_BONE_CONSTRUCT, 500.0f);
|
||||
for (Creature* const& summon : constructList)
|
||||
{
|
||||
if (summon && !summon->IsAlive())
|
||||
{
|
||||
summon->Respawn();
|
||||
summon->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
|
||||
summon->SetReactState(REACT_AGGRESSIVE);
|
||||
summon->SetStandState(UNIT_STAND_STATE_STAND);
|
||||
DoZoneInCombat(summon);
|
||||
}
|
||||
}
|
||||
|
||||
Phase3 = true;
|
||||
Talk(SAY_RAISE_SKELETONS);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
@@ -762,7 +752,6 @@ struct boss_nefarian : public BossAI
|
||||
}
|
||||
|
||||
private:
|
||||
bool Phase3;
|
||||
bool _introDone;
|
||||
std::set<uint8> classesPresent;
|
||||
};
|
||||
@@ -797,7 +786,7 @@ struct npc_corrupted_totem : public ScriptedAI
|
||||
}
|
||||
|
||||
me->AddAura(AURA_AVOIDANCE, me);
|
||||
_scheduler.CancelAll();
|
||||
scheduler.CancelAll();
|
||||
}
|
||||
|
||||
void SetAura(bool apply) const
|
||||
@@ -877,8 +866,7 @@ struct npc_corrupted_totem : public ScriptedAI
|
||||
{
|
||||
me->SetInCombatWithZone();
|
||||
|
||||
_scheduler
|
||||
.Schedule(1ms, [this](TaskContext context)
|
||||
scheduler.Schedule(1ms, [this](TaskContext context)
|
||||
{
|
||||
if (me->GetEntry() == NPC_TOTEM_C_FIRE_NOVA)
|
||||
{
|
||||
@@ -913,7 +901,7 @@ struct npc_corrupted_totem : public ScriptedAI
|
||||
SetAura(false);
|
||||
}
|
||||
|
||||
_scheduler.CancelAll();
|
||||
scheduler.CancelAll();
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
@@ -923,11 +911,10 @@ struct npc_corrupted_totem : public ScriptedAI
|
||||
return;
|
||||
}
|
||||
|
||||
_scheduler.Update(diff);
|
||||
scheduler.Update(diff);
|
||||
}
|
||||
|
||||
protected:
|
||||
TaskScheduler _scheduler;
|
||||
bool _auraAdded;
|
||||
};
|
||||
|
||||
@@ -940,14 +927,14 @@ struct npc_drakonid_spawner : public ScriptedAI
|
||||
if (action == ACTION_SPAWNER_STOP)
|
||||
{
|
||||
me->RemoveAurasDueToSpell(SPELL_SPAWN_DRAKONID_GEN);
|
||||
_scheduler.CancelAll();
|
||||
scheduler.CancelAll();
|
||||
}
|
||||
}
|
||||
|
||||
void IsSummonedBy(WorldObject* summoner) override
|
||||
{
|
||||
DoCastSelf(SPELL_SPAWN_DRAKONID_GEN);
|
||||
_scheduler.Schedule(10s, 60s, [this](TaskContext /*context*/)
|
||||
scheduler.Schedule(10s, 60s, [this](TaskContext /*context*/)
|
||||
{
|
||||
DoCastSelf(SPELL_SPAWN_CHROMATIC_DRAKONID);
|
||||
});
|
||||
@@ -957,46 +944,29 @@ struct npc_drakonid_spawner : public ScriptedAI
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
_scheduler.Update(diff);
|
||||
scheduler.Update(diff);
|
||||
}
|
||||
|
||||
void SummonedCreatureDies(Creature* summon, Unit* /*unit*/) override
|
||||
{
|
||||
if (summon->GetEntry() != NPC_BONE_CONSTRUCT)
|
||||
if (Creature* victor = ObjectAccessor::GetCreature(*me, _owner))
|
||||
{
|
||||
if (Creature* victor = ObjectAccessor::GetCreature(*me, _owner))
|
||||
{
|
||||
victor->AI()->DoAction(ACTION_NEFARIUS_ADD_KILLED);
|
||||
}
|
||||
|
||||
ObjectGuid summonGuid = summon->GetGUID();
|
||||
|
||||
summon->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
|
||||
summon->SetHomePosition(summon->GetPosition());
|
||||
|
||||
_scheduler.Schedule(1s, [this, summonGuid](TaskContext /*context*/)
|
||||
{
|
||||
if (Creature* construct = ObjectAccessor::GetCreature(*me, summonGuid))
|
||||
{
|
||||
construct->SetVisible(false);
|
||||
}
|
||||
}).Schedule(2s, [this, summonGuid](TaskContext /*context*/)
|
||||
{
|
||||
if (Creature* construct = ObjectAccessor::GetCreature(*me, summonGuid))
|
||||
{
|
||||
construct->UpdateEntry(NPC_BONE_CONSTRUCT, true);
|
||||
construct->SetReactState(REACT_PASSIVE);
|
||||
construct->SetStandState(UNIT_STAND_STATE_DEAD);
|
||||
construct->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
|
||||
construct->SetCorpseRemoveTime(DAY * IN_MILLISECONDS);
|
||||
construct->SetVisible(true);
|
||||
}
|
||||
});
|
||||
victor->AI()->DoAction(ACTION_NEFARIUS_ADD_KILLED);
|
||||
}
|
||||
|
||||
ObjectGuid summonGuid = summon->GetGUID();
|
||||
|
||||
scheduler.Schedule(1s, [this, summonGuid](TaskContext /*context*/)
|
||||
{
|
||||
if (Creature* construct = ObjectAccessor::GetCreature(*me, summonGuid))
|
||||
{
|
||||
construct->SetVisible(false);
|
||||
construct->CastSpell(construct, SPELL_SUMMON_DRAKONID_CORPSE, true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected:
|
||||
TaskScheduler _scheduler;
|
||||
ObjectGuid _owner;
|
||||
};
|
||||
|
||||
|
||||
@@ -20,24 +20,27 @@
|
||||
#include "PassiveAI.h"
|
||||
#include "Player.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "SpellScript.h"
|
||||
#include "SpellScriptLoader.h"
|
||||
#include "TaskScheduler.h"
|
||||
#include "karazhan.h"
|
||||
|
||||
enum Spells
|
||||
{
|
||||
// Ground Phase
|
||||
SPELL_RAIN_OF_BONES = 37098,
|
||||
SPELL_SMOKING_BLAST = 37057,
|
||||
SPELL_FIREBALL_BARRAGE = 30282,
|
||||
SPELL_SEARING_CINDERS = 30127,
|
||||
// Air Phase
|
||||
SPELL_BELLOWING_ROAR = 39427,
|
||||
SPELL_CLEAVE = 30131,
|
||||
SPELL_CHARRED_EARTH = 30129,
|
||||
SPELL_DISTRACTING_ASH = 30130,
|
||||
SPELL_SMOLDERING_BREATH = 30210,
|
||||
SPELL_TAIL_SWEEP = 25653,
|
||||
SPELL_SUMMON_SKELETON = 30170
|
||||
SPELL_SMOLDERING_BREATH = 30210,
|
||||
SPELL_CHARRED_EARTH = 30129,
|
||||
SPELL_BELLOWING_ROAR = 36922,
|
||||
// Air Phase
|
||||
SPELL_SMOKING_BLAST = 30128,
|
||||
SPELL_SMOKING_BLAST_T = 37057,
|
||||
SPELL_RAIN_OF_BONES = 37098,
|
||||
SPELL_SUMMON_SKELETON = 30170,
|
||||
SPELL_DISTRACTING_ASH = 30130,
|
||||
// Both Phases
|
||||
SPELL_FIREBALL_BARRAGE = 30282
|
||||
};
|
||||
|
||||
enum Says
|
||||
@@ -188,21 +191,21 @@ struct boss_nightbane : public BossAI
|
||||
|
||||
void ScheduleGround()
|
||||
{
|
||||
scheduler.Schedule(30s, GROUP_GROUND, [this](TaskContext context)
|
||||
{
|
||||
DoCastAOE(SPELL_BELLOWING_ROAR);
|
||||
context.Repeat(30s, 40s);
|
||||
}).Schedule(15s, GROUP_GROUND, [this](TaskContext context)
|
||||
scheduler.Schedule(18s, 25s, GROUP_GROUND, [this](TaskContext context)
|
||||
{
|
||||
DoCastRandomTarget(SPELL_CHARRED_EARTH, 0, 100.0f, true);
|
||||
context.Repeat(20s);
|
||||
}).Schedule(10s, GROUP_GROUND, [this](TaskContext context)
|
||||
}).Schedule(25s, 35s, GROUP_GROUND, [this](TaskContext context)
|
||||
{
|
||||
DoCastVictim(SPELL_SMOLDERING_BREATH);
|
||||
context.Repeat(20s);
|
||||
}).Schedule(45s, GROUP_GROUND, [this](TaskContext context)
|
||||
{
|
||||
DoCastAOE(SPELL_BELLOWING_ROAR);
|
||||
context.Repeat(32s, 40s);
|
||||
}).Schedule(12s, GROUP_GROUND, [this](TaskContext context)
|
||||
{
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 100, true))
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 100.0f, true))
|
||||
{
|
||||
if (!me->HasInArc(M_PI, target))
|
||||
{
|
||||
@@ -210,14 +213,17 @@ struct boss_nightbane : public BossAI
|
||||
}
|
||||
}
|
||||
context.Repeat(15s);
|
||||
}).Schedule(14s, GROUP_GROUND, [this](TaskContext context)
|
||||
{
|
||||
DoCastRandomTarget(SPELL_SEARING_CINDERS);
|
||||
context.Repeat(10s);
|
||||
}).Schedule(1500ms, GROUP_GROUND, [this](TaskContext context)
|
||||
}).Schedule(5s, GROUP_GROUND, [this](TaskContext context)
|
||||
{
|
||||
DoCastVictim(SPELL_CLEAVE);
|
||||
context.Repeat(1500ms, 45s);
|
||||
context.Repeat(6s, 12s);
|
||||
}).Schedule(25s, GROUP_GROUND, [this](TaskContext context)
|
||||
{
|
||||
if (SelectTarget(SelectTargetMethod::MinDistance, 0, -40.0f, true))
|
||||
{
|
||||
DoCastAOE(SPELL_FIREBALL_BARRAGE);
|
||||
}
|
||||
context.Repeat(3s);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -225,7 +231,7 @@ struct boss_nightbane : public BossAI
|
||||
{
|
||||
_skeletonSpawnCounter = 0;
|
||||
|
||||
scheduler.Schedule(2s, GROUP_AIR, [this](TaskContext)
|
||||
scheduler.Schedule(2s, GROUP_AIR, [this](TaskContext /*context*/)
|
||||
{
|
||||
DoResetThreatList();
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 100.0f))
|
||||
@@ -244,26 +250,31 @@ struct boss_nightbane : public BossAI
|
||||
}
|
||||
});
|
||||
}
|
||||
}).Schedule(20s, GROUP_AIR, [this](TaskContext context)
|
||||
}).Schedule(15s, GROUP_AIR, [this](TaskContext context)
|
||||
{
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random))
|
||||
{
|
||||
me->SetFacingToObject(target);
|
||||
DoCast(target, SPELL_DISTRACTING_ASH);
|
||||
DoCast(target, SPELL_SMOKING_BLAST_T);
|
||||
}
|
||||
context.Repeat(2s); //timer wrong?
|
||||
}).Schedule(25s, GROUP_AIR, [this](TaskContext context)
|
||||
context.Repeat(6s);
|
||||
}).Schedule(15500ms, GROUP_AIR, [this](TaskContext context)
|
||||
{
|
||||
//5 seconds added due to double trigger?
|
||||
//trigger for timer in original + in rain of bones
|
||||
//timers need some investigation
|
||||
me->SetFacingToObject(me->GetVictim());
|
||||
DoCastVictim(SPELL_SMOKING_BLAST);
|
||||
context.Repeat(1500ms); //timer wrong?
|
||||
}).Schedule(13s, GROUP_AIR, [this](TaskContext context)
|
||||
context.Repeat(1500ms);
|
||||
}).Schedule(20s, GROUP_AIR, [this](TaskContext /*context*/)
|
||||
{
|
||||
DoCastOnFarAwayPlayers(SPELL_FIREBALL_BARRAGE, false, 80.0f);
|
||||
context.Repeat(20s);
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 100.0f, true))
|
||||
{
|
||||
DoCast(target, SPELL_DISTRACTING_ASH);
|
||||
}
|
||||
}).Schedule(14s, GROUP_AIR, [this](TaskContext context)
|
||||
{
|
||||
if (SelectTarget(SelectTargetMethod::MinDistance, 0, -40.0f, true))
|
||||
{
|
||||
DoCastAOE(SPELL_FIREBALL_BARRAGE);
|
||||
}
|
||||
context.Repeat(3s);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -407,22 +418,6 @@ struct boss_nightbane : public BossAI
|
||||
summons.Summon(summon);
|
||||
}
|
||||
|
||||
void DoCastOnFarAwayPlayers(uint32 spellid, bool triggered, float tresholddistance)
|
||||
{
|
||||
//resembles DoCastToAllHostilePlayers a bit/lot
|
||||
ThreatContainer::StorageType targets = me->GetThreatMgr().GetThreatList();
|
||||
for (ThreatContainer::StorageType::const_iterator itr = targets.begin(); itr != targets.end(); ++itr)
|
||||
{
|
||||
if (Unit* unit = ObjectAccessor::GetUnit(*me, (*itr)->getUnitGuid()))
|
||||
{
|
||||
if (unit->IsPlayer() && !unit->IsWithinDist(me, tresholddistance, false))
|
||||
{
|
||||
me->CastSpell(unit, spellid, triggered);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TriggerHealthTakeOff()
|
||||
{
|
||||
if (_phase != PHASE_GROUND)
|
||||
@@ -465,7 +460,7 @@ struct boss_nightbane : public BossAI
|
||||
|
||||
void ScheduleLand()
|
||||
{
|
||||
scheduler.Schedule(30s, GROUP_LAND, [this](TaskContext) /*context*/
|
||||
scheduler.Schedule(35s, GROUP_LAND, [this](TaskContext) /*context*/
|
||||
{
|
||||
Talk(YELL_LAND_PHASE);
|
||||
scheduler.CancelGroup(GROUP_AIR);
|
||||
@@ -510,7 +505,6 @@ public:
|
||||
{
|
||||
if (InstanceScript* instance = go->GetInstanceScript())
|
||||
{
|
||||
// if (instance->GetBossState(DATA_NIGHTBANE) == NOT_STARTED || instance->GetBossState(DATA_NIGHTBANE) == FAIL)
|
||||
if (instance->GetBossState(DATA_NIGHTBANE) == NOT_STARTED)
|
||||
{
|
||||
if (Creature* nightbane = instance->GetCreature(DATA_NIGHTBANE))
|
||||
@@ -532,9 +526,30 @@ struct npc_nightbane_helper_target : public NullCreatureAI
|
||||
npc_nightbane_helper_target(Creature* creature) : NullCreatureAI(creature) { me->SetDisableGravity(true); }
|
||||
};
|
||||
|
||||
// 30282 - Fireball Barrage
|
||||
class spell_nightbane_fireball_barrage : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_nightbane_fireball_barrage);
|
||||
|
||||
void FilterTargets(std::list<WorldObject*>& targets)
|
||||
{
|
||||
Unit* caster = GetCaster();
|
||||
targets.remove_if([&](WorldObject* target) -> bool
|
||||
{
|
||||
return !target->IsPlayer() || caster->IsWithinCombatRange(target->ToUnit(), 40.0f);
|
||||
});
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_nightbane_fireball_barrage::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_nightbane()
|
||||
{
|
||||
RegisterKarazhanCreatureAI(boss_nightbane);
|
||||
new go_blackened_urn();
|
||||
RegisterKarazhanCreatureAI(npc_nightbane_helper_target);
|
||||
RegisterSpellScript(spell_nightbane_fireball_barrage);
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ enum Spells
|
||||
{
|
||||
SPELL_BRAIN_WASH_TOTEM = 24262,
|
||||
SPELL_POWERFULL_HEALING_WARD = 24309,
|
||||
SPELL_HEX = 24053,
|
||||
SPELL_HEX = 17172,
|
||||
SPELL_DELUSIONS_OF_JINDO = 24306,
|
||||
SPELL_SUMMON_SHADE_OF_JINDO = 24308,
|
||||
SPELL_BANISH = 24466,
|
||||
|
||||
@@ -164,7 +164,7 @@ struct go_firework_show : public GameObjectAI
|
||||
uint32 posIdx = _show->schedule.entries[_curIdx].spawnIndex;
|
||||
if (posIdx < _show->spawns.size)
|
||||
{
|
||||
me->SummonGameObject(_show->schedule.entries[_curIdx].gameobjectId,
|
||||
GameObject* go = me->SummonGameObject(_show->schedule.entries[_curIdx].gameobjectId,
|
||||
_show->spawns.entries[posIdx].x,
|
||||
_show->spawns.entries[posIdx].y,
|
||||
_show->spawns.entries[posIdx].z,
|
||||
@@ -174,6 +174,13 @@ struct go_firework_show : public GameObjectAI
|
||||
_show->spawns.entries[posIdx].rot2,
|
||||
_show->spawns.entries[posIdx].rot3,
|
||||
0);
|
||||
|
||||
// trigger despawn animation for firework explosion
|
||||
if (go)
|
||||
{
|
||||
go->DespawnOrUnsummon();
|
||||
go->AddObjectToRemoveList();
|
||||
}
|
||||
}
|
||||
|
||||
uint32 ts = _show->schedule.entries[_curIdx].timestamp;
|
||||
|
||||
@@ -243,6 +243,7 @@ struct npc_midsummer_bonfire : public ScriptedAI
|
||||
if (_spellFocus)
|
||||
{
|
||||
_spellFocus->DespawnOrUnsummon();
|
||||
_spellFocus->AddObjectToRemoveList();
|
||||
_spellFocus = nullptr;
|
||||
}
|
||||
|
||||
@@ -378,7 +379,10 @@ struct npc_midsummer_bonfire_despawner : public ScriptedAI
|
||||
{
|
||||
// spawnID is 0 for temp spawns
|
||||
if (0 == (*itr)->GetSpawnId())
|
||||
{
|
||||
(*itr)->DespawnOrUnsummon();
|
||||
(*itr)->AddObjectToRemoveList();
|
||||
}
|
||||
}
|
||||
|
||||
me->DespawnOrUnsummon();
|
||||
|
||||
@@ -60,10 +60,10 @@ public:
|
||||
{
|
||||
DoCastVictim(SPELL_CLEAVE);
|
||||
context.Repeat(8s, 16s);
|
||||
}).Schedule(25s, [this](TaskContext context)
|
||||
}).Schedule(20s, 25s, [this](TaskContext context)
|
||||
{
|
||||
DoCastRandomTarget(SPELL_RAIN_OF_FIRE, 0, 40.f, false);
|
||||
context.Repeat(15s);
|
||||
context.Repeat(12s, 35s);
|
||||
}).Schedule(30s, [this](TaskContext context)
|
||||
{
|
||||
DoCastAOE(SPELL_HOWL_OF_AZGALOR);
|
||||
|
||||
@@ -83,6 +83,5 @@ inline AI* GetAhnKahetAI(T* obj)
|
||||
}
|
||||
|
||||
#define RegisterAhnKahetCreatureAI(ai_name) RegisterCreatureAIWithFactory(ai_name, GetAhnKahetAI)
|
||||
#define RegisterAhnKahetGameObjectAI(ai_name) RegisterGameObjectAIWithFactory(ai_name, GetAhnKahetAI)
|
||||
|
||||
#endif // DEF_AHNKAHET_H
|
||||
|
||||
@@ -331,11 +331,12 @@ class spell_ioc_repair_turret_aura : public AuraScript
|
||||
|
||||
enum blastCriteria
|
||||
{
|
||||
SPELL_SEAFORIUM_BLAST = 66676,
|
||||
SPELL_HUGE_SEAFORIUM_BLAST = 66672,
|
||||
|
||||
SPELL_BOMB_INABLE_CREDIT = 68366,
|
||||
SPELL_BOMB_INATION_CREDIT = 68367,
|
||||
SPELL_SEAFORIUM_BLAST = 66676,
|
||||
SPELL_SEAFORIUM_BLAST_H = 67814,
|
||||
SPELL_HUGE_SEAFORIUM_BLAST = 66672,
|
||||
SPELL_HUGE_SEAFORIUM_BLAST_H = 67813,
|
||||
SPELL_BOMB_INABLE_CREDIT = 68366,
|
||||
SPELL_BOMB_INATION_CREDIT = 68367
|
||||
};
|
||||
|
||||
class spell_ioc_bomb_blast_criteria : public SpellScript
|
||||
@@ -347,16 +348,20 @@ class spell_ioc_bomb_blast_criteria : public SpellScript
|
||||
return ValidateSpellInfo({ SPELL_BOMB_INABLE_CREDIT, SPELL_BOMB_INATION_CREDIT });
|
||||
}
|
||||
|
||||
void HandleGameObjectDamage(SpellEffIndex /*effIndex*/)
|
||||
void HandleGameObjectDamage(SpellEffIndex /*effIndex*/)
|
||||
{
|
||||
uint32 creditSpell = 0;
|
||||
Unit* owner = GetCaster()->GetOwner();
|
||||
if (!owner)
|
||||
return;
|
||||
|
||||
if (GetSpellInfo()->Id == SPELL_SEAFORIUM_BLAST)
|
||||
owner->CastSpell(owner, SPELL_BOMB_INABLE_CREDIT, true);
|
||||
else if (GetSpellInfo()->Id == SPELL_HUGE_SEAFORIUM_BLAST)
|
||||
owner->CastSpell(owner, SPELL_BOMB_INATION_CREDIT, true);
|
||||
uint32 spellId = GetSpellInfo()->Id;
|
||||
if (spellId == SPELL_SEAFORIUM_BLAST || spellId == SPELL_SEAFORIUM_BLAST_H)
|
||||
creditSpell = SPELL_BOMB_INABLE_CREDIT;
|
||||
else if (spellId == SPELL_HUGE_SEAFORIUM_BLAST || spellId == SPELL_HUGE_SEAFORIUM_BLAST_H)
|
||||
creditSpell = SPELL_BOMB_INATION_CREDIT;
|
||||
|
||||
owner->CastSpell(owner, creditSpell, true);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
|
||||
@@ -115,7 +115,8 @@ enum MiscIds
|
||||
SPELL_SHADOW_INFERNO_DAMAGE = 39646,
|
||||
SPELL_CHAOTIC_CHARGE = 41033,
|
||||
SPELL_DEMENTIA1 = 41406,
|
||||
SPELL_DEMENTIA2 = 41409
|
||||
SPELL_DEMENTIA2 = 41409,
|
||||
SPELL_SUMMON_SHADOWFIENDS = 41159
|
||||
};
|
||||
|
||||
template <class AI, class T>
|
||||
|
||||
@@ -458,6 +458,32 @@ class spell_black_temple_dementia_aura : public AuraScript
|
||||
}
|
||||
};
|
||||
|
||||
// 39649 - Summon Shadowfiends
|
||||
class spell_black_temple_summon_shadowfiends : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_black_temple_summon_shadowfiends);
|
||||
|
||||
bool Validate(SpellInfo const* /*spellInfo*/) override
|
||||
{
|
||||
return ValidateSpellInfo({ SPELL_SUMMON_SHADOWFIENDS });
|
||||
}
|
||||
|
||||
void HandleScriptEffect(SpellEffIndex /*effIndex*/)
|
||||
{
|
||||
Unit* caster = GetCaster();
|
||||
if (!caster)
|
||||
return;
|
||||
|
||||
for (uint8 i = 0; i < 11; i++)
|
||||
caster->CastSpell(caster, SPELL_SUMMON_SHADOWFIENDS, true);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectHitTarget += SpellEffectFn(spell_black_temple_summon_shadowfiends::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_instance_black_temple()
|
||||
{
|
||||
new instance_black_temple();
|
||||
@@ -473,5 +499,6 @@ void AddSC_instance_black_temple()
|
||||
RegisterSpellScript(spell_black_temple_consuming_strikes_aura);
|
||||
RegisterSpellScript(spell_black_temple_curse_of_vitality_aura);
|
||||
RegisterSpellScript(spell_black_temple_dementia_aura);
|
||||
RegisterSpellScript(spell_black_temple_summon_shadowfiends);
|
||||
}
|
||||
|
||||
|
||||
@@ -1140,7 +1140,14 @@ class spell_kaelthas_mind_control : public SpellScript
|
||||
{
|
||||
targets.remove_if(Acore::ObjectGUIDCheck(victim->GetGUID(), true));
|
||||
}
|
||||
targets.remove_if(Acore::ObjectTypeIdCheck(TYPEID_PLAYER, false));
|
||||
|
||||
targets.remove_if([&](WorldObject const* target) -> bool
|
||||
{
|
||||
if (!target->ToPlayer())
|
||||
return true;
|
||||
|
||||
return (!GetCaster()->IsWithinLOSInMap(target));
|
||||
});
|
||||
}
|
||||
|
||||
void HandleEffect(SpellEffIndex /*effIndex*/)
|
||||
|
||||
@@ -79,37 +79,8 @@ struct boss_zereketh_the_unbound : public BossAI
|
||||
}
|
||||
};
|
||||
|
||||
// 36123, 39367 -- Seed of Corruption
|
||||
class spell_zereketh_seed_of_corruption: public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_zereketh_seed_of_corruption);
|
||||
|
||||
bool Validate(SpellInfo const* /*spellInfo*/) override
|
||||
{
|
||||
return ValidateSpellInfo({ SPELL_CORRUPTION_PROC });
|
||||
}
|
||||
|
||||
void HandleProc(AuraEffect const* /*aurEff*/, ProcEventInfo& /*eventInfo*/)
|
||||
{
|
||||
PreventDefaultAction();
|
||||
uint32 val = GetSpellInfo()->GetEffect(EFFECT_1).BasePoints;
|
||||
GetTarget()->RemoveAurasDueToSpell(GetSpellInfo()->Id);
|
||||
|
||||
if (GetCaster())
|
||||
{
|
||||
GetCaster()->CastCustomSpell(SPELL_CORRUPTION_PROC, SPELLVALUE_BASE_POINT0, val, GetTarget(), true);
|
||||
}
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectProc += AuraEffectProcFn(spell_zereketh_seed_of_corruption::HandleProc, EFFECT_1, SPELL_AURA_DUMMY);
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_zereketh_the_unbound()
|
||||
{
|
||||
RegisterArcatrazCreatureAI(boss_zereketh_the_unbound);
|
||||
RegisterSpellScript(spell_zereketh_seed_of_corruption);
|
||||
}
|
||||
|
||||
|
||||
@@ -580,137 +580,6 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
/*######
|
||||
## npc_phase_hunter
|
||||
######*/
|
||||
|
||||
enum PhaseHunterData
|
||||
{
|
||||
QUEST_RECHARGING_THE_BATTERIES = 10190,
|
||||
|
||||
NPC_PHASE_HUNTER_ENTRY = 18879,
|
||||
NPC_DRAINED_PHASE_HUNTER_ENTRY = 19595,
|
||||
|
||||
EMOTE_WEAK = 0,
|
||||
|
||||
// Spells
|
||||
SPELL_RECHARGING_BATTERY = 34219,
|
||||
SPELL_PHASE_SLIP = 36574,
|
||||
SPELL_MANA_BURN = 13321,
|
||||
SPELL_MATERIALIZE = 34804,
|
||||
SPELL_DE_MATERIALIZE = 34814,
|
||||
};
|
||||
|
||||
class npc_phase_hunter : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_phase_hunter() : CreatureScript("npc_phase_hunter") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return new npc_phase_hunterAI(creature);
|
||||
}
|
||||
|
||||
struct npc_phase_hunterAI : public ScriptedAI
|
||||
{
|
||||
npc_phase_hunterAI(Creature* creature) : ScriptedAI(creature) { }
|
||||
|
||||
bool Weak;
|
||||
bool Materialize;
|
||||
bool Drained;
|
||||
uint8 WeakPercent;
|
||||
|
||||
ObjectGuid PlayerGUID;
|
||||
|
||||
uint32 ManaBurnTimer;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
Weak = false;
|
||||
Materialize = false;
|
||||
Drained = false;
|
||||
WeakPercent = 25 + (rand() % 16); // 25-40
|
||||
|
||||
PlayerGUID.Clear();
|
||||
|
||||
ManaBurnTimer = 5000 + (rand() % 3 * 1000); // 5-8 sec cd
|
||||
|
||||
if (me->GetEntry() == NPC_DRAINED_PHASE_HUNTER_ENTRY)
|
||||
me->UpdateEntry(NPC_PHASE_HUNTER_ENTRY);
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit* who) override
|
||||
{
|
||||
if (who->GetTypeId() == TYPEID_PLAYER)
|
||||
PlayerGUID = who->GetGUID();
|
||||
}
|
||||
|
||||
//void SpellHit(Unit* /*caster*/, SpellInfo const* /*spell*/)
|
||||
//{
|
||||
// DoCast(me, SPELL_DE_MATERIALIZE);
|
||||
//}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!Materialize)
|
||||
{
|
||||
DoCast(me, SPELL_MATERIALIZE);
|
||||
Materialize = true;
|
||||
}
|
||||
|
||||
if (me->HasAuraType(SPELL_AURA_MOD_DECREASE_SPEED) || me->HasUnitState(UNIT_STATE_ROOT)) // if the mob is rooted/slowed by spells eg.: Entangling Roots, Frost Nova, Hamstring, Crippling Poison, etc. => remove it
|
||||
DoCast(me, SPELL_PHASE_SLIP);
|
||||
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
// some code to cast spell Mana Burn on random target which has mana
|
||||
if (ManaBurnTimer <= diff)
|
||||
{
|
||||
std::list<HostileReference*> AggroList = me->GetThreatMgr().GetThreatList();
|
||||
std::list<Unit*> UnitsWithMana;
|
||||
|
||||
for (std::list<HostileReference*>::const_iterator itr = AggroList.begin(); itr != AggroList.end(); ++itr)
|
||||
{
|
||||
if (Unit* unit = ObjectAccessor::GetUnit(*me, (*itr)->getUnitGuid()))
|
||||
{
|
||||
if (unit->GetCreateMana() > 0)
|
||||
UnitsWithMana.push_back(unit);
|
||||
}
|
||||
}
|
||||
if (!UnitsWithMana.empty())
|
||||
{
|
||||
DoCast(Acore::Containers::SelectRandomContainerElement(UnitsWithMana), SPELL_MANA_BURN);
|
||||
ManaBurnTimer = 8000 + (rand() % 10 * 1000); // 8-18 sec cd
|
||||
}
|
||||
else
|
||||
ManaBurnTimer = 3500;
|
||||
}
|
||||
else ManaBurnTimer -= diff;
|
||||
|
||||
if (Player* player = ObjectAccessor::GetPlayer(*me, PlayerGUID)) // start: support for quest 10190
|
||||
{
|
||||
if (!Weak && HealthBelowPct(WeakPercent)
|
||||
&& player->GetQuestStatus(QUEST_RECHARGING_THE_BATTERIES) == QUEST_STATUS_INCOMPLETE)
|
||||
{
|
||||
Talk(EMOTE_WEAK);
|
||||
Weak = true;
|
||||
}
|
||||
if (Weak && !Drained && me->HasAura(SPELL_RECHARGING_BATTERY))
|
||||
{
|
||||
Drained = true;
|
||||
int32 uHpPct = int32(me->GetHealthPct());
|
||||
me->SetHealth(me->CountPctFromMaxHealth(uHpPct));
|
||||
me->LowerPlayerDamageReq(me->GetMaxHealth() - me->GetHealth());
|
||||
me->SetInCombatWith(player);
|
||||
}
|
||||
} // end: support for quest 10190
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
/*######
|
||||
## npc_bessy
|
||||
######*/
|
||||
@@ -911,6 +780,12 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
enum PhaseHunterData
|
||||
{
|
||||
NPC_PHASE_HUNTER_ENTRY = 18879,
|
||||
NPC_DRAINED_PHASE_HUNTER_ENTRY = 19595
|
||||
};
|
||||
|
||||
class spell_q10190_battery_recharging_blaster : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_q10190_battery_recharging_blaster);
|
||||
@@ -918,7 +793,7 @@ class spell_q10190_battery_recharging_blaster : public SpellScript
|
||||
SpellCastResult CheckCast()
|
||||
{
|
||||
if (Unit* target = GetExplTargetUnit())
|
||||
if (target->GetHealthPct() <= 25.0f)
|
||||
if (target->GetHealthPct() <= 35.0f)
|
||||
return SPELL_CAST_OK;
|
||||
|
||||
return SPELL_FAILED_BAD_TARGETS;
|
||||
@@ -941,7 +816,7 @@ class spell_q10190_battery_recharging_blaster_aura : public AuraScript
|
||||
|
||||
if (Creature* phasehunter = GetTarget()->ToCreature())
|
||||
if (phasehunter->GetEntry() == NPC_PHASE_HUNTER_ENTRY)
|
||||
phasehunter->UpdateEntry(NPC_DRAINED_PHASE_HUNTER_ENTRY);
|
||||
phasehunter->UpdateEntry(NPC_DRAINED_PHASE_HUNTER_ENTRY, nullptr, false);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
@@ -989,7 +864,6 @@ void AddSC_netherstorm()
|
||||
// Theirs
|
||||
new npc_commander_dawnforge();
|
||||
new at_commander_dawnforge();
|
||||
new npc_phase_hunter();
|
||||
new npc_bessy();
|
||||
new npc_maxx_a_million_escort();
|
||||
RegisterSpellAndAuraScriptPair(spell_q10190_battery_recharging_blaster, spell_q10190_battery_recharging_blaster_aura);
|
||||
|
||||
@@ -1702,10 +1702,8 @@ class spell_gen_pet_summoned : public SpellScript
|
||||
{
|
||||
PetType newPetType = (player->IsClass(CLASS_HUNTER, CLASS_CONTEXT_PET)) ? HUNTER_PET : SUMMON_PET;
|
||||
Pet* newPet = new Pet(player, newPetType);
|
||||
if (newPet->LoadPetFromDB(player, 0, player->GetLastPetNumber(), true, 100))
|
||||
if (newPet->LoadPetFromDB(player, 0, player->GetLastPetNumber(), true, 100, true))
|
||||
{
|
||||
newPet->SetPower(newPet->getPowerType(), newPet->GetMaxPower(newPet->getPowerType()));
|
||||
|
||||
switch (newPet->GetEntry())
|
||||
{
|
||||
case NPC_DOOMGUARD:
|
||||
@@ -5252,6 +5250,77 @@ class spell_gen_sober_up : public AuraScript
|
||||
}
|
||||
};
|
||||
|
||||
enum StealWeapon
|
||||
{
|
||||
SPELL_STEAL_WEAPON = 36207, // in 36208 as script_effect
|
||||
NPC_GLUMDOR = 20730,
|
||||
SAY_GLUMDOR_STEAL = 0 // Stupid, squishy $r. That weapon mine now! Give!
|
||||
};
|
||||
|
||||
// 36208 - Steal Weapon
|
||||
class spell_gen_steal_weapon : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_gen_steal_weapon);
|
||||
|
||||
bool Validate(SpellInfo const* /*spellInfo*/) override
|
||||
{
|
||||
return ValidateSpellInfo({ SPELL_STEAL_WEAPON });
|
||||
}
|
||||
|
||||
void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
|
||||
{
|
||||
Unit* caster = GetCaster();
|
||||
Unit* target = GetTarget();
|
||||
if (!caster || !target)
|
||||
return;
|
||||
|
||||
if (Creature* stealer = caster->ToCreature())
|
||||
{
|
||||
if (Player* player = target->ToPlayer())
|
||||
{
|
||||
if (Item* mainItem = player->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND))
|
||||
{
|
||||
stealer->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, mainItem->GetEntry());
|
||||
stealer->CastSpell(stealer, SPELL_STEAL_WEAPON, true);
|
||||
|
||||
if (stealer->GetEntry() == NPC_GLUMDOR)
|
||||
{
|
||||
stealer->AI()->Talk(SAY_GLUMDOR_STEAL, player);
|
||||
}
|
||||
}
|
||||
}
|
||||
// He can steal creature weapons too
|
||||
if (Creature* creature = target->ToCreature())
|
||||
{
|
||||
int8 mainhand = 1;
|
||||
if (EquipmentInfo const* eInfo = sObjectMgr->GetEquipmentInfo(creature->GetEntry(), mainhand))
|
||||
{
|
||||
stealer->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, eInfo->ItemEntry[0]);
|
||||
stealer->CastSpell(stealer, SPELL_STEAL_WEAPON, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
|
||||
{
|
||||
Unit* caster = GetCaster();
|
||||
if (!caster)
|
||||
return;
|
||||
|
||||
if (Creature* stealer = caster->ToCreature())
|
||||
{
|
||||
stealer->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
AfterEffectApply += AuraEffectApplyFn(spell_gen_steal_weapon::OnApply, EFFECT_1, SPELL_AURA_MOD_DISARM, AURA_EFFECT_HANDLE_REAL);
|
||||
AfterEffectRemove += AuraEffectRemoveFn(spell_gen_steal_weapon::OnRemove, EFFECT_1, SPELL_AURA_MOD_DISARM, AURA_EFFECT_HANDLE_REAL);
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_generic_spell_scripts()
|
||||
{
|
||||
RegisterSpellScript(spell_silithyst);
|
||||
@@ -5408,5 +5477,6 @@ void AddSC_generic_spell_scripts()
|
||||
RegisterSpellScript(spell_gen_choking_vines);
|
||||
RegisterSpellScript(spell_gen_consumption);
|
||||
RegisterSpellScript(spell_gen_sober_up);
|
||||
RegisterSpellScript(spell_gen_steal_weapon);
|
||||
}
|
||||
|
||||
|
||||
@@ -4021,6 +4021,36 @@ class spell_item_fel_mana_potion : public AuraScript
|
||||
}
|
||||
};
|
||||
|
||||
// 32578 - Gor'drek's Ointment
|
||||
enum DreksOintment
|
||||
{
|
||||
NPC_THUNDERLORD_DIRE_WOLF = 20748,
|
||||
SPELL_GOR_DREKS_OINTMENT = 32578
|
||||
};
|
||||
|
||||
class spell_item_gor_dreks_ointment : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_item_gor_dreks_ointment)
|
||||
|
||||
SpellCastResult CheckCast()
|
||||
{
|
||||
if (Unit* target = GetExplTargetUnit())
|
||||
{
|
||||
if (target->GetEntry() == NPC_THUNDERLORD_DIRE_WOLF && !target->HasAura(SPELL_GOR_DREKS_OINTMENT))
|
||||
return SPELL_CAST_OK;
|
||||
if (target->GetEntry() != NPC_THUNDERLORD_DIRE_WOLF)
|
||||
return SPELL_FAILED_BAD_TARGETS;
|
||||
}
|
||||
|
||||
return SPELL_FAILED_CANT_DO_THAT_RIGHT_NOW;
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnCheckCast += SpellCheckCastFn(spell_item_gor_dreks_ointment::CheckCast);
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_item_spell_scripts()
|
||||
{
|
||||
RegisterSpellScript(spell_item_massive_seaforium_charge);
|
||||
@@ -4144,5 +4174,6 @@ void AddSC_item_spell_scripts()
|
||||
RegisterSpellScript(spell_item_scroll_of_retribution);
|
||||
RegisterSpellAndAuraScriptPair(spell_item_eye_of_grillok, spell_item_eye_of_grillok_aura);
|
||||
RegisterSpellScript(spell_item_fel_mana_potion);
|
||||
RegisterSpellScript(spell_item_gor_dreks_ointment);
|
||||
}
|
||||
|
||||
|
||||
@@ -58,6 +58,12 @@ enum WarlockSpells
|
||||
SPELL_WARLOCK_IMPROVED_HEALTH_FUNNEL_BUFF_R2 = 60956,
|
||||
SPELL_WARLOCK_LIFE_TAP_ENERGIZE = 31818,
|
||||
SPELL_WARLOCK_LIFE_TAP_ENERGIZE_2 = 32553,
|
||||
SPELL_WARLOCK_SEED_OF_CORRUPTION_R1 = 27243,
|
||||
SPELL_WARLOCK_SEED_OF_CORRUPTION_DAMAGE_R1 = 27285,
|
||||
SPELL_WARLOCK_SEED_OF_CORRUPTION_DAMAGE_R2 = 47833,
|
||||
SPELL_WARLOCK_SEED_OF_CORRUPTION_DAMAGE_R3 = 47834,
|
||||
SPELL_WARLOCK_SEED_OF_CORRUPTION_DAMAGE_GENERIC = 32865,
|
||||
SPELL_WARLOCK_SEED_OF_CORRUPTION_VISUAL = 37826,
|
||||
SPELL_WARLOCK_SOULSHATTER = 32835,
|
||||
SPELL_WARLOCK_SIPHON_LIFE_HEAL = 63106,
|
||||
SPELL_WARLOCK_UNSTABLE_AFFLICTION_DISPEL = 31117,
|
||||
@@ -65,12 +71,14 @@ enum WarlockSpells
|
||||
SPELL_WARLOCK_IMPROVED_DRAIN_SOUL_PROC = 18371,
|
||||
SPELL_WARLOCK_EYE_OF_KILROGG_FLY = 58083,
|
||||
SPELL_WARLOCK_PET_VOID_STAR_TALISMAN = 37386, // Void Star Talisman
|
||||
SPELL_WARLOCK_DEMONIC_PACT_PROC = 48090,
|
||||
};
|
||||
|
||||
enum WarlockSpellIcons
|
||||
{
|
||||
WARLOCK_ICON_ID_IMPROVED_LIFE_TAP = 208,
|
||||
WARLOCK_ICON_ID_MANA_FEED = 1982
|
||||
WARLOCK_ICON_ID_MANA_FEED = 1982,
|
||||
WARLOCK_ICON_ID_DEMONIC_PACT = 3220
|
||||
};
|
||||
|
||||
class spell_warl_eye_of_kilrogg : public AuraScript
|
||||
@@ -670,9 +678,10 @@ class spell_warl_ritual_of_doom_effect : public SpellScript
|
||||
};
|
||||
|
||||
// -27285 - Seed of Corruption
|
||||
class spell_warl_seed_of_corruption : public SpellScript
|
||||
// 32865 - Seed of Corruption
|
||||
class spell_warl_seed_of_corruption_damage : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_warl_seed_of_corruption);
|
||||
PrepareSpellScript(spell_warl_seed_of_corruption_damage);
|
||||
|
||||
void FilterTargets(std::list<WorldObject*>& targets)
|
||||
{
|
||||
@@ -695,7 +704,124 @@ class spell_warl_seed_of_corruption : public SpellScript
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_warl_seed_of_corruption::FilterTargets, EFFECT_0, TARGET_UNIT_DEST_AREA_ENEMY);
|
||||
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_warl_seed_of_corruption_damage::FilterTargets, EFFECT_0, TARGET_UNIT_DEST_AREA_ENEMY);
|
||||
}
|
||||
};
|
||||
|
||||
// -27243 - Seed of Corruption
|
||||
class spell_warl_seed_of_corruption_aura: public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_warl_seed_of_corruption_aura);
|
||||
|
||||
bool Validate(SpellInfo const* /*spellInfo*/) override
|
||||
{
|
||||
return ValidateSpellInfo({
|
||||
SPELL_WARLOCK_SEED_OF_CORRUPTION_DAMAGE_R1,
|
||||
SPELL_WARLOCK_SEED_OF_CORRUPTION_DAMAGE_R2,
|
||||
SPELL_WARLOCK_SEED_OF_CORRUPTION_DAMAGE_R3,
|
||||
SPELL_WARLOCK_SEED_OF_CORRUPTION_VISUAL
|
||||
});
|
||||
}
|
||||
|
||||
void CalculateAmount(AuraEffect const* aurEff, int32& amount, bool& /*canBeRecalculated*/)
|
||||
{
|
||||
if (!GetCaster())
|
||||
return;
|
||||
|
||||
// effect 1 scales with 14% of caster's SP (DBC data)
|
||||
amount = GetCaster()->SpellDamageBonusDone(GetUnitOwner(), GetSpellInfo(), amount, DOT, aurEff->GetEffIndex(), aurEff->GetPctMods());
|
||||
}
|
||||
|
||||
void Detonate(AuraEffect const* aurEff)
|
||||
{
|
||||
if (!GetCaster() || !GetTarget())
|
||||
return;
|
||||
|
||||
GetTarget()->CastSpell(GetTarget(), SPELL_WARLOCK_SEED_OF_CORRUPTION_VISUAL, true, nullptr, aurEff);
|
||||
GetCaster()->CastSpell(GetTarget(), sSpellMgr->GetSpellWithRank(SPELL_WARLOCK_SEED_OF_CORRUPTION_DAMAGE_R1, GetSpellInfo()->GetRank()), true, nullptr, aurEff);
|
||||
}
|
||||
|
||||
void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo)
|
||||
{
|
||||
PreventDefaultAction();
|
||||
DamageInfo* damageInfo = eventInfo.GetDamageInfo();
|
||||
if (!damageInfo || !damageInfo->GetDamage())
|
||||
return;
|
||||
|
||||
int32 remainingDamage = aurEff->GetAmount() - damageInfo->GetDamage();
|
||||
if (remainingDamage > 0)
|
||||
{
|
||||
GetAura()->GetEffect(EFFECT_1)->SetAmount(remainingDamage);
|
||||
}
|
||||
else // damage threshold has been reached
|
||||
{
|
||||
Remove(AURA_REMOVE_BY_DEFAULT);
|
||||
Detonate(aurEff);
|
||||
}
|
||||
}
|
||||
|
||||
void OnRemove(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
|
||||
{
|
||||
AuraRemoveMode removeMode = GetTargetApplication()->GetRemoveMode();
|
||||
if (removeMode == AURA_REMOVE_BY_DEATH)
|
||||
Detonate(aurEff);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_warl_seed_of_corruption_aura::CalculateAmount, EFFECT_1, SPELL_AURA_DUMMY);
|
||||
AfterEffectRemove += AuraEffectRemoveFn(spell_warl_seed_of_corruption_aura::OnRemove, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE, AURA_EFFECT_HANDLE_REAL);
|
||||
OnEffectProc += AuraEffectProcFn(spell_warl_seed_of_corruption_aura::HandleProc, EFFECT_1, SPELL_AURA_DUMMY);
|
||||
}
|
||||
};
|
||||
|
||||
// Monster spells, triggered only on detonation threshold reached (not on death)
|
||||
// 32863 - Seed of Corruption
|
||||
// 36123 - Seed of Corruption
|
||||
// 38252 - Seed of Corruption
|
||||
// 39367 - Seed of Corruption
|
||||
// 44141 - Seed of Corruption
|
||||
// 70388 - Seed of Corruption
|
||||
class spell_warl_seed_of_corruption_generic_aura: public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_warl_seed_of_corruption_generic_aura);
|
||||
|
||||
bool Validate(SpellInfo const* /*spellInfo*/) override
|
||||
{
|
||||
return ValidateSpellInfo({ SPELL_WARLOCK_SEED_OF_CORRUPTION_DAMAGE_GENERIC, SPELL_WARLOCK_SEED_OF_CORRUPTION_VISUAL });
|
||||
}
|
||||
|
||||
void Detonate(AuraEffect const* aurEff)
|
||||
{
|
||||
if (!GetCaster() || !GetTarget())
|
||||
return;
|
||||
|
||||
GetTarget()->CastSpell(GetTarget(), SPELL_WARLOCK_SEED_OF_CORRUPTION_VISUAL, true, nullptr, aurEff);
|
||||
GetCaster()->CastCustomSpell(SPELL_WARLOCK_SEED_OF_CORRUPTION_DAMAGE_GENERIC, SPELLVALUE_BASE_POINT0, GetSpellInfo()->GetEffect(EFFECT_1).CalcValue(), GetTarget(), true, nullptr, aurEff);
|
||||
}
|
||||
|
||||
void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo)
|
||||
{
|
||||
PreventDefaultAction();
|
||||
DamageInfo* damageInfo = eventInfo.GetDamageInfo();
|
||||
if (!damageInfo || !damageInfo->GetDamage())
|
||||
return;
|
||||
|
||||
int32 remainingDamage = aurEff->GetAmount() - damageInfo->GetDamage();
|
||||
if (remainingDamage > 0)
|
||||
{
|
||||
GetAura()->GetEffect(EFFECT_1)->SetAmount(remainingDamage);
|
||||
}
|
||||
else // damage threshold has been reached
|
||||
{
|
||||
Remove(AURA_REMOVE_BY_DEFAULT);
|
||||
Detonate(aurEff);
|
||||
}
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectProc += AuraEffectProcFn(spell_warl_seed_of_corruption_generic_aura::HandleProc, EFFECT_1, SPELL_AURA_DUMMY);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1321,6 +1447,54 @@ class spell_warl_glyph_of_voidwalker : public AuraScript
|
||||
}
|
||||
};
|
||||
|
||||
// 54909, 53646 - Demonic Pact
|
||||
class spell_warl_demonic_pact_aura : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_warl_demonic_pact_aura);
|
||||
|
||||
bool Validate(SpellInfo const* /*spellInfo*/) override
|
||||
{
|
||||
return ValidateSpellInfo({ SPELL_WARLOCK_DEMONIC_PACT_PROC });
|
||||
}
|
||||
|
||||
bool AfterCheckProc(ProcEventInfo& eventInfo, bool isTriggeredAtSpellProcEvent)
|
||||
{
|
||||
return isTriggeredAtSpellProcEvent && eventInfo.GetActor() && eventInfo.GetActor()->IsPet();
|
||||
}
|
||||
|
||||
void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo)
|
||||
{
|
||||
PreventDefaultAction();
|
||||
|
||||
if (eventInfo.GetActor()->HasSpellCooldown(aurEff->GetId()))
|
||||
return;
|
||||
|
||||
if (Unit* owner = eventInfo.GetActor()->GetOwner())
|
||||
{
|
||||
int32 currentBonus = 0;
|
||||
if (AuraEffect* demonicAurEff = owner->GetAuraEffect(SPELL_WARLOCK_DEMONIC_PACT_PROC, EFFECT_0))
|
||||
{
|
||||
currentBonus = demonicAurEff->GetAmount();
|
||||
}
|
||||
|
||||
if (AuraEffect* talentAurEff = owner->GetDummyAuraEffect(SPELLFAMILY_WARLOCK, WARLOCK_ICON_ID_DEMONIC_PACT, EFFECT_0))
|
||||
{
|
||||
int32 spellDamageMinusBonus = owner->SpellBaseDamageBonusDone(SPELL_SCHOOL_MASK_MAGIC) - currentBonus;
|
||||
if (spellDamageMinusBonus < 0)
|
||||
return;
|
||||
int32 bp = int32((talentAurEff->GetAmount() / 100.0f) * spellDamageMinusBonus);
|
||||
owner->CastCustomSpell((Unit*)nullptr, SPELL_WARLOCK_DEMONIC_PACT_PROC, &bp, &bp, 0, true, nullptr, talentAurEff);
|
||||
eventInfo.GetActor()->AddSpellCooldown(aurEff->GetId(), 0, eventInfo.GetProcCooldown());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectProc += AuraEffectProcFn(spell_warl_demonic_pact_aura::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL);
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_warlock_spell_scripts()
|
||||
{
|
||||
RegisterSpellScript(spell_warl_eye_of_kilrogg);
|
||||
@@ -1345,7 +1519,9 @@ void AddSC_warlock_spell_scripts()
|
||||
RegisterSpellScript(spell_warl_health_funnel);
|
||||
RegisterSpellScript(spell_warl_life_tap);
|
||||
RegisterSpellScript(spell_warl_ritual_of_doom_effect);
|
||||
RegisterSpellScript(spell_warl_seed_of_corruption);
|
||||
RegisterSpellScript(spell_warl_seed_of_corruption_damage);
|
||||
RegisterSpellScript(spell_warl_seed_of_corruption_aura);
|
||||
RegisterSpellScript(spell_warl_seed_of_corruption_generic_aura);
|
||||
RegisterSpellScript(spell_warl_shadow_ward);
|
||||
RegisterSpellScript(spell_warl_siphon_life);
|
||||
RegisterSpellScript(spell_warl_soulshatter);
|
||||
@@ -1354,5 +1530,6 @@ void AddSC_warlock_spell_scripts()
|
||||
RegisterSpellScript(spell_warl_shadowburn);
|
||||
RegisterSpellScript(spell_warl_glyph_of_felguard);
|
||||
RegisterSpellScript(spell_warl_glyph_of_voidwalker);
|
||||
RegisterSpellScript(spell_warl_demonic_pact_aura);
|
||||
}
|
||||
|
||||
|
||||
@@ -39,23 +39,29 @@ public:
|
||||
|
||||
void OnChat(Player* player, uint32 type, uint32 lang, std::string& msg) override
|
||||
{
|
||||
std::string logType = "";
|
||||
std::string chatType = "";
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case CHAT_MSG_SAY:
|
||||
LOG_INFO("chat.say", "Player {} says (language {}): {}",
|
||||
player->GetName(), lang, msg);
|
||||
logType = "chat.say";
|
||||
chatType = "says";
|
||||
break;
|
||||
|
||||
case CHAT_MSG_EMOTE:
|
||||
LOG_INFO("chat.emote", "Player {} emotes: {}",
|
||||
player->GetName(), msg);
|
||||
logType = "chat.emote";
|
||||
chatType = "emotes";
|
||||
break;
|
||||
|
||||
case CHAT_MSG_YELL:
|
||||
LOG_INFO("chat.yell", "Player {} yells (language {}): {}",
|
||||
player->GetName(), lang, msg);
|
||||
logType = "chat.yell";
|
||||
chatType = "yells";
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
LOG_INFO(logType, "Player {} {} (language {}): {}",
|
||||
player->GetName(), chatType, lang, msg);
|
||||
}
|
||||
|
||||
void OnChat(Player* player, uint32 /*type*/, uint32 /*lang*/, std::string& msg, Player* receiver) override
|
||||
@@ -66,63 +72,59 @@ public:
|
||||
|
||||
void OnChat(Player* player, uint32 type, uint32 lang, std::string& msg, Group* group) override
|
||||
{
|
||||
std::string str = lang != LANG_ADDON ? "chat." : "chat.addon.";
|
||||
//! NOTE:
|
||||
//! LANG_ADDON can only be sent by client in "PARTY", "RAID", "GUILD", "BATTLEGROUND", "WHISPER"
|
||||
std::string logType = (lang != LANG_ADDON) ? "chat." : "chat.addon.";
|
||||
std::string msgType = "";
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case CHAT_MSG_PARTY:
|
||||
LOG_INFO(str + "party", "Player {} tells group with leader {}: {}",
|
||||
player->GetName(), group ? group->GetLeaderName() : "<unknown>", msg);
|
||||
break;
|
||||
|
||||
case CHAT_MSG_PARTY_LEADER:
|
||||
LOG_INFO(str + "party", "Leader {} tells group: {}",
|
||||
player->GetName(), msg);
|
||||
msgType = "party";
|
||||
break;
|
||||
|
||||
case CHAT_MSG_RAID:
|
||||
LOG_INFO(str + "raid", "Player {} tells raid with leader {}: {}",
|
||||
player->GetName(), group ? group->GetLeaderName() : "<unknown>", msg);
|
||||
break;
|
||||
|
||||
case CHAT_MSG_RAID_LEADER:
|
||||
LOG_INFO(str + "raid", "Leader player {} tells raid: {}",
|
||||
player->GetName(), msg);
|
||||
break;
|
||||
|
||||
case CHAT_MSG_RAID_WARNING:
|
||||
LOG_INFO(str + "raid", "Leader player {} sends raid warning: {}",
|
||||
player->GetName(), msg);
|
||||
msgType = "raid";
|
||||
break;
|
||||
|
||||
case CHAT_MSG_BATTLEGROUND:
|
||||
LOG_INFO(str + "bg", "Player {} tells battleground with leader {}: {}",
|
||||
player->GetName(), group ? group->GetLeaderName() : "<unknown>", msg);
|
||||
break;
|
||||
|
||||
case CHAT_MSG_BATTLEGROUND_LEADER:
|
||||
LOG_INFO(str + "bg", "Leader player {} tells battleground: {}",
|
||||
player->GetName(), msg);
|
||||
msgType = "bg";
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
std::string role = (type == CHAT_MSG_PARTY_LEADER || type == CHAT_MSG_RAID_LEADER || type == CHAT_MSG_BATTLEGROUND_LEADER) ? "Leader player" : "Player";
|
||||
std::string action = (type == CHAT_MSG_RAID_WARNING) ? "sends raid warning" : "tells";
|
||||
std::string targetGroup = group ? group->GetLeaderName() : "<unknown>";
|
||||
|
||||
LOG_INFO(logType + msgType, "{} {} {} {} with leader {}: {}",
|
||||
role, player->GetName(), action, msgType, targetGroup, msg);
|
||||
}
|
||||
|
||||
void OnChat(Player* player, uint32 type, uint32 lang, std::string& msg, Guild* guild) override
|
||||
{
|
||||
std::string str = lang != LANG_ADDON ? "chat." : "chat.addon.";
|
||||
//! NOTE:
|
||||
//! LANG_ADDON can only be sent by client in "PARTY", "RAID", "GUILD", "BATTLEGROUND", "WHISPER"
|
||||
std::string logType = (lang != LANG_ADDON) ? "chat." : "chat.addon.";
|
||||
std::string msgType = "";
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case CHAT_MSG_GUILD:
|
||||
LOG_INFO(str + "guild", "Player {} tells guild {}: {}",
|
||||
player->GetName(), guild ? guild->GetName() : "<unknown>", msg);
|
||||
msgType = "guild";
|
||||
break;
|
||||
|
||||
case CHAT_MSG_OFFICER:
|
||||
LOG_INFO(str + "guild.officer", "Player {} tells guild {} officers: {}",
|
||||
player->GetName(), guild ? guild->GetName() : "<unknown>", msg);
|
||||
msgType = "guild.officer";
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
LOG_INFO(logType + msgType, "Player {} tells {} \"{}\": {}",
|
||||
player->GetName(), msgType, guild ? guild->GetName() : "<unknown>", msg);
|
||||
}
|
||||
|
||||
void OnChat(Player* player, uint32 /*type*/, uint32 /*lang*/, std::string& msg, Channel* channel) override
|
||||
|
||||
@@ -20,18 +20,6 @@
|
||||
#include "Player.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "Spell.h"
|
||||
/* ScriptData
|
||||
SDName: Item_Scripts
|
||||
SD%Complete: 100
|
||||
SDComment: Items for a range of different items. See content below (in script)
|
||||
SDCategory: Items
|
||||
EndScriptData */
|
||||
|
||||
/* ContentData
|
||||
item_flying_machine(i34060, i34061) Engineering crafted flying machines
|
||||
item_gor_dreks_ointment(i30175) Protecting Our Own(q10488)
|
||||
item_only_for_flight Items which should only useable while flying
|
||||
EndContentData */
|
||||
|
||||
/*#####
|
||||
# item_only_for_flight
|
||||
@@ -79,26 +67,6 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
/*#####
|
||||
# item_gor_dreks_ointment
|
||||
#####*/
|
||||
|
||||
class item_gor_dreks_ointment : public ItemScript
|
||||
{
|
||||
public:
|
||||
item_gor_dreks_ointment() : ItemScript("item_gor_dreks_ointment") { }
|
||||
|
||||
bool OnUse(Player* player, Item* item, SpellCastTargets const& targets) override
|
||||
{
|
||||
if (targets.GetUnitTarget() && targets.GetUnitTarget()->GetTypeId() == TYPEID_UNIT &&
|
||||
targets.GetUnitTarget()->GetEntry() == 20748 && !targets.GetUnitTarget()->HasAura(32578))
|
||||
return false;
|
||||
|
||||
player->SendEquipError(EQUIP_ERR_CANT_DO_RIGHT_NOW, item, nullptr);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
/*#####
|
||||
# item_incendiary_explosives
|
||||
#####*/
|
||||
@@ -248,7 +216,6 @@ public:
|
||||
void AddSC_item_scripts()
|
||||
{
|
||||
new item_only_for_flight();
|
||||
new item_gor_dreks_ointment();
|
||||
new item_incendiary_explosives();
|
||||
new item_mysterious_egg();
|
||||
new item_disgusting_jar();
|
||||
|
||||
@@ -29,19 +29,48 @@ public:
|
||||
// CHARACTER_LOGIN = 8
|
||||
void OnLogin(Player* player) override
|
||||
{
|
||||
for (auto const& servMail : sObjectMgr->GetAllServerMailStore())
|
||||
// Retrieve all server mail records and session only once
|
||||
auto const& serverMailStore = sObjectMgr->GetAllServerMailStore();
|
||||
WorldSession* session = player->GetSession();
|
||||
// We should always have a session, just incase
|
||||
if (!session)
|
||||
return;
|
||||
|
||||
uint32 playerGUID = player->GetGUID().GetCounter();
|
||||
|
||||
for (auto const& [mailId, servMail] : serverMailStore)
|
||||
{
|
||||
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_MAIL_SERVER_CHARACTER);
|
||||
stmt->SetData(0, player->GetGUID().GetCounter());
|
||||
stmt->SetData(1, servMail.second.id);
|
||||
stmt->SetData(0, playerGUID);
|
||||
stmt->SetData(1, mailId);
|
||||
|
||||
WorldSession* mySess = player->GetSession();
|
||||
mySess->GetQueryProcessor().AddCallback(CharacterDatabase.AsyncQuery(stmt)
|
||||
.WithPreparedCallback([mySess, servMail](PreparedQueryResult result)
|
||||
// Capture servMail by value
|
||||
auto callback = [session, servMailWrapper = std::reference_wrapper<ServerMail const>(servMail)](PreparedQueryResult result)
|
||||
{
|
||||
ServerMail const& servMail = servMailWrapper.get(); // Dereference the wrapper to get the original object
|
||||
|
||||
if (!result)
|
||||
{
|
||||
if (!result)
|
||||
sObjectMgr->SendServerMail(mySess->GetPlayer(), servMail.second.id, servMail.second.reqLevel, servMail.second.reqPlayTime, servMail.second.moneyA, servMail.second.moneyH, servMail.second.itemA, servMail.second.itemCountA, servMail.second.itemH, servMail.second.itemCountH, servMail.second.subject, servMail.second.body, servMail.second.active);
|
||||
}));
|
||||
sObjectMgr->SendServerMail(
|
||||
session->GetPlayer(),
|
||||
servMail.id,
|
||||
servMail.reqLevel,
|
||||
servMail.reqPlayTime,
|
||||
servMail.moneyA,
|
||||
servMail.moneyH,
|
||||
servMail.itemA,
|
||||
servMail.itemCountA,
|
||||
servMail.itemH,
|
||||
servMail.itemCountH,
|
||||
servMail.subject,
|
||||
servMail.body,
|
||||
servMail.active
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
// Execute the query asynchronously and add the callback
|
||||
session->GetQueryProcessor().AddCallback(CharacterDatabase.AsyncQuery(stmt).WithPreparedCallback(callback));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user