Merge branch 'azerothcore:master' into Playerbot

This commit is contained in:
ZhengPeiRu21
2023-03-22 09:35:01 -06:00
committed by GitHub
18 changed files with 378 additions and 401 deletions

View File

@@ -277,6 +277,9 @@ public:
if (IsAnyPlayerValid())
return;
instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
if (Creature* controller = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_HALION_CONTROLLER)))
controller->AI()->DoAction(ACTION_RESET_ENCOUNTER);
BossAI::EnterEvadeMode(why);
}
@@ -286,14 +289,6 @@ public:
BossAI::AttackStart(who);
}
void JustReachedHome() override
{
instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
if (Creature* controller = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_HALION_CONTROLLER)))
controller->AI()->DoAction(ACTION_RESET_ENCOUNTER);
BossAI::JustReachedHome();
}
void JustEngagedWith(Unit* who) override
{
BossAI::JustEngagedWith(who);

View File

@@ -308,6 +308,7 @@ enum Phases
};
Position const CenterPosition = {503.6282f, -2124.655f, 840.8569f, 0.0f};
Position const TirionSpawn = { 505.2118f, -2124.353f, 840.9403f, 3.141593f };
Position const TirionIntro = {488.2970f, -2124.840f, 840.8569f, 0.0f};
Position const TirionCharge = {472.8500f, -2124.350f, 840.8570f, 0.0f};
Position const LichKingIntro[3] = { {432.0851f, -2123.673f, 864.6582f, 0.0f}, {457.8351f, -2123.423f, 841.1582f, 0.0f}, {465.0730f, -2123.470f, 840.8569f, 0.0f} };
@@ -660,6 +661,21 @@ public:
SetEquipmentSlots(true);
if (me->IsImmuneToPC())
me->SetStandState(UNIT_STAND_STATE_SIT);
DoAction(ACTION_RESTORE_LIGHT);
// Reset The Frozen Throne gameobjects
FrozenThroneResetWorker reset;
Acore::GameObjectWorker<FrozenThroneResetWorker> worker(me, reset);
Cell::VisitGridObjects(me, worker, 333.0f);
me->AddAura(SPELL_EMOTE_SIT_NO_SHEATH, me);
me->SetImmuneToPC(true);
me->SetReactState(REACT_PASSIVE);
me->SetStandState(UNIT_STAND_STATE_SIT);
if (!ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_HIGHLORD_TIRION_FORDRING)))
me->SummonCreature(NPC_HIGHLORD_TIRION_FORDRING_LK, TirionSpawn, TEMPSUMMON_MANUAL_DESPAWN);
}
void JustDied(Unit* /*killer*/) override
@@ -693,22 +709,6 @@ public:
events.ScheduleEvent(EVENT_SHADOW_TRAP, 15s + 500ms, EVENT_GROUP_ABILITIES);
}
void JustReachedHome() override
{
_JustReachedHome();
DoAction(ACTION_RESTORE_LIGHT);
// Reset The Frozen Throne gameobjects
FrozenThroneResetWorker reset;
Acore::GameObjectWorker<FrozenThroneResetWorker> worker(me, reset);
Cell::VisitGridObjects(me, worker, 333.0f);
me->AddAura(SPELL_EMOTE_SIT_NO_SHEATH, me);
me->SetImmuneToPC(true);
me->SetReactState(REACT_PASSIVE);
me->SetStandState(UNIT_STAND_STATE_SIT);
}
bool CanAIAttack(Unit const* target) const override
{
return me->IsVisible() && IsValidPlatformTarget(target) && !target->GetVehicle();
@@ -1262,7 +1262,7 @@ public:
me->SetReactState(REACT_AGGRESSIVE);
if (Creature* tirion = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_HIGHLORD_TIRION_FORDRING)))
tirion->AI()->EnterEvadeMode();
tirion->DespawnOrUnsummon();
}
};

View File

@@ -56,8 +56,7 @@ enum Events
EVENT_MARK_CAST = 1,
EVENT_PRIMARY_SPELL = 2,
EVENT_SECONDARY_SPELL = 3,
EVENT_PUNISH = 4,
EVENT_BERSERK = 5
EVENT_BERSERK = 4
};
enum Misc
@@ -75,12 +74,12 @@ enum Misc
enum FourHorsemen
{
SAY_AGGRO = 0,
SAY_TAUNT = 1,
SAY_SPECIAL = 2,
SAY_SLAY = 3,
SAY_DEATH = 4,
EMOTE_RAGECAST = 7
SAY_AGGRO = 0,
SAY_TAUNT = 1,
SAY_SPECIAL = 2,
SAY_SLAY = 3,
SAY_DEATH = 4,
EMOTE_RAGECAST = 7
};
// MARKS
@@ -201,7 +200,6 @@ public:
}
else
{
events.RescheduleEvent(EVENT_PUNISH, 5s);
events.RescheduleEvent(EVENT_SECONDARY_SPELL, 15s);
}
if (pInstance)
@@ -348,25 +346,29 @@ public:
me->CastSpell(me->GetVictim(), RAID_MODE(TABLE_SPELL_PRIMARY_10[horsemanId], TABLE_SPELL_PRIMARY_25[horsemanId]), false);
events.Repeat(15s);
return;
case EVENT_PUNISH:
if (!SelectTarget(SelectTargetMethod::MaxDistance, 0, 45.0f, true))
{
me->CastSpell(me, TABLE_SPELL_PUNISH[horsemanId], false);
Talk(EMOTE_RAGECAST);
}
events.Repeat(2s);
return;
case EVENT_SECONDARY_SPELL:
me->CastSpell(me->GetVictim(), RAID_MODE(TABLE_SPELL_SECONDARY_10[horsemanId], TABLE_SPELL_SECONDARY_25[horsemanId]), false);
events.Repeat(15s);
return;
}
if ((me->GetEntry() == NPC_LADY_BLAUMEUX || me->GetEntry() == NPC_SIR_ZELIEK))
if (me->GetEntry() == NPC_LADY_BLAUMEUX || me->GetEntry() == NPC_SIR_ZELIEK)
{
if (Unit* target = SelectTarget(SelectTargetMethod::MaxDistance, 0, 45.0f, true))
if (Unit* pTarget = me->SelectNearestPlayer(300.0f))
{
me->CastSpell(target, RAID_MODE(TABLE_SPELL_PRIMARY_10[horsemanId], TABLE_SPELL_PRIMARY_25[horsemanId]), false);
if (pTarget && me->IsValidAttackTarget(pTarget))
{
AttackStart(pTarget);
}
}
if (me->IsWithinDistInMap(me->GetVictim(), 45.0f) && me->IsValidAttackTarget(me->GetVictim()))
{
DoCastVictim(RAID_MODE(TABLE_SPELL_PRIMARY_10[horsemanId], TABLE_SPELL_PRIMARY_25[horsemanId]));
}
else if (!me->IsWithinDistInMap(me->GetVictim(), 45.0f) || !me->IsValidAttackTarget(me->GetVictim()))
{
DoCastAOE(TABLE_SPELL_PUNISH[horsemanId]);
Talk(EMOTE_RAGECAST);
}
}
else
@@ -406,7 +408,7 @@ public:
damage = 4000;
break;
case 5:
damage = 12000;
damage = 12500;
break;
case 6:
damage = 20000;

View File

@@ -107,7 +107,7 @@ void AddSC_netherstorm();
void AddSC_shadowmoon_valley();
void AddSC_shattrath_city();
void AddSC_terokkar_forest();
void AddSC_zangarmarsh();
//void AddSC_zangarmarsh();
// The name of this function should match:
// void Add${NameOfDirectory}Scripts()
@@ -204,5 +204,5 @@ void AddOutlandScripts()
AddSC_shadowmoon_valley();
AddSC_shattrath_city();
AddSC_terokkar_forest();
AddSC_zangarmarsh();
//AddSC_zangarmarsh();
}

View File

@@ -1,325 +0,0 @@
/*
* This file is part of the AzerothCore 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 Affero General Public License as published by the
* Free Software Foundation; either version 3 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 Affero 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 "Player.h"
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "ScriptedEscortAI.h"
#include "ScriptedGossip.h"
/*######
## npc_cooshcoosh
######*/
#define GOSSIP_COOSH "You owe Sim'salabim money. Hand them over or die!"
enum Cooshhooosh
{
SPELL_LIGHTNING_BOLT = 9532,
QUEST_CRACK_SKULLS = 10009
};
class npc_cooshcoosh : public CreatureScript
{
public:
npc_cooshcoosh() : CreatureScript("npc_cooshcoosh") { }
struct npc_cooshcooshAI : public ScriptedAI
{
npc_cooshcooshAI(Creature* creature) : ScriptedAI(creature)
{
m_uiNormFaction = creature->GetFaction();
}
uint32 m_uiNormFaction;
uint32 LightningBolt_Timer;
void Reset() override
{
LightningBolt_Timer = 2000;
if (me->GetFaction() != m_uiNormFaction)
me->SetFaction(m_uiNormFaction);
}
void JustEngagedWith(Unit* /*who*/) override { }
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
return;
if (LightningBolt_Timer <= diff)
{
DoCastVictim(SPELL_LIGHTNING_BOLT);
LightningBolt_Timer = 5000;
}
else LightningBolt_Timer -= diff;
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI(Creature* creature) const override
{
return new npc_cooshcooshAI(creature);
}
bool OnGossipHello(Player* player, Creature* creature) override
{
if (player->GetQuestStatus(QUEST_CRACK_SKULLS) == QUEST_STATUS_INCOMPLETE)
AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_COOSH, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF);
SendGossipMenuFor(player, 9441, creature->GetGUID());
return true;
}
bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) override
{
ClearGossipMenuFor(player);
if (action == GOSSIP_ACTION_INFO_DEF)
{
CloseGossipMenuFor(player);
creature->SetFaction(FACTION_OGRE);
creature->AI()->AttackStart(player);
}
return true;
}
};
/*######
## npc_elder_kuruti
######*/
#define GOSSIP_ITEM_KUR1 "Greetings, elder. It is time for your people to end their hostility towards the draenei and their allies."
#define GOSSIP_ITEM_KUR2 "I did not mean to deceive you, elder. The draenei of Telredor thought to approach you in a way that would seem familiar to you."
#define GOSSIP_ITEM_KUR3 "I will tell them. Farewell, elder."
class npc_elder_kuruti : public CreatureScript
{
public:
npc_elder_kuruti() : CreatureScript("npc_elder_kuruti") { }
bool OnGossipHello(Player* player, Creature* creature) override
{
if (player->GetQuestStatus(9803) == QUEST_STATUS_INCOMPLETE)
AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_ITEM_KUR1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF);
SendGossipMenuFor(player, 9226, creature->GetGUID());
return true;
}
bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) override
{
ClearGossipMenuFor(player);
switch (action)
{
case GOSSIP_ACTION_INFO_DEF:
AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_ITEM_KUR2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
SendGossipMenuFor(player, 9227, creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 1:
AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_ITEM_KUR3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
SendGossipMenuFor(player, 9229, creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 2:
{
if (!player->HasItemCount(24573))
{
ItemPosCountVec dest;
uint32 itemId = 24573;
InventoryResult msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, itemId, 1, nullptr);
if (msg == EQUIP_ERR_OK)
{
player->StoreNewItem(dest, itemId, true);
}
else
player->SendEquipError(msg, nullptr, nullptr, itemId);
}
SendGossipMenuFor(player, 9231, creature->GetGUID());
break;
}
}
return true;
}
};
/*######
## npc_mortog_steamhead
######*/
class npc_mortog_steamhead : public CreatureScript
{
public:
npc_mortog_steamhead() : CreatureScript("npc_mortog_steamhead") { }
bool OnGossipHello(Player* player, Creature* creature) override
{
if (creature->IsVendor() && player->GetReputationRank(942) == REP_EXALTED)
AddGossipItemFor(player, GOSSIP_ICON_VENDOR, GOSSIP_TEXT_BROWSE_GOODS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRADE);
SendGossipMenuFor(player, player->GetGossipTextId(creature), creature->GetGUID());
return true;
}
bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) override
{
ClearGossipMenuFor(player);
if (action == GOSSIP_ACTION_TRADE)
player->GetSession()->SendListInventory(creature->GetGUID());
return true;
}
};
/*######
## npc_kayra_longmane
######*/
enum Kayra
{
SAY_START = 0,
SAY_AMBUSH1 = 1,
SAY_PROGRESS = 2,
SAY_AMBUSH2 = 3,
SAY_END = 4,
QUEST_ESCAPE_FROM = 9752,
NPC_SLAVEBINDER = 18042
};
class npc_kayra_longmane : public CreatureScript
{
public:
npc_kayra_longmane() : CreatureScript("npc_kayra_longmane") { }
struct npc_kayra_longmaneAI : public npc_escortAI
{
npc_kayra_longmaneAI(Creature* creature) : npc_escortAI(creature) { }
void Reset() override { }
void WaypointReached(uint32 waypointId) override
{
Player* player = GetPlayerForEscort();
if (!player)
return;
switch (waypointId)
{
case 4:
Talk(SAY_AMBUSH1, player);
DoSpawnCreature(NPC_SLAVEBINDER, -10.0f, -5.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000);
DoSpawnCreature(NPC_SLAVEBINDER, -8.0f, 5.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000);
break;
case 5:
Talk(SAY_PROGRESS, player);
SetRun();
break;
case 16:
Talk(SAY_AMBUSH2, player);
DoSpawnCreature(NPC_SLAVEBINDER, -10.0f, -5.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000);
DoSpawnCreature(NPC_SLAVEBINDER, -8.0f, 5.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000);
break;
case 17:
SetRun(false);
break;
case 25:
Talk(SAY_END, player);
player->GroupEventHappens(QUEST_ESCAPE_FROM, me);
break;
}
}
};
bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) override
{
if (quest->GetQuestId() == QUEST_ESCAPE_FROM)
{
creature->AI()->Talk(SAY_START, player);
if (npc_escortAI* pEscortAI = CAST_AI(npc_kayra_longmane::npc_kayra_longmaneAI, creature->AI()))
pEscortAI->Start(false, false, player->GetGUID());
}
return true;
}
CreatureAI* GetAI(Creature* creature) const override
{
return new npc_kayra_longmaneAI(creature);
}
};
/*######
## npc_timothy_daniels
######*/
#define GOSSIP_TIMOTHY_DANIELS_ITEM1 "Specialist, eh? Just what kind of specialist are you, anyway?"
#define GOSSIP_TEXT_BROWSE_POISONS "Let me browse your reagents and poison supplies."
enum Timothy
{
GOSSIP_TEXTID_TIMOTHY_DANIELS1 = 9239
};
class npc_timothy_daniels : public CreatureScript
{
public:
npc_timothy_daniels() : CreatureScript("npc_timothy_daniels") { }
bool OnGossipHello(Player* player, Creature* creature) override
{
if (creature->IsQuestGiver())
player->PrepareQuestMenu(creature->GetGUID());
if (creature->IsVendor())
AddGossipItemFor(player, GOSSIP_ICON_VENDOR, GOSSIP_TEXT_BROWSE_POISONS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRADE);
AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_TIMOTHY_DANIELS_ITEM1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
SendGossipMenuFor(player, player->GetGossipTextId(creature), creature->GetGUID());
return true;
}
bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) override
{
ClearGossipMenuFor(player);
switch (action)
{
case GOSSIP_ACTION_INFO_DEF+1:
SendGossipMenuFor(player, GOSSIP_TEXTID_TIMOTHY_DANIELS1, creature->GetGUID());
break;
case GOSSIP_ACTION_TRADE:
player->GetSession()->SendListInventory(creature->GetGUID());
break;
}
return true;
}
};
/*######
## AddSC
######*/
void AddSC_zangarmarsh()
{
// Theirs
new npc_cooshcoosh();
new npc_elder_kuruti();
new npc_mortog_steamhead();
new npc_kayra_longmane();
new npc_timothy_daniels();
}

View File

@@ -811,6 +811,44 @@ class spell_item_gnomish_shrink_ray : public SpellScript
}
};
enum GoblinWeatherMachiene
{
SPELL_PERSONALIZED_WEATHER_RAIN = 46736,
SPELL_PERSONALIZED_WEATHER_SNOW = 46738,
SPELL_PERSONALIZED_WEATHER_SUN = 46739,
SPELL_PERSONALIZED_WEATHER_CLOUDS = 46740
};
uint32 WeatherForcast()
{
if (!SpellScript::ValidateSpellInfo({
SPELL_PERSONALIZED_WEATHER_RAIN,
SPELL_PERSONALIZED_WEATHER_SNOW,
SPELL_PERSONALIZED_WEATHER_SUN,
SPELL_PERSONALIZED_WEATHER_CLOUDS
}))
return 0;
uint32 spellId = 0;
switch (urand(0, 3))
{
case 0:
spellId = SPELL_PERSONALIZED_WEATHER_RAIN;
break;
case 1:
spellId = SPELL_PERSONALIZED_WEATHER_SNOW;
break;
case 2:
spellId = SPELL_PERSONALIZED_WEATHER_SUN;
break;
case 3:
spellId = SPELL_PERSONALIZED_WEATHER_CLOUDS;
break;
}
return spellId;
}
class spell_item_goblin_weather_machine : public SpellScript
{
PrepareSpellScript(spell_item_goblin_weather_machine);
@@ -819,18 +857,13 @@ class spell_item_goblin_weather_machine : public SpellScript
{
if (Unit* target = GetHitUnit())
{
uint32 spellId = 46736;
if (uint8 add = urand(0, 3))
spellId += add + 1;
target->CastSpell(target, spellId, true);
target->CastSpell(target, WeatherForcast(), true);
}
}
void Register() override
{
if (m_scriptSpellId == 46203)
OnEffectHitTarget += SpellEffectFn(spell_item_goblin_weather_machine::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
OnEffectHitTarget += SpellEffectFn(spell_item_goblin_weather_machine::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
}
};
@@ -843,17 +876,12 @@ class spell_item_goblin_weather_machine_aura : public AuraScript
if (roll_chance_i(50))
return;
uint32 spellId = 46736;
if (uint8 add = urand(0, 3))
spellId += add + 1;
GetUnitOwner()->CastSpell(GetUnitOwner(), spellId, true);
GetUnitOwner()->CastSpell(GetUnitOwner(), WeatherForcast(), true);
}
void Register() override
{
if (m_scriptSpellId != 46203)
AfterEffectRemove += AuraEffectRemoveFn(spell_item_goblin_weather_machine_aura::OnRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
AfterEffectRemove += AuraEffectRemoveFn(spell_item_goblin_weather_machine_aura::OnRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
}
};
@@ -3845,7 +3873,8 @@ void AddSC_item_spell_scripts()
RegisterSpellScript(spell_item_strong_anti_venom);
RegisterSpellScript(spell_item_anti_venom);
RegisterSpellScript(spell_item_gnomish_shrink_ray);
RegisterSpellAndAuraScriptPair(spell_item_goblin_weather_machine, spell_item_goblin_weather_machine_aura);
RegisterSpellScript(spell_item_goblin_weather_machine);
RegisterSpellScript(spell_item_goblin_weather_machine_aura);
RegisterSpellScript(spell_item_light_lamp);
RegisterSpellScript(spell_item_fetch_ball);
RegisterSpellScript(spell_item_oracle_ablutions);