189 lines
5.9 KiB
C#
Raw Normal View History

2021-11-08 20:55:53 +00:00
using HarmonyLib;
2022-02-26 00:02:14 -08:00
using QSB.EchoesOfTheEye.LightSensorSync.WorldObjects;
2021-11-08 20:55:53 +00:00
using QSB.Patches;
using QSB.Player;
2022-02-26 00:02:14 -08:00
using QSB.WorldSync;
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;
2022-05-27 10:40:20 -07:00
/// <summary>
/// its okay for this to be here. it's just temporary storage
/// </summary>
private static bool _illuminated;
[HarmonyPrefix]
2022-05-26 21:23:05 -07:00
[HarmonyPatch(nameof(SingleLightSensor.ManagedFixedUpdate))]
private static bool ManagedFixedUpdate(SingleLightSensor __instance)
{
if (!QSBWorldSync.AllObjectsReady)
{
return true;
}
2022-03-29 13:46:44 -07:00
2022-05-26 21:27:17 -07:00
if (!__instance.TryGetWorldObject(out QSBLightSensor qsbLightSensor))
2022-04-10 15:28:05 -07:00
{
return true;
}
2022-05-26 21:23:05 -07:00
if (__instance._fixedUpdateFrameDelayCount > 0)
{
2022-05-26 21:23:05 -07:00
__instance._fixedUpdateFrameDelayCount--;
return false;
}
var locallyIlluminated = qsbLightSensor.LocallyIlluminated;
2022-05-27 10:40:20 -07:00
var illuminated = _illuminated;
2022-05-26 21:23:05 -07:00
__instance.UpdateIllumination();
2022-05-27 10:41:22 -07:00
__instance._illuminated = _illuminated; // temp
2022-05-26 21:23:05 -07:00
if (!locallyIlluminated && qsbLightSensor.LocallyIlluminated)
{
qsbLightSensor.OnDetectLocalLight?.Invoke();
}
else if (locallyIlluminated && !__instance._illuminated)
{
qsbLightSensor.OnDetectLocalDarkness?.Invoke();
2022-05-27 10:40:20 -07:00
}
if (!illuminated && _illuminated)
{
__instance.OnDetectLight.Invoke();
}
else if (illuminated && !_illuminated)
{
__instance.OnDetectDarkness.Invoke();
2022-05-26 21:23:05 -07:00
}
return false;
}
[HarmonyPrefix]
[HarmonyPatch(nameof(SingleLightSensor.UpdateIllumination))]
private static bool UpdateIllumination(SingleLightSensor __instance)
{
if (!QSBWorldSync.AllObjectsReady)
{
return true;
}
2022-05-26 21:27:17 -07:00
if (!__instance.TryGetWorldObject(out QSBLightSensor qsbLightSensor))
2022-05-26 21:23:05 -07:00
{
return true;
}
qsbLightSensor.LocallyIlluminated = false;
2022-05-27 10:40:20 -07:00
_illuminated = false;
2022-05-26 21:23:05 -07:00
__instance._illuminatingDreamLanternList?.Clear();
if (__instance._lightSources == null || __instance._lightSources.Count == 0)
{
return false;
}
var vector = __instance.transform.TransformPoint(__instance._localSensorOffset);
var sensorWorldDir = Vector3.zero;
if (__instance._directionalSensor)
{
sensorWorldDir = __instance.transform.TransformDirection(__instance._localDirection).normalized;
}
2022-05-26 21:23:05 -07:00
foreach (var lightSource in __instance._lightSources)
{
2022-05-27 10:40:20 -07:00
if ((__instance._lightSourceMask & lightSource.GetLightSourceType()) == lightSource.GetLightSourceType()
&& lightSource.CheckIlluminationAtPoint(vector, __instance._sensorRadius, __instance._maxDistance))
{
var lightSourceType = lightSource.GetLightSourceType();
2022-05-26 21:23:05 -07:00
switch (lightSourceType)
{
2022-05-26 21:23:05 -07:00
case LightSourceType.UNDEFINED:
{
var owlight = lightSource as OWLight2;
2022-05-26 21:23:05 -07:00
var occludableLight = owlight.GetLight().shadows != LightShadows.None && owlight.GetLight().shadowStrength > 0.5f;
if (owlight.CheckIlluminationAtPoint(vector, __instance._sensorRadius, __instance._maxDistance)
&& !__instance.CheckOcclusion(owlight.transform.position, vector, sensorWorldDir, occludableLight))
{
qsbLightSensor.LocallyIlluminated = true;
2022-05-27 10:40:20 -07:00
_illuminated = true;
2022-05-26 21:23:05 -07:00
}
break;
}
case LightSourceType.FLASHLIGHT:
{
var position = Locator.GetPlayerCamera().transform.position;
var to = __instance.transform.position - position;
if (Vector3.Angle(Locator.GetPlayerCamera().transform.forward, to) <= __instance._maxSpotHalfAngle
&& !__instance.CheckOcclusion(position, vector, sensorWorldDir))
{
qsbLightSensor.LocallyIlluminated = true;
2022-05-27 10:40:20 -07:00
_illuminated = true;
2022-05-26 21:23:05 -07:00
}
break;
}
case LightSourceType.PROBE:
{
var probe = Locator.GetProbe();
if (probe != null
&& probe.IsLaunched()
&& !probe.IsRetrieving()
&& probe.CheckIlluminationAtPoint(vector, __instance._sensorRadius, __instance._maxDistance)
&& !__instance.CheckOcclusion(probe.GetLightSourcePosition(), vector, sensorWorldDir))
{
qsbLightSensor.LocallyIlluminated = true;
2022-05-27 10:40:20 -07:00
_illuminated = true;
2022-05-26 21:23:05 -07:00
}
2022-05-26 21:23:05 -07:00
break;
}
2022-03-02 19:46:33 -08:00
case LightSourceType.DREAM_LANTERN:
{
var dreamLanternController = lightSource as DreamLanternController;
2022-03-02 19:46:33 -08:00
if (dreamLanternController.IsLit()
2022-03-07 15:02:10 -08:00
&& dreamLanternController.IsFocused(__instance._lanternFocusThreshold)
&& dreamLanternController.CheckIlluminationAtPoint(vector, __instance._sensorRadius, __instance._maxDistance)
&& !__instance.CheckOcclusion(dreamLanternController.GetLightPosition(), vector, sensorWorldDir))
2021-11-08 20:55:53 +00:00
{
2022-03-02 19:46:33 -08:00
__instance._illuminatingDreamLanternList.Add(dreamLanternController);
2022-04-06 10:37:41 -07:00
var dreamLanternItem = dreamLanternController.GetComponent<DreamLanternItem>();
2022-05-27 10:40:20 -07:00
qsbLightSensor.LocallyIlluminated |= QSBPlayerManager.LocalPlayer.HeldItem?.AttachedObject == dreamLanternItem;
_illuminated = true;
2021-11-08 20:55:53 +00:00
}
2021-11-25 15:38:05 +00:00
2021-11-08 20:55:53 +00:00
break;
2022-03-02 19:46:33 -08:00
}
case LightSourceType.SIMPLE_LANTERN:
foreach (var owlight in lightSource.GetLights())
2022-03-02 19:46:33 -08:00
{
var occludableLight = owlight.GetLight().shadows != LightShadows.None && owlight.GetLight().shadowStrength > 0.5f;
2022-03-02 19:46:33 -08:00
var maxDistance = Mathf.Min(__instance._maxSimpleLanternDistance, __instance._maxDistance);
if (owlight.CheckIlluminationAtPoint(vector, __instance._sensorRadius, maxDistance)
2022-03-07 15:02:10 -08:00
&& !__instance.CheckOcclusion(owlight.transform.position, vector, sensorWorldDir, occludableLight))
2021-11-08 20:55:53 +00:00
{
2022-04-06 10:37:41 -07:00
var simpleLanternItem = (SimpleLanternItem)lightSource;
2022-05-27 10:40:20 -07:00
qsbLightSensor.LocallyIlluminated |= QSBPlayerManager.LocalPlayer.HeldItem?.AttachedObject == simpleLanternItem;
_illuminated = true;
2022-03-02 19:46:33 -08:00
break;
2021-11-08 20:55:53 +00:00
}
2022-03-02 19:46:33 -08:00
}
2021-11-25 15:38:05 +00:00
2022-03-02 19:46:33 -08:00
break;
default:
if (lightSourceType == LightSourceType.VOLUME_ONLY)
{
2022-05-27 10:40:20 -07:00
_illuminated = true;
2022-03-02 19:46:33 -08:00
}
break;
2021-11-08 20:55:53 +00:00
}
}
}
2022-03-02 19:46:33 -08:00
return false;
2021-11-08 20:55:53 +00:00
}
}