diff options
author | Meji <alvaro.megias@outlook.com> | 2023-12-30 17:14:09 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-12-30 17:14:09 +0100 |
commit | 37eb2e64a6ad075e9866af6feb72bb4fbccb2adc (patch) | |
tree | 664b202a458f43fa73815fb40d39e1cae85debca /src | |
parent | dbe54dc877416367c5d6297893fcefd269d2b031 (diff) |
Core/AreaTriggers: Refactor (#29500)
* Moved IsServerside to custom flags
* Flags moved from areatrigger_template to areatrigger_create_properties
* New field to create custom CreateProperties (IsCustom)
* New field to reference custom areatriggers (IsAreatriggerCustom)
* Moved fields for shape data to areatrigger_create_properties
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/AI/SmartScripts/SmartScript.cpp | 8 | ||||
-rw-r--r-- | src/server/game/AI/SmartScripts/SmartScriptMgr.cpp | 8 | ||||
-rw-r--r-- | src/server/game/AI/SmartScripts/SmartScriptMgr.h | 28 | ||||
-rw-r--r-- | src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp | 2 | ||||
-rw-r--r-- | src/server/game/Entities/AreaTrigger/AreaTrigger.cpp | 233 | ||||
-rw-r--r-- | src/server/game/Entities/AreaTrigger/AreaTrigger.h | 9 | ||||
-rw-r--r-- | src/server/game/Entities/AreaTrigger/AreaTriggerTemplate.cpp | 54 | ||||
-rw-r--r-- | src/server/game/Entities/AreaTrigger/AreaTriggerTemplate.h | 103 | ||||
-rw-r--r-- | src/server/game/Entities/Object/Object.cpp | 25 | ||||
-rw-r--r-- | src/server/game/Globals/AreaTriggerDataStore.cpp | 244 | ||||
-rw-r--r-- | src/server/game/Globals/AreaTriggerDataStore.h | 4 | ||||
-rw-r--r-- | src/server/game/Miscellaneous/Language.h | 4 | ||||
-rw-r--r-- | src/server/game/Spells/Auras/SpellAuraEffects.cpp | 3 | ||||
-rw-r--r-- | src/server/game/Spells/SpellEffects.cpp | 3 |
14 files changed, 367 insertions, 361 deletions
diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp index 9433a4b8761..b3c7be43c7a 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.cpp +++ b/src/server/game/AI/SmartScripts/SmartScript.cpp @@ -3794,7 +3794,7 @@ void SmartScript::OnUpdate(uint32 const diff) if ((mScriptType == SMART_SCRIPT_TYPE_CREATURE || mScriptType == SMART_SCRIPT_TYPE_GAMEOBJECT || mScriptType == SMART_SCRIPT_TYPE_AREATRIGGER_ENTITY - || mScriptType == SMART_SCRIPT_TYPE_AREATRIGGER_ENTITY_SERVERSIDE) + || mScriptType == SMART_SCRIPT_TYPE_AREATRIGGER_ENTITY_CUSTOM) && !GetBaseObject()) return; @@ -3975,7 +3975,7 @@ void SmartScript::GetScript() FillScript(std::move(e), go, nullptr, nullptr, nullptr, 0); break; case SMART_SCRIPT_TYPE_AREATRIGGER_ENTITY: - case SMART_SCRIPT_TYPE_AREATRIGGER_ENTITY_SERVERSIDE: + case SMART_SCRIPT_TYPE_AREATRIGGER_ENTITY_CUSTOM: e = sSmartScriptMgr->GetScript((int32)areaTrigger->GetEntry(), mScriptType); FillScript(std::move(e), areaTrigger, nullptr, nullptr, nullptr, 0); break; @@ -4086,8 +4086,8 @@ void SmartScript::OnInitialize(WorldObject* obj, AreaTriggerEntry const* at, Sce break; case TYPEID_AREATRIGGER: areaTrigger = obj->ToAreaTrigger(); - mScriptType = areaTrigger->IsServerSide() ? SMART_SCRIPT_TYPE_AREATRIGGER_ENTITY_SERVERSIDE : SMART_SCRIPT_TYPE_AREATRIGGER_ENTITY; - TC_LOG_DEBUG("scripts.ai", "SmartScript::OnInitialize: source is AreaTrigger {}, IsServerSide {}", areaTrigger->GetEntry(), uint32(areaTrigger->IsServerSide())); + mScriptType = areaTrigger->IsCustom() ? SMART_SCRIPT_TYPE_AREATRIGGER_ENTITY_CUSTOM : SMART_SCRIPT_TYPE_AREATRIGGER_ENTITY; + TC_LOG_DEBUG("scripts.ai", "SmartScript::OnInitialize: source is AreaTrigger {}, IsCustom {}", areaTrigger->GetEntry(), uint32(areaTrigger->IsCustom())); break; default: TC_LOG_ERROR("misc", "SmartScript::OnInitialize: Unhandled TypeID !WARNING!"); diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp index 10c3914d9a7..2aa5a25e129 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp @@ -176,11 +176,11 @@ void SmartAIMgr::LoadSmartAIFromDB() } break; } - case SMART_SCRIPT_TYPE_AREATRIGGER_ENTITY_SERVERSIDE: + case SMART_SCRIPT_TYPE_AREATRIGGER_ENTITY_CUSTOM: { if (!sAreaTriggerDataStore->GetAreaTriggerTemplate({ (uint32)temp.entryOrGuid, true })) { - TC_LOG_ERROR("sql.sql", "SmartAIMgr::LoadSmartAIFromDB: AreaTrigger entry ({} IsServerSide true) does not exist, skipped loading.", uint32(temp.entryOrGuid)); + TC_LOG_ERROR("sql.sql", "SmartAIMgr::LoadSmartAIFromDB: AreaTrigger entry ({} IsCustom true) does not exist, skipped loading.", uint32(temp.entryOrGuid)); continue; } break; @@ -1318,9 +1318,9 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e) } case SMART_EVENT_AREATRIGGER_ONTRIGGER: { - if (e.event.areatrigger.id && (e.GetScriptType() == SMART_SCRIPT_TYPE_AREATRIGGER_ENTITY || e.GetScriptType() == SMART_SCRIPT_TYPE_AREATRIGGER_ENTITY_SERVERSIDE)) + if (e.event.areatrigger.id && (e.GetScriptType() == SMART_SCRIPT_TYPE_AREATRIGGER_ENTITY || e.GetScriptType() == SMART_SCRIPT_TYPE_AREATRIGGER_ENTITY_CUSTOM)) { - TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry {} SourceType {} Event {} Action {} areatrigger param not supported for SMART_SCRIPT_TYPE_AREATRIGGER_ENTITY and SMART_SCRIPT_TYPE_AREATRIGGER_ENTITY_SERVERSIDE, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType()); + TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry {} SourceType {} Event {} Action {} areatrigger param not supported for SMART_SCRIPT_TYPE_AREATRIGGER_ENTITY and SMART_SCRIPT_TYPE_AREATRIGGER_ENTITY_CUSTOM, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType()); return false; } if (e.event.areatrigger.id && !IsAreaTriggerValid(e, e.event.areatrigger.id)) diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.h b/src/server/game/AI/SmartScripts/SmartScriptMgr.h index 0409ec84385..904c21544ab 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.h +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.h @@ -1458,7 +1458,7 @@ enum SmartScriptType SMART_SCRIPT_TYPE_TIMED_ACTIONLIST = 9, SMART_SCRIPT_TYPE_SCENE = 10, SMART_SCRIPT_TYPE_AREATRIGGER_ENTITY = 11, - SMART_SCRIPT_TYPE_AREATRIGGER_ENTITY_SERVERSIDE = 12, + SMART_SCRIPT_TYPE_AREATRIGGER_ENTITY_CUSTOM = 12, SMART_SCRIPT_TYPE_MAX }; @@ -1480,19 +1480,19 @@ enum SmartAITypeMaskId const uint32 SmartAITypeMask[SMART_SCRIPT_TYPE_MAX][2] = { - {SMART_SCRIPT_TYPE_CREATURE, SMART_SCRIPT_TYPE_MASK_CREATURE }, - {SMART_SCRIPT_TYPE_GAMEOBJECT, SMART_SCRIPT_TYPE_MASK_GAMEOBJECT }, - {SMART_SCRIPT_TYPE_AREATRIGGER, SMART_SCRIPT_TYPE_MASK_AREATRIGGER }, - {SMART_SCRIPT_TYPE_EVENT, SMART_SCRIPT_TYPE_MASK_EVENT }, - {SMART_SCRIPT_TYPE_GOSSIP, SMART_SCRIPT_TYPE_MASK_GOSSIP }, - {SMART_SCRIPT_TYPE_QUEST, SMART_SCRIPT_TYPE_MASK_QUEST }, - {SMART_SCRIPT_TYPE_SPELL, SMART_SCRIPT_TYPE_MASK_SPELL }, - {SMART_SCRIPT_TYPE_TRANSPORT, SMART_SCRIPT_TYPE_MASK_TRANSPORT }, - {SMART_SCRIPT_TYPE_INSTANCE, SMART_SCRIPT_TYPE_MASK_INSTANCE }, - {SMART_SCRIPT_TYPE_TIMED_ACTIONLIST, SMART_SCRIPT_TYPE_MASK_TIMED_ACTIONLIST }, - {SMART_SCRIPT_TYPE_SCENE, SMART_SCRIPT_TYPE_MASK_SCENE }, - {SMART_SCRIPT_TYPE_AREATRIGGER_ENTITY, SMART_SCRIPT_TYPE_MASK_AREATRIGGER_ENTITY }, - {SMART_SCRIPT_TYPE_AREATRIGGER_ENTITY_SERVERSIDE, SMART_SCRIPT_TYPE_MASK_AREATRIGGER_ENTITY } + {SMART_SCRIPT_TYPE_CREATURE, SMART_SCRIPT_TYPE_MASK_CREATURE }, + {SMART_SCRIPT_TYPE_GAMEOBJECT, SMART_SCRIPT_TYPE_MASK_GAMEOBJECT }, + {SMART_SCRIPT_TYPE_AREATRIGGER, SMART_SCRIPT_TYPE_MASK_AREATRIGGER }, + {SMART_SCRIPT_TYPE_EVENT, SMART_SCRIPT_TYPE_MASK_EVENT }, + {SMART_SCRIPT_TYPE_GOSSIP, SMART_SCRIPT_TYPE_MASK_GOSSIP }, + {SMART_SCRIPT_TYPE_QUEST, SMART_SCRIPT_TYPE_MASK_QUEST }, + {SMART_SCRIPT_TYPE_SPELL, SMART_SCRIPT_TYPE_MASK_SPELL }, + {SMART_SCRIPT_TYPE_TRANSPORT, SMART_SCRIPT_TYPE_MASK_TRANSPORT }, + {SMART_SCRIPT_TYPE_INSTANCE, SMART_SCRIPT_TYPE_MASK_INSTANCE }, + {SMART_SCRIPT_TYPE_TIMED_ACTIONLIST, SMART_SCRIPT_TYPE_MASK_TIMED_ACTIONLIST }, + {SMART_SCRIPT_TYPE_SCENE, SMART_SCRIPT_TYPE_MASK_SCENE }, + {SMART_SCRIPT_TYPE_AREATRIGGER_ENTITY, SMART_SCRIPT_TYPE_MASK_AREATRIGGER_ENTITY }, + {SMART_SCRIPT_TYPE_AREATRIGGER_ENTITY_CUSTOM, SMART_SCRIPT_TYPE_MASK_AREATRIGGER_ENTITY } }; const uint32 SmartAIEventMask[SMART_EVENT_END][2] = diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp index c7d2e026c51..22cb9ce841c 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp +++ b/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp @@ -357,7 +357,7 @@ void BattlegroundWS::OnGameObjectCreate(GameObject* gameObject) void BattlegroundWS::OnAreaTriggerCreate(AreaTrigger* areaTrigger) { - if (!areaTrigger->IsServerSide()) + if (!areaTrigger->IsStaticSpawn()) return; switch (areaTrigger->GetEntry()) diff --git a/src/server/game/Entities/AreaTrigger/AreaTrigger.cpp b/src/server/game/Entities/AreaTrigger/AreaTrigger.cpp index 0af01e062a7..d99e005a76d 100644 --- a/src/server/game/Entities/AreaTrigger/AreaTrigger.cpp +++ b/src/server/game/Entities/AreaTrigger/AreaTrigger.cpp @@ -95,30 +95,30 @@ void AreaTrigger::RemoveFromWorld() WorldObject::RemoveFromWorld(); - if (_spawnId) + if (IsStaticSpawn()) Trinity::Containers::MultimapErasePair(GetMap()->GetAreaTriggerBySpawnIdStore(), _spawnId, this); GetMap()->GetObjectsStore().Remove<AreaTrigger>(GetGUID()); } } -bool AreaTrigger::Create(uint32 areaTriggerCreatePropertiesId, Unit* caster, Unit* target, SpellInfo const* spellInfo, Position const& pos, int32 duration, SpellCastVisual spellVisual, Spell* spell, AuraEffect const* aurEff) +bool AreaTrigger::Create(AreaTriggerCreatePropertiesId areaTriggerCreatePropertiesId, Map* map, Position const& pos, int32 duration, AreaTriggerSpawn const* spawnData /* nullptr */, Unit* caster /*= nullptr*/, Unit* target /*= nullptr*/, SpellCastVisual spellVisual /*= { 0, 0 }*/, SpellInfo const* spellInfo /*= nullptr*/, Spell* spell /*= nullptr*/, AuraEffect const* aurEff /*= nullptr*/) { _targetGuid = target ? target->GetGUID() : ObjectGuid::Empty; _aurEff = aurEff; - SetMap(caster->GetMap()); + SetMap(map); Relocate(pos); RelocateStationaryPosition(pos); if (!IsPositionValid()) { - TC_LOG_ERROR("entities.areatrigger", "AreaTrigger (areaTriggerCreatePropertiesId {}) not created. Invalid coordinates (X: {} Y: {})", areaTriggerCreatePropertiesId, GetPositionX(), GetPositionY()); + TC_LOG_ERROR("entities.areatrigger", "AreaTrigger (AreaTriggerCreatePropertiesId: (Id: {}, IsCustom: {})) not created. Invalid coordinates (X: {} Y: {})", areaTriggerCreatePropertiesId.Id, uint32(areaTriggerCreatePropertiesId.IsCustom), GetPositionX(), GetPositionY()); return false; } _areaTriggerCreateProperties = sAreaTriggerDataStore->GetAreaTriggerCreateProperties(areaTriggerCreatePropertiesId); if (!_areaTriggerCreateProperties) { - TC_LOG_ERROR("entities.areatrigger", "AreaTrigger (areaTriggerCreatePropertiesId {}) not created. Invalid areatrigger create properties id ({})", areaTriggerCreatePropertiesId, areaTriggerCreatePropertiesId); + TC_LOG_ERROR("entities.areatrigger", "AreaTrigger (AreaTriggerCreatePropertiesId: (Id: {}, IsCustom: {})) not created. Invalid areatrigger create properties id", areaTriggerCreatePropertiesId.Id, uint32(areaTriggerCreatePropertiesId.IsCustom)); return false; } @@ -126,59 +126,71 @@ bool AreaTrigger::Create(uint32 areaTriggerCreatePropertiesId, Unit* caster, Uni _areaTriggerTemplate = _areaTriggerCreateProperties->Template; - Object::_Create(ObjectGuid::Create<HighGuid::AreaTrigger>(GetMapId(), GetTemplate() ? GetTemplate()->Id.Id : 0, caster->GetMap()->GenerateLowGuid<HighGuid::AreaTrigger>())); + Object::_Create(ObjectGuid::Create<HighGuid::AreaTrigger>(GetMapId(), GetTemplate() ? GetTemplate()->Id.Id : 0, GetMap()->GenerateLowGuid<HighGuid::AreaTrigger>())); if (GetTemplate()) SetEntry(GetTemplate()->Id.Id); - SetDuration(duration); - SetObjectScale(1.0f); + SetDuration(duration); _shape = GetCreateProperties()->Shape; auto areaTriggerData = m_values.ModifyValue(&AreaTrigger::m_areaTriggerData); - SetUpdateFieldValue(areaTriggerData.ModifyValue(&UF::AreaTriggerData::Caster), caster->GetGUID()); + if (caster) + SetUpdateFieldValue(areaTriggerData.ModifyValue(&UF::AreaTriggerData::Caster), caster->GetGUID()); if (spell) SetUpdateFieldValue(areaTriggerData.ModifyValue(&UF::AreaTriggerData::CreatingEffectGUID), spell->m_castId); - - SetUpdateFieldValue(areaTriggerData.ModifyValue(&UF::AreaTriggerData::SpellID), spellInfo->Id); - SetUpdateFieldValue(areaTriggerData.ModifyValue(&UF::AreaTriggerData::SpellForVisuals), spellInfo->Id); + if (spellInfo && !IsStaticSpawn()) + SetUpdateFieldValue(areaTriggerData.ModifyValue(&UF::AreaTriggerData::SpellID), spellInfo->Id); + if (spellInfo) + SetUpdateFieldValue(areaTriggerData.ModifyValue(&UF::AreaTriggerData::SpellForVisuals), spellInfo->Id); SetUpdateFieldValue(areaTriggerData.ModifyValue(&UF::AreaTriggerData::SpellVisual).ModifyValue(&UF::SpellCastVisual::SpellXSpellVisualID), spellVisual.SpellXSpellVisualID); SetUpdateFieldValue(areaTriggerData.ModifyValue(&UF::AreaTriggerData::SpellVisual).ModifyValue(&UF::SpellCastVisual::ScriptVisualID), spellVisual.ScriptVisualID); - SetUpdateFieldValue(areaTriggerData.ModifyValue(&UF::AreaTriggerData::TimeToTargetScale), GetCreateProperties()->TimeToTargetScale != 0 ? GetCreateProperties()->TimeToTargetScale : *m_areaTriggerData->Duration); - SetUpdateFieldValue(areaTriggerData.ModifyValue(&UF::AreaTriggerData::BoundsRadius2D), GetCreateProperties()->GetMaxSearchRadius()); + if (!IsStaticSpawn()) + SetUpdateFieldValue(areaTriggerData.ModifyValue(&UF::AreaTriggerData::TimeToTargetScale), GetCreateProperties()->TimeToTargetScale != 0 ? GetCreateProperties()->TimeToTargetScale : *m_areaTriggerData->Duration); + SetUpdateFieldValue(areaTriggerData.ModifyValue(&UF::AreaTriggerData::BoundsRadius2D), GetCreateProperties()->Shape.GetMaxSearchRadius()); SetUpdateFieldValue(areaTriggerData.ModifyValue(&UF::AreaTriggerData::DecalPropertiesID), GetCreateProperties()->DecalPropertiesId); + if (IsServerSide()) + SetUpdateFieldValue(areaTriggerData.ModifyValue(&UF::AreaTriggerData::DecalPropertiesID), 24); // Blue decal, for .debug areatrigger visibility - SetScaleCurve(areaTriggerData.ModifyValue(&UF::AreaTriggerData::ExtraScaleCurve), GetCreateProperties()->ExtraScale); + AreaTriggerScaleCurveTemplate const extraScaleCurve = IsStaticSpawn() ? AreaTriggerScaleCurveTemplate() : *GetCreateProperties()->ExtraScale; + SetScaleCurve(areaTriggerData.ModifyValue(&UF::AreaTriggerData::ExtraScaleCurve), extraScaleCurve); - if (Player const* modOwner = caster->GetSpellModOwner()) + if (caster) { - float multiplier = 1.0f; - int32 flat = 0; - modOwner->GetSpellModValues(spellInfo, SpellModOp::Radius, spell, *m_areaTriggerData->BoundsRadius2D, &flat, &multiplier); - if (multiplier != 1.0f) + if (Player const* modOwner = caster->GetSpellModOwner()) { - AreaTriggerScaleCurveTemplate overrideScale; - overrideScale.Curve = multiplier; - SetScaleCurve(areaTriggerData.ModifyValue(&UF::AreaTriggerData::OverrideScaleCurve), overrideScale); + float multiplier = 1.0f; + int32 flat = 0; + modOwner->GetSpellModValues(spellInfo, SpellModOp::Radius, spell, *m_areaTriggerData->BoundsRadius2D, &flat, &multiplier); + if (multiplier != 1.0f) + { + AreaTriggerScaleCurveTemplate overrideScale; + overrideScale.Curve = multiplier; + SetScaleCurve(areaTriggerData.ModifyValue(&UF::AreaTriggerData::OverrideScaleCurve), overrideScale); + } } } SetUpdateFieldValue(areaTriggerData.ModifyValue(&UF::AreaTriggerData::VisualAnim).ModifyValue(&UF::VisualAnim::AnimationDataID), GetCreateProperties()->AnimId); SetUpdateFieldValue(areaTriggerData.ModifyValue(&UF::AreaTriggerData::VisualAnim).ModifyValue(&UF::VisualAnim::AnimKitID), GetCreateProperties()->AnimKitId); - if (GetTemplate() && GetTemplate()->HasFlag(AREATRIGGER_FLAG_UNK3)) + if (GetCreateProperties() && GetCreateProperties()->Flags.HasFlag(AreaTriggerCreatePropertiesFlag::Unk3)) SetUpdateFieldValue(areaTriggerData.ModifyValue(&UF::AreaTriggerData::VisualAnim).ModifyValue(&UF::VisualAnim::Field_C), true); - PhasingHandler::InheritPhaseShift(this, caster); - - if (target && GetTemplate() && GetTemplate()->HasFlag(AREATRIGGER_FLAG_HAS_ATTACHED)) + if (caster) + PhasingHandler::InheritPhaseShift(this, caster); + else if (IsStaticSpawn() && spawnData) { - m_movementInfo.transport.guid = target->GetGUID(); + if (spawnData->phaseUseFlags || spawnData->phaseId || spawnData->phaseGroup) + PhasingHandler::InitDbPhaseShift(GetPhaseShift(), spawnData->phaseUseFlags, spawnData->phaseId, spawnData->phaseGroup); } - UpdatePositionData(); - SetZoneScript(); + if (target && GetCreateProperties() && GetCreateProperties()->Flags.HasFlag(AreaTriggerCreatePropertiesFlag::HasAttached)) + m_movementInfo.transport.guid = target->GetGUID(); + + if (!IsStaticSpawn()) + UpdatePositionData(); UpdateShape(); @@ -187,7 +199,7 @@ bool AreaTrigger::Create(uint32 areaTriggerCreatePropertiesId, Unit* caster, Uni if (GetCreateProperties()->OrbitInfo) { AreaTriggerOrbitInfo orbit = *GetCreateProperties()->OrbitInfo; - if (target && GetTemplate() && GetTemplate()->HasFlag(AREATRIGGER_FLAG_HAS_ATTACHED)) + if (target && GetCreateProperties() && GetCreateProperties()->Flags.HasFlag(AreaTriggerCreatePropertiesFlag::HasAttached)) orbit.PathTarget = target->GetGUID(); else orbit.Center = pos; @@ -200,16 +212,20 @@ bool AreaTrigger::Create(uint32 areaTriggerCreatePropertiesId, Unit* caster, Uni } // movement on transport of areatriggers on unit is handled by themself - TransportBase* transport = m_movementInfo.transport.guid.IsEmpty() ? caster->GetTransport() : nullptr; - if (transport) + TransportBase* transport = nullptr; + if (caster) { - float x, y, z, o; - pos.GetPosition(x, y, z, o); - transport->CalculatePassengerOffset(x, y, z, &o); - m_movementInfo.transport.pos.Relocate(x, y, z, o); + transport = m_movementInfo.transport.guid.IsEmpty() ? caster->GetTransport() : nullptr; + if (transport) + { + float x, y, z, o; + pos.GetPosition(x, y, z, o); + transport->CalculatePassengerOffset(x, y, z, &o); + m_movementInfo.transport.pos.Relocate(x, y, z, o); - // This object must be added to transport before adding to map for the client to properly display it - transport->AddPassenger(this); + // This object must be added to transport before adding to map for the client to properly display it + transport->AddPassenger(this); + } } AI_Initialize(); @@ -218,25 +234,29 @@ bool AreaTrigger::Create(uint32 areaTriggerCreatePropertiesId, Unit* caster, Uni if (HasOrbit()) Relocate(CalculateOrbitPosition()); - if (!GetMap()->AddToMap(this)) + if (!IsStaticSpawn()) { - // Returning false will cause the object to be deleted - remove from transport - if (transport) - transport->RemovePassenger(this); - return false; + if (!GetMap()->AddToMap(this)) + { + // Returning false will cause the object to be deleted - remove from transport + if (transport) + transport->RemovePassenger(this); + return false; + } } - caster->_RegisterAreaTrigger(this); + if (caster) + caster->_RegisterAreaTrigger(this); - _ai->OnCreate(spell); + _ai->OnCreate(spell ? spell : nullptr); return true; } -AreaTrigger* AreaTrigger::CreateAreaTrigger(uint32 areaTriggerCreatePropertiesId, Unit* caster, Unit* target, SpellInfo const* spellInfo, Position const& pos, int32 duration, SpellCastVisual spellVisual, Spell* spell /*= nullptr*/, AuraEffect const* aurEff /*= nullptr*/) +AreaTrigger* AreaTrigger::CreateAreaTrigger(AreaTriggerCreatePropertiesId areaTriggerCreatePropertiesId, Position const& pos, int32 duration, Unit * caster, Unit * target, SpellCastVisual spellVisual /*= { 0, 0 }*/, SpellInfo const* spellInfo /*= nullptr*/, Spell* spell /*= nullptr*/, AuraEffect const* aurEff /*= nullptr*/) { AreaTrigger* at = new AreaTrigger(); - if (!at->Create(areaTriggerCreatePropertiesId, caster, target, spellInfo, pos, duration, spellVisual, spell, aurEff)) + if (!at->Create(areaTriggerCreatePropertiesId, caster->GetMap(), pos, duration, nullptr, caster, target, spellVisual, spellInfo, spell, aurEff)) { delete at; return nullptr; @@ -254,69 +274,25 @@ bool AreaTrigger::LoadFromDB(ObjectGuid::LowType spawnId, Map* map, bool /*addTo { _spawnId = spawnId; - AreaTriggerSpawn const* position = sAreaTriggerDataStore->GetAreaTriggerSpawn(spawnId); - if (!position) + AreaTriggerSpawn const* spawnData = sAreaTriggerDataStore->GetAreaTriggerSpawn(spawnId); + if (!spawnData) return false; - AreaTriggerTemplate const* areaTriggerTemplate = sAreaTriggerDataStore->GetAreaTriggerTemplate(position->Id); - if (!areaTriggerTemplate) + AreaTriggerCreateProperties const* createProperties = sAreaTriggerDataStore->GetAreaTriggerCreateProperties(spawnData->Id); + if (!createProperties) return false; - return CreateServer(map, areaTriggerTemplate, *position); -} - -bool AreaTrigger::CreateServer(Map* map, AreaTriggerTemplate const* areaTriggerTemplate, AreaTriggerSpawn const& position) -{ - SetMap(map); - Relocate(position.spawnPoint); - RelocateStationaryPosition(position.spawnPoint); - if (!IsPositionValid()) + SpellInfo const* spellInfo = nullptr; + SpellCastVisual spellVisual; + if (spawnData->SpellForVisuals) { - TC_LOG_ERROR("entities.areatrigger", "AreaTriggerServer (id {}) not created. Invalid coordinates (X: {} Y: {})", - areaTriggerTemplate->Id.Id, GetPositionX(), GetPositionY()); - return false; - } - - SetZoneScript(); - - _areaTriggerTemplate = areaTriggerTemplate; - - Object::_Create(ObjectGuid::Create<HighGuid::AreaTrigger>(GetMapId(), areaTriggerTemplate->Id.Id, GetMap()->GenerateLowGuid<HighGuid::AreaTrigger>())); + spellInfo = sSpellMgr->GetSpellInfo(*spawnData->SpellForVisuals, DIFFICULTY_NONE); - SetEntry(areaTriggerTemplate->Id.Id); - - SetObjectScale(1.0f); - SetDuration(-1); - - _shape = position.Shape; - - auto areaTriggerData = m_values.ModifyValue(&AreaTrigger::m_areaTriggerData); - if (position.SpellForVisuals) - { - SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(*position.SpellForVisuals, DIFFICULTY_NONE); - SetUpdateFieldValue(areaTriggerData.ModifyValue(&UF::AreaTriggerData::SpellForVisuals), *position.SpellForVisuals); - SetUpdateFieldValue(areaTriggerData.ModifyValue(&UF::AreaTriggerData::SpellVisual).ModifyValue(&UF::SpellCastVisual::SpellXSpellVisualID), spellInfo->GetSpellXSpellVisualId()); - SetUpdateFieldValue(areaTriggerData.ModifyValue(&UF::AreaTriggerData::SpellVisual).ModifyValue(&UF::SpellCastVisual::ScriptVisualID), 0); + if (spellInfo) + spellVisual.SpellXSpellVisualID = spellInfo->GetSpellXSpellVisualId(); } - SetUpdateFieldValue(areaTriggerData.ModifyValue(&UF::AreaTriggerData::BoundsRadius2D), _shape.GetMaxSearchRadius()); - if (IsServerSide()) - SetUpdateFieldValue(areaTriggerData.ModifyValue(&UF::AreaTriggerData::DecalPropertiesID), 24); // blue decal, for .debug areatrigger visibility - - SetScaleCurve(areaTriggerData.ModifyValue(&UF::AreaTriggerData::ExtraScaleCurve), AreaTriggerScaleCurveTemplate()); - - SetUpdateFieldValue(areaTriggerData.ModifyValue(&UF::AreaTriggerData::VisualAnim).ModifyValue(&UF::VisualAnim::AnimationDataID), -1); - - if (position.phaseUseFlags || position.phaseId || position.phaseGroup) - PhasingHandler::InitDbPhaseShift(GetPhaseShift(), position.phaseUseFlags, position.phaseId, position.phaseGroup); - - UpdateShape(); - - AI_Initialize(); - - _ai->OnCreate(nullptr); - - return true; + return Create(spawnData->Id, map, spawnData->spawnPoint, -1, spawnData, nullptr, nullptr, spellVisual, spellInfo); } void AreaTrigger::Update(uint32 diff) @@ -324,7 +300,7 @@ void AreaTrigger::Update(uint32 diff) WorldObject::Update(diff); _timeSinceCreated += diff; - if (!IsServerSide()) + if (!IsStaticSpawn()) { // "If" order matter here, Orbit > Attached > Splines if (HasOverridePosition()) @@ -335,7 +311,7 @@ void AreaTrigger::Update(uint32 diff) { UpdateOrbitPosition(diff); } - else if (GetTemplate() && GetTemplate()->HasFlag(AREATRIGGER_FLAG_HAS_ATTACHED)) + else if (GetCreateProperties() && GetCreateProperties()->Flags.HasFlag(AreaTriggerCreatePropertiesFlag::HasAttached)) { if (Unit* target = GetTarget()) { @@ -344,7 +320,7 @@ void AreaTrigger::Update(uint32 diff) if (createProperties->FacingCurveId) orientation = sDB2Manager.GetCurveValueAt(createProperties->FacingCurveId, GetProgress()); - if (!GetTemplate() || !GetTemplate()->HasFlag(AREATRIGGER_FLAG_HAS_ABSOLUTE_ORIENTATION)) + if (!GetCreateProperties() || !GetCreateProperties()->Flags.HasFlag(AreaTriggerCreatePropertiesFlag::HasAbsoluteOrientation)) orientation += target->GetOrientation(); GetMap()->AreaTriggerRelocation(this, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), orientation); @@ -361,7 +337,7 @@ void AreaTrigger::Update(uint32 diff) if (createProperties->FacingCurveId) { float orientation = sDB2Manager.GetCurveValueAt(createProperties->FacingCurveId, GetProgress()); - if (!GetTemplate() || !GetTemplate()->HasFlag(AREATRIGGER_FLAG_HAS_ABSOLUTE_ORIENTATION)) + if (!GetCreateProperties() || !GetCreateProperties()->Flags.HasFlag(AreaTriggerCreatePropertiesFlag::HasAbsoluteOrientation)) orientation += GetStationaryO(); SetOrientation(orientation); @@ -618,22 +594,22 @@ void AreaTrigger::UpdateTargetList() switch (_shape.Type) { - case AREATRIGGER_TYPE_SPHERE: + case AreaTriggerShapeType::Sphere: SearchUnitInSphere(targetList); break; - case AREATRIGGER_TYPE_BOX: + case AreaTriggerShapeType::Box: SearchUnitInBox(targetList); break; - case AREATRIGGER_TYPE_POLYGON: + case AreaTriggerShapeType::Polygon: SearchUnitInPolygon(targetList); break; - case AREATRIGGER_TYPE_CYLINDER: + case AreaTriggerShapeType::Cylinder: SearchUnitInCylinder(targetList); break; - case AREATRIGGER_TYPE_DISK: + case AreaTriggerShapeType::Disk: SearchUnitInDisk(targetList); break; - case AREATRIGGER_TYPE_BOUNDED_PLANE: + case AreaTriggerShapeType::BoundedPlane: SearchUnitInBoundedPlane(targetList); break; default: @@ -642,7 +618,7 @@ void AreaTrigger::UpdateTargetList() if (GetTemplate()) { - if (ConditionContainer const* conditions = sConditionMgr->GetConditionsForAreaTrigger(GetTemplate()->Id.Id, GetTemplate()->Id.IsServerSide)) + if (ConditionContainer const* conditions = sConditionMgr->GetConditionsForAreaTrigger(GetTemplate()->Id.Id, GetTemplate()->Id.IsCustom)) { Trinity::Containers::EraseIf(targetList, [conditions](Unit const* target) { @@ -657,7 +633,7 @@ void AreaTrigger::UpdateTargetList() void AreaTrigger::SearchUnits(std::vector<Unit*>& targetList, float radius, bool check3D) { Trinity::AnyUnitInObjectRangeCheck check(this, radius, check3D); - if (IsServerSide()) + if (IsStaticSpawn()) { Trinity::PlayerListSearcher<Trinity::AnyUnitInObjectRangeCheck> searcher(this, targetList, check); Cell::VisitWorldObjects(this, searcher, GetMaxSearchRadius()); @@ -816,7 +792,7 @@ void AreaTrigger::HandleUnitEnterExit(std::vector<Unit*> const& newTargetList) if (Player* player = unit->ToPlayer()) { if (player->isDebugAreaTriggers) - ChatHandler(player->GetSession()).PSendSysMessage(LANG_DEBUG_AREATRIGGER_ENTERED, GetEntry()); + ChatHandler(player->GetSession()).PSendSysMessage(LANG_DEBUG_AREATRIGGER_ENTITY_ENTERED, GetEntry(), IsCustom(), IsStaticSpawn(), GetGUID().GetCounter()); player->UpdateQuestObjectiveProgress(QUEST_OBJECTIVE_AREA_TRIGGER_ENTER, GetEntry(), 1); } @@ -833,7 +809,7 @@ void AreaTrigger::HandleUnitEnterExit(std::vector<Unit*> const& newTargetList) if (Player* player = leavingUnit->ToPlayer()) { if (player->isDebugAreaTriggers) - ChatHandler(player->GetSession()).PSendSysMessage(LANG_DEBUG_AREATRIGGER_LEFT, GetEntry()); + ChatHandler(player->GetSession()).PSendSysMessage(LANG_DEBUG_AREATRIGGER_ENTITY_LEFT, GetEntry(), IsCustom(), IsStaticSpawn(), GetGUID().GetCounter()); player->UpdateQuestObjectiveProgress(QUEST_OBJECTIVE_AREA_TRIGGER_EXIT, GetEntry(), 1); } @@ -891,14 +867,15 @@ float AreaTrigger::GetMaxSearchRadius() const void AreaTrigger::UpdatePolygonVertices() { AreaTriggerCreateProperties const* createProperties = GetCreateProperties(); + AreaTriggerShapeInfo const& shape = GetShape(); float newOrientation = GetOrientation(); // No need to recalculate, orientation didn't change - if (G3D::fuzzyEq(_verticesUpdatePreviousOrientation, newOrientation) && (!createProperties || createProperties->PolygonVerticesTarget.empty())) + if (G3D::fuzzyEq(_verticesUpdatePreviousOrientation, newOrientation) && shape.PolygonVerticesTarget.empty()) return; - _polygonVertices.assign(createProperties->PolygonVertices.begin(), createProperties->PolygonVertices.end()); - if (!createProperties->PolygonVerticesTarget.empty()) + _polygonVertices.assign(shape.PolygonVertices.begin(), shape.PolygonVertices.end()); + if (!shape.PolygonVerticesTarget.empty()) { float progress = GetProgress(); if (createProperties->MorphCurveId) @@ -907,7 +884,7 @@ void AreaTrigger::UpdatePolygonVertices() for (std::size_t i = 0; i < _polygonVertices.size(); ++i) { Position& vertex = _polygonVertices[i]; - Position const& vertexTarget = createProperties->PolygonVerticesTarget[i].Pos; + Position const& vertexTarget = shape.PolygonVerticesTarget[i].Pos; vertex.m_positionX = G3D::lerp(vertex.GetPositionX(), vertexTarget.GetPositionX(), progress); vertex.m_positionY = G3D::lerp(vertex.GetPositionY(), vertexTarget.GetPositionY(), progress); @@ -1044,13 +1021,13 @@ bool UnitFitToActionRequirement(Unit* unit, Unit* caster, AreaTriggerAction cons void AreaTrigger::DoActions(Unit* unit) { - Unit* caster = IsServerSide() ? unit : GetCaster(); + Unit* caster = IsStaticSpawn() ? unit : GetCaster(); if (caster && GetTemplate()) { for (AreaTriggerAction const& action : GetTemplate()->Actions) { - if (IsServerSide() || UnitFitToActionRequirement(unit, caster, action)) + if (IsStaticSpawn() || UnitFitToActionRequirement(unit, caster, action)) { switch (action.ActionType) { @@ -1252,7 +1229,7 @@ Position AreaTrigger::CalculateOrbitPosition() const if (createProperties && createProperties->FacingCurveId) orientation = sDB2Manager.GetCurveValueAt(createProperties->FacingCurveId, GetProgress()); - if (!GetTemplate() || !GetTemplate()->HasFlag(AREATRIGGER_FLAG_HAS_ABSOLUTE_ORIENTATION)) + if (!GetCreateProperties() || !GetCreateProperties()->Flags.HasFlag(AreaTriggerCreatePropertiesFlag::HasAbsoluteOrientation)) { orientation += angle; orientation += cmi.CounterClockwise ? float(M_PI_4) : -float(M_PI_4); @@ -1310,8 +1287,8 @@ void AreaTrigger::UpdateSplinePosition(uint32 diff) float progress = sDB2Manager.GetCurveValueAt(createProperties->MoveCurveId, currentTimePercent); if (progress < 0.f || progress > 1.f) { - TC_LOG_ERROR("entities.areatrigger", "AreaTrigger (Id: {}, AreaTriggerCreatePropertiesId: {}) has wrong progress ({}) caused by curve calculation (MoveCurveId: {})", - GetEntry(), createProperties->Id, progress, createProperties->MoveCurveId); + TC_LOG_ERROR("entities.areatrigger", "AreaTrigger (Id: {}, AreaTriggerCreatePropertiesId: (Id: {}, IsCustom: {})) has wrong progress ({}) caused by curve calculation (MoveCurveId: {})", + GetEntry(), createProperties->Id.Id, uint32(createProperties->Id.IsCustom), progress, createProperties->MoveCurveId); } else currentTimePercent = progress; @@ -1328,7 +1305,7 @@ void AreaTrigger::UpdateSplinePosition(uint32 diff) if (createProperties && createProperties->FacingCurveId) orientation += sDB2Manager.GetCurveValueAt(createProperties->FacingCurveId, GetProgress()); - if (GetTemplate() && !GetTemplate()->HasFlag(AREATRIGGER_FLAG_HAS_ABSOLUTE_ORIENTATION) && GetTemplate()->HasFlag(AREATRIGGER_FLAG_HAS_FACE_MOVEMENT_DIR)) + if (GetCreateProperties() && !GetCreateProperties()->Flags.HasFlag(AreaTriggerCreatePropertiesFlag::HasAbsoluteOrientation) && GetCreateProperties()->Flags.HasFlag(AreaTriggerCreatePropertiesFlag::HasFaceMovementDir)) { G3D::Vector3 derivative; _spline->evaluate_derivative(lastPositionIndex, percentFromLastPoint, derivative); @@ -1362,7 +1339,7 @@ void AreaTrigger::UpdateOverridePosition() if (createProperties->FacingCurveId) { orientation = sDB2Manager.GetCurveValueAt(createProperties->FacingCurveId, GetProgress()); - if (!GetTemplate() || !GetTemplate()->HasFlag(AREATRIGGER_FLAG_HAS_ABSOLUTE_ORIENTATION)) + if (!GetCreateProperties() || !GetCreateProperties()->Flags.HasFlag(AreaTriggerCreatePropertiesFlag::HasAbsoluteOrientation)) orientation += GetStationaryO(); } } diff --git a/src/server/game/Entities/AreaTrigger/AreaTrigger.h b/src/server/game/Entities/AreaTrigger/AreaTrigger.h index 0d03f845cdf..5d49ba798eb 100644 --- a/src/server/game/Entities/AreaTrigger/AreaTrigger.h +++ b/src/server/game/Entities/AreaTrigger/AreaTrigger.h @@ -73,7 +73,9 @@ class TC_GAME_API AreaTrigger : public WorldObject, public GridObject<AreaTrigge AreaTriggerAI* AI() { return _ai.get(); } - bool IsServerSide() const { return _areaTriggerTemplate->Id.IsServerSide; } + bool IsCustom() const { return _areaTriggerTemplate->Id.IsCustom; } + bool IsServerSide() const { return _areaTriggerTemplate->Flags.HasFlag(AreaTriggerFlag::IsServerSide); } + bool IsStaticSpawn() const { return _spawnId != 0; } bool IsNeverVisibleFor(WorldObject const* seer, bool allowServersideObjects = false) const override; @@ -84,11 +86,10 @@ class TC_GAME_API AreaTrigger : public WorldObject, public GridObject<AreaTrigge void RelocateStationaryPosition(Position const& pos) { _stationaryPosition.Relocate(pos); } private: - bool Create(uint32 areaTriggerCreatePropertiesId, Unit* caster, Unit* target, SpellInfo const* spellInfo, Position const& pos, int32 duration, SpellCastVisual spellVisual, Spell* spell, AuraEffect const* aurEff); - bool CreateServer(Map* map, AreaTriggerTemplate const* areaTriggerTemplate, AreaTriggerSpawn const& position); + bool Create(AreaTriggerCreatePropertiesId areaTriggerCreatePropertiesId, Map* map, Position const& pos, int32 duration, AreaTriggerSpawn const* spawnData = nullptr, Unit* caster = nullptr, Unit* target = nullptr, SpellCastVisual spellVisual = { 0, 0 }, SpellInfo const* spellInfo = nullptr, Spell* spell = nullptr, AuraEffect const* aurEff = nullptr); public: - static AreaTrigger* CreateAreaTrigger(uint32 areaTriggerCreatePropertiesId, Unit* caster, Unit* target, SpellInfo const* spellInfo, Position const& pos, int32 duration, SpellCastVisual spellVisual, Spell* spell = nullptr, AuraEffect const* aurEff = nullptr); + static AreaTrigger* CreateAreaTrigger(AreaTriggerCreatePropertiesId areaTriggerCreatePropertiesId, Position const& pos, int32 duration, Unit* caster, Unit* target, SpellCastVisual spellVisual = { 0, 0 }, SpellInfo const* spellInfo = nullptr, Spell* spell = nullptr, AuraEffect const* aurEff = nullptr); static ObjectGuid CreateNewMovementForceId(Map* map, uint32 areaTriggerId); bool LoadFromDB(ObjectGuid::LowType spawnId, Map* map, bool addToMap, bool allowDuplicate); diff --git a/src/server/game/Entities/AreaTrigger/AreaTriggerTemplate.cpp b/src/server/game/Entities/AreaTrigger/AreaTriggerTemplate.cpp index 906d48437f7..769a3a4033c 100644 --- a/src/server/game/Entities/AreaTrigger/AreaTriggerTemplate.cpp +++ b/src/server/game/Entities/AreaTrigger/AreaTriggerTemplate.cpp @@ -31,7 +31,7 @@ AreaTriggerScaleCurveTemplate::AreaTriggerScaleCurveTemplate() : StartTimeOffset AreaTriggerShapeInfo::AreaTriggerShapeInfo() { - Type = AREATRIGGER_TYPE_MAX; + Type = AreaTriggerShapeType::Max; memset(DefaultDatas.Data, 0, sizeof(DefaultDatas.Data)); } @@ -39,17 +39,30 @@ float AreaTriggerShapeInfo::GetMaxSearchRadius() const { switch (Type) { - case AREATRIGGER_TYPE_SPHERE: + case AreaTriggerShapeType::Sphere: return std::max(SphereDatas.Radius, SphereDatas.RadiusTarget); - case AREATRIGGER_TYPE_BOX: + case AreaTriggerShapeType::Box: return std::sqrt(std::max( BoxDatas.Extents[0] * BoxDatas.Extents[0] + BoxDatas.Extents[1] * BoxDatas.Extents[1], BoxDatas.ExtentsTarget[0] * BoxDatas.ExtentsTarget[0] + BoxDatas.ExtentsTarget[1] * BoxDatas.ExtentsTarget[1])); - case AREATRIGGER_TYPE_CYLINDER: + case AreaTriggerShapeType::Polygon: + { + Position center(0.0f, 0.0f); + float maxSearchRadius = 0.0f; + + for (TaggedPosition<Position::XY> const& vertex : PolygonVertices) + maxSearchRadius = std::max(maxSearchRadius, center.GetExactDist2d(vertex)); + + for (TaggedPosition<Position::XY> const& vertex : PolygonVerticesTarget) + maxSearchRadius = std::max(maxSearchRadius, center.GetExactDist2d(vertex)); + + return maxSearchRadius; + } + case AreaTriggerShapeType::Cylinder: return std::max(CylinderDatas.Radius, CylinderDatas.RadiusTarget); - case AREATRIGGER_TYPE_DISK: + case AreaTriggerShapeType::Disk: return std::max(DiskDatas.OuterRadius, DiskDatas.OuterRadiusTarget); - case AREATRIGGER_TYPE_BOUNDED_PLANE: + case AreaTriggerShapeType::BoundedPlane: return std::sqrt(std::max( BoundedPlaneDatas.Extents[0] * BoundedPlaneDatas.Extents[0] / 4 + BoundedPlaneDatas.Extents[1] * BoundedPlaneDatas.Extents[1] / 4, BoundedPlaneDatas.ExtentsTarget[0] * BoundedPlaneDatas.ExtentsTarget[0] / 4 + BoundedPlaneDatas.ExtentsTarget[1] * BoundedPlaneDatas.ExtentsTarget[1] / 4)); @@ -60,17 +73,17 @@ float AreaTriggerShapeInfo::GetMaxSearchRadius() const return 0.0f; } -AreaTriggerTemplate::AreaTriggerTemplate() +AreaTriggerTemplate::AreaTriggerTemplate() : Flags(AreaTriggerFlag::None) { Id = { 0, false }; - Flags = 0; } AreaTriggerTemplate::~AreaTriggerTemplate() = default; -AreaTriggerCreateProperties::AreaTriggerCreateProperties() +AreaTriggerCreateProperties::AreaTriggerCreateProperties() : Flags(AreaTriggerCreatePropertiesFlag::None) { - Id = 0; + Id = { 0, false }; + Template = nullptr; MoveCurveId = 0; ScaleCurveId = 0; @@ -87,8 +100,6 @@ AreaTriggerCreateProperties::AreaTriggerCreateProperties() ExtraScale.emplace(); - Template = nullptr; - ScriptId = 0; } @@ -98,22 +109,3 @@ bool AreaTriggerCreateProperties::HasSplines() const { return SplinePoints.size() >= 2; } - -float AreaTriggerCreateProperties::GetMaxSearchRadius() const -{ - if (Shape.Type == AREATRIGGER_TYPE_POLYGON) - { - Position center(0.0f, 0.0f); - float maxSearchRadius = 0.0f; - - for (TaggedPosition<Position::XY> const& vertex : PolygonVertices) - maxSearchRadius = std::max(maxSearchRadius, center.GetExactDist2d(vertex)); - - for (TaggedPosition<Position::XY> const& vertex : PolygonVerticesTarget) - maxSearchRadius = std::max(maxSearchRadius, center.GetExactDist2d(vertex)); - - return maxSearchRadius; - } - - return Shape.GetMaxSearchRadius(); -} diff --git a/src/server/game/Entities/AreaTrigger/AreaTriggerTemplate.h b/src/server/game/Entities/AreaTrigger/AreaTriggerTemplate.h index 735a6413e48..c6e3f4f67eb 100644 --- a/src/server/game/Entities/AreaTrigger/AreaTriggerTemplate.h +++ b/src/server/game/Entities/AreaTrigger/AreaTriggerTemplate.h @@ -19,6 +19,7 @@ #define TRINITYCORE_AREATRIGGER_TEMPLATE_H #include "Define.h" +#include "EnumFlag.h" #include "ObjectGuid.h" #include "Optional.h" #include "SpawnData.h" @@ -28,32 +29,24 @@ #define MAX_AREATRIGGER_ENTITY_DATA 8 #define MAX_AREATRIGGER_SCALE 7 -enum AreaTriggerFlags +enum class AreaTriggerFlag : uint32 { - AREATRIGGER_FLAG_HAS_ABSOLUTE_ORIENTATION = 0x00001, - AREATRIGGER_FLAG_HAS_DYNAMIC_SHAPE = 0x00002, // Implemented for Spheres & Disks - AREATRIGGER_FLAG_HAS_ATTACHED = 0x00004, - AREATRIGGER_FLAG_HAS_FACE_MOVEMENT_DIR = 0x00008, - AREATRIGGER_FLAG_HAS_FOLLOWS_TERRAIN = 0x00010, // NYI - AREATRIGGER_FLAG_UNK1 = 0x00020, - AREATRIGGER_FLAG_HAS_TARGET_ROLL_PITCH_YAW = 0x00040, // NYI - AREATRIGGER_FLAG_HAS_ANIM_ID = 0x00080, // DEPRECATED - AREATRIGGER_FLAG_UNK3 = 0x00100, - AREATRIGGER_FLAG_HAS_ANIM_KIT_ID = 0x00200, // DEPRECATED - AREATRIGGER_FLAG_HAS_CIRCULAR_MOVEMENT = 0x00400, // DEPRECATED - AREATRIGGER_FLAG_UNK5 = 0x00800, + None = 0x00, + IsServerSide = 0x01 }; -enum AreaTriggerTypes +DEFINE_ENUM_FLAG(AreaTriggerFlag); + +enum class AreaTriggerShapeType : uint8 { - AREATRIGGER_TYPE_SPHERE = 0, - AREATRIGGER_TYPE_BOX = 1, - AREATRIGGER_TYPE_UNK = 2, - AREATRIGGER_TYPE_POLYGON = 3, - AREATRIGGER_TYPE_CYLINDER = 4, - AREATRIGGER_TYPE_DISK = 5, - AREATRIGGER_TYPE_BOUNDED_PLANE = 6, - AREATRIGGER_TYPE_MAX + Sphere = 0, + Box = 1, + Unk = 2, + Polygon = 3, + Cylinder = 4, + Disk = 5, + BoundedPlane = 6, + Max }; enum AreaTriggerActionTypes @@ -75,14 +68,35 @@ enum AreaTriggerActionUserTypes AREATRIGGER_ACTION_USER_MAX = 6 }; +enum class AreaTriggerCreatePropertiesFlag : uint32 +{ + None = 0x00000, + HasAbsoluteOrientation = 0x00001, + HasDynamicShape = 0x00002, + HasAttached = 0x00004, + HasFaceMovementDir = 0x00008, + HasFollowsTerrain = 0x00010, // NYI + Unk1 = 0x00020, + HasTargetRollPitchYaw = 0x00040, // NYI + HasAnimId = 0x00080, // DEPRECATED + Unk3 = 0x00100, + HasAnimKitId = 0x00200, // DEPRECATED + HasCircularMovement = 0x00400, // DEPRECATED + Unk5 = 0x00800, +}; + +DEFINE_ENUM_FLAG(AreaTriggerCreatePropertiesFlag); + struct AreaTriggerId { uint32 Id = 0; - bool IsServerSide = false; + bool IsCustom = false; friend bool operator==(AreaTriggerId const& left, AreaTriggerId const& right) = default; }; +typedef AreaTriggerId AreaTriggerCreatePropertiesId; + struct AreaTriggerAction { uint32 Param; @@ -110,15 +124,18 @@ struct AreaTriggerShapeInfo { AreaTriggerShapeInfo(); - bool IsSphere() const { return Type == AREATRIGGER_TYPE_SPHERE; } - bool IsBox() const { return Type == AREATRIGGER_TYPE_BOX; } - bool IsPolygon() const { return Type == AREATRIGGER_TYPE_POLYGON; } - bool IsCylinder() const { return Type == AREATRIGGER_TYPE_CYLINDER; } - bool IsDisk() const { return Type == AREATRIGGER_TYPE_DISK; } - bool IsBoudedPlane() const { return Type == AREATRIGGER_TYPE_BOUNDED_PLANE; } + bool IsSphere() const { return Type == AreaTriggerShapeType::Sphere; } + bool IsBox() const { return Type == AreaTriggerShapeType::Box; } + bool IsPolygon() const { return Type == AreaTriggerShapeType::Polygon; } + bool IsCylinder() const { return Type == AreaTriggerShapeType::Cylinder; } + bool IsDisk() const { return Type == AreaTriggerShapeType::Disk; } + bool IsBoundedPlane() const { return Type == AreaTriggerShapeType::BoundedPlane; } float GetMaxSearchRadius() const; - AreaTriggerTypes Type; + AreaTriggerShapeType Type; + + std::vector<TaggedPosition<Position::XY>> PolygonVertices; + std::vector<TaggedPosition<Position::XY>> PolygonVerticesTarget; union { @@ -127,28 +144,28 @@ struct AreaTriggerShapeInfo float Data[MAX_AREATRIGGER_ENTITY_DATA]; } DefaultDatas; - // AREATRIGGER_TYPE_SPHERE + // AreaTriggerShapeType::Sphere struct { float Radius; float RadiusTarget; } SphereDatas; - // AREATRIGGER_TYPE_BOX + // AreaTriggerShapeType::Box struct { float Extents[3]; float ExtentsTarget[3]; } BoxDatas; - // AREATRIGGER_TYPE_POLYGON + // AreaTriggerShapeType::Polygon struct { float Height; float HeightTarget; } PolygonDatas; - // AREATRIGGER_TYPE_CYLINDER + // AreaTriggerShapeType::Cylinder struct { float Radius; @@ -159,7 +176,7 @@ struct AreaTriggerShapeInfo float LocationZOffsetTarget; } CylinderDatas; - // AREATRIGGER_TYPE_DISK + // AreaTriggerShapeType::Disk struct { float InnerRadius; @@ -172,7 +189,7 @@ struct AreaTriggerShapeInfo float LocationZOffsetTarget; } DiskDatas; - // AREATRIGGER_TYPE_BOUNDED_PLANE + // AreaTriggerShapeType::BoundedPlane struct { float Extents[2]; @@ -202,10 +219,8 @@ public: AreaTriggerTemplate(); ~AreaTriggerTemplate(); - bool HasFlag(AreaTriggerFlags flag) const { return (Flags & flag) != 0; } - AreaTriggerId Id; - uint32 Flags; + EnumFlag<AreaTriggerFlag> Flags; std::vector<AreaTriggerAction> Actions; }; @@ -216,10 +231,10 @@ public: ~AreaTriggerCreateProperties(); bool HasSplines() const; - float GetMaxSearchRadius() const; - uint32 Id; + AreaTriggerCreatePropertiesId Id; AreaTriggerTemplate const* Template; + EnumFlag<AreaTriggerCreatePropertiesFlag> Flags; uint32 MoveCurveId; uint32 ScaleCurveId; @@ -238,8 +253,6 @@ public: Optional<AreaTriggerScaleCurveTemplate> ExtraScale; AreaTriggerShapeInfo Shape; - std::vector<TaggedPosition<Position::XY>> PolygonVertices; - std::vector<TaggedPosition<Position::XY>> PolygonVerticesTarget; std::vector<Position> SplinePoints; Optional<AreaTriggerOrbitInfo> OrbitInfo; @@ -251,9 +264,7 @@ struct AreaTriggerSpawn : SpawnData { AreaTriggerSpawn() : SpawnData(SPAWN_TYPE_AREATRIGGER) { } - AreaTriggerId Id; - - AreaTriggerShapeInfo Shape; + AreaTriggerCreatePropertiesId Id; Optional<int32> SpellForVisuals; }; diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp index 96f75e910b4..4181d5611ca 100644 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -441,20 +441,19 @@ void Object::BuildMovementUpdate(ByteBuffer* data, CreateObjectBits flags, Playe { AreaTrigger const* areaTrigger = ToAreaTrigger(); AreaTriggerCreateProperties const* createProperties = areaTrigger->GetCreateProperties(); - AreaTriggerTemplate const* areaTriggerTemplate = areaTrigger->GetTemplate(); AreaTriggerShapeInfo const& shape = areaTrigger->GetShape(); *data << uint32(areaTrigger->GetTimeSinceCreated()); *data << areaTrigger->GetRollPitchYaw().PositionXYZStream(); - bool hasAbsoluteOrientation = areaTriggerTemplate && areaTrigger->GetTemplate()->HasFlag(AREATRIGGER_FLAG_HAS_ABSOLUTE_ORIENTATION); - bool hasDynamicShape = areaTriggerTemplate && areaTrigger->GetTemplate()->HasFlag(AREATRIGGER_FLAG_HAS_DYNAMIC_SHAPE); - bool hasAttached = areaTriggerTemplate && areaTrigger->GetTemplate()->HasFlag(AREATRIGGER_FLAG_HAS_ATTACHED); - bool hasFaceMovementDir = areaTriggerTemplate && areaTrigger->GetTemplate()->HasFlag(AREATRIGGER_FLAG_HAS_FACE_MOVEMENT_DIR); - bool hasFollowsTerrain = areaTriggerTemplate && areaTrigger->GetTemplate()->HasFlag(AREATRIGGER_FLAG_HAS_FOLLOWS_TERRAIN); - bool hasUnk1 = areaTriggerTemplate && areaTrigger->GetTemplate()->HasFlag(AREATRIGGER_FLAG_UNK1); - bool hasTargetRollPitchYaw = areaTriggerTemplate && areaTrigger->GetTemplate()->HasFlag(AREATRIGGER_FLAG_HAS_TARGET_ROLL_PITCH_YAW); + bool hasAbsoluteOrientation = createProperties && createProperties->Flags.HasFlag(AreaTriggerCreatePropertiesFlag::HasAbsoluteOrientation); + bool hasDynamicShape = createProperties && createProperties->Flags.HasFlag(AreaTriggerCreatePropertiesFlag::HasDynamicShape); + bool hasAttached = createProperties && createProperties->Flags.HasFlag(AreaTriggerCreatePropertiesFlag::HasAttached); + bool hasFaceMovementDir = createProperties && createProperties->Flags.HasFlag(AreaTriggerCreatePropertiesFlag::HasFaceMovementDir); + bool hasFollowsTerrain = createProperties && createProperties->Flags.HasFlag(AreaTriggerCreatePropertiesFlag::HasFollowsTerrain); + bool hasUnk1 = createProperties && createProperties->Flags.HasFlag(AreaTriggerCreatePropertiesFlag::Unk1); + bool hasTargetRollPitchYaw = createProperties && createProperties->Flags.HasFlag(AreaTriggerCreatePropertiesFlag::HasTargetRollPitchYaw); bool hasScaleCurveID = createProperties && createProperties->ScaleCurveId != 0; bool hasMorphCurveID = createProperties && createProperties->MorphCurveId != 0; bool hasFacingCurveID = createProperties && createProperties->FacingCurveId != 0; @@ -464,7 +463,7 @@ void Object::BuildMovementUpdate(ByteBuffer* data, CreateObjectBits flags, Playe bool hasAreaTriggerPolygon = createProperties && shape.IsPolygon(); bool hasAreaTriggerCylinder = shape.IsCylinder(); bool hasDisk = shape.IsDisk(); - bool hasBoundedPlane = shape.IsBoudedPlane(); + bool hasBoundedPlane = shape.IsBoundedPlane(); bool hasAreaTriggerSpline = areaTrigger->HasSplines(); bool hasOrbit = areaTrigger->HasOrbit(); bool hasMovementScript = false; @@ -533,15 +532,15 @@ void Object::BuildMovementUpdate(ByteBuffer* data, CreateObjectBits flags, Playe if (hasAreaTriggerPolygon) { - *data << int32(createProperties->PolygonVertices.size()); - *data << int32(createProperties->PolygonVerticesTarget.size()); + *data << int32(shape.PolygonVertices.size()); + *data << int32(shape.PolygonVerticesTarget.size()); *data << float(shape.PolygonDatas.Height); *data << float(shape.PolygonDatas.HeightTarget); - for (TaggedPosition<Position::XY> const& vertice : createProperties->PolygonVertices) + for (TaggedPosition<Position::XY> const& vertice : shape.PolygonVertices) *data << vertice; - for (TaggedPosition<Position::XY> const& vertice : createProperties->PolygonVerticesTarget) + for (TaggedPosition<Position::XY> const& vertice : shape.PolygonVerticesTarget) *data << vertice; } diff --git a/src/server/game/Globals/AreaTriggerDataStore.cpp b/src/server/game/Globals/AreaTriggerDataStore.cpp index a8a930fe01b..a664f56431d 100644 --- a/src/server/game/Globals/AreaTriggerDataStore.cpp +++ b/src/server/game/Globals/AreaTriggerDataStore.cpp @@ -35,7 +35,7 @@ struct std::hash<AreaTriggerId> { size_t hashVal = 0; Trinity::hash_combine(hashVal, value.Id); - Trinity::hash_combine(hashVal, value.IsServerSide); + Trinity::hash_combine(hashVal, value.IsCustom); return hashVal; } }; @@ -48,24 +48,24 @@ namespace AtMapObjectGuids _areaTriggerSpawnsByLocation; std::unordered_map<ObjectGuid::LowType, AreaTriggerSpawn> _areaTriggerSpawnsBySpawnId; std::unordered_map<AreaTriggerId, AreaTriggerTemplate> _areaTriggerTemplateStore; - std::unordered_map<uint32, AreaTriggerCreateProperties> _areaTriggerCreateProperties; + std::unordered_map<AreaTriggerCreatePropertiesId, AreaTriggerCreateProperties> _areaTriggerCreateProperties; } void AreaTriggerDataStore::LoadAreaTriggerTemplates() { uint32 oldMSTime = getMSTime(); - std::unordered_map<uint32, std::vector<TaggedPosition<Position::XY>>> verticesByCreateProperties; - std::unordered_map<uint32, std::vector<TaggedPosition<Position::XY>>> verticesTargetByCreateProperties; - std::unordered_map<uint32, std::vector<Position>> splinesByCreateProperties; + std::unordered_map<AreaTriggerCreatePropertiesId, std::vector<TaggedPosition<Position::XY>>> verticesByCreateProperties; + std::unordered_map<AreaTriggerCreatePropertiesId, std::vector<TaggedPosition<Position::XY>>> verticesTargetByCreateProperties; + std::unordered_map<AreaTriggerCreatePropertiesId, std::vector<Position>> splinesByCreateProperties; std::unordered_map<AreaTriggerId, std::vector<AreaTriggerAction>> actionsByAreaTrigger; - // 0 1 2 3 4 - if (QueryResult templateActions = WorldDatabase.Query("SELECT AreaTriggerId, IsServerSide, ActionType, ActionParam, TargetType FROM `areatrigger_template_actions`")) + // 0 1 2 3 4 + if (QueryResult templateActions = WorldDatabase.Query("SELECT AreaTriggerId, IsCustom, ActionType, ActionParam, TargetType FROM `areatrigger_template_actions`")) { do { Field* templateActionFields = templateActions->Fetch(); - AreaTriggerId areaTriggerId = { templateActionFields[0].GetUInt32(), templateActionFields[1].GetUInt8() == 1 }; + AreaTriggerId areaTriggerId = { templateActionFields[0].GetUInt32(), templateActionFields[1].GetBool()}; AreaTriggerAction action; action.Param = templateActionFields[3].GetUInt32(); @@ -74,15 +74,15 @@ void AreaTriggerDataStore::LoadAreaTriggerTemplates() if (actionType >= AREATRIGGER_ACTION_MAX) { - TC_LOG_ERROR("sql.sql", "Table `areatrigger_template_actions` has invalid ActionType ({},{}) for AreaTriggerId {} and Param {}", - actionType, areaTriggerId.Id, uint32(areaTriggerId.IsServerSide), action.Param); + TC_LOG_ERROR("sql.sql", "Table `areatrigger_template_actions` has invalid ActionType {} for AreaTriggerId ({},{}) and Param {}", + actionType, areaTriggerId.Id, uint32(areaTriggerId.IsCustom), action.Param); continue; } if (targetType >= AREATRIGGER_ACTION_USER_MAX) { - TC_LOG_ERROR("sql.sql", "Table `areatrigger_template_actions` has invalid TargetType ({},{}) for AreaTriggerId {} and Param {}", - targetType, areaTriggerId.Id, uint32(areaTriggerId.IsServerSide), action.Param); + TC_LOG_ERROR("sql.sql", "Table `areatrigger_template_actions` has invalid TargetType {} for AreaTriggerId ({},{}) and Param {}", + targetType, areaTriggerId.Id, uint32(areaTriggerId.IsCustom), action.Param); continue; } @@ -90,8 +90,8 @@ void AreaTriggerDataStore::LoadAreaTriggerTemplates() { if (!sObjectMgr->GetWorldSafeLoc(action.Param)) { - TC_LOG_ERROR("sql.sql", "Table `areatrigger_template_actions` has invalid entry ({},{}) with TargetType=Teleport and Param ({}) not a valid world safe loc entry", - areaTriggerId.Id, uint32(areaTriggerId.IsServerSide), action.Param); + TC_LOG_ERROR("sql.sql", "Table `areatrigger_template_actions` has invalid entry for AreaTriggerId ({},{}) with TargetType=Teleport and Param ({}) not a valid world safe loc entry", + areaTriggerId.Id, uint32(areaTriggerId.IsCustom), action.Param); continue; } } @@ -108,20 +108,21 @@ void AreaTriggerDataStore::LoadAreaTriggerTemplates() TC_LOG_INFO("server.loading", ">> Loaded 0 AreaTrigger templates actions. DB table `areatrigger_template_actions` is empty."); } - // 0 1 2 3 4 5 - if (QueryResult vertices = WorldDatabase.Query("SELECT AreaTriggerCreatePropertiesId, Idx, VerticeX, VerticeY, VerticeTargetX, VerticeTargetY FROM `areatrigger_create_properties_polygon_vertex` ORDER BY `AreaTriggerCreatePropertiesId`, `Idx`")) + // 0 1 2 3 4 5 6 + if (QueryResult vertices = WorldDatabase.Query("SELECT AreaTriggerCreatePropertiesId, IsCustom, Idx, VerticeX, VerticeY, VerticeTargetX, VerticeTargetY FROM `areatrigger_create_properties_polygon_vertex` ORDER BY `AreaTriggerCreatePropertiesId`, `IsCustom`, `Idx`")) { do { Field* verticeFields = vertices->Fetch(); - uint32 areaTriggerCreatePropertiesId = verticeFields[0].GetUInt32(); + AreaTriggerCreatePropertiesId createPropertiesId = { verticeFields[0].GetUInt32(), verticeFields[1].GetBool() }; - verticesByCreateProperties[areaTriggerCreatePropertiesId].emplace_back(verticeFields[2].GetFloat(), verticeFields[3].GetFloat()); + verticesByCreateProperties[createPropertiesId].emplace_back(verticeFields[3].GetFloat(), verticeFields[4].GetFloat()); - if (!verticeFields[4].IsNull() && !verticeFields[5].IsNull()) - verticesTargetByCreateProperties[areaTriggerCreatePropertiesId].emplace_back(verticeFields[4].GetFloat(), verticeFields[5].GetFloat()); - else if (verticeFields[4].IsNull() != verticeFields[5].IsNull()) - TC_LOG_ERROR("sql.sql", "Table `areatrigger_create_properties_polygon_vertex` has listed invalid target vertices (AreaTriggerCreatePropertiesId: {}, Index: {}).", areaTriggerCreatePropertiesId, verticeFields[1].GetUInt32()); + if (!verticeFields[5].IsNull() && !verticeFields[6].IsNull()) + verticesTargetByCreateProperties[createPropertiesId].emplace_back(verticeFields[5].GetFloat(), verticeFields[6].GetFloat()); + else if (verticeFields[5].IsNull() != verticeFields[6].IsNull()) + TC_LOG_ERROR("sql.sql", "Table `areatrigger_create_properties_polygon_vertex` has listed invalid target vertices (AreaTriggerCreatePropertiesId: (Id: {}, IsCustom: {}), Index: {}).", + createPropertiesId.Id, uint32(createPropertiesId.IsCustom), verticeFields[1].GetUInt32()); } while (vertices->NextRow()); } @@ -130,14 +131,14 @@ void AreaTriggerDataStore::LoadAreaTriggerTemplates() TC_LOG_INFO("server.loading", ">> Loaded 0 AreaTrigger polygon vertices. DB table `areatrigger_create_properties_polygon_vertex` is empty."); } - // 0 1 2 3 - if (QueryResult splines = WorldDatabase.Query("SELECT AreaTriggerCreatePropertiesId, X, Y, Z FROM `areatrigger_create_properties_spline_point` ORDER BY `AreaTriggerCreatePropertiesId`, `Idx`")) + // 0 1 2 3, 4 + if (QueryResult splines = WorldDatabase.Query("SELECT AreaTriggerCreatePropertiesId, IsCustom, X, Y, Z FROM `areatrigger_create_properties_spline_point` ORDER BY `AreaTriggerCreatePropertiesId`, `IsCustom`, `Idx`")) { do { Field* splineFields = splines->Fetch(); - uint32 areaTriggerCreatePropertiesId = splineFields[0].GetUInt32(); - splinesByCreateProperties[areaTriggerCreatePropertiesId].emplace_back(splineFields[1].GetFloat(), splineFields[2].GetFloat(), splineFields[3].GetFloat()); + AreaTriggerCreatePropertiesId createPropertiesId = { splineFields[0].GetUInt32(), splineFields[1].GetBool() }; + splinesByCreateProperties[createPropertiesId].emplace_back(splineFields[2].GetFloat(), splineFields[3].GetFloat(), splineFields[4].GetFloat()); } while (splines->NextRow()); } @@ -146,8 +147,8 @@ void AreaTriggerDataStore::LoadAreaTriggerTemplates() TC_LOG_INFO("server.loading", ">> Loaded 0 AreaTrigger splines. DB table `areatrigger_create_properties_spline_point` is empty."); } - // 0 1 2 - if (QueryResult templates = WorldDatabase.Query("SELECT Id, IsServerSide, Flags FROM `areatrigger_template`")) + // 0 1 2 + if (QueryResult templates = WorldDatabase.Query("SELECT Id, IsCustom, Flags FROM `areatrigger_template`")) { do { @@ -155,16 +156,8 @@ void AreaTriggerDataStore::LoadAreaTriggerTemplates() AreaTriggerTemplate areaTriggerTemplate; areaTriggerTemplate.Id.Id = fields[0].GetUInt32(); - areaTriggerTemplate.Id.IsServerSide = fields[1].GetUInt8() == 1; - areaTriggerTemplate.Flags = fields[2].GetUInt32(); - - if (areaTriggerTemplate.Id.IsServerSide && areaTriggerTemplate.Flags != 0) - { - TC_LOG_ERROR("sql.sql", "Table `areatrigger_template` has listed server-side areatrigger (Id: {}, IsServerSide: {}) with non-zero flags", - areaTriggerTemplate.Id.Id, uint32(areaTriggerTemplate.Id.IsServerSide)); - continue; - } - + areaTriggerTemplate.Id.IsCustom = fields[1].GetBool(); + areaTriggerTemplate.Flags = AreaTriggerFlag(fields[2].GetUInt32()); areaTriggerTemplate.Actions = std::move(actionsByAreaTrigger[areaTriggerTemplate.Id]); _areaTriggerTemplateStore[areaTriggerTemplate.Id] = areaTriggerTemplate; @@ -172,9 +165,11 @@ void AreaTriggerDataStore::LoadAreaTriggerTemplates() while (templates->NextRow()); } - // 0 1 2 3 4 5 6 7 8 9 10 - if (QueryResult areatriggerCreateProperties = WorldDatabase.Query("SELECT Id, AreaTriggerId, MoveCurveId, ScaleCurveId, MorphCurveId, FacingCurveId, AnimId, AnimKitId, DecalPropertiesId, TimeToTarget, TimeToTargetScale, " - // 11 12 13 14 15 16 17 18 19 20 + // 0 1 2 3 4 + if (QueryResult areatriggerCreateProperties = WorldDatabase.Query("SELECT Id, IsCustom, AreaTriggerId, IsAreatriggerCustom, Flags, " + // 5 6 7 8 9 10 11 12 13 + "MoveCurveId, ScaleCurveId, MorphCurveId, FacingCurveId, AnimId, AnimKitId, DecalPropertiesId, TimeToTarget, TimeToTargetScale, " + // 14 15 16 17 18 19 20 21 22 23 "Shape, ShapeData0, ShapeData1, ShapeData2, ShapeData3, ShapeData4, ShapeData5, ShapeData6, ShapeData7, ScriptName FROM `areatrigger_create_properties`")) { do @@ -182,23 +177,27 @@ void AreaTriggerDataStore::LoadAreaTriggerTemplates() AreaTriggerCreateProperties createProperties; Field* fields = areatriggerCreateProperties->Fetch(); - createProperties.Id = fields[0].GetUInt32(); + AreaTriggerCreatePropertiesId createPropertiesId = { fields[0].GetUInt32(), fields[1].GetBool() }; + createProperties.Id = createPropertiesId; + + AreaTriggerId areaTriggerId = { fields[2].GetUInt32(), fields[3].GetBool() }; + createProperties.Template = GetAreaTriggerTemplate(areaTriggerId); - uint32 areatriggerId = fields[1].GetUInt32(); - createProperties.Template = GetAreaTriggerTemplate({ areatriggerId, false }); + createProperties.Flags = AreaTriggerCreatePropertiesFlag(fields[4].GetUInt32()); - uint8 shape = fields[11].GetUInt8(); + AreaTriggerShapeType shape = AreaTriggerShapeType(fields[14].GetUInt8()); - if (areatriggerId && !createProperties.Template) + if (areaTriggerId.Id && !createProperties.Template) { - TC_LOG_ERROR("sql.sql", "Table `areatrigger_create_properties` references invalid AreaTriggerId {} for AreaTriggerCreatePropertiesId {}", areatriggerId, createProperties.Id); + TC_LOG_ERROR("sql.sql", "Table `areatrigger_create_properties` references invalid AreaTrigger (Id: {}, IsCustom: {}) for AreaTriggerCreatePropertiesId (Id: {}, IsCustom: {})", + areaTriggerId.Id, uint32(areaTriggerId.IsCustom), createPropertiesId.Id, uint32(createPropertiesId.IsCustom)); continue; } - if (shape >= AREATRIGGER_TYPE_MAX) + if (shape >= AreaTriggerShapeType::Max) { - TC_LOG_ERROR("sql.sql", "Table `areatrigger_create_properties` has listed areatrigger create properties {} with invalid shape {}.", - createProperties.Id, uint32(shape)); + TC_LOG_ERROR("sql.sql", "Table `areatrigger_create_properties` has listed AreaTriggerCreatePropertiesId (Id: {}, IsCustom: {}) with invalid shape {}.", + createPropertiesId.Id, uint32(createPropertiesId.IsCustom), uint32(shape)); continue; } @@ -206,33 +205,33 @@ void AreaTriggerDataStore::LoadAreaTriggerTemplates() createProperties.Curve = Value; \ if (createProperties.Curve && !sCurveStore.LookupEntry(createProperties.Curve)) \ { \ - TC_LOG_ERROR("sql.sql", "Table `areatrigger_create_properties` has listed areatrigger (AreaTriggerCreatePropertiesId: {}, Id: {}) with invalid " #Curve " ({}), set to 0!", \ - createProperties.Id, areatriggerId, createProperties.Curve); \ + TC_LOG_ERROR("sql.sql", "Table `areatrigger_create_properties` has listed AreaTrigger (Id: {}, IsCustom: {}) for AreaTriggerCreatePropertiesId (Id: {}, IsCustom: {}) with invalid " #Curve " ({}), set to 0!", \ + areaTriggerId.Id, uint32(areaTriggerId.IsCustom), createPropertiesId.Id, uint32(createPropertiesId.IsCustom), createProperties.Curve); \ createProperties.Curve = 0; \ } - VALIDATE_AND_SET_CURVE(MoveCurveId, fields[2].GetUInt32()); - VALIDATE_AND_SET_CURVE(ScaleCurveId, fields[3].GetUInt32()); - VALIDATE_AND_SET_CURVE(MorphCurveId, fields[4].GetUInt32()); - VALIDATE_AND_SET_CURVE(FacingCurveId, fields[5].GetUInt32()); + VALIDATE_AND_SET_CURVE(MoveCurveId, fields[5].GetUInt32()); + VALIDATE_AND_SET_CURVE(ScaleCurveId, fields[6].GetUInt32()); + VALIDATE_AND_SET_CURVE(MorphCurveId, fields[7].GetUInt32()); + VALIDATE_AND_SET_CURVE(FacingCurveId, fields[8].GetUInt32()); #undef VALIDATE_AND_SET_CURVE - createProperties.AnimId = fields[6].GetInt32(); - createProperties.AnimKitId = fields[7].GetInt32(); + createProperties.AnimId = fields[9].GetInt32(); + createProperties.AnimKitId = fields[10].GetInt32(); - createProperties.DecalPropertiesId = fields[8].GetUInt32(); + createProperties.DecalPropertiesId = fields[11].GetUInt32(); - createProperties.TimeToTarget = fields[9].GetUInt32(); - createProperties.TimeToTargetScale = fields[10].GetUInt32(); + createProperties.TimeToTarget = fields[12].GetUInt32(); + createProperties.TimeToTargetScale = fields[13].GetUInt32(); - createProperties.Shape.Type = static_cast<AreaTriggerTypes>(shape); + createProperties.Shape.Type = static_cast<AreaTriggerShapeType>(shape); for (uint8 i = 0; i < MAX_AREATRIGGER_ENTITY_DATA; ++i) - createProperties.Shape.DefaultDatas.Data[i] = fields[12 + i].GetFloat(); + createProperties.Shape.DefaultDatas.Data[i] = fields[15 + i].GetFloat(); - createProperties.ScriptId = sObjectMgr->GetScriptId(fields[20].GetString()); + createProperties.ScriptId = sObjectMgr->GetScriptId(fields[23].GetString()); - if (shape == AREATRIGGER_TYPE_POLYGON) + if (shape == AreaTriggerShapeType::Polygon) { if (createProperties.Shape.PolygonDatas.Height <= 0.0f) { @@ -242,13 +241,13 @@ void AreaTriggerDataStore::LoadAreaTriggerTemplates() } } - createProperties.PolygonVertices = std::move(verticesByCreateProperties[createProperties.Id]); - createProperties.PolygonVerticesTarget = std::move(verticesTargetByCreateProperties[createProperties.Id]); - if (!createProperties.PolygonVerticesTarget.empty() && createProperties.PolygonVertices.size() != createProperties.PolygonVerticesTarget.size()) + createProperties.Shape.PolygonVertices = std::move(verticesByCreateProperties[createProperties.Id]); + createProperties.Shape.PolygonVerticesTarget = std::move(verticesTargetByCreateProperties[createProperties.Id]); + if (!createProperties.Shape.PolygonVerticesTarget.empty() && createProperties.Shape.PolygonVertices.size() != createProperties.Shape.PolygonVerticesTarget.size()) { - TC_LOG_ERROR("sql.sql", "Table `areatrigger_create_properties_polygon_vertex` has invalid target vertices, either all or none vertices must have a corresponding target vertex (AreaTriggerCreatePropertiesId: {}).", - createProperties.Id); - createProperties.PolygonVerticesTarget.clear(); + TC_LOG_ERROR("sql.sql", "Table `areatrigger_create_properties_polygon_vertex` has invalid target vertices, either all or none vertices must have a corresponding target vertex (AreaTriggerCreatePropertiesId: (Id: {}, IsCustom: {})).", + createPropertiesId.Id, uint32(createPropertiesId.IsCustom)); + createProperties.Shape.PolygonVerticesTarget.clear(); } createProperties.SplinePoints = std::move(splinesByCreateProperties[createProperties.Id]); @@ -262,43 +261,43 @@ void AreaTriggerDataStore::LoadAreaTriggerTemplates() TC_LOG_INFO("server.loading", ">> Loaded 0 AreaTrigger create properties. DB table `areatrigger_create_properties` is empty."); } - // 0 1 2 3 4 5 6 7 - if (QueryResult circularMovementInfos = WorldDatabase.Query("SELECT AreaTriggerCreatePropertiesId, StartDelay, CircleRadius, BlendFromRadius, InitialAngle, ZOffset, CounterClockwise, CanLoop FROM `areatrigger_create_properties_orbit`")) + // 0 1 2 3 4 5 6 7 8 + if (QueryResult circularMovementInfos = WorldDatabase.Query("SELECT AreaTriggerCreatePropertiesId, IsCustom, StartDelay, CircleRadius, BlendFromRadius, InitialAngle, ZOffset, CounterClockwise, CanLoop FROM `areatrigger_create_properties_orbit`")) { do { Field* circularMovementInfoFields = circularMovementInfos->Fetch(); - uint32 areaTriggerCreatePropertiesId = circularMovementInfoFields[0].GetUInt32(); + AreaTriggerCreatePropertiesId createPropertiesId = { circularMovementInfoFields[0].GetUInt32(), circularMovementInfoFields[1].GetBool() }; - AreaTriggerCreateProperties* createProperties = Trinity::Containers::MapGetValuePtr(_areaTriggerCreateProperties, areaTriggerCreatePropertiesId); + AreaTriggerCreateProperties* createProperties = Trinity::Containers::MapGetValuePtr(_areaTriggerCreateProperties, createPropertiesId); if (!createProperties) { - TC_LOG_ERROR("sql.sql", "Table `areatrigger_create_properties_orbit` reference invalid AreaTriggerCreatePropertiesId {}", areaTriggerCreatePropertiesId); + TC_LOG_ERROR("sql.sql", "Table `areatrigger_create_properties_orbit` reference invalid AreaTriggerCreatePropertiesId: (Id: {}, IsCustom: {})", createPropertiesId.Id, uint32(createPropertiesId.IsCustom)); continue; } createProperties->OrbitInfo.emplace(); - createProperties->OrbitInfo->StartDelay = circularMovementInfoFields[1].GetUInt32(); + createProperties->OrbitInfo->StartDelay = circularMovementInfoFields[2].GetUInt32(); #define VALIDATE_AND_SET_FLOAT(Float, Value) \ createProperties->OrbitInfo->Float = Value; \ if (!std::isfinite(createProperties->OrbitInfo->Float)) \ { \ - TC_LOG_ERROR("sql.sql", "Table `areatrigger_create_properties_orbit` has listed areatrigger (AreaTriggerCreatePropertiesId: {}) with invalid " #Float " ({}), set to 0!", \ - areaTriggerCreatePropertiesId, createProperties->OrbitInfo->Float); \ + TC_LOG_ERROR("sql.sql", "Table `areatrigger_create_properties_orbit` has listed areatrigger (AreaTriggerCreatePropertiesId: {}, IsCustom: {}) with invalid " #Float " ({}), set to 0!", \ + createPropertiesId.Id, uint32(createPropertiesId.IsCustom), createProperties->OrbitInfo->Float); \ createProperties->OrbitInfo->Float = 0.0f; \ } - VALIDATE_AND_SET_FLOAT(Radius, circularMovementInfoFields[2].GetFloat()); - VALIDATE_AND_SET_FLOAT(BlendFromRadius, circularMovementInfoFields[3].GetFloat()); - VALIDATE_AND_SET_FLOAT(InitialAngle, circularMovementInfoFields[4].GetFloat()); - VALIDATE_AND_SET_FLOAT(ZOffset, circularMovementInfoFields[5].GetFloat()); + VALIDATE_AND_SET_FLOAT(Radius, circularMovementInfoFields[3].GetFloat()); + VALIDATE_AND_SET_FLOAT(BlendFromRadius, circularMovementInfoFields[4].GetFloat()); + VALIDATE_AND_SET_FLOAT(InitialAngle, circularMovementInfoFields[5].GetFloat()); + VALIDATE_AND_SET_FLOAT(ZOffset, circularMovementInfoFields[6].GetFloat()); #undef VALIDATE_AND_SET_FLOAT - createProperties->OrbitInfo->CounterClockwise = circularMovementInfoFields[6].GetBool(); - createProperties->OrbitInfo->CanLoop = circularMovementInfoFields[7].GetBool(); + createProperties->OrbitInfo->CounterClockwise = circularMovementInfoFields[7].GetBool(); + createProperties->OrbitInfo->CanLoop = circularMovementInfoFields[8].GetBool(); } while (circularMovementInfos->NextRow()); } @@ -318,38 +317,64 @@ void AreaTriggerDataStore::LoadAreaTriggerSpawns() spawnMasks[mapDifficulty->MapID].insert(Difficulty(mapDifficulty->DifficultyID)); uint32 oldMSTime = getMSTime(); - // 0 1 2 3 4 5 6 7 8 9 10 11 - if (QueryResult templates = WorldDatabase.Query("SELECT SpawnId, AreaTriggerId, IsServerSide, MapId, SpawnDifficulties, PosX, PosY, PosZ, Orientation, PhaseUseFlags, PhaseId, PhaseGroup, " - // 12 13 14 15 16 17 18 19 20 21 22 - "Shape, ShapeData0, ShapeData1, ShapeData2, ShapeData3, ShapeData4, ShapeData5, ShapeData6, ShapeData7, SpellForVisuals, ScriptName FROM `areatrigger`")) + // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 + if (QueryResult templates = WorldDatabase.Query("SELECT SpawnId, AreaTriggerCreatePropertiesId, IsCustom, MapId, SpawnDifficulties, PosX, PosY, PosZ, Orientation, PhaseUseFlags, PhaseId, PhaseGroup, SpellForVisuals, ScriptName FROM `areatrigger`")) { do { Field* fields = templates->Fetch(); ObjectGuid::LowType spawnId = fields[0].GetUInt64(); - AreaTriggerId areaTriggerid = { fields[1].GetUInt32(), fields[2].GetUInt8() == 1 }; + AreaTriggerCreatePropertiesId createPropertiesId = { fields[1].GetUInt32(), fields[2].GetBool() }; WorldLocation location(fields[3].GetUInt32(), fields[5].GetFloat(), fields[6].GetFloat(), fields[7].GetFloat(), fields[8].GetFloat()); - uint8 shape = fields[12].GetUInt8(); - if (!GetAreaTriggerTemplate(areaTriggerid)) + AreaTriggerCreateProperties const* createProperties = GetAreaTriggerCreateProperties(createPropertiesId); + if (!createProperties) { - TC_LOG_ERROR("sql.sql", "Table `areatrigger` has listed areatrigger that doesn't exist: Id: {}, IsServerSide: {} for SpawnId " UI64FMTD, - areaTriggerid.Id, uint32(areaTriggerid.IsServerSide), spawnId); + TC_LOG_ERROR("sql.sql", "Table `areatrigger` has listed AreaTriggerCreatePropertiesId (Id: {}, IsCustom: {}) that doesn't exist for SpawnId " UI64FMTD, + createPropertiesId.Id, uint32(createPropertiesId.IsCustom), spawnId); continue; } - if (!MapManager::IsValidMapCoord(location)) + if (createProperties->Flags != AreaTriggerCreatePropertiesFlag::None) { - TC_LOG_ERROR("sql.sql", "Table `areatrigger` has listed an invalid position: SpawnId: {}, MapId {}, Position {{}}", - spawnId, location.GetMapId(), location.ToString()); + TC_LOG_ERROR("sql.sql", "Table `areatrigger` has listed AreaTriggerCreatePropertiesId (Id: {}, IsCustom: {}) with non - zero flags", + createPropertiesId.Id, uint32(createPropertiesId.IsCustom)); + continue; + } + + if (createProperties->ScaleCurveId || createProperties->MorphCurveId || createProperties->FacingCurveId || createProperties->MoveCurveId) + { + TC_LOG_ERROR("sql.sql", "Table `areatrigger` has listed AreaTriggerCreatePropertiesId (Id: {}, IsCustom: {}) with curve values", + createPropertiesId.Id, uint32(createPropertiesId.IsCustom)); continue; } - if (shape >= AREATRIGGER_TYPE_MAX) + if (createProperties->TimeToTarget || createProperties->TimeToTargetScale || createProperties->FacingCurveId || createProperties->MoveCurveId) { - TC_LOG_ERROR("sql.sql", "Table `areatrigger` has listed areatrigger SpawnId: {} with invalid shape {}.", - spawnId, uint32(shape)); + TC_LOG_ERROR("sql.sql", "Table `areatrigger` has listed AreaTriggerCreatePropertiesId (Id: {}, IsCustom: {}) with time to target values", + createPropertiesId.Id, uint32(createPropertiesId.IsCustom)); + continue; + } + + if (createProperties->OrbitInfo) + { + TC_LOG_ERROR("sql.sql", "Table `areatrigger` has listed AreaTriggerCreatePropertiesId (Id: {}, IsCustom: {}) with orbit info", + createPropertiesId.Id, uint32(createPropertiesId.IsCustom)); + continue; + } + + if (createProperties->HasSplines()) + { + TC_LOG_ERROR("sql.sql", "Table `areatrigger` has listed AreaTriggerCreatePropertiesId (Id: {}, IsCustom: {}) with splines", + createPropertiesId.Id, uint32(createPropertiesId.IsCustom)); + continue; + } + + if (!MapManager::IsValidMapCoord(location)) + { + TC_LOG_ERROR("sql.sql", "Table `areatrigger` has listed an invalid position: SpawnId: {}, MapId {}, Position {{}}", + spawnId, location.GetMapId(), location.ToString()); continue; } @@ -363,29 +388,24 @@ void AreaTriggerDataStore::LoadAreaTriggerSpawns() AreaTriggerSpawn& spawn = _areaTriggerSpawnsBySpawnId[spawnId]; spawn.spawnId = spawnId; spawn.mapId = location.GetMapId(); - spawn.Id = areaTriggerid; + spawn.Id = createPropertiesId; spawn.spawnPoint.Relocate(location); spawn.phaseUseFlags = fields[9].GetUInt8(); spawn.phaseId = fields[10].GetUInt32(); spawn.phaseGroup = fields[11].GetUInt32(); - spawn.Shape.Type = static_cast<AreaTriggerTypes>(shape); - for (uint8 i = 0; i < MAX_AREATRIGGER_ENTITY_DATA; ++i) - spawn.Shape.DefaultDatas.Data[i] = fields[13 + i].GetFloat(); - - if (!fields[21].IsNull()) + if (!fields[12].IsNull()) { - spawn.SpellForVisuals = fields[21].GetInt32(); - if (!sSpellMgr->GetSpellInfo(*spawn.SpellForVisuals, DIFFICULTY_NONE)) + spawn.SpellForVisuals = fields[12].GetInt32(); + if (!sSpellMgr->GetSpellInfo(spawn.SpellForVisuals.value(), DIFFICULTY_NONE)) { - TC_LOG_ERROR("sql.sql", "Table `areatrigger` has listed areatrigger SpawnId: {} with invalid SpellForVisual {}, set to none.", - spawnId, *spawn.SpellForVisuals); + TC_LOG_ERROR("sql.sql", "Table `areatrigger` has areatrigger (GUID: {}) with invalid SpellForVisual {}, set to none.", spawnId, *spawn.SpellForVisuals); spawn.SpellForVisuals.reset(); } } - spawn.scriptId = sObjectMgr->GetScriptId(fields[22].GetString()); + spawn.scriptId = sObjectMgr->GetScriptId(fields[13].GetString()); spawn.spawnGroupData = sObjectMgr->GetLegacySpawnGroup(); // Add the trigger to a map::cell map, which is later used by GridLoader to query @@ -403,7 +423,7 @@ AreaTriggerTemplate const* AreaTriggerDataStore::GetAreaTriggerTemplate(AreaTrig return Trinity::Containers::MapGetValuePtr(_areaTriggerTemplateStore, areaTriggerId); } -AreaTriggerCreateProperties const* AreaTriggerDataStore::GetAreaTriggerCreateProperties(uint32 areaTriggerCreatePropertiesId) const +AreaTriggerCreateProperties const* AreaTriggerDataStore::GetAreaTriggerCreateProperties(AreaTriggerCreatePropertiesId const& areaTriggerCreatePropertiesId) const { return Trinity::Containers::MapGetValuePtr(_areaTriggerCreateProperties, areaTriggerCreatePropertiesId); } diff --git a/src/server/game/Globals/AreaTriggerDataStore.h b/src/server/game/Globals/AreaTriggerDataStore.h index 07bbf64cc92..b13315a3abc 100644 --- a/src/server/game/Globals/AreaTriggerDataStore.h +++ b/src/server/game/Globals/AreaTriggerDataStore.h @@ -28,6 +28,8 @@ enum Difficulty : uint8; struct AreaTriggerId; struct AreaTriggerSpawn; +typedef AreaTriggerId AreaTriggerCreatePropertiesId; + class TC_GAME_API AreaTriggerDataStore { public: @@ -37,7 +39,7 @@ public: std::set<ObjectGuid::LowType> const* GetAreaTriggersForMapAndCell(uint32 mapId, Difficulty difficulty, uint32 cellId) const; AreaTriggerSpawn const* GetAreaTriggerSpawn(ObjectGuid::LowType spawnId) const; AreaTriggerTemplate const* GetAreaTriggerTemplate(AreaTriggerId const& areaTriggerId) const; - AreaTriggerCreateProperties const* GetAreaTriggerCreateProperties(uint32 areaTriggerCreatePropertiesId) const; + AreaTriggerCreateProperties const* GetAreaTriggerCreateProperties(AreaTriggerCreatePropertiesId const& areaTriggerCreatePropertiesId) const; static AreaTriggerDataStore* Instance(); }; diff --git a/src/server/game/Miscellaneous/Language.h b/src/server/game/Miscellaneous/Language.h index 856213af388..053bc664687 100644 --- a/src/server/game/Miscellaneous/Language.h +++ b/src/server/game/Miscellaneous/Language.h @@ -1014,7 +1014,9 @@ enum TrinityStrings LANG_CMDPARSER_CURRENCY_NO_EXIST = 1516, LANG_CMDPARSER_QUEST_NO_EXIST = 1517, - // 1516-1998 - free + // 1516-1996 - free + LANG_DEBUG_AREATRIGGER_ENTITY_ENTERED = 1997, + LANG_DEBUG_AREATRIGGER_ENTITY_LEFT = 1998, LANG_DEBUG_AREATRIGGER_LEFT = 1999, // Ticket Strings 2000-2030 LANG_COMMAND_TICKETNEW = 2000, // 3.3.5 RESERVED diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index 7d8551f55dc..2d973be8d99 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -6111,7 +6111,8 @@ void AuraEffect::HandleCreateAreaTrigger(AuraApplication const* aurApp, uint8 mo if (apply) { - AreaTrigger::CreateAreaTrigger(GetMiscValue(), GetCaster(), target, GetSpellInfo(), *target, GetBase()->GetDuration(), GetBase()->GetSpellVisual(), nullptr, this); + AreaTriggerCreatePropertiesId createPropertiesId = { uint32(GetMiscValue()), false }; + AreaTrigger::CreateAreaTrigger(createPropertiesId, *target, GetBase()->GetDuration(), GetCaster(), target, GetBase()->GetSpellVisual(), GetSpellInfo(), nullptr, this); } else { diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index d24e3337e6c..f4b8ecc9be7 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -5289,9 +5289,10 @@ void Spell::EffectCreateAreaTrigger() if (!unitCaster || !m_targets.HasDst()) return; + AreaTriggerCreatePropertiesId createPropertiesId = { uint32(effectInfo->MiscValue), false }; int32 duration = GetSpellInfo()->CalcDuration(GetCaster()); - AreaTrigger::CreateAreaTrigger(effectInfo->MiscValue, unitCaster, nullptr, GetSpellInfo(), destTarget->GetPosition(), duration, m_SpellVisual, this); + AreaTrigger::CreateAreaTrigger(createPropertiesId, destTarget->GetPosition(), duration, unitCaster, nullptr, m_SpellVisual, GetSpellInfo(), this); } void Spell::EffectRemoveTalent() |