summaryrefslogtreecommitdiff
path: root/src/server
diff options
context:
space:
mode:
Diffstat (limited to 'src/server')
-rw-r--r--src/server/game/AI/SmartScripts/SmartAI.cpp47
-rw-r--r--src/server/game/AI/SmartScripts/SmartAI.h1
-rw-r--r--src/server/game/AI/SmartScripts/SmartScript.cpp8
-rw-r--r--src/server/game/AI/SmartScripts/SmartScript.h2
-rw-r--r--src/server/game/AI/SmartScripts/SmartScriptMgr.h21
-rw-r--r--src/server/game/DungeonFinding/LFGMgr.cpp11
-rw-r--r--src/server/game/DungeonFinding/LFGMgr.h2
-rw-r--r--src/server/scripts/Northrend/zone_storm_peaks.cpp84
8 files changed, 94 insertions, 82 deletions
diff --git a/src/server/game/AI/SmartScripts/SmartAI.cpp b/src/server/game/AI/SmartScripts/SmartAI.cpp
index f888403491..3c952a42d9 100644
--- a/src/server/game/AI/SmartScripts/SmartAI.cpp
+++ b/src/server/game/AI/SmartScripts/SmartAI.cpp
@@ -858,7 +858,7 @@ void SmartAI::AttackStart(Unit* who)
return;
}
- if (who && me->Attack(who, me->IsWithinMeleeRange(who)))
+ if (who && me->Attack(who, me->IsWithinMeleeRange(who) || _currentRangeMode))
{
if (!me->HasUnitState(UNIT_STATE_NO_COMBAT_MOVEMENT))
{
@@ -870,7 +870,7 @@ void SmartAI::AttackStart(Unit* who)
me->GetMotionMaster()->Clear(false);
}
- me->GetMotionMaster()->MoveChase(who);
+ me->GetMotionMaster()->MoveChase(who, _attackDistance);
}
}
}
@@ -941,6 +941,35 @@ void SmartAI::PassengerBoarded(Unit* who, int8 seatId, bool apply)
void SmartAI::InitializeAI()
{
GetScript()->OnInitialize(me);
+
+ for (SmartScriptHolder const& event : GetScript()->GetEvents())
+ {
+ if (event.GetActionType() != SMART_ACTION_CAST)
+ continue;
+
+ if (!(event.action.cast.castFlags & SMARTCAST_MAIN_SPELL))
+ continue;
+
+ SetMainSpell(event.action.cast.spell);
+ break;
+ }
+
+ // Fallback: use first SMARTCAST_COMBAT_MOVE if no MAIN_SPELL found
+ if (!_currentRangeMode)
+ {
+ for (SmartScriptHolder const& event : GetScript()->GetEvents())
+ {
+ if (event.GetActionType() != SMART_ACTION_CAST)
+ continue;
+
+ if (!(event.action.cast.castFlags & SMARTCAST_COMBAT_MOVE))
+ continue;
+
+ SetMainSpell(event.action.cast.spell);
+ break;
+ }
+ }
+
if (!me->isDead())
{
mJustReset = true;
@@ -1083,6 +1112,20 @@ void SmartAI::SetCurrentRangeMode(bool on, float range)
me->GetMotionMaster()->MoveChase(victim, _attackDistance);
}
+void SmartAI::SetMainSpell(uint32 spellId)
+{
+ SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
+ if (!spellInfo)
+ return;
+
+ float maxRange = spellInfo->GetMaxRange(false);
+ if (maxRange <= NOMINAL_MELEE_RANGE)
+ return;
+
+ _attackDistance = std::max(maxRange - NOMINAL_MELEE_RANGE, 0.0f);
+ _currentRangeMode = true;
+}
+
void SmartAI::DistanceYourself(float range)
{
Unit* victim = me->GetVictim();
diff --git a/src/server/game/AI/SmartScripts/SmartAI.h b/src/server/game/AI/SmartScripts/SmartAI.h
index d6b957cc00..0876336458 100644
--- a/src/server/game/AI/SmartScripts/SmartAI.h
+++ b/src/server/game/AI/SmartScripts/SmartAI.h
@@ -67,6 +67,7 @@ public:
void SetAutoAttack(bool on) { mCanAutoAttack = on; }
void SetCombatMovement(bool on, bool stopOrStartMovement);
void SetCurrentRangeMode(bool on, float range = 0.f);
+ void SetMainSpell(uint32 spellId);
void DistanceYourself(float range);
void SetFollow(Unit* target, float dist = 0.0f, float angle = 0.0f, uint32 credit = 0, uint32 end = 0, uint32 creditType = 0, bool aliveState = true);
void StopFollow(bool complete);
diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp
index e7a5c4fd84..2f66b4ac11 100644
--- a/src/server/game/AI/SmartScripts/SmartScript.cpp
+++ b/src/server/game/AI/SmartScripts/SmartScript.cpp
@@ -707,7 +707,6 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
continue;
}
- // Let us not try to cast spell if we know it is going to fail anyway. Stick to chasing and continue.
if (distanceToTarget > spellMaxRange && isWithinLOSInMap)
{
failedSpellCast = true;
@@ -745,12 +744,9 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
if (e.action.cast.castFlags & SMARTCAST_COMBAT_MOVE)
{
- // If cast flag SMARTCAST_COMBAT_MOVE is set combat movement will not be allowed unless target is outside spell range, out of mana, or LOS.
- if (result == SPELL_FAILED_OUT_OF_RANGE || result == SPELL_CAST_OK)
- // if we are just out of range, we only chase until we are back in spell range.
+ if (result == SPELL_FAILED_OUT_OF_RANGE)
CAST_AI(SmartAI, me->AI())->SetCurrentRangeMode(true, std::max(spellMaxRange - NOMINAL_MELEE_RANGE, 0.0f));
- else // move into melee on any other fail
- // if spell fail for any other reason, we chase to melee range, or stay where we are if spellcast was successful.
+ else if (result != SPELL_CAST_OK)
CAST_AI(SmartAI, me->AI())->SetCurrentRangeMode(false, 0.f);
}
diff --git a/src/server/game/AI/SmartScripts/SmartScript.h b/src/server/game/AI/SmartScripts/SmartScript.h
index e0f32438c8..250fdd775a 100644
--- a/src/server/game/AI/SmartScripts/SmartScript.h
+++ b/src/server/game/AI/SmartScripts/SmartScript.h
@@ -207,6 +207,8 @@ public:
void AddCreatureSummon(ObjectGuid const& guid);
void RemoveCreatureSummon(ObjectGuid const& guid);
+ SmartAIEventList const& GetEvents() const { return mEvents; }
+
private:
void IncPhase(uint32 p);
void DecPhase(uint32 p);
diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.h b/src/server/game/AI/SmartScripts/SmartScriptMgr.h
index 5e8e5e9e0c..8dd177dfa6 100644
--- a/src/server/game/AI/SmartScripts/SmartScriptMgr.h
+++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.h
@@ -1932,16 +1932,17 @@ enum SmartEventFlags
enum SmartCastFlags
{
- SMARTCAST_INTERRUPT_PREVIOUS = 0x001, // Interrupt any spell casting
- SMARTCAST_TRIGGERED = 0x002, // Triggered (this makes spell cost zero mana and have no cast time)
- //CAST_FORCE_CAST = 0x004, // Forces cast even if creature is out of mana or out of range
- //CAST_NO_MELEE_IF_OOM = 0x008, // Prevents creature from entering melee if out of mana or out of range
- //CAST_FORCE_TARGET_SELF = 0x010, // Forces the target to cast this spell on itself
- SMARTCAST_AURA_NOT_PRESENT = 0x020, // Only casts the spell if the target does not have an aura from the spell
- SMARTCAST_COMBAT_MOVE = 0x040, // Prevents combat movement if cast successful. Allows movement on range, OOM, LOS
- SMARTCAST_THREATLIST_NOT_SINGLE = 0x080, // Only cast if the source's threatlist is higher than one. This includes pets (see Skeram's True Fulfillment)
- SMARTCAST_TARGET_POWER_MANA = 0x100, // Only cast if the target has power type mana (e.g. Mana Drain)
- SMARTCAST_ENABLE_COMBAT_MOVE_ON_LOS = 0x200,
+ SMARTCAST_INTERRUPT_PREVIOUS = 0x001, // Interrupt any spell casting
+ SMARTCAST_TRIGGERED = 0x002, // Triggered (this makes spell cost zero mana and have no cast time)
+ //CAST_FORCE_CAST = 0x004, // Forces cast even if creature is out of mana or out of range
+ //CAST_NO_MELEE_IF_OOM = 0x008, // Prevents creature from entering melee if out of mana or out of range
+ //CAST_FORCE_TARGET_SELF = 0x010, // Forces the target to cast this spell on itself
+ SMARTCAST_AURA_NOT_PRESENT = 0x020, // Only casts the spell if the target does not have an aura from the spell
+ SMARTCAST_COMBAT_MOVE = 0x040, // Prevents combat movement if cast successful. Allows movement on range, OOM, LOS
+ SMARTCAST_THREATLIST_NOT_SINGLE = 0x080, // Only cast if the source's threatlist is higher than one. This includes pets (see Skeram's True Fulfillment)
+ SMARTCAST_TARGET_POWER_MANA = 0x100, // Only cast if the target has power type mana (e.g. Mana Drain)
+ SMARTCAST_ENABLE_COMBAT_MOVE_ON_LOS = 0x200, // Allows combat movement when not in line of sight
+ SMARTCAST_MAIN_SPELL = 0x400, // Sets this spell's max range as the creature's chase distance on spawn
};
enum SmartFollowType
diff --git a/src/server/game/DungeonFinding/LFGMgr.cpp b/src/server/game/DungeonFinding/LFGMgr.cpp
index b88d04c65e..b48138a8ba 100644
--- a/src/server/game/DungeonFinding/LFGMgr.cpp
+++ b/src/server/game/DungeonFinding/LFGMgr.cpp
@@ -688,7 +688,7 @@ namespace lfg
// xinef: dont check compatibile dungeons for already running group (bind problems)
if (!isContinue)
{
- GetCompatibleDungeons(dungeons, players, joinData.lockmap);
+ GetCompatibleDungeons(dungeons, players, joinData.lockmap, rDungeonId);
if (dungeons.empty())
joinData.result = grp ? LFG_JOIN_PARTY_NOT_MEET_REQS : LFG_JOIN_NOT_MEET_REQS;
}
@@ -1485,7 +1485,7 @@ namespace lfg
@param[in] players Set of players to check their dungeon restrictions
@param[out] lockMap Map of players Lock status info of given dungeons (Empty if dungeons is not empty)
*/
- void LFGMgr::GetCompatibleDungeons(LfgDungeonSet& dungeons, LfgGuidSet const& players, LfgLockPartyMap& lockMap)
+ void LFGMgr::GetCompatibleDungeons(LfgDungeonSet& dungeons, LfgGuidSet const& players, LfgLockPartyMap& lockMap, bool isRDF)
{
lockMap.clear();
for (LfgGuidSet::const_iterator it = players.begin(); it != players.end() && !dungeons.empty(); ++it)
@@ -1496,6 +1496,9 @@ namespace lfg
{
uint32 dungeonId = (it2->first & 0x00FFFFFF); // Compare dungeon ids
+ if (it2->second == LFG_LOCKSTATUS_RAID_LOCKED && isRDF)
+ continue;
+
LfgDungeonSet::iterator itDungeon = dungeons.find(dungeonId);
if (itDungeon != dungeons.end())
{
@@ -1762,10 +1765,8 @@ namespace lfg
else
{
// RDF removes all binds to that map
- if (randomDungeon && !sInstanceSaveMgr->PlayerIsPermBoundToInstance(player->GetGUID(), dungeon->map, player->GetDungeonDifficulty()))
- {
+ if (randomDungeon)
sInstanceSaveMgr->PlayerUnbindInstance(player->GetGUID(), dungeon->map, player->GetDungeonDifficulty(), true);
- }
}
playersTeleported.push_back(player);
diff --git a/src/server/game/DungeonFinding/LFGMgr.h b/src/server/game/DungeonFinding/LFGMgr.h
index 426f0c679a..e52bbda7dd 100644
--- a/src/server/game/DungeonFinding/LFGMgr.h
+++ b/src/server/game/DungeonFinding/LFGMgr.h
@@ -589,7 +589,7 @@ namespace lfg
void DecreaseKicksLeft(ObjectGuid guid);
void SetState(ObjectGuid guid, LfgState state);
void SetCanOverrideRBState(ObjectGuid guid, bool val);
- void GetCompatibleDungeons(LfgDungeonSet& dungeons, LfgGuidSet const& players, LfgLockPartyMap& lockMap);
+ void GetCompatibleDungeons(LfgDungeonSet& dungeons, LfgGuidSet const& players, LfgLockPartyMap& lockMap, bool isRDF = false);
void _SaveToDB(ObjectGuid guid);
LFGDungeonData const* GetLFGDungeon(uint32 id);
diff --git a/src/server/scripts/Northrend/zone_storm_peaks.cpp b/src/server/scripts/Northrend/zone_storm_peaks.cpp
index 5c208f1187..836469a3e8 100644
--- a/src/server/scripts/Northrend/zone_storm_peaks.cpp
+++ b/src/server/scripts/Northrend/zone_storm_peaks.cpp
@@ -915,72 +915,40 @@ public:
}
};
-class npc_hyldsmeet_protodrake : public CreatureScript
+enum HyldsmeetProtoDrake
{
- enum NPCs
- {
- NPC_HYLDSMEET_DRAKERIDER = 29694
- };
+ NPC_HYLDSMEET_DRAKERIDER = 29694
+};
-public:
- npc_hyldsmeet_protodrake() : CreatureScript("npc_hyldsmeet_protodrake") { }
+struct npc_hyldsmeet_protodrake : public CreatureAI
+{
+ explicit npc_hyldsmeet_protodrake(Creature* creature) : CreatureAI(creature), _accessoryRespawnTimer(0) { }
- class npc_hyldsmeet_protodrakeAI : public CreatureAI
+ void PassengerBoarded(Unit* who, int8 /*seat*/, bool apply) override
{
- public:
- npc_hyldsmeet_protodrakeAI(Creature* creature) : CreatureAI(creature), _accessoryRespawnTimer(0), _vehicleKit(creature->GetVehicleKit()) { }
-
- void PassengerBoarded(Unit* who, int8 /*seat*/, bool apply) override
- {
- if (apply)
- {
- class DelayedTransportPositionOffsets : public BasicEvent
- {
- public:
- DelayedTransportPositionOffsets(Unit* owner) : _owner(owner) { }
-
- bool Execute(uint64 /*eventTime*/, uint32 /*updateTime*/) override
- {
- _owner->m_movementInfo.transport.pos.Relocate(-3.5f, 0.f, -0.2f, 0.f);
- return true;
- }
-
- private:
- Unit* _owner;
- };
-
- if (who->IsPlayer())
- who->m_Events.AddEventAtOffset(new DelayedTransportPositionOffsets(who), 500ms);
-
- return;
- }
+ if (apply)
+ return;
- if (who->GetEntry() == NPC_HYLDSMEET_DRAKERIDER)
- _accessoryRespawnTimer = 5 * MINUTE * IN_MILLISECONDS;
- }
+ if (who->GetEntry() == NPC_HYLDSMEET_DRAKERIDER)
+ _accessoryRespawnTimer = 5 * MINUTE * IN_MILLISECONDS;
+ }
- void UpdateAI(uint32 diff) override
+ void UpdateAI(uint32 diff) override
+ {
+ //! We need to manually reinstall accessories because the vehicle itself is friendly to players,
+ //! so EnterEvadeMode is never triggered. The accessory on the other hand is hostile and killable.
+ Vehicle* vehicleKit = me->GetVehicleKit();
+ if (_accessoryRespawnTimer && _accessoryRespawnTimer <= diff && vehicleKit)
{
- //! We need to manually reinstall accessories because the vehicle itself is friendly to players,
- //! so EnterEvadeMode is never triggered. The accessory on the other hand is hostile and killable.
- if (_accessoryRespawnTimer && _accessoryRespawnTimer <= diff && _vehicleKit)
- {
- _vehicleKit->InstallAllAccessories(true);
- _accessoryRespawnTimer = 0;
- }
- else
- _accessoryRespawnTimer -= diff;
+ vehicleKit->InstallAllAccessories(true);
+ _accessoryRespawnTimer = 0;
}
-
- private:
- uint32 _accessoryRespawnTimer;
- Vehicle* _vehicleKit;
- };
-
- CreatureAI* GetAI(Creature* creature) const override
- {
- return new npc_hyldsmeet_protodrakeAI(creature);
+ else
+ _accessoryRespawnTimer -= diff;
}
+
+private:
+ uint32 _accessoryRespawnTimer;
};
enum CloseRift
@@ -1215,7 +1183,7 @@ void AddSC_storm_peaks()
new npc_brunnhildar_prisoner();
new npc_freed_protodrake();
new npc_icefang();
- new npc_hyldsmeet_protodrake();
+ RegisterCreatureAI(npc_hyldsmeet_protodrake);
RegisterSpellScript(spell_close_rift_aura);
new npc_vehicle_d16_propelled_delivery();
RegisterSpellScript(spell_q12823_remove_collapsing_cave_aura);