Transports - phase 3
- The gnome engineers have finally repaired the computers of DeeprunTram, and now both trams travel properly between stations. - The pets try hard to learn the paths. For example, they will now properly follow their masters on bridges. - There are now 2 types of transporters: local transporters (elevators, platforms) and global transporters (ships, zeppelins). - Some obsolete methods have been removed. - Some methods have been rewritten to make room for the final phase.
This commit is contained in:
parent
d9fa1c272f
commit
59156f5ec1
@ -1,59 +0,0 @@
|
||||
# MaNGOS is a full featured server for World of Warcraft, supporting
|
||||
# the following clients: 1.12.x, 2.4.3, 3.2.5a, 4.2.3 and 5.4.8
|
||||
#
|
||||
# Copyright (C) 2005-2016 MaNGOS project <https://getmangos.eu>
|
||||
#
|
||||
# ***** BEGIN GPL LICENSE BLOCK *****
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#
|
||||
# ***** END GPL LICENSE BLOCK *****
|
||||
#
|
||||
# World of Warcraft, and all World of Warcraft or Warcraft art, images,
|
||||
# and lore are copyrighted by Blizzard Entertainment, Inc.
|
||||
|
||||
include(MacroMangosSourceGroup)
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Define the battleground library
|
||||
file(GLOB sources *.cpp)
|
||||
file(GLOB headers *.h)
|
||||
|
||||
set(battleground_LIB_SRCS ${sources} ${headers})
|
||||
|
||||
mangos_source_group(${battleground_LIB_SRCS})
|
||||
|
||||
include_directories(
|
||||
${ACE_INCLUDE_DIRS}
|
||||
${MYSQL_INCLUDE_DIR}
|
||||
${CMAKE_SOURCE_DIR}/dep/include/g3dlite/
|
||||
${CMAKE_SOURCE_DIR}/src/framework/
|
||||
${CMAKE_SOURCE_DIR}/src/shared/
|
||||
${CMAKE_SOURCE_DIR}/src/game/
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
${CMAKE_BINARY_DIR}
|
||||
${CMAKE_BINARY_DIR}/src/shared/
|
||||
)
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Build the battleground library
|
||||
add_library(mangos-battleground STATIC ${battleground_LIB_SRCS})
|
||||
target_link_libraries(mangos-battleground mangos-shared mangos-framework g3dlite ${ACE_LIBRARIES} ${MYSQL_LIBRARIES})
|
||||
|
||||
if(${CMAKE_BUILD_TYPE} MATCHES Debug)
|
||||
set(BUILD_PROPERTIES "-DMANGOS_DEBUG")
|
||||
set_target_properties(mangos-battleground PROPERTIES COMPILE_FLAGS ${BUILD_PROPERTIES})
|
||||
endif()
|
@ -137,18 +137,11 @@ void Camera::UpdateVisibilityOf(WorldObject* target)
|
||||
m_owner.UpdateVisibilityOf(m_source, target);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void Camera::UpdateVisibilityOf(T* target, UpdateData& data, std::set<WorldObject*>& vis)
|
||||
void Camera::UpdateVisibilityOf(WorldObject* target, UpdateData& data, std::set<WorldObject*>& vis)
|
||||
{
|
||||
m_owner.template UpdateVisibilityOf<T>(m_source, target, data, vis);
|
||||
m_owner.UpdateVisibilityOf(m_source, target, data, vis);
|
||||
}
|
||||
|
||||
template void Camera::UpdateVisibilityOf(Player* , UpdateData& , std::set<WorldObject*>&);
|
||||
template void Camera::UpdateVisibilityOf(Creature* , UpdateData& , std::set<WorldObject*>&);
|
||||
template void Camera::UpdateVisibilityOf(Corpse* , UpdateData& , std::set<WorldObject*>&);
|
||||
template void Camera::UpdateVisibilityOf(GameObject* , UpdateData& , std::set<WorldObject*>&);
|
||||
template void Camera::UpdateVisibilityOf(DynamicObject* , UpdateData& , std::set<WorldObject*>&);
|
||||
|
||||
void Camera::UpdateVisibilityForOwner()
|
||||
{
|
||||
MaNGOS::VisibleNotifier notifier(*this);
|
||||
|
@ -54,8 +54,7 @@ class Camera
|
||||
// set view to camera's owner
|
||||
void ResetView(bool update_far_sight_field = true);
|
||||
|
||||
template<class T>
|
||||
void UpdateVisibilityOf(T* obj, UpdateData& d, std::set<WorldObject*>& vis);
|
||||
void UpdateVisibilityOf(WorldObject* obj, UpdateData& d, std::set<WorldObject*>& vis);
|
||||
void UpdateVisibilityOf(WorldObject* obj);
|
||||
|
||||
void ReceivePacket(WorldPacket* data);
|
||||
|
@ -158,6 +158,12 @@ bool GameObject::Create(uint32 guidlow, uint32 name_id, Map* map, float x, float
|
||||
return false;
|
||||
}
|
||||
|
||||
if (goinfo->type >= MAX_GAMEOBJECT_TYPE)
|
||||
{
|
||||
sLog.outErrorDb("Gameobject (GUID: %u) not created: Entry %u has invalid type %u in `gameobject_template`. It may crash client if created.", guidlow, name_id, goinfo->type);
|
||||
return false;
|
||||
}
|
||||
|
||||
Object::_Create(guidlow, goinfo->id, HIGHGUID_GAMEOBJECT);
|
||||
|
||||
// let's make sure we don't send the client invalid quaternion
|
||||
@ -181,32 +187,17 @@ bool GameObject::Create(uint32 guidlow, uint32 name_id, Map* map, float x, float
|
||||
}
|
||||
|
||||
SetQuaternion(q);
|
||||
|
||||
m_goInfo = goinfo;
|
||||
|
||||
if (goinfo->type >= MAX_GAMEOBJECT_TYPE)
|
||||
{
|
||||
sLog.outErrorDb("Gameobject (GUID: %u) not created: Entry %u has invalid type %u in `gameobject_template`. It may crash client if created.", guidlow, name_id, goinfo->type);
|
||||
return false;
|
||||
}
|
||||
|
||||
SetObjectScale(goinfo->size);
|
||||
|
||||
SetGOInfo(goinfo);
|
||||
SetObjectScale(m_goInfo->size);
|
||||
SetFloatValue(GAMEOBJECT_POS_X, x);
|
||||
SetFloatValue(GAMEOBJECT_POS_Y, y);
|
||||
SetFloatValue(GAMEOBJECT_POS_Z, z);
|
||||
|
||||
SetUInt32Value(GAMEOBJECT_FACTION, goinfo->faction);
|
||||
SetUInt32Value(GAMEOBJECT_FLAGS, goinfo->flags);
|
||||
|
||||
if (goinfo->type == GAMEOBJECT_TYPE_TRANSPORT)
|
||||
{ SetFlag(GAMEOBJECT_FLAGS, (GO_FLAG_TRANSPORT | GO_FLAG_NODESPAWN)); }
|
||||
|
||||
SetEntry(goinfo->id);
|
||||
SetDisplayId(goinfo->displayId);
|
||||
|
||||
SetUInt32Value(GAMEOBJECT_FACTION, m_goInfo->faction);
|
||||
SetUInt32Value(GAMEOBJECT_FLAGS, m_goInfo->flags);
|
||||
SetEntry(m_goInfo->id);
|
||||
SetDisplayId(m_goInfo->displayId);
|
||||
SetGoState(go_state);
|
||||
SetGoType(GameobjectTypes(goinfo->type));
|
||||
SetGoType(GameobjectTypes(m_goInfo->type));
|
||||
|
||||
SetGoAnimProgress(animprogress);
|
||||
|
||||
@ -752,11 +743,6 @@ void GameObject::DeleteFromDB()
|
||||
WorldDatabase.PExecuteLog("DELETE FROM gameobject_battleground WHERE guid = '%u'", GetGUIDLow());
|
||||
}
|
||||
|
||||
GameObjectInfo const* GameObject::GetGOInfo() const
|
||||
{
|
||||
return m_goInfo;
|
||||
}
|
||||
|
||||
/*********************************************************/
|
||||
/*** QUEST SYSTEM ***/
|
||||
/*********************************************************/
|
||||
@ -1801,7 +1787,7 @@ void GameObject::RollIfMineralVein()
|
||||
GameObjectInfo const* goinfo = ObjectMgr::GetGameObjectInfo(GetEntry());
|
||||
if (goinfo->chest.minSuccessOpens != 0 && goinfo->chest.maxSuccessOpens > goinfo->chest.minSuccessOpens) //in this case it is a mineral vein
|
||||
{
|
||||
uint32 entrynew = RollMineralVein(GetRealEntry());
|
||||
uint32 entrynew = RollMineralVein(GetObjectGuid().GetEntry());
|
||||
|
||||
GameObjectInfo const* goinfonew = ObjectMgr::GetGameObjectInfo(entrynew);
|
||||
m_goInfo = goinfonew;
|
||||
|
@ -565,7 +565,9 @@ class GameObject : public WorldObject
|
||||
bool Create(uint32 guidlow, uint32 name_id, Map* map, float x, float y, float z, float ang,
|
||||
float rotation0 = 0.0f, float rotation1 = 0.0f, float rotation2 = 0.0f, float rotation3 = 0.0f, uint32 animprogress = GO_ANIMPROGRESS_DEFAULT, GOState go_state = GO_STATE_READY);
|
||||
void Update(uint32 update_diff, uint32 p_time) override;
|
||||
GameObjectInfo const* GetGOInfo() const;
|
||||
|
||||
GameObjectInfo const* GetGOInfo() const { return m_goInfo; }
|
||||
void SetGOInfo(GameObjectInfo const* pg) { m_goInfo = pg; }
|
||||
|
||||
bool IsTransport() const;
|
||||
|
||||
@ -584,7 +586,7 @@ class GameObject : public WorldObject
|
||||
void SaveToDB();
|
||||
void SaveToDB(uint32 mapid);
|
||||
bool LoadFromDB(uint32 guid, Map* map);
|
||||
void DeleteFromDB();
|
||||
virtual void DeleteFromDB();
|
||||
|
||||
void SetOwnerGuid(ObjectGuid ownerGuid)
|
||||
{
|
||||
|
@ -1226,7 +1226,7 @@ void WorldObject::UpdateAllowedPositionZ(float x, float y, float& z, Map* atMap
|
||||
// non swim unit must be at ground (mostly speedup, because it don't must be in water and water level check less fast
|
||||
if (!((Creature const*)this)->CanFly())
|
||||
{
|
||||
bool canSwim = ((Creature const*)this)->CanSwim();
|
||||
bool canSwim = ((Creature const*)this)->CanSwim() && ((Creature const*)this)->IsInWater();
|
||||
float ground_z = z;
|
||||
float max_z = canSwim
|
||||
? atMap->GetTerrain()->GetWaterOrGroundLevel(x, y, z, &ground_z, !((Unit const*)this)->HasAuraType(SPELL_AURA_WATER_WALK))
|
||||
|
@ -149,11 +149,9 @@ class Object
|
||||
}
|
||||
|
||||
ObjectGuid const& GetObjectGuid() const { return GetGuidValue(OBJECT_FIELD_GUID); }
|
||||
const uint64& GetGUID() const { return GetUInt64Value(OBJECT_FIELD_GUID); } // DEPRECATED, not use, will removed soon
|
||||
uint32 GetGUIDLow() const { return GetObjectGuid().GetCounter(); }
|
||||
PackedGuid const& GetPackGUID() const { return m_PackGUID; }
|
||||
std::string GetGuidStr() const { return GetObjectGuid().GetString(); }
|
||||
uint32 GetRealEntry() const { return GetObjectGuid().GetEntry(); } //returns the db entry needed for mineral spawn system
|
||||
|
||||
uint32 GetEntry() const { return GetUInt32Value(OBJECT_FIELD_ENTRY); }
|
||||
void SetEntry(uint32 entry) { SetUInt32Value(OBJECT_FIELD_ENTRY, entry); }
|
||||
|
@ -759,7 +759,7 @@ void ObjectMgr::LoadCreatureItemTemplates()
|
||||
|
||||
if (!eqInfo)
|
||||
{ continue; }
|
||||
|
||||
|
||||
EquipmentInfoItem const* itemProto = GetEquipmentInfoItem(eqInfo->entry);
|
||||
|
||||
switch (itemProto->InventoryType)
|
||||
@ -1199,12 +1199,10 @@ void ObjectMgr::LoadCreatures()
|
||||
}
|
||||
|
||||
if (gameEvent == 0 && GuidPoolId == 0 && EntryPoolId == 0) // if not this is to be managed by GameEvent System or Pool system
|
||||
{
|
||||
AddCreatureToGrid(guid, &data);
|
||||
{ AddCreatureToGrid(guid, &data); }
|
||||
|
||||
if (cInfo->ExtraFlags & CREATURE_EXTRA_FLAG_ACTIVE)
|
||||
m_activeCreatures.insert(ActiveCreatureGuidsOnMap::value_type(data.mapid, guid));
|
||||
}
|
||||
if (cInfo->ExtraFlags & CREATURE_EXTRA_FLAG_ACTIVE)
|
||||
{ m_activeCreatures.insert(ActiveCreatureGuidsOnMap::value_type(data.mapid, guid)); }
|
||||
|
||||
++count;
|
||||
}
|
||||
@ -1236,14 +1234,12 @@ void ObjectMgr::RemoveCreatureFromGrid(uint32 guid, CreatureData const* data)
|
||||
|
||||
void ObjectMgr::LoadGameObjects()
|
||||
{
|
||||
uint32 count = 0;
|
||||
|
||||
// 0 1 2 3 4 5 6
|
||||
QueryResult* result = WorldDatabase.Query("SELECT gameobject.guid, gameobject.id, map, position_x, position_y, position_z, orientation,"
|
||||
// 7 8 9 10 11 12 13 14
|
||||
"rotation0, rotation1, rotation2, rotation3, spawntimesecs, animprogress, state, event,"
|
||||
// 15 16
|
||||
"pool_gameobject.pool_entry, pool_gameobject_template.pool_entry "
|
||||
// 0 1 2 3 4 5 6
|
||||
QueryResult* result = WorldDatabase.Query("SELECT gameobject.guid, gameobject.id, gameobject.map, gameobject.position_x, gameobject.position_y, gameobject.position_z, gameobject.orientation, "
|
||||
// 7 8 9 10 11 12 13
|
||||
"gameobject.rotation0, gameobject.rotation1, gameobject.rotation2, gameobject.rotation3, gameobject.spawntimesecs, gameobject.animprogress, gameobject.state, "
|
||||
// 14 15 16
|
||||
"game_event_gameobject.`event`, pool_gameobject.pool_entry, pool_gameobject_template.pool_entry "
|
||||
"FROM gameobject "
|
||||
"LEFT OUTER JOIN game_event_gameobject ON gameobject.guid = game_event_gameobject.guid "
|
||||
"LEFT OUTER JOIN pool_gameobject ON gameobject.guid = pool_gameobject.guid "
|
||||
@ -1260,6 +1256,7 @@ void ObjectMgr::LoadGameObjects()
|
||||
|
||||
BarGoLink bar(result->GetRowCount());
|
||||
|
||||
uint32 local_transports = 0;
|
||||
do
|
||||
{
|
||||
Field* fields = result->Fetch();
|
||||
@ -1355,21 +1352,22 @@ void ObjectMgr::LoadGameObjects()
|
||||
continue;
|
||||
}
|
||||
|
||||
if (gameEvent == 0 && GuidPoolId == 0 && EntryPoolId == 0) // if not this is to be managed by GameEvent System or Pool system
|
||||
if (gInfo->type != GAMEOBJECT_TYPE_TRANSPORT && gameEvent == 0 && GuidPoolId == 0 && EntryPoolId == 0) // if not this is to be managed by GameEvent System or Pool system
|
||||
{ AddGameobjectToGrid(guid, &data); }
|
||||
|
||||
//uint32 zoneId, areaId;
|
||||
//sTerrainMgr.LoadTerrain(data.mapid)->GetZoneAndAreaId(zoneId, areaId, data.posX, data.posY, data.posZ);
|
||||
//sLog.outErrorDb("UPDATE gameobject SET zone_id=%u, area_id=%u WHERE guid=%u;", zoneId, areaId, guid);
|
||||
|
||||
++count;
|
||||
if (gInfo->type == GAMEOBJECT_TYPE_TRANSPORT)
|
||||
{
|
||||
m_localTransports.insert(LocalTransportGuidsOnMap::value_type(data.mapid, guid));
|
||||
++local_transports;
|
||||
}
|
||||
}
|
||||
while (result->NextRow());
|
||||
|
||||
delete result;
|
||||
|
||||
sLog.outString(">> Loaded " SIZEFMTD " gameobjects", mGameObjectDataMap.size());
|
||||
sLog.outString();
|
||||
sLog.outString(">> Loaded " SIZEFMTD " gameobjects", mGameObjectDataMap.size());
|
||||
sLog.outString(">>> Loaded %u local transport objects", local_transports);
|
||||
}
|
||||
|
||||
void ObjectMgr::AddGameobjectToGrid(uint32 guid, GameObjectData const* data)
|
||||
@ -8099,56 +8097,6 @@ void ObjectMgr::LoadVendorTemplates()
|
||||
{ sLog.outErrorDb("Table `npc_vendor_template` has vendor template %u not used by any vendors ", *vItr); }
|
||||
}
|
||||
|
||||
/* This function is supposed to take care of three things:
|
||||
* 1) Load Transports on Map or on Continents
|
||||
* 2) Load Active Npcs on Map or Continents
|
||||
* 3) Load Everything dependend on config setting LoadAllGridsOnMaps
|
||||
*
|
||||
* This function is currently WIP, hence parts exist only as draft.
|
||||
*/
|
||||
void ObjectMgr::LoadActiveEntities(Map* _map)
|
||||
{
|
||||
// Special case on startup - load continents
|
||||
if (!_map)
|
||||
{
|
||||
uint32 continents[] = {0, 1};
|
||||
for (uint8 i = 0; i < countof(continents); ++i)
|
||||
{
|
||||
_map = sMapMgr.FindMap(continents[i]);
|
||||
if (!_map)
|
||||
{ _map = sMapMgr.CreateMap(continents[i], NULL); }
|
||||
|
||||
if (_map)
|
||||
{ LoadActiveEntities(_map); }
|
||||
else
|
||||
{ sLog.outError("ObjectMgr::LoadActiveEntities - Unable to create Map %u", continents[i]); }
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Load active objects for _map
|
||||
if (sWorld.isForceLoadMap(_map->GetId()))
|
||||
{
|
||||
for (CreatureDataMap::const_iterator itr = mCreatureDataMap.begin(); itr != mCreatureDataMap.end(); ++itr)
|
||||
{
|
||||
if (itr->second.mapid == _map->GetId())
|
||||
{ _map->ForceLoadGrid(itr->second.posX, itr->second.posY); }
|
||||
}
|
||||
}
|
||||
else // Normal case - Load all npcs that are active
|
||||
{
|
||||
std::pair<ActiveCreatureGuidsOnMap::const_iterator, ActiveCreatureGuidsOnMap::const_iterator> bounds = m_activeCreatures.equal_range(_map->GetId());
|
||||
for (ActiveCreatureGuidsOnMap::const_iterator itr = bounds.first; itr != bounds.second; ++itr)
|
||||
{
|
||||
CreatureData const& data = mCreatureDataMap[itr->second];
|
||||
{ _map->ForceLoadGrid(data.posX, data.posY); }
|
||||
}
|
||||
}
|
||||
|
||||
// Load Transports on Map _map
|
||||
}
|
||||
|
||||
void ObjectMgr::LoadNpcGossips()
|
||||
{
|
||||
|
||||
|
@ -117,6 +117,9 @@ struct MangosStringLocale
|
||||
typedef UNORDERED_MAP<uint32 /*guid*/, CreatureData> CreatureDataMap;
|
||||
typedef CreatureDataMap::value_type CreatureDataPair;
|
||||
|
||||
typedef std::multimap<uint32 /*mapId*/, uint32 /*guid*/> ActiveCreatureGuidsOnMap;
|
||||
typedef std::multimap<uint32 /*mapId*/, uint32 /*guid*/> LocalTransportGuidsOnMap;
|
||||
|
||||
class FindCreatureData
|
||||
{
|
||||
public:
|
||||
@ -718,9 +721,6 @@ class ObjectMgr
|
||||
{
|
||||
LoadTrainers("npc_trainer", false);
|
||||
}
|
||||
|
||||
/// @param _map Map* of the map for which to load active entities. If NULL active entities on continents are loaded
|
||||
void LoadActiveEntities(Map* _map);
|
||||
|
||||
std::string GeneratePetName(uint32 entry);
|
||||
uint32 GetBaseXP(uint32 level) const;
|
||||
@ -826,6 +826,8 @@ class ObjectMgr
|
||||
{ return "There is no info for this item"; }
|
||||
}
|
||||
|
||||
CreatureDataMap const* GetCreatureDataMap() const { return &mCreatureDataMap; }
|
||||
|
||||
CreatureDataPair const* GetCreatureDataPair(uint32 guid) const
|
||||
{
|
||||
CreatureDataMap::const_iterator itr = mCreatureDataMap.find(guid);
|
||||
@ -853,6 +855,8 @@ class ObjectMgr
|
||||
{ break; }
|
||||
}
|
||||
|
||||
ActiveCreatureGuidsOnMap const* GetActiveCreatureGuids() const { return &m_activeCreatures; }
|
||||
|
||||
CreatureLocale const* GetCreatureLocale(uint32 entry) const
|
||||
{
|
||||
CreatureLocaleMap::const_iterator itr = mCreatureLocaleMap.find(entry);
|
||||
@ -919,6 +923,7 @@ class ObjectMgr
|
||||
return &itr->second;
|
||||
}
|
||||
|
||||
LocalTransportGuidsOnMap const* GetLocalTransportGuids() const { return &m_localTransports; }
|
||||
GameObjectDataPair const* GetGODataPair(uint32 guid) const
|
||||
{
|
||||
GameObjectDataMap::const_iterator itr = mGameObjectDataMap.find(guid);
|
||||
@ -1234,13 +1239,13 @@ class ObjectMgr
|
||||
HalfNameMap PetHalfName0;
|
||||
HalfNameMap PetHalfName1;
|
||||
|
||||
typedef std::multimap<uint32 /*mapId*/, uint32 /*guid*/> ActiveCreatureGuidsOnMap;
|
||||
|
||||
// Array to store creature stats, Max creature level + 1 (for data alignement with in game level)
|
||||
CreatureClassLvlStats m_creatureClassLvlStats[DEFAULT_MAX_CREATURE_LEVEL + 1][MAX_CREATURE_CLASS];
|
||||
|
||||
MapObjectGuids mMapObjectGuids;
|
||||
ActiveCreatureGuidsOnMap m_activeCreatures;
|
||||
LocalTransportGuidsOnMap m_localTransports;
|
||||
CreatureDataMap mCreatureDataMap;
|
||||
CreatureLocaleMap mCreatureLocaleMap;
|
||||
GameObjectDataMap mGameObjectDataMap;
|
||||
|
@ -14447,10 +14447,10 @@ bool Player::isAllowedToLoot(Creature* creature)
|
||||
|
||||
/* This is the player that will be given permission to loot */
|
||||
Player* final_looter = recipient;
|
||||
|
||||
|
||||
/* Iterate through the valid party members */
|
||||
Group::MemberSlotList slots = plr_group->GetMemberSlots();
|
||||
|
||||
|
||||
for (Group::MemberSlotList::iterator itr = slots.begin(); itr != slots.end(); ++itr)
|
||||
{
|
||||
/* Get the player data */
|
||||
@ -14473,18 +14473,17 @@ bool Player::isAllowedToLoot(Creature* creature)
|
||||
|
||||
/* We have our looter, update their loot time */
|
||||
final_looter->lastTimeLooted = time(NULL);
|
||||
|
||||
|
||||
/* Update the creature with the looter that has been assigned to them */
|
||||
creature->assignedLooter = final_looter->GetGUIDLow();
|
||||
final_looter->GetGroup()->SetLooterGuid(final_looter->GetGUID());
|
||||
|
||||
final_looter->GetGroup()->SetLooterGuid(final_looter->GetObjectGuid());
|
||||
|
||||
/* Finally, return if we are the assigned looter */
|
||||
return (final_looter->GetGUIDLow() == GetGUIDLow() || hasSharedLoot || hasStartingQuestLoot);
|
||||
/* End of switch statement */
|
||||
}
|
||||
default:
|
||||
// Something went wrong, avoid crash
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -16879,7 +16878,7 @@ void Player::HandleStealthedUnitsDetection()
|
||||
(*i)->SendCreateUpdateToPlayer(this);
|
||||
m_clientGUIDs.insert(i_guid);
|
||||
|
||||
DEBUG_FILTER_LOG(LOG_FILTER_VISIBILITY_CHANGES, "UpdateVisibilityOf(TemplateV): %s is detected in stealth by player %u. Distance = %f", i_guid.GetString().c_str(), GetGUIDLow(), GetDistance(*i));
|
||||
DEBUG_FILTER_LOG(LOG_FILTER_VISIBILITY_CHANGES, "UpdateVisibilityOf(): %s is detected in stealth by player %u. Distance = %f", i_guid.GetString().c_str(), GetGUIDLow(), GetDistance(*i));
|
||||
|
||||
// target aura duration for caster show only if target exist at caster client
|
||||
// send data at target visibility change (adding to client)
|
||||
@ -17711,18 +17710,16 @@ bool Player::IsVisibleGloballyFor(Player* u) const
|
||||
return true;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline void BeforeVisibilityDestroy(T* /*t*/, Player* /*p*/)
|
||||
inline void BeforeVisibilityDestroy(WorldObject* o, Player* p)
|
||||
{
|
||||
if (Creature* t = o->ToCreature())
|
||||
{
|
||||
if (p->GetPetGuid() == t->GetObjectGuid() && t->IsPet())
|
||||
{ ((Pet*)t)->Unsummon(PET_SAVE_REAGENTS); }
|
||||
}
|
||||
}
|
||||
|
||||
template<>
|
||||
inline void BeforeVisibilityDestroy<Creature>(Creature* t, Player* p)
|
||||
{
|
||||
if (p->GetPetGuid() == t->GetObjectGuid() && ((Creature*)t)->IsPet())
|
||||
{ ((Pet*)t)->Unsummon(PET_SAVE_REAGENTS); }
|
||||
}
|
||||
|
||||
//2 params version (2p)
|
||||
void Player::UpdateVisibilityOf(WorldObject const* viewPoint, WorldObject* target)
|
||||
{
|
||||
if (HaveAtClient(target))
|
||||
@ -17732,12 +17729,12 @@ void Player::UpdateVisibilityOf(WorldObject const* viewPoint, WorldObject* targe
|
||||
ObjectGuid t_guid = target->GetObjectGuid();
|
||||
|
||||
if (target->GetTypeId() == TYPEID_UNIT)
|
||||
{ BeforeVisibilityDestroy<Creature>((Creature*)target, this); }
|
||||
{ BeforeVisibilityDestroy(target, this); }
|
||||
|
||||
target->DestroyForPlayer(this);
|
||||
m_clientGUIDs.erase(t_guid);
|
||||
|
||||
DEBUG_FILTER_LOG(LOG_FILTER_VISIBILITY_CHANGES, "UpdateVisibilityOf: %s out of range for player %u. Distance = %f", t_guid.GetString().c_str(), GetGUIDLow(), GetDistance(target));
|
||||
DEBUG_FILTER_LOG(LOG_FILTER_VISIBILITY_CHANGES, "UpdateVisibilityOf(2p): %s out of range for player %u. Distance = %f", t_guid.GetString().c_str(), GetGUIDLow(), GetDistance(target));
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -17748,7 +17745,7 @@ void Player::UpdateVisibilityOf(WorldObject const* viewPoint, WorldObject* targe
|
||||
if (target->GetTypeId() != TYPEID_GAMEOBJECT || !((GameObject*)target)->IsTransport())
|
||||
{ m_clientGUIDs.insert(target->GetObjectGuid()); }
|
||||
|
||||
DEBUG_FILTER_LOG(LOG_FILTER_VISIBILITY_CHANGES, "UpdateVisibilityOf: %s is visible now for player %u. Distance = %f", target->GetGuidStr().c_str(), GetGUIDLow(), GetDistance(target));
|
||||
DEBUG_FILTER_LOG(LOG_FILTER_VISIBILITY_CHANGES, "UpdateVisibilityOf(2p): %s is visible now for player %u. Distance = %f", target->GetGuidStr().c_str(), GetGUIDLow(), GetDistance(target));
|
||||
|
||||
// target aura duration for caster show only if target exist at caster client
|
||||
// send data at target visibility change (adding to client)
|
||||
@ -17758,34 +17755,21 @@ void Player::UpdateVisibilityOf(WorldObject const* viewPoint, WorldObject* targe
|
||||
}
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline void UpdateVisibilityOf_helper(GuidSet& s64, T* target)
|
||||
{
|
||||
s64.insert(target->GetObjectGuid());
|
||||
}
|
||||
|
||||
template<>
|
||||
inline void UpdateVisibilityOf_helper(GuidSet& s64, GameObject* target)
|
||||
{
|
||||
if (!target->IsTransport())
|
||||
{ s64.insert(target->GetObjectGuid()); }
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void Player::UpdateVisibilityOf(WorldObject const* viewPoint, T* target, UpdateData& data, std::set<WorldObject*>& visibleNow)
|
||||
//4 params version (4p)
|
||||
void Player::UpdateVisibilityOf(WorldObject const* viewPoint, WorldObject* target, UpdateData& data, std::set<WorldObject*>& visibleNow)
|
||||
{
|
||||
if (HaveAtClient(target))
|
||||
{
|
||||
if (!target->IsVisibleForInState(this, viewPoint, true))
|
||||
{
|
||||
BeforeVisibilityDestroy<T>(target, this);
|
||||
BeforeVisibilityDestroy(target, this);
|
||||
|
||||
ObjectGuid t_guid = target->GetObjectGuid();
|
||||
|
||||
target->BuildOutOfRangeUpdateBlock(&data);
|
||||
m_clientGUIDs.erase(t_guid);
|
||||
|
||||
DEBUG_FILTER_LOG(LOG_FILTER_VISIBILITY_CHANGES, "UpdateVisibilityOf(TemplateV): %s is out of range for %s. Distance = %f", t_guid.GetString().c_str(), GetGuidStr().c_str(), GetDistance(target));
|
||||
DEBUG_FILTER_LOG(LOG_FILTER_VISIBILITY_CHANGES, "UpdateVisibilityOf(4p): %s is out of range for %s. Distance = %f", t_guid.GetString().c_str(), GetGuidStr().c_str(), GetDistance(target));
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -17794,19 +17778,22 @@ void Player::UpdateVisibilityOf(WorldObject const* viewPoint, T* target, UpdateD
|
||||
{
|
||||
visibleNow.insert(target);
|
||||
target->BuildCreateUpdateBlockForPlayer(&data, this);
|
||||
UpdateVisibilityOf_helper(m_clientGUIDs, target);
|
||||
|
||||
DEBUG_FILTER_LOG(LOG_FILTER_VISIBILITY_CHANGES, "UpdateVisibilityOf(TemplateV): %s is visible now for %s. Distance = %f", target->GetGuidStr().c_str(), GetGuidStr().c_str(), GetDistance(target));
|
||||
if (GameObject* g = target->ToGameObject())
|
||||
{
|
||||
if (!g->IsTransport())
|
||||
{
|
||||
m_clientGUIDs.insert(g->GetObjectGuid());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_clientGUIDs.insert(target->GetObjectGuid());
|
||||
}
|
||||
DEBUG_FILTER_LOG(LOG_FILTER_VISIBILITY_CHANGES, "UpdateVisibilityOf(4p): %s is visible now for %s. Distance = %f", target->GetGuidStr().c_str(), GetGuidStr().c_str(), GetDistance(target));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template void Player::UpdateVisibilityOf(WorldObject const* viewPoint, Player* target, UpdateData& data, std::set<WorldObject*>& visibleNow);
|
||||
template void Player::UpdateVisibilityOf(WorldObject const* viewPoint, Creature* target, UpdateData& data, std::set<WorldObject*>& visibleNow);
|
||||
template void Player::UpdateVisibilityOf(WorldObject const* viewPoint, Corpse* target, UpdateData& data, std::set<WorldObject*>& visibleNow);
|
||||
template void Player::UpdateVisibilityOf(WorldObject const* viewPoint, GameObject* target, UpdateData& data, std::set<WorldObject*>& visibleNow);
|
||||
template void Player::UpdateVisibilityOf(WorldObject const* viewPoint, DynamicObject* target, UpdateData& data, std::set<WorldObject*>& visibleNow);
|
||||
|
||||
void Player::InitPrimaryProfessions()
|
||||
{
|
||||
uint32 maxProfs = GetSession()->GetSecurity() < AccountTypes(sWorld.getConfig(CONFIG_UINT32_TRADE_SKILL_GMIGNORE_MAX_PRIMARY_COUNT))
|
||||
|
@ -2241,9 +2241,7 @@ class Player : public Unit
|
||||
bool IsVisibleGloballyFor(Player* pl) const;
|
||||
|
||||
void UpdateVisibilityOf(WorldObject const* viewPoint, WorldObject* target);
|
||||
|
||||
template<class T>
|
||||
void UpdateVisibilityOf(WorldObject const* viewPoint, T* target, UpdateData& data, std::set<WorldObject*>& visibleNow);
|
||||
void UpdateVisibilityOf(WorldObject const* viewPoint, WorldObject* target, UpdateData& data, std::set<WorldObject*>& visibleNow);
|
||||
|
||||
// Stealth detection system
|
||||
void HandleStealthedUnitsDetection();
|
||||
|
@ -1,59 +0,0 @@
|
||||
# MaNGOS is a full featured server for World of Warcraft, supporting
|
||||
# the following clients: 1.12.x, 2.4.3, 3.2.5a, 4.2.3 and 5.4.8
|
||||
#
|
||||
# Copyright (C) 2005-2016 MaNGOS project <https://getmangos.eu>
|
||||
#
|
||||
# ***** BEGIN GPL LICENSE BLOCK *****
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#
|
||||
# ***** END GPL LICENSE BLOCK *****
|
||||
#
|
||||
# World of Warcraft, and all World of Warcraft or Warcraft art, images,
|
||||
# and lore are copyrighted by Blizzard Entertainment, Inc.
|
||||
|
||||
include(MacroMangosSourceGroup)
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Define the outdoor-pvp library
|
||||
file(GLOB sources *.cpp)
|
||||
file(GLOB headers *.h)
|
||||
|
||||
set(outdoor-pvp_LIB_SRCS ${sources} ${headers})
|
||||
|
||||
mangos_source_group(${outdoor-pvp_LIB_SRCS})
|
||||
|
||||
include_directories(
|
||||
${ACE_INCLUDE_DIRS}
|
||||
${MYSQL_INCLUDE_DIR}
|
||||
${CMAKE_SOURCE_DIR}/dep/include/g3dlite/
|
||||
${CMAKE_SOURCE_DIR}/src/framework/
|
||||
${CMAKE_SOURCE_DIR}/src/shared/
|
||||
${CMAKE_SOURCE_DIR}/src/game/
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
${CMAKE_BINARY_DIR}
|
||||
${CMAKE_BINARY_DIR}/src/shared/
|
||||
)
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Build the outdoor-pvp library
|
||||
add_library(mangos-outdoor-pvp STATIC ${outdoor-pvp_LIB_SRCS})
|
||||
target_link_libraries(mangos-outdoor-pvp mangos-shared mangos-framework g3dlite ${ACE_LIBRARIES} ${MYSQL_LIBRARIES})
|
||||
|
||||
if(${CMAKE_BUILD_TYPE} MATCHES Debug)
|
||||
set(BUILD_PROPERTIES "-DMANGOS_DEBUG")
|
||||
set_target_properties(mangos-outdoor-pvp PROPERTIES COMPILE_FLAGS ${BUILD_PROPERTIES})
|
||||
endif()
|
@ -50,13 +50,14 @@ void VisibleNotifier::Notify()
|
||||
// but exist one case when this possible and object not out of range: transports
|
||||
if (Transport* transport = player.GetTransport())
|
||||
{
|
||||
for (Transport::PlayerSet::const_iterator itr = transport->GetPassengers().begin(); itr != transport->GetPassengers().end(); ++itr)
|
||||
for (UnitSet::const_iterator itr = transport->GetPassengers().begin(); itr != transport->GetPassengers().end(); ++itr)
|
||||
{
|
||||
if (i_clientGUIDs.find((*itr)->GetObjectGuid()) != i_clientGUIDs.end())
|
||||
{
|
||||
// ignore far sight case
|
||||
(*itr)->UpdateVisibilityOf(*itr, &player);
|
||||
player.UpdateVisibilityOf(&player, *itr, i_data, i_visibleNow);
|
||||
if(Player* p = (*itr)->ToPlayer())
|
||||
{ p->UpdateVisibilityOf(p, &player); }
|
||||
player.UpdateVisibilityOf(&player, (WorldObject*)(*itr), i_data, i_visibleNow);
|
||||
i_clientGUIDs.erase((*itr)->GetObjectGuid());
|
||||
}
|
||||
}
|
||||
|
@ -543,7 +543,7 @@ void Group::SendUpdateToPlayer(Player* pPlayer)
|
||||
// guess size
|
||||
WorldPacket data(SMSG_GROUP_LIST, (1 + 1 + 1 + 4 + GetMembersCount() * 20) + 8 + 1 + 8 + 1);
|
||||
data << (uint8)m_groupType; // group type
|
||||
data << (uint8)(subGroup | (IsAssistant(pPlayer->GetGUID()) ? 0x80 : 0)); // own flags (groupid | (assistant?0x80:0))
|
||||
data << (uint8)(subGroup | (IsAssistant(pPlayer->GetObjectGuid()) ? 0x80 : 0)); // own flags (groupid | (assistant?0x80:0))
|
||||
|
||||
data << uint32(GetMembersCount() - 1);
|
||||
for (member_citerator citr = m_memberSlots.begin(); citr != m_memberSlots.end(); ++citr)
|
||||
@ -1043,7 +1043,7 @@ void Group::CountTheRoll(Rolls::iterator& rollI)
|
||||
|
||||
if (Player* player = sObjectMgr.GetPlayer(maxguid))
|
||||
{
|
||||
if (Object* object = player->GetMap()->GetWorldObject(roll->lootedTargetGUID))
|
||||
if (WorldObject* object = player->GetMap()->GetWorldObject(roll->lootedTargetGUID))
|
||||
{
|
||||
SendLootRollWon(maxguid, maxresul, ROLL_NEED, *roll);
|
||||
won = true;
|
||||
@ -1060,10 +1060,8 @@ void Group::CountTheRoll(Rolls::iterator& rollI)
|
||||
Item* newitem = player->StoreNewItem(dest, roll->itemid, true, item->randomPropertyId);
|
||||
player->SendNewItem(newitem, uint32(item->count), false, false, true);
|
||||
|
||||
if (object->GetTypeId() == TYPEID_UNIT)
|
||||
if (Creature* creature = object->ToCreature())
|
||||
{
|
||||
/// Warn players about the loot status on the corpse.
|
||||
Creature * creature = object->ToCreature();
|
||||
/// If creature has been fully looted, remove flag.
|
||||
if (creature->loot.isLooted())
|
||||
{
|
||||
@ -1108,7 +1106,7 @@ void Group::CountTheRoll(Rolls::iterator& rollI)
|
||||
|
||||
if (Player* player = sObjectMgr.GetPlayer(maxguid))
|
||||
{
|
||||
if (Object * object = player->GetMap()->GetWorldObject(roll->lootedTargetGUID))
|
||||
if (WorldObject* object = player->GetMap()->GetWorldObject(roll->lootedTargetGUID))
|
||||
{
|
||||
SendLootRollWon(maxguid, maxresul, ROLL_GREED, *roll);
|
||||
won = true;
|
||||
@ -1124,10 +1122,8 @@ void Group::CountTheRoll(Rolls::iterator& rollI)
|
||||
--roll->getLoot()->unlootedCount;
|
||||
Item* newitem = player->StoreNewItem(dest, roll->itemid, true, item->randomPropertyId);
|
||||
player->SendNewItem(newitem, uint32(item->count), false, false, true);
|
||||
if (object->GetTypeId() == TYPEID_UNIT)
|
||||
if (Creature* creature = object->ToCreature())
|
||||
{
|
||||
/// Warn players about the loot status on the corpse.
|
||||
Creature * creature = object->ToCreature();
|
||||
/// If creature has been fully looted, remove flag.
|
||||
if (creature->loot.isLooted())
|
||||
{
|
||||
|
@ -64,7 +64,7 @@ void WorldSession::HandleMeetingStoneJoinOpcode(WorldPacket& recv_data)
|
||||
|
||||
if (Group* grp = _player->GetGroup())
|
||||
{
|
||||
if (!grp->IsLeader(_player->GetGUID()))
|
||||
if (!grp->IsLeader(_player->GetObjectGuid()))
|
||||
{
|
||||
SendMeetingstoneFailed(MEETINGSTONE_FAIL_PARTYLEADER);
|
||||
|
||||
|
@ -348,7 +348,7 @@ void LFGQueue::Update(uint32 diff)
|
||||
}
|
||||
|
||||
WorldPacket data;
|
||||
BuildMemberAddedPacket(data, member->GetGUID());
|
||||
BuildMemberAddedPacket(data, member->GetObjectGuid());
|
||||
|
||||
leader->GetSession()->SendPacket(&data);
|
||||
|
||||
@ -432,7 +432,7 @@ bool LFGQueue::FindRoleToGroup(Player* plr, Group* grp, ClassRoles role)
|
||||
}
|
||||
|
||||
WorldPacket data;
|
||||
BuildMemberAddedPacket(data, plr->GetGUID());
|
||||
BuildMemberAddedPacket(data, plr->GetObjectGuid());
|
||||
grp->BroadcastPacket(&data, true);
|
||||
|
||||
// Add member to the group.
|
||||
@ -506,7 +506,7 @@ bool LFGQueue::FindRoleToGroup(Player* plr, Group* grp, ClassRoles role)
|
||||
}
|
||||
|
||||
WorldPacket data;
|
||||
BuildMemberAddedPacket(data, plr->GetGUID());
|
||||
BuildMemberAddedPacket(data, plr->GetObjectGuid());
|
||||
grp->BroadcastPacket(&data, true);
|
||||
|
||||
// Add member to the group.
|
||||
|
@ -44,6 +44,8 @@
|
||||
#include "BattleGround/BattleGroundMgr.h"
|
||||
#include "Chat.h"
|
||||
#include "Weather.h"
|
||||
#include "Transports.h"
|
||||
|
||||
#ifdef ENABLE_ELUNA
|
||||
#include "LuaEngine.h"
|
||||
#endif /* ENABLE_ELUNA */
|
||||
@ -70,6 +72,12 @@ Map::~Map()
|
||||
delete i_data;
|
||||
i_data = NULL;
|
||||
|
||||
// unload all local transporters
|
||||
for (std::set<Transport*>::iterator t = i_transports.begin(); t != i_transports.end(); ++t)
|
||||
{
|
||||
delete *t;
|
||||
}
|
||||
|
||||
// unload instance specific navigation data
|
||||
MMAP::MMapFactory::createOrGetMMapManager()->unloadMapInstance(m_TerrainData->GetMapId(), GetInstanceId());
|
||||
|
||||
@ -121,6 +129,7 @@ Map::Map(uint32 id, time_t expiry, uint32 InstanceId)
|
||||
m_persistentState->SetUsedByMapState(this);
|
||||
|
||||
m_weatherSystem = new WeatherSystem(this);
|
||||
i_transports.clear();
|
||||
#ifdef ENABLE_ELUNA
|
||||
sEluna->OnCreate(this);
|
||||
#endif /* ENABLE_ELUNA */
|
||||
@ -527,6 +536,13 @@ void Map::Update(const uint32& t_diff)
|
||||
}
|
||||
}
|
||||
|
||||
/// update local transports
|
||||
for (std::set<Transport*>::iterator t = i_transports.begin(); t != i_transports.end(); ++t)
|
||||
{
|
||||
WorldObject::UpdateHelper helper(*t);
|
||||
helper.Update(t_diff);
|
||||
}
|
||||
|
||||
/// update active cells around players and active objects
|
||||
resetMarkedCells();
|
||||
|
||||
@ -946,7 +962,7 @@ void Map::SendInitSelf(Player* player)
|
||||
// build other passengers at transport also (they always visible and marked as visible and will not send at visibility update at add to map
|
||||
if (Transport* transport = player->GetTransport())
|
||||
{
|
||||
for (Transport::PlayerSet::const_iterator itr = transport->GetPassengers().begin(); itr != transport->GetPassengers().end(); ++itr)
|
||||
for (UnitSet::const_iterator itr = transport->GetPassengers().begin(); itr != transport->GetPassengers().end(); ++itr)
|
||||
{
|
||||
if (player != (*itr) && player->HaveAtClient(*itr))
|
||||
{
|
||||
@ -963,55 +979,87 @@ void Map::SendInitSelf(Player* player)
|
||||
|
||||
void Map::SendInitTransports(Player* player)
|
||||
{
|
||||
// Hack to send out transports
|
||||
// Send out global transports
|
||||
MapManager::TransportMap& tmap = sMapMgr.m_TransportsByMap;
|
||||
|
||||
// no transports at map
|
||||
if (tmap.find(player->GetMapId()) == tmap.end())
|
||||
{ return; }
|
||||
|
||||
UpdateData transData;
|
||||
|
||||
MapManager::TransportSet& tset = tmap[player->GetMapId()];
|
||||
|
||||
bool hasTransport = false;
|
||||
|
||||
for (MapManager::TransportSet::const_iterator i = tset.begin(); i != tset.end(); ++i)
|
||||
if (tmap.find(player->GetMapId()) != tmap.end())
|
||||
{
|
||||
// send data for current transport in other place
|
||||
if ((*i) != player->GetTransport() && (*i)->GetMapId() == i_id)
|
||||
MapManager::TransportSet& tset = tmap[player->GetMapId()];
|
||||
|
||||
UpdateData transData;
|
||||
bool hasTransport = false;
|
||||
|
||||
for (MapManager::TransportSet::const_iterator i = tset.begin(); i != tset.end(); ++i)
|
||||
{
|
||||
hasTransport = true;
|
||||
(*i)->BuildCreateUpdateBlockForPlayer(&transData, player);
|
||||
// send data for current transport in other place
|
||||
if ((*i) != player->GetTransport() && (*i)->GetMapId() == i_id)
|
||||
{
|
||||
hasTransport = true;
|
||||
(*i)->BuildCreateUpdateBlockForPlayer(&transData, player);
|
||||
}
|
||||
}
|
||||
|
||||
WorldPacket packet;
|
||||
transData.BuildPacket(&packet, hasTransport);
|
||||
player->GetSession()->SendPacket(&packet);
|
||||
}
|
||||
|
||||
WorldPacket packet;
|
||||
transData.BuildPacket(&packet, hasTransport);
|
||||
player->GetSession()->SendPacket(&packet);
|
||||
// Now send out local transports
|
||||
if (i_transports.size() != 0)
|
||||
{
|
||||
UpdateData transData;
|
||||
bool hasTransport = false;
|
||||
|
||||
for (MapManager::TransportSet::const_iterator i = i_transports.begin(); i != i_transports.end(); ++i)
|
||||
{
|
||||
// send data for current transport in other place
|
||||
if ((*i) != player->GetTransport() && (*i)->GetMapId() == i_id)
|
||||
{
|
||||
hasTransport = true;
|
||||
(*i)->BuildCreateUpdateBlockForPlayer(&transData, player);
|
||||
}
|
||||
}
|
||||
|
||||
WorldPacket packet;
|
||||
transData.BuildPacket(&packet, hasTransport);
|
||||
player->GetSession()->SendPacket(&packet);
|
||||
}
|
||||
}
|
||||
|
||||
void Map::SendRemoveTransports(Player* player)
|
||||
{
|
||||
// Hack to send out transports
|
||||
// Global transports
|
||||
MapManager::TransportMap& tmap = sMapMgr.m_TransportsByMap;
|
||||
|
||||
// no transports at map
|
||||
if (tmap.find(player->GetMapId()) == tmap.end())
|
||||
{ return; }
|
||||
if (tmap.find(player->GetMapId()) != tmap.end())
|
||||
{
|
||||
UpdateData transData;
|
||||
MapManager::TransportSet& tset = tmap[player->GetMapId()];
|
||||
|
||||
UpdateData transData;
|
||||
// except used transport
|
||||
for (MapManager::TransportSet::const_iterator i = tset.begin(); i != tset.end(); ++i)
|
||||
if ((*i) != player->GetTransport() && (*i)->GetMapId() != i_id)
|
||||
{ (*i)->BuildOutOfRangeUpdateBlock(&transData); }
|
||||
|
||||
MapManager::TransportSet& tset = tmap[player->GetMapId()];
|
||||
WorldPacket packet;
|
||||
transData.BuildPacket(&packet);
|
||||
player->GetSession()->SendPacket(&packet);
|
||||
}
|
||||
|
||||
// except used transport
|
||||
for (MapManager::TransportSet::const_iterator i = tset.begin(); i != tset.end(); ++i)
|
||||
if ((*i) != player->GetTransport() && (*i)->GetMapId() != i_id)
|
||||
{ (*i)->BuildOutOfRangeUpdateBlock(&transData); }
|
||||
// Local transports
|
||||
if (i_transports.size() != 0)
|
||||
{
|
||||
UpdateData transData;
|
||||
|
||||
WorldPacket packet;
|
||||
transData.BuildPacket(&packet);
|
||||
player->GetSession()->SendPacket(&packet);
|
||||
// except used transport
|
||||
for (MapManager::TransportSet::const_iterator i = i_transports.begin(); i != i_transports.end(); ++i)
|
||||
if ((*i) != player->GetTransport() && (*i)->GetMapId() != i_id)
|
||||
{ (*i)->BuildOutOfRangeUpdateBlock(&transData); }
|
||||
|
||||
WorldPacket packet;
|
||||
transData.BuildPacket(&packet);
|
||||
player->GetSession()->SendPacket(&packet);
|
||||
}
|
||||
}
|
||||
|
||||
inline void Map::setNGrid(NGridType* grid, uint32 x, uint32 y)
|
||||
@ -2343,4 +2391,4 @@ bool Map::GetReachableRandomPosition(Unit* unit, float& x, float& y, float& z, f
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
@ -63,6 +63,7 @@ class BattleGround;
|
||||
class GridMap;
|
||||
class GameObjectModel;
|
||||
class WeatherSystem;
|
||||
class Transport;
|
||||
|
||||
namespace MaNGOS { struct ObjectUpdater; }
|
||||
|
||||
@ -294,6 +295,8 @@ class Map : public GridRefManager<NGridType>
|
||||
bool GetRandomPointInTheAir(float& x, float& y, float& z, float radius);
|
||||
bool GetRandomPointUnderWater(float& x, float& y, float& z, float radius, GridMapLiquidData& liquid_status);
|
||||
|
||||
void LoadLocalTransports();
|
||||
|
||||
private:
|
||||
void LoadMapAndVMap(int gx, int gy);
|
||||
|
||||
@ -358,6 +361,7 @@ class Map : public GridRefManager<NGridType>
|
||||
std::bitset<TOTAL_NUMBER_OF_CELLS_PER_MAP* TOTAL_NUMBER_OF_CELLS_PER_MAP> marked_cells;
|
||||
|
||||
std::set<WorldObject*> i_objectsToRemove;
|
||||
std::set<Transport*> i_transports;
|
||||
|
||||
typedef std::multimap<time_t, ScriptAction> ScriptScheduleMap;
|
||||
ScriptScheduleMap m_scriptSchedule;
|
||||
|
@ -115,7 +115,8 @@ Map* MapManager::CreateMap(uint32 id, const WorldObject* obj)
|
||||
// create DungeonMap object
|
||||
m = CreateInstance(id, (Player*)obj);
|
||||
// Load active objects for this map
|
||||
sObjectMgr.LoadActiveEntities(m);
|
||||
if (m != NULL)
|
||||
{ LoadActiveEntities(m); }
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -127,6 +128,8 @@ Map* MapManager::CreateMap(uint32 id, const WorldObject* obj)
|
||||
// add map into container
|
||||
i_maps[MapID(id)] = m;
|
||||
|
||||
LoadActiveEntities(m);
|
||||
|
||||
// non-instanceable maps always expected have saved state
|
||||
m->CreateInstanceData(true);
|
||||
}
|
||||
@ -390,3 +393,51 @@ BattleGroundMap* MapManager::CreateBattleGroundMap(uint32 id, uint32 InstanceId,
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
void MapManager::LoadContinents()
|
||||
{
|
||||
uint32 continents[] = {0, 1};
|
||||
Map* _map = NULL;
|
||||
|
||||
for (uint8 i = 0; i < countof(continents); ++i)
|
||||
{
|
||||
_map = sMapMgr.FindMap(continents[i]);
|
||||
|
||||
if (!_map)
|
||||
{ _map = sMapMgr.CreateMap(continents[i], NULL); }
|
||||
|
||||
if (!_map)
|
||||
{ sLog.outError("MapManager::LoadContinents() - Unable to create map %u", continents[i]); }
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void MapManager::LoadActiveEntities(Map* m)
|
||||
{
|
||||
|
||||
// Create all local transporters for this map
|
||||
m->LoadLocalTransports();
|
||||
|
||||
// Load grids for all objects on this map, if configured so
|
||||
if (sWorld.isForceLoadMap(m->GetId()))
|
||||
{
|
||||
for (CreatureDataMap::const_iterator itr = sObjectMgr.GetCreatureDataMap()->begin(); itr != sObjectMgr.GetCreatureDataMap()->end(); ++itr)
|
||||
{
|
||||
if (itr->second.mapid == m->GetId())
|
||||
{
|
||||
m->ForceLoadGrid(itr->second.posX, itr->second.posY);
|
||||
}
|
||||
}
|
||||
}
|
||||
else // Normal case - load only grids for npcs that are active
|
||||
{
|
||||
std::pair<ActiveCreatureGuidsOnMap::const_iterator, ActiveCreatureGuidsOnMap::const_iterator> bounds = sObjectMgr.GetActiveCreatureGuids()->equal_range(m->GetId());
|
||||
for (ActiveCreatureGuidsOnMap::const_iterator itr = bounds.first; itr != bounds.second; ++itr)
|
||||
{
|
||||
CreatureData const* data = sObjectMgr.GetCreatureData(itr->second);
|
||||
m->ForceLoadGrid(data->posX, data->posY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -65,7 +65,6 @@ class MapManager : public MaNGOS::Singleton<MapManager, MaNGOS::ClassLevelLockab
|
||||
Map* CreateMap(uint32, const WorldObject* obj);
|
||||
Map* CreateBgMap(uint32 mapid, BattleGround* bg);
|
||||
Map* FindMap(uint32 mapid, uint32 instanceId = 0) const;
|
||||
|
||||
void UpdateGridState(grid_state_t state, Map& map, NGridType& ngrid, GridInfo& ginfo, const uint32& x, const uint32& y, const uint32& t_diff);
|
||||
|
||||
// only const version for outer users
|
||||
@ -133,6 +132,7 @@ class MapManager : public MaNGOS::Singleton<MapManager, MaNGOS::ClassLevelLockab
|
||||
|
||||
void RemoveAllObjectsInRemoveList();
|
||||
|
||||
void LoadContinents();
|
||||
void LoadTransports();
|
||||
|
||||
typedef std::set<Transport*> TransportSet;
|
||||
@ -172,6 +172,7 @@ class MapManager : public MaNGOS::Singleton<MapManager, MaNGOS::ClassLevelLockab
|
||||
|
||||
void InitStateMachine();
|
||||
void DeleteStateMachine();
|
||||
void LoadActiveEntities(Map* m);
|
||||
|
||||
Map* CreateInstance(uint32 id, Player* player);
|
||||
DungeonMap* CreateDungeonMap(uint32 id, uint32 InstanceId, DungeonPersistentState* save = NULL);
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "Common.h"
|
||||
|
||||
#include "Transports.h"
|
||||
#include "Map.h"
|
||||
#include "MapManager.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "ObjectGuid.h"
|
||||
@ -34,6 +35,34 @@
|
||||
#include "DBCStores.h"
|
||||
#include "ProgressBar.h"
|
||||
|
||||
#include <G3D/Quat.h>
|
||||
|
||||
|
||||
void Map::LoadLocalTransports()
|
||||
{
|
||||
//load local transports for this map
|
||||
std::pair<LocalTransportGuidsOnMap::const_iterator, LocalTransportGuidsOnMap::const_iterator> bounds = sObjectMgr.GetLocalTransportGuids()->equal_range(GetId());
|
||||
for (LocalTransportGuidsOnMap::const_iterator itr = bounds.first; itr != bounds.second; ++itr)
|
||||
{
|
||||
LocalTransport* lt = new LocalTransport();
|
||||
if (lt->Initialize(itr->second, this))
|
||||
{
|
||||
i_transports.insert(lt);
|
||||
}
|
||||
else
|
||||
{
|
||||
delete lt;
|
||||
}
|
||||
}
|
||||
/*
|
||||
sLog.outString();
|
||||
for (std::set<Transport*>::const_iterator i = i_transports.begin(); i != i_transports.end(); ++i)
|
||||
sLog.outString(">>>%s initialized", (*i)->GetGuidStr().c_str());
|
||||
*/
|
||||
sLog.outString(">> Loaded " SIZEFMTD " local transports for map %u", i_transports.size(), GetId());
|
||||
|
||||
}
|
||||
|
||||
void MapManager::LoadTransports()
|
||||
{
|
||||
QueryResult* result = WorldDatabase.Query("SELECT entry, name, period FROM transports");
|
||||
@ -44,7 +73,7 @@ void MapManager::LoadTransports()
|
||||
{
|
||||
BarGoLink bar(1);
|
||||
bar.step();
|
||||
sLog.outString(">> Loaded %u transports", count);
|
||||
sLog.outString(">> Loaded 0 global transports");
|
||||
sLog.outString();
|
||||
return;
|
||||
}
|
||||
@ -55,73 +84,28 @@ void MapManager::LoadTransports()
|
||||
{
|
||||
bar.step();
|
||||
|
||||
Transport* t = new Transport;
|
||||
|
||||
Field* fields = result->Fetch();
|
||||
|
||||
uint32 entry = fields[0].GetUInt32();
|
||||
uint32 entry = fields[0].GetUInt32();
|
||||
std::string name = fields[1].GetCppString();
|
||||
t->m_period = fields[2].GetUInt32();
|
||||
uint32 period = fields[2].GetUInt32();
|
||||
|
||||
const GameObjectInfo* goinfo = ObjectMgr::GetGameObjectInfo(entry);
|
||||
|
||||
if (!goinfo)
|
||||
{
|
||||
sLog.outErrorDb("Transport ID:%u, Name: %s, will not be loaded, gameobject_template missing", entry, name.c_str());
|
||||
delete t;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (goinfo->type != GAMEOBJECT_TYPE_MO_TRANSPORT)
|
||||
{
|
||||
sLog.outErrorDb("Transport ID:%u, Name: %s, will not be loaded, gameobject_template type wrong", entry, name.c_str());
|
||||
delete t;
|
||||
continue;
|
||||
}
|
||||
|
||||
// sLog.outString("Loading transport %d between %s, %s", entry, name.c_str(), goinfo->name);
|
||||
|
||||
std::set<uint32> mapsUsed;
|
||||
|
||||
if (!t->GenerateWaypoints(goinfo->moTransport.taxiPathId, mapsUsed))
|
||||
// skip transports with empty waypoints list
|
||||
{
|
||||
sLog.outErrorDb("Transport (path id %u) path size = 0. Transport ignored, check DBC files or transport GO data0 field.", goinfo->moTransport.taxiPathId);
|
||||
delete t;
|
||||
continue;
|
||||
}
|
||||
|
||||
float x, y, z, o;
|
||||
uint32 mapid;
|
||||
x = t->m_WayPoints[0].x; y = t->m_WayPoints[0].y; z = t->m_WayPoints[0].z; mapid = t->m_WayPoints[0].mapid; o = 1;
|
||||
|
||||
// current code does not support transports in dungeon!
|
||||
const MapEntry* pMapInfo = sMapStore.LookupEntry(mapid);
|
||||
if (!pMapInfo || pMapInfo->Instanceable())
|
||||
GlobalTransport* t = new GlobalTransport();
|
||||
if (!t->Initialize(entry, period, name))
|
||||
{
|
||||
delete t;
|
||||
continue;
|
||||
}
|
||||
|
||||
// creates the Gameobject
|
||||
if (!t->Create(entry, mapid, x, y, z, o, GO_ANIMPROGRESS_DEFAULT))
|
||||
{
|
||||
delete t;
|
||||
continue;
|
||||
}
|
||||
for (std::set<uint32>::const_iterator i = t->GetMapsUsed()->begin(); i != t->GetMapsUsed()->end(); ++i)
|
||||
{ m_TransportsByMap[*i].insert(t); }
|
||||
|
||||
m_Transports.insert(t);
|
||||
|
||||
for (std::set<uint32>::const_iterator i = mapsUsed.begin(); i != mapsUsed.end(); ++i)
|
||||
{ m_TransportsByMap[*i].insert(t); }
|
||||
|
||||
// If we someday decide to use the grid to track transports, here:
|
||||
t->SetMap(sMapMgr.CreateMap(mapid, t));
|
||||
|
||||
// t->GetMap()->Add<GameObject>((GameObject *)t);
|
||||
++count;
|
||||
}
|
||||
while (result->NextRow());
|
||||
|
||||
delete result;
|
||||
|
||||
// check transport data DB integrity
|
||||
@ -142,54 +126,195 @@ void MapManager::LoadTransports()
|
||||
delete result;
|
||||
}
|
||||
|
||||
sLog.outString(">> Loaded %u transports", count);
|
||||
sLog.outString();
|
||||
for (std::set<Transport*>::const_iterator i = m_Transports.begin(); i != m_Transports.end(); ++i)
|
||||
sLog.outString(">>>Global transporter %s (id = %u) initialized", (*i)->GetName(), (*i)->GetEntry());
|
||||
|
||||
sLog.outString(">> Loaded %u global transports", count);
|
||||
}
|
||||
|
||||
|
||||
//*****************************//
|
||||
// Base Transport
|
||||
//*****************************//
|
||||
Transport::Transport() : GameObject()
|
||||
{
|
||||
m_updateFlag = (UPDATEFLAG_TRANSPORT | UPDATEFLAG_ALL | UPDATEFLAG_HAS_POSITION);
|
||||
}
|
||||
|
||||
bool Transport::Create(uint32 guidlow, uint32 mapid, float x, float y, float z, float ang, uint32 animprogress)
|
||||
Transport::~Transport()
|
||||
{
|
||||
Relocate(x, y, z, ang);
|
||||
}
|
||||
|
||||
bool Transport::AddPassenger(Unit* passenger)
|
||||
{
|
||||
if (m_passengers.find(passenger) == m_passengers.end())
|
||||
{
|
||||
DETAIL_LOG("%s boarded transport %s.", passenger->GetGuidStr().c_str(), GetName());
|
||||
m_passengers.insert(passenger);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Transport::RemovePassenger(Unit* passenger)
|
||||
{
|
||||
if (m_passengers.erase(passenger))
|
||||
{ DETAIL_LOG("%s removed from transport %s.", passenger->GetGuidStr().c_str(), GetName()); }
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//*****************************//
|
||||
// LocalTransport
|
||||
//*****************************//
|
||||
LocalTransport::LocalTransport() : Transport()
|
||||
{
|
||||
}
|
||||
|
||||
LocalTransport::~LocalTransport()
|
||||
{
|
||||
//sLog.outString("Deleting %s, map %u", GetGuidStr().c_str(), GetMap()->GetId());
|
||||
}
|
||||
|
||||
bool LocalTransport::Initialize(uint32 guid, Map* m)
|
||||
{
|
||||
if (m == NULL)
|
||||
{ return false; }
|
||||
|
||||
GameObjectData const* gdata = sObjectMgr.GetGOData(guid);
|
||||
if (!gdata)
|
||||
{
|
||||
sLog.outErrorDb("Local transport GUID %u does not exist into `gameobject` table", guid);
|
||||
return false;
|
||||
}
|
||||
|
||||
GameObjectInfo const* goinfo = ObjectMgr::GetGameObjectInfo(gdata->id);
|
||||
if (goinfo->type != GAMEOBJECT_TYPE_TRANSPORT)
|
||||
{
|
||||
sLog.outErrorDb("Local transport GUID:%u, Name:%s, Entry:%u will not be loaded, `gameobject_template` type record is wrong", guid, goinfo->name, goinfo->id);
|
||||
return false;
|
||||
}
|
||||
|
||||
Object::_Create(guid, goinfo->id, HIGHGUID_TRANSPORT);
|
||||
|
||||
float r0, r1, r2, r3;
|
||||
r0 = gdata->rotation0;
|
||||
r1 = gdata->rotation1;
|
||||
r2 = gdata->rotation2;
|
||||
r3 = gdata->rotation3;
|
||||
|
||||
if (r0 == 0.0f && r1 == 0.0f && r2 == 0.0f) //TODO make a method for this
|
||||
{
|
||||
r2 = sin(gdata->orientation/2);
|
||||
r3 = cos(gdata->orientation/2);
|
||||
}
|
||||
|
||||
G3D::Quat q(r0, r1, r2, r3);
|
||||
q.unitize();
|
||||
|
||||
float o = GetOrientationFromQuat(q);
|
||||
SetMap(m);
|
||||
Relocate(gdata->posX, gdata->posY, gdata->posZ, o);
|
||||
|
||||
if (!IsPositionValid())
|
||||
{
|
||||
sLog.outError("Transport (GUID: %u) not created. Suggested coordinates isn't valid (X: %f Y: %f)",
|
||||
guidlow, x, y);
|
||||
sLog.outError("Local transport GUID:%u, Name:%s, Entry:%u not created. Suggested coordinates are not valid: (X, Y, Z)=(%f, %f, %f)",
|
||||
guid, goinfo->name, goinfo->id, gdata->posX, gdata->posY, gdata->posZ);
|
||||
return false;
|
||||
}
|
||||
|
||||
Object::_Create(guidlow, 0, HIGHGUID_MO_TRANSPORT);
|
||||
|
||||
GameObjectInfo const* goinfo = ObjectMgr::GetGameObjectInfo(guidlow);
|
||||
|
||||
if (!goinfo)
|
||||
{
|
||||
sLog.outErrorDb("Transport not created: entry in `gameobject_template` not found, guidlow: %u map: %u (X: %f Y: %f Z: %f) ang: %f", guidlow, mapid, x, y, z, ang);
|
||||
return false;
|
||||
}
|
||||
|
||||
m_goInfo = goinfo;
|
||||
|
||||
SetQuaternion(q);
|
||||
SetGOInfo(goinfo);
|
||||
SetObjectScale(goinfo->size);
|
||||
|
||||
SetUInt32Value(GAMEOBJECT_FACTION, goinfo->faction);
|
||||
SetUInt32Value(GAMEOBJECT_FLAGS, goinfo->flags);
|
||||
|
||||
SetGoType(GAMEOBJECT_TYPE_TRANSPORT);
|
||||
SetEntry(goinfo->id);
|
||||
|
||||
//SetDisplayId(goinfo->displayId);
|
||||
// Use SetDisplayId only if we have the GO assigned to a proper map!
|
||||
SetFloatValue(GAMEOBJECT_POS_X, gdata->posX);
|
||||
SetFloatValue(GAMEOBJECT_POS_Y, gdata->posY);
|
||||
SetFloatValue(GAMEOBJECT_POS_Z, gdata->posZ);
|
||||
SetUInt32Value(GAMEOBJECT_FACTION, goinfo->faction);
|
||||
SetUInt32Value(GAMEOBJECT_FLAGS, goinfo->flags);
|
||||
SetUInt32Value(GAMEOBJECT_DISPLAYID, goinfo->displayId);
|
||||
|
||||
SetGoState(GO_STATE_READY);
|
||||
SetGoType(GameobjectTypes(goinfo->type));
|
||||
SetGoAnimProgress(GO_ANIMPROGRESS_DEFAULT);
|
||||
SetName(goinfo->name);
|
||||
return true;
|
||||
}
|
||||
|
||||
SetGoAnimProgress(animprogress);
|
||||
//*****************************//
|
||||
// GlobalTransport
|
||||
//*****************************//
|
||||
GlobalTransport::GlobalTransport() : Transport()
|
||||
{
|
||||
}
|
||||
|
||||
GlobalTransport::~GlobalTransport()
|
||||
{
|
||||
}
|
||||
|
||||
bool GlobalTransport::Initialize(uint32 entry, uint32 period, std::string const& name)
|
||||
{
|
||||
const GameObjectInfo* goinfo = ObjectMgr::GetGameObjectInfo(entry);
|
||||
if (!goinfo)
|
||||
{
|
||||
sLog.outErrorDb("Transport ID:%u, Name: %s, will not be loaded, gameobject_template missing", entry, name.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (goinfo->type != GAMEOBJECT_TYPE_MO_TRANSPORT)
|
||||
{
|
||||
sLog.outErrorDb("Transport ID:%u, Name: %s, will not be loaded, gameobject_template type wrong", entry, name.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
m_period = period;
|
||||
SetGOInfo(goinfo); //order is important. GenerateWaypoints needs m_goInfo access
|
||||
|
||||
if (!GenerateWaypoints())
|
||||
{
|
||||
sLog.outErrorDb("Transport (path id %u) path size = 0. Transport ignored, check DBC files or transport GO data0 field.", goinfo->moTransport.taxiPathId);
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32 mapid = m_WayPoints[0].mapid;
|
||||
|
||||
// no global transports in dungeons
|
||||
const MapEntry* pMapInfo = sMapStore.LookupEntry(mapid);
|
||||
if (!pMapInfo || pMapInfo->Instanceable())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
Map* m = sMapMgr.CreateMap(mapid, this);
|
||||
if (m == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
float x = m_WayPoints[0].x;
|
||||
float y = m_WayPoints[0].y;
|
||||
float z = m_WayPoints[0].z;
|
||||
float o = 0.0f;
|
||||
|
||||
SetMap(m);
|
||||
Relocate(x, y, z, o);
|
||||
|
||||
if (!IsPositionValid())
|
||||
{
|
||||
sLog.outError("Transport ID:%u not created. Suggested coordinates are not valid: (X, Y, Z)=(%f, %f, %f)", goinfo->id, x, y, z);
|
||||
return false;
|
||||
}
|
||||
|
||||
Object::_Create(goinfo->id, 0, HIGHGUID_MO_TRANSPORT);
|
||||
|
||||
SetObjectScale(goinfo->size);
|
||||
SetGoType(GAMEOBJECT_TYPE_MO_TRANSPORT);
|
||||
SetUInt32Value(GAMEOBJECT_FACTION, goinfo->faction);
|
||||
SetUInt32Value(GAMEOBJECT_FLAGS, goinfo->flags);
|
||||
SetEntry(goinfo->id);
|
||||
SetUInt32Value(GAMEOBJECT_DISPLAYID, goinfo->displayId);
|
||||
SetGoState(GO_STATE_READY);
|
||||
SetGoAnimProgress(GO_ANIMPROGRESS_DEFAULT);
|
||||
SetName(goinfo->name);
|
||||
|
||||
return true;
|
||||
@ -210,16 +335,21 @@ struct keyFrame
|
||||
float tFrom, tTo;
|
||||
};
|
||||
|
||||
bool Transport::GenerateWaypoints(uint32 pathid, std::set<uint32>& mapids)
|
||||
bool GlobalTransport::GenerateWaypoints()
|
||||
{
|
||||
uint32 pathid = GetGOInfo()->moTransport.taxiPathId;
|
||||
|
||||
if (pathid >= sTaxiPathNodesByPath.size())
|
||||
{ return false; }
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
TaxiPathNodeList const& path = sTaxiPathNodesByPath[pathid];
|
||||
|
||||
std::vector<keyFrame> keyFrames;
|
||||
int mapChange = 0;
|
||||
mapids.clear();
|
||||
|
||||
m_mapsUsed.clear();
|
||||
for (size_t i = 1; i < path.size() - 1; ++i)
|
||||
{
|
||||
if (mapChange == 0)
|
||||
@ -229,7 +359,7 @@ bool Transport::GenerateWaypoints(uint32 pathid, std::set<uint32>& mapids)
|
||||
{
|
||||
keyFrame k(node_i);
|
||||
keyFrames.push_back(k);
|
||||
mapids.insert(k.node->mapid);
|
||||
m_mapsUsed.insert(k.node->mapid);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -428,7 +558,7 @@ bool Transport::GenerateWaypoints(uint32 pathid, std::set<uint32>& mapids)
|
||||
return true;
|
||||
}
|
||||
|
||||
void Transport::MoveToNextWayPoint()
|
||||
void GlobalTransport::MoveToNextWayPoint()
|
||||
{
|
||||
m_curr = m_next;
|
||||
|
||||
@ -437,40 +567,35 @@ void Transport::MoveToNextWayPoint()
|
||||
{ m_next = m_WayPoints.begin(); }
|
||||
}
|
||||
|
||||
void Transport::TeleportTransport(uint32 newMapid, float x, float y, float z)
|
||||
void GlobalTransport::TeleportTransport(uint32 newMapid, float x, float y, float z)
|
||||
{
|
||||
Map const* oldMap = GetMap();
|
||||
Map* newMap = sMapMgr.CreateMap(newMapid, this);
|
||||
SetMap(newMap);
|
||||
Relocate(x, y, z);
|
||||
|
||||
for (PlayerSet::iterator itr = m_passengers.begin(); itr != m_passengers.end();)
|
||||
for (UnitSet::iterator itr = m_passengers.begin(); itr != m_passengers.end();)
|
||||
{
|
||||
PlayerSet::iterator it2 = itr;
|
||||
UnitSet::iterator it2 = itr;
|
||||
++itr;
|
||||
|
||||
Player* plr = *it2;
|
||||
if (!plr)
|
||||
Unit* unit = *it2;
|
||||
if (!unit)
|
||||
{
|
||||
m_passengers.erase(it2);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (plr->IsDead() && !plr->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_GHOST))
|
||||
if (Player* plr = unit->ToPlayer())
|
||||
{
|
||||
plr->ResurrectPlayer(1.0);
|
||||
if (plr->IsDead() && !plr->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_GHOST))
|
||||
{
|
||||
plr->ResurrectPlayer(1.0);
|
||||
}
|
||||
plr->TeleportTo(newMapid, x, y, z, GetOrientation(), TELE_TO_NOT_LEAVE_TRANSPORT);
|
||||
}
|
||||
plr->TeleportTo(newMapid, x, y, z, GetOrientation(), TELE_TO_NOT_LEAVE_TRANSPORT);
|
||||
|
||||
// WorldPacket data(SMSG_811, 4);
|
||||
// data << uint32(0);
|
||||
// plr->GetSession()->SendPacket(&data);
|
||||
}
|
||||
|
||||
// we need to create and save new Map object with 'newMapid' because if not done -> lead to invalid Map object reference...
|
||||
// player far teleport would try to create same instance, but we need it NOW for transport...
|
||||
// correct me if I'm wrong O.o
|
||||
Map* newMap = sMapMgr.CreateMap(newMapid, this);
|
||||
SetMap(newMap);
|
||||
|
||||
if (oldMap != newMap)
|
||||
{
|
||||
UpdateForMap(oldMap);
|
||||
@ -478,24 +603,7 @@ void Transport::TeleportTransport(uint32 newMapid, float x, float y, float z)
|
||||
}
|
||||
}
|
||||
|
||||
bool Transport::AddPassenger(Player* passenger)
|
||||
{
|
||||
if (m_passengers.find(passenger) == m_passengers.end())
|
||||
{
|
||||
DETAIL_LOG("Player %s boarded transport %s.", passenger->GetName(), GetName());
|
||||
m_passengers.insert(passenger);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Transport::RemovePassenger(Player* passenger)
|
||||
{
|
||||
if (m_passengers.erase(passenger))
|
||||
{ DETAIL_LOG("Player %s removed from transport %s.", passenger->GetName(), GetName()); }
|
||||
return true;
|
||||
}
|
||||
|
||||
void Transport::Update(uint32 /*update_diff*/, uint32 /*p_time*/)
|
||||
void GlobalTransport::Update(uint32 /*update_diff*/, uint32 /*p_time*/)
|
||||
{
|
||||
if (m_WayPoints.size() <= 1)
|
||||
{ return; }
|
||||
@ -515,15 +623,6 @@ void Transport::Update(uint32 /*update_diff*/, uint32 /*p_time*/)
|
||||
Relocate(m_curr->second.x, m_curr->second.y, m_curr->second.z);
|
||||
}
|
||||
|
||||
/*
|
||||
for(PlayerSet::const_iterator itr = m_passengers.begin(); itr != m_passengers.end();)
|
||||
{
|
||||
PlayerSet::const_iterator it2 = itr;
|
||||
++itr;
|
||||
//(*it2)->SetPosition( m_curr->second.x + (*it2)->GetTransOffsetX(), m_curr->second.y + (*it2)->GetTransOffsetY(), m_curr->second.z + (*it2)->GetTransOffsetZ(), (*it2)->GetTransOffsetO() );
|
||||
}
|
||||
*/
|
||||
|
||||
m_nextNodeTime = m_curr->first;
|
||||
|
||||
if (m_curr == m_WayPoints.begin())
|
||||
@ -533,7 +632,7 @@ void Transport::Update(uint32 /*update_diff*/, uint32 /*p_time*/)
|
||||
}
|
||||
}
|
||||
|
||||
void Transport::UpdateForMap(Map const* targetMap)
|
||||
void GlobalTransport::UpdateForMap(Map const* targetMap)
|
||||
{
|
||||
Map::PlayerList const& pl = targetMap->GetPlayers();
|
||||
if (pl.isEmpty())
|
||||
|
@ -31,19 +31,57 @@
|
||||
#include <set>
|
||||
#include <string>
|
||||
|
||||
typedef std::set<Unit*> UnitSet;
|
||||
|
||||
//Base class for all transporter types
|
||||
class Transport : public GameObject
|
||||
{
|
||||
public:
|
||||
|
||||
explicit Transport();
|
||||
virtual ~Transport();
|
||||
|
||||
bool Create(uint32 guidlow, uint32 mapid, float x, float y, float z, float ang, uint32 animprogress);
|
||||
bool GenerateWaypoints(uint32 pathid, std::set<uint32>& mapids);
|
||||
void Update(uint32 update_diff, uint32 p_time) override;
|
||||
bool AddPassenger(Player* passenger);
|
||||
bool RemovePassenger(Player* passenger);
|
||||
bool AddPassenger(Unit* passenger);
|
||||
bool RemovePassenger(Unit* passenger);
|
||||
|
||||
typedef std::set<Player*> PlayerSet;
|
||||
PlayerSet const& GetPassengers() const { return m_passengers; }
|
||||
virtual void Update(uint32 update_diff, uint32 p_time) = 0;
|
||||
virtual void DeleteFromDB() override {}
|
||||
|
||||
UnitSet const& GetPassengers() const { return m_passengers; }
|
||||
|
||||
protected:
|
||||
UnitSet m_passengers;
|
||||
|
||||
};
|
||||
|
||||
|
||||
class LocalTransport : public Transport
|
||||
{
|
||||
public:
|
||||
explicit LocalTransport();
|
||||
virtual ~LocalTransport();
|
||||
bool Initialize(uint32 guid, Map* m);
|
||||
virtual void Update(uint32 update_diff, uint32 p_time) override {} //NYI
|
||||
private:
|
||||
uint32 m_period;
|
||||
};
|
||||
|
||||
|
||||
class GlobalTransport : public Transport
|
||||
{
|
||||
public:
|
||||
explicit GlobalTransport();
|
||||
virtual ~GlobalTransport();
|
||||
virtual void Update(uint32 update_diff, uint32 p_time) override;
|
||||
|
||||
bool Initialize(uint32 entry, uint32 period, std::string const& name);
|
||||
std::set<uint32> const* GetMapsUsed() const { return &m_mapsUsed; }
|
||||
|
||||
private:
|
||||
bool GenerateWaypoints();
|
||||
void TeleportTransport(uint32 newMapid, float x, float y, float z);
|
||||
void UpdateForMap(Map const* map);
|
||||
void MoveToNextWayPoint(); // move m_next/m_cur to next points
|
||||
|
||||
private:
|
||||
struct WayPoint
|
||||
@ -60,21 +98,15 @@ class Transport : public GameObject
|
||||
|
||||
typedef std::map<uint32, WayPoint> WayPointMap;
|
||||
|
||||
WayPointMap m_WayPoints;
|
||||
WayPointMap::const_iterator m_curr;
|
||||
WayPointMap::const_iterator m_next;
|
||||
|
||||
std::set<uint32> m_mapsUsed;
|
||||
|
||||
uint32 m_pathTime;
|
||||
uint32 m_timer;
|
||||
|
||||
PlayerSet m_passengers;
|
||||
|
||||
public:
|
||||
WayPointMap m_WayPoints;
|
||||
uint32 m_nextNodeTime;
|
||||
uint32 m_period;
|
||||
|
||||
private:
|
||||
void TeleportTransport(uint32 newMapid, float x, float y, float z);
|
||||
void UpdateForMap(Map const* map);
|
||||
void MoveToNextWayPoint(); // move m_next/m_cur to next points
|
||||
};
|
||||
#endif
|
||||
|
@ -1349,9 +1349,6 @@ void World::SetInitialWorldSettings()
|
||||
sLog.outString("Starting Outdoor PvP System");
|
||||
sOutdoorPvPMgr.InitOutdoorPvP();
|
||||
|
||||
// Not sure if this can be moved up in the sequence (with static data loading) as it uses MapManager
|
||||
sLog.outString("Loading Transports...");
|
||||
sMapMgr.LoadTransports();
|
||||
|
||||
// Initialize Warden
|
||||
sLog.outString("Loading Warden Checks...");
|
||||
@ -1377,8 +1374,12 @@ void World::SetInitialWorldSettings()
|
||||
m_timers[WUPDATE_EVENTS].SetInterval(nextGameEvent); // depend on next event
|
||||
sLog.outString();
|
||||
|
||||
sLog.outString("Loading grids for active creatures or transports...");
|
||||
sObjectMgr.LoadActiveEntities(NULL);
|
||||
sLog.outString("Loading grids for active creatures and local transports...");
|
||||
sMapMgr.LoadContinents();
|
||||
sLog.outString();
|
||||
|
||||
sLog.outString("Loading global transports...");
|
||||
sMapMgr.LoadTransports();
|
||||
sLog.outString();
|
||||
|
||||
// Delete all characters which have been deleted X days before
|
||||
|
@ -1,60 +0,0 @@
|
||||
# MaNGOS is a full featured server for World of Warcraft, supporting
|
||||
# the following clients: 1.12.x, 2.4.3, 3.2.5a, 4.2.3 and 5.4.8
|
||||
#
|
||||
# Copyright (C) 2005-2016 MaNGOS project <https://getmangos.eu>
|
||||
#
|
||||
# ***** BEGIN GPL LICENSE BLOCK *****
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#
|
||||
# ***** END GPL LICENSE BLOCK *****
|
||||
#
|
||||
# World of Warcraft, and all World of Warcraft or Warcraft art, images,
|
||||
# and lore are copyrighted by Blizzard Entertainment, Inc.
|
||||
|
||||
include(MacroMangosSourceGroup)
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Define the movement library
|
||||
file(GLOB sources *.cpp)
|
||||
file(GLOB headers *.h)
|
||||
|
||||
set(movement_LIB_SRCS ${sources} ${headers})
|
||||
|
||||
mangos_source_group(${movement_LIB_SRCS})
|
||||
|
||||
include_directories(
|
||||
${ACE_INCLUDE_DIRS}
|
||||
${MYSQL_INCLUDE_DIR}
|
||||
${CMAKE_SOURCE_DIR}/dep/include/g3dlite/
|
||||
${CMAKE_SOURCE_DIR}/dep/recastnavigation/Detour/Include/
|
||||
${CMAKE_SOURCE_DIR}/src/framework/
|
||||
${CMAKE_SOURCE_DIR}/src/shared/
|
||||
${CMAKE_SOURCE_DIR}/src/game/
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
${CMAKE_BINARY_DIR}
|
||||
${CMAKE_BINARY_DIR}/src/shared/
|
||||
)
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Build the movement library
|
||||
add_library(mangos-movement STATIC ${movement_LIB_SRCS})
|
||||
target_link_libraries(mangos-movement mangos-shared mangos-framework Detour g3dlite ${ACE_LIBRARIES} ${MYSQL_LIBRARIES})
|
||||
|
||||
if(${CMAKE_BUILD_TYPE} MATCHES Debug)
|
||||
set(BUILD_PROPERTIES "-DMANGOS_DEBUG")
|
||||
set_target_properties(mangos-movement PROPERTIES COMPILE_FLAGS ${BUILD_PROPERTIES})
|
||||
endif()
|
@ -1,59 +0,0 @@
|
||||
# MaNGOS is a full featured server for World of Warcraft, supporting
|
||||
# the following clients: 1.12.x, 2.4.3, 3.2.5a, 4.2.3 and 5.4.8
|
||||
#
|
||||
# Copyright (C) 2005-2016 MaNGOS project <https://getmangos.eu>
|
||||
#
|
||||
# ***** BEGIN GPL LICENSE BLOCK *****
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#
|
||||
# ***** END GPL LICENSE BLOCK *****
|
||||
#
|
||||
# World of Warcraft, and all World of Warcraft or Warcraft art, images,
|
||||
# and lore are copyrighted by Blizzard Entertainment, Inc.
|
||||
|
||||
include(MacroMangosSourceGroup)
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Define the vmap library
|
||||
file(GLOB sources *.cpp)
|
||||
file(GLOB headers *.h)
|
||||
|
||||
set(vmap_LIB_SRCS ${sources} ${headers})
|
||||
|
||||
mangos_source_group(${vmap_LIB_SRCS})
|
||||
|
||||
include_directories(
|
||||
${ACE_INCLUDE_DIRS}
|
||||
${MYSQL_INCLUDE_DIR}
|
||||
${CMAKE_SOURCE_DIR}/dep/g3dlite/
|
||||
${CMAKE_SOURCE_DIR}/src/framework/
|
||||
${CMAKE_SOURCE_DIR}/src/shared/
|
||||
${CMAKE_SOURCE_DIR}/src/game/
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
${CMAKE_BINARY_DIR}
|
||||
${CMAKE_BINARY_DIR}/src/shared/
|
||||
)
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Build the vmap library
|
||||
add_library(mangos-vmap STATIC ${vmap_LIB_SRCS})
|
||||
target_link_libraries(mangos-vmap mangos-shared mangos-framework g3dlite ${ACE_LIBRARIES} ${MYSQL_LIBRARIES})
|
||||
|
||||
if(${CMAKE_BUILD_TYPE} MATCHES Debug)
|
||||
set(BUILD_PROPERTIES "-DMANGOS_DEBUG")
|
||||
set_target_properties(mangos-vmap PROPERTIES COMPILE_FLAGS ${BUILD_PROPERTIES})
|
||||
endif()
|
@ -192,7 +192,7 @@ bool GameObjectModel::GetIntersectPoint(const G3D::Vector3& srcPoint, G3D::Vecto
|
||||
{
|
||||
G3D::Vector3 p;
|
||||
if (absolute)
|
||||
p = (iQuat * G3D::Quat((srcPoint - iPos) * iInvScale) * iQuat.conj()).imag();
|
||||
p = (iQuat.conj() * G3D::Quat((srcPoint - iPos) * iInvScale) * iQuat).imag();
|
||||
else
|
||||
p = srcPoint;
|
||||
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 4aba0d6da2f637cee2c3eb0c7b6f255cf6fe0aa9
|
||||
Subproject commit 57214b69c71d6a0d5ff2a353b4e3f8881317fe86
|
@ -1 +1 @@
|
||||
Subproject commit f52ae4ad1e5baddb4dd9476e81fe177ab9ca5f4f
|
||||
Subproject commit 888c9c332d3251adf7b9945a89ba44a16c84486d
|
Loading…
x
Reference in New Issue
Block a user