diff options
Diffstat (limited to 'src')
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__ |
