Compare commits

..

22 commits

Author SHA1 Message Date
08a0badd37 Add support for setting cluster limit and remove the volume limit 2022-04-12 03:33:45 +02:00
8877f96ec9 Add support for object IDs again, some material stuff 2022-04-12 00:54:05 +02:00
8223447319 Fix speed label not disappearing on machine edit 2022-02-24 00:43:05 +01:00
1f94cf1608 Add command for setting tweak limits 2022-02-20 02:58:16 +01:00
94e8a0dc5a Added some more info and a speedometer 2022-02-19 03:03:15 +01:00
343867e67c Remove no clip and update set limits command 2022-02-01 00:54:47 +01:00
2ec15427d6 Remove noGarage and improve mirror mode
- Mirroring relative to where the player enabled the mode
- Removing blocks that are where the mirrored counterpart of the removed block would be
2021-11-25 02:01:30 +01:00
39be331d94 Mirror mode attempt and update to latest Techblox 2021-11-04 20:58:12 +01:00
72a447cc0e Add wire info 2021-08-12 03:30:39 +02:00
3e309a4e4c Add command to disable the environment switch
Was in the test plugin
2021-08-10 01:04:58 +02:00
12fd814c45 SetLimits command and updates
Only the command update is from now
2021-07-23 04:08:30 +02:00
a15634f003 Update to the latest API 2021-06-08 01:12:33 +02:00
c4f0198965
Rename API references 2021-05-02 02:00:06 +02:00
160eecabb7
Update to the latest version of the API 2021-04-27 01:55:00 +02:00
a83eb1d405
Update for Techblox 2021-04-13 01:07:14 +02:00
8ef3b0a8a6 Nothing to see here 2020-12-31 03:08:21 +01:00
ffb7fc7cf9 Add support for block groups and some fixes 2020-12-31 02:15:50 +01:00
5a24074fef Constantly set the collision filter
Something is resetting it
2020-12-31 00:52:43 +01:00
2b0cec100e Add free scaling and attempt to fix noclip 2020-12-28 00:20:55 +01:00
19bf8fbe18 Fix issues with the Blueprints update 2020-11-18 16:08:32 +01:00
568799440a Update 'README.md' 2020-10-02 22:33:45 +00:00
4cb9277059 Add warning about noClip
Whoops
2020-10-02 22:11:31 +00:00
9 changed files with 1811 additions and 765 deletions

View file

@ -1,7 +1,7 @@
using System.Linq;
using GamecraftModdingAPI;
using GamecraftModdingAPI.Blocks;
using GamecraftModdingAPI.Utility;
using TechbloxModdingAPI;
using TechbloxModdingAPI.Blocks;
using TechbloxModdingAPI.Utility;
namespace BuildingTools
{
@ -21,17 +21,9 @@ namespace BuildingTools
return false;
}
public Block[] SelectBlocks(byte id)
{
var blocks = ObjectIdentifier.GetBySimID(id).SelectMany(block => block.GetConnectedCubes()).ToArray();
return blocks;
}
public Block[] SelectBlocks(char id)
{
var blocks = ObjectIdentifier.GetByID(id).SelectMany(oid => oid.GetConnectedCubes())
.ToArray();
return blocks;
return ObjectID.GetByID(id).SelectMany(oid => oid.GetConnectedCubes()).ToArray();
}
}
}

View file

@ -1,16 +1,21 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Gamecraft.Wires;
using GamecraftModdingAPI;
using GamecraftModdingAPI.Blocks;
using GamecraftModdingAPI.Commands;
using GamecraftModdingAPI.Players;
using GamecraftModdingAPI.Utility;
using System.Reflection;
using DataLoader;
using HarmonyLib;
using TechbloxModdingAPI;
using TechbloxModdingAPI.Blocks;
using TechbloxModdingAPI.Commands;
using TechbloxModdingAPI.Utility;
using IllusionPlugin;
using RobocraftX.CommandLine.Custom;
using RobocraftX.Schedulers;
using Svelto.Tasks;
using Svelto.Tasks.Enumerators;
using Svelto.Tasks.Lean;
using TechbloxModdingAPI.App;
using Unity.Mathematics;
using Main = GamecraftModdingAPI.Main;
using Main = TechbloxModdingAPI.Main;
namespace BuildingTools
{
@ -19,6 +24,8 @@ namespace BuildingTools
private readonly CommandUtils _commandUtils;
private readonly BlockSelections _blockSelections;
//private readonly MirrorModeEngine _mirrorModeEngine = new MirrorModeEngine();
public BuildingTools()
{
_blockSelections = new BlockSelections();
@ -28,8 +35,8 @@ namespace BuildingTools
public override void OnApplicationStart()
{
Main.Init();
GameClient.SetDebugInfo("PlayerInfo", GetPlayerInfo);
GameClient.SetDebugInfo("BlockModInfo", GetBlockInfo);
Game.AddPersistentDebugInfo("PlayerInfo", GetPlayerInfo);
Game.AddPersistentDebugInfo("BlockModInfo", GetBlockInfo);
_commandUtils.RegisterBlockCommand("scaleBlocks",
"Scales the selected blocks, relative to current size (current scale * new scale)." +
" The block you're looking at stays where it is, everything else is moved next to it.",
@ -37,7 +44,6 @@ namespace BuildingTools
{
if (!GameState.IsBuildMode()) return; //Scaling & positioning is weird in simulation
if (_blockSelections.CheckNoBlocks(blocks)) return;
// ReSharper disable once PossibleNullReferenceException
float3? reference = Player.LocalPlayer.GetBlockLookedAt()?.Position;
if (!reference.HasValue)
{
@ -51,7 +57,7 @@ namespace BuildingTools
block.Position = (float3) (reference + (block.Position - reference) * scale);
}
Logging.CommandLog("Blocks scaled.");
Logging.CommandLog("Blocks scaled and moved.");
});
_commandUtils.RegisterBlockCommand("scaleIndividually", "Scales the blocks you're looking at, but doesn't move them." +
" The scale is relative, 1 means no change.",
@ -61,6 +67,7 @@ namespace BuildingTools
float3 scale = new float3(scaleX, scaleY, scaleZ);
foreach (var block in blocks)
block.Scale *= scale;
Logging.CommandLog("Blocks scaled individually.");
});
_commandUtils.RegisterBlockCommand("moveBlocks", "Moves (teleports) the selected blocks around both in time stopped and running. The latter will be reset as expected.", (x, y, z, blocks, refBlock) =>
{
@ -70,6 +77,7 @@ namespace BuildingTools
else if (GameState.IsSimulationMode())
foreach (var body in GetSimBodies(blocks))
body.Position += new float3(x, y, z);
Logging.CommandLog("Blocks moved.");
});
_commandUtils.RegisterBlockCommand("colorBlocks", "Colors the selected blocks permanently both in time stopped and running. It won't be reset when stopping time.",
(color, darkness, blocks, refBlock) =>
@ -81,11 +89,32 @@ namespace BuildingTools
}
foreach (var block in blocks)
block.Color = new BlockColor {Color = clr, Darkness = darkness};
block.Color = new BlockColor(clr, darkness);
Logging.CommandLog("Blocks colored.");
});
_commandUtils.RegisterBlockCommand("materialBlocks", "Sets the material of the selected blocks permanently both in time stopped and running. It won't be reset when stopping time.",
(material, darkness, blocks, refBlock) =>
{
if (!Enum.TryParse(material, true, out BlockMaterial mat))
{
Logging.CommandLogWarning("Material " + material + " not found");
}
IEnumerator<TaskContract> SetMaterial()
{
foreach (var block in blocks)
{
block.Material = mat;
yield return new WaitForSecondsEnumerator(0.2f).Continue();
}
}
SetMaterial().RunOn(ClientLean.UIScheduler);
Logging.CommandLog("Block materials set.");
});
CommandBuilder.Builder("selectBlocksLookedAt",
"Selects blocks (1 or more) to change. Only works in time stopped mode, however the blocks can be changed afterwards in both modes." +
"Selects blocks (1 or more) to change. Only works in time stopped mode." +
" Parameter: whether one (true) or all connected (false) blocks should be selected.")
.Action<bool>(single =>
{
@ -109,8 +138,8 @@ namespace BuildingTools
.Action<char>(id =>
{
_blockSelections.blocks =
(_blockSelections.refBlock = ObjectIdentifier.GetByID(id).FirstOrDefault())
?.GetConnectedCubes() ?? new Block[0];
(_blockSelections.refBlock = ObjectID.GetByID(id).FirstOrDefault())
?.GetConnectedCubes() ?? Array.Empty<Block>();
Logging.CommandLog(_blockSelections.blocks.Length + " blocks selected.");
}).Build();
CommandBuilder.Builder("selectSelectedBlocks", "Selects blocks that are box selected by the player.")
@ -120,6 +149,22 @@ namespace BuildingTools
_blockSelections.refBlock = _blockSelections.blocks.Length > 0 ? _blockSelections.blocks[0] : null;
Logging.CommandLog(_blockSelections.blocks.Length + " blocks selected.");
}).Build();
CommandBuilder.Builder("selectBlocksInGroup",
"Selects the blocks in the block group you are looking at (the blocks currently highlighted when in blueprint mode).")
.Action(() =>
{
var block = Player.LocalPlayer.GetBlockLookedAt();
if (block is null)
{
Logging.CommandLogError("You need to look at a block first (and be close to it).");
return;
}
var group = block.BlockGroup;
_blockSelections.blocks = group is null ? new[] {block} : group.ToArray();
_blockSelections.refBlock = block;
Logging.CommandLog(_blockSelections.blocks.Length + " blocks selected.");
}).Build();
/*ConsoleCommands.RegisterWithChannel("selectSendSignal", ch => { }, ChannelType.Object,
"Sends a signal for selecting a given object ID for a command block.");*/
@ -134,6 +179,7 @@ namespace BuildingTools
}
foreach (var block in GetSimBodies(blocks))
block.Velocity += new float3(x, y, z);
Logging.CommandLog("Blocks pushed.");
});
_commandUtils.RegisterBlockCommand("pushRotateBlocks",
"Adds angular velocity to the selected blocks. Only works in simulation.",
@ -146,21 +192,115 @@ namespace BuildingTools
}
foreach (var block in GetSimBodies(blocks))
block.AngularVelocity += new float3(x, y, z);
Logging.CommandLog("Blocks pushed to rotate.");
});
CommandBuilder.Builder("pushPlayer", "Adds velocity to the player.")
.Action<float, float, float>((x, y, z) =>
{
Player.LocalPlayer.Velocity += new float3(x, y, z);
Logging.CommandLog("Player pushed.");
}).Build();
CommandBuilder.Builder("pushRotatePlayer", "Adds angular velocity to the player.")
.Action<float, float, float>((x, y, z) =>
{
Player.LocalPlayer.AngularVelocity += new float3(x, y, z);
Logging.CommandLog("Player pushed to rotate.");
}).Build();
var noClip = new NoClipCommand();
GameEngineManager.AddGameEngine(noClip);
CommandBuilder.Builder("noClip", "Allows you to go through blocks. Run again to disable.")
.Action(noClip.Toggle).Build();
CommandBuilder.Builder("addBlocksToGroup",
"Adds the selected blocks to the same group (they will be highlighted together)." +
" This command recreates the blocks that are moved into the group, but block data is almost certainly preserved.")
.Action(() =>
{
if (_blockSelections.blocks.Length == 0)
{
Logging.CommandLogWarning("No blocks selected. Use a select command first.");
return;
}
var group = _blockSelections.refBlock.BlockGroup;
uint refID = _blockSelections.refBlock.Id.entityID;
if (group is null)
{
var copy = _blockSelections.refBlock.Copy();
group = BlockGroup.Create(copy);
_blockSelections.refBlock.Remove();
_blockSelections.refBlock = copy;
}
_blockSelections.blocks = _blockSelections.blocks.Where(block => block.Id.entityID != refID)
.Select(block =>
{
if (block.BlockGroup == group) return block;
var copy = block.Copy();
group.Add(copy);
block.Remove();
return copy;
}).ToArray();
}).Build();
var setLimits = new SetLimitsCommandEngine();
CommandBuilder.Builder("setBuildLimits", "Set build limits").Action((Action<int, int, int>)setLimits.SetLimits).Build();
GameEngineManager.AddGameEngine(setLimits);
CommandBuilder.Builder("freeScaling", "This command removes scaling restrictions on the selected block. Reselect block to apply.")
.Action(() =>
{
var blockID = Player.LocalPlayer.SelectedBlock;
if (blockID == BlockIDs.Invalid)
{
Logging.CommandLogWarning("You don't have any blocks in your hand.");
return;
}
FullGameFields._dataDb.GetValue<CubeListData>((int) blockID).scalingPermission =
ScalingPermission.NonUniform;
Logging.CommandLog("Free scaling enabled for " + blockID + " until the game is restarted. Reselect block to apply.");
}).Build();
CommandBuilder.Builder("setTweakLimit",
"Sets the limit on the tweakable stat on selected block. Usage: setTweakLimit [stat] [value]. Sets all stats to 1000 by default.")
.Action((string stat, int value) =>
{
var bl = Player.LocalPlayer.SelectedBlock;
if (bl == BlockIDs.Invalid)
{
Logging.CommandLogError("Select the block in the inventory first.");
return;
}
if (!FullGameFields._dataDb.TryGetValue<TweakableStatsData>((int)bl, out var data))
{
Logging.CommandLogError($"No tweakable stats found on {bl} (selected)");
return;
}
TweakPropertyInfo[] stats;
if (stat is null || stat.Length == 0)
{
stats = data.Stats;
}
else
{
if (!data.statsByName.TryGetValue(stat, out var statInfo))
{
Logging.CommandLogError($"Tweakable stat {stat} not found. Stats: {data.statsByName.Keys.Aggregate((a, b) => a + ", " + b)}");
return;
}
stats = new[] { statInfo };
}
foreach (var statInfo in stats)
{
statInfo.max = value == 0 ? 1000 : value;
statInfo.min = -1000;
}
Logging.CommandLog($"{(stat is null || stat.Length == 0 ? "All stats" : $"Stat {stat}")} max changed to {(value == 0 ? 1000 : value)} on {bl}");
}).Build();
//_mirrorModeEngine.Init();
UI.Init();
new Harmony("BuildTools").PatchAll(Assembly.GetExecutingAssembly());
}
private string GetBlockInfo()
@ -176,16 +316,32 @@ namespace BuildingTools
private static string GetBlockInfoInBuildMode()
{
var block = Player.LocalPlayer.GetBlockLookedAt();
if (block == null) return "";
if (block == null) return GetWireInfoInBuildMode();
float3 pos = block.Position;
float3 rot = block.Rotation;
float3 scale = block.Scale;
return $"Block: {block.Type} at {pos.x:F} {pos.y:F} {pos.z:F}\n" +
$"- Rotation: {rot.x:F}° {rot.y:F}° {rot.z:F}°\n" +
$"- Color: {block.Color.Color} darkness: {block.Color.Darkness}\n" +
$"- Material: {block.Material}\n" +
$"- Scale: {scale.x:F} {scale.y:F} {scale.z:F}\n" +
$"- Label: {block.Label}\n" +
$"- ID: {block.Id}";
$"- ID: {block.Id}\n" +
(block.BlockGroup != null ? $"- Group: {block.BlockGroup.Id}\n" : "") +
$"- Mass: {block.Mass}";
}
private static string GetWireInfoInBuildMode()
{
var wire = Player.LocalPlayer.GetWireLookedAt();
if (wire == null) return "";
var startPos = wire.Start.Position;
var endPos = wire.End.Position;
return $"Wire with {wire.Id}\n" +
$"- From block {wire.Start.Type} at {startPos.x:F} {startPos.y:F} {startPos.z:F}\n" +
$"- at port {wire.StartPortName}\n" +
$"- To block {wire.End.Type} at {endPos.x:F} {endPos.y:F} {endPos.z:F}\n" +
$"- at port {wire.EndPortName}";
}
private static string GetBodyInfoInSimMode()
@ -202,36 +358,37 @@ namespace BuildingTools
$"- Rotation: {rot.x:F}° {rot.y:F}° {rot.z:F}°\n" +
$"- Velocity: {vel.x:F} {vel.y:F} {vel.z:F}\n" +
$"- Angular velocity: {ave.x:F} {ave.y:F} {ave.z:F}\n" +
$"- {(body.Static ? "Static body" : $"Mass: {body.Mass:F} center: {com.x:F} {com.y:F} {com.z:F}")}\n" +
$"- {(body.Static ? "Static body" : $"Center of mass: {com.x:F} {com.y:F} {com.z:F}")}\n" +
$"- Volume: {body.Volume:F}\n" +
$"- Chunk health: {body.CurrentHealth:F} / {body.InitialHealth:F} - Multiplier: {body.HealthMultiplier:F}\n" +
(cluster == null
? ""
: $"- Cluster health: {cluster.CurrentHealth:F} / {cluster.InitialHealth:F} - Multiplier: {cluster.HealthMultiplier:F}"
: $"- Cluster health: {cluster.CurrentHealth:F} / {cluster.InitialHealth:F} - Multiplier: {cluster.HealthMultiplier:F}\n" +
$"- Cluster mass: {cluster.Mass}"
);
}
private string GetPlayerInfo()
{
var player = Player.LocalPlayer;
if (player == null) return GetBlockInfoInBuildMode();
if (player == null) return "";
float3 pos = player.Position;
float3 rot = player.Rotation;
float3 vel = player.Velocity;
float3 ave = player.AngularVelocity;
return $"Player rotation: {rot.x:F}° {rot.y:F}° {rot.z:F}°\n" +
return $"Player position: {pos.x:F} {pos.y:F} {pos.z:F}\n" +
$"- Rotation: {rot.x:F}° {rot.y:F}° {rot.z:F}°\n" +
$"- Velocity: {vel.x:F} {vel.y:F} {vel.z:F}\n" +
$"- Angular velocity: {ave.x:F} {ave.y:F} {ave.z:F}\n" +
$"- Mass: {player.Mass:F}\n" +
$"- Health: {player.CurrentHealth:F} / {player.InitialHealth:F}";
}
private IEnumerable<SimBody> GetSimBodies(Block[] blocks)
=> blocks.Select(block => block.GetSimBody()).Distinct();
=> blocks.Select(block => block.GetSimBody()).Where(block => !(block is null)).Distinct();
public override void OnApplicationQuit() => Main.Shutdown();
public override string Name { get; } = "BuildingTools";
public override string Version { get; } = "v1.0.0";
public override string Name => "BuildingTools";
public override string Version => "v1.1.0";
}
}

File diff suppressed because it is too large Load diff

View file

@ -1,9 +1,8 @@
using System;
using Gamecraft.Wires;
using GamecraftModdingAPI;
using GamecraftModdingAPI.Commands;
using RobocraftX.CommandLine.Custom;
using uREPL;
using TechbloxModdingAPI;
using TechbloxModdingAPI.Commands;
using TechbloxModdingAPI.Utility;
namespace BuildingTools
{
@ -22,12 +21,6 @@ namespace BuildingTools
{
action(a1, _blockSelections.blocks, _blockSelections.refBlock);
}).Build();
ConsoleCommands.RegisterWithChannel<string>(name + "Chan", (a1, ch) =>
{
Console.WriteLine($"Command {name} with args {a1} and channel {ch} executing");
var blks = _blockSelections.SelectBlocks(ch);
action(a1, blks, blks[0]);
}, ChannelType.Object, desc);
}
public void RegisterBlockCommand(string name, string desc, Action<float, float, float, Block[], Block> action)
@ -37,14 +30,14 @@ namespace BuildingTools
var argsa = args.Split(' ');
if (argsa.Length < 3)
{
Log.Error("Too few arguments. Needed arguments are: <x> <y> <z> and [id] is optional.");
Logging.CommandLogError("Too few arguments. Needed arguments are: <x> <y> <z> and [id] is optional.");
return;
}
if (!float.TryParse(argsa[0], out float x) || !float.TryParse(argsa[1], out float y) ||
!float.TryParse(argsa[2], out float z))
{
Log.Error("Could not parse arguments as floats.");
Logging.CommandLogError("Could not parse arguments as floats.");
return;
}
@ -52,7 +45,7 @@ namespace BuildingTools
{
if (argsa[3].Length == 0)
{
Log.Error("Missing object ID.");
Logging.CommandLogError("Missing object ID.");
return;
}
@ -72,13 +65,13 @@ namespace BuildingTools
var argsa = args.Split(' ');
if (argsa.Length < 2)
{
Log.Error("Too few arguments. Needed arguments are: <color> <darkness> and [id] is optional.");
Logging.CommandLogError("Too few arguments. Needed arguments are: <color> <darkness> and [id] is optional.");
return;
}
if (!byte.TryParse(argsa[1], out byte darkness))
{
Log.Error("Could not parse color darkness.");
Logging.CommandLogError("Could not parse color darkness.");
return;
}
@ -86,7 +79,7 @@ namespace BuildingTools
{
if (argsa[2].Length == 0)
{
Log.Error("Missing channel.");
Logging.CommandLogError("Missing channel.");
return;
}

View file

@ -0,0 +1,122 @@
using System;
using System.Collections.Generic;
using Gamecraft.GUI.Blueprints;
using RobocraftX.Blocks.Ghost;
using RobocraftX.Common;
using RobocraftX.CR.MachineEditing.BoxSelect;
using RobocraftX.Physics;
using Svelto.ECS;
using Svelto.ECS.EntityStructs;
using Svelto.Tasks;
using Svelto.Tasks.Enumerators;
using Svelto.Tasks.Lean;
using Techblox.Blocks;
using TechbloxModdingAPI;
using TechbloxModdingAPI.App;
using TechbloxModdingAPI.Blocks;
using TechbloxModdingAPI.Blocks.Engines;
using TechbloxModdingAPI.Engines;
using TechbloxModdingAPI.Interface.IMGUI;
using TechbloxModdingAPI.Players;
using TechbloxModdingAPI.Tasks;
using TechbloxModdingAPI.Utility;
using Unity.Mathematics;
using UnityEngine;
namespace BuildingTools
{
public class MirrorModeEngine : IApiEngine
{
private Button _button;
private bool _enabled;
private Block _lastPlaced;
private Block _ghostBlock;
private float3 _offset;
private void BlockOnPlaced(object sender, BlockPlacedRemovedEventArgs e)
{
if (!_enabled) return;
if (Player.LocalPlayer.BuildingMode != PlayerBuildingMode.BlockMode) return;
if (e.ID == _lastPlaced?.Id) return;
_lastPlaced = e.Block.Copy();
_lastPlaced.Position = MirrorPos(_lastPlaced.Position);
_lastPlaced.Flipped = !_lastPlaced.Flipped;
if (math.abs(_lastPlaced.Rotation.y - 90) < float.Epsilon ||
math.abs(_lastPlaced.Rotation.y - 270) < float.Epsilon)
_lastPlaced.Rotation += new float3(0, 180, 0);
}
private void BlockOnRemoved(object sender, BlockPlacedRemovedEventArgs e)
{
if (!_enabled) return;
if (Player.LocalPlayer.BuildingMode != PlayerBuildingMode.BlockMode) return;
var newpos = MirrorPos(e.Block.Position);
foreach (var block in Game.CurrentGame().GetBlocksInGame())
{
if (math.all(math.abs(block.Position - newpos) < 0.1f))
block.Remove();
}
}
private float3 MirrorPos(float3 pos)
{
pos -= _offset;
pos *= new float3(-1, 1, 1);
pos += _offset;
return pos;
}
public void Init()
{
Block.Placed += BlockOnPlaced;
Block.Removed+=BlockOnRemoved;
Game.Enter += OnGameOnEnter;
Game.Exit += (sender, args) => _button = null;
}
private void OnGameOnEnter(object sender, GameEventArgs args)
{
_button = new Button("Mirror mode");
_button.OnClick += (_, __) =>
{
_enabled = !_enabled;
if(_enabled)
_offset = new float3((float)(Math.Round(Player.LocalPlayer.Position.x / 2, 1) * 2), 0, 0);
};
//TryCreateGhostBlock().RunOn(Scheduler.leanRunner);
}
private IEnumerator<TaskContract> TryCreateGhostBlock()
{
int c = 0;
while (_ghostBlock == null && c++ < 10)
{
Console.WriteLine($"Ghost block is {_ghostBlock} and c is {c}");
try
{
//_ghostBlock = Block.CreateGhostBlock();
Console.WriteLine($"New block: {_ghostBlock}");
_ghostBlock.Position += 1;
}
catch (Exception e)
{
Console.WriteLine(e);
}
yield return new WaitForSecondsEnumerator(1f).Continue();
}
}
public void Ready()
{
}
public EntitiesDB entitiesDB { get; set; }
public void Dispose()
{
}
public string Name { get; } = "BuildingToolsMirroModeEngine";
public bool isRemovable { get; } = true;
}
}

View file

@ -1,124 +0,0 @@
using System;
using System.Collections;
using GamecraftModdingAPI;
using GamecraftModdingAPI.Engines;
using GamecraftModdingAPI.Utility;
using RobocraftX.Character;
using RobocraftX.Character.Camera;
using RobocraftX.Character.Factories;
using RobocraftX.Character.Movement;
using RobocraftX.Common;
using RobocraftX.Common.Input;
using RobocraftX.Common.UnityECSWrappers;
using RobocraftX.UECS;
using Svelto.ECS;
using Svelto.Tasks.ExtraLean;
using Unity.Entities;
using Unity.Mathematics;
using Unity.Physics;
using UnityEngine;
using Collider = Unity.Physics.Collider;
using Yield = Svelto.Tasks.Yield;
namespace BuildingTools
{
public class NoClipCommand : IApiEngine
{
private readonly CollisionFilter _collisionFilter = new CollisionFilter
{ //AddCollidersToRigidBodyEngineUECS._simCubeNoCollisionFilter
BelongsTo = 0,
CollidesWith = 239532
};
private EntityManager _entityManager;
private BlobAssetReference<Collider> _oldCollider;
private bool _enabled;
private void Enable()
{
if (_entityManager == default) _entityManager = FullGameFields._physicsWorld.EntityManager;
Logging.CommandLog("Enabling no clip");
_oldCollider = ChangeCollider(_collisionFilter, null);
OnUpdate().RunOn(GamecraftModdingAPI.Tasks.Scheduler.extraLeanRunner);
_enabled = true;
Logging.CommandLog("No clip enabled");
}
private void Disable()
{
Logging.CommandLog("Disabling no clip");
ChangeCollider(null, _oldCollider).Dispose(); //Dispose old (cloned) collider
_enabled = false;
Logging.CommandLog("No clip disabled");
}
public void Toggle()
{
// ReSharper disable once AssignmentInConditionalExpression
if (_enabled = !_enabled) Enable();
else Disable();
}
private IEnumerator OnUpdate()
{ //ScreenshotTakerCompositionRoot
while (_enabled)
{
EnsureFlying();
if (!entitiesDB.Exists<LocalInputEntityStruct>(0U, CommonExclusiveGroups.GameStateGroup))
{
Disable();
yield break;
}
yield return Yield.It;
}
}
private BlobAssetReference<Collider> ChangeCollider(CollisionFilter? newFilter, BlobAssetReference<Collider>? newCollider)
{
foreach (var group in CharacterExclusiveGroups.AllCharacters)
{
if (!entitiesDB.Exists<UECSPhysicsEntityStruct>(new EGID(Player.LocalPlayer.Id, group)))
continue;
ref var uecsEntity =
ref entitiesDB.QueryEntity<UECSPhysicsEntityStruct>(new EGID(Player.LocalPlayer.Id, group));
var collider = _entityManager.GetComponentData<PhysicsCollider>(uecsEntity.uecsEntity);
var oldCollider = collider.Value;
if (newFilter.HasValue)
{
unsafe
{
var colRef = ColliderUtilityUECS.ClonePhysicsCollider(collider.ColliderPtr, newFilter.Value);
collider.Value = colRef;
}
}
else if (newCollider.HasValue)
collider.Value = newCollider.Value;
_entityManager.SetComponentData(uecsEntity.uecsEntity, collider);
return oldCollider;
}
throw new InvalidOperationException("No character physics found!");
}
private void EnsureFlying()
{
foreach (ref var ent in entitiesDB.QueryEntities<CharacterMovementEntityStruct>(CharacterExclusiveGroups.AllCharacters).entities)
{
ent.moveState = MovementState.Flying;
}
}
public void Ready()
{
}
public EntitiesDB entitiesDB { get; set; }
public void Dispose()
{
}
public string Name { get; } = "BuildingToolsNoClipEngine";
public bool isRemovable { get; } = true;
}
}

View file

@ -0,0 +1,48 @@
using System;
using Svelto.ECS;
using Techblox.Building.Rules;
using Techblox.Building.Rules.Entities;
using TechbloxModdingAPI.Engines;
using TechbloxModdingAPI.Utility;
using Unity.Mathematics;
namespace BuildingTools
{
public class SetLimitsCommandEngine : IApiEngine
{
public void Ready()
{
}
public EntitiesDB entitiesDB { get; set; }
public void Dispose()
{
}
public void SetLimits(int cpu, int power, int clusters)
{
if (entitiesDB is null)
{
Logging.CommandLog("This command only works in build mode. If you're in build mode, well, report pls.");
return;
}
ref var rules = ref entitiesDB.QueryUniqueEntity<MachineRulesComponent>(GroupCompound<MACHINE, LOCAL>.BuildGroup);
Logging.CommandLog($"Old CPU limit: {rules.cpu.max}, power limit: {rules.power.max}, cluster limit: {rules.clusters.max}");
rules.cpu.max = cpu;
rules.power.max = power;
rules.clusters.max = clusters;
if (BuildRulesUtils.GetLocalMachine(entitiesDB, out var egid))
{
entitiesDB.QueryEntity<MachineVolumeLimitAabbComponent>(egid).aabb =
new AABB { Center = 0, Extents = float.MaxValue };
Logging.CommandLog("Removed volume limits");
}
Logging.CommandLog($"New CPU limit: {rules.cpu.max}, power limit: {rules.power.max}, cluster limit: {rules.clusters.max}");
}
public string Name => "SetLimitsEngine";
public bool isRemovable => true;
}
}

45
BuildingTools/UI.cs Normal file
View file

@ -0,0 +1,45 @@
using TechbloxModdingAPI;
using TechbloxModdingAPI.App;
using TechbloxModdingAPI.Interface.IMGUI;
using TechbloxModdingAPI.Tasks;
using Unity.Mathematics;
using UnityEngine;
namespace BuildingTools
{
public class UI
{
private static Label _speedLabel = new Label(new Rect(Screen.width - 200, 0, 200, 20), "Speed: ", "SpeedLabel")
{
Enabled = false
};
public static void Init()
{
Game.Simulate += OnGameOnSimulate;
Game.Edit += OnGameOnEditOrExit;
Game.Exit += OnGameOnEditOrExit;
}
private static void OnGameOnSimulate(object sender, GameEventArgs args)
{
_speedLabel.Enabled = true;
Scheduler.Schedule(new Repeatable(UpdateTask, ShouldLabelBeUpdated));
}
private static void OnGameOnEditOrExit(object sender, GameEventArgs args)
{
_speedLabel.Enabled = false;
}
private static void UpdateTask()
{
_speedLabel.Text = $"Speed: {math.length(Player.LocalPlayer?.Velocity ?? 0) * 3.6:F} km/h";
}
private static bool ShouldLabelBeUpdated()
{
return _speedLabel.Enabled;
}
}
}

View file

@ -1,7 +1,6 @@
# BuildingTools
Tools for building games, mainly focused on changing block properties.
And no clip.
Tools for building games, mainly focused on changing and displaying (F3) block properties.
## Commands
### Selection commands
@ -59,10 +58,6 @@ Only works in time running mode.
### Push player
The `pushPlayer` and `pushRotatePlayer` commands will apply a specified (regular or angular) force to the player in any mode.
### No clip
The `noClip` command allows you to go through blocks. Run to toggle.
It works in both time stopped and running modes.
### Examples
* Select and move box selected blocks by 5 blocks in the +X direction:
```