Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion Maploader/Renderer/ChunkRenderer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,8 @@ public void RenderChunk(TImage dest, Chunk c, int xOffset, int zOffset)
textureFinder.FindTexturePath(block.Block.Id, block.Block.Data, block.X, block.Z, block.Y);
if (textures == null)
{
Console.WriteLine($"Missing Texture(2): {block.ToString().PadRight(30)}");
Console.WriteLine($"\r\nMissing Texture(2): {block.ToString().PadRight(30)}");
Console.WriteLine("\tin " + c);
MissingTextures.Add($"ID: {block.Block.Id}");
continue;
}
Expand Down
105 changes: 69 additions & 36 deletions Maploader/Renderer/Texture/TextureFinder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,10 @@ public class TextureFinder<TImage> where TImage : class
{"minecraft:red_candle", true},
{"minecraft:black_candle", true},
{"minecraft:spore_blossom", true},

// Special cases
{"minecraft:invisibleBedrock", true},
{"minecraft:movingBlock", true},

// 1.19
{"minecraft:mangrove_propagule", true},
Expand Down Expand Up @@ -280,15 +284,24 @@ public TextureStack FindTexturePath(string name, Dictionary<string, Object> data
{
name = name.Replace("minecraft:", "");

var newTexture = GetSubstitution(name, data, x, z, y);

if (newTexture != null)
try
{
return newTexture;
var newTexture = GetSubstitution(name, data, x, z, y);
if (newTexture != null)
{
return newTexture;
}
if (texturesJson.ContainsKey(name))
{
return GetTexture(name, data);
}
}
if (texturesJson.ContainsKey(name))
catch (Exception ex)
{
return GetTexture(name, data);
Console.WriteLine("Error getting texture for:");
String datastring = string.Join(", ", data.Select(kvp => kvp.Key + ": " + kvp.Value.ToString()));
Console.WriteLine($"{x} {z} {y}: {name}, {datastring}");
Console.WriteLine("Error: " + ex);
}
return null;

Expand Down Expand Up @@ -335,7 +348,7 @@ private TextureStack GetSubstitution(string name, Dictionary<string, Object> dat
{
// TODO: fix bed colours
int headBit = (int)data.GetValueOrDefault("head_piece_bit", 0);
RotateFlip rot = RotateFromDirection(((int)data["direction"] + 3) % 4);
RotateFlip rot = data.ContainsKey("direction") ? RotateFromDirection(((int)data["direction"] + 3) % 4) : 0;
return CreateTexture(headBit != 0
? "textures/blocks/bed_head_top"
: "textures/blocks/bed_feet_top")
Expand All @@ -346,7 +359,7 @@ private TextureStack GetSubstitution(string name, Dictionary<string, Object> dat
case "wooden_slab":
case "double_wooden_slab":
{
int plankIndex = WoodIndexes[(string)data.GetValueOrDefault("wood_type")];
int plankIndex = data.ContainsKey("wood_type") ? WoodIndexes[(string)data.GetValueOrDefault("wood_type")] : 0;
return GetTexture("planks", plankIndex);
}

Expand Down Expand Up @@ -452,9 +465,9 @@ private TextureStack GetSubstitution(string name, Dictionary<string, Object> dat
return RenderRail("rail_detector", "rail_detector_powered", data);

case "stonebrick":
return GetTexture("stonebrick", StoneBrickIndexes[(string)data["stone_brick_type"]]);
return GetTexture("stonebrick", data.ContainsKey("stone_brick_type") ? StoneBrickIndexes[(string)data["stone_brick_type"]] : 0);
case "monster_egg":
return GetTexture("monster_egg", MonsterEggIndexes[(string)data["monster_egg_stone_type"]]);
return GetTexture("monster_egg", data.ContainsKey("monster_egg_stone_type") ? MonsterEggIndexes[(string)data["monster_egg_stone_type"]] : 0);

case "red_mushroom_block":
return GetTexture("mushroom_red_top", data);
Expand Down Expand Up @@ -493,7 +506,8 @@ private TextureStack GetSubstitution(string name, Dictionary<string, Object> dat
return GetTexture("daylight_detector_top", 1);
case "dispenser":
{
switch ((BlockFace) data["facing_direction"])
var facingDirection = data.ContainsKey("facing_direction") ? data["facing_direction"] : BlockFace.Down;
switch ((BlockFace) facingDirection)
{
case BlockFace.Up:
return GetTexture("dispenser_front_vertical");
Expand All @@ -504,7 +518,8 @@ private TextureStack GetSubstitution(string name, Dictionary<string, Object> dat
case "observer":
{
int powered = (int)data.GetValueOrDefault("powered_bit", 0);
switch ((BlockFace) data["facing_direction"])
var facingDirection = data.ContainsKey("facing_direction") ? data["facing_direction"] : BlockFace.South;
switch ((BlockFace) facingDirection)
{
case BlockFace.Down:
return GetTexture("observer_south", powered);
Expand All @@ -523,7 +538,8 @@ private TextureStack GetSubstitution(string name, Dictionary<string, Object> dat
}
case "dropper":
{
switch ((BlockFace) data["facing_direction"])
var facingDirection = data.ContainsKey("facing_direction") ? data["facing_direction"] : BlockFace.Down;
switch ((BlockFace) facingDirection)
{
case BlockFace.Up:
return GetTexture("dropper_front_vertical");
Expand Down Expand Up @@ -558,12 +574,17 @@ private TextureStack GetSubstitution(string name, Dictionary<string, Object> dat
case "anvil":
{
int damage = 0;
switch ((string)data["damage"])
if (data.ContainsKey("damage"))
{
case "slightly_damaged":
damage = 1; break;
case "very_damaged":
damage = 2; break;
switch ((string)data["damage"])
{
case "slightly_damaged":
damage = 1;
break;
case "very_damaged":
damage = 2;
break;
}
}
return GetTexture("anvil_top_damaged_x", damage, null, RotateFromDirection(data));
}
Expand Down Expand Up @@ -621,7 +642,7 @@ private TextureStack GetSubstitution(string name, Dictionary<string, Object> dat
case "nether_brick_fence":
return RenderFence("nether_brick", data);
case "fence":
data["val"] = WoodIndexes[(string)data.GetValueOrDefault("wood_type")];
data["val"] = data.ContainsKey("wood_type") ? WoodIndexes[(string)data.GetValueOrDefault("wood_type")] : 0;
return RenderFence("planks", data);
case "podzol":
return GetTexture("dirt_podzol_top", data);
Expand Down Expand Up @@ -821,21 +842,25 @@ private TextureStack GetSubstitution(string name, Dictionary<string, Object> dat

case "stone_slab":
case "double_stone_slab":
return GetTexture("stone_slab_top", data.ContainsKey("stone_slab_type") ? StoneSlabIndexes[1][(string)data["stone_slab_type"]] : 0);
case "stone_slab2":
case "double_stone_slab2":
return GetTexture("stone_slab_top_2", data.ContainsKey("stone_slab_type_2") ? StoneSlabIndexes[2][(string)data["stone_slab_type_2"]] : 0);
case "stone_slab3":
case "double_stone_slab3":
return GetTexture("stone_slab_top_3", data.ContainsKey("stone_slab_type_3") ? StoneSlabIndexes[3][(string)data["stone_slab_type_3"]] : 0);
case "stone_slab4":
case "double_stone_slab4":
return GetTexture("stone_slab_top_4", data.ContainsKey("stone_slab_type_4") ? StoneSlabIndexes[4][(string)data["stone_slab_type_4"]] : 0);
case "stone_block_slab":
case "double_stone_block_slab":
return GetTexture("stone_slab_top", StoneSlabIndexes[1][(string)data["stone_slab_type"]]);
case "stone_slab2":
case "double_stone_slab2":
case "stone_block_slab2":
case "double_stone_block_slab2":
return GetTexture("stone_slab_top_2", StoneSlabIndexes[2][(string)data["stone_slab_type_2"]]);
case "stone_slab3":
case "double_stone_slab3":
case "stone_block_slab3":
case "double_stone_block_slab3":
return GetTexture("stone_slab_top_3", StoneSlabIndexes[3][(string)data["stone_slab_type_3"]]);
case "stone_slab4":
case "double_stone_slab4":
case "stone_block_slab4":
case "double_stone_block_slab4":
return GetTexture("stone_slab_top_4", StoneSlabIndexes[4][(string)data["stone_slab_type_4"]]);
Expand Down Expand Up @@ -926,8 +951,7 @@ private TextureStack GetSubstitution(string name, Dictionary<string, Object> dat

case "sapling":
{
int val = WoodIndexes[(string)data.GetValueOrDefault("sapling_type")];
return GetTexture("sapling", val);
return GetTexture("sapling", data.ContainsKey("sapling_type") ? WoodIndexes[(string)data.GetValueOrDefault("sapling_type")] : 0);
}

case "enchanting_table":
Expand Down Expand Up @@ -1170,7 +1194,7 @@ private TextureStack GetSubstitution(string name, Dictionary<string, Object> dat
new Rect(0, 0, 4, 11), // 11 might not be the right number
new Rect(6, 5, 4, 11));
case "sponge":
return GetTexture("sponge", (string)data["sponge_type"] == "wet" ? 1 : 0);
return GetTexture("sponge", data.ContainsKey("sponge_type") && (string)data["sponge_type"] == "wet" ? 1 : 0);
case "stone":
{
int index = StoneIndexes[(string)data.GetValueOrDefault("stone_type", "stone")];
Expand Down Expand Up @@ -1325,6 +1349,15 @@ private TextureStack GetSubstitution(string name, Dictionary<string, Object> dat
case "red_candle":
case "black_candle":
return RenderCandle(name, data);

// Special cases
// These blocks either don't strictly "exist" and are not visible,
// but they can be in the world either via commands or old Bedrock worlds
// I am using a structure_void block because it is in he default tile set
// and seems to indicate "look, something is here"
case "invisibleBedrock":
case "movingBlock":
return "textures/blocks/structure_void";

// 1.19
case "mangrove_wood":
Expand Down Expand Up @@ -1605,7 +1638,7 @@ private TextureStack RenderButton (Dictionary<string, Object> data, string textu
}
private TextureStack RenderButton(string texture, Dictionary<string, Object> data)
{
int direction = (int)data["facing_direction"];
int direction = data.ContainsKey("facing_direction") ? (int)data["facing_direction"] : 0;
var t = GetTexture(texture, 0);
int thickness = (int)data.GetValueOrDefault("button_pressed_bit", 0) == 0 ? 2 : 1;
switch (direction)
Expand Down Expand Up @@ -1643,8 +1676,8 @@ private TextureStack RenderFenceGate (Dictionary<string, Object> data, string te
}
private TextureStack RenderFenceGate (string texture, Dictionary<string, Object> data)
{
int direction = (int)data["direction"];
int open_bit = (int)data["open_bit"];
int direction = data.ContainsKey("direction") ? (int)data["direction"] : 0;
int open_bit = data.ContainsKey("open_bit") ? (int)data["open_bit"] : 0;

if (open_bit != 0)
{
Expand Down Expand Up @@ -2241,11 +2274,11 @@ private TextureStack RenderBamboo(Dictionary<string, Object> data)

private RotateFlip RotateFromDirection(Dictionary<string, Object> data, int offset)
{
return RotateFromDirection((int)data["direction"] + offset);
return RotateFromDirection(data.ContainsKey("direction") ? (int)data["direction"] + offset : offset);
}
private RotateFlip RotateFromDirection(Dictionary<string, Object> data)
{
return RotateFromDirection((int)data["direction"]);
return RotateFromDirection(data.ContainsKey("direction") ? (int)data["direction"] : 0);
}
private RotateFlip RotateFromDirection(int direction)
{
Expand Down Expand Up @@ -2390,7 +2423,7 @@ private TextureStack CreateTexture(string texturePath)
{1, new Dictionary<string, int>() {
{"smooth_stone", 0},
{"sandstone", 1},
// {"planks"?, 2},
{"wood", 2},
{"cobblestone", 3},
{"brick", 4},
{"stone_brick", 5},
Expand Down Expand Up @@ -2564,7 +2597,7 @@ private TextureStack GetTexture(string name, Dictionary<string, Object> data, Te
}
if(blockProperties.Key == "facing_direction")
{
int direction = (int)data["facing_direction"];
int direction = data.ContainsKey("facing_direction") ? (int)data["facing_direction"] : 0;
switch (direction)
{
case 2:
Expand Down Expand Up @@ -2603,4 +2636,4 @@ private int LegacyGetOldDataValue (Dictionary<string, Object> data)
return result;
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,14 @@ public CreateChunkAndRenderBlock(
var z = chunk.Z % chunksPerDimension;
if (x < 0) x += chunksPerDimension;
if (z < 0) z += chunksPerDimension;
chunkRenderer.ChunkRenderer.RenderChunk(b, chunk, x * chunkSize, z * chunkSize);
try
{
chunkRenderer.ChunkRenderer.RenderChunk(b, chunk, x * chunkSize, z * chunkSize);
}
catch (Exception ex)
{
Console.WriteLine("RenderChunk Error at " + chunkData.X + " " + chunkData.Z + " : " + ex.Message);
}

world.ChunkPool?.Return(chunk);
count++;
Expand Down
2 changes: 1 addition & 1 deletion readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ Copyright (C) 2020 Markus Jungnickel

## Building
Papyrus runs on .NET Core 3.0+.
First, make sure you have [.NET Core 3.0](https://dotnet.microsoft.com/download/dotnet-core/3.0) on your development machine.
First, make sure you have [.NET Core 3.1](https://dotnet.microsoft.com/download/dotnet-core/3.1) on your development machine.

To compile for Windows, either use a recent Visual Studio or run:
```dotnet publish PapyrusCs -c Release --self-contained --runtime win-x64```
Expand Down