2021-11-10 23:55:39 -08:00
|
|
|
|
using System;
|
2021-11-12 22:34:28 -08:00
|
|
|
|
using System.Linq;
|
2021-11-10 23:55:39 -08:00
|
|
|
|
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)
|
|
|
|
|
{
|
2021-11-12 02:24:27 -08:00
|
|
|
|
var qsbMeteorLauncher = QSBWorldSync.GetWorldFromUnity<QSBMeteorLauncher>(__instance);
|
|
|
|
|
|
2021-11-11 02:08:03 -08:00
|
|
|
|
MeteorController meteorController = null;
|
2021-11-12 22:34:28 -08:00
|
|
|
|
QSBMeteor qsbMeteor = null;
|
|
|
|
|
|
|
|
|
|
bool MeteorMatches(MeteorController x)
|
2021-11-11 02:08:03 -08:00
|
|
|
|
{
|
2021-11-12 22:34:28 -08:00
|
|
|
|
qsbMeteor = QSBWorldSync.GetWorldFromUnity<QSBMeteor>(x);
|
|
|
|
|
return qsbMeteor.ObjectId == qsbMeteorLauncher.MeteorId;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (__instance._meteorPool != null)
|
|
|
|
|
{
|
|
|
|
|
var poolIndex = __instance._meteorPool.FindIndex(MeteorMatches);
|
|
|
|
|
if (poolIndex != -1)
|
2021-11-11 02:08:03 -08:00
|
|
|
|
{
|
2021-11-12 02:24:27 -08:00
|
|
|
|
meteorController = __instance._meteorPool[poolIndex];
|
2021-11-11 02:08:03 -08:00
|
|
|
|
meteorController.Initialize(__instance.transform, __instance._detectableField, __instance._detectableFluid);
|
2021-11-12 02:24:27 -08:00
|
|
|
|
__instance._meteorPool.QuickRemoveAt(poolIndex);
|
2021-11-11 02:08:03 -08:00
|
|
|
|
__instance._launchedMeteors.Add(meteorController);
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-11-12 22:34:28 -08:00
|
|
|
|
else if (__instance._dynamicMeteorPool != null)
|
2021-11-11 02:08:03 -08:00
|
|
|
|
{
|
2021-11-12 22:34:28 -08:00
|
|
|
|
var poolIndex = __instance._dynamicMeteorPool.FindIndex(MeteorMatches);
|
|
|
|
|
if (poolIndex != -1)
|
|
|
|
|
{
|
|
|
|
|
meteorController = __instance._dynamicMeteorPool[poolIndex];
|
|
|
|
|
meteorController.Initialize(__instance.transform, null, null);
|
|
|
|
|
__instance._dynamicMeteorPool.QuickRemoveAt(poolIndex);
|
|
|
|
|
__instance._launchedDynamicMeteors.Add(meteorController);
|
|
|
|
|
}
|
2021-11-11 02:08:03 -08:00
|
|
|
|
}
|
|
|
|
|
if (meteorController != null)
|
|
|
|
|
{
|
|
|
|
|
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);
|
|
|
|
|
}
|
2021-11-12 22:34:28 -08:00
|
|
|
|
DebugLog.DebugWrite($"{qsbMeteorLauncher.LogName} - launch {qsbMeteor.LogName} {launchSpeed}");
|
2021-11-11 02:08:03 -08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2021-11-12 22:34:28 -08:00
|
|
|
|
[HarmonyPostfix]
|
|
|
|
|
[HarmonyPatch(typeof(MeteorController), nameof(MeteorController.Launch))]
|
|
|
|
|
public static void Launch(MeteorController __instance,
|
|
|
|
|
Transform parent, Vector3 worldPosition, Quaternion worldRotation, Vector3 linearVelocity, Vector3 angularVelocity)
|
|
|
|
|
{
|
|
|
|
|
__instance.gameObject.SetActive(true);
|
|
|
|
|
__instance.transform.SetParent(parent);
|
|
|
|
|
__instance.transform.SetPositionAndRotation(worldPosition, worldRotation);
|
|
|
|
|
__instance._owRigidbody.MakeNonKinematic();
|
|
|
|
|
__instance._owRigidbody.SetVelocity(linearVelocity);
|
|
|
|
|
__instance._owRigidbody.SetAngularVelocity(angularVelocity);
|
|
|
|
|
__instance._intactRenderer.enabled = true;
|
|
|
|
|
__instance._glowLight.intensity = __instance._lightStartIntensity;
|
|
|
|
|
__instance._smokeTrail.enabled = true;
|
|
|
|
|
__instance._smokeTrail.GetParticleSystem().Play();
|
|
|
|
|
__instance._suspended = false;
|
|
|
|
|
__instance._hasLaunched = true;
|
|
|
|
|
__instance._launchTime = Time.time;
|
|
|
|
|
__instance._hasImpacted = false;
|
|
|
|
|
__instance._impactTime = 0f;
|
|
|
|
|
__instance._heat = 1f;
|
|
|
|
|
}
|
2021-11-11 02:16:14 -08:00
|
|
|
|
|
|
|
|
|
|
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 22:34:28 -08:00
|
|
|
|
var componentInParent = hitObject.GetComponentInParent<FragmentIntegrity>();
|
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 22:34:28 -08:00
|
|
|
|
__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 22:34:28 -08:00
|
|
|
|
if (qsbMeteor.ShouldImpact)
|
2021-11-12 01:22:09 -08:00
|
|
|
|
{
|
|
|
|
|
DebugLog.DebugWrite($"{qsbMeteor.LogName} - impact! {hitObject.name} {impactPoint} {impactVel} {damage}");
|
2021-11-12 22:34:28 -08:00
|
|
|
|
qsbMeteor.ShouldImpact = false;
|
2021-11-12 01:22:09 -08:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2021-11-12 22:34:28 -08:00
|
|
|
|
DebugLog.ToConsole($"{qsbMeteor.LogName} - impacted locally, but not on server. THIS SHOULD BE IMPOSSIBLE", MessageType.Error);
|
2021-11-12 01:22:09 -08:00
|
|
|
|
}
|
|
|
|
|
|
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);
|
2021-11-12 22:34:28 -08:00
|
|
|
|
if (qsbMeteor.ShouldImpact)
|
|
|
|
|
{
|
|
|
|
|
DebugLog.ToConsole($"{qsbMeteor.LogName} - impacted on server, but not locally", MessageType.Error);
|
|
|
|
|
qsbMeteor.ShouldImpact = false;
|
|
|
|
|
}
|
2021-11-10 23:55:39 -08:00
|
|
|
|
DebugLog.DebugWrite($"{qsbMeteor.LogName} - suspended");
|
|
|
|
|
}
|
2021-11-10 21:13:49 -08:00
|
|
|
|
}
|
|
|
|
|
}
|