Slightly major redesign of the codecs to allow for arrays of matchers in the legend for structures

This commit is contained in:
Quarris
2022-08-13 12:40:05 +00:00
parent 1a4c3c9471
commit c27ef6a590
10 changed files with 220 additions and 136 deletions

View File

@@ -21,7 +21,7 @@ apply plugin: 'eclipse'
apply plugin: 'maven-publish'
apply plugin: 'org.spongepowered.mixin'
version = '1.16.5-0.1.65-B' + getVersionNumber()
version = '1.16.5-0.1.66-B' + getVersionNumber()
group = 'com.ticticboooom.mods.mm' // http://maven.apache.org/guides/mini/guide-naming-conventions.html
archivesBaseName = 'MasterfulMachinery'
java.toolchain.languageVersion = JavaLanguageVersion.of(8) // Mojang ships Java 8 to end users, so your mod should target Java 8.

View File

@@ -9,6 +9,7 @@ import com.ticticboooom.mods.mm.client.util.GuiBlockRenderBuilder;
import com.ticticboooom.mods.mm.data.MachineStructureRecipe;
import com.ticticboooom.mods.mm.data.model.structure.MachineStructureBlockPos;
import com.ticticboooom.mods.mm.data.model.structure.MachineStructurePort;
import com.ticticboooom.mods.mm.data.model.structure.MachineStructureRecipeData;
import com.ticticboooom.mods.mm.data.model.structure.MachineStructureRecipeKeyModel;
import com.ticticboooom.mods.mm.helper.GLScissor;
import com.ticticboooom.mods.mm.helper.RLUtils;
@@ -195,13 +196,15 @@ public class MachineStructureRecipeCategory implements IRecipeCategory<MachineSt
zero.transform(matrixStack.getLast().getMatrix().copy());
GLScissor.enable((int)zero.getX(), (int)zero.getY(), 160, 120);
// Render the block parts
for (MachineStructureRecipeKeyModel part : parts) {
this.variantIndices.putIfAbsent(part.getPos(), 0);
for (MachineStructureRecipeKeyModel model : parts) {
MachineStructureRecipeData part = model.getData().get(0);
this.variantIndices.putIfAbsent(model.getPos(), 0);
if (part.getBlock().isEmpty() && part.getTag().isEmpty() && part.getPort() == null) {
continue;
}
BlockPos bp = new BlockPos(-part.getPos().getX(), part.getPos().getY(), -part.getPos().getZ());
BlockPos bp = new BlockPos(-model.getPos().getX(), model.getPos().getY(), -model.getPos().getZ());
if (!part.getBlock().equals("")) {
ResourceLocation resourceLocation = new ResourceLocation(part.getBlock());
@@ -214,11 +217,11 @@ public class MachineStructureRecipeCategory implements IRecipeCategory<MachineSt
} else if (!part.getTag().equals("")) {
ResourceLocation resourceLocation = new ResourceLocation(part.getTag());
ITag<Block> tag = BlockTags.getCollection().getTagByID(resourceLocation);
Integer index = this.variantIndices.get(part.getPos());
Integer index = this.variantIndices.get(model.getPos());
Block block = tag.getAllElements().get(index);
if (this.tickTimer == 0) {
this.variantIndices.put(part.getPos(), (index + 1) % tag.getAllElements().size());
this.variantIndices.put(model.getPos(), (index + 1) % tag.getAllElements().size());
}
if (block != null) {
@@ -229,10 +232,10 @@ public class MachineStructureRecipeCategory implements IRecipeCategory<MachineSt
} else if (part.getPort() != null) {
MachineStructurePort port = part.getPort();
ArrayList<RegistryObject<MachinePortBlock>> ports = port.isInput() ? MMLoader.IPORT_BLOCKS : MMLoader.OPORT_BLOCKS;
Integer index = this.variantIndices.get(part.getPos());
Integer index = this.variantIndices.get(model.getPos());
String controllerId = port.getControllerId().get(index);
if (this.tickTimer == 0) {
this.variantIndices.put(part.getPos(), (index + 1) % port.getControllerId().size());
this.variantIndices.put(model.getPos(), (index + 1) % port.getControllerId().size());
}
String type = port.getType();
MachinePortBlock block = null;

View File

@@ -63,9 +63,9 @@ public class MachineStructureRecipe implements IRecipe<IInventory> {
BlockPos rotatedPos1 = new BlockPos(model.getPos().getX(), model.getPos().getY(), model.getPos().getZ()).rotate(Rotation.CLOCKWISE_180);
BlockPos rotatedPos2 = new BlockPos(model.getPos().getX(), model.getPos().getY(), model.getPos().getZ()).rotate(Rotation.COUNTERCLOCKWISE_90);
rotated.add(new MachineStructureRecipeKeyModel(new MachineStructureBlockPos(rotatedPos.getX(), rotatedPos.getY(), rotatedPos.getZ()), model.getTag(), model.getBlock(), model.getProperties(), model.getPort()));
rotated1.add(new MachineStructureRecipeKeyModel(new MachineStructureBlockPos(rotatedPos1.getX(), rotatedPos1.getY(), rotatedPos1.getZ()), model.getTag(), model.getBlock(), model.getProperties(), model.getPort()));
rotated2.add(new MachineStructureRecipeKeyModel(new MachineStructureBlockPos(rotatedPos2.getX(), rotatedPos2.getY(), rotatedPos2.getZ()), model.getTag(), model.getBlock(), model.getProperties(), model.getPort()));
rotated.add(new MachineStructureRecipeKeyModel(new MachineStructureBlockPos(rotatedPos.getX(), rotatedPos.getY(), rotatedPos.getZ()), model.getData()));
rotated1.add(new MachineStructureRecipeKeyModel(new MachineStructureBlockPos(rotatedPos1.getX(), rotatedPos1.getY(), rotatedPos1.getZ()), model.getData()));
rotated2.add(new MachineStructureRecipeKeyModel(new MachineStructureBlockPos(rotatedPos2.getX(), rotatedPos2.getY(), rotatedPos2.getZ()), model.getData()));
}
this.models = new ArrayList<>();
@@ -85,7 +85,7 @@ public class MachineStructureRecipe implements IRecipe<IInventory> {
List<MachineStructureRecipeKeyModel> mirrored = new ArrayList<>();
for (MachineStructureRecipeKeyModel model : models) {
BlockPos mirroredPos = new BlockPos(-model.getPos().getX(), model.getPos().getY(), model.getPos().getZ());
mirrored.add(new MachineStructureRecipeKeyModel(new MachineStructureBlockPos(mirroredPos.getX(), mirroredPos.getY(), mirroredPos.getZ()), model.getTag(), model.getBlock(), model.getProperties(), model.getPort()));
mirrored.add(new MachineStructureRecipeKeyModel(new MachineStructureBlockPos(mirroredPos.getX(), mirroredPos.getY(), mirroredPos.getZ()), model.getData()));
}
return mirrored;
}
@@ -135,51 +135,56 @@ public class MachineStructureRecipe implements IRecipe<IInventory> {
public boolean innerBlockMatch(BlockPos controllerPos, World world, MachineStructureRecipeKeyModel model) {
BlockPos pos = controllerPos.add(model.getPos().getX(), model.getPos().getY(), model.getPos().getZ());
BlockState blockState = world.getBlockState(pos);
boolean valid = false;
if (!model.getTag().equals("")) {
String[] split = model.getTag().split(":");
if (split.length != 2) {
MM.LOG.fatal("too many : (colons) in structure tag: {}", model.getTag());
return false;
}
ITag<Block> tag = BlockTags.getCollection().get(new ResourceLocation(split[0], split[1]));
if (tag == null) {
MM.LOG.fatal("no existing block tag for structure tag: {}", model.getTag());
return false;
}
valid = tag.contains(blockState.getBlock());
} else if (!model.getBlock().equals("")) {
valid = blockState.getBlock().getRegistryName().toString().equals(model.getBlock());
} else if (model.getPort() != null) {
MachineStructurePort structurePort = model.getPort();
TileEntity portBlockEntity = world.getTileEntity(pos);
if (portBlockEntity instanceof IMachinePortTile && blockState.getBlock() instanceof MachinePortBlock) {
IMachinePortTile portTile = (IMachinePortTile) portBlockEntity;
MachinePortBlock portBlock = ((MachinePortBlock) blockState.getBlock());
if (portTile.isInput() == structurePort.isInput() &&
portBlock.getPortTypeId().equals(RLUtils.toRL(structurePort.getType()))) {
List<String> controllerIds = structurePort.getControllerId() != null ? structurePort.getControllerId() : this.controllerId;
valid = controllerIds.contains(portBlock.getControllerId());
//List<MachineStructureRecipeKeyModel> toMatch = matcher.getData() == null ? Collections.singletonList(matcher) : matcher.getData();
for (MachineStructureRecipeData data : model.getData()) {
BlockPos pos = controllerPos.add(model.getPos().getX(), model.getPos().getY(), model.getPos().getZ());
BlockState blockState = world.getBlockState(pos);
boolean valid = false;
if (!data.getTag().equals("")) {
String[] split = data.getTag().split(":");
if (split.length != 2) {
MM.LOG.fatal("too many : (colons) in structure tag: {}", data.getTag());
continue;
}
ITag<Block> tag = BlockTags.getCollection().get(new ResourceLocation(split[0], split[1]));
if (tag == null) {
MM.LOG.fatal("no existing block tag for structure tag: {}", data.getTag());
continue;
}
valid = tag.contains(blockState.getBlock());
} else if (!data.getBlock().equals("")) {
valid = blockState.getBlock().getRegistryName().toString().equals(data.getBlock());
} else if (data.getPort() != null) {
MachineStructurePort structurePort = data.getPort();
TileEntity portBlockEntity = world.getTileEntity(pos);
if (portBlockEntity instanceof IMachinePortTile && blockState.getBlock() instanceof MachinePortBlock) {
IMachinePortTile portTile = (IMachinePortTile) portBlockEntity;
MachinePortBlock portBlock = ((MachinePortBlock) blockState.getBlock());
if (portTile.isInput() == structurePort.isInput() &&
portBlock.getPortTypeId().equals(RLUtils.toRL(structurePort.getType()))) {
List<String> controllerIds = structurePort.getControllerId() != null ? structurePort.getControllerId() : this.controllerId;
valid = controllerIds.contains(portBlock.getControllerId());
}
}
}
}
if (!valid) {
return false;
}
if (!valid) {
continue;
}
if (model.getProperties() == null) {
return true;
}
if (data.getProperties() == null) {
return true;
}
for (Map.Entry<String, String> stringStringEntry : model.getProperties().entrySet()) {
for (Map.Entry<Property<?>, Comparable<?>> propertyEntry : blockState.getValues().entrySet()) {
if (propertyEntry.getKey().getName().equals(stringStringEntry.getKey())) {
Optional<?> o = propertyEntry.getKey().parseValue(stringStringEntry.getValue());
return propertyEntry.getValue().equals(o.get());
for (Map.Entry<String, String> stringStringEntry : data.getProperties().entrySet()) {
for (Map.Entry<Property<?>, Comparable<?>> propertyEntry : blockState.getValues().entrySet()) {
if (propertyEntry.getKey().getName().equals(stringStringEntry.getKey())) {
Optional<?> o = propertyEntry.getKey().parseValue(stringStringEntry.getValue());
if (propertyEntry.getValue().equals(o.get())) {
return true;
}
}
}
}
}
@@ -262,9 +267,11 @@ public class MachineStructureRecipe implements IRecipe<IInventory> {
private List<MachineStructureRecipeKeyModel> getResult(JsonObject legend, List<List<String>> layout) throws InvalidStructureDefinitionException {
HashMap<Character, MachineStructureRecipeLegendModel> model = new HashMap<>();
for (Map.Entry<String, JsonElement> entry : legend.entrySet()) {
DataResult<Pair<MachineStructureRecipeLegendModel, JsonElement>> apply = JsonOps.INSTANCE.withDecoder(MachineStructureRecipeLegendModel.CODEC).apply(entry.getValue());
MachineStructureRecipeLegendModel first = apply.result().get().getFirst();
model.put(entry.getKey().charAt(0), first);
MachineStructureRecipeLegendModel legendModel = apply.result().get().getFirst();
model.put(entry.getKey().charAt(0), legendModel);
}
ArrayList<MachineStructureRecipeKeyModel> result = new ArrayList<>();
Vector3i controllerPos = getControllerPos(layout);
@@ -283,7 +290,12 @@ public class MachineStructureRecipe implements IRecipe<IInventory> {
}
MachineStructureRecipeLegendModel machineStructureRecipeLegendModel = model.get(c);
BlockPos pos = new BlockPos(x, y, z).subtract(new BlockPos(controllerPos));
result.add(new MachineStructureRecipeKeyModel(new MachineStructureBlockPos(pos.getX(), pos.getY(), pos.getZ()), machineStructureRecipeLegendModel.getTag(), machineStructureRecipeLegendModel.getBlock(), machineStructureRecipeLegendModel.getProperties(), machineStructureRecipeLegendModel.getPort()));
result.add(new MachineStructureRecipeKeyModel(
new MachineStructureBlockPos(pos.getX(), pos.getY(), pos.getZ()),
machineStructureRecipeLegendModel.getData()
));
}
z++;
}
@@ -341,6 +353,7 @@ public class MachineStructureRecipe implements IRecipe<IInventory> {
buf.writeString(recipe.id);
buf.writeString(recipe.name);
try {
List<MachineStructureRecipeKeyModel> model = recipe.getModels().get(0);
buf.func_240629_a_(MachineStructureObject.CODEC, new MachineStructureObject(recipe.getModels().get(0)));
} catch (Exception e) {
e.printStackTrace();
@@ -364,26 +377,8 @@ public class MachineStructureRecipe implements IRecipe<IInventory> {
private void validateStructure(List<MachineStructureRecipeKeyModel> models, List<String> controllerId, String id, ResourceLocation rl) throws InvalidStructureDefinitionException {
for (MachineStructureRecipeKeyModel model : models) {
if (!model.getBlock().equals("")) {
if (RLUtils.isRL(model.getBlock())) {
if (!ForgeRegistries.BLOCKS.containsKey(RLUtils.toRL(model.getBlock()))) {
throw new InvalidStructureDefinitionException("Block: " + model.getBlock() + " is not an existing block in the game");
}
} else {
throw new InvalidStructureDefinitionException("Block: " + model.getBlock() + " is defined but not a valid block id (ResourceLocation)");
}
} else if (!model.getTag().equals("")) {
if (!RLUtils.isRL(model.getTag())) {
throw new InvalidStructureDefinitionException("Block Tag: " + model.getBlock() + " is defined but not a valid block tag id (ResourceLocation)");
}
} else if (model.getPort() != null) {
if (!MMPorts.PORTS.containsKey(RLUtils.toRL(model.getPort().getType()))) {
throw new InvalidStructureDefinitionException("Port: " + model.getPort() + " is defined but not a valid port type id (ResourceLocation)");
} else if (!controllerId.containsAll(model.getPort().getControllerId())) {
throw new InvalidStructureDefinitionException("Port: " + model.getPort() + " is defined but not a valid port controller id specified (ResourceLocation)");
}
} else {
throw new InvalidStructureDefinitionException("You must define at least 1 'block' or 'tag' per port within the 'data' object");
for (MachineStructureRecipeData data : model.getData()) {
validateModelData(data, controllerId);
}
}
@@ -397,5 +392,29 @@ public class MachineStructureRecipe implements IRecipe<IInventory> {
}
}
}
private void validateModelData(MachineStructureRecipeData model, List<String> controllerId) throws InvalidStructureDefinitionException {
if (!model.getBlock().equals("")) {
if (RLUtils.isRL(model.getBlock())) {
if (!ForgeRegistries.BLOCKS.containsKey(RLUtils.toRL(model.getBlock()))) {
throw new InvalidStructureDefinitionException("Block: " + model.getBlock() + " is not an existing block in the game");
}
} else {
throw new InvalidStructureDefinitionException("Block: " + model.getBlock() + " is defined but not a valid block id (ResourceLocation)");
}
} else if (!model.getTag().equals("")) {
if (!RLUtils.isRL(model.getTag())) {
throw new InvalidStructureDefinitionException("Block Tag: " + model.getBlock() + " is defined but not a valid block tag id (ResourceLocation)");
}
} else if (model.getPort() != null) {
if (!MMPorts.PORTS.containsKey(RLUtils.toRL(model.getPort().getType()))) {
throw new InvalidStructureDefinitionException("Port: " + model.getPort() + " is defined but not a valid port type id (ResourceLocation)");
} else if (!controllerId.containsAll(model.getPort().getControllerId())) {
throw new InvalidStructureDefinitionException("Port: " + model.getPort() + " is defined but not a valid port controller id specified (ResourceLocation)");
}
} else {
throw new InvalidStructureDefinitionException("You must define at least 1 'block' or 'tag' per port within the 'data' object");
}
}
}
}

View File

@@ -0,0 +1,26 @@
package com.ticticboooom.mods.mm.data.model.structure;
import com.mojang.serialization.Codec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.Map;
import java.util.Optional;
@Getter
@AllArgsConstructor
public class MachineStructureRecipeData {
public static final Codec<MachineStructureRecipeData> CODEC = RecordCodecBuilder.create(x -> x.group(
Codec.STRING.optionalFieldOf("tag").forGetter(z -> Optional.of(z.tag)),
Codec.STRING.optionalFieldOf("block").forGetter(z -> Optional.of(z.block)),
Codec.unboundedMap(Codec.STRING, Codec.STRING).optionalFieldOf("props").forGetter(z -> Optional.ofNullable(z.properties)),
MachineStructurePort.CODEC.optionalFieldOf("port").forGetter(z -> Optional.ofNullable(z.port))
).apply(x, (tag, block, props, port) -> new MachineStructureRecipeData(tag.orElse(""), block.orElse(""), props.orElse(null), port.orElse(null))));
private final String tag;
private final String block;
private final Map<String, String> properties;
private final MachineStructurePort port;
}

View File

@@ -1,27 +1,27 @@
package com.ticticboooom.mods.mm.data.model.structure;
import com.mojang.datafixers.util.Either;
import com.mojang.serialization.Codec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.Map;
import java.util.Optional;
import java.util.Collections;
import java.util.List;
import java.util.function.Function;
@Getter
@AllArgsConstructor
public class MachineStructureRecipeKeyModel {
public static final Codec<MachineStructureRecipeKeyModel> CODEC = RecordCodecBuilder.create(x -> x.group(
MachineStructureBlockPos.CODEC.fieldOf("pos").forGetter(z -> z.pos),
Codec.STRING.optionalFieldOf("tag").forGetter(z -> Optional.of(z.tag)),
Codec.STRING.optionalFieldOf("block").forGetter(z -> Optional.of(z.block)),
Codec.unboundedMap(Codec.STRING, Codec.STRING).optionalFieldOf("nbt").forGetter(z -> Optional.ofNullable(z.properties)),
MachineStructurePort.CODEC.optionalFieldOf("port").forGetter(z -> Optional.ofNullable(z.port))
).apply(x, (w0, w, y, z, z0) -> new MachineStructureRecipeKeyModel(w0, w.orElse(""), y.orElse(""), z.orElse(null), z0.orElse(null))));
private MachineStructureBlockPos pos;
private final String tag;
private final String block;
private final Map<String, String> properties;
private final MachineStructurePort port;
Codec.either(MachineStructureRecipeData.CODEC, Codec.list(MachineStructureRecipeData.CODEC)).xmap(
either -> either.map(Collections::singletonList, Function.identity()),
data -> data.size() == 1 ? Either.left(data.get(0)) : Either.right(data)
).fieldOf("data").forGetter(z -> z.data)
).apply(x, MachineStructureRecipeKeyModel::new));
private MachineStructureBlockPos pos;
private final List<MachineStructureRecipeData> data;
}

View File

@@ -1,26 +1,24 @@
package com.ticticboooom.mods.mm.data.model.structure;
import com.mojang.datafixers.util.Either;
import com.mojang.serialization.Codec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import com.mojang.serialization.DataResult;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
import java.util.Map;
import java.util.Optional;
import java.util.Collections;
import java.util.List;
import java.util.function.Function;
@Getter
@AllArgsConstructor
public class MachineStructureRecipeLegendModel {
public static final Codec<MachineStructureRecipeLegendModel> CODEC = RecordCodecBuilder.create(x -> x.group(
Codec.STRING.optionalFieldOf("tag").forGetter(z -> Optional.of(z.tag)),
Codec.STRING.optionalFieldOf("block").forGetter(z -> Optional.of(z.block)),
Codec.unboundedMap(Codec.STRING, Codec.STRING).optionalFieldOf("props").forGetter(z -> Optional.ofNullable(z.properties)),
MachineStructurePort.CODEC.optionalFieldOf("port").forGetter(z -> Optional.ofNullable(z.port))
).apply(x, (w, y, z, z0) -> new MachineStructureRecipeLegendModel(w.orElse(""), y.orElse(""), z.orElse(null), z0.orElse(null))));
private final String tag;
private final String block;
@Setter
private Map<String, String> properties;
private final MachineStructurePort port;
public static final Codec<MachineStructureRecipeLegendModel> CODEC =
Codec.either(MachineStructureRecipeData.CODEC, Codec.list(MachineStructureRecipeData.CODEC)).xmap(
either -> either.map(Collections::singletonList, Function.identity()),
data -> data.size() == 1 ? Either.left(data.get(0)) : Either.right(data)
).comapFlatMap(data -> DataResult.success(new MachineStructureRecipeLegendModel(data)), model -> model.data);
private final List<MachineStructureRecipeData> data;
}

View File

@@ -1,19 +1,19 @@
{
"type": "masterfulmachinery:machine_structure",
"id": "test_energy",
"controllerId": "basic",
"name": "Test Energy",
"layout": [
[
"1C2"
]
],
"legend": {
"1": {
"block": "masterfulmachinery:basic_simple_port_energy_input"
},
"2": {
"block": "masterfulmachinery:basic_simple_port_energy_output"
"type": "masterfulmachinery:machine_structure",
"id": "test_energy",
"controllerId": "basic",
"name": "Test Energy",
"layout": [
[
"1C2"
]
],
"legend": {
"1": {
"block": "masterfulmachinery:basic_simple_port_energy_input"
},
"2": {
"block": "masterfulmachinery:basic_simple_port_energy_output"
}
}
}
}

View File

@@ -1,19 +1,19 @@
{
"type": "masterfulmachinery:machine_structure",
"id": "test_fluids",
"controllerId": "basic",
"name": "Test Fluids",
"layout": [
[
"1C2"
]
],
"legend": {
"1": {
"block": "masterfulmachinery:basic_simple_port_fluids_input"
},
"2": {
"block": "masterfulmachinery:basic_simple_port_fluids_output"
"type": "masterfulmachinery:machine_structure",
"id": "test_fluids",
"controllerId": "basic",
"name": "Test Fluids",
"layout": [
[
"1C2"
]
],
"legend": {
"1": {
"block": "masterfulmachinery:basic_simple_port_fluids_input"
},
"2": {
"block": "masterfulmachinery:basic_simple_port_fluids_output"
}
}
}
}

View File

@@ -0,0 +1,38 @@
{
"type": "masterfulmachinery:machine_structure",
"id": "test_multi_legend",
"controllerId": "basic",
"name": "Test Multi Legend",
"layout": [
[
"12C34"
]
],
"legend": {
"1": {
"block": "masterfulmachinery:basic_simple_port_items_input"
},
"2": {
"block": "masterfulmachinery:basic_simple_port_create_rotation_input"
},
"3": [
{
"block": "minecraft:stone"
},
{
"tag": "minecraft:planks"
}
],
"4": [
{
"block": "minecraft:glowstone"
},
{
"block": "minecraft:piston",
"props": {
"extended": "true"
}
}
]
}
}

View File

@@ -1,2 +1,2 @@
#Fri Aug 12 14:32:26 UTC 2022
VERSION_CODE=989
#Sat Aug 13 11:52:53 UTC 2022
VERSION_CODE=1019