228 lines
6.7 KiB
C#
Raw Normal View History

2021-11-08 20:55:53 +00:00
using HarmonyLib;
2022-05-27 19:07:05 -07:00
using QSB.EchoesOfTheEye.LightSensorSync.Messages;
2022-02-26 00:02:14 -08:00
using QSB.EchoesOfTheEye.LightSensorSync.WorldObjects;
2022-05-27 19:07:05 -07:00
using QSB.Messaging;
2021-11-08 20:55:53 +00:00
using QSB.Patches;
2022-02-26 00:02:14 -08:00
using QSB.WorldSync;
using System.Collections.Generic;
2022-05-28 09:51:34 -07:00
using System.Linq;
2021-11-08 20:55:53 +00:00
using UnityEngine;
2022-03-02 19:46:33 -08:00
namespace QSB.EchoesOfTheEye.LightSensorSync.Patches;
[HarmonyPatch(typeof(SingleLightSensor))]
2022-03-02 19:46:33 -08:00
internal class LightSensorPatches : QSBPatch
2021-11-08 20:55:53 +00:00
{
2022-03-02 19:46:33 -08:00
public override QSBPatchTypes Type => QSBPatchTypes.OnClientConnect;
[HarmonyPrefix]
[HarmonyPatch(nameof(SingleLightSensor.Start))]
private static bool Start(SingleLightSensor __instance)
{
if (!QSBWorldSync.AllObjectsReady)
{
return true;
}
2022-05-28 14:14:25 -07:00
var isPlayerLightSensor = LightSensorManager.IsPlayerLightSensor(__instance);
2022-05-28 14:49:20 -07:00
var qsbPlayerLightSensor = isPlayerLightSensor ? __instance.GetComponent<QSBPlayerLightSensor>() : null;
2022-05-28 14:14:25 -07:00
var qsbLightSensor = isPlayerLightSensor ? null : __instance.GetWorldObject<QSBLightSensor>();
if (__instance._lightDetector != null)
{
__instance._lightSources = new List<ILightSource>();
__instance._lightSourceMask = LightSourceType.VOLUME_ONLY;
if (__instance._detectFlashlight)
{
__instance._lightSourceMask |= LightSourceType.FLASHLIGHT;
}
if (__instance._detectProbe)
{
__instance._lightSourceMask |= LightSourceType.PROBE;
}
if (__instance._detectDreamLanterns)
{
__instance._lightSourceMask |= LightSourceType.DREAM_LANTERN;
}
if (__instance._detectSimpleLanterns)
{
__instance._lightSourceMask |= LightSourceType.SIMPLE_LANTERN;
}
__instance._lightDetector.OnLightVolumeEnter += __instance.OnLightSourceEnter;
__instance._lightDetector.OnLightVolumeExit += __instance.OnLightSourceExit;
}
else
{
Debug.LogError("LightSensor has no LightSourceDetector", __instance);
}
if (__instance._sector != null)
{
__instance.enabled = false;
__instance._lightDetector.GetShape().enabled = false;
if (__instance._startIlluminated)
{
2022-05-28 14:14:25 -07:00
if (isPlayerLightSensor)
{
qsbPlayerLightSensor._locallyIlluminated = true;
new PlayerSetIlluminatedMessage(qsbPlayerLightSensor.PlayerId, true).Send();
}
else
{
qsbLightSensor._locallyIlluminated = true;
qsbLightSensor.OnDetectLocalLight?.Invoke();
qsbLightSensor.SendMessage(new SetIlluminatedMessage(true));
}
}
}
return false;
}
[HarmonyPrefix]
[HarmonyPatch(nameof(SingleLightSensor.OnSectorOccupantsUpdated))]
private static bool OnSectorOccupantsUpdated(SingleLightSensor __instance)
{
if (!QSBWorldSync.AllObjectsReady)
{
return true;
}
2022-05-28 14:14:25 -07:00
var isPlayerLightSensor = LightSensorManager.IsPlayerLightSensor(__instance);
2022-05-28 14:49:20 -07:00
var qsbPlayerLightSensor = isPlayerLightSensor ? __instance.GetComponent<QSBPlayerLightSensor>() : null;
2022-05-28 14:14:25 -07:00
var qsbLightSensor = isPlayerLightSensor ? null : __instance.GetWorldObject<QSBLightSensor>();
var containsAnyOccupants = __instance._sector.ContainsAnyOccupants(DynamicOccupant.Player | DynamicOccupant.Probe);
if (containsAnyOccupants && !__instance.enabled)
{
__instance.enabled = true;
__instance._lightDetector.GetShape().enabled = true;
if (__instance._preserveStateWhileDisabled)
{
__instance._fixedUpdateFrameDelayCount = 10;
}
}
else if (!containsAnyOccupants && __instance.enabled)
{
__instance.enabled = false;
__instance._lightDetector.GetShape().enabled = false;
if (!__instance._preserveStateWhileDisabled)
{
2022-05-28 14:14:25 -07:00
if (isPlayerLightSensor)
{
if (qsbPlayerLightSensor._locallyIlluminated)
{
qsbPlayerLightSensor._locallyIlluminated = false;
new PlayerSetIlluminatedMessage(qsbPlayerLightSensor.PlayerId, false).Send();
}
}
else
{
2022-05-28 14:14:25 -07:00
if (qsbLightSensor._locallyIlluminated)
{
qsbLightSensor._locallyIlluminated = false;
qsbLightSensor.OnDetectLocalDarkness?.Invoke();
qsbLightSensor.SendMessage(new SetIlluminatedMessage(false));
}
}
}
}
return false;
}
2022-05-28 09:58:19 -07:00
2022-05-28 10:12:15 -07:00
/// <summary>
/// to prevent allocating a new list every frame
/// </summary>
2022-05-28 09:51:34 -07:00
private static readonly List<DreamLanternController> _prevIlluminatingDreamLanternList = new();
[HarmonyPrefix]
[HarmonyPatch(nameof(SingleLightSensor.ManagedFixedUpdate))]
private static bool ManagedFixedUpdate(SingleLightSensor __instance)
{
if (!QSBWorldSync.AllObjectsReady)
{
return true;
}
2022-05-28 14:14:25 -07:00
var isPlayerLightSensor = LightSensorManager.IsPlayerLightSensor(__instance);
2022-05-28 14:49:20 -07:00
var qsbPlayerLightSensor = isPlayerLightSensor ? __instance.GetComponent<QSBPlayerLightSensor>() : null;
2022-05-28 14:14:25 -07:00
var qsbLightSensor = isPlayerLightSensor ? null : __instance.GetWorldObject<QSBLightSensor>();
if (__instance._fixedUpdateFrameDelayCount > 0)
{
__instance._fixedUpdateFrameDelayCount--;
}
if (__instance._illuminatingDreamLanternList != null)
{
_prevIlluminatingDreamLanternList.Clear();
_prevIlluminatingDreamLanternList.AddRange(__instance._illuminatingDreamLanternList);
}
2022-05-28 09:51:34 -07:00
2022-05-27 21:57:59 -07:00
var illuminated = __instance._illuminated;
__instance.UpdateIllumination();
2022-05-28 14:14:25 -07:00
bool locallyIlluminated;
if (isPlayerLightSensor)
{
locallyIlluminated = qsbPlayerLightSensor._locallyIlluminated;
qsbPlayerLightSensor._locallyIlluminated = __instance._illuminated;
}
else
{
locallyIlluminated = qsbLightSensor._locallyIlluminated;
qsbLightSensor._locallyIlluminated = __instance._illuminated;
}
2022-05-27 21:57:59 -07:00
__instance._illuminated = illuminated;
2022-05-28 14:14:25 -07:00
if (isPlayerLightSensor)
{
2022-05-28 14:14:25 -07:00
if (!locallyIlluminated && qsbPlayerLightSensor._locallyIlluminated)
{
qsbPlayerLightSensor._locallyIlluminated = true;
new PlayerSetIlluminatedMessage(qsbPlayerLightSensor.PlayerId, true).Send();
}
else if (locallyIlluminated && !qsbPlayerLightSensor._locallyIlluminated)
{
qsbPlayerLightSensor._locallyIlluminated = false;
new PlayerSetIlluminatedMessage(qsbPlayerLightSensor.PlayerId, false).Send();
}
}
2022-05-28 14:14:25 -07:00
else
{
2022-05-28 14:14:25 -07:00
if (!locallyIlluminated && qsbLightSensor._locallyIlluminated)
{
qsbLightSensor._locallyIlluminated = true;
qsbLightSensor.OnDetectLocalLight?.Invoke();
qsbLightSensor.SendMessage(new SetIlluminatedMessage(true));
}
else if (locallyIlluminated && !qsbLightSensor._locallyIlluminated)
{
qsbLightSensor._locallyIlluminated = false;
qsbLightSensor.OnDetectLocalDarkness?.Invoke();
qsbLightSensor.SendMessage(new SetIlluminatedMessage(false));
}
}
if (__instance._illuminatingDreamLanternList != null
&& !__instance._illuminatingDreamLanternList.SequenceEqual(_prevIlluminatingDreamLanternList))
2022-05-28 09:51:34 -07:00
{
2022-05-28 14:14:25 -07:00
if (isPlayerLightSensor)
{
new PlayerIlluminatingLanternsMessage(qsbPlayerLightSensor.PlayerId, __instance._illuminatingDreamLanternList).Send();
}
else
{
qsbLightSensor.SendMessage(new IlluminatingLanternsMessage(__instance._illuminatingDreamLanternList));
}
2022-05-28 09:51:34 -07:00
}
return false;
}
}