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 "MapUtils.h"
27#include "MiscPackets.h"
28#include "ObjectAccessor.h"
29#include "ObjectMgr.h"
30#include "PartyPackets.h"
31#include "PhaseShift.h"
32#include "Player.h"
33#include "SpellAuraEffects.h"
34#include "TerrainMgr.h"
35#include "Vehicle.h"
36#include <boost/container/small_vector.hpp>
37#include <sstream>
38
39namespace
40{
41PhaseShift const Empty;
43{
44 PhaseShift phaseShift;
46 return phaseShift;
47}();
48
49inline PhaseFlags GetPhaseFlags(uint32 phaseId)
50{
51 if (PhaseEntry const* phase = sPhaseStore.LookupEntry(phaseId))
52 {
53 if (phase->GetFlags().HasFlag(PhaseEntryFlags::Cosmetic))
55
56 if (phase->GetFlags().HasFlag(PhaseEntryFlags::Personal))
58 }
59
60 return PhaseFlags::None;
61}
62}
63
65{
66public:
68 {
69 _visited.insert(owner);
70 }
71
72 template<typename Func>
73 inline void VisitControlledOf(Unit* unit, Func&& func)
74 {
75 for (Unit* controlled : unit->m_Controlled)
76 if (controlled->GetTypeId() != TYPEID_PLAYER
77 && !controlled->GetVehicle()) // Player inside nested vehicle should not phase the root vehicle and its accessories (only direct root vehicle control does)
78 if (_visited.insert(controlled).second)
79 func(controlled);
80
81 for (ObjectGuid summonGuid : unit->m_SummonSlot)
82 if (!summonGuid.IsEmpty())
83 if (Creature* summon = ObjectAccessor::GetCreature(*unit, summonGuid))
84 if (_visited.insert(summon).second)
85 func(summon);
86
87 if (Vehicle const* vehicle = unit->GetVehicleKit())
88 for (auto const& [_, seat] : vehicle->Seats)
89 if (Unit* passenger = ObjectAccessor::GetUnit(*unit, seat.Passenger.Guid); passenger && passenger != unit)
90 if (_visited.insert(passenger).second)
91 func(passenger);
92 }
93
94private:
95 Trinity::Containers::FlatSet<WorldObject*, std::less<WorldObject*>, boost::container::small_vector<WorldObject*, 8>> _visited;
96};
97
98void PhasingHandler::AddPhase(WorldObject* object, uint32 phaseId, bool updateVisibility)
99{
100 ControlledUnitVisitor visitor(object);
101 AddPhase(object, phaseId, object->GetGUID(), updateVisibility, visitor);
102}
103
104void PhasingHandler::AddPhase(WorldObject* object, uint32 phaseId, ObjectGuid const& personalGuid, bool updateVisibility, ControlledUnitVisitor& visitor)
105{
106 bool changed = object->GetPhaseShift().AddPhase(phaseId, GetPhaseFlags(phaseId), nullptr);
107
108 if (object->GetPhaseShift().PersonalReferences)
109 object->GetPhaseShift().PersonalGuid = personalGuid;
110
111 if (Unit* unit = object->ToUnit())
112 {
113 unit->OnPhaseChange();
114 visitor.VisitControlledOf(unit, [&](Unit* controlled)
115 {
116 AddPhase(controlled, phaseId, personalGuid, updateVisibility, visitor);
117 });
118 unit->RemoveNotOwnSingleTargetAuras(true);
119 }
120
121 UpdateVisibilityIfNeeded(object, updateVisibility, changed);
122}
123
124void PhasingHandler::RemovePhase(WorldObject* object, uint32 phaseId, bool updateVisibility)
125{
126 ControlledUnitVisitor visitor(object);
127 RemovePhase(object, phaseId, updateVisibility, visitor);
128}
129
130void PhasingHandler::RemovePhase(WorldObject* object, uint32 phaseId, bool updateVisibility, ControlledUnitVisitor& visitor)
131{
132 bool changed = object->GetPhaseShift().RemovePhase(phaseId).Erased;
133
134 if (Unit* unit = object->ToUnit())
135 {
136 unit->OnPhaseChange();
137 visitor.VisitControlledOf(unit, [&](Unit* controlled)
138 {
139 RemovePhase(controlled, phaseId, updateVisibility, visitor);
140 });
141 unit->RemoveNotOwnSingleTargetAuras(true);
142 }
143
144 UpdateVisibilityIfNeeded(object, updateVisibility, changed);
145}
146
147void PhasingHandler::AddPhaseGroup(WorldObject* object, uint32 phaseGroupId, bool updateVisibility)
148{
149 std::vector<uint32> const* phasesInGroup = sDB2Manager.GetPhasesForGroup(phaseGroupId);
150 if (!phasesInGroup)
151 return;
152
153 ControlledUnitVisitor visitor(object);
154 AddPhaseGroup(object, phasesInGroup, object->GetGUID(), updateVisibility, visitor);
155}
156
157void PhasingHandler::AddPhaseGroup(WorldObject* object, std::vector<uint32> const* phasesInGroup, ObjectGuid const& personalGuid, bool updateVisibility, ControlledUnitVisitor& visitor)
158{
159 bool changed = false;
160 for (uint32 phaseId : *phasesInGroup)
161 changed = object->GetPhaseShift().AddPhase(phaseId, GetPhaseFlags(phaseId), nullptr) || changed;
162
163 if (object->GetPhaseShift().PersonalReferences)
164 object->GetPhaseShift().PersonalGuid = personalGuid;
165
166 if (Unit* unit = object->ToUnit())
167 {
168 unit->OnPhaseChange();
169 visitor.VisitControlledOf(unit, [&](Unit* controlled)
170 {
171 AddPhaseGroup(controlled, phasesInGroup, personalGuid, updateVisibility, visitor);
172 });
173 unit->RemoveNotOwnSingleTargetAuras(true);
174 }
175
176 UpdateVisibilityIfNeeded(object, updateVisibility, changed);
177}
178
179void PhasingHandler::RemovePhaseGroup(WorldObject* object, uint32 phaseGroupId, bool updateVisibility)
180{
181 std::vector<uint32> const* phasesInGroup = sDB2Manager.GetPhasesForGroup(phaseGroupId);
182 if (!phasesInGroup)
183 return;
184
185 ControlledUnitVisitor visitor(object);
186 RemovePhaseGroup(object, phasesInGroup, updateVisibility, visitor);
187}
188
189void PhasingHandler::RemovePhaseGroup(WorldObject* object, std::vector<uint32> const* phasesInGroup, bool updateVisibility, ControlledUnitVisitor& visitor)
190{
191 bool changed = false;
192 for (uint32 phaseId : *phasesInGroup)
193 changed = object->GetPhaseShift().RemovePhase(phaseId).Erased || changed;
194
195 if (Unit* unit = object->ToUnit())
196 {
197 unit->OnPhaseChange();
198 visitor.VisitControlledOf(unit, [&](Unit* controlled)
199 {
200 RemovePhaseGroup(controlled, phasesInGroup, updateVisibility, visitor);
201 });
202 unit->RemoveNotOwnSingleTargetAuras(true);
203 }
204
205 UpdateVisibilityIfNeeded(object, updateVisibility, changed);
206}
207
209{
210 ControlledUnitVisitor visitor(object);
211 AddVisibleMapId(object, visibleMapId, visitor);
212}
213
215{
216 TerrainSwapInfo const* terrainSwapInfo = sObjectMgr->GetTerrainSwapInfo(visibleMapId);
217 bool changed = object->GetPhaseShift().AddVisibleMapId(visibleMapId, terrainSwapInfo);
218
219 for (uint32 uiMapPhaseId : terrainSwapInfo->UiMapPhaseIDs)
220 changed = object->GetPhaseShift().AddUiMapPhaseId(uiMapPhaseId) || changed;
221
222 if (Unit* unit = object->ToUnit())
223 {
224 visitor.VisitControlledOf(unit, [&](Unit* controlled)
225 {
226 AddVisibleMapId(controlled, visibleMapId, visitor);
227 });
228 }
229
230 UpdateVisibilityIfNeeded(object, false, changed);
231}
232
234{
235 ControlledUnitVisitor visitor(object);
236 RemoveVisibleMapId(object, visibleMapId, visitor);
237}
238
240{
241 TerrainSwapInfo const* terrainSwapInfo = sObjectMgr->GetTerrainSwapInfo(visibleMapId);
242 bool changed = object->GetPhaseShift().RemoveVisibleMapId(visibleMapId).Erased;
243
244 for (uint32 uiWorldMapAreaIDSwap : terrainSwapInfo->UiMapPhaseIDs)
245 changed = object->GetPhaseShift().RemoveUiMapPhaseId(uiWorldMapAreaIDSwap).Erased || changed;
246
247 if (Unit* unit = object->ToUnit())
248 {
249 visitor.VisitControlledOf(unit, [&](Unit* controlled)
250 {
251 RemoveVisibleMapId(controlled, visibleMapId, visitor);
252 });
253 }
254
255 UpdateVisibilityIfNeeded(object, false, changed);
256}
257
259{
260 object->GetPhaseShift().Clear();
261 object->GetSuppressedPhaseShift().Clear();
262}
263
265{
266 target->GetPhaseShift() = source->GetPhaseShift();
268}
269
271{
272 PhaseShift& phaseShift = object->GetPhaseShift();
273 PhaseShift& suppressedPhaseShift = object->GetSuppressedPhaseShift();
275
276 object->GetPhaseShift().VisibleMapIds.clear();
277 object->GetPhaseShift().UiMapPhaseIds.clear();
278 object->GetSuppressedPhaseShift().VisibleMapIds.clear();
279
280 for (auto const& visibleMapPair : sObjectMgr->GetTerrainSwaps())
281 {
282 for (TerrainSwapInfo const* visibleMapInfo : visibleMapPair.second)
283 {
284 if (sConditionMgr->IsObjectMeetingNotGroupedConditions(CONDITION_SOURCE_TYPE_TERRAIN_SWAP, visibleMapInfo->Id, srcInfo))
285 {
286 if (visibleMapPair.first == object->GetMapId())
287 phaseShift.AddVisibleMapId(visibleMapInfo->Id, visibleMapInfo);
288
289 // ui map is visible on all maps
290 for (uint32 uiMapPhaseId : visibleMapInfo->UiMapPhaseIDs)
291 phaseShift.AddUiMapPhaseId(uiMapPhaseId);
292 }
293 else if (visibleMapPair.first == object->GetMapId())
294 suppressedPhaseShift.AddVisibleMapId(visibleMapInfo->Id, visibleMapInfo);
295 }
296 }
297
298 UpdateVisibilityIfNeeded(object, false, true);
299}
300
302{
303 PhaseShift& phaseShift = object->GetPhaseShift();
304 PhaseShift& suppressedPhaseShift = object->GetSuppressedPhaseShift();
305 PhaseShift::PhaseContainer oldPhases = std::move(phaseShift.Phases); // for comparison
307
308 object->GetPhaseShift().ClearPhases();
309 object->GetSuppressedPhaseShift().ClearPhases();
310
311 uint32 areaId = object->GetAreaId();
312 AreaTableEntry const* areaEntry = sAreaTableStore.LookupEntry(areaId);
313 while (areaEntry)
314 {
315 if (std::vector<PhaseAreaInfo> const* newAreaPhases = sObjectMgr->GetPhasesForArea(areaEntry->ID))
316 {
317 for (PhaseAreaInfo const& phaseArea : *newAreaPhases)
318 {
319 if (phaseArea.SubAreaExclusions.contains(areaId))
320 continue;
321
322 uint32 phaseId = phaseArea.PhaseInfo->Id;
324 continue;
325
326 if (sConditionMgr->IsObjectMeetToConditions(srcInfo, phaseArea.Conditions))
327 phaseShift.AddPhase(phaseId, GetPhaseFlags(phaseId), &phaseArea.Conditions);
328 else
329 suppressedPhaseShift.AddPhase(phaseId, GetPhaseFlags(phaseId), &phaseArea.Conditions);
330 }
331 }
332
333 areaEntry = sAreaTableStore.LookupEntry(areaEntry->ParentAreaID);
334 }
335
336 bool changed = phaseShift.Phases != oldPhases;
337 if (Unit* unit = object->ToUnit())
338 {
339 for (AuraEffect const* aurEff : unit->GetAuraEffectsByType(SPELL_AURA_PHASE))
340 {
341 uint32 phaseId = uint32(aurEff->GetMiscValueB());
342 changed = phaseShift.AddPhase(phaseId, GetPhaseFlags(phaseId), nullptr) || changed;
343 }
344
345 for (AuraEffect const* aurEff : unit->GetAuraEffectsByType(SPELL_AURA_PHASE_GROUP))
346 if (std::vector<uint32> const* phasesInGroup = sDB2Manager.GetPhasesForGroup(uint32(aurEff->GetMiscValueB())))
347 for (uint32 phaseId : *phasesInGroup)
348 changed = phaseShift.AddPhase(phaseId, GetPhaseFlags(phaseId), nullptr) || changed;
349
350 if (phaseShift.PersonalReferences)
351 phaseShift.PersonalGuid = unit->GetGUID();
352
353 if (changed)
354 unit->OnPhaseChange();
355
356 ControlledUnitVisitor visitor(unit);
357 visitor.VisitControlledOf(unit, [&](Unit* controlled)
358 {
359 InheritPhaseShift(controlled, unit);
360 });
361
362 if (changed)
363 unit->RemoveNotOwnSingleTargetAuras(true);
364 }
365 else
366 {
367 if (phaseShift.PersonalReferences)
368 phaseShift.PersonalGuid = object->GetGUID();
369 }
370
371 UpdateVisibilityIfNeeded(object, true, changed);
372}
373
374bool PhasingHandler::OnConditionChange(WorldObject* object, bool updateVisibility /*= true*/)
375{
376 PhaseShift& phaseShift = object->GetPhaseShift();
377 PhaseShift& suppressedPhaseShift = object->GetSuppressedPhaseShift();
378 PhaseShift newSuppressions;
380 bool changed = false;
381
382 for (auto itr = phaseShift.Phases.begin(); itr != phaseShift.Phases.end();)
383 {
384 if (itr->AreaConditions && !sConditionMgr->IsObjectMeetToConditions(srcInfo, *itr->AreaConditions))
385 {
386 newSuppressions.AddPhase(itr->Id, itr->Flags, itr->AreaConditions, itr->References);
387 phaseShift.ModifyPhasesReferences(itr, -itr->References);
388 itr = phaseShift.Phases.erase(itr);
389 }
390 else
391 ++itr;
392 }
393
394 for (auto itr = suppressedPhaseShift.Phases.begin(); itr != suppressedPhaseShift.Phases.end();)
395 {
396 if (!DisableMgr::IsDisabledFor(DISABLE_TYPE_PHASE_AREA, itr->Id, object) && sConditionMgr->IsObjectMeetToConditions(srcInfo, *ASSERT_NOTNULL(itr->AreaConditions)))
397 {
398 changed = phaseShift.AddPhase(itr->Id, itr->Flags, itr->AreaConditions, itr->References) || changed;
399 suppressedPhaseShift.ModifyPhasesReferences(itr, -itr->References);
400 itr = suppressedPhaseShift.Phases.erase(itr);
401 }
402 else
403 ++itr;
404 }
405
406 for (auto itr = phaseShift.VisibleMapIds.begin(); itr != phaseShift.VisibleMapIds.end();)
407 {
408 if (!sConditionMgr->IsObjectMeetingNotGroupedConditions(CONDITION_SOURCE_TYPE_TERRAIN_SWAP, itr->first, srcInfo))
409 {
410 newSuppressions.AddVisibleMapId(itr->first, itr->second.VisibleMapInfo, itr->second.References);
411 for (uint32 uiMapPhaseId : itr->second.VisibleMapInfo->UiMapPhaseIDs)
412 changed = phaseShift.RemoveUiMapPhaseId(uiMapPhaseId).Erased || changed;
413
414 itr = phaseShift.VisibleMapIds.erase(itr);
415 }
416 else
417 ++itr;
418 }
419
420 for (auto itr = suppressedPhaseShift.VisibleMapIds.begin(); itr != suppressedPhaseShift.VisibleMapIds.end();)
421 {
422 if (sConditionMgr->IsObjectMeetingNotGroupedConditions(CONDITION_SOURCE_TYPE_TERRAIN_SWAP, itr->first, srcInfo))
423 {
424 changed = phaseShift.AddVisibleMapId(itr->first, itr->second.VisibleMapInfo, itr->second.References) || changed;
425 for (uint32 uiMapPhaseId : itr->second.VisibleMapInfo->UiMapPhaseIDs)
426 changed = phaseShift.AddUiMapPhaseId(uiMapPhaseId) || changed;
427
428 itr = suppressedPhaseShift.VisibleMapIds.erase(itr);
429 }
430 else
431 ++itr;
432 }
433
434 Unit* unit = object->ToUnit();
435 if (unit)
436 {
437 for (AuraEffect const* aurEff : unit->GetAuraEffectsByType(SPELL_AURA_PHASE))
438 {
439 uint32 phaseId = uint32(aurEff->GetMiscValueB());
440 auto eraseResult = newSuppressions.RemovePhase(phaseId);
441 // if condition was met previously there is nothing to erase
442 if (eraseResult.Iterator != newSuppressions.Phases.end() || eraseResult.Erased)
443 phaseShift.AddPhase(phaseId, GetPhaseFlags(phaseId), nullptr);
444 }
445
446 for (AuraEffect const* aurEff : unit->GetAuraEffectsByType(SPELL_AURA_PHASE_GROUP))
447 {
448 if (std::vector<uint32> const* phasesInGroup = sDB2Manager.GetPhasesForGroup(uint32(aurEff->GetMiscValueB())))
449 {
450 for (uint32 phaseId : *phasesInGroup)
451 {
452 auto eraseResult = newSuppressions.RemovePhase(phaseId);
453 // if condition was met previously there is nothing to erase
454 if (eraseResult.Iterator != newSuppressions.Phases.end() || eraseResult.Erased)
455 phaseShift.AddPhase(phaseId, GetPhaseFlags(phaseId), nullptr);
456 }
457 }
458 }
459 }
460
461 if (phaseShift.PersonalReferences)
462 phaseShift.PersonalGuid = object->GetGUID();
463
464 changed = changed || !newSuppressions.Phases.empty() || !newSuppressions.VisibleMapIds.empty();
465 for (PhaseShift::PhaseRef const& phaseRef : newSuppressions.Phases)
466 suppressedPhaseShift.AddPhase(phaseRef.Id, phaseRef.Flags, phaseRef.AreaConditions, phaseRef.References);
467
468 for (std::pair<uint32 const, PhaseShift::VisibleMapIdRef> const& visibleMap : newSuppressions.VisibleMapIds)
469 suppressedPhaseShift.AddVisibleMapId(visibleMap.first, visibleMap.second.VisibleMapInfo, visibleMap.second.References);
470
471 if (unit)
472 {
473 if (changed)
474 unit->OnPhaseChange();
475
476 ControlledUnitVisitor visitor(unit);
477 visitor.VisitControlledOf(unit, [&](Unit* controlled)
478 {
479 InheritPhaseShift(controlled, unit);
480 });
481
482 if (changed)
484 }
485
486 UpdateVisibilityIfNeeded(object, updateVisibility, changed);
487 return changed;
488}
489
490void PhasingHandler::SendToPlayer(Player const* player, PhaseShift const& phaseShift)
491{
493 phaseShiftChange.Client = player->GetGUID();
494 phaseShiftChange.Phaseshift.PhaseShiftFlags = phaseShift.Flags.AsUnderlyingType();
495 phaseShiftChange.Phaseshift.PersonalGUID = phaseShift.PersonalGuid;
496
497 phaseShiftChange.Phaseshift.Phases.resize(phaseShift.Phases.size());
498 std::ranges::transform(phaseShift.Phases, phaseShiftChange.Phaseshift.Phases.begin(),
499 [](PhaseShift::PhaseRef const& phase) { return WorldPackets::Misc::PhaseShiftDataPhase{ .PhaseFlags = phase.Flags.AsUnderlyingType(), .Id = phase.Id }; });
500
501 phaseShiftChange.VisibleMapIDs.resize(phaseShift.VisibleMapIds.size());
502 std::ranges::transform(phaseShift.VisibleMapIds, phaseShiftChange.VisibleMapIDs.begin(), Trinity::Containers::MapKey);
503
504 phaseShiftChange.UiMapPhaseIDs.resize(phaseShift.UiMapPhaseIds.size());
505 std::ranges::transform(phaseShift.UiMapPhaseIds, phaseShiftChange.UiMapPhaseIDs.begin(), Trinity::Containers::MapKey);
506
507 player->SendDirectMessage(phaseShiftChange.Write());
508}
509
511{
512 SendToPlayer(player, player->GetPhaseShift());
513}
514
516{
517 partyMemberPhases->PhaseShiftFlags = phaseShift.Flags.AsUnderlyingType();
518 partyMemberPhases->PersonalGUID = phaseShift.PersonalGuid;
519 partyMemberPhases->List.resize(phaseShift.Phases.size());
520 std::ranges::transform(phaseShift.Phases, partyMemberPhases->List.begin(),
521 [](PhaseShift::PhaseRef const& phase) { return WorldPackets::Party::PartyMemberPhase{ .Flags = phase.Flags.AsUnderlyingType(), .Id = phase.Id }; });
522}
523
525{
526 return Empty;
527}
528
530{
531 return AlwaysVisible;
532}
533
534void PhasingHandler::InitDbPhaseShift(PhaseShift& phaseShift, uint8 phaseUseFlags, uint16 phaseId, uint32 phaseGroupId)
535{
536 phaseShift.ClearPhases();
537 phaseShift.IsDbPhaseShift = true;
538
540 if (phaseUseFlags & PHASE_USE_FLAGS_ALWAYS_VISIBLE)
542 if (phaseUseFlags & PHASE_USE_FLAGS_INVERSE)
544
545 if (phaseId)
546 phaseShift.AddPhase(phaseId, GetPhaseFlags(phaseId), nullptr);
547 else if (phaseGroupId)
548 if (std::vector<uint32> const* phasesInGroup = sDB2Manager.GetPhasesForGroup(phaseGroupId))
549 for (uint32 phaseInGroup : *phasesInGroup)
550 phaseShift.AddPhase(phaseInGroup, GetPhaseFlags(phaseInGroup), nullptr);
551
552 if (phaseShift.Phases.empty() || phaseShift.HasPhase(DEFAULT_PHASE))
553 {
554 if (flags.HasFlag(PhaseShiftFlags::Inverse))
556 else
558 }
559
560 phaseShift.Flags = flags;
561}
562
564{
565 ASSERT(phaseShift.IsDbPhaseShift);
566 ASSERT(phaseShift.HasPersonalPhase());
567 phaseShift.PersonalGuid = personalGuid;
568}
569
571{
572 phaseShift.VisibleMapIds.clear();
573 if (visibleMapId != -1)
574 phaseShift.AddVisibleMapId(visibleMapId, sObjectMgr->GetTerrainSwapInfo(visibleMapId));
575}
576
577bool PhasingHandler::InDbPhaseShift(WorldObject const* object, uint8 phaseUseFlags, uint16 phaseId, uint32 phaseGroupId)
578{
579 PhaseShift phaseShift;
580 InitDbPhaseShift(phaseShift, phaseUseFlags, phaseId, phaseGroupId);
581 return object->GetPhaseShift().CanSee(phaseShift);
582}
583
584uint32 PhasingHandler::GetTerrainMapId(PhaseShift const& phaseShift, uint32 mapId, TerrainInfo const* terrain, float x, float y)
585{
586 if (phaseShift.VisibleMapIds.empty())
587 return mapId;
588
589 if (phaseShift.VisibleMapIds.size() == 1)
590 return phaseShift.VisibleMapIds.begin()->first;
591
592 GridCoord gridCoord = Trinity::ComputeGridCoord(x, y);
593 int32 gx = (MAX_NUMBER_OF_GRIDS - 1) - gridCoord.x_coord;
594 int32 gy = (MAX_NUMBER_OF_GRIDS - 1) - gridCoord.y_coord;
595
596 for (std::pair<uint32 const, PhaseShift::VisibleMapIdRef> const& visibleMap : phaseShift.VisibleMapIds)
597 if (terrain->HasChildTerrainGridFile(visibleMap.first, gx, gy))
598 return visibleMap.first;
599
600 return mapId;
601}
602
603void PhasingHandler::SetAlwaysVisible(WorldObject* object, bool apply, bool updateVisibility)
604{
605 if (apply)
606 object->GetPhaseShift().Flags |= PhaseShiftFlags::AlwaysVisible;
607 else
608 object->GetPhaseShift().Flags &= ~PhaseShiftFlags::AlwaysVisible;
609
610 UpdateVisibilityIfNeeded(object, updateVisibility, true);
611}
612
613void PhasingHandler::SetInversed(WorldObject* object, bool apply, bool updateVisibility)
614{
615 if (apply)
616 object->GetPhaseShift().Flags |= PhaseShiftFlags::Inverse;
617 else
618 object->GetPhaseShift().Flags &= PhaseShiftFlags::Inverse;
619
620 object->GetPhaseShift().UpdateUnphasedFlag();
621
622 UpdateVisibilityIfNeeded(object, updateVisibility, true);
623}
624
626{
627 PhaseShift const& phaseShift = target->GetPhaseShift();
628
629 std::string phaseOwnerName = "N/A";
630 if (phaseShift.HasPersonalPhase())
631 if (WorldObject* personalGuid = ObjectAccessor::GetWorldObject(*target, phaseShift.PersonalGuid))
632 phaseOwnerName = personalGuid->GetName();
633
635 phaseShift.PersonalGuid.ToString().c_str(), phaseOwnerName.c_str());
636
637 if (!phaseShift.Phases.empty())
638 {
639 std::ostringstream phases;
640 std::string cosmetic = sObjectMgr->GetTrinityString(LANG_PHASE_FLAG_COSMETIC, chat->GetSessionDbLocaleIndex());
641 std::string personal = sObjectMgr->GetTrinityString(LANG_PHASE_FLAG_PERSONAL, chat->GetSessionDbLocaleIndex());
642 for (PhaseShift::PhaseRef const& phase : phaseShift.Phases)
643 {
644 phases << "\r\n";
645 phases << ' ' << ' ' << ' ';
646 phases << phase.Id << ' ' << '(' << sObjectMgr->GetPhaseName(phase.Id) << ')';
648 phases << ' ' << '(' << cosmetic << ')';
650 phases << ' ' << '(' << personal << ')';
652 phases << " (Disabled)";
653 }
654
655 chat->PSendSysMessage(LANG_PHASESHIFT_PHASES, phases.str().c_str());
656 }
657
658 if (!phaseShift.VisibleMapIds.empty())
659 {
660 std::ostringstream visibleMapIds;
661 for (PhaseShift::VisibleMapIdContainer::value_type const& visibleMapId : phaseShift.VisibleMapIds)
662 visibleMapIds << visibleMapId.first << ',' << ' ';
663
664 chat->PSendSysMessage(LANG_PHASESHIFT_VISIBLE_MAP_IDS, visibleMapIds.str().c_str());
665 }
666
667 if (!phaseShift.UiMapPhaseIds.empty())
668 {
669 std::ostringstream uiWorldMapAreaIdSwaps;
670 for (PhaseShift::UiMapPhaseIdContainer::value_type const& uiWorldMapAreaIdSwap : phaseShift.UiMapPhaseIds)
671 uiWorldMapAreaIdSwaps << uiWorldMapAreaIdSwap.first << ',' << ' ';
672
673 chat->PSendSysMessage(LANG_PHASESHIFT_UI_WORLD_MAP_AREA_SWAPS, uiWorldMapAreaIdSwaps.str().c_str());
674 }
675}
676
677std::string PhasingHandler::FormatPhases(PhaseShift const& phaseShift)
678{
679 std::ostringstream phases;
680 for (PhaseShift::PhaseRef const& phase : phaseShift.Phases)
681 phases << phase.Id << ',';
682
683 return std::move(phases).str();
684}
685
687{
688 if (PhaseEntry const* phase = sPhaseStore.LookupEntry(phaseId))
689 return phase->GetFlags().HasFlag(PhaseEntryFlags::Personal);
690
691 return false;
692}
693
694void PhasingHandler::UpdateVisibilityIfNeeded(WorldObject* object, bool updateVisibility, bool changed)
695{
696 if (changed && object->IsInWorld())
697 {
698 if (Player* player = object->ToPlayer())
699 SendToPlayer(player);
700
701 if (updateVisibility)
702 {
703 if (Player* player = object->ToPlayer())
704 player->GetMap()->SendUpdateTransportVisibility(player);
705
706 object->UpdateObjectVisibility();
707 }
708 }
709}
#define sConditionMgr
Definition: ConditionMgr.h:374
@ 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:557
@ PHASE_USE_FLAGS_ALWAYS_VISIBLE
Definition: DBCEnums.h:1927
@ PHASE_USE_FLAGS_INVERSE
Definition: DBCEnums.h:1928
uint8_t uint8
Definition: Define.h:150
int32_t int32
Definition: Define.h:144
uint16_t uint16
Definition: Define.h:149
uint32_t uint32
Definition: Define.h:148
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:1985
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:592
void PSendSysMessage(char const *fmt, Args &&... args)
Definition: Chat.h:61
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:755
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:632
Vehicle * GetVehicle() const
Definition: Unit.h:1764
AuraEffectList const & GetAuraEffectsByType(AuraType type) const
Definition: Unit.h:1334
virtual void OnPhaseChange()
Definition: Unit.cpp:12237
std::array< ObjectGuid, MAX_SUMMON_SLOT > m_SummonSlot
Definition: Unit.h:1492
ControlList m_Controlled
Definition: Unit.h:1224
Vehicle * GetVehicleKit() const
Definition: Unit.h:1762
void RemoveNotOwnSingleTargetAuras(bool onPhaseChange=false)
Definition: Unit.cpp:4106
constexpr uint32 GetMapId() const
Definition: Position.h:215
PhaseShift & GetPhaseShift()
Definition: Object.h:672
PhaseShift & GetSuppressedPhaseShift()
Definition: Object.h:674
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)
constexpr auto MapKey
Definition: MapUtils.h:72
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:1006
std::vector< PhaseShiftDataPhase > Phases
Definition: MiscPackets.h:575
std::vector< PartyMemberPhase > List
Definition: PartyPackets.h:163