From 241daec138c2c66d23add6f384ef1f210b6addeb Mon Sep 17 00:00:00 2001 From: Sollace Date: Sat, 12 Jun 2021 14:54:01 +0200 Subject: [PATCH] More work towards making it possible to move state maps to json --- .../unicopia/block/state/BlockStateMap.java | 79 +++++--- .../block/state/ReversableBlockStateMap.java | 22 ++- .../unicopia/block/state/StateMapping.java | 56 ++++-- .../unicopia/block/state/StateMaps.java | 179 ++++++++---------- 4 files changed, 186 insertions(+), 150 deletions(-) diff --git a/src/main/java/com/minelittlepony/unicopia/block/state/BlockStateMap.java b/src/main/java/com/minelittlepony/unicopia/block/state/BlockStateMap.java index f6ec0900..edc08a56 100644 --- a/src/main/java/com/minelittlepony/unicopia/block/state/BlockStateMap.java +++ b/src/main/java/com/minelittlepony/unicopia/block/state/BlockStateMap.java @@ -1,6 +1,7 @@ package com.minelittlepony.unicopia.block.state; import java.util.ArrayList; +import java.util.List; import java.util.function.Predicate; import javax.annotation.Nonnull; @@ -8,6 +9,7 @@ import javax.annotation.Nullable; import net.minecraft.block.Block; import net.minecraft.block.BlockState; +import net.minecraft.block.Material; import net.minecraft.state.property.Property; import net.minecraft.tag.Tag; import net.minecraft.world.World; @@ -16,43 +18,22 @@ import net.minecraft.world.World; * A collection of block-state mappings. * */ -class BlockStateMap extends ArrayList implements BlockStateConverter { - private static final long serialVersionUID = 2602772651960588745L; +class BlockStateMap implements BlockStateConverter { + private final List mappings; - public void removeBlock(Predicate mapper) { - add(StateMapping.removeBlock(mapper)); - } - - public void removeBlock(Block from) { - add(StateMapping.removeBlock(from)); - } - - - public void replaceBlock(Block from, Block to) { - add(StateMapping.replaceBlock(from, to)); - } - - public void replaceBlock(Tag from, Block to) { - add(StateMapping.replaceBlock(from, to)); - } - - public > void replaceProperty(Block block, Property property, T from, T to) { - add(StateMapping.replaceProperty(block, property, from, to)); - } - - public > void setProperty(Block block, Property property, T to) { - add(StateMapping.setProperty(block, property, to)); + BlockStateMap(List mappings) { + this.mappings = new ArrayList<>(mappings); } @Override public boolean canConvert(@Nullable BlockState state) { - return state != null && stream().anyMatch(i -> i.test(state)); + return state != null && mappings.stream().anyMatch(i -> i.test(state)); } @Override @Nonnull public BlockState getConverted(World world, @Nonnull BlockState state) { - for (StateMapping i : this) { + for (StateMapping i : mappings) { if (i.test(state)) { return i.apply(world, state); } @@ -60,4 +41,48 @@ class BlockStateMap extends ArrayList implements BlockStateConvert return state; } + + public static class Builder { + protected final ArrayList items = new ArrayList<>(); + + public Builder add(StateMapping mapping) { + items.add(mapping); + return this; + } + + public Builder removeBlock(Predicate mapper) { + return add(StateMapping.removeBlock(mapper)); + } + + public Builder removeBlock(Block from) { + return add(StateMapping.removeBlock(s -> s.isOf(from))); + } + + public Builder replaceMaterial(Material from, Block to) { + return add(StateMapping.replaceMaterial(from, to)); + } + + public Builder replaceBlock(Block from, Block to) { + return add(StateMapping.replaceBlock(from, to)); + } + + public Builder replaceBlock(Tag from, Block to) { + return add(StateMapping.replaceBlock(from, to)); + } + + public > Builder replaceProperty(Block block, Property property, T from, T to) { + return add(StateMapping.replaceProperty(block, property, from, to)); + } + + public > Builder setProperty(Block block, Property property, T to) { + return add(StateMapping.build( + s -> s.isOf(block), + (w, s) -> s.with(property, to))); + } + + @SuppressWarnings("unchecked") + public T build() { + return (T)new BlockStateMap(items); + } + } } diff --git a/src/main/java/com/minelittlepony/unicopia/block/state/ReversableBlockStateMap.java b/src/main/java/com/minelittlepony/unicopia/block/state/ReversableBlockStateMap.java index 0d50c198..a2a2cb3b 100644 --- a/src/main/java/com/minelittlepony/unicopia/block/state/ReversableBlockStateMap.java +++ b/src/main/java/com/minelittlepony/unicopia/block/state/ReversableBlockStateMap.java @@ -1,18 +1,26 @@ package com.minelittlepony.unicopia.block.state; -class ReversableBlockStateMap extends BlockStateMap implements ReversableBlockStateConverter { - private static final long serialVersionUID = 6154365988455383098L; +import java.util.List; +import java.util.stream.Collectors; - private final BlockStateMap inverse = new BlockStateMap(); +class ReversableBlockStateMap extends BlockStateMap implements ReversableBlockStateConverter { + private final BlockStateMap inverse; + + ReversableBlockStateMap(List mappings) { + super(mappings); + inverse = new BlockStateMap(mappings.stream().map(StateMapping::inverse).collect(Collectors.toList())); + } @Override public BlockStateMap getInverse() { return inverse; } - @Override - public boolean add(StateMapping mapping) { - inverse.add(mapping.inverse()); - return super.add(mapping); + public static class Builder extends BlockStateMap.Builder { + @Override + @SuppressWarnings("unchecked") + public T build() { + return (T)new ReversableBlockStateMap(items); + } } } diff --git a/src/main/java/com/minelittlepony/unicopia/block/state/StateMapping.java b/src/main/java/com/minelittlepony/unicopia/block/state/StateMapping.java index 6bb4bd32..b22ee469 100644 --- a/src/main/java/com/minelittlepony/unicopia/block/state/StateMapping.java +++ b/src/main/java/com/minelittlepony/unicopia/block/state/StateMapping.java @@ -1,6 +1,5 @@ package com.minelittlepony.unicopia.block.state; -import java.util.Random; import java.util.function.BiFunction; import java.util.function.Function; import java.util.function.Predicate; @@ -10,13 +9,36 @@ import javax.annotation.Nonnull; import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.block.Blocks; +import net.minecraft.block.Material; +import net.minecraft.block.SnowBlock; import net.minecraft.state.property.Property; import net.minecraft.tag.Tag; import net.minecraft.world.World; interface StateMapping extends Predicate, BiFunction { - Random RNG = new Random(); + static StateMapping incrementSnow() { + return build( + isOf(Blocks.SNOW), + (w, s) -> { + s = s.cycle(SnowBlock.LAYERS); + if (s.get(SnowBlock.LAYERS) >= 7) { + return Blocks.SNOW_BLOCK.getDefaultState(); + } + + return s; + }); + } + static Predicate isOf(Block block) { + return s -> s.isOf(block); + } + + static StateMapping replaceMaterial(Material mat, Block block) { + return build(isOf(Material.WATER), Blocks.ICE); + } + static Predicate isOf(Material mat) { + return s -> s.getMaterial() == mat; + } static StateMapping removeBlock(Predicate mapper) { return build( @@ -24,10 +46,6 @@ interface StateMapping extends Predicate, BiFunction Blocks.AIR.getDefaultState()); } - static StateMapping removeBlock(Block from) { - return removeBlock(s -> s.isOf(from)); - } - static StateMapping replaceBlock(Tag tag, Block to) { return build( s -> s.isIn(tag), @@ -42,7 +60,7 @@ interface StateMapping extends Predicate, BiFunction s.getBlock() == from, + s -> s.isOf(from), (w, s) -> { BlockState newState = to.getDefaultState(); for (@SuppressWarnings("rawtypes") Property i : s.getProperties()) { @@ -57,21 +75,23 @@ interface StateMapping extends Predicate, BiFunction> StateMapping replaceProperty(Block block, Property property, T from, T to) { return build( - s -> s.getBlock() == block && s.get(property) == from, + s -> s.isOf(block) && s.get(property) == from, (w, s) -> s.with(property, to), s -> replaceProperty(block, property, to, from)); } - static > StateMapping setProperty(Block block, Property property, T to) { - return build( - s -> s.getBlock() == block, - (w, s) -> s.with(property, to)); + static StateMapping build(Predicate predicate, Block result) { + return build(predicate, (w, s) -> result.getDefaultState()); } static StateMapping build(Predicate predicate, BiFunction converter) { return build(predicate, converter, s -> s); } + static StateMapping build(Predicate predicate, Block result, Function inverter) { + return build(predicate, (w, s) -> result.getDefaultState(), inverter); + } + static StateMapping build(Predicate predicate, BiFunction converter, Function inverter) { return new StateMapping() { private StateMapping inverse; @@ -104,9 +124,7 @@ interface StateMapping extends Predicate, BiFunction, BiFunction { - a.add(StateMapping.build( - s -> s.getMaterial() == Material.WATER, - (w, s) -> Blocks.ICE.getDefaultState())); - a.add(StateMapping.build( - s -> s.getMaterial() == Material.LAVA, - (w, s) -> Blocks.OBSIDIAN.getDefaultState())); - a.add(StateMapping.build( - s -> s.getBlock() == Blocks.SNOW, - (w, s) -> { - s = s.cycle(SnowBlock.LAYERS); - if (s.get(SnowBlock.LAYERS) >= 7) { - return Blocks.SNOW_BLOCK.getDefaultState(); - } + private static final Registry REGISTRY = Registries.createSimple(new Identifier("unicopia", "state_map")); - return s; - })); - a.replaceBlock(Blocks.FIRE, Blocks.AIR); - a.setProperty(Blocks.REDSTONE_WIRE, RedstoneWireBlock.POWER, 0); - }), "ice"); + public static final BlockStateConverter ICE_AFFECTED = register("ice", new BlockStateMap.Builder() + .replaceMaterial(Material.WATER, Blocks.ICE) + .replaceMaterial(Material.LAVA, Blocks.OBSIDIAN) + .add(StateMapping.incrementSnow()) + .replaceBlock(Blocks.FIRE, Blocks.AIR) + .setProperty(Blocks.REDSTONE_WIRE, RedstoneWireBlock.POWER, 0)); - public static final ReversableBlockStateConverter MOSS_AFFECTED = register(Util.make(new ReversableBlockStateMap(), a -> { - a.replaceBlock(Blocks.MOSSY_COBBLESTONE, Blocks.COBBLESTONE); - a.replaceBlock(Blocks.MOSSY_COBBLESTONE_SLAB, Blocks.COBBLESTONE_SLAB); - a.replaceBlock(Blocks.MOSSY_COBBLESTONE_STAIRS, Blocks.COBBLESTONE_STAIRS); - a.replaceBlock(Blocks.MOSSY_COBBLESTONE_WALL, Blocks.COBBLESTONE_WALL); - a.replaceBlock(Blocks.MOSSY_STONE_BRICK_SLAB, Blocks.STONE_BRICK_SLAB); - a.replaceBlock(Blocks.MOSSY_STONE_BRICK_STAIRS, Blocks.STONE_BRICK_STAIRS); - a.replaceBlock(Blocks.MOSSY_STONE_BRICK_WALL, Blocks.MOSSY_STONE_BRICK_WALL); - a.replaceBlock(Blocks.MOSSY_STONE_BRICKS, Blocks.STONE_BRICKS); - a.replaceBlock(Blocks.INFESTED_MOSSY_STONE_BRICKS, Blocks.INFESTED_STONE_BRICKS); - }), "moss"); + public static final ReversableBlockStateConverter MOSS_AFFECTED = register("moss", new ReversableBlockStateMap.Builder() + .replaceBlock(Blocks.MOSSY_COBBLESTONE, Blocks.COBBLESTONE) + .replaceBlock(Blocks.MOSSY_COBBLESTONE_SLAB, Blocks.COBBLESTONE_SLAB) + .replaceBlock(Blocks.MOSSY_COBBLESTONE_STAIRS, Blocks.COBBLESTONE_STAIRS) + .replaceBlock(Blocks.MOSSY_COBBLESTONE_WALL, Blocks.COBBLESTONE_WALL) + .replaceBlock(Blocks.MOSSY_STONE_BRICK_SLAB, Blocks.STONE_BRICK_SLAB) + .replaceBlock(Blocks.MOSSY_STONE_BRICK_STAIRS, Blocks.STONE_BRICK_STAIRS) + .replaceBlock(Blocks.MOSSY_STONE_BRICK_WALL, Blocks.MOSSY_STONE_BRICK_WALL) + .replaceBlock(Blocks.MOSSY_STONE_BRICKS, Blocks.STONE_BRICKS) + .replaceBlock(Blocks.INFESTED_MOSSY_STONE_BRICKS, Blocks.INFESTED_STONE_BRICKS)); - public static final BlockStateConverter SILVERFISH_AFFECTED = register(Util.make(new BlockStateMap(), a -> { - a.replaceBlock(Blocks.CHISELED_STONE_BRICKS, Blocks.INFESTED_CHISELED_STONE_BRICKS); - a.replaceBlock(Blocks.COBBLESTONE, Blocks.INFESTED_COBBLESTONE); - a.replaceBlock(Blocks.CRACKED_STONE_BRICKS, Blocks.INFESTED_CRACKED_STONE_BRICKS); - a.replaceBlock(Blocks.MOSSY_STONE_BRICKS, Blocks.INFESTED_MOSSY_STONE_BRICKS); - a.replaceBlock(Blocks.STONE, Blocks.INFESTED_STONE); - a.replaceBlock(Blocks.STONE_BRICKS, Blocks.INFESTED_STONE_BRICKS); - }), "infestation"); + public static final BlockStateConverter SILVERFISH_AFFECTED = register("infestation", new BlockStateMap.Builder() + .replaceBlock(Blocks.CHISELED_STONE_BRICKS, Blocks.INFESTED_CHISELED_STONE_BRICKS) + .replaceBlock(Blocks.COBBLESTONE, Blocks.INFESTED_COBBLESTONE) + .replaceBlock(Blocks.CRACKED_STONE_BRICKS, Blocks.INFESTED_CRACKED_STONE_BRICKS) + .replaceBlock(Blocks.MOSSY_STONE_BRICKS, Blocks.INFESTED_MOSSY_STONE_BRICKS) + .replaceBlock(Blocks.STONE, Blocks.INFESTED_STONE) + .replaceBlock(Blocks.STONE_BRICKS, Blocks.INFESTED_STONE_BRICKS)); - public static final BlockStateConverter FIRE_AFFECTED = register(Util.make(new BlockStateMap(), a -> { - a.removeBlock(Blocks.SNOW); - a.removeBlock(Blocks.SNOW_BLOCK); - a.removeBlock(s -> s.getBlock() instanceof PlantBlock); - a.replaceBlock(Blocks.ICE, Blocks.WATER); - a.replaceBlock(Blocks.PACKED_ICE, Blocks.WATER); - a.replaceBlock(Blocks.CLAY, Blocks.BROWN_CONCRETE); - a.replaceBlock(Blocks.OBSIDIAN, Blocks.LAVA); - a.replaceBlock(Blocks.GRASS_BLOCK, Blocks.DIRT); - a.replaceBlock(Blocks.MOSSY_COBBLESTONE, Blocks.COBBLESTONE); - a.replaceBlock(Blocks.MOSSY_COBBLESTONE_WALL, Blocks.COBBLESTONE_WALL); - a.replaceBlock(Blocks.MOSSY_STONE_BRICKS, Blocks.STONE_BRICKS); - a.replaceBlock(Blocks.INFESTED_MOSSY_STONE_BRICKS, Blocks.INFESTED_STONE_BRICKS); - a.replaceBlock(Blocks.PODZOL, Blocks.COARSE_DIRT); - a.setProperty(Blocks.FARMLAND, FarmlandBlock.MOISTURE, 0); - a.add(StateMapping.build( - s -> s.getBlock() == Blocks.DIRT, - (w, s) -> (w.random.nextFloat() <= 0.15 ? Blocks.COARSE_DIRT.getDefaultState() : s))); - }), "fire"); + public static final BlockStateConverter FIRE_AFFECTED = register("fire", new BlockStateMap.Builder() + .removeBlock(Blocks.SNOW) + .removeBlock(Blocks.SNOW_BLOCK) + .removeBlock(StateMaps::isPlant) + .replaceBlock(Blocks.ICE, Blocks.WATER) + .replaceBlock(Blocks.PACKED_ICE, Blocks.WATER) + .replaceBlock(Blocks.CLAY, Blocks.BROWN_CONCRETE) + .replaceBlock(Blocks.OBSIDIAN, Blocks.LAVA) + .replaceBlock(Blocks.GRASS_BLOCK, Blocks.DIRT) + .replaceBlock(Blocks.MOSSY_COBBLESTONE, Blocks.COBBLESTONE) + .replaceBlock(Blocks.MOSSY_COBBLESTONE_WALL, Blocks.COBBLESTONE_WALL) + .replaceBlock(Blocks.MOSSY_STONE_BRICKS, Blocks.STONE_BRICKS) + .replaceBlock(Blocks.INFESTED_MOSSY_STONE_BRICKS, Blocks.INFESTED_STONE_BRICKS) + .replaceBlock(Blocks.PODZOL, Blocks.COARSE_DIRT) + .setProperty(Blocks.FARMLAND, FarmlandBlock.MOISTURE, 0) + .add(StateMapping.build(isOf(Blocks.DIRT), (w, s) -> (w.random.nextFloat() <= 0.15 ? Blocks.COARSE_DIRT.getDefaultState() : s)))); - public static final ReversableBlockStateConverter HELLFIRE_AFFECTED = register(Util.make(new ReversableBlockStateMap(), a -> { - a.replaceBlock(Blocks.GRASS_BLOCK, Blocks.WARPED_NYLIUM); - a.replaceBlock(Blocks.STONE, Blocks.NETHERRACK); - a.replaceBlock(Blocks.SAND, Blocks.SOUL_SAND); - a.replaceBlock(Blocks.GRAVEL, Blocks.SOUL_SAND); - a.replaceBlock(Blocks.DIRT, Blocks.SOUL_SOIL); - a.replaceBlock(Blocks.COARSE_DIRT, Blocks.SOUL_SOIL); - a.replaceBlock(Blocks.TORCH, Blocks.SOUL_TORCH); - a.replaceBlock(Blocks.WALL_TORCH, Blocks.SOUL_WALL_TORCH); - a.replaceBlock(Blocks.OAK_LOG, Blocks.WARPED_STEM); - a.replaceBlock(Blocks.STRIPPED_OAK_LOG, Blocks.STRIPPED_WARPED_STEM); - a.replaceBlock(Blocks.STRIPPED_OAK_WOOD, Blocks.STRIPPED_WARPED_HYPHAE); - a.replaceBlock(Blocks.OAK_PLANKS, Blocks.WARPED_PLANKS); - a.replaceBlock(Blocks.OAK_DOOR, Blocks.WARPED_DOOR); - a.replaceBlock(Blocks.OAK_STAIRS, Blocks.WARPED_STAIRS); - a.replaceBlock(Blocks.OAK_TRAPDOOR, Blocks.WARPED_TRAPDOOR); - a.replaceBlock(Blocks.OAK_PRESSURE_PLATE, Blocks.WARPED_PRESSURE_PLATE); - a.replaceBlock(Blocks.OAK_BUTTON, Blocks.WARPED_BUTTON); - a.replaceBlock(Blocks.OAK_FENCE, Blocks.WARPED_FENCE); - a.replaceBlock(Blocks.OAK_FENCE_GATE, Blocks.WARPED_FENCE_GATE); - a.replaceBlock(BlockTags.LEAVES, Blocks.WARPED_HYPHAE); - a.add(StateMapping.build( - s -> s.getMaterial() == Material.WATER, - (w, s) -> Blocks.OBSIDIAN.getDefaultState(), - s -> StateMapping.replaceBlock(Blocks.OBSIDIAN, Blocks.WATER))); - a.add(StateMapping.build( - s -> s.getBlock() instanceof PlantBlock, - (w, s) -> Blocks.NETHER_WART.getDefaultState(), - s -> StateMapping.replaceBlock(Blocks.NETHER_WART, Blocks.GRASS))); - a.add(StateMapping.build( - s -> (s.getBlock() != Blocks.NETHER_QUARTZ_ORE) && (s.getBlock() instanceof OreBlock), - (w, s) -> Blocks.NETHER_QUARTZ_ORE.getDefaultState(), - s -> StateMapping.replaceBlock(Blocks.NETHER_QUARTZ_ORE, Blocks.COAL_ORE))); - }), "hellfire"); + public static final ReversableBlockStateConverter HELLFIRE_AFFECTED = register("hellfire", new ReversableBlockStateMap.Builder() + .replaceBlock(Blocks.GRASS_BLOCK, Blocks.WARPED_NYLIUM) + .replaceBlock(Blocks.STONE, Blocks.NETHERRACK) + .replaceBlock(Blocks.SAND, Blocks.SOUL_SAND) + .replaceBlock(Blocks.GRAVEL, Blocks.SOUL_SAND) + .replaceBlock(Blocks.DIRT, Blocks.SOUL_SOIL) + .replaceBlock(Blocks.COARSE_DIRT, Blocks.SOUL_SOIL) + .replaceBlock(Blocks.TORCH, Blocks.SOUL_TORCH) + .replaceBlock(Blocks.WALL_TORCH, Blocks.SOUL_WALL_TORCH) + .replaceBlock(Blocks.OAK_LOG, Blocks.WARPED_STEM) + .replaceBlock(Blocks.STRIPPED_OAK_LOG, Blocks.STRIPPED_WARPED_STEM) + .replaceBlock(Blocks.STRIPPED_OAK_WOOD, Blocks.STRIPPED_WARPED_HYPHAE) + .replaceBlock(Blocks.OAK_PLANKS, Blocks.WARPED_PLANKS) + .replaceBlock(Blocks.OAK_DOOR, Blocks.WARPED_DOOR) + .replaceBlock(Blocks.OAK_STAIRS, Blocks.WARPED_STAIRS) + .replaceBlock(Blocks.OAK_TRAPDOOR, Blocks.WARPED_TRAPDOOR) + .replaceBlock(Blocks.OAK_PRESSURE_PLATE, Blocks.WARPED_PRESSURE_PLATE) + .replaceBlock(Blocks.OAK_BUTTON, Blocks.WARPED_BUTTON) + .replaceBlock(Blocks.OAK_FENCE, Blocks.WARPED_FENCE) + .replaceBlock(Blocks.OAK_FENCE_GATE, Blocks.WARPED_FENCE_GATE) + .replaceBlock(BlockTags.LEAVES, Blocks.WARPED_HYPHAE) + .replaceMaterial(Material.WATER, Blocks.OBSIDIAN) + .add(StateMapping.build(StateMaps::isPlant, Blocks.NETHER_WART, s -> StateMapping.replaceBlock(Blocks.NETHER_WART, Blocks.GRASS))) + .add(StateMapping.build(s -> !s.isOf(Blocks.NETHER_QUARTZ_ORE) && isOre(s), Blocks.NETHER_QUARTZ_ORE, s -> StateMapping.replaceBlock(Blocks.NETHER_QUARTZ_ORE, Blocks.COAL_ORE)))); - private static T register(T value, String name) { - return value; + private static T register(String name, BlockStateMap.Builder value) { + return Registry.register(REGISTRY, new Identifier("unicopia", name), value.build()); + } + + static Predicate isOf(Block block) { + return s -> s.isOf(block); + } + static boolean isPlant(BlockState s) { + return s.getBlock() instanceof PlantBlock; + } + static boolean isOre(BlockState s) { + return s.getBlock() instanceof OreBlock; } }