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