Use identified objects in console blocks
This commit is contained in:
parent
dbb65ac65a
commit
0b42884f3a
1 changed files with 85 additions and 100 deletions
|
@ -16,25 +16,26 @@ using RobocraftX.Common.Players;
|
||||||
using Svelto.ECS;
|
using Svelto.ECS;
|
||||||
using Svelto.ECS.Internal;
|
using Svelto.ECS.Internal;
|
||||||
using Unity.Mathematics;
|
using Unity.Mathematics;
|
||||||
|
using uREPL;
|
||||||
using Main = GamecraftModdingAPI.Main;
|
using Main = GamecraftModdingAPI.Main;
|
||||||
|
|
||||||
namespace BlockMod
|
namespace BlockMod
|
||||||
{
|
{
|
||||||
public class BlockMod : IPlugin
|
public class BlockMod : IPlugin
|
||||||
{
|
{
|
||||||
|
private Block[] blocks = new Block[0];
|
||||||
|
private Block refBlock;
|
||||||
public void OnApplicationStart()
|
public void OnApplicationStart()
|
||||||
{
|
{
|
||||||
Main.Init();
|
Main.Init();
|
||||||
GameClient.SetDebugInfo("BlockModInfo", GetBlockInfo);
|
GameClient.SetDebugInfo("BlockModInfo", GetBlockInfo);
|
||||||
Block[] blocks = new Block[0];
|
RegisterBlockCommand("scaleBlocks",
|
||||||
Block refBlock = null;
|
"Scales the blocks you're looking at, relative to current size (current scale * new scale)." +
|
||||||
CommandBuilder.Builder("scaleBlocks",
|
" The block you're looking at stays where it is, everything else is moved next to it.",
|
||||||
"Scales the blocks you're looking at, relative to current size (current scale * new scale)." +
|
(scaleX, scaleY, scaleZ, blocks, refBlock) =>
|
||||||
" The block you're looking at stays where it is, everything else is moved next to it." +
|
|
||||||
" The command remembers the cluster of blocks, use forgetBlocks to forget it.")
|
|
||||||
.Action<float, float, float>((scaleX, scaleY, scaleZ) =>
|
|
||||||
{
|
{
|
||||||
if(CheckNoBlocks(blocks)) return;
|
if (!GameState.IsBuildMode()) return; //Scaling & positioning is weird in simulation
|
||||||
|
if (CheckNoBlocks(blocks)) return;
|
||||||
// ReSharper disable once PossibleNullReferenceException
|
// ReSharper disable once PossibleNullReferenceException
|
||||||
float3 reference = refBlock.Position;
|
float3 reference = refBlock.Position;
|
||||||
float3 scale = new float3(scaleX, scaleY, scaleZ);
|
float3 scale = new float3(scaleX, scaleY, scaleZ);
|
||||||
|
@ -45,38 +46,36 @@ namespace BlockMod
|
||||||
}
|
}
|
||||||
|
|
||||||
Logging.CommandLog("Blocks scaled.");
|
Logging.CommandLog("Blocks scaled.");
|
||||||
}).Build();
|
});
|
||||||
CommandBuilder.Builder("scaleIndividually", "Scales the blocks you're looking at, but doesn't move them." +
|
RegisterBlockCommand("scaleIndividually", "Scales the blocks you're looking at, but doesn't move them." +
|
||||||
"The scale is relative, 1 means no change. Look at a block previously scaled to scale all of the blocks that were connected to it.")
|
"The scale is relative, 1 means no change. Look at a block previously scaled to scale all of the blocks that were connected to it.",
|
||||||
.Action<float, float, float>((scaleX, scaleY, scaleZ) =>
|
(scaleX, scaleY, scaleZ, blocks, refBlock) =>
|
||||||
{
|
{
|
||||||
if(CheckNoBlocks(blocks)) return;
|
if (!GameState.IsBuildMode()) return; //Scaling & positioning is weird in simulation
|
||||||
float3 scale = new float3(scaleX, scaleY, scaleZ);
|
float3 scale = new float3(scaleX, scaleY, scaleZ);
|
||||||
foreach (var block in blocks)
|
foreach (var block in blocks)
|
||||||
block.Scale *= scale;
|
block.Scale *= scale;
|
||||||
}).Build();
|
});
|
||||||
CommandBuilder.Builder("moveBlocks", "Moves the blocks around.")
|
RegisterBlockCommand("moveBlocks", "Moves the blocks around.", (x, y, z, blocks, refBlock) =>
|
||||||
.Action<float, float, float>((x, y, z) =>
|
{
|
||||||
|
if (GameState.IsBuildMode())
|
||||||
|
foreach (var block in blocks)
|
||||||
|
block.Position += new float3(x, y, z);
|
||||||
|
else if (GameState.IsSimulationMode())
|
||||||
|
foreach (var body in GetSimBodies(blocks))
|
||||||
|
body.Position += new float3(x, y, z);
|
||||||
|
});
|
||||||
|
RegisterBlockCommand("colorBlocks", "Colors the blocks you're looking at",
|
||||||
|
(color, darkness, blocks, refBlock) =>
|
||||||
{
|
{
|
||||||
if (CheckNoBlocks(blocks)) return;
|
|
||||||
if (GameState.IsBuildMode())
|
|
||||||
foreach (var block in blocks)
|
|
||||||
block.Position += new float3(x, y, z);
|
|
||||||
else if (GameState.IsSimulationMode())
|
|
||||||
foreach (var body in GetSimBodies(blocks))
|
|
||||||
body.Position += new float3(x, y, z);
|
|
||||||
}).Build();
|
|
||||||
CommandBuilder.Builder("colorBlocks", "Colors the blocks you're looking at")
|
|
||||||
.Action<string, byte>((color, darkness) =>
|
|
||||||
{
|
|
||||||
if(CheckNoBlocks(blocks)) return;
|
|
||||||
if (!Enum.TryParse(color, true, out BlockColors clr))
|
if (!Enum.TryParse(color, true, out BlockColors clr))
|
||||||
{
|
{
|
||||||
Logging.CommandLogWarning("Color " + color + " not found");
|
Logging.CommandLogWarning("Color " + color + " not found");
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var block in blocks)
|
foreach (var block in blocks)
|
||||||
block.Color = new BlockColor {Color = clr, Darkness = darkness};
|
block.Color = new BlockColor {Color = clr, Darkness = darkness};
|
||||||
}).Build();
|
});
|
||||||
|
|
||||||
CommandBuilder.Builder("selectBlocksLookedAt", "Selects blocks (1 or more) to change. Only works in build mode, however the blocks can be changed afterwards." +
|
CommandBuilder.Builder("selectBlocksLookedAt", "Selects blocks (1 or more) to change. Only works in build mode, however the blocks can be changed afterwards." +
|
||||||
" Paramter: whether one (true) or all connected (false) blocks should be selected.")
|
" Paramter: whether one (true) or all connected (false) blocks should be selected.")
|
||||||
|
@ -90,24 +89,20 @@ namespace BlockMod
|
||||||
.Action<char>(id =>
|
.Action<char>(id =>
|
||||||
blocks = (refBlock = ObjectIdentifier.GetByID(id).FirstOrDefault())?.GetConnectedCubes() ??
|
blocks = (refBlock = ObjectIdentifier.GetByID(id).FirstOrDefault())?.GetConnectedCubes() ??
|
||||||
new Block[0]).Build();
|
new Block[0]).Build();
|
||||||
ConsoleCommands.RegisterWithChannel("selectBlocksFromChannel", id =>
|
|
||||||
{
|
|
||||||
blocks = ObjectIdentifier.GetBySimID(id).SelectMany(block => block.GetConnectedCubes()).ToArray();
|
|
||||||
},
|
|
||||||
BinaryChannelUtilities.ChannelType.Object);
|
|
||||||
|
|
||||||
CommandBuilder.Builder("pushBlocks", "Adds velocity to the selected blocks. Only works in simulation.")
|
RegisterBlockCommand("pushBlocks", "Adds velocity to the selected blocks. Only works in simulation.",
|
||||||
.Action<float, float, float>((x, y, z) =>
|
(x, y, z, blocks, refBlock) =>
|
||||||
{
|
{
|
||||||
foreach (var block in GetSimBodies(blocks))
|
foreach (var block in GetSimBodies(blocks))
|
||||||
block.Velocity += new float3(x, y, z);
|
block.Velocity += new float3(x, y, z);
|
||||||
}).Build();
|
});
|
||||||
CommandBuilder.Builder("pushRotateBlocks", "Adds angular velocity to the selected blocks. Only works in simulation.")
|
RegisterBlockCommand("pushRotateBlocks",
|
||||||
.Action<float, float, float>((x, y, z) =>
|
"Adds angular velocity to the selected blocks. Only works in simulation.",
|
||||||
|
(x, y, z, blocks, refBlock) =>
|
||||||
{
|
{
|
||||||
foreach (var block in GetSimBodies(blocks))
|
foreach (var block in GetSimBodies(blocks))
|
||||||
block.AngularVelocity += new float3(x, y, z);
|
block.AngularVelocity += new float3(x, y, z);
|
||||||
}).Build();
|
});
|
||||||
CommandBuilder.Builder("pushPlayer", "Adds velocity to the player.")
|
CommandBuilder.Builder("pushPlayer", "Adds velocity to the player.")
|
||||||
.Action<float, float, float>((x, y, z) =>
|
.Action<float, float, float>((x, y, z) =>
|
||||||
{
|
{
|
||||||
|
@ -118,66 +113,8 @@ namespace BlockMod
|
||||||
{
|
{
|
||||||
new Player(PlayerType.Local).AngularVelocity += new float3(x, y, z);
|
new Player(PlayerType.Local).AngularVelocity += new float3(x, y, z);
|
||||||
}).Build();
|
}).Build();
|
||||||
GameEngineManager.AddGameEngine(new Test());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private class Test : IApiEngine
|
|
||||||
{
|
|
||||||
public void Ready()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
CommandBuilder.Builder("weaponTest").Action(() =>
|
|
||||||
{
|
|
||||||
var type = AccessTools.TypeByName("RobocraftX.Character.Weapons.CharacterEquippedWeaponStruct");
|
|
||||||
var dict = QueryEntitiesAndIndexInternal(
|
|
||||||
new EGID(new Player(PlayerType.Local).Id, PlayersExclusiveGroups.LocalPlayers),
|
|
||||||
out uint i, type);
|
|
||||||
var dtype = typeof(ITypeSafeDictionary<>).MakeGenericType(type);
|
|
||||||
var obj = Convert.ChangeType(dict, dtype);
|
|
||||||
Array arr = (Array) AccessTools.PropertyGetter(dtype, "unsafeValues")
|
|
||||||
.Invoke(obj, new object[0]);
|
|
||||||
foreach (var element in arr)
|
|
||||||
element.GetType().GetField("equippedWeaponType")
|
|
||||||
.SetValue(element, WeaponType.PISTOL);
|
|
||||||
}).Build();
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
// ignored
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private ITypeSafeDictionary QueryEntitiesAndIndexInternal(EGID entityGID, out uint index, Type type)
|
|
||||||
{
|
|
||||||
index = 0U;
|
|
||||||
ITypeSafeDictionary typeSafeDictionary;
|
|
||||||
if (!QueryEntityDictionary(entityGID.groupID, out typeSafeDictionary, type))
|
|
||||||
return null;
|
|
||||||
return !typeSafeDictionary.TryFindIndex(entityGID.entityID, out index) ? null : typeSafeDictionary;
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool QueryEntityDictionary(
|
|
||||||
uint group,
|
|
||||||
out ITypeSafeDictionary typeSafeDictionary,
|
|
||||||
Type type)
|
|
||||||
{
|
|
||||||
object[] ps = {group, type, null};
|
|
||||||
bool ret = (bool) AccessTools.Method("Svelto.ECS.EntitiesDB:UnsafeQueryEntityDictionary")
|
|
||||||
.Invoke(entitiesDB, ps);
|
|
||||||
typeSafeDictionary = (ITypeSafeDictionary) ps[2];
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
public EntitiesDB entitiesDB { get; set; }
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public string Name { get; } = "TestEngine";
|
|
||||||
public bool isRemovable { get; } = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private string GetBlockInfo()
|
private string GetBlockInfo()
|
||||||
{
|
{
|
||||||
if (GameState.IsBuildMode())
|
if (GameState.IsBuildMode())
|
||||||
|
@ -221,9 +158,57 @@ namespace BlockMod
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<SimBody> GetSimBodies(Block[] blocks)
|
private IEnumerable<SimBody> GetSimBodies(Block[] blocks)
|
||||||
=> blocks.Select(block => block.GetSimBody()).Distinct();
|
=> blocks.Select(block => block.GetSimBody()).Distinct();
|
||||||
|
|
||||||
|
private Block[] SelectBlocks(byte id)
|
||||||
|
{
|
||||||
|
var blocks = ObjectIdentifier.GetBySimID(id).SelectMany(block => block.GetConnectedCubes()).ToArray();
|
||||||
|
return blocks;
|
||||||
|
}
|
||||||
|
|
||||||
|
//private void RegisterBlockCommand<T>(string name, string desc, T action) where T : Delegate
|
||||||
|
private void RegisterBlockCommand(string name, string desc, Action<string, byte, Block[], Block> action)
|
||||||
|
{
|
||||||
|
/*switch (action)
|
||||||
|
{
|
||||||
|
case Action<Block[], Block> act
|
||||||
|
break;
|
||||||
|
case Action<float, float, float, Block[], Block> act:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
Logging.LogWarning("Unexpected parameters for command: " + name);
|
||||||
|
break;
|
||||||
|
}*/
|
||||||
|
RuntimeCommands.Register<string, byte>(name, (a1, a2) =>
|
||||||
|
{
|
||||||
|
if (CheckNoBlocks(blocks)) return;
|
||||||
|
action(a1, a2, blocks, refBlock);
|
||||||
|
}, desc);
|
||||||
|
ConsoleCommands.RegisterWithChannel<string, byte>(name, (a1, a2, ch) =>
|
||||||
|
{
|
||||||
|
var blks = SelectBlocks(ch);
|
||||||
|
if (CheckNoBlocks(blks)) return;
|
||||||
|
action(a1, a2, blks, blks[0]);
|
||||||
|
}, BinaryChannelUtilities.ChannelType.Object, desc);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RegisterBlockCommand(string name, string desc, Action<float, float, float, Block[], Block> action)
|
||||||
|
{
|
||||||
|
RuntimeCommands.Register<float, float, float>(name, (x, y, z) =>
|
||||||
|
{
|
||||||
|
if (CheckNoBlocks(blocks)) return;
|
||||||
|
action(x, y, z, blocks, refBlock);
|
||||||
|
},
|
||||||
|
desc);
|
||||||
|
ConsoleCommands.RegisterWithChannel<float, float, float>(name, (x, y, z, ch) =>
|
||||||
|
{
|
||||||
|
var blks = SelectBlocks(ch);
|
||||||
|
if (CheckNoBlocks(blks)) return;
|
||||||
|
action(x, y, z, blks, blks[0]);
|
||||||
|
}, BinaryChannelUtilities.ChannelType.Object, desc);
|
||||||
|
}
|
||||||
|
|
||||||
public void OnApplicationQuit()
|
public void OnApplicationQuit()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue