aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/bindings/scripts/include/sc_creature.cpp23
-rw-r--r--src/bindings/scripts/include/sc_creature.h3
-rw-r--r--src/game/BattleGround.cpp4
-rw-r--r--src/game/BattleGround.h2
-rw-r--r--src/game/Creature.cpp14
-rw-r--r--src/game/Creature.h4
-rw-r--r--src/game/CreatureAI.cpp25
-rw-r--r--src/game/CreatureAI.h3
-rw-r--r--src/game/GameObject.cpp10
-rw-r--r--src/game/GridNotifiersImpl.h18
-rw-r--r--src/game/Level1.cpp4
-rw-r--r--src/game/Level3.cpp11
-rw-r--r--src/game/Map.cpp42
-rw-r--r--src/game/Map.h14
-rw-r--r--src/game/MapManager.h14
-rw-r--r--src/game/MiscHandler.cpp8
-rw-r--r--src/game/NPCHandler.cpp11
-rw-r--r--src/game/NullCreatureAI.cpp25
-rw-r--r--src/game/NullCreatureAI.h12
-rw-r--r--src/game/Object.cpp5
-rw-r--r--src/game/Object.h1
-rw-r--r--src/game/OutdoorPvPMgr.cpp1
-rw-r--r--src/game/PetAI.cpp95
-rw-r--r--src/game/PetAI.h2
-rw-r--r--src/game/PetHandler.cpp4
-rw-r--r--src/game/Player.cpp71
-rw-r--r--src/game/Player.h4
-rw-r--r--src/game/PossessedAI.cpp102
-rw-r--r--src/game/PossessedAI.h28
-rw-r--r--src/game/SharedDefines.h2
-rw-r--r--src/game/Spell.cpp12
-rw-r--r--src/game/SpellAuras.cpp8
-rw-r--r--src/game/SpellEffects.cpp7
-rw-r--r--src/game/SpellMgr.cpp2
-rw-r--r--src/game/Unit.cpp31
-rw-r--r--src/game/Unit.h3
-rw-r--r--src/shared/revision_nr.h4
37 files changed, 256 insertions, 373 deletions
diff --git a/src/bindings/scripts/include/sc_creature.cpp b/src/bindings/scripts/include/sc_creature.cpp
index efb6ef36fa2..1f5dc77aa26 100644
--- a/src/bindings/scripts/include/sc_creature.cpp
+++ b/src/bindings/scripts/include/sc_creature.cpp
@@ -169,29 +169,6 @@ void ScriptedAI::DoStartNoMovement(Unit* victim)
m_creature->StopMoving();
}
-void ScriptedAI::DoMeleeAttackIfReady()
-{
- //Make sure our attack is ready before checking distance
- if (m_creature->isAttackReady())
- {
- //If we are within range melee the target
- if (m_creature->IsWithinMeleeRange(m_creature->getVictim()))
- {
- m_creature->AttackerStateUpdate(m_creature->getVictim());
- m_creature->resetAttackTimer();
- }
- }
- if (m_creature->haveOffhandWeapon() && m_creature->isAttackReady(OFF_ATTACK) && !m_creature->hasUnitState(UNIT_STAT_CASTING))
- {
- //If we are within range melee the target
- if (m_creature->IsWithinMeleeRange(m_creature->getVictim()))
- {
- m_creature->AttackerStateUpdate(m_creature->getVictim(), OFF_ATTACK);
- m_creature->resetAttackTimer(OFF_ATTACK);
- }
- }
-}
-
void ScriptedAI::DoStopAttack()
{
if (m_creature->getVictim() != NULL)
diff --git a/src/bindings/scripts/include/sc_creature.h b/src/bindings/scripts/include/sc_creature.h
index 03039fd709e..d6ea69bf457 100644
--- a/src/bindings/scripts/include/sc_creature.h
+++ b/src/bindings/scripts/include/sc_creature.h
@@ -113,9 +113,6 @@ struct TRINITY_DLL_DECL ScriptedAI : public CreatureAI
//Start no movement on victim
void DoStartNoMovement(Unit* victim);
- //Do melee swing of current victim if in rnage and ready and not casting
- void DoMeleeAttackIfReady();
-
//Stop attack of current victim
void DoStopAttack();
diff --git a/src/game/BattleGround.cpp b/src/game/BattleGround.cpp
index 39dc135cffd..e058589483f 100644
--- a/src/game/BattleGround.cpp
+++ b/src/game/BattleGround.cpp
@@ -1128,9 +1128,7 @@ void BattleGround::AddPlayer(Player *plr)
if(GetStatus() == STATUS_WAIT_JOIN) // not started yet
{
- if(GetStatus() == STATUS_IN_PROGRESS)
- plr->RemoveAurasDueToSpell(SPELL_ARENA_PREPARATION);
- else plr->CastSpell(plr, SPELL_ARENA_PREPARATION, true);
+ plr->CastSpell(plr, SPELL_ARENA_PREPARATION, true);
plr->SetHealth(plr->GetMaxHealth());
plr->SetPower(POWER_MANA, plr->GetMaxPower(POWER_MANA));
diff --git a/src/game/BattleGround.h b/src/game/BattleGround.h
index 7d11fc78944..5f483564c98 100644
--- a/src/game/BattleGround.h
+++ b/src/game/BattleGround.h
@@ -71,7 +71,7 @@ enum BattleGroundSpells
SPELL_SPIRIT_HEAL_CHANNEL = 22011, // Spirit Heal Channel
SPELL_SPIRIT_HEAL = 22012, // Spirit Heal
SPELL_RESURRECTION_VISUAL = 24171, // Resurrection Impact Visual
- SPELL_ARENA_PREPARATION = 32728, // use this one, 32727 has an invisibility aura which is wrong
+ SPELL_ARENA_PREPARATION = 32727, // use this one, 32728 not correct
SPELL_ALLIANCE_GOLD_FLAG = 32724,
SPELL_ALLIANCE_GREEN_FLAG = 32725,
SPELL_HORDE_GOLD_FLAG = 35774,
diff --git a/src/game/Creature.cpp b/src/game/Creature.cpp
index 71f53cdabb0..115906e94a3 100644
--- a/src/game/Creature.cpp
+++ b/src/game/Creature.cpp
@@ -45,7 +45,6 @@
#include "CellImpl.h"
#include "OutdoorPvPMgr.h"
#include "GameEventMgr.h"
-#include "PossessedAI.h"
#include "CreatureGroups.h"
// apply implementation of the singletons
#include "Policies/SingletonImp.h"
@@ -133,7 +132,7 @@ bool AssistDelayEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/)
}
Creature::Creature() :
-Unit(), i_AI(NULL),
+Unit(),
lootForPickPocketed(false), lootForBody(false), m_groupLootTimer(0), lootingGroupLeaderGUID(0),
m_lootMoney(0), m_lootRecipient(0),
m_deathTimer(0), m_respawnTime(0), m_respawnDelay(25), m_corpseDelay(60), m_respawnradius(0.0f),
@@ -414,7 +413,7 @@ void Creature::Update(uint32 diff)
setDeathState( JUST_ALIVED );
//Call AI respawn virtual function
- i_AI->JustRespawned();
+ AI()->JustRespawned();
uint16 poolid = poolhandler.IsPartOfAPool(GetGUIDLow(), GetTypeId());
if (poolid)
@@ -478,6 +477,9 @@ void Creature::Update(uint32 diff)
if(!isAlive())
break;
+ // if creature is charmed, switch to charmed AI
+ UpdateCharmAI();
+
if(!IsInEvadeMode() && IsAIEnabled)
{
// do not allow the AI to be changed during update
@@ -590,11 +592,9 @@ bool Creature::AIM_Initialize(CreatureAI* ai)
return false;
}
- CreatureAI * oldAI = i_AI;
- i_motionMaster.Initialize();
+ if(i_AI) delete i_AI;
i_AI = ai ? ai : FactorySelector::selectAI(this);
- if (oldAI)
- delete oldAI;
+ i_motionMaster.Initialize();
IsAIEnabled = true;
return true;
}
diff --git a/src/game/Creature.h b/src/game/Creature.h
index 8c448432cbe..7a2a9508216 100644
--- a/src/game/Creature.h
+++ b/src/game/Creature.h
@@ -416,8 +416,6 @@ typedef std::map<uint32,time_t> CreatureSpellCooldowns;
class TRINITY_DLL_SPEC Creature : public Unit
{
- CreatureAI *i_AI;
-
public:
explicit Creature();
@@ -484,7 +482,7 @@ class TRINITY_DLL_SPEC Creature : public Unit
bool AIM_Initialize(CreatureAI* ai = NULL);
void AI_SendMoveToPacket(float x, float y, float z, uint32 time, uint32 MovementFlags, uint8 type);
- CreatureAI* AI() { return i_AI; }
+ CreatureAI* AI() { return (CreatureAI*)i_AI; }
uint32 GetShieldBlockValue() const //dunno mob block value
{
diff --git a/src/game/CreatureAI.cpp b/src/game/CreatureAI.cpp
index 06b2d382d8f..0fa85a4d9e2 100644
--- a/src/game/CreatureAI.cpp
+++ b/src/game/CreatureAI.cpp
@@ -36,11 +36,34 @@ void UnitAI::AttackStart(Unit *victim)
}
}
+void UnitAI::DoMeleeAttackIfReady()
+{
+ //Make sure our attack is ready and we aren't currently casting before checking distance
+ if (me->isAttackReady() && !me->hasUnitState(UNIT_STAT_CASTING))
+ {
+ //If we are within range melee the target
+ if (me->IsWithinMeleeRange(me->getVictim()))
+ {
+ me->AttackerStateUpdate(me->getVictim());
+ me->resetAttackTimer();
+ }
+ }
+ if (me->haveOffhandWeapon() && me->isAttackReady(OFF_ATTACK) && !me->hasUnitState(UNIT_STAT_CASTING))
+ {
+ //If we are within range melee the target
+ if (me->IsWithinMeleeRange(me->getVictim()))
+ {
+ me->AttackerStateUpdate(me->getVictim(), OFF_ATTACK);
+ me->resetAttackTimer(OFF_ATTACK);
+ }
+ }
+}
+
//Enable PlayerAI when charmed
void PlayerAI::OnCharmed(bool apply) { me->IsAIEnabled = apply; }
//Disable CreatureAI when charmed
-void CreatureAI::OnCharmed(bool apply) { me->IsAIEnabled = !apply; }
+void CreatureAI::OnCharmed(bool apply) { /*me->IsAIEnabled = !apply;*/ }
void CreatureAI::MoveInLineOfSight(Unit *who)
{
diff --git a/src/game/CreatureAI.h b/src/game/CreatureAI.h
index 78d856416ff..a15ae59a0ad 100644
--- a/src/game/CreatureAI.h
+++ b/src/game/CreatureAI.h
@@ -81,6 +81,9 @@ class TRINITY_DLL_SPEC UnitAI
// Called when unit is charmed
virtual void OnCharmed(bool apply) = 0;
+
+ //Do melee swing of current victim if in rnage and ready and not casting
+ void DoMeleeAttackIfReady();
};
class TRINITY_DLL_SPEC PlayerAI : public UnitAI
diff --git a/src/game/GameObject.cpp b/src/game/GameObject.cpp
index f967bb50dfc..d0c27cdde34 100644
--- a/src/game/GameObject.cpp
+++ b/src/game/GameObject.cpp
@@ -498,14 +498,15 @@ void GameObject::getFishLoot(Loot *fishloot, Player* loot_owner)
{
fishloot->clear();
- uint32 subzone = GetAreaId();
+ uint32 zone, subzone;
+ GetZoneAndAreaId(zone,subzone);
// if subzone loot exist use it
if(LootTemplates_Fishing.HaveLootFor(subzone))
fishloot->FillLoot(subzone, LootTemplates_Fishing, loot_owner,true);
// else use zone loot
else
- fishloot->FillLoot(GetZoneId(), LootTemplates_Fishing, loot_owner,true);
+ fishloot->FillLoot(zone, LootTemplates_Fishing, loot_owner,true);
}
void GameObject::SaveToDB()
@@ -1078,11 +1079,12 @@ void GameObject::Use(Unit* user)
// 2) if skill == base_zone_skill => 5% chance
// 3) chance is linear dependence from (base_zone_skill-skill)
- uint32 subzone = GetAreaId();
+ uint32 zone, subzone;
+ GetZoneAndAreaId(zone,subzone);
int32 zone_skill = objmgr.GetFishingBaseSkillLevel( subzone );
if(!zone_skill)
- zone_skill = objmgr.GetFishingBaseSkillLevel( GetZoneId() );
+ zone_skill = objmgr.GetFishingBaseSkillLevel( zone );
//provide error, no fishable zone or area should be 0
if(!zone_skill)
diff --git a/src/game/GridNotifiersImpl.h b/src/game/GridNotifiersImpl.h
index 9bf0bbe6fb3..33e3563ae7e 100644
--- a/src/game/GridNotifiersImpl.h
+++ b/src/game/GridNotifiersImpl.h
@@ -175,7 +175,18 @@ inline void Trinity::DynamicObjectUpdater::VisitHelper(Unit* target)
if( target->GetTypeId()==TYPEID_PLAYER && target != i_check && (((Player*)target)->isGameMaster() || ((Player*)target)->GetVisibility()==VISIBILITY_OFF) )
return;
- if (i_check->GetTypeId()==TYPEID_PLAYER )
+ if (i_dynobject.IsAffecting(target))
+ return;
+
+ SpellEntry const *spellInfo = sSpellStore.LookupEntry(i_dynobject.GetSpellId());
+ uint32 eff_index = i_dynobject.GetEffIndex();
+ if(spellInfo->EffectImplicitTargetB[eff_index] == TARGET_UNIT_AREA_ALLY_CHANNEL
+ || spellInfo->EffectImplicitTargetB[eff_index] == TARGET_UNIT_AREA_ALLY_GROUND)
+ {
+ if(!i_check->IsFriendlyTo(target))
+ return;
+ }
+ else if( i_check->GetTypeId()==TYPEID_PLAYER )
{
if (i_check->IsFriendlyTo( target ))
return;
@@ -186,11 +197,6 @@ inline void Trinity::DynamicObjectUpdater::VisitHelper(Unit* target)
return;
}
- if (i_dynobject.IsAffecting(target))
- return;
-
- SpellEntry const *spellInfo = sSpellStore.LookupEntry(i_dynobject.GetSpellId());
- uint32 eff_index = i_dynobject.GetEffIndex();
// Check target immune to spell or aura
if (target->IsImmunedToSpell(spellInfo) || target->IsImmunedToSpellEffect(spellInfo, eff_index))
return;
diff --git a/src/game/Level1.cpp b/src/game/Level1.cpp
index 346547e0c4b..bcb2d5d2525 100644
--- a/src/game/Level1.cpp
+++ b/src/game/Level1.cpp
@@ -687,8 +687,8 @@ bool ChatHandler::HandleGPSCommand(const char* args)
CellPair cell_val = Trinity::ComputeCellPair(obj->GetPositionX(), obj->GetPositionY());
Cell cell(cell_val);
- uint32 zone_id = obj->GetZoneId();
- uint32 area_id = obj->GetAreaId();
+ uint32 zone_id, area_id;
+ obj->GetZoneAndAreaId(zone_id,area_id);
MapEntry const* mapEntry = sMapStore.LookupEntry(obj->GetMapId());
AreaTableEntry const* zoneEntry = GetAreaEntryByAreaID(zone_id);
diff --git a/src/game/Level3.cpp b/src/game/Level3.cpp
index 80d73d4dffe..bbf6f47d949 100644
--- a/src/game/Level3.cpp
+++ b/src/game/Level3.cpp
@@ -4092,7 +4092,7 @@ bool ChatHandler::HandleLinkGraveCommand(const char* args)
return false;
}
- if(objmgr.AddGraveYardLink(g_id,player->GetZoneId(),g_team))
+ if(objmgr.AddGraveYardLink(g_id,zoneId,g_team))
PSendSysMessage(LANG_COMMAND_GRAVEYARDLINKED, g_id,zoneId);
else
PSendSysMessage(LANG_COMMAND_GRAVEYARDALRLINKED, g_id,zoneId);
@@ -4116,6 +4116,7 @@ bool ChatHandler::HandleNearGraveCommand(const char* args)
return false;
Player* player = m_session->GetPlayer();
+ uint32 zone_id = player->GetZoneId();
WorldSafeLocsEntry const* graveyard = objmgr.GetClosestGraveYard(
player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(),player->GetMapId(),g_team);
@@ -4124,7 +4125,7 @@ bool ChatHandler::HandleNearGraveCommand(const char* args)
{
uint32 g_id = graveyard->ID;
- GraveYardData const* data = objmgr.FindGraveYardData(g_id,player->GetZoneId());
+ GraveYardData const* data = objmgr.FindGraveYardData(g_id,zone_id);
if (!data)
{
PSendSysMessage(LANG_COMMAND_GRAVEYARDERROR,g_id);
@@ -4143,7 +4144,7 @@ bool ChatHandler::HandleNearGraveCommand(const char* args)
else if(g_team == ALLIANCE)
team_name = GetTrinityString(LANG_COMMAND_GRAVEYARD_ALLIANCE);
- PSendSysMessage(LANG_COMMAND_GRAVEYARDNEAREST, g_id,team_name.c_str(),player->GetZoneId());
+ PSendSysMessage(LANG_COMMAND_GRAVEYARDNEAREST, g_id,team_name.c_str(),zone_id);
}
else
{
@@ -4157,9 +4158,9 @@ bool ChatHandler::HandleNearGraveCommand(const char* args)
team_name = GetTrinityString(LANG_COMMAND_GRAVEYARD_ALLIANCE);
if(g_team == ~uint32(0))
- PSendSysMessage(LANG_COMMAND_ZONENOGRAVEYARDS, player->GetZoneId());
+ PSendSysMessage(LANG_COMMAND_ZONENOGRAVEYARDS, zone_id);
else
- PSendSysMessage(LANG_COMMAND_ZONENOGRAFACTION, player->GetZoneId(),team_name.c_str());
+ PSendSysMessage(LANG_COMMAND_ZONENOGRAFACTION, zone_id,team_name.c_str());
}
return true;
diff --git a/src/game/Map.cpp b/src/game/Map.cpp
index ef9c6cdb5a7..6c7903fef10 100644
--- a/src/game/Map.cpp
+++ b/src/game/Map.cpp
@@ -679,6 +679,13 @@ void Map::Update(const uint32 &t_diff)
}
}
}
+
+ if(plr->m_seer != plr)
+ {
+ Trinity::PlayerVisibilityNotifier notifier(*plr);
+ VisitAll(plr->m_seer->GetPositionX(), plr->m_seer->GetPositionY(), World::GetMaxVisibleDistance(), notifier);
+ notifier.Notify();
+ }
}
// non-player active objects
@@ -728,28 +735,6 @@ void Map::Update(const uint32 &t_diff)
}
}
}
-
- // Update bindsight players
- if(obj->isType(TYPEMASK_UNIT))
- {
- if(!((Unit*)obj)->GetSharedVisionList().empty())
- for(SharedVisionList::const_iterator itr = ((Unit*)obj)->GetSharedVisionList().begin(); itr != ((Unit*)obj)->GetSharedVisionList().end(); ++itr)
- {
- Trinity::PlayerVisibilityNotifier notifier(**itr);
- VisitAll(obj->GetPositionX(), obj->GetPositionY(), World::GetMaxVisibleDistance(), notifier);
- notifier.Notify();
- }
- }
- else if(obj->GetTypeId() == TYPEID_DYNAMICOBJECT)
- {
- if(Unit *caster = ((DynamicObject*)obj)->GetCaster())
- if(caster->GetTypeId() == TYPEID_PLAYER && caster->GetUInt64Value(PLAYER_FARSIGHT) == obj->GetGUID())
- {
- Trinity::PlayerVisibilityNotifier notifier(*((Player*)caster));
- VisitAll(obj->GetPositionX(), obj->GetPositionY(), World::GetMaxVisibleDistance(), notifier);
- notifier.Notify();
- }
- }
}
}
@@ -1802,7 +1787,7 @@ float Map::GetWaterLevel(float x, float y ) const
return 0;
}
-uint32 Map::GetAreaId(uint16 areaflag,uint32 map_id)
+uint32 Map::GetAreaIdByAreaFlag(uint16 areaflag,uint32 map_id)
{
AreaTableEntry const *entry = GetAreaEntryByAreaFlagAndMap(areaflag,map_id);
@@ -1812,7 +1797,7 @@ uint32 Map::GetAreaId(uint16 areaflag,uint32 map_id)
return 0;
}
-uint32 Map::GetZoneId(uint16 areaflag,uint32 map_id)
+uint32 Map::GetZoneIdByAreaFlag(uint16 areaflag,uint32 map_id)
{
AreaTableEntry const *entry = GetAreaEntryByAreaFlagAndMap(areaflag,map_id);
@@ -1822,6 +1807,14 @@ uint32 Map::GetZoneId(uint16 areaflag,uint32 map_id)
return 0;
}
+void Map::GetZoneAndAreaIdByAreaFlag(uint32& zoneid, uint32& areaid, uint16 areaflag,uint32 map_id)
+{
+ AreaTableEntry const *entry = GetAreaEntryByAreaFlagAndMap(areaflag,map_id);
+
+ areaid = entry ? entry->ID : 0;
+ zoneid = entry ? (( entry->zone != 0 ) ? entry->zone : entry->ID) : 0;
+}
+
bool Map::IsInWater(float x, float y, float pZ) const
{
// Check surface in x, y point for liquid
@@ -2308,7 +2301,6 @@ bool InstanceMap::Add(Player *player)
// first player enters (no players yet)
SetResetSchedule(false);
- player->SendInitWorldStates();
sLog.outDetail("MAP: Player '%s' entered the instance '%u' of map '%s'", player->GetName(), GetInstanceId(), GetMapName());
// initialize unload state
m_unloadTimer = 0;
diff --git a/src/game/Map.h b/src/game/Map.h
index 3a2c4e8e2fd..d2fd3fcf1d5 100644
--- a/src/game/Map.h
+++ b/src/game/Map.h
@@ -320,17 +320,23 @@ class TRINITY_DLL_SPEC Map : public GridRefManager<NGridType>, public Trinity::O
float GetWaterLevel(float x, float y ) const;
bool IsUnderWater(float x, float y, float z) const;
- static uint32 GetAreaId(uint16 areaflag,uint32 map_id);
- static uint32 GetZoneId(uint16 areaflag,uint32 map_id);
+ static uint32 GetAreaIdByAreaFlag(uint16 areaflag,uint32 map_id);
+ static uint32 GetZoneIdByAreaFlag(uint16 areaflag,uint32 map_id);
+ static void GetZoneAndAreaIdByAreaFlag(uint32& zoneid, uint32& areaid, uint16 areaflag,uint32 map_id);
uint32 GetAreaId(float x, float y, float z) const
{
- return GetAreaId(GetAreaFlag(x,y,z),i_id);
+ return GetAreaIdByAreaFlag(GetAreaFlag(x,y,z),i_id);
}
uint32 GetZoneId(float x, float y, float z) const
{
- return GetZoneId(GetAreaFlag(x,y,z),i_id);
+ return GetZoneIdByAreaFlag(GetAreaFlag(x,y,z),i_id);
+ }
+
+ void GetZoneAndAreaId(uint32& zoneid, uint32& areaid, float x, float y, float z) const
+ {
+ GetZoneAndAreaIdByAreaFlag(zoneid,areaid,GetAreaFlag(x,y,z),i_id);
}
virtual void MoveAllCreaturesInMoveList();
diff --git a/src/game/MapManager.h b/src/game/MapManager.h
index 6ca9305711d..143248de162 100644
--- a/src/game/MapManager.h
+++ b/src/game/MapManager.h
@@ -52,8 +52,18 @@ class TRINITY_DLL_DECL MapManager : public Trinity::Singleton<MapManager, Trinit
Map const* m = GetBaseMap(mapid);
return m->GetAreaFlag(x, y, z);
}
- uint32 GetAreaId(uint32 mapid, float x, float y, float z) const { return Map::GetAreaId(GetAreaFlag(mapid, x, y, z),mapid); }
- uint32 GetZoneId(uint32 mapid, float x, float y, float z) const { return Map::GetZoneId(GetAreaFlag(mapid, x, y, z),mapid); }
+ uint32 GetAreaId(uint32 mapid, float x, float y, float z) const
+ {
+ return Map::GetAreaIdByAreaFlag(GetAreaFlag(mapid, x, y, z),mapid);
+ }
+ uint32 GetZoneId(uint32 mapid, float x, float y, float z) const
+ {
+ return Map::GetZoneIdByAreaFlag(GetAreaFlag(mapid, x, y, z),mapid);
+ }
+ void GetZoneAndAreaId(uint32& zoneid, uint32& areaid, uint32 mapid, float x, float y, float z)
+ {
+ Map::GetZoneAndAreaIdByAreaFlag(zoneid,areaid,GetAreaFlag(mapid, x, y, z),mapid);
+ }
void Initialize(void);
void Update(uint32);
diff --git a/src/game/MiscHandler.cpp b/src/game/MiscHandler.cpp
index 93659bd6e0a..c406694cf11 100644
--- a/src/game/MiscHandler.cpp
+++ b/src/game/MiscHandler.cpp
@@ -395,9 +395,11 @@ void WorldSession::HandleZoneUpdateOpcode( WorldPacket & recv_data )
sLog.outDetail("WORLD: Recvd ZONE_UPDATE: %u", newZone);
- GetPlayer()->UpdateZone(newZone);
-
- GetPlayer()->SendInitWorldStates(true,newZone);
+ // use server size data
+ uint32 newzone, newarea;
+ GetPlayer()->GetZoneAndAreaId(newzone,newarea);
+ GetPlayer()->UpdateZone(newzone,newarea);
+ //GetPlayer()->SendInitWorldStates(true,newZone);
}
void WorldSession::HandleSetTargetOpcode( WorldPacket & recv_data )
diff --git a/src/game/NPCHandler.cpp b/src/game/NPCHandler.cpp
index 4cc24fb1e9e..6e9b768ede4 100644
--- a/src/game/NPCHandler.cpp
+++ b/src/game/NPCHandler.cpp
@@ -439,11 +439,12 @@ void WorldSession::HandleBinderActivateOpcode( WorldPacket & recv_data )
void WorldSession::SendBindPoint(Creature *npc)
{
uint32 bindspell = 3286;
+ uint32 zone_id = _player->GetZoneId();
// update sql homebind
- CharacterDatabase.PExecute("UPDATE character_homebind SET map = '%u', zone = '%u', position_x = '%f', position_y = '%f', position_z = '%f' WHERE guid = '%u'", _player->GetMapId(), _player->GetZoneId(), _player->GetPositionX(), _player->GetPositionY(), _player->GetPositionZ(), _player->GetGUIDLow());
+ CharacterDatabase.PExecute("UPDATE character_homebind SET map = '%u', zone = '%u', position_x = '%f', position_y = '%f', position_z = '%f' WHERE guid = '%u'", _player->GetMapId(), zone_id, _player->GetPositionX(), _player->GetPositionY(), _player->GetPositionZ(), _player->GetGUIDLow());
_player->m_homebindMapId = _player->GetMapId();
- _player->m_homebindZoneId = _player->GetZoneId();
+ _player->m_homebindZoneId = zone_id;
_player->m_homebindX = _player->GetPositionX();
_player->m_homebindY = _player->GetPositionY();
_player->m_homebindZ = _player->GetPositionZ();
@@ -462,19 +463,19 @@ void WorldSession::SendBindPoint(Creature *npc)
data << float(_player->GetPositionY());
data << float(_player->GetPositionZ());
data << uint32(_player->GetMapId());
- data << uint32(_player->GetZoneId());
+ data << uint32(zone_id);
SendPacket( &data );
DEBUG_LOG("New Home Position X is %f",_player->GetPositionX());
DEBUG_LOG("New Home Position Y is %f",_player->GetPositionY());
DEBUG_LOG("New Home Position Z is %f",_player->GetPositionZ());
DEBUG_LOG("New Home MapId is %u",_player->GetMapId());
- DEBUG_LOG("New Home ZoneId is %u",_player->GetZoneId());
+ DEBUG_LOG("New Home ZoneId is %u",zone_id);
// zone update
data.Initialize( SMSG_PLAYERBOUND, 8+4 );
data << uint64(_player->GetGUID());
- data << uint32(_player->GetZoneId());
+ data << uint32(zone_id);
SendPacket( &data );
_player->PlayerTalkClass->CloseGossip();
diff --git a/src/game/NullCreatureAI.cpp b/src/game/NullCreatureAI.cpp
index 33218251718..2745dd3ea8d 100644
--- a/src/game/NullCreatureAI.cpp
+++ b/src/game/NullCreatureAI.cpp
@@ -27,6 +27,30 @@ void PassiveAI::UpdateAI(const uint32)
EnterEvadeMode();
}
+void PossessedAI::UpdateAI(const uint32 diff)
+{
+ if(me->getVictim())
+ {
+ if(!me->canAttack(me->getVictim()))
+ me->AttackStop();
+ else
+ DoMeleeAttackIfReady();
+ }
+}
+
+void PossessedAI::JustDied(Unit *u)
+{
+ // We died while possessed, disable our loot
+ me->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
+}
+
+void PossessedAI::KilledUnit(Unit* victim)
+{
+ // We killed a creature, disable victim's loot
+ if (victim->GetTypeId() == TYPEID_UNIT)
+ victim->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
+}
+
void CritterAI::DamageTaken(Unit *done_by, uint32 &)
{
if(!me->hasUnitState(UNIT_STAT_FLEEING))
@@ -39,4 +63,3 @@ void CritterAI::EnterEvadeMode()
me->SetControlled(false, UNIT_STAT_FLEEING);
CreatureAI::EnterEvadeMode();
}
-
diff --git a/src/game/NullCreatureAI.h b/src/game/NullCreatureAI.h
index 671e9ea63ab..f628a7e8ac9 100644
--- a/src/game/NullCreatureAI.h
+++ b/src/game/NullCreatureAI.h
@@ -36,6 +36,18 @@ class TRINITY_DLL_DECL PassiveAI : public CreatureAI
static int Permissible(const Creature *) { return PERMIT_BASE_IDLE; }
};
+class TRINITY_DLL_DECL PossessedAI : public PassiveAI
+{
+ public:
+ PossessedAI(Creature *c) : PassiveAI(c) {}
+
+ void UpdateAI(const uint32);
+ void EnterEvadeMode() {}
+
+ void JustDied(Unit*);
+ void KilledUnit(Unit* victim);
+};
+
class TRINITY_DLL_DECL NullCreatureAI : public PassiveAI
{
public:
diff --git a/src/game/Object.cpp b/src/game/Object.cpp
index 9fdca51777a..4ff05307403 100644
--- a/src/game/Object.cpp
+++ b/src/game/Object.cpp
@@ -1161,6 +1161,11 @@ uint32 WorldObject::GetAreaId() const
return MapManager::Instance().GetBaseMap(m_mapId)->GetAreaId(m_positionX,m_positionY,m_positionZ);
}
+void WorldObject::GetZoneAndAreaId(uint32& zoneid, uint32& areaid) const
+{
+ MapManager::Instance().GetBaseMap(m_mapId)->GetZoneAndAreaId(zoneid,areaid,m_positionX,m_positionY,m_positionZ);
+}
+
InstanceData* WorldObject::GetInstanceData()
{
Map *map = GetMap();
diff --git a/src/game/Object.h b/src/game/Object.h
index 93cde906468..a8017d3883d 100644
--- a/src/game/Object.h
+++ b/src/game/Object.h
@@ -433,6 +433,7 @@ class TRINITY_DLL_SPEC WorldObject : public Object
uint32 GetZoneId() const;
uint32 GetAreaId() const;
+ void GetZoneAndAreaId(uint32& zoneid, uint32& areaid) const;
InstanceData* GetInstanceData();
diff --git a/src/game/OutdoorPvPMgr.cpp b/src/game/OutdoorPvPMgr.cpp
index f6af15e7529..2050a6c11f7 100644
--- a/src/game/OutdoorPvPMgr.cpp
+++ b/src/game/OutdoorPvPMgr.cpp
@@ -143,7 +143,6 @@ void OutdoorPvPMgr::HandlePlayerEnterZone(Player *plr, uint32 zoneid)
}
// add possibly beneficial buffs to plr for zone
itr->second->HandlePlayerEnterZone(plr, zoneid);
- plr->SendInitWorldStates();
sLog.outDebug("Player %u entered outdoorpvp id %u",plr->GetGUIDLow(), itr->second->GetTypeId());
}
diff --git a/src/game/PetAI.cpp b/src/game/PetAI.cpp
index 6f43d511dd0..068548ac8d7 100644
--- a/src/game/PetAI.cpp
+++ b/src/game/PetAI.cpp
@@ -44,44 +44,6 @@ PetAI::PetAI(Creature *c) : CreatureAI(c), i_pet(*c), i_tracker(TIME_INTERVAL_LO
UpdateAllies();
}
-void PetAI::MoveInLineOfSight(Unit *u)
-{
- if( !i_pet.getVictim() && i_pet.GetCharmInfo() &&
- i_pet.IsHostileTo( u ) && i_pet.canAttack(u) &&
- u->isInAccessiblePlaceFor(&i_pet))
- {
- float attackRadius = i_pet.GetAttackDistance(u);
- if(i_pet.IsWithinDistInMap(u, attackRadius) && i_pet.GetDistanceZ(u) <= CREATURE_Z_ATTACK_RANGE)
- {
- if(i_pet.IsWithinLOSInMap(u))
- {
- AttackStart(u);
- //u->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);
- }
- }
- }
-}
-
-void PetAI::AttackStart(Unit *u)
-{
- if( !u || (i_pet.isPet() && ((Pet&)i_pet).getPetType() == MINI_PET) )
- return;
-
- if (inCombat && i_pet.getVictim() && u != i_pet.getVictim())
- i_pet.AttackStop();
-
- if(i_pet.Attack(u,true))
- {
- i_pet.clearUnitState(UNIT_STAT_FOLLOW);
- // TMGs call CreatureRelocation which via MoveInLineOfSight can call this function
- // thus with the following clear the original TMG gets invalidated and crash, doh
- // hope it doesn't start to leak memory without this :-/
- //i_pet->Clear();
- i_pet.GetMotionMaster()->MoveChase(u);
- inCombat = true;
- }
-}
-
void PetAI::EnterEvadeMode()
{
}
@@ -138,9 +100,6 @@ void PetAI::UpdateAI(const uint32 diff)
else
m_updateAlliesTimer -= diff;
- if (inCombat && !i_pet.getVictim())
- _stopAttack();
-
// i_pet.getVictim() can't be used for check in case stop fighting, i_pet.getVictim() clear at Unit death etc.
if( i_pet.getVictim() )
{
@@ -150,50 +109,23 @@ void PetAI::UpdateAI(const uint32 diff)
_stopAttack();
return;
}
- else if( i_pet.IsStopped() || i_pet.IsWithinMeleeRange(i_pet.getVictim()))
- {
- // required to be stopped cases
- if ( i_pet.IsStopped() && i_pet.IsNonMeleeSpellCasted(false) )
- {
- if( i_pet.hasUnitState(UNIT_STAT_FOLLOW) )
- i_pet.InterruptNonMeleeSpells(false);
- else
- return;
- }
- // not required to be stopped case
- else if( i_pet.isAttackReady() && i_pet.IsWithinMeleeRange(i_pet.getVictim()) )
- {
- i_pet.AttackerStateUpdate(i_pet.getVictim());
- i_pet.resetAttackTimer();
-
- if ( !i_pet.getVictim() )
- return;
-
- //if pet misses its target, it will also be the first in threat list
- i_pet.getVictim()->AddThreat(&i_pet,0.0f);
-
- if( _needToStop() )
- _stopAttack();
- }
- }
+ DoMeleeAttackIfReady();
}
- else if(owner && i_pet.GetCharmInfo())
+ else
{
- if(owner->isInCombat() && !(i_pet.HasReactState(REACT_PASSIVE) || i_pet.GetCharmInfo()->HasCommandState(COMMAND_STAY)))
+ if(me->isInCombat())
+ _stopAttack();
+ else if(owner && i_pet.GetCharmInfo()) //no victim
{
- AttackStart(owner->getAttackerForHelper());
- }
- else if(i_pet.GetCharmInfo()->HasCommandState(COMMAND_FOLLOW))
- {
- if (!i_pet.hasUnitState(UNIT_STAT_FOLLOW) )
- {
+ if(owner->isInCombat() && !(i_pet.HasReactState(REACT_PASSIVE) || i_pet.GetCharmInfo()->HasCommandState(COMMAND_STAY)))
+ AttackStart(owner->getAttackerForHelper());
+ else if(i_pet.GetCharmInfo()->HasCommandState(COMMAND_FOLLOW) && !i_pet.hasUnitState(UNIT_STAT_FOLLOW))
i_pet.GetMotionMaster()->MoveFollow(owner,PET_FOLLOW_DIST,PET_FOLLOW_ANGLE);
- }
}
}
- if (i_pet.GetGlobalCooldown() == 0 && !i_pet.IsNonMeleeSpellCasted(false))
+ if (i_pet.GetGlobalCooldown() == 0 && !i_pet.hasUnitState(UNIT_STAT_CASTING))
{
//Autocast
for (uint8 i = 0; i < i_pet.GetPetAutoSpellSize(); i++)
@@ -323,12 +255,3 @@ void PetAI::UpdateAllies()
else //remove group
m_AllySet.insert(owner->GetGUID());
}
-
-/*void PetAI::AttackedBy(Unit *attacker)
-{
- //when attacked, fight back in case 1)no victim already AND 2)not set to passive AND 3)not set to stay, unless can it can reach attacker with melee attack anyway
- if(!i_pet.getVictim() && i_pet.GetCharmInfo() && !i_pet.GetCharmInfo()->HasReactState(REACT_PASSIVE) &&
- (!i_pet.GetCharmInfo()->HasCommandState(COMMAND_STAY) || i_pet.IsWithinMeleeRange(attacker)))
- AttackStart(attacker);
-}*/
-
diff --git a/src/game/PetAI.h b/src/game/PetAI.h
index 82f143e725e..056a9efa205 100644
--- a/src/game/PetAI.h
+++ b/src/game/PetAI.h
@@ -33,8 +33,6 @@ class TRINITY_DLL_DECL PetAI : public CreatureAI
PetAI(Creature *c);
- void MoveInLineOfSight(Unit *);
- void AttackStart(Unit *);
void EnterEvadeMode();
void JustDied(Unit* who) { _stopAttack(); }
diff --git a/src/game/PetHandler.cpp b/src/game/PetHandler.cpp
index 2cc049ebd84..f158f3a8fcc 100644
--- a/src/game/PetHandler.cpp
+++ b/src/game/PetHandler.cpp
@@ -82,13 +82,15 @@ void WorldSession::HandlePetAction( WorldPacket & recv_data )
switch(spellid)
{
case COMMAND_STAY: //flat=1792 //STAY
+ pet->AttackStop();
+ pet->InterruptNonMeleeSpells(false);
pet->StopMoving();
- pet->GetMotionMaster()->Clear();
pet->GetMotionMaster()->MoveIdle();
charmInfo->SetCommandState( COMMAND_STAY );
break;
case COMMAND_FOLLOW: //spellid=1792 //FOLLOW
pet->AttackStop();
+ pet->InterruptNonMeleeSpells(false);
pet->GetMotionMaster()->MoveFollow(_player,PET_FOLLOW_DIST,PET_FOLLOW_ANGLE);
charmInfo->SetCommandState( COMMAND_FOLLOW );
break;
diff --git a/src/game/Player.cpp b/src/game/Player.cpp
index 9571f415ac7..3123bfab829 100644
--- a/src/game/Player.cpp
+++ b/src/game/Player.cpp
@@ -1295,14 +1295,15 @@ void Player::Update( uint32 p_time )
{
if(p_time >= m_zoneUpdateTimer)
{
- uint32 newzone = GetZoneId();
+ uint32 newzone, newarea;
+ GetZoneAndAreaId(newzone,newarea);
+
if( m_zoneUpdateId != newzone )
- UpdateZone(newzone); // also update area
+ UpdateZone(newzone,newarea); // also update area
else
{
// use area updates as well
// needed for free far all arenas for example
- uint32 newarea = GetAreaId();
if( m_areaUpdateId != newarea )
UpdateArea(newarea);
@@ -1732,16 +1733,19 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati
}
}
+ uint32 newzone, newarea;
+ GetZoneAndAreaId(newzone,newarea);
+
if(!GetSession()->PlayerLogout())
{
// don't reset teleport semaphore while logging out, otherwise m_teleport_dest won't be used in Player::SaveToDB
SetSemaphoreTeleport(false);
- UpdateZone(GetZoneId());
+ UpdateZone(newzone,newarea);
}
// new zone
- if(old_zone != GetZoneId())
+ if(old_zone != newzone)
{
// honorless target
if(pvpInfo.inHostileArea)
@@ -4046,7 +4050,9 @@ void Player::ResurrectPlayer(float restore_percent, bool applySickness)
}
// trigger update zone for alive state zone updates
- UpdateZone(GetZoneId());
+ uint32 newzone, newarea;
+ GetZoneAndAreaId(newzone,newarea);
+ UpdateZone(newzone,newarea);
// update visibility
//ObjectAccessor::UpdateVisibilityForPlayer(this);
@@ -6529,26 +6535,25 @@ void Player::UpdateArea(uint32 newArea)
UpdateAreaDependentAuras(newArea);
}
-void Player::UpdateZone(uint32 newZone)
+void Player::UpdateZone(uint32 newZone, uint32 newArea)
{
- uint32 oldZoneId = m_zoneUpdateId;
+ if(m_zoneUpdateId != newZone)
+ {
+ sOutdoorPvPMgr.HandlePlayerLeaveZone(this, m_zoneUpdateId);
+ sOutdoorPvPMgr.HandlePlayerEnterZone(this, newZone);
+ SendInitWorldStates(newZone, newArea); // only if really enters to new zone, not just area change, works strange...
+ }
+
m_zoneUpdateId = newZone;
m_zoneUpdateTimer = ZONE_UPDATE_INTERVAL;
// zone changed, so area changed as well, update it
- UpdateArea(GetAreaId());
+ UpdateArea(newArea);
AreaTableEntry const* zone = GetAreaEntryByAreaID(newZone);
if(!zone)
return;
- // inform outdoor pvp
- if(oldZoneId != m_zoneUpdateId)
- {
- sOutdoorPvPMgr.HandlePlayerLeaveZone(this, oldZoneId);
- sOutdoorPvPMgr.HandlePlayerEnterZone(this, m_zoneUpdateId);
- }
-
if (sWorld.getConfig(CONFIG_WEATHER))
{
Weather *wth = sWorld.FindWeather(zone->ID);
@@ -7927,20 +7932,16 @@ void Player::SendUpdateWorldState(uint32 Field, uint32 Value)
GetSession()->SendPacket(&data);
}
-void Player::SendInitWorldStates(bool forceZone, uint32 forceZoneId)
+void Player::SendInitWorldStates(uint32 zoneid, uint32 areaid)
{
// data depends on zoneid/mapid...
BattleGround* bg = GetBattleGround();
uint16 NumberOfFields = 0;
uint32 mapid = GetMapId();
- uint32 zoneid;
- if(forceZone)
- zoneid = forceZoneId;
- else
- zoneid = GetZoneId();
OutdoorPvP * pvp = sOutdoorPvPMgr.GetOutdoorPvPToZoneId(zoneid);
- uint32 areaid = GetAreaId();
+
sLog.outDebug("Sending SMSG_INIT_WORLD_STATES to Map:%u, Zone: %u", mapid, zoneid);
+
// may be exist better way to do this...
switch(zoneid)
{
@@ -13061,8 +13062,8 @@ void Player::AddQuest( Quest const *pQuest, Object *questGiver )
SpellAreaForQuestMapBounds saBounds = spellmgr.GetSpellAreaForQuestMapBounds(quest_id,true);
if(saBounds.first != saBounds.second)
{
- uint32 zone = GetZoneId();
- uint32 area = GetAreaId();
+ uint32 zone, area;
+ GetZoneAndAreaId(zone,area);
for(SpellAreaForAreaMap::const_iterator itr = saBounds.first; itr != saBounds.second; ++itr)
if(itr->second->autocast && itr->second->IsFitToRequirements(this,zone,area))
@@ -13168,7 +13169,7 @@ void Player::RewardQuest( Quest const *pQuest, uint32 reward, Object* questGiver
GiveXP( XP , NULL );
else
{
- int32 money = int32(pQuest->GetRewMoneyMaxLevel() * sWorld.getRate(RATE_DROP_MONEY));
+ uint32 money = uint32(pQuest->GetRewMoneyMaxLevel() * sWorld.getRate(RATE_DROP_MONEY));
ModifyMoney( money );
GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_MONEY_FROM_QUEST_REWARD, money);
}
@@ -13177,7 +13178,9 @@ void Player::RewardQuest( Quest const *pQuest, uint32 reward, Object* questGiver
if(pQuest->GetRewOrReqMoney())
{
ModifyMoney( pQuest->GetRewOrReqMoney() );
- GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_MONEY_FROM_QUEST_REWARD, pQuest->GetRewOrReqMoney());
+
+ if(pQuest->GetRewOrReqMoney() > 0)
+ GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_MONEY_FROM_QUEST_REWARD, pQuest->GetRewOrReqMoney());
}
// honor reward
@@ -13276,8 +13279,7 @@ void Player::RewardQuest( Quest const *pQuest, uint32 reward, Object* questGiver
SpellAreaForQuestMapBounds saEndBounds = spellmgr.GetSpellAreaForQuestEndMapBounds(quest_id);
if(saEndBounds.first != saEndBounds.second)
{
- uint32 zone = GetZoneId();
- uint32 area = GetAreaId();
+ GetZoneAndAreaId(zone,area);
for(SpellAreaForAreaMap::const_iterator itr = saEndBounds.first; itr != saEndBounds.second; ++itr)
if(!itr->second->IsFitToRequirements(this,zone,area))
@@ -13288,8 +13290,8 @@ void Player::RewardQuest( Quest const *pQuest, uint32 reward, Object* questGiver
SpellAreaForQuestMapBounds saBounds = spellmgr.GetSpellAreaForQuestMapBounds(quest_id,false);
if(saBounds.first != saBounds.second)
{
- if(!zone) zone = GetZoneId();
- if(!area) area = GetAreaId();
+ if(!zone || !area)
+ GetZoneAndAreaId(zone,area);
for(SpellAreaForAreaMap::const_iterator itr = saBounds.first; itr != saBounds.second; ++itr)
if(itr->second->autocast && itr->second->IsFitToRequirements(this,zone,area))
@@ -18954,8 +18956,11 @@ void Player::SendInitialPacketsBeforeAddToMap()
SendInitialActionButtons();
SendInitialReputations();
m_achievementMgr.SendAllAchievementData();
- UpdateZone(GetZoneId());
- SendInitWorldStates();
+
+ // update zone
+ uint32 newzone, newarea;
+ GetZoneAndAreaId(newzone,newarea);
+ UpdateZone(newzone,newarea); // also call SendInitWorldStates();
// SMSG_SET_AURA_SINGLE
diff --git a/src/game/Player.h b/src/game/Player.h
index 686dc86d5e9..5a60d04eeaf 100644
--- a/src/game/Player.h
+++ b/src/game/Player.h
@@ -1550,7 +1550,7 @@ class TRINITY_DLL_SPEC Player : public Unit
PvPInfo pvpInfo;
void UpdatePvP(bool state, bool ovrride=false);
- void UpdateZone(uint32 newZone);
+ void UpdateZone(uint32 newZone,uint32 newArea);
void UpdateArea(uint32 newArea);
void UpdateZoneDependentAuras( uint32 zone_id ); // zones
@@ -1867,7 +1867,7 @@ class TRINITY_DLL_SPEC Player : public Unit
void CastItemCombatSpell(Item *item,Unit* Target, WeaponAttackType attType);
void CastItemUseSpell(Item *item,SpellCastTargets const& targets,uint8 cast_count, uint32 glyphIndex);
- void SendInitWorldStates(bool force = false, uint32 forceZoneId = 0);
+ void SendInitWorldStates(uint32 zone, uint32 area);
void SendUpdateWorldState(uint32 Field, uint32 Value);
void SendDirectMessage(WorldPacket *data);
diff --git a/src/game/PossessedAI.cpp b/src/game/PossessedAI.cpp
index e8d499bf576..8fd2e5ca014 100644
--- a/src/game/PossessedAI.cpp
+++ b/src/game/PossessedAI.cpp
@@ -18,105 +18,3 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include "PossessedAI.h"
-#include "Creature.h"
-#include "World.h"
-
-void PossessedAI::AttackStart(Unit *u)
-{
- if( !u || i_pet.GetCharmer()->HasAuraType(SPELL_AURA_MOD_PACIFY))
- return;
-
- if (i_pet.getVictim() && u != i_pet.getVictim())
- i_pet.AttackStop();
-
- if(i_pet.Attack(u, true))
- i_victimGuid = u->GetGUID();
-
- // Do not autochase our target, and also make sure our current movement generator
- // is removed since the motion master is reset before this function is called
- i_pet.GetMotionMaster()->Clear(false);
- i_pet.GetMotionMaster()->MoveIdle();
-}
-
-bool PossessedAI::_needToStop() const
-{
- if(!i_pet.getVictim() || !i_pet.isAlive())
- return true;
-
- // This is needed for charmed creatures, as once their target was reset other effects can trigger threat
- if(i_pet.getVictim() == i_pet.GetCharmer())
- return true;
-
- return !i_pet.canAttack(i_pet.getVictim());
-}
-
-void PossessedAI::_stopAttack()
-{
- if( !i_victimGuid )
- return;
-
- Unit* victim = Unit::GetUnit(i_pet, i_victimGuid );
-
- if ( !victim )
- return;
-
- assert(!i_pet.getVictim() || i_pet.getVictim() == victim);
-
- if( !i_pet.isAlive() )
- {
- i_pet.StopMoving();
- i_pet.GetMotionMaster()->Clear(false);
- i_pet.GetMotionMaster()->MoveIdle();
- i_victimGuid = 0;
- i_pet.CombatStop();
- i_pet.getHostilRefManager().deleteReferences();
-
- return;
- }
-
- i_pet.GetMotionMaster()->Clear(false);
- i_pet.GetMotionMaster()->MoveIdle();
- i_victimGuid = 0;
- i_pet.AttackStop();
-}
-
-void PossessedAI::UpdateAI(const uint32 diff)
-{
- // update i_victimGuid if i_pet.getVictim() !=0 and changed
- if(i_pet.getVictim())
- i_victimGuid = i_pet.getVictim()->GetGUID();
-
- // i_pet.getVictim() can't be used for check in case stop fighting, i_pet.getVictim() clear at Unit death etc.
- if( i_victimGuid )
- {
- if( _needToStop() )
- {
- _stopAttack(); // i_victimGuid == 0 && i_pet.getVictim() == NULL now
- return;
- }
- else if(i_pet.IsWithinMeleeRange(i_pet.getVictim()) && i_pet.isAttackReady() && !i_pet.GetCharmer()->HasAuraType(SPELL_AURA_MOD_PACIFY))
- {
- i_pet.AttackerStateUpdate(i_pet.getVictim());
-
- i_pet.resetAttackTimer();
-
- if( _needToStop() )
- _stopAttack();
- }
- }
-}
-
-void PossessedAI::JustDied(Unit *u)
-{
- // We died while possessed, disable our loot
- i_pet.RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
-}
-
-void PossessedAI::KilledUnit(Unit* victim)
-{
- // We killed a creature, disable victim's loot
- if (victim->GetTypeId() == TYPEID_UNIT)
- victim->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
-}
-
diff --git a/src/game/PossessedAI.h b/src/game/PossessedAI.h
index fd90c5429b0..bef7853246e 100644
--- a/src/game/PossessedAI.h
+++ b/src/game/PossessedAI.h
@@ -21,33 +21,5 @@
#ifndef MANGOS_POSSESSEDAI_H
#define MANGOS_POSSESSEDAI_H
-#include "CreatureAI.h"
-class Creature;
-
-class TRINITY_DLL_DECL PossessedAI : public CreatureAI
-{
- public:
- PossessedAI(Creature *c) : CreatureAI(c), i_pet(*c), i_victimGuid(0) {}
-
- // Possessed creatures shouldn't aggro by themselves
- void MoveInLineOfSight(Unit *) {}
- void AttackStart(Unit *);
- void EnterEvadeMode() {}
- void JustDied(Unit*);
- void KilledUnit(Unit* victim);
-
- void UpdateAI(const uint32);
- // Never permit this to be used, it must always be initialized with Creature::InitPossessedAI()
- static int Permissible(const Creature *) { return PERMIT_BASE_NO; }
-
- private:
- bool _isVisible(Unit *) const;
- bool _needToStop(void) const;
- void _stopAttack(void);
-
- Creature &i_pet;
- uint64 i_victimGuid;
-};
#endif
-
diff --git a/src/game/SharedDefines.h b/src/game/SharedDefines.h
index 3d76e2aec79..1411e78cb14 100644
--- a/src/game/SharedDefines.h
+++ b/src/game/SharedDefines.h
@@ -893,7 +893,7 @@ enum Targets
TARGET_UNIT_CLASS_TARGET = 61,
TARGET_TEST = 62, // for a test spell
TARGET_DUELVSPLAYER_COORDINATES = 63,
- TARGET_DEST_TARGET_FRIEND = 63,
+ TARGET_DEST_TARGET_ANY = 63,
TARGET_DEST_TARGET_FRONT = 64,
TARGET_DEST_TARGET_BACK = 65, // uses in teleport behind spells
TARGET_DEST_TARGET_RIGHT = 66,
diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp
index 6c04104d619..34f52daa974 100644
--- a/src/game/Spell.cpp
+++ b/src/game/Spell.cpp
@@ -1892,16 +1892,11 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,std::list<Unit*> &TagUnitMap)
break;
}
- if(cur == TARGET_DEST_TARGET_ENEMY)
+ if(cur == TARGET_DEST_TARGET_ENEMY || cur == TARGET_DEST_TARGET_ANY)
{
m_targets.setDestination(target, true);
break;
}
- else if(cur == TARGET_DEST_TARGET_FRIEND) // no ground?
- {
- m_targets.setDestination(target, false);
- break;
- }
float x, y, z, angle, dist;
@@ -3733,7 +3728,10 @@ uint8 Spell::CanCast(bool strict)
return SPELL_FAILED_NOT_IN_ARENA;
// zone check
- if (uint8 res= spellmgr.GetSpellAllowedInLocationError(m_spellInfo,m_caster->GetMapId(),m_caster->GetZoneId(),m_caster->GetAreaId(),
+ uint32 zone, area;
+ m_caster->GetZoneAndAreaId(zone,area);
+
+ if (uint8 res= spellmgr.GetSpellAllowedInLocationError(m_spellInfo,m_caster->GetMapId(),zone,area,
m_caster->GetTypeId()==TYPEID_PLAYER ? ((Player*)m_caster) : NULL))
return res;
diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp
index e361f09aa24..053beedd4cc 100644
--- a/src/game/SpellAuras.cpp
+++ b/src/game/SpellAuras.cpp
@@ -2242,8 +2242,8 @@ void Aura::HandleAuraDummy(bool apply, bool Real)
SpellAreaForAreaMapBounds saBounds = spellmgr.GetSpellAreaForAuraMapBounds(GetId());
if(saBounds.first != saBounds.second)
{
- uint32 zone = m_target->GetZoneId();
- uint32 area = m_target->GetAreaId();
+ uint32 zone, area;
+ m_target->GetZoneAndAreaId(zone,area);
for(SpellAreaForAreaMap::const_iterator itr = saBounds.first; itr != saBounds.second; ++itr)
{
@@ -6588,8 +6588,8 @@ void Aura::HandlePhase(bool apply, bool Real)
SpellAreaForAreaMapBounds saBounds = spellmgr.GetSpellAreaForAuraMapBounds(GetId());
if(saBounds.first != saBounds.second)
{
- uint32 zone = m_target->GetZoneId();
- uint32 area = m_target->GetAreaId();
+ uint32 zone, area;
+ m_target->GetZoneAndAreaId(zone,area);
for(SpellAreaForAreaMap::const_iterator itr = saBounds.first; itr != saBounds.second; ++itr)
{
diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp
index ef206ae4660..b9eb8af9e02 100644
--- a/src/game/SpellEffects.cpp
+++ b/src/game/SpellEffects.cpp
@@ -2818,9 +2818,10 @@ void Spell::EffectPersistentAA(uint32 i)
if(Player* modOwner = m_originalCaster->GetSpellModOwner())
modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_RADIUS, radius);
+ Unit *caster = m_caster->GetEntry() == WORLD_TRIGGER ? m_originalCaster : m_caster;
int32 duration = GetSpellDuration(m_spellInfo);
DynamicObject* dynObj = new DynamicObject;
- if(!dynObj->Create(objmgr.GenerateLowGuid(HIGHGUID_DYNAMICOBJECT), m_originalCaster, m_spellInfo->Id, i, m_targets.m_destX, m_targets.m_destY, m_targets.m_destZ, duration, radius))
+ if(!dynObj->Create(objmgr.GenerateLowGuid(HIGHGUID_DYNAMICOBJECT), caster, m_spellInfo->Id, i, m_targets.m_destX, m_targets.m_destY, m_targets.m_destZ, duration, radius))
{
delete dynObj;
return;
@@ -2828,8 +2829,8 @@ void Spell::EffectPersistentAA(uint32 i)
dynObj->SetUInt32Value(OBJECT_FIELD_TYPE, 65);
dynObj->SetUInt32Value(GAMEOBJECT_DISPLAYID, 368003);
dynObj->SetUInt32Value(DYNAMICOBJECT_BYTES, 0x01eeeeee);
- m_originalCaster->AddDynObject(dynObj);
- MapManager::Instance().GetMap(dynObj->GetMapId(), dynObj)->Add(dynObj);
+ caster->AddDynObject(dynObj);
+ dynObj->GetMap()->Add(dynObj);
}
void Spell::EffectEnergize(uint32 i)
diff --git a/src/game/SpellMgr.cpp b/src/game/SpellMgr.cpp
index ccc6cc85f5a..57efba7560a 100644
--- a/src/game/SpellMgr.cpp
+++ b/src/game/SpellMgr.cpp
@@ -129,7 +129,7 @@ SpellMgr::SpellMgr()
SpellTargetType[i] = TARGET_TYPE_AREA_DEST;
break;
case TARGET_DEST_TARGET_ENEMY:
- case TARGET_DEST_TARGET_FRIEND:
+ case TARGET_DEST_TARGET_ANY:
case TARGET_DEST_TARGET_FRONT:
case TARGET_DEST_TARGET_BACK:
case TARGET_DEST_TARGET_RIGHT:
diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp
index 85661e97dbf..a77155ab87a 100644
--- a/src/game/Unit.cpp
+++ b/src/game/Unit.cpp
@@ -47,6 +47,8 @@
#include "CellImpl.h"
#include "Path.h"
#include "CreatureGroups.h"
+#include "PetAI.h"
+#include "NullCreatureAI.h"
#include "Traveller.h"
#include <math.h>
@@ -76,6 +78,7 @@ static bool procPrepared = InitTriggerAuraData();
Unit::Unit()
: WorldObject(), i_motionMaster(this), m_ThreatManager(this), m_HostilRefManager(this)
, m_IsInNotifyList(false), m_Notified(false), IsAIEnabled(false)
+, i_AI(NULL), i_disabledAI(NULL)
{
m_objectType |= TYPEMASK_UNIT;
m_objectTypeId = TYPEID_UNIT;
@@ -11284,10 +11287,38 @@ void Unit::CleanupsBeforeDelete()
RemoveFromWorld();
}
+void Unit::UpdateCharmAI()
+{
+ if(GetTypeId() == TYPEID_PLAYER)
+ return;
+
+ if(i_disabledAI) // disabled AI must be primary AI
+ {
+ if(!isCharmed())
+ {
+ if(i_AI) delete i_AI;
+ i_AI = i_disabledAI;
+ i_disabledAI = NULL;
+ }
+ }
+ else
+ {
+ if(isCharmed())
+ {
+ i_disabledAI = i_AI;
+ if(isPossessed())
+ i_AI = new PossessedAI((Creature*)this);
+ else
+ i_AI = new PetAI((Creature*)this);
+ }
+ }
+}
+
CharmInfo* Unit::InitCharmInfo()
{
if(!m_charmInfo)
m_charmInfo = new CharmInfo(this);
+
return m_charmInfo;
}
diff --git a/src/game/Unit.h b/src/game/Unit.h
index 1f40b748fb6..cae075b07dc 100644
--- a/src/game/Unit.h
+++ b/src/game/Unit.h
@@ -1214,6 +1214,7 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
CharmInfo* GetCharmInfo() { return m_charmInfo; }
CharmInfo* InitCharmInfo();
void DeleteCharmInfo();
+ void UpdateCharmAI();
SharedVisionList const& GetSharedVisionList() { return m_sharedVision; }
void AddPlayerToVision(Player* plr);
void RemovePlayerFromVision(Player* plr);
@@ -1549,6 +1550,8 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
protected:
explicit Unit ();
+ UnitAI *i_AI, *i_disabledAI;
+
void _UpdateSpells(uint32 time);
void _UpdateAutoRepeatSpell();
diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h
deleted file mode 100644
index b4cca70987c..00000000000
--- a/src/shared/revision_nr.h
+++ /dev/null
@@ -1,4 +0,0 @@
-#ifndef __REVISION_NR_H__
-#define __REVISION_NR_H__
- #define REVISION_NR "7439"
-#endif // __REVISION_NR_H__