Scripts/City of Threads: Implement Orator Krix Vizk encounter (#30398)

This commit is contained in:
Aqua Deus
2025-10-03 16:02:49 +02:00
committed by GitHub
parent da03588f1c
commit 26a0befe2e
5 changed files with 763 additions and 0 deletions

View File

@@ -0,0 +1,103 @@
SET @ATSPAWNID := 266;
SET @ATPROPERTIESID := 163;
SET @ATID := 169;
SET @CGUID := 10006844;
-- Creature
UPDATE `creature_template_difficulty` SET `ContentTuningID`=2722, `VerifiedBuild`=57388 WHERE (`Entry`=216619 AND `DifficultyID`=0); -- 216619 (Orator Krix'vizk) - CanSwim
UPDATE `creature_template_addon` SET `auras`='422356' WHERE `entry`=216619;
UPDATE `creature_template` SET `ScriptName`='boss_orator_krix_vizk' WHERE `entry`=216619;
UPDATE `creature_template` SET `faction`=35, `BaseAttackTime`=2000, `unit_flags`=0x2000000, `unit_flags2`=0x800, `unit_flags3`=0x41000001 WHERE `entry`=220769; -- Orator Krix'vizk
DELETE FROM `creature` WHERE `guid` = @CGUID+0;
INSERT INTO `creature` (`guid`, `id`, `map`, `zoneId`, `areaId`, `spawnDifficulties`, `PhaseId`, `PhaseGroup`, `modelid`, `equipment_id`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecs`, `wander_distance`, `currentwaypoint`, `MovementType`, `npcflag`, `unit_flags`, `unit_flags2`, `unit_flags3`, `VerifiedBuild`) VALUES
(@CGUID+0, 220769, 2669, 14979, 15111, '1,2,23,8,205', '0', 0, 0, 0, -1857.5416259765625, -1155.314208984375, -1244.12255859375, 0.737591743469238281, 7200, 0, 0, 0, NULL, NULL, NULL, NULL, 57388); -- Orator Krix'vizk (Area: Umbral Bazaar - Difficulty: Mythic) CreateObject1
DELETE FROM `creature_template_difficulty` WHERE (`DifficultyID`=23 AND `Entry` = 220769);
INSERT INTO `creature_template_difficulty` (`Entry`, `DifficultyID`, `LevelScalingDeltaMin`, `LevelScalingDeltaMax`, `ContentTuningID`, `StaticFlags1`, `StaticFlags2`, `StaticFlags3`, `StaticFlags4`, `StaticFlags5`, `StaticFlags6`, `StaticFlags7`, `StaticFlags8`, `VerifiedBuild`) VALUES
(220769, 23, 0, 0, 1279, 0x20000100, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 57388); -- 220769 (Orator Krix'vizk) - Sessile, Floating
-- Instance
DELETE FROM `instance_template` WHERE `map`=2669;
INSERT INTO `instance_template` (`map`, `parent`, `script`) VALUES
(2669, 0, 'instance_city_of_threads');
DELETE FROM `areatrigger_template` WHERE (`IsCustom`=0 AND `Id` IN (34764, 35433, 34738));
INSERT INTO `areatrigger_template` (`Id`, `IsCustom`, `Flags`, `VerifiedBuild`) VALUES
(34764, 0, 0, 57388),
(35433, 0, 0, 58238),
(34738, 0, 0, 57292);
DELETE FROM `areatrigger_template_actions` WHERE `AreaTriggerId`=35803 AND `IsCustom`=0;
INSERT INTO `areatrigger_template_actions` (`AreaTriggerId`, `IsCustom`, `ActionType`, `ActionParam`, `TargetType`) VALUES
(35803, 0, 0, 449122, 0);
DELETE FROM `areatrigger_create_properties` WHERE (`IsCustom`=0 AND `Id` IN (31997, 32026));
INSERT INTO `areatrigger_create_properties` (`Id`, `IsCustom`, `AreaTriggerId`, `IsAreatriggerCustom`, `Flags`, `MoveCurveId`, `ScaleCurveId`, `MorphCurveId`, `FacingCurveId`, `AnimId`, `AnimKitId`, `DecalPropertiesId`, `SpellForVisuals`, `TimeToTargetScale`, `Speed`, `Shape`, `ShapeData0`, `ShapeData1`, `ShapeData2`, `ShapeData3`, `ShapeData4`, `ShapeData5`, `ShapeData6`, `ShapeData7`, `ScriptName`, `VerifiedBuild`) VALUES
(32026, 0, 34764, 0, 2, 0, 0, 0, 0, -1, 0, 82, NULL, 6000, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 'at_orator_krix_vizk_lingering_influence', 58238), -- Spell: 434923 (Lingering Influence)
(31997, 0, 34738, 0, 4, 0, 0, 0, 0, -1, 0, 0, NULL, 0, 0, 5, 10, 10, 80, 80, 30, 30, 10, 10, 'at_orator_krix_vizk_chains_of_oppression', 58238); -- Spell: 434691 (Chains of Oppression)
DELETE FROM `areatrigger_template` WHERE `Id` BETWEEN @ATID+0 AND @ATID+1;
INSERT INTO `areatrigger_template` (`Id`, `IsCustom`, `Flags`, `ActionSetId`, `ActionSetFlags`, `VerifiedBuild`) VALUES
(@ATID+0, 1, 1, 0, 0, 0),
(@ATID+1, 1, 1, 0, 0, 0);
DELETE FROM `areatrigger` WHERE `SpawnId` BETWEEN @ATSPAWNID+0 AND @ATSPAWNID+2;
INSERT INTO `areatrigger` (`SpawnId`, `AreaTriggerCreatePropertiesId`, `IsCustom`, `MapId`, `SpawnDifficulties`, `PosX`, `PosY`, `PosZ`, `Orientation`, `PhaseUseFlags`, `PhaseId`, `PhaseGroup`, `ScriptName`, `Comment`, `VerifiedBuild`) VALUES
(@ATSPAWNID+0, @ATPROPERTIESID+0, 1, 2669, '1,2,8,23', -1691.11, -903.29, -1249.49, 1.498532, 0, 0, 0, 'at_orator_conversation_intro_1', 'City of Threads - Orator Krixvizk Conversation 1', 56647),
(@ATSPAWNID+1, @ATPROPERTIESID+1, 1, 2669, '1,2,8,23', -1790.64, -1026.74, -1243.88, 1.247988, 0, 0, 0, 'at_orator_conversation_intro_2', 'City of Threads - Orator Krixvizk Conversation 2', 56647),
(@ATSPAWNID+2, @ATPROPERTIESID+0, 1, 2669, '1,2,8,23', -1826.44, -1082.34, -1244.16, 1.094052, 0, 0, 0, 'at_orator_conversation_intro_3', 'City of Threads - Orator Krixvizk Conversation 3', 56647);
DELETE FROM `areatrigger_create_properties` WHERE `Id` BETWEEN @ATPROPERTIESID+0 AND @ATPROPERTIESID+2;
INSERT INTO `areatrigger_create_properties` (`Id`, `IsCustom`, `AreaTriggerId`, `IsAreatriggerCustom`, `Flags`, `MoveCurveId`, `ScaleCurveId`, `MorphCurveId`, `FacingCurveId`, `AnimId`, `AnimKitId`, `DecalPropertiesId`, `SpellForVisuals`, `TimeToTargetScale`, `Speed`, `Shape`, `ShapeData0`, `ShapeData1`, `ShapeData2`, `ShapeData3`, `ShapeData4`, `ShapeData5`, `ShapeData6`, `ShapeData7`, `ScriptName`, `VerifiedBuild`) VALUES
(@ATPROPERTIESID+0, 1, @ATID+0, 1, 0, 0, 0, 0, 0, -1, 0, 0, NULL, 0, 0, 1, 10, 50, 5, 10, 50, 5, 0, 0, '', 0),
(@ATPROPERTIESID+1, 1, @ATID+1, 1, 0, 0, 0, 0, 0, -1, 0, 0, NULL, 0, 0, 0, 50, 50, 0, 0, 0, 0, 0, 0, '', 0),
(@ATPROPERTIESID+2, 1, 35433, 0, 16, 0, 0, 0, 0, -1, 0, 601, 443437, 30000, 12, 0, 1, 1, 0, 0, 0, 0, 0, 0, 'at_orator_krix_vizk_doubt', 58238); -- SpellForVisuals: 443437 (Shadows of Doubt)
-- Jumpcharge Parameters
DELETE FROM `jump_charge_params` WHERE `id`=959;
INSERT INTO `jump_charge_params` (`id`, `speed`, `treatSpeedAsMoveTimeSeconds`, `jumpGravity`, `spellVisualId`, `progressCurveId`, `parabolicCurveId`) VALUES
(959, 35, 0, 56.1096, NULL, NULL, NULL);
-- Conversations
DELETE FROM `conversation_actors` WHERE (`Idx`=0 AND `ConversationId` IN (24642, 24643, 24644));
INSERT INTO `conversation_actors` (`ConversationId`, `ConversationActorId`, `Idx`, `CreatureId`, `CreatureDisplayInfoId`, `NoActorObject`, `ActivePlayerObject`, `VerifiedBuild`) VALUES
(24644, 51642, 0, 216619, 116692, 0, 0, 57388),
(24642, 51642, 0, 220769, 116692, 0, 0, 57388),
(24643, 51642, 0, 216619, 116692, 0, 0, 57388);
DELETE FROM `conversation_template` WHERE `Id` IN (24642, 24643, 24644);
INSERT INTO `conversation_template` (`Id`, `FirstLineID`, `TextureKitId`, `VerifiedBuild`) VALUES
(24644, 67092, 0, 57388),
(24643, 67091, 0, 57388),
(24642, 67085, 0, 57388);
DELETE FROM `conversation_line_template` WHERE `Id` IN (67085, 67091, 67092);
INSERT INTO `conversation_line_template` (`Id`, `UiCameraID`, `ActorIdx`, `Flags`, `ChatType`, `VerifiedBuild`) VALUES
(67092, 1751, 0, 0, 0, 57388),
(67091, 1751, 0, 0, 0, 57388),
(67085, 1751, 0, 0, 0, 57388);
-- Spells
DELETE FROM `spell_script_names` WHERE `spell_id` IN (440310, 448560, 434808, 448561, 434829);
INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES
(440310, 'spell_orator_krix_vizk_chains_of_oppression_periodic'),
(448560, 'spell_orator_krix_vizk_shadows_of_doubt_selector'),
(434808, 'spell_orator_krix_vizk_terrorize_selector'),
(448561, 'spell_orator_krix_vizk_shadows_of_doubt_periodic'),
(434829, 'spell_orator_krix_vizk_vociferous_indoctrination_periodic');
-- Texts
DELETE FROM `creature_text` WHERE `CreatureID`=216619;
INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES
(216619, 0, 0, 'Come! Let us speak.', 14, 0, 100, 0, 0, 247788, 262861, 0, 'Orator Krix\'vizk'),
(216619, 1, 0, 'Bow before me!', 14, 0, 100, 0, 0, 247792, 262867, 0, 'Orator Krix\'vizk'),
(216619, 1, 1, 'Bend the knee!', 14, 0, 100, 0, 0, 247791, 262866, 0, 'Orator Krix\'vizk'),
(216619, 2, 0, 'We revel in your fear!', 14, 0, 100, 0, 0, 247794, 262869, 0, 'Orator Krix\'vizk'),
(216619, 2, 1, 'Your terror is our victory!', 14, 0, 100, 0, 0, 247793, 262868, 0, 'Orator Krix\'vizk'),
(216619, 3, 0, 'We rise through conquest!', 14, 0, 100, 0, 0, 247797, 262872, 0, 'Orator Krix\'vizk'),
(216619, 3, 1, 'Azj-Kahet will thrive!', 14, 0, 100, 0, 0, 247798, 262873, 0, 'Orator Krix\'vizk'),
(216619, 4, 0, 'Should have listened.', 14, 0, 100, 0, 0, 247789, 262862, 0, 'Orator Krix\'vizk'),
(216619, 4, 1, 'Blessed silence.', 14, 0, 100, 0, 0, 247790, 262863, 0, 'Orator Krix\'vizk'),
(216619, 4, 2, 'I shall prepare your eulogy myself.', 14, 0, 100, 0, 0, 247799, 262864, 0, 'Orator Krix\'vizk'),
(216619, 5, 0, 'My... beautiful... voice...', 14, 0, 100, 0, 0, 247800, 262865, 0, 'Orator Krix\'vizk');

View File

@@ -0,0 +1,525 @@
/*
* This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "AreaTrigger.h"
#include "AreaTriggerAI.h"
#include "CellImpl.h"
#include "Conversation.h"
#include "Creature.h"
#include "GridNotifiers.h"
#include "InstanceScript.h"
#include "MotionMaster.h"
#include "PathGenerator.h"
#include "Player.h"
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "SpellAuras.h"
#include "SpellScript.h"
#include "city_of_threads.h"
enum OratorKrixVizkSpells
{
SPELL_ORATION = 454689,
SPELL_CHAINS_OF_OPPRESSION = 434691,
SPELL_CHAINS_OF_OPPRESSION_PERIODIC = 440310,
SPELL_CHAINS_OF_OPPRESSION_CHARGE = 434712,
SPELL_CHAINS_OF_OPPRESSION_DAMAGE = 434710,
SPELL_SUBJUGATE = 434722,
SPELL_TERRORIZE_SELECTOR = 434808,
SPELL_TERRORIZE = 434779,
SPELL_SHADOWS_OF_DOUBT_SELECTOR = 448560,
SPELL_SHADOWS_OF_DOUBT = 448561,
SPELL_DOUBT = 448562,
SPELL_VOCIFEROUS_INDOCTRINATION = 434829,
SPELL_VOCIFEROUS_INDOCTRINATION_DAMAGE = 434832,
SPELL_LINGERING_INFLUENCE_AREATRIGGER = 434923,
SPELL_LINGERING_INFLUENCE_DAMAGE = 434926
};
enum OratorKrixVizkConversations
{
CONVERSATION_ORATOR_INTRO_1 = 24642,
CONVERSATION_ORATOR_INTRO_2 = 24643,
CONVERSATION_ORATOR_INTRO_3 = 24644
};
enum OratorKrixVizkTexts
{
SAY_AGGRO = 0,
SAY_SUBJUGATE = 1,
SAY_TERRORIZE = 2,
SAY_VOCIFEROUS_INDOCTRINATION = 3,
SAY_KILL = 4,
SAY_DEATH = 5
};
enum OratorKrixVizkEvents
{
EVENT_SUBJUGATE = 1,
EVENT_TERRORIZE,
EVENT_SHADOWS_OF_DOUBT,
EVENT_ENERGIZE
};
enum OratorKrixVizkMisc
{
AREATRIGGER_BARRIER = 35803,
DISPLAY_POWERID = 527
};
// 163
// 164
template<uint32 conversationEntry, uint32 data>
struct at_orator_conversation_intro : AreaTriggerAI
{
at_orator_conversation_intro(AreaTrigger* areatrigger) : AreaTriggerAI(areatrigger) { }
void OnUnitEnter(Unit* unit) override
{
InstanceScript* instance = at->GetInstanceScript();
if (!instance)
return;
Player* player = unit->ToPlayer();
if (!player || player->IsGameMaster())
return;
if (Creature* oratorKrixVizk = instance->GetCreature(data))
Conversation::CreateConversation(conversationEntry, oratorKrixVizk, player->GetPosition(), player->GetGUID());
at->Remove();
}
};
// 216619 - Orator Krix'vizk <The Fifth Strand>
struct boss_orator_krix_vizk : public BossAI
{
boss_orator_krix_vizk(Creature* creature) : BossAI(creature, DATA_ORATOR_KRIX_VIZK), _subjugateCount(1), _terrorizeCount(1), _energizeCount(0) { }
void JustAppeared() override
{
DoCastSelf(SPELL_ORATION);
me->SetPower(POWER_ENERGY, 0);
}
void JustDied(Unit* /*killer*/) override
{
_JustDied();
Talk(SAY_DEATH);
instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
WorldObject* obj = nullptr;
Trinity::ObjectEntryAndPrivateOwnerIfExistsCheck check(ObjectGuid::Empty, AREATRIGGER_BARRIER);
Trinity::WorldObjectSearcher<Trinity::ObjectEntryAndPrivateOwnerIfExistsCheck> checker(me, obj, check, GRID_MAP_TYPE_MASK_AREATRIGGER);
Cell::VisitGridObjects(me, checker, 100.0f);
if (!obj)
return;
if (AreaTrigger* at = obj->ToAreaTrigger())
at->Remove();
}
void EnterEvadeMode(EvadeReason /*why*/) override
{
instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
_EnterEvadeMode();
_DespawnAtEvade();
}
void KilledUnit(Unit* victim) override
{
if (!victim->IsPlayer())
return;
Talk(SAY_KILL);
}
void Reset() override
{
_Reset();
_subjugateCount = 1;
_terrorizeCount = 1;
_energizeCount = 0;
}
void JustEngagedWith(Unit* who) override
{
BossAI::JustEngagedWith(who);
Talk(SAY_AGGRO);
DoCastSelf(SPELL_CHAINS_OF_OPPRESSION);
instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, me, 1);
me->SetOverrideDisplayPowerId(DISPLAY_POWERID); // No aura handle
events.ScheduleEvent(EVENT_ENERGIZE, 1s);
events.ScheduleEvent(EVENT_SUBJUGATE, 4500ms);
events.ScheduleEvent(EVENT_TERRORIZE, 9400ms);
if (IsMythic() || IsMythicPlus())
events.ScheduleEvent(EVENT_SHADOWS_OF_DOUBT, 15200ms);
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
return;
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
while (uint32 eventId = events.ExecuteEvent())
{
switch (eventId)
{
case EVENT_SUBJUGATE:
{
Talk(SAY_SUBJUGATE);
DoCastVictim(SPELL_SUBJUGATE);
_subjugateCount++;
if (_subjugateCount % 2 == 0)
events.ScheduleEvent(EVENT_SUBJUGATE, 17100ms);
else
events.ScheduleEvent(EVENT_SUBJUGATE, 12s);
break;
}
case EVENT_TERRORIZE:
{
Talk(SAY_TERRORIZE);
DoCast(SPELL_TERRORIZE_SELECTOR);
_terrorizeCount++;
if (_terrorizeCount % 2 == 0)
events.ScheduleEvent(EVENT_TERRORIZE, 8100ms);
else
events.ScheduleEvent(EVENT_TERRORIZE, 21100ms);
break;
}
case EVENT_SHADOWS_OF_DOUBT:
{
DoCast(SPELL_SHADOWS_OF_DOUBT_SELECTOR);
events.ScheduleEvent(EVENT_SHADOWS_OF_DOUBT, 30300ms);
break;
}
case EVENT_ENERGIZE:
{
if (me->GetPower(POWER_ENERGY) == 100)
{
Talk(SAY_VOCIFEROUS_INDOCTRINATION);
DoCastSelf(SPELL_VOCIFEROUS_INDOCTRINATION);
events.RescheduleEvent(EVENT_ENERGIZE, 6s);
}
else
{
me->SetPower(POWER_ENERGY, me->GetPower(POWER_ENERGY) + 4);
_energizeCount++;
events.ScheduleEvent(EVENT_ENERGIZE, (_energizeCount % 2) ? 1200ms : 800ms);
}
break;
}
default:
break;
}
}
}
private:
uint8 _subjugateCount;
uint8 _terrorizeCount;
uint8 _energizeCount;
};
// 434808 - Terrorize
class spell_orator_krix_vizk_terrorize_selector : public SpellScript
{
bool Validate(SpellInfo const* /*spellInfo*/) override
{
return ValidateSpellInfo({ SPELL_TERRORIZE });
}
void HandleHitTarget(SpellEffIndex /*effIndex*/) const
{
GetCaster()->CastSpell(GetHitUnit(), SPELL_TERRORIZE, CastSpellExtraArgsInit{
.TriggerFlags = TRIGGERED_IGNORE_CAST_IN_PROGRESS | TRIGGERED_DONT_REPORT_CAST_ERROR,
.TriggeringSpell = GetSpell()
});
}
void Register() override
{
OnEffectHitTarget += SpellEffectFn(spell_orator_krix_vizk_terrorize_selector::HandleHitTarget, EFFECT_0, SPELL_EFFECT_DUMMY);
}
};
// 448560 - Shadows of Doubt
class spell_orator_krix_vizk_shadows_of_doubt_selector : public SpellScript
{
bool Validate(SpellInfo const* /*spellInfo*/) override
{
return ValidateSpellInfo({ SPELL_SHADOWS_OF_DOUBT });
}
void HandleHitTarget(SpellEffIndex /*effIndex*/) const
{
GetCaster()->CastSpell(GetHitUnit(), SPELL_SHADOWS_OF_DOUBT, CastSpellExtraArgsInit{
.TriggerFlags = TRIGGERED_IGNORE_CAST_IN_PROGRESS | TRIGGERED_DONT_REPORT_CAST_ERROR,
.TriggeringSpell = GetSpell()
});
}
void Register() override
{
OnEffectHitTarget += SpellEffectFn(spell_orator_krix_vizk_shadows_of_doubt_selector::HandleHitTarget, EFFECT_0, SPELL_EFFECT_DUMMY);
}
};
// 440310 - Chains of Oppression
class spell_orator_krix_vizk_chains_of_oppression_periodic : public AuraScript
{
bool Validate(SpellInfo const* /*spellInfo*/) override
{
return ValidateSpellInfo({ SPELL_CHAINS_OF_OPPRESSION_DAMAGE, SPELL_CHAINS_OF_OPPRESSION_CHARGE });
}
void Tick(AuraEffect const* /*aurEff*/) const
{
if (Unit* caster = GetCaster())
{
Unit* target = GetTarget();
CastSpellExtraArgs args;
args.TriggerFlags = TRIGGERED_IGNORE_CAST_IN_PROGRESS | TRIGGERED_DONT_REPORT_CAST_ERROR;
caster->CastSpell(target, SPELL_CHAINS_OF_OPPRESSION_DAMAGE, args);
target->CastSpell(caster, SPELL_CHAINS_OF_OPPRESSION_CHARGE, args);
}
}
void Register() override
{
OnEffectPeriodic += AuraEffectPeriodicFn(spell_orator_krix_vizk_chains_of_oppression_periodic::Tick, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY);
}
};
// 448561 - Shadows of Doubt
class spell_orator_krix_vizk_shadows_of_doubt_periodic : public AuraScript
{
static constexpr uint8 MAX_SHADOW_OF_DOUBTS = 5;
static constexpr uint32 DOUBT_AT_CREATE_PROPERTIES = 165;
bool Validate(SpellInfo const* /*spell*/) override
{
return ValidateSpellInfo({ SPELL_DOUBT });
}
void AfterRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) const
{
if (GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_EXPIRE && GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_ENEMY_SPELL)
return;
Unit* caster = GetCaster();
if (!caster)
return;
for (uint8 i = 0; i < MAX_SHADOW_OF_DOUBTS; ++i)
{
Unit* target = GetTarget();
float angle = 2.f * float(M_PI) / MAX_SHADOW_OF_DOUBTS * i;
Position dest(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), angle);
AreaTrigger::CreateAreaTrigger({ DOUBT_AT_CREATE_PROPERTIES, true }, dest, -1, caster, target);
}
}
void Register() override
{
AfterEffectRemove += AuraEffectRemoveFn(spell_orator_krix_vizk_shadows_of_doubt_periodic::AfterRemove, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE, AURA_EFFECT_HANDLE_REAL);
}
};
// 434829 - Vociferous Indoctrination
class spell_orator_krix_vizk_vociferous_indoctrination_periodic : public AuraScript
{
bool Validate(SpellInfo const* /*spellInfo*/) override
{
return ValidateSpellInfo({ SPELL_VOCIFEROUS_INDOCTRINATION_DAMAGE, SPELL_LINGERING_INFLUENCE_AREATRIGGER });
}
void Tick(AuraEffect const* aurEff) const
{
if (Unit* caster = GetCaster())
caster->CastSpell(GetTarget(), SPELL_VOCIFEROUS_INDOCTRINATION_DAMAGE, CastSpellExtraArgsInit{
.TriggerFlags = TRIGGERED_IGNORE_CAST_IN_PROGRESS | TRIGGERED_DONT_REPORT_CAST_ERROR,
.TriggeringAura = aurEff
});
}
void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) const
{
if (Unit* caster = GetCaster())
GetTarget()->CastSpell(caster, SPELL_LINGERING_INFLUENCE_AREATRIGGER, TRIGGERED_IGNORE_CAST_IN_PROGRESS | TRIGGERED_DONT_REPORT_CAST_ERROR);
if (Creature* creatureTarget = GetTarget()->ToCreature())
creatureTarget->SetPower(POWER_ENERGY, 0);
}
void Register() override
{
OnEffectPeriodic += AuraEffectPeriodicFn(spell_orator_krix_vizk_vociferous_indoctrination_periodic::Tick, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY);
AfterEffectRemove += AuraEffectRemoveFn(spell_orator_krix_vizk_vociferous_indoctrination_periodic::OnRemove, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY, AURA_EFFECT_HANDLE_REAL);
}
};
// 434691 - Chains of Oppression
// Id - 31997
struct at_orator_krix_vizk_chains_of_oppression : AreaTriggerAI
{
at_orator_krix_vizk_chains_of_oppression(AreaTrigger* areatrigger) : AreaTriggerAI(areatrigger) { }
void OnUnitEnter(Unit* unit) override
{
if (!unit->IsPlayer())
return;
Unit* caster = at->GetCaster();
if (!caster)
return;
caster->CastSpell(unit, SPELL_CHAINS_OF_OPPRESSION_PERIODIC, TRIGGERED_IGNORE_CAST_IN_PROGRESS | TRIGGERED_DONT_REPORT_CAST_ERROR);
}
void OnUnitExit(Unit* unit, AreaTriggerExitReason /*reason*/) override
{
if (!unit->IsPlayer())
return;
unit->RemoveAurasDueToSpell(SPELL_CHAINS_OF_OPPRESSION_PERIODIC);
}
};
// 434923 - Lingering Influence
// ID - 32026
struct at_orator_krix_vizk_lingering_influence : AreaTriggerAI
{
at_orator_krix_vizk_lingering_influence(AreaTrigger* areatrigger) : AreaTriggerAI(areatrigger) { }
void OnUnitEnter(Unit* unit) override
{
if (!unit->IsPlayer())
return;
Unit* caster = at->GetCaster();
if (!caster)
return;
caster->CastSpell(unit, SPELL_LINGERING_INFLUENCE_DAMAGE, TRIGGERED_IGNORE_CAST_IN_PROGRESS | TRIGGERED_DONT_REPORT_CAST_ERROR);
}
void OnUnitExit(Unit* unit, AreaTriggerExitReason /*reason*/) override
{
if (!unit->IsPlayer())
return;
unit->RemoveAurasDueToSpell(SPELL_LINGERING_INFLUENCE_DAMAGE);
}
void OnInitialize() override
{
std::array<DBCPosition2D, 2> points =
{ {
{ 0.0f, 1.0f },
{ 1.0f, 18.0f }
} };
at->SetTimeToTargetScale(6000);
at->SetOverrideScaleCurve(points, 2);
}
};
// 165
struct at_orator_krix_vizk_doubt : AreaTriggerAI
{
explicit at_orator_krix_vizk_doubt(AreaTrigger* areaTrigger) : AreaTriggerAI(areaTrigger), _canHitOrigin(false) {}
void OnInitialize() override
{
Position destPos = at->GetPosition();
at->MovePositionToFirstCollision(destPos, 200.0f, 0.0f);
PathGenerator path(at);
path.CalculatePath(destPos.GetPositionX(), destPos.GetPositionY(), destPos.GetPositionZ(), true);
at->InitSplines(path.GetPath());
_canHitOrigin = false;
_scheduler.Schedule(1s, [this](TaskContext /*task*/)
{
_canHitOrigin = true;
});
}
void OnUpdate(uint32 diff) override
{
_scheduler.Update(diff);
}
void OnDestinationReached() override
{
at->Remove();
}
void OnUnitEnter(Unit* unit) override
{
if (!unit->IsPlayer())
return;
if (!_canHitOrigin && unit == at->GetTarget())
return;
Unit* caster = at->GetCaster();
if (!caster)
return;
caster->CastSpell(unit, SPELL_DOUBT, TRIGGERED_IGNORE_CAST_IN_PROGRESS | TRIGGERED_DONT_REPORT_CAST_ERROR);
}
private:
TaskScheduler _scheduler;
bool _canHitOrigin;
};
void AddSC_boss_orator_krix_vizk()
{
new GenericAreaTriggerEntityScript<at_orator_conversation_intro<CONVERSATION_ORATOR_INTRO_1, DATA_ORATOR_CONVO>>("at_orator_conversation_intro_1");
new GenericAreaTriggerEntityScript<at_orator_conversation_intro<CONVERSATION_ORATOR_INTRO_2, DATA_ORATOR_KRIX_VIZK>>("at_orator_conversation_intro_2");
new GenericAreaTriggerEntityScript<at_orator_conversation_intro<CONVERSATION_ORATOR_INTRO_3, DATA_ORATOR_KRIX_VIZK>>("at_orator_conversation_intro_3");
RegisterCityOfThreadsCreatureAI(boss_orator_krix_vizk);
RegisterSpellScript(spell_orator_krix_vizk_terrorize_selector);
RegisterSpellScript(spell_orator_krix_vizk_shadows_of_doubt_selector);
RegisterSpellScript(spell_orator_krix_vizk_chains_of_oppression_periodic);
RegisterSpellScript(spell_orator_krix_vizk_shadows_of_doubt_periodic);
RegisterSpellScript(spell_orator_krix_vizk_vociferous_indoctrination_periodic);
RegisterAreaTriggerAI(at_orator_krix_vizk_chains_of_oppression);
RegisterAreaTriggerAI(at_orator_krix_vizk_lingering_influence);
RegisterAreaTriggerAI(at_orator_krix_vizk_doubt);
}

View File

@@ -0,0 +1,61 @@
/*
* This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef DEF_CITY_OF_THREADS_H_
#define DEF_CITY_OF_THREADS_H_
#include "CreatureAIImpl.h"
#define COTScriptName "instance_city_of_threads"
#define DataHeader "CityOfThreads"
uint32 const EncounterCount = 4;
enum CityOfThreadsDataTypes
{
// Encounters
DATA_ORATOR_KRIX_VIZK = 0,
DATA_FANGS_OF_THE_QUEEN = 1,
DATA_THE_COAGLAMATION = 2,
DATA_IZO_THE_GRAND_SPLICER = 3,
// Additional Data
DATA_ORATOR_CONVO
};
enum CityOfThreadsCreatureIds
{
// Bosses
BOSS_ORATOR_KRIX_VIZK = 216619,
BOSS_NX = 216648,
BOSS_VX = 216649,
BOSS_THE_COAGLAMATION = 216320,
BOSS_IZO_THE_GRAND_SPLICER = 216658,
// Npcs
NPC_ORATOR_KRIX_VIZK_CONVO = 220769
};
template <class AI, class T>
inline AI* GetCityOfThreadsAI(T* obj)
{
return GetInstanceAI<AI>(obj, COTScriptName);
}
#define RegisterCityOfThreadsCreatureAI(ai_name) RegisterCreatureAIWithFactory(ai_name, GetCityOfThreadsAI)
#endif

View File

@@ -0,0 +1,66 @@
/*
* This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "InstanceScript.h"
#include "ScriptMgr.h"
#include "city_of_threads.h"
static constexpr ObjectData creatureData[] =
{
{ BOSS_ORATOR_KRIX_VIZK, DATA_ORATOR_KRIX_VIZK },
{ BOSS_NX, DATA_FANGS_OF_THE_QUEEN },
{ BOSS_VX, DATA_FANGS_OF_THE_QUEEN },
{ BOSS_THE_COAGLAMATION, DATA_THE_COAGLAMATION },
{ BOSS_IZO_THE_GRAND_SPLICER, DATA_IZO_THE_GRAND_SPLICER },
{ NPC_ORATOR_KRIX_VIZK_CONVO, DATA_ORATOR_CONVO },
{ 0, 0 } // END
};
static constexpr DungeonEncounterData const encounters[] =
{
{ DATA_ORATOR_KRIX_VIZK, {{ 2907 }} },
{ DATA_FANGS_OF_THE_QUEEN, {{ 2908 }} },
{ DATA_THE_COAGLAMATION, {{ 2905 }} },
{ DATA_IZO_THE_GRAND_SPLICER, {{ 2909 }} }
};
class instance_city_of_threads : public InstanceMapScript
{
public:
instance_city_of_threads() : InstanceMapScript(COTScriptName, 2669) { }
struct instance_city_of_threads_InstanceMapScript: public InstanceScript
{
instance_city_of_threads_InstanceMapScript(InstanceMap* map) : InstanceScript(map)
{
SetHeaders(DataHeader);
SetBossNumber(EncounterCount);
LoadObjectData(creatureData, nullptr);
LoadDungeonEncounterData(encounters);
}
};
InstanceScript* GetInstanceScript(InstanceMap* map) const override
{
return new instance_city_of_threads_InstanceMapScript(map);
}
};
void AddSC_instance_city_of_threads()
{
new instance_city_of_threads();
}

View File

@@ -32,6 +32,10 @@ void AddSC_boss_skarmorak();
void AddSC_instance_nerubar_palace();
void AddSC_boss_ulgrax_the_devourer();
// City of Threads
void AddSC_instance_city_of_threads();
void AddSC_boss_orator_krix_vizk();
// The name of this function should match:
// void Add${NameOfDirectory}Scripts()
void AddKhazAlgarScripts()
@@ -50,4 +54,8 @@ void AddKhazAlgarScripts()
// Nerub'ar Palace
AddSC_instance_nerubar_palace();
AddSC_boss_ulgrax_the_devourer();
// City of Threads
AddSC_instance_city_of_threads();
AddSC_boss_orator_krix_vizk();
}