diff --git a/contrib/extractor/ad.exe b/contrib/extractor/ad.exe index eec43be65..2ee6e5be8 100755 Binary files a/contrib/extractor/ad.exe and b/contrib/extractor/ad.exe differ diff --git a/src/game/Map.cpp b/src/game/Map.cpp index 323cc2326..2e6c60244 100644 --- a/src/game/Map.cpp +++ b/src/game/Map.cpp @@ -692,7 +692,7 @@ Map::Remove(T *obj, bool remove) CellPair p = MaNGOS::ComputeCellPair(obj->GetPositionX(), obj->GetPositionY()); if(p.x_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP || p.y_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP ) { - sLog.outError("Map::Remove: Object " I64FMTD " have invalid coordinates X:%f Y:%f grid cell [%u:%u]", obj->GetGUID(), obj->GetPositionX(), obj->GetPositionY(), p.x_coord, p.y_coord); + sLog.outError("Map::Remove: Object " I64FMT " have invalid coordinates X:%f Y:%f grid cell [%u:%u]", obj->GetGUID(), obj->GetPositionX(), obj->GetPositionY(), p.x_coord, p.y_coord); return; } @@ -700,7 +700,7 @@ Map::Remove(T *obj, bool remove) if( !loaded(GridPair(cell.data.Part.grid_x, cell.data.Part.grid_y)) ) return; - DEBUG_LOG("Remove object " I64FMTD " from grid[%u,%u]", obj->GetGUID(), cell.data.Part.grid_x, cell.data.Part.grid_y); + DEBUG_LOG("Remove object " I64FMT " from grid[%u,%u]", obj->GetGUID(), cell.data.Part.grid_x, cell.data.Part.grid_y); NGridType *grid = getNGrid(cell.GridX(), cell.GridY()); assert( grid != NULL ); @@ -954,7 +954,7 @@ bool Map::UnloadGrid(const uint32 &x, const uint32 &y, bool pForce) if (i_InstanceId == 0) { if(GridMaps[gx][gy]) delete (GridMaps[gx][gy]); - // x and y are swaped + // x and y are swapped VMAP::VMapFactory::createOrGetVMapManager()->unloadMap(GetId(), gy, gx); } else diff --git a/src/game/MovementHandler.cpp b/src/game/MovementHandler.cpp index 13b987610..59d71c31b 100644 --- a/src/game/MovementHandler.cpp +++ b/src/game/MovementHandler.cpp @@ -364,7 +364,7 @@ void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data ) data.append(recv_data.contents(), recv_data.size()); GetPlayer()->SendMessageToSet(&data, false); - if(!_player->GetCharmGUID()) + if(!_player->GetCharmGUID()) // nothing is charmed { _player->SetPosition(movementInfo.x, movementInfo.y, movementInfo.z, movementInfo.o); _player->m_movementInfo = movementInfo; @@ -372,12 +372,13 @@ void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data ) } else { - if(mover->GetTypeId() != TYPEID_PLAYER) + if(mover->GetTypeId() != TYPEID_PLAYER) // unit, creature, pet, vehicle... { - mover->Relocate(movementInfo.x, movementInfo.y, movementInfo.z, movementInfo.o); + if(Map *map = mover->GetMap()) + map->CreatureRelocation((Creature*)mover, movementInfo.x, movementInfo.y, movementInfo.z, movementInfo.o); mover->SetUnitMovementFlags(MovementFlags); } - else + else // player { ((Player*)mover)->SetPosition(movementInfo.x, movementInfo.y, movementInfo.z, movementInfo.o); ((Player*)mover)->m_movementInfo = movementInfo; diff --git a/src/game/Pet.cpp b/src/game/Pet.cpp index 4838ac098..d31585995 100644 --- a/src/game/Pet.cpp +++ b/src/game/Pet.cpp @@ -517,7 +517,7 @@ void Pet::Update(uint32 diff) { // unsummon pet that lost owner Unit* owner = GetOwner(); - if(!owner || !IsWithinDistInMap(owner, OWNER_MAX_DISTANCE) || isControlled() && !owner->GetPetGUID()) + if(!owner || (!IsWithinDistInMap(owner, OWNER_MAX_DISTANCE) && (owner->GetCharmGUID() && (owner->GetCharmGUID() != GetGUID()))) || (isControlled() && !owner->GetPetGUID())) { Remove(PET_SAVE_NOT_IN_SLOT, true); return; diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 606d1e7bf..36fba438e 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -1222,7 +1222,7 @@ void Player::Update( uint32 p_time ) SendUpdateToOutOfRangeGroupMembers(); Pet* pet = GetPet(); - if(pet && !IsWithinDistInMap(pet, OWNER_MAX_DISTANCE)) + if(pet && !IsWithinDistInMap(pet, OWNER_MAX_DISTANCE) && (GetCharmGUID() && (pet->GetGUID() != GetCharmGUID()))) { RemovePet(pet, PET_SAVE_NOT_IN_SLOT, true); return; @@ -15889,8 +15889,8 @@ void Player::RemovePet(Pet* pet, PetSaveMode mode, bool returnreagent) m_guardianPets.erase(pet->GetGUID()); break; default: - if(GetPetGUID()==pet->GetGUID()) - SetPet(0); + if(GetPetGUID() == pet->GetGUID()) + SetPet(NULL); break; } diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index e775150e1..ab4e4544a 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -2983,19 +2983,30 @@ void Aura::HandleModPossessPet(bool apply, bool Real) return; Unit* caster = GetCaster(); - if(!caster || caster->GetTypeId() != TYPEID_PLAYER) - return; - if(caster->GetPet() != m_target) + Pet *pet = caster->GetPet(); + if(!pet || (pet != m_target) || !caster || (caster->GetTypeId() != TYPEID_PLAYER)) return; if(apply) - m_target->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNKNOWN5); + pet->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNKNOWN5); else - m_target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNKNOWN5); + pet->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNKNOWN5); - ((Player*)caster)->SetFarSight(apply ? m_target->GetGUID() : NULL); - ((Player*)caster)->SetCharm(apply ? m_target : NULL); - ((Player*)caster)->SetClientControl(m_target, apply ? 1 : 0); + ((Player*)caster)->SetFarSight(apply ? pet->GetGUID() : NULL); + ((Player*)caster)->SetCharm(apply ? pet : NULL); + ((Player*)caster)->SetClientControl(pet, apply ? 1 : 0); + + if(apply) + { + pet->StopMoving(); + pet->GetMotionMaster()->Clear(); + pet->GetMotionMaster()->MoveIdle(); + } + else + { + pet->AttackStop(); + pet->GetMotionMaster()->MoveFollow(caster, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE); + } } void Aura::HandleModCharm(bool apply, bool Real) diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 8344bc0da..05246322c 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -4133,7 +4133,7 @@ void Unit::RemoveAura(AuraMap::iterator &i, AuraRemoveMode mode) m_Auras.erase(i); ++m_removedAuras; // internal count used by unit update - // Status unsummoned at aura remove + // Statue unsummoned at aura remove Totem* statue = NULL; if(IsChanneledSpell(Aur->GetSpellProto())) if(Unit* caster = Aur->GetCaster())