private string GetWoodBlock(BlockStateContainer record) { string type = "oak"; bool stripped = false; string axis = "y"; foreach (var state in record.States) { switch (state.Name) { case "wood_type": type = state.Value(); break; case "stripped_bit": stripped = state.Value() == "1"; break; case "pillar_axis": axis = state.Value(); break; } } string result = $"{type}_log"; if (stripped) { result = "stripped_" + result; } return($"minecraft:{result}"); }
} // method public override BlockStateContainer GetState() { var record = new BlockStateContainer(); record.Name = "minecraft:chalkboard"; record.Id = 230; return(record); } // method
public static Block GetBlockById(int blockId, byte metadata) { int runtimeId = (int)GetRuntimeId(blockId, metadata); BlockStateContainer blockState = BlockPalette[runtimeId]; Block block = GetBlockById(blockState.Id); block.SetState(blockState.States); return(block); }
private static BlockStateContainer GetBlockStateContainer(NbtTag tag) { var record = new BlockStateContainer(); string name = tag["name"].StringValue; record.Name = name; record.States = GetBlockStates(tag); return(record); }
public virtual BlockStateContainer GetGlobalState() { BlockStateContainer currentState = GetState(); if (!BlockFactory.BlockStates.TryGetValue(currentState, out var blockstate)) { Log.Warn($"Did not find block state for {this}, {currentState}"); return(null); } return(blockstate); }
public int GetRuntimeId() { BlockStateContainer currentState = GetState(); if (!BlockFactory.BlockStates.TryGetValue(currentState, out var blockstate)) { Log.Warn($"Did not find block state for {this}, {currentState}"); return(-1); } return(blockstate.RuntimeId); }
public void GetItemFromBlockStateTest() { // Picked block minecraft:cobblestone_wall from blockstate 3313 int runtimeId = 3313; BlockStateContainer blocStateFromPick = BlockFactory.BlockPalette[runtimeId]; var block = BlockFactory.GetBlockById(blocStateFromPick.Id) as CobblestoneWall; Assert.IsNotNull(block); block.SetState(blocStateFromPick.States); Item item = block.GetItem(); Assert.AreEqual("minecraft:cobblestone_wall", item.Name); Assert.AreEqual(139, item.Id); Assert.AreEqual(12, item.Metadata); }
private string BlockStateToString(BlockStateContainer record) { StringBuilder sb = new StringBuilder(); sb.Append($"{record.Name}["); foreach (var state in record.States) { sb.Append($"{state.Name}={state.Value()},"); } sb.Append("]"); return(sb.ToString()); }
public void GetItemFromBlockStateTest() { // Picked block minecraft:chain from blockstate 917 int runtimeId = 917; BlockStateContainer blocStateFromPick = BlockFactory.BlockPalette[runtimeId]; var block = BlockFactory.GetBlockById(blocStateFromPick.Id) as Chain; Assert.IsNotNull(block); block.SetState(blocStateFromPick.States); Item item = block.GetItem(); Assert.AreEqual("minecraft:chain", item.Name); Assert.AreEqual(758, item.Id); Assert.AreEqual(0, item.Metadata); }
public Block GetBlockObject(int bx, int @by, int bz) { if (_runtimeIds.Count == 0) { return(new Air()); } int index = _blocks[GetIndex(bx, by, bz)]; int runtimeId = _runtimeIds[index]; BlockStateContainer blockState = BlockFactory.BlockPalette[runtimeId]; Block block = BlockFactory.GetBlockById(blockState.Id); block.SetState(blockState.States); block.Metadata = (byte)blockState.Data; //TODO: REMOVE metadata. Not needed. return(block); }
public void GetDoorItemFromBlockStateTest() { // Picked block minecraft:dark_oak_door from blockstate 4003. Expected block to be in slot 9 // Picked block minecraft:dark_oak_door from blockstate 3991. Expected block to be in slot 9 int runtimeId = 3991; BlockStateContainer blocStateFromPick = BlockFactory.BlockPalette[runtimeId]; var block = BlockFactory.GetBlockById(blocStateFromPick.Id) as DarkOakDoor; Assert.IsNotNull(block); block.SetState(blocStateFromPick.States); ItemBlock item = block.GetItem() as ItemBlock; Assert.IsNotNull(item, "Found no item"); Assert.IsNotNull(item.Block); Assert.AreEqual("minecraft:dark_oak_door", item.Name); Assert.AreEqual(431, item.Id); Assert.AreEqual(0, item.Metadata); }
public BlockPalette ReadAlternateBlockPalette() { var result = new BlockPalette(); uint count = ReadUnsignedVarInt(); //Log.Info($"Block count startgame: {count}"); for (int runtimeId = 0; runtimeId < count; runtimeId++) { var record = new BlockStateContainer(); record.RuntimeId = runtimeId; record.Id = record.RuntimeId; record.Name = ReadString(); record.States = new List<IBlockState>(); var nbt = NetworkUtils.ReadNewNbt(_reader); var rootTag = nbt.NbtFile.RootTag; if (rootTag is NbtList nbtList) { foreach (NbtTag tag in nbtList) { var s = tag["states"]; if (s is NbtCompound compound) { foreach (NbtTag stateTag in compound) { IBlockState state = null; switch (stateTag.TagType) { case NbtTagType.Byte: state = new BlockStateByte() {Name = stateTag.Name, Value = stateTag.ByteValue}; break; case NbtTagType.Int: state = new BlockStateInt() {Name = stateTag.Name, Value = stateTag.IntValue}; break; case NbtTagType.String: state = new BlockStateString() { Name = stateTag.Name, Value = stateTag.StringValue }; break; default: throw new ArgumentOutOfRangeException(); } record.States.Add(state); } } else if (s is NbtList list) { foreach (NbtTag stateTag in list) { IBlockState state = null; switch (stateTag.TagType) { case NbtTagType.Byte: state = new BlockStateByte() {Name = stateTag.Name, Value = stateTag.ByteValue}; break; case NbtTagType.Int: state = new BlockStateInt() {Name = stateTag.Name, Value = stateTag.IntValue}; break; case NbtTagType.String: state = new BlockStateString() { Name = stateTag.Name, Value = stateTag.StringValue }; break; default: throw new ArgumentOutOfRangeException(); } record.States.Add(state); } } result.Add(record); } } else if (rootTag is NbtCompound c) { foreach (NbtTag tag in c) { var s = tag["states"]; if (s is NbtCompound compound) { foreach (NbtTag stateTag in compound) { IBlockState state = null; switch (stateTag.TagType) { case NbtTagType.Byte: state = new BlockStateByte() { Name = stateTag.Name, Value = stateTag.ByteValue }; break; case NbtTagType.Int: state = new BlockStateInt() { Name = stateTag.Name, Value = stateTag.IntValue }; break; case NbtTagType.String: state = new BlockStateString() { Name = stateTag.Name, Value = stateTag.StringValue }; break; default: throw new ArgumentOutOfRangeException(); } record.States.Add(state); } } else if (s is NbtList list) { foreach (NbtTag stateTag in list) { IBlockState state = null; switch (stateTag.TagType) { case NbtTagType.Byte: state = new BlockStateByte() { Name = stateTag.Name, Value = stateTag.ByteValue }; break; case NbtTagType.Int: state = new BlockStateInt() { Name = stateTag.Name, Value = stateTag.IntValue }; break; case NbtTagType.String: state = new BlockStateString() { Name = stateTag.Name, Value = stateTag.StringValue }; break; default: throw new ArgumentOutOfRangeException(); } record.States.Add(state); } } result.Add(record); } } } return result; }
private void HandleMcpeUpdateBlock(BedrockTraceHandler caller, McpeUpdateBlock message) { //if (message.OrderingIndex <= lastNumber) return; //lastNumber = message.OrderingIndex; if (message.storage != 0) { return; } if (message.blockPriority != 3) { return; } if (!_runningBlockMetadataDiscovery) { _resetEventUpdateBlock.Set(); return; } int runtimeId = (int)message.blockRuntimeId; int bid = message.coordinates.X / 2; int meta = (message.coordinates.Y - 100) / 2; //TODO: Fix for doors and beds. They get 2 updates. BlockStateContainer blockstate = caller.Client.BlockPalette[runtimeId]; if (message.coordinates.X % 2 != 0 || message.coordinates.Y % 2 != 0) { Log.Warn($"Update block outside of grid {message.coordinates}, {caller.Client.BlockPalette[runtimeId]}"); if (blockstate.Name.EndsWith("_door")) { if (blockstate.States.First(s => s.Name.Equals("upper_block_bit") && ((BlockStateInt)s).Value == 1) != null) { blockstate.Data = (short)meta; } } else if (blockstate.Name.Equals("minecraft:bed")) { if (blockstate.States.First(s => s.Name.Equals("head_piece_bit") && ((BlockStateInt)s).Value == 0) != null) { blockstate.Data = (short)meta; } } return; } if (blockstate.Id == 0) { return; } if (blockstate.Data == -1) { lock (_lastUpdatedBlockstate) { try { if (bid != blockstate.Id) { Log.Warn($"Wrong id. Expected {blockstate.Id}, got {bid}"); } else { blockstate.Data = (short)meta; Log.Debug($"Correct id. Expected {blockstate.Id}, and got {bid}"); } Log.Debug($"Block update {bid}, {meta}, with blockstate\n{blockstate}"); } finally { Log.Warn($"Got {blockstate.Id}, {meta} storage {message.storage}, {message.blockPriority}"); _lastUpdatedBlockstate = blockstate; _resetEventUpdateBlock.Set(); } } } else { Log.Warn($"Blockstate {runtimeId} {blockstate.Id}, {meta} already had meta set to {blockstate.Data}"); } }
private ChunkSection(BlockStateContainer blockContainer, BiomeContainer biomeContainer, int?yBase) { BlockStateContainer = blockContainer; BiomeContainer = biomeContainer; YBase = yBase; }
public ChunkSection Clone() { return(new ChunkSection(BlockStateContainer.Clone(), BiomeContainer.Clone(), YBase)); }
public virtual void SetState(BlockStateContainer blockstate) { SetState(blockstate.States); }
public R12ToCurrentBlockMapEntry(string id, short meta, BlockStateContainer state) { StringId = id; Meta = meta; State = state; }
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 bool TryConvertBlockState(BlockStateContainer record, out BlockState result) { if (_convertedStates.TryGetValue((uint)record.RuntimeId, out var alreadyConverted)) { result = alreadyConverted; return(true); } result = null; string searchName = record.Name; switch (record.Name) { case "minecraft:torch": if (record.States.Any(x => x.Name.Equals("torch_facing_direction") && x.Value() != "top")) { searchName = "minecraft:wall_torch"; } break; case "minecraft:unlit_redstone_torch": case "minecraft:redstone_torch": if (record.States.Any(x => x.Name.Equals("torch_facing_direction") && x.Value() != "top")) { searchName = "minecraft:redstone_wall_torch"; } break; case "minecraft:flowing_water": searchName = "minecraft:water"; break; case "minecraft:wood": searchName = GetWoodBlock(record); break; case "minecraft:tallgrass": searchName = "minecraft:tall_grass"; break; } string prefix = ""; foreach (var state in record.States.ToArray()) { switch (state.Name) { case "stone_type": switch (state.Value()) { case "granite": case "diorite": case "andesite": searchName = $"minecraft:{state.Value()}"; break; case "granite_smooth": case "diorite_smooth": case "andesite_smooth": var split = state.Value().Split('_'); searchName = $"minecraft:polished_{split[0]}"; break; } break; case "old_log_type": { searchName = $"minecraft:{state.Value()}_log"; } break; case "old_leaf_type": searchName = $"minecraft:{state.Value()}_leaves"; break; case "wood_type": switch (record.Name.ToLower()) { case "minecraft:fence": searchName = $"minecraft:{state.Value()}_fence"; break; case "minecraft:planks": searchName = $"minecraft:{state.Value()}_planks"; break; case "minecraft:wooden_slab": searchName = $"minecraft:{state.Value()}_slab"; break; // case "minecraft:wood": // searchName = $"minecraft:{state.Value}_log"; // break; } break; case "sapling_type": //case "old_log_type": // case "old_leaf_type": searchName = $"minecraft:{state.Value()}_sapling"; //prefix = "_"; break; case "flower_type": searchName = $"minecraft:{state.Value()}"; break; case "double_plant_type": switch (state.Value()) { case "grass": searchName = "minecraft:tall_grass"; break; case "sunflower": searchName = "minecraft:sunflower"; break; case "fern": searchName = "minecraft:large_fern"; break; case "rose": searchName = "minecraft:rose_bush"; break; case "paeonia": searchName = "minecraft:peony"; break; } break; case "color": switch (record.Name) { case "minecraft:carpet": searchName = $"minecraft:{state.Value()}_carpet"; break; case "minecraft:wool": searchName = $"minecraft:{state.Value()}_wool"; break; case "minecraft:stained_glass": searchName = $"minecraft:{state.Value()}_stained_glass"; break; case "minecraft:concrete": searchName = $"minecraft:{state.Value()}_concrete"; break; case "minecraft:stained_glass_pane": searchName = $"minecraft:{state.Value()}_stained_glass_pane"; break; } record.States.Remove(state); break; } } BlockState r; // = BlockFactory.GetBlockState(record.Name); r = BlockFactory.GetBlockState(prefix + searchName); if (r == null || r.Name == "Unknown") { r = BlockFactory.GetBlockState(searchName); } if (r == null || r.Name == "Unknown") { var mapResult = BlockFactory.RuntimeIdTable.FirstOrDefault(xx => xx.Name == searchName); if (mapResult != null && mapResult.Id >= 0) { var reverseMap = MiNET.Worlds.AnvilWorldProvider.Convert.FirstOrDefault(map => map.Value.Item1 == mapResult.Id); var id = mapResult.Id; if (reverseMap.Value != null) { id = reverseMap.Key; } var res = BlockFactory.GetBlockStateID( (int)id, (byte)record.Data); if (AnvilWorldProvider.BlockStateMapper.TryGetValue( res, out var res2)) { r = BlockFactory.GetBlockState(res2); } else { Log.Info( $"Did not find anvil statemap: {result.Name}"); r = BlockFactory.GetBlockState(mapResult.Name); } } } if (r == null || r.Name == "Unknown") { Log.Warn($"Could not translate block: {record.Name}"); return(false); } foreach (var state in record.States) { switch (state.Name) { case "direction": case "weirdo_direction": if (r.Block is FenceGate) { switch (state.Value()) { case "0": r = r.WithProperty(facing, "north"); break; case "1": r = r.WithProperty(facing, "west"); break; case "2": r = r.WithProperty(facing, "south"); break; case "3": r = r.WithProperty(facing, "east"); break; } } else { r = FixFacing(r, int.Parse(state.Value())); } break; case "upside_down_bit": r = (r).WithProperty("half", state.Value() == "1" ? "top" : "bottom"); break; case "door_hinge_bit": r = r.WithProperty("hinge", (state.Value() == "0") ? "left" : "right"); break; case "open_bit": r = r.WithProperty("open", (state.Value() == "1") ? "true" : "false"); break; case "upper_block_bit": r = r.WithProperty("half", (state.Value() == "1") ? "upper" : "lower"); break; case "torch_facing_direction": string facingValue = state.Value(); switch (facingValue) { case "north": facingValue = "south"; break; case "east": facingValue = "west"; break; case "south": facingValue = "north"; break; case "west": facingValue = "east"; break; } r = r.WithProperty("facing", facingValue); break; case "liquid_depth": r = r.WithProperty("level", state.Value()); break; case "height": r = r.WithProperty("layers", state.Value()); break; case "growth": r = r.WithProperty("age", state.Value()); break; case "button_pressed_bit": r = r.WithProperty("powered", state.Value() == "1" ? "true" : "false"); break; case "facing_direction": switch (int.Parse(state.Value())) { case 0: case 4: r = r.WithProperty(facing, "west"); break; case 1: case 5: r = r.WithProperty(facing, "east"); break; case 6: case 2: r = r.WithProperty(facing, "north"); break; case 7: case 3: r = r.WithProperty(facing, "south"); break; } break; case "head_piece_bit": r = r.WithProperty("part", state.Value() == "1" ? "head" : "foot"); break; case "pillar_axis": r = r.WithProperty("axis", state.Value()); break; case "top_slot_bit": r = r.WithProperty("type", state.Value() == "1" ? "top" : "bottom", true); break; case "moisturized_amount": r = r.WithProperty("moisture", state.Value()); break; case "age": r = r.WithProperty("age", state.Value()); break; default: // Log.Info($"Unknown property for {record.Name}: {state.Name} - {state.Value()}"); // r = r.WithProperty(state.Name, state.Value()); break; } } if (record.Name.Equals("minecraft:unlit_redstone_torch")) { r = r.WithProperty("lit", "false"); } result = r; return(true); }
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); }
public Block Next(BlockCoordinates position) { BlockDataEntry blockEntry = GetRandomBlock(_random, BlockList); Block block; if (blockEntry.HasMetadata) { block = BlockFactory.GetBlockById(blockEntry.Id, blockEntry.Metadata); } else { block = BlockFactory.GetBlockById(blockEntry.Id); if (blockEntry.HasBlockStates) { BlockStateContainer currentStates = block.GetState(); foreach (BlockStateEntry stateEntry in blockEntry.BlockStates) { IBlockState state = currentStates.States.FirstOrDefault(s => s.Name == stateEntry.Name); if (state == null) { continue; } switch (state) { case BlockStateByte s: { if (byte.TryParse(stateEntry.Value, out byte v)) { s.Value = v; } break; } case BlockStateInt s: { if (int.TryParse(stateEntry.Value, out int v)) { s.Value = v; } break; } case BlockStateString s: { s.Value = stateEntry.Value; break; } } } block.SetState(currentStates); } } block ??= new Air(); block.Coordinates = position; return(block); }