mirror of
https://github.com/misternebula/quantum-space-buddies.git
synced 2025-02-13 12:40:50 +00:00
light sensor: better detection of local light/darkness
This commit is contained in:
parent
ebd3af69b8
commit
66339575cd
@ -9,14 +9,14 @@ using UnityEngine;
|
||||
|
||||
namespace QSB.EchoesOfTheEye.LightSensorSync.Patches;
|
||||
|
||||
[HarmonyPatch]
|
||||
[HarmonyPatch(typeof(SingleLightSensor))]
|
||||
internal class LightSensorPatches : QSBPatch
|
||||
{
|
||||
public override QSBPatchTypes Type => QSBPatchTypes.OnClientConnect;
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(SingleLightSensor), nameof(SingleLightSensor.UpdateIllumination))]
|
||||
public static bool UpdateIlluminationReplacement(SingleLightSensor __instance)
|
||||
[HarmonyPatch(nameof(SingleLightSensor.UpdateIllumination))]
|
||||
private static bool UpdateIllumination(SingleLightSensor __instance)
|
||||
{
|
||||
if (!QSBWorldSync.AllObjectsReady)
|
||||
{
|
||||
@ -24,11 +24,20 @@ internal class LightSensorPatches : QSBPatch
|
||||
}
|
||||
|
||||
var qsbLightSensor = __instance.GetWorldObject<QSBLightSensor>();
|
||||
qsbLightSensor._illuminatedByLocal = false;
|
||||
var illuminatedByLocal = qsbLightSensor.IlluminatedByLocal;
|
||||
qsbLightSensor.IlluminatedByLocal = false;
|
||||
|
||||
__instance._illuminated = false;
|
||||
if (__instance._illuminatingDreamLanternList != null)
|
||||
__instance._illuminatingDreamLanternList?.Clear();
|
||||
|
||||
if (__instance._lightSources == null || __instance._lightSources.Count == 0)
|
||||
{
|
||||
__instance._illuminatingDreamLanternList.Clear();
|
||||
if (illuminatedByLocal)
|
||||
{
|
||||
qsbLightSensor.OnDetectLocalDarkness?.Invoke();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
var vector = __instance.transform.TransformPoint(__instance._localSensorOffset);
|
||||
@ -38,65 +47,46 @@ internal class LightSensorPatches : QSBPatch
|
||||
sensorWorldDir = __instance.transform.TransformDirection(__instance._localDirection).normalized;
|
||||
}
|
||||
|
||||
if (__instance._lightSources == null)
|
||||
foreach (var lightSource in __instance._lightSources)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (var i = 0; i < __instance._lightSources.Count; i++)
|
||||
{
|
||||
var source = __instance._lightSources[i];
|
||||
|
||||
if ((__instance._lightSourceMask & source.GetLightSourceType()) == source.GetLightSourceType()
|
||||
&& source.CheckIlluminationAtPoint(vector, __instance._sensorRadius, __instance._maxDistance))
|
||||
if ((__instance._lightSourceMask & lightSource.GetLightSourceType()) == lightSource.GetLightSourceType() &&
|
||||
lightSource.CheckIlluminationAtPoint(vector, __instance._sensorRadius, __instance._maxDistance))
|
||||
{
|
||||
var lightSourceType = source.GetLightSourceType();
|
||||
var lightSourceType = lightSource.GetLightSourceType();
|
||||
switch (lightSourceType)
|
||||
{
|
||||
case LightSourceType.UNDEFINED:
|
||||
{
|
||||
var light = source as OWLight2;
|
||||
var occludableLight = light.GetLight().shadows != LightShadows.None
|
||||
&& light.GetLight().shadowStrength > 0.5f;
|
||||
|
||||
if (light.CheckIlluminationAtPoint(vector, __instance._sensorRadius, __instance._maxDistance)
|
||||
&& !__instance.CheckOcclusion(light.transform.position, vector, sensorWorldDir, occludableLight))
|
||||
var owlight = lightSource as OWLight2;
|
||||
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))
|
||||
{
|
||||
__instance._illuminated = true;
|
||||
qsbLightSensor._illuminatedByLocal = true;
|
||||
qsbLightSensor.IlluminatedByLocal = true;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case LightSourceType.FLASHLIGHT:
|
||||
{
|
||||
if (Locator.GetFlashlight() == source as 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))
|
||||
{
|
||||
__instance._illuminated = true;
|
||||
qsbLightSensor._illuminatedByLocal = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var player = QSBPlayerManager.PlayerList.First(x => x.FlashLight == source as QSBFlashlight);
|
||||
var player = lightSource as Flashlight == Locator.GetFlashlight()
|
||||
? QSBPlayerManager.LocalPlayer
|
||||
: QSBPlayerManager.PlayerList.First(x => lightSource as QSBFlashlight == x.FlashLight);
|
||||
var playerCamera = player.Camera;
|
||||
|
||||
var position = player.Camera.transform.position;
|
||||
var to = __instance.transform.position - position;
|
||||
if (Vector3.Angle(player.Camera.transform.forward, to) <= __instance._maxSpotHalfAngle
|
||||
&& !__instance.CheckOcclusion(position, vector, sensorWorldDir))
|
||||
{
|
||||
__instance._illuminated = true;
|
||||
}
|
||||
var position = playerCamera.transform.position;
|
||||
var to = __instance.transform.position - position;
|
||||
if (Vector3.Angle(playerCamera.transform.forward, to) <= __instance._maxSpotHalfAngle
|
||||
&& !__instance.CheckOcclusion(position, vector, sensorWorldDir))
|
||||
{
|
||||
__instance._illuminated = true;
|
||||
qsbLightSensor.IlluminatedByLocal = player == QSBPlayerManager.LocalPlayer;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case LightSourceType.PROBE:
|
||||
case LightSourceType.PROBE: // todo remote probes
|
||||
{
|
||||
var probe = Locator.GetProbe();
|
||||
if (probe != null
|
||||
@ -106,7 +96,7 @@ internal class LightSensorPatches : QSBPatch
|
||||
&& !__instance.CheckOcclusion(probe.GetLightSourcePosition(), vector, sensorWorldDir))
|
||||
{
|
||||
__instance._illuminated = true;
|
||||
qsbLightSensor._illuminatedByLocal = true;
|
||||
qsbLightSensor.IlluminatedByLocal = true;
|
||||
}
|
||||
|
||||
break;
|
||||
@ -118,7 +108,7 @@ internal class LightSensorPatches : QSBPatch
|
||||
break;
|
||||
case LightSourceType.DREAM_LANTERN:
|
||||
{
|
||||
var dreamLanternController = __instance._lightSources[i] as DreamLanternController;
|
||||
var dreamLanternController = lightSource as DreamLanternController;
|
||||
if (dreamLanternController.IsLit()
|
||||
&& dreamLanternController.IsFocused(__instance._lanternFocusThreshold)
|
||||
&& dreamLanternController.CheckIlluminationAtPoint(vector, __instance._sensorRadius, __instance._maxDistance)
|
||||
@ -126,21 +116,21 @@ internal class LightSensorPatches : QSBPatch
|
||||
{
|
||||
__instance._illuminatingDreamLanternList.Add(dreamLanternController);
|
||||
__instance._illuminated = true;
|
||||
qsbLightSensor._illuminatedByLocal = true;
|
||||
qsbLightSensor.IlluminatedByLocal = true; // todo remote dream lanterns
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case LightSourceType.SIMPLE_LANTERN:
|
||||
foreach (var light in __instance._lightSources[i].GetLights())
|
||||
foreach (var owlight in lightSource.GetLights())
|
||||
{
|
||||
var occludableLight = light.GetLight().shadows != LightShadows.None
|
||||
&& light.GetLight().shadowStrength > 0.5f;
|
||||
var occludableLight = owlight.GetLight().shadows != LightShadows.None && owlight.GetLight().shadowStrength > 0.5f;
|
||||
var maxDistance = Mathf.Min(__instance._maxSimpleLanternDistance, __instance._maxDistance);
|
||||
if (light.CheckIlluminationAtPoint(vector, __instance._sensorRadius, maxDistance) && !__instance.CheckOcclusion(light.transform.position, vector, sensorWorldDir, occludableLight))
|
||||
if (owlight.CheckIlluminationAtPoint(vector, __instance._sensorRadius, maxDistance)
|
||||
&& !__instance.CheckOcclusion(owlight.transform.position, vector, sensorWorldDir, occludableLight))
|
||||
{
|
||||
__instance._illuminated = true;
|
||||
qsbLightSensor._illuminatedByLocal = true;
|
||||
qsbLightSensor.IlluminatedByLocal = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -150,7 +140,7 @@ internal class LightSensorPatches : QSBPatch
|
||||
if (lightSourceType == LightSourceType.VOLUME_ONLY)
|
||||
{
|
||||
__instance._illuminated = true;
|
||||
qsbLightSensor._illuminatedByLocal = true;
|
||||
qsbLightSensor.IlluminatedByLocal = true;
|
||||
}
|
||||
|
||||
break;
|
||||
@ -158,6 +148,15 @@ internal class LightSensorPatches : QSBPatch
|
||||
}
|
||||
}
|
||||
|
||||
if (qsbLightSensor.IlluminatedByLocal && !illuminatedByLocal)
|
||||
{
|
||||
qsbLightSensor.OnDetectLocalLight?.Invoke();
|
||||
}
|
||||
else if (!qsbLightSensor.IlluminatedByLocal && illuminatedByLocal)
|
||||
{
|
||||
qsbLightSensor.OnDetectLocalDarkness?.Invoke();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,45 +1,14 @@
|
||||
using Cysharp.Threading.Tasks;
|
||||
using QSB.WorldSync;
|
||||
using QSB.WorldSync;
|
||||
using System;
|
||||
using System.Threading;
|
||||
|
||||
namespace QSB.EchoesOfTheEye.LightSensorSync.WorldObjects;
|
||||
|
||||
// will be implemented when eote
|
||||
internal class QSBLightSensor : WorldObject<SingleLightSensor>
|
||||
{
|
||||
internal bool _illuminatedByLocal;
|
||||
public bool IlluminatedByLocal;
|
||||
|
||||
public event Action OnDetectLocalLight;
|
||||
public event Action OnDetectLocalDarkness;
|
||||
|
||||
public override async UniTask Init(CancellationToken ct)
|
||||
{
|
||||
AttachedObject.OnDetectLight += OnDetectLight;
|
||||
AttachedObject.OnDetectDarkness += OnDetectDarkness;
|
||||
}
|
||||
|
||||
public override void OnRemoval()
|
||||
{
|
||||
AttachedObject.OnDetectLight -= OnDetectLight;
|
||||
AttachedObject.OnDetectDarkness -= OnDetectDarkness;
|
||||
}
|
||||
|
||||
private void OnDetectLight()
|
||||
{
|
||||
if (_illuminatedByLocal)
|
||||
{
|
||||
OnDetectLocalLight?.Invoke();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDetectDarkness()
|
||||
{
|
||||
if (_illuminatedByLocal)
|
||||
{
|
||||
OnDetectLocalDarkness?.Invoke();
|
||||
}
|
||||
}
|
||||
public Action OnDetectLocalLight;
|
||||
public Action OnDetectLocalDarkness;
|
||||
|
||||
public override void SendInitialState(uint to) { }
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user