Compare commits
16 commits
Author | SHA1 | Date | |
---|---|---|---|
08a0badd37 | |||
8877f96ec9 | |||
8223447319 | |||
1f94cf1608 | |||
94e8a0dc5a | |||
343867e67c | |||
2ec15427d6 | |||
39be331d94 | |||
72a447cc0e | |||
3e309a4e4c | |||
12fd814c45 | |||
a15634f003 | |||
c4f0198965 | |||
160eecabb7 | |||
a83eb1d405 | |||
8ef3b0a8a6 |
9 changed files with 1736 additions and 872 deletions
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,14 +1,21 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using DataLoader;
|
||||
using GamecraftModdingAPI;
|
||||
using GamecraftModdingAPI.Blocks;
|
||||
using GamecraftModdingAPI.Commands;
|
||||
using GamecraftModdingAPI.Utility;
|
||||
using HarmonyLib;
|
||||
using TechbloxModdingAPI;
|
||||
using TechbloxModdingAPI.Blocks;
|
||||
using TechbloxModdingAPI.Commands;
|
||||
using TechbloxModdingAPI.Utility;
|
||||
using IllusionPlugin;
|
||||
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
|
||||
{
|
||||
|
@ -17,6 +24,8 @@ namespace BuildingTools
|
|||
private readonly CommandUtils _commandUtils;
|
||||
private readonly BlockSelections _blockSelections;
|
||||
|
||||
//private readonly MirrorModeEngine _mirrorModeEngine = new MirrorModeEngine();
|
||||
|
||||
public BuildingTools()
|
||||
{
|
||||
_blockSelections = new BlockSelections();
|
||||
|
@ -26,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.",
|
||||
|
@ -35,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)
|
||||
{
|
||||
|
@ -81,12 +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 =>
|
||||
{
|
||||
|
@ -110,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.")
|
||||
|
@ -193,7 +221,7 @@ namespace BuildingTools
|
|||
uint refID = _blockSelections.refBlock.Id.entityID;
|
||||
if (group is null)
|
||||
{
|
||||
var copy = _blockSelections.refBlock.Copy<Block>();
|
||||
var copy = _blockSelections.refBlock.Copy();
|
||||
group = BlockGroup.Create(copy);
|
||||
_blockSelections.refBlock.Remove();
|
||||
_blockSelections.refBlock = copy;
|
||||
|
@ -203,17 +231,16 @@ namespace BuildingTools
|
|||
.Select(block =>
|
||||
{
|
||||
if (block.BlockGroup == group) return block;
|
||||
var copy = block.Copy<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);
|
||||
|
||||
var noClip = new NoClipCommand();
|
||||
GameEngineManager.AddGameEngine(noClip);
|
||||
CommandBuilder.Builder("noclip", "Allows you to go through blocks. Run again to disable. Disable before entering the menu.")
|
||||
.Action(noClip.Toggle).Build();
|
||||
CommandBuilder.Builder("freeScaling", "This command removes scaling restrictions on the selected block. Reselect block to apply.")
|
||||
.Action(() =>
|
||||
{
|
||||
|
@ -225,8 +252,55 @@ namespace BuildingTools
|
|||
}
|
||||
FullGameFields._dataDb.GetValue<CubeListData>((int) blockID).scalingPermission =
|
||||
ScalingPermission.NonUniform;
|
||||
Logging.CommandLog("Free scaling enabled for " + blockID + " until the game is restarted.");
|
||||
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()
|
||||
|
@ -242,17 +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}\n" +
|
||||
$"- Group: {block.BlockGroup.Id}";
|
||||
(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()
|
||||
|
@ -269,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.1.0";
|
||||
public override string Name => "BuildingTools";
|
||||
public override string Version => "v1.1.0";
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load diff
|
@ -1,9 +1,8 @@
|
|||
using System;
|
||||
using Gamecraft.Wires;
|
||||
using GamecraftModdingAPI;
|
||||
using GamecraftModdingAPI.Commands;
|
||||
using GamecraftModdingAPI.Utility;
|
||||
using RobocraftX.CommandLine.Custom;
|
||||
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)
|
||||
|
|
122
BuildingTools/MirrorModeEngine.cs
Normal file
122
BuildingTools/MirrorModeEngine.cs
Normal 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;
|
||||
}
|
||||
}
|
|
@ -1,120 +0,0 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Reflection;
|
||||
using GamecraftModdingAPI;
|
||||
using GamecraftModdingAPI.Engines;
|
||||
using GamecraftModdingAPI.Players;
|
||||
using GamecraftModdingAPI.Utility;
|
||||
using HarmonyLib;
|
||||
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 CollisionFilter _oldFilter;
|
||||
private bool _enabled;
|
||||
|
||||
private void Enable()
|
||||
{
|
||||
if (_entityManager == default) _entityManager = FullGameFields._physicsWorld.EntityManager;
|
||||
Logging.CommandLog("Enabling noclip");
|
||||
_oldFilter = ChangeCollider(_collisionFilter);
|
||||
OnUpdate().RunOn(GamecraftModdingAPI.Tasks.Scheduler.extraLeanRunner);
|
||||
_enabled = true;
|
||||
Logging.CommandLog("Noclip enabled");
|
||||
}
|
||||
|
||||
private void Disable()
|
||||
{
|
||||
Logging.CommandLog("Disabling noclip");
|
||||
ChangeCollider(_oldFilter);
|
||||
_enabled = false;
|
||||
Logging.CommandLog("Noclip disabled");
|
||||
}
|
||||
|
||||
public void Toggle()
|
||||
{
|
||||
if (_enabled) Enable();
|
||||
else Disable();
|
||||
}
|
||||
|
||||
private IEnumerator OnUpdate()
|
||||
{ //ScreenshotTakerCompositionRoot
|
||||
while (_enabled)
|
||||
{
|
||||
EnsureFlying();
|
||||
ChangeCollider(_collisionFilter);
|
||||
if (!entitiesDB.Exists<LocalInputEntityStruct>(0U, CommonExclusiveGroups.GameStateGroup))
|
||||
{
|
||||
yield break;
|
||||
}
|
||||
|
||||
yield return Yield.It;
|
||||
}
|
||||
}
|
||||
|
||||
private CollisionFilter ChangeCollider(CollisionFilter newFilter)
|
||||
{
|
||||
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);
|
||||
|
||||
unsafe
|
||||
{
|
||||
var coll = (CompoundCollider*) collider.Value.GetUnsafePtr();
|
||||
var filter = coll->Filter;
|
||||
coll->Filter = newFilter;
|
||||
return filter;
|
||||
}
|
||||
}
|
||||
|
||||
throw new InvalidOperationException("No character physics found!");
|
||||
}
|
||||
|
||||
private void EnsureFlying()
|
||||
{
|
||||
foreach (var ((coll, count), _) in entitiesDB.QueryEntities<CharacterMovementEntityStruct>(CharacterExclusiveGroups.AllCharacters))
|
||||
for (int i = 0; i < count; i++)
|
||||
coll[i].moveState = MovementState.Flying;
|
||||
}
|
||||
|
||||
public void Ready()
|
||||
{
|
||||
}
|
||||
|
||||
public EntitiesDB entitiesDB { get; set; }
|
||||
public void Dispose()
|
||||
{
|
||||
}
|
||||
|
||||
public string Name { get; } = "BuildingToolsNoClipEngine";
|
||||
public bool isRemovable { get; } = true;
|
||||
}
|
||||
}
|
48
BuildingTools/SetLimitsCommandEngine.cs
Normal file
48
BuildingTools/SetLimitsCommandEngine.cs
Normal 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
45
BuildingTools/UI.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,7 +1,6 @@
|
|||
# BuildingTools
|
||||
|
||||
Tools for building games, mainly focused on changing and displaying (F3) block properties.
|
||||
And no clip.
|
||||
|
||||
## Commands
|
||||
### Selection commands
|
||||
|
@ -59,12 +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.
|
||||
|
||||
**Always exit noClip before leaving a game save or it will crash the game at the moment.**
|
||||
|
||||
### Examples
|
||||
* Select and move box selected blocks by 5 blocks in the +X direction:
|
||||
```
|
||||
|
|
Loading…
Reference in a new issue