Skip to content

Commit

Permalink
Block update/tags fix (#318)
Browse files Browse the repository at this point in the history
* Update tags generator

* Fix block updates

* Update MinecraftStream.Writing.cs
  • Loading branch information
Tides authored Jan 7, 2023
1 parent b6fc51d commit e49cce5
Show file tree
Hide file tree
Showing 16 changed files with 206 additions and 64 deletions.
1 change: 1 addition & 0 deletions Obsidian.API/Obsidian.API.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
<ItemGroup>
<AdditionalFiles Include="..\Obsidian\Assets\blocks.json" Link="Assets\blocks.json" />
<AdditionalFiles Include="..\Obsidian\Assets\items.json" Link="Assets\items.json" />
<AdditionalFiles Include="..\Obsidian\Assets\fluids.json" Link="Assets\fluids.json" />
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ private static void GenerateBlocks(Block[] blocks, SourceProductionContext ctx)
builder.Line($"public string UnlocalizedName => \"{block.Tag}\";");
builder.Line($"public int BaseId => {block.BaseId};");
builder.Line($"public int DefaultId => {block.DefaultId};");
builder.Line($"public int RegistryId => {block.NumericId};");
builder.Line($"public int RegistryId => {block.RegistryId};");

builder.Line($"public Material Material => Material.{block.Name};");

Expand Down
2 changes: 1 addition & 1 deletion Obsidian.SourceGenerators/Registry/BlocksGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ private void Generate(SourceProductionContext context, (Compilation compilation,
{
var asm = output.compilation.AssemblyName;

var assets = Assets.Get(output.files);
var assets = Assets.Get(output.files, context);

if (asm == "Obsidian.API")
{
Expand Down
74 changes: 67 additions & 7 deletions Obsidian.SourceGenerators/Registry/Models/Assets.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,36 @@ private Assets(Block[] blocks, Tag[] tags, Item[] items)
Items = items;
}

public static Assets Get(ImmutableArray<(string name, string json)> files)
public static Assets Get(ImmutableArray<(string name, string json)> files, SourceProductionContext ctx)
{
Block[] blocks = GetBlocks(files.GetJsonFromArray("blocks"));
Tag[] tags = GetTags(files.GetJsonFromArray("tags"), blocks);
Fluid[] fluids = GetFluids(files.GetJsonFromArray("fluids"));
Tag[] tags = GetTags(files.GetJsonFromArray("tags"), blocks, fluids);
Item[] items = GetItems(files.GetJsonFromArray("items"));

return new Assets(blocks, tags, items);
}

public static Fluid[] GetFluids(string? json)
{
if (json is null)
return Array.Empty<Fluid>();

var fluids = new List<Fluid>();
using var document = JsonDocument.Parse(json);

var fluidProperties = document.RootElement.EnumerateObject();

foreach(JsonProperty property in fluidProperties)
{
var name = property.Name;

fluids.Add(new Fluid(name, name.Substring(name.IndexOf(':') + 1), property.Value.GetInt32()));
}

return fluids.ToArray();
}

public static Block[] GetBlocks(string? json)
{
if (json is null)
Expand All @@ -41,17 +62,17 @@ public static Block[] GetBlocks(string? json)

foreach (JsonProperty property in blockProperties)
{
foreach(var state in property.Value.GetProperty("states").EnumerateArray())
foreach (var state in property.Value.GetProperty("states").EnumerateArray())
{
if(state.TryGetProperty("default", out var element))
if (state.TryGetProperty("default", out var element))
{
newBlocks.Add(state.GetProperty("id").GetInt32(), property);
break;
}
}
}

foreach(var property in newBlocks.OrderBy(x => x.Key).Select(x => x.Value))
foreach (var property in newBlocks.OrderBy(x => x.Key).Select(x => x.Value))
blocks.Add(Block.Get(property, id++));

return blocks.ToArray();
Expand All @@ -73,26 +94,65 @@ private static Item[] GetItems(string? json)
return items.ToArray();
}

public static Tag[] GetTags(string? json, Block[] blocks)
public static Tag[] GetTags(string? json, Block[] blocks, Fluid[] fluids)
{
if (json is null)
return Array.Empty<Tag>();

var taggables = new Dictionary<string, ITaggable>();
foreach (Block block in blocks)
{
if (block.Tag is "minecraft:water" or "minecraft:lava")//Skip fluids
continue;

taggables.Add(block.Tag, block);
}

foreach(Fluid fluid in fluids)
taggables.Add(fluid.Tag, fluid);

var tags = new List<Tag>();
var knownTags = new Dictionary<string, Tag>();
var missedTags = new Dictionary<string, List<string>>();

using var document = JsonDocument.Parse(json);

foreach (JsonProperty property in document.RootElement.EnumerateObject())
{
tags.Add(Tag.Get(property, taggables, knownTags));
tags.Add(Tag.Get(property, taggables, knownTags, missedTags));
}

VerifyTags(knownTags, missedTags, taggables);
VerifyTags(knownTags, missedTags, taggables);//I can't think of a better solution :skull:

return tags.ToArray();
}

private static void VerifyTags(Dictionary<string, Tag> knownTags, Dictionary<string, List<string>> missedTags, Dictionary<string, ITaggable> taggables)
{
foreach (var missedTag in missedTags)
{
var propertyName = missedTag.Key;
var tagsMissed = missedTag.Value;

var prop = knownTags[propertyName];
foreach (var tagMissed in tagsMissed)
{
if (knownTags.TryGetValue(tagMissed, out var tag))
{
foreach (var value in tag.Values)
{
if (prop.Values.Contains(value))
continue;

prop.Values.Add(value);
}
}
else if (taggables.TryGetValue(tagMissed, out var taggable) && !prop.Values.Contains(taggable))
{
prop.Values.Add(taggable);
}
}
}
}
}
10 changes: 5 additions & 5 deletions Obsidian.SourceGenerators/Registry/Models/Block.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,25 @@

namespace Obsidian.SourceGenerators.Registry.Models;

internal sealed class Block : ITaggable, IHasName
internal sealed class Block : ITaggable, IHasName, IRegistryItem
{
public string Name { get; }
public string Tag { get; }
public int BaseId { get; }
public int DefaultId { get; }
public int NumericId { get; }
public int RegistryId { get; }
public int StatesCount { get; }
public BlockProperty[] Properties { get; }
public Dictionary<int, List<string>> StateValues { get; }

private Block(string name, string tag, int baseId, int defaultId, int numericId, int statesCount, BlockProperty[] properties,
private Block(string name, string tag, int baseId, int defaultId, int registryId, int statesCount, BlockProperty[] properties,
Dictionary<int, List<string>> stateValues)
{
Name = name;
Tag = tag;
BaseId = baseId;
DefaultId = defaultId;
NumericId = numericId;
RegistryId = registryId;
StatesCount = statesCount;
Properties = properties;
StateValues = stateValues;
Expand Down Expand Up @@ -78,5 +78,5 @@ private static IEnumerable<BlockProperty> GetBlockProperties(JsonProperty block)
}
}

public string GetTagValue() => NumericId.ToString();
public string GetTagValue() => RegistryId.ToString();
}
18 changes: 18 additions & 0 deletions Obsidian.SourceGenerators/Registry/Models/Fluid.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
namespace Obsidian.SourceGenerators.Registry.Models;
public sealed class Fluid : ITaggable, IHasName, IRegistryItem
{
public string Tag { get; }

public string Name { get; }

public int RegistryId { get; }

public Fluid(string tag, string name, int registryId)
{
this.Tag = tag;
this.Name = name;
this.RegistryId = registryId;
}

public string GetTagValue() => this.RegistryId.ToString();
}
5 changes: 5 additions & 0 deletions Obsidian.SourceGenerators/Registry/Models/IRegistryItem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
namespace Obsidian.SourceGenerators.Registry.Models;
public interface IRegistryItem
{
public int RegistryId { get; }
}
20 changes: 19 additions & 1 deletion Obsidian.SourceGenerators/Registry/Models/Tag.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Text.Json;
using System.Threading.Tasks;

namespace Obsidian.SourceGenerators.Registry.Models;

Expand All @@ -17,7 +18,7 @@ private Tag(string name, string minecraftName, string type, List<ITaggable> valu
Values = values;
}

public static Tag Get(JsonProperty property, Dictionary<string, ITaggable> taggables, Dictionary<string, Tag> knownTags)
public static Tag Get(JsonProperty property, Dictionary<string, ITaggable> taggables, Dictionary<string, Tag> knownTags, Dictionary<string, List<string>> missedTags)
{
JsonElement propertyValues = property.Value;

Expand All @@ -26,6 +27,7 @@ public static Tag Get(JsonProperty property, Dictionary<string, ITaggable> tagga
string type = property.Name.Substring(0, property.Name.IndexOf('/'));

var values = new List<ITaggable>();

foreach (JsonElement value in propertyValues.GetProperty("values").EnumerateArray())
{
string valueTag = value.GetString()!;
Expand All @@ -40,15 +42,31 @@ public static Tag Get(JsonProperty property, Dictionary<string, ITaggable> tagga
values.Add(taggable);
}
}
else
{
UpdateMissedTags(property.Name, valueTag, missedTags);
}
}
else if (taggables.TryGetValue(valueTag, out ITaggable taggable))
{
values.Add(taggable);
}
else
{
UpdateMissedTags(property.Name, valueTag, missedTags);
}
}

var tag = new Tag(name, minecraftName, type, values);
knownTags[property.Name] = tag;
return tag;
}

private static void UpdateMissedTags(string propertyName, string valueTag, Dictionary<string, List<string>> missedTags)
{
if (!missedTags.ContainsKey(propertyName))
missedTags.Add(propertyName, new() { valueTag });
else
missedTags[propertyName].Add(valueTag);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ private static void GenerateBlockIds(Assets assets, SourceProductionContext cont
builder.Line();
builder.Type("internal static partial class BlocksRegistry");

var blocks = assets.Blocks.OrderBy(block => block.NumericId);
var blocks = assets.Blocks.OrderBy(block => block.RegistryId);

builder.Indent().Append("internal static readonly ushort[] AllStates = { ");
foreach (Block block in blocks)
Expand All @@ -37,7 +37,7 @@ private static void GenerateBlockIds(Assets assets, SourceProductionContext cont
builder.Indent().Append("internal static readonly ushort[] StateToNumeric = { ");
foreach (Block block in blocks)
{
string entry = $"{block.NumericId}, ";
string entry = $"{block.RegistryId}, ";
for (int i = 0; i < block.StatesCount; i++)
builder.Append(entry);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,18 @@ private static void GenerateTags(Assets assets, SourceProductionContext context)

builder.Line();
builder.Line($"public static Tag[] All = new[] {{ {string.Join(", ", assets.Tags.Select(tag => tag.Type.ToPascalCase() + "." + tag.Name))} }};");
builder.Indent().Append($"public static Dictionary<string, Tag[]> Categories = new() {{ ");
builder.Method($"public static Dictionary<string, Tag[]> Categories = new()");
foreach (IGrouping<string, Tag> tagGroup in grouped)
{
builder.Append($"{{ \"{tagGroup.Key}\", new Tag[] {{ ");
builder.Indent().Append($"{{ \"{tagGroup.Key}\", new Tag[] {{ ");
foreach (Tag tag in tagGroup)
{
builder.Append(tag.Type.ToPascalCase()).Append(".").Append(tag.Name).Append(", ");
}
builder.Append("} }, ");
builder.Line();
}
builder.Append("};").Append(Environment.NewLine);
builder.Line().EndScope(true);

builder.EndScope();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ private void Generate(SourceProductionContext context, (Compilation compilation,
{
var asm = output.compilation.AssemblyName;

var assets = Assets.Get(output.files);
var assets = Assets.Get(output.files, context);

if (asm == "Obsidian")
{
Expand Down
7 changes: 7 additions & 0 deletions Obsidian/Assets/fluids.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"minecraft:empty": 0,
"minecraft:flowing_lava": 3,
"minecraft:flowing_water": 1,
"minecraft:lava": 4,
"minecraft:water": 2
}
37 changes: 23 additions & 14 deletions Obsidian/Assets/tags.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@
"minecraft:dragon_egg"
]
},
"blocks/replaceable_by_water": {
"name": "replaceable_by_water",
"blocks/replaceable_by_liquid": {
"name": "replaceable_by_liquid",
"type": "blocks",
"values": [
"#minecraft:replaceable_plants",
Expand All @@ -53,7 +53,20 @@
"#minecraft:flowers",
"minecraft:sugar_cane",
"minecraft:sweet_berry_bush",
"minecraft:tall_grass"
"minecraft:tall_grass",
"minecraft:air",
"minecraft:cave_air"
]
},
"blocks/flowers": {
"name": "flowers",
"type": "blocks",
"values": [
"#minecraft:small_flowers",
"#minecraft:tall_flowers",
"minecraft:flowering_azalea_leaves",
"minecraft:flowering_azalea",
"minecraft:mangrove_propagule"
]
},
"banner_pattern/no_item_required": {
Expand Down Expand Up @@ -783,17 +796,6 @@
"minecraft:potted_mangrove_propagule"
]
},
"blocks/flowers": {
"name": "flowers",
"type": "blocks",
"values": [
"#minecraft:small_flowers",
"#minecraft:tall_flowers",
"minecraft:flowering_azalea_leaves",
"minecraft:flowering_azalea",
"minecraft:mangrove_propagule"
]
},
"blocks/foxes_spawnable_on": {
"name": "foxes_spawnable_on",
"type": "blocks",
Expand Down Expand Up @@ -2679,6 +2681,13 @@
"minecraft:flowing_water"
]
},
"fluids/empty": {
"name": "empty",
"type": "fluids",
"values": [
"minecraft:empty"
]
},
"game_events/allay_can_listen": {
"name": "allay_can_listen",
"type": "game_events",
Expand Down
Loading

0 comments on commit e49cce5

Please sign in to comment.