Component to process conditional checks

This commit is contained in:
Joshua Thome 2025-02-16 16:46:47 -06:00
parent ad3c18517e
commit 27ff63d400
2 changed files with 91 additions and 0 deletions

View File

@ -0,0 +1,83 @@
using NewHorizons.External.Modules.Conditionals;
using NewHorizons.Handlers;
using NewHorizons.Utility.OWML;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
namespace NewHorizons.Components.Conditionals
{
public class ConditionalsManager : MonoBehaviour
{
public const int MAX_RECURSION = 100;
List<ConditionalCheckInfo> _checks = new();
int _recursionCount = 0;
bool _avoidRecursionLogSpam = false;
public void AddCheck(ConditionalCheckInfo check)
{
_checks.Add(check);
}
public void RemoveCheck(ConditionalCheckInfo check)
{
_checks.Remove(check);
}
protected void Awake()
{
GlobalMessenger.AddListener("DialogueConditionsReset", CalculateChecks);
GlobalMessenger<string, bool>.AddListener("DialogueConditionChanged", CalculateChecks);
GlobalMessenger<string, bool>.AddListener("NHPersistentConditionChanged", CalculateChecks);
GlobalMessenger.AddListener("ShipLogUpdated", CalculateChecks);
}
protected void OnDestroy()
{
GlobalMessenger.RemoveListener("DialogueConditionsReset", CalculateChecks);
GlobalMessenger<string, bool>.RemoveListener("DialogueConditionChanged", CalculateChecks);
GlobalMessenger<string, bool>.RemoveListener("NHPersistentConditionChanged", CalculateChecks);
GlobalMessenger.RemoveListener("ShipLogUpdated", CalculateChecks);
}
protected void Update()
{
_recursionCount = 0;
enabled = false;
}
void CalculateChecks()
{
if (_recursionCount >= MAX_RECURSION)
{
if (!_avoidRecursionLogSpam)
{
NHLogger.LogError($"Possible infinite loop detected while processing conditional checks. This is likely caused by a mod using conflicting conditional checks that both set and unset the same condition.");
_avoidRecursionLogSpam = true;
}
return;
}
foreach (var check in _checks)
{
bool checkPassed = ConditionalsHandler.Check(check.check);
if (checkPassed)
{
ConditionalsHandler.ApplyEffects(check.then, checkPassed);
}
}
_recursionCount++;
enabled = true;
}
// We could theoretically filter checks by conditionName here and only do the checks that matter, but the performance gain is likely not significant enough to be worth the extra complexity
void CalculateChecks(string conditionName, bool conditionState)
{
CalculateChecks();
}
}
}

View File

@ -143,5 +143,13 @@ namespace NewHorizons.Patches.PlayerPatches
{ {
NewHorizonsData.Save(); NewHorizonsData.Save();
} }
[HarmonyPostfix]
[HarmonyPatch(nameof(PlayerData.SetPersistentCondition))]
public static void PlayerData_SetPersistentCondition(string condition, bool state)
{
// Firing off a custom event for the Conditionals system to use. This could've been done with direct calls or a Unity event but it felt cleaner to mirror the vanilla "DialogueConditionChanged" event.
GlobalMessenger<string, bool>.FireEvent("NHPersistentConditionChanged", condition, state);
}
} }
} }