public IBlockState GetBlock(int x, int y, int z) { var index = Index(x, y, z); var id = _nBitsArray[index]; return(id == Nil ? null : BlockPalette.GetBlockState(id)); }
public virtual void HandleMcpeStartGame(McpeStartGame message) { var client = Client; client.EntityId = message.runtimeEntityId; client.NetworkEntityId = message.entityIdSelf; client.SpawnPoint = message.spawn; client.CurrentLocation = new PlayerLocation(client.SpawnPoint, message.rotation.X, message.rotation.X, message.rotation.Y); BlockPalette blockPalette = message.blockPalette; client.BlockPalette = blockPalette; client.LevelInfo.LevelName = message.worldName; client.LevelInfo.Version = 19133; client.LevelInfo.GameType = message.gamemode; var packet = McpeRequestChunkRadius.CreateObject(); client.ChunkRadius = 5; packet.chunkRadius = client.ChunkRadius; if (Client.IsEmulator) { Client.HasSpawned = true; Client.PlayerStatusChangedWaitHandle.Set(); Client.SendMcpeMovePlayer(); } client.SendPacket(packet); }
// ** Initialization and control public void Configure(RenderConfiguration Configuration) { _Config = Configuration; _ColourPalette = _Config.Palette; _Metrics = _Config.Metrics; _Chunks = Configuration.Chunks; if (_Config.AdvancedRenderOptions.Exists(x => x.Key.ToLower() == "mode")) { switch (_Config.AdvancedRenderOptions.Find(x => x.Key.ToLower() == "mode").Value) { case "c": _RenderStartY = GetStartRenderYCave; break; case "C": _RenderStartY = GetStartRenderYCaveAlternate; break; default: _RenderStartY = GetStartRenderYNormal; break; } } else { _RenderStartY = GetStartRenderYNormal; } }
public override void HandleMcpeStartGame(McpeStartGame message) { Client.EntityId = message.runtimeEntityId; Client.NetworkEntityId = message.entityIdSelf; Client.SpawnPoint = message.spawn; Client.CurrentLocation = new PlayerLocation(Client.SpawnPoint, message.rotation.X, message.rotation.X, message.rotation.Y); Client.LevelInfo.LevelName = message.levelId; Client.LevelInfo.Version = 19133; Client.LevelInfo.GameType = message.gamemode; BlockPalette = message.blockPalette; _internalStates = new HashSet <BlockStateContainer>(BlockFactory.BlockPalette); { int viewDistance = Config.GetProperty("ViewDistance", 11); var packet = McpeRequestChunkRadius.CreateObject(); Client.ChunkRadius = viewDistance; packet.chunkRadius = Client.ChunkRadius; Client.SendPacket(packet); } }
private void Start() { m_World = Locator <IWorld> .GetService(); m_Picker = MonoSingleton <GameSystem> .Instance.InputMngIns.PickerIns; BlockPalette Palette = m_World.BlkPalette; var buttons = GetComponentsInChildren <BlockSlot_Bar>(); byte i = 1; foreach (var bt in buttons) { if (i >= Palette.Count) { break; } bt.SetBlock(Palette[i]); ++i; } //set default selected DefaultSlot.OnSelect(); }
private void ExecuteWritePallet(BedrockTraceHandler caller) { var client = caller.Client; BlockPalette palette = client.BlockPalette; _runningBlockMetadataDiscovery = false; WritePaletteToJson(palette); }
public void SetPreviewPalette(string toSet) //called on buttonpress calls from methods in MainMenu.cs; updates the preview { BlockPalette blockPalette = new BlockPalette(toSet); for (int i = 0; i < 8; i++) { previewBlocks[i].GetComponent <SpriteRenderer>().color = blockPalette.palette[i]; } }
static BlockFactory() { for (int i = 0; i < byte.MaxValue * 2; i++) { var block = GetBlockById(i); if (block != null) { if (block.IsTransparent) { TransparentBlocks[block.Id] = 1; } if (block.LightLevel > 0) { LuminousBlocks[block.Id] = (byte)block.LightLevel; } } } NameToId = BuildNameToId(); for (int i = 0; i < LegacyToRuntimeId.Length; ++i) { LegacyToRuntimeId[i] = -1; } var assembly = Assembly.GetAssembly(typeof(Block)); lock (lockObj) { using (var stream = assembly.GetManifestResourceStream(typeof(Block).Namespace + ".blockstates.json")) using (var reader = new StreamReader(stream)) { BlockPalette = BlockPalette.FromJson(reader.ReadToEnd()); } } int palletSize = BlockPalette.Count; for (int i = 0; i < palletSize; i++) { if (BlockPalette[i].Data > 15) { continue; // TODO: figure out why palette contains blocks with meta more than 15 } if (BlockPalette[i].Data == -1) { continue; // These are blockstates that does not have a metadata mapping } LegacyToRuntimeId[(BlockPalette[i].Id << 4) | (byte)BlockPalette[i].Data] = i; } BlockStates = new HashSet <BlockStateContainer>(BlockPalette); }
public void FillBlock(BlockState block) { _blocks.Fill(BlockPalette.IdForBlock(block)); if (block == AirBlock) { IsEmpty = true; } else { IsEmpty = false; } }
private static void PopulateBlockPalette() { BlockPalette.Add("Air", new Block("Air", BlockTypes.Air, Textures["Air"], dummyPosition)); BlockPalette.Add("FuelCell", new FuelCell("FuelCell", Textures["FuelCell"], dummyPosition)); foreach (Cooler cooler in coolers) { BlockPalette.Add(cooler.CoolerType.ToString(), cooler); } foreach (Moderator moderator in moderators) { BlockPalette.Add(moderator.ModeratorType.ToString(), moderator); } }
/* Set Default Settings * Returns all settings to their defaults for the normal gamemode. * Called my MainMenu before applying other modifiers here and loading the game */ public void SetDefaultSettings() { currentModeName = GameMode.Normal; fireMode = "tetromino"; rotate45 = false; minWaitTime = 0.4f; maxWaitTime = 2.5f; flipCamera = false; makeScoreNegative = false; settingPalette = new BlockPalette(); //default constructor slipperyJumpAllowed = false; //TODO maybe remove? boostCooldown = 10.0f; impossibleMode = false; immuneToCrush = false; }
private static BlockStateContainer GetServerRuntimeId(BlockPalette bedrockPalette, HashSet <BlockStateContainer> internalBlockPallet, int runtimeId) { if (runtimeId < 0 || runtimeId >= bedrockPalette.Count) { Log.Error($"RuntimeId = {runtimeId}"); } var record = bedrockPalette[runtimeId]; if (!internalBlockPallet.TryGetValue(record, out BlockStateContainer internalRecord)) { Log.Error($"Did not find {record.Id}"); return(null); } return(internalRecord); }
internal RenderConfiguration(BlockPalette UsePalette, WorldMetrics UseMetrics) { MinLightLevel = 15; WorldPath = ""; SaveFilename = ""; ScanFilename = ""; MetricsFilename = ""; Dimension = ""; EnableMultithreading = false; Palette = UsePalette; Metrics = UseMetrics; RendererName = "Standard"; MaxThreads = Environment.ProcessorCount; AdvancedRenderOptions = new List <KeyValuePair <string, string> >(); SubregionChunks = new Rectangle(); RenderSubregion = false; }
public void SetBlock(int x, int y, int z, IBlockState blockState) { var id = blockState != null?BlockPalette.GetId(blockState) : Nil; if (id == -1) // block not registered { Resize((byte)(BlockPalette.BitsPerBlock + 1)); id = BlockPalette.GetId(blockState); if (id == -1) { throw new InvalidOperationException("Invalid block state palette id"); } } var index = Index(x, y, z); _nBitsArray[index] = id; _blockCount = ushort.MaxValue; }
//Unity function //----------------------------------------------------------- public void Start() { BlockPalette palette = Locator <IWorld> .GetService().BlkPalette; var Slots = GetComponentsInChildren <BlockSlot_Menu>(); byte i = 1; foreach (var slot in Slots) { if (i >= palette.Count) { break; } slot.SetBlock(palette[i]); ++i; } }
private static void WritePaletteToJson(BlockPalette palette) { var jsonSerializerSettings = new JsonSerializerSettings { PreserveReferencesHandling = PreserveReferencesHandling.None, Formatting = Formatting.None, }; jsonSerializerSettings.Converters.Add(new StringEnumConverter()); jsonSerializerSettings.Converters.Add(new NbtIntConverter()); jsonSerializerSettings.Converters.Add(new NbtStringConverter()); jsonSerializerSettings.Converters.Add(new IPAddressConverter()); jsonSerializerSettings.Converters.Add(new IPEndPointConverter()); var records = palette.OrderBy(bs => bs.Id).ThenBy(bs => bs.Data).ToArray(); string fileName = Path.GetTempPath() + "blockstates_" + Guid.NewGuid() + ".json"; var writer = File.AppendText(fileName); bool isFirst = true; writer.WriteLine("["); foreach (var record in records) { string result = JsonConvert.SerializeObject(record, jsonSerializerSettings); writer.Write($"{(isFirst ? "" : ",\n")}{result}"); isFirst = false; } writer.WriteLine("\n]"); var stringRecords = records.Where(r => r.States.Any(s => s is BlockStateString)); foreach (BlockStateContainer stringRecord in stringRecords) { writer.WriteLine($"Item {stringRecord.Name}"); } writer.Close(); }
/// <summary> /// Resize the storage to match the bitsPerBlock /// </summary> /// <param name="bitsPerBlock">The number of bits used to store a block state</param> private void Resize(byte bitsPerBlock) { var previousDataBits = _nBitsArray; var previousBlockPalette = BlockPalette; if (!UpdatePalette(bitsPerBlock)) { return; } for (var i = 0; i < previousDataBits.Capacity; i++) { var blockStateId = previousDataBits[i]; if (blockStateId == 0) { continue; } var blockState = previousBlockPalette.GetBlockState(blockStateId); _nBitsArray[i] = BlockPalette.GetId(blockState); } }
public void BlcoksWithBlockstates() { List <string> blocksWithStates = new List <string>(); BlockPalette blockPalette = BlockFactory.BlockPalette; foreach (BlockStateContainer stateContainer in blockPalette) { if (stateContainer.States.Count > 0) { if (stateContainer.States.Count(s => s.Name.Contains("direction")) > 0) { blocksWithStates.Add(stateContainer.Name); } if (stateContainer.States.Count(s => s.Name.Contains("face")) > 0) { blocksWithStates.Add(stateContainer.Name); } } } foreach (string name in blocksWithStates.OrderBy(n => n).Distinct()) { Console.WriteLine($"{name}"); foreach (var state in BlockFactory.GetBlockByName(name).GetState().States) { if (state.Name.Contains("direction")) { Console.WriteLine($"\t{state.Name}"); } if (state.Name.Contains("face")) { Console.WriteLine($"\t{state.Name}"); } } } }
public override void HandleMcpeStartGame(McpeStartGame message) { Client.EntityId = message.runtimeEntityId; Client.NetworkEntityId = message.entityIdSelf; Client.SpawnPoint = message.spawn; Client.CurrentLocation = new PlayerLocation(Client.SpawnPoint, message.rotation.X, message.rotation.X, message.rotation.Y); BlockPalette blockPalette = message.blockPalette; Client.BlockPalette = blockPalette; Log.Warn($"Got position from startgame packet: {Client.CurrentLocation}"); var settings = new JsonSerializerSettings { PreserveReferencesHandling = PreserveReferencesHandling.Arrays, TypeNameHandling = TypeNameHandling.Auto, Formatting = Formatting.Indented, DefaultValueHandling = DefaultValueHandling.Include }; var fileNameItemstates = Path.GetTempPath() + "itemstates_" + Guid.NewGuid() + ".json"; File.WriteAllText(fileNameItemstates, JsonConvert.SerializeObject(message.itemstates, settings)); string fileName = Path.GetTempPath() + "MissingBlocks_" + Guid.NewGuid() + ".txt"; using (FileStream file = File.OpenWrite(fileName)) { var writer = new IndentedTextWriter(new StreamWriter(file)); Log.Warn($"Directory:\n{Path.GetTempPath()}"); Log.Warn($"Filename:\n{fileName}"); writer.WriteLine($"namespace MiNET.Blocks"); writer.WriteLine($"{{"); writer.Indent++; var blocks = new List <(int, string)>(); foreach (IGrouping <string, BlockStateContainer> blockstateGrouping in blockPalette.OrderBy(record => record.Name).ThenBy(record => record.Data).ThenBy(record => record.RuntimeId).GroupBy(record => record.Name)) { BlockStateContainer currentBlockState = blockstateGrouping.First(); Log.Debug($"{currentBlockState.Name}, Id={currentBlockState.Id}"); BlockStateContainer defaultBlockState = BlockFactory.GetBlockById(currentBlockState.Id, 0)?.GetGlobalState(); if (defaultBlockState == null) { defaultBlockState = blockstateGrouping.FirstOrDefault(bs => bs.Data == 0); } Log.Debug($"{currentBlockState.RuntimeId}, {currentBlockState.Name}, {currentBlockState.Data}"); Block blockById = BlockFactory.GetBlockById(currentBlockState.Id); bool existingBlock = blockById.GetType() != typeof(Block) && !blockById.IsGenerated; int id = existingBlock ? currentBlockState.Id : -1; string blockClassName = CodeName(currentBlockState.Name.Replace("minecraft:", ""), true); blocks.Add((blockById.Id, blockClassName)); writer.WriteLineNoTabs($""); writer.WriteLine($"public partial class {blockClassName} // {blockById.Id} typeof={blockById.GetType().Name}"); writer.WriteLine($"{{"); writer.Indent++; writer.WriteLine($"public override string Name => \"{currentBlockState.Name}\";"); writer.WriteLineNoTabs(""); var bits = new List <BlockStateByte>(); foreach (var state in blockstateGrouping.First().States) { var q = blockstateGrouping.SelectMany(c => c.States); // If this is on base, skip this property. We need this to implement common functionality. Type baseType = blockById.GetType().BaseType; bool propOverride = baseType != null && ("Block" != baseType.Name && baseType.GetProperty(CodeName(state.Name, true)) != null); switch (state) { case BlockStateByte blockStateByte: { var values = q.Where(s => s.Name == state.Name).Select(d => ((BlockStateByte)d).Value).Distinct().OrderBy(s => s).ToList(); byte defaultVal = ((BlockStateByte)defaultBlockState?.States.First(s => s.Name == state.Name))?.Value ?? 0; if (values.Min() == 0 && values.Max() == 1) { bits.Add(blockStateByte); writer.Write($"[StateBit] "); writer.WriteLine($"public{(propOverride ? " override" : "")} bool {CodeName(state.Name, true)} {{ get; set; }} = {(defaultVal == 1 ? "true" : "false")};"); } else { writer.Write($"[StateRange({values.Min()}, {values.Max()})] "); writer.WriteLine($"public{(propOverride ? " override" : "")} byte {CodeName(state.Name, true)} {{ get; set; }} = {defaultVal};"); } break; } case BlockStateInt blockStateInt: { var values = q.Where(s => s.Name == state.Name).Select(d => ((BlockStateInt)d).Value).Distinct().OrderBy(s => s).ToList(); int defaultVal = ((BlockStateInt)defaultBlockState?.States.First(s => s.Name == state.Name))?.Value ?? 0; writer.Write($"[StateRange({values.Min()}, {values.Max()})] "); writer.WriteLine($"public{(propOverride ? " override" : "")} int {CodeName(state.Name, true)} {{ get; set; }} = {defaultVal};"); break; } case BlockStateString blockStateString: { var values = q.Where(s => s.Name == state.Name).Select(d => ((BlockStateString)d).Value).Distinct().ToList(); string defaultVal = ((BlockStateString)defaultBlockState?.States.First(s => s.Name == state.Name))?.Value ?? ""; if (values.Count > 1) { writer.WriteLine($"[StateEnum({string.Join(',', values.Select(v => $"\"{v}\""))})]"); } writer.WriteLine($"public{(propOverride ? " override" : "")} string {CodeName(state.Name, true)} {{ get; set; }} = \"{defaultVal}\";"); break; } default: throw new ArgumentOutOfRangeException(nameof(state)); } } // Constructor //if (id == -1 || blockById.IsGenerated) //{ // writer.WriteLine($""); // writer.WriteLine($"public {blockClassName}() : base({currentBlockState.Id})"); // writer.WriteLine($"{{"); // writer.Indent++; // writer.WriteLine($"IsGenerated = true;"); // writer.WriteLine($"SetGenerated();"); // writer.Indent--; // writer.WriteLine($"}}"); //} writer.WriteLineNoTabs($""); writer.WriteLine($"public override void SetState(List<IBlockState> states)"); writer.WriteLine($"{{"); writer.Indent++; writer.WriteLine($"foreach (var state in states)"); writer.WriteLine($"{{"); writer.Indent++; writer.WriteLine($"switch(state)"); writer.WriteLine($"{{"); writer.Indent++; foreach (var state in blockstateGrouping.First().States) { writer.WriteLine($"case {state.GetType().Name} s when s.Name == \"{state.Name}\":"); writer.Indent++; writer.WriteLine($"{CodeName(state.Name, true)} = {(bits.Contains(state) ? "Convert.ToBoolean(s.Value)" : "s.Value")};"); writer.WriteLine($"break;"); writer.Indent--; } writer.Indent--; writer.WriteLine($"}} // switch"); writer.Indent--; writer.WriteLine($"}} // foreach"); writer.Indent--; writer.WriteLine($"}} // method"); writer.WriteLineNoTabs($""); writer.WriteLine($"public override BlockStateContainer GetState()"); writer.WriteLine($"{{"); writer.Indent++; writer.WriteLine($"var record = new BlockStateContainer();"); writer.WriteLine($"record.Name = \"{blockstateGrouping.First().Name}\";"); writer.WriteLine($"record.Id = {blockstateGrouping.First().Id};"); foreach (var state in blockstateGrouping.First().States) { string propName = CodeName(state.Name, true); writer.WriteLine($"record.States.Add(new {state.GetType().Name} {{Name = \"{state.Name}\", Value = {(bits.Contains(state) ? $"Convert.ToByte({propName})" : propName)}}});"); } writer.WriteLine($"return record;"); writer.Indent--; writer.WriteLine($"}} // method"); writer.Indent--; writer.WriteLine($"}} // class"); } writer.WriteLine(); foreach (var block in blocks.OrderBy(tuple => tuple.Item1)) { int clazzId = block.Item1; Block blockById = BlockFactory.GetBlockById(clazzId); bool existingBlock = blockById.GetType() != typeof(Block) && !blockById.IsGenerated; if (existingBlock) { continue; } string clazzName = block.Item2; string baseClazz = clazzName.EndsWith("Stairs") ? "BlockStairs" : "Block"; baseClazz = clazzName.EndsWith("Slab") && !clazzName.EndsWith("DoubleSlab")? "SlabBase" : baseClazz; writer.WriteLine($"public partial class {clazzName} : {baseClazz} {{ " + $"public {clazzName}() : base({clazzId}) {{ IsGenerated = true; }} " + $"}}"); } writer.Indent--; writer.WriteLine($"}}"); // namespace //foreach (var block in blocks.OrderBy(tuple => tuple.Item1)) //{ // // 495 => new StrippedCrimsonStem(), // writer.WriteLine($"\t\t\t\t{block.Item1} => new {block.Item2}(),"); //} writer.Flush(); } LogGamerules(message.gamerules); Client.LevelInfo.LevelName = "Default"; Client.LevelInfo.Version = 19133; Client.LevelInfo.GameType = message.gamemode; //ClientUtils.SaveLevel(_level); { var packet = McpeRequestChunkRadius.CreateObject(); Client.ChunkRadius = 5; packet.chunkRadius = Client.ChunkRadius; Client.SendPacket(packet); } }
public static ChunkColumn DecodeChunkColumn(int subChunkCount, byte[] buffer, BlockPalette bedrockPalette = null, HashSet <BlockStateContainer> internalBlockPallet = null) { //lock (_chunkRead) { var stream = new MemoryStream(buffer); { var defStream = new BinaryReader(stream); if (subChunkCount < 1) { Log.Warn("Nothing to read"); return(null); } //if (Log.IsTraceEnabled()) Log.Trace($"Reading {subChunkCount} sections"); var chunkColumn = new ChunkColumn(false); for (int chunkIndex = 0; chunkIndex < subChunkCount; chunkIndex++) { int version = stream.ReadByte(); int storageSize = stream.ReadByte(); var subChunk = chunkColumn[chunkIndex]; for (int storageIndex = 0; storageIndex < storageSize; storageIndex++) { int flags = stream.ReadByte(); bool isRuntime = (flags & 1) != 0; int bitsPerBlock = flags >> 1; int blocksPerWord = (int)Math.Floor(32f / bitsPerBlock); int wordsPerChunk = (int)Math.Ceiling(4096f / blocksPerWord); if (Log.IsTraceEnabled()) { Log.Trace($"New section {chunkIndex}, " + $"version={version}, " + $"storageSize={storageSize}, " + $"storageIndex={storageIndex}, " + $"bitsPerBlock={bitsPerBlock}, " + $"isRuntime={isRuntime}, " + $"noBlocksPerWord={blocksPerWord}, " + $"wordCount={wordsPerChunk}, " + $""); } long jumpPos = stream.Position; stream.Seek(wordsPerChunk * 4, SeekOrigin.Current); int paletteCount = VarInt.ReadSInt32(stream); var palette = new int[paletteCount]; for (int j = 0; j < paletteCount; j++) { if (!isRuntime) { var file = new NbtFile { BigEndian = false, UseVarInt = true }; file.LoadFromStream(stream, NbtCompression.None); var tag = (NbtCompound)file.RootTag; Block block = BlockFactory.GetBlockByName(tag["name"].StringValue); if (block != null && block.GetType() != typeof(Block) && !(block is Air)) { List <IBlockState> blockState = ReadBlockState(tag); block.SetState(blockState); } else { block = new Air(); } palette[j] = block.GetRuntimeId(); } else { int runtimeId = VarInt.ReadSInt32(stream); if (bedrockPalette == null || internalBlockPallet == null) { continue; } palette[j] = GetServerRuntimeId(bedrockPalette, internalBlockPallet, runtimeId); } } long afterPos = stream.Position; stream.Position = jumpPos; int position = 0; for (int w = 0; w < wordsPerChunk; w++) { uint word = defStream.ReadUInt32(); for (int block = 0; block < blocksPerWord; block++) { if (position >= 4096) { continue; } uint state = (uint)((word >> ((position % blocksPerWord) * bitsPerBlock)) & ((1 << bitsPerBlock) - 1)); int x = (position >> 8) & 0xF; int y = position & 0xF; int z = (position >> 4) & 0xF; int runtimeId = palette[state]; if (storageIndex == 0) { subChunk.SetBlockByRuntimeId(x, y, z, (int)runtimeId); } else { subChunk.SetLoggedBlockByRuntimeId(x, y, z, (int)runtimeId); } position++; } } stream.Position = afterPos; } } if (stream.Read(chunkColumn.biomeId, 0, 256) != 256) { return(chunkColumn); } //Log.Debug($"biomeId:\n{Package.HexDump(chunk.biomeId)}"); if (stream.Position >= stream.Length - 1) { return(chunkColumn); } int borderBlock = VarInt.ReadSInt32(stream); if (borderBlock != 0) { Log.Warn($"??? Got borderblock with value {borderBlock}."); int len = (int)(stream.Length - stream.Position); var bytes = new byte[len]; stream.Read(bytes, 0, len); Log.Warn($"Data to read for border blocks\n{Packet.HexDump(new ReadOnlyMemory<byte>(bytes))}"); //byte[] buf = new byte[borderBlock]; //int len = stream.Read(buf, 0, borderBlock); //Log.Warn($"??? Got borderblock {borderBlock}. Read {len} bytes"); //Log.Debug($"{Packet.HexDump(buf)}"); //for (int i = 0; i < borderBlock; i++) //{ // int x = (buf[i] & 0xf0) >> 4; // int z = buf[i] & 0x0f; // Log.Debug($"x={x}, z={z}"); //} } if (stream.Position < stream.Length - 1) { while (stream.Position < stream.Length) { NbtFile file = new NbtFile() { BigEndian = false, UseVarInt = true }; file.LoadFromStream(stream, NbtCompression.None); var blockEntityTag = file.RootTag; if (blockEntityTag.Name != "alex") { int x = blockEntityTag["x"].IntValue; int y = blockEntityTag["y"].IntValue; int z = blockEntityTag["z"].IntValue; chunkColumn.SetBlockEntity(new BlockCoordinates(x, y, z), (NbtCompound)file.RootTag); if (Log.IsTraceEnabled()) { Log.Trace($"Blockentity:\n{file.RootTag}"); } } } } if (stream.Position < stream.Length - 1) { int len = (int)(stream.Length - stream.Position); var bytes = new byte[len]; stream.Read(bytes, 0, len); Log.Warn($"Still have data to read\n{Packet.HexDump(new ReadOnlyMemory<byte>(bytes))}"); } return(chunkColumn); } } }
static BlockFactory() { for (int i = 0; i < byte.MaxValue * 2; i++) { var block = GetBlockById(i); if (block != null) { if (block.IsTransparent) { TransparentBlocks[block.Id] = 1; } if (block.LightLevel > 0) { LuminousBlocks[block.Id] = (byte)block.LightLevel; } } } NameToId = BuildNameToId(); for (int i = 0; i < LegacyToRuntimeId.Length; ++i) { LegacyToRuntimeId[i] = -1; } var assembly = Assembly.GetAssembly(typeof(Block)); lock (lockObj) { Dictionary <string, int> idMapping; using (var stream = assembly.GetManifestResourceStream(typeof(Block).Namespace + ".block_id_map.json")) using (var reader = new StreamReader(stream)) { idMapping = JsonConvert.DeserializeObject <Dictionary <string, int> >(reader.ReadToEnd()); } Dictionary <string, short> itemIdMapping; using (var stream = assembly.GetManifestResourceStream(typeof(Block).Namespace + ".item_id_map.json")) using (var reader = new StreamReader(stream)) { itemIdMapping = JsonConvert.DeserializeObject <Dictionary <string, short> >(reader.ReadToEnd()); } int runtimeId = 0; BlockPalette = new BlockPalette(); using (var stream = assembly.GetManifestResourceStream(typeof(Block).Namespace + ".canonical_block_states.nbt")) { var reader = new NbtFile(); reader.UseVarInt = true; reader.AllowAlternativeRootTag = true; do { reader.LoadFromStream(stream, NbtCompression.AutoDetect); var record = new BlockStateContainer(); var tag = reader.RootTag; string name = tag["name"].StringValue; record.Name = name; record.States = new List <IBlockState>(); if (idMapping.TryGetValue(name, out var id)) { record.Id = id; } var states = tag["states"]; if (states != null && states is NbtCompound compound) { foreach (var stateEntry in compound) { switch (stateEntry) { case NbtInt nbtInt: record.States.Add(new BlockStateInt() { Name = nbtInt.Name, Value = nbtInt.Value }); break; case NbtByte nbtByte: record.States.Add(new BlockStateByte() { Name = nbtByte.Name, Value = nbtByte.Value }); break; case NbtString nbtString: record.States.Add(new BlockStateString() { Name = nbtString.Name, Value = nbtString.Value }); break; } } } if (itemIdMapping.TryGetValue(name, out var itemId)) { record.ItemInstance = new ItemPickInstance() { Id = itemId, WantNbt = false, Metadata = 0 }; } record.RuntimeId = runtimeId++; BlockPalette.Add(record); } while (stream.Position < stream.Length); } /*using (var stream = assembly.GetManifestResourceStream(typeof(Block).Namespace + ".blockstates.json")) * using (var reader = new StreamReader(stream)) * { * BlockPalette = BlockPalette.FromJson(reader.ReadToEnd()); * }*/ foreach (var record in BlockPalette) { var states = new List <NbtTag>(); foreach (IBlockState state in record.States) { NbtTag stateTag = null; switch (state) { case BlockStateByte blockStateByte: stateTag = new NbtByte(state.Name, blockStateByte.Value); break; case BlockStateInt blockStateInt: stateTag = new NbtInt(state.Name, blockStateInt.Value); break; case BlockStateString blockStateString: stateTag = new NbtString(state.Name, blockStateString.Value); break; default: throw new ArgumentOutOfRangeException(nameof(state)); } states.Add(stateTag); } var nbt = new NbtFile() { BigEndian = false, UseVarInt = true, RootTag = new NbtCompound("states", states) }; byte[] nbtBinary = nbt.SaveToBuffer(NbtCompression.None); record.StatesCacheNbt = nbtBinary; } } int palletSize = BlockPalette.Count; for (int i = 0; i < palletSize; i++) { if (BlockPalette[i].Data > 15) { continue; // TODO: figure out why palette contains blocks with meta more than 15 } if (BlockPalette[i].Data == -1) { continue; // These are blockstates that does not have a metadata mapping } LegacyToRuntimeId[(BlockPalette[i].Id << 4) | (byte)BlockPalette[i].Data] = i; } BlockStates = new HashSet <BlockStateContainer>(BlockPalette); }
private void ExecutePickBlocks(BedrockTraceHandler caller) { var client = caller.Client; int count = 500; int yStart = 100; int x = 0; int z = 0; string fileName = Path.GetTempPath() + "pick_items_" + Guid.NewGuid() + ".json"; var writer = File.AppendText(fileName); var jsonSerializerSettings = new JsonSerializerSettings { PreserveReferencesHandling = PreserveReferencesHandling.None, Formatting = Formatting.None, }; jsonSerializerSettings.Converters.Add(new NbtIntConverter()); jsonSerializerSettings.Converters.Add(new NbtStringConverter()); //BlockPalette palette = client.BlockPalette; BlockPalette palette = BlockFactory.BlockPalette; // only if we have updated it _resetEventPlayerHotbar.Reset(); for (int id = 0; id < count; id++) { try { { var request = new McpeCommandRequest(); request.command = $"/tp TheGrey {x} {150} {z}"; request.unknownUuid = new UUID(Guid.NewGuid().ToString()); client.SendPacket(request); } var block = BlockFactory.GetBlockById(id); if (block.GetType() == typeof(Block)) { continue; } if (block is Cocoa) { continue; // crashes on meta=15 } int y = yStart; for (int meta = 0; meta <= 15; meta++) { var blockstate = palette.FirstOrDefault(b => b.Id == id && b.Data == meta); if (blockstate == null) { continue; } blockstate.ItemInstance = null; // reset to nothing string name = blockstate.Name.Replace("minecraft:", ""); if (name == "double_plant" || name == "air" || name.StartsWith("element")) { break; } var pick = McpeBlockPickRequest.CreateObject(); pick.x = x; pick.y = y; pick.z = z; client.SendPacket(pick); //Thread.Sleep(100); if (!_resetEventPlayerHotbar.WaitOne(300)) { Log.Error($"No picked item for {id}, {meta}, {name}"); _lastSelectedItem = new ItemAir(); continue; //break; } // Investigate last selected item. This should be the one we picked Item item; lock (_lastSelectedItem) { item = _lastSelectedItem; _lastSelectedItem = new ItemAir(); } Log.Warn($"For {id}, {meta} we picked {item}"); blockstate.ItemInstance = new ItemPickInstance() { Id = item.Id, Metadata = item.Metadata, WantNbt = item.ExtraData != null }; string result = JsonConvert.SerializeObject(blockstate, jsonSerializerSettings); writer.WriteLine($"{item}; {result}"); writer.Flush(); if (blockstate.States.Count == 0) { break; } y += 2; } } finally { x += 2; } } writer.Close(); WritePaletteToJson(palette); Log.Warn("Finished!"); }
public BlockState GetBlock(int index) { return(BlockPalette.BlockForId(_blocks[index])); }
public static ChunkColumn DecodeChunkColumn(int subChunkCount, byte[] buffer, BlockPalette bedrockPalette = null, HashSet <BlockStateContainer> internalBlockPallet = null) { lock (_chunkRead) { var stream = new MemoryStream(buffer); { var defStream = new NbtBinaryReader(stream, true); if (subChunkCount < 1) { Log.Warn("Nothing to read"); return(null); } Log.Debug($"Reading {subChunkCount} sections"); var chunkColumn = new ChunkColumn(false); for (int chunkIndex = 0; chunkIndex < subChunkCount; chunkIndex++) { int version = defStream.ReadByte(); int storageSize = defStream.ReadByte(); var subChunk = chunkColumn[chunkIndex]; for (int storageIndex = 0; storageIndex < storageSize; storageIndex++) { int bitsPerBlock = defStream.ReadByte() >> 1; int blocksPerWord = (int)Math.Floor(32f / bitsPerBlock); int wordsPerChunk = (int)Math.Ceiling(4096f / blocksPerWord); Log.Debug($"New section {chunkIndex}, " + $"version={version}, " + $"storageSize={storageSize}, " + $"storageIndex={storageIndex}, " + $"bitsPerBlock={bitsPerBlock}, " + $"noBlocksPerWord={blocksPerWord}, " + $"wordCount={wordsPerChunk}, " + $""); long jumpPos = stream.Position; stream.Seek(wordsPerChunk * 4, SeekOrigin.Current); int paletteCount = VarInt.ReadSInt32(stream); var palette = new int[paletteCount]; for (int j = 0; j < paletteCount; j++) { int runtimeId = VarInt.ReadSInt32(stream); if (bedrockPalette == null || internalBlockPallet == null) { continue; } palette[j] = GetServerRuntimeId(bedrockPalette, internalBlockPallet, runtimeId); } long afterPos = stream.Position; stream.Position = jumpPos; int position = 0; for (int w = 0; w < wordsPerChunk; w++) { uint word = defStream.ReadUInt32(); for (int block = 0; block < blocksPerWord; block++) { if (position >= 4096) { continue; } uint state = (uint)((word >> ((position % blocksPerWord) * bitsPerBlock)) & ((1 << bitsPerBlock) - 1)); int x = (position >> 8) & 0xF; int y = position & 0xF; int z = (position >> 4) & 0xF; int runtimeId = palette[state]; if (storageIndex == 0) { subChunk.SetBlockByRuntimeId(x, y, z, (int)runtimeId); } else { subChunk.SetLoggedBlockByRuntimeId(x, y, z, (int)runtimeId); } position++; } } stream.Position = afterPos; } } if (defStream.Read(chunkColumn.biomeId, 0, 256) != 256) { Log.Error($"Out of data biomeId"); } //Log.Debug($"biomeId:\n{Package.HexDump(chunk.biomeId)}"); //if (stream.Position >= stream.Length - 1) return chunkColumn; int borderBlock = VarInt.ReadSInt32(stream); if (borderBlock != 0) { byte[] buf = new byte[borderBlock]; int len = defStream.Read(buf, 0, borderBlock); Log.Warn($"??? Got borderblock {borderBlock}. Read {len} bytes"); Log.Debug($"{Packet.HexDump(buf)}"); for (int i = 0; i < borderBlock; i++) { int x = (buf[i] & 0xf0) >> 4; int z = buf[i] & 0x0f; Log.Debug($"x={x}, z={z}"); } } if (stream.Position < stream.Length - 1) { while (stream.Position < stream.Length) { NbtFile file = new NbtFile() { BigEndian = false, UseVarInt = true }; file.LoadFromStream(stream, NbtCompression.None); var blockEntityTag = file.RootTag; if (blockEntityTag.Name != "alex") { int x = blockEntityTag["x"].IntValue; int y = blockEntityTag["y"].IntValue; int z = blockEntityTag["z"].IntValue; chunkColumn.SetBlockEntity(new BlockCoordinates(x, y, z), (NbtCompound)file.RootTag); Log.Debug($"Blockentity:\n{file.RootTag}"); } } } if (stream.Position < stream.Length - 1) { Log.Warn($"Still have data to read\n{Packet.HexDump(defStream.ReadBytes((int) (stream.Length - stream.Position)))}"); } return(chunkColumn); } } }
public void FillBlockLevel(BlockState block, int y) { _blocks.Slice(y * LevelBlockCount, LevelBlockCount).Fill(BlockPalette.IdForBlock(block)); IsEmpty = false; }
private static void CreateBlock(Vector3 position, SubChunk chunk) { // subChunk index in the Chunk itself. [0, 15] int subChunkId = chunk.SubChunkId; // Position as integer. int x = (int)position.x; int y = (int)position.y; int z = (int)position.z; // False if there is a block next to those faces. bool left, right, top, bottom, front, back; top = y != 15 ? chunk.GetBlock(x, y + 1, z) == -1 : true; bottom = y != 0 ? chunk.GetBlock(x, y - 1, z) == -1 : true; left = x != 0 ? chunk.GetBlock(x - 1, y, z) == -1 : true; right = x != 15 ? chunk.GetBlock(x + 1, y, z) == -1 : true; front = z != 15 ? chunk.GetBlock(x, y, z + 1) == -1 : true; back = z != 0 ? chunk.GetBlock(x, y, z - 1) == -1 : true; // If the block is completly surrounded(not seen). if (left && right && top && bottom && front && back) { return; } // Should draw faces? except chunk borders. bool leftChunk = true; bool rightChunk = true; bool backChunk = true; bool frontChunk = true; if (x == 0) { leftChunk = chunk.Chunk.ChunkLeft.GetSubChunk(subChunkId).GetBlock(15, y, z) == -1; } if (x == 15) { rightChunk = chunk.Chunk.ChunkRight.GetSubChunk(subChunkId).GetBlock(0, y, z) == -1; } if (z == 0) { backChunk = chunk.Chunk.ChunkBack.GetSubChunk(subChunkId).GetBlock(x, y, 15) == -1; } if (z == 15) { frontChunk = chunk.Chunk.ChunkFront.GetSubChunk(subChunkId).GetBlock(x, y, 0) == -1; } // Check if there is a block in the above subchunk. // Dont check if the subchunk is the bottom or top one. bool topChunk = true; bool bottomChunk = true; if (subChunkId != 15) { SubChunk topSubChunk = chunk.Chunk.GetSubChunk(subChunkId + 1); if (topSubChunk.isFull()) { topChunk = true; } else { topChunk = topSubChunk.GetBlock(x, 0, z) == -1; } } if (subChunkId != 0) { SubChunk botSubChunk = chunk.Chunk.GetSubChunk(subChunkId - 1); if (botSubChunk.isFull()) { bottomChunk = false; } else { bottomChunk = botSubChunk.GetBlock(x, 15, z) == -1; } } // False if should not render chunk border faces. bool topBorder = y == 15 ? chunk.RenderTop && topChunk : top; bool bottomBorder = y == 0 ? chunk.RenderBottom && bottomChunk : bottom; bool leftBorder = x == 0 ? chunk.RenderLeft && leftChunk : left; bool rightBorder = x == 15 ? chunk.RenderRight && rightChunk : right; bool frontBorder = z == 15 ? chunk.RenderFront && frontChunk : front; bool backBorder = z == 0 ? chunk.RenderBack && backChunk : back; // Display the chunk in green if chunk is surrounded. int gx = (int)(chunk.Chunk.Position.x * 16) + x; int gz = (int)(chunk.Chunk.Position.y * 16) + z; CurrentColor = BlockPalette.GetColor((BLOCK_TYPE)chunk.GetBlock(x, y, z), gx, gz); // Represent each faces of a cube and if it should place // each faces. Placed in the same order in CUBE_FACES enum. bool[] lutFaces = { topBorder, bottomBorder, leftBorder, rightBorder, frontBorder, backBorder }; for (int i = 0; i < 6; i++) { if (lutFaces[i] == true) { CreateFace(i, position); } } }
static BlockFactory() { for (int i = 0; i < byte.MaxValue * 2; i++) { var block = GetBlockById(i); if (block != null) { if (block.IsTransparent) { TransparentBlocks[block.Id] = 1; } if (block.LightLevel > 0) { LuminousBlocks[block.Id] = (byte)block.LightLevel; } } } NameToId = BuildNameToId(); for (int i = 0; i < LegacyToRuntimeId.Length; ++i) { LegacyToRuntimeId[i] = -1; } var assembly = Assembly.GetAssembly(typeof(Block)); lock (lockObj) { Dictionary <string, int> idMapping = new Dictionary <string, int>(ResourceUtil.ReadResource <Dictionary <string, int> >("block_id_map.json", typeof(Block), "Data"), StringComparer.OrdinalIgnoreCase); int runtimeId = 0; BlockPalette = new BlockPalette(); using (var stream = assembly.GetManifestResourceStream(typeof(Block).Namespace + ".Data.canonical_block_states.nbt")) { do { var compound = Packet.ReadNbtCompound(stream, true); var container = GetBlockStateContainer(compound); container.RuntimeId = runtimeId++; BlockPalette.Add(container); } while (stream.Position < stream.Length); } List <R12ToCurrentBlockMapEntry> legacyStateMap = new List <R12ToCurrentBlockMapEntry>(); using (var stream = assembly.GetManifestResourceStream(typeof(Block).Namespace + ".Data.r12_to_current_block_map.bin")) { while (stream.Position < stream.Length) { var length = VarInt.ReadUInt32(stream); byte[] bytes = new byte[length]; stream.Read(bytes, 0, bytes.Length); string stringId = Encoding.UTF8.GetString(bytes); bytes = new byte[2]; stream.Read(bytes, 0, bytes.Length); var meta = BitConverter.ToInt16(bytes); var compound = Packet.ReadNbtCompound(stream, true); legacyStateMap.Add(new R12ToCurrentBlockMapEntry(stringId, meta, GetBlockStateContainer(compound))); } } Dictionary <string, List <int> > idToStatesMap = new Dictionary <string, List <int> >(StringComparer.OrdinalIgnoreCase); for (var index = 0; index < BlockPalette.Count; index++) { var state = BlockPalette[index]; List <int> candidates; if (!idToStatesMap.TryGetValue(state.Name, out candidates)) { candidates = new List <int>(); } candidates.Add(index); idToStatesMap[state.Name] = candidates; } foreach (var pair in legacyStateMap) { if (!idMapping.TryGetValue(pair.StringId, out int id)) { continue; } var data = pair.Meta; if (data > 15) { continue; } var mappedState = pair.State; var mappedName = pair.State.Name; if (!idToStatesMap.TryGetValue(mappedName, out var matching)) { continue; } foreach (var match in matching) { var networkState = BlockPalette[match]; var thisStates = new HashSet <IBlockState>(mappedState.States); var otherStates = new HashSet <IBlockState>(networkState.States); otherStates.IntersectWith(thisStates); if (otherStates.Count == thisStates.Count) { BlockPalette[match].Id = id; BlockPalette[match].Data = data; BlockPalette[match].ItemInstance = new ItemPickInstance() { Id = (short)id, Metadata = data, WantNbt = false }; LegacyToRuntimeId[(id << 4) | (byte)data] = match; break; } } } foreach (var record in BlockPalette) { var states = new List <NbtTag>(); foreach (IBlockState state in record.States) { NbtTag stateTag = null; switch (state) { case BlockStateByte blockStateByte: stateTag = new NbtByte(state.Name, blockStateByte.Value); break; case BlockStateInt blockStateInt: stateTag = new NbtInt(state.Name, blockStateInt.Value); break; case BlockStateString blockStateString: stateTag = new NbtString(state.Name, blockStateString.Value); break; default: throw new ArgumentOutOfRangeException(nameof(state)); } states.Add(stateTag); } var nbt = new NbtFile() { BigEndian = false, UseVarInt = true, RootTag = new NbtCompound("states", states) }; byte[] nbtBinary = nbt.SaveToBuffer(NbtCompression.None); record.StatesCacheNbt = nbtBinary; } } BlockStates = new HashSet <BlockStateContainer>(BlockPalette); }
public void Throw(string fireMode, bool rotate45, BlockPalette blockPalette) { if (fireMode.Equals("tetromino")) { toSpawn = tetrominoObjects[Random.Range(0, 7)]; } else if (fireMode.Equals("tromino")) { toSpawn = trominoObjects[Random.Range(0, 2)]; } else if (fireMode.Equals("pentomino")) { toSpawn = pentominoObjects[Random.Range(0, 18)]; } else if (fireMode.Equals("tiny")) { toSpawn = tinyBlockObjects[Random.Range(0, 2)]; } else if (fireMode.Equals("all")) { int set = Random.Range(0, 3); if (set == 0) { toSpawn = tetrominoObjects[Random.Range(0, 7)]; } else if (set == 1) { toSpawn = trominoObjects[Random.Range(0, 2)]; } else if (set == 2) { toSpawn = pentominoObjects[Random.Range(0, 18)]; } } else if (fireMode.Equals("warped")) { toSpawn = warpedObjects[Random.Range(0, 17)]; } else if (fireMode.Equals("university")) { toSpawn = octominoF; } //how fast? float xtraj = Random.Range(-trajectoryRandomFactor, trajectoryRandomFactor); float ytraj = Random.Range(-trajectoryRandomFactor, trajectoryRandomFactor); Vector3 trajectory = new Vector3(baseTrajectory.x + xtraj, baseTrajectory.y + ytraj, 0); //what color? Color colour = blockPalette.palette[Random.Range(0, 8)]; //how much rotation? float rotation = 90f * (Mathf.Floor(Random.Range(0, 4))); // optional mode modifier if (rotate45) { rotation += 45f; } chuckerBlocked = AmIBlocked(); //check the surroundings to ensure you can fire without overlapping somethign else if (!chuckerBlocked) { GameObject tetrominoClone = (GameObject)Instantiate(toSpawn, transform.position, transform.rotation); tetrominoClone.GetComponent <Rigidbody2D>().AddForce(trajectory, ForceMode2D.Impulse); //tetrominoClone.GetComponent<Rigidbody2D>().AddTorque(rot); tetrominoClone.GetComponent <SpriteRenderer>().color = colour; Quaternion finalRotation = Quaternion.Euler(0, 0, rotation); //finalRotation.z = rotation; tetrominoClone.transform.rotation = finalRotation; } else { Debug.Log(gameObject.name + " was blocked from throwing."); } }
public void GeneratePartialBlocksFromBlockstates() { BlockPalette blockPalette = BlockFactory.BlockPalette; string fileName = Path.GetTempPath() + "MissingBlocks_" + Guid.NewGuid() + ".txt"; using (FileStream file = File.OpenWrite(fileName)) { var blocks = new List <(int, string)>(); var writer = new IndentedTextWriter(new StreamWriter(file)); Console.WriteLine($"Directory:\n{Path.GetTempPath()}"); Console.WriteLine($"Filename:\n{fileName}"); Log.Warn($"Writing blocks to filename:\n{fileName}"); writer.WriteLine($"namespace MiNET.Blocks"); writer.WriteLine($"{{"); writer.Indent++; foreach (IGrouping <string, BlockStateContainer> blockstateGrouping in blockPalette.OrderBy(record => record.Name).ThenBy(record => record.Data).GroupBy(record => record.Name)) { var currentBlockState = blockstateGrouping.First(); var defaultBlockState = blockstateGrouping.FirstOrDefault(bs => bs.Data == 0); Log.Debug($"{currentBlockState.RuntimeId}, {currentBlockState.Name}, {currentBlockState.Data}"); Block blockById = BlockFactory.GetBlockById(currentBlockState.Id); bool existingBlock = blockById.GetType() != typeof(Block) && !blockById.IsGenerated; int id = existingBlock ? currentBlockState.Id : -1; string blockClassName = CodeName(currentBlockState.Name.Replace("minecraft:", ""), true); blocks.Add((blockById.Id, blockClassName)); writer.WriteLineNoTabs($""); writer.WriteLine($"public partial class {blockClassName} {(existingBlock ? "" : ": Block")} // {blockById.Id} typeof={blockById.GetType().Name}"); writer.WriteLine($"{{"); writer.Indent++; var bits = new List <BlockStateByte>(); foreach (var state in blockstateGrouping.First().States) { var q = blockstateGrouping.SelectMany(c => c.States); // If this is on base, skip this property. We need this to implement common functionality. Type baseType = blockById.GetType().BaseType; bool propOverride = baseType != null && ("Block" != baseType.Name && baseType.GetProperty(CodeName(state.Name, true)) != null); switch (state) { case BlockStateByte blockStateByte: { var values = q.Where(s => s.Name == state.Name).Select(d => ((BlockStateByte)d).Value).Distinct().OrderBy(s => s).ToList(); byte defaultVal = ((BlockStateByte)defaultBlockState?.States.First(s => s.Name == state.Name))?.Value ?? 0; if (values.Min() == 0 && values.Max() == 1) { bits.Add(blockStateByte); writer.Write($"[StateBit] "); writer.WriteLine($"public {(propOverride ? "override" : "")} bool {CodeName(state.Name, true)} {{ get; set; }} = {(defaultVal == 1 ? "true" : "false")};"); } else { writer.Write($"[StateRange({values.Min()}, {values.Max()})] "); writer.WriteLine($"public {(propOverride ? "override" : "")} byte {CodeName(state.Name, true)} {{ get; set; }} = {defaultVal};"); } break; } case BlockStateInt blockStateInt: { var values = q.Where(s => s.Name == state.Name).Select(d => ((BlockStateInt)d).Value).Distinct().OrderBy(s => s).ToList(); int defaultVal = ((BlockStateInt)defaultBlockState?.States.First(s => s.Name == state.Name))?.Value ?? 0; writer.Write($"[StateRange({values.Min()}, {values.Max()})] "); writer.WriteLine($"public {(propOverride ? "override" : "")} int {CodeName(state.Name, true)} {{ get; set; }} = {defaultVal};"); break; } case BlockStateString blockStateString: { var values = q.Where(s => s.Name == state.Name).Select(d => ((BlockStateString)d).Value).Distinct().ToList(); string defaultVal = ((BlockStateString)defaultBlockState?.States.First(s => s.Name == state.Name))?.Value ?? ""; if (values.Count > 1) { writer.WriteLine($"[StateEnum({string.Join(',', values.Select(v => $"\"{v}\""))})]"); } writer.WriteLine($"public {(propOverride ? "override" : "")} string {CodeName(state.Name, true)} {{ get; set; }} = \"{defaultVal}\";"); break; } default: throw new ArgumentOutOfRangeException(nameof(state)); } } if (id == -1 || blockById.IsGenerated) { writer.WriteLine($""); writer.WriteLine($"public {blockClassName}() : base({currentBlockState.Id})"); writer.WriteLine($"{{"); writer.Indent++; writer.WriteLine($"IsGenerated = true;"); writer.Indent--; writer.WriteLine($"}}"); } writer.WriteLineNoTabs($""); writer.WriteLine($"public override void SetState(List<IBlockState> states)"); writer.WriteLine($"{{"); writer.Indent++; writer.WriteLine($"foreach (var state in states)"); writer.WriteLine($"{{"); writer.Indent++; writer.WriteLine($"switch(state)"); writer.WriteLine($"{{"); writer.Indent++; foreach (var state in blockstateGrouping.First().States) { writer.WriteLine($"case {state.GetType().Name} s when s.Name == \"{state.Name}\":"); writer.Indent++; writer.WriteLine($"{CodeName(state.Name, true)} = {(bits.Contains(state) ? "Convert.ToBoolean(s.Value)" : "s.Value")};"); writer.WriteLine($"break;"); writer.Indent--; } writer.Indent--; writer.WriteLine($"}} // switch"); writer.Indent--; writer.WriteLine($"}} // foreach"); writer.Indent--; writer.WriteLine($"}} // method"); writer.WriteLineNoTabs($""); writer.WriteLine($"public override BlockStateContainer GetState()"); writer.WriteLine($"{{"); writer.Indent++; writer.WriteLine($"var record = new BlockStateContainer();"); writer.WriteLine($"record.Name = \"{blockstateGrouping.First().Name}\";"); writer.WriteLine($"record.Id = {blockstateGrouping.First().Id};"); foreach (var state in blockstateGrouping.First().States) { string propName = CodeName(state.Name, true); writer.WriteLine($"record.States.Add(new {state.GetType().Name} {{Name = \"{state.Name}\", Value = {(bits.Contains(state) ? $"Convert.ToByte({propName})" : propName)}}});"); } writer.WriteLine($"return record;"); writer.Indent--; writer.WriteLine($"}} // method"); //writer.WriteLine($""); //writer.WriteLine($"public byte GetMetadataFromState()"); //writer.WriteLine($"{{"); //writer.Indent++; //writer.WriteLine($"switch(this)"); //writer.WriteLine($"{{"); //writer.Indent++; //i = 0; //foreach (var record in message.BlockPalette.Where(b => b.Id == enumerator.Current.Id).OrderBy(b => b.Data)) //{ // //case { } b when b.ButtonPressedBit == 0 && b.FacingDirection == 0: // // return 0; // writer.Write($"case {{ }} b when true"); // string retVal = ""; // foreach (var state in record.States.OrderBy(s => s.Name).ThenBy(s => s.Value)) // { // if (state.Type == (byte) NbtTagType.Byte) // { // writer.Write($" && b.{Client.CodeName(state.Name, true)} == {state.Value}"); // } // else if (state.Type == (byte) NbtTagType.Int) // { // writer.Write($" && b.{Client.CodeName(state.Name, true)} == {state.Value}"); // } // else if (state.Type == (byte) NbtTagType.String) // { // writer.Write($" && b.{Client.CodeName(state.Name, true)} == \"{state.Value}\""); // } // } // writer.WriteLine($":"); // writer.Indent++; // writer.WriteLine($"return { i++ };"); // writer.Indent--; //} //writer.Indent--; //writer.WriteLine($"}} // switch"); //writer.WriteLine($"throw new ArithmeticException(\"Invalid state. Unable to convert state to valid metadata\");"); //writer.Indent--; //writer.WriteLine($"}} // method"); writer.Indent--; writer.WriteLine($"}} // class"); } writer.Indent--; writer.WriteLine($"}}"); foreach (var block in blocks.OrderBy(tuple => tuple.Item1)) { writer.WriteLine($"else if (blockId == {block.Item1}) block = new {block.Item2}();"); } writer.Flush(); } }
public void SetBlock(BlockState block, int index) { _blocks[index] = BlockPalette.IdForBlock(block); IsEmpty = false; }