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