aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormaximius <none@none>2009-09-10 09:59:16 -0700
committermaximius <none@none>2009-09-10 09:59:16 -0700
commit5633ea57d11e23d8609994bd2ee9cdf7e36ed5e7 (patch)
tree7518b778737a45d768b1f67edaef5bffcbb105c2
parent580b3f8805bf307fe057ea852aa469fe9f5e4848 (diff)
*MrSmite's PetAI patch, plus Hawthorne's Instant Flight Paths (now with actual code! >_<)
--HG-- branch : trunk
-rw-r--r--src/game/Pet.cpp12
-rw-r--r--src/game/PetAI.cpp232
-rw-r--r--src/game/PetAI.h13
-rw-r--r--src/game/PetHandler.cpp42
-rw-r--r--src/game/Player.cpp24
-rw-r--r--src/game/TargetedMovementGenerator.cpp21
-rw-r--r--src/game/TargetedMovementGenerator.h3
-rw-r--r--src/game/Unit.cpp63
-rw-r--r--src/game/Unit.h22
-rw-r--r--src/game/World.cpp1
-rw-r--r--src/game/World.h1
11 files changed, 407 insertions, 27 deletions
diff --git a/src/game/Pet.cpp b/src/game/Pet.cpp
index e6dcf0ed19c..1578bd5badd 100644
--- a/src/game/Pet.cpp
+++ b/src/game/Pet.cpp
@@ -77,6 +77,18 @@ void Pet::AddToWorld()
Unit::AddToWorld();
AIM_Initialize();
}
+
+ // MrSmite 09-09-2009 PetAI_v1.1
+ // Prevent stuck pets when zoning. Pets default to "follow" when added to world
+ // so we'll reset flags and let the AI handle things
+ if (this->GetCharmInfo() && this->GetCharmInfo()->HasCommandState(COMMAND_FOLLOW))
+ {
+ this->GetCharmInfo()->SetIsCommandAttack(false);
+ this->GetCharmInfo()->SetIsAtStay(false);
+ this->GetCharmInfo()->SetIsFollowing(false);
+ this->GetCharmInfo()->SetIsReturning(false);
+ }
+
}
void Pet::RemoveFromWorld()
diff --git a/src/game/PetAI.cpp b/src/game/PetAI.cpp
index 0fcc707b104..db7270bf553 100644
--- a/src/game/PetAI.cpp
+++ b/src/game/PetAI.cpp
@@ -70,19 +70,10 @@ void PetAI::_stopAttack()
return;
}
- Unit* owner = m_creature->GetCharmerOrOwner();
-
- if(owner && m_creature->GetCharmInfo() && m_creature->GetCharmInfo()->HasCommandState(COMMAND_FOLLOW))
- {
- m_creature->GetMotionMaster()->MoveFollow(owner,PET_FOLLOW_DIST, m_creature->GetFollowAngle());
- }
- else
- {
- m_creature->clearUnitState(UNIT_STAT_FOLLOW);
- m_creature->GetMotionMaster()->Clear();
- m_creature->GetMotionMaster()->MoveIdle();
- }
+ // MrSmite 09-05-2009 PetAI_v1.0
m_creature->AttackStop();
+ me->GetCharmInfo()->SetIsCommandAttack(false);
+ HandleReturnMovement();
}
void PetAI::UpdateAI(const uint32 diff)
@@ -109,10 +100,14 @@ void PetAI::UpdateAI(const uint32 diff)
}
else if(owner && m_creature->GetCharmInfo()) //no victim
{
- if(owner->isInCombat() && !(m_creature->HasReactState(REACT_PASSIVE) || m_creature->GetCharmInfo()->HasCommandState(COMMAND_STAY)))
- AttackStart(owner->getAttackerForHelper());
- else if(m_creature->GetCharmInfo()->HasCommandState(COMMAND_FOLLOW) && !m_creature->hasUnitState(UNIT_STAT_FOLLOW))
- m_creature->GetMotionMaster()->MoveFollow(owner,PET_FOLLOW_DIST, m_creature->GetFollowAngle());
+ // MrSmite 05-09-2009 PetAI_v1.0
+
+ Unit *nextTarget = SelectNextTarget();
+
+ if (nextTarget)
+ AttackStart(nextTarget);
+ else
+ HandleReturnMovement();
}
else if (owner && !m_creature->hasUnitState(UNIT_STAT_FOLLOW)) // no charm info and no victim
m_creature->GetMotionMaster()->MoveFollow(owner,PET_FOLLOW_DIST, m_creature->GetFollowAngle());
@@ -170,7 +165,8 @@ void PetAI::UpdateAI(const uint32 diff)
Spell *spell = new Spell(m_creature, spellInfo, false, 0);
- if (inCombat && !m_creature->hasUnitState(UNIT_STAT_FOLLOW) && spell->CanAutoCast(m_creature->getVictim()))
+ // MrSmite 09-05-2009 PetAI_v1.0 - Fix to allow pets on STAY to autocast
+ if (inCombat && _CanAttack(me->getVictim()) && spell->CanAutoCast(me->getVictim()))
{
targetSpellStore.push_back(std::make_pair<Unit*, Spell*>(m_creature->getVictim(), spell));
continue;
@@ -270,3 +266,205 @@ void PetAI::UpdateAllies()
else //remove group
m_AllySet.insert(owner->GetGUID());
}
+
+void PetAI::KilledUnit(Unit *victim)
+{
+ // MrSmite 09-09-2009 PetAI_v1.2
+
+ // Called from Unit::Kill() in case where pet or owner kills something
+ // if owner killed this victim, pet may still be attacking something else
+ if (me->getVictim() && me->getVictim() != victim)
+ return;
+
+ // Clear target just in case. May help problem where health / focus / mana
+ // regen gets stuck. Also resets attack command.
+ _stopAttack();
+
+ Unit *nextTarget = SelectNextTarget();
+
+ if (nextTarget)
+ AttackStart(nextTarget);
+ else
+ HandleReturnMovement(); // Return
+}
+
+void PetAI::AttackStart(Unit *target)
+{
+ // MrSmite 09-05-2009 PetAI_v1.0
+ // Overrides Unit::AttackStart to correctly evaluate Pet states
+
+ // Check all pet states to decide if we can attack this target
+ if (!_CanAttack(target))
+ return;
+
+ // We can attack, should we chase or not?
+ if (me->GetCharmInfo()->HasCommandState(COMMAND_FOLLOW))
+ DoAttack(target,true); // FOLLOW, attack with chase
+ else
+ {
+ if (me->GetCharmInfo()->IsCommandAttack())
+ DoAttack(target,true); // STAY or FOLLOW, player clicked "attack" so attack with chase
+ else
+ DoAttack(target,false); // STAY, target in range, attack not clicked so attack without chase
+ }
+}
+
+Unit *PetAI::SelectNextTarget()
+{
+ // MrSmite 09-05-2009 PetAI_v1.0
+
+ // Provides next target selection after current target death
+
+ // Passive pets don't do next target selection
+ if (me->HasReactState(REACT_PASSIVE))
+ return NULL;
+
+ // Check pet's attackers first to prevent dragging mobs back
+ // to owner
+ if (me->getAttackerForHelper())
+ return me->getAttackerForHelper();
+
+ // Check owner's attackers if pet didn't have any
+ if (me->GetCharmerOrOwner()->getAttackerForHelper())
+ return me->GetCharmerOrOwner()->getAttackerForHelper();
+
+ // Default
+ return NULL;
+}
+
+void PetAI::HandleReturnMovement()
+{
+ // MrSmite 09-05-2009 PetAI_v1.0
+
+ // Handles moving the pet back to stay or owner
+
+ if (me->GetCharmInfo()->HasCommandState(COMMAND_STAY))
+ {
+ if (!me->GetCharmInfo()->IsAtStay() && !me->GetCharmInfo()->IsReturning())
+ {
+ // Return to previous position where stay was clicked
+ if (!me->GetCharmInfo()->IsCommandAttack())
+ {
+ float x,y,z;
+
+ me->GetCharmInfo()->GetStayPosition(x, y, z);
+ me->GetCharmInfo()->SetIsReturning(true);
+ me->GetMotionMaster()->Clear();
+ me->GetMotionMaster()->MovePoint(me->GetGUIDLow(),x,y,z);
+ }
+ }
+ }
+ else // COMMAND_FOLLOW
+ {
+ if (!me->GetCharmInfo()->IsFollowing() && !me->GetCharmInfo()->IsReturning())
+ {
+ if (!me->GetCharmInfo()->IsCommandAttack())
+ {
+ me->GetCharmInfo()->SetIsReturning(true);
+ me->GetMotionMaster()->Clear();
+ me->GetMotionMaster()->MoveFollow(me->GetCharmerOrOwner(), PET_FOLLOW_DIST, me->GetFollowAngle());
+ }
+ }
+ }
+
+}
+
+void PetAI::DoAttack(Unit *target, bool chase)
+{
+ // Handles attack with or without chase and also resets all
+ // PetAI flags for next update / creature kill
+
+ // me->GetCharmInfo()->SetIsCommandAttack(false);
+
+ // The following conditions are true if chase == true
+ // (Follow && (Aggressive || Defensive))
+ // ((Stay || Follow) && (Passive && player clicked attack))
+
+ if (chase)
+ {
+ if (me->Attack(target,true))
+ {
+ me->GetCharmInfo()->SetIsAtStay(false);
+ me->GetCharmInfo()->SetIsFollowing(false);
+ me->GetCharmInfo()->SetIsReturning(false);
+ me->GetMotionMaster()->Clear();
+ me->GetMotionMaster()->MoveChase(target);
+ }
+ }
+ else // (Stay && ((Aggressive || Defensive) && In Melee Range)))
+ {
+ me->GetCharmInfo()->SetIsAtStay(true);
+ me->GetCharmInfo()->SetIsFollowing(false);
+ me->GetCharmInfo()->SetIsReturning(false);
+ me->Attack(target,true);
+ }
+}
+
+void PetAI::MovementInform(uint32 moveType, uint32 data)
+{
+ // MrSmite 09-05-2009 PetAI_v1.0
+ // Receives notification when pet reaches stay or follow owner
+ switch (moveType)
+ {
+ case POINT_MOTION_TYPE:
+ {
+ // Pet is returning to where stay was clicked. data should be
+ // pet's GUIDLow since we set that as the waypoint ID
+ if (data == me->GetGUIDLow() && me->GetCharmInfo()->IsReturning())
+ {
+ me->GetCharmInfo()->SetIsAtStay(true);
+ me->GetCharmInfo()->SetIsReturning(false);
+ me->GetCharmInfo()->SetIsFollowing(false);
+ me->GetCharmInfo()->SetIsCommandAttack(false);
+ me->GetMotionMaster()->Clear();
+ me->GetMotionMaster()->MoveIdle();
+ }
+ }
+ break;
+
+ case TARGETED_MOTION_TYPE:
+ {
+ // If data is owner's GUIDLow then we've reached follow point,
+ // otherwise we're probably chasing a creature
+ if (data == me->GetCharmerOrOwner()->GetGUIDLow() && me->GetCharmInfo()->IsReturning())
+ {
+ me->GetCharmInfo()->SetIsAtStay(false);
+ me->GetCharmInfo()->SetIsReturning(false);
+ me->GetCharmInfo()->SetIsFollowing(true);
+ me->GetCharmInfo()->SetIsCommandAttack(false);
+ me->addUnitState(UNIT_STAT_FOLLOW);
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+bool PetAI::_CanAttack(Unit *target)
+{
+ // Evaluates wether a pet can attack a specific
+ // target based on CommandState, ReactState and other flags
+
+ // Returning - check first since pets returning ignore attacks
+ if (me->GetCharmInfo()->IsReturning())
+ return false;
+
+ // Passive - check now so we don't have to worry about passive in later checks
+ if (me->HasReactState(REACT_PASSIVE))
+ return me->GetCharmInfo()->IsCommandAttack();
+
+ // From this point on, pet will always be either aggressive or defensive
+
+ // Stay - can attack if target is within range or commanded to
+ if (me->GetCharmInfo()->HasCommandState(COMMAND_STAY))
+ return (me->IsWithinMeleeRange(target, MIN_MELEE_REACH) || me->GetCharmInfo()->IsCommandAttack());
+
+ // Follow
+ if (me->GetCharmInfo()->HasCommandState(COMMAND_FOLLOW))
+ return true;
+
+ // default, though we shouldn't ever get here
+ return false;
+} \ No newline at end of file
diff --git a/src/game/PetAI.h b/src/game/PetAI.h
index 918259cd098..b9059ad869e 100644
--- a/src/game/PetAI.h
+++ b/src/game/PetAI.h
@@ -34,11 +34,16 @@ class TRINITY_DLL_DECL PetAI : public CreatureAI
explicit PetAI(Creature *c);
void EnterEvadeMode();
- void JustDied(Unit* who) { _stopAttack(); }
+ void JustDied(Unit *who) { _stopAttack(); }
void UpdateAI(const uint32);
static int Permissible(const Creature *);
+ // MrSmite 09-05-2009 PetAI_v1.0
+ void KilledUnit(Unit *victim);
+ void AttackStart(Unit *target);
+ void MovementInform(uint32 moveType, uint32 data);
+
private:
bool _isVisible(Unit *) const;
bool _needToStop(void) const;
@@ -50,6 +55,12 @@ class TRINITY_DLL_DECL PetAI : public CreatureAI
bool inCombat;
std::set<uint64> m_AllySet;
uint32 m_updateAlliesTimer;
+
+ // MrSmite 09-05-2009 PetAI_v1.0
+ Unit *SelectNextTarget();
+ void HandleReturnMovement();
+ void DoAttack(Unit *target, bool chase);
+ bool _CanAttack(Unit *target);
};
#endif
diff --git a/src/game/PetHandler.cpp b/src/game/PetHandler.cpp
index 0975a072841..90a5a69d1b6 100644
--- a/src/game/PetHandler.cpp
+++ b/src/game/PetHandler.cpp
@@ -96,12 +96,23 @@ void WorldSession::HandlePetActionHelper(Unit *pet, uint64 guid1, uint16 spellid
pet->InterruptNonMeleeSpells(false);
pet->GetMotionMaster()->MoveIdle();
charmInfo->SetCommandState( COMMAND_STAY );
+ // MrSmite 09-05-2009 PetAI_v1.0
+ charmInfo->SetIsCommandAttack(false);
+ charmInfo->SetIsAtStay(true);
+ charmInfo->SetIsFollowing(false);
+ charmInfo->SetIsReturning(false);
+ charmInfo->SaveStayPosition();
break;
case COMMAND_FOLLOW: //spellid=1792 //FOLLOW
pet->AttackStop();
pet->InterruptNonMeleeSpells(false);
pet->GetMotionMaster()->MoveFollow(_player,PET_FOLLOW_DIST,pet->GetFollowAngle());
charmInfo->SetCommandState( COMMAND_FOLLOW );
+ // MrSmite 09-05-2009 PetAI_v1.0
+ charmInfo->SetIsCommandAttack(false);
+ charmInfo->SetIsAtStay(false);
+ charmInfo->SetIsReturning(true);
+ charmInfo->SetIsFollowing(false);
break;
case COMMAND_ATTACK: //spellid=1792 //ATTACK
{
@@ -139,6 +150,12 @@ void WorldSession::HandlePetActionHelper(Unit *pet, uint64 guid1, uint16 spellid
if(pet->GetTypeId() != TYPEID_PLAYER && ((Creature*)pet)->IsAIEnabled)
{
+ // MrSmite 09-05-2009 PetAI_v1.0
+ charmInfo->SetIsCommandAttack(true);
+ charmInfo->SetIsAtStay(false);
+ charmInfo->SetIsFollowing(false);
+ charmInfo->SetIsReturning(false);
+
((Creature*)pet)->AI()->AttackStart(TargetUnit);
//10% chance to play special pet attack talk, else growl
@@ -155,6 +172,12 @@ void WorldSession::HandlePetActionHelper(Unit *pet, uint64 guid1, uint16 spellid
if(pet->getVictim() && pet->getVictim() != TargetUnit)
pet->AttackStop();
+ // MrSmite 09-05-2009 PetAI_v1.0
+ charmInfo->SetIsCommandAttack(true);
+ charmInfo->SetIsAtStay(false);
+ charmInfo->SetIsFollowing(false);
+ charmInfo->SetIsReturning(false);
+
pet->Attack(TargetUnit,true);
pet->SendPetAIReaction(guid1);
}
@@ -189,6 +212,9 @@ void WorldSession::HandlePetActionHelper(Unit *pet, uint64 guid1, uint16 spellid
switch(spellid)
{
case REACT_PASSIVE: //passive
+ // MrSmite 09-05-2009 PetAI_v1.0
+ pet->AttackStop();
+
case REACT_DEFENSIVE: //recovery
case REACT_AGGRESSIVE: //activete
if(pet->GetTypeId() == TYPEID_UNIT)
@@ -225,7 +251,16 @@ void WorldSession::HandlePetActionHelper(Unit *pet, uint64 guid1, uint16 spellid
if(!pet->HasSpell(spellid) || IsPassiveSpell(spellid))
return;
- pet->clearUnitState(UNIT_STAT_FOLLOW);
+ // MrSmite 09-08-2009 PetAI_v1.1
+ // Clear the flags as if owner clicked 'attack'. AI will reset them
+ // after AttackStart, even if spell failed
+ if (pet->GetCharmInfo())
+ {
+ pet->GetCharmInfo()->SetIsAtStay(false);
+ pet->GetCharmInfo()->SetIsCommandAttack(true);
+ pet->GetCharmInfo()->SetIsReturning(false);
+ pet->GetCharmInfo()->SetIsFollowing(false);
+ }
Spell *spell = new Spell(pet, spellInfo, false);
@@ -294,6 +329,11 @@ void WorldSession::HandlePetActionHelper(Unit *pet, uint64 guid1, uint16 spellid
spell->finish(false);
delete spell;
+
+ // MrSmite 09-08-2009 PetAI_v1.1
+ // reset specific flags in case of spell fail. AI will reset other flags
+ if (pet->GetCharmInfo())
+ pet->GetCharmInfo()->SetIsCommandAttack(false);
}
break;
}
diff --git a/src/game/Player.cpp b/src/game/Player.cpp
index 928caebef6a..d25f27fff66 100644
--- a/src/game/Player.cpp
+++ b/src/game/Player.cpp
@@ -17962,14 +17962,22 @@ bool Player::ActivateTaxiPathTo(std::vector<uint32> const& nodes, Creature* npc
// prevent stealth flight
//RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_TALK);
- WorldPacket data(SMSG_ACTIVATETAXIREPLY, 4);
- data << uint32(ERR_TAXIOK);
- GetSession()->SendPacket(&data);
-
- sLog.outDebug("WORLD: Sent SMSG_ACTIVATETAXIREPLY");
-
- GetSession()->SendDoFlight(mount_display_id, sourcepath);
-
+ //Hawthorne - Instant Taxi Option
+ if ((bool)sWorld.getConfig(CONFIG_INSTANT_TAXI))
+ {
+ TaxiNodesEntry const* lastnode = sTaxiNodesStore.LookupEntry(nodes[nodes.size()-1]);
+ m_taxi.ClearTaxiDestinations();
+ TeleportTo(lastnode->map_id, lastnode->x, lastnode->y, lastnode->z, GetOrientation());
+ return false;
+ }
+ else
+ {
+ WorldPacket data(SMSG_ACTIVATETAXIREPLY, 4);
+ data << uint32(ERR_TAXIOK);
+ GetSession()->SendPacket(&data);
+ sLog.outDebug("WORLD: Sent SMSG_ACTIVATETAXIREPLY");
+ GetSession()->SendDoFlight(mount_display_id, sourcepath);
+ }
return true;
}
diff --git a/src/game/TargetedMovementGenerator.cpp b/src/game/TargetedMovementGenerator.cpp
index 46c18b1578f..061e875a91c 100644
--- a/src/game/TargetedMovementGenerator.cpp
+++ b/src/game/TargetedMovementGenerator.cpp
@@ -22,6 +22,7 @@
#include "TargetedMovementGenerator.h"
#include "Errors.h"
#include "Creature.h"
+#include "CreatureAI.h" // MrSmite 09-05-2009 PetAI_v1.0
#include "DestinationHolderImp.h"
#include "World.h"
@@ -236,6 +237,12 @@ TargetedMovementGenerator<T>::Update(T &owner, const uint32 & time_diff)
owner.Attack(i_target.getTarget(),true);
}
}
+
+ // MrSmite 09-05-2009 PetAI_v1.0
+ // Implemented for PetAI to handle resetting flags when pet owner reached
+ if (i_destinationHolder.HasArrived())
+ MovementInform(owner);
+
return true;
}
@@ -246,6 +253,20 @@ TargetedMovementGenerator<T>::GetTarget() const
return i_target.getTarget();
}
+template<class T>
+void TargetedMovementGenerator<T>::MovementInform(T &unit)
+{
+ // MrSmite 09-05-2009 PetAI_v1.0
+}
+
+template <> void TargetedMovementGenerator<Creature>::MovementInform(Creature &unit)
+{
+ // MrSmite 09-05-2009 PetAI_v1.0
+ // Pass back the GUIDLow of the target. If it is pet's owner then PetAI will handle
+ unit.AI()->MovementInform(TARGETED_MOTION_TYPE, i_target.getTarget()->GetGUIDLow());
+}
+
+template void TargetedMovementGenerator<Player>::MovementInform(Player&); // MrSmite 09-05-2009 PetAI_v1.0 - Not implemented for players
template TargetedMovementGenerator<Player>::TargetedMovementGenerator(Unit &target, float offset, float angle);
template TargetedMovementGenerator<Creature>::TargetedMovementGenerator(Unit &target, float offset, float angle);
template bool TargetedMovementGenerator<Player>::_setTargetLocation(Player &);
diff --git a/src/game/TargetedMovementGenerator.h b/src/game/TargetedMovementGenerator.h
index 1f886625f3a..a2b09c822c8 100644
--- a/src/game/TargetedMovementGenerator.h
+++ b/src/game/TargetedMovementGenerator.h
@@ -49,6 +49,9 @@ class TRINITY_DLL_SPEC TargetedMovementGenerator
bool Update(T &, const uint32 &);
MovementGeneratorType GetMovementGeneratorType() { return TARGETED_MOTION_TYPE; }
+ // MrSmite 09-05-2009 PetAI_v1.0
+ void MovementInform(T &);
+
Unit* GetTarget() const;
bool GetDestination(float &x, float &y, float &z) const
diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp
index e059c497084..1432898ae1d 100644
--- a/src/game/Unit.cpp
+++ b/src/game/Unit.cpp
@@ -12214,6 +12214,7 @@ CharmInfo::CharmInfo(Unit* unit)
m_oldReactState = ((Creature*)m_unit)->GetReactState();
((Creature*)m_unit)->SetReactState(REACT_PASSIVE);
}
+
}
CharmInfo::~CharmInfo()
@@ -13610,6 +13611,16 @@ void Unit::Kill(Unit *pVictim, bool durabilityLoss)
if (!pVictim->GetHealth())
return;
+ // MrSmite 09-09-2009 PetAI_v1.2
+ // Inform pets (if any) when player kills target)
+ if (this->GetTypeId() == TYPEID_PLAYER && ((Player*)this)->GetPet())
+ {
+ Pet *pPet = ((Player *)this)->GetPet();
+
+ if (pPet && pPet->isAlive() && pPet->isControlled())
+ pPet->AI()->KilledUnit(pVictim);
+ }
+
//sLog.outError("%u kill %u", GetEntry(), pVictim->GetEntry());
pVictim->SetHealth(0);
@@ -15022,3 +15033,55 @@ void Unit::OutDebugInfo() const
sLog.outString("On vehicle %u.", GetVehicleBase()->GetEntry());
}
+// MrSmite 09-05-2009 PetAI_v1.0
+void CharmInfo::SetIsCommandAttack(bool val)
+{
+ m_isCommandAttack = val;
+}
+
+bool CharmInfo::IsCommandAttack()
+{
+ return m_isCommandAttack;
+}
+
+void CharmInfo::SaveStayPosition()
+{
+ m_unit->GetPosition(m_stayX, m_stayY, m_stayZ);
+}
+
+void CharmInfo::GetStayPosition(float &x, float &y, float &z)
+{
+ x = m_stayX;
+ y = m_stayY;
+ z = m_stayZ;
+}
+
+void CharmInfo::SetIsAtStay(bool val)
+{
+ m_isAtStay = val;
+}
+
+bool CharmInfo::IsAtStay()
+{
+ return m_isAtStay;
+}
+
+void CharmInfo::SetIsFollowing(bool val)
+{
+ m_isFollowing = val;
+}
+
+bool CharmInfo::IsFollowing()
+{
+ return m_isFollowing;
+}
+
+void CharmInfo::SetIsReturning(bool val)
+{
+ m_isReturning = val;
+}
+
+bool CharmInfo::IsReturning()
+{
+ return m_isReturning;
+} \ No newline at end of file
diff --git a/src/game/Unit.h b/src/game/Unit.h
index 709eb50c850..bd1abcc20e5 100644
--- a/src/game/Unit.h
+++ b/src/game/Unit.h
@@ -1010,6 +1010,19 @@ struct CharmInfo
void ToggleCreatureAutocast(uint32 spellid, bool apply);
CharmSpellEntry* GetCharmSpell(uint8 index) { return &(m_charmspells[index]); }
+
+ // MrSmite 09-05-2009 PetAI_v1.0
+ void SetIsCommandAttack(bool val);
+ bool IsCommandAttack();
+ void SetIsAtStay(bool val);
+ bool IsAtStay();
+ void SetIsFollowing(bool val);
+ bool IsFollowing();
+ void SetIsReturning(bool val);
+ bool IsReturning();
+ void SaveStayPosition();
+ void GetStayPosition(float &x, float &y, float &z);
+
private:
Unit* m_unit;
@@ -1022,6 +1035,15 @@ struct CharmInfo
//for restoration after charmed
ReactStates m_oldReactState;
+
+ // MrSmite 09-05-2009 PetAI_v1.0
+ bool m_isCommandAttack;
+ bool m_isAtStay;
+ bool m_isFollowing;
+ bool m_isReturning;
+ float m_stayX;
+ float m_stayY;
+ float m_stayZ;
};
// for clearing special attacks
diff --git a/src/game/World.cpp b/src/game/World.cpp
index 6314f4212bc..a270680ae84 100644
--- a/src/game/World.cpp
+++ b/src/game/World.cpp
@@ -821,6 +821,7 @@ void World::LoadConfigSettings(bool reload)
}
m_configs[CONFIG_ALL_TAXI_PATHS] = sConfig.GetBoolDefault("AllFlightPaths", false);
+ m_configs[CONFIG_INSTANT_TAXI] = sConfig.GetBoolDefault("InstantFlightPaths", false);
m_configs[CONFIG_INSTANCE_IGNORE_LEVEL] = sConfig.GetBoolDefault("Instance.IgnoreLevel", false);
m_configs[CONFIG_INSTANCE_IGNORE_RAID] = sConfig.GetBoolDefault("Instance.IgnoreRaid", false);
diff --git a/src/game/World.h b/src/game/World.h
index 823d172d7f4..34de2ef0f2e 100644
--- a/src/game/World.h
+++ b/src/game/World.h
@@ -206,6 +206,7 @@ enum WorldConfigs
CONFIG_INSTANT_LOGOUT,
CONFIG_DISABLE_BREATHING,
CONFIG_ALL_TAXI_PATHS,
+ CONFIG_INSTANT_TAXI,
CONFIG_DECLINED_NAMES_USED,
CONFIG_LISTEN_RANGE_SAY,
CONFIG_LISTEN_RANGE_TEXTEMOTE,