From c7b583433609babb17579b62413710f5b4a43183 Mon Sep 17 00:00:00 2001 From: dymanoid <9433345+dymanoid@users.noreply.github.com> Date: Sun, 19 May 2019 18:12:37 +0200 Subject: [PATCH] Disallow shopping at stadiums, concert areas, varsity sport locations --- src/RealTime/CustomAI/RealTimeBuildingAI.cs | 26 +++++++++++++++++++ .../BuildingManagerConnection.cs | 26 +++++++++++++++++++ .../IBuildingManagerConnection.cs | 11 +++++++- .../Patches/TransferManagerPatch.cs | 10 +++++++ 4 files changed, 72 insertions(+), 1 deletion(-) diff --git a/src/RealTime/CustomAI/RealTimeBuildingAI.cs b/src/RealTime/CustomAI/RealTimeBuildingAI.cs index 3fe1b58..ae6e887 100644 --- a/src/RealTime/CustomAI/RealTimeBuildingAI.cs +++ b/src/RealTime/CustomAI/RealTimeBuildingAI.cs @@ -319,6 +319,32 @@ namespace RealTime.CustomAI return true; } + /// + /// Determines whether the building with the specified ID is a shopping target. + /// + /// The building ID to check. + /// + /// true if the building is a shopping target; otherwise, false. + /// + public bool IsShoppingTarget(ushort buildingId) + { + if (buildingId == 0) + { + return true; + } + + // A building still can post outgoing offers while inactive. + // This is to prevent those offers from being dispatched. + if (!buildingManager.BuildingHasFlags(buildingId, Building.Flags.Active)) + { + return false; + } + + var buildingService = buildingManager.GetBuildingService(buildingId); + return buildingService != ItemClass.Service.VarsitySports + && buildingManager.IsRealUniqueBuilding(buildingId); + } + /// Determines whether a building with specified ID is currently active. /// The ID of the building to check. /// diff --git a/src/RealTime/GameConnection/BuildingManagerConnection.cs b/src/RealTime/GameConnection/BuildingManagerConnection.cs index b9cd34a..491042c 100644 --- a/src/RealTime/GameConnection/BuildingManagerConnection.cs +++ b/src/RealTime/GameConnection/BuildingManagerConnection.cs @@ -422,6 +422,32 @@ namespace RealTime.GameConnection public bool IsAreaEvacuating(ushort buildingId) => buildingId != 0 && DisasterManager.instance.IsEvacuating(BuildingManager.instance.m_buildings.m_buffer[buildingId].m_position); + /// + /// Determines whether the building with specified ID is a real unique building (not a stadium, not a concert area). + /// + /// The building ID to check. + /// + /// true if the building with the specified ID is a real unique building; otherwise, false. + /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("General", "RCS1130", Justification = "The EventType enum has no [Flags] attribute but has values of power of 2")] + public bool IsRealUniqueBuilding(ushort buildingId) + { + if (buildingId == 0) + { + return false; + } + + var buildingInfo = BuildingManager.instance.m_buildings.m_buffer[buildingId].Info; + if (buildingInfo?.m_class?.m_service != ItemClass.Service.Monument) + { + return false; + } + + var monumentAI = buildingInfo.m_buildingAI as MonumentAI; + return monumentAI != null + && (monumentAI.m_supportEvents & (EventManager.EventType.Football | EventManager.EventType.Concert)) == 0; + } + private static bool BuildingCanBeVisited(ushort buildingId) { uint currentUnitId = BuildingManager.instance.m_buildings.m_buffer[buildingId].m_citizenUnits; diff --git a/src/RealTime/GameConnection/IBuildingManagerConnection.cs b/src/RealTime/GameConnection/IBuildingManagerConnection.cs index 81e73a6..baa11dc 100644 --- a/src/RealTime/GameConnection/IBuildingManagerConnection.cs +++ b/src/RealTime/GameConnection/IBuildingManagerConnection.cs @@ -184,8 +184,17 @@ namespace RealTime.GameConnection /// /// The building ID to check. /// - /// true if the area around the building with specified ID is currently being evacuated.; otherwise, false. + /// true if the area around the building with specified ID is currently being evacuated; otherwise, false. /// bool IsAreaEvacuating(ushort buildingId); + + /// + /// Determines whether the building with specified ID is a real unique building (not a stadium, not a concert area). + /// + /// The building ID to check. + /// + /// true if the building with the specified ID is a real unique building; otherwise, false. + /// + bool IsRealUniqueBuilding(ushort buildingId); } } \ No newline at end of file diff --git a/src/RealTime/GameConnection/Patches/TransferManagerPatch.cs b/src/RealTime/GameConnection/Patches/TransferManagerPatch.cs index 8e91d9c..4fb03a9 100644 --- a/src/RealTime/GameConnection/Patches/TransferManagerPatch.cs +++ b/src/RealTime/GameConnection/Patches/TransferManagerPatch.cs @@ -46,6 +46,16 @@ namespace RealTime.GameConnection.Patches case TransferManager.TransferReason.TouristD: return RealTimeAI.IsEntertainmentTarget(offer.Building); + case TransferManager.TransferReason.Shopping: + case TransferManager.TransferReason.ShoppingB: + case TransferManager.TransferReason.ShoppingC: + case TransferManager.TransferReason.ShoppingD: + case TransferManager.TransferReason.ShoppingE: + case TransferManager.TransferReason.ShoppingF: + case TransferManager.TransferReason.ShoppingG: + case TransferManager.TransferReason.ShoppingH: + return RealTimeAI.IsShoppingTarget(offer.Building); + case TransferManager.TransferReason.ParkMaintenance: return RealTimeAI.IsBuildingActive(offer.Building); -- GitLab