TrinityCore
PhasingHandler.cpp
Go to the documentation of this file.
1/*
2 * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#include "PhasingHandler.h"
19#include "Chat.h"
20#include "ConditionMgr.h"
21#include "Creature.h"
22#include "DB2Stores.h"
23#include "DisableMgr.h"
24#include "Language.h"
25#include "Map.h"
26#include "MiscPackets.h"
27#include "ObjectAccessor.h"
28#include "ObjectMgr.h"
29#include "PartyPackets.h"
30#include "PhaseShift.h"
31#include "Player.h"
32#include "SpellAuraEffects.h"
33#include "TerrainMgr.h"
34#include "Vehicle.h"
35#include <boost/container/small_vector.hpp>
36#include <sstream>
37
38namespace
39{
40PhaseShift const Empty;
42{
43 PhaseShift phaseShift;
45 return phaseShift;
46}();
47
48inline PhaseFlags GetPhaseFlags(uint32 phaseId)
49{
50 if (PhaseEntry const* phase = sPhaseStore.LookupEntry(phaseId))
51 {
52 if (phase->GetFlags().HasFlag(PhaseEntryFlags::Cosmetic))
54
55 if (phase->GetFlags().HasFlag(PhaseEntryFlags::Personal))
57 }
58
59 return PhaseFlags::None;
60}
61}
62
64{
65public:
67 {
68 _visited.insert(owner);
69 }
70
71 template<typename Func>
72 inline void VisitControlledOf(Unit* unit, Func&& func)
73 {
74 for (Unit* controlled : unit->m_Controlled)
75 if (controlled->GetTypeId() != TYPEID_PLAYER
76 && !controlled->GetVehicle()) // Player inside nested vehicle should not phase the root vehicle and its accessories (only direct root vehicle control does)
77 if (_visited.insert(controlled).second)
78 func(controlled);
79
80 for (ObjectGuid summonGuid : unit->m_SummonSlot)
81 if (!summonGuid.IsEmpty())
82 if (Creature* summon = ObjectAccessor::GetCreature(*unit, summonGuid))
83 if (_visited.insert(summon).second)
84 func(summon);
85
86 if (Vehicle const* vehicle = unit->GetVehicleKit())
87 for (auto seat = vehicle->Seats.begin(); seat != vehicle->Seats.end(); ++seat)
88 if (Unit* passenger = ObjectAccessor::GetUnit(*unit, seat->second.Passenger.Guid); passenger && passenger != unit)
89 if (_visited.insert(passenger).second)
90 func(passenger);
91 }
92
93private:
94 Trinity::Containers::FlatSet<WorldObject*, std::less<WorldObject*>, boost::container::small_vector<WorldObject*, 8>> _visited;
95};
96
97void PhasingHandler::AddPhase(WorldObject* object, uint32 phaseId, bool updateVisibility)
98{
99 ControlledUnitVisitor visitor(object);
100 AddPhase(object, phaseId, object->GetGUID(), updateVisibility, visitor);
101}
102
103void PhasingHandler::AddPhase(WorldObject* object, uint32 phaseId, ObjectGuid const& personalGuid, bool updateVisibility, ControlledUnitVisitor& visitor)
104{
105 bool changed = object->GetPhaseShift().AddPhase(phaseId, GetPhaseFlags(phaseId), nullptr);
106
107 if (object->GetPhaseShift().PersonalReferences)
108 object->GetPhaseShift().PersonalGuid = personalGuid;
109
110 if (Unit* unit = object->ToUnit())
111 {
112 unit->OnPhaseChange();
113 visitor.VisitControlledOf(unit, [&](Unit* controlled)
114 {
115 AddPhase(controlled, phaseId, personalGuid, updateVisibility, visitor);
116 });
117 unit->RemoveNotOwnSingleTargetAuras(true);
118 }
119
120 UpdateVisibilityIfNeeded(object, updateVisibility, changed);
121}
122
123void PhasingHandler::RemovePhase(WorldObject* object, uint32 phaseId, bool updateVisibility)
124{
125 ControlledUnitVisitor visitor(object);
126 RemovePhase(object, phaseId, updateVisibility, visitor);
127}
128
129void PhasingHandler::RemovePhase(WorldObject* object, uint32 phaseId, bool updateVisibility, ControlledUnitVisitor& visitor)
130{
131 bool changed = object->GetPhaseShift().RemovePhase(phaseId).Erased;
132
133 if (Unit* unit = object->ToUnit())
134 {
135 unit->OnPhaseChange();
136 visitor.VisitControlledOf(unit, [&](Unit* controlled)
137 {
138 RemovePhase(controlled, phaseId, updateVisibility, visitor);
139 });
140 unit->RemoveNotOwnSingleTargetAuras(true);
141 }
142
143 UpdateVisibilityIfNeeded(object, updateVisibility, changed);
144}
145
146void PhasingHandler::AddPhaseGroup(WorldObject* object, uint32 phaseGroupId, bool updateVisibility)
147{
148 std::vector<uint32> const* phasesInGroup = sDB2Manager.GetPhasesForGroup(phaseGroupId);
149 if (!phasesInGroup)
150 return;
151
152 ControlledUnitVisitor visitor(object);
153 AddPhaseGroup(object, phasesInGroup, object->GetGUID(), updateVisibility, visitor);
154}
155
156void PhasingHandler::AddPhaseGroup(WorldObject* object, std::vector<uint32> const* phasesInGroup, ObjectGuid const& personalGuid, bool updateVisibility, ControlledUnitVisitor& visitor)
157{
158 bool changed = false;
159 for (uint32 phaseId : *phasesInGroup)
160 changed = object->GetPhaseShift().AddPhase(phaseId, GetPhaseFlags(phaseId), nullptr) || changed;
161
162 if (object->GetPhaseShift().PersonalReferences)
163 object->GetPhaseShift().PersonalGuid = personalGuid;
164
165 if (Unit* unit = object->ToUnit())
166 {
167 unit->OnPhaseChange();
168 visitor.VisitControlledOf(unit, [&](Unit* controlled)
169 {
170 AddPhaseGroup(controlled, phasesInGroup, personalGuid, updateVisibility, visitor);
171 });
172 unit->RemoveNotOwnSingleTargetAuras(true);
173 }
174
175 UpdateVisibilityIfNeeded(object, updateVisibility, changed);
176}
177
178void PhasingHandler::RemovePhaseGroup(WorldObject* object, uint32 phaseGroupId, bool updateVisibility)
179{
180 std::vector<uint32> const* phasesInGroup = sDB2Manager.GetPhasesForGroup(phaseGroupId);
181 if (!phasesInGroup)
182 return;
183
184 ControlledUnitVisitor visitor(object);
185 RemovePhaseGroup(object, phasesInGroup, updateVisibility, visitor);
186}
187
188void PhasingHandler::RemovePhaseGroup(WorldObject* object, std::vector<uint32> const* phasesInGroup, bool updateVisibility, ControlledUnitVisitor& visitor)
189{
190 bool changed = false;
191 for (uint32 phaseId : *phasesInGroup)
192 changed = object->GetPhaseShift().RemovePhase(phaseId).Erased || changed;
193
194 if (Unit* unit = object->ToUnit())
195 {
196 unit->OnPhaseChange();
197 visitor.VisitControlledOf(unit, [&](Unit* controlled)
198 {
199 RemovePhaseGroup(controlled, phasesInGroup, updateVisibility, visitor);
200 });
201 unit->RemoveNotOwnSingleTargetAuras(true);
202 }
203
204 UpdateVisibilityIfNeeded(object, updateVisibility, changed);
205}
206
208{
209 ControlledUnitVisitor visitor(object);
210 AddVisibleMapId(object, visibleMapId, visitor);
211}
212
214{
215 TerrainSwapInfo const* terrainSwapInfo = sObjectMgr->GetTerrainSwapInfo(visibleMapId);
216 bool changed = object->GetPhaseShift().AddVisibleMapId(visibleMapId, terrainSwapInfo);
217
218 for (uint32 uiMapPhaseId : terrainSwapInfo->UiMapPhaseIDs)
219 changed = object->GetPhaseShift().AddUiMapPhaseId(uiMapPhaseId) || changed;
220
221 if (Unit* unit = object->ToUnit())
222 {
223 visitor.VisitControlledOf(unit, [&](Unit* controlled)
224 {
225 AddVisibleMapId(controlled, visibleMapId, visitor);
226 });
227 }
228
229 UpdateVisibilityIfNeeded(object, false, changed);
230}
231
233{
234 ControlledUnitVisitor visitor(object);
235 RemoveVisibleMapId(object, visibleMapId, visitor);
236}
237
239{
240 TerrainSwapInfo const* terrainSwapInfo = sObjectMgr->GetTerrainSwapInfo(visibleMapId);
241 bool changed = object->GetPhaseShift().RemoveVisibleMapId(visibleMapId).Erased;
242
243 for (uint32 uiWorldMapAreaIDSwap : terrainSwapInfo->UiMapPhaseIDs)
244 changed = object->GetPhaseShift().RemoveUiMapPhaseId(uiWorldMapAreaIDSwap).Erased || changed;
245
246 if (Unit* unit = object->ToUnit())
247 {
248 visitor.VisitControlledOf(unit, [&](Unit* controlled)
249 {
250 RemoveVisibleMapId(controlled, visibleMapId, visitor);
251 });
252 }
253
254 UpdateVisibilityIfNeeded(object, false, changed);
255}
256
258{
259 object->GetPhaseShift().Clear();
260 object->GetSuppressedPhaseShift().Clear();
261}
262
264{
265 target->GetPhaseShift() = source->GetPhaseShift();
267}
268
270{
271 PhaseShift& phaseShift = object->GetPhaseShift();
272 PhaseShift& suppressedPhaseShift = object->GetSuppressedPhaseShift();
274
275 object->GetPhaseShift().VisibleMapIds.clear();
276 object->GetPhaseShift().UiMapPhaseIds.clear();
277 object->GetSuppressedPhaseShift().VisibleMapIds.clear();
278
279 for (auto const& visibleMapPair : sObjectMgr->GetTerrainSwaps())
280 {
281 for (TerrainSwapInfo const* visibleMapInfo : visibleMapPair.second)
282 {
283 if (sConditionMgr->IsObjectMeetingNotGroupedConditions(CONDITION_SOURCE_TYPE_TERRAIN_SWAP, visibleMapInfo->Id, srcInfo))
284 {
285 if (visibleMapPair.first == object->GetMapId())
286 phaseShift.AddVisibleMapId(visibleMapInfo->Id, visibleMapInfo);
287
288 // ui map is visible on all maps
289 for (uint32 uiMapPhaseId : visibleMapInfo->UiMapPhaseIDs)
290 phaseShift.AddUiMapPhaseId(uiMapPhaseId);
291 }
292 else if (visibleMapPair.first == object->GetMapId())
293 suppressedPhaseShift.AddVisibleMapId(visibleMapInfo->Id, visibleMapInfo);
294 }
295 }
296
297 UpdateVisibilityIfNeeded(object, false, true);
298}
299
301{
302 PhaseShift& phaseShift = object->GetPhaseShift();
303 PhaseShift& suppressedPhaseShift = object->GetSuppressedPhaseShift();
304 PhaseShift::PhaseContainer oldPhases = std::move(phaseShift.Phases); // for comparison
306
307 object->GetPhaseShift().ClearPhases();
308 object->GetSuppressedPhaseShift().ClearPhases();
309
310 uint32 areaId = object->GetAreaId();
311 AreaTableEntry const* areaEntry = sAreaTableStore.LookupEntry(areaId);
312 while (areaEntry)
313 {
314 if (std::vector<PhaseAreaInfo> const* newAreaPhases = sObjectMgr->GetPhasesForArea(areaEntry->ID))
315 {
316 for (PhaseAreaInfo const& phaseArea : *newAreaPhases)
317 {
318 if (phaseArea.SubAreaExclusions.find(areaId) != phaseArea.SubAreaExclusions.end())
319 continue;
320
321 uint32 phaseId = phaseArea.PhaseInfo->Id;
323 continue;
324
325 if (sConditionMgr->IsObjectMeetToConditions(srcInfo, phaseArea.Conditions))
326 phaseShift.AddPhase(phaseId, GetPhaseFlags(phaseId), &phaseArea.Conditions);
327 else
328 suppressedPhaseShift.AddPhase(phaseId, GetPhaseFlags(phaseId), &phaseArea.Conditions);
329 }
330 }
331
332 areaEntry = sAreaTableStore.LookupEntry(areaEntry->ParentAreaID);
333 }
334
335 bool changed = phaseShift.Phases != oldPhases;
336 if (Unit* unit = object->ToUnit())
337 {
338 for (AuraEffect const* aurEff : unit->GetAuraEffectsByType(SPELL_AURA_PHASE))
339 {
340 uint32 phaseId = uint32(aurEff->GetMiscValueB());
341 changed = phaseShift.AddPhase(phaseId, GetPhaseFlags(phaseId), nullptr) || changed;
342 }
343
344 for (AuraEffect const* aurEff : unit->GetAuraEffectsByType(SPELL_AURA_PHASE_GROUP))
345 if (std::vector<uint32> const* phasesInGroup = sDB2Manager.GetPhasesForGroup(uint32(aurEff->GetMiscValueB())))
346 for (uint32 phaseId : *phasesInGroup)
347 changed = phaseShift.AddPhase(phaseId, GetPhaseFlags(phaseId), nullptr) || changed;
348
349 if (phaseShift.PersonalReferences)
350 phaseShift.PersonalGuid = unit->GetGUID();
351
352 if (changed)
353 unit->OnPhaseChange();
354
355 ControlledUnitVisitor visitor(unit);
356 visitor.VisitControlledOf(unit, [&](Unit* controlled)
357 {
358 InheritPhaseShift(controlled, unit);
359 });
360
361 if (changed)
362 unit->RemoveNotOwnSingleTargetAuras(true);
363 }
364 else
365 {
366 if (phaseShift.PersonalReferences)
367 phaseShift.PersonalGuid = object->GetGUID();
368 }
369
370 UpdateVisibilityIfNeeded(object, true, changed);
371}
372
373bool PhasingHandler::OnConditionChange(WorldObject* object, bool updateVisibility /*= true*/)
374{
375 PhaseShift& phaseShift = object->GetPhaseShift();
376 PhaseShift& suppressedPhaseShift = object->GetSuppressedPhaseShift();
377 PhaseShift newSuppressions;
379 bool changed = false;
380
381 for (auto itr = phaseShift.Phases.begin(); itr != phaseShift.Phases.end();)
382 {
383 if (itr->AreaConditions && !sConditionMgr->IsObjectMeetToConditions(srcInfo, *itr->AreaConditions))
384 {
385 newSuppressions.AddPhase(itr->Id, itr->Flags, itr->AreaConditions, itr->References);
386 phaseShift.ModifyPhasesReferences(itr, -itr->References);
387 itr = phaseShift.Phases.erase(itr);
388 }
389 else
390 ++itr;
391 }
392
393 for (auto itr = suppressedPhaseShift.Phases.begin(); itr != suppressedPhaseShift.Phases.end();)
394 {
395 if (!DisableMgr::IsDisabledFor(DISABLE_TYPE_PHASE_AREA, itr->Id, object) && sConditionMgr->IsObjectMeetToConditions(srcInfo, *ASSERT_NOTNULL(itr->AreaConditions)))
396 {
397 changed = phaseShift.AddPhase(itr->Id, itr->Flags, itr->AreaConditions, itr->References) || changed;
398 suppressedPhaseShift.ModifyPhasesReferences(itr, -itr->References);
399 itr = suppressedPhaseShift.Phases.erase(itr);
400 }
401 else
402 ++itr;
403 }
404
405 for (auto itr = phaseShift.VisibleMapIds.begin(); itr != phaseShift.VisibleMapIds.end();)
406 {
407 if (!sConditionMgr->IsObjectMeetingNotGroupedConditions(CONDITION_SOURCE_TYPE_TERRAIN_SWAP, itr->first, srcInfo))
408 {
409 newSuppressions.AddVisibleMapId(itr->first, itr->second.VisibleMapInfo, itr->second.References);
410 for (uint32 uiMapPhaseId : itr->second.VisibleMapInfo->UiMapPhaseIDs)
411 changed = phaseShift.RemoveUiMapPhaseId(uiMapPhaseId).Erased || changed;
412
413 itr = phaseShift.VisibleMapIds.erase(itr);
414 }
415 else
416 ++itr;
417 }
418
419 for (auto itr = suppressedPhaseShift.VisibleMapIds.begin(); itr != suppressedPhaseShift.VisibleMapIds.end();)
420 {
421 if (sConditionMgr->IsObjectMeetingNotGroupedConditions(CONDITION_SOURCE_TYPE_TERRAIN_SWAP, itr->first, srcInfo))
422 {
423 changed = phaseShift.AddVisibleMapId(itr->first, itr->second.VisibleMapInfo, itr->second.References) || changed;
424 for (uint32 uiMapPhaseId : itr->second.VisibleMapInfo->UiMapPhaseIDs)
425 changed = phaseShift.AddUiMapPhaseId(uiMapPhaseId) || changed;
426
427 itr = suppressedPhaseShift.VisibleMapIds.erase(itr);
428 }
429 else
430 ++itr;
431 }
432
433 Unit* unit = object->ToUnit();
434 if (unit)
435 {
436 for (AuraEffect const* aurEff : unit->GetAuraEffectsByType(SPELL_AURA_PHASE))
437 {
438 uint32 phaseId = uint32(aurEff->GetMiscValueB());
439 auto eraseResult = newSuppressions.RemovePhase(phaseId);
440 // if condition was met previously there is nothing to erase
441 if (eraseResult.Iterator != newSuppressions.Phases.end() || eraseResult.Erased)
442 phaseShift.AddPhase(phaseId, GetPhaseFlags(phaseId), nullptr);
443 }
444
445 for (AuraEffect const* aurEff : unit->GetAuraEffectsByType(SPELL_AURA_PHASE_GROUP))
446 {
447 if (std::vector<uint32> const* phasesInGroup = sDB2Manager.GetPhasesForGroup(uint32(aurEff->GetMiscValueB())))
448 {
449 for (uint32 phaseId : *phasesInGroup)
450 {
451 auto eraseResult = newSuppressions.RemovePhase(phaseId);
452 // if condition was met previously there is nothing to erase
453 if (eraseResult.Iterator != newSuppressions.Phases.end() || eraseResult.Erased)
454 phaseShift.AddPhase(phaseId, GetPhaseFlags(phaseId), nullptr);
455 }
456 }
457 }
458 }
459
460 if (phaseShift.PersonalReferences)
461 phaseShift.PersonalGuid = object->GetGUID();
462
463 changed = changed || !newSuppressions.Phases.empty() || !newSuppressions.VisibleMapIds.empty();
464 for (PhaseShift::PhaseRef const& phaseRef : newSuppressions.Phases)
465 suppressedPhaseShift.AddPhase(phaseRef.Id, phaseRef.Flags, phaseRef.AreaConditions, phaseRef.References);
466
467 for (std::pair<uint32 const, PhaseShift::VisibleMapIdRef> const& visibleMap : newSuppressions.VisibleMapIds)
468 suppressedPhaseShift.AddVisibleMapId(visibleMap.first, visibleMap.second.VisibleMapInfo, visibleMap.second.References);
469
470 if (unit)
471 {
472 if (changed)
473 unit->OnPhaseChange();
474
475 ControlledUnitVisitor visitor(unit);
476 visitor.VisitControlledOf(unit, [&](Unit* controlled)
477 {
478 InheritPhaseShift(controlled, unit);
479 });
480
481 if (changed)
483 }
484
485 UpdateVisibilityIfNeeded(object, updateVisibility, changed);
486 return changed;
487}
488
489void PhasingHandler::SendToPlayer(Player const* player, PhaseShift const& phaseShift)
490{
492 phaseShiftChange.Client = player->GetGUID();
493 phaseShiftChange.Phaseshift.PhaseShiftFlags = phaseShift.Flags.AsUnderlyingType();
494 phaseShiftChange.Phaseshift.PersonalGUID = phaseShift.PersonalGuid;
495 phaseShiftChange.Phaseshift.Phases.reserve(phaseShift.Phases.size());
496 std::transform(phaseShift.Phases.begin(), phaseShift.Phases.end(), std::back_inserter(phaseShiftChange.Phaseshift.Phases),
497 [](PhaseShift::PhaseRef const& phase) -> WorldPackets::Misc::PhaseShiftDataPhase { return { phase.Flags.AsUnderlyingType(), phase.Id }; });
498 phaseShiftChange.VisibleMapIDs.reserve(phaseShift.VisibleMapIds.size());
499 std::transform(phaseShift.VisibleMapIds.begin(), phaseShift.VisibleMapIds.end(), std::back_inserter(phaseShiftChange.VisibleMapIDs),
500 [](PhaseShift::VisibleMapIdContainer::value_type const& visibleMapId) { return visibleMapId.first; });
501 phaseShiftChange.UiMapPhaseIDs.reserve(phaseShift.UiMapPhaseIds.size());
502 std::transform(phaseShift.UiMapPhaseIds.begin(), phaseShift.UiMapPhaseIds.end(), std::back_inserter(phaseShiftChange.UiMapPhaseIDs),
503 [](PhaseShift::UiMapPhaseIdContainer::value_type const& uiWorldMapAreaIdSwap) { return uiWorldMapAreaIdSwap.first; });
504
505 player->SendDirectMessage(phaseShiftChange.Write());
506}
507
509{
510 SendToPlayer(player, player->GetPhaseShift());
511}
512
514{
515 partyMemberPhases->PhaseShiftFlags = phaseShift.Flags.AsUnderlyingType();
516 partyMemberPhases->PersonalGUID = phaseShift.PersonalGuid;
517 partyMemberPhases->List.reserve(phaseShift.Phases.size());
518 std::transform(phaseShift.Phases.begin(), phaseShift.Phases.end(), std::back_inserter(partyMemberPhases->List),
519 [](PhaseShift::PhaseRef const& phase) -> WorldPackets::Party::PartyMemberPhase { return { phase.Flags.AsUnderlyingType(), phase.Id }; });
520}
521
523{
524 return Empty;
525}
526
528{
529 return AlwaysVisible;
530}
531
532void PhasingHandler::InitDbPhaseShift(PhaseShift& phaseShift, uint8 phaseUseFlags, uint16 phaseId, uint32 phaseGroupId)
533{
534 phaseShift.ClearPhases();
535 phaseShift.IsDbPhaseShift = true;
536
538 if (phaseUseFlags & PHASE_USE_FLAGS_ALWAYS_VISIBLE)
540 if (phaseUseFlags & PHASE_USE_FLAGS_INVERSE)
542
543 if (phaseId)
544 phaseShift.AddPhase(phaseId, GetPhaseFlags(phaseId), nullptr);
545 else if (phaseGroupId)
546 if (std::vector<uint32> const* phasesInGroup = sDB2Manager.GetPhasesForGroup(phaseGroupId))
547 for (uint32 phaseInGroup : *phasesInGroup)
548 phaseShift.AddPhase(phaseInGroup, GetPhaseFlags(phaseInGroup), nullptr);
549
550 if (phaseShift.Phases.empty() || phaseShift.HasPhase(DEFAULT_PHASE))
551 {
552 if (flags.HasFlag(PhaseShiftFlags::Inverse))
554 else
556 }
557
558 phaseShift.Flags = flags;
559}
560
562{
563 ASSERT(phaseShift.IsDbPhaseShift);
564 ASSERT(phaseShift.HasPersonalPhase());
565 phaseShift.PersonalGuid = personalGuid;
566}
567
569{
570 phaseShift.VisibleMapIds.clear();
571 if (visibleMapId != -1)
572 phaseShift.AddVisibleMapId(visibleMapId, sObjectMgr->GetTerrainSwapInfo(visibleMapId));
573}
574
575bool PhasingHandler::InDbPhaseShift(WorldObject const* object, uint8 phaseUseFlags, uint16 phaseId, uint32 phaseGroupId)
576{
577 PhaseShift phaseShift;
578 InitDbPhaseShift(phaseShift, phaseUseFlags, phaseId, phaseGroupId);
579 return object->GetPhaseShift().CanSee(phaseShift);
580}
581
582uint32 PhasingHandler::GetTerrainMapId(PhaseShift const& phaseShift, uint32 mapId, TerrainInfo const* terrain, float x, float y)
583{
584 if (phaseShift.VisibleMapIds.empty())
585 return mapId;
586
587 if (phaseShift.VisibleMapIds.size() == 1)
588 return phaseShift.VisibleMapIds.begin()->first;
589
590 GridCoord gridCoord = Trinity::ComputeGridCoord(x, y);
591 int32 gx = (MAX_NUMBER_OF_GRIDS - 1) - gridCoord.x_coord;
592 int32 gy = (MAX_NUMBER_OF_GRIDS - 1) - gridCoord.y_coord;
593
594 for (std::pair<uint32 const, PhaseShift::VisibleMapIdRef> const& visibleMap : phaseShift.VisibleMapIds)
595 if (terrain->HasChildTerrainGridFile(visibleMap.first, gx, gy))
596 return visibleMap.first;
597
598 return mapId;
599}
600
601void PhasingHandler::SetAlwaysVisible(WorldObject* object, bool apply, bool updateVisibility)
602{
603 if (apply)
604 object->GetPhaseShift().Flags |= PhaseShiftFlags::AlwaysVisible;
605 else
606 object->GetPhaseShift().Flags &= ~PhaseShiftFlags::AlwaysVisible;
607
608 UpdateVisibilityIfNeeded(object, updateVisibility, true);
609}
610
611void PhasingHandler::SetInversed(WorldObject* object, bool apply, bool updateVisibility)
612{
613 if (apply)
614 object->GetPhaseShift().Flags |= PhaseShiftFlags::Inverse;
615 else
616 object->GetPhaseShift().Flags &= PhaseShiftFlags::Inverse;
617
618 object->GetPhaseShift().UpdateUnphasedFlag();
619
620 UpdateVisibilityIfNeeded(object, updateVisibility, true);
621}
622
624{
625 PhaseShift const& phaseShift = target->GetPhaseShift();
626
627 std::string phaseOwnerName = "N/A";
628 if (phaseShift.HasPersonalPhase())
629 if (WorldObject* personalGuid = ObjectAccessor::GetWorldObject(*target, phaseShift.PersonalGuid))
630 phaseOwnerName = personalGuid->GetName();
631
633 phaseShift.PersonalGuid.ToString().c_str(), phaseOwnerName.c_str());
634
635 if (!phaseShift.Phases.empty())
636 {
637 std::ostringstream phases;
638 std::string cosmetic = sObjectMgr->GetTrinityString(LANG_PHASE_FLAG_COSMETIC, chat->GetSessionDbLocaleIndex());
639 std::string personal = sObjectMgr->GetTrinityString(LANG_PHASE_FLAG_PERSONAL, chat->GetSessionDbLocaleIndex());
640 for (PhaseShift::PhaseRef const& phase : phaseShift.Phases)
641 {
642 phases << "\r\n";
643 phases << ' ' << ' ' << ' ';
644 phases << phase.Id << ' ' << '(' << sObjectMgr->GetPhaseName(phase.Id) << ')';
646 phases << ' ' << '(' << cosmetic << ')';
648 phases << ' ' << '(' << personal << ')';
650 phases << " (Disabled)";
651 }
652
653 chat->PSendSysMessage(LANG_PHASESHIFT_PHASES, phases.str().c_str());
654 }
655
656 if (!phaseShift.VisibleMapIds.empty())
657 {
658 std::ostringstream visibleMapIds;
659 for (PhaseShift::VisibleMapIdContainer::value_type const& visibleMapId : phaseShift.VisibleMapIds)
660 visibleMapIds << visibleMapId.first << ',' << ' ';
661
662 chat->PSendSysMessage(LANG_PHASESHIFT_VISIBLE_MAP_IDS, visibleMapIds.str().c_str());
663 }
664
665 if (!phaseShift.UiMapPhaseIds.empty())
666 {
667 std::ostringstream uiWorldMapAreaIdSwaps;
668 for (PhaseShift::UiMapPhaseIdContainer::value_type const& uiWorldMapAreaIdSwap : phaseShift.UiMapPhaseIds)
669 uiWorldMapAreaIdSwaps << uiWorldMapAreaIdSwap.first << ',' << ' ';
670
671 chat->PSendSysMessage(LANG_PHASESHIFT_UI_WORLD_MAP_AREA_SWAPS, uiWorldMapAreaIdSwaps.str().c_str());
672 }
673}
674
675std::string PhasingHandler::FormatPhases(PhaseShift const& phaseShift)
676{
677 std::ostringstream phases;
678 for (PhaseShift::PhaseRef const& phase : phaseShift.Phases)
679 phases << phase.Id << ',';
680
681 return phases.str();
682}
683
685{
686 if (PhaseEntry const* phase = sPhaseStore.LookupEntry(phaseId))
687 return phase->GetFlags().HasFlag(PhaseEntryFlags::Personal);
688
689 return false;
690}
691
692void PhasingHandler::UpdateVisibilityIfNeeded(WorldObject* object, bool updateVisibility, bool changed)
693{
694 if (changed && object->IsInWorld())
695 {
696 if (Player* player = object->ToPlayer())
697 SendToPlayer(player);
698
699 if (updateVisibility)
700 {
701 if (Player* player = object->ToPlayer())
702 player->GetMap()->SendUpdateTransportVisibility(player);
703
704 object->UpdateObjectVisibility();
705 }
706 }
707}
#define sConditionMgr
Definition: ConditionMgr.h:368
@ CONDITION_SOURCE_TYPE_TERRAIN_SWAP
Definition: ConditionMgr.h:180
DB2Storage< PhaseEntry > sPhaseStore("Phase.db2", &PhaseLoadInfo::Instance)
DB2Storage< AreaTableEntry > sAreaTableStore("AreaTable.db2", &AreaTableLoadInfo::Instance)
#define sDB2Manager
Definition: DB2Stores.h:553
@ PHASE_USE_FLAGS_ALWAYS_VISIBLE
Definition: DBCEnums.h:1897
@ PHASE_USE_FLAGS_INVERSE
Definition: DBCEnums.h:1898
uint8_t uint8
Definition: Define.h:144
int32_t int32
Definition: Define.h:138
uint16_t uint16
Definition: Define.h:143
uint32_t uint32
Definition: Define.h:142
uint16 flags
Definition: DisableMgr.cpp:49
@ DISABLE_TYPE_PHASE_AREA
Definition: DisableMgr.h:36
#define ASSERT_NOTNULL(pointer)
Definition: Errors.h:84
#define ASSERT
Definition: Errors.h:68
#define MAX_NUMBER_OF_GRIDS
Definition: GridDefines.h:38
@ LANG_PHASESHIFT_STATUS
Definition: Language.h:222
@ LANG_PHASE_FLAG_PERSONAL
Definition: Language.h:227
@ LANG_PHASESHIFT_PHASES
Definition: Language.h:223
@ LANG_PHASESHIFT_UI_WORLD_MAP_AREA_SWAPS
Definition: Language.h:225
@ LANG_PHASESHIFT_VISIBLE_MAP_IDS
Definition: Language.h:224
@ LANG_PHASE_FLAG_COSMETIC
Definition: Language.h:226
@ TYPEID_PLAYER
Definition: ObjectGuid.h:43
#define sObjectMgr
Definition: ObjectMgr.h:1995
PhaseFlags
Definition: PhaseShift.h:45
#define DEFAULT_PHASE
Definition: PhaseShift.h:31
PhaseShiftFlags
Definition: PhaseShift.h:34
@ SPELL_AURA_PHASE_GROUP
@ SPELL_AURA_PHASE
virtual LocaleConstant GetSessionDbLocaleIndex() const
Definition: Chat.cpp:597
void PSendSysMessage(const char *fmt, Args &&... args)
Definition: Chat.h:57
constexpr bool HasFlag(T flag) const
Definition: EnumFlag.h:106
constexpr std::underlying_type_t< T > AsUnderlyingType() const
Definition: EnumFlag.h:122
bool IsEmpty() const
Definition: ObjectGuid.h:322
std::string ToString() const
Definition: ObjectGuid.cpp:777
static Unit * ToUnit(Object *o)
Definition: Object.h:261
bool IsInWorld() const
Definition: Object.h:190
TypeID GetTypeId() const
Definition: Object.h:209
static ObjectGuid GetGUID(Object const *o)
Definition: Object.h:195
static Player * ToPlayer(Object *o)
Definition: Object.h:249
void ClearPhases()
Definition: PhaseShift.cpp:96
EnumFlag< PhaseShiftFlags > Flags
Definition: PhaseShift.h:123
ObjectGuid PersonalGuid
Definition: PhaseShift.h:124
bool HasPhase(uint32 phaseId) const
Definition: PhaseShift.h:100
void ModifyPhasesReferences(PhaseContainer::iterator itr, int32 references)
Definition: PhaseShift.cpp:155
bool HasPersonalPhase() const
Definition: PhaseShift.cpp:197
EraseResult< PhaseContainer > RemovePhase(uint32 phaseId)
Definition: PhaseShift.cpp:38
UiMapPhaseIdContainer UiMapPhaseIds
Definition: PhaseShift.h:127
bool AddVisibleMapId(uint32 visibleMapId, TerrainSwapInfo const *visibleMapInfo, int32 references=1)
Definition: PhaseShift.cpp:51
EraseResult< UiMapPhaseIdContainer > RemoveUiMapPhaseId(uint32 uiMapPhaseId)
Definition: PhaseShift.cpp:77
bool IsDbPhaseShift
Definition: PhaseShift.h:136
PhaseContainer Phases
Definition: PhaseShift.h:125
bool AddUiMapPhaseId(uint32 uiMapPhaseId, int32 references=1)
Definition: PhaseShift.cpp:70
bool AddPhase(uint32 phaseId, PhaseFlags flags, std::vector< Condition > const *areaConditions, int32 references=1)
Definition: PhaseShift.cpp:28
int32 PersonalReferences
Definition: PhaseShift.h:134
VisibleMapIdContainer VisibleMapIds
Definition: PhaseShift.h:126
void VisitControlledOf(Unit *unit, Func &&func)
Trinity::Containers::FlatSet< WorldObject *, std::less< WorldObject * >, boost::container::small_vector< WorldObject *, 8 > > _visited
static void SetInversed(WorldObject *object, bool apply, bool updateVisibility)
static void OnAreaChange(WorldObject *object)
static void UpdateVisibilityIfNeeded(WorldObject *object, bool updateVisibility, bool changed)
static void PrintToChat(ChatHandler *chat, WorldObject const *target)
static void AddVisibleMapId(WorldObject *object, uint32 visibleMapId)
static uint32 GetTerrainMapId(PhaseShift const &phaseShift, uint32 mapId, TerrainInfo const *terrain, float x, float y)
static bool IsPersonalPhase(uint32 phaseId)
static void AddPhase(WorldObject *object, uint32 phaseId, bool updateVisibility)
static std::string FormatPhases(PhaseShift const &phaseShift)
static void AddPhaseGroup(WorldObject *object, uint32 phaseGroupId, bool updateVisibility)
static void RemoveVisibleMapId(WorldObject *object, uint32 visibleMapId)
static void FillPartyMemberPhase(WorldPackets::Party::PartyMemberPhaseStates *partyMemberPhases, PhaseShift const &phaseShift)
static void RemovePhaseGroup(WorldObject *object, uint32 phaseGroupId, bool updateVisibility)
static bool InDbPhaseShift(WorldObject const *object, uint8 phaseUseFlags, uint16 phaseId, uint32 phaseGroupId)
static void InheritPhaseShift(WorldObject *target, WorldObject const *source)
static PhaseShift const & GetAlwaysVisiblePhaseShift()
static void ResetPhaseShift(WorldObject *object)
static void RemovePhase(WorldObject *object, uint32 phaseId, bool updateVisibility)
static void OnMapChange(WorldObject *object)
static void SendToPlayer(Player const *player, PhaseShift const &phaseShift)
static void InitDbPersonalOwnership(PhaseShift &phaseShift, ObjectGuid const &personalGuid)
static bool OnConditionChange(WorldObject *object, bool updateVisibility=true)
static PhaseShift const & GetEmptyPhaseShift()
static void InitDbVisibleMapId(PhaseShift &phaseShift, int32 visibleMapId)
static void SetAlwaysVisible(WorldObject *object, bool apply, bool updateVisibility)
static void InitDbPhaseShift(PhaseShift &phaseShift, uint8 phaseUseFlags, uint16 phaseId, uint32 phaseGroupId)
bool HasChildTerrainGridFile(uint32 mapId, int32 gx, int32 gy) const
Definition: TerrainMgr.cpp:145
std::pair< iterator, bool > insert(Key const &key)
Definition: FlatSet.h:73
std::size_t erase(Key const &key)
Definition: FlatSet.h:75
Definition: Unit.h:630
Vehicle * GetVehicle() const
Definition: Unit.h:1743
AuraEffectList const & GetAuraEffectsByType(AuraType type) const
Definition: Unit.h:1332
virtual void OnPhaseChange()
Definition: Unit.cpp:12212
std::array< ObjectGuid, MAX_SUMMON_SLOT > m_SummonSlot
Definition: Unit.h:1478
ControlList m_Controlled
Definition: Unit.h:1222
Vehicle * GetVehicleKit() const
Definition: Unit.h:1741
void RemoveNotOwnSingleTargetAuras(bool onPhaseChange=false)
Definition: Unit.cpp:4088
constexpr uint32 GetMapId() const
Definition: Position.h:215
PhaseShift & GetPhaseShift()
Definition: Object.h:648
PhaseShift & GetSuppressedPhaseShift()
Definition: Object.h:650
void apply(T *val)
Definition: ByteConverter.h:41
bool IsDisabledFor(DisableType type, uint32 entry, WorldObject const *ref, uint8 flags)
Definition: DisableMgr.cpp:296
TC_GAME_API WorldObject * GetWorldObject(WorldObject const &, ObjectGuid const &)
TC_GAME_API Unit * GetUnit(WorldObject const &, ObjectGuid const &guid)
TC_GAME_API Creature * GetCreature(WorldObject const &u, ObjectGuid const &guid)
GridCoord ComputeGridCoord(float x, float y)
Definition: GridDefines.h:190
uint16 ParentAreaID
Definition: DB2Structure.h:131
uint32 x_coord
Definition: GridDefines.h:169
uint32 y_coord
Definition: GridDefines.h:170
std::vector< Condition > const * AreaConditions
Definition: PhaseShift.h:65
EnumFlag< PhaseFlags > Flags
Definition: PhaseShift.h:63
std::vector< uint32 > UiMapPhaseIDs
Definition: ObjectMgr.h:1016
std::vector< PhaseShiftDataPhase > Phases
Definition: MiscPackets.h:571
std::vector< PartyMemberPhase > List
Definition: PartyPackets.h:156