Skip to content

Commit

Permalink
- Fix animated items reading the wrong vertical offset
Browse files Browse the repository at this point in the history
- Fix alignment on most Placeable surfaces instead of limiting it to the Cupboard only
  • Loading branch information
mattymatty97 committed Oct 21, 2024
1 parent 1213b45 commit c9041d4
Show file tree
Hide file tree
Showing 9 changed files with 153 additions and 96 deletions.
2 changes: 1 addition & 1 deletion Plugin/Plugin.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<RootNamespace>MattyFixes</RootNamespace>
<AssemblyName>$(RootNamespace)</AssemblyName>
<Product>Matty's Fixes</Product>
<Version>1.1.27</Version>
<Version>1.1.29</Version>
<PackageLicenseExpression>GPL-3.0</PackageLicenseExpression>
<TargetFramework>netstandard2.1</TargetFramework>
<LangVersion>Latest</LangVersion>
Expand Down
2 changes: 1 addition & 1 deletion Plugin/src/MattyFixes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ internal partial class MattyFixes : BaseUnityPlugin
{
public const string GUID = "mattymatty.MattyFixes";
public const string NAME = "Matty's Fixes";
public const string VERSION = "1.1.27";
public const string VERSION = "1.1.29";
internal static ManualLogSource Log;

internal static MattyFixes Instance { get; private set; }
Expand Down
8 changes: 2 additions & 6 deletions Plugin/src/Patches/CupBoardFix.cs
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ private static void ShelfCheck(GrabbableObject grabbable, float offset = 0f)
{
foreach (var shelfHolder in closet.Shelves)
{
var hitPoint = shelfHolder.Collider.ClosestPoint(pos);
var hitPoint = shelfHolder.Collider.ClosestPointOnBounds(pos);
var tmp = pos.y - hitPoint.y;

MattyFixes.VerboseCupboardLog(LogLevel.Debug, () =>
Expand All @@ -158,11 +158,7 @@ private static void ShelfCheck(GrabbableObject grabbable, float offset = 0f)
var transform = grabbable.transform;
if (found != null)
{
Vector3 newPos;
if (MattyFixes.PluginConfig.ItemClipping.Enabled.Value)
newPos = ItemPatches.FixPlacement(closest.Value, found.transform, grabbable);
else
newPos = closest.Value + Vector3.up * MattyFixes.PluginConfig.CupBoard.Shift.Value;
Vector3 newPos = closest.Value + Vector3.up * grabbable.itemProperties.verticalOffset; //ItemPatches.FixPlacement(closest.Value, found.transform, grabbable);
transform.parent = closet.gameObject.transform;
transform.position = newPos;
grabbable.targetFloorPosition = transform.localPosition;
Expand Down
90 changes: 47 additions & 43 deletions Plugin/src/Patches/GrabbableStartPatch.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,57 +23,62 @@ internal static void OnObjectSpawn(GrabbableObject __instance)
{
if (!MattyFixes.PluginConfig.ItemClipping.Enabled.Value)
return;

var itemType = __instance.itemProperties;

if (ComputedOffsets.Contains(itemType))
return;

MattyFixes.Log.LogDebug($"{itemType.itemName}({__instance.NetworkObjectId}) needs to compute vertical offset - scheduled");

MattyFixes.Log.LogDebug(
$"{itemType.itemName}({__instance.NetworkObjectId}) needs to compute vertical offset - scheduled");

__instance.StartCoroutine(ProcessGrabbable(__instance));

if (!ShouldSpawnOnGround(__instance) && __instance.transform.parent != CupBoardFix.Closet.gameObject.transform)
if (!ShouldSpawnOnGround(__instance) && __instance.transform.parent != CupBoardFix.Closet.gameObject.transform)
return;

if (!PendingObjects.TryGetValue(itemType, out var list))
{
list = ListPool<GrabbableObject>.Get();
PendingObjects[itemType] = list;
}

list.Add(__instance);

MattyFixes.Log.LogDebug($"{itemType.itemName}({__instance.NetworkObjectId}) will need to update the position - enqueued");

MattyFixes.Log.LogDebug(
$"{itemType.itemName}({__instance.NetworkObjectId}) will need to update the position - enqueued");
}

private static IEnumerator ProcessGrabbable(GrabbableObject grabbable)
{
var itemType = grabbable.itemProperties;
//wait two frames
yield return null;
yield return null;


var animators = grabbable.GetComponentsInChildren<Animator>();

//wait till animators stop
yield return new WaitUntil(() => animators.All(
a => Mathf.Approximately(a.speed, 0f) || a.GetCurrentAnimatorStateInfo(0).normalizedTime >= 1));

//only run the code on the first coroutine that completes
if (!ComputedOffsets.Add(itemType))
yield break;

MattyFixes.Log.LogDebug($"{itemType.itemName}({grabbable.NetworkObjectId}) is computing vertical offset");

var oldOffset = itemType.verticalOffset;
itemType.verticalOffset = ComputeVerticalOffset(grabbable);

var isOriginal = Mathf.Approximately(oldOffset, itemType.verticalOffset);

MattyFixes.Log.LogDebug($"{itemType.itemName} {(isOriginal ? "original" : "new")} offset is {itemType.verticalOffset}");


MattyFixes.Log.LogDebug(
$"{itemType.itemName} {(isOriginal ? "original" : "new")} offset is {itemType.verticalOffset}");

if (isOriginal)
yield break;

if (!PendingObjects.TryGetValue(itemType, out var list))
if (!PendingObjects.TryGetValue(itemType, out var list))
yield break;

foreach (var gObject in list)
{
if (!gObject)
Expand All @@ -82,30 +87,29 @@ private static IEnumerator ProcessGrabbable(GrabbableObject grabbable)
var oldPosition = gObject.targetFloorPosition;
gObject.targetFloorPosition -= Vector3.up * oldOffset;
gObject.targetFloorPosition += Vector3.up * itemType.verticalOffset;

MattyFixes.Log.LogDebug($"{itemType.itemName}({gObject.NetworkObjectId}) position updated [{oldPosition}] -> [{gObject.targetFloorPosition}]");

MattyFixes.Log.LogDebug(
$"{itemType.itemName}({gObject.NetworkObjectId}) position updated [{oldPosition}] -> [{gObject.targetFloorPosition}]");
}

list.Clear();

ListPool<GrabbableObject>.Release(list);

PendingObjects.Remove(itemType);

}


private static float ComputeVerticalOffset(GrabbableObject grabbable)
{

var itemType = grabbable.itemProperties;

try
{
if (MattyFixes.PluginConfig.ItemClipping.ManualOffsetMap.TryGetValue(itemType.itemName,
out var offset))
out var offset))
return offset;

var executionOptions = new ExecutionOptions()
{
VertexCache = VertexesExtensions.GlobalPartialCache,
Expand Down Expand Up @@ -146,16 +150,16 @@ private static IEnumerable<CodeInstruction> RedirectSpawnOnGroundCheck(IEnumerab
var spawnsOnGroundFld = AccessTools.Field(typeof(Item), nameof(Item.itemSpawnsOnGround));

var replacementMethod = AccessTools.Method(typeof(GrabbableStartPatch), nameof(NewSpawnOnGroundCheck));

var matcher = new CodeMatcher(codes);


matcher.MatchForward(false,
matcher.MatchForward(false,
new CodeMatch(OpCodes.Ldarg_0),
new CodeMatch(OpCodes.Ldfld, itemPropertiesFld),
new CodeMatch(OpCodes.Ldfld, spawnsOnGroundFld),
new CodeMatch(OpCodes.Brfalse)
);
);

if (matcher.IsInvalid)
{
Expand All @@ -167,7 +171,7 @@ private static IEnumerable<CodeInstruction> RedirectSpawnOnGroundCheck(IEnumerab
matcher.RemoveInstructions(2);

matcher.Insert(new CodeInstruction(OpCodes.Call, replacementMethod));

MattyFixes.Log.LogDebug("GrabbableObject.Start patched!");

return matcher.Instructions();
Expand All @@ -179,38 +183,38 @@ private static bool NewSpawnOnGroundCheck(GrabbableObject grabbableObject)
$"{grabbableObject.itemProperties.itemName}({grabbableObject.NetworkObjectId}) processing GrabbableObject pos {grabbableObject.transform.position}");

var ret = ShouldSpawnOnGround(grabbableObject);

MattyFixes.VerboseItemsLog(LogLevel.Debug, () =>
$"{grabbableObject.itemProperties.itemName}({grabbableObject.NetworkObjectId}) processing GrabbableObject spawnState " +
$"OnGround - was: {grabbableObject.itemProperties.itemSpawnsOnGround} new:{ret}");

return ret;
}

private static bool ShouldSpawnOnGround(GrabbableObject grabbableObject)
{
var ret = grabbableObject.itemProperties.itemSpawnsOnGround;

//run normal code if settings are off
if (!MattyFixes.PluginConfig.OutOfBounds.Enabled.Value && !MattyFixes.PluginConfig.CupBoard.Enabled.Value)
return ret;

//or if it's one of the pre-existing items
if (grabbableObject is ClipboardItem ||
(grabbableObject is PhysicsProp && grabbableObject.itemProperties.itemName == "Sticky note"))
return ret;

if (StartOfRound.Instance.localPlayerController && !StartOfRoundPatch._isInitializingGame)
if (StartOfRound.Instance.localPlayerController && !StartOfRoundPatch._isInitializingGame)
return ret;

if (MattyFixes.PluginConfig.OutOfBounds.Enabled.Value)
{
ret = StartOfRound.Instance.IsServer;
}

if (!MattyFixes.PluginConfig.CupBoard.Enabled.Value)
if (!MattyFixes.PluginConfig.CupBoard.Enabled.Value)
return ret;

if (CupBoardFix.Closet.gameObject &&
grabbableObject.transform.parent == CupBoardFix.Closet.gameObject.transform)
ret = false;
Expand Down
44 changes: 0 additions & 44 deletions Plugin/src/Patches/ItemPatches.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,47 +25,6 @@ internal static class ItemPatches
private static readonly Dictionary<MeshFilter, Mesh> ReverseMeshMap = new();
private static Vector3 _staticElectricityParticleOffset;

internal static Vector3 FixPlacement(Vector3 hitPoint, Transform shelfTransform, GrabbableObject heldObject)
{
var renderer = shelfTransform.gameObject.GetComponent<Renderer>();
var bounds = renderer?.bounds;

var yOffset = bounds.HasValue ? bounds.Value.extents.y : shelfTransform.localScale.z / 2f;
hitPoint.y = shelfTransform.position.y + yOffset + heldObject.itemProperties.verticalOffset;
return hitPoint;
}

[HarmonyPrefix]
[HarmonyPatch(typeof(PlaceableObjectsSurface), nameof(PlaceableObjectsSurface.itemPlacementPosition))]
private static bool ItemPlacementPositionPatch(PlaceableObjectsSurface __instance, ref Vector3 __result,
Transform gameplayCamera, GrabbableObject heldObject)
{
if (!MattyFixes.PluginConfig.ItemClipping.Enabled.Value)
return true;

//only tweak if we're placing inside the CupBoard
if (__instance.transform.parent.parent != CupBoardFix.Closet.gameObject?.transform)
return true;

try
{
if (Physics.Raycast(gameplayCamera.position, gameplayCamera.forward, out var val, 7f,
1073744640, (QueryTriggerInteraction)1))
{
var hitPoint = __instance.placeableBounds.ClosestPoint(val.point);
__result = FixPlacement(hitPoint, __instance.transform, heldObject);
return false;
}

__result = Vector3.zero;
return false;
}
catch (Exception ex)
{
MattyFixes.Log.LogError($"Exception while finding the Cupboard Placement {ex}");
return true;
}
}

private static void UpdateItemRotation(string modName, Item item)
{
Expand Down Expand Up @@ -158,9 +117,6 @@ private static void RegisterItems(StartOfRound __instance, bool __runOriginal)
}
}




[HarmonyPatch(typeof(NetworkBehaviour), nameof(NetworkBehaviour.OnNetworkSpawn))]
internal static class NetworkSpawnPatch
{
Expand Down
38 changes: 38 additions & 0 deletions Plugin/src/Patches/PlaceableSurfacePatch.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
using System;
using HarmonyLib;
using UnityEngine;

namespace MattyFixes.Patches;

[HarmonyPatch]
public static class PlaceableSurfacePatch
{

[HarmonyPrefix]
[HarmonyPatch(typeof(PlaceableObjectsSurface), nameof(PlaceableObjectsSurface.itemPlacementPosition))]
private static bool ItemPlacementPositionPatch(PlaceableObjectsSurface __instance, ref Vector3 __result,
Transform gameplayCamera, GrabbableObject heldObject)
{
if (!MattyFixes.PluginConfig.CupBoard.Enabled.Value)
return true;

try
{
if (Physics.Raycast(gameplayCamera.position, gameplayCamera.forward, out var val, 7f,
1073744640, QueryTriggerInteraction.Ignore))
{
var hitPoint = val.collider.ClosestPointOnBounds(val.point);
__result = hitPoint + Vector3.up * heldObject.itemProperties.verticalOffset;
return false;
}

__result = Vector3.zero;
return false;
}
catch (Exception ex)
{
MattyFixes.Log.LogError($"Exception while finding the Placement {ex}");
return true;
}
}
}
59 changes: 59 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
Matty's Fixes
============
[![GitHub Release](https://img.shields.io/github/v/release/mattymatty97/LTC_MattyFixes?display_name=release&logo=github&logoColor=white)](https://github.com/mattymatty97/LTC_MattyFixes/releases/latest)
[![GitHub Pre-Release](https://img.shields.io/github/v/release/mattymatty97/LTC_MattyFixes?include_prereleases&display_name=release&logo=github&logoColor=white&label=preview)](https://github.com/mattymatty97/LTC_MattyFixes/releases)
[![Thunderstore Downloads](https://img.shields.io/thunderstore/dt/mattymatty/Matty_Fixes?style=flat&logo=thunderstore&logoColor=white&label=thunderstore)](https://thunderstore.io/c/lethal-company/p/mattymatty/Matty_Fixes/)


A collection of Fixes for the vanilla game, with focus on vanilla compatibility.

some of the changes will only be visible to players with the mod installed ( it is suggested for everybody to have the mod )

**This mod is 100% Vanilla Compatible** and does not change any of the vanilla gameplay.

Patches:
--------
- ### Storage Cabinet
- **fix items inside of Storage Cabinet falling to the ground on load**
- **fix items on top of Storage Cabinet falling to the ground on load**
- ### ItemClippingFix
- **fix rotation of some items while dropped**
- **prevent items from clipping into the ground**
- **recalculate the offset from ground based on the actual item model**
- ### RadarFixes
- **fix orphaned radar icons from deleted scrap**
( scarp sold will appear on the radar in all the maps )
- **fix items from a newly created lobby being visible on the radar**
- ### OutOfBounds Patch
- prevent items from falling **below of the ship**
- prevent items from **generating inside furniture**
( eg: kitchen counter )
- ### Alternate Lightning Particles
- show particles around items in a sphere
- ### Readable Meshes
- mark conductive item meshes as readable to fix various vanilla bugs:
- Stormy weather spamming zero_surface_area warnings
- Lightning particle showing as a point instead of on the item model

Differences to [ItemClippingFix](https://thunderstore.io/c/lethal-company/p/ViViKo/ItemClippingFix/)
------------------------
This mod uses the same values from ItemClippingFix but additionally:
- fixes the rotation of Objects in a newly hosted game
- fixes items clipping into the ground ( included modded ones )

Differences to [CupboardFix](https://thunderstore.io/c/lethal-company/p/Rocksnotch/CupboardFix/)
------------------------
CupboardFix removes the gravity from all item types that are above the ground and never resets it,
this causes a lot of items to spawn floating both from the DropShip and inside the Factory.
This mod instead only affects the items specifically inside the Closet and above it,
additionally snaps the items to the shelves and forces the parent to the closet itself allowing you to move them together with the closet,
as would happen if you had deposited the items manually inside

Installation
------------

- Install [BepInEx](https://thunderstore.io/c/lethal-company/p/BepInEx/BepInExPack/)
- Unzip this mod into your `Lethal Company/BepInEx/plugins` folder

Or use the mod manager to handle the installing for you.

Loading

0 comments on commit c9041d4

Please sign in to comment.