quantum-space-buddies/QSB/MeteorSync/Patches/MeteorClientPatches.cs

189 lines
6.2 KiB
C#
Raw Normal View History

2021-11-10 23:55:39 -08:00
using System;
using HarmonyLib;
2021-11-12 01:55:43 -08:00
using OWML.Common;
2021-11-10 21:36:30 -08:00
using QSB.MeteorSync.WorldObjects;
2021-11-10 21:13:49 -08:00
using QSB.Patches;
2021-11-10 23:55:39 -08:00
using QSB.Utility;
2021-11-10 21:36:30 -08:00
using QSB.WorldSync;
using UnityEngine;
2021-11-11 02:08:03 -08:00
using Random = UnityEngine.Random;
2021-11-10 21:13:49 -08:00
namespace QSB.MeteorSync.Patches
{
public class MeteorClientPatches : QSBPatch
{
public override QSBPatchTypes Type => QSBPatchTypes.OnNonServerClientConnect;
[HarmonyPrefix]
[HarmonyPatch(typeof(MeteorLauncher), nameof(MeteorLauncher.FixedUpdate))]
public static bool FixedUpdate(MeteorLauncher __instance)
{
if (__instance._launchedMeteors != null)
{
for (var i = __instance._launchedMeteors.Count - 1; i >= 0; i--)
{
if (__instance._launchedMeteors[i] == null)
{
__instance._launchedMeteors.QuickRemoveAt(i);
}
else if (__instance._launchedMeteors[i].isSuspended)
{
__instance._meteorPool.Add(__instance._launchedMeteors[i]);
__instance._launchedMeteors.QuickRemoveAt(i);
}
}
}
if (__instance._launchedDynamicMeteors != null)
{
for (var j = __instance._launchedDynamicMeteors.Count - 1; j >= 0; j--)
{
if (__instance._launchedDynamicMeteors[j] == null)
{
__instance._launchedDynamicMeteors.QuickRemoveAt(j);
}
else if (__instance._launchedDynamicMeteors[j].isSuspended)
{
__instance._dynamicMeteorPool.Add(__instance._launchedDynamicMeteors[j]);
__instance._launchedDynamicMeteors.QuickRemoveAt(j);
}
}
}
2021-11-10 21:36:30 -08:00
// skip meteor launching
2021-11-10 21:13:49 -08:00
return false;
}
2021-11-11 02:08:03 -08:00
[HarmonyPrefix]
[HarmonyPatch(typeof(MeteorLauncher), nameof(MeteorLauncher.LaunchMeteor))]
public static bool LaunchMeteor(MeteorLauncher __instance)
{
var flag = __instance._dynamicMeteorPool != null && (__instance._meteorPool == null || Random.value < __instance._dynamicProbability);
MeteorController meteorController = null;
if (!flag)
{
if (__instance._meteorPool.Count == 0)
{
Debug.LogWarning("MeteorLauncher is out of Meteors!", __instance);
}
else
{
meteorController = __instance._meteorPool[__instance._meteorPool.Count - 1];
meteorController.Initialize(__instance.transform, __instance._detectableField, __instance._detectableFluid);
__instance._meteorPool.QuickRemoveAt(__instance._meteorPool.Count - 1);
__instance._launchedMeteors.Add(meteorController);
}
}
else if (__instance._dynamicMeteorPool.Count == 0)
{
Debug.LogWarning("MeteorLauncher is out of Dynamic Meteors!", __instance);
}
else
{
meteorController = __instance._dynamicMeteorPool[__instance._dynamicMeteorPool.Count - 1];
meteorController.Initialize(__instance.transform, null, null);
__instance._dynamicMeteorPool.QuickRemoveAt(__instance._dynamicMeteorPool.Count - 1);
__instance._launchedDynamicMeteors.Add(meteorController);
}
if (meteorController != null)
{
var qsbMeteorLauncher = QSBWorldSync.GetWorldFromUnity<QSBMeteorLauncher>(__instance);
var launchSpeed = qsbMeteorLauncher.LaunchSpeed;
var linearVelocity = __instance._parentBody.GetPointVelocity(__instance.transform.position) + __instance.transform.TransformDirection(__instance._launchDirection) * launchSpeed;
var angularVelocity = __instance.transform.forward * 2f;
meteorController.Launch(null, __instance.transform.position, __instance.transform.rotation, linearVelocity, angularVelocity);
if (__instance._audioSector.ContainsOccupant(DynamicOccupant.Player))
{
__instance._launchSource.pitch = Random.Range(0.4f, 0.6f);
__instance._launchSource.PlayOneShot(AudioType.BH_MeteorLaunch);
}
}
return false;
}
[HarmonyPrefix]
[HarmonyPatch(typeof(MeteorController), nameof(MeteorController.OnCollisionEnter))]
public static bool OnCollisionEnter(MeteorController __instance,
Collision collision)
=> false;
2021-11-10 21:36:30 -08:00
[HarmonyPrefix]
[HarmonyPatch(typeof(MeteorController), nameof(MeteorController.Impact))]
public static bool Impact(MeteorController __instance,
GameObject hitObject, Vector3 impactPoint, Vector3 impactVel)
{
var qsbMeteor = QSBWorldSync.GetWorldFromUnity<QSBMeteor>(__instance);
2021-11-12 01:22:09 -08:00
var componentInParent = hitObject != null ? hitObject.GetComponentInParent<FragmentIntegrity>() : null;
2021-11-10 23:55:39 -08:00
var damage = qsbMeteor.Damage;
2021-11-10 21:36:30 -08:00
if (componentInParent != null)
{
if (!componentInParent.GetIgnoreMeteorDamage())
{
componentInParent.AddDamage(damage);
}
else if (componentInParent.GetParentFragment() != null && !componentInParent.GetParentFragment().GetIgnoreMeteorDamage())
{
componentInParent.GetParentFragment().AddDamage(damage);
}
}
MeteorImpactMapper.RecordImpact(impactPoint, componentInParent);
__instance._intactRenderer.enabled = false;
__instance._impactLight.enabled = true;
__instance._impactLight.intensity = __instance._impactLightCurve.Evaluate(0f);
var rotation = Quaternion.LookRotation(impactVel);
foreach (var particleSystem in __instance._impactParticles)
{
particleSystem.transform.rotation = rotation;
particleSystem.Play();
}
__instance._impactSource.PlayOneShot(AudioType.BH_MeteorImpact);
2021-11-10 21:13:49 -08:00
foreach (var owCollider in __instance._owColliders)
{
owCollider.SetActivation(false);
}
__instance._owRigidbody.MakeKinematic();
2021-11-12 01:22:09 -08:00
if (hitObject != null)
{
__instance.transform.SetParent(hitObject.GetAttachedOWRigidbody().transform);
}
2021-11-10 21:36:30 -08:00
FragmentSurfaceProxy.UntrackMeteor(__instance);
FragmentCollisionProxy.UntrackMeteor(__instance);
__instance._ignoringCollisions = false;
__instance._hasImpacted = true;
__instance._impactTime = Time.time;
2021-11-12 01:22:09 -08:00
if (hitObject != null)
{
DebugLog.DebugWrite($"{qsbMeteor.LogName} - impact! {hitObject.name} {impactPoint} {impactVel} {damage}");
}
else
{
DebugLog.ToConsole($"{qsbMeteor.LogName} - got impact from server, but found no hit object locally "
+ $"({impactPoint} {impactVel} {damage})", MessageType.Error);
}
2021-11-10 21:36:30 -08:00
return false;
2021-11-10 21:13:49 -08:00
}
2021-11-10 23:55:39 -08:00
[HarmonyPostfix]
[HarmonyPatch(typeof(MeteorController), nameof(MeteorController.Suspend), new Type[0])]
public static void Suspend(MeteorController __instance)
{
if (!MeteorManager.MeteorsReady)
{
return;
}
var qsbMeteor = QSBWorldSync.GetWorldFromUnity<QSBMeteor>(__instance);
DebugLog.DebugWrite($"{qsbMeteor.LogName} - suspended");
}
2021-11-10 21:13:49 -08:00
}
}