From 2a194b0434332b12909d994d17801b702ebd7cad Mon Sep 17 00:00:00 2001 From: wizjany Date: Tue, 26 Mar 2019 18:11:32 -0400 Subject: [PATCH] Add pattern that randomly chooses states. Also works with fuzzy states. Syntax is `*type`, e.g. `//set *stone_slab` or with states, `//set *oak_fence[waterlogged=false]` --- .../extension/factory/PatternFactory.java | 4 +- .../pattern/RandomStatePatternParser.java | 56 +++++++++++++++++++ .../pattern/SingleBlockPatternParser.java | 8 +-- .../function/pattern/RandomStatePattern.java | 45 +++++++++++++++ 4 files changed, 105 insertions(+), 8 deletions(-) create mode 100644 worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/pattern/RandomStatePatternParser.java create mode 100644 worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/RandomStatePattern.java diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/PatternFactory.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/PatternFactory.java index 8c23c4ef8..8457f3fc3 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/PatternFactory.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/PatternFactory.java @@ -23,6 +23,7 @@ import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.extension.factory.parser.pattern.BlockCategoryPatternParser; import com.sk89q.worldedit.extension.factory.parser.pattern.ClipboardPatternParser; import com.sk89q.worldedit.extension.factory.parser.pattern.RandomPatternParser; +import com.sk89q.worldedit.extension.factory.parser.pattern.RandomStatePatternParser; import com.sk89q.worldedit.extension.factory.parser.pattern.SingleBlockPatternParser; import com.sk89q.worldedit.extension.factory.parser.pattern.TypeOrStateApplyingPatternParser; import com.sk89q.worldedit.function.pattern.Pattern; @@ -52,8 +53,9 @@ public final class PatternFactory extends AbstractFactory { register(new BlockCategoryPatternParser(worldEdit)); register(new ClipboardPatternParser(worldEdit)); register(new TypeOrStateApplyingPatternParser(worldEdit)); + register(new RandomStatePatternParser(worldEdit)); - // inner-most pattern: just one block + // inner-most pattern: just one block - must be last register(new SingleBlockPatternParser(worldEdit)); } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/pattern/RandomStatePatternParser.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/pattern/RandomStatePatternParser.java new file mode 100644 index 000000000..27423f59e --- /dev/null +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/pattern/RandomStatePatternParser.java @@ -0,0 +1,56 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * Copyright (C) WorldEdit team and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldedit.extension.factory.parser.pattern; + +import com.sk89q.worldedit.WorldEdit; +import com.sk89q.worldedit.extension.input.InputParseException; +import com.sk89q.worldedit.extension.input.ParserContext; +import com.sk89q.worldedit.function.pattern.BlockPattern; +import com.sk89q.worldedit.function.pattern.Pattern; +import com.sk89q.worldedit.function.pattern.RandomStatePattern; +import com.sk89q.worldedit.internal.registry.InputParser; +import com.sk89q.worldedit.world.block.BaseBlock; +import com.sk89q.worldedit.world.block.FuzzyBlockState; + +public class RandomStatePatternParser extends InputParser { + public RandomStatePatternParser(WorldEdit worldEdit) { + super(worldEdit); + } + + @Override + public Pattern parseFromInput(String input, ParserContext context) throws InputParseException { + if (!input.startsWith("*")) { + return null; + } + + boolean wasFuzzy = context.isPreferringWildcard(); + context.setPreferringWildcard(true); + BaseBlock block = worldEdit.getBlockFactory().parseFromInput(input.substring(1), context); + context.setPreferringWildcard(wasFuzzy); + if (block.getStates().size() == block.getBlockType().getPropertyMap().size()) { + // they requested random with *, but didn't leave any states empty - simplify + return new BlockPattern(block); + } else if (block.toImmutableState() instanceof FuzzyBlockState) { + return new RandomStatePattern((FuzzyBlockState) block.toImmutableState()); + } else { + return null; // only should happen if parseLogic changes + } + } +} diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/pattern/SingleBlockPatternParser.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/pattern/SingleBlockPatternParser.java index 960983780..e71530a2e 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/pattern/SingleBlockPatternParser.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/pattern/SingleBlockPatternParser.java @@ -34,13 +34,7 @@ public class SingleBlockPatternParser extends InputParser { @Override public Pattern parseFromInput(String input, ParserContext context) throws InputParseException { - String[] items = input.split(","); - - if (items.length == 1) { - return new BlockPattern(worldEdit.getBlockFactory().parseFromInput(items[0], context)); - } else { - return null; - } + return new BlockPattern(worldEdit.getBlockFactory().parseFromInput(input, context)); } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/RandomStatePattern.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/RandomStatePattern.java new file mode 100644 index 000000000..f2e2870a9 --- /dev/null +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/RandomStatePattern.java @@ -0,0 +1,45 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * Copyright (C) WorldEdit team and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldedit.function.pattern; + +import com.sk89q.worldedit.math.BlockVector3; +import com.sk89q.worldedit.world.block.BaseBlock; +import com.sk89q.worldedit.world.block.BlockState; +import com.sk89q.worldedit.world.block.FuzzyBlockState; + +import java.util.List; +import java.util.Random; +import java.util.stream.Collectors; + +public class RandomStatePattern implements Pattern { + + private final Random rand = new Random(); + private final List blocks; + + public RandomStatePattern(FuzzyBlockState state) { + blocks = state.getBlockType().getAllStates().stream().filter(state::equalsFuzzy) + .map(BlockState::toBaseBlock).collect(Collectors.toList()); + } + + @Override + public BaseBlock apply(BlockVector3 position) { + return blocks.get(rand.nextInt(blocks.size())); + } +}