From 8959aa57a9fe18f395e20522019c0eee0b28b4ca Mon Sep 17 00:00:00 2001 From: Richard Griffiths Date: Fri, 24 Apr 2026 09:19:28 +0200 Subject: [PATCH] Reveal AL objectives on player visibility fix --- .../ConditionalBuilder.cs | 19 ++++++- .../LanceVisibleToPlayerConditional.cs | 53 +++++++++++++++++++ ...ddPlayer2LanceWithDestroyObjectiveBatch.cs | 8 ++- ...AddTargetLanceWithDestroyObjectiveBatch.cs | 10 +++- 4 files changed, 85 insertions(+), 5 deletions(-) create mode 100644 src/Core/EncounterConditionals/LanceVisibleToPlayerConditional.cs diff --git a/src/Core/ContractTypeBuilders/ConditionalBuilder.cs b/src/Core/ContractTypeBuilders/ConditionalBuilder.cs index 5d33817a..d95a3389 100644 --- a/src/Core/ContractTypeBuilders/ConditionalBuilder.cs +++ b/src/Core/ContractTypeBuilders/ConditionalBuilder.cs @@ -76,6 +76,7 @@ private void BuildConditional(JObject conditionalObject) { case "TimerStatus": BuildTimerStatusConditional(conditionalObject); break; case "WhoDied": BuildWhoDiedConditional(conditionalObject); break; case "WhoKilled": BuildWhoKilledConditional(conditionalObject); break; + case "LanceVisibleToPlayer": BuildLanceVisibleToPlayerConditional(conditionalObject); break; case "PlayerTonnage": BuildPlayerTonnageConditional(conditionalObject); break; default: Main.Logger.LogError($"[ChunkTypeBuilder.{contractTypeKey}] No valid conditional was built for '{type}'"); @@ -423,6 +424,22 @@ private void BuildWhoKilledConditional(JObject conditionalObject) { conditionalList.Add(new EncounterConditionalBox(conditional)); } + private void BuildLanceVisibleToPlayerConditional(JObject conditionalObject) { + Main.LogDebug("[BuildLanceVisibleToPlayerConditional] Building 'LanceVisibleToPlayer' conditional"); + string targetLanceGuid = conditionalObject.ContainsKey("TargetLanceGuid") ? conditionalObject["TargetLanceGuid"].ToString() : null; + if (targetLanceGuid == null && conditionalObject.ContainsKey("LanceGuid")) targetLanceGuid = conditionalObject["LanceGuid"].ToString(); + + if (string.IsNullOrEmpty(targetLanceGuid)) { + Main.Logger.LogError("[BuildLanceVisibleToPlayerConditional] You have not provided a 'TargetLanceGuid' or 'LanceGuid'."); + return; + } + + LanceVisibleToPlayerConditional conditional = ScriptableObject.CreateInstance(); + conditional.TargetLanceGuid = targetLanceGuid; + + conditionalList.Add(new EncounterConditionalBox(conditional)); + } + private void BuildPlayerTonnageConditional(JObject conditionalObject) { Main.LogDebug("[BuildPlayerTonnageConditional] Building 'PlayerTonnage' conditional"); string operation = conditionalObject["Operation"].ToString(); @@ -439,4 +456,4 @@ private void BuildPlayerTonnageConditional(JObject conditionalObject) { conditionalList.Add(new EncounterConditionalBox(conditional)); } } -} \ No newline at end of file +} diff --git a/src/Core/EncounterConditionals/LanceVisibleToPlayerConditional.cs b/src/Core/EncounterConditionals/LanceVisibleToPlayerConditional.cs new file mode 100644 index 00000000..a2e3a67f --- /dev/null +++ b/src/Core/EncounterConditionals/LanceVisibleToPlayerConditional.cs @@ -0,0 +1,53 @@ +using BattleTech; +using BattleTech.Framework; + +namespace MissionControl.Conditional { + public class LanceVisibleToPlayerConditional : DesignConditional { + public string TargetLanceGuid { get; set; } + + public override bool Evaluate(MessageCenterMessage message, string responseName) { + base.Evaluate(message, responseName); + + if (string.IsNullOrEmpty(TargetLanceGuid)) { + Main.Logger.LogError($"[LanceVisibleToPlayerConditional] TargetLanceGuid is empty. '{responseName}'"); + return false; + } + + VisibilityLevelIncreasedMessage visibilityMessage = message as VisibilityLevelIncreasedMessage; + if (visibilityMessage == null) { + return false; + } + + CombatGameState combat = UnityGameInstance.BattleTechGame?.Combat; + if (combat == null) { + Main.Logger.LogError($"[LanceVisibleToPlayerConditional] Combat state is unavailable. '{responseName}'"); + return false; + } + + VisibilityLevelAndAttribution visibility = visibilityMessage.VisibilityLevelAndAttribution; + if (visibility.SpottingTeamGUID != combat.LocalPlayerTeamGuid) { + return false; + } + + if (visibility.VisibilityLevel <= VisibilityLevel.None) { + return false; + } + + AbstractActor targetActor = combat.FindActorByGUID(visibilityMessage.TargetUnitGUID); + if (targetActor == null) { + return false; + } + + if (targetActor.lance == null || string.IsNullOrEmpty(targetActor.lance.GUID)) { + return false; + } + + if (targetActor.lance.GUID.Contains(TargetLanceGuid)) { + Main.LogDebug($"[LanceVisibleToPlayerConditional] Player visibility matches target lance guid '{TargetLanceGuid}'. '{responseName}'"); + return true; + } + + return false; + } + } +} diff --git a/src/Core/EncounterLogic/BatchedLogic/AddPlayer2LanceWithDestroyObjectiveBatch.cs b/src/Core/EncounterLogic/BatchedLogic/AddPlayer2LanceWithDestroyObjectiveBatch.cs index 7ff7fe12..f0194633 100644 --- a/src/Core/EncounterLogic/BatchedLogic/AddPlayer2LanceWithDestroyObjectiveBatch.cs +++ b/src/Core/EncounterLogic/BatchedLogic/AddPlayer2LanceWithDestroyObjectiveBatch.cs @@ -2,6 +2,8 @@ using System; using System.Collections.Generic; +using BattleTech; +using MissionControl.Conditional; using MissionControl.Rules; using MissionControl.Trigger; using MissionControl.Messages; @@ -27,10 +29,12 @@ public AddPlayer2LanceWithDestroyObjectiveBatch(EncounterRules encounterRules, s SpawnLogic.LookDirection.AWAY_FROM_TARGET, minDistance, maxDistance)); if (showObjectiveOnLanceDetected) { - encounterRules.EncounterLogic.Add(new ShowObjectiveTrigger(MessageCenterMessageType.OnLanceDetected, lanceGuid, objectiveGuid, false)); + LanceVisibleToPlayerConditional lanceVisibleToPlayerConditional = ScriptableObject.CreateInstance(); + lanceVisibleToPlayerConditional.TargetLanceGuid = lanceGuid; + encounterRules.EncounterLogic.Add(new ShowObjectiveTrigger(MessageCenterMessageType.OnVisibilityIncreased, lanceGuid, objectiveGuid, false, lanceVisibleToPlayerConditional)); } encounterRules.ObjectReferenceQueue.Add(spawnerName); } } -} \ No newline at end of file +} diff --git a/src/Core/EncounterLogic/BatchedLogic/AddTargetLanceWithDestroyObjectiveBatch.cs b/src/Core/EncounterLogic/BatchedLogic/AddTargetLanceWithDestroyObjectiveBatch.cs index 8f8bcde4..298f5d62 100644 --- a/src/Core/EncounterLogic/BatchedLogic/AddTargetLanceWithDestroyObjectiveBatch.cs +++ b/src/Core/EncounterLogic/BatchedLogic/AddTargetLanceWithDestroyObjectiveBatch.cs @@ -1,7 +1,11 @@ using System; using System.Collections.Generic; +using BattleTech; +using UnityEngine; + using MissionControl.Data; +using MissionControl.Conditional; using MissionControl.Rules; using MissionControl.Trigger; @@ -27,10 +31,12 @@ public AddTargetLanceWithDestroyObjectiveBatch(EncounterRules encounterRules, st SpawnLogic.LookDirection.AWAY_FROM_TARGET, mustBeBeyondDistance, mustBeWithinDistance)); if (showObjectiveOnLanceDetected) { - encounterRules.EncounterLogic.Add(new ShowObjectiveTrigger(MessageCenterMessageType.OnLanceDetected, lanceGuid, objectiveGuid, false)); + LanceVisibleToPlayerConditional lanceVisibleToPlayerConditional = ScriptableObject.CreateInstance(); + lanceVisibleToPlayerConditional.TargetLanceGuid = lanceGuid; + encounterRules.EncounterLogic.Add(new ShowObjectiveTrigger(MessageCenterMessageType.OnVisibilityIncreased, lanceGuid, objectiveGuid, false, lanceVisibleToPlayerConditional)); } encounterRules.ObjectReferenceQueue.Add(spawnerName); } } -} \ No newline at end of file +}