diff options
-rw-r--r-- | sql/updates/hotfixes/master/2024_06_23_00_hotfixes.sql | 7 | ||||
-rw-r--r-- | src/server/database/Database/Implementation/HotfixDatabase.cpp | 4 | ||||
-rw-r--r-- | src/server/database/Database/Implementation/HotfixDatabase.h | 3 | ||||
-rw-r--r-- | src/server/game/DataStores/DB2LoadInfo.h | 11 | ||||
-rw-r--r-- | src/server/game/DataStores/DB2Stores.cpp | 2 | ||||
-rw-r--r-- | src/server/game/DataStores/DB2Stores.h | 1 | ||||
-rw-r--r-- | src/server/game/DataStores/DB2Structure.h | 10 | ||||
-rw-r--r-- | src/server/game/DataStores/DBCEnums.h | 33 | ||||
-rw-r--r-- | src/server/game/Entities/AreaTrigger/AreaTriggerTemplate.h | 12 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 31 | ||||
-rw-r--r-- | src/server/game/Globals/ObjectMgr.cpp | 2 |
11 files changed, 98 insertions, 18 deletions
diff --git a/sql/updates/hotfixes/master/2024_06_23_00_hotfixes.sql b/sql/updates/hotfixes/master/2024_06_23_00_hotfixes.sql new file mode 100644 index 00000000000..0aa04fbc9a1 --- /dev/null +++ b/sql/updates/hotfixes/master/2024_06_23_00_hotfixes.sql @@ -0,0 +1,7 @@ +DROP TABLE IF EXISTS `area_trigger_action_set`; +CREATE TABLE `area_trigger_action_set` ( + `ID` int unsigned NOT NULL DEFAULT '0', + `Flags` int NOT NULL DEFAULT '0', + `VerifiedBuild` int NOT NULL DEFAULT '0', + PRIMARY KEY (`ID`,`VerifiedBuild`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; diff --git a/src/server/database/Database/Implementation/HotfixDatabase.cpp b/src/server/database/Database/Implementation/HotfixDatabase.cpp index 73ac2c07afd..3bc8463be31 100644 --- a/src/server/database/Database/Implementation/HotfixDatabase.cpp +++ b/src/server/database/Database/Implementation/HotfixDatabase.cpp @@ -93,6 +93,10 @@ void HotfixDatabaseConnection::DoPrepareStatements() "BoxWidth, BoxHeight, BoxYaw, ShapeType, ShapeID, AreaTriggerActionSetID, Flags FROM area_trigger WHERE (`VerifiedBuild` > 0) = ?", CONNECTION_SYNCH); PREPARE_MAX_ID_STMT(HOTFIX_SEL_AREA_TRIGGER, "SELECT MAX(ID) + 1 FROM area_trigger", CONNECTION_SYNCH); + // AreaTriggerActionSet.db2 + PrepareStatement(HOTFIX_SEL_AREA_TRIGGER_ACTION_SET, "SELECT ID, Flags FROM area_trigger_action_set WHERE (`VerifiedBuild` > 0) = ?", CONNECTION_SYNCH); + PREPARE_MAX_ID_STMT(HOTFIX_SEL_AREA_TRIGGER_ACTION_SET, "SELECT MAX(ID) + 1 FROM area_trigger_action_set", CONNECTION_SYNCH); + // ArmorLocation.db2 PrepareStatement(HOTFIX_SEL_ARMOR_LOCATION, "SELECT ID, Clothmodifier, Leathermodifier, Chainmodifier, Platemodifier, Modifier FROM armor_location" " WHERE (`VerifiedBuild` > 0) = ?", CONNECTION_SYNCH); diff --git a/src/server/database/Database/Implementation/HotfixDatabase.h b/src/server/database/Database/Implementation/HotfixDatabase.h index 03b0631c45c..9120b72da52 100644 --- a/src/server/database/Database/Implementation/HotfixDatabase.h +++ b/src/server/database/Database/Implementation/HotfixDatabase.h @@ -63,6 +63,9 @@ enum HotfixDatabaseStatements : uint32 HOTFIX_SEL_AREA_TRIGGER, HOTFIX_SEL_AREA_TRIGGER_MAX_ID, + HOTFIX_SEL_AREA_TRIGGER_ACTION_SET, + HOTFIX_SEL_AREA_TRIGGER_ACTION_SET_MAX_ID, + HOTFIX_SEL_ARMOR_LOCATION, HOTFIX_SEL_ARMOR_LOCATION_MAX_ID, diff --git a/src/server/game/DataStores/DB2LoadInfo.h b/src/server/game/DataStores/DB2LoadInfo.h index 0e2207b5fe9..fea6183ebed 100644 --- a/src/server/game/DataStores/DB2LoadInfo.h +++ b/src/server/game/DataStores/DB2LoadInfo.h @@ -223,6 +223,17 @@ struct AreaTriggerLoadInfo static constexpr DB2LoadInfo Instance{ Fields, 17, &AreaTriggerMeta::Instance, HOTFIX_SEL_AREA_TRIGGER }; }; +struct AreaTriggerActionSetLoadInfo +{ + static constexpr DB2FieldMeta Fields[2] = + { + { false, FT_INT, "ID" }, + { true, FT_INT, "Flags" }, + }; + + static constexpr DB2LoadInfo Instance{ Fields, 2, &AreaTriggerActionSetMeta::Instance, HOTFIX_SEL_AREA_TRIGGER_ACTION_SET }; +}; + struct ArmorLocationLoadInfo { static constexpr DB2FieldMeta Fields[6] = diff --git a/src/server/game/DataStores/DB2Stores.cpp b/src/server/game/DataStores/DB2Stores.cpp index 502d813c008..65907211126 100644 --- a/src/server/game/DataStores/DB2Stores.cpp +++ b/src/server/game/DataStores/DB2Stores.cpp @@ -50,6 +50,7 @@ DB2Storage<AnimKitEntry> sAnimKitStore("AnimKit.db2", &An DB2Storage<AreaGroupMemberEntry> sAreaGroupMemberStore("AreaGroupMember.db2", &AreaGroupMemberLoadInfo::Instance); DB2Storage<AreaTableEntry> sAreaTableStore("AreaTable.db2", &AreaTableLoadInfo::Instance); DB2Storage<AreaTriggerEntry> sAreaTriggerStore("AreaTrigger.db2", &AreaTriggerLoadInfo::Instance); +DB2Storage<AreaTriggerActionSetEntry> sAreaTriggerActionSetStore("AreaTriggerActionSet.db2", &AreaTriggerActionSetLoadInfo::Instance); DB2Storage<ArmorLocationEntry> sArmorLocationStore("ArmorLocation.db2", &ArmorLocationLoadInfo::Instance); DB2Storage<ArtifactEntry> sArtifactStore("Artifact.db2", &ArtifactLoadInfo::Instance); DB2Storage<ArtifactAppearanceEntry> sArtifactAppearanceStore("ArtifactAppearance.db2", &ArtifactAppearanceLoadInfo::Instance); @@ -660,6 +661,7 @@ uint32 DB2Manager::LoadStores(std::string const& dataPath, LocaleConstant defaul LOAD_DB2(sAreaGroupMemberStore); LOAD_DB2(sAreaTableStore); LOAD_DB2(sAreaTriggerStore); + LOAD_DB2(sAreaTriggerActionSetStore); LOAD_DB2(sArmorLocationStore); LOAD_DB2(sArtifactStore); LOAD_DB2(sArtifactAppearanceStore); diff --git a/src/server/game/DataStores/DB2Stores.h b/src/server/game/DataStores/DB2Stores.h index 9a92f3f93fb..f159cdd729a 100644 --- a/src/server/game/DataStores/DB2Stores.h +++ b/src/server/game/DataStores/DB2Stores.h @@ -44,6 +44,7 @@ TC_GAME_API extern DB2Storage<AnimationDataEntry> sAnimationDa TC_GAME_API extern DB2Storage<AnimKitEntry> sAnimKitStore; TC_GAME_API extern DB2Storage<AreaTableEntry> sAreaTableStore; TC_GAME_API extern DB2Storage<AreaTriggerEntry> sAreaTriggerStore; +TC_GAME_API extern DB2Storage<AreaTriggerActionSetEntry> sAreaTriggerActionSetStore; TC_GAME_API extern DB2Storage<ArmorLocationEntry> sArmorLocationStore; TC_GAME_API extern DB2Storage<ArtifactEntry> sArtifactStore; TC_GAME_API extern DB2Storage<ArtifactCategoryEntry> sArtifactCategoryStore; diff --git a/src/server/game/DataStores/DB2Structure.h b/src/server/game/DataStores/DB2Structure.h index 54de72ea26e..97d1798dd32 100644 --- a/src/server/game/DataStores/DB2Structure.h +++ b/src/server/game/DataStores/DB2Structure.h @@ -177,6 +177,16 @@ struct AreaTriggerEntry int16 ShapeID; int32 AreaTriggerActionSetID; int8 Flags; + + AreaTriggerShapeType GetShapeType() const { return static_cast<AreaTriggerShapeType>(ShapeType); } +}; + +struct AreaTriggerActionSetEntry +{ + uint32 ID; + int32 Flags; + + EnumFlag<AreaTriggerActionSetFlag> GetFlags() const { return static_cast<AreaTriggerActionSetFlag>(Flags); } }; struct ArmorLocationEntry diff --git a/src/server/game/DataStores/DBCEnums.h b/src/server/game/DataStores/DBCEnums.h index 4c088350339..ee36e011ff2 100644 --- a/src/server/game/DataStores/DBCEnums.h +++ b/src/server/game/DataStores/DBCEnums.h @@ -177,6 +177,39 @@ enum class AreaMountFlags : uint8 DEFINE_ENUM_FLAG(AreaMountFlags); +enum class AreaTriggerActionSetFlag : uint32 +{ + None = 0x0000, + OnlyTriggeredByCaster = 0x0001, + ResurrectIfConditionFails = 0x0002, + Obsolete = 0x0004, + AllowWhileGhost = 0x0008, + AllowWhileDead = 0x0010, + UnifyAllInstances = 0x0020, + SuppressConditionError = 0x0040, // NYI + NotTriggeredbyCaster = 0x0080, + CreatorsPartyOnly = 0x0100, + DontRunOnLeaveWhenExpiring = 0x0200, + CanAffectUninteractible = 0x0400, + DontDespawnWithCreator = 0x0800, + CanAffectBeastmaster = 0x1000, + RequiresLineOfSight = 0x2000 +}; + +DEFINE_ENUM_FLAG(AreaTriggerActionSetFlag); + +enum class AreaTriggerShapeType : int8 +{ + Sphere = 0, + Box = 1, + Unk = 2, + Polygon = 3, + Cylinder = 4, + Disk = 5, + BoundedPlane = 6, + Max +}; + enum ArtifactCategory : uint32 { ARTIFACT_CATEGORY_PRIMARY = 1, diff --git a/src/server/game/Entities/AreaTrigger/AreaTriggerTemplate.h b/src/server/game/Entities/AreaTrigger/AreaTriggerTemplate.h index df8f6aa2094..549baf41496 100644 --- a/src/server/game/Entities/AreaTrigger/AreaTriggerTemplate.h +++ b/src/server/game/Entities/AreaTrigger/AreaTriggerTemplate.h @@ -37,18 +37,6 @@ enum class AreaTriggerFlag : uint32 DEFINE_ENUM_FLAG(AreaTriggerFlag); -enum class AreaTriggerShapeType : uint8 -{ - Sphere = 0, - Box = 1, - Unk = 2, - Polygon = 3, - Cylinder = 4, - Disk = 5, - BoundedPlane = 6, - Max -}; - enum AreaTriggerActionTypes { AREATRIGGER_ACTION_CAST = 0, diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 1fe191d8e91..dd2ce8fc587 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -2028,25 +2028,46 @@ bool Player::IsInAreaTrigger(AreaTriggerEntry const* areaTrigger) const if (!PhasingHandler::InDbPhaseShift(this, areaTrigger->PhaseUseFlags, areaTrigger->PhaseID, areaTrigger->PhaseGroupID)) return false; + auto hasActionSetFlag = [=](AreaTriggerActionSetFlag flag) + { + if (AreaTriggerActionSetEntry const* areaTriggerActionSet = sAreaTriggerActionSetStore.LookupEntry(areaTrigger->AreaTriggerActionSetID)) + return areaTriggerActionSet->GetFlags().HasFlag(flag); + return false; + }; + + switch (getDeathState()) + { + case DEAD: + if (!hasActionSetFlag(AreaTriggerActionSetFlag::AllowWhileGhost)) + return false; + break; + case CORPSE: + if (!hasActionSetFlag(AreaTriggerActionSetFlag::AllowWhileDead)) + return false; + break; + default: + break; + } + Position areaTriggerPos(areaTrigger->Pos.X, areaTrigger->Pos.Y, areaTrigger->Pos.Z, areaTrigger->BoxYaw); - switch (areaTrigger->ShapeType) + switch (areaTrigger->GetShapeType()) { - case 0: // Sphere + case AreaTriggerShapeType::Sphere: if (!IsInDist(&areaTriggerPos, areaTrigger->Radius)) return false; break; - case 1: // Box + case AreaTriggerShapeType::Box: if (!IsWithinBox(areaTriggerPos, areaTrigger->BoxLength / 2.f, areaTrigger->BoxWidth / 2.f, areaTrigger->BoxHeight / 2.f)) return false; break; - case 3: // Polygon + case AreaTriggerShapeType::Polygon: { AreaTriggerPolygon const* polygon = sObjectMgr->GetAreaTriggerPolygon(areaTrigger->ID); if (!polygon || (polygon->Height && GetPositionZ() > areaTrigger->Pos.Z + *polygon->Height) || !IsInPolygon2D(areaTriggerPos, polygon->Vertices)) return false; break; } - case 4: // Cylinder + case AreaTriggerShapeType::Cylinder: if (!IsWithinVerticalCylinder(areaTriggerPos, areaTrigger->Radius, areaTrigger->BoxHeight)) return false; break; diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index 6afcda680c4..8b7411634f9 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -7197,7 +7197,7 @@ void ObjectMgr::LoadAreaTriggerPolygons() { for (AreaTriggerEntry const* areaTrigger : sAreaTriggerStore) { - if (areaTrigger->ShapeType != 3) + if (areaTrigger->GetShapeType() != AreaTriggerShapeType::Polygon) continue; PathDb2 const* path = sDB2Manager.GetPath(areaTrigger->ShapeID); |