Compare commits
No commits in common. "master" and "experimental" have entirely different histories.
master
...
experiment
19 changed files with 676 additions and 481 deletions
|
@ -1,5 +1,4 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using RobocraftX.GUI.CommandLine;
|
using RobocraftX.GUI.CommandLine;
|
||||||
using RobocraftX.Multiplayer;
|
using RobocraftX.Multiplayer;
|
||||||
using RobocraftX.StateSync;
|
using RobocraftX.StateSync;
|
||||||
|
@ -9,61 +8,89 @@ using Unity.Entities;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using uREPL;
|
using uREPL;
|
||||||
using Svelto.Context;
|
using Svelto.Context;
|
||||||
using Svelto.Tasks;
|
|
||||||
using Svelto.Tasks.ExtraLean;
|
|
||||||
using RobocraftX;
|
using RobocraftX;
|
||||||
using RobocraftX.Schedulers;
|
|
||||||
|
|
||||||
using GamecraftModdingAPI.Commands;
|
|
||||||
using GamecraftModdingAPI.Tasks;
|
|
||||||
using GamecraftModdingAPI.Utility;
|
|
||||||
|
|
||||||
namespace ExtraCommands.Basics
|
namespace ExtraCommands.Basics
|
||||||
{
|
{
|
||||||
//[CustomCommand("Chain")]
|
[CustomCommand]
|
||||||
class ChainCommandEngine : ICustomCommandEngine
|
class ChainCommandEngine : CustomCommandEngine
|
||||||
{
|
{
|
||||||
public string Description => "Run two commands one after the other";
|
public ChainCommandEngine(UnityContext<FullGameCompositionRoot> ctxHolder, EnginesRoot enginesRoot, World physW, Action reloadGame, MultiplayerInitParameters mpParams) : base(ctxHolder, enginesRoot, physW, reloadGame, mpParams)
|
||||||
|
|
||||||
public string Name => "Chain";
|
|
||||||
|
|
||||||
public IEntitiesDB entitiesDB { set; private get; }
|
|
||||||
|
|
||||||
public void Ready()
|
|
||||||
{
|
{
|
||||||
CommandRegistrationHelper.Register<string, string>(Name, ChainCommand, Description);
|
}
|
||||||
|
|
||||||
|
public override void Ready()
|
||||||
|
{
|
||||||
|
CustomCommandUtility.Register<string, string>("Chain", ChainCommand, "Run two commands, one after the other");
|
||||||
|
CustomCommandUtility.Register<string, string>("ChainNoFail", ChainNoFailCommand, "Run two commands, one after the other even if the first one is invalid");
|
||||||
|
CustomCommandUtility.Register<string, string>("ChainQuiet", ChainQuietCommand, "Run two commands, one after the other quietly");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ChainCommand(string command1, string command2)
|
private void ChainCommand(string command1, string command2)
|
||||||
{
|
{
|
||||||
string command1a = decomma(command1);
|
string command1a = decomma(command1);
|
||||||
string command2a = decomma(command2);
|
string command2a = decomma(command2);
|
||||||
ScheduleCommands(command1a, command2a).RunOn(Scheduler.extraLeanRunner);
|
bool success1 = uREPL.Evaluator.Evaluate(command1a).type == CompileResult.Type.Success;
|
||||||
|
if (!success1) {
|
||||||
|
uREPL.Log.Error("First command was not executed successfully");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
bool success2 = uREPL.Evaluator.Evaluate(command2a).type == CompileResult.Type.Success;
|
||||||
|
if (!success2) {
|
||||||
|
uREPL.Log.Error("Second command was not executed successfully");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private IEnumerator<TaskContract> ScheduleCommands(string c1, string c2)
|
private void ChainNoFailCommand(string command1, string command2)
|
||||||
{
|
{
|
||||||
yield return Yield.It;
|
string command1a = decomma(command1);
|
||||||
bool success1 = uREPL.Evaluator.Evaluate(c1).type == CompileResult.Type.Success;
|
string command2a = decomma(command2);
|
||||||
if (!success1)
|
bool success1 = uREPL.Evaluator.Evaluate(command1a).type == CompileResult.Type.Success;
|
||||||
{
|
if (!success1) {
|
||||||
Logging.CommandLogError("First command was not executed successfully");
|
uREPL.Log.Error("First command was not executed successfully");
|
||||||
}
|
}
|
||||||
bool success2 = uREPL.Evaluator.Evaluate(c2).type == CompileResult.Type.Success;
|
bool success2 = uREPL.Evaluator.Evaluate(command2a).type == CompileResult.Type.Success;
|
||||||
if (!success2)
|
if (!success2) {
|
||||||
{
|
uREPL.Log.Error("Second command was not executed successfully");
|
||||||
Logging.CommandLogError("Second command was not executed successfully");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void ChainQuietCommand(string command1, string command2)
|
||||||
|
{
|
||||||
|
string command1a = decomma(command1);
|
||||||
|
string command2a = decomma(command2);
|
||||||
|
uREPL.Evaluator.Evaluate(command1a);
|
||||||
|
uREPL.Evaluator.Evaluate(command2a);
|
||||||
|
}
|
||||||
|
|
||||||
private string decomma(string strIn)
|
private string decomma(string strIn)
|
||||||
{
|
{
|
||||||
return strIn.Replace(", ", " ");
|
string strOut = "";
|
||||||
|
bool wasCommaLast = false;
|
||||||
|
foreach (char c in strIn)
|
||||||
|
{
|
||||||
|
if (wasCommaLast)
|
||||||
|
{
|
||||||
|
wasCommaLast = false;
|
||||||
|
if (c == ' ')
|
||||||
|
{
|
||||||
|
strOut = strOut.Substring(0, strOut.Length - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (c == ',')
|
||||||
|
{
|
||||||
|
wasCommaLast = true;
|
||||||
|
}
|
||||||
|
strOut += c;
|
||||||
|
}
|
||||||
|
return strOut;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public override void Dispose()
|
||||||
{
|
{
|
||||||
CommandRegistrationHelper.Unregister("Chain");
|
CustomCommandUtility.Unregister("Chain");
|
||||||
|
CustomCommandUtility.Unregister("ChainNoFail");
|
||||||
|
CustomCommandUtility.Unregister("ChainQuiet");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,24 +0,0 @@
|
||||||
using GamecraftModdingAPI.Commands;
|
|
||||||
using Svelto.ECS;
|
|
||||||
|
|
||||||
namespace ExtraCommands
|
|
||||||
{
|
|
||||||
[CustomCommand("ClearConsole")]
|
|
||||||
public class ClearConsoleCommandEngine : ICustomCommandEngine
|
|
||||||
{
|
|
||||||
public void Ready()
|
|
||||||
{
|
|
||||||
CommandRegistrationHelper.Register("ClearConsole", uREPL.Window.ClearOutputCommand,
|
|
||||||
"Clears the console output.");
|
|
||||||
}
|
|
||||||
|
|
||||||
public IEntitiesDB entitiesDB { get; set; }
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
CommandRegistrationHelper.Unregister("ClearConsole");
|
|
||||||
}
|
|
||||||
|
|
||||||
public string Name { get; } = "ClearConsole";
|
|
||||||
public string Description { get; } = "Clears the console output.";
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1 +1,54 @@
|
||||||
|
using System;
|
||||||
|
using System.Reflection;
|
||||||
|
using Harmony;
|
||||||
|
using UnityEngine;
|
||||||
|
using Unity.Entities;
|
||||||
|
using RobocraftX;
|
||||||
|
using RobocraftX.GUI.CommandLine;
|
||||||
|
using RobocraftX.Multiplayer;
|
||||||
|
using Svelto.ECS;
|
||||||
|
using Svelto.Context;
|
||||||
|
|
||||||
|
namespace ExtraCommands
|
||||||
|
{
|
||||||
|
[HarmonyPatch]
|
||||||
|
class CommandLineCompositionRootSaveCommandPatch
|
||||||
|
{
|
||||||
|
static void Postfix(UnityContext<FullGameCompositionRoot> contextHolder, EnginesRoot enginesRoot, World physicsWorld, Action reloadGame, MultiplayerInitParameters multiplayerParameters)
|
||||||
|
{
|
||||||
|
int engineCount = 0;
|
||||||
|
MethodInfo commandHelp = Harmony.AccessTools.Method(Harmony.AccessTools.TypeByName("RobocraftX.GUI.CommandLine.CommandLineUtility"), "SaveCommandHelp", new Type[] { typeof(string), typeof(string) });
|
||||||
|
foreach (Type t in typeof(CustomCommandEngine).Assembly.GetTypes())
|
||||||
|
{
|
||||||
|
CustomCommandAttribute[] attributes = (CustomCommandAttribute[])t.GetCustomAttributes(typeof(CustomCommandAttribute), false);
|
||||||
|
CustomCommandEngine inst = null;
|
||||||
|
foreach (CustomCommandAttribute attr in attributes)
|
||||||
|
{
|
||||||
|
if (attr != null && t.IsSubclassOf(typeof(CustomCommandEngine)))
|
||||||
|
{
|
||||||
|
if (inst == null)
|
||||||
|
{
|
||||||
|
// create instance by getting the constructor through reflection
|
||||||
|
inst = (CustomCommandEngine)t.GetConstructor(new Type[] { typeof(UnityContext<FullGameCompositionRoot>), typeof(EnginesRoot), typeof(World), typeof(Action), typeof(MultiplayerInitParameters) })
|
||||||
|
.Invoke(new object[] { contextHolder, enginesRoot, physicsWorld, reloadGame, multiplayerParameters });
|
||||||
|
// add to engineRoot
|
||||||
|
enginesRoot.AddEngine(inst);
|
||||||
|
engineCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Debug.Log($"Added {engineCount} custom command engines");
|
||||||
|
}
|
||||||
|
|
||||||
|
static MethodBase TargetMethod(HarmonyInstance instance)
|
||||||
|
{
|
||||||
|
return _ComposeMethodInfo(CommandLineCompositionRoot.Compose<UnityContext<FullGameCompositionRoot>>);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static MethodInfo _ComposeMethodInfo(Action<UnityContext<FullGameCompositionRoot>, EnginesRoot, World, Action, MultiplayerInitParameters> a)
|
||||||
|
{
|
||||||
|
return a.Method;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,35 +1,18 @@
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
using GamecraftModdingAPI.Commands;
|
|
||||||
|
|
||||||
namespace ExtraCommands
|
namespace ExtraCommands
|
||||||
{
|
{
|
||||||
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
|
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
|
||||||
public class CustomCommandAttribute: Attribute
|
public class CustomCommandAttribute: Attribute
|
||||||
{
|
{
|
||||||
public readonly string Name;
|
public string Name { get; protected set; }
|
||||||
|
|
||||||
public readonly string Description;
|
public string Description { get; protected set; }
|
||||||
|
|
||||||
public readonly bool IsFactory;
|
public CustomCommandAttribute(string name = "", string description = "")
|
||||||
|
|
||||||
public CustomCommandAttribute(string name = "", string description = "", bool factory = false)
|
|
||||||
{
|
{
|
||||||
this.Name = name;
|
this.Name = name;
|
||||||
this.Description = description;
|
this.Description = description;
|
||||||
this.IsFactory = factory;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool IsCompatible(Type t)
|
|
||||||
{
|
|
||||||
foreach (var i in t.GetInterfaces())
|
|
||||||
{
|
|
||||||
if (i == typeof(ICustomCommandEngine))
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
39
extracommands/CustomCommandEngine.cs
Normal file
39
extracommands/CustomCommandEngine.cs
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
using RobocraftX.GUI.CommandLine;
|
||||||
|
using RobocraftX.Multiplayer;
|
||||||
|
using Svelto.Context;
|
||||||
|
using Svelto.ECS;
|
||||||
|
using System;
|
||||||
|
using Unity.Entities;
|
||||||
|
using RobocraftX;
|
||||||
|
|
||||||
|
namespace ExtraCommands
|
||||||
|
{
|
||||||
|
class CustomCommandEngine : IQueryingEntitiesEngine, IEngine, IDisposable
|
||||||
|
{
|
||||||
|
protected UnityContext<FullGameCompositionRoot> context;
|
||||||
|
|
||||||
|
protected EnginesRoot enginesRoot;
|
||||||
|
|
||||||
|
protected World physWorld;
|
||||||
|
|
||||||
|
protected Action reloadGame;
|
||||||
|
|
||||||
|
protected MultiplayerInitParameters multiplayerInitParameters;
|
||||||
|
|
||||||
|
public CustomCommandEngine(UnityContext<FullGameCompositionRoot> ctxHolder, EnginesRoot enginesRoot, World physW, Action reloadGame, MultiplayerInitParameters mpParams)
|
||||||
|
{
|
||||||
|
this.context = ctxHolder;
|
||||||
|
this.enginesRoot = enginesRoot;
|
||||||
|
this.physWorld = physW;
|
||||||
|
this.reloadGame = reloadGame;
|
||||||
|
this.multiplayerInitParameters = mpParams;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEntitiesDB entitiesDB { set; get; }
|
||||||
|
|
||||||
|
virtual public void Dispose() { }
|
||||||
|
|
||||||
|
// NOTE: Ready() should call CustomCommandUtility.Register to add the command to the command line
|
||||||
|
virtual public void Ready() { }
|
||||||
|
}
|
||||||
|
}
|
54
extracommands/CustomCommandUtility.cs
Normal file
54
extracommands/CustomCommandUtility.cs
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using uREPL;
|
||||||
|
using RobocraftX.CommandLine.Custom;
|
||||||
|
|
||||||
|
namespace ExtraCommands
|
||||||
|
{
|
||||||
|
static class CustomCommandUtility
|
||||||
|
{
|
||||||
|
public static void Register(string name, Action action, string desc)
|
||||||
|
{
|
||||||
|
RuntimeCommands.Register(name, action, desc);
|
||||||
|
ConsoleCommands.Register(name, action, desc);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Register(string name, Action<object> action, string desc)
|
||||||
|
{
|
||||||
|
RuntimeCommands.Register<object>(name, action, desc);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Register<Param0>(string name, Action<Param0> action, string desc)
|
||||||
|
{
|
||||||
|
RuntimeCommands.Register<Param0>(name, action, desc);
|
||||||
|
ConsoleCommands.Register<Param0>(name, action, desc);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Register<Param0, Param1>(string name, Action<Param0, Param1> action, string desc)
|
||||||
|
{
|
||||||
|
RuntimeCommands.Register<Param0, Param1>(name, action, desc);
|
||||||
|
ConsoleCommands.Register<Param0, Param1>(name, action, desc);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Register(string name, Action<object, object, object> action, string desc)
|
||||||
|
{
|
||||||
|
RuntimeCommands.Register<object, object, object>(name, action, desc);
|
||||||
|
ConsoleCommands.Register<object, object, object>(name, action, desc);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Register<Param0, Param1, Param2>(string name, Action<Param0, Param1, Param2> action, string desc)
|
||||||
|
{
|
||||||
|
RuntimeCommands.Register<Param0, Param1, Param2>(name, action, desc);
|
||||||
|
ConsoleCommands.Register<Param0, Param1, Param2>(name, action, desc);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Unregister(string name)
|
||||||
|
{
|
||||||
|
RuntimeCommands.Unregister(name);
|
||||||
|
ConsoleCommands.Unregister(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -10,8 +10,6 @@ using uREPL;
|
||||||
using Svelto.Context;
|
using Svelto.Context;
|
||||||
using RobocraftX;
|
using RobocraftX;
|
||||||
|
|
||||||
using GamecraftModdingAPI.Commands;
|
|
||||||
|
|
||||||
// checklist of things to rename to make this command your own:
|
// checklist of things to rename to make this command your own:
|
||||||
// [ ] namespace ExtraCommands.Example -> namespace ExtraCommands.[your command's namespace]
|
// [ ] namespace ExtraCommands.Example -> namespace ExtraCommands.[your command's namespace]
|
||||||
// [ ] class ExampleCommandEngine : CustomCommandEngine -> class [your command name]CommandEngine : CustomCommandEngine
|
// [ ] class ExampleCommandEngine : CustomCommandEngine -> class [your command name]CommandEngine : CustomCommandEngine
|
||||||
|
@ -27,26 +25,24 @@ namespace ExtraCommands.Example
|
||||||
{
|
{
|
||||||
// !!! Uncomment the line below this !!!
|
// !!! Uncomment the line below this !!!
|
||||||
// [CustomCommand("Example")]
|
// [CustomCommand("Example")]
|
||||||
class ExampleCommandEngine : ICustomCommandEngine
|
class ExampleCommandEngine : CustomCommandEngine
|
||||||
{
|
{
|
||||||
public string Description => "This is an example command which does nothing!";
|
// This class is a custom implementation of CustomCommandEngine specific to this command
|
||||||
|
// You can use Svelto.ECS.IEntityDB entitiesDB to query game entities or one of the protected variables for other things
|
||||||
|
// More documentation on Svelto.ECS: https://github.com/sebas77/Svelto.ECS
|
||||||
|
// Unfortunately the documentation is severely lacking and out of date; you may have better luck decompiling Svelto.ECS.dll
|
||||||
|
// See CustomCommandEngine.cs for more information on the super class
|
||||||
|
|
||||||
public string Name => "Example";
|
public ExampleCommandEngine(UnityContext<FullGameCompositionRoot> ctxHolder, EnginesRoot enginesRoot, World physW, Action reloadGame, MultiplayerInitParameters mpParams) : base(ctxHolder, enginesRoot, physW, reloadGame, mpParams)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
public IEntitiesDB entitiesDB { set; private get; }
|
// Ready() is called when the command is registered in-game (this happens whenever you load a game)
|
||||||
|
public override void Ready()
|
||||||
// This class is a custom implementation of CustomCommandEngine specific to this command
|
|
||||||
// You can use Svelto.ECS.IEntityDB entitiesDB to query game entities or one of the protected variables for other things
|
|
||||||
// More documentation on Svelto.ECS: https://github.com/sebas77/Svelto.ECS
|
|
||||||
// Unfortunately the documentation is severely lacking and out of date; you may have better luck decompiling Svelto.ECS.dll
|
|
||||||
// See CustomCommandEngine.cs for more information on the super class
|
|
||||||
|
|
||||||
// Ready() is called when the command is registered in-game (this happens whenever you load a game)
|
|
||||||
public void Ready()
|
|
||||||
{
|
{
|
||||||
// CustomCommandUtility.Register has multiple overloads depending on how many parameters you want to pass to your command
|
// CustomCommandUtility.Register has multiple overloads depending on how many parameters you want to pass to your command
|
||||||
// See CustomCommandUtility.cs for more information
|
// See CustomCommandUtility.cs for more information
|
||||||
CommandRegistrationHelper.Register(Name, ExampleCommand, Description);
|
CustomCommandUtility.Register("Example", ExampleCommand, "This is an example command which does nothing!");
|
||||||
}
|
}
|
||||||
|
|
||||||
// ExampleCommand() is called whenever the command is executed. This can accept up to three parameters
|
// ExampleCommand() is called whenever the command is executed. This can accept up to three parameters
|
||||||
|
@ -57,11 +53,11 @@ namespace ExtraCommands.Example
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dispose() is called when the command is unregistered in-game (this happens whenever you leave a game)
|
// Dispose() is called when the command is unregistered in-game (this happens whenever you leave a game)
|
||||||
public void Dispose()
|
public override void Dispose()
|
||||||
{
|
{
|
||||||
// You must unregister the command so it doesn't waste memory and so
|
// You must unregister the command so it doesn't waste memory and so
|
||||||
// it can be re-registered next time
|
// it can be re-registered next time
|
||||||
CommandRegistrationHelper.Unregister(Name);
|
CustomCommandUtility.Unregister("Example");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,22 +10,18 @@ using uREPL;
|
||||||
using Svelto.Context;
|
using Svelto.Context;
|
||||||
using RobocraftX;
|
using RobocraftX;
|
||||||
|
|
||||||
using GamecraftModdingAPI.Commands;
|
|
||||||
|
|
||||||
namespace ExtraCommands.Basics
|
namespace ExtraCommands.Basics
|
||||||
{
|
{
|
||||||
[CustomCommand("Exit")]
|
[CustomCommand("Exit")]
|
||||||
class ExitCommandEngine : ICustomCommandEngine
|
class ExitCommandEngine : CustomCommandEngine
|
||||||
{
|
{
|
||||||
public string Description => "Close Gamecraft without any prompts";
|
public ExitCommandEngine(UnityContext<FullGameCompositionRoot> ctxHolder, EnginesRoot enginesRoot, World physW, Action reloadGame, MultiplayerInitParameters mpParams) : base(ctxHolder, enginesRoot, physW, reloadGame, mpParams)
|
||||||
|
|
||||||
public string Name => "Exit";
|
|
||||||
|
|
||||||
public IEntitiesDB entitiesDB { set; private get; }
|
|
||||||
|
|
||||||
public void Ready()
|
|
||||||
{
|
{
|
||||||
CommandRegistrationHelper.Register(Name, ExitCommand, Description);
|
}
|
||||||
|
|
||||||
|
public override void Ready()
|
||||||
|
{
|
||||||
|
CustomCommandUtility.Register("Exit", ExitCommand, "Forcefully close Gamecraft");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ExitCommand()
|
private void ExitCommand()
|
||||||
|
@ -33,9 +29,9 @@ namespace ExtraCommands.Basics
|
||||||
Application.Quit();
|
Application.Quit();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public override void Dispose()
|
||||||
{
|
{
|
||||||
CommandRegistrationHelper.Unregister(Name);
|
CustomCommandUtility.Unregister("Exit");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net472</TargetFramework>
|
<TargetFramework>net48</TargetFramework>
|
||||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
@ -10,104 +10,89 @@
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Reference Include="GamecraftModdingAPI">
|
|
||||||
<HintPath>..\ref\Plugins\GamecraftModdingAPI.dll</HintPath>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="CommandLine">
|
<Reference Include="CommandLine">
|
||||||
<HintPath>..\ref\Gamecraft_Data\Managed\CommandLine.dll</HintPath>
|
<HintPath>..\ref\CommandLine.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="Facepunch.Steamworks.Win64">
|
<Reference Include="Facepunch.Steamworks.Win64">
|
||||||
<HintPath>..\ref\Gamecraft_Data\Managed\Facepunch.Steamworks.Win64.dll</HintPath>
|
<HintPath>..\ref\Facepunch.Steamworks.Win64.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="FullGame">
|
<Reference Include="FullGame">
|
||||||
<HintPath>..\ref\Gamecraft_Data\Managed\FullGame.dll</HintPath>
|
<HintPath>..\ref\FullGame.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="IllusionPlugin">
|
<Reference Include="IllusionPlugin">
|
||||||
<HintPath>..\ref\Gamecraft_Data\Managed\IllusionPlugin.dll</HintPath>
|
<HintPath>..\IllusionPlugin.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="RobocraftX.Character">
|
<Reference Include="RobocraftX.Character">
|
||||||
<HintPath>..\ref\Gamecraft_Data\Managed\RobocraftX.Character.dll</HintPath>
|
<HintPath>..\ref\RobocraftX.Character.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="CommandLine">
|
<Reference Include="CommandLine">
|
||||||
<HintPath>..\ref\Gamecraft_Data\Managed\RobocraftX.Common.dll</HintPath>
|
<HintPath>..\ref\RobocraftX.Common.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="RobocraftX.Blocks">
|
<Reference Include="RobocraftX.Blocks">
|
||||||
<HintPath>..\ref\Gamecraft_Data\Managed\RobocraftX.Blocks.dll</HintPath>
|
<HintPath>..\ref\RobocraftX.Blocks.dll</HintPath>
|
||||||
</Reference>
|
|
||||||
<Reference Include="RobocraftX.Blocks.Ghost">
|
|
||||||
<HintPath>..\ref\Gamecraft_Data\Managed\RobocraftX.Blocks.Ghost.dll</HintPath>
|
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="RobocraftX.Character">
|
<Reference Include="RobocraftX.Character">
|
||||||
<HintPath>..\ref\Gamecraft_Data\Managed\RobocraftX.Character.dll</HintPath>
|
<HintPath>..\ref\RobocraftX.Character.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="RobocraftX.Input">
|
<Reference Include="RobocraftX.Input">
|
||||||
<HintPath>..\ref\Gamecraft_Data\Managed\RobocraftX.Input.dll</HintPath>
|
<HintPath>..\ref\RobocraftX.Input.dll</HintPath>
|
||||||
</Reference>
|
|
||||||
<Reference Include="RobocraftX.MachineEditor, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null">
|
|
||||||
<HintPath>..\ref\Gamecraft_Data\Managed\RobocraftX.MachineEditor.dll</HintPath>
|
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="RobocraftX.MainGame">
|
<Reference Include="RobocraftX.MainGame">
|
||||||
<HintPath>..\ref\Gamecraft_Data\Managed\RobocraftX.MainGame.dll</HintPath>
|
<HintPath>..\ref\RobocraftX.MainGame.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="RobocraftX.Multiplayer">
|
<Reference Include="RobocraftX.Multiplayer">
|
||||||
<HintPath>..\ref\Gamecraft_Data\Managed\RobocraftX.Multiplayer.dll</HintPath>
|
<HintPath>..\ref\RobocraftX.Multiplayer.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="RobocraftX.Multiplayer.NetworkEntityStream">
|
<Reference Include="RobocraftX.Multiplayer.NetworkEntityStream">
|
||||||
<HintPath>..\ref\Gamecraft_Data\Managed\RobocraftX.Multiplayer.NetworkEntityStream.dll</HintPath>
|
<HintPath>..\ref\RobocraftX.Multiplayer.NetworkEntityStream.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="RobocraftX.MultiplayerInput">
|
<Reference Include="RobocraftX.MultiplayerInput">
|
||||||
<HintPath>..\ref\Gamecraft_Data\Managed\RobocraftX.MultiplayerInput.dll</HintPath>
|
<HintPath>..\ref\RobocraftX.MultiplayerInput.dll</HintPath>
|
||||||
</Reference>
|
|
||||||
<Reference Include="RobocraftX.Physics">
|
|
||||||
<HintPath>..\ref\Gamecraft_Data\Managed\RobocraftX.Physics.dll</HintPath>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="RobocraftX.Services, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null">
|
|
||||||
<HintPath>..\ref\Gamecraft_Data\Managed\RobocraftX.Services.dll</HintPath>
|
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="RobocraftX.StateSync">
|
<Reference Include="RobocraftX.StateSync">
|
||||||
<HintPath>..\ref\Gamecraft_Data\Managed\RobocraftX.StateSync.dll</HintPath>
|
<HintPath>..\ref\RobocraftX.StateSync.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="Svelto.Common">
|
<Reference Include="Svelto.Common">
|
||||||
<HintPath>..\ref\Gamecraft_Data\Managed\Svelto.Common.dll</HintPath>
|
<HintPath>..\ref\Svelto.Common.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="Svelto.ECS">
|
<Reference Include="Svelto.ECS">
|
||||||
<HintPath>..\ref\Gamecraft_Data\Managed\Svelto.ECS.dll</HintPath>
|
<HintPath>..\ref\Svelto.ECS.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="Svelto.Tasks">
|
<Reference Include="Svelto.Tasks">
|
||||||
<HintPath>..\ref\Gamecraft_Data\Managed\Svelto.Tasks.dll</HintPath>
|
<HintPath>..\ref\Svelto.Tasks.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="Unity.Entities">
|
<Reference Include="Unity.Entities">
|
||||||
<HintPath>..\ref\Gamecraft_Data\Managed\Unity.Entities.dll</HintPath>
|
<HintPath>..\ref\Unity.Entities.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="Unity.Entities.Hybrid">
|
<Reference Include="Unity.Entities.Hybrid">
|
||||||
<HintPath>..\ref\Gamecraft_Data\Managed\Unity.Entities.Hybrid.dll</HintPath>
|
<HintPath>..\ref\Unity.Entities.Hybrid.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="Unity.Entities.Properties">
|
<Reference Include="Unity.Entities.Properties">
|
||||||
<HintPath>..\ref\Gamecraft_Data\Managed\Unity.Entities.Properties.dll</HintPath>
|
<HintPath>..\ref\Unity.Entities.Properties.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="Unity.Entities.StaticTypeRegistry">
|
<Reference Include="Unity.Entities.StaticTypeRegistry">
|
||||||
<HintPath>..\ref\Gamecraft_Data\Managed\Unity.Entities.StaticTypeRegistry.dll</HintPath>
|
<HintPath>..\ref\Unity.Entities.StaticTypeRegistry.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="Unity.Mathematics">
|
<Reference Include="Unity.Mathematics">
|
||||||
<HintPath>..\ref\Gamecraft_Data\Managed\Unity.Mathematics.dll</HintPath>
|
<HintPath>..\ref\Unity.Mathematics.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="Unity.Mathematics.Extensions">
|
<Reference Include="Unity.Mathematics.Extensions">
|
||||||
<HintPath>..\ref\Gamecraft_Data\Managed\Unity.Mathematics.Extensions.dll</HintPath>
|
<HintPath>..\ref\Unity.Mathematics.Extensions.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="Unity.Mathematics.Extensions.Hybrid">
|
<Reference Include="Unity.Mathematics.Extensions.Hybrid">
|
||||||
<HintPath>..\ref\Gamecraft_Data\Managed\Unity.Mathematics.Extensions.Hybrid.dll</HintPath>
|
<HintPath>..\ref\Unity.Mathematics.Extensions.Hybrid.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="Unity.Transforms">
|
<Reference Include="Unity.Transforms">
|
||||||
<HintPath>..\ref\Gamecraft_Data\Managed\Unity.Transforms.dll</HintPath>
|
<HintPath>..\ref\Unity.Transforms.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="UnityEngine">
|
<Reference Include="UnityEngine">
|
||||||
<HintPath>..\ref\Gamecraft_Data\Managed\UnityEngine.dll</HintPath>
|
<HintPath>..\ref\UnityEngine.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="UnityEngine.CoreModule">
|
<Reference Include="UnityEngine.CoreModule">
|
||||||
<HintPath>..\ref\Gamecraft_Data\Managed\UnityEngine.CoreModule.dll</HintPath>
|
<HintPath>..\ref\UnityEngine.CoreModule.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="uREPL">
|
<Reference Include="uREPL">
|
||||||
<HintPath>..\ref\Gamecraft_Data\Managed\uREPL.dll</HintPath>
|
<HintPath>..\ref\uREPL.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
|
|
@ -1,53 +1,38 @@
|
||||||
using System;
|
using System;
|
||||||
using IllusionPlugin;
|
using IllusionPlugin;
|
||||||
//using UnityEngine;
|
using UnityEngine;
|
||||||
|
using Harmony;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
|
||||||
using GamecraftModdingAPI.Commands;
|
|
||||||
using GamecraftModdingAPI.Utility;
|
|
||||||
|
|
||||||
namespace ExtraCommands
|
namespace ExtraCommands
|
||||||
{
|
{
|
||||||
public class Plugin : IllusionPlugin.IEnhancedPlugin
|
public class Plugin : IllusionPlugin.IEnhancedPlugin
|
||||||
{
|
{
|
||||||
|
public static HarmonyInstance harmony { get; protected set; }
|
||||||
|
|
||||||
public string[] Filter { get; } = new string[] { "RobocraftX", "Gamecraft", "GamecraftPreview" };
|
public string[] Filter { get; } = new string[] { "RobocraftX", "Gamecraft", "GamecraftPreview" };
|
||||||
|
|
||||||
public string Name { get; } = "ExtraCommands";
|
public string Name { get; } = "ExtraCommands";
|
||||||
|
|
||||||
public string Version { get; } = Assembly.GetExecutingAssembly().GetName().Version.ToString();
|
public string Version { get; } = "v0.0.1";
|
||||||
|
|
||||||
public string HarmonyID { get; } = "org.git.exmods.extracommands.extracommands";
|
public string HarmonyID { get; } = "org.git.exmods.extracommands.extracommands";
|
||||||
|
|
||||||
public void OnApplicationQuit()
|
public void OnApplicationQuit()
|
||||||
{
|
{
|
||||||
GamecraftModdingAPI.Main.Shutdown();
|
harmony.UnpatchAll(HarmonyID);
|
||||||
|
Debug.Log("ExtraCommands shutdown & unpatch complete");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnApplicationStart()
|
public void OnApplicationStart()
|
||||||
{
|
{
|
||||||
GamecraftModdingAPI.Main.Init();
|
if (harmony == null)
|
||||||
object[] empty = new object[] { };
|
{
|
||||||
int engineCount = 0;
|
harmony = HarmonyInstance.Create(HarmonyID);
|
||||||
foreach (Type t in Assembly.GetExecutingAssembly().GetTypes())
|
harmony.PatchAll(Assembly.GetExecutingAssembly());
|
||||||
{
|
}
|
||||||
CustomCommandAttribute[] attributes = (CustomCommandAttribute[])t.GetCustomAttributes(typeof(CustomCommandAttribute), false);
|
Debug.Log("ExtraCommands start & patch complete");
|
||||||
ICustomCommandEngine inst = null;
|
}
|
||||||
foreach (CustomCommandAttribute attr in attributes)
|
|
||||||
{
|
|
||||||
if (attr != null && CustomCommandAttribute.IsCompatible(t))
|
|
||||||
{
|
|
||||||
if (inst == null)
|
|
||||||
{
|
|
||||||
// create instance by getting the constructor through reflection
|
|
||||||
inst = (ICustomCommandEngine)t.GetConstructor(new Type[] { }).Invoke(empty);
|
|
||||||
CommandManager.AddCommand(inst);
|
|
||||||
engineCount++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Logging.MetaLog($"Added {engineCount} custom command engines");
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnFixedUpdate()
|
public void OnFixedUpdate()
|
||||||
{
|
{
|
||||||
|
|
|
@ -3,7 +3,6 @@ using System.Collections.Generic;
|
||||||
using RobocraftX.Multiplayer;
|
using RobocraftX.Multiplayer;
|
||||||
using RobocraftX.Common;
|
using RobocraftX.Common;
|
||||||
using RobocraftX.Blocks;
|
using RobocraftX.Blocks;
|
||||||
using RobocraftX.Blocks.Ghost;
|
|
||||||
using Svelto.ECS;
|
using Svelto.ECS;
|
||||||
using Svelto.ECS.EntityStructs;
|
using Svelto.ECS.EntityStructs;
|
||||||
using Unity.Entities;
|
using Unity.Entities;
|
||||||
|
@ -14,39 +13,174 @@ using RobocraftX.SimulationModeState;
|
||||||
using RobocraftX.UECS;
|
using RobocraftX.UECS;
|
||||||
using Unity.Transforms;
|
using Unity.Transforms;
|
||||||
using Unity.Mathematics;
|
using Unity.Mathematics;
|
||||||
using UnityEngine;
|
|
||||||
|
|
||||||
using GamecraftModdingAPI.Blocks;
|
|
||||||
using GamecraftModdingAPI.Commands;
|
|
||||||
|
|
||||||
namespace ExtraCommands.Building
|
namespace ExtraCommands.Building
|
||||||
{
|
{
|
||||||
//[CustomCommand("MoveBlocks", "Move all blocks (including ground) from their original position")]
|
[CustomCommand("MoveBlocks", "Move all blocks (including ground) from their original position")]
|
||||||
[CustomCommand("MoveLastBlock", "Move last block from original position")]
|
[CustomCommand("MoveLastBlock", "Move last block from original position")]
|
||||||
class MoveBlocksCommandEngine : ICustomCommandEngine
|
class MoveBlocksCommandEngine : CustomCommandEngine
|
||||||
{
|
{
|
||||||
public string Description => "Move blocks";
|
public MoveBlocksCommandEngine(UnityContext<FullGameCompositionRoot> ctxHolder, EnginesRoot enginesRoot, World physW, Action reloadGame, MultiplayerInitParameters mpParams) : base(ctxHolder, enginesRoot, physW, reloadGame, mpParams)
|
||||||
|
|
||||||
public string Name => "MoveBlocks";
|
|
||||||
|
|
||||||
public IEntitiesDB entitiesDB { set; private get; }
|
|
||||||
|
|
||||||
public void Ready()
|
|
||||||
{
|
|
||||||
//CustomCommandUtility.Register<float, float, float>("MoveBlocks", MoveBlocksCommand, "Move all blocks (including ground) from their original position");
|
|
||||||
CommandRegistrationHelper.Register<float, float, float>("MoveLastBlock", MoveLastBlockCommand, "Move last block from original position");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void MoveLastBlockCommand(float x, float y, float z)
|
|
||||||
{
|
|
||||||
float3 vector = new float3(x, y, z);
|
|
||||||
Movement.MoveConnectedBlocks(BlockIdentifiers.LatestBlockID, vector);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Dispose()
|
|
||||||
{
|
{
|
||||||
//CommandRegistrationHelper.Unregister("MoveBlocks");
|
}
|
||||||
CommandRegistrationHelper.Unregister("MoveLastBlock");
|
|
||||||
|
public override void Ready()
|
||||||
|
{
|
||||||
|
CustomCommandUtility.Register<float, float, float>("MoveBlocks", MoveBlocksCommand, "Move all blocks (including ground) from their original position");
|
||||||
|
CustomCommandUtility.Register<float, float, float>("MoveLastBlock", MoveLastBlockCommand, "Move last block from original position");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Move every block by vector (x,y,z)
|
||||||
|
private void MoveBlocksCommand(float x, float y, float z)
|
||||||
|
{
|
||||||
|
ref SimulationModeStateEntityStruct simMode = ref this.entitiesDB.QueryUniqueEntity<SimulationModeStateEntityStruct>(SimulationModeStateExclusiveGroups.GAME_STATE_GROUP);
|
||||||
|
if (simMode.simulationMode != SimulationMode.Build)
|
||||||
|
{
|
||||||
|
uREPL.Log.Error("Blocks can only be moved in Build Mode");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
uint count = this.entitiesDB.Count<PositionEntityStruct>(CommonExclusiveGroups.OWNED_BLOCKS_GROUP);
|
||||||
|
float3 translationVector = new float3(x,y,z);
|
||||||
|
for (uint i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
TranslateSingleBlock(i, translationVector);
|
||||||
|
}
|
||||||
|
uREPL.Log.Output($"Moved {count} blocks");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Move block with highest index by vector (x,y,z)
|
||||||
|
private void MoveLastBlockCommand(float x, float y, float z)
|
||||||
|
{
|
||||||
|
uint count = entitiesDB.Count<PositionEntityStruct>(CommonExclusiveGroups.OWNED_BLOCKS_GROUP);
|
||||||
|
ref SimulationModeStateEntityStruct simMode = ref this.entitiesDB.QueryUniqueEntity<SimulationModeStateEntityStruct>(SimulationModeStateExclusiveGroups.GAME_STATE_GROUP);
|
||||||
|
if (simMode.simulationMode != SimulationMode.Build)
|
||||||
|
{
|
||||||
|
uREPL.Log.Error("Blocks can only be moved in Build Mode");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
float3 newPos = TranslateConnectedBlocks(count-1, new float3(x,y,z));
|
||||||
|
uREPL.Log.Output($"Moved block to ({newPos.x},{newPos.y},{newPos.z})");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Move the block denoted by blockID by translationVector (old_position += translationVector)
|
||||||
|
private float3 TranslateSingleBlock(uint blockID, float3 translationVector)
|
||||||
|
{
|
||||||
|
ref PositionEntityStruct posStruct = ref this.entitiesDB.QueryEntity<PositionEntityStruct>(blockID, CommonExclusiveGroups.OWNED_BLOCKS_GROUP);
|
||||||
|
ref GridRotationStruct gridStruct = ref this.entitiesDB.QueryEntity<GridRotationStruct>(blockID, CommonExclusiveGroups.OWNED_BLOCKS_GROUP);
|
||||||
|
ref LocalTransformEntityStruct transStruct = ref this.entitiesDB.QueryEntity<LocalTransformEntityStruct>(blockID, CommonExclusiveGroups.OWNED_BLOCKS_GROUP);
|
||||||
|
ref UECSPhysicsEntityStruct phyStruct = ref this.entitiesDB.QueryEntity<UECSPhysicsEntityStruct>(blockID, CommonExclusiveGroups.OWNED_BLOCKS_GROUP);
|
||||||
|
// main (persistent) position
|
||||||
|
posStruct.position.x += translationVector.x;
|
||||||
|
posStruct.position.y += translationVector.y;
|
||||||
|
posStruct.position.z += translationVector.z;
|
||||||
|
// placement grid position
|
||||||
|
gridStruct.position.x += translationVector.x;
|
||||||
|
gridStruct.position.y += translationVector.y;
|
||||||
|
gridStruct.position.z += translationVector.z;
|
||||||
|
// rendered position
|
||||||
|
transStruct.position.x += translationVector.x;
|
||||||
|
transStruct.position.y += translationVector.y;
|
||||||
|
transStruct.position.z += translationVector.z;
|
||||||
|
// collision position
|
||||||
|
this.physWorld.EntityManager.SetComponentData(phyStruct.uecsEntity, new Translation
|
||||||
|
{
|
||||||
|
Value = posStruct.position
|
||||||
|
});
|
||||||
|
return posStruct.position;
|
||||||
|
}
|
||||||
|
|
||||||
|
private float3 TranslateConnectedBlocks(uint blockID, float3 translationVector)
|
||||||
|
{
|
||||||
|
//float3 newPosition = TranslateSingleBlock(blockID, translationVector);
|
||||||
|
HashSet<uint> processedCubes = new HashSet<uint>();
|
||||||
|
Stack<uint> cubeStack = new Stack<uint>();
|
||||||
|
cubeStack.Push(blockID);
|
||||||
|
uint count;
|
||||||
|
GridConnectionsEntityStruct blockConnections;
|
||||||
|
MachineGraphConnectionEntityStruct[] connections;
|
||||||
|
|
||||||
|
while (cubeStack.Count > 0) // find all inter-connected blocks
|
||||||
|
{
|
||||||
|
uint connectedBlockID = cubeStack.Pop();
|
||||||
|
processedCubes.Add(connectedBlockID);
|
||||||
|
ScalingEntityStruct scale = entitiesDB.QueryEntity<ScalingEntityStruct>(connectedBlockID, CommonExclusiveGroups.OWNED_BLOCKS_GROUP);
|
||||||
|
uREPL.Log.Output($"Catching {connectedBlockID} with scale {scale.scale}");
|
||||||
|
blockConnections = entitiesDB.QueryEntity<GridConnectionsEntityStruct>(connectedBlockID, CommonExclusiveGroups.OWNED_BLOCKS_GROUP);
|
||||||
|
connections = entitiesDB.QueryEntities<MachineGraphConnectionEntityStruct>(blockConnections.connectionGroup, out count);
|
||||||
|
|
||||||
|
foreach (MachineGraphConnectionEntityStruct conn in connections)
|
||||||
|
{
|
||||||
|
if (!processedCubes.Contains(conn.connectedBlock.entityID)
|
||||||
|
&& blockConnections.isConnectionGroupAssigned
|
||||||
|
&& (conn.oppositeConnectionEgid.entityID != 0u
|
||||||
|
|| conn.oppositeConnectionEgid.entityID != conn.connectedBlock.entityID))
|
||||||
|
{
|
||||||
|
uREPL.Log.Output($"Block {connectedBlockID} connects to {conn.connectedBlock.entityID} (opposite {conn.oppositeConnectionEgid.entityID})");
|
||||||
|
cubeStack.Push(conn.connectedBlock.entityID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foreach (uint id in processedCubes)
|
||||||
|
{
|
||||||
|
TranslateSingleBlock(id, translationVector);
|
||||||
|
}
|
||||||
|
uREPL.Log.Output($"Found {processedCubes.Count} connected blocks");
|
||||||
|
return this.entitiesDB.QueryEntity<PositionEntityStruct>(blockID, CommonExclusiveGroups.OWNED_BLOCKS_GROUP).position;
|
||||||
|
}
|
||||||
|
|
||||||
|
// unused; for future reference
|
||||||
|
private void ToggleMode()
|
||||||
|
{
|
||||||
|
ref SimulationModeStateEntityStruct ptr = ref this.entitiesDB.QueryUniqueEntity<SimulationModeStateEntityStruct>(SimulationModeStateExclusiveGroups.GAME_STATE_GROUP);
|
||||||
|
ref SimulationFrameEntityStruct ptr2 = ref this.entitiesDB.QueryUniqueEntity<SimulationFrameEntityStruct>(SimulationFrame.SimulationFrameGroup);
|
||||||
|
switch (ptr.simulationMode)
|
||||||
|
{
|
||||||
|
case SimulationMode.Build:
|
||||||
|
ptr.simulationMode = SimulationMode.SwitchToSim;
|
||||||
|
ptr.simulationModeChangeFrame = ptr2.simFrame;
|
||||||
|
return;
|
||||||
|
case SimulationMode.SwitchToSim:
|
||||||
|
case SimulationMode.SwitchToBuild:
|
||||||
|
return;
|
||||||
|
case SimulationMode.Simulation:
|
||||||
|
ptr.simulationMode = SimulationMode.SwitchToBuild;
|
||||||
|
ptr.simulationModeChangeFrame = ptr2.simFrame;
|
||||||
|
ptr.rigidBodiesCreated = false;
|
||||||
|
return;
|
||||||
|
default:
|
||||||
|
throw new ArgumentOutOfRangeException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// unused; for future reference
|
||||||
|
private IEnumerator<TaskContract> TriggerSwitchToSimTask()
|
||||||
|
{
|
||||||
|
this.ToggleMode();
|
||||||
|
yield break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// unused; for future reference
|
||||||
|
private IEnumerator<TaskContract> WaitThenTriggerSwitchToBuildTask()
|
||||||
|
{
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
SimulationModeStateEntityStruct modeStruct = this.entitiesDB.QueryUniqueEntity<SimulationModeStateEntityStruct>(SimulationModeStateExclusiveGroups.GAME_STATE_GROUP);
|
||||||
|
if (modeStruct.simulationMode == SimulationMode.Simulation)
|
||||||
|
{
|
||||||
|
this.ToggleMode();
|
||||||
|
break;
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
yield return Yield.It;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
yield break;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Dispose()
|
||||||
|
{
|
||||||
|
CustomCommandUtility.Unregister("MoveBlocks");
|
||||||
|
CustomCommandUtility.Unregister("MoveLastBlock");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,37 +14,139 @@ using Unity.Transforms;
|
||||||
using Unity.Mathematics;
|
using Unity.Mathematics;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
using GamecraftModdingAPI.Commands;
|
|
||||||
using GamecraftModdingAPI.Blocks;
|
|
||||||
|
|
||||||
namespace ExtraCommands.Building
|
namespace ExtraCommands.Building
|
||||||
{
|
{
|
||||||
//[CustomCommand("RotateBlocks", "Rotate all blocks (including ground) from their original position")]
|
//[CustomCommand("RotateBlocks", "Rotate all blocks (including ground) from their original position")]
|
||||||
[CustomCommand("RotateLastBlock", "Rotate last block from original position")]
|
[CustomCommand("RotateLastBlock", "Rotate last block from original position")]
|
||||||
class RotateBlocksCommandEngine : ICustomCommandEngine
|
class RotateBlocksCommandEngine : CustomCommandEngine
|
||||||
{
|
{
|
||||||
public string Description => "Rotate last block from original position";
|
public RotateBlocksCommandEngine(UnityContext<FullGameCompositionRoot> ctxHolder, EnginesRoot enginesRoot, World physW, Action reloadGame, MultiplayerInitParameters mpParams) : base(ctxHolder, enginesRoot, physW, reloadGame, mpParams)
|
||||||
|
|
||||||
public string Name => "RotateLastBlock";
|
|
||||||
|
|
||||||
public IEntitiesDB entitiesDB { set; private get; }
|
|
||||||
|
|
||||||
public void Ready()
|
|
||||||
{
|
{
|
||||||
CommandRegistrationHelper.Register<float, float, float>(Name, RotateLastBlockCommand, Description);
|
}
|
||||||
|
|
||||||
|
public override void Ready()
|
||||||
|
{
|
||||||
|
//CustomCommandUtility.Register<float, float, float>("RotateBlocks", RotateBlocksCommand, "Rotate all blocks (including ground) from their original position");
|
||||||
|
CustomCommandUtility.Register<float, float, float>("RotateLastBlock", RotateLastBlockCommand, "Rotate last block from original position");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Move every block by vector (x,y,z)
|
||||||
|
private void RotateBlocksCommand(float x, float y, float z)
|
||||||
|
{
|
||||||
|
Vector3 eulerAngles = new Vector3(x, y, z);
|
||||||
|
ref SimulationModeStateEntityStruct simMode = ref this.entitiesDB.QueryUniqueEntity<SimulationModeStateEntityStruct>(SimulationModeStateExclusiveGroups.GAME_STATE_GROUP);
|
||||||
|
if (simMode.simulationMode != SimulationMode.Build)
|
||||||
|
{
|
||||||
|
uREPL.Log.Error("Blocks can only be moved in Build Mode");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
uint count = entitiesDB.Count<RotationEntityStruct>(CommonExclusiveGroups.OWNED_BLOCKS_GROUP);
|
||||||
|
for (uint i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
RotateSingleBlock(i, eulerAngles);
|
||||||
|
}
|
||||||
|
uREPL.Log.Output($"Moved {count} blocks");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Move block with highest index by vector (x,y,z)
|
// Move block with highest index by vector (x,y,z)
|
||||||
private void RotateLastBlockCommand(float x, float y, float z)
|
private void RotateLastBlockCommand(float x, float y, float z)
|
||||||
{
|
{
|
||||||
float3 eulerAngles = new float3(x, y, z);
|
Vector3 eulerAngles = new Vector3(x, y, z);
|
||||||
GamecraftModdingAPI.Blocks.Rotation.RotateBlock(BlockIdentifiers.LatestBlockID, eulerAngles);
|
ref SimulationModeStateEntityStruct simMode = ref this.entitiesDB.QueryUniqueEntity<SimulationModeStateEntityStruct>(SimulationModeStateExclusiveGroups.GAME_STATE_GROUP);
|
||||||
|
if (simMode.simulationMode != SimulationMode.Build)
|
||||||
|
{
|
||||||
|
uREPL.Log.Error("Blocks can only be moved in Build Mode");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
uint count = entitiesDB.Count<RotationEntityStruct>(CommonExclusiveGroups.OWNED_BLOCKS_GROUP);
|
||||||
|
if (count == 0)
|
||||||
|
{
|
||||||
|
uREPL.Log.Error("No block found");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Vector3 newRotation = RotateSingleBlock(count - 1, eulerAngles);
|
||||||
|
uREPL.Log.Output($"Rotated block to ({newRotation.x},{newRotation.y},{newRotation.z})");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
private float3 RotateSingleBlock(uint blockID, Vector3 rotationVector)
|
||||||
|
{
|
||||||
|
ref RotationEntityStruct rotStruct = ref this.entitiesDB.QueryEntity<RotationEntityStruct>(blockID, CommonExclusiveGroups.OWNED_BLOCKS_GROUP);
|
||||||
|
ref GridRotationStruct gridStruct = ref this.entitiesDB.QueryEntity<GridRotationStruct>(blockID, CommonExclusiveGroups.OWNED_BLOCKS_GROUP);
|
||||||
|
ref LocalTransformEntityStruct transStruct = ref this.entitiesDB.QueryEntity<LocalTransformEntityStruct>(blockID, CommonExclusiveGroups.OWNED_BLOCKS_GROUP);
|
||||||
|
ref UECSPhysicsEntityStruct phyStruct = ref this.entitiesDB.QueryEntity<UECSPhysicsEntityStruct>(blockID, CommonExclusiveGroups.OWNED_BLOCKS_GROUP);
|
||||||
|
// main (persistent) position
|
||||||
|
Quaternion newRotation = (Quaternion)rotStruct.rotation;
|
||||||
|
newRotation.eulerAngles += rotationVector;
|
||||||
|
rotStruct.rotation = (quaternion)newRotation;
|
||||||
|
// placement grid rotation
|
||||||
|
Quaternion newGridRotation = (Quaternion)gridStruct.rotation;
|
||||||
|
newGridRotation.eulerAngles += rotationVector;
|
||||||
|
gridStruct.rotation = (quaternion)newGridRotation;
|
||||||
|
// rendered position
|
||||||
|
Quaternion newTransRotation = (Quaternion)rotStruct.rotation;
|
||||||
|
newTransRotation.eulerAngles += rotationVector;
|
||||||
|
transStruct.rotation = newTransRotation;
|
||||||
|
// collision position
|
||||||
|
this.physWorld.EntityManager.SetComponentData(phyStruct.uecsEntity, new Rotation
|
||||||
|
{
|
||||||
|
Value = rotStruct.rotation
|
||||||
|
});
|
||||||
|
return ((Quaternion)rotStruct.rotation).eulerAngles;
|
||||||
|
}
|
||||||
|
|
||||||
|
// unused; for future reference
|
||||||
|
private void ToggleMode()
|
||||||
|
{
|
||||||
|
ref SimulationModeStateEntityStruct ptr = ref this.entitiesDB.QueryUniqueEntity<SimulationModeStateEntityStruct>(SimulationModeStateExclusiveGroups.GAME_STATE_GROUP);
|
||||||
|
ref SimulationFrameEntityStruct ptr2 = ref this.entitiesDB.QueryUniqueEntity<SimulationFrameEntityStruct>(SimulationFrame.SimulationFrameGroup);
|
||||||
|
switch (ptr.simulationMode)
|
||||||
|
{
|
||||||
|
case SimulationMode.Build:
|
||||||
|
ptr.simulationMode = SimulationMode.SwitchToSim;
|
||||||
|
ptr.simulationModeChangeFrame = ptr2.simFrame;
|
||||||
|
return;
|
||||||
|
case SimulationMode.SwitchToSim:
|
||||||
|
case SimulationMode.SwitchToBuild:
|
||||||
|
return;
|
||||||
|
case SimulationMode.Simulation:
|
||||||
|
ptr.simulationMode = SimulationMode.SwitchToBuild;
|
||||||
|
ptr.simulationModeChangeFrame = ptr2.simFrame;
|
||||||
|
ptr.rigidBodiesCreated = false;
|
||||||
|
return;
|
||||||
|
default:
|
||||||
|
throw new ArgumentOutOfRangeException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// unused; for future reference
|
||||||
|
private IEnumerator<TaskContract> TriggerSwitchToSimTask()
|
||||||
|
{
|
||||||
|
this.ToggleMode();
|
||||||
|
yield break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// unused; for future reference
|
||||||
|
private IEnumerator<TaskContract> WaitThenTriggerSwitchToBuildTask()
|
||||||
|
{
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
SimulationModeStateEntityStruct modeStruct = this.entitiesDB.QueryUniqueEntity<SimulationModeStateEntityStruct>(SimulationModeStateExclusiveGroups.GAME_STATE_GROUP);
|
||||||
|
if (modeStruct.simulationMode == SimulationMode.Simulation)
|
||||||
|
{
|
||||||
|
this.ToggleMode();
|
||||||
|
break;
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
yield return Yield.It;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
yield break;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Dispose()
|
||||||
{
|
{
|
||||||
//CustomCommandUtility.Unregister("RotateBlocks");
|
//CustomCommandUtility.Unregister("RotateBlocks");
|
||||||
CommandRegistrationHelper.Unregister("RotateLastBlock");
|
CustomCommandUtility.Unregister("RotateLastBlock");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,35 +9,34 @@ using UnityEngine;
|
||||||
using uREPL;
|
using uREPL;
|
||||||
using Svelto.Context;
|
using Svelto.Context;
|
||||||
using RobocraftX;
|
using RobocraftX;
|
||||||
|
using Svelto.ECS.EntityStructs;
|
||||||
using Unity.Mathematics;
|
using Unity.Mathematics;
|
||||||
using RobocraftX.Character.Camera;
|
using RobocraftX.Character.Camera;
|
||||||
using RobocraftX.Character.Factories;
|
using RobocraftX.Character.Factories;
|
||||||
|
|
||||||
using GamecraftModdingAPI.Commands;
|
|
||||||
|
|
||||||
namespace ExtraCommands.Basics
|
namespace ExtraCommands.Basics
|
||||||
{
|
{
|
||||||
[CustomCommand("Rotation")]
|
[CustomCommand("RotateTo")]
|
||||||
class RotatePlayerCommandEngine : ICustomCommandEngine
|
class RotatePlayerCommandEngine : CustomCommandEngine
|
||||||
{
|
{
|
||||||
public string Description => "Rotation";
|
|
||||||
|
|
||||||
public string Name => "Rotation commands";
|
public RotatePlayerCommandEngine(UnityContext<FullGameCompositionRoot> ctxHolder, EnginesRoot enginesRoot, World physW, Action reloadGame, MultiplayerInitParameters mpParams) : base(ctxHolder, enginesRoot, physW, reloadGame, mpParams)
|
||||||
|
|
||||||
public IEntitiesDB entitiesDB { set; private get; }
|
|
||||||
|
|
||||||
public void Ready()
|
|
||||||
{
|
{
|
||||||
CommandRegistrationHelper.Register<float, float>("RotateAbsolute", RotateAbsoluteCommand, "Rotate the player camera to the entered rotation");
|
}
|
||||||
CommandRegistrationHelper.Register<float, float>("RotateRelative", RotateRelativeCommand, "Rotate the player camera by the entered rotation");
|
|
||||||
|
public override void Ready()
|
||||||
|
{
|
||||||
|
CustomCommandUtility.Register<float, float>("RotateAbsolute", RotateAbsoluteCommand, "Rotate the player camera to the entered rotation");
|
||||||
|
CustomCommandUtility.Register<float, float>("RotateRelative", RotateRelativeCommand, "Rotate the player camera by the entered rotation");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void RotateAbsoluteCommand(float vertical, float horizontal)
|
private void RotateAbsoluteCommand(float vertical, float horizontal)
|
||||||
{
|
{
|
||||||
EntityCollection<CharacterCameraEntityStruct> cameras = entitiesDB.QueryEntities<CharacterCameraEntityStruct>(CameraExclusiveGroups.VisualCameraGroup);
|
uint count;
|
||||||
|
CharacterCameraEntityStruct[] cameras = entitiesDB.QueryEntities<CharacterCameraEntityStruct>(CameraExclusiveGroups.VisualCameraGroup, out count);
|
||||||
int num2 = 0;
|
int num2 = 0;
|
||||||
while (num2 < cameras.length)
|
while ((long)num2 < (long)((ulong)count))
|
||||||
{
|
{
|
||||||
cameras[num2].eulerRotation.x = vertical;
|
cameras[num2].eulerRotation.x = vertical;
|
||||||
cameras[num2].eulerRotation.y = horizontal;
|
cameras[num2].eulerRotation.y = horizontal;
|
||||||
|
@ -58,11 +57,12 @@ namespace ExtraCommands.Basics
|
||||||
private void RotateRelativeCommand(float vertical, float horizontal)
|
private void RotateRelativeCommand(float vertical, float horizontal)
|
||||||
{
|
{
|
||||||
float2 angleDelta = new float2(vertical, horizontal);
|
float2 angleDelta = new float2(vertical, horizontal);
|
||||||
EntityCollection<CharacterCameraSettingsEntityStruct, CharacterCameraEntityStruct> tuple = this.entitiesDB.QueryEntities<CharacterCameraSettingsEntityStruct, CharacterCameraEntityStruct>(CameraExclusiveGroups.VisualCameraGroup);
|
uint count;
|
||||||
EntityCollection<CharacterCameraSettingsEntityStruct> settings = tuple.Item1;
|
ValueTuple<CharacterCameraSettingsEntityStruct[], CharacterCameraEntityStruct[]> tuple = this.entitiesDB.QueryEntities<CharacterCameraSettingsEntityStruct, CharacterCameraEntityStruct>(CameraExclusiveGroups.VisualCameraGroup, out count);
|
||||||
EntityCollection<CharacterCameraEntityStruct> cameras = tuple.Item2;
|
CharacterCameraSettingsEntityStruct[] settings = tuple.Item1;
|
||||||
|
CharacterCameraEntityStruct[] cameras = tuple.Item2;
|
||||||
int num2 = 0;
|
int num2 = 0;
|
||||||
while (num2 < cameras.length)
|
while ((long)num2 < (long)((ulong)count))
|
||||||
{
|
{
|
||||||
CharacterCameraMovementUtility.UpdateCameraRotationFromDelta(ref cameras[num2], in settings[num2], angleDelta);
|
CharacterCameraMovementUtility.UpdateCameraRotationFromDelta(ref cameras[num2], in settings[num2], angleDelta);
|
||||||
// TODO: Multiplayer compatibility
|
// TODO: Multiplayer compatibility
|
||||||
|
@ -79,10 +79,10 @@ namespace ExtraCommands.Basics
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public override void Dispose()
|
||||||
{
|
{
|
||||||
CommandRegistrationHelper.Unregister("RotateAbsolute");
|
CustomCommandUtility.Unregister("RotateAbsolute");
|
||||||
CommandRegistrationHelper.Unregister("RotateRelative");
|
CustomCommandUtility.Unregister("RotateRelative");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,22 +10,18 @@ using uREPL;
|
||||||
using Svelto.Context;
|
using Svelto.Context;
|
||||||
using RobocraftX;
|
using RobocraftX;
|
||||||
|
|
||||||
using GamecraftModdingAPI.Commands;
|
|
||||||
|
|
||||||
namespace ExtraCommands.Basics
|
namespace ExtraCommands.Basics
|
||||||
{
|
{
|
||||||
[CustomCommand("SetFieldOfView")]
|
[CustomCommand("SetFieldOfView")]
|
||||||
class SetFOVCommandEngine : ICustomCommandEngine
|
class SetFOVCommandEngine : CustomCommandEngine
|
||||||
{
|
{
|
||||||
public string Description => "Set the camera's field of view";
|
public SetFOVCommandEngine(UnityContext<FullGameCompositionRoot> ctxHolder, EnginesRoot enginesRoot, World physW, Action reloadGame, MultiplayerInitParameters mpParams) : base(ctxHolder, enginesRoot, physW, reloadGame, mpParams)
|
||||||
|
|
||||||
public string Name => "SetFieldOfView";
|
|
||||||
|
|
||||||
public IEntitiesDB entitiesDB { set; private get; }
|
|
||||||
|
|
||||||
public void Ready()
|
|
||||||
{
|
{
|
||||||
CommandRegistrationHelper.Register<float>(Name, SetFieldOfViewCommand, Description);
|
}
|
||||||
|
|
||||||
|
public override void Ready()
|
||||||
|
{
|
||||||
|
CustomCommandUtility.Register<float>("SetFieldOfView", SetFieldOfViewCommand, "Set the camera's field of view");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetFieldOfViewCommand(float newFoV)
|
private void SetFieldOfViewCommand(float newFoV)
|
||||||
|
@ -33,9 +29,9 @@ namespace ExtraCommands.Basics
|
||||||
Camera.main.fieldOfView = newFoV;
|
Camera.main.fieldOfView = newFoV;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public override void Dispose()
|
||||||
{
|
{
|
||||||
CommandRegistrationHelper.Unregister(Name);
|
CustomCommandUtility.Unregister("SetFieldOfView");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,158 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Reflection;
|
|
||||||
using GamecraftModdingAPI.Commands;
|
|
||||||
using Harmony;
|
|
||||||
using RobocraftX.GUI.CommandLine;
|
|
||||||
using RobocraftX.Multiplayer;
|
|
||||||
using RobocraftX.StateSync;
|
|
||||||
using RobocraftX.Character;
|
|
||||||
using Svelto.ECS;
|
|
||||||
using Unity.Entities;
|
|
||||||
using UnityEngine;
|
|
||||||
using uREPL;
|
|
||||||
using Svelto.Context;
|
|
||||||
using RobocraftX;
|
|
||||||
using RobocraftX.Blocks.Ghost;
|
|
||||||
using RobocraftX.Blocks.Scaling;
|
|
||||||
using RobocraftX.Common;
|
|
||||||
using RobocraftX.CR.MachineEditing;
|
|
||||||
using Svelto.ECS.EntityStructs;
|
|
||||||
using Unity.Mathematics;
|
|
||||||
|
|
||||||
namespace ExtraCommands.Basics
|
|
||||||
{
|
|
||||||
[CustomCommand("SetScale")]
|
|
||||||
class SetScaleCommandEngine : ICustomCommandEngine
|
|
||||||
{
|
|
||||||
|
|
||||||
public void Ready()
|
|
||||||
{
|
|
||||||
CommandRegistrationHelper.Register<float, float, float>("SetScale", SetScaleCommand, "Set the scale for the next block. Use 0 0 0 to reset. The displayed cube is uniformly scaled until placed.");
|
|
||||||
}
|
|
||||||
|
|
||||||
public IEntitiesDB entitiesDB { get; set; }
|
|
||||||
|
|
||||||
private static float3 _scale;
|
|
||||||
//private HarmonyInstance harmony;
|
|
||||||
|
|
||||||
private void SetScaleCommand(float x, float y, float z)
|
|
||||||
{
|
|
||||||
/*if (harmony == null)
|
|
||||||
{
|
|
||||||
Console.WriteLine("Patching...");
|
|
||||||
harmony = HarmonyInstance.Create("org.exmods.extracommands.setscale");
|
|
||||||
var type = Type.GetType("RobocraftX.CR.MachineEditing.PlacementCursorEngine");
|
|
||||||
var method = type.GetMethod("<UpdateCursor>g__UpdatePlacementCursorScales|10_0");
|
|
||||||
harmony.Patch(method, new HarmonyMethod(((Func<bool>) PatchPrefix).Method));
|
|
||||||
Console.WriteLine("Patched");
|
|
||||||
}*/
|
|
||||||
|
|
||||||
_scale = new float3(x, y, z);
|
|
||||||
EntityCollection<GhostScalingEntityStruct> scalings =
|
|
||||||
entitiesDB.QueryEntities<GhostScalingEntityStruct>(
|
|
||||||
(ExclusiveGroupStruct) NamedExclusiveGroup<GHOST_BLOCKS>.Group);
|
|
||||||
Console.WriteLine("Found " + scalings.length + " scalings.");
|
|
||||||
var egid = new EGID(0, NamedExclusiveGroup<GHOST_BLOCKS>.Group);
|
|
||||||
for (int index = 0; index < scalings.length; index++)
|
|
||||||
{
|
|
||||||
Console.WriteLine("G scaling " + index + ": " + scalings[index].ghostScale);
|
|
||||||
ref var scaling = ref entitiesDB.QueryEntity<ScalingEntityStruct>(egid);
|
|
||||||
Console.WriteLine("Scaling " + index + ": " + scaling);
|
|
||||||
ref var scale = ref entitiesDB.QueryEntity<BlockPlacementScaleEntityStruct>(egid);
|
|
||||||
Console.WriteLine("Scale " + index + ": " + scale.snapGridScale);
|
|
||||||
UpdateScale(ref scale, ref scaling, ref scalings[index], egid);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void UpdateScale(ref BlockPlacementScaleEntityStruct scale, ref ScalingEntityStruct scaling,
|
|
||||||
ref GhostScalingEntityStruct gscaling, EGID egid)
|
|
||||||
{
|
|
||||||
Console.WriteLine("Attempting to update scale...");
|
|
||||||
if (_scale.x < 4e-5 || _scale.y < 4e-5 || _scale.z < 4e-5) return;
|
|
||||||
Console.WriteLine("Scale is set, continuing.");
|
|
||||||
scale.snapGridScale = Math.Max((int) _scale.x, 1);
|
|
||||||
scale.blockPlacementHeight = Math.Max((int) _scale.y, 1);
|
|
||||||
scale.desiredScaleFactor = Math.Max((int) _scale.x, 1);
|
|
||||||
entitiesDB.PublishEntityChange<BlockPlacementScaleEntityStruct>(egid);
|
|
||||||
Console.WriteLine("Scale published");
|
|
||||||
scaling.scale = _scale;
|
|
||||||
entitiesDB.PublishEntityChange<ScalingEntityStruct>(egid);
|
|
||||||
Console.WriteLine("Scaling published");
|
|
||||||
gscaling.ghostScale = _scale;
|
|
||||||
gscaling.hasBlockBeenUnformedScaled = true; //Apply scale instead of overwriting it
|
|
||||||
entitiesDB.PublishEntityChange<GhostScalingEntityStruct>(egid);
|
|
||||||
Console.WriteLine("Scale updated (" + scaling.scale + ")");
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
CommandRegistrationHelper.Unregister("SetScale");
|
|
||||||
}
|
|
||||||
|
|
||||||
/*public void Add(ref GhostScalingEntityStruct entityView, EGID egid)
|
|
||||||
{ //If the cursor is near a block, it recreates the entity - nope
|
|
||||||
Console.WriteLine("Entity " + egid + " added: " + entityView.ghostScale);
|
|
||||||
ref var scale = ref entitiesDB.QueryEntity<BlockPlacementScaleEntityStruct>(egid);
|
|
||||||
ref var scaling = ref entitiesDB.QueryEntity<ScalingEntityStruct>(egid);
|
|
||||||
UpdateScale(ref scale, ref scaling, ref entityView);
|
|
||||||
entitiesDB.PublishEntityChange<ScalingEntityStruct>(egid);
|
|
||||||
entitiesDB.PublishEntityChange<BlockPlacementScaleEntityStruct>(egid);
|
|
||||||
entitiesDB.PublishEntityChange<GhostScalingEntityStruct>(egid);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Remove(ref GhostScalingEntityStruct entityView, EGID egid)
|
|
||||||
{
|
|
||||||
}*/
|
|
||||||
|
|
||||||
/*private bool PatchPrefix()
|
|
||||||
{
|
|
||||||
if (math.any(_scale < new float3(4e-5)))
|
|
||||||
return true;
|
|
||||||
return false; //Prevent updating
|
|
||||||
}*/
|
|
||||||
|
|
||||||
//ScaleGhostBlockEngine.UpdateScaling
|
|
||||||
[HarmonyPatch]
|
|
||||||
public class ScalePatch
|
|
||||||
{
|
|
||||||
static bool Prefix()
|
|
||||||
{
|
|
||||||
if (math.any(_scale < new float3(4e-5)))
|
|
||||||
return true;
|
|
||||||
return false; //Prevent updating
|
|
||||||
}
|
|
||||||
|
|
||||||
static MethodBase TargetMethod(HarmonyInstance instance)
|
|
||||||
{
|
|
||||||
return typeof(ScaleGhostBlockEngine).GetMethod("UpdateScaling",
|
|
||||||
BindingFlags.NonPublic | BindingFlags.Instance);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//RobocraftX.Blocks.Ghost.UniformScaleGhostBlockEngine.SimulatePhysicsStep - Does not update the ghost block but the outline still gets rounded
|
|
||||||
//RobocraftX.Blocks.Ghost.GhostScalingSyncEngine.SimulatePhysicsStep (reflection) - Doesn't do anything immediately visible
|
|
||||||
//RobocraftX.CR.MachineEditing.PlacementCursorEngine.<UpdateCursor>g__UpdatePlacementCursorScales|10_0
|
|
||||||
//[HarmonyPatch(typeof(UniformScaleGhostBlockEngine))]
|
|
||||||
//[HarmonyPatch("SimulatePhysicsStep")]
|
|
||||||
//[HarmonyPatch]
|
|
||||||
public class UniformScalePatch
|
|
||||||
{
|
|
||||||
static bool Prefix()
|
|
||||||
{
|
|
||||||
if (math.any(_scale < new float3(4e-5)))
|
|
||||||
return true;
|
|
||||||
return false; //Prevent updating
|
|
||||||
}
|
|
||||||
|
|
||||||
static MethodBase TargetMethod(HarmonyInstance instance)
|
|
||||||
{
|
|
||||||
return typeof(PlacementCursorEngine)
|
|
||||||
.GetMethods(BindingFlags.NonPublic | BindingFlags.Instance)
|
|
||||||
.First(m => m.Name.Contains("UpdatePlacementCursorScales"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public string Name { get; } = "SetScale";
|
|
||||||
public string Description { get; } = "Set the scale for the next block to be placed.";
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -10,22 +10,18 @@ using uREPL;
|
||||||
using Svelto.Context;
|
using Svelto.Context;
|
||||||
using RobocraftX;
|
using RobocraftX;
|
||||||
|
|
||||||
using GamecraftModdingAPI.Commands;
|
|
||||||
|
|
||||||
namespace ExtraCommands.Basics
|
namespace ExtraCommands.Basics
|
||||||
{
|
{
|
||||||
[CustomCommand("SetTargetFPS")]
|
[CustomCommand("SetTargetFPS")]
|
||||||
class SetTargetFramerateCommandEngine : ICustomCommandEngine
|
class SetTargetFramerateCommandEngine : CustomCommandEngine
|
||||||
{
|
{
|
||||||
public string Description => "Set Gamecraft's target FPS'";
|
public SetTargetFramerateCommandEngine(UnityContext<FullGameCompositionRoot> ctxHolder, EnginesRoot enginesRoot, World physW, Action reloadGame, MultiplayerInitParameters mpParams) : base(ctxHolder, enginesRoot, physW, reloadGame, mpParams)
|
||||||
|
|
||||||
public string Name => "SetTargetFPS";
|
|
||||||
|
|
||||||
public IEntitiesDB entitiesDB { set; private get; }
|
|
||||||
|
|
||||||
public void Ready()
|
|
||||||
{
|
{
|
||||||
CommandRegistrationHelper.Register<int>(Name, SetFramerateCommand, Description);
|
}
|
||||||
|
|
||||||
|
public override void Ready()
|
||||||
|
{
|
||||||
|
CustomCommandUtility.Register<int>("SetTargetFPS", SetFramerateCommand, "Set Gamecraft's target FPS");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetFramerateCommand(int newFoV)
|
private void SetFramerateCommand(int newFoV)
|
||||||
|
@ -33,9 +29,9 @@ namespace ExtraCommands.Basics
|
||||||
Application.targetFrameRate = newFoV;
|
Application.targetFrameRate = newFoV;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public override void Dispose()
|
||||||
{
|
{
|
||||||
CommandRegistrationHelper.Unregister(Name);
|
CustomCommandUtility.Unregister("SetTargetFPS");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,42 +9,26 @@ using Unity.Entities;
|
||||||
using uREPL;
|
using uREPL;
|
||||||
using Svelto.Context;
|
using Svelto.Context;
|
||||||
using RobocraftX;
|
using RobocraftX;
|
||||||
using RobocraftX.Physics;
|
|
||||||
|
|
||||||
using GamecraftModdingAPI.Commands;
|
|
||||||
|
|
||||||
namespace ExtraCommands.Waypoints
|
namespace ExtraCommands.Waypoints
|
||||||
{
|
{
|
||||||
[CustomCommand("Waypoints")]
|
[CustomCommand]
|
||||||
class TeleportWaypointCommandEngine : ICustomCommandEngine
|
class TeleportWaypointCommandEngine : CustomCommandEngine
|
||||||
{
|
{
|
||||||
private Dictionary<object, float[]> _waypoints = new Dictionary<object, float[]>();
|
private Dictionary<object, float[]> _waypoints = new Dictionary<object, float[]>();
|
||||||
|
public TeleportWaypointCommandEngine(UnityContext<FullGameCompositionRoot> ctxHolder, EnginesRoot enginesRoot, World physW, Action reloadGame, MultiplayerInitParameters mpParams) : base(ctxHolder, enginesRoot, physW, reloadGame, mpParams)
|
||||||
public string Description => "";
|
|
||||||
|
|
||||||
public string Name => "Waypoints";
|
|
||||||
|
|
||||||
public IEntitiesDB entitiesDB { set; private get; }
|
|
||||||
|
|
||||||
public void Ready()
|
|
||||||
{
|
{
|
||||||
CommandRegistrationHelper.Register<object>("CreateWaypoint", CreateWaypointCommand, "Create a waypoint in your current location");
|
}
|
||||||
CommandRegistrationHelper.Register<object>("TeleportPlayerWaypoint", TeleportToWaypointCommand, "Teleport to a waypoint");
|
|
||||||
|
public override void Ready()
|
||||||
|
{
|
||||||
|
CustomCommandUtility.Register<object>("CreateWaypoint", CreateWaypointCommand, "Create a waypoint in your current location");
|
||||||
|
CustomCommandUtility.Register<object>("TeleportPlayerWaypoint", TeleportToWaypointCommand, "Teleport to a waypoint");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CreateWaypointCommand(object name)
|
private void CreateWaypointCommand(object name)
|
||||||
{
|
{
|
||||||
RigidBodyEntityStruct reference;
|
ref RigidBodyEntityStruct reference = ref entitiesDB.QueryEntity<RigidBodyEntityStruct>(0u, CharacterExclusiveGroups.CharacterGroup);
|
||||||
if (entitiesDB.TryQueryEntitiesAndIndex(0u, CharacterExclusiveGroups.OnFootGroup, out uint index,
|
|
||||||
out RigidBodyEntityStruct[] array)
|
|
||||||
|| entitiesDB.TryQueryEntitiesAndIndex(0u, CharacterExclusiveGroups.InPilotSeatGroup, out index,
|
|
||||||
out array))
|
|
||||||
reference = array[index];
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Log.Output("Player not found!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
_waypoints[name] = new float[3] { reference.position.x, reference.position.y, reference.position.z };
|
_waypoints[name] = new float[3] { reference.position.x, reference.position.y, reference.position.z };
|
||||||
uREPL.Log.Output("Saved " + name.ToString());
|
uREPL.Log.Output("Saved " + name.ToString());
|
||||||
}
|
}
|
||||||
|
@ -56,20 +40,14 @@ namespace ExtraCommands.Waypoints
|
||||||
uREPL.Log.Error("Waypoint not found");
|
uREPL.Log.Error("Waypoint not found");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
float[] loc = _waypoints[name];
|
||||||
if (entitiesDB.Exists<RigidBodyEntityStruct>(0u, CharacterExclusiveGroups.InPilotSeatGroup))
|
|
||||||
{
|
|
||||||
Log.Error("Cannot teleport from a pilot seat");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
float[] loc = _waypoints[name];
|
|
||||||
uREPL.RuntimeCommands.Call<float, float, float>("TeleportPlayerAbsolute", loc[0], loc[1], loc[2]);
|
uREPL.RuntimeCommands.Call<float, float, float>("TeleportPlayerAbsolute", loc[0], loc[1], loc[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public override void Dispose()
|
||||||
{
|
{
|
||||||
CommandRegistrationHelper.Unregister("CreateWaypoint");
|
CustomCommandUtility.Unregister("CreateWaypoint");
|
||||||
CommandRegistrationHelper.Unregister("TeleportPlayerWaypoint");
|
CustomCommandUtility.Unregister("TeleportPlayerWaypoint");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
57
extracommands/ToggleJumpCommandEngine.cs
Normal file
57
extracommands/ToggleJumpCommandEngine.cs
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
using System;
|
||||||
|
using System.Reflection;
|
||||||
|
using Harmony;
|
||||||
|
using RobocraftX.GUI.CommandLine;
|
||||||
|
using RobocraftX.Multiplayer;
|
||||||
|
using RobocraftX.StateSync;
|
||||||
|
using RobocraftX.Character;
|
||||||
|
using RobocraftX.Character.Movement;
|
||||||
|
using RobocraftX.Common.Input;
|
||||||
|
using Svelto.ECS;
|
||||||
|
using Unity.Entities;
|
||||||
|
using UnityEngine;
|
||||||
|
using uREPL;
|
||||||
|
using Svelto.Context;
|
||||||
|
using RobocraftX;
|
||||||
|
|
||||||
|
namespace ExtraCommands.Basics
|
||||||
|
{
|
||||||
|
//[HarmonyPatch]
|
||||||
|
//[CustomCommand("ToggleJumpEnabled")]
|
||||||
|
class ToggleJumpCommandEngine : CustomCommandEngine
|
||||||
|
{
|
||||||
|
private static bool isJumpEnabled = false;
|
||||||
|
public ToggleJumpCommandEngine(UnityContext<FullGameCompositionRoot> ctxHolder, EnginesRoot enginesRoot, World physW, Action reloadGame, MultiplayerInitParameters mpParams) : base(ctxHolder, enginesRoot, physW, reloadGame, mpParams)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Ready()
|
||||||
|
{
|
||||||
|
CustomCommandUtility.Register<bool>("ToggleJumpEnabled", ToggleJumpCommand, "Enable or disable the character's ability to jump");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ToggleJumpCommand(bool isEnabled)
|
||||||
|
{
|
||||||
|
isJumpEnabled = isEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Dispose()
|
||||||
|
{
|
||||||
|
CustomCommandUtility.Unregister("ToggleJumpEnabled");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Postfix (ref CharacterInputEntityStruct input, InputStruct entity)
|
||||||
|
{
|
||||||
|
if (entity.CheckInputAction(ActionInput.Up) && !isJumpEnabled)
|
||||||
|
{
|
||||||
|
input.action.y -= 1f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static MethodBase TargetMethod(HarmonyInstance instance)
|
||||||
|
{
|
||||||
|
Type targetType = Harmony.AccessTools.TypeByName("RobocraftX.Character.Input.CharacterInputEngine");
|
||||||
|
return Harmony.AccessTools.Method(targetType, "SaveInput", new Type[] { typeof(CharacterInputEntityStruct), typeof(InputStruct) });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -10,22 +10,18 @@ using uREPL;
|
||||||
using Svelto.Context;
|
using Svelto.Context;
|
||||||
using RobocraftX;
|
using RobocraftX;
|
||||||
|
|
||||||
using GamecraftModdingAPI.Commands;
|
|
||||||
|
|
||||||
namespace ExtraCommands.Basics
|
namespace ExtraCommands.Basics
|
||||||
{
|
{
|
||||||
[CustomCommand("Wait")]
|
[CustomCommand("Wait")]
|
||||||
class WaitCommandEngine : ICustomCommandEngine
|
class WaitCommandEngine : CustomCommandEngine
|
||||||
{
|
{
|
||||||
public string Description => "Delay execution (freeze the game) for a length of time (ms)";
|
public WaitCommandEngine(UnityContext<FullGameCompositionRoot> ctxHolder, EnginesRoot enginesRoot, World physW, Action reloadGame, MultiplayerInitParameters mpParams) : base(ctxHolder, enginesRoot, physW, reloadGame, mpParams)
|
||||||
|
|
||||||
public string Name => "Wait";
|
|
||||||
|
|
||||||
public IEntitiesDB entitiesDB { set; private get; }
|
|
||||||
|
|
||||||
public void Ready()
|
|
||||||
{
|
{
|
||||||
CommandRegistrationHelper.Register<int>("Wait", WaitCommand, "Delay execution (freeze the game) for a length of time (ms)");
|
}
|
||||||
|
|
||||||
|
public override void Ready()
|
||||||
|
{
|
||||||
|
CustomCommandUtility.Register<int>("Wait", WaitCommand, "Delay execution (freeze the game) for a length of time (ms)");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void WaitCommand(int ms)
|
private void WaitCommand(int ms)
|
||||||
|
@ -33,9 +29,9 @@ namespace ExtraCommands.Basics
|
||||||
System.Threading.Thread.Sleep(ms);
|
System.Threading.Thread.Sleep(ms);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public override void Dispose()
|
||||||
{
|
{
|
||||||
CommandRegistrationHelper.Unregister("Wait");
|
CustomCommandUtility.Unregister("Wait");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue