diff options
Diffstat (limited to 'src')
62 files changed, 584 insertions, 1031 deletions
diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp index 23386f82d73..140bb5507b4 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.cpp +++ b/src/server/game/AI/SmartScripts/SmartScript.cpp @@ -1045,7 +1045,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u              delete targets;              break;          } -        case SMART_ACTION_SET_INGAME_PHASE_MASK: +        case SMART_ACTION_SET_INGAME_PHASE_ID:          {              ObjectList* targets = GetTargets(e, unit); @@ -1053,12 +1053,23 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u                  break;              for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) -            { -                if (IsUnit(*itr)) -                    (*itr)->ToUnit()->SetPhaseMask(e.action.ingamePhaseMask.mask, true); -                else if (IsGameObject(*itr)) -                    (*itr)->ToGameObject()->SetPhaseMask(e.action.ingamePhaseMask.mask, true); -            } +                (*itr)->SetInPhase(e.action.ingamePhaseId.id, true, e.action.ingamePhaseId.apply == 1); + +            delete targets; +            break; +        } +        case SMART_ACTION_SET_INGAME_PHASE_GROUP: +        { +            ObjectList* targets = GetTargets(e, unit); + +            if (!targets) +                break; + +            std::set<uint32> const& phases = GetPhasesForGroup(e.action.ingamePhaseGroup.groupId); + +            for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) +                for (auto phase : phases) +                    (*itr)->SetInPhase(phase, true, e.action.ingamePhaseGroup.apply == 1);              delete targets;              break; diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp index 2e8453904a1..af24298c60d 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp @@ -1008,6 +1008,44 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)              }              break;          } +        case SMART_ACTION_SET_INGAME_PHASE_ID: +        { +            uint32 phaseId = e.action.ingamePhaseId.id; +            uint32 apply = e.action.ingamePhaseId.apply; + +            if (apply != 0 && apply != 1) +            { +                TC_LOG_ERROR("sql.sql", "SmartScript: SMART_ACTION_SET_INGAME_PHASE_ID uses invalid apply value %u (Should be 0 or 1) for creature %u, skipped", apply, e.entryOrGuid); +                return false; +            } + +            PhaseEntry const* phase = sPhaseStore.LookupEntry(phaseId); +            if (!phase) +            { +                TC_LOG_ERROR("sql.sql", "SmartScript: SMART_ACTION_SET_INGAME_PHASE_ID uses invalid phaseid %u for creature %u, skipped", phaseId, e.entryOrGuid); +                return false; +            } +            break; +        } +        case SMART_ACTION_SET_INGAME_PHASE_GROUP: +        { +            uint32 phaseGroup = e.action.ingamePhaseGroup.groupId; +            uint32 apply = e.action.ingamePhaseGroup.apply; + +            if (apply != 0 && apply != 1) +            { +                TC_LOG_ERROR("sql.sql", "SmartScript: SMART_ACTION_SET_INGAME_PHASE_GROUP uses invalid apply value %u (Should be 0 or 1) for creature %u, skipped", apply, e.entryOrGuid); +                return false; +            } + +            PhaseGroupEntry const* phase = sPhaseGroupStore.LookupEntry(phaseGroup); +            if (!phase) +            { +                TC_LOG_ERROR("sql.sql", "SmartScript: SMART_ACTION_SET_INGAME_PHASE_GROUP uses invalid phase group id %u for creature %u, skipped", phaseGroup, e.entryOrGuid); +                return false; +            } +            break; +        }          case SMART_ACTION_FOLLOW:          case SMART_ACTION_SET_ORIENTATION:          case SMART_ACTION_STORE_TARGET_LIST: @@ -1037,7 +1075,6 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)          case SMART_ACTION_SET_RUN:          case SMART_ACTION_SET_SWIM:          case SMART_ACTION_FORCE_DESPAWN: -        case SMART_ACTION_SET_INGAME_PHASE_MASK:          case SMART_ACTION_SET_UNIT_FLAG:          case SMART_ACTION_REMOVE_UNIT_FLAG:          case SMART_ACTION_PLAYMOVIE: diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.h b/src/server/game/AI/SmartScripts/SmartScriptMgr.h index 5574e45c614..8ec2cdb1ff9 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.h +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.h @@ -433,7 +433,7 @@ enum SMART_ACTION      SMART_ACTION_THREAT_SINGLE_PCT                  = 13,     // Threat%      SMART_ACTION_THREAT_ALL_PCT                     = 14,     // Threat%      SMART_ACTION_CALL_AREAEXPLOREDOREVENTHAPPENS    = 15,     // QuestID -    SMART_ACTION_UNUSED_16                          = 16,     // UNUSED +    SMART_ACTION_SET_INGAME_PHASE_GROUP             = 16,     // phaseGroupId, apply      SMART_ACTION_SET_EMOTE_STATE                    = 17,     // emoteID      SMART_ACTION_SET_UNIT_FLAG                      = 18,     // Flags (may be more than one field OR'd together), Target      SMART_ACTION_REMOVE_UNIT_FLAG                   = 19,     // Flags (may be more than one field OR'd together), Target @@ -461,7 +461,7 @@ enum SMART_ACTION      SMART_ACTION_FORCE_DESPAWN                      = 41,     // timer      SMART_ACTION_SET_INVINCIBILITY_HP_LEVEL         = 42,     // MinHpValue(+pct, -flat)      SMART_ACTION_MOUNT_TO_ENTRY_OR_MODEL            = 43,     // Creature_template entry(param1) OR ModelId (param2) (or 0 for both to dismount) -    SMART_ACTION_SET_INGAME_PHASE_MASK              = 44,     // mask +    SMART_ACTION_SET_INGAME_PHASE_ID                = 44,     // PhaseId, apply      SMART_ACTION_SET_DATA                           = 45,     // Field, Data (only creature @todo)      SMART_ACTION_MOVE_FORWARD                       = 46,     // distance      SMART_ACTION_SET_VISIBILITY                     = 47,     // on/off @@ -728,9 +728,16 @@ struct SmartAction          struct          { -            uint32 mask; -        } ingamePhaseMask; +            uint32 id; +            uint32 apply; +        } ingamePhaseId; +        struct   +        { +            uint32 groupId; +            uint32 apply; +        } ingamePhaseGroup; +                  struct          {              uint32 field; diff --git a/src/server/game/Battlefield/Battlefield.cpp b/src/server/game/Battlefield/Battlefield.cpp index a797f6109ca..046af770aff 100644 --- a/src/server/game/Battlefield/Battlefield.cpp +++ b/src/server/game/Battlefield/Battlefield.cpp @@ -479,14 +479,12 @@ void Battlefield::HideNpc(Creature* creature)      creature->CombatStop();      creature->SetReactState(REACT_PASSIVE);      creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE); -    creature->SetPhaseMask(2, true);      creature->DisappearAndDie();      creature->SetVisible(false);  }  void Battlefield::ShowNpc(Creature* creature, bool aggressive)  { -    creature->SetPhaseMask(1, true);      creature->SetVisible(true);      creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);      if (!creature->IsAlive()) @@ -800,7 +798,6 @@ Creature* Battlefield::SpawnCreature(uint32 entry, float x, float y, float z, fl          delete creature;          return NULL;      } -      creature->SetHomePosition(x, y, z, o);      CreatureTemplate const* cinfo = sObjectMgr->GetCreatureTemplate(entry); diff --git a/src/server/game/Battlegrounds/Battleground.cpp b/src/server/game/Battlegrounds/Battleground.cpp index dff99280e73..ba207c1ffc3 100644 --- a/src/server/game/Battlegrounds/Battleground.cpp +++ b/src/server/game/Battlegrounds/Battleground.cpp @@ -1539,6 +1539,7 @@ bool Battleground::AddObject(uint32 type, uint32 entry, float x, float y, float          delete go;          return false;      } +  /*      uint32 guid = go->GetGUIDLow(); diff --git a/src/server/game/Combat/ThreatManager.cpp b/src/server/game/Combat/ThreatManager.cpp index 339ec579b1a..edf15aaf1ff 100644 --- a/src/server/game/Combat/ThreatManager.cpp +++ b/src/server/game/Combat/ThreatManager.cpp @@ -75,7 +75,7 @@ bool ThreatCalcHelper::isValidProcess(Unit* hatedUnit, Unit* hatingUnit, SpellIn          return false;      // not in same map or phase -    if (!hatedUnit->IsInMap(hatingUnit) || !hatedUnit->InSamePhase(hatingUnit)) +    if (!hatedUnit->IsInMap(hatingUnit) || !hatedUnit->IsInPhase(hatingUnit))          return false;      // spell not causing threat @@ -182,7 +182,7 @@ void HostileReference::updateOnlineStatus()          && (getTarget()->GetTypeId() != TYPEID_PLAYER || !getTarget()->ToPlayer()->IsGameMaster())          && !getTarget()->HasUnitState(UNIT_STATE_IN_FLIGHT)          && getTarget()->IsInMap(GetSourceUnit()) -        && getTarget()->InSamePhase(GetSourceUnit()) +        && getTarget()->IsInPhase(GetSourceUnit())          )      {          Creature* creature = GetSourceUnit()->ToCreature(); diff --git a/src/server/game/Conditions/ConditionMgr.cpp b/src/server/game/Conditions/ConditionMgr.cpp index 74beed534c6..0217363862e 100644 --- a/src/server/game/Conditions/ConditionMgr.cpp +++ b/src/server/game/Conditions/ConditionMgr.cpp @@ -295,9 +295,9 @@ bool Condition::Meets(ConditionSourceInfo& sourceInfo)              condMeets = ConditionValue2 == sWorld->getWorldState(ConditionValue1);              break;          } -        case CONDITION_PHASEMASK: +        case CONDITION_PHASEID:          { -            condMeets = object->GetPhaseMask() & ConditionValue1; +            condMeets = object->IsInPhase(ConditionValue1);              break;          }          case CONDITION_TITLE: @@ -474,7 +474,7 @@ uint32 Condition::GetSearcherTypeMaskForCondition()          case CONDITION_WORLD_STATE:              mask |= GRID_MAP_TYPE_MASK_ALL;              break; -        case CONDITION_PHASEMASK: +        case CONDITION_PHASEID:              mask |= GRID_MAP_TYPE_MASK_ALL;              break;          case CONDITION_TITLE: @@ -1512,11 +1512,11 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)              }              break;          case CONDITION_SOURCE_TYPE_PHASE_DEFINITION: -            if (!PhaseMgr::IsConditionTypeSupported(cond->ConditionType)) +            /*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:          { @@ -1995,12 +1995,17 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond)                  TC_LOG_ERROR("sql.sql", "World state condition has useless data in value3 (%u)!", cond->ConditionValue3);              break;          } -        case CONDITION_PHASEMASK: +        case CONDITION_PHASEID:          { +            if (!sPhaseStore.LookupEntry(cond->ConditionValue1)) +            { +                TC_LOG_ERROR("sql.sql", "Phase condition has nonexistent phaseid in value1 (%u), skipped", cond->ConditionValue1); +                return false; +            }              if (cond->ConditionValue2) -                TC_LOG_ERROR("sql.sql", "Phasemask condition has useless data in value2 (%u)!", cond->ConditionValue2); +                TC_LOG_ERROR("sql.sql", "Phase condition has useless data in value2 (%u)!", cond->ConditionValue2);              if (cond->ConditionValue3) -                TC_LOG_ERROR("sql.sql", "Phasemask condition has useless data in value3 (%u)!", cond->ConditionValue3); +                TC_LOG_ERROR("sql.sql", "Phase condition has useless data in value3 (%u)!", cond->ConditionValue3);              break;          }          case CONDITION_TITLE: diff --git a/src/server/game/Conditions/ConditionMgr.h b/src/server/game/Conditions/ConditionMgr.h index 8843aa243a7..35aa60772bd 100644 --- a/src/server/game/Conditions/ConditionMgr.h +++ b/src/server/game/Conditions/ConditionMgr.h @@ -59,7 +59,7 @@ enum ConditionTypes      CONDITION_AREAID                = 23,                   // area_id          0              0                  true if in area_id      CONDITION_CREATURE_TYPE         = 24,                   // cinfo.type       0              0                  true if creature_template.type = value1      CONDITION_SPELL                 = 25,                   // spell_id         0              0                  true if player has learned spell -    CONDITION_PHASEMASK             = 26,                   // phasemask        0              0                  true if object is in phasemask +    CONDITION_PHASEID               = 26,                   // phaseid          0              0                  true if object is in phaseid      CONDITION_LEVEL                 = 27,                   // level            ComparisonType 0                  true if unit's level is equal to param1 (param2 can modify the statement)      CONDITION_QUEST_COMPLETE        = 28,                   // quest_id         0              0                  true if player has quest_id with all objectives complete, but not yet rewarded      CONDITION_NEAR_CREATURE         = 29,                   // creature entry   distance       0                  true if there is a creature of entry in range diff --git a/src/server/game/Entities/AreaTrigger/AreaTrigger.cpp b/src/server/game/Entities/AreaTrigger/AreaTrigger.cpp index f399686d5d5..a8e32b82f01 100644 --- a/src/server/game/Entities/AreaTrigger/AreaTrigger.cpp +++ b/src/server/game/Entities/AreaTrigger/AreaTrigger.cpp @@ -81,6 +81,9 @@ bool AreaTrigger::CreateAreaTrigger(uint32 guidlow, uint32 triggerEntry, Unit* c      SetFloatValue(AREATRIGGER_FINAL_POS + 1, pos.GetPositionY());      SetFloatValue(AREATRIGGER_FINAL_POS + 2, pos.GetPositionZ()); +    for (auto phase : caster->GetPhases()) +        SetInPhase(phase, false, true); +      if (!GetMap()->AddToMap(this))          return false; diff --git a/src/server/game/Entities/Corpse/Corpse.cpp b/src/server/game/Entities/Corpse/Corpse.cpp index 2fa82acdaf5..b6b46ff45df 100644 --- a/src/server/game/Entities/Corpse/Corpse.cpp +++ b/src/server/game/Entities/Corpse/Corpse.cpp @@ -187,7 +187,6 @@ bool Corpse::LoadCorpseFromDB(uint32 guid, Field* fields)      // place      SetLocationInstanceId(instanceId);      SetLocationMapId(mapId); -    SetPhaseMask(phaseMask, false);      Relocate(posX, posY, posZ, o);      if (!IsPositionValid()) diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index 0f86669f14c..f976fb2c3e4 100644 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -738,7 +738,13 @@ bool Creature::Create(uint32 guidlow, Map* map, uint32 phaseMask, uint32 entry,  {      ASSERT(map);      SetMap(map); -    SetPhaseMask(phaseMask, false); + +    if (data && data->phaseid) +        SetInPhase(data->phaseid, false, true); + +    if (data && data->phaseGroup) +        for (auto ph : GetPhasesForGroup(data->phaseGroup)) +            SetInPhase(ph, false, true);      CreatureTemplate const* cinfo = sObjectMgr->GetCreatureTemplate(entry);      if (!cinfo) @@ -1506,8 +1512,6 @@ void Creature::setDeathState(DeathState s)          SetMeleeDamageSchool(SpellSchools(cinfo->dmgschool));          LoadCreaturesAddon(true);          Motion_Initialize(); -        if (GetCreatureData() && GetPhaseMask() != GetCreatureData()->phaseMask) -            SetPhaseMask(GetCreatureData()->phaseMask, false);          Unit::setDeathState(ALIVE);      }  } diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h index 8a22ce61f0d..574c10d14f4 100644 --- a/src/server/game/Entities/Creature/Creature.h +++ b/src/server/game/Entities/Creature/Creature.h @@ -254,7 +254,7 @@ struct CreatureData      CreatureData() : id(0), mapid(0), phaseMask(0), displayid(0), equipmentId(0),                       posX(0.0f), posY(0.0f), posZ(0.0f), orientation(0.0f), spawntimesecs(0),                       spawndist(0.0f), currentwaypoint(0), curhealth(0), curmana(0), movementType(0), -                     spawnMask(0), npcflag(0), unit_flags(0), dynamicflags(0), dbData(true) { } +                     spawnMask(0), npcflag(0), unit_flags(0), dynamicflags(0), phaseid(0), phaseGroup(0), dbData(true) { }      uint32 id;                                              // entry in creature_template      uint16 mapid;      uint32 phaseMask; @@ -274,6 +274,8 @@ struct CreatureData      uint32 npcflag;      uint32 unit_flags;                                      // enum UnitFlags mask values      uint32 dynamicflags; +    uint32 phaseid; +    uint32 phaseGroup;      bool dbData;  }; diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp index 4e1b8ed29b2..a2528c78516 100644 --- a/src/server/game/Entities/GameObject/GameObject.cpp +++ b/src/server/game/Entities/GameObject/GameObject.cpp @@ -180,8 +180,6 @@ bool GameObject::Create(uint32 guidlow, uint32 name_id, Map* map, uint32 phaseMa          return false;      } -    SetPhaseMask(phaseMask, false); -      SetZoneScript();      if (m_zoneScript)      { @@ -832,6 +830,16 @@ bool GameObject::LoadGameObjectFromDB(uint32 guid, Map* map, bool addToMap)      if (!Create(guid, entry, map, phaseMask, x, y, z, ang, rotation0, rotation1, rotation2, rotation3, animprogress, go_state, artKit))          return false; +    if (data->phaseid) +        SetInPhase(data->phaseid, false, true); +     +    if (data->phaseGroup) +    { +        // Set the gameobject in all the phases of the phasegroup +        for (auto ph : GetPhasesForGroup(data->phaseGroup)) +            SetInPhase(ph, false, true); +    } +      if (data->spawntimesecs >= 0)      {          m_spawnedByDefault = true; @@ -2071,9 +2079,9 @@ void GameObject::SetDisplayId(uint32 displayid)      UpdateModel();  } -void GameObject::SetPhaseMask(uint32 newPhaseMask, bool update) +void GameObject::SetInPhase(uint32 id, bool update, bool apply)  { -    WorldObject::SetPhaseMask(newPhaseMask, update); +    WorldObject::SetInPhase(id, update, apply);      if (m_model && m_model->isEnabled())          EnableCollision(true);  } diff --git a/src/server/game/Entities/GameObject/GameObject.h b/src/server/game/Entities/GameObject/GameObject.h index 47a92ee4fa5..11df5a17409 100644 --- a/src/server/game/Entities/GameObject/GameObject.h +++ b/src/server/game/Entities/GameObject/GameObject.h @@ -592,7 +592,7 @@ struct GameObjectData  {      explicit GameObjectData() : id(0), mapid(0), phaseMask(0), posX(0.0f), posY(0.0f), posZ(0.0f), orientation(0.0f),                                  rotation0(0.0f), rotation1(0.0f), rotation2(0.0f), rotation3(0.0f), spawntimesecs(0), -                                animprogress(0), go_state(GO_STATE_ACTIVE), spawnMask(0), artKit(0), dbData(true) { } +                                animprogress(0), go_state(GO_STATE_ACTIVE), spawnMask(0), artKit(0), phaseid(0), phaseGroup(0), dbData(true) { }      uint32 id;                                              // entry in gamobject_template      uint16 mapid;      uint32 phaseMask; @@ -609,6 +609,8 @@ struct GameObjectData      GOState go_state;      uint8 spawnMask;      uint8 artKit; +    uint32 phaseid; +    uint32 phaseGroup;      bool dbData;  }; @@ -725,7 +727,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, uint32 lowguid = 0); -        void SetPhaseMask(uint32 newPhaseMask, bool update); +        void SetInPhase(uint32 id, bool update, bool apply);          void EnableCollision(bool enable);          void Use(Unit* user); @@ -877,6 +879,7 @@ class GameObject : public WorldObject, public GridObject<GameObject>, public Map              //! Following check does check 3d distance              return IsInRange(obj->GetPositionX(), obj->GetPositionY(), obj->GetPositionZ(), dist2compare);          } +                  GameObjectAI* m_AI;  };  #endif diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp index 28839775732..38f1469f7bd 100644 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -1496,7 +1496,7 @@ bool WorldObject::IsWithinDist(WorldObject const* obj, float dist2compare, bool  bool WorldObject::IsWithinDistInMap(WorldObject const* obj, float dist2compare, bool is3D /*= true*/) const  { -    return obj && IsInMap(obj) && InSamePhase(obj) && _IsWithinDist(obj, dist2compare, is3D); +    return obj && IsInMap(obj) && IsInPhase(obj) && _IsWithinDist(obj, dist2compare, is3D);  }  bool WorldObject::IsWithinLOS(float ox, float oy, float oz) const @@ -1935,7 +1935,7 @@ bool WorldObject::CanSeeOrDetect(WorldObject const* obj, bool ignoreStealth, boo  bool WorldObject::CanNeverSee(WorldObject const* obj) const  { -    return GetMap() != obj->GetMap() || !InSamePhase(obj); +    return GetMap() != obj->GetMap() || !IsInPhase(obj);  }  bool WorldObject::CanDetect(WorldObject const* obj, bool ignoreStealth) const @@ -2332,9 +2332,9 @@ TempSummon* Map::SummonCreature(uint32 entry, Position const& pos, SummonPropert          }      } -    uint32 phase = PHASEMASK_NORMAL; +    std::set<uint32> phases;      if (summoner) -        phase = summoner->GetPhaseMask(); +        phases = summoner->GetPhases();      TempSummon* summon = NULL;      switch (mask) @@ -2356,12 +2356,16 @@ TempSummon* Map::SummonCreature(uint32 entry, Position const& pos, SummonPropert              break;      } -    if (!summon->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), this, phase, entry, pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation(), nullptr, vehId)) +    if (!summon->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), this, 0, entry, pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation(), nullptr, vehId))      {          delete summon;          return NULL;      } +    // Set the summon to the summoner's phase +    for (auto phaseId : phases) +        summon->SetInPhase(phaseId, false, true); +      summon->SetUInt32Value(UNIT_CREATED_BY_SPELL, spellId);      summon->SetHomePosition(pos); @@ -2456,6 +2460,9 @@ GameObject* WorldObject::SummonGameObject(uint32 entry, float x, float y, float          return NULL;      } +    for (auto phase : GetPhases()) +        go->SetInPhase(phase, false, true); +      go->SetRespawnTime(respawnTime);      if (GetTypeId() == TYPEID_PLAYER || GetTypeId() == TYPEID_UNIT) //not sure how to handle this          ToUnit()->AddGameObject(go); @@ -2838,9 +2845,36 @@ void WorldObject::SetPhaseMask(uint32 newPhaseMask, bool update)          UpdateObjectVisibility();  } +void WorldObject::SetInPhase(uint32 id, bool update, bool apply) +{ +    if (apply) +        _phases.insert(id); +    else +        _phases.erase(id); +     +    if (update && IsInWorld()) +        UpdateObjectVisibility(); +} + +bool WorldObject::IsInPhase(WorldObject const* obj) const +{ +    // PhaseId 169 is the default fallback phase +    if (_phases.empty() && obj->GetPhases().empty()) +        return true; + +    if (_phases.empty() && obj->IsInPhase(169)) +        return true; + +    if (obj->GetPhases().empty() && IsInPhase(169)) +        return true; + +    return Trinity::Containers::Intersects(_phases.begin(), _phases.end(), obj->GetPhases().begin(), obj->GetPhases().end()); +} +  bool WorldObject::InSamePhase(WorldObject const* obj) const  { -    return InSamePhase(obj->GetPhaseMask()); +    return IsInPhase(obj); +    // return InSamePhase(obj->GetPhaseMask());  }  void WorldObject::PlayDistanceSound(uint32 sound_id, Player* target /*= NULL*/) diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h index 5e525f1e0d5..2d7a6f12016 100644 --- a/src/server/game/Entities/Object/Object.h +++ b/src/server/game/Entities/Object/Object.h @@ -676,9 +676,13 @@ 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);          uint32 GetPhaseMask() const { return m_phaseMask; }          bool InSamePhase(WorldObject const* obj) const;          bool InSamePhase(uint32 phasemask) const { return (GetPhaseMask() & phasemask); } +        bool IsInPhase(uint32 phase) const { return _phases.find(phase) != _phases.end(); } +        bool IsInPhase(WorldObject const* obj) const; +        std::set<uint32> const& GetPhases() const { return _phases; }          uint32 GetZoneId() const;          uint32 GetAreaId() const; @@ -861,6 +865,7 @@ class WorldObject : public Object, public WorldLocation          //uint32 m_mapId;                                     // object at map with map_id          uint32 m_InstanceId;                                // in map copy with instance id          uint32 m_phaseMask;                                 // in area phase state +        std::set<uint32> _phases;          uint16 m_notifyflags;          uint16 m_executed_notifies; diff --git a/src/server/game/Entities/Pet/Pet.cpp b/src/server/game/Entities/Pet/Pet.cpp index 82c6f1541ef..c1b0ef43dbf 100644 --- a/src/server/game/Entities/Pet/Pet.cpp +++ b/src/server/game/Entities/Pet/Pet.cpp @@ -179,6 +179,9 @@ bool Pet::LoadPetFromDB(Player* owner, uint32 petEntry, uint32 petnumber, bool c      if (!Create(guid, map, owner->GetPhaseMask(), petEntry, petId))          return false; +    for (auto itr : owner->GetPhases()) +        SetInPhase(itr, false, true); +      setPetType(petType);      setFaction(owner->getFaction());      SetUInt32Value(UNIT_CREATED_BY_SPELL, summonSpellId); diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 0325c288944..9c05f77cdf1 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -668,7 +668,7 @@ void KillRewarder::Reward()  } -Player::Player(WorldSession* session): Unit(true), phaseMgr(this) +Player::Player(WorldSession* session): Unit(true)  {      m_speakTime = 0;      m_speakCount = 0; @@ -2892,7 +2892,6 @@ void Player::SetGameMaster(bool on)          getHostileRefManager().setOnlineOfflineState(false);          CombatStopWithPets(); -        SetPhaseMask(uint32(PHASEMASK_ANYWHERE), false);    // see and visible in all phases          m_serverSideVisibilityDetect.SetValue(SERVERSIDE_VISIBILITY_GM, GetSession()->GetSecurity());      }      else @@ -2917,9 +2916,6 @@ void Player::SetGameMaster(bool on)          getHostileRefManager().setOnlineOfflineState(true);          m_serverSideVisibilityDetect.SetValue(SERVERSIDE_VISIBILITY_GM, SEC_PLAYER); - -        phaseMgr.AddUpdateFlag(PHASE_UPDATE_FLAG_SERVERSIDE_CHANGED); -        phaseMgr.Update();      }      UpdateObjectVisibility(); @@ -3160,11 +3156,6 @@ void Player::GiveLevel(uint8 level)      UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_LEVEL); -    PhaseUpdateData phaseUpdateData; -    phaseUpdateData.AddConditionType(CONDITION_LEVEL); - -    phaseMgr.NotifyConditionChanged(phaseUpdateData); -      // Refer-A-Friend      if (GetSession()->GetRecruiterId())          if (level < sWorld->getIntConfig(CONFIG_MAX_RECRUIT_A_FRIEND_BONUS_PLAYER_LEVEL)) @@ -7789,8 +7780,6 @@ void Player::UpdateArea(uint32 newArea)      // so apply them accordingly      m_areaUpdateId    = newArea; -    phaseMgr.AddUpdateFlag(PHASE_UPDATE_FLAG_AREA_UPDATE); -      AreaTableEntry const* area = GetAreaEntryByAreaID(newArea);      pvpInfo.IsInFFAPvPArea = area && (area->flags & AREA_FLAG_ARENA);      UpdatePvPState(true); @@ -7821,14 +7810,10 @@ void Player::UpdateArea(uint32 newArea)          RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING);          SetRestType(REST_TYPE_NO);      } - -    phaseMgr.RemoveUpdateFlag(PHASE_UPDATE_FLAG_AREA_UPDATE);  }  void Player::UpdateZone(uint32 newZone, uint32 newArea)  { -    phaseMgr.AddUpdateFlag(PHASE_UPDATE_FLAG_ZONE_UPDATE); -      if (m_zoneUpdateId != newZone)      {          sOutdoorPvPMgr->HandlePlayerLeaveZone(this, m_zoneUpdateId); @@ -7933,8 +7918,6 @@ void Player::UpdateZone(uint32 newZone, uint32 newArea)      UpdateLocalChannels(newZone);      UpdateZoneDependentAuras(newZone); - -    phaseMgr.RemoveUpdateFlag(PHASE_UPDATE_FLAG_ZONE_UPDATE);  }  //If players are too far away from the duel flag... they lose the duel @@ -15484,10 +15467,6 @@ void Player::RewardQuest(Quest const* quest, uint32 reward, Object* questGiver,      m_RewardedQuests.insert(quest_id);      m_RewardedQuestsSave[quest_id] = true; -    PhaseUpdateData phaseUpdateData; -    phaseUpdateData.AddQuestUpdate(quest_id); -    phaseMgr.NotifyConditionChanged(phaseUpdateData); -      // StoreNewItem, mail reward, etc. save data directly to the database      // to prevent exploitable data desynchronisation we save the quest status to the database too      // (to prevent rewarding this quest another time while rewards were already given out) @@ -16137,11 +16116,6 @@ void Player::SetQuestStatus(uint32 questId, QuestStatus status, bool update /*=          m_QuestStatusSave[questId] = true;      } -    PhaseUpdateData phaseUpdateData; -    phaseUpdateData.AddQuestUpdate(questId); - -    phaseMgr.NotifyConditionChanged(phaseUpdateData); -      if (update)          SendQuestUpdate(questId);  } @@ -16153,11 +16127,6 @@ void Player::RemoveActiveQuest(uint32 questId, bool update /*= true*/)      {          m_QuestStatus.erase(itr);          m_QuestStatusSave[questId] = false; - -        PhaseUpdateData phaseUpdateData; -        phaseUpdateData.AddQuestUpdate(questId); - -        phaseMgr.NotifyConditionChanged(phaseUpdateData);      }      if (update) @@ -16171,11 +16140,6 @@ void Player::RemoveRewardedQuest(uint32 questId, bool update /*= true*/)      {          m_RewardedQuests.erase(rewItr);          m_RewardedQuestsSave[questId] = false; - -        PhaseUpdateData phaseUpdateData; -        phaseUpdateData.AddQuestUpdate(questId); - -        phaseMgr.NotifyConditionChanged(phaseUpdateData);      }      if (update) @@ -27538,6 +27502,9 @@ Pet* Player::SummonPet(uint32 entry, float x, float y, float z, float ang, PetTy          return NULL;      } +    for (auto itr : GetPhases()) +        pet->SetInPhase(itr, false, true); +      pet->SetCreatorGUID(GetGUID());      pet->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE, getFaction()); @@ -27910,3 +27877,24 @@ void Player::ReadMovementInfo(WorldPacket& data, MovementInfo* mi, Movement::Ext      #undef REMOVE_VIOLATING_FLAGS  } + +void Player::UpdatePhasing() +{ +    if (!IsInWorld()) +        return; + +    std::set<uint32> phaseIds; +    std::set<uint32> terrainswaps; +    std::set<uint32> worldAreaSwaps; + +    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); +} diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 94d90de8813..3d0300a681b 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -25,7 +25,6 @@  #include "Item.h"  #include "PetDefines.h" -#include "PhaseMgr.h"  #include "QuestDef.h"  #include "SpellMgr.h"  #include "Unit.h" @@ -56,7 +55,6 @@ class PlayerMenu;  class PlayerSocial;  class SpellCastTargets;  class UpdateMask; -class PhaseMgr;  typedef std::deque<Mail*> PlayerMails; @@ -1333,8 +1331,6 @@ class Player : public Unit, public GridObject<Player>          Pet* SummonPet(uint32 entry, float x, float y, float z, float ang, PetType petType, uint32 despwtime);          void RemovePet(Pet* pet, PetSaveMode mode, bool returnreagent = false); -        PhaseMgr& GetPhaseMgr() { return phaseMgr; } -          /// Handles said message in regular chat based on declared language and in config pre-defined Range.          void Say(std::string const& text, const uint32 language);          /// Handles yelled message in regular chat based on declared language and in config pre-defined Range. @@ -2362,6 +2358,8 @@ class Player : public Unit, public GridObject<Player>          void UpdateVisibilityOf(WorldObject* target);          void UpdateTriggerVisibility(); +        void UpdatePhasing(); +          template<class T>          void UpdateVisibilityOf(T* target, UpdateData& data, std::set<Unit*>& visibleNow); @@ -2890,8 +2888,6 @@ class Player : public Unit, public GridObject<Player>          uint32 _activeCheats;          uint32 _maxPersonalArenaRate; - -        PhaseMgr phaseMgr;  };  void AddItemsSetItem(Player*player, Item* item); diff --git a/src/server/game/Entities/Transport/Transport.cpp b/src/server/game/Entities/Transport/Transport.cpp index 4509d0f4d12..0c22caed882 100644 --- a/src/server/game/Entities/Transport/Transport.cpp +++ b/src/server/game/Entities/Transport/Transport.cpp @@ -301,6 +301,15 @@ Creature* Transport::CreateNPCPassenger(uint32 guid, CreatureData const* data)          return NULL;      } +    if (data->phaseid) +        creature->SetInPhase(data->phaseid, false, true); +    else if (data->phaseGroup) +        for (auto phase : 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); +      if (!map->AddToMap(creature))      {          delete creature; @@ -405,9 +414,11 @@ TempSummon* Transport::SummonPassenger(uint32 entry, Position const& pos, TempSu          }      } -    uint32 phase = PHASEMASK_NORMAL; +    std::set<uint32> phases;      if (summoner) -        phase = summoner->GetPhaseMask(); +        phases = summoner->GetPhases(); +    else +        phases = GetPhases(); // If there was no summoner, try to use the transport phases      TempSummon* summon = NULL;      switch (mask) @@ -433,12 +444,15 @@ TempSummon* Transport::SummonPassenger(uint32 entry, Position const& pos, TempSu      pos.GetPosition(x, y, z, o);      CalculatePassengerPosition(x, y, z, &o); -    if (!summon->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), map, phase, entry, x, y, z, o, nullptr, vehId)) +    if (!summon->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), map, 0, entry, x, y, z, o, nullptr, vehId))      {          delete summon;          return NULL;      } +    for (auto itr : phases) +        summon->SetInPhase(itr, false, true); +      summon->SetUInt32Value(UNIT_CREATED_BY_SPELL, spellId);      summon->SetTransport(this); diff --git a/src/server/game/Entities/Transport/Transport.h b/src/server/game/Entities/Transport/Transport.h index e644417f1ac..7da8c11861c 100644 --- a/src/server/game/Entities/Transport/Transport.h +++ b/src/server/game/Entities/Transport/Transport.h @@ -27,7 +27,7 @@ struct CreatureData;  class Transport : public GameObject, public TransportBase  { -        friend Transport* TransportMgr::CreateTransport(uint32, uint32, Map*); +        friend Transport* TransportMgr::CreateTransport(uint32, uint32, Map*, uint32, uint32);          Transport();      public: diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 4e9954116eb..f2fd90bb964 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -435,7 +435,7 @@ float Unit::GetMeleeReach() const  bool Unit::IsWithinCombatRange(const Unit* obj, float dist2compare) const  { -    if (!obj || !IsInMap(obj) || !InSamePhase(obj)) +    if (!obj || !IsInMap(obj) || !IsInPhase(obj))          return false;      float dx = GetPositionX() - obj->GetPositionX(); @@ -451,7 +451,7 @@ bool Unit::IsWithinCombatRange(const Unit* obj, float dist2compare) const  bool Unit::IsWithinMeleeRange(const Unit* obj, float dist) const  { -    if (!obj || !IsInMap(obj) || !InSamePhase(obj)) +    if (!obj || !IsInMap(obj) || !IsInPhase(obj))          return false;      float dx = GetPositionX() - obj->GetPositionX(); @@ -3643,7 +3643,7 @@ void Unit::RemoveAurasWithAttribute(uint32 flags)      }  } -void Unit::RemoveNotOwnSingleTargetAuras(uint32 newPhase) +void Unit::RemoveNotOwnSingleTargetAuras(uint32 newPhase, bool phaseid)  {      // single target auras from other casters      for (AuraApplicationMap::iterator iter = m_appliedAuras.begin(); iter != m_appliedAuras.end();) @@ -3653,12 +3653,12 @@ void Unit::RemoveNotOwnSingleTargetAuras(uint32 newPhase)          if (aura->GetCasterGUID() != GetGUID() && aura->GetSpellInfo()->IsSingleTarget())          { -            if (!newPhase) +            if (!newPhase && !phaseid)                  RemoveAura(iter);              else              {                  Unit* caster = aura->GetCaster(); -                if (!caster || !caster->InSamePhase(newPhase)) +                if (!caster || (newPhase && !caster->InSamePhase(newPhase)) || (!newPhase && !caster->IsInPhase(this)))                      RemoveAura(iter);                  else                      ++iter; @@ -14656,61 +14656,54 @@ float Unit::MeleeSpellMissChance(const Unit* victim, WeaponAttackType attType, u      return missChance;  } -void Unit::SetPhaseMask(uint32 newPhaseMask, bool update) +void Unit::SetInPhase(uint32 id, bool update, bool apply)  { -    if (newPhaseMask == GetPhaseMask()) +    WorldObject::SetInPhase(id, update, apply); + +    if (!IsInWorld())          return; +     +    RemoveNotOwnSingleTargetAuras(0, true); -    if (IsInWorld()) +    if (GetTypeId() == TYPEID_UNIT || (!ToPlayer()->IsGameMaster() && !ToPlayer()->GetSession()->PlayerLogout()))      { -        RemoveNotOwnSingleTargetAuras(newPhaseMask);            // we can lost access to caster or target +        HostileRefManager& refManager = getHostileRefManager(); +        HostileReference* ref = refManager.getFirst(); -        // modify hostile references for new phasemask, some special cases deal with hostile references themselves -        if (GetTypeId() == TYPEID_UNIT || (!ToPlayer()->IsGameMaster() && !ToPlayer()->GetSession()->PlayerLogout())) +        while (ref)          { -            HostileRefManager& refManager = getHostileRefManager(); -            HostileReference* ref = refManager.getFirst(); - -            while (ref) -            { -                if (Unit* unit = ref->GetSource()->GetOwner()) -                    if (Creature* creature = unit->ToCreature()) -                        refManager.setOnlineOfflineState(creature, creature->InSamePhase(newPhaseMask)); +            if (Unit* unit = ref->GetSource()->GetOwner()) +                if (Creature* creature = unit->ToCreature()) +                    refManager.setOnlineOfflineState(creature, creature->IsInPhase(this)); -                ref = ref->next(); -            } +            ref = ref->next(); +        } -            // modify threat lists for new phasemask -            if (GetTypeId() != TYPEID_PLAYER) -            { -                std::list<HostileReference*> threatList = getThreatManager().getThreatList(); -                std::list<HostileReference*> offlineThreatList = getThreatManager().getOfflineThreatList(); +        // modify threat lists for new phasemask +        if (GetTypeId() != TYPEID_PLAYER) +        { +            std::list<HostileReference*> threatList = getThreatManager().getThreatList(); +            std::list<HostileReference*> offlineThreatList = getThreatManager().getOfflineThreatList(); -                // merge expects sorted lists -                threatList.sort(); -                offlineThreatList.sort(); -                threatList.merge(offlineThreatList); +            // merge expects sorted lists +            threatList.sort(); +            offlineThreatList.sort(); +            threatList.merge(offlineThreatList); -                for (std::list<HostileReference*>::const_iterator itr = threatList.begin(); itr != threatList.end(); ++itr) -                    if (Unit* unit = (*itr)->getTarget()) -                        unit->getHostileRefManager().setOnlineOfflineState(ToCreature(), unit->InSamePhase(newPhaseMask)); -            } +            for (std::list<HostileReference*>::const_iterator itr = threatList.begin(); itr != threatList.end(); ++itr) +                if (Unit* unit = (*itr)->getTarget()) +                    unit->getHostileRefManager().setOnlineOfflineState(ToCreature(), unit->IsInPhase(this));          }      } -    WorldObject::SetPhaseMask(newPhaseMask, update); - -    if (!IsInWorld()) -        return; -      for (ControlList::const_iterator itr = m_Controlled.begin(); itr != m_Controlled.end(); ++itr)          if ((*itr)->GetTypeId() == TYPEID_UNIT) -            (*itr)->SetPhaseMask(newPhaseMask, true); +            (*itr)->SetInPhase(id, true, apply);      for (uint8 i = 0; i < MAX_SUMMON_SLOT; ++i)          if (m_SummonSlot[i])              if (Creature* summon = GetMap()->GetCreature(m_SummonSlot[i])) -                summon->SetPhaseMask(newPhaseMask, true); +                summon->SetInPhase(id, true, apply);  }  void Unit::UpdateObjectVisibility(bool forced) diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index 8adccb25f84..eb0882e3b64 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -1762,7 +1762,7 @@ class Unit : public WorldObject          void RemoveAurasDueToSpellBySteal(uint32 spellId, uint64 casterGUID, Unit* stealer);          void RemoveAurasDueToItemSpell(uint32 spellId, uint64 castItemGuid);          void RemoveAurasByType(AuraType auraType, uint64 casterGUID = 0, Aura* except = NULL, bool negative = true, bool positive = true); -        void RemoveNotOwnSingleTargetAuras(uint32 newPhase = 0x0); +        void RemoveNotOwnSingleTargetAuras(uint32 newPhase = 0x0, bool phaseid = false);          void RemoveAurasWithInterruptFlags(uint32 flag, uint32 except = 0);          void RemoveAurasWithAttribute(uint32 flags);          void RemoveAurasWithFamily(SpellFamilyNames family, uint32 familyFlag1, uint32 familyFlag2, uint32 familyFlag3, uint64 casterGUID); @@ -1928,7 +1928,7 @@ class Unit : public WorldObject          void SetVisible(bool x);          // common function for visibility checks for player/creatures with detection code -        void SetPhaseMask(uint32 newPhaseMask, bool update);// overwrite WorldObject::SetPhaseMask +        void SetInPhase(uint32 id, bool update, bool apply);          void UpdateObjectVisibility(bool forced = true);          SpellImmuneList m_spellImmune[MAX_SPELL_IMMUNITY]; diff --git a/src/server/game/Globals/ObjectAccessor.cpp b/src/server/game/Globals/ObjectAccessor.cpp index 7de319df07f..13609f8e949 100644 --- a/src/server/game/Globals/ObjectAccessor.cpp +++ b/src/server/game/Globals/ObjectAccessor.cpp @@ -371,7 +371,6 @@ Corpse* ObjectAccessor::ConvertCorpseForPlayer(uint64 player_guid, bool insignia          // bones->m_time = m_time;                              // don't overwrite time          // bones->m_type = m_type;                              // don't overwrite type          bones->Relocate(corpse->GetPositionX(), corpse->GetPositionY(), corpse->GetPositionZ(), corpse->GetOrientation()); -        bones->SetPhaseMask(corpse->GetPhaseMask(), false);          bones->SetUInt32Value(CORPSE_FIELD_FLAGS, CORPSE_FLAG_UNK2 | CORPSE_FLAG_BONES);          bones->SetUInt64Value(CORPSE_FIELD_OWNER, 0); diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index f64f57602c7..fae3683a140 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -1627,8 +1627,8 @@ void ObjectMgr::LoadCreatures()      //                                               0              1   2    3        4             5           6           7           8            9              10      QueryResult result = WorldDatabase.Query("SELECT creature.guid, id, map, modelid, equipment_id, position_x, position_y, position_z, orientation, spawntimesecs, spawndist, " -    //   11               12         13       14            15         16         17          18          19                20                   21 -        "currentwaypoint, curhealth, curmana, MovementType, spawnMask, phaseMask, eventEntry, pool_entry, creature.npcflag, creature.unit_flags, creature.dynamicflags " +    //   11               12         13       14            15         16         17          18          19                20                   21                         22                    23 +        "currentwaypoint, curhealth, curmana, MovementType, spawnMask, phaseMask, eventEntry, pool_entry, creature.npcflag, creature.unit_flags, creature.dynamicflags, creature.phaseid, creature.phasegroup "          "FROM creature "          "LEFT OUTER JOIN game_event_creature ON creature.guid = game_event_creature.guid "          "LEFT OUTER JOIN pool_creature ON creature.guid = pool_creature.guid"); @@ -1685,6 +1685,8 @@ void ObjectMgr::LoadCreatures()          data.npcflag        = fields[19].GetUInt32();          data.unit_flags     = fields[20].GetUInt32();          data.dynamicflags   = fields[21].GetUInt32(); +        data.phaseid = fields[22].GetUInt32(); +        data.phaseGroup = fields[23].GetUInt32();          MapEntry const* mapEntry = sMapStore.LookupEntry(data.mapid);          if (!mapEntry) @@ -1754,6 +1756,12 @@ void ObjectMgr::LoadCreatures()              data.phaseMask = 1;          } +        if (data.phaseGroup && data.phaseid) +        { +            TC_LOG_ERROR("sql.sql", "Table `creature` have creature (GUID: %u Entry: %u) with both `phaseid` and `phasegroup` set, `phasegroup` set to 0", guid, data.id); +            data.phaseGroup = 0; +        } +          // Add to grid if not managed by the game event or pool system          if (gameEvent == 0 && PoolId == 0)              AddCreatureToGrid(guid, &data); @@ -1937,8 +1945,8 @@ void ObjectMgr::LoadGameobjects()      //                                                0                1   2    3           4           5           6      QueryResult result = WorldDatabase.Query("SELECT gameobject.guid, id, map, position_x, position_y, position_z, orientation, " -    //   7          8          9          10         11             12            13     14         15         16          17 -        "rotation0, rotation1, rotation2, rotation3, spawntimesecs, animprogress, state, spawnMask, phaseMask, eventEntry, pool_entry " +    //   7          8          9          10         11             12            13     14         15         16          17           18        19 +        "rotation0, rotation1, rotation2, rotation3, spawntimesecs, animprogress, state, spawnMask, phaseMask, eventEntry, pool_entry, phaseid, phasegroup "          "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"); @@ -2035,6 +2043,14 @@ void ObjectMgr::LoadGameobjects()          data.phaseMask      = fields[15].GetUInt32();          int16 gameEvent     = fields[16].GetInt8();          uint32 PoolId       = fields[17].GetUInt32(); +        data.phaseid = fields[18].GetUInt32(); +        data.phaseGroup = fields[19].GetUInt32(); + +        if (data.phaseGroup && data.phaseid) +        { +            TC_LOG_ERROR("sql.sql", "Table `gameobject` have gameobject (GUID: %u Entry: %u) with both `phaseid` and `phasegroup` set, `phasegroup` set to 0", guid, data.id); +            data.phaseGroup = 0; +        }          if (data.rotation2 < -1.0f || data.rotation2 > 1.0f)          { @@ -9149,8 +9165,8 @@ void ObjectMgr::LoadPhaseDefinitions()      uint32 oldMSTime = getMSTime(); -    //                                                 0       1       2         3            4           5 -    QueryResult result = WorldDatabase.Query("SELECT zoneId, entry, phasemask, phaseId, terrainswapmap, flags FROM `phase_definitions` ORDER BY `entry` ASC"); +    //                                                 0       1       2        3 +    QueryResult result = WorldDatabase.Query("SELECT zoneId, entry, phaseId, phaseGroup FROM `phase_definitions` ORDER BY `entry` ASC");      if (!result)      { @@ -9168,18 +9184,14 @@ void ObjectMgr::LoadPhaseDefinitions()          PhaseDefinition.zoneId                = fields[0].GetUInt32();          PhaseDefinition.entry                 = fields[1].GetUInt32(); -        PhaseDefinition.phasemask             = fields[2].GetUInt32(); -        PhaseDefinition.phaseId               = fields[3].GetUInt32(); -        PhaseDefinition.terrainswapmap        = fields[4].GetUInt32(); -        PhaseDefinition.flags                 = fields[5].GetUInt32(); +        PhaseDefinition.phaseId               = fields[2].GetUInt32(); +        PhaseDefinition.phaseGroup = fields[3].GetUInt32(); -        // Checks -        if ((PhaseDefinition.flags & PHASE_FLAG_OVERWRITE_EXISTING) && (PhaseDefinition.flags & PHASE_FLAG_NEGATE_PHASE)) +        if (PhaseDefinition.phaseGroup && PhaseDefinition.phaseId)          { -            TC_LOG_ERROR("sql.sql", "Flags defined in phase_definitions in zoneId %d and entry %u does contain PHASE_FLAG_OVERWRITE_EXISTING and PHASE_FLAG_NEGATE_PHASE. Setting flags to PHASE_FLAG_OVERWRITE_EXISTING", PhaseDefinition.zoneId, PhaseDefinition.entry); -            PhaseDefinition.flags &= ~PHASE_FLAG_NEGATE_PHASE; +            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; @@ -9189,18 +9201,18 @@ void ObjectMgr::LoadPhaseDefinitions()      TC_LOG_INFO("server.loading", ">> Loaded %u phasing definitions in %u ms.", count, GetMSTimeDiffToNow(oldMSTime));  } -void ObjectMgr::LoadSpellPhaseInfo() +void ObjectMgr::LoadPhaseInfo()  { -    _SpellPhaseStore.clear(); +    _PhaseInfoStore.clear();      uint32 oldMSTime = getMSTime(); -    //                                               0       1            2 -    QueryResult result = WorldDatabase.Query("SELECT id, phasemask, terrainswapmap FROM `spell_phase`"); +    //                                               0       1                   2        +    QueryResult result = WorldDatabase.Query("SELECT id, worldmapareaswap, terrainswapmap FROM `phase_info`");      if (!result)      { -        TC_LOG_INFO("server.loading", ">> Loaded 0 spell dbc infos. DB table `spell_phase` is empty."); +        TC_LOG_INFO("server.loading", ">> Loaded 0 phase infos. DB table `phase_info` is empty.");          return;      } @@ -9209,31 +9221,25 @@ void ObjectMgr::LoadSpellPhaseInfo()      {          Field* fields = result->Fetch(); -        SpellPhaseInfo spellPhaseInfo; -        spellPhaseInfo.spellId                = fields[0].GetUInt32(); - -        SpellInfo const* spell = sSpellMgr->GetSpellInfo(spellPhaseInfo.spellId); -        if (!spell) -        { -            TC_LOG_ERROR("sql.sql", "Spell %u defined in `spell_phase` does not exists, skipped.", spellPhaseInfo.spellId); -            continue; -        } +        PhaseInfo phaseInfo; +        phaseInfo.phaseId = fields[0].GetUInt32(); -        if (!spell->HasAura(SPELL_AURA_PHASE)) +        PhaseEntry const* phase = sPhaseStore.LookupEntry(phaseInfo.phaseId); +        if (!phase)          { -            TC_LOG_ERROR("sql.sql", "Spell %u defined in `spell_phase` does not have aura effect type SPELL_AURA_PHASE, useless value.", spellPhaseInfo.spellId); +            TC_LOG_ERROR("sql.sql", "Phase %u defined in `phase_info` does not exists, skipped.", phaseInfo.phaseId);              continue;          } -        spellPhaseInfo.phasemask              = fields[1].GetUInt32(); -        spellPhaseInfo.terrainswapmap         = fields[2].GetUInt32(); +        phaseInfo.worldMapAreaSwap              = fields[1].GetUInt32(); +        phaseInfo.terrainSwapMap         = fields[2].GetUInt32(); -        _SpellPhaseStore[spellPhaseInfo.spellId] = spellPhaseInfo; +        _PhaseInfoStore[phaseInfo.phaseId] = phaseInfo;          ++count;      }      while (result->NextRow()); -    TC_LOG_INFO("server.loading", ">> Loaded %u spell dbc infos in %u ms.", count, GetMSTimeDiffToNow(oldMSTime)); +    TC_LOG_INFO("server.loading", ">> Loaded %u phase infos in %u ms.", count, GetMSTimeDiffToNow(oldMSTime));  }  GameObjectTemplate const* ObjectMgr::GetGameObjectTemplate(uint32 entry) diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h index a5894ed1805..62a770f06a8 100644 --- a/src/server/game/Globals/ObjectMgr.h +++ b/src/server/game/Globals/ObjectMgr.h @@ -42,11 +42,9 @@  #include <limits>  #include "ConditionMgr.h"  #include <functional> -#include "PhaseMgr.h"  #include "DB2Stores.h"  class Item; -class PhaseMgr;  struct AccessRequirement;  struct PlayerInfo;  struct PlayerLevelInfo; @@ -132,6 +130,34 @@ 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; @@ -1018,10 +1044,7 @@ class ObjectMgr          void AddSpellToTrainer(uint32 entry, uint32 spell, uint32 spellCost, uint32 reqSkill, uint32 reqSkillValue, uint32 reqLevel);          void LoadPhaseDefinitions(); -        void LoadSpellPhaseInfo(); - -        PhaseDefinitionStore const* GetPhaseDefinitionStore() { return &_PhaseDefinitionStore; } -        SpellPhaseStore const* GetSpellPhaseStore() { return &_SpellPhaseStore; } +        void LoadPhaseInfo();          std::string GeneratePetName(uint32 entry);          uint32 GetBaseXP(uint8 level); @@ -1277,6 +1300,8 @@ class ObjectMgr              return _gossipMenuItemsStore.equal_range(uiMenuId);          } +        PhaseInfo const* GetPhaseInfo(uint32 phase) { return _PhaseInfoStore.find(phase) != _PhaseInfoStore.end() ? &_PhaseInfoStore[phase] : nullptr; } +          // for wintergrasp only          GraveYardContainer GraveYardStore; @@ -1389,7 +1414,7 @@ class ObjectMgr          InstanceTemplateContainer _instanceTemplateStore;          PhaseDefinitionStore _PhaseDefinitionStore; -        SpellPhaseStore _SpellPhaseStore; +        PhaseInfoContainer _PhaseInfoStore;      private:          void LoadScripts(ScriptsType type); diff --git a/src/server/game/Grids/Notifiers/GridNotifiers.cpp b/src/server/game/Grids/Notifiers/GridNotifiers.cpp index 08b681ae53f..8040728133f 100644 --- a/src/server/game/Grids/Notifiers/GridNotifiers.cpp +++ b/src/server/game/Grids/Notifiers/GridNotifiers.cpp @@ -263,7 +263,7 @@ void MessageDistDeliverer::Visit(PlayerMapType &m)      for (PlayerMapType::iterator iter = m.begin(); iter != m.end(); ++iter)      {          Player* target = iter->GetSource(); -        if (!target->InSamePhase(i_phaseMask)) +        if (!target->IsInPhase(i_source))              continue;          if (target->GetExactDist2dSq(i_source) > i_distSq) @@ -288,7 +288,7 @@ void MessageDistDeliverer::Visit(CreatureMapType &m)      for (CreatureMapType::iterator iter = m.begin(); iter != m.end(); ++iter)      {          Creature* target = iter->GetSource(); -        if (!target->InSamePhase(i_phaseMask)) +        if (!target->IsInPhase(i_source))              continue;          if (target->GetExactDist2dSq(i_source) > i_distSq) @@ -310,7 +310,7 @@ void MessageDistDeliverer::Visit(DynamicObjectMapType &m)      for (DynamicObjectMapType::iterator iter = m.begin(); iter != m.end(); ++iter)      {          DynamicObject* target = iter->GetSource(); -        if (!target->InSamePhase(i_phaseMask)) +        if (!target->IsInPhase(i_source))              continue;          if (target->GetExactDist2dSq(i_source) > i_distSq) diff --git a/src/server/game/Grids/Notifiers/GridNotifiers.h b/src/server/game/Grids/Notifiers/GridNotifiers.h index e229c782f49..e82533b1cb2 100644 --- a/src/server/game/Grids/Notifiers/GridNotifiers.h +++ b/src/server/game/Grids/Notifiers/GridNotifiers.h @@ -126,12 +126,11 @@ namespace Trinity      {          WorldObject* i_source;          WorldPacket* i_message; -        uint32 i_phaseMask;          float i_distSq;          uint32 team;          Player const* skipped_receiver;          MessageDistDeliverer(WorldObject* src, WorldPacket* msg, float dist, bool own_team_only = false, Player const* skipped = NULL) -            : i_source(src), i_message(msg), i_phaseMask(src->GetPhaseMask()), i_distSq(dist * dist) +            : i_source(src), i_message(msg), i_distSq(dist * dist)              , team(0)              , skipped_receiver(skipped)          { @@ -176,12 +175,12 @@ namespace Trinity      struct WorldObjectSearcher      {          uint32 i_mapTypeMask; -        uint32 i_phaseMask; -        WorldObject* &i_object; +        WorldObject*& i_object; +        WorldObject const* _searcher;          Check &i_check;          WorldObjectSearcher(WorldObject const* searcher, WorldObject* & result, Check& check, uint32 mapTypeMask = GRID_MAP_TYPE_MASK_ALL) -            : i_mapTypeMask(mapTypeMask), i_phaseMask(searcher->GetPhaseMask()), i_object(result), i_check(check) { } +            : i_mapTypeMask(mapTypeMask), _searcher(searcher), i_object(result), i_check(check) { }          void Visit(GameObjectMapType &m);          void Visit(PlayerMapType &m); @@ -197,12 +196,12 @@ namespace Trinity      struct WorldObjectLastSearcher      {          uint32 i_mapTypeMask; -        uint32 i_phaseMask;          WorldObject* &i_object; +        WorldObject const* _searcher;          Check &i_check;          WorldObjectLastSearcher(WorldObject const* searcher, WorldObject* & result, Check& check, uint32 mapTypeMask = GRID_MAP_TYPE_MASK_ALL) -            :  i_mapTypeMask(mapTypeMask), i_phaseMask(searcher->GetPhaseMask()), i_object(result), i_check(check) { } +            :  i_mapTypeMask(mapTypeMask), _searcher(searcher), i_object(result), i_check(check) { }          void Visit(GameObjectMapType &m);          void Visit(PlayerMapType &m); @@ -218,12 +217,12 @@ namespace Trinity      struct WorldObjectListSearcher      {          uint32 i_mapTypeMask; -        uint32 i_phaseMask; +        WorldObject const* _searcher;          std::list<WorldObject*> &i_objects;          Check& i_check;          WorldObjectListSearcher(WorldObject const* searcher, std::list<WorldObject*> &objects, Check & check, uint32 mapTypeMask = GRID_MAP_TYPE_MASK_ALL) -            : i_mapTypeMask(mapTypeMask), i_phaseMask(searcher->GetPhaseMask()), i_objects(objects), i_check(check) { } +            : i_mapTypeMask(mapTypeMask), _searcher(searcher), i_objects(objects), i_check(check) { }          void Visit(PlayerMapType &m);          void Visit(CreatureMapType &m); @@ -239,18 +238,18 @@ namespace Trinity      struct WorldObjectWorker      {          uint32 i_mapTypeMask; -        uint32 i_phaseMask; +        WorldObject const* _searcher;          Do const& i_do;          WorldObjectWorker(WorldObject const* searcher, Do const& _do, uint32 mapTypeMask = GRID_MAP_TYPE_MASK_ALL) -            : i_mapTypeMask(mapTypeMask), i_phaseMask(searcher->GetPhaseMask()), i_do(_do) { } +            : i_mapTypeMask(mapTypeMask), _searcher(searcher), i_do(_do) { }          void Visit(GameObjectMapType &m)          {              if (!(i_mapTypeMask & GRID_MAP_TYPE_MASK_GAMEOBJECT))                  return;              for (GameObjectMapType::iterator itr=m.begin(); itr != m.end(); ++itr) -                if (itr->GetSource()->InSamePhase(i_phaseMask)) +                if (itr->GetSource()->IsInPhase(_searcher))                      i_do(itr->GetSource());          } @@ -259,7 +258,7 @@ namespace Trinity              if (!(i_mapTypeMask & GRID_MAP_TYPE_MASK_PLAYER))                  return;              for (PlayerMapType::iterator itr=m.begin(); itr != m.end(); ++itr) -                if (itr->GetSource()->InSamePhase(i_phaseMask)) +                if (itr->GetSource()->IsInPhase(_searcher))                      i_do(itr->GetSource());          }          void Visit(CreatureMapType &m) @@ -267,7 +266,7 @@ namespace Trinity              if (!(i_mapTypeMask & GRID_MAP_TYPE_MASK_CREATURE))                  return;              for (CreatureMapType::iterator itr=m.begin(); itr != m.end(); ++itr) -                if (itr->GetSource()->InSamePhase(i_phaseMask)) +                if (itr->GetSource()->IsInPhase(_searcher))                      i_do(itr->GetSource());          } @@ -276,7 +275,7 @@ namespace Trinity              if (!(i_mapTypeMask & GRID_MAP_TYPE_MASK_CORPSE))                  return;              for (CorpseMapType::iterator itr=m.begin(); itr != m.end(); ++itr) -                if (itr->GetSource()->InSamePhase(i_phaseMask)) +                if (itr->GetSource()->IsInPhase(_searcher))                      i_do(itr->GetSource());          } @@ -285,7 +284,7 @@ namespace Trinity              if (!(i_mapTypeMask & GRID_MAP_TYPE_MASK_DYNAMICOBJECT))                  return;              for (DynamicObjectMapType::iterator itr=m.begin(); itr != m.end(); ++itr) -                if (itr->GetSource()->InSamePhase(i_phaseMask)) +                if (itr->GetSource()->IsInPhase(_searcher))                      i_do(itr->GetSource());          } @@ -294,7 +293,7 @@ namespace Trinity              if (!(i_mapTypeMask & GRID_MAP_TYPE_MASK_AREATRIGGER))                  return;              for (AreaTriggerMapType::iterator itr=m.begin(); itr != m.end(); ++itr) -                if (itr->GetSource()->InSamePhase(i_phaseMask)) +                if (itr->GetSource()->IsInPhase(_searcher))                      i_do(itr->GetSource());          } @@ -306,12 +305,12 @@ namespace Trinity      template<class Check>      struct GameObjectSearcher      { -        uint32 i_phaseMask; +        WorldObject const* _searcher;          GameObject* &i_object;          Check &i_check;          GameObjectSearcher(WorldObject const* searcher, GameObject* & result, Check& check) -            : i_phaseMask(searcher->GetPhaseMask()), i_object(result), i_check(check) { } +            : _searcher(searcher), i_object(result), i_check(check) { }          void Visit(GameObjectMapType &m); @@ -322,12 +321,12 @@ namespace Trinity      template<class Check>      struct GameObjectLastSearcher      { -        uint32 i_phaseMask; +        WorldObject const* _searcher;          GameObject* &i_object;          Check& i_check;          GameObjectLastSearcher(WorldObject const* searcher, GameObject* & result, Check& check) -            : i_phaseMask(searcher->GetPhaseMask()), i_object(result), i_check(check) { } +            : _searcher(searcher), i_object(result), i_check(check) { }          void Visit(GameObjectMapType &m); @@ -337,12 +336,12 @@ namespace Trinity      template<class Check>      struct GameObjectListSearcher      { -        uint32 i_phaseMask; +        WorldObject const* _searcher;          std::list<GameObject*> &i_objects;          Check& i_check;          GameObjectListSearcher(WorldObject const* searcher, std::list<GameObject*> &objects, Check & check) -            : i_phaseMask(searcher->GetPhaseMask()), i_objects(objects), i_check(check) { } +            : _searcher(searcher), i_objects(objects), i_check(check) { }          void Visit(GameObjectMapType &m); @@ -353,12 +352,12 @@ namespace Trinity      struct GameObjectWorker      {          GameObjectWorker(WorldObject const* searcher, Functor& func) -            : _func(func), _phaseMask(searcher->GetPhaseMask()) { } +            : _func(func), _searcher(searcher) { }          void Visit(GameObjectMapType& m)          {              for (GameObjectMapType::iterator itr = m.begin(); itr != m.end(); ++itr) -                if (itr->GetSource()->InSamePhase(_phaseMask)) +                if (itr->GetSource()->IsInPhase(_searcher))                      _func(itr->GetSource());          } @@ -366,7 +365,7 @@ namespace Trinity      private:          Functor& _func; -        uint32 _phaseMask; +        WorldObject const* _searcher;      };      // Unit searchers @@ -375,12 +374,12 @@ namespace Trinity      template<class Check>      struct UnitSearcher      { -        uint32 i_phaseMask; +        WorldObject const* _searcher;          Unit* &i_object;          Check & i_check;          UnitSearcher(WorldObject const* searcher, Unit* & result, Check & check) -            : i_phaseMask(searcher->GetPhaseMask()), i_object(result), i_check(check) { } +            : _searcher(searcher), i_object(result), i_check(check) { }          void Visit(CreatureMapType &m);          void Visit(PlayerMapType &m); @@ -392,12 +391,12 @@ namespace Trinity      template<class Check>      struct UnitLastSearcher      { -        uint32 i_phaseMask; +        WorldObject const* _searcher;          Unit* &i_object;          Check & i_check;          UnitLastSearcher(WorldObject const* searcher, Unit* & result, Check & check) -            : i_phaseMask(searcher->GetPhaseMask()), i_object(result), i_check(check) { } +            : _searcher(searcher), i_object(result), i_check(check) { }          void Visit(CreatureMapType &m);          void Visit(PlayerMapType &m); @@ -409,12 +408,12 @@ namespace Trinity      template<class Check>      struct UnitListSearcher      { -        uint32 i_phaseMask; +        WorldObject const* _searcher;          std::list<Unit*> &i_objects;          Check& i_check;          UnitListSearcher(WorldObject const* searcher, std::list<Unit*> &objects, Check & check) -            : i_phaseMask(searcher->GetPhaseMask()), i_objects(objects), i_check(check) { } +            : _searcher(searcher), i_objects(objects), i_check(check) { }          void Visit(PlayerMapType &m);          void Visit(CreatureMapType &m); @@ -427,12 +426,12 @@ namespace Trinity      template<class Check>      struct CreatureSearcher      { -        uint32 i_phaseMask; +        WorldObject const* _searcher;          Creature* &i_object;          Check & i_check;          CreatureSearcher(WorldObject const* searcher, Creature* & result, Check & check) -            : i_phaseMask(searcher->GetPhaseMask()), i_object(result), i_check(check) { } +            : _searcher(searcher), i_object(result), i_check(check) { }          void Visit(CreatureMapType &m); @@ -443,12 +442,12 @@ namespace Trinity      template<class Check>      struct CreatureLastSearcher      { -        uint32 i_phaseMask; +        WorldObject const* _searcher;          Creature* &i_object;          Check & i_check;          CreatureLastSearcher(WorldObject const* searcher, Creature* & result, Check & check) -            : i_phaseMask(searcher->GetPhaseMask()), i_object(result), i_check(check) { } +            : _searcher(searcher), i_object(result), i_check(check) { }          void Visit(CreatureMapType &m); @@ -458,12 +457,12 @@ namespace Trinity      template<class Check>      struct CreatureListSearcher      { -        uint32 i_phaseMask; +        WorldObject const* _searcher;          std::list<Creature*> &i_objects;          Check& i_check;          CreatureListSearcher(WorldObject const* searcher, std::list<Creature*> &objects, Check & check) -            : i_phaseMask(searcher->GetPhaseMask()), i_objects(objects), i_check(check) { } +            : _searcher(searcher), i_objects(objects), i_check(check) { }          void Visit(CreatureMapType &m); @@ -473,16 +472,16 @@ namespace Trinity      template<class Do>      struct CreatureWorker      { -        uint32 i_phaseMask; +        WorldObject const* _searcher;          Do& i_do;          CreatureWorker(WorldObject const* searcher, Do& _do) -            : i_phaseMask(searcher->GetPhaseMask()), i_do(_do) { } +            : _searcher(searcher), i_do(_do) { }          void Visit(CreatureMapType &m)          {              for (CreatureMapType::iterator itr=m.begin(); itr != m.end(); ++itr) -                if (itr->GetSource()->InSamePhase(i_phaseMask)) +                if (itr->GetSource()->IsInPhase(_searcher))                      i_do(itr->GetSource());          } @@ -494,12 +493,12 @@ namespace Trinity      template<class Check>      struct PlayerSearcher      { -        uint32 i_phaseMask; +        WorldObject const* _searcher;          Player* &i_object;          Check & i_check;          PlayerSearcher(WorldObject const* searcher, Player* & result, Check & check) -            : i_phaseMask(searcher->GetPhaseMask()), i_object(result), i_check(check) { } +            : _searcher(searcher), i_object(result), i_check(check) { }          void Visit(PlayerMapType &m); @@ -509,12 +508,12 @@ namespace Trinity      template<class Check>      struct PlayerListSearcher      { -        uint32 i_phaseMask; +        WorldObject const* _searcher;          std::list<Player*> &i_objects;          Check& i_check;          PlayerListSearcher(WorldObject const* searcher, std::list<Player*> &objects, Check & check) -            : i_phaseMask(searcher->GetPhaseMask()), i_objects(objects), i_check(check) { } +            : _searcher(searcher), i_objects(objects), i_check(check) { }          void Visit(PlayerMapType &m); @@ -524,11 +523,11 @@ namespace Trinity      template<class Check>      struct PlayerLastSearcher      { -        uint32 i_phaseMask; +        WorldObject const* _searcher;          Player* &i_object;          Check& i_check; -        PlayerLastSearcher(WorldObject const* searcher, Player*& result, Check& check) : i_phaseMask(searcher->GetPhaseMask()), i_object(result), i_check(check) +        PlayerLastSearcher(WorldObject const* searcher, Player*& result, Check& check) : _searcher(searcher), i_object(result), i_check(check)          {          } @@ -540,16 +539,16 @@ namespace Trinity      template<class Do>      struct PlayerWorker      { -        uint32 i_phaseMask; +        WorldObject const* _searcher;          Do& i_do;          PlayerWorker(WorldObject const* searcher, Do& _do) -            : i_phaseMask(searcher->GetPhaseMask()), i_do(_do) { } +            : _searcher(searcher), i_do(_do) { }          void Visit(PlayerMapType &m)          {              for (PlayerMapType::iterator itr=m.begin(); itr != m.end(); ++itr) -                if (itr->GetSource()->InSamePhase(i_phaseMask)) +                if (itr->GetSource()->IsInPhase(_searcher))                      i_do(itr->GetSource());          } @@ -569,7 +568,7 @@ namespace Trinity          void Visit(PlayerMapType &m)          {              for (PlayerMapType::iterator itr=m.begin(); itr != m.end(); ++itr) -                if (itr->GetSource()->InSamePhase(i_searcher) && itr->GetSource()->IsWithinDist(i_searcher, i_dist)) +                if (itr->GetSource()->IsInPhase(i_searcher) && itr->GetSource()->IsWithinDist(i_searcher, i_dist))                      i_do(itr->GetSource());          } @@ -1344,7 +1343,7 @@ namespace Trinity          AllWorldObjectsInRange(const WorldObject* object, float maxRange) : m_pObject(object), m_fRange(maxRange) { }          bool operator() (WorldObject* go)          { -            return m_pObject->IsWithinDist(go, m_fRange, false) && m_pObject->InSamePhase(go); +            return m_pObject->IsWithinDist(go, m_fRange, false) && m_pObject->IsInPhase(go);          }      private:          const WorldObject* m_pObject; diff --git a/src/server/game/Grids/Notifiers/GridNotifiersImpl.h b/src/server/game/Grids/Notifiers/GridNotifiersImpl.h index febc42af25a..e73f18abf90 100644 --- a/src/server/game/Grids/Notifiers/GridNotifiersImpl.h +++ b/src/server/game/Grids/Notifiers/GridNotifiersImpl.h @@ -54,7 +54,7 @@ void Trinity::WorldObjectSearcher<Check>::Visit(GameObjectMapType &m)      for (GameObjectMapType::iterator itr=m.begin(); itr != m.end(); ++itr)      { -        if (!itr->GetSource()->InSamePhase(i_phaseMask)) +        if (!itr->GetSource()->IsInPhase(_searcher))              continue;          if (i_check(itr->GetSource())) @@ -77,7 +77,7 @@ void Trinity::WorldObjectSearcher<Check>::Visit(PlayerMapType &m)      for (PlayerMapType::iterator itr=m.begin(); itr != m.end(); ++itr)      { -        if (!itr->GetSource()->InSamePhase(i_phaseMask)) +        if (!itr->GetSource()->IsInPhase(_searcher))              continue;          if (i_check(itr->GetSource())) @@ -100,7 +100,7 @@ void Trinity::WorldObjectSearcher<Check>::Visit(CreatureMapType &m)      for (CreatureMapType::iterator itr=m.begin(); itr != m.end(); ++itr)      { -        if (!itr->GetSource()->InSamePhase(i_phaseMask)) +        if (!itr->GetSource()->IsInPhase(_searcher))              continue;          if (i_check(itr->GetSource())) @@ -123,7 +123,7 @@ void Trinity::WorldObjectSearcher<Check>::Visit(CorpseMapType &m)      for (CorpseMapType::iterator itr=m.begin(); itr != m.end(); ++itr)      { -        if (!itr->GetSource()->InSamePhase(i_phaseMask)) +        if (!itr->GetSource()->IsInPhase(_searcher))              continue;          if (i_check(itr->GetSource())) @@ -146,7 +146,7 @@ void Trinity::WorldObjectSearcher<Check>::Visit(DynamicObjectMapType &m)      for (DynamicObjectMapType::iterator itr=m.begin(); itr != m.end(); ++itr)      { -        if (!itr->GetSource()->InSamePhase(i_phaseMask)) +        if (!itr->GetSource()->IsInPhase(_searcher))              continue;          if (i_check(itr->GetSource())) @@ -169,7 +169,7 @@ void Trinity::WorldObjectSearcher<Check>::Visit(AreaTriggerMapType &m)      for (AreaTriggerMapType::iterator itr=m.begin(); itr != m.end(); ++itr)      { -        if (!itr->GetSource()->InSamePhase(i_phaseMask)) +        if (!itr->GetSource()->IsInPhase(_searcher))              continue;          if (i_check(itr->GetSource())) @@ -188,7 +188,7 @@ void Trinity::WorldObjectLastSearcher<Check>::Visit(GameObjectMapType &m)      for (GameObjectMapType::iterator itr=m.begin(); itr != m.end(); ++itr)      { -        if (!itr->GetSource()->InSamePhase(i_phaseMask)) +        if (!itr->GetSource()->IsInPhase(_searcher))              continue;          if (i_check(itr->GetSource())) @@ -204,7 +204,7 @@ void Trinity::WorldObjectLastSearcher<Check>::Visit(PlayerMapType &m)      for (PlayerMapType::iterator itr=m.begin(); itr != m.end(); ++itr)      { -        if (!itr->GetSource()->InSamePhase(i_phaseMask)) +        if (!itr->GetSource()->IsInPhase(_searcher))              continue;          if (i_check(itr->GetSource())) @@ -220,7 +220,7 @@ void Trinity::WorldObjectLastSearcher<Check>::Visit(CreatureMapType &m)      for (CreatureMapType::iterator itr=m.begin(); itr != m.end(); ++itr)      { -        if (!itr->GetSource()->InSamePhase(i_phaseMask)) +        if (!itr->GetSource()->IsInPhase(_searcher))              continue;          if (i_check(itr->GetSource())) @@ -236,7 +236,7 @@ void Trinity::WorldObjectLastSearcher<Check>::Visit(CorpseMapType &m)      for (CorpseMapType::iterator itr=m.begin(); itr != m.end(); ++itr)      { -        if (!itr->GetSource()->InSamePhase(i_phaseMask)) +        if (!itr->GetSource()->IsInPhase(_searcher))              continue;          if (i_check(itr->GetSource())) @@ -252,7 +252,7 @@ void Trinity::WorldObjectLastSearcher<Check>::Visit(DynamicObjectMapType &m)      for (DynamicObjectMapType::iterator itr=m.begin(); itr != m.end(); ++itr)      { -        if (!itr->GetSource()->InSamePhase(i_phaseMask)) +        if (!itr->GetSource()->IsInPhase(_searcher))              continue;          if (i_check(itr->GetSource())) @@ -268,7 +268,7 @@ void Trinity::WorldObjectLastSearcher<Check>::Visit(AreaTriggerMapType &m)      for (AreaTriggerMapType::iterator itr=m.begin(); itr != m.end(); ++itr)      { -        if (!itr->GetSource()->InSamePhase(i_phaseMask)) +        if (!itr->GetSource()->IsInPhase(_searcher))              continue;          if (i_check(itr->GetSource())) @@ -353,7 +353,7 @@ void Trinity::GameObjectSearcher<Check>::Visit(GameObjectMapType &m)      for (GameObjectMapType::iterator itr=m.begin(); itr != m.end(); ++itr)      { -        if (!itr->GetSource()->InSamePhase(i_phaseMask)) +        if (!itr->GetSource()->IsInPhase(_searcher))              continue;          if (i_check(itr->GetSource())) @@ -369,7 +369,7 @@ void Trinity::GameObjectLastSearcher<Check>::Visit(GameObjectMapType &m)  {      for (GameObjectMapType::iterator itr=m.begin(); itr != m.end(); ++itr)      { -        if (!itr->GetSource()->InSamePhase(i_phaseMask)) +        if (!itr->GetSource()->IsInPhase(_searcher))              continue;          if (i_check(itr->GetSource())) @@ -381,7 +381,7 @@ template<class Check>  void Trinity::GameObjectListSearcher<Check>::Visit(GameObjectMapType &m)  {      for (GameObjectMapType::iterator itr=m.begin(); itr != m.end(); ++itr) -        if (itr->GetSource()->InSamePhase(i_phaseMask)) +        if (itr->GetSource()->IsInPhase(_searcher))              if (i_check(itr->GetSource()))                  i_objects.push_back(itr->GetSource());  } @@ -397,7 +397,7 @@ void Trinity::UnitSearcher<Check>::Visit(CreatureMapType &m)      for (CreatureMapType::iterator itr=m.begin(); itr != m.end(); ++itr)      { -        if (!itr->GetSource()->InSamePhase(i_phaseMask)) +        if (!itr->GetSource()->IsInPhase(_searcher))              continue;          if (i_check(itr->GetSource())) @@ -417,7 +417,7 @@ void Trinity::UnitSearcher<Check>::Visit(PlayerMapType &m)      for (PlayerMapType::iterator itr=m.begin(); itr != m.end(); ++itr)      { -        if (!itr->GetSource()->InSamePhase(i_phaseMask)) +        if (!itr->GetSource()->IsInPhase(_searcher))              continue;          if (i_check(itr->GetSource())) @@ -433,7 +433,7 @@ void Trinity::UnitLastSearcher<Check>::Visit(CreatureMapType &m)  {      for (CreatureMapType::iterator itr=m.begin(); itr != m.end(); ++itr)      { -        if (!itr->GetSource()->InSamePhase(i_phaseMask)) +        if (!itr->GetSource()->IsInPhase(_searcher))              continue;          if (i_check(itr->GetSource())) @@ -446,7 +446,7 @@ void Trinity::UnitLastSearcher<Check>::Visit(PlayerMapType &m)  {      for (PlayerMapType::iterator itr=m.begin(); itr != m.end(); ++itr)      { -        if (!itr->GetSource()->InSamePhase(i_phaseMask)) +        if (!itr->GetSource()->IsInPhase(_searcher))              continue;          if (i_check(itr->GetSource())) @@ -458,7 +458,7 @@ template<class Check>  void Trinity::UnitListSearcher<Check>::Visit(PlayerMapType &m)  {      for (PlayerMapType::iterator itr=m.begin(); itr != m.end(); ++itr) -        if (itr->GetSource()->InSamePhase(i_phaseMask)) +        if (itr->GetSource()->IsInPhase(_searcher))              if (i_check(itr->GetSource()))                  i_objects.push_back(itr->GetSource());  } @@ -467,7 +467,7 @@ template<class Check>  void Trinity::UnitListSearcher<Check>::Visit(CreatureMapType &m)  {      for (CreatureMapType::iterator itr=m.begin(); itr != m.end(); ++itr) -        if (itr->GetSource()->InSamePhase(i_phaseMask)) +        if (itr->GetSource()->IsInPhase(_searcher))              if (i_check(itr->GetSource()))                  i_objects.push_back(itr->GetSource());  } @@ -483,7 +483,7 @@ void Trinity::CreatureSearcher<Check>::Visit(CreatureMapType &m)      for (CreatureMapType::iterator itr=m.begin(); itr != m.end(); ++itr)      { -        if (!itr->GetSource()->InSamePhase(i_phaseMask)) +        if (!itr->GetSource()->IsInPhase(_searcher))              continue;          if (i_check(itr->GetSource())) @@ -499,7 +499,7 @@ void Trinity::CreatureLastSearcher<Check>::Visit(CreatureMapType &m)  {      for (CreatureMapType::iterator itr=m.begin(); itr != m.end(); ++itr)      { -        if (!itr->GetSource()->InSamePhase(i_phaseMask)) +        if (!itr->GetSource()->IsInPhase(_searcher))              continue;          if (i_check(itr->GetSource())) @@ -511,7 +511,7 @@ template<class Check>  void Trinity::CreatureListSearcher<Check>::Visit(CreatureMapType &m)  {      for (CreatureMapType::iterator itr=m.begin(); itr != m.end(); ++itr) -        if (itr->GetSource()->InSamePhase(i_phaseMask)) +        if (itr->GetSource()->IsInPhase(_searcher))              if (i_check(itr->GetSource()))                  i_objects.push_back(itr->GetSource());  } @@ -520,7 +520,7 @@ template<class Check>  void Trinity::PlayerListSearcher<Check>::Visit(PlayerMapType &m)  {      for (PlayerMapType::iterator itr=m.begin(); itr != m.end(); ++itr) -        if (itr->GetSource()->InSamePhase(i_phaseMask)) +        if (itr->GetSource()->IsInPhase(_searcher))              if (i_check(itr->GetSource()))                  i_objects.push_back(itr->GetSource());  } @@ -534,7 +534,7 @@ void Trinity::PlayerSearcher<Check>::Visit(PlayerMapType &m)      for (PlayerMapType::iterator itr=m.begin(); itr != m.end(); ++itr)      { -        if (!itr->GetSource()->InSamePhase(i_phaseMask)) +        if (!itr->GetSource()->IsInPhase(_searcher))              continue;          if (i_check(itr->GetSource())) @@ -550,7 +550,7 @@ void Trinity::PlayerLastSearcher<Check>::Visit(PlayerMapType& m)  {      for (PlayerMapType::iterator itr = m.begin(); itr != m.end(); ++itr)      { -        if (!itr->GetSource()->InSamePhase(i_phaseMask)) +        if (!itr->GetSource()->IsInPhase(_searcher))              continue;          if (i_check(itr->GetSource())) diff --git a/src/server/game/Handlers/GroupHandler.cpp b/src/server/game/Handlers/GroupHandler.cpp index 971daa550c0..8565da90f40 100644 --- a/src/server/game/Handlers/GroupHandler.cpp +++ b/src/server/game/Handlers/GroupHandler.cpp @@ -32,6 +32,7 @@  #include "World.h"  #include "WorldPacket.h"  #include "WorldSession.h" +#include "SpellAuraEffects.h"  class Aura; @@ -944,8 +945,7 @@ void WorldSession::BuildPartyMemberStatsChangedPacket(Player* player, WorldPacke      if (mask == GROUP_UPDATE_FLAG_NONE)          return; -    std::set<uint32> phases; -    player->GetPhaseMgr().GetActivePhases(phases); +    std::set<uint32> const& phases = player->GetPhases();      if (mask & GROUP_UPDATE_FLAG_POWER_TYPE)                // if update power type, update current/max power also          mask |= (GROUP_UPDATE_FLAG_CUR_POWER | GROUP_UPDATE_FLAG_MAX_POWER); @@ -1197,8 +1197,7 @@ void WorldSession::HandleRequestPartyMemberStatsOpcode(WorldPacket& recvData)      Pet* pet = player->GetPet();      Powers powerType = player->getPowerType(); -    std::set<uint32> phases; -    player->GetPhaseMgr().GetActivePhases(phases); +    std::set<uint32> const& phases = player->GetPhases();      WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 4+2+2+2+1+2*6+8+1+8);      data << uint8(0);                                       // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp index fe731121f1c..7a66d747342 100644 --- a/src/server/game/Handlers/MiscHandler.cpp +++ b/src/server/game/Handlers/MiscHandler.cpp @@ -1749,7 +1749,7 @@ void WorldSession::HandleReadyForAccountDataTimes(WorldPacket& /*recvData*/)      SendAccountDataTimes(GLOBAL_CACHE_MASK);  } -void WorldSession::SendSetPhaseShift(std::set<uint32> const& phaseIds, std::set<uint32> const& terrainswaps) +void WorldSession::SendSetPhaseShift(std::set<uint32> const& phaseIds, std::set<uint32> const& terrainswaps, std::set<uint32> const& worldMapAreaSwaps)  {      ObjectGuid guid = _player->GetGUID(); @@ -1766,9 +1766,9 @@ void WorldSession::SendSetPhaseShift(std::set<uint32> const& phaseIds, std::set<      data.WriteByteSeq(guid[7]);      data.WriteByteSeq(guid[4]); -    data << uint32(0); -    //for (uint8 i = 0; i < worldMapAreaCount; ++i) -    //    data << uint16(0);                    // WorldMapArea.dbc id (controls map display) +    data << uint32(worldMapAreaSwaps.size()); +    for (auto mapSwap : worldMapAreaSwaps) +        data << uint16(mapSwap);                    // WorldMapArea.dbc id (controls map display)      data.WriteByteSeq(guid[1]); diff --git a/src/server/game/Instances/InstanceScript.cpp b/src/server/game/Instances/InstanceScript.cpp index 1b6399fb6fd..c8d495baab2 100644 --- a/src/server/game/Instances/InstanceScript.cpp +++ b/src/server/game/Instances/InstanceScript.cpp @@ -469,11 +469,8 @@ void InstanceScript::UpdateEncounterState(EncounterCreditType type, uint32 credi  void InstanceScript::UpdatePhasing()  { -    PhaseUpdateData phaseUdateData; -    phaseUdateData.AddConditionType(CONDITION_INSTANCE_INFO); -      Map::PlayerList const& players = instance->GetPlayers();      for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)          if (Player* player = itr->GetSource()) -            player->GetPhaseMgr().NotifyConditionChanged(phaseUdateData); +            player->UpdatePhasing();  } diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index 0203c7e0821..a1ee67fe6e4 100644 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -2520,7 +2520,7 @@ void Map::SendInitTransports(Player* player)      // Hack to send out transports      UpdateData transData(player->GetMapId());      for (TransportsContainer::const_iterator i = _transports.begin(); i != _transports.end(); ++i) -        if (*i != player->GetTransport()) +        if (*i != player->GetTransport() && player->IsInPhase(*i))              (*i)->BuildCreateUpdateBlockForPlayer(&transData, player);      WorldPacket packet; @@ -2541,6 +2541,26 @@ void Map::SendRemoveTransports(Player* player)      player->GetSession()->SendPacket(&packet);  } +void Map::SendUpdateTransportVisibility(Player* player, std::set<uint32> const& previousPhases) +{ +    // Hack to send out transports +    UpdateData transData(player->GetMapId()); +    for (TransportsContainer::const_iterator i = _transports.begin(); i != _transports.end(); ++i) +    { +        if (*i == player->GetTransport()) +            continue; + +        if (player->IsInPhase(*i) && !Trinity::Containers::Intersects(previousPhases.begin(), previousPhases.end(), (*i)->GetPhases().begin(), (*i)->GetPhases().end())) +            (*i)->BuildCreateUpdateBlockForPlayer(&transData, player); +        else if (!player->IsInPhase(*i)) +            (*i)->BuildOutOfRangeUpdateBlock(&transData); +    } + +    WorldPacket packet; +    transData.BuildPacket(&packet); +    player->GetSession()->SendPacket(&packet); +} +  inline void Map::setNGrid(NGridType *grid, uint32 x, uint32 y)  {      if (x >= MAX_NUMBER_OF_GRIDS || y >= MAX_NUMBER_OF_GRIDS) diff --git a/src/server/game/Maps/Map.h b/src/server/game/Maps/Map.h index c160d7a0f91..3b66fd0fed5 100644 --- a/src/server/game/Maps/Map.h +++ b/src/server/game/Maps/Map.h @@ -510,6 +510,7 @@ class Map : public GridRefManager<NGridType>          void SendInitTransports(Player* player);          void SendRemoveTransports(Player* player); +        void SendUpdateTransportVisibility(Player* player, std::set<uint32> const& previousPhases);          void SendZoneDynamicInfo(Player* player);          void SetZoneMusic(uint32 zoneId, uint32 musicId); diff --git a/src/server/game/Maps/PhaseMgr.cpp b/src/server/game/Maps/PhaseMgr.cpp deleted file mode 100644 index 13d357702ab..00000000000 --- a/src/server/game/Maps/PhaseMgr.cpp +++ /dev/null @@ -1,438 +0,0 @@ -/* - * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/> - * - * 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, see <http://www.gnu.org/licenses/>. - */ - -#include "PhaseMgr.h" -#include "Chat.h" -#include "Group.h" -#include "Language.h" -#include "ObjectMgr.h" -#include "Player.h" - -////////////////////////////////////////////////////////////////// -// Updating - -PhaseMgr::PhaseMgr(Player* _player) : player(_player), phaseData(_player), _UpdateFlags(0) -{ -    _PhaseDefinitionStore = sObjectMgr->GetPhaseDefinitionStore(); -    _SpellPhaseStore = sObjectMgr->GetSpellPhaseStore(); -} - -void PhaseMgr::Update() -{ -    if (IsUpdateInProgress()) -        return; - -    if (_UpdateFlags & PHASE_UPDATE_FLAG_CLIENTSIDE_CHANGED) -    { -        phaseData.SendPhaseshiftToPlayer(); -        player->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PHASE); -    } - -    if (_UpdateFlags & PHASE_UPDATE_FLAG_SERVERSIDE_CHANGED) -        phaseData.SendPhaseMaskToPlayer(); - -    _UpdateFlags = 0; -} - -void PhaseMgr::RemoveUpdateFlag(PhaseUpdateFlag updateFlag) -{ -    _UpdateFlags &= ~updateFlag; - -    if (updateFlag == PHASE_UPDATE_FLAG_ZONE_UPDATE) -    { -        // Update zone changes -        if (phaseData.HasActiveDefinitions()) -        { -            phaseData.ResetDefinitions(); -            _UpdateFlags |= (PHASE_UPDATE_FLAG_CLIENTSIDE_CHANGED | PHASE_UPDATE_FLAG_SERVERSIDE_CHANGED); -        } - -        if (_PhaseDefinitionStore->find(player->GetZoneId()) != _PhaseDefinitionStore->end()) -            Recalculate(); -    } - -    Update(); -} - -///////////////////////////////////////////////////////////////// -// Notifier - -void PhaseMgr::NotifyConditionChanged(PhaseUpdateData const& updateData) -{ -    if (NeedsPhaseUpdateWithData(updateData)) -    { -        Recalculate(); -        Update(); -    } -} - -////////////////////////////////////////////////////////////////// -// Phasing Definitions - -void PhaseMgr::Recalculate() -{ -    if (phaseData.HasActiveDefinitions()) -    { -        phaseData.ResetDefinitions(); -        _UpdateFlags |= (PHASE_UPDATE_FLAG_CLIENTSIDE_CHANGED | PHASE_UPDATE_FLAG_SERVERSIDE_CHANGED); -    } - -    PhaseDefinitionStore::const_iterator itr = _PhaseDefinitionStore->find(player->GetZoneId()); -    if (itr != _PhaseDefinitionStore->end()) -    { -        for (PhaseDefinitionContainer::const_iterator phase = itr->second.begin(); phase != itr->second.end(); ++phase) -        { -            if (CheckDefinition(&(*phase))) -            { -                phaseData.AddPhaseDefinition(&(*phase)); - -                if (phase->phasemask) -                    _UpdateFlags |= PHASE_UPDATE_FLAG_SERVERSIDE_CHANGED; - -                if (phase->phaseId || phase->terrainswapmap) -                    _UpdateFlags |= PHASE_UPDATE_FLAG_CLIENTSIDE_CHANGED; - -                if (phase->IsLastDefinition()) -                    break; -            } -        } -    } -} - -inline bool PhaseMgr::CheckDefinition(PhaseDefinition const* phaseDefinition) -{ -    ConditionList const* conditions = sConditionMgr->GetConditionsForPhaseDefinition(phaseDefinition->zoneId, phaseDefinition->entry); -    if (!conditions) -        return true; - -    ConditionSourceInfo srcInfo(player); -    return sConditionMgr->IsObjectMeetToConditions(srcInfo, *conditions); -} - -bool PhaseMgr::NeedsPhaseUpdateWithData(PhaseUpdateData const& updateData) const -{ -    PhaseDefinitionStore::const_iterator itr = _PhaseDefinitionStore->find(player->GetZoneId()); -    if (itr != _PhaseDefinitionStore->end()) -    { -        for (PhaseDefinitionContainer::const_iterator phase = itr->second.begin(); phase != itr->second.end(); ++phase) -        { -            ConditionList const* conditionList = sConditionMgr->GetConditionsForPhaseDefinition(phase->zoneId, phase->entry); -            if (!conditionList) -                continue; - -            for (ConditionList::const_iterator condition = conditionList->begin(); condition != conditionList->end(); ++condition) -                if (updateData.IsConditionRelated(*condition)) -                    return true; -        } -    } -    return false; -} - -////////////////////////////////////////////////////////////////// -// Auras - -void PhaseMgr::RegisterPhasingAuraEffect(AuraEffect const* auraEffect) -{ -    std::list<PhaseInfo> phases; - -    if (auraEffect->GetAuraType() == SPELL_AURA_PHASE) -    { -        PhaseInfo phaseInfo; - -        if (auraEffect->GetMiscValue()) -        { -            _UpdateFlags |= PHASE_UPDATE_FLAG_SERVERSIDE_CHANGED; -            phaseInfo.phasemask = auraEffect->GetMiscValue(); -        } -        else -        { -            SpellPhaseStore::const_iterator itr = _SpellPhaseStore->find(auraEffect->GetId()); -            if (itr != _SpellPhaseStore->end()) -            { -                if (itr->second.phasemask) -                { -                    _UpdateFlags |= PHASE_UPDATE_FLAG_SERVERSIDE_CHANGED; -                    phaseInfo.phasemask = itr->second.phasemask; -                } - -                if (itr->second.terrainswapmap) -                    phaseInfo.terrainswapmap = itr->second.terrainswapmap; -            } -        } - -        phaseInfo.phaseId = auraEffect->GetMiscValueB(); - -        if (phaseInfo.NeedsClientSideUpdate()) -            _UpdateFlags |= PHASE_UPDATE_FLAG_CLIENTSIDE_CHANGED; - -        phases.push_back(phaseInfo); -    } -    else if (auraEffect->GetAuraType() == SPELL_AURA_PHASE_GROUP) -    { -        uint32 group = auraEffect->GetMiscValueB(); -        std::set<uint32> const& groupPhases = GetPhasesForGroup(group); -        for (auto itr = groupPhases.begin(); itr != groupPhases.end(); ++itr) -        { -            PhaseInfo phaseInfo; -            phaseInfo.phaseId = auraEffect->GetMiscValueB(); -            if (phaseInfo.NeedsClientSideUpdate()) -                _UpdateFlags |= PHASE_UPDATE_FLAG_CLIENTSIDE_CHANGED; -            phases.push_back(phaseInfo); -        } -    } - -    for (auto itr = phases.begin(); itr != phases.end(); ++itr) -        phaseData.AddAuraInfo(auraEffect->GetId(), *itr); - -    Update(); -} - -void PhaseMgr::UnRegisterPhasingAuraEffect(AuraEffect const* auraEffect) -{ -    _UpdateFlags |= phaseData.RemoveAuraInfo(auraEffect->GetId()); - -    Update(); -} - -////////////////////////////////////////////////////////////////// -// Commands - -void PhaseMgr::SendDebugReportToPlayer(Player* const debugger) -{ -    ChatHandler(debugger->GetSession()).PSendSysMessage(LANG_PHASING_REPORT_STATUS, player->GetName().c_str(), player->GetZoneId(), player->getLevel(), player->GetTeamId(), _UpdateFlags); - -    PhaseDefinitionStore::const_iterator itr = _PhaseDefinitionStore->find(player->GetZoneId()); -    if (itr == _PhaseDefinitionStore->end()) -        ChatHandler(debugger->GetSession()).PSendSysMessage(LANG_PHASING_NO_DEFINITIONS, player->GetZoneId()); -    else -    { -        for (PhaseDefinitionContainer::const_iterator phase = itr->second.begin(); phase != itr->second.end(); ++phase) -        { -            if (CheckDefinition(&(*phase))) -                ChatHandler(debugger->GetSession()).PSendSysMessage(LANG_PHASING_SUCCESS, phase->entry, phase->IsNegatingPhasemask() ? "negated Phase" : "Phase", phase->phasemask); -            else -                ChatHandler(debugger->GetSession()).PSendSysMessage(LANG_PHASING_FAILED, phase->phasemask, phase->entry, phase->zoneId); - -            if (phase->IsLastDefinition()) -            { -                ChatHandler(debugger->GetSession()).PSendSysMessage(LANG_PHASING_LAST_PHASE, phase->phasemask, phase->entry, phase->zoneId); -                break; -            } -        } -    } - -    ChatHandler(debugger->GetSession()).PSendSysMessage(LANG_PHASING_LIST, phaseData._PhasemaskThroughDefinitions, phaseData._PhasemaskThroughAuras, phaseData._CustomPhasemask); - -    ChatHandler(debugger->GetSession()).PSendSysMessage(LANG_PHASING_PHASEMASK, phaseData.GetPhaseMaskForSpawn(), player->GetPhaseMask()); -} - -void PhaseMgr::SetCustomPhase(uint32 phaseMask) -{ -    phaseData._CustomPhasemask = phaseMask; - -    _UpdateFlags |= PHASE_UPDATE_FLAG_SERVERSIDE_CHANGED; - -    Update(); -} - -////////////////////////////////////////////////////////////////// -// Phase Data - -uint32 PhaseData::GetCurrentPhasemask() const -{ -    if (player->IsGameMaster()) -        return uint32(PHASEMASK_ANYWHERE); - -    if (_CustomPhasemask) -        return _CustomPhasemask; - -    return GetPhaseMaskForSpawn(); -} - -inline uint32 PhaseData::GetPhaseMaskForSpawn() const -{ -    uint32 const phase = (_PhasemaskThroughDefinitions | _PhasemaskThroughAuras); -    return (phase ? phase : PHASEMASK_NORMAL); -} - -void PhaseData::SendPhaseMaskToPlayer() -{ -    // Server side update -    uint32 const phasemask = GetCurrentPhasemask(); -    if (player->GetPhaseMask() == phasemask) -        return; - -    player->SetPhaseMask(phasemask, false); - -    if (player->IsVisible()) -        player->UpdateObjectVisibility(); -} - -void PhaseData::SendPhaseshiftToPlayer() -{ -    // Client side update -    std::set<uint32> phaseIds; -    std::set<uint32> terrainswaps; - -    for (PhaseInfoContainer::const_iterator itr = spellPhaseInfo.begin(); itr != spellPhaseInfo.end(); ++itr) -    { -        for (auto ph = itr->second.begin(); ph != itr->second.end(); ++ph) -        { -            if (ph->terrainswapmap) -                terrainswaps.insert(ph->terrainswapmap); - -            if (ph->phaseId) -                phaseIds.insert(ph->phaseId); -        } -    } - -    // Phase Definitions -    for (std::list<PhaseDefinition const*>::const_iterator itr = activePhaseDefinitions.begin(); itr != activePhaseDefinitions.end(); ++itr) -    { -        if ((*itr)->phaseId) -            phaseIds.insert((*itr)->phaseId); - -        if ((*itr)->terrainswapmap) -            terrainswaps.insert((*itr)->terrainswapmap); -    } - -    player->GetSession()->SendSetPhaseShift(phaseIds, terrainswaps); -} - -void PhaseData::GetActivePhases(std::set<uint32>& phases) const -{ -    for (PhaseInfoContainer::const_iterator itr = spellPhaseInfo.begin(); itr != spellPhaseInfo.end(); ++itr) -        for (auto phase = itr->second.begin(); phase != itr->second.end(); ++phase) -            if (phase->phaseId) -                phases.insert(phase->phaseId); - -    // Phase Definitions -    for (std::list<PhaseDefinition const*>::const_iterator itr = activePhaseDefinitions.begin(); itr != activePhaseDefinitions.end(); ++itr) -        if ((*itr)->phaseId) -            phases.insert((*itr)->phaseId); -} - -void PhaseData::AddPhaseDefinition(PhaseDefinition const* phaseDefinition) -{ -    if (phaseDefinition->IsOverwritingExistingPhases()) -    { -        activePhaseDefinitions.clear(); -        _PhasemaskThroughDefinitions = phaseDefinition->phasemask; -    } -    else -    { -        if (phaseDefinition->IsNegatingPhasemask()) -            _PhasemaskThroughDefinitions &= ~phaseDefinition->phasemask; -        else -            _PhasemaskThroughDefinitions |= phaseDefinition->phasemask; -    } - -    activePhaseDefinitions.push_back(phaseDefinition); -} - -void PhaseData::AddAuraInfo(uint32 spellId, PhaseInfo const& phaseInfo) -{ -    if (phaseInfo.phasemask) -        _PhasemaskThroughAuras |= phaseInfo.phasemask; - -    spellPhaseInfo[spellId].push_back(phaseInfo); -} - -uint32 PhaseData::RemoveAuraInfo(uint32 spellId) -{ -    PhaseInfoContainer::const_iterator rAura = spellPhaseInfo.find(spellId); -    if (rAura != spellPhaseInfo.end()) -    { -        uint32 updateflag = 0; - -        for (auto phase = rAura->second.begin(); phase != rAura->second.end(); ++phase) -        { -            if (phase->NeedsClientSideUpdate()) -                updateflag |= PHASE_UPDATE_FLAG_CLIENTSIDE_CHANGED; - -            if (phase->NeedsServerSideUpdate()) -            { -                _PhasemaskThroughAuras = 0; -                updateflag |= PHASE_UPDATE_FLAG_SERVERSIDE_CHANGED; -            } -        } - -        if (updateflag & PHASE_UPDATE_FLAG_SERVERSIDE_CHANGED) -        { -            spellPhaseInfo.erase(rAura); - -            for (PhaseInfoContainer::const_iterator itr = spellPhaseInfo.begin(); itr != spellPhaseInfo.end(); ++itr) -                for (auto ph = itr->second.begin(); ph != itr->second.end(); ++ph) -                    _PhasemaskThroughAuras |= ph->phasemask; -        } - -        return updateflag; -    } - -    return 0; -} - -////////////////////////////////////////////////////////////////// -// Phase Update Data - -void PhaseUpdateData::AddQuestUpdate(uint32 questId) -{ -    AddConditionType(CONDITION_QUESTREWARDED); -    AddConditionType(CONDITION_QUESTTAKEN); -    AddConditionType(CONDITION_QUEST_COMPLETE); -    AddConditionType(CONDITION_QUEST_NONE); - -    _questId = questId; -} - -bool PhaseUpdateData::IsConditionRelated(Condition const* condition) const -{ -    switch (condition->ConditionType) -    { -        case CONDITION_QUESTREWARDED: -        case CONDITION_QUESTTAKEN: -        case CONDITION_QUEST_COMPLETE: -        case CONDITION_QUEST_NONE: -            return condition->ConditionValue1 == _questId && ((1 << condition->ConditionType) & _conditionTypeFlags); -        default: -            return (1 << condition->ConditionType) & _conditionTypeFlags; -    } -} - -bool PhaseMgr::IsConditionTypeSupported(ConditionTypes conditionType) -{ -    switch (conditionType) -    { -        case CONDITION_QUESTREWARDED: -        case CONDITION_QUESTTAKEN: -        case CONDITION_QUEST_COMPLETE: -        case CONDITION_QUEST_NONE: -        case CONDITION_TEAM: -        case CONDITION_CLASS: -        case CONDITION_RACE: -        case CONDITION_INSTANCE_INFO: -        case CONDITION_LEVEL: -            return true; -        default: -            return false; -    } -} - -void PhaseMgr::GetActivePhases(std::set<uint32>& phases) const -{ -    phaseData.GetActivePhases(phases); -} diff --git a/src/server/game/Maps/PhaseMgr.h b/src/server/game/Maps/PhaseMgr.h deleted file mode 100644 index f5226e6468c..00000000000 --- a/src/server/game/Maps/PhaseMgr.h +++ /dev/null @@ -1,179 +0,0 @@ -/* - * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/> - * - * 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, see <http://www.gnu.org/licenses/>. - */ - -#ifndef TRINITY_PHASEMGR_H -#define TRINITY_PHASEMGR_H - -#include "SharedDefines.h" -#include "SpellAuras.h" -#include "SpellAuraEffects.h" -#include "ConditionMgr.h" - -class ObjectMgr; -class Player; - -// 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 -}; - -enum PhaseUpdateFlag -{ -    PHASE_UPDATE_FLAG_ZONE_UPDATE           = 0x01, -    PHASE_UPDATE_FLAG_AREA_UPDATE           = 0x02, - -    // Internal flags -    PHASE_UPDATE_FLAG_CLIENTSIDE_CHANGED    = 0x08, -    PHASE_UPDATE_FLAG_SERVERSIDE_CHANGED    = 0x10, -}; - -struct PhaseDefinition -{ -    uint32 zoneId; -    uint32 entry; -    uint32 phasemask; -    uint32 phaseId; -    uint32 terrainswapmap; -    uint8 flags; - -    bool IsOverwritingExistingPhases() const { return flags & PHASE_FLAG_OVERWRITE_EXISTING; } -    bool IsLastDefinition() const { return flags & PHASE_FLAG_NO_MORE_PHASES; } -    bool IsNegatingPhasemask() const { return flags & PHASE_FLAG_NEGATE_PHASE; } -}; - -typedef std::list<PhaseDefinition> PhaseDefinitionContainer; -typedef std::unordered_map<uint32 /*zoneId*/, PhaseDefinitionContainer> PhaseDefinitionStore; - -struct SpellPhaseInfo -{ -    uint32 spellId; -    uint32 phasemask; -    uint32 terrainswapmap; -}; - -typedef std::unordered_map<uint32 /*spellId*/, SpellPhaseInfo> SpellPhaseStore; - -struct PhaseInfo -{ -    PhaseInfo() : phasemask(0), terrainswapmap(0), phaseId(0) {} - -    uint32 phasemask; -    uint32 terrainswapmap; -    uint32 phaseId; - -    bool NeedsServerSideUpdate() const { return phasemask; } -    bool NeedsClientSideUpdate() const { return terrainswapmap || phaseId; } -}; - -typedef std::unordered_map<uint32 /*spellId*/, std::list<PhaseInfo>> PhaseInfoContainer; - -struct PhaseData -{ -    PhaseData(Player* _player) : _PhasemaskThroughDefinitions(0), _PhasemaskThroughAuras(0), _CustomPhasemask(0), player(_player) {} - -    uint32 _PhasemaskThroughDefinitions; -    uint32 _PhasemaskThroughAuras; -    uint32 _CustomPhasemask; - -    uint32 GetCurrentPhasemask() const; -    inline uint32 GetPhaseMaskForSpawn() const; - -    void ResetDefinitions() { _PhasemaskThroughDefinitions = 0; activePhaseDefinitions.clear(); } -    void AddPhaseDefinition(PhaseDefinition const* phaseDefinition); -    bool HasActiveDefinitions() const { return !activePhaseDefinitions.empty(); } - -    void AddAuraInfo(uint32 spellId, PhaseInfo const& phaseInfo); -    uint32 RemoveAuraInfo(uint32 spellId); - -    void SendPhaseMaskToPlayer(); -    void SendPhaseshiftToPlayer(); - -    void GetActivePhases(std::set<uint32>& phases) const; - -private: -    Player* player; -    std::list<PhaseDefinition const*> activePhaseDefinitions; -    PhaseInfoContainer spellPhaseInfo; -}; - -struct PhaseUpdateData -{ -    PhaseUpdateData(): _conditionTypeFlags(0), _questId(0) { } -    void AddConditionType(ConditionTypes const conditionType) { _conditionTypeFlags |= (1 << conditionType); } -    void AddQuestUpdate(uint32 const questId); - -    bool IsConditionRelated(Condition const* condition) const; - -private: -    uint32 _conditionTypeFlags; -    uint32 _questId; -}; - -class PhaseMgr -{ -public: -    PhaseMgr(Player* _player); -    ~PhaseMgr() {} - -    uint32 GetCurrentPhasemask() { return phaseData.GetCurrentPhasemask(); }; -    inline uint32 GetPhaseMaskForSpawn() { return phaseData.GetCurrentPhasemask(); } - -    // Phase definitions update handling -    void NotifyConditionChanged(PhaseUpdateData const& updateData); -    void NotifyStoresReloaded() { Recalculate(); Update(); } - -    void Update(); - -    // Aura phase effects -    void RegisterPhasingAuraEffect(AuraEffect const* auraEffect); -    void UnRegisterPhasingAuraEffect(AuraEffect const* auraEffect); - -    // Update flags (delayed phasing) -    void AddUpdateFlag(PhaseUpdateFlag updateFlag) { _UpdateFlags |= updateFlag; } -    void RemoveUpdateFlag(PhaseUpdateFlag updateFlag); - -    // Needed for modify phase command -    void SetCustomPhase(uint32 phaseMask); - -    // Debug -    void SendDebugReportToPlayer(Player* const debugger); - -    static bool IsConditionTypeSupported(ConditionTypes conditionType); - -    void GetActivePhases(std::set<uint32>& phases) const; - -private: -    void Recalculate(); - -    inline bool CheckDefinition(PhaseDefinition const* phaseDefinition); - -    bool NeedsPhaseUpdateWithData(PhaseUpdateData const& updateData) const; - -    inline bool IsUpdateInProgress() const { return (_UpdateFlags & PHASE_UPDATE_FLAG_ZONE_UPDATE) || (_UpdateFlags & PHASE_UPDATE_FLAG_AREA_UPDATE); } - -    PhaseDefinitionStore const* _PhaseDefinitionStore; -    SpellPhaseStore const* _SpellPhaseStore; - -    Player* player; -    PhaseData phaseData; -    uint8 _UpdateFlags; -}; - -#endif diff --git a/src/server/game/Maps/TransportMgr.cpp b/src/server/game/Maps/TransportMgr.cpp index 28869d264c4..ba7d3784157 100644 --- a/src/server/game/Maps/TransportMgr.cpp +++ b/src/server/game/Maps/TransportMgr.cpp @@ -348,7 +348,7 @@ void TransportMgr::AddPathNodeToTransport(uint32 transportEntry, uint32 timeSeg,      animNode.Path[timeSeg] = node;  } -Transport* TransportMgr::CreateTransport(uint32 entry, uint32 guid /*= 0*/, Map* map /*= NULL*/) +Transport* TransportMgr::CreateTransport(uint32 entry, uint32 guid /*= 0*/, Map* map /*= NULL*/, uint32 phaseid /*= 0*/, uint32 phasegroup /*= 0*/)  {      // instance case, execute GetGameObjectEntry hook      if (map) @@ -388,6 +388,13 @@ Transport* TransportMgr::CreateTransport(uint32 entry, uint32 guid /*= 0*/, Map*          return NULL;      } +    if (phaseid) +        trans->SetInPhase(phaseid, false, true); + +    if (phasegroup) +        for (auto ph : GetPhasesForGroup(phasegroup)) +            trans->SetInPhase(ph, false, true); +      if (MapEntry const* mapEntry = sMapStore.LookupEntry(mapId))      {          if (mapEntry->Instanceable() != tInfo->inInstance) @@ -416,7 +423,7 @@ void TransportMgr::SpawnContinentTransports()      uint32 oldMSTime = getMSTime(); -    QueryResult result = WorldDatabase.Query("SELECT guid, entry FROM transports"); +    QueryResult result = WorldDatabase.Query("SELECT guid, entry, phaseid, phasegroup FROM transports");      uint32 count = 0;      if (result) @@ -426,10 +433,12 @@ void TransportMgr::SpawnContinentTransports()              Field* fields = result->Fetch();              uint32 guid = fields[0].GetUInt32();              uint32 entry = fields[1].GetUInt32(); +            uint32 phaseid = fields[2].GetUInt32(); +            uint32 phasegroup = fields[3].GetUInt32();              if (TransportTemplate const* tInfo = GetTransportTemplate(entry))                  if (!tInfo->inInstance) -                    if (CreateTransport(entry, guid)) +                    if (CreateTransport(entry, guid, nullptr, phaseid, phasegroup))                          ++count;          } while (result->NextRow()); diff --git a/src/server/game/Maps/TransportMgr.h b/src/server/game/Maps/TransportMgr.h index 5da856b185c..759b761c3f1 100644 --- a/src/server/game/Maps/TransportMgr.h +++ b/src/server/game/Maps/TransportMgr.h @@ -105,7 +105,7 @@ class TransportMgr          void LoadTransportTemplates();          // Creates a transport using given GameObject template entry -        Transport* CreateTransport(uint32 entry, uint32 guid = 0, Map* map = NULL); +        Transport* CreateTransport(uint32 entry, uint32 guid = 0, Map* map = nullptr, uint32 phaseid = 0, uint32 phasegroup = 0);          // Spawns all continent transports, used at core startup          void SpawnContinentTransports(); diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h index 05346da0eb9..9c44fa8fad3 100644 --- a/src/server/game/Server/WorldSession.h +++ b/src/server/game/Server/WorldSession.h @@ -233,7 +233,7 @@ class WorldSession          void SendPetNameInvalid(uint32 error, std::string const& name, DeclinedName *declinedName);          void SendPartyResult(PartyOperation operation, std::string const& member, PartyResult res, uint32 val = 0);          void SendAreaTriggerMessage(const char* Text, ...) ATTR_PRINTF(2, 3); -        void SendSetPhaseShift(std::set<uint32> const& phaseIds, std::set<uint32> const& terrainswaps); +        void SendSetPhaseShift(std::set<uint32> const& phaseIds, std::set<uint32> const& terrainswaps, std::set<uint32> const& worldMapAreaSwaps);          void SendQueryTimeResponse();          void SendAuthResponse(uint8 code, bool queued, uint32 queuePos = 0); diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index bb1396b5633..03512b85460 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -1608,31 +1608,8 @@ void AuraEffect::HandlePhase(AuraApplication const* aurApp, uint8 mode, bool app      Unit* target = aurApp->GetTarget(); -    if (Player* player = target->ToPlayer()) -    { -        if (apply) -            player->GetPhaseMgr().RegisterPhasingAuraEffect(this); -        else -            player->GetPhaseMgr().UnRegisterPhasingAuraEffect(this); -    } -    else -    { -        uint32 newPhase = 0; -        Unit::AuraEffectList const& phases = target->GetAuraEffectsByType(SPELL_AURA_PHASE); -        if (!phases.empty()) -            for (Unit::AuraEffectList::const_iterator itr = phases.begin(); itr != phases.end(); ++itr) -                newPhase |= (*itr)->GetMiscValue(); - -        if (!newPhase) -        { -            newPhase = PHASEMASK_NORMAL; -            if (Creature* creature = target->ToCreature()) -                if (CreatureData const* data = sObjectMgr->GetCreatureData(creature->GetDBTableGUIDLow())) -                    newPhase = data->phaseMask; -        } - -        target->SetPhaseMask(newPhase, false); -    } +    std::set<uint32> const& oldPhases = target->GetPhases(); +    target->SetInPhase(GetMiscValueB(), false, apply);      // call functions which may have additional effects after chainging state of unit      // phase auras normally not expected at BG but anyway better check @@ -1642,6 +1619,13 @@ void AuraEffect::HandlePhase(AuraApplication const* aurApp, uint8 mode, bool app          target->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION);      } +    if (Player* player = target->ToPlayer()) +    { +        if (player->IsInWorld()) +            player->GetMap()->SendUpdateTransportVisibility(player, oldPhases); +        player->UpdatePhasing(); +    } +      // need triggering visibility update base at phase update of not GM invisible (other GMs anyway see in any phases)      if (target->IsVisible())          target->UpdateObjectVisibility(); @@ -1654,13 +1638,10 @@ void AuraEffect::HandlePhaseGroup(AuraApplication const* aurApp, uint8 mode, boo      Unit* target = aurApp->GetTarget(); -    if (Player* player = target->ToPlayer()) -    { -        if (apply) -            player->GetPhaseMgr().RegisterPhasingAuraEffect(this); -        else -            player->GetPhaseMgr().UnRegisterPhasingAuraEffect(this); -    } +    std::set<uint32> const& oldPhases = target->GetPhases(); +    std::set<uint32> const& phases = GetPhasesForGroup(GetMiscValueB()); +    for (auto phase : phases) +        target->SetInPhase(phase, false, apply);      // call functions which may have additional effects after chainging state of unit      // phase auras normally not expected at BG but anyway better check @@ -1670,6 +1651,13 @@ void AuraEffect::HandlePhaseGroup(AuraApplication const* aurApp, uint8 mode, boo          target->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION);      } +    if (Player* player = target->ToPlayer()) +    { +        if (player->IsInWorld()) +            player->GetMap()->SendUpdateTransportVisibility(player, oldPhases); +        player->UpdatePhasing(); +    } +      // need triggering visibility update base at phase update of not GM invisible (other GMs anyway see in any phases)      if (target->IsVisible())          target->UpdateObjectVisibility(); diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index 1750dbc26f2..bdfe78d941a 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -3206,6 +3206,9 @@ void Spell::EffectSummonObjectWild(SpellEffIndex effIndex)          return;      } +    for (auto phase : m_caster->GetPhases()) +        pGameObj->SetInPhase(phase, false, true); +      int32 duration = m_spellInfo->GetDuration();      pGameObj->SetRespawnTime(duration > 0 ? duration/IN_MILLISECONDS : 0); @@ -3227,6 +3230,9 @@ void Spell::EffectSummonObjectWild(SpellEffIndex effIndex)          if (linkedGO->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_GAMEOBJECT), 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->SetRespawnTime(duration > 0 ? duration/IN_MILLISECONDS : 0);              linkedGO->SetSpellId(m_spellInfo->Id); @@ -3848,7 +3854,7 @@ void Spell::EffectDuel(SpellEffIndex effIndex)      Map* map = m_caster->GetMap();      if (!pGameObj->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_GAMEOBJECT), gameobject_id, -        map, m_caster->GetPhaseMask(), +        map, 0,          m_caster->GetPositionX()+(unitTarget->GetPositionX()-m_caster->GetPositionX())/2,          m_caster->GetPositionY()+(unitTarget->GetPositionY()-m_caster->GetPositionY())/2,          m_caster->GetPositionZ(), @@ -3858,6 +3864,9 @@ void Spell::EffectDuel(SpellEffIndex effIndex)          return;      } +    for (auto phase : m_caster->GetPhases()) +        pGameObj->SetInPhase(phase, false, true); +      pGameObj->SetUInt32Value(GAMEOBJECT_FACTION, m_caster->getFaction());      pGameObj->SetUInt32Value(GAMEOBJECT_LEVEL, m_caster->getLevel()+1);      int32 duration = m_spellInfo->GetDuration(); @@ -4208,12 +4217,15 @@ void Spell::EffectSummonObject(SpellEffIndex effIndex)      Map* map = m_caster->GetMap();      if (!go->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_GAMEOBJECT), go_id, map, -        m_caster->GetPhaseMask(), x, y, z, m_caster->GetOrientation(), 0.0f, 0.0f, 0.0f, 0.0f, 0, GO_STATE_READY)) +        0, x, y, z, m_caster->GetOrientation(), 0.0f, 0.0f, 0.0f, 0.0f, 0, GO_STATE_READY))      {          delete go;          return;      } +    for (auto phase : m_caster->GetPhases()) +        go->SetInPhase(phase, false, true); +      //pGameObj->SetUInt32Value(GAMEOBJECT_LEVEL, m_caster->getLevel());      int32 duration = m_spellInfo->GetDuration();      go->SetRespawnTime(duration > 0 ? duration/IN_MILLISECONDS : 0); @@ -4837,12 +4849,15 @@ void Spell::EffectTransmitted(SpellEffIndex effIndex)      GameObject* pGameObj = new GameObject;      if (!pGameObj->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_GAMEOBJECT), name_id, cMap, -        m_caster->GetPhaseMask(), fx, fy, fz, m_caster->GetOrientation(), 0.0f, 0.0f, 0.0f, 0.0f, 100, GO_STATE_READY)) +        0, fx, fy, fz, m_caster->GetOrientation(), 0.0f, 0.0f, 0.0f, 0.0f, 100, GO_STATE_READY))      {          delete pGameObj;          return;      } +    for (auto phase : m_caster->GetPhases()) +        pGameObj->SetInPhase(phase, false, true); +      int32 duration = m_spellInfo->GetDuration();      switch (goinfo->type) @@ -4903,8 +4918,11 @@ void Spell::EffectTransmitted(SpellEffIndex effIndex)      {          GameObject* linkedGO = new GameObject;          if (linkedGO->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_GAMEOBJECT), linkedEntry, cMap, -            m_caster->GetPhaseMask(), fx, fy, fz, m_caster->GetOrientation(), 0.0f, 0.0f, 0.0f, 0.0f, 100, GO_STATE_READY)) +            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->SetRespawnTime(duration > 0 ? duration/IN_MILLISECONDS : 0);              //linkedGO->SetUInt32Value(GAMEOBJECT_LEVEL, m_caster->getLevel());              linkedGO->SetSpellId(m_spellInfo->Id); diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp index 7491920c36a..03076b003be 100644 --- a/src/server/game/Spells/SpellInfo.cpp +++ b/src/server/game/Spells/SpellInfo.cpp @@ -17,6 +17,7 @@  #include "SpellInfo.h"  #include "SpellAuraDefines.h" +#include "SpellAuraEffects.h"  #include "SpellMgr.h"  #include "Spell.h"  #include "DBCStores.h" diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index a9507b174b6..4375ad09e4c 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -1457,7 +1457,7 @@ void World::SetInitialWorldSettings()      sSpellMgr->LoadSpellGroupStackRules();      TC_LOG_INFO("server.loading", "Loading Spell Phase Dbc Info..."); -    sObjectMgr->LoadSpellPhaseInfo(); +    sObjectMgr->LoadPhaseInfo();      TC_LOG_INFO("server.loading", "Loading NPC Texts...");      sObjectMgr->LoadGossipText(); @@ -3284,10 +3284,7 @@ CharacterNameData const* World::GetCharacterNameData(uint32 guid) const  void World::UpdatePhaseDefinitions()  { -    SessionMap::const_iterator itr; -    for (itr = m_sessions.begin(); itr != m_sessions.end(); ++itr) -        if (itr->second && itr->second->GetPlayer() && itr->second->GetPlayer()->IsInWorld()) -            itr->second->GetPlayer()->GetPhaseMgr().NotifyStoresReloaded(); +  }  void World::ReloadRBAC() diff --git a/src/server/scripts/Commands/cs_debug.cpp b/src/server/scripts/Commands/cs_debug.cpp index d0a005f356e..52886d60c4b 100644 --- a/src/server/scripts/Commands/cs_debug.cpp +++ b/src/server/scripts/Commands/cs_debug.cpp @@ -934,6 +934,9 @@ public:              return false;          } +        for (auto phase : handler->GetSession()->GetPlayer()->GetPhases()) +            v->SetInPhase(phase, false, true); +          map->AddToMap(v->ToCreature());          return true; @@ -962,13 +965,14 @@ public:          std::set<uint32> terrainswap;          std::set<uint32> phaseId; +        std::set<uint32> worldMapSwap;          terrainswap.insert((uint32)atoi(t));          if (p)              phaseId.insert((uint32)atoi(p)); -        handler->GetSession()->SendSetPhaseShift(phaseId, terrainswap); +        handler->GetSession()->SendSetPhaseShift(phaseId, terrainswap, worldMapSwap);          return true;      } @@ -1393,7 +1397,7 @@ public:          if (unit && unit->GetTypeId() == TYPEID_PLAYER)              player = unit->ToPlayer(); -        player->GetPhaseMgr().SendDebugReportToPlayer(handler->GetSession()->GetPlayer()); +                  return true;      }  }; diff --git a/src/server/scripts/Commands/cs_gobject.cpp b/src/server/scripts/Commands/cs_gobject.cpp index e556854c2ab..de23c33e591 100644 --- a/src/server/scripts/Commands/cs_gobject.cpp +++ b/src/server/scripts/Commands/cs_gobject.cpp @@ -152,12 +152,15 @@ public:          GameObject* object = new GameObject;          uint32 guidLow = sObjectMgr->GenerateLowGuid(HIGHGUID_GAMEOBJECT); -        if (!object->Create(guidLow, objectInfo->entry, map, player->GetPhaseMgr().GetPhaseMaskForSpawn(), x, y, z, o, 0.0f, 0.0f, 0.0f, 0.0f, 0, GO_STATE_READY)) +        if (!object->Create(guidLow, objectInfo->entry, map, 0, x, y, z, o, 0.0f, 0.0f, 0.0f, 0.0f, 0, GO_STATE_READY))          {              delete object;              return false;          } +        for (auto phase : player->GetPhases()) +            object->SetInPhase(phase, false, true); +          if (spawntimeSecs)          {              uint32 value = atoi((char*)spawntimeSecs); @@ -165,7 +168,7 @@ public:          }          // fill the gameobject data and save to the db -        object->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), player->GetPhaseMgr().GetPhaseMaskForSpawn()); +        object->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), player->GetPhaseMask());          // delete the old object and do a clean load from DB with a fresh new GameObject instance.          // this is required to avoid weird behavior and memory leaks          delete object; @@ -507,7 +510,7 @@ public:      //set phasemask for selected object      static bool HandleGameObjectSetPhaseCommand(ChatHandler* handler, char const* args)      { -        // number or [name] Shift-click form |color|Hgameobject:go_id|h[name]|h|r +        /*// number or [name] Shift-click form |color|Hgameobject:go_id|h[name]|h|r          char* id = handler->extractKeyFromLink((char*)args, "Hgameobject");          if (!id)              return false; @@ -539,7 +542,7 @@ public:          }          object->SetPhaseMask(phaseMask, true); -        object->SaveToDB(); +        object->SaveToDB();*/          return true;      } diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp index bff12d4330e..1d812a8f4eb 100644 --- a/src/server/scripts/Commands/cs_misc.cpp +++ b/src/server/scripts/Commands/cs_misc.cpp @@ -370,7 +370,8 @@ public:              target->GetContactPoint(_player, x, y, z);              _player->TeleportTo(target->GetMapId(), x, y, z, _player->GetAngle(target), TELE_TO_GM_MODE); -            _player->SetPhaseMask(target->GetPhaseMask(), true); +            for (auto phase : target->GetPhases()) +                _player->SetInPhase(phase, true, true);          }          else          { @@ -494,7 +495,8 @@ 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()); -            target->SetPhaseMask(handler->GetSession()->GetPlayer()->GetPhaseMask(), true); +            for (auto phase : handler->GetSession()->GetPlayer()->GetPhases()) +                target->SetInPhase(phase, true, true);          }          else          { diff --git a/src/server/scripts/Commands/cs_modify.cpp b/src/server/scripts/Commands/cs_modify.cpp index d47ee20fac5..8d44068a00d 100644 --- a/src/server/scripts/Commands/cs_modify.cpp +++ b/src/server/scripts/Commands/cs_modify.cpp @@ -1267,24 +1267,19 @@ public:          return true;      } -    //set temporary phase mask for player +    // Toggles a phaseid on a player      static bool HandleModifyPhaseCommand(ChatHandler* handler, const char* args)      {          if (!*args)              return false; -        uint32 phasemask = (uint32)atoi((char*)args); +        uint32 phase = (uint32)atoi((char*)args);          Unit* target = handler->getSelectedUnit();          if (target) -        { -            if (target->GetTypeId() == TYPEID_PLAYER) -                target->ToPlayer()->GetPhaseMgr().SetCustomPhase(phasemask); -            else -                target->SetPhaseMask(phasemask, true); -        } +            target->SetInPhase(phase, true, !target->IsInPhase(phase));          else -            handler->GetSession()->GetPlayer()->GetPhaseMgr().SetCustomPhase(phasemask); +            handler->GetSession()->GetPlayer()->SetInPhase(phase, true, !handler->GetSession()->GetPlayer()->IsInPhase(phase));          return true;      } diff --git a/src/server/scripts/Commands/cs_npc.cpp b/src/server/scripts/Commands/cs_npc.cpp index 3b3eb303d58..84716ad9590 100644 --- a/src/server/scripts/Commands/cs_npc.cpp +++ b/src/server/scripts/Commands/cs_npc.cpp @@ -264,7 +264,7 @@ public:              uint32 guid = sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT);              CreatureData& data = sObjectMgr->NewOrExistCreatureData(guid);              data.id = id; -            data.phaseMask = chr->GetPhaseMgr().GetPhaseMaskForSpawn(); +            data.phaseMask = chr->GetPhaseMask();              data.posX = chr->GetTransOffsetX();              data.posY = chr->GetTransOffsetY();              data.posZ = chr->GetTransOffsetZ(); @@ -272,20 +272,23 @@ public:              Creature* creature = trans->CreateNPCPassenger(guid, &data); -            creature->SaveToDB(trans->GetGOInfo()->moTransport.mapID, 1 << map->GetSpawnMode(), chr->GetPhaseMgr().GetPhaseMaskForSpawn()); +            creature->SaveToDB(trans->GetGOInfo()->moTransport.mapID, 1 << map->GetSpawnMode(), chr->GetPhaseMask());              sObjectMgr->AddCreatureToGrid(guid, &data);              return true;          }          Creature* creature = new Creature(); -        if (!creature->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMgr().GetPhaseMaskForSpawn(), id, x, y, z, o)) +        if (!creature->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMask(), id, x, y, z, o))          {              delete creature;              return false;          } -        creature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMgr().GetPhaseMaskForSpawn()); +        for (auto phase : chr->GetPhases()) +            creature->SetInPhase(phase, false, true); + +        creature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMask());          uint32 db_guid = creature->GetDBTableGUIDLow(); @@ -1096,20 +1099,14 @@ public:          return true;      } -    //npc phasemask handling -    //change phasemask of creature or pet +    //npc phase handling +    //change phase of creature or pet      static bool HandleNpcSetPhaseCommand(ChatHandler* handler, char const* args)      {          if (!*args)              return false; -        uint32 phasemask = (uint32) atoi((char*)args); -        if (phasemask == 0) -        { -            handler->SendSysMessage(LANG_BAD_VALUE); -            handler->SetSentErrorMessage(true); -            return false; -        } +        uint32 phase = (uint32) atoi((char*)args);          Creature* creature = handler->getSelectedCreature();          if (!creature) @@ -1119,7 +1116,7 @@ public:              return false;          } -        creature->SetPhaseMask(phasemask, true); +        creature->SetInPhase(phase, true, !creature->IsInPhase(phase));          if (!creature->IsPet())              creature->SaveToDB(); diff --git a/src/server/scripts/Commands/cs_wp.cpp b/src/server/scripts/Commands/cs_wp.cpp index 5306e0e1d9e..210c47a7d3d 100644 --- a/src/server/scripts/Commands/cs_wp.cpp +++ b/src/server/scripts/Commands/cs_wp.cpp @@ -694,7 +694,7 @@ public:                      }                      // re-create                      Creature* wpCreature2 = new Creature(); -                    if (!wpCreature2->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMgr().GetPhaseMaskForSpawn(), VISUAL_WAYPOINT, chr->GetPositionX(), chr->GetPositionY(), chr->GetPositionZ(), chr->GetOrientation())) +                    if (!wpCreature2->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMask(), VISUAL_WAYPOINT, chr->GetPositionX(), chr->GetPositionY(), chr->GetPositionZ(), chr->GetOrientation()))                      {                          handler->PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, VISUAL_WAYPOINT);                          delete wpCreature2; @@ -702,7 +702,10 @@ public:                          return false;                      } -                    wpCreature2->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMgr().GetPhaseMaskForSpawn()); +                    for (auto phase : chr->GetPhases()) +                        wpCreature2->SetInPhase(phase, false, true); + +                    wpCreature2->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMask());                      // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();                      /// @todo Should we first use "Create" then use "LoadFromDB"?                      if (!wpCreature2->LoadCreatureFromDB(wpCreature2->GetDBTableGUIDLow(), map)) @@ -918,13 +921,16 @@ public:                  float o = chr->GetOrientation();                  Creature* wpCreature = new Creature(); -                if (!wpCreature->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMgr().GetPhaseMaskForSpawn(), id, x, y, z, o)) +                if (!wpCreature->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMask(), id, x, y, z, o))                  {                      handler->PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, id);                      delete wpCreature;                      return false;                  } +                for (auto phase : chr->GetPhases()) +                    wpCreature->SetInPhase(phase, false, true); +                  // Set "wpguid" column to the visual waypoint                  PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_UPD_WAYPOINT_DATA_WPGUID); @@ -934,7 +940,7 @@ public:                  WorldDatabase.Execute(stmt); -                wpCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMgr().GetPhaseMaskForSpawn()); +                wpCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMask());                  // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();                  if (!wpCreature->LoadCreatureFromDB(wpCreature->GetDBTableGUIDLow(), map))                  { @@ -982,14 +988,17 @@ public:              Map* map = chr->GetMap();              Creature* creature = new Creature(); -            if (!creature->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMgr().GetPhaseMaskForSpawn(), id, x, y, z, o)) +            if (!creature->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMask(), id, x, y, z, o))              {                  handler->PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, id);                  delete creature;                  return false;              } -            creature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMgr().GetPhaseMaskForSpawn()); +            for (auto phase : chr->GetPhases()) +                creature->SetInPhase(phase, false, true); + +            creature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMask());              if (!creature->LoadCreatureFromDB(creature->GetDBTableGUIDLow(), map))              {                  handler->PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, id); @@ -1031,14 +1040,17 @@ public:              Map* map = chr->GetMap();              Creature* creature = new Creature(); -            if (!creature->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMgr().GetPhaseMaskForSpawn(), id, x, y, z, o)) +            if (!creature->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMask(), id, x, y, z, o))              {                  handler->PSendSysMessage(LANG_WAYPOINT_NOTCREATED, id);                  delete creature;                  return false;              } -            creature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMgr().GetPhaseMaskForSpawn()); +            for (auto phase : chr->GetPhases()) +                creature->SetInPhase(phase, false, true); + +            creature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMask());              if (!creature->LoadCreatureFromDB(creature->GetDBTableGUIDLow(), map))              {                  handler->PSendSysMessage(LANG_WAYPOINT_NOTCREATED, id); diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_nefarian.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_nefarian.cpp index f7aedb42561..a3804f8b35a 100644 --- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_nefarian.cpp +++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_nefarian.cpp @@ -178,7 +178,6 @@ public:                      _Reset();                  me->SetVisible(true); -                me->SetPhaseMask(1, true);                  me->SetUInt32Value(UNIT_NPC_FLAGS, 1);                  me->setFaction(35);                  me->SetStandState(UNIT_STAND_STATE_SIT_HIGH_CHAIR); diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/instance_blackwing_lair.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/instance_blackwing_lair.cpp index be8bc34acf1..8bd1ef26aec 100644 --- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/instance_blackwing_lair.cpp +++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/instance_blackwing_lair.cpp @@ -155,7 +155,7 @@ public:              {                  case 177807: // Egg                      if (GetBossState(BOSS_FIREMAW) == DONE) -                        go->SetPhaseMask(2, true); +                        go->SetLootState(GO_JUST_DEACTIVATED);                      else                          EggList.push_back(go->GetGUID());                      break; @@ -201,7 +201,7 @@ public:                      {                          for (std::list<uint64>::const_iterator itr = EggList.begin(); itr != EggList.end(); ++itr)                              if (GameObject* egg = instance->GetGameObject((*itr))) -                                egg->SetPhaseMask(2, true); +                                egg->SetLootState(GO_JUST_DEACTIVATED);                      }                      SetData(DATA_EGG_EVENT, NOT_STARTED);                      break; diff --git a/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_herald_volazj.cpp b/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_herald_volazj.cpp index 1c042f4d185..4b352b98af2 100644 --- a/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_herald_volazj.cpp +++ b/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_herald_volazj.cpp @@ -111,8 +111,14 @@ public:                      me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);                      me->SetControlled(true, UNIT_STATE_STUNNED);                  } -                // phase mask -                target->CastSpell(target, SPELL_INSANITY_TARGET+insanityHandled, true); + +                // phase the player +                target->CastSpell(target, SPELL_INSANITY_TARGET + insanityHandled, true); + +                SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(SPELL_INSANITY_TARGET + insanityHandled); +                if (!spellInfo) +                    return; +                  // summon twisted party members for this target                  Map::PlayerList const &players = me->GetMap()->GetPlayers();                  for (Map::PlayerList::const_iterator i = players.begin(); i != players.end(); ++i) @@ -125,21 +131,22 @@ public:                      {                          // clone                          player->CastSpell(summon, SPELL_CLONE_PLAYER, true); -                        // set phase -                        summon->SetPhaseMask((1<<(4+insanityHandled)), true); +                        // phase the summon +                        summon->SetInPhase(spellInfo->Effects[EFFECT_0].MiscValueB, true, true);                      }                  }                  ++insanityHandled;              }          } -        void ResetPlayersPhaseMask() +        void ResetPlayersPhase()          {              Map::PlayerList const &players = me->GetMap()->GetPlayers();              for (Map::PlayerList::const_iterator i = players.begin(); i != players.end(); ++i)              {                  Player* player = i->GetSource(); -                player->RemoveAurasDueToSpell(GetSpellForPhaseMask(player->GetPhaseMask())); +                for (uint32 index = 0; index <= 4; ++index) +                    player->RemoveAurasDueToSpell(SPELL_INSANITY_TARGET + index);              }          } @@ -153,11 +160,14 @@ public:              instance->DoStopTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_QUICK_DEMISE_START_EVENT);              // Visible for all players in insanity -            me->SetPhaseMask((1|16|32|64|128|256), true); +            me->SetInPhase(169, true, true); +            for (uint32 i = 173; i <= 177; ++i) +                me->SetInPhase(i, true, true); +              // Used for Insanity handling              insanityHandled = 0; -            ResetPlayersPhaseMask(); +            ResetPlayersPhase();              // Cleanup              Summons.DespawnAll(); @@ -178,33 +188,8 @@ public:              Summons.Summon(summon);          } -        uint32 GetSpellForPhaseMask(uint32 phase) -        { -            uint32 spell = 0; -            switch (phase) -            { -                case 16: -                    spell = SPELL_INSANITY_PHASING_1; -                    break; -                case 32: -                    spell = SPELL_INSANITY_PHASING_2; -                    break; -                case 64: -                    spell = SPELL_INSANITY_PHASING_3; -                    break; -                case 128: -                    spell = SPELL_INSANITY_PHASING_4; -                    break; -                case 256: -                    spell = SPELL_INSANITY_PHASING_5; -                    break; -            } -            return spell; -        } -          void SummonedCreatureDespawn(Creature* summon) override          { -            uint32 phase = summon->GetPhaseMask();              uint32 nextPhase = 0;              Summons.Despawn(summon); @@ -214,16 +199,17 @@ public:                  if (Creature* visage = ObjectAccessor::GetCreature(*me, *iter))                  {                      // Not all are dead -                    if (phase == visage->GetPhaseMask()) +                    if (visage->IsInPhase(summon))                          return;                      else -                        nextPhase = visage->GetPhaseMask(); +                    { +                        nextPhase = *visage->GetPhases().begin(); +                        break; +                    }                  }              }              // Roll Insanity -            uint32 spell = GetSpellForPhaseMask(phase); -            uint32 spell2 = GetSpellForPhaseMask(nextPhase);              Map* map = me->GetMap();              if (!map)                  return; @@ -235,12 +221,9 @@ public:                  {                      if (Player* player = i->GetSource())                      { -                        if (player->HasAura(spell)) -                        { -                            player->RemoveAurasDueToSpell(spell); -                            if (spell2) // if there is still some different mask cast spell for it -                                player->CastSpell(player, spell2, true); -                        } +                        for (uint32 index = 0; index <= 4; ++index) +                            player->RemoveAurasDueToSpell(SPELL_INSANITY_TARGET + index); +                        player->CastSpell(player, SPELL_INSANITY_TARGET + nextPhase - 173, true);                      }                  }              } @@ -292,7 +275,7 @@ public:              instance->SetBossState(DATA_HERALD_VOLAZJ, DONE);              Summons.DespawnAll(); -            ResetPlayersPhaseMask(); +            ResetPlayersPhase();          }          void KilledUnit(Unit* who) override diff --git a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp index 6d03774ea8c..78e8f2d248e 100644 --- a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp +++ b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp @@ -380,7 +380,7 @@ class boss_halion : public CreatureScript                  if (events.IsInPhase(PHASE_THREE))                  {                      // Don't consider copied damage. -                    if (!me->InSamePhase(attacker)) +                    if (!me->IsInPhase(attacker))                          return;                      if (Creature* controller = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_HALION_CONTROLLER))) @@ -541,7 +541,7 @@ class boss_twilight_halion : public CreatureScript                  if (events.IsInPhase(PHASE_THREE))                  {                      // Don't consider copied damage. -                    if (!me->InSamePhase(attacker)) +                    if (!me->IsInPhase(attacker))                          return;                      if (Creature* controller = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_HALION_CONTROLLER))) diff --git a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp index 4303026ba64..21a0f92c7b5 100644 --- a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp +++ b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp @@ -636,7 +636,7 @@ class npc_jaina_or_sylvanas_intro_hor : public CreatureScript                          if (Creature* lichking = ObjectAccessor::GetCreature(*me, _lichkingGUID))                          {                              if (GameObject* frostmourne = ObjectAccessor::GetGameObject(*me, _instance->GetData64(DATA_FROSTMOURNE))) -                                frostmourne->SetPhaseMask(2, true); +                                frostmourne->SetLootState(GO_JUST_DEACTIVATED);                              lichking->CastSpell(lichking, SPELL_TAKE_FROSTMOURNE, true);                              lichking->CastSpell(lichking, SPELL_FROSTMOURNE_VISUAL, true);                          } diff --git a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/instance_halls_of_reflection.cpp b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/instance_halls_of_reflection.cpp index 6f33e80b92b..b17a5dbc8f5 100644 --- a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/instance_halls_of_reflection.cpp +++ b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/instance_halls_of_reflection.cpp @@ -248,7 +248,7 @@ class instance_halls_of_reflection : public InstanceMapScript                      case GO_FROSTMOURNE:                          FrostmourneGUID = go->GetGUID();                          if (GetData(DATA_INTRO_EVENT) == DONE) -                            go->SetPhaseMask(2, true); +                            go->SetLootState(GO_JUST_DEACTIVATED);                          break;                      case GO_ENTRANCE_DOOR:                          EntranceDoorGUID = go->GetGUID(); diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp index 0c504842c08..68344593434 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp @@ -618,7 +618,7 @@ class npc_the_lich_king_controller : public CreatureScript              void JustSummoned(Creature* summon) override              {                  // must not be in dream phase -                summon->SetPhaseMask((summon->GetPhaseMask() & ~0x10), true); +                summon->SetInPhase(173, true, false);                  if (summon->GetEntry() != NPC_SUPPRESSER)                      if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true))                          summon->AI()->AttackStart(target); diff --git a/src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp b/src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp index c5c70cf3957..9875eb5aa68 100644 --- a/src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp +++ b/src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp @@ -305,7 +305,7 @@ public:              if (GameObject* trigger = ObjectAccessor::GetGameObject(*me, instance->GetData64(DATA_KELTHUZAD_TRIGGER)))              {                  trigger->ResetDoorOrButton(); -                trigger->SetPhaseMask(1, true); +                trigger->SetLootState(GO_READY);              }              for (uint8 i = 0; i <= 3; ++i) @@ -394,7 +394,7 @@ public:                              break;                          case EVENT_TRIGGER:                              if (GameObject* trigger = ObjectAccessor::GetGameObject(*me, instance->GetData64(DATA_KELTHUZAD_TRIGGER))) -                                trigger->SetPhaseMask(2, true); +                                trigger->SetLootState(GO_JUST_DEACTIVATED);                              break;                          case EVENT_PHASE:                              events.Reset(); diff --git a/src/server/scripts/Northrend/Nexus/EyeOfEternity/instance_eye_of_eternity.cpp b/src/server/scripts/Northrend/Nexus/EyeOfEternity/instance_eye_of_eternity.cpp index 8a1fb6a9829..4fa80c7bac2 100644 --- a/src/server/scripts/Northrend/Nexus/EyeOfEternity/instance_eye_of_eternity.cpp +++ b/src/server/scripts/Northrend/Nexus/EyeOfEternity/instance_eye_of_eternity.cpp @@ -90,7 +90,6 @@ public:                  delete go;                  return;              } -              instance->AddToMap(go);          } diff --git a/src/server/scripts/Northrend/Nexus/Oculus/instance_oculus.cpp b/src/server/scripts/Northrend/Nexus/Oculus/instance_oculus.cpp index 2b15ddf32c4..d78a07f5c2b 100644 --- a/src/server/scripts/Northrend/Nexus/Oculus/instance_oculus.cpp +++ b/src/server/scripts/Northrend/Nexus/Oculus/instance_oculus.cpp @@ -69,7 +69,7 @@ class instance_oculus : public InstanceMapScript                      case NPC_VAROS:                          VarosGUID = creature->GetGUID();                          if (GetBossState(DATA_DRAKOS) == DONE) -                           creature->SetPhaseMask(1, true); +                            creature->SetPhaseMask(1, true);                          break;                      case NPC_UROM:                          UromGUID = creature->GetGUID(); diff --git a/src/server/scripts/Northrend/VioletHold/boss_zuramat.cpp b/src/server/scripts/Northrend/VioletHold/boss_zuramat.cpp index 7ae1c7840db..753d4ebea01 100644 --- a/src/server/scripts/Northrend/VioletHold/boss_zuramat.cpp +++ b/src/server/scripts/Northrend/VioletHold/boss_zuramat.cpp @@ -190,7 +190,8 @@ public:          {              summon->AI()->AttackStart(me->GetVictim());              summon->CastSpell((Unit*)NULL, SPELL_ZURAMAT_ADD_2); -            summon->SetPhaseMask(17, true); +            summon->SetInPhase(169, true, true); // Normal phase +            summon->SetInPhase(173, true, true); // Void phase          }      }; diff --git a/src/server/scripts/Northrend/zone_borean_tundra.cpp b/src/server/scripts/Northrend/zone_borean_tundra.cpp index 38d73e0673d..08936df4589 100644 --- a/src/server/scripts/Northrend/zone_borean_tundra.cpp +++ b/src/server/scripts/Northrend/zone_borean_tundra.cpp @@ -1853,7 +1853,7 @@ public:                      me->HandleEmoteCommand(EMOTE_ONESHOT_EXCLAMATION);                      break;                  case 20: -                    me->SetPhaseMask(1, true); +                    me->SetInPhase(170, true, false);                      Talk(SAY_5);                      me->HandleEmoteCommand(EMOTE_ONESHOT_EXCLAMATION);                      player->GroupEventHappens(QUEST_ESCAPING_THE_MIST, me); diff --git a/src/server/scripts/OutdoorPvP/OutdoorPvPSI.cpp b/src/server/scripts/OutdoorPvP/OutdoorPvPSI.cpp index a3ef9ce7b5c..b43904f2223 100644 --- a/src/server/scripts/OutdoorPvP/OutdoorPvPSI.cpp +++ b/src/server/scripts/OutdoorPvP/OutdoorPvPSI.cpp @@ -170,6 +170,9 @@ bool OutdoorPvPSI::HandleDropFlag(Player* player, uint32 spellId)                              return true;                          } +                        for (auto phase : player->GetPhases()) +                            go->SetInPhase(phase, false, true); +                          go->SetRespawnTime(0);                          if (!map->AddToMap(go)) @@ -204,6 +207,9 @@ bool OutdoorPvPSI::HandleDropFlag(Player* player, uint32 spellId)                              return true;                          } +                        for (auto phase : player->GetPhases()) +                            go->SetInPhase(phase, false, true); +                          go->SetRespawnTime(0);                          if (!map->AddToMap(go))  | 
