diff --git a/CLre/API/Engines/FrontEndEngines.cs b/CLre/API/Engines/FrontEndEngines.cs index 62b8cf7..f066e6b 100644 --- a/CLre/API/Engines/FrontEndEngines.cs +++ b/CLre/API/Engines/FrontEndEngines.cs @@ -86,9 +86,9 @@ namespace CLre.API.Engines [HarmonyPatch(typeof(FrontEnd.MainFrontEnd), "BuildEngines")] class MainFrontEnd_BuildEngines_Patch { - internal static FasterList beforeBuildEngines = new FasterList(); + internal static FasterList beforeBuildEngines = new FasterList(); - internal static FasterList afterBuildEngines = new FasterList(); + internal static FasterList afterBuildEngines = new FasterList(); internal static MethodInfo addEngine = AccessTools.Method(typeof(FrontEnd.MainFrontEnd), "AddEngine"); diff --git a/CLre/API/Engines/GameEngines.cs b/CLre/API/Engines/GameEngines.cs index 0c776ee..ebb26d2 100644 --- a/CLre/API/Engines/GameEngines.cs +++ b/CLre/API/Engines/GameEngines.cs @@ -31,9 +31,9 @@ namespace CLre.API.Engines [HarmonyPatch(typeof(GameFramework.MainLevel), "BuildDeprecatedEngines")] class MainLevel_BuildDeprecatedEngines_Patch { - internal static FasterList beforeBuildEngines = new FasterList(); + internal static FasterList beforeBuildEngines = new FasterList(); - internal static FasterList afterBuildEngines = new FasterList(); + internal static FasterList afterBuildEngines = new FasterList(); [HarmonyPrefix] public static void BeforeMethodCall(GameFramework.MainLevel __instance) diff --git a/CLre/CLre.cs b/CLre/CLre.cs index 2bc4b61..1784aad 100644 --- a/CLre/CLre.cs +++ b/CLre/CLre.cs @@ -49,6 +49,7 @@ namespace CLre // patches for bugs Fixes.InitLogSooner.Init(); Fixes.MiniScreenHelper.Init(); + Fixes.UnderStructureCollider.Init(); // misc LogIPAPlugins(); @@ -119,7 +120,7 @@ namespace CLre int modCount = IllusionInjector.PluginManager.Plugins.Count(); StringBuilder sb = new StringBuilder(); sb.AppendFormat(" {0} {1}\n", Name, Version); - sb.AppendFormat("{0} bugfixes, {1} plugins, no frills\n", fixCount, modCount); + sb.AppendFormat(" {0} bugfixes, {1} plugins, no frills\n", fixCount, modCount); #if DEBUG sb.AppendFormat(" DEBUG version\n"); #endif diff --git a/CLre/Fixes/UnderStructureCollider.cs b/CLre/Fixes/UnderStructureCollider.cs new file mode 100644 index 0000000..03d7a95 --- /dev/null +++ b/CLre/Fixes/UnderStructureCollider.cs @@ -0,0 +1,186 @@ +using System.Collections; +using System.Reflection; +using CLre.API.Engines; +using Game.Building; +using Game.Character; +using Game.Utilities; +using HarmonyLib; +using Svelto.ECS; +using Svelto.Tasks; +using UnityEngine; +using voxelfarm.VFCol; + +namespace CLre.Fixes +{ + [Bugfix(name = "UnderStructureCollider", + description = "Prevent passing through structures from below a bit better", + more = "https://trello.com/c/nfuaZWQZ/10-passing-through-structures", + component = BugfixType.Initialiser, id = 7)] + public static class UnderStructureCollider + { + public static void Init() + { +#if DEBUG + MainLevel_BuildDeprecatedEngines_Patch.afterBuildEngines.Add(new CharacterGroundedCheckEngine()); +#endif + MainLevel_BuildDeprecatedEngines_Patch.afterBuildEngines.Add(new CharacterUnderStructureRaycastEngine()); + } + } + + [Bugfix(name = "UnderStructureCollider", + description = "Prevent passing through structures from below a bit better", + more = "https://trello.com/c/nfuaZWQZ/10-passing-through-structures", + component = BugfixType.HarmonyPatch, id = 7)] + [HarmonyPatch(typeof(VFColUtility), "Move")] + class VFCOlUtility_Move_Patch + { + internal static bool Override = false; + + [HarmonyPostfix] + public static void AfterMethodCall(ref Vector3 __result) + { +#if DEBUG + API.Utility.Logging.MetaLog("Intercepting CharacterMovementEngine.ApplyForces(...)"); +#endif + if (Override) + { + if (__result.y > 0) + { + __result = Vector3.zero; + } + } + } + } + +#if DEBUG + [Bugfix(name = "UnderStructureCollider", + description = "Prevent passing through structures from below a bit better", + more = "https://trello.com/c/nfuaZWQZ/10-passing-through-structures", + component = BugfixType.Debug, id = 7)] + public class CharacterGroundedCheckEngine : SingleEntityViewEngine, ICLreEngine + { + private CharacterOnStructureNode _characterOnStructureNode; + + public void Ready() {} + + public IEntitiesDB entitiesDB { get; set; } + public IEntityFactory entityFactory { get; set; } + + protected override void Add(CharacterOnStructureNode entityView) + { + _characterOnStructureNode = entityView; + CheckNode().Run(); + } + + protected override void Remove(CharacterOnStructureNode entityView) + { + _characterOnStructureNode = null; + } + + public IEnumerator CheckNode() + { + while (_characterOnStructureNode != null) + { + if (_characterOnStructureNode.characterGroundedRaycastComponent.didHit) + { + if (_characterOnStructureNode.characterGroundedRaycastComponent.hitResult.transform != null) + { + API.Utility.Logging.MetaLog($"HIT: {_characterOnStructureNode.characterGroundedRaycastComponent.hitResult.transform.tag} (audio: '{_characterOnStructureNode.characterOnStructureComponent.characterPositionStructureAudioSwitch.value}')"); + RaycastHit raycastHitInfo = _characterOnStructureNode.characterGroundedRaycastComponent.hitResult; + if (raycastHitInfo.transform.tag == GameTags.STRUCTURE_TAG) + { + int instanceID = raycastHitInfo.transform.GetComponentInParent().gameObject.GetInstanceID(); + if (entitiesDB.TryQueryEntityView(instanceID, DEPRECATED_SveltoExtensions.DEPRECATED_GROUP, + out PlacedStructureNode entityView)) + { + API.Utility.Logging.MetaLog($"Structure: {entityView.structureNameComponent.resourceName}"); + } + } + } + else + { + API.Utility.Logging.MetaLog("No transform (not on a structure?)"); + } + + } + else + { + API.Utility.Logging.MetaLog("No hit"); + } + yield return null; + } + } + } +#endif + + [Bugfix(name = "UnderStructureCollider", + description = "Prevent passing through structures from below a bit better", + more = "https://trello.com/c/nfuaZWQZ/10-passing-through-structures", + component = BugfixType.Miscellaneous, id = 7)] + public class CharacterUnderStructureRaycastEngine : SingleEntityViewEngine, ICLreEngine + { + private bool _playerExists = false; + + private int _layer = GameLayers.CARD_INTERACTABLE; + + public void Ready() + { + } + + public IEntitiesDB entitiesDB { get; set; } + public IEntityFactory entityFactory { get; set; } + + protected override void Add(CharacterMovementNode entityView) + { + _playerExists = true; + RaycastStructureCheck(entityView.ID.entityID).RunOnScheduler(StandardSchedulers.physicScheduler); + } + + protected override void Remove(CharacterMovementNode entityView) + { + _playerExists = false; + } + + public IEnumerator RaycastStructureCheck(int playerId) + { + while (_playerExists) + { + CharacterMovementNode cmn; + while (entitiesDB.TryQueryEntityView(playerId, DEPRECATED_SveltoExtensions.DEPRECATED_GROUP, out cmn)) + { + Vector3 position = cmn.characterMovementComponent.characterController.transform.position; + CharacterController cc = cmn.characterMovementComponent.characterController; + RaycastHit rayInfo; + bool didHit = Physics.SphereCast( + position, //+ Vector3.up * (cc.height * 0.5f), // center of player + cc.radius, + Vector3.up, + out rayInfo, + cc.height, //* 0.5f - cc.radius * 0.05f, + _layer); + if (didHit && rayInfo.transform != null) + { + if (rayInfo.transform.CompareTag(GameTags.STRUCTURE_TAG)) + { +#if DEBUG + API.Utility.Logging.MetaLog("Structure is above me!"); +#endif + VFCOlUtility_Move_Patch.Override = true; + } + } + else + { +#if DEBUG + API.Utility.Logging.MetaLog("No structure above :("); +#endif + VFCOlUtility_Move_Patch.Override = false; + } + yield return null; + } + + yield return null; + } + + } + } +} \ No newline at end of file