Compare commits
21 commits
Author | SHA1 | Date | |
---|---|---|---|
|
ae069f6d93 | ||
|
53564b9c56 | ||
|
d761e4c16a | ||
|
89f5d9eb43 | ||
|
c3dc80fc84 | ||
|
3c00d05a3b | ||
|
0e65267e88 | ||
|
85c1342313 | ||
|
3c9c60b679 | ||
|
84fc330b12 | ||
|
d2a2ce52f0 | ||
|
742bcf25ef | ||
16f833ceda | |||
a0ab2ec9e7 | |||
30a3f5001f | |||
db5ff7223c | |||
02401f39f9 | |||
60cf8bdd67 | |||
ab169fb87c | |||
5bc0351bd1 | |||
bd813d852d |
14 changed files with 1429 additions and 943 deletions
37
Pixi/Audio/AudioFakeImporter.cs
Normal file
37
Pixi/Audio/AudioFakeImporter.cs
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
using System;
|
||||||
|
using GamecraftModdingAPI;
|
||||||
|
using GamecraftModdingAPI.Utility;
|
||||||
|
using Pixi.Common;
|
||||||
|
|
||||||
|
namespace Pixi.Audio
|
||||||
|
{
|
||||||
|
public class AudioFakeImporter : Importer
|
||||||
|
{
|
||||||
|
public int Priority { get; } = 0;
|
||||||
|
public bool Optimisable { get; } = false;
|
||||||
|
public string Name { get; } = "AudioWarning~Spell";
|
||||||
|
public BlueprintProvider BlueprintProvider { get; } = null;
|
||||||
|
public bool Qualifies(string name)
|
||||||
|
{
|
||||||
|
return name.EndsWith(".flac", StringComparison.InvariantCultureIgnoreCase)
|
||||||
|
|| name.EndsWith(".ogg", StringComparison.InvariantCultureIgnoreCase)
|
||||||
|
|| name.EndsWith(".mp3", StringComparison.InvariantCultureIgnoreCase)
|
||||||
|
|| name.EndsWith(".wav", StringComparison.InvariantCultureIgnoreCase)
|
||||||
|
|| name.EndsWith(".aac", StringComparison.InvariantCultureIgnoreCase);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BlockJsonInfo[] Import(string name)
|
||||||
|
{
|
||||||
|
Logging.CommandLogWarning($"Audio importing only works with MIDI (.mid) files, which '{name}' is not.\nThere are many converters online, but for best quality use a MIDI file made from a music transcription.\nFor example, musescore.com has lots of good transcriptions and they offer a 30-day free trial.");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void PreProcess(string name, ref ProcessedVoxelObjectNotation[] blocks)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void PostProcess(string name, ref Block[] blocks)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -31,6 +31,8 @@ namespace Pixi.Audio
|
||||||
|
|
||||||
public static byte Key = 0;
|
public static byte Key = 0;
|
||||||
|
|
||||||
|
public static float VolumeMultiplier = 1f;
|
||||||
|
|
||||||
public MidiImporter()
|
public MidiImporter()
|
||||||
{
|
{
|
||||||
AudioTools.GenerateProgramMap();
|
AudioTools.GenerateProgramMap();
|
||||||
|
@ -49,10 +51,6 @@ namespace Pixi.Audio
|
||||||
Logging.MetaLog($"Found {midi.GetNotes().Count()} notes over {midi.GetDuration<MidiTimeSpan>().TimeSpan} time units");
|
Logging.MetaLog($"Found {midi.GetNotes().Count()} notes over {midi.GetDuration<MidiTimeSpan>().TimeSpan} time units");
|
||||||
BlockJsonInfo[] blocks = new BlockJsonInfo[(midi.GetNotes().Count() * 2) + 3];
|
BlockJsonInfo[] blocks = new BlockJsonInfo[(midi.GetNotes().Count() * 2) + 3];
|
||||||
List<BlockJsonInfo> blocksToBuild = new List<BlockJsonInfo>();
|
List<BlockJsonInfo> blocksToBuild = new List<BlockJsonInfo>();
|
||||||
#if DEBUG
|
|
||||||
// test (for faster, but incomplete, imports)
|
|
||||||
if (blocks.Length > 103) blocks = new BlockJsonInfo[103];
|
|
||||||
#endif
|
|
||||||
// convert Midi notes to sfx blocks
|
// convert Midi notes to sfx blocks
|
||||||
Dictionary<long, uint> breadthCache = new Dictionary<long, uint>();
|
Dictionary<long, uint> breadthCache = new Dictionary<long, uint>();
|
||||||
Dictionary<long, uint> depthCache = new Dictionary<long, uint>();
|
Dictionary<long, uint> depthCache = new Dictionary<long, uint>();
|
||||||
|
@ -194,7 +192,7 @@ namespace Pixi.Audio
|
||||||
sfx.Pitch = n.NoteNumber - 60 + Key; // In MIDI, 60 is middle C, but GC uses 0 for middle C
|
sfx.Pitch = n.NoteNumber - 60 + Key; // In MIDI, 60 is middle C, but GC uses 0 for middle C
|
||||||
sfx.TrackIndex = channelPrograms[n.Channel];
|
sfx.TrackIndex = channelPrograms[n.Channel];
|
||||||
sfx.Is3D = ThreeDee;
|
sfx.Is3D = ThreeDee;
|
||||||
sfx.Volume = AudioTools.VelocityToVolume(n.Velocity);
|
sfx.Volume = AudioTools.VelocityToVolume(n.Velocity) * VolumeMultiplier;
|
||||||
count++;
|
count++;
|
||||||
// connect wires
|
// connect wires
|
||||||
if (t == null) continue; // this should never happen
|
if (t == null) continue; // this should never happen
|
||||||
|
|
|
@ -17,8 +17,15 @@ namespace Pixi.Common
|
||||||
|
|
||||||
public static Dictionary<string, BlockJsonInfo[]> ParseBlueprintResource(string name)
|
public static Dictionary<string, BlockJsonInfo[]> ParseBlueprintResource(string name)
|
||||||
{
|
{
|
||||||
StreamReader bluemap = new StreamReader(Assembly.GetExecutingAssembly().GetManifestResourceStream(name));
|
StreamReader bluemap;
|
||||||
return JsonConvert.DeserializeObject<Dictionary<string, BlockJsonInfo[]>>(bluemap.ReadToEnd());
|
#if DEBUG
|
||||||
|
if (File.Exists(name))
|
||||||
|
bluemap = File.OpenText(name);
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
bluemap = new StreamReader(Assembly.GetExecutingAssembly().GetManifestResourceStream(name));
|
||||||
|
using (bluemap)
|
||||||
|
return JsonConvert.DeserializeObject<Dictionary<string, BlockJsonInfo[]>>(bluemap.ReadToEnd());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ProcessedVoxelObjectNotation[][] ProcessAndExpandBlocks(string name, BlockJsonInfo[] blocks, BlueprintProvider blueprints)
|
public static ProcessedVoxelObjectNotation[][] ProcessAndExpandBlocks(string name, BlockJsonInfo[] blocks, BlueprintProvider blueprints)
|
||||||
|
|
|
@ -314,6 +314,7 @@ namespace Pixi.Common
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
yield return asyncHandle.Continue();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -157,7 +157,7 @@ namespace Pixi.Common
|
||||||
#endif
|
#endif
|
||||||
// import blocks
|
// import blocks
|
||||||
BlockJsonInfo[] blocksInfo = magicImporter.Import(name);
|
BlockJsonInfo[] blocksInfo = magicImporter.Import(name);
|
||||||
if (blocksInfo.Length == 0)
|
if (blocksInfo == null || blocksInfo.Length == 0)
|
||||||
{
|
{
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
Logging.CommandLogError($"Importer {magicImporter.Name} didn't provide any blocks to import. Mission Aborted!");
|
Logging.CommandLogError($"Importer {magicImporter.Name} didn't provide any blocks to import. Mission Aborted!");
|
||||||
|
@ -564,6 +564,58 @@ namespace Pixi.Common
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case BlockIDs.DampedSpring:
|
||||||
|
string[] springSplit = pVONs[i].metadata.Split('\t');
|
||||||
|
if (springSplit.Length > 1 && float.TryParse(springSplit[1], out float stiffness))
|
||||||
|
{
|
||||||
|
DampedSpring d = blocks[i].Specialise<DampedSpring>();
|
||||||
|
d.Stiffness = stiffness;
|
||||||
|
if (springSplit.Length > 2 && float.TryParse(springSplit[2], out float damping))
|
||||||
|
{
|
||||||
|
d.Damping = damping;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case BlockIDs.ServoAxle:
|
||||||
|
case BlockIDs.ServoHinge:
|
||||||
|
case BlockIDs.PneumaticAxle:
|
||||||
|
case BlockIDs.PneumaticHinge:
|
||||||
|
string[] servoSplit = pVONs[i].metadata.Split('\t');
|
||||||
|
if (servoSplit.Length > 1 && float.TryParse(servoSplit[1], out float minAngle))
|
||||||
|
{
|
||||||
|
Servo s = blocks[i].Specialise<Servo>();
|
||||||
|
s.MinimumAngle = minAngle;
|
||||||
|
if (servoSplit.Length > 2 && float.TryParse(servoSplit[2], out float maxAngle))
|
||||||
|
{
|
||||||
|
s.MaximumAngle = maxAngle;
|
||||||
|
if (servoSplit.Length > 3 && float.TryParse(servoSplit[3], out float maxForce))
|
||||||
|
{
|
||||||
|
s.MaximumForce = maxForce;
|
||||||
|
if (servoSplit.Length > 4 && bool.TryParse(servoSplit[4], out bool reverse))
|
||||||
|
{
|
||||||
|
s.Reverse = reverse;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case BlockIDs.MotorM:
|
||||||
|
case BlockIDs.MotorS:
|
||||||
|
string[] motorSplit = pVONs[i].metadata.Split('\t');
|
||||||
|
if (motorSplit.Length > 1 && float.TryParse(motorSplit[1], out float topSpeed))
|
||||||
|
{
|
||||||
|
Motor m = blocks[i].Specialise<Motor>();
|
||||||
|
m.TopSpeed = topSpeed;
|
||||||
|
if (motorSplit.Length > 2 && float.TryParse(motorSplit[2], out float torque))
|
||||||
|
{
|
||||||
|
m.Torque = torque;
|
||||||
|
if (motorSplit.Length > 3 && bool.TryParse(motorSplit[3], out bool reverse))
|
||||||
|
{
|
||||||
|
m.Reverse = reverse;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
default: break; // do nothing
|
default: break; // do nothing
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,7 +42,7 @@ namespace Pixi.Common
|
||||||
public static BlockJsonInfo JsonObject(Block block, float[] origin = null)
|
public static BlockJsonInfo JsonObject(Block block, float[] origin = null)
|
||||||
{
|
{
|
||||||
if (origin == null) origin = origin_base;
|
if (origin == null) origin = origin_base;
|
||||||
return new BlockJsonInfo
|
BlockJsonInfo jsonInfo = new BlockJsonInfo
|
||||||
{
|
{
|
||||||
name = block.Type.ToString(),
|
name = block.Type.ToString(),
|
||||||
position = new float[3] { block.Position.x - origin[0], block.Position.y - origin[1], block.Position.z - origin[2]},
|
position = new float[3] { block.Position.x - origin[0], block.Position.y - origin[1], block.Position.z - origin[2]},
|
||||||
|
@ -50,6 +50,37 @@ namespace Pixi.Common
|
||||||
color = ColorSpaceUtility.UnquantizeToArray(block.Color),
|
color = ColorSpaceUtility.UnquantizeToArray(block.Color),
|
||||||
scale = new float[3] {block.Scale.x, block.Scale.y, block.Scale.z},
|
scale = new float[3] {block.Scale.x, block.Scale.y, block.Scale.z},
|
||||||
};
|
};
|
||||||
|
// custom stats for special blocks
|
||||||
|
switch (block.Type)
|
||||||
|
{
|
||||||
|
case BlockIDs.TextBlock:
|
||||||
|
TextBlock t = block.Specialise<TextBlock>();
|
||||||
|
jsonInfo.name += "\t" + t.Text + "\t" + t.TextBlockId;
|
||||||
|
break;
|
||||||
|
case BlockIDs.ConsoleBlock:
|
||||||
|
ConsoleBlock c = block.Specialise<ConsoleBlock>();
|
||||||
|
jsonInfo.name += "\t" + c.Command + "\t" + c.Arg1 + "\t" + c.Arg2 + "\t" + c.Arg3;
|
||||||
|
break;
|
||||||
|
case BlockIDs.DampedSpring:
|
||||||
|
DampedSpring d = block.Specialise<DampedSpring>();
|
||||||
|
jsonInfo.name += "\t" + d.Stiffness + "\t" + d.Damping;
|
||||||
|
break;
|
||||||
|
case BlockIDs.ServoAxle:
|
||||||
|
case BlockIDs.ServoHinge:
|
||||||
|
case BlockIDs.PneumaticAxle:
|
||||||
|
case BlockIDs.PneumaticHinge:
|
||||||
|
Servo s = block.Specialise<Servo>();
|
||||||
|
jsonInfo.name += "\t" + s.MinimumAngle + "\t" + s.MaximumAngle + "\t" + s.MaximumForce + "\t" +
|
||||||
|
s.Reverse;
|
||||||
|
break;
|
||||||
|
case BlockIDs.MotorM:
|
||||||
|
case BlockIDs.MotorS:
|
||||||
|
Motor m = block.Specialise<Motor>();
|
||||||
|
jsonInfo.name += "\t" + m.TopSpeed + "\t" + m.Torque + "\t" + m.Reverse;
|
||||||
|
break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
return jsonInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static BlockIDs NameToEnum(BlockJsonInfo block)
|
public static BlockIDs NameToEnum(BlockJsonInfo block)
|
||||||
|
|
1837
Pixi/Pixi.csproj
1837
Pixi/Pixi.csproj
File diff suppressed because it is too large
Load diff
|
@ -47,16 +47,19 @@ namespace Pixi
|
||||||
root.Inject(new ImageTextBlockImporter());
|
root.Inject(new ImageTextBlockImporter());
|
||||||
root.Inject(new ImageCommandImporter());
|
root.Inject(new ImageCommandImporter());
|
||||||
// Robot functionality
|
// Robot functionality
|
||||||
root.Inject(new RobotInternetImporter());
|
var robot = new RobotInternetImporter();
|
||||||
|
root.Inject(robot);
|
||||||
//RobotCommands.CreateRobotCRFCommand();
|
//RobotCommands.CreateRobotCRFCommand();
|
||||||
//RobotCommands.CreateRobotFileCommand();
|
//RobotCommands.CreateRobotFileCommand();
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
// Development functionality
|
// Development functionality
|
||||||
RobotCommands.CreatePartDumpCommand();
|
RobotCommands.CreatePartDumpCommand();
|
||||||
|
((RobotBlueprintProvider) robot.BlueprintProvider).AddDebugCommands();
|
||||||
root.Inject(new TestImporter());
|
root.Inject(new TestImporter());
|
||||||
#endif
|
#endif
|
||||||
// Audio functionality
|
// Audio functionality
|
||||||
root.Inject(new MidiImporter());
|
root.Inject(new MidiImporter());
|
||||||
|
root.Inject(new AudioFakeImporter());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -215,10 +215,10 @@ namespace Pixi.Robots
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
private static void TranslateBlockId(uint cubeId, ref CubeInfo result)
|
private static void TranslateBlockId(uint cubeId, ref CubeInfo result)
|
||||||
{
|
{
|
||||||
if (map == null)
|
if (map == null)
|
||||||
{
|
{
|
||||||
StreamReader cubemap = new StreamReader(Assembly.GetExecutingAssembly().GetManifestResourceStream("Pixi.cubes-id.json"));
|
StreamReader cubemap = new StreamReader(Assembly.GetExecutingAssembly().GetManifestResourceStream("Pixi.cubes-id.json"));
|
||||||
map = JsonConvert.DeserializeObject<Dictionary<uint, string>>(cubemap.ReadToEnd());
|
map = JsonConvert.DeserializeObject<Dictionary<uint, string>>(cubemap.ReadToEnd());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!map.ContainsKey(cubeId))
|
if (!map.ContainsKey(cubeId))
|
||||||
|
@ -231,81 +231,34 @@ namespace Pixi.Robots
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
string cubeName = map[cubeId];
|
string cubeName = map[cubeId];
|
||||||
|
|
||||||
|
string gcName = cubeName.Contains("glass") || cubeName.Contains("windshield")
|
||||||
|
? "Glass"
|
||||||
|
: "Aluminium";
|
||||||
|
if (cubeName.Contains("round"))
|
||||||
|
gcName += "Rounded";
|
||||||
|
|
||||||
if (cubeName.Contains("cube"))
|
if (cubeName.Contains("cube"))
|
||||||
{
|
gcName += "Cube";
|
||||||
result.block = BlockIDs.AluminiumCube;
|
|
||||||
result.rotation = float3.zero;
|
|
||||||
}
|
|
||||||
else if (cubeName.Contains("prism") || cubeName.Contains("edge"))
|
else if (cubeName.Contains("prism") || cubeName.Contains("edge"))
|
||||||
{
|
gcName += "Slope";
|
||||||
if (cubeName.Contains("round"))
|
|
||||||
{
|
|
||||||
if (cubeName.Contains("glass") || cubeName.Contains("windshield"))
|
|
||||||
{
|
|
||||||
result.block = BlockIDs.GlassRoundedSlope;
|
|
||||||
} else
|
|
||||||
result.block = BlockIDs.AluminiumRoundedSlope;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (cubeName.Contains("glass") || cubeName.Contains("windshield"))
|
|
||||||
{
|
|
||||||
result.block = BlockIDs.GlassSlope;
|
|
||||||
} else
|
|
||||||
result.block = BlockIDs.AluminiumSlope;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (cubeName.Contains("inner"))
|
else if (cubeName.Contains("inner"))
|
||||||
{
|
gcName += "SlicedCube";
|
||||||
if (cubeName.Contains("round"))
|
|
||||||
{
|
|
||||||
if (cubeName.Contains("glass") || cubeName.Contains("windshield"))
|
|
||||||
{
|
|
||||||
result.block = BlockIDs.GlassRoundedSlicedCube;
|
|
||||||
} else
|
|
||||||
result.block = BlockIDs.AluminiumRoundedSlicedCube;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (cubeName.Contains("glass") || cubeName.Contains("windshield"))
|
|
||||||
{
|
|
||||||
result.block = BlockIDs.GlassSlicedCube;
|
|
||||||
} else
|
|
||||||
result.block = BlockIDs.AluminiumSlicedCube;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (cubeName.Contains("tetra") || cubeName.Contains("corner"))
|
else if (cubeName.Contains("tetra") || cubeName.Contains("corner"))
|
||||||
{
|
gcName += "Corner";
|
||||||
if (cubeName.Contains("round"))
|
|
||||||
{
|
|
||||||
if (cubeName.Contains("glass") || cubeName.Contains("windshield"))
|
|
||||||
{
|
|
||||||
result.block = BlockIDs.GlassRoundedCorner;
|
|
||||||
} else
|
|
||||||
result.block = BlockIDs.AluminiumRoundedCorner;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (cubeName.Contains("glass") || cubeName.Contains("windshield"))
|
|
||||||
{
|
|
||||||
result.block = BlockIDs.GlassCorner;
|
|
||||||
} else
|
|
||||||
result.block = BlockIDs.AluminiumCorner;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (cubeName.Contains("pyramid"))
|
else if (cubeName.Contains("pyramid"))
|
||||||
{
|
gcName += "PyramidSegment";
|
||||||
result.block = BlockIDs.AluminiumPyramidSegment;
|
|
||||||
}
|
|
||||||
else if (cubeName.Contains("cone"))
|
else if (cubeName.Contains("cone"))
|
||||||
{
|
gcName += "ConeSegment";
|
||||||
result.block = BlockIDs.AluminiumConeSegment;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
result.block = BlockIDs.TextBlock;
|
result.block = BlockIDs.TextBlock;
|
||||||
result.name = cubeName;
|
result.name = cubeName;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BlockIDs id = VoxelObjectNotationUtility.NameToEnum(gcName);
|
||||||
|
result.block = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
|
|
@ -1,12 +1,14 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
using Svelto.DataStructures;
|
using Svelto.DataStructures;
|
||||||
using Unity.Mathematics;
|
using Unity.Mathematics;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
using GamecraftModdingAPI.Blocks;
|
using GamecraftModdingAPI.Blocks;
|
||||||
|
using GamecraftModdingAPI.Commands;
|
||||||
using GamecraftModdingAPI.Utility;
|
using GamecraftModdingAPI.Utility;
|
||||||
|
using Newtonsoft.Json;
|
||||||
using Pixi.Common;
|
using Pixi.Common;
|
||||||
|
|
||||||
namespace Pixi.Robots
|
namespace Pixi.Robots
|
||||||
|
@ -33,14 +35,8 @@ namespace Pixi.Robots
|
||||||
|
|
||||||
if (!botprints.ContainsKey(root.name) || RobotInternetImporter.CubeSize != 3)
|
if (!botprints.ContainsKey(root.name) || RobotInternetImporter.CubeSize != 3)
|
||||||
{
|
{
|
||||||
if (!parent.textBlockInfo.ContainsKey(name))
|
BlockJsonInfo copy = root;
|
||||||
{
|
copy.name = $"TextBlock\t{root.name} ({CubeUtility.CubeIdDescription(uint.Parse(root.name))})\tPixi";
|
||||||
parent.textBlockInfo[name] = new FasterList<string>();
|
|
||||||
}
|
|
||||||
BlockJsonInfo copy = root;
|
|
||||||
copy.name = "TextBlock";
|
|
||||||
Logging.MetaLog($"Parsing uint from '{root.name}'");
|
|
||||||
parent.textBlockInfo[name].Add(root.name + " (" + CubeUtility.CubeIdDescription(uint.Parse(root.name)) + ")");
|
|
||||||
return new BlockJsonInfo[1] {copy};
|
return new BlockJsonInfo[1] {copy};
|
||||||
}
|
}
|
||||||
BlockJsonInfo[] blueprint = botprints[root.name];
|
BlockJsonInfo[] blueprint = botprints[root.name];
|
||||||
|
@ -96,5 +92,49 @@ namespace Pixi.Robots
|
||||||
}
|
}
|
||||||
return adjustedBlueprint;
|
return adjustedBlueprint;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
public void AddDebugCommands()
|
||||||
|
{
|
||||||
|
CommandBuilder.Builder("PixiReload", "Reloads the robot blueprints")
|
||||||
|
.Action(() => botprints = null).Build();
|
||||||
|
CommandBuilder.Builder("RotateBlueprint",
|
||||||
|
"Rotates a blueprint with a given ID and dumps the result to a file. 1 means 90 degrees.")
|
||||||
|
.Action<string>(RotateBlueprint).Build();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RotateBlueprint(string parameters)
|
||||||
|
{
|
||||||
|
var p = parameters.Split(' ');
|
||||||
|
string id = p[0];
|
||||||
|
var xyz = new int[3];
|
||||||
|
for (int i = 0; i < xyz.Length; i++)
|
||||||
|
xyz[i] = int.Parse(p[i + 1]) * 90;
|
||||||
|
if (botprints == null)
|
||||||
|
{
|
||||||
|
botprints = BlueprintUtility.ParseBlueprintResource("Pixi.blueprints.json");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!botprints.ContainsKey(id))
|
||||||
|
{
|
||||||
|
Logging.CommandLogWarning("Blueprint with that ID not found.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var bp = botprints[id];
|
||||||
|
var rotChange = Quaternion.Euler(xyz[0], xyz[1], xyz[2]);
|
||||||
|
for (var i = 0; i < bp.Length; i++)
|
||||||
|
{
|
||||||
|
ref var info = ref bp[i];
|
||||||
|
var pos = ConversionUtility.FloatArrayToFloat3(info.position);
|
||||||
|
info.position = ConversionUtility.Float3ToFloatArray(rotChange * pos);
|
||||||
|
var rot = Quaternion.Euler(ConversionUtility.FloatArrayToFloat3(info.rotation));
|
||||||
|
info.rotation = ConversionUtility.Float3ToFloatArray((rotChange * rot).eulerAngles);
|
||||||
|
}
|
||||||
|
|
||||||
|
File.WriteAllText(id, JsonConvert.SerializeObject(bp));
|
||||||
|
Logging.CommandLog("Blueprint rotated " + rotChange.eulerAngles + " and dumped");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -31,7 +31,9 @@ namespace Pixi.Robots
|
||||||
{
|
{
|
||||||
Player local = new Player(PlayerType.Local);
|
Player local = new Player(PlayerType.Local);
|
||||||
Block baseBlock = local.GetBlockLookedAt();
|
Block baseBlock = local.GetBlockLookedAt();
|
||||||
Block[] blocks = baseBlock.GetConnectedCubes();
|
Block[] blocks = local.GetSelectedBlocks();
|
||||||
|
if (blocks.Length == 0)
|
||||||
|
blocks = baseBlock.GetConnectedCubes();
|
||||||
bool isBaseScaled = !(baseBlock.Scale.x > 0 && baseBlock.Scale.x < 2 && baseBlock.Scale.y > 0 && baseBlock.Scale.y < 2 && baseBlock.Scale.z > 0 && baseBlock.Scale.z < 2);
|
bool isBaseScaled = !(baseBlock.Scale.x > 0 && baseBlock.Scale.x < 2 && baseBlock.Scale.y > 0 && baseBlock.Scale.y < 2 && baseBlock.Scale.z > 0 && baseBlock.Scale.z < 2);
|
||||||
if (isBaseScaled)
|
if (isBaseScaled)
|
||||||
{
|
{
|
||||||
|
|
|
@ -28,8 +28,6 @@ namespace Pixi.Robots
|
||||||
|
|
||||||
public static int CubeSize = 3;
|
public static int CubeSize = 3;
|
||||||
|
|
||||||
internal readonly Dictionary<string, FasterList<string>> textBlockInfo = new Dictionary<string, FasterList<string>>();
|
|
||||||
|
|
||||||
public RobotInternetImporter()
|
public RobotInternetImporter()
|
||||||
{
|
{
|
||||||
BlueprintProvider = new RobotBlueprintProvider(this);
|
BlueprintProvider = new RobotBlueprintProvider(this);
|
||||||
|
@ -126,34 +124,26 @@ namespace Pixi.Robots
|
||||||
blocks[i].position += pos;
|
blocks[i].position += pos;
|
||||||
}
|
}
|
||||||
// set textblock colors (replace <color="white"> with <color=#HEX> in textblocks)
|
// set textblock colors (replace <color="white"> with <color=#HEX> in textblocks)
|
||||||
Regex pattern = new Regex("<color=(\"white\")|(white)>", RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.IgnoreCase | RegexOptions.CultureInvariant);
|
Regex pattern = new Regex("<color=((?:\"white\")|(?:white))>", RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.IgnoreCase | RegexOptions.CultureInvariant);
|
||||||
for (int i = 0; i < blocks.Length; i++)
|
for (int i = 0; i < blocks.Length; i++)
|
||||||
{
|
{
|
||||||
if (blocks[i].block == BlockIDs.TextBlock)
|
if (blocks[i].block == BlockIDs.TextBlock)
|
||||||
{
|
{
|
||||||
// TODO this blindly replaces color tags anywhere in metadata, not just ones that will go in the TextBlock's text field
|
// TODO this blindly replaces color tags anywhere in metadata, not just ones that will go in the TextBlock's text field
|
||||||
|
#if DEBUG
|
||||||
|
Logging.MetaLog($"Replacing text field in block with colour {blocks[i].color} with #{ColorUtility.ToHtmlStringRGBA(ColorSpaceUtility.UnquantizeToColor(blocks[i].color))}");
|
||||||
|
#endif
|
||||||
blocks[i].metadata = pattern.Replace(
|
blocks[i].metadata = pattern.Replace(
|
||||||
blocks[i].metadata,
|
blocks[i].metadata,
|
||||||
$"<color=#{ColorUtility.ToHtmlStringRGBA(ColorSpaceUtility.UnquantizeToColor(blocks[i].color))}>");
|
$"<color=#{ColorUtility.ToHtmlStringRGBA(ColorSpaceUtility.UnquantizeToColor(blocks[i].color))}>");
|
||||||
|
// NOTE: Regex.Replace replaces the whole match string only when there's a capture group (it's dumb, idk why).
|
||||||
|
// The non-capturing groups may be messing with .NET or something
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void PostProcess(string name, ref Block[] blocks)
|
public void PostProcess(string name, ref Block[] blocks)
|
||||||
{
|
{
|
||||||
int textBlockInfoIndex = 0;
|
|
||||||
for (int c = 0; c < blocks.Length; c++)
|
|
||||||
{
|
|
||||||
Block block = blocks[c];
|
|
||||||
// the goal is for this to never evaluate to true (ie all cubes are translated correctly)
|
|
||||||
if (block.Type == BlockIDs.TextBlock)
|
|
||||||
{
|
|
||||||
textBlockInfoIndex++;
|
|
||||||
block.Specialise<TextBlock>().Text = textBlockInfo[name][textBlockInfoIndex];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
textBlockInfo.Remove(name);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Loading…
Reference in a new issue