From e31532c7f38a6d75e29e4f0259c1301514e37fcd Mon Sep 17 00:00:00 2001 From: "NGnius (Graham)" Date: Sat, 24 Apr 2021 17:21:12 -0400 Subject: [PATCH] Initial camera work --- .gitmodules | 3 + HelloModdingWorld/MyPlugin.cs | 52 ------------- LICENSE | 2 +- HelloModdingWorld.sln => NScript.sln | 2 +- NScript/CameraEngine.cs | 66 ++++++++++++++++ NScript/CameraPatch.cs | 60 +++++++++++++++ NScript/Filmscript/GeneralBindings.cs | 29 +++++++ .../NScript.csproj | 0 NScript/NScriptPlugin.cs | 76 +++++++++++++++++++ README.md | 30 ++------ filmscript-rs | 1 + 11 files changed, 242 insertions(+), 79 deletions(-) create mode 100644 .gitmodules delete mode 100644 HelloModdingWorld/MyPlugin.cs rename HelloModdingWorld.sln => NScript.sln (85%) create mode 100644 NScript/CameraEngine.cs create mode 100644 NScript/CameraPatch.cs create mode 100644 NScript/Filmscript/GeneralBindings.cs rename HelloModdingWorld/HelloModdingWorld.csproj => NScript/NScript.csproj (100%) create mode 100644 NScript/NScriptPlugin.cs create mode 160000 filmscript-rs diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..0c67a3f --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "filmscript-rs"] + path = filmscript-rs + url = https://git.exmods.org/NGnius/filmscript-rs diff --git a/HelloModdingWorld/MyPlugin.cs b/HelloModdingWorld/MyPlugin.cs deleted file mode 100644 index d261f30..0000000 --- a/HelloModdingWorld/MyPlugin.cs +++ /dev/null @@ -1,52 +0,0 @@ -using System.Reflection; - -using IllusionPlugin; -//using GamecraftModdingAPI; - -namespace HelloModdingWorld -{ - public class MyPlugin : IEnhancedPlugin // the Illusion Plugin Architecture (IPA) will ignore classes that don't implement IPlugin' - { - public override string Name { get; } = Assembly.GetExecutingAssembly().GetName().Name; // HelloModdingWorld by default - // To change the name, change the project's name - - public override string Version { get; } = Assembly.GetExecutingAssembly().GetName().Version.ToString(); // 0.0.1 by default - // To change the version, change 0.0.1 in HelloModdingWorld.csproj - - // called when Gamecraft shuts down - public override void OnApplicationQuit() - { - // Shutdown this mod - GamecraftModdingAPI.Utility.Logging.LogDebug($"{Name} has shutdown"); - - // Shutdown the Gamecraft modding API last - GamecraftModdingAPI.Main.Shutdown(); - } - - // called when Gamecraft starts up - public override void OnApplicationStart() - { - // Initialize the Gamecraft modding API first - GamecraftModdingAPI.Main.Init(); - // check out the modding API docs here: https://mod.exmods.org/ - - // Initialize this mod - // create HelloWorld command - // this writes "Hello modding world!" when you execute it in Gamecraft's console - // (use the forward-slash key '/' to open the console in Gamecraft when in a game) - GamecraftModdingAPI.Commands.CommandBuilder.Builder() - .Name("HelloWorld") // command name (used to invoke it in the console) - .Description("Says Hello modding world!") // command description (displayed in help and hint toolbar) - .Action(() => { GamecraftModdingAPI.Utility.Logging.CommandLog("Hello modding world!"); }) - .Build(); // construct and automatically register the command so the modding API knows about it - - GamecraftModdingAPI.Utility.Logging.MetaLog($"{Name} has started up"); - } - - // unused methods - - public override void OnFixedUpdate() { } // called once per physics update - - public override void OnUpdate() { } // called once per rendered frame (frame update) - } -} diff --git a/LICENSE b/LICENSE index d449d3e..3237729 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) +Copyright (c) 2021 NGnius Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/HelloModdingWorld.sln b/NScript.sln similarity index 85% rename from HelloModdingWorld.sln rename to NScript.sln index 53b74f0..68f1e04 100644 --- a/HelloModdingWorld.sln +++ b/NScript.sln @@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 16 VisualStudioVersion = 16.0.29609.76 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HelloModdingWorld", "HelloModdingWorld\HelloModdingWorld.csproj", "{E0EEA15D-AB3C-4C73-A000-C49B5AE9EA66}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NScript", "NScript\NScript.csproj", "{E0EEA15D-AB3C-4C73-A000-C49B5AE9EA66}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/NScript/CameraEngine.cs b/NScript/CameraEngine.cs new file mode 100644 index 0000000..4c30e31 --- /dev/null +++ b/NScript/CameraEngine.cs @@ -0,0 +1,66 @@ +using GamecraftModdingAPI.Engines; +using GamecraftModdingAPI.Tasks; +using RobocraftX.Character; +using RobocraftX.Character.Movement; +using Svelto.DataStructures; +using Svelto.ECS; +using Techblox.Camera; + +namespace NScript +{ + class CameraEngine: IApiEngine + { + private Repeatable task; + + private bool isDisposed = false; + + public static bool useDefaultBehaviour = true; + + public void Ready() + { + task = new Repeatable( + Tick, + () => !(isDisposed && entitiesDB != null) + ); + Scheduler.Schedule(task); + } + + public EntitiesDB entitiesDB { get; set; } + + public void Dispose() + { + isDisposed = true; + } + + public string Name { get; } = "NScriptModCameraEngine"; + public bool isRemovable { get; } = true; + + private void Tick() + { + if (useDefaultBehaviour) return; + entitiesDB.QueryEntities(CharacterExclusiveGroups.OnFootGroup) + .Deconstruct(out NB tags, out int count); + for (int i = 0; i < count; i++) + { + if (entitiesDB.TryQueryEntitiesAndIndex(tags[i].ID.entityID, CameraExclusiveGroups.CameraGroup, + out uint index, out NB cams)) + { + ref var ccses = ref entitiesDB.QueryEntity(tags[i].ID.entityID, + CameraExclusiveGroups.CameraGroup); + ccses.targetPosition.y += 1; + cams[index].targetPosition.y += 1; + cams[index].position.y += 1; + cams[index].smoothedDistance = 0; + } + } + entitiesDB.QueryEntities(CameraExclusiveGroups.VisualCameraGroup) + .Deconstruct(out NB cces, out int count2); + for (int i = 0; i < count; i++) + { + cces[i].position.y += 1; + cces[i].targetPosition.y += 1; + } + GamecraftModdingAPI.Utility.Logging.MetaLog($"Ticked on {count+count2} cameras ({count} C & {count2} VC)"); + } + } +} \ No newline at end of file diff --git a/NScript/CameraPatch.cs b/NScript/CameraPatch.cs new file mode 100644 index 0000000..070bc01 --- /dev/null +++ b/NScript/CameraPatch.cs @@ -0,0 +1,60 @@ +using System.Reflection; +using HarmonyLib; +using Svelto.ECS; +using Unity.Jobs; + +namespace NScript +{ + [HarmonyPatch] + class CameraPatch + { + public static bool AllowDefaultBehaviour = true; + + public static bool Prefix(in float deltaTime, ExclusiveGroup cameraGroup) + { + if (!AllowDefaultBehaviour) GamecraftModdingAPI.Utility.Logging.MetaLog("Doing custom camera"); + return AllowDefaultBehaviour; + } + + [HarmonyTargetMethod] + static MethodBase Target() + { + return AccessTools.Method("Techblox.Camera.CharacterCameraMovementEngine:SimulateCameras"); + } + + } + + [HarmonyPatch] + class RotationPatch + { + public static bool Prefix(JobHandle jobHandle, ref JobHandle __result) + { + if (!CameraPatch.AllowDefaultBehaviour) GamecraftModdingAPI.Utility.Logging.MetaLog("Doing custom rotation"); + __result = default(JobHandle); + return CameraPatch.AllowDefaultBehaviour; + } + + [HarmonyTargetMethod] + static MethodBase Target() + { + return AccessTools.Method("Techblox.Camera.VisualCameraRotationEngine:Execute"); + } + } + + [HarmonyPatch] + class VisualPatch + { + public static bool Prefix(JobHandle jobHandle, ref JobHandle __result) + { + if (!CameraPatch.AllowDefaultBehaviour) GamecraftModdingAPI.Utility.Logging.MetaLog("Doing custom visual"); + __result = default(JobHandle); + return CameraPatch.AllowDefaultBehaviour; + } + + [HarmonyTargetMethod] + static MethodBase Target() + { + return AccessTools.Method("Techblox.Camera.VisualCameraEffectsEngine:Execute"); + } + } +} \ No newline at end of file diff --git a/NScript/Filmscript/GeneralBindings.cs b/NScript/Filmscript/GeneralBindings.cs new file mode 100644 index 0000000..3724e6b --- /dev/null +++ b/NScript/Filmscript/GeneralBindings.cs @@ -0,0 +1,29 @@ +using System; +using System.Runtime.InteropServices; + +namespace NScript.Filmscript +{ + public static class GeneralBindings + { + [DllImport("filmscript.dll")] + public static extern string filmscript_version(); + + public static string Version() + { + return filmscript_version(); + } + + public static bool Exists() + { + try + { + filmscript_version(); + return true; + } + catch (DllNotFoundException) + { + return false; + } + } + } +} \ No newline at end of file diff --git a/HelloModdingWorld/HelloModdingWorld.csproj b/NScript/NScript.csproj similarity index 100% rename from HelloModdingWorld/HelloModdingWorld.csproj rename to NScript/NScript.csproj diff --git a/NScript/NScriptPlugin.cs b/NScript/NScriptPlugin.cs new file mode 100644 index 0000000..b941338 --- /dev/null +++ b/NScript/NScriptPlugin.cs @@ -0,0 +1,76 @@ +using System; +using System.Reflection; + +using IllusionPlugin; +//using GamecraftModdingAPI; + +namespace NScript +{ + public class NScriptPlugin : IEnhancedPlugin + { + public override string Name { get; } = Assembly.GetExecutingAssembly().GetName().Name; + + public override string Version { get; } = Assembly.GetExecutingAssembly().GetName().Version.ToString(); + + private string toggleButtonText = "Turn On"; + + private HarmonyLib.Harmony instance; + + // called when Gamecraft shuts down + public override void OnApplicationQuit() + { + // Shutdown this mod + instance?.UnpatchAll(Assembly.GetExecutingAssembly().GetName().FullName); + GamecraftModdingAPI.Utility.Logging.LogDebug($"{Name} has shutdown"); + + // Shutdown the Gamecraft modding API last + GamecraftModdingAPI.Main.Shutdown(); + } + + // called when Gamecraft starts up + public override void OnApplicationStart() + { + // Initialize the Gamecraft modding API first + GamecraftModdingAPI.Main.Init(); + // check out the modding API docs here: https://mod.exmods.org/ + instance = new HarmonyLib.Harmony(Assembly.GetExecutingAssembly().GetName().FullName); + instance.PatchAll(Assembly.GetExecutingAssembly()); + + // load external libraries + try + { + string filmscriptVersion = Filmscript.GeneralBindings.Version(); + GamecraftModdingAPI.Utility.Logging.MetaLog($"filmscript.dll {filmscriptVersion}"); + } + catch (DllNotFoundException e) + { + GamecraftModdingAPI.Utility.Logging.MetaLog($"Failed to find filmscript DLL: {e.Message} ({e.TypeName} | {e.Source})"); + } + + // Initialize this mod + GamecraftModdingAPI.Utility.GameEngineManager.AddGameEngine(new CameraEngine()); + + GamecraftModdingAPI.Utility.Logging.MetaLog($"{Name} has started up"); + } + + public override void OnGUI() + { + // toggle custom camera mode + if (UnityEngine.GUILayout.Button(toggleButtonText)) + { + // toggle button text indicates what the button will do *next* time it's pressed + if (CameraPatch.AllowDefaultBehaviour) + { + toggleButtonText = "Turn Off"; // custom camera mode is turning on + } + else + { + toggleButtonText = "Turn On"; // custom camera mode is turning off + } + + CameraPatch.AllowDefaultBehaviour = !CameraPatch.AllowDefaultBehaviour; + CameraEngine.useDefaultBehaviour = !CameraEngine.useDefaultBehaviour; + } + } + } +} diff --git a/README.md b/README.md index 1af4fef..02bf64d 100644 --- a/README.md +++ b/README.md @@ -1,35 +1,15 @@ -# HelloModdingWorld +# NScript -Shell project for Techblox mods. -Use this as a quick-start project structure for your own mods, or to learn how modding works. +An automagically cinematic mod. ## Setup -This project requires most of Techblox's `.dll` files to function correctly. -Most, but not all, of these files are stored in Techblox's `Techblox_Data/Managed` folder. -The project is pre-configured to look in a folder called ref in the solution's main directory or one level up from that. - -You can make sure HelloModdingWorld can find all of `.dll` files it needs by copying your Techblox folder here and renaming it to `ref`, but you'll have to re-copy it after every Techblox update. -You can also create a symbolic link (look it up) to your Techblox install folder named `ref` in this folder to avoid having to re-copy files. - -For any mod to work, you will have to patch your game with [GCIPA](https://git.exmods.org/modtainers/GCIPA). -[Direct link to install guide](https://git.exmods.org/modtainers/GCIPA/src/branch/master/README.md#how-to-install). - -This project also requires the [GamecraftModdingAPI](https://git.exmods.org/modtainers/GamecraftModdingAPI) library to be installed (in `ref/Plugins/GamecraftModdingAPI.dll`). -[Direct link to install guide](https://www.exmods.org/guides/install.html). - -If you don't want to use the standard modding API, -you can remove the dependency by removing ` ... ` in `HelloModdingWorld.csproj` and removing all mentions in `MyPlugin.cs`. +Refer to the HelloModdingWorld template project. ## Building -After you've completed the setup, open the solution file `HelloModdingWorld.sln` in your prefered C# .NET/Mono development environment. -I'd recommend Visual Studio Community Edition or JetBrains Rider for Windows and Monodevelop for Linux. - -If you've successfully completed setup, you should be able to build the HelloModdingWorld project without errors. -The build configuration should be automatically imported from the project's files. -If it doesn't work and you can't figure out why, ask for help on [our Discord server](https://discord.gg/xjnFxQV). +Refer to the HelloModdingWorld template project. ## Installation -To install the HelloModdingWorld mod, copy the build's `HelloModdingWorld.dll` into the `Plugins` folder in Techblox's main folder. +Refer to the HelloModdingWorld template project. diff --git a/filmscript-rs b/filmscript-rs new file mode 160000 index 0000000..9ad3b1b --- /dev/null +++ b/filmscript-rs @@ -0,0 +1 @@ +Subproject commit 9ad3b1bbc06b43363d2983caa88896ef7eab330e