diff options
Diffstat (limited to 'src/server/game/AI/ScriptedAI')
| -rw-r--r-- | src/server/game/AI/ScriptedAI/ScriptedCreature.cpp | 72 | ||||
| -rw-r--r-- | src/server/game/AI/ScriptedAI/ScriptedCreature.h | 42 | ||||
| -rw-r--r-- | src/server/game/AI/ScriptedAI/ScriptedEscortAI.cpp | 31 | ||||
| -rw-r--r-- | src/server/game/AI/ScriptedAI/ScriptedEscortAI.h | 5 | ||||
| -rw-r--r-- | src/server/game/AI/ScriptedAI/ScriptedFollowerAI.cpp | 80 | ||||
| -rw-r--r-- | src/server/game/AI/ScriptedAI/ScriptedFollowerAI.h | 43 | ||||
| -rw-r--r-- | src/server/game/AI/ScriptedAI/ScriptedGossip.h | 4 |
7 files changed, 128 insertions, 149 deletions
diff --git a/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp b/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp index 32ba4bdf5a1..3af141dae8a 100644 --- a/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp +++ b/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp @@ -118,9 +118,7 @@ void SummonList::DoActionImpl(int32 action, StorageType const& summons) ScriptedAI::ScriptedAI(Creature* creature) : ScriptedAI(creature, creature->GetScriptId()) { } -ScriptedAI::ScriptedAI(Creature* creature, uint32 scriptId) : CreatureAI(creature, scriptId), - IsFleeing(false), - _isCombatMovementAllowed(true) +ScriptedAI::ScriptedAI(Creature* creature, uint32 scriptId) : CreatureAI(creature, scriptId), IsFleeing(false), _isCombatMovementAllowed(true) { _isHeroic = me->GetMap()->IsHeroic(); _difficulty = me->GetMap()->GetDifficultyID(); @@ -145,7 +143,7 @@ void ScriptedAI::AttackStart(Unit* who) void ScriptedAI::UpdateAI(uint32 /*diff*/) { - //Check if we have a current target + // Check if we have a current target if (!UpdateVictim()) return; @@ -188,7 +186,7 @@ void ScriptedAI::DoPlaySoundToSet(WorldObject* source, uint32 soundId) if (!sSoundKitStore.LookupEntry(soundId)) { - TC_LOG_ERROR("scripts", "Invalid soundId %u used in DoPlaySoundToSet (Source: %s)", soundId, source->GetGUID().ToString().c_str()); + TC_LOG_ERROR("scripts.ai", "ScriptedAI::DoPlaySoundToSet: Invalid soundId %u used in DoPlaySoundToSet (Source: %s)", soundId, source->GetGUID().ToString().c_str()); return; } @@ -255,15 +253,15 @@ bool ScriptedAI::HealthAbovePct(uint32 pct) const SpellInfo const* ScriptedAI::SelectSpell(Unit* target, uint32 school, uint32 mechanic, SelectTargetType targets, float rangeMin, float rangeMax, SelectEffect effect) { - //No target so we can't cast + // No target so we can't cast if (!target) return nullptr; - //Silenced so we can't cast + // Silenced so we can't cast if (me->HasUnitFlag(UNIT_FLAG_SILENCED)) return nullptr; - //Using the extended script system we first create a list of viable spells + // Using the extended script system we first create a list of viable spells SpellInfo const* apSpell[MAX_CREATURE_SPELLS]; memset(apSpell, 0, MAX_CREATURE_SPELLS * sizeof(SpellInfo*)); @@ -272,49 +270,63 @@ SpellInfo const* ScriptedAI::SelectSpell(Unit* target, uint32 school, uint32 mec SpellInfo const* tempSpell = nullptr; AISpellInfoType const* aiSpell = nullptr; - //Check if each spell is viable(set it to null if not) + // Check if each spell is viable(set it to null if not) for (uint32 i = 0; i < MAX_CREATURE_SPELLS; i++) { tempSpell = sSpellMgr->GetSpellInfo(me->m_spells[i], me->GetMap()->GetDifficultyID()); aiSpell = GetAISpellInfo(me->m_spells[i], me->GetMap()->GetDifficultyID()); - //This spell doesn't exist + // This spell doesn't exist if (!tempSpell || !aiSpell) continue; // Targets and Effects checked first as most used restrictions - //Check the spell targets if specified + // Check the spell targets if specified if (targets && !(aiSpell->Targets & (1 << (targets-1)))) continue; - //Check the type of spell if we are looking for a specific spell type + // Check the type of spell if we are looking for a specific spell type if (effect && !(aiSpell->Effects & (1 << (effect-1)))) continue; - //Check for school if specified + // Check for school if specified if (school && (tempSpell->SchoolMask & school) == 0) continue; - //Check for spell mechanic if specified + // Check for spell mechanic if specified if (mechanic && tempSpell->Mechanic != mechanic) continue; - //Check if the spell meets our range requirements + // Continue if we don't have the mana to actually cast this spell + bool hasPower = true; + for (SpellPowerCost const& cost : tempSpell->CalcPowerCost(me, tempSpell->GetSchoolMask())) + { + if (cost.Amount > me->GetPower(cost.Power)) + { + hasPower = false; + break; + } + } + + if (!hasPower) + continue; + + // Check if the spell meets our range requirements if (rangeMin && me->GetSpellMinRangeForTarget(target, tempSpell) < rangeMin) continue; if (rangeMax && me->GetSpellMaxRangeForTarget(target, tempSpell) > rangeMax) continue; - //Check if our target is in range + // Check if our target is in range if (me->IsWithinDistInMap(target, float(me->GetSpellMinRangeForTarget(target, tempSpell))) || !me->IsWithinDistInMap(target, float(me->GetSpellMaxRangeForTarget(target, tempSpell)))) continue; - //All good so lets add it to the spell list + // All good so lets add it to the spell list apSpell[spellCount] = tempSpell; ++spellCount; } - //We got our usable spells so now lets randomly pick one + // We got our usable spells so now lets randomly pick one if (!spellCount) return nullptr; @@ -341,7 +353,7 @@ void ScriptedAI::DoTeleportPlayer(Unit* unit, float x, float y, float z, float o if (Player* player = unit->ToPlayer()) player->TeleportTo(unit->GetMapId(), x, y, z, o, TELE_TO_NOT_LEAVE_COMBAT); else - TC_LOG_ERROR("scripts", "Creature %s Tried to teleport non-player unit (%s) to x: %f y:%f z: %f o: %f. Aborted.", + TC_LOG_ERROR("scripts.ai", "ScriptedAI::DoTeleportPlayer: Creature %s Tried to teleport non-player unit (%s) to x: %f y:%f z: %f o: %f. Aborted.", me->GetGUID().ToString().c_str(), unit->GetGUID().ToString().c_str(), x, y, z, o); } @@ -432,19 +444,8 @@ void ScriptedAI::SetCombatMovement(bool allowMovement) _isCombatMovementAllowed = allowMovement; } -enum NPCs -{ - NPC_BROODLORD = 12017, - NPC_VOID_REAVER = 19516, - NPC_JAN_ALAI = 23578, - NPC_SARTHARION = 28860 -}; - // BossAI - for instanced bosses -BossAI::BossAI(Creature* creature, uint32 bossId) : ScriptedAI(creature), - instance(creature->GetInstanceScript()), - summons(creature), - _bossId(bossId) +BossAI::BossAI(Creature* creature, uint32 bossId) : ScriptedAI(creature), instance(creature->GetInstanceScript()), summons(creature), _bossId(bossId) { if (instance) SetBoundary(instance->GetBossBoundary(bossId)); @@ -555,7 +556,7 @@ void BossAI::_DespawnAtEvade(Seconds delayToRespawn /*= 30s*/, Creature* who /*= { if (delayToRespawn < Seconds(2)) { - TC_LOG_ERROR("scripts", "_DespawnAtEvade called with delay of " SI64FMTD " seconds, defaulting to 2.", delayToRespawn.count()); + TC_LOG_ERROR("scripts.ai", "BossAI::_DespawnAtEvade: called with delay of " SI64FMTD " seconds, defaulting to 2 (me: %s)", delayToRespawn.count(), me->GetGUID().ToString().c_str()); delayToRespawn = Seconds(2); } @@ -564,7 +565,7 @@ void BossAI::_DespawnAtEvade(Seconds delayToRespawn /*= 30s*/, Creature* who /*= if (TempSummon* whoSummon = who->ToTempSummon()) { - TC_LOG_WARN("scripts", "_DespawnAtEvade called on a temporary summon."); + TC_LOG_WARN("scripts.ai", "BossAI::_DespawnAtEvade: called on a temporary summon (who: %s)", who->GetGUID().ToString().c_str()); whoSummon->UnSummon(); return; } @@ -576,10 +577,7 @@ void BossAI::_DespawnAtEvade(Seconds delayToRespawn /*= 30s*/, Creature* who /*= } // WorldBossAI - for non-instanced bosses - -WorldBossAI::WorldBossAI(Creature* creature) : - ScriptedAI(creature), - summons(creature) { } +WorldBossAI::WorldBossAI(Creature* creature) : ScriptedAI(creature), summons(creature) { } void WorldBossAI::_Reset() { diff --git a/src/server/game/AI/ScriptedAI/ScriptedCreature.h b/src/server/game/AI/ScriptedAI/ScriptedCreature.h index f6f9f23a322..68980803da5 100644 --- a/src/server/game/AI/ScriptedAI/ScriptedCreature.h +++ b/src/server/game/AI/ScriptedAI/ScriptedCreature.h @@ -15,8 +15,8 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#ifndef SCRIPTEDCREATURE_H_ -#define SCRIPTEDCREATURE_H_ +#ifndef TRINITY_SCRIPTEDCREATURE_H +#define TRINITY_SCRIPTEDCREATURE_H #include "CreatureAI.h" #include "Creature.h" // convenience include for scripts, all uses of ScriptedCreature also need Creature (except ScriptedCreature itself doesn't need Creature) @@ -136,45 +136,45 @@ struct TC_GAME_API ScriptedAI : public CreatureAI virtual ~ScriptedAI() { } // ************* - //CreatureAI Functions + // CreatureAI Functions // ************* void AttackStartNoMove(Unit* target); - //Called at World update tick + // Called at World update tick virtual void UpdateAI(uint32 diff) override; // ************* // Variables // ************* - //For fleeing + // For fleeing bool IsFleeing; // ************* - //Pure virtual functions + // Pure virtual functions // ************* // Called before JustEngagedWith even before the creature is in combat. void AttackStart(Unit* /*target*/) override; // ************* - //AI Helper Functions + // AI Helper Functions // ************* - //Start movement toward victim + // Start movement toward victim void DoStartMovement(Unit* target, float distance = 0.0f, float angle = 0.0f); - //Start no movement on victim + // Start no movement on victim void DoStartNoMovement(Unit* target); - //Stop attack of current victim + // Stop attack of current victim void DoStopAttack(); - //Cast spell by spell info + // Cast spell by spell info void DoCastSpell(Unit* target, SpellInfo const* spellInfo, bool triggered = false); - //Plays a sound to all nearby players + // Plays a sound to all nearby players void DoPlaySoundToSet(WorldObject* source, uint32 soundId); // Add specified amount of threat directly to victim (ignores redirection effects) - also puts victim in combat and engages them if necessary @@ -191,32 +191,32 @@ struct TC_GAME_API ScriptedAI : public CreatureAI void DoTeleportTo(float x, float y, float z, uint32 time = 0); void DoTeleportTo(float const pos[4]); - //Teleports a player without dropping threat (only teleports to same map) + // Teleports a player without dropping threat (only teleports to same map) void DoTeleportPlayer(Unit* unit, float x, float y, float z, float o); void DoTeleportAll(float x, float y, float z, float o); - //Returns friendly unit with the most amount of hp missing from max hp + // Returns friendly unit with the most amount of hp missing from max hp Unit* DoSelectLowestHpFriendly(float range, uint32 minHPDiff = 1); - //Returns friendly unit with hp pct below specified and with specified entry + // Returns friendly unit with hp pct below specified and with specified entry Unit* DoSelectBelowHpPctFriendlyWithEntry(uint32 entry, float range, uint8 hpPct = 1, bool excludeSelf = true); - //Returns a list of friendly CC'd units within range + // Returns a list of friendly CC'd units within range std::list<Creature*> DoFindFriendlyCC(float range); - //Returns a list of all friendly units missing a specific buff within range + // Returns a list of all friendly units missing a specific buff within range std::list<Creature*> DoFindFriendlyMissingBuff(float range, uint32 spellId); - //Return a player with at least minimumRange from me + // Return a player with at least minimumRange from me Player* GetPlayerAtMinimumRange(float minRange); - //Spawns a creature relative to me + // Spawns a creature relative to me Creature* DoSpawnCreature(uint32 entry, float offsetX, float offsetY, float offsetZ, float angle, uint32 type, uint32 despawntime); bool HealthBelowPct(uint32 pct) const; bool HealthAbovePct(uint32 pct) const; - //Returns spells that meet the specified criteria from the creatures spell list + // Returns spells that meet the specified criteria from the creatures spell list SpellInfo const* SelectSpell(Unit* target, uint32 school, uint32 mechanic, SelectTargetType targets, float rangeMin, float rangeMax, SelectEffect effect); void SetEquipmentSlots(bool loadDefault, int32 mainHand = EQUIP_NO_CHANGE, int32 offHand = EQUIP_NO_CHANGE, int32 ranged = EQUIP_NO_CHANGE); @@ -405,4 +405,4 @@ inline void GetPlayerListInGrid(Container& container, WorldObject* source, float source->GetPlayerListInGrid(container, maxSearchRange); } -#endif // SCRIPTEDCREATURE_H_ +#endif // TRINITY_SCRIPTEDCREATURE_H diff --git a/src/server/game/AI/ScriptedAI/ScriptedEscortAI.cpp b/src/server/game/AI/ScriptedAI/ScriptedEscortAI.cpp index da3fe4c0783..fdc8214f254 100644 --- a/src/server/game/AI/ScriptedAI/ScriptedEscortAI.cpp +++ b/src/server/game/AI/ScriptedAI/ScriptedEscortAI.cpp @@ -101,7 +101,7 @@ void EscortAI::EnterEvadeMode(EvadeReason /*why*/) { AddEscortState(STATE_ESCORT_RETURNING); ReturnToLastPoint(); - TC_LOG_DEBUG("scripts", "EscortAI::EnterEvadeMode: left combat and is now returning to last point"); + TC_LOG_DEBUG("scripts.ai.escortai", "EscortAI::EnterEvadeMode: left combat and is now returning to last point (%s)", me->GetGUID().ToString().c_str()); } else { @@ -126,22 +126,22 @@ void EscortAI::MovementInform(uint32 type, uint32 id) // continue waypoint movement if (id == POINT_LAST_POINT) { - TC_LOG_DEBUG("scripts", "EscortAI::MovementInform: returned to before combat position"); + TC_LOG_DEBUG("scripts.ai.escortai", "EscortAI::MovementInform: returned to before combat position (%s)", me->GetGUID().ToString().c_str()); me->SetWalk(!_running); RemoveEscortState(STATE_ESCORT_RETURNING); } else if (id == POINT_HOME) { - TC_LOG_DEBUG("scripts", "EscortAI::MovementInform: returned to home location and restarting waypoint path"); + TC_LOG_DEBUG("scripts.ai.escortai", "EscortAI::MovementInform: returned to home location and restarting waypoint path (%s)", me->GetGUID().ToString().c_str()); _started = false; } } else if (type == WAYPOINT_MOTION_TYPE) { - ASSERT(id < _path.nodes.size(), "EscortAI::MovementInform: referenced movement id (%u) points to non-existing node in loaded path", id); + ASSERT(id < _path.nodes.size(), "EscortAI::MovementInform: referenced movement id (%u) points to non-existing node in loaded path (%s)", id, me->GetGUID().ToString().c_str()); WaypointNode waypoint = _path.nodes[id]; - TC_LOG_DEBUG("scripts", "EscortAI::MovementInform: waypoint node %u reached", waypoint.id); + TC_LOG_DEBUG("scripts.ai.escortai", "EscortAI::MovementInform: waypoint node %u reached (%s)", waypoint.id, me->GetGUID().ToString().c_str()); // last point if (id == _path.nodes.size() - 1) @@ -171,7 +171,7 @@ void EscortAI::UpdateAI(uint32 diff) if (_despawnAtEnd) { - TC_LOG_DEBUG("scripts", "EscortAI::UpdateAI: reached end of waypoints, despawning at end"); + TC_LOG_DEBUG("scripts.ai.escortai", "EscortAI::UpdateAI: reached end of waypoints, despawning at end (%s)", me->GetGUID().ToString().c_str()); if (_returnToStart) { Position respawnPosition; @@ -179,14 +179,14 @@ void EscortAI::UpdateAI(uint32 diff) me->GetRespawnPosition(respawnPosition.m_positionX, respawnPosition.m_positionY, respawnPosition.m_positionZ, &orientation); respawnPosition.SetOrientation(orientation); me->GetMotionMaster()->MovePoint(POINT_HOME, respawnPosition); - TC_LOG_DEBUG("scripts", "EscortAI::UpdateAI: returning to spawn location: %s", respawnPosition.ToString().c_str()); + TC_LOG_DEBUG("scripts.ai.escortai", "EscortAI::UpdateAI: returning to spawn location: %s (%s)", respawnPosition.ToString().c_str(), me->GetGUID().ToString().c_str()); } else if (_instantRespawn) me->Respawn(true); else me->DespawnOrUnsummon(); } - TC_LOG_DEBUG("scripts", "EscortAI::UpdateAI: reached end of waypoints"); + TC_LOG_DEBUG("scripts.ai.escortai", "EscortAI::UpdateAI: reached end of waypoints (%s)", me->GetGUID().ToString().c_str()); RemoveEscortState(STATE_ESCORT_ESCORTING); return; } @@ -215,7 +215,7 @@ void EscortAI::UpdateAI(uint32 diff) { if (!IsPlayerOrGroupInRange()) { - TC_LOG_DEBUG("scripts", "EscortAI::UpdateAI: failed because player/group was to far away or not found"); + TC_LOG_DEBUG("scripts.ai.escortai", "EscortAI::UpdateAI: failed because player/group was to far away or not found (%s)", me->GetGUID().ToString().c_str()); bool isEscort = false; if (CreatureData const* creatureData = me->GetCreatureData()) @@ -290,15 +290,15 @@ void EscortAI::Start(bool isActiveAttacker /* = true*/, bool run /* = false */, } } - if (me->GetVictim()) + if (me->IsEngaged()) { - TC_LOG_ERROR("scripts", "EscortAI::Start: (script: %s, creature entry: %u) attempts to Start while in combat", me->GetScriptName().c_str(), me->GetEntry()); + TC_LOG_ERROR("scripts.ai.escortai", "EscortAI::Start: (script: %s) attempts to Start while in combat (%s)", me->GetScriptName().c_str(), me->GetGUID().ToString().c_str()); return; } if (HasEscortState(STATE_ESCORT_ESCORTING)) { - TC_LOG_ERROR("scripts", "EscortAI::Start: (script: %s, creature entry: %u) attempts to Start while already escorting", me->GetScriptName().c_str(), me->GetEntry()); + TC_LOG_ERROR("scripts.ai.escortai", "EscortAI::Start: (script: %s) attempts to Start while already escorting (%s)", me->GetScriptName().c_str(), me->GetGUID().ToString().c_str()); return; } @@ -309,7 +309,7 @@ void EscortAI::Start(bool isActiveAttacker /* = true*/, bool run /* = false */, if (_path.nodes.empty()) { - TC_LOG_ERROR("scripts", "EscortAI::Start: (script: %s, creature entry: %u) starts with 0 waypoints (possible missing entry in script_waypoint. Quest: %u).", me->GetScriptName().c_str(), me->GetEntry(), quest ? quest->GetQuestId() : 0); + TC_LOG_ERROR("scripts.ai.escortai", "EscortAI::Start: (script: %s) is set to return home after waypoint end and instant respawn at waypoint end. Creature will never despawn (%s)", me->GetScriptName().c_str(), me->GetGUID().ToString().c_str()); return; } @@ -321,7 +321,7 @@ void EscortAI::Start(bool isActiveAttacker /* = true*/, bool run /* = false */, _returnToStart = canLoopPath; if (_returnToStart && _instantRespawn) - TC_LOG_DEBUG("scripts", "EscortAI::Start: (script: %s, creature entry: %u) is set to return home after waypoint end and instant respawn at waypoint end. Creature will never despawn.", me->GetScriptName().c_str(), me->GetEntry()); + TC_LOG_ERROR("scripts.ai.escortai", "EscortAI::Start: (script: %s) is set to return home after waypoint end and instant respawn at waypoint end. Creature will never despawn (%s)", me->GetScriptName().c_str(), me->GetGUID().ToString().c_str()); me->GetMotionMaster()->MoveIdle(); me->GetMotionMaster()->Clear(MOTION_PRIORITY_NORMAL); @@ -335,7 +335,8 @@ void EscortAI::Start(bool isActiveAttacker /* = true*/, bool run /* = false */, me->SetImmuneToNPC(false); } - TC_LOG_DEBUG("scripts", "EscortAI::Start: (script: %s, creature entry: %u) started with %u waypoints. ActiveAttacker = %d, Run = %d, Player = %s", me->GetScriptName().c_str(), me->GetEntry(), uint32(_path.nodes.size()), _activeAttacker, _running, _playerGUID.ToString().c_str()); + TC_LOG_DEBUG("scripts.ai.escortai", "EscortAI::Start: (script: %s) started with %u waypoints. ActiveAttacker = %d, Run = %d, Player = %s (%s)", + me->GetScriptName().c_str(), uint32(_path.nodes.size()), _activeAttacker, _running, _playerGUID.ToString().c_str(), me->GetGUID().ToString().c_str()); // set initial speed me->SetWalk(!_running); diff --git a/src/server/game/AI/ScriptedAI/ScriptedEscortAI.h b/src/server/game/AI/ScriptedAI/ScriptedEscortAI.h index 69bd4b5f6f3..903f81cc8d3 100644 --- a/src/server/game/AI/ScriptedAI/ScriptedEscortAI.h +++ b/src/server/game/AI/ScriptedAI/ScriptedEscortAI.h @@ -15,8 +15,8 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#ifndef SC_ESCORTAI_H -#define SC_ESCORTAI_H +#ifndef TRINITY_SCRIPTEDESCORTAI_H +#define TRINITY_SCRIPTEDESCORTAI_H #include "ScriptedCreature.h" #include "WaypointDefines.h" @@ -98,4 +98,5 @@ struct TC_GAME_API EscortAI : public ScriptedAI bool _ended; bool _resume; }; + #endif diff --git a/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.cpp b/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.cpp index 156daa0aed9..9e36c07ffa4 100644 --- a/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.cpp +++ b/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.cpp @@ -15,13 +15,6 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -/* ScriptData -SDName: FollowerAI -SD%Complete: 50 -SDComment: This AI is under development -SDCategory: Npc -EndScriptData */ - #include "ScriptedFollowerAI.h" #include "Creature.h" #include "Group.h" @@ -31,18 +24,14 @@ EndScriptData */ #include "ObjectAccessor.h" #include "Player.h" -const float MAX_PLAYER_DISTANCE = 100.0f; +float constexpr MAX_PLAYER_DISTANCE = 100.0f; enum Points { - POINT_COMBAT_START = 0xFFFFFF + POINT_COMBAT_START = 0xFFFFFF }; -FollowerAI::FollowerAI(Creature* creature) : ScriptedAI(creature), - _updateFollowTimer(2500), - _followState(STATE_FOLLOW_NONE), - _questForFollow(nullptr) -{ } +FollowerAI::FollowerAI(Creature* creature) : ScriptedAI(creature), _updateFollowTimer(2500), _followState(STATE_FOLLOW_NONE), _questForFollow(nullptr) { } void FollowerAI::AttackStart(Unit* who) { @@ -61,27 +50,27 @@ void FollowerAI::AttackStart(Unit* who) } } -//This part provides assistance to a player that are attacked by who, even if out of normal aggro range -//It will cause me to attack who that are attacking _any_ player (which has been confirmed may happen also on offi) -//The flag (type_flag) is unconfirmed, but used here for further research and is a good candidate. +// This part provides assistance to a player that are attacked by who, even if out of normal aggro range +// It will cause me to attack who that are attacking _any_ player (which has been confirmed may happen also on offi) +// The flag (type_flag) is unconfirmed, but used here for further research and is a good candidate. bool FollowerAI::AssistPlayerInCombatAgainst(Unit* who) { if (!who || !who->GetVictim()) return false; - //experimental (unknown) flag not present + // experimental (unknown) flag not present if (!(me->GetCreatureTemplate()->type_flags & CREATURE_TYPE_FLAG_CAN_ASSIST)) return false; - //not a player + // not a player if (!who->EnsureVictim()->GetCharmerOrOwnerPlayerOrPlayerItself()) return false; - //never attack friendly + // never attack friendly if (me->IsFriendlyTo(who)) return false; - //too far away and no free sight? + // too far away and no free sight? if (me->IsWithinDistInMap(who, MAX_PLAYER_DISTANCE) && me->IsWithinLOSInMap(who)) { me->EngageWithTarget(who); @@ -166,14 +155,10 @@ void FollowerAI::EnterEvadeMode(EvadeReason /*why*/) if (HasFollowState(STATE_FOLLOW_INPROGRESS)) { - TC_LOG_DEBUG("scripts", "FollowerAI left combat, returning to CombatStartPosition."); + TC_LOG_DEBUG("scripts.ai.followerai", "FollowerAI::EnterEvadeMode: left combat, returning to CombatStartPosition. (%s)", me->GetGUID().ToString().c_str()); if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() == CHASE_MOTION_TYPE) - { - float fPosX, fPosY, fPosZ; - me->GetPosition(fPosX, fPosY, fPosZ); - me->GetMotionMaster()->MovePoint(POINT_COMBAT_START, fPosX, fPosY, fPosZ); - } + me->GetMotionMaster()->MovePoint(POINT_COMBAT_START, me->GetPosition()); } else { @@ -186,24 +171,24 @@ void FollowerAI::EnterEvadeMode(EvadeReason /*why*/) void FollowerAI::UpdateAI(uint32 uiDiff) { - if (HasFollowState(STATE_FOLLOW_INPROGRESS) && !me->GetVictim()) + if (HasFollowState(STATE_FOLLOW_INPROGRESS) && !me->IsEngaged()) { if (_updateFollowTimer <= uiDiff) { if (HasFollowState(STATE_FOLLOW_COMPLETE) && !HasFollowState(STATE_FOLLOW_POSTEVENT)) { - TC_LOG_DEBUG("scripts", "FollowerAI is set completed, despawns."); + TC_LOG_DEBUG("scripts.ai.followerai", "FollowerAI::UpdateAI: is set completed, despawns. (%s)", me->GetGUID().ToString().c_str()); me->DespawnOrUnsummon(); return; } - bool bIsMaxRangeExceeded = true; + bool maxRangeExceeded = true; if (Player* player = GetLeaderForFollower()) { if (HasFollowState(STATE_FOLLOW_RETURNING)) { - TC_LOG_DEBUG("scripts", "FollowerAI is returning to leader."); + TC_LOG_DEBUG("scripts.ai.followerai", "FollowerAI::UpdateAI: is returning to leader. (%s)", me->GetGUID().ToString().c_str()); RemoveFollowState(STATE_FOLLOW_RETURNING); me->GetMotionMaster()->MoveFollow(player, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE); @@ -217,7 +202,7 @@ void FollowerAI::UpdateAI(uint32 uiDiff) Player* member = groupRef->GetSource(); if (member && me->IsWithinDistInMap(member, MAX_PLAYER_DISTANCE)) { - bIsMaxRangeExceeded = false; + maxRangeExceeded = false; break; } } @@ -225,13 +210,13 @@ void FollowerAI::UpdateAI(uint32 uiDiff) else { if (me->IsWithinDistInMap(player, MAX_PLAYER_DISTANCE)) - bIsMaxRangeExceeded = false; + maxRangeExceeded = false; } } - if (bIsMaxRangeExceeded) + if (maxRangeExceeded) { - TC_LOG_DEBUG("scripts", "FollowerAI failed because player/group was to far away or not found"); + TC_LOG_DEBUG("scripts.ai.followerai", "FollowerAI::UpdateAI: failed because player/group was to far away or not found (%s)", me->GetGUID().ToString().c_str()); me->DespawnOrUnsummon(); return; } @@ -253,12 +238,12 @@ void FollowerAI::UpdateFollowerAI(uint32 /*uiDiff*/) DoMeleeAttackIfReady(); } -void FollowerAI::MovementInform(uint32 motionType, uint32 pointId) +void FollowerAI::MovementInform(uint32 type, uint32 id) { - if (motionType != POINT_MOTION_TYPE || !HasFollowState(STATE_FOLLOW_INPROGRESS)) + if (type != POINT_MOTION_TYPE || !HasFollowState(STATE_FOLLOW_INPROGRESS)) return; - if (pointId == POINT_COMBAT_START) + if (id == POINT_COMBAT_START) { if (GetLeaderForFollower()) { @@ -272,19 +257,19 @@ void FollowerAI::MovementInform(uint32 motionType, uint32 pointId) void FollowerAI::StartFollow(Player* player, uint32 factionForFollower, Quest const* quest) { - if (me->GetVictim()) + if (me->IsEngaged()) { - TC_LOG_DEBUG("scripts", "FollowerAI attempt to StartFollow while in combat."); + TC_LOG_DEBUG("scripts.ai.followerai", "FollowerAI::StartFollow: attempt to StartFollow while in combat. (%s)", me->GetGUID().ToString().c_str()); return; } if (HasFollowState(STATE_FOLLOW_INPROGRESS)) { - TC_LOG_ERROR("scripts", "FollowerAI attempt to StartFollow while already following."); + TC_LOG_ERROR("scripts.ai.followerai", "FollowerAI::StartFollow: attempt to StartFollow while already following. (%s)", me->GetGUID().ToString().c_str()); return; } - //set variables + // set variables _leaderGUID = player->GetGUID(); if (factionForFollower) @@ -296,7 +281,6 @@ void FollowerAI::StartFollow(Player* player, uint32 factionForFollower, Quest co { me->GetMotionMaster()->Clear(); me->GetMotionMaster()->MoveIdle(); - TC_LOG_DEBUG("scripts", "FollowerAI start with WAYPOINT_MOTION_TYPE, set to MoveIdle."); } me->SetNpcFlags(UNIT_NPC_FLAG_NONE); @@ -306,7 +290,7 @@ void FollowerAI::StartFollow(Player* player, uint32 factionForFollower, Quest co me->GetMotionMaster()->MoveFollow(player, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE); - TC_LOG_DEBUG("scripts", "FollowerAI start follow %s (%s)", player->GetName().c_str(), _leaderGUID.ToString().c_str()); + TC_LOG_DEBUG("scripts.ai.followerai", "FollowerAI::StartFollow: start follow %s - %s (%s)", player->GetName().c_str(), _leaderGUID.ToString().c_str(), me->GetGUID().ToString().c_str()); } Player* FollowerAI::GetLeaderForFollower() @@ -324,7 +308,7 @@ Player* FollowerAI::GetLeaderForFollower() Player* member = groupRef->GetSource(); if (member && me->IsWithinDistInMap(member, MAX_PLAYER_DISTANCE) && member->IsAlive()) { - TC_LOG_DEBUG("scripts", "FollowerAI GetLeader changed and returned new leader."); + TC_LOG_DEBUG("scripts.ai.followerai", "FollowerAI::GetLeaderForFollower: GetLeader changed and returned new leader. (%s)", me->GetGUID().ToString().c_str()); _leaderGUID = member->GetGUID(); return member; } @@ -333,11 +317,11 @@ Player* FollowerAI::GetLeaderForFollower() } } - TC_LOG_DEBUG("scripts", "FollowerAI GetLeader can not find suitable leader."); + TC_LOG_DEBUG("scripts.ai.followerai", "FollowerAI::GetLeaderForFollower: GetLeader can not find suitable leader. (%s)", me->GetGUID().ToString().c_str()); return nullptr; } -void FollowerAI::SetFollowComplete(bool bWithEndEvent) +void FollowerAI::SetFollowComplete(bool withEndEvent) { if (me->HasUnitState(UNIT_STATE_FOLLOW)) { @@ -348,7 +332,7 @@ void FollowerAI::SetFollowComplete(bool bWithEndEvent) me->GetMotionMaster()->MoveIdle(); } - if (bWithEndEvent) + if (withEndEvent) AddFollowState(STATE_FOLLOW_POSTEVENT); else { diff --git a/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.h b/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.h index f0f8fbb26a1..775e67988f3 100644 --- a/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.h +++ b/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.h @@ -15,23 +15,22 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#ifndef SC_FOLLOWERAI_H -#define SC_FOLLOWERAI_H +#ifndef TRINITY_SCRIPTEDFOLLOWERAI_H +#define TRINITY_SCRIPTEDFOLLOWERAI_H #include "ScriptedCreature.h" -#include "ScriptSystem.h" class Quest; -enum eFollowState +enum FollowerState : uint32 { STATE_FOLLOW_NONE = 0x000, - STATE_FOLLOW_INPROGRESS = 0x001, //must always have this state for any follow - STATE_FOLLOW_RETURNING = 0x002, //when returning to combat start after being in combat - STATE_FOLLOW_PAUSED = 0x004, //disables following - STATE_FOLLOW_COMPLETE = 0x008, //follow is completed and may end - STATE_FOLLOW_PREEVENT = 0x010, //not implemented (allow pre event to run, before follow is initiated) - STATE_FOLLOW_POSTEVENT = 0x020 //can be set at complete and allow post event to run + STATE_FOLLOW_INPROGRESS = 0x001, // must always have this state for any follow + STATE_FOLLOW_RETURNING = 0x002, // when returning to combat start after being in combat + STATE_FOLLOW_PAUSED = 0x004, // disables following + STATE_FOLLOW_COMPLETE = 0x008, // follow is completed and may end + STATE_FOLLOW_PREEVENT = 0x010, // not implemented (allow pre event to run, before follow is initiated) + STATE_FOLLOW_POSTEVENT = 0x020 // can be set at complete and allow post event to run }; class TC_GAME_API FollowerAI : public ScriptedAI @@ -40,25 +39,22 @@ class TC_GAME_API FollowerAI : public ScriptedAI explicit FollowerAI(Creature* creature); ~FollowerAI() { } - void MovementInform(uint32 motionType, uint32 pointId) override; - + void MovementInform(uint32 type, uint32 id) override; void AttackStart(Unit*) override; - void MoveInLineOfSight(Unit*) override; - void EnterEvadeMode(EvadeReason /*why*/ = EVADE_REASON_OTHER) override; - void JustDied(Unit*) override; - void JustAppeared() override; + // the "internal" update, calls UpdateFollowerAI() + void UpdateAI(uint32) override; - void UpdateAI(uint32) override; //the "internal" update, calls UpdateFollowerAI() - virtual void UpdateFollowerAI(uint32); //used when it's needed to add code in update (abilities, scripted events, etc) + // used when it's needed to add code in update (abilities, scripted events, etc) + virtual void UpdateFollowerAI(uint32); void StartFollow(Player* player, uint32 factionForFollower = 0, Quest const* quest = nullptr); - - void SetFollowPaused(bool bPaused); //if special event require follow mode to hold/resume during the follow - void SetFollowComplete(bool bWithEndEvent = false); + // if special event require follow mode to hold/resume during the follow + void SetFollowPaused(bool paused); + void SetFollowComplete(bool withEndEvent = false); bool HasFollowState(uint32 uiFollowState) { return (_followState & uiFollowState) != 0; } @@ -66,9 +62,8 @@ class TC_GAME_API FollowerAI : public ScriptedAI Player* GetLeaderForFollower(); private: - void AddFollowState(uint32 uiFollowState) { _followState |= uiFollowState; } - void RemoveFollowState(uint32 uiFollowState) { _followState &= ~uiFollowState; } - + void AddFollowState(uint32 followState) { _followState |= followState; } + void RemoveFollowState(uint32 followState) { _followState &= ~followState; } bool AssistPlayerInCombatAgainst(Unit* who); ObjectGuid _leaderGUID; diff --git a/src/server/game/AI/ScriptedAI/ScriptedGossip.h b/src/server/game/AI/ScriptedAI/ScriptedGossip.h index 5e82ef115e8..15d72787e76 100644 --- a/src/server/game/AI/ScriptedAI/ScriptedGossip.h +++ b/src/server/game/AI/ScriptedAI/ScriptedGossip.h @@ -15,8 +15,8 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#ifndef SC_GOSSIP_H -#define SC_GOSSIP_H +#ifndef TRINITY_SCRIPTEDGOSSIP_H +#define TRINITY_SCRIPTEDGOSSIP_H #include "Define.h" #include "GossipDef.h" |
