structure detection WIP.

This commit is contained in:
ticticboooom
2022-04-12 13:25:24 +01:00
parent f74e7db4df
commit 95948670b9
22 changed files with 674 additions and 37 deletions

View File

@@ -135,6 +135,10 @@ shadowJar {
repositories {
maven {
name = "Progwml6 maven"
url = "https://dvs1.progwml6.com/files/maven/"
}
maven { url 'https://modmaven.dev/' }
maven {
name = "Cursemaven"
@@ -166,16 +170,17 @@ repositories {
includeGroup "me.shedaniel"
}
}
mavenCentral()
}
dependencies {
// Specify the version of Minecraft to use, If this is any group other then 'net.minecraft' it is assumed
// that the dep is a ForgeGradle 'patcher' dependency. And it's patches will be applied.
// The userdev artifact is a special name and will get all sorts of transformations applied to it.
compileOnly 'org.projectlombok:lombok:1.18.18'
annotationProcessor 'org.projectlombok:lombok:1.18.18'
compileOnly 'org.projectlombok:lombok:1.18.22'
annotationProcessor 'org.projectlombok:lombok:1.18.22'
minecraft 'net.minecraftforge:forge:1.16.5-36.2.20'
compileOnly 'com.google.code.gson:gson:2.8.7'
// compileOnly 'com.google.code.gson:gson:2.9.0'
implementation 'org.spongepowered:mixin:0.8-SNAPSHOT'
annotationProcessor 'org.spongepowered:mixin:0.8.2:processor'
//

View File

@@ -2,11 +2,14 @@ package com.ticticboooom.mods.mm;
import com.ticticboooom.mods.mm.block.ter.model.controller.ControllerBlockModel;
import com.ticticboooom.mods.mm.block.ter.model.port.PortBlockModel;
import com.ticticboooom.mods.mm.client.screen.ControllerScreen;
import com.ticticboooom.mods.mm.ports.PortTypeRegistry;
import com.ticticboooom.mods.mm.ports.base.PortType;
import com.ticticboooom.mods.mm.setup.MMBlocks;
import com.ticticboooom.mods.mm.setup.MMContainerTypes;
import com.ticticboooom.mods.mm.setup.MMItems;
import com.ticticboooom.mods.mm.setup.MMTiles;
import net.minecraft.client.gui.ScreenManager;
import net.minecraft.client.renderer.BlockModelShapes;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.RenderTypeLookup;
@@ -26,12 +29,15 @@ import java.util.Map;
@Mod(Ref.MOD_ID)
public class ModRoot {
public ModRoot() {
PortTypeRegistry.registerDefault();
IEventBus bus = FMLJavaModLoadingContext.get().getModEventBus();
MMTiles.TILES.register(bus);
MMBlocks.BLOCKS.register(bus);
MMItems.ITEMS.register(bus);
MMContainerTypes.CONTAINERS.register(bus);
if (EffectiveSide.get().isClient()) {
bus.addListener(ModRoot::modelRegistry);
@@ -71,6 +77,7 @@ public class ModRoot {
event.enqueueWork(() -> {
RenderTypeLookup.setRenderLayer(MMBlocks.CONTROLLER.get(), RenderType.getTranslucent());
RenderTypeLookup.setRenderLayer(MMBlocks.PORT.get(), RenderType.getTranslucent());
ScreenManager.registerFactory(MMContainerTypes.CONTROLLER.get(), ControllerScreen::new);
});
}
}

View File

@@ -1,10 +1,17 @@
package com.ticticboooom.mods.mm;
import com.electronwill.nightconfig.core.AbstractConfig;
import net.minecraft.util.ResourceLocation;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.lwjgl.system.CallbackI;
public class Ref {
public static final String MOD_ID = "mm";
public static final Logger LOG = LogManager.getLogger(MOD_ID);
public static ResourceLocation res(String path){
return new ResourceLocation(MOD_ID, path);
}
@@ -21,6 +28,8 @@ public class Ref {
public static final ResourceLocation BLOCK = res("block");
public static final ResourceLocation PORT = res("port");
public static final ResourceLocation PORT_TIER = res("port_tier");
public static final ResourceLocation PORT_GROUP = res("port_group");
public static final ResourceLocation MODIFIABLE = res("modifiable");
}
}

View File

@@ -1,15 +1,24 @@
package com.ticticboooom.mods.mm.block;
import com.ticticboooom.mods.mm.block.tile.ControllerTile;
import com.ticticboooom.mods.mm.setup.MMTiles;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.DirectionalBlock;
import net.minecraft.block.material.Material;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.ServerPlayerEntity;
import net.minecraft.item.BlockItemUseContext;
import net.minecraft.state.StateContainer;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.ActionResultType;
import net.minecraft.util.Direction;
import net.minecraft.util.Hand;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.BlockRayTraceResult;
import net.minecraft.world.IBlockReader;
import net.minecraft.world.World;
import net.minecraftforge.fml.network.NetworkHooks;
import javax.annotation.Nullable;
@@ -40,4 +49,15 @@ public class ControllerBlock extends DirectionalBlock {
public TileEntity createTileEntity(BlockState state, IBlockReader world) {
return MMTiles.CONTROLLER.get().create();
}
@Override
public ActionResultType onBlockActivated(BlockState state, World worldIn, BlockPos pos, PlayerEntity player, Hand handIn, BlockRayTraceResult hit) {
if (!worldIn.isRemote()) {
TileEntity blockEntity = worldIn.getTileEntity(pos);
if (blockEntity instanceof ControllerTile) {
NetworkHooks.openGui((ServerPlayerEntity) player, (ControllerTile)blockEntity, pos);
}
}
return ActionResultType.SUCCESS;
}
}

View File

@@ -1,29 +1,263 @@
package com.ticticboooom.mods.mm.block.tile;
import com.ticticboooom.mods.mm.Ref;
import com.ticticboooom.mods.mm.block.ter.model.controller.ControllerBlockModel;
import com.ticticboooom.mods.mm.client.container.ControllerContainer;
import com.ticticboooom.mods.mm.data.DataRegistry;
import com.ticticboooom.mods.mm.data.model.ControllerModel;
import com.ticticboooom.mods.mm.data.model.StructureModel;
import com.ticticboooom.mods.mm.setup.MMBlocks;
import com.ticticboooom.mods.mm.setup.MMTiles;
import com.ticticboooom.mods.mm.structures.StructureKeyTypeValue;
import com.ticticboooom.mods.mm.structures.keys.*;
import net.minecraft.block.BlockState;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.inventory.container.Container;
import net.minecraft.inventory.container.INamedContainerProvider;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.tags.BlockTags;
import net.minecraft.tileentity.ITickableTileEntity;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.Direction;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.Rotation;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Rotations;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.TranslationTextComponent;
import net.minecraftforge.client.model.data.IModelData;
import net.minecraftforge.client.model.data.ModelDataMap;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
public class ControllerTile extends TileEntity implements ITickableTileEntity {
public class ControllerTile extends TileEntity implements ITickableTileEntity, INamedContainerProvider {
public ControllerTile() {
super(MMTiles.CONTROLLER.get());
}
public ControllerModel controllerModel;
public String status = "";
@Override
public void tick() {
if (controllerModel == null) {
return;
}
StructureModel valid = getValid();
if (valid == null) {
return;
}
}
private StructureModel getValid() {
for (Map.Entry<ResourceLocation, StructureModel> entry : DataRegistry.STRUCTURES.entrySet()) {
List<ResourceLocation> controllerId = entry.getValue().controllerId;
if (!controllerIdMatches(controllerId)) {
continue;
}
if (isValidBlockPlacement(entry.getValue())) {
status = "Structure Found!";
return entry.getValue();
}
}
status = "Structure Not Found!";
return null;
}
private boolean controllerIdMatches(List<ResourceLocation> ids) {
for (ResourceLocation id : ids) {
if (id.equals(controllerModel.id)) {
return true;
}
}
return false;
}
private boolean isValidBlock(StructureKeyTypeValue dataIn, StructureModel model, BlockState blockState, BlockPos pos) {
BlockStructureKeyType.Value data = (BlockStructureKeyType.Value) dataIn;
boolean matches = false;
for (String s : data.blockSelector) {
if (s.startsWith("#")) {
String tagName = s.substring(1);
if (blockState.isIn(BlockTags.getCollection().getTagByID(Objects.requireNonNull(ResourceLocation.tryCreate(tagName))))) {
matches = true;
}
} else {
if (blockState.getBlock().getRegistryName().toString().equals(s)) {
matches = true;
}
}
}
return matches;
}
private boolean isValidPort(StructureKeyTypeValue dataIn, StructureModel model, BlockState blockState, BlockPos pos) {
PortStructureKeyType.Value data = (PortStructureKeyType.Value) dataIn;
if (blockState.getBlock().getRegistryName().equals(MMBlocks.PORT.getId())) {
TileEntity te = world.getTileEntity(pos);
if (te instanceof PortTile) {
PortTile pte = (PortTile) te;
boolean io = true;
if (data.input.isPresent()) {
io = data.input.get() == pte.isInput;
}
return io && pte.portModel.type.equals(data.port);
}
}
return false;
}
private boolean isValidPortTier(StructureKeyTypeValue dataIn, StructureModel model, BlockState blockState, BlockPos pos) {
PortTierStructureKeyType.Value data = (PortTierStructureKeyType.Value) dataIn;
if (blockState.getBlock().getRegistryName().equals(MMBlocks.PORT.getId())) {
TileEntity te = world.getTileEntity(pos);
if (te instanceof PortTile) {
PortTile pte = (PortTile) te;
boolean io = true;
if (data.input.isPresent()) {
io = data.input.get() == pte.isInput;
}
return io && pte.portModel.id.equals(data.portTier);
}
}
return false;
}
private boolean isValidPortGroup(StructureKeyTypeValue dataIn, StructureModel model, BlockState blockState, BlockPos pos) {
PortGroupStructureKeyType.Value data = (PortGroupStructureKeyType.Value) dataIn;
TileEntity te = world.getTileEntity(pos);
if (te instanceof PortTile) {
PortTile pte = (PortTile) te;
List<String> reqKeys = model.portGroupings.get(data.group);
for (String reqKey : reqKeys) {
StructureModel.RequiredPort requiredPort = model.requiredPorts.get(reqKey);
if (!requiredPort.port.equals(pte.portModel.type)) {
return false;
}
return requiredPort.tiers.contains(pte.portModel.id);
}
}
return false;
}
private boolean isValidModifiable(StructureKeyTypeValue dataIn, StructureModel model, BlockState blockState, BlockPos pos) {
ModifiableStructureKeyType.Value data = (ModifiableStructureKeyType.Value) dataIn;
for (Map.Entry<String, StructureKeyTypeValue> entry : data.modifiers.entrySet()) {
if (isValidBlockSingleWithData(entry.getValue(), model, pos)) {
return true;
}
}
return false;
}
private boolean isValidBlockSingleWithKey(StructureModel.PositionedKey positionedKey, StructureModel model) {
BlockState blockState = world.getBlockState(this.pos.add(positionedKey.pos));
if (positionedKey.type.equals(Ref.Reg.SKT.BLOCK)) {
return isValidBlock(positionedKey.data, model, blockState, positionedKey.pos);
}
if (positionedKey.type.equals(Ref.Reg.SKT.PORT)) {
return isValidPort(positionedKey.data, model, blockState, positionedKey.pos);
}
if (positionedKey.type.equals(Ref.Reg.SKT.PORT_TIER)) {
return isValidPortTier(positionedKey.data, model, blockState, positionedKey.pos);
}
if (positionedKey.type.equals(Ref.Reg.SKT.PORT_GROUP)) {
return isValidPortGroup(positionedKey.data, model, blockState, positionedKey.pos);
}
if (positionedKey.type.equals(Ref.Reg.SKT.MODIFIABLE)) {
return isValidModifiable(positionedKey.data, model, blockState, positionedKey.pos);
}
return true;
}
private boolean isValidBlockSingleWithData(StructureKeyTypeValue dataIn, StructureModel model, BlockPos pos) {
BlockState blockState = world.getBlockState(this.pos.add(pos));
if (dataIn instanceof BlockStructureKeyType.Value) {
return isValidBlock(dataIn, model, blockState, pos);
}
if (dataIn instanceof PortStructureKeyType.Value) {
return isValidPort(dataIn, model, blockState, pos);
}
if (dataIn instanceof PortTierStructureKeyType.Value) {
return isValidPortTier(dataIn, model, blockState, pos);
}
if (dataIn instanceof PortGroupStructureKeyType.Value) {
return isValidPortGroup(dataIn, model, blockState, pos);
}
if (dataIn instanceof ModifiableStructureKeyType.Value) {
return isValidModifiable(dataIn, model, blockState, pos);
}
return true;
}
private List<StructureModel.PositionedKey> rotateKeys(StructureModel model, Rotation rotation) {
List<StructureModel.PositionedKey> result = new ArrayList<>();
for (StructureModel.PositionedKey positionedKey : model.positionedKeys) {
result.add(new StructureModel.PositionedKey(positionedKey.pos.rotate(rotation), new StructureModel.Key(positionedKey.type, positionedKey.data)));
}
return result;
}
private boolean isValidBlockPlacement(StructureModel model) {
Rotation rotation = Rotation.NONE;
for (int i = 0; i < 4; i++) {
boolean found = true;
for (StructureModel.PositionedKey positionedKey : rotateKeys(model, rotation)) {
if (!isValidBlockSingleWithKey(positionedKey, model)) {
found = false;
}
}
if (found) {
return true;
}
rotation = rotation.add(Rotation.CLOCKWISE_90);
}
return false;
}
@Nonnull
@Override
public IModelData getModelData() {
return new ModelDataMap.Builder().withInitial(ControllerBlockModel.CONTROLLER, controllerModel).build();
}
@Override
public ITextComponent getDisplayName() {
return new TranslationTextComponent("container.mm.controller");
}
@Nullable
@Override
public Container createMenu(int p_createMenu_1_, PlayerInventory p_createMenu_2_, PlayerEntity p_createMenu_3_) {
return new ControllerContainer(this, p_createMenu_2_, p_createMenu_1_);
}
@Override
public void read(BlockState state, CompoundNBT nbt) {
if (nbt.contains("ControllerId")) {
String controllerId = nbt.getString("ControllerId");
controllerModel = DataRegistry.CONTROLLERS.get(ResourceLocation.tryCreate(controllerId));
}
super.read(state, nbt);
}
@Override
public CompoundNBT write(CompoundNBT compound) {
if (controllerModel.id != null) {
compound.putString("ControllerId", controllerModel.id.toString());
}
return super.write(compound);
}
}

View File

@@ -0,0 +1,32 @@
package com.ticticboooom.mods.mm.client.container;
import com.ticticboooom.mods.mm.block.tile.ControllerTile;
import com.ticticboooom.mods.mm.setup.MMContainerTypes;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.inventory.container.Container;
import net.minecraft.network.PacketBuffer;
public class ControllerContainer extends Container {
private ControllerTile tile;
private PlayerInventory inv;
public ControllerContainer(ControllerTile tile, PlayerInventory inv, int id) {
super(MMContainerTypes.CONTROLLER.get(), id);
this.tile = tile;
this.inv = inv;
}
public ControllerContainer(int windowId, PlayerInventory inv, PacketBuffer data) {
this((ControllerTile) inv.player.world.getTileEntity(data.readBlockPos()), inv, windowId);
}
@Override
public boolean canInteractWith(PlayerEntity playerIn) {
return true;
}
public ControllerTile getTile() {
return tile;
}
}

View File

@@ -0,0 +1,42 @@
package com.ticticboooom.mods.mm.client.screen;
import com.mojang.blaze3d.matrix.MatrixStack;
import com.ticticboooom.mods.mm.Ref;
import com.ticticboooom.mods.mm.client.container.ControllerContainer;
import net.minecraft.client.gui.screen.inventory.ContainerScreen;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.text.ITextComponent;
public class ControllerScreen extends ContainerScreen<ControllerContainer> {
public ControllerScreen(ControllerContainer screenContainer, PlayerInventory inv, ITextComponent titleIn) {
super(screenContainer, inv, titleIn);
}
private static final ResourceLocation GUI = new ResourceLocation(Ref.MOD_ID, "textures/gui/gui_large.png");
@Override
public void render(MatrixStack stack, int mouseX, int mouseY, float p_230430_4_) {
super.render(stack, mouseX, mouseY, p_230430_4_);
this.renderHoveredTooltip(stack, mouseX, mouseY);
}
@Override
protected void drawGuiContainerForegroundLayer(MatrixStack stack, int x0, int y0) {
this.minecraft.fontRenderer.func_238418_a_(container.getTile().controllerModel.name, 10, -20, 176, 0xfefefe);
drawString(stack, this.minecraft.fontRenderer, "Inventory", 7, 100, 0xfefefe);
int y = 40;
for (String s : container.getTile().status.split("\n")) {
drawString(stack, this.minecraft.fontRenderer, s, 12, y, 0xfefefe);
y += 12;
}
}
@Override
protected void drawGuiContainerBackgroundLayer(MatrixStack stack, float partialTicks, int x, int y) {
this.renderBackground(stack);
this.minecraft.textureManager.bindTexture(GUI);
this.blit(stack, this.guiLeft, this.guiTop - 30, 0, 0, 256, 256);
}
}

View File

@@ -1,18 +1,51 @@
package com.ticticboooom.mods.mm.data.model;
import com.sun.org.apache.xpath.internal.operations.Bool;
import com.ticticboooom.mods.mm.structures.StructureKeyTypeValue;
import javafx.geometry.Pos;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos;
import org.lwjgl.system.CallbackI;
import java.util.List;
import java.util.Map;
import java.util.Optional;
public class StructureModel {
public ResourceLocation id;
public ResourceLocation controllerId;
public List<ResourceLocation> controllerId;
public List<List<String>> pattern;
public Map<Character, Key> keys;
public Map<String, RequiredPort> requiredPorts;
public Map<String, List<String>> portGroupings;
public List<PositionedKey> positionedKeys;
public static class Key {
public Key(ResourceLocation type, StructureKeyTypeValue data){
this.type = type;
this.data = data;
}
public Key() {
}
public static final class Key {
public ResourceLocation type;
public Object data;
public StructureKeyTypeValue data;
}
public static final class PositionedKey extends Key {
public PositionedKey(BlockPos pos, Key key) {
this.pos = pos;
this.data = key.data;
this.type = key.type;
}
public BlockPos pos;
}
public static final class RequiredPort {
public ResourceLocation port;
public Optional<Boolean> input;
public List<ResourceLocation> tiers;
}
}

View File

@@ -1,19 +1,26 @@
package com.ticticboooom.mods.mm.data.reload;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.ticticboooom.mods.mm.data.DataRegistry;
import com.ticticboooom.mods.mm.data.model.StructureModel;
import com.ticticboooom.mods.mm.data.util.ParserUtils;
import com.ticticboooom.mods.mm.setup.MMRegistries;
import com.ticticboooom.mods.mm.structures.StructureKeyType;
import com.ticticboooom.mods.mm.structures.StructureKeyTypeValue;
import lombok.SneakyThrows;
import net.minecraft.client.resources.JsonReloadListener;
import net.minecraft.profiler.IProfiler;
import net.minecraft.resources.IResourceManager;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos;
import net.minecraftforge.event.AddReloadListenerEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
import java.util.Map;
import java.util.*;
@Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.FORGE)
public class StructureReloadListener extends JsonReloadListener {
@@ -35,7 +42,120 @@ public class StructureReloadListener extends JsonReloadListener {
}
}
private StructureModel parse(ResourceLocation key, JsonObject asJsonObject) {
private StructureModel parse(ResourceLocation key, JsonObject json) {
StructureModel result = new StructureModel();
result.id = key;
result.portGroupings = ParserUtils.parseOrDefault(json, "portGroupings", x -> {
JsonObject obj = x.getAsJsonObject();
Map<String, List<String>> res = new HashMap<>();
Set<Map.Entry<String, JsonElement>> entries = obj.entrySet();
for (Map.Entry<String, JsonElement> s : entries) {
JsonArray arr = s.getValue().getAsJsonArray();
ArrayList<String> strings = new ArrayList<>();
for (JsonElement jsonElement : arr) {
strings.add(jsonElement.getAsString());
}
res.put(s.getKey(), strings);
}
return res;
}, new HashMap<>());
JsonObject requiredPortsJson = json.get("requiredPorts").getAsJsonObject();
Set<Map.Entry<String, JsonElement>> portKeys = requiredPortsJson.entrySet();
result.requiredPorts = new HashMap<>();
for (Map.Entry<String, JsonElement> portKey : portKeys) {
JsonObject portObj = portKey.getValue().getAsJsonObject();
StructureModel.RequiredPort requiredPort = new StructureModel.RequiredPort();
requiredPort.port = ResourceLocation.tryCreate(portObj.get("port").getAsString());
requiredPort.input = ParserUtils.parseOrDefault(portObj, "input", x -> Optional.of(x.getAsBoolean()), Optional.empty());
requiredPort.tiers = ParserUtils.parseOrDefault(portObj, "tiers", x -> {
JsonArray asJsonArray = x.getAsJsonArray();
ArrayList<ResourceLocation> strings = new ArrayList<>();
for (JsonElement jsonElement : asJsonArray) {
strings.add(ResourceLocation.tryCreate(jsonElement.getAsString()));
}
return strings;
}, new ArrayList<>());
result.requiredPorts.put(portKey.getKey(), requiredPort);
}
List<List<String>> pattern = new ArrayList<>();
JsonArray patternJson = json.getAsJsonArray("pattern");
for (JsonElement elem : patternJson) {
JsonArray arr = elem.getAsJsonArray();
ArrayList<String> strings = new ArrayList<>();
for (JsonElement jsonElement : arr) {
strings.add(jsonElement.getAsString());
}
pattern.add(strings);
}
result.pattern = pattern;
JsonArray controllerId = json.getAsJsonArray("controllerId");
result.controllerId = new ArrayList<>();
for (JsonElement elem : controllerId) {
result.controllerId.add(ResourceLocation.tryCreate(elem.getAsString()));
}
JsonObject keys = json.getAsJsonObject("keys");
Set<Map.Entry<String, JsonElement>> entries = keys.entrySet();
result.keys = new HashMap<>();
for (Map.Entry<String, JsonElement> keyStr : entries) {
JsonElement jsonElement = keyStr.getValue();
StructureModel.Key parsedKey = parseKey(jsonElement, keyStr.getKey(), result.controllerId, key);
result.keys.put(keyStr.getKey().charAt(0), parsedKey);
}
result = processStructure(result);
return result;
}
private StructureModel.Key parseKey(JsonElement body, String key, List<ResourceLocation> controllerIds, ResourceLocation structureId) {
for (StructureKeyType structureKeyType : MMRegistries.STRUCTURE_KEY_TYPES) {
if (structureKeyType.matches(body)) {
StructureKeyTypeValue parsed = structureKeyType.parse(body, controllerIds, structureId);
StructureModel.Key result = new StructureModel.Key();
result.data = parsed;
result.type = structureKeyType.getRegistryName();
return result;
}
}
return null;
}
@SneakyThrows
public BlockPos getControllerPos(StructureModel model) {
for (int y = 0; y < model.pattern.size(); y++) {
List<String> layer = model.pattern.get(y);
for (int x = 0; x < layer.size(); x++) {
String row = layer.get(x);
for (int z = 0; z < row.length(); z++) {
if (row.charAt(z) == 'C') {
return new BlockPos(x, y, z);
}
}
}
}
throw new Exception("Structure: " + model.id + "never defines a controller position");
}
public StructureModel processStructure(StructureModel model) {
List<StructureModel.PositionedKey> keys = new ArrayList<>();
BlockPos controllerPos = getControllerPos(model);
for (int y = 0; y < model.pattern.size(); y++) {
List<String> layer = model.pattern.get(y);
for (int x = 0; x < layer.size(); x++) {
String row = layer.get(x);
for (int z = 0; z < row.length(); z++) {
char c = row.charAt(z);
if (c == ' ') {
continue;
}
if (c == 'C') {
continue;
}
StructureModel.Key key = model.keys.get(c);
keys.add(new StructureModel.PositionedKey(new BlockPos(x, y, z).subtract(controllerPos), key));
}
}
}
model.positionedKeys = keys;
return model;
}
}

View File

@@ -0,0 +1,18 @@
package com.ticticboooom.mods.mm.setup;
import com.ticticboooom.mods.mm.Ref;
import com.ticticboooom.mods.mm.block.ControllerBlock;
import com.ticticboooom.mods.mm.block.PortBlock;
import com.ticticboooom.mods.mm.client.container.ControllerContainer;
import net.minecraft.block.Block;
import net.minecraft.inventory.container.ContainerType;
import net.minecraftforge.common.extensions.IForgeContainerType;
import net.minecraftforge.fml.RegistryObject;
import net.minecraftforge.registries.DeferredRegister;
import net.minecraftforge.registries.ForgeRegistries;
public class MMContainerTypes {
public static final DeferredRegister<ContainerType<?>> CONTAINERS = DeferredRegister.create(ForgeRegistries.CONTAINERS, Ref.MOD_ID);
public static final RegistryObject<ContainerType<ControllerContainer>> CONTROLLER = CONTAINERS.register("controller", () -> IForgeContainerType.create(ControllerContainer::new));
}

View File

@@ -2,7 +2,7 @@ package com.ticticboooom.mods.mm.setup;
import com.ticticboooom.mods.mm.Ref;
import com.ticticboooom.mods.mm.structures.StructureKeyType;
import com.ticticboooom.mods.mm.structures.keys.BlockStructureKeyType;
import com.ticticboooom.mods.mm.structures.keys.*;
import net.minecraftforge.event.RegistryEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
@@ -22,7 +22,11 @@ public class MMRegistries {
@SubscribeEvent
public static void register(RegistryEvent.Register<StructureKeyType> event) {
event.getRegistry().registerAll(
new BlockStructureKeyType().setRegistryName(Ref.Reg.SKT.BLOCK)
new BlockStructureKeyType().setRegistryName(Ref.Reg.SKT.BLOCK),
new PortStructureKeyType().setRegistryName(Ref.Reg.SKT.PORT),
new PortTierStructureKeyType().setRegistryName(Ref.Reg.SKT.PORT_TIER),
new PortGroupStructureKeyType().setRegistryName(Ref.Reg.SKT.PORT_GROUP),
new ModifiableStructureKeyType().setRegistryName(Ref.Reg.SKT.MODIFIABLE)
);
}
}

View File

@@ -1,7 +1,6 @@
package com.ticticboooom.mods.mm.structures;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.registries.ForgeRegistryEntry;
@@ -9,5 +8,5 @@ import java.util.List;
public abstract class StructureKeyType extends ForgeRegistryEntry<StructureKeyType> {
public abstract boolean matches(JsonElement json);
public abstract Object parse(JsonElement json, List<ResourceLocation> controllerIds, ResourceLocation structureId);
public abstract StructureKeyTypeValue parse(JsonElement json, List<ResourceLocation> controllerIds, ResourceLocation structureId);
}

View File

@@ -0,0 +1,4 @@
package com.ticticboooom.mods.mm.structures;
public interface StructureKeyTypeValue {
}

View File

@@ -5,6 +5,7 @@ import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.ticticboooom.mods.mm.data.util.ParserUtils;
import com.ticticboooom.mods.mm.structures.StructureKeyType;
import com.ticticboooom.mods.mm.structures.StructureKeyTypeValue;
import net.minecraft.util.ResourceLocation;
import java.util.ArrayList;
@@ -27,7 +28,7 @@ public class BlockStructureKeyType extends StructureKeyType {
}
@Override
public Object parse(JsonElement json, List<ResourceLocation> controllerIds, ResourceLocation structureId) {
public StructureKeyTypeValue parse(JsonElement json, List<ResourceLocation> controllerIds, ResourceLocation structureId) {
Value result = new Value();
result.blockSelector = new ArrayList<>();
if (json.isJsonPrimitive()) {
@@ -47,8 +48,8 @@ public class BlockStructureKeyType extends StructureKeyType {
result.properties = ParserUtils.parseOrDefault(jsonObj, "properties", x -> {
HashMap<String, String> res = new HashMap<>();
JsonObject obj = x.getAsJsonObject();
obj.keySet().forEach(z -> {
res.put(z, obj.get(z).getAsString());
obj.entrySet().forEach(z -> {
res.put(z.getKey(), z.getValue().getAsString());
});
return res;
}, new HashMap<>());
@@ -56,7 +57,7 @@ public class BlockStructureKeyType extends StructureKeyType {
return result;
}
public static final class Value {
public static final class Value implements StructureKeyTypeValue {
public List<String> blockSelector;
public Map<String, String> properties;
}

View File

@@ -0,0 +1,48 @@
package com.ticticboooom.mods.mm.structures.keys;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.ticticboooom.mods.mm.Ref;
import com.ticticboooom.mods.mm.setup.MMRegistries;
import com.ticticboooom.mods.mm.structures.StructureKeyType;
import com.ticticboooom.mods.mm.structures.StructureKeyTypeValue;
import lombok.SneakyThrows;
import net.minecraft.util.ResourceLocation;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class ModifiableStructureKeyType extends StructureKeyType {
@Override
public boolean matches(JsonElement json) {
JsonObject obj = json.getAsJsonObject();
String type = obj.get("type").getAsString();
return type.equals(Ref.Reg.SKT.MODIFIABLE.toString());
}
@Override
public StructureKeyTypeValue parse(JsonElement json, List<ResourceLocation> controllerIds, ResourceLocation structureId) {
JsonObject obj = json.getAsJsonObject();
JsonObject modifiers = obj.getAsJsonObject("modifiers");
HashMap<String, StructureKeyTypeValue> modifiersMap = new HashMap<>();
modifiers.entrySet().forEach(x -> {
JsonElement jsonElement = x.getValue();
for (StructureKeyType skt : MMRegistries.STRUCTURE_KEY_TYPES) {
if (skt.matches(jsonElement)) {
modifiersMap.put(x.getKey(), skt.parse(jsonElement, controllerIds, structureId));
return;
}
}
Ref.LOG.error("Error parsing modifiable structure key: could not find suitable sub type for modifier.");
});
Value value = new Value();
value.modifiers = modifiersMap;
return value;
}
public static final class Value implements StructureKeyTypeValue {
public Map<String, StructureKeyTypeValue> modifiers;
}
}

View File

@@ -0,0 +1,32 @@
package com.ticticboooom.mods.mm.structures.keys;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.ticticboooom.mods.mm.Ref;
import com.ticticboooom.mods.mm.structures.StructureKeyType;
import com.ticticboooom.mods.mm.structures.StructureKeyTypeValue;
import net.minecraft.util.ResourceLocation;
import java.util.List;
public class PortGroupStructureKeyType extends StructureKeyType {
@Override
public boolean matches(JsonElement json) {
JsonObject obj = json.getAsJsonObject();
String type = obj.get("type").getAsString();
return type.equals(Ref.Reg.SKT.PORT_GROUP.toString());
}
@Override
public StructureKeyTypeValue parse(JsonElement json, List<ResourceLocation> controllerIds, ResourceLocation structureId) {
JsonObject obj = json.getAsJsonObject();
Value result = new Value();
result.group = obj.get("group").getAsString();
return result;
}
public static final class Value implements StructureKeyTypeValue {
public String group;
}
}

View File

@@ -5,6 +5,7 @@ import com.google.gson.JsonObject;
import com.ticticboooom.mods.mm.Ref;
import com.ticticboooom.mods.mm.data.util.ParserUtils;
import com.ticticboooom.mods.mm.structures.StructureKeyType;
import com.ticticboooom.mods.mm.structures.StructureKeyTypeValue;
import net.minecraft.util.ResourceLocation;
import java.util.List;
@@ -19,7 +20,7 @@ public class PortStructureKeyType extends StructureKeyType {
}
@Override
public Object parse(JsonElement json, List<ResourceLocation> controllerIds, ResourceLocation structureId) {
public StructureKeyTypeValue parse(JsonElement json, List<ResourceLocation> controllerIds, ResourceLocation structureId) {
Value result = new Value();
JsonObject obj = json.getAsJsonObject();
result.port = ResourceLocation.tryCreate(obj.get("port").getAsString());
@@ -27,8 +28,8 @@ public class PortStructureKeyType extends StructureKeyType {
return result;
}
public static final class Value {
public ResourceLocation port;
public static final class Value implements StructureKeyTypeValue {
public ResourceLocation port;
public Optional<Boolean> input;
}
}

View File

@@ -5,6 +5,7 @@ import com.google.gson.JsonObject;
import com.ticticboooom.mods.mm.Ref;
import com.ticticboooom.mods.mm.data.util.ParserUtils;
import com.ticticboooom.mods.mm.structures.StructureKeyType;
import com.ticticboooom.mods.mm.structures.StructureKeyTypeValue;
import net.minecraft.util.ResourceLocation;
import java.util.List;
@@ -19,10 +20,15 @@ public class PortTierStructureKeyType extends StructureKeyType {
}
@Override
public Object parse(JsonElement json, List<ResourceLocation> controllerIds, ResourceLocation structureId) {
public StructureKeyTypeValue parse(JsonElement json, List<ResourceLocation> controllerIds, ResourceLocation structureId) {
Value result = new Value();
JsonObject obj = json.getAsJsonObject();
result.portTier = ResourceLocation.tryCreate(obj.get("portTier").getAsString());
result.input = ParserUtils.parseOrDefault(obj, "input", x -> Optional.of(x.getAsBoolean()), Optional.empty());
return result;
}
public static final class Value {
public static final class Value implements StructureKeyTypeValue {
public ResourceLocation portTier;
public Optional<Boolean> input;
}

View File

@@ -15,7 +15,7 @@ license="All rights reserved"
# A list of mods - how many allowed here is determined by the individual mod loader
[[mods]] #mandatory
# The modid of the mod
modId="masterfulmachinery" #mandatory
modId="mm" #mandatory
# The version number of the mod - there's a few well known ${} variables useable here or just hardcode it
# ${file.jarVersion} will substitute the value of the Implementation-Version as read from the mod's JAR file metadata
# see the associated build.gradle script for how to populate this completely automatically during a build
@@ -41,7 +41,7 @@ Have some lorem ipsum.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed mollis lacinia magna. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Sed sagittis luctus odio eu tempus. Interdum et malesuada fames ac ante ipsum primis in faucibus. Pellentesque volutpat ligula eget lacus auctor sagittis. In hac habitasse platea dictumst. Nunc gravida elit vitae sem vehicula efficitur. Donec mattis ipsum et arcu lobortis, eleifend sagittis sem rutrum. Cras pharetra quam eget posuere fermentum. Sed id tincidunt justo. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
'''
# A dependency - use the . to indicate dependency for a specific modid. Dependencies are optional.
[[dependencies.masterfulmachinery]] #optional
[[dependencies.mm]] #optional
# the modid of the dependency
modId="forge" #mandatory
# Does this dependency have to exist - if not, ordering below must be specified
@@ -53,7 +53,7 @@ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed mollis lacinia magn
# Side this dependency is applied on - BOTH, CLIENT or SERVER
side="BOTH"
# Here's another dependency
[[dependencies.masterfulmachinery]]
[[dependencies.mm]]
modId="minecraft"
mandatory=true
# This version range declares a minimum of the current minecraft version up to but not including the next major version

View File

@@ -8,19 +8,14 @@
},
"pattern": [
[
"ABC",
"DEF",
"GHI"
"ABD",
"EFG",
"HIJ"
],
[
" ",
" C ",
" "
],
[
"KLM",
"NOP",
" "
]
],
"keys": {
@@ -44,7 +39,7 @@
},
"G": {
"type": "mm:port_tier",
"portTier": "item_main",
"portTier": "test:item_main",
"input": false
},
"H": {
@@ -79,7 +74,7 @@
"port": "mm:items",
"input": true,
"tiers": [
"item_main"
"mm:item_main"
]
},
"second": {

View File

@@ -0,0 +1,27 @@
{
"controllerId": [
"test:main",
"test:second"
],
"controllerSettings": {
"facing": "west"
},
"pattern": [
[
"ACB"
]
],
"keys": {
"A": {
"include": [
"minecraft:dirt",
"#minecraft:logs"
]
},
"B": "minecraft:glass"
},
"requiredPorts": {
},
"portGroupings": {
}
}

View File

@@ -1,2 +1,2 @@
#Thu Feb 17 07:48:47 GMT 2022
VERSION_CODE=1358
#Tue Apr 12 13:18:55 BST 2022
VERSION_CODE=1454