Core/Phases: Ported new phasing system from 4.3.4 branch and fixed some map swap logic

This commit is contained in:
Rat
2015-03-16 07:28:49 +01:00
parent 8366ed5a72
commit 8f3a80c1cf
41 changed files with 744 additions and 322 deletions
+12
View File
@@ -0,0 +1,12 @@
DELETE FROM `rbac_permissions` WHERE `id`=776;
INSERT INTO `rbac_permissions` (`id`, `name`) VALUES (776, 'Command: debug phase');
DELETE FROM `rbac_linked_permissions` WHERE `id`=192 AND linkedId=776;
INSERT INTO `rbac_linked_permissions` (`id`, `linkedId`) VALUES (192, 776);
DELETE FROM `rbac_permissions` WHERE `id`=776;
INSERT INTO `rbac_permissions` (`id`, `name`) VALUES (776, 'Command: debug phase');
DELETE FROM `rbac_linked_permissions` WHERE `id`=192 AND linkedId=776;
INSERT INTO `rbac_linked_permissions` (`id`, `linkedId`) VALUES (192, 776);
@@ -0,0 +1,11 @@
ALTER TABLE `corpse` DROP `phaseMask`;
DROP TABLE IF EXISTS `corpse_phases`;
CREATE TABLE `corpse_phases` (
`Guid` int(10) unsigned NOT NULL,
`PhaseId` int(10) unsigned NOT NULL,
`OwnerGuid` int(10) unsigned NOT NULL,
`Time` int(10) unsigned NOT NULL DEFAULT '0',
`CorpseType` tinyint(3) unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`Guid`,`PhaseId`)
);
+53
View File
@@ -0,0 +1,53 @@
DROP TABLE IF EXISTS `phase_definitions`;
DROP TABLE IF EXISTS `phase_info`;
DROP TABLE IF EXISTS `terrain_phase_info`;
DROP TABLE IF EXISTS `terrain_map_info`;
DROP TABLE IF EXISTS `terrain_swap_defaults`;
DROP TABLE IF EXISTS `terrain_worldmap`;
DROP TABLE IF EXISTS `phase_area`;
CREATE TABLE `terrain_phase_info`(
`Id` INT(10) unsigned NOT NULL,
`TerrainSwapMap` INT(10) unsigned NOT NULL,
`Comment` VARCHAR(255),
PRIMARY KEY (`Id`, `TerrainSwapMap`)
);
CREATE TABLE `terrain_swap_defaults`(
`MapId` INT(10) unsigned NOT NULL,
`TerrainSwapMap` INT(10) unsigned NOT NULL,
`Comment` VARCHAR(255),
PRIMARY KEY (`MapId`, `TerrainSwapMap`)
);
CREATE TABLE `terrain_worldmap`(
`TerrainSwapMap` INT(10) unsigned NOT NULL,
`WorldMapArea` INT(10) unsigned NOT NULL,
`Comment` VARCHAR(255),
PRIMARY KEY (`TerrainSwapMap`, `WorldMapArea`)
);
CREATE TABLE `phase_area` (
`AreaId` int(10) unsigned NOT NULL,
`PhaseId` int(10) unsigned NOT NULL,
`Comment` varchar(255) DEFAULT NULL,
PRIMARY KEY (`AreaId`,`PhaseId`)
);
INSERT INTO `terrain_phase_info` (Id, TerrainSwapMap, Comment) VALUES
(182, 655, 'Quest Zone-Specific 07'),
(186, 656, 'Quest Zone-Specific 11');
INSERT INTO `terrain_worldmap` (TerrainSwapMap, WorldMapArea, Comment) VALUES
(638, 545, 'Gilneas'),
(655, 678, 'Gilneas_terrain1'),
(719, 683, 'Hyjal_terrain1'),
(656, 679, 'Gilneas_terrain2');
INSERT INTO `terrain_swap_defaults` (MapId, TerrainSwapMap, Comment) VALUES
(1, 719, 'Mount Hyjal default terrain'),
(654, 638, 'Gilneas default terrain');
DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=25 AND `SourceEntry`=719;
INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
(25, 0, 719, 0, 0, 8, 0, 25372, 0, 0, 1, 0, 0, '', 'Hyjal terrain swap if Aessina''s Miracle quest is not rewarded');
+18 -44
View File
@@ -416,6 +416,11 @@ bool Condition::Meets(ConditionSourceInfo& sourceInfo)
condMeets = creature->GetCreatureTemplate()->type == ConditionValue1;
break;
}
case CONDITION_TERRAIN_SWAP:
{
condMeets = object->IsInTerrainSwap(ConditionValue1);
break;
}
default:
condMeets = false;
break;
@@ -585,6 +590,9 @@ uint32 Condition::GetSearcherTypeMaskForCondition()
case CONDITION_CREATURE_TYPE:
mask |= GRID_MAP_TYPE_MASK_CREATURE;
break;
case CONDITION_TERRAIN_SWAP:
mask |= GRID_MAP_TYPE_MASK_ALL;
break;
default:
ASSERT(false && "Condition::GetSearcherTypeMaskForCondition - missing condition handling!");
break;
@@ -784,7 +792,6 @@ bool ConditionMgr::CanHaveSourceGroupSet(ConditionSourceType sourceType)
sourceType == CONDITION_SOURCE_TYPE_SPELL_IMPLICIT_TARGET ||
sourceType == CONDITION_SOURCE_TYPE_SPELL_CLICK_EVENT ||
sourceType == CONDITION_SOURCE_TYPE_SMART_EVENT ||
sourceType == CONDITION_SOURCE_TYPE_PHASE_DEFINITION ||
sourceType == CONDITION_SOURCE_TYPE_NPC_VENDOR);
}
@@ -860,22 +867,6 @@ ConditionList ConditionMgr::GetConditionsForSmartEvent(int64 entryOrGuid, uint32
return cond;
}
ConditionList const* ConditionMgr::GetConditionsForPhaseDefinition(uint32 zone, uint32 entry)
{
PhaseDefinitionConditionContainer::const_iterator itr = PhaseDefinitionsConditionStore.find(zone);
if (itr != PhaseDefinitionsConditionStore.end())
{
ConditionTypeContainer::const_iterator i = itr->second.find(entry);
if (i != itr->second.end())
{
TC_LOG_DEBUG("condition", "GetConditionsForPhaseDefinition: found conditions for zone %u entry %u", zone, entry);
return &i->second;
}
}
return NULL;
}
ConditionList ConditionMgr::GetConditionsForNpcVendorEvent(uint32 creatureId, uint32 itemId)
{
ConditionList cond;
@@ -1115,13 +1106,6 @@ void ConditionMgr::LoadConditions(bool isReload)
++count;
continue;
}
case CONDITION_SOURCE_TYPE_PHASE_DEFINITION:
{
PhaseDefinitionsConditionStore[cond->SourceGroup][cond->SourceEntry].push_back(cond);
valid = true;
++count;
continue;
}
case CONDITION_SOURCE_TYPE_NPC_VENDOR:
{
NpcVendorConditionContainerStore[cond->SourceGroup][cond->SourceEntry].push_back(cond);
@@ -1650,13 +1634,6 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
return false;
}
break;
case CONDITION_SOURCE_TYPE_PHASE_DEFINITION:
/*if (!PhaseMgr::IsConditionTypeSupported(cond->ConditionType))
{
TC_LOG_ERROR("sql.sql", "Condition source type `CONDITION_SOURCE_TYPE_PHASE_DEFINITION` does not support condition type %u, ignoring.", cond->ConditionType);
return false;
}*/
break;
case CONDITION_SOURCE_TYPE_NPC_VENDOR:
{
if (!sObjectMgr->GetCreatureTemplate(cond->SourceGroup))
@@ -1676,6 +1653,8 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
case CONDITION_SOURCE_TYPE_GOSSIP_MENU_OPTION:
case CONDITION_SOURCE_TYPE_SMART_EVENT:
case CONDITION_SOURCE_TYPE_NONE:
case CONDITION_SOURCE_TYPE_TERRAIN_SWAP:
case CONDITION_SOURCE_TYPE_PHASE:
default:
break;
}
@@ -2075,6 +2054,14 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond)
}
break;
}
case CONDITION_TERRAIN_SWAP:
{
if (cond->ConditionValue2)
TC_LOG_ERROR("sql.sql", "Terrain swap condition has useless data in value2 (%u)!", cond->ConditionValue2);
if (cond->ConditionValue3)
TC_LOG_ERROR("sql.sql", "Terrain swap condition has useless data in value3 (%u)!", cond->ConditionValue3);
break;
}
case CONDITION_TITLE:
{
CharTitlesEntry const* titleEntry = sCharTitlesStore.LookupEntry(cond->ConditionValue1);
@@ -2198,19 +2185,6 @@ void ConditionMgr::Clean()
SpellClickEventConditionStore.clear();
for (PhaseDefinitionConditionContainer::iterator itr = PhaseDefinitionsConditionStore.begin(); itr != PhaseDefinitionsConditionStore.end(); ++itr)
{
for (ConditionTypeContainer::iterator it = itr->second.begin(); it != itr->second.end(); ++it)
{
for (ConditionList::const_iterator i = it->second.begin(); i != it->second.end(); ++i)
delete *i;
it->second.clear();
}
itr->second.clear();
}
PhaseDefinitionsConditionStore.clear();
for (NpcVendorConditionContainer::iterator itr = NpcVendorConditionContainerStore.begin(); itr != NpcVendorConditionContainerStore.end(); ++itr)
{
for (ConditionTypeContainer::iterator it = itr->second.begin(); it != itr->second.end(); ++it)
+5 -6
View File
@@ -72,7 +72,8 @@ enum ConditionTypes
CONDITION_ALIVE = 36, // 0 0 0 true if unit is alive
CONDITION_HP_VAL = 37, // hpVal ComparisonType 0 true if unit's hp matches given value
CONDITION_HP_PCT = 38, // hpPct ComparisonType 0 true if unit's hp matches given pct
CONDITION_MAX = 39 // MAX
CONDITION_TERRAIN_SWAP = 39, // terrainSwap 0 0 true if object is in terrainswap
CONDITION_MAX = 40 // MAX
};
/*! Documentation on implementing a new ConditionSourceType:
@@ -129,8 +130,9 @@ enum ConditionSourceType
CONDITION_SOURCE_TYPE_SMART_EVENT = 22,
CONDITION_SOURCE_TYPE_NPC_VENDOR = 23,
CONDITION_SOURCE_TYPE_SPELL_PROC = 24,
CONDITION_SOURCE_TYPE_PHASE_DEFINITION = 25, // only 4.3.4
CONDITION_SOURCE_TYPE_MAX = 26 // MAX
CONDITION_SOURCE_TYPE_TERRAIN_SWAP = 25,
CONDITION_SOURCE_TYPE_PHASE = 26,
CONDITION_SOURCE_TYPE_MAX = 27 // MAX
};
enum RelationType
@@ -221,7 +223,6 @@ typedef std::map<ConditionSourceType, ConditionTypeContainer> ConditionContainer
typedef std::map<uint32, ConditionTypeContainer> CreatureSpellConditionContainer;
typedef std::map<uint32, ConditionTypeContainer> NpcVendorConditionContainer;
typedef std::map<std::pair<int32, uint32 /*SAI source_type*/>, ConditionTypeContainer> SmartEventConditionContainer;
typedef std::map<int32 /*zoneId*/, ConditionTypeContainer> PhaseDefinitionConditionContainer;
typedef std::map<uint32, ConditionList> ConditionReferenceContainer;//only used for references
@@ -252,7 +253,6 @@ class ConditionMgr
ConditionList GetConditionsForSpellClickEvent(uint32 creatureId, uint32 spellId);
ConditionList GetConditionsForSmartEvent(int64 entryOrGuid, uint32 eventId, uint32 sourceType);
ConditionList GetConditionsForVehicleSpell(uint32 creatureId, uint32 spellId);
ConditionList const* GetConditionsForPhaseDefinition(uint32 zone, uint32 entry);
ConditionList GetConditionsForNpcVendorEvent(uint32 creatureId, uint32 itemId);
struct ConditionTypeInfo
@@ -284,7 +284,6 @@ class ConditionMgr
CreatureSpellConditionContainer SpellClickEventConditionStore;
NpcVendorConditionContainer NpcVendorConditionContainerStore;
SmartEventConditionContainer SmartEventConditionStore;
PhaseDefinitionConditionContainer PhaseDefinitionsConditionStore;
};
#define sConditionMgr ConditionMgr::instance()
@@ -78,8 +78,7 @@ bool AreaTrigger::CreateAreaTrigger(ObjectGuid::LowType guidlow, uint32 triggerE
SetUInt32Value(AREATRIGGER_SPELLVISUALID, spell->SpellVisual[0]);
SetUInt32Value(AREATRIGGER_DURATION, spell->GetDuration());
for (auto phase : caster->GetPhases())
SetInPhase(phase, false, true);
CopyPhaseFrom(caster);
if (!GetMap()->AddToMap(this))
return false;
+30 -8
View File
@@ -94,6 +94,8 @@ bool Corpse::Create(ObjectGuid::LowType guidlow, Player* owner)
_gridCoord = Trinity::ComputeGridCoord(GetPositionX(), GetPositionY());
CopyPhaseFrom(owner);
return true;
}
@@ -121,9 +123,20 @@ void Corpse::SaveToDB()
stmt->setUInt32(index++, uint32(m_time)); // time
stmt->setUInt8 (index++, GetType()); // corpseType
stmt->setUInt32(index++, GetInstanceId()); // instanceId
stmt->setUInt32(index++, GetPhaseMask()); // phaseMask
trans->Append(stmt);
for (uint32 phaseId : GetPhases())
{
index = 0;
stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CORPSE_PHASES);
stmt->setUInt32(index++, GetGUID().GetCounter()); // Guid (corpse's)
stmt->setUInt32(index++, phaseId); // PhaseId
stmt->setUInt32(index++, GetOwnerGUID().GetCounter()); // OwnerGuid
stmt->setUInt32(index++, uint32(m_time)); // Time
stmt->setUInt8(index++, GetType()); // CorpseType
trans->Append(stmt);
}
CharacterDatabase.CommitTransaction(trans);
}
@@ -148,21 +161,31 @@ void Corpse::DeleteFromDB(SQLTransaction& trans)
{
// Only specific bones
stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CORPSE);
stmt->setUInt64(0, GetGUID().GetCounter());
stmt->setUInt32(0, GetGUID().GetCounter());
trans->Append(stmt);
stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CORPSE_PHASES);
stmt->setUInt32(0, GetGUID().GetCounter());
trans->Append(stmt);
}
else
{
// all corpses (not bones)
stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_PLAYER_CORPSES);
stmt->setUInt64(0, GetOwnerGUID().GetCounter());
stmt->setUInt32(0, GetOwnerGUID().GetCounter());
trans->Append(stmt);
stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_PLAYER_CORPSES_PHASES);
stmt->setUInt32(0, GetOwnerGUID().GetCounter());
trans->Append(stmt);
}
trans->Append(stmt);
}
bool Corpse::LoadCorpseFromDB(ObjectGuid::LowType guid, Field* fields)
{
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
// SELECT posX, posY, posZ, orientation, mapId, displayId, itemCache, bytes1, bytes2, flags, dynFlags, time, corpseType, instanceId, phaseMask, corpseGuid, guid FROM corpse WHERE corpseType <> 0
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
// SELECT posX, posY, posZ, orientation, mapId, displayId, itemCache, bytes1, bytes2, flags, dynFlags, time, corpseType, instanceId, corpseGuid, guid FROM corpse WHERE corpseType <> 0
float posX = fields[0].GetFloat();
float posY = fields[1].GetFloat();
@@ -178,12 +201,11 @@ bool Corpse::LoadCorpseFromDB(ObjectGuid::LowType guid, Field* fields)
SetUInt32Value(CORPSE_FIELD_BYTES_2, fields[8].GetUInt32());
SetUInt32Value(CORPSE_FIELD_FLAGS, fields[9].GetUInt8());
SetUInt32Value(CORPSE_FIELD_DYNAMIC_FLAGS, fields[10].GetUInt8());
SetGuidValue(CORPSE_FIELD_OWNER, ObjectGuid::Create<HighGuid::Player>(fields[16].GetUInt64()));
SetGuidValue(CORPSE_FIELD_OWNER, ObjectGuid::Create<HighGuid::Player>(fields[15].GetUInt64()));
m_time = time_t(fields[11].GetUInt32());
uint32 instanceId = fields[13].GetUInt32();
//uint32 phaseMask = fields[14].GetUInt32();
// place
SetLocationInstanceId(instanceId);
@@ -1011,6 +1011,9 @@ void Creature::SaveToDB(uint32 mapid, uint32 spawnMask, uint32 phaseMask)
data.npcflag = npcflag;
data.unit_flags = unit_flags;
data.dynamicflags = dynamicflags;
data.phaseid = GetDBPhase() > 0 ? GetDBPhase() : 0;
data.phaseGroup = GetDBPhase() < 0 ? abs(GetDBPhase()) : 0;
// update in DB
SQLTransaction trans = WorldDatabase.BeginTransaction();
@@ -1027,6 +1030,8 @@ void Creature::SaveToDB(uint32 mapid, uint32 spawnMask, uint32 phaseMask)
stmt->setUInt16(index++, uint16(mapid));
stmt->setUInt32(index++, spawnMask);
stmt->setUInt32(index++, GetPhaseMask());
stmt->setUInt32(index++, data.phaseid);
stmt->setUInt32(index++, data.phaseGroup);
stmt->setUInt32(index++, displayId);
stmt->setUInt8(index++, GetCurrentEquipmentId());
stmt->setFloat(index++, GetPositionX());
@@ -2163,11 +2163,13 @@ void GameObject::SetDisplayId(uint32 displayid)
UpdateModel();
}
void GameObject::SetInPhase(uint32 id, bool update, bool apply)
bool GameObject::SetInPhase(uint32 id, bool update, bool apply)
{
WorldObject::SetInPhase(id, update, apply);
bool res = WorldObject::SetInPhase(id, update, apply);
if (m_model && m_model->isEnabled())
EnableCollision(true);
return res;
}
void GameObject::EnableCollision(bool enable)
@@ -949,7 +949,7 @@ class GameObject : public WorldObject, public GridObject<GameObject>, public Map
void SetGoAnimProgress(uint8 animprogress) { SetByteValue(GAMEOBJECT_BYTES_1, 3, animprogress); }
static void SetGoArtKit(uint8 artkit, GameObject* go, ObjectGuid::LowType lowguid = UI64LIT(0));
void SetInPhase(uint32 id, bool update, bool apply);
bool SetInPhase(uint32 id, bool update, bool apply);
void EnableCollision(bool enable);
void Use(Unit* user);
+220 -20
View File
@@ -1557,7 +1557,7 @@ void MovementInfo::OutDebug()
WorldObject::WorldObject(bool isWorldObject) : WorldLocation(), LastUsedScriptID(0),
m_name(""), m_isActive(false), m_isWorldObject(isWorldObject), m_zoneScript(NULL),
m_transport(NULL), m_currMap(NULL), m_InstanceId(0),
m_phaseMask(PHASEMASK_NORMAL), m_notifyflags(0), m_executed_notifies(0)
m_phaseMask(PHASEMASK_NORMAL), _dbPhase(0), m_notifyflags(0), m_executed_notifies(0)
{
m_serverSideVisibility.SetValue(SERVERSIDE_VISIBILITY_GHOST, GHOST_VISIBILITY_ALIVE | GHOST_VISIBILITY_GHOST);
m_serverSideVisibilityDetect.SetValue(SERVERSIDE_VISIBILITY_GHOST, GHOST_VISIBILITY_ALIVE);
@@ -2463,10 +2463,6 @@ TempSummon* Map::SummonCreature(uint32 entry, Position const& pos, SummonPropert
}
}
std::set<uint32> phases;
if (summoner)
phases = summoner->GetPhases();
TempSummon* summon = NULL;
switch (mask)
{
@@ -2494,8 +2490,7 @@ TempSummon* Map::SummonCreature(uint32 entry, Position const& pos, SummonPropert
}
// Set the summon to the summoner's phase
for (auto phaseId : phases)
summon->SetInPhase(phaseId, false, true);
summon->CopyPhaseFrom(summoner);
summon->SetUInt32Value(UNIT_CREATED_BY_SPELL, spellId);
@@ -2591,8 +2586,7 @@ GameObject* WorldObject::SummonGameObject(uint32 entry, float x, float y, float
return NULL;
}
for (auto phase : GetPhases())
go->SetInPhase(phase, false, true);
go->CopyPhaseFrom(this);
go->SetRespawnTime(respawnTime);
if (GetTypeId() == TYPEID_PLAYER || GetTypeId() == TYPEID_UNIT) //not sure how to handle this
@@ -3003,12 +2997,138 @@ void WorldObject::SetPhaseMask(uint32 newPhaseMask, bool update)
UpdateObjectVisibility();
}
void WorldObject::SetInPhase(uint32 id, bool update, bool apply)
bool WorldObject::HasInPhaseList(uint32 phase)
{
if (apply)
_phases.insert(id);
else
_phases.erase(id);
return _phases.find(phase) != _phases.end();
}
// Updates Area based phases, does not remove phases from auras
// Phases from gm commands are not taken into calculations, they can be lost!!
void WorldObject::UpdateAreaPhase()
{
bool updateNeeded = false;
PhaseInfo phases = sObjectMgr->GetAreaPhases();
for (PhaseInfo::const_iterator itr = phases.begin(); itr != phases.end(); ++itr)
{
uint32 areaId = itr->first;
for (uint32 phaseId : itr->second)
{
if (areaId == GetAreaId())
{
ConditionList conditions = sConditionMgr->GetConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_PHASE, phaseId);
if (sConditionMgr->IsObjectMeetToConditions(this, conditions))
{
// add new phase if condition passed, true if it wasnt added before
bool up = SetInPhase(phaseId, false, true);
if (!updateNeeded && up)
updateNeeded = true;
}
else
{
// condition failed, remove phase, true if there was something removed
bool up = SetInPhase(phaseId, false, false);
if (!updateNeeded && up)
updateNeeded = true;
}
}
else
{
// not in area, remove phase, true if there was something removed
bool up = SetInPhase(phaseId, false, false);
if (!updateNeeded && up)
updateNeeded = true;
}
}
}
// do not remove a phase if it would be removed by an area but we have the same phase from an aura
if (Unit* unit = ToUnit())
{
Unit::AuraEffectList const& auraPhaseList = unit->GetAuraEffectsByType(SPELL_AURA_PHASE);
for (Unit::AuraEffectList::const_iterator itr = auraPhaseList.begin(); itr != auraPhaseList.end(); ++itr)
{
uint32 phase = uint32((*itr)->GetMiscValueB());
bool up = SetInPhase(phase, false, true);
if (!updateNeeded && up)
updateNeeded = true;
}
Unit::AuraEffectList const& auraPhaseGroupList = unit->GetAuraEffectsByType(SPELL_AURA_PHASE_GROUP);
for (Unit::AuraEffectList::const_iterator itr = auraPhaseGroupList.begin(); itr != auraPhaseGroupList.end(); ++itr)
{
bool up = false;
uint32 phaseGroup = uint32((*itr)->GetMiscValueB());
std::set<uint32> const& phases = sDB2Manager.GetPhasesForGroup(phaseGroup);
for (uint32 phase : phases)
up = SetInPhase(phase, false, true);
if (!updateNeeded && up)
updateNeeded = true;
}
}
// only update visibility and send packets if there was a change in the phase list
if (updateNeeded && GetTypeId() == TYPEID_PLAYER && IsInWorld())
ToPlayer()->GetSession()->SendSetPhaseShift(GetPhases(), GetTerrainSwaps(), GetWorldMapAreaSwaps());
// only update visibilty once, to prevent objects appearing for a moment while adding in multiple phases
if (updateNeeded && IsInWorld())
UpdateObjectVisibility();
}
bool WorldObject::SetInPhase(uint32 id, bool update, bool apply)
{
if (id)
{
if (apply)
{
if (HasInPhaseList(id)) // do not run the updates if we are already in this phase
return false;
_phases.insert(id);
}
else
{
for (uint32 phaseId : sObjectMgr->GetPhasesForArea(GetAreaId()))
{
if (id == phaseId)
{
ConditionList conditions = sConditionMgr->GetConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_PHASE, phaseId);
if (sConditionMgr->IsObjectMeetToConditions(this, conditions))
{
// if area phase passes the condition we should not remove it (ie: if remove called from aura remove)
// this however breaks the .mod phase command, you wont be able to remove any area based phases with it
return false;
}
}
}
if (!HasInPhaseList(id)) // do not run the updates if we are not in this phase
return false;
_phases.erase(id);
}
}
RebuildTerrainSwaps();
if (update && IsInWorld())
UpdateObjectVisibility();
return true;
}
void WorldObject::CopyPhaseFrom(WorldObject* obj, bool update)
{
if (!obj)
return;
for (uint32 phase : obj->GetPhases())
SetInPhase(phase, false, true);
if (update && IsInWorld())
UpdateObjectVisibility();
}
void WorldObject::ClearPhases(bool update)
{
_phases.clear();
RebuildTerrainSwaps();
if (update && IsInWorld())
UpdateObjectVisibility();
@@ -3026,13 +3146,10 @@ bool WorldObject::IsInPhase(WorldObject const* obj) const
if (obj->GetPhases().empty() && IsInPhase(169))
return true;
return Trinity::Containers::Intersects(_phases.begin(), _phases.end(), obj->GetPhases().begin(), obj->GetPhases().end());
}
if (GetTypeId() == TYPEID_PLAYER && ToPlayer()->IsGameMaster())
return true;
bool WorldObject::InSamePhase(WorldObject const* obj) const
{
return IsInPhase(obj);
// return InSamePhase(obj->GetPhaseMask());
return Trinity::Containers::Intersects(_phases.begin(), _phases.end(), obj->GetPhases().begin(), obj->GetPhases().end());
}
void WorldObject::PlayDistanceSound(uint32 sound_id, Player* target /*= NULL*/)
@@ -3181,3 +3298,86 @@ ObjectGuid WorldObject::GetTransGUID() const
return GetTransport()->GetGUID();
return ObjectGuid::Empty;
}
void WorldObject::RebuildTerrainSwaps()
{
// Clear all terrain swaps, will be rebuilt below
// Reason for this is, multiple phases can have the same terrain swap, we should not remove the swap if another phase still use it
_terrainSwaps.clear();
ConditionList conditions;
// Check all applied phases for terrain swap and add it only once
for (uint32 phaseId : _phases)
{
std::list<uint32>& swaps = sObjectMgr->GetPhaseTerrainSwaps(phaseId);
for (uint32 swap : swaps)
{
// only add terrain swaps for current map
MapEntry const* mapEntry = sMapStore.LookupEntry(swap);
if (!mapEntry || mapEntry->ParentMapID != GetMapId())
continue;
conditions = sConditionMgr->GetConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_TERRAIN_SWAP, swap);
if (sConditionMgr->IsObjectMeetToConditions(this, conditions))
_terrainSwaps.insert(swap);
}
}
// get default terrain swaps, only for current map always
std::list<uint32>& mapSwaps = sObjectMgr->GetDefaultTerrainSwaps(GetMapId());
for (uint32 swap : mapSwaps)
{
conditions = sConditionMgr->GetConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_TERRAIN_SWAP, swap);
if (sConditionMgr->IsObjectMeetToConditions(this, conditions))
_terrainSwaps.insert(swap);
}
// online players have a game client with world map display
if (GetTypeId() == TYPEID_PLAYER)
RebuildWorldMapAreaSwaps();
}
void WorldObject::RebuildWorldMapAreaSwaps()
{
// Clear all world map area swaps, will be rebuilt below
_worldMapAreaSwaps.clear();
// get ALL default terrain swaps, if we are using it (condition is true)
// send the worldmaparea for it, to see swapped worldmaparea in client from other maps too, not just from our current
TerrainPhaseInfo defaults = sObjectMgr->GetDefaultTerrainSwapStore();
for (TerrainPhaseInfo::const_iterator itr = defaults.begin(); itr != defaults.end(); ++itr)
{
for (uint32 swap : itr->second)
{
ConditionList conditions = sConditionMgr->GetConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_TERRAIN_SWAP, swap);
if (sConditionMgr->IsObjectMeetToConditions(this, conditions))
{
for (uint32 map : sObjectMgr->GetTerrainWorldMaps(swap))
_worldMapAreaSwaps.insert(map);
}
}
}
// Check all applied phases for world map area swaps
for (uint32 phaseId : _phases)
{
std::list<uint32>& swaps = sObjectMgr->GetPhaseTerrainSwaps(phaseId);
for (uint32 swap : swaps)
{
// add world map swaps for ANY map
ConditionList conditions = sConditionMgr->GetConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_TERRAIN_SWAP, swap);
if (sConditionMgr->IsObjectMeetToConditions(this, conditions))
{
for (uint32 map : sObjectMgr->GetTerrainWorldMaps(swap))
_worldMapAreaSwaps.insert(map);
}
}
}
}
+17 -3
View File
@@ -612,13 +612,24 @@ class WorldObject : public Object, public WorldLocation
uint32 GetInstanceId() const { return m_InstanceId; }
virtual void SetPhaseMask(uint32 newPhaseMask, bool update);
virtual void SetInPhase(uint32 id, bool update, bool apply);
virtual bool SetInPhase(uint32 id, bool update, bool apply);
void CopyPhaseFrom(WorldObject* obj, bool update = false);
void UpdateAreaPhase();
void ClearPhases(bool update = false);
void RebuildTerrainSwaps();
void RebuildWorldMapAreaSwaps();
bool HasInPhaseList(uint32 phase);
uint32 GetPhaseMask() const { return m_phaseMask; }
bool InSamePhase(WorldObject const* obj) const;
bool InSamePhase(uint32 phasemask) const { return (GetPhaseMask() & phasemask) != 0; }
bool IsInPhase(uint32 phase) const { return _phases.find(phase) != _phases.end(); }
bool IsInPhase(WorldObject const* obj) const;
bool IsInTerrainSwap(uint32 terrainSwap) const { return _terrainSwaps.find(terrainSwap) != _terrainSwaps.end(); }
std::set<uint32> const& GetPhases() const { return _phases; }
std::set<uint32> const& GetTerrainSwaps() const { return _terrainSwaps; }
std::set<uint32> const& GetWorldMapAreaSwaps() const { return _worldMapAreaSwaps; }
int32 GetDBPhase() { return _dbPhase; }
// if negative it is used as PhaseGroupId
void SetDBPhase(int32 p) { _dbPhase = p; }
uint32 GetZoneId() const;
uint32 GetAreaId() const;
@@ -791,6 +802,9 @@ class WorldObject : public Object, public WorldLocation
uint32 m_InstanceId; // in map copy with instance id
uint32 m_phaseMask; // in area phase state
std::set<uint32> _phases;
std::set<uint32> _terrainSwaps;
std::set<uint32> _worldMapAreaSwaps;
int32 _dbPhase;
uint16 m_notifyflags;
uint16 m_executed_notifies;
+7 -9
View File
@@ -176,11 +176,10 @@ bool Pet::LoadPetFromDB(Player* owner, uint32 petEntry, uint32 petnumber, bool c
}
Map* map = owner->GetMap();
if (!Create(sObjectMgr->GetGenerator<HighGuid::Pet>()->Generate(), map, owner->GetPhaseMask(), petEntry))
if (!Create(sObjectMgr->GetGenerator<HighGuid::Pet>()->Generate(), map, petEntry))
return false;
for (auto itr : owner->GetPhases())
SetInPhase(itr, false, true);
CopyPhaseFrom(owner);
setPetType(petType);
setFaction(owner->getFaction());
@@ -732,7 +731,7 @@ bool Pet::CreateBaseAtCreature(Creature* creature)
{
ASSERT(creature);
if (!CreateBaseAtTamed(creature->GetCreatureTemplate(), creature->GetMap(), creature->GetPhaseMask()))
if (!CreateBaseAtTamed(creature->GetCreatureTemplate(), creature->GetMap()))
return false;
Relocate(creature->GetPositionX(), creature->GetPositionY(), creature->GetPositionZ(), creature->GetOrientation());
@@ -763,7 +762,7 @@ bool Pet::CreateBaseAtCreature(Creature* creature)
bool Pet::CreateBaseAtCreatureInfo(CreatureTemplate const* cinfo, Unit* owner)
{
if (!CreateBaseAtTamed(cinfo, owner->GetMap(), owner->GetPhaseMask()))
if (!CreateBaseAtTamed(cinfo, owner->GetMap()))
return false;
if (CreatureFamilyEntry const* cFamily = sCreatureFamilyStore.LookupEntry(cinfo->family))
@@ -774,10 +773,10 @@ bool Pet::CreateBaseAtCreatureInfo(CreatureTemplate const* cinfo, Unit* owner)
return true;
}
bool Pet::CreateBaseAtTamed(CreatureTemplate const* cinfo, Map* map, uint32 phaseMask)
bool Pet::CreateBaseAtTamed(CreatureTemplate const* cinfo, Map* map)
{
TC_LOG_DEBUG("entities.pet", "Pet::CreateBaseForTamed");
if (!Create(sObjectMgr->GetGenerator<HighGuid::Pet>()->Generate(), map, phaseMask, cinfo->Entry))
if (!Create(sObjectMgr->GetGenerator<HighGuid::Pet>()->Generate(), map, cinfo->Entry))
return false;
setPowerType(POWER_FOCUS);
@@ -1800,12 +1799,11 @@ bool Pet::IsPermanentPetFor(Player* owner) const
}
}
bool Pet::Create(ObjectGuid::LowType guidlow, Map* map, uint32 phaseMask, uint32 Entry)
bool Pet::Create(ObjectGuid::LowType guidlow, Map* map, uint32 Entry)
{
ASSERT(map);
SetMap(map);
SetPhaseMask(phaseMask, false);
Object::_Create(ObjectGuid::Create<HighGuid::Pet>(map->GetId(), Entry, guidlow));
m_DBTableGuid = guidlow;
+2 -2
View File
@@ -55,10 +55,10 @@ class Pet : public Guardian
bool IsPermanentPetFor(Player* owner) const; // pet have tab in character windows and set UNIT_FIELD_PETNUMBER
bool Create(ObjectGuid::LowType guidlow, Map* map, uint32 phaseMask, uint32 Entry);
bool Create(ObjectGuid::LowType guidlow, Map* map, uint32 Entry);
bool CreateBaseAtCreature(Creature* creature);
bool CreateBaseAtCreatureInfo(CreatureTemplate const* cinfo, Unit* owner);
bool CreateBaseAtTamed(CreatureTemplate const* cinfo, Map* map, uint32 phaseMask);
bool CreateBaseAtTamed(CreatureTemplate const* cinfo, Map* map);
bool LoadPetFromDB(Player* owner, uint32 petentry = 0, uint32 petnumber = 0, bool current = false);
bool IsLoading() const override { return m_loading;}
void SavePetToDB(PetSaveMode mode);
+9 -17
View File
@@ -7431,6 +7431,8 @@ void Player::UpdateZone(uint32 newZone, uint32 newArea)
UpdateLocalChannels(newZone);
UpdateZoneDependentAuras(newZone);
UpdateAreaPhase();
}
//If players are too far away from the duel flag... they lose the duel
@@ -15423,6 +15425,7 @@ void Player::SendQuestUpdate(uint32 questId)
}
UpdateForQuestWorldObjects();
SendUpdatePhasing();
}
QuestGiverStatus Player::GetQuestDialogStatus(Object* questgiver)
@@ -26207,15 +26210,15 @@ Pet* Player::SummonPet(uint32 entry, float x, float y, float z, float ang, PetTy
Map* map = GetMap();
uint32 pet_number = sObjectMgr->GeneratePetNumber();
if (!pet->Create(sObjectMgr->GetGenerator<HighGuid::Pet>()->Generate(), map, GetPhaseMask(), entry))
if (!pet->Create(sObjectMgr->GetGenerator<HighGuid::Pet>()->Generate(), map, entry))
{
TC_LOG_ERROR("misc", "no such creature entry %u", entry);
delete pet;
return NULL;
}
for (auto itr : GetPhases())
pet->SetInPhase(itr, false, true);
pet->CopyPhaseFrom(this);
pet->SetCreatorGUID(GetGUID());
pet->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE, getFaction());
@@ -26585,25 +26588,14 @@ void Player::ReadMovementInfo(WorldPacket& data, MovementInfo* mi, Movement::Ext
#undef REMOVE_VIOLATING_FLAGS
}
void Player::UpdatePhasing()
void Player::SendUpdatePhasing()
{
if (!IsInWorld())
return;
std::set<uint32> phaseIds;
std::set<uint32> terrainswaps;
std::set<uint32> worldAreaSwaps;
RebuildTerrainSwaps(); // to set default map swaps
for (auto phase : GetPhases())
{
PhaseInfo const* info = sObjectMgr->GetPhaseInfo(phase);
if (!info)
continue;
terrainswaps.insert(info->terrainSwapMap);
worldAreaSwaps.insert(info->worldMapAreaSwap);
}
GetSession()->SendSetPhaseShift(GetPhases(), terrainswaps, worldAreaSwaps);
GetSession()->SendSetPhaseShift(GetPhases(), GetTerrainSwaps(), GetWorldMapAreaSwaps());
}
void Player::SendSupercededSpell(uint32 oldSpell, uint32 newSpell)
+1 -1
View File
@@ -2449,7 +2449,7 @@ class Player : public Unit, public GridObject<Player>
void UpdateVisibilityOf(WorldObject* target);
void UpdateTriggerVisibility();
void UpdatePhasing();
void SendUpdatePhasing();
template<class T>
void UpdateVisibilityOf(T* target, UpdateData& data, std::set<Unit*>& visibleNow);
@@ -318,8 +318,7 @@ Creature* Transport::CreateNPCPassenger(ObjectGuid::LowType guid, CreatureData c
for (auto phase : sDB2Manager.GetPhasesForGroup(data->phaseGroup))
creature->SetInPhase(phase, false, true);
else
for (auto phase : GetPhases()) // Set the creature to the transport's phases
creature->SetInPhase(phase, false, true);
creature->CopyPhaseFrom(this);
if (!map->AddToMap(creature))
{
@@ -463,8 +462,8 @@ TempSummon* Transport::SummonPassenger(uint32 entry, Position const& pos, TempSu
return NULL;
}
for (auto itr : phases)
summon->SetInPhase(itr, false, true);
for (uint32 phase : phases)
summon->SetInPhase(phase, false, true);
summon->SetUInt32Value(UNIT_CREATED_BY_SPELL, spellId);
+10 -5
View File
@@ -3660,7 +3660,7 @@ void Unit::RemoveNotOwnSingleTargetAuras(uint32 newPhase, bool phaseid)
else
{
Unit* caster = aura->GetCaster();
if (!caster || (newPhase && !caster->InSamePhase(newPhase)) || (!newPhase && !caster->IsInPhase(this)))
if (!caster || (newPhase && !caster->IsInPhase(newPhase)) || (!newPhase && !caster->IsInPhase(this)))
RemoveAura(iter);
else
++iter;
@@ -3675,7 +3675,7 @@ void Unit::RemoveNotOwnSingleTargetAuras(uint32 newPhase, bool phaseid)
for (AuraList::iterator iter = scAuras.begin(); iter != scAuras.end();)
{
Aura* aura = *iter;
if (aura->GetUnitOwner() != this && !aura->GetUnitOwner()->InSamePhase(newPhase))
if (aura->GetUnitOwner() != this && !aura->GetUnitOwner()->IsInPhase(newPhase))
{
aura->Remove();
iter = scAuras.begin();
@@ -11563,6 +11563,7 @@ void Unit::AddToWorld()
{
WorldObject::AddToWorld();
}
RebuildTerrainSwaps();
}
void Unit::RemoveFromWorld()
@@ -13091,6 +13092,8 @@ bool Unit::InitTamedPet(Pet* pet, uint8 level, uint32 spell_id)
return false;
}
pet->CopyPhaseFrom(this);
pet->GetCharmInfo()->SetPetNumber(sObjectMgr->GeneratePetNumber(), true);
// this enables pet details window (Shift+P)
pet->InitPetCreateSpells();
@@ -14421,12 +14424,12 @@ float Unit::MeleeSpellMissChance(const Unit* victim, WeaponAttackType attType, u
return missChance;
}
void Unit::SetInPhase(uint32 id, bool update, bool apply)
bool Unit::SetInPhase(uint32 id, bool update, bool apply)
{
WorldObject::SetInPhase(id, update, apply);
bool res = WorldObject::SetInPhase(id, update, apply);
if (!IsInWorld())
return;
return res;
if (GetTypeId() == TYPEID_UNIT || (!ToPlayer()->IsGameMaster() && !ToPlayer()->GetSession()->PlayerLogout()))
{
@@ -14469,6 +14472,8 @@ void Unit::SetInPhase(uint32 id, bool update, bool apply)
summon->SetInPhase(id, true, apply);
RemoveNotOwnSingleTargetAuras(0, true);
return res;
}
void Unit::UpdateObjectVisibility(bool forced)
+1 -1
View File
@@ -1958,7 +1958,7 @@ class Unit : public WorldObject
void SetVisible(bool x);
// common function for visibility checks for player/creatures with detection code
void SetInPhase(uint32 id, bool update, bool apply);
bool SetInPhase(uint32 id, bool update, bool apply);
void UpdateObjectVisibility(bool forced = true) override;
SpellImmuneList m_spellImmune[MAX_SPELL_IMMUNITY];
@@ -411,6 +411,8 @@ Corpse* ObjectAccessor::ConvertCorpseForPlayer(ObjectGuid player_guid, bool insi
bones->SetUInt32Value(CORPSE_FIELD_ITEM + i, 0);
}
bones->CopyPhaseFrom(corpse);
// add bones in grid store if grid loaded where corpse placed
map->AddToMap(bones);
}
+153 -61
View File
@@ -6448,11 +6448,28 @@ uint64 ObjectMgr::GenerateVoidStorageItemId()
void ObjectMgr::LoadCorpses()
{
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
// SELECT posX, posY, posZ, orientation, mapId, displayId, itemCache, bytes1, bytes2, flags, dynFlags, time, corpseType, instanceId, phaseMask, corpseGuid, guid FROM corpse WHERE corpseType <> 0
uint32 oldMSTime = getMSTime();
std::unordered_map<uint32, std::list<uint32>> phases;
// 0 1
// SELECT Guid, PhaseId FROM corpse_phases
PreparedQueryResult phaseResult = CharacterDatabase.Query(CharacterDatabase.GetPreparedStatement(CHAR_SEL_CORPSE_PHASES));
if (phaseResult)
{
do
{
Field* fields = phaseResult->Fetch();
uint32 guid = fields[0].GetUInt32();
uint32 phaseId = fields[1].GetUInt32();
phases[guid].push_back(phaseId);
} while (phaseResult->NextRow());
}
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
// SELECT posX, posY, posZ, orientation, mapId, displayId, itemCache, bytes1, bytes2, flags, dynFlags, time, corpseType, instanceId, corpseGuid, guid FROM corpse WHERE corpseType <> 0
PreparedQueryResult result = CharacterDatabase.Query(CharacterDatabase.GetPreparedStatement(CHAR_SEL_CORPSES));
if (!result)
{
@@ -6464,11 +6481,11 @@ void ObjectMgr::LoadCorpses()
do
{
Field* fields = result->Fetch();
ObjectGuid::LowType guid = fields[15].GetUInt64();
uint32 guid = fields[14].GetUInt32();
CorpseType type = CorpseType(fields[12].GetUInt8());
if (type >= MAX_CORPSE_TYPE)
{
TC_LOG_ERROR("misc", "Corpse (guid: " UI64FMTD ") have wrong corpse type (%u), not loading.", guid, type);
TC_LOG_ERROR("misc", "Corpse (guid: %u) have wrong corpse type (%u), not loading.", guid, type);
continue;
}
@@ -6479,6 +6496,9 @@ void ObjectMgr::LoadCorpses()
continue;
}
for (auto phaseId : phases[guid])
corpse->SetInPhase(phaseId, false, true);
sObjectAccessor->AddCorpse(corpse);
++count;
}
@@ -8527,60 +8547,18 @@ void ObjectMgr::LoadFactionChangeTitles()
TC_LOG_INFO("server.loading", ">> Loaded %u faction change title pairs in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
}
void ObjectMgr::LoadPhaseDefinitions()
void ObjectMgr::LoadTerrainSwapDefaults()
{
_PhaseDefinitionStore.clear();
_terrainMapDefaultStore.clear();
uint32 oldMSTime = getMSTime();
// 0 1 2 3
QueryResult result = WorldDatabase.Query("SELECT zoneId, entry, phaseId, phaseGroup FROM `phase_definitions` ORDER BY `entry` ASC");
// 0 1
QueryResult result = WorldDatabase.Query("SELECT MapId, TerrainSwapMap FROM `terrain_swap_defaults`");
if (!result)
{
TC_LOG_INFO("server.loading", ">> Loaded 0 phasing definitions. DB table `phase_definitions` is empty.");
return;
}
uint32 count = 0;
do
{
Field* fields = result->Fetch();
PhaseDefinition PhaseDefinition;
PhaseDefinition.zoneId = fields[0].GetUInt32();
PhaseDefinition.entry = fields[1].GetUInt32();
PhaseDefinition.phaseId = fields[2].GetUInt32();
PhaseDefinition.phaseGroup = fields[3].GetUInt32();
if (PhaseDefinition.phaseGroup && PhaseDefinition.phaseId)
{
TC_LOG_ERROR("sql.sql", "Phase definition for zone %u (Entry: %u) has phaseGroup and phaseId set, phaseGroup set to 0", PhaseDefinition.zoneId, PhaseDefinition.entry);
PhaseDefinition.phaseGroup = 0;
}
_PhaseDefinitionStore[PhaseDefinition.zoneId].push_back(PhaseDefinition);
++count;
}
while (result->NextRow());
TC_LOG_INFO("server.loading", ">> Loaded %u phasing definitions in %u ms.", count, GetMSTimeDiffToNow(oldMSTime));
}
void ObjectMgr::LoadPhaseInfo()
{
_PhaseInfoStore.clear();
uint32 oldMSTime = getMSTime();
// 0 1 2
QueryResult result = WorldDatabase.Query("SELECT id, worldmapareaswap, terrainswapmap FROM `phase_info`");
if (!result)
{
TC_LOG_INFO("server.loading", ">> Loaded 0 phase infos. DB table `phase_info` is empty.");
TC_LOG_INFO("server.loading", ">> Loaded 0 terrain swap defaults. DB table `terrain_swap_defaults` is empty.");
return;
}
@@ -8589,25 +8567,139 @@ void ObjectMgr::LoadPhaseInfo()
{
Field* fields = result->Fetch();
PhaseInfo phaseInfo;
phaseInfo.phaseId = fields[0].GetUInt32();
uint32 mapId = fields[0].GetUInt32();
PhaseEntry const* phase = sPhaseStore.LookupEntry(phaseInfo.phaseId);
if (!phase)
MapEntry const* map = sMapStore.LookupEntry(mapId);
if (!map)
{
TC_LOG_ERROR("sql.sql", "Phase %u defined in `phase_info` does not exists, skipped.", phaseInfo.phaseId);
TC_LOG_ERROR("sql.sql", "Map %u defined in `terrain_swap_defaults` does not exist, skipped.", mapId);
continue;
}
phaseInfo.worldMapAreaSwap = fields[1].GetUInt32();
phaseInfo.terrainSwapMap = fields[2].GetUInt32();
uint32 terrainSwap = fields[1].GetUInt32();
_PhaseInfoStore[phaseInfo.phaseId] = phaseInfo;
map = sMapStore.LookupEntry(terrainSwap);
if (!map)
{
TC_LOG_ERROR("sql.sql", "TerrainSwapMap %u defined in `terrain_swap_defaults` does not exist, skipped.", terrainSwap);
continue;
}
_terrainMapDefaultStore[mapId].push_back(terrainSwap);
++count;
} while (result->NextRow());
TC_LOG_INFO("server.loading", ">> Loaded %u terrain swap defaults in %u ms.", count, GetMSTimeDiffToNow(oldMSTime));
}
void ObjectMgr::LoadTerrainPhaseInfo()
{
_terrainPhaseInfoStore.clear();
uint32 oldMSTime = getMSTime();
// 0 1
QueryResult result = WorldDatabase.Query("SELECT Id, TerrainSwapMap FROM `terrain_phase_info`");
if (!result)
{
TC_LOG_INFO("server.loading", ">> Loaded 0 terrain phase infos. DB table `terrain_phase_info` is empty.");
return;
}
uint32 count = 0;
do
{
Field* fields = result->Fetch();
uint32 phaseId = fields[0].GetUInt32();
PhaseEntry const* phase = sPhaseStore.LookupEntry(phaseId);
if (!phase)
{
TC_LOG_ERROR("sql.sql", "Phase %u defined in `terrain_phase_info` does not exist, skipped.", phaseId);
continue;
}
uint32 terrainSwap = fields[1].GetUInt32();
_terrainPhaseInfoStore[phaseId].push_back(terrainSwap);
++count;
}
while (result->NextRow());
TC_LOG_INFO("server.loading", ">> Loaded %u phase infos in %u ms.", count, GetMSTimeDiffToNow(oldMSTime));
TC_LOG_INFO("server.loading", ">> Loaded %u terrain phase infos in %u ms.", count, GetMSTimeDiffToNow(oldMSTime));
}
void ObjectMgr::LoadTerrainWorldMaps()
{
_terrainWorldMapStore.clear();
uint32 oldMSTime = getMSTime();
// 0 1
QueryResult result = WorldDatabase.Query("SELECT TerrainSwapMap, WorldMapArea FROM `terrain_worldmap`");
if (!result)
{
TC_LOG_INFO("server.loading", ">> Loaded 0 terrain world maps. DB table `terrain_worldmap` is empty.");
return;
}
uint32 count = 0;
do
{
Field* fields = result->Fetch();
uint32 mapId = fields[0].GetUInt32();
if (!sMapStore.LookupEntry(mapId))
{
TC_LOG_ERROR("sql.sql", "TerrainSwapMap %u defined in `terrain_worldmap` does not exist, skipped.", mapId);
continue;
}
uint32 worldMapArea = fields[1].GetUInt32();
_terrainWorldMapStore[mapId].push_back(worldMapArea);
++count;
} while (result->NextRow());
TC_LOG_INFO("server.loading", ">> Loaded %u terrain world maps in %u ms.", count, GetMSTimeDiffToNow(oldMSTime));
}
void ObjectMgr::LoadAreaPhases()
{
_phases.clear();
uint32 oldMSTime = getMSTime();
// 0 1
QueryResult result = WorldDatabase.Query("SELECT AreaId, PhaseId FROM `phase_area`");
if (!result)
{
TC_LOG_INFO("server.loading", ">> Loaded 0 phase areas. DB table `phase_area` is empty.");
return;
}
uint32 count = 0;
do
{
Field* fields = result->Fetch();
uint32 area = fields[0].GetUInt32();
uint32 phase = fields[1].GetUInt32();
_phases[area].push_back(phase);
++count;
} while (result->NextRow());
TC_LOG_INFO("server.loading", ">> Loaded %u phase areas in %u ms.", count, GetMSTimeDiffToNow(oldMSTime));
}
GameObjectTemplate const* ObjectMgr::GetGameObjectTemplate(uint32 entry)
+17 -33
View File
@@ -129,34 +129,6 @@ typedef std::map<uint32, PageText> PageTextContainer;
// Benchmarked: Faster than std::map (insert/find)
typedef std::unordered_map<uint16, InstanceTemplate> InstanceTemplateContainer;
// Phasing (visibility)
enum PhasingFlags
{
PHASE_FLAG_OVERWRITE_EXISTING = 0x01, // don't stack with existing phases, overwrites existing phases
PHASE_FLAG_NO_MORE_PHASES = 0x02, // stop calculating phases after this phase was applied (no more phases will be applied)
PHASE_FLAG_NEGATE_PHASE = 0x04 // negate instead to add the phasemask
};
struct PhaseInfo
{
uint32 phaseId;
uint32 worldMapAreaSwap;
uint32 terrainSwapMap;
};
typedef std::unordered_map<uint32, PhaseInfo> PhaseInfoContainer;
struct PhaseDefinition
{
uint32 zoneId;
uint32 entry;
uint32 phaseId;
uint32 phaseGroup;
};
typedef std::list<PhaseDefinition> PhaseDefinitionContainer;
typedef std::unordered_map<uint32 /*zoneId*/, PhaseDefinitionContainer> PhaseDefinitionStore;
struct GameTele
{
float position_x;
@@ -672,6 +644,9 @@ struct DungeonEncounter
typedef std::list<DungeonEncounter const*> DungeonEncounterList;
typedef std::unordered_map<uint64, DungeonEncounterList> DungeonEncounterContainer;
typedef std::unordered_map<uint32, std::list<uint32>> TerrainPhaseInfo;
typedef std::unordered_map<uint32, std::list<uint32>> PhaseInfo;
class PlayerDumpReader;
class ObjectMgr
@@ -1008,8 +983,10 @@ class ObjectMgr
void LoadTrainerSpell();
void AddSpellToTrainer(uint32 entry, uint32 spell, uint32 spellCost, uint32 reqSkill, uint32 reqSkillValue, uint32 reqLevel);
void LoadPhaseDefinitions();
void LoadPhaseInfo();
void LoadTerrainPhaseInfo();
void LoadTerrainSwapDefaults();
void LoadTerrainWorldMaps();
void LoadAreaPhases();
std::string GeneratePetName(uint32 entry);
uint32 GetBaseXP(uint8 level);
@@ -1243,7 +1220,12 @@ class ObjectMgr
return _gossipMenuItemsStore.equal_range(uiMenuId);
}
PhaseInfo const* GetPhaseInfo(uint32 phase) { return _PhaseInfoStore.find(phase) != _PhaseInfoStore.end() ? &_PhaseInfoStore[phase] : nullptr; }
std::list<uint32>& GetPhaseTerrainSwaps(uint32 phaseid) { return _terrainPhaseInfoStore[phaseid]; }
std::list<uint32>& GetDefaultTerrainSwaps(uint32 mapid) { return _terrainMapDefaultStore[mapid]; }
std::list<uint32>& GetTerrainWorldMaps(uint32 terrainId) { return _terrainWorldMapStore[terrainId]; }
TerrainPhaseInfo& GetDefaultTerrainSwapStore() { return _terrainMapDefaultStore; }
std::list<uint32>& GetPhasesForArea(uint32 area) { return _phases[area]; }
PhaseInfo& GetAreaPhases() { return _phases; }
// for wintergrasp only
GraveYardContainer GraveYardStore;
@@ -1369,8 +1351,10 @@ class ObjectMgr
PageTextContainer _pageTextStore;
InstanceTemplateContainer _instanceTemplateStore;
PhaseDefinitionStore _PhaseDefinitionStore;
PhaseInfoContainer _PhaseInfoStore;
TerrainPhaseInfo _terrainPhaseInfoStore;
TerrainPhaseInfo _terrainMapDefaultStore;
TerrainPhaseInfo _terrainWorldMapStore;
PhaseInfo _phases;
private:
void LoadScripts(ScriptsType type);
+17 -35
View File
@@ -1423,48 +1423,30 @@ void WorldSession::HandleUITimeRequest(WorldPackets::Misc::UITimeRequest& /*requ
void WorldSession::SendSetPhaseShift(std::set<uint32> const& phaseIds, std::set<uint32> const& terrainswaps, std::set<uint32> const& worldMapAreaSwaps)
{
ObjectGuid guid = _player->GetGUID();
WorldPacket data(SMSG_SET_PHASE_SHIFT_CHANGE, 1 + 8 + 4 + 4 + 4 + 4 + 2 * phaseIds.size() + 4 + terrainswaps.size() * 2);
data.WriteBit(guid[2]);
data.WriteBit(guid[3]);
data.WriteBit(guid[1]);
data.WriteBit(guid[6]);
data.WriteBit(guid[4]);
data.WriteBit(guid[5]);
data.WriteBit(guid[0]);
data.WriteBit(guid[7]);
data.WriteByteSeq(guid[7]);
data.WriteByteSeq(guid[4]);
data << uint32(worldMapAreaSwaps.size());
for (auto mapSwap : worldMapAreaSwaps)
data << uint16(mapSwap); // WorldMapArea.dbc id (controls map display)
data.WriteByteSeq(guid[1]);
data << uint32(phaseIds.size() ? 0 : 8); // flags (not phasemask)
data.WriteByteSeq(guid[2]);
data.WriteByteSeq(guid[6]);
data << uint32(0); // Inactive terrain swaps
//for (uint8 i = 0; i < inactiveSwapsCount; ++i)
// data << uint16(0);
data << uint32(phaseIds.size()) * 2; // Phase.dbc ids
data << _player->GetGUID(); // Client
data << uint32(phaseIds.size() ? 0 : 8); // PhaseShiftFlags
data << uint32(phaseIds.size()); // PhaseShiftCount
data << _player->GetGUID(); // PersonalGUID
for (std::set<uint32>::const_iterator itr = phaseIds.begin(); itr != phaseIds.end(); ++itr)
data << uint16(*itr);
data.WriteByteSeq(guid[3]);
data.WriteByteSeq(guid[0]);
{
data << uint16(1); // PhaseFlags
data << uint16(*itr); // Id
}
data << uint32(terrainswaps.size()) * 2; // Active terrain swaps
for (std::set<uint32>::const_iterator itr = terrainswaps.begin(); itr != terrainswaps.end(); ++itr)
data << uint16(*itr);
data.WriteByteSeq(guid[5]);
data << uint32(0); // Inactive terrain swaps
//for (uint8 i = 0; i < inactiveSwapsCount; ++i)
// data << uint16(0);
data << uint32(worldMapAreaSwaps.size()) * 2;
for (auto mapSwap : worldMapAreaSwaps)
data << uint16(mapSwap); // WorldMapArea.dbc id (controls map display)
SendPacket(&data);
}
+1 -1
View File
@@ -631,5 +631,5 @@ void InstanceScript::UpdatePhasing()
Map::PlayerList const& players = instance->GetPlayers();
for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
if (Player* player = itr->GetSource())
player->UpdatePhasing();
player->SendUpdatePhasing();
}
+4
View File
@@ -498,6 +498,8 @@ bool Map::AddPlayerToMap(Player* player)
player->m_clientGUIDs.clear();
player->UpdateObjectVisibility(false);
player->SendUpdatePhasing();
sScriptMgr->OnPlayerEnterMap(this, player);
return true;
}
@@ -556,6 +558,8 @@ bool Map::AddToMap(T* obj)
if (obj->isActiveObject())
AddToActive(obj);
obj->RebuildTerrainSwaps();
//something, such as vehicle, needs to be update immediately
//also, trigger needs to cast spell, if not update, cannot see visual
obj->UpdateObjectVisibility(true);
+1 -1
View File
@@ -1743,7 +1743,7 @@ void OpcodeTable::Initialize()
DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_MAX_WEEKLY_QUANTITY, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_MELEE_ANIM_KIT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_PCT_SPELL_MODIFIER, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_PHASE_SHIFT_CHANGE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_PHASE_SHIFT_CHANGE, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_PLAYER_DECLINED_NAMES_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_PLAY_HOVER_ANIM, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_PROFICIENCY, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
@@ -1733,7 +1733,7 @@ void AuraEffect::HandlePhase(AuraApplication const* aurApp, uint8 mode, bool app
{
if (player->IsInWorld())
player->GetMap()->SendUpdateTransportVisibility(player, oldPhases);
player->UpdatePhasing();
player->SendUpdatePhasing();
}
// need triggering visibility update base at phase update of not GM invisible (other GMs anyway see in any phases)
@@ -1765,7 +1765,7 @@ void AuraEffect::HandlePhaseGroup(AuraApplication const* aurApp, uint8 mode, boo
{
if (player->IsInWorld())
player->GetMap()->SendUpdateTransportVisibility(player, oldPhases);
player->UpdatePhasing();
player->SendUpdatePhasing();
}
// need triggering visibility update base at phase update of not GM invisible (other GMs anyway see in any phases)
+6 -12
View File
@@ -3212,8 +3212,7 @@ void Spell::EffectSummonObjectWild(SpellEffIndex effIndex)
return;
}
for (auto phase : m_caster->GetPhases())
pGameObj->SetInPhase(phase, false, true);
pGameObj->CopyPhaseFrom(m_caster);
int32 duration = m_spellInfo->GetDuration();
@@ -3236,8 +3235,7 @@ void Spell::EffectSummonObjectWild(SpellEffIndex effIndex)
if (linkedGO->Create(sObjectMgr->GetGenerator<HighGuid::GameObject>()->Generate(), linkedEntry, map,
m_caster->GetPhaseMask(), x, y, z, target->GetOrientation(), 0.0f, 0.0f, 0.0f, 0.0f, 100, GO_STATE_READY))
{
for (auto phase : m_caster->GetPhases())
linkedGO->SetInPhase(phase, false, true);
linkedGO->CopyPhaseFrom(m_caster);
linkedGO->SetRespawnTime(duration > 0 ? duration/IN_MILLISECONDS : 0);
linkedGO->SetSpellId(m_spellInfo->Id);
@@ -3871,8 +3869,7 @@ void Spell::EffectDuel(SpellEffIndex effIndex)
return;
}
for (auto phase : m_caster->GetPhases())
pGameObj->SetInPhase(phase, false, true);
pGameObj->CopyPhaseFrom(m_caster);
pGameObj->SetUInt32Value(GAMEOBJECT_FACTION, m_caster->getFaction());
pGameObj->SetUInt32Value(GAMEOBJECT_LEVEL, m_caster->getLevel()+1);
@@ -4244,8 +4241,7 @@ void Spell::EffectSummonObject(SpellEffIndex effIndex)
return;
}
for (auto phase : m_caster->GetPhases())
go->SetInPhase(phase, false, true);
go->CopyPhaseFrom(m_caster);
//pGameObj->SetUInt32Value(GAMEOBJECT_LEVEL, m_caster->getLevel());
int32 duration = m_spellInfo->GetDuration();
@@ -4882,8 +4878,7 @@ void Spell::EffectTransmitted(SpellEffIndex effIndex)
return;
}
for (auto phase : m_caster->GetPhases())
pGameObj->SetInPhase(phase, false, true);
pGameObj->CopyPhaseFrom(m_caster);
int32 duration = m_spellInfo->GetDuration();
@@ -4947,8 +4942,7 @@ void Spell::EffectTransmitted(SpellEffIndex effIndex)
if (linkedGO->Create(sObjectMgr->GetGenerator<HighGuid::GameObject>()->Generate(), linkedEntry, cMap,
0, fx, fy, fz, m_caster->GetOrientation(), 0.0f, 0.0f, 0.0f, 0.0f, 100, GO_STATE_READY))
{
for (auto phase : m_caster->GetPhases())
linkedGO->SetInPhase(phase, false, true);
linkedGO->CopyPhaseFrom(m_caster);
linkedGO->SetRespawnTime(duration > 0 ? duration/IN_MILLISECONDS : 0);
//linkedGO->SetUInt32Value(GAMEOBJECT_LEVEL, m_caster->getLevel());
+15 -5
View File
@@ -1460,6 +1460,10 @@ void World::SetInitialWorldSettings()
stmt->setUInt32(0, 3 * DAY);
CharacterDatabase.Execute(stmt);
stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_OLD_CORPSE_PHASES);
stmt->setUInt32(0, 3 * DAY);
CharacterDatabase.Execute(stmt);
///- Load the DBC files
TC_LOG_INFO("server.loading", "Initialize data stores...");
LoadDBCStores(m_dataPath);
@@ -1550,9 +1554,6 @@ void World::SetInitialWorldSettings()
TC_LOG_INFO("server.loading", "Loading Spell Group Stack Rules...");
sSpellMgr->LoadSpellGroupStackRules();
TC_LOG_INFO("server.loading", "Loading Spell Phase Dbc Info...");
sObjectMgr->LoadPhaseInfo();
TC_LOG_INFO("server.loading", "Loading NPC Texts...");
sObjectMgr->LoadGossipText();
@@ -1801,8 +1802,17 @@ void World::SetInitialWorldSettings()
TC_LOG_INFO("server.loading", "Loading World States..."); // must be loaded before battleground, outdoor PvP and conditions
LoadWorldStates();
TC_LOG_INFO("server.loading", "Loading Phase definitions...");
sObjectMgr->LoadPhaseDefinitions();
TC_LOG_INFO("server.loading", "Loading Terrain Phase definitions...");
sObjectMgr->LoadTerrainPhaseInfo();
TC_LOG_INFO("server.loading", "Loading Terrain Swap Default definitions...");
sObjectMgr->LoadTerrainSwapDefaults();
TC_LOG_INFO("server.loading", "Loading Terrain World Map definitions...");
sObjectMgr->LoadTerrainWorldMaps();
TC_LOG_INFO("server.loading", "Loading Phase Area definitions...");
sObjectMgr->LoadAreaPhases();
TC_LOG_INFO("server.loading", "Loading Conditions...");
sConditionMgr->LoadConditions();
+31 -11
View File
@@ -934,8 +934,7 @@ public:
return false;
}
for (auto phase : handler->GetSession()->GetPlayer()->GetPhases())
v->SetInPhase(phase, false, true);
v->CopyPhaseFrom(handler->GetSession()->GetPlayer());
map->AddToMap(v->ToCreature());
@@ -959,6 +958,7 @@ public:
char* t = strtok((char*)args, " ");
char* p = strtok(NULL, " ");
char* m = strtok(NULL, " ");
if (!t)
return false;
@@ -967,10 +967,16 @@ public:
std::set<uint32> phaseId;
std::set<uint32> worldMapSwap;
terrainswap.insert((uint32)atoi(t));
if (uint32 ut = (uint32)atoi(t))
terrainswap.insert(ut);
if (p)
phaseId.insert((uint32)atoi(p));
if (uint32 up = (uint32)atoi(p))
phaseId.insert(up);
if (m)
if (uint32 um = (uint32)atoi(m))
worldMapSwap.insert(um);
handler->GetSession()->SendSetPhaseShift(phaseId, terrainswap, worldMapSwap);
return true;
@@ -1390,14 +1396,28 @@ public:
return true;
}
static bool HandleDebugPhaseCommand(ChatHandler* /*handler*/, char const* /*args*/)
static bool HandleDebugPhaseCommand(ChatHandler* handler, char const* /*args*/)
{
/*/
Unit* unit = handler->getSelectedUnit();
Player* player = handler->GetSession()->GetPlayer();
if (unit && unit->GetTypeId() == TYPEID_PLAYER)
player = unit->ToPlayer();
*/
Unit* target = handler->getSelectedUnit();
if (!target)
{
handler->SendSysMessage(LANG_SELECT_CREATURE);
handler->SetSentErrorMessage(true);
return false;
}
std::stringstream phases;
for (uint32 phase : target->GetPhases())
{
phases << phase << " ";
}
if (!phases.str().empty())
handler->PSendSysMessage("Target's current phases: %s", phases.str().c_str());
else
handler->SendSysMessage("Target is not phased");
return true;
}
};
+1 -2
View File
@@ -158,8 +158,7 @@ public:
return false;
}
for (auto phase : player->GetPhases())
object->SetInPhase(phase, false, true);
object->CopyPhaseFrom(player);
if (spawntimeSecs)
{
+17 -4
View File
@@ -247,6 +247,21 @@ public:
if (status)
handler->PSendSysMessage(LANG_LIQUID_STATUS, liquidStatus.level, liquidStatus.depth_level, liquidStatus.entry, liquidStatus.type_flags, status);
if (!object->GetTerrainSwaps().empty())
{
std::stringstream ss;
for (uint32 swap : object->GetTerrainSwaps())
ss << swap << " ";
handler->PSendSysMessage("Target's active terrain swaps: %s", ss.str().c_str());
}
if (!object->GetWorldMapAreaSwaps().empty())
{
std::stringstream ss;
for (uint32 swap : object->GetWorldMapAreaSwaps())
ss << swap << " ";
handler->PSendSysMessage("Target's active world map area swaps: %s", ss.str().c_str());
}
return true;
}
@@ -407,8 +422,7 @@ public:
target->GetContactPoint(_player, x, y, z);
_player->TeleportTo(target->GetMapId(), x, y, z, _player->GetAngle(target), TELE_TO_GM_MODE);
for (auto phase : target->GetPhases())
_player->SetInPhase(phase, true, true);
_player->CopyPhaseFrom(target, true);
}
else
{
@@ -532,8 +546,7 @@ public:
float x, y, z;
handler->GetSession()->GetPlayer()->GetClosePoint(x, y, z, target->GetObjectSize());
target->TeleportTo(handler->GetSession()->GetPlayer()->GetMapId(), x, y, z, target->GetOrientation());
for (auto phase : handler->GetSession()->GetPlayer()->GetPhases())
target->SetInPhase(phase, true, true);
target->CopyPhaseFrom(handler->GetSession()->GetPlayer(), true);
}
else
{
+7 -4
View File
@@ -1279,10 +1279,13 @@ public:
uint32 phase = (uint32)atoi((char*)args);
Unit* target = handler->getSelectedUnit();
if (target)
target->SetInPhase(phase, true, !target->IsInPhase(phase));
else
handler->GetSession()->GetPlayer()->SetInPhase(phase, true, !handler->GetSession()->GetPlayer()->IsInPhase(phase));
if (!target)
target = handler->GetSession()->GetPlayer();
target->SetInPhase(phase, true, !target->IsInPhase(phase));
if (target->GetTypeId() == TYPEID_PLAYER)
target->ToPlayer()->SendUpdatePhasing();
return true;
}
+37 -8
View File
@@ -206,6 +206,7 @@ public:
{ "model", rbac::RBAC_PERM_COMMAND_NPC_SET_MODEL, false, &HandleNpcSetModelCommand, "", NULL },
{ "movetype", rbac::RBAC_PERM_COMMAND_NPC_SET_MOVETYPE, false, &HandleNpcSetMoveTypeCommand, "", NULL },
{ "phase", rbac::RBAC_PERM_COMMAND_NPC_SET_PHASE, false, &HandleNpcSetPhaseCommand, "", NULL },
{ "phasegroup", rbac::RBAC_PERM_COMMAND_NPC_SET_PHASE, false, &HandleNpcSetPhaseGroup, "", NULL },
{ "spawndist", rbac::RBAC_PERM_COMMAND_NPC_SET_SPAWNDIST, false, &HandleNpcSetSpawnDistCommand, "", NULL },
{ "spawntime", rbac::RBAC_PERM_COMMAND_NPC_SET_SPAWNTIME, false, &HandleNpcSetSpawnTimeCommand, "", NULL },
{ "data", rbac::RBAC_PERM_COMMAND_NPC_SET_DATA, false, &HandleNpcSetDataCommand, "", NULL },
@@ -285,9 +286,6 @@ public:
return false;
}
for (auto phase : chr->GetPhases())
creature->SetInPhase(phase, false, true);
creature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMask());
ObjectGuid::LowType db_guid = creature->GetDBTableGUIDLow();
@@ -1100,7 +1098,37 @@ public:
}
//npc phase handling
//change phase of creature or pet
//change phase of creature
static bool HandleNpcSetPhaseGroup(ChatHandler* handler, char const* args)
{
if (!*args)
return false;
uint32 phaseGroupId = (uint32)atoi((char*)args);
Creature* creature = handler->getSelectedCreature();
if (!creature || creature->IsPet())
{
handler->SendSysMessage(LANG_SELECT_CREATURE);
handler->SetSentErrorMessage(true);
return false;
}
creature->ClearPhases();
for (uint32 id : sDB2Manager.GetPhasesForGroup(phaseGroupId))
creature->SetInPhase(id, false, true); // don't send update here for multiple phases, only send it once after adding all phases
creature->UpdateObjectVisibility();
creature->SetDBPhase(-int(phaseGroupId));
creature->SaveToDB();
return true;
}
//npc phase handling
//change phase of creature
static bool HandleNpcSetPhaseCommand(ChatHandler* handler, char const* args)
{
if (!*args)
@@ -1109,17 +1137,18 @@ public:
uint32 phase = (uint32) atoi((char*)args);
Creature* creature = handler->getSelectedCreature();
if (!creature)
if (!creature || creature->IsPet())
{
handler->SendSysMessage(LANG_SELECT_CREATURE);
handler->SetSentErrorMessage(true);
return false;
}
creature->SetInPhase(phase, true, !creature->IsInPhase(phase));
creature->ClearPhases();
creature->SetInPhase(phase, true, true);
creature->SetDBPhase(phase);
if (!creature->IsPet())
creature->SaveToDB();
creature->SaveToDB();
return true;
}
+3 -3
View File
@@ -1104,10 +1104,10 @@ public:
static bool HandleReloadPhaseDefinitionsCommand(ChatHandler* handler, const char* /*args*/)
{
TC_LOG_INFO("misc", "Reloading phase_definitions table...");
sObjectMgr->LoadPhaseDefinitions();
TC_LOG_INFO("misc", "Reloading terrain_phase_info table...");
sObjectMgr->LoadTerrainPhaseInfo();
sWorld->UpdatePhaseDefinitions();
handler->SendGlobalGMSysMessage("Phase Definitions reloaded.");
handler->SendGlobalGMSysMessage("Terrain phase infos reloaded.");
return true;
}
+4 -8
View File
@@ -682,8 +682,7 @@ public:
return false;
}
for (auto phase : chr->GetPhases())
wpCreature2->SetInPhase(phase, false, true);
wpCreature2->CopyPhaseFrom(chr);
wpCreature2->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMask());
// To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
@@ -902,8 +901,7 @@ public:
return false;
}
for (auto phase : chr->GetPhases())
wpCreature->SetInPhase(phase, false, true);
wpCreature->CopyPhaseFrom(chr);
// Set "wpguid" column to the visual waypoint
stmt = WorldDatabase.GetPreparedStatement(WORLD_UPD_WAYPOINT_DATA_WPGUID);
@@ -967,8 +965,7 @@ public:
return false;
}
for (auto phase : chr->GetPhases())
creature->SetInPhase(phase, false, true);
creature->CopyPhaseFrom(chr);
creature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMask());
if (!creature->LoadCreatureFromDB(creature->GetDBTableGUIDLow(), map))
@@ -1019,8 +1016,7 @@ public:
return false;
}
for (auto phase : chr->GetPhases())
creature->SetInPhase(phase, false, true);
creature->CopyPhaseFrom(chr);
creature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMask());
if (!creature->LoadCreatureFromDB(creature->GetDBTableGUIDLow(), map))
@@ -172,8 +172,7 @@ bool OutdoorPvPSI::HandleDropFlag(Player* player, uint32 spellId)
return true;
}
for (auto phase : player->GetPhases())
go->SetInPhase(phase, false, true);
go->CopyPhaseFrom(player);
go->SetRespawnTime(0);
@@ -209,8 +208,7 @@ bool OutdoorPvPSI::HandleDropFlag(Player* player, uint32 spellId)
return true;
}
for (auto phase : player->GetPhases())
go->SetInPhase(phase, false, true);
go->CopyPhaseFrom(player);
go->SetRespawnTime(0);
@@ -336,11 +336,16 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PrepareStatement(CHAR_DEL_PLAYER_HOMEBIND, "DELETE FROM character_homebind WHERE guid = ?", CONNECTION_ASYNC);
// Corpse
PrepareStatement(CHAR_SEL_CORPSES, "SELECT posX, posY, posZ, orientation, mapId, displayId, itemCache, bytes1, bytes2, flags, dynFlags, time, corpseType, instanceId, phaseMask, corpseGuid, guid FROM corpse WHERE corpseType <> 0", CONNECTION_SYNCH);
PrepareStatement(CHAR_INS_CORPSE, "INSERT INTO corpse (corpseGuid, guid, posX, posY, posZ, orientation, mapId, displayId, itemCache, bytes1, bytes2, flags, dynFlags, time, corpseType, instanceId, phaseMask) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
PrepareStatement(CHAR_SEL_CORPSES, "SELECT posX, posY, posZ, orientation, mapId, displayId, itemCache, bytes1, bytes2, flags, dynFlags, time, corpseType, instanceId, corpseGuid, guid FROM corpse WHERE corpseType <> 0", CONNECTION_SYNCH);
PrepareStatement(CHAR_INS_CORPSE, "INSERT INTO corpse (corpseGuid, guid, posX, posY, posZ, orientation, mapId, displayId, itemCache, bytes1, bytes2, flags, dynFlags, time, corpseType, instanceId) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_CORPSE, "DELETE FROM corpse WHERE corpseGuid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_PLAYER_CORPSES, "DELETE FROM corpse WHERE guid = ? AND corpseType <> 0", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_OLD_CORPSES, "DELETE FROM corpse WHERE corpseType = 0 OR time < (UNIX_TIMESTAMP(NOW()) - ?)", CONNECTION_ASYNC);
PrepareStatement(CHAR_SEL_CORPSE_PHASES, "SELECT Guid, PhaseId FROM corpse_phases", CONNECTION_SYNCH);
PrepareStatement(CHAR_DEL_CORPSE_PHASES, "DELETE FROM corpse_phases WHERE Guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_PLAYER_CORPSES_PHASES, "DELETE FROM corpse_phases WHERE OwnerGuid = ? AND CorpseType <> 0", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_OLD_CORPSE_PHASES, "DELETE FROM corpse_phases WHERE CorpseType = 0 OR Time < (UNIX_TIMESTAMP(NOW()) - ?)", CONNECTION_ASYNC);
PrepareStatement(CHAR_INS_CORPSE_PHASES, "INSERT INTO corpse_phases (Guid, PhaseId, OwnerGuid, Time, CorpseType) VALUES (?, ?, ?, ?, ?)", CONNECTION_ASYNC);
// Creature respawn
PrepareStatement(CHAR_SEL_CREATURE_RESPAWNS, "SELECT guid, respawnTime FROM creature_respawn WHERE mapId = ? AND instanceId = ?", CONNECTION_SYNCH);
@@ -294,6 +294,11 @@ enum CharacterDatabaseStatements
CHAR_DEL_CORPSE,
CHAR_DEL_PLAYER_CORPSES,
CHAR_DEL_OLD_CORPSES,
CHAR_SEL_CORPSE_PHASES,
CHAR_DEL_CORPSE_PHASES,
CHAR_DEL_PLAYER_CORPSES_PHASES,
CHAR_DEL_OLD_CORPSE_PHASES,
CHAR_INS_CORPSE_PHASES,
CHAR_SEL_CREATURE_RESPAWNS,
CHAR_REP_CREATURE_RESPAWN,
@@ -81,7 +81,7 @@ void WorldDatabaseConnection::DoPrepareStatements()
PrepareStatement(WORLD_SEL_CREATURE_BY_ID, "SELECT guid FROM creature WHERE id = ?", CONNECTION_SYNCH);
PrepareStatement(WORLD_SEL_GAMEOBJECT_NEAREST, "SELECT guid, id, position_x, position_y, position_z, map, (POW(position_x - ?, 2) + POW(position_y - ?, 2) + POW(position_z - ?, 2)) AS order_ FROM gameobject WHERE map = ? AND (POW(position_x - ?, 2) + POW(position_y - ?, 2) + POW(position_z - ?, 2)) <= ? ORDER BY order_", CONNECTION_SYNCH);
PrepareStatement(WORLD_SEL_CREATURE_NEAREST, "SELECT guid, id, position_x, position_y, position_z, map, (POW(position_x - ?, 2) + POW(position_y - ?, 2) + POW(position_z - ?, 2)) AS order_ FROM creature WHERE map = ? AND (POW(position_x - ?, 2) + POW(position_y - ?, 2) + POW(position_z - ?, 2)) <= ? ORDER BY order_", CONNECTION_SYNCH);
PrepareStatement(WORLD_INS_CREATURE, "INSERT INTO creature (guid, id , map, spawnMask, phaseMask, modelid, equipment_id, position_x, position_y, position_z, orientation, spawntimesecs, spawndist, currentwaypoint, curhealth, curmana, MovementType, npcflag, unit_flags, dynamicflags) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
PrepareStatement(WORLD_INS_CREATURE, "INSERT INTO creature (guid, id , map, spawnMask, phaseMask, PhaseId, PhaseGroup, modelid, equipment_id, position_x, position_y, position_z, orientation, spawntimesecs, spawndist, currentwaypoint, curhealth, curmana, MovementType, npcflag, unit_flags, dynamicflags) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
PrepareStatement(WORLD_DEL_GAME_EVENT_CREATURE, "DELETE FROM game_event_creature WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(WORLD_DEL_GAME_EVENT_MODEL_EQUIP, "DELETE FROM game_event_model_equip WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(WORLD_INS_GAMEOBJECT, "INSERT INTO gameobject (guid, id, map, spawnMask, phaseMask, position_x, position_y, position_z, orientation, rotation0, rotation1, rotation2, rotation3, spawntimesecs, animprogress, state) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
@@ -3258,6 +3258,7 @@ Logger.sql.sql=5,Console DBErrors
#Logger.network.opcode=3,Console Server
#Logger.network.soap=3,Console Server
#Logger.outdoorpvp=3,Console Server
#Logger.phase=3,Console Server
#Logger.pool=3,Console Server
#Logger.rbac=3,Console Server
#Logger.scripts=3,Console Server