@@ -0,0 +1,3 @@ | |||
[submodule "filmscript-rs"] | |||
path = filmscript-rs | |||
url = https://git.exmods.org/NGnius/filmscript-rs |
@@ -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 <Version>0.0.1</Version> 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) | |||
} | |||
} |
@@ -1,6 +1,6 @@ | |||
MIT License | |||
Copyright (c) <year> <copyright holders> | |||
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 | |||
@@ -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 |
@@ -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<CharacterTagEntityStruct>(CharacterExclusiveGroups.OnFootGroup) | |||
.Deconstruct(out NB<CharacterTagEntityStruct> 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<CharacterCameraEntityStruct> cams)) | |||
{ | |||
ref var ccses = ref entitiesDB.QueryEntity<CameraTargetEntityStruct>(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<CharacterCameraEntityStruct>(CameraExclusiveGroups.VisualCameraGroup) | |||
.Deconstruct(out NB<CharacterCameraEntityStruct> 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)"); | |||
} | |||
} | |||
} |
@@ -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"); | |||
} | |||
} | |||
} |
@@ -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; | |||
} | |||
} | |||
} | |||
} |
@@ -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; | |||
} | |||
} | |||
} | |||
} |
@@ -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 `<Reference Include="GamecraftModdingAPI"> ... </Reference>` 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. |
@@ -0,0 +1 @@ | |||
Subproject commit 9ad3b1bbc06b43363d2983caa88896ef7eab330e |