474 lines
13 KiB
C#
Raw Normal View History

using HarmonyLib;
using OWML.Common;
2021-02-21 18:25:25 +00:00
using QSB.Events;
2021-01-18 12:33:07 +00:00
using QSB.Patches;
2021-01-26 23:41:53 +00:00
using QSB.Player;
using QSB.QuantumSync.WorldObjects;
using QSB.Utility;
using QSB.WorldSync;
using System.Collections.Generic;
using System.Linq;
2021-02-16 20:49:10 +00:00
using System.Reflection;
2021-01-18 12:33:07 +00:00
using UnityEngine;
namespace QSB.QuantumSync.Patches
{
[HarmonyPatch]
2021-01-18 12:33:07 +00:00
public class QuantumPatches : QSBPatch
{
public override QSBPatchTypes Type => QSBPatchTypes.OnClientConnect;
[HarmonyPrefix]
[HarmonyPatch(typeof(QuantumObject), nameof(QuantumObject.IsLockedByPlayerContact))]
2021-06-18 21:54:32 +01:00
public static bool QuantumObject_IsLockedByPlayerContact(ref bool __result, QuantumObject __instance)
2021-02-26 14:19:42 +00:00
{
var playersEntangled = QuantumManager.GetEntangledPlayers(__instance);
__result = playersEntangled.Count() != 0 && __instance.IsIlluminated();
return false;
2021-02-18 15:36:11 +00:00
}
[HarmonyPrefix]
[HarmonyPatch(typeof(SocketedQuantumObject), nameof(SocketedQuantumObject.ChangeQuantumState))]
2021-06-18 21:54:32 +01:00
public static bool SocketedQuantumObject_ChangeQuantumState(
2021-02-21 18:25:25 +00:00
SocketedQuantumObject __instance,
ref bool __result,
2021-12-24 15:25:13 +00:00
bool skipInstantVisibilityCheck)
2021-02-21 18:25:25 +00:00
{
if (WorldObjectManager.AllObjectsReady)
2021-02-21 18:25:25 +00:00
{
2021-11-01 15:49:00 +00:00
var socketedWorldObject = QSBWorldSync.GetWorldFromUnity<QSBSocketedQuantumObject>(__instance);
if (socketedWorldObject.ControllingPlayer != QSBPlayerManager.LocalPlayerId)
{
return false;
}
2021-02-21 18:25:25 +00:00
}
2021-12-24 15:25:13 +00:00
foreach (var socket in __instance._childSockets)
2021-02-21 18:25:25 +00:00
{
if (socket.IsOccupied())
{
__result = false;
return false;
}
}
2021-12-24 15:25:13 +00:00
if (__instance._socketList.Count <= 1)
2021-02-21 18:25:25 +00:00
{
DebugLog.ToConsole($"Error - Not enough quantum sockets in list for {__instance.name}!", MessageType.Error);
__result = false;
return false;
}
var list = new List<QuantumSocket>();
2021-12-24 15:25:13 +00:00
foreach (var socket in __instance._socketList)
2021-02-21 18:25:25 +00:00
{
if (!socket.IsOccupied() && socket.IsActive())
{
list.Add(socket);
}
}
if (list.Count == 0)
{
__result = false;
return false;
}
2021-12-24 15:25:13 +00:00
if (__instance._recentlyObscuredSocket != null)
2021-02-21 18:25:25 +00:00
{
2021-12-24 15:25:13 +00:00
__instance.MoveToSocket(__instance._recentlyObscuredSocket);
__instance._recentlyObscuredSocket = null;
2021-02-21 18:25:25 +00:00
__result = true;
return false;
}
2021-12-24 15:25:13 +00:00
var occupiedSocket = __instance._occupiedSocket;
2021-02-21 18:25:25 +00:00
for (var i = 0; i < 20; i++)
{
2021-12-24 15:25:13 +00:00
var index = Random.Range(0, list.Count);
__instance.MoveToSocket(list[index]);
2021-02-21 18:25:25 +00:00
if (skipInstantVisibilityCheck)
{
__result = true;
return false;
}
2021-06-18 22:38:32 +01:00
2021-02-21 18:25:25 +00:00
bool socketNotSuitable;
2021-12-24 15:25:13 +00:00
var isSocketIlluminated = __instance.CheckIllumination();
2021-02-21 18:25:25 +00:00
var playersEntangled = QuantumManager.GetEntangledPlayers(__instance);
if (playersEntangled.Count() != 0)
{
// socket not suitable if illuminated
socketNotSuitable = isSocketIlluminated;
}
else
{
2021-12-24 15:25:13 +00:00
var checkVisInstant = __instance.CheckVisibilityInstantly();
2021-02-21 18:25:25 +00:00
if (isSocketIlluminated)
{
// socket not suitable if object is visible
socketNotSuitable = checkVisInstant;
}
else
{
// socket not suitable if player is inside object
socketNotSuitable = playersEntangled.Any(x => __instance.CheckPointInside(x.CameraBody.transform.position));
}
}
if (!socketNotSuitable)
{
__result = true;
return false;
}
2021-06-18 22:38:32 +01:00
2021-02-21 18:25:25 +00:00
list.RemoveAt(index);
if (list.Count == 0)
{
break;
}
}
2021-06-18 22:38:32 +01:00
2021-12-24 15:25:13 +00:00
__instance.MoveToSocket(occupiedSocket);
2021-02-21 18:25:25 +00:00
__result = false;
return false;
}
2021-01-26 23:41:53 +00:00
[HarmonyPostfix]
[HarmonyPatch(typeof(SocketedQuantumObject), nameof(SocketedQuantumObject.MoveToSocket))]
2021-06-18 21:54:32 +01:00
public static void SocketedQuantumObject_MoveToSocket(SocketedQuantumObject __instance, QuantumSocket socket)
2021-01-26 23:41:53 +00:00
{
if (!WorldObjectManager.AllObjectsReady)
{
return;
}
2021-02-26 17:04:16 +00:00
if (socket == null)
{
DebugLog.ToConsole($"Error - Trying to move {__instance.name} to a null socket!", MessageType.Error);
return;
}
2021-06-18 22:38:32 +01:00
2021-11-01 15:49:00 +00:00
var objectWorldObject = QSBWorldSync.GetWorldFromUnity<QSBSocketedQuantumObject>(__instance);
var socketWorldObject = QSBWorldSync.GetWorldFromUnity<QSBQuantumSocket>(socket);
2021-02-26 21:55:39 +00:00
2021-02-18 10:34:35 +00:00
if (objectWorldObject == null)
2021-01-26 23:41:53 +00:00
{
2021-02-18 10:34:35 +00:00
DebugLog.ToConsole($"Worldobject is null for {__instance.name}!");
2021-01-26 23:41:53 +00:00
return;
}
2021-02-18 10:34:35 +00:00
if (objectWorldObject.ControllingPlayer != QSBPlayerManager.LocalPlayerId)
2021-01-26 23:41:53 +00:00
{
return;
}
QSBEventManager.FireEvent(
2021-01-26 23:41:53 +00:00
EventNames.QSBSocketStateChange,
2021-02-18 10:34:35 +00:00
objectWorldObject.ObjectId,
socketWorldObject.ObjectId,
2021-01-26 23:41:53 +00:00
__instance.transform.localRotation);
}
[HarmonyPrefix]
[HarmonyPatch(typeof(QuantumShuffleObject), nameof(QuantumShuffleObject.ChangeQuantumState))]
2021-06-18 21:54:32 +01:00
public static bool QuantumShuffleObject_ChangeQuantumState(
2021-01-26 23:41:53 +00:00
QuantumShuffleObject __instance,
ref bool __result)
{
QSBQuantumShuffleObject shuffleWorldObject = default;
if (WorldObjectManager.AllObjectsReady)
2021-01-26 23:41:53 +00:00
{
2021-11-01 15:49:00 +00:00
shuffleWorldObject = QSBWorldSync.GetWorldFromUnity<QSBQuantumShuffleObject>(__instance);
if (shuffleWorldObject.ControllingPlayer != QSBPlayerManager.LocalPlayerId)
{
return false;
}
2021-01-26 23:41:53 +00:00
}
2021-12-24 15:25:13 +00:00
__instance._indexList.Clear();
__instance._indexList = Enumerable.Range(0, __instance._localPositions.Length).ToList();
for (var i = 0; i < __instance._indexList.Count; ++i)
2021-01-26 23:41:53 +00:00
{
2021-12-24 15:25:13 +00:00
var random = Random.Range(i, __instance._indexList.Count);
var temp = __instance._indexList[i];
__instance._indexList[i] = __instance._indexList[random];
__instance._indexList[random] = temp;
2021-01-26 23:41:53 +00:00
}
2021-12-24 15:25:13 +00:00
for (var j = 0; j < __instance._shuffledObjects.Length; j++)
2021-01-26 23:41:53 +00:00
{
2021-12-24 15:25:13 +00:00
__instance._shuffledObjects[j].localPosition = __instance._localPositions[__instance._indexList[j]];
2021-01-26 23:41:53 +00:00
}
if (WorldObjectManager.AllObjectsReady)
{
QSBEventManager.FireEvent(
2021-01-26 23:41:53 +00:00
EventNames.QSBQuantumShuffle,
2021-02-18 10:34:35 +00:00
shuffleWorldObject.ObjectId,
2021-12-24 15:25:13 +00:00
__instance._indexList.ToArray());
__result = true;
}
2021-01-26 23:41:53 +00:00
return false;
}
[HarmonyPrefix]
[HarmonyPatch(typeof(MultiStateQuantumObject), nameof(MultiStateQuantumObject.Start))]
2021-12-24 15:25:13 +00:00
public static bool MultiStateQuantumObject_Start(MultiStateQuantumObject __instance)
2021-03-18 13:35:11 +00:00
{
if (!WorldObjectManager.AllObjectsReady)
{
return true;
}
2021-11-01 15:49:00 +00:00
var qsbObj = QSBWorldSync.GetWorldFromUnity<QSBMultiStateQuantumObject>(__instance);
2021-03-18 13:35:11 +00:00
if (qsbObj.ControllingPlayer == 0)
{
return true;
}
foreach (var state in qsbObj.QuantumStates)
{
if (!state.IsMeantToBeEnabled)
{
state.SetVisible(false);
}
}
2021-12-24 15:25:13 +00:00
if (__instance._sector == null)
2021-03-18 13:35:11 +00:00
{
__instance.CheckEnabled();
2021-03-18 13:35:11 +00:00
}
2021-06-18 22:38:32 +01:00
2021-12-24 15:25:13 +00:00
if (__instance._collapseOnStart)
2021-03-18 13:35:11 +00:00
{
__instance.Collapse(true);
2021-03-18 13:35:11 +00:00
}
return false;
}
[HarmonyPrefix]
[HarmonyPatch(typeof(MultiStateQuantumObject), nameof(MultiStateQuantumObject.ChangeQuantumState))]
2021-06-18 21:54:32 +01:00
public static bool MultiStateQuantumObject_ChangeQuantumState(MultiStateQuantumObject __instance)
2021-01-26 23:41:53 +00:00
{
if (!WorldObjectManager.AllObjectsReady)
{
return true;
}
2021-11-01 15:49:00 +00:00
var qsbObj = QSBWorldSync.GetWorldFromUnity<QSBMultiStateQuantumObject>(__instance);
2021-03-18 13:35:11 +00:00
if (qsbObj.ControllingPlayer == 0 && qsbObj.CurrentState == -1)
2021-03-17 17:04:57 +00:00
{
return true;
}
2021-06-18 22:38:32 +01:00
2021-03-18 13:35:11 +00:00
var isInControl = qsbObj.ControllingPlayer == QSBPlayerManager.LocalPlayerId;
2021-01-26 23:41:53 +00:00
return isInControl;
}
[HarmonyPostfix]
[HarmonyPatch(typeof(QuantumState), nameof(QuantumState.SetVisible))]
2021-01-26 23:41:53 +00:00
public static void QuantumState_SetVisible(QuantumState __instance, bool visible)
{
if (!WorldObjectManager.AllObjectsReady)
{
return;
}
2021-01-26 23:41:53 +00:00
if (!visible)
{
return;
}
2021-06-18 22:38:32 +01:00
2021-01-26 23:41:53 +00:00
var allMultiStates = QSBWorldSync.GetWorldObjects<QSBMultiStateQuantumObject>();
2021-11-01 15:49:00 +00:00
var stateObject = QSBWorldSync.GetWorldFromUnity<QSBQuantumState>(__instance);
var owner = allMultiStates.FirstOrDefault(x => x.QuantumStates.Contains(stateObject));
if (owner == default)
{
2021-10-24 10:47:25 +01:00
DebugLog.ToConsole($"Error - Could not find QSBMultiStateQuantumObject for state {__instance.name}", MessageType.Error);
return;
}
2021-01-26 23:41:53 +00:00
if (owner.ControllingPlayer != QSBPlayerManager.LocalPlayerId)
{
return;
}
2021-06-18 22:38:32 +01:00
2021-03-18 13:35:11 +00:00
var stateIndex = owner.QuantumStates.IndexOf(stateObject);
QSBEventManager.FireEvent(
2021-01-26 23:41:53 +00:00
EventNames.QSBMultiStateChange,
2021-02-18 10:34:35 +00:00
owner.ObjectId,
2021-03-17 17:04:57 +00:00
stateIndex);
2021-01-26 23:41:53 +00:00
}
[HarmonyPrefix]
[HarmonyPatch(typeof(QuantumShrine), nameof(QuantumShrine.IsPlayerInDarkness))]
2021-12-24 15:25:13 +00:00
public static bool QuantumShrine_IsPlayerInDarkness(QuantumShrine __instance, ref bool __result)
2021-01-26 23:41:53 +00:00
{
2021-12-24 15:25:13 +00:00
foreach (var lamp in __instance._lamps)
2021-01-26 23:41:53 +00:00
{
if (lamp.intensity > 0f)
{
__result = false;
return false;
}
}
var playersInMoon = QSBPlayerManager.PlayerList.Where(x => x.IsInMoon);
2021-03-25 20:56:26 +00:00
if (playersInMoon.Any(player => !player.IsInShrine))
2021-01-26 23:41:53 +00:00
{
__result = false;
return false;
}
2021-03-25 20:56:26 +00:00
if (playersInMoon.Any(player => player.FlashLight != null && player.FlashLight.FlashlightOn))
{
__result = false;
return false;
}
if (playersInMoon.Count() == 0)
{
__result = false;
return false;
}
2021-03-25 22:01:10 +00:00
if (QSBPlayerManager.LocalPlayer != null
&& QSBPlayerManager.LocalPlayer.IsInShrine
2021-03-25 20:56:26 +00:00
&& PlayerState.IsFlashlightOn())
{
__result = false;
return false;
}
2021-08-22 16:40:50 +01:00
// BUG : make this *really* check for all players - check other probes and other jetpacks!
2021-12-24 15:25:13 +00:00
__result = __instance._gate.GetOpenFraction() == 0f
&& !__instance._isProbeInside
2021-01-26 23:41:53 +00:00
&& Locator.GetThrusterLightTracker().GetLightRange() <= 0f;
return false;
}
[HarmonyPrefix]
[HarmonyPatch(typeof(QuantumShrine), nameof(QuantumShrine.ChangeQuantumState))]
2021-06-18 21:54:32 +01:00
public static bool QuantumShrine_ChangeQuantumState(QuantumShrine __instance)
2021-01-26 23:41:53 +00:00
{
2021-11-01 15:49:00 +00:00
var shrineWorldObject = QSBWorldSync.GetWorldFromUnity<QSBSocketedQuantumObject>(__instance);
2021-02-18 10:34:35 +00:00
var isInControl = shrineWorldObject.ControllingPlayer == QSBPlayerManager.LocalPlayerId;
2021-01-26 23:41:53 +00:00
return isInControl;
}
[HarmonyPrefix]
[HarmonyPatch(typeof(QuantumShrine), nameof(QuantumShrine.OnEntry))]
2021-06-18 21:54:32 +01:00
public static bool QuantumShrine_OnEntry(
2021-12-24 15:25:13 +00:00
QuantumShrine __instance,
GameObject hitObj)
2021-01-18 12:33:07 +00:00
{
if (hitObj.CompareTag("PlayerDetector"))
{
2021-12-24 15:25:13 +00:00
__instance._isPlayerInside = true;
__instance._fading = true;
__instance._exteriorLightController.FadeTo(0f, 1f);
2021-02-10 19:59:28 +00:00
QSBEventManager.FireEvent(EventNames.QSBEnterShrine);
2021-01-18 12:33:07 +00:00
}
else if (hitObj.CompareTag("ProbeDetector"))
{
2021-12-24 15:25:13 +00:00
__instance._isProbeInside = true;
2021-01-18 12:33:07 +00:00
}
2021-06-18 22:38:32 +01:00
2021-01-18 12:33:07 +00:00
return false;
}
[HarmonyPrefix]
[HarmonyPatch(typeof(QuantumShrine), nameof(QuantumShrine.OnExit))]
2021-06-18 21:54:32 +01:00
public static bool QuantumShrine_OnExit(
2021-12-24 15:25:13 +00:00
QuantumShrine __instance,
GameObject hitObj)
2021-01-18 12:33:07 +00:00
{
if (hitObj.CompareTag("PlayerDetector"))
{
2021-12-24 15:25:13 +00:00
__instance._isPlayerInside = false;
__instance._fading = true;
__instance._exteriorLightController.FadeTo(1f, 1f);
2021-02-10 19:59:28 +00:00
QSBEventManager.FireEvent(EventNames.QSBExitShrine);
2021-01-18 12:33:07 +00:00
}
else if (hitObj.CompareTag("ProbeDetector"))
{
2021-12-24 15:25:13 +00:00
__instance._isProbeInside = false;
2021-01-18 12:33:07 +00:00
}
2021-06-18 22:38:32 +01:00
2021-01-18 12:33:07 +00:00
return false;
}
2021-02-16 20:49:10 +00:00
[HarmonyPrefix]
[HarmonyPatch(typeof(QuantumMoon), nameof(QuantumMoon.CheckPlayerFogProximity))]
2021-12-24 15:25:13 +00:00
public static bool QuantumMoon_CheckPlayerFogProximity(QuantumMoon __instance)
2021-02-16 20:49:10 +00:00
{
var playerDistance = Vector3.Distance(__instance.transform.position, Locator.GetPlayerCamera().transform.position);
2021-12-24 15:25:13 +00:00
var fogOffset = (__instance._stateIndex != 5) ? 0f : __instance._eyeStateFogOffset;
var distanceFromFog = playerDistance - (__instance._fogRadius + fogOffset);
2021-02-16 20:49:10 +00:00
var fogAlpha = 0f;
2021-12-24 15:25:13 +00:00
if (!__instance._isPlayerInside)
2021-02-16 20:49:10 +00:00
{
2021-12-24 15:25:13 +00:00
fogAlpha = Mathf.InverseLerp(__instance._fogThickness + __instance._fogRolloffDistance, __instance._fogThickness, distanceFromFog);
2021-02-16 20:49:10 +00:00
if (distanceFromFog < 0f)
{
2021-12-24 15:25:13 +00:00
if (__instance.IsLockedByProbeSnapshot() || QuantumManager.IsVisibleUsingCameraFrustum((ShapeVisibilityTracker)__instance._visibilityTracker, true).Item1)
2021-02-16 20:49:10 +00:00
{
2021-12-24 15:25:13 +00:00
__instance._isPlayerInside = true;
__instance.SetSurfaceState(__instance._stateIndex);
Locator.GetShipLogManager().RevealFact(__instance._revealFactID, true, true);
2021-02-16 20:49:10 +00:00
QSBEventManager.FireEvent("PlayerEnterQuantumMoon");
}
else
{
2021-12-24 15:25:13 +00:00
__instance.Collapse(true);
2021-02-16 20:49:10 +00:00
}
}
}
2021-12-24 15:25:13 +00:00
else if (__instance._isPlayerInside)
2021-02-16 20:49:10 +00:00
{
2021-12-24 15:25:13 +00:00
fogAlpha = Mathf.InverseLerp(-__instance._fogThickness - __instance._fogRolloffDistance, -__instance._fogThickness, distanceFromFog);
2021-02-16 20:49:10 +00:00
if (distanceFromFog >= 0f)
{
2021-12-24 15:25:13 +00:00
if (__instance._stateIndex != 5)
2021-02-16 20:49:10 +00:00
{
2021-12-24 15:25:13 +00:00
__instance._isPlayerInside = false;
if (!__instance.IsLockedByProbeSnapshot() && !QuantumManager.IsVisibleUsingCameraFrustum((ShapeVisibilityTracker)__instance._visibilityTracker, true).Item1)
2021-02-16 20:49:10 +00:00
{
2021-12-24 15:25:13 +00:00
__instance.Collapse(true);
2021-02-16 20:49:10 +00:00
}
2021-06-18 22:38:32 +01:00
2021-12-24 15:25:13 +00:00
__instance.SetSurfaceState(-1);
2021-02-16 20:49:10 +00:00
QSBEventManager.FireEvent("PlayerExitQuantumMoon");
}
else
{
var vector = Locator.GetPlayerTransform().position - __instance.transform.position;
2021-12-24 15:25:13 +00:00
Locator.GetPlayerBody().SetVelocity(__instance._moonBody.GetPointVelocity(Locator.GetPlayerTransform().position) - (vector.normalized * 5f));
2021-02-16 20:49:10 +00:00
var d = 80f;
2021-12-24 15:25:13 +00:00
Locator.GetPlayerBody().SetPosition(__instance.transform.position + (__instance._vortexReturnPivot.up * d));
2021-02-16 20:49:10 +00:00
if (!Physics.autoSyncTransforms)
{
Physics.SyncTransforms();
}
2021-06-18 22:38:32 +01:00
2021-02-16 20:49:10 +00:00
var component = Locator.GetPlayerCamera().GetComponent<PlayerCameraController>();
component.SetDegreesY(component.GetMinDegreesY());
2021-12-24 15:25:13 +00:00
__instance._vortexAudio.SetLocalVolume(0f);
__instance._collapseToIndex = 1;
__instance.Collapse(true);
2021-02-16 20:49:10 +00:00
}
}
}
2021-06-18 22:38:32 +01:00
2021-12-24 15:25:13 +00:00
__instance._playerFogBubble.SetFogAlpha(fogAlpha);
__instance._shipLandingCamFogBubble.SetFogAlpha(fogAlpha);
2021-02-16 20:49:10 +00:00
return false;
}
2021-01-18 12:33:07 +00:00
}
}