202 lines
No EOL
9.8 KiB
C#
202 lines
No EOL
9.8 KiB
C#
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 IllusionPlugin;
|
|
using RobocraftX.CommandLine.Custom;
|
|
using Unity.Mathematics;
|
|
using uREPL;
|
|
using Main = GamecraftModdingAPI.Main;
|
|
|
|
namespace BlockMod
|
|
{
|
|
public class BlockMod : IEnhancedPlugin
|
|
{
|
|
private readonly CommandUtils _commandUtils;
|
|
private readonly BlockSelections _blockSelections;
|
|
|
|
public BlockMod()
|
|
{
|
|
_blockSelections = new BlockSelections();
|
|
_commandUtils = new CommandUtils(_blockSelections);
|
|
}
|
|
|
|
public override void OnApplicationStart()
|
|
{
|
|
Main.Init();
|
|
GameClient.SetDebugInfo("PlayerInfo", GetPlayerInfo);
|
|
GameClient.SetDebugInfo("BlockModInfo", GetBlockInfo);
|
|
_commandUtils.RegisterBlockCommand("scaleBlocks",
|
|
"Scales the selected blocks, relative to current size (current scale * new scale)." +
|
|
" The block you're looking at (when selected based on that) stays where it is, everything else is moved next to it.",
|
|
(scaleX, scaleY, scaleZ, blocks, refBlock) =>
|
|
{
|
|
if (!GameState.IsBuildMode()) return; //Scaling & positioning is weird in simulation
|
|
if (_blockSelections.CheckNoBlocks(blocks)) return;
|
|
// ReSharper disable once PossibleNullReferenceException
|
|
float3 reference = refBlock.Position;
|
|
float3 scale = new float3(scaleX, scaleY, scaleZ);
|
|
foreach (var block in blocks)
|
|
{
|
|
block.Scale *= scale;
|
|
block.Position = reference + (block.Position - reference) * scale;
|
|
}
|
|
|
|
Logging.CommandLog("Blocks scaled.");
|
|
});
|
|
_commandUtils.RegisterBlockCommand("scaleIndividually", "Scales the blocks you're looking at, but doesn't move them." +
|
|
" The scale is relative, 1 means no change.",
|
|
(scaleX, scaleY, scaleZ, blocks, refBlock) =>
|
|
{
|
|
if (!GameState.IsBuildMode()) return; //Scaling & positioning is weird in simulation
|
|
float3 scale = new float3(scaleX, scaleY, scaleZ);
|
|
foreach (var block in blocks)
|
|
block.Scale *= scale;
|
|
});
|
|
_commandUtils.RegisterBlockCommand("moveBlocks", "Moves the blocks around.", (x, y, z, blocks, refBlock) =>
|
|
{
|
|
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);
|
|
});
|
|
_commandUtils.RegisterBlockCommand("colorBlocks", "Colors the blocks you're looking at",
|
|
(color, darkness, blocks, refBlock) =>
|
|
{
|
|
|
|
if (!Enum.TryParse(color, true, out BlockColors clr))
|
|
{
|
|
Logging.CommandLogWarning("Color " + color + " not found");
|
|
}
|
|
|
|
foreach (var block in blocks)
|
|
block.Color = new BlockColor {Color = clr, Darkness = darkness};
|
|
});
|
|
|
|
CommandBuilder.Builder("selectBlocksLookedAt",
|
|
"Selects blocks (1 or more) to change. Only works in build mode, however the blocks can be changed afterwards." +
|
|
" Parameter: whether one (true) or all connected (false) blocks should be selected.")
|
|
.Action<bool>(single =>
|
|
{
|
|
_blockSelections.refBlock = new Player(PlayerType.Local).GetBlockLookedAt();
|
|
var refBlock = _blockSelections.refBlock;
|
|
_blockSelections.blocks = single ? new[] {refBlock} : refBlock?.GetConnectedCubes() ?? new Block[0];
|
|
var blocks = _blockSelections.blocks;
|
|
Logging.CommandLog(blocks == null ? "Selection cleared." : blocks.Length + " blocks selected.");
|
|
}).Build();
|
|
CommandBuilder.Builder("selectBlocksWithID", "Selects blocks with a specific object ID.")
|
|
.Action<char>(id =>
|
|
_blockSelections.blocks = (_blockSelections.refBlock = ObjectIdentifier.GetByID(id).FirstOrDefault())
|
|
?.GetConnectedCubes() ?? new Block[0]).Build();
|
|
CommandBuilder.Builder("selectSelectedBlocks", "Selects blocks that are box selected by the player.")
|
|
.Action(() =>
|
|
{
|
|
_blockSelections.blocks = new Player(PlayerType.Local).GetSelectedBlocks();
|
|
_blockSelections.refBlock = _blockSelections.blocks.Length > 0 ? _blockSelections.blocks[0] : null;
|
|
}).Build();
|
|
|
|
ConsoleCommands.RegisterWithChannel("selectSendSignal", ch => { }, ChannelType.Object,
|
|
"Sends a signal for selecting a given object ID for a command block.");
|
|
|
|
_commandUtils.RegisterBlockCommand("pushBlocks", "Adds velocity to the selected blocks. Only works in simulation.",
|
|
(x, y, z, blocks, refBlock) =>
|
|
{
|
|
foreach (var block in GetSimBodies(blocks))
|
|
block.Velocity += new float3(x, y, z);
|
|
});
|
|
_commandUtils.RegisterBlockCommand("pushRotateBlocks",
|
|
"Adds angular velocity to the selected blocks. Only works in simulation.",
|
|
(x, y, z, blocks, refBlock) =>
|
|
{
|
|
foreach (var block in GetSimBodies(blocks))
|
|
block.AngularVelocity += new float3(x, y, z);
|
|
});
|
|
CommandBuilder.Builder("pushPlayer", "Adds velocity to the player.")
|
|
.Action<float, float, float>((x, y, z) =>
|
|
{
|
|
new Player(PlayerType.Local).Velocity += new float3(x, y, z);
|
|
}).Build();
|
|
CommandBuilder.Builder("pushRotatePlayer", "Adds angular velocity to the player.")
|
|
.Action<float, float, float>((x, y, z) =>
|
|
{
|
|
new Player(PlayerType.Local).AngularVelocity += new float3(x, y, z);
|
|
}).Build();
|
|
}
|
|
|
|
private string GetBlockInfo()
|
|
{
|
|
if (GameState.IsBuildMode())
|
|
return GetBlockInfoInBuildMode();
|
|
if (GameState.IsSimulationMode())
|
|
return GetBodyInfoInSimMode();
|
|
|
|
return "Switching modes...";
|
|
}
|
|
|
|
private static string GetBlockInfoInBuildMode()
|
|
{
|
|
var block = Player.LocalPlayer.GetBlockLookedAt();
|
|
if (block == null) return "";
|
|
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" +
|
|
$"- Scale: {scale.x:F} {scale.y:F} {scale.z:F}\n" +
|
|
$"- Label: {block.Label}\n" +
|
|
$"- ID: {block.Id}";
|
|
}
|
|
|
|
private static string GetBodyInfoInSimMode()
|
|
{
|
|
var body = Player.LocalPlayer.GetSimBodyLookedAt();
|
|
if (body == null) return GetBlockInfoInBuildMode();
|
|
float3 pos = body.Position;
|
|
float3 rot = body.Rotation;
|
|
float3 vel = body.Velocity;
|
|
float3 ave = body.AngularVelocity;
|
|
float3 com = body.CenterOfMass;
|
|
Cluster cluster = body.Cluster;
|
|
return $"Body at {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" +
|
|
$"- {(body.Static ? "Static body" : $"Mass: {body.Mass:F} center: {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 health: {cluster?.CurrentHealth:F} / {cluster?.InitialHealth:F} - Multiplier: {cluster?.HealthMultiplier:F}";
|
|
}
|
|
|
|
private string GetPlayerInfo()
|
|
{
|
|
var body = Player.LocalPlayer;
|
|
if (body == null) return GetBlockInfoInBuildMode();
|
|
float3 pos = body.Position;
|
|
float3 rot = body.Rotation;
|
|
float3 vel = body.Velocity;
|
|
float3 ave = body.AngularVelocity;
|
|
return $"You are at {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: {body.Mass:F}\n" +
|
|
$"- Health: {body.CurrentHealth:F} / {body.InitialHealth:F}";
|
|
}
|
|
|
|
private IEnumerable<SimBody> GetSimBodies(Block[] blocks)
|
|
=> blocks.Select(block => block.GetSimBody()).Distinct();
|
|
|
|
public override void OnApplicationQuit() => Main.Shutdown();
|
|
|
|
public override string Name { get; } = "BlockMod";
|
|
public override string Version { get; } = "v1.0.0";
|
|
}
|
|
} |