2018-11-07 13:33:49 +01:00
|
|
|
package de.ellpeck.naturesaura.blocks.multi;
|
|
|
|
|
2018-11-23 19:21:52 +01:00
|
|
|
import de.ellpeck.naturesaura.api.NaturesAuraAPI;
|
|
|
|
import de.ellpeck.naturesaura.api.multiblock.IMultiblock;
|
|
|
|
import de.ellpeck.naturesaura.api.multiblock.Matcher;
|
2019-03-01 18:27:24 +01:00
|
|
|
import de.ellpeck.naturesaura.compat.patchouli.PatchouliCompat;
|
2018-11-07 13:33:49 +01:00
|
|
|
import net.minecraft.block.Block;
|
2019-10-20 22:30:49 +02:00
|
|
|
import net.minecraft.block.BlockState;
|
2018-11-07 13:33:49 +01:00
|
|
|
import net.minecraft.util.ResourceLocation;
|
|
|
|
import net.minecraft.util.math.BlockPos;
|
2020-01-21 23:02:39 +01:00
|
|
|
import net.minecraft.world.IWorld;
|
2020-04-29 16:38:50 +02:00
|
|
|
import net.minecraft.world.World;
|
2018-11-07 13:33:49 +01:00
|
|
|
|
|
|
|
import java.util.HashMap;
|
|
|
|
import java.util.Map;
|
|
|
|
import java.util.function.BiFunction;
|
|
|
|
|
2018-11-23 19:21:52 +01:00
|
|
|
public class Multiblock implements IMultiblock {
|
2018-11-07 13:33:49 +01:00
|
|
|
|
2018-11-23 19:21:52 +01:00
|
|
|
private final ResourceLocation name;
|
2019-01-26 00:34:05 +01:00
|
|
|
private final Map<BlockPos, Matcher> matchers = new HashMap<>();
|
2018-11-23 19:21:52 +01:00
|
|
|
private final int width;
|
|
|
|
private final int height;
|
|
|
|
private final int depth;
|
|
|
|
private final int xOffset;
|
|
|
|
private final int yOffset;
|
|
|
|
private final int zOffset;
|
|
|
|
private final char[][][] rawPattern;
|
2018-11-07 13:33:49 +01:00
|
|
|
|
|
|
|
public Multiblock(ResourceLocation name, String[][] pattern, Object... rawMatchers) {
|
|
|
|
this.name = name;
|
|
|
|
|
|
|
|
int width = -1;
|
|
|
|
this.height = pattern.length;
|
|
|
|
int depth = -1;
|
|
|
|
int xOff = 0;
|
|
|
|
int yOff = 0;
|
|
|
|
int zOff = 0;
|
|
|
|
char[][][] raw = null;
|
|
|
|
|
|
|
|
for (int i = 0; i < pattern.length; i++) {
|
|
|
|
String[] row = pattern[i];
|
|
|
|
|
|
|
|
if (width < 0)
|
|
|
|
width = row.length;
|
|
|
|
else if (row.length != width)
|
|
|
|
throw new IllegalArgumentException();
|
|
|
|
|
|
|
|
for (int j = 0; j < row.length; j++) {
|
|
|
|
String column = row[j];
|
|
|
|
if (depth < 0)
|
|
|
|
depth = column.length();
|
|
|
|
else if (column.length() != depth)
|
|
|
|
throw new IllegalArgumentException();
|
|
|
|
|
|
|
|
if (raw == null)
|
|
|
|
raw = new char[width][this.height][depth];
|
|
|
|
for (int k = 0; k < column.length(); k++) {
|
|
|
|
char c = column.charAt(k);
|
|
|
|
raw[k][this.height - 1 - i][j] = c;
|
|
|
|
|
|
|
|
if (c == '0') {
|
|
|
|
xOff = k;
|
|
|
|
yOff = this.height - 1 - i;
|
|
|
|
zOff = j;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
this.depth = depth;
|
|
|
|
this.width = width;
|
|
|
|
this.xOffset = xOff;
|
|
|
|
this.yOffset = yOff;
|
|
|
|
this.zOffset = zOff;
|
|
|
|
this.rawPattern = raw;
|
|
|
|
|
|
|
|
Map<Character, Matcher> matchers = new HashMap<>();
|
|
|
|
for (int i = 0; i < rawMatchers.length; i += 2) {
|
|
|
|
char c = (char) rawMatchers[i];
|
|
|
|
if (matchers.containsKey(c))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
Object value = rawMatchers[i + 1];
|
2019-10-20 22:30:49 +02:00
|
|
|
if (value instanceof BlockState) {
|
|
|
|
BlockState state = (BlockState) value;
|
2018-11-23 19:21:52 +01:00
|
|
|
matchers.put(c, new Matcher(state,
|
|
|
|
(world, start, offset, pos, other, otherC) -> other == state));
|
|
|
|
} else if (value instanceof Block) {
|
|
|
|
Block block = (Block) value;
|
|
|
|
matchers.put(c, new Matcher(block.getDefaultState(),
|
|
|
|
(world, start, offset, pos, state, otherC) -> state.getBlock() == block));
|
|
|
|
} else
|
2018-11-07 13:33:49 +01:00
|
|
|
matchers.put(c, (Matcher) value);
|
|
|
|
}
|
|
|
|
|
|
|
|
for (int x = 0; x < this.width; x++)
|
|
|
|
for (int y = 0; y < this.height; y++)
|
|
|
|
for (int z = 0; z < this.depth; z++) {
|
|
|
|
Matcher matcher = matchers.get(this.rawPattern[x][y][z]);
|
|
|
|
if (matcher == null)
|
|
|
|
throw new IllegalStateException();
|
2018-11-23 19:21:52 +01:00
|
|
|
if (matcher.getCheck() != null)
|
2018-11-07 13:33:49 +01:00
|
|
|
this.matchers.put(new BlockPos(x, y, z), matcher);
|
|
|
|
}
|
|
|
|
|
2019-03-01 18:27:24 +01:00
|
|
|
PatchouliCompat.addPatchouliMultiblock(name, pattern, rawMatchers);
|
2018-11-23 19:21:52 +01:00
|
|
|
NaturesAuraAPI.MULTIBLOCKS.put(this.name, this);
|
2018-11-07 13:33:49 +01:00
|
|
|
}
|
|
|
|
|
2018-11-23 19:21:52 +01:00
|
|
|
@Override
|
2020-04-29 16:38:50 +02:00
|
|
|
public boolean isComplete(World world, BlockPos center) {
|
2018-11-07 13:33:49 +01:00
|
|
|
BlockPos start = this.getStart(center);
|
|
|
|
return this.forEach(center, (char) 0, (pos, matcher) -> {
|
|
|
|
BlockPos offset = pos.subtract(start);
|
2018-11-23 19:21:52 +01:00
|
|
|
return matcher.getCheck().matches(world, start, offset, pos, world.getBlockState(pos), this.getChar(offset));
|
2018-11-07 13:33:49 +01:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2018-11-23 19:21:52 +01:00
|
|
|
@Override
|
2019-01-26 00:34:05 +01:00
|
|
|
public boolean forEach(BlockPos center, char c, BiFunction<BlockPos, Matcher, Boolean> function) {
|
2018-11-07 13:33:49 +01:00
|
|
|
BlockPos start = this.getStart(center);
|
2019-01-26 00:34:05 +01:00
|
|
|
for (Map.Entry<BlockPos, Matcher> entry : this.matchers.entrySet()) {
|
2018-11-07 13:33:49 +01:00
|
|
|
BlockPos offset = entry.getKey();
|
|
|
|
if (c == 0 || this.getChar(offset) == c)
|
|
|
|
if (!function.apply(start.add(offset), entry.getValue()))
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2018-11-23 19:21:52 +01:00
|
|
|
@Override
|
2018-11-07 13:33:49 +01:00
|
|
|
public BlockPos getStart(BlockPos center) {
|
|
|
|
return center.add(-this.xOffset, -this.yOffset, -this.zOffset);
|
|
|
|
}
|
|
|
|
|
2018-11-23 19:21:52 +01:00
|
|
|
@Override
|
2018-11-07 13:33:49 +01:00
|
|
|
public char getChar(BlockPos offset) {
|
|
|
|
return this.rawPattern[offset.getX()][offset.getY()][offset.getZ()];
|
|
|
|
}
|
|
|
|
|
2018-11-23 19:21:52 +01:00
|
|
|
@Override
|
|
|
|
public ResourceLocation getName() {
|
|
|
|
return this.name;
|
|
|
|
}
|
2018-11-07 13:33:49 +01:00
|
|
|
|
2018-11-23 19:21:52 +01:00
|
|
|
@Override
|
2019-01-26 00:34:05 +01:00
|
|
|
public Map<BlockPos, Matcher> getMatchers() {
|
2018-11-23 19:21:52 +01:00
|
|
|
return this.matchers;
|
|
|
|
}
|
2018-11-07 13:33:49 +01:00
|
|
|
|
2018-11-23 19:21:52 +01:00
|
|
|
@Override
|
|
|
|
public int getWidth() {
|
|
|
|
return this.width;
|
|
|
|
}
|
2018-11-07 13:33:49 +01:00
|
|
|
|
2018-11-23 19:21:52 +01:00
|
|
|
@Override
|
|
|
|
public int getHeight() {
|
|
|
|
return this.height;
|
|
|
|
}
|
2018-11-07 13:33:49 +01:00
|
|
|
|
2018-11-23 19:21:52 +01:00
|
|
|
@Override
|
|
|
|
public int getDepth() {
|
|
|
|
return this.depth;
|
|
|
|
}
|
2018-11-07 13:33:49 +01:00
|
|
|
|
2018-11-23 19:21:52 +01:00
|
|
|
@Override
|
|
|
|
public int getXOffset() {
|
|
|
|
return this.xOffset;
|
|
|
|
}
|
2018-11-17 21:31:57 +01:00
|
|
|
|
2018-11-23 19:21:52 +01:00
|
|
|
@Override
|
|
|
|
public int getYOffset() {
|
|
|
|
return this.yOffset;
|
|
|
|
}
|
2018-11-17 21:31:57 +01:00
|
|
|
|
2018-11-23 19:21:52 +01:00
|
|
|
@Override
|
|
|
|
public int getZOffset() {
|
|
|
|
return this.zOffset;
|
2018-11-07 13:33:49 +01:00
|
|
|
}
|
|
|
|
|
2018-11-23 19:21:52 +01:00
|
|
|
@Override
|
|
|
|
public char[][][] getRawPattern() {
|
|
|
|
return this.rawPattern;
|
2018-11-07 13:33:49 +01:00
|
|
|
}
|
|
|
|
}
|