Skip to content

Commit

Permalink
Start moving to IBlockState more.
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelzangl committed Jul 3, 2017
1 parent 91b6774 commit ff8cb24
Show file tree
Hide file tree
Showing 6 changed files with 218 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package net.famzangl.minecraft.minebot.ai.command;

import java.util.Collection;
import java.util.List;

/**
* This is the definition of a single argument to be passed on the command line.
Expand All @@ -42,10 +43,20 @@ public ArgumentDefinition(String descriptionType, String descriptionInfo) {
this.descriptionInfo = descriptionInfo;
}

public void getTabCompleteOptions(List<String> previousArguments, String currentStart,
Collection<String> addTo) {
getTabCompleteOptions(currentStart, addTo);
}

public void getTabCompleteOptions(String currentStart,
Collection<String> addTo) {
}


public boolean couldEvaluateAgainst(List<String> previousArguments, String string) {
return couldEvaluateAgainst(string);
}

/**
* Check if this argument could be from that parameter. Checks e.g. for
* integer values.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
/*******************************************************************************
* This file is part of Minebot.
*
* Minebot is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Minebot 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Minebot. If not, see <http://www.gnu.org/licenses/>.
*******************************************************************************/
package net.famzangl.minecraft.minebot.ai.command;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Stream;

import net.famzangl.minecraft.minebot.ai.AIHelper;
import net.famzangl.minecraft.minebot.ai.command.AICommandParameter.BlockFilter;
import net.minecraft.block.Block;
import net.minecraft.block.properties.IProperty;
import net.minecraft.command.CommandBase;
import net.minecraft.command.CommandFill;
import net.minecraft.command.InvalidBlockStateException;
import net.minecraft.command.NumberInvalidException;

public class BlockStateNameBuilder extends ParameterBuilder {


private static final String DEFAULT_STATE = "default";

public BlockStateNameBuilder(AICommandParameter annot) {
super(annot);
}

@Override
public void addArguments(ArrayList<ArgumentDefinition> list) {
Class<? extends BlockFilter> blockFilterClass = annot.blockFilter();
list.add(new ArgumentDefinition("Block", annot.description()) {
private final BlockFilter blockFilter;
{
BlockFilter blockFilter;
try {
blockFilter = blockFilterClass.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
blockFilter = new AICommandParameter.AnyBlockFilter();
} catch (IllegalAccessException e) {
e.printStackTrace();
blockFilter = new AICommandParameter.AnyBlockFilter();
}
this.blockFilter = blockFilter;
}

@Override
public boolean couldEvaluateAgainst(String string) {
try {
Block block = CommandBase.getBlockByText(null, string);
return blockFilter.matches(new BlockWithDontcare(block));
} catch (NumberInvalidException e) {
return false;
}
}

@Override
public void getTabCompleteOptions(String currentStart,
Collection<String> addTo) {
Block.REGISTRY.getKeys()
.stream()
.filter(name -> blockFilter.matches(new BlockWithDontcare(Block.REGISTRY.getObject(name))))
.map(Object::toString)
.filter(name -> name.startsWith(currentStart))
.forEach(addTo::add);
}
});
list.add(new ArgumentDefinition("Meta", "Meta value for that block, '" + DEFAULT_STATE + "' for default") {

public boolean couldEvaluateAgainst(List<String> previousArguments, String string) {
if (DEFAULT_STATE.equals(string)) {
return true;
}
try {
Block block = CommandBase.getBlockByText(null, previousArguments.get(previousArguments.size() - 1));
CommandFill.convertArgToBlockState(block, string);
return true;
} catch (NumberInvalidException | InvalidBlockStateException e) {
return false;
}

};

@Override
public void getTabCompleteOptions(List<String> previousArguments, String currentStart,
Collection<String> addTo) {
if (DEFAULT_STATE.startsWith(currentStart)) {
addTo.add(DEFAULT_STATE);
}

try {
Block block = CommandBase.getBlockByText(null, previousArguments.get(previousArguments.size() - 1));

Matcher inValuePart = Pattern.compile("^(<start>.*,(<key>[^,=]*)=)(<value>[^=,]*)$").matcher(currentStart);
if (inValuePart.matches()) {
String key = inValuePart.group("key");
String valueStart = inValuePart.group("value");

IProperty<?> property = block.getBlockState().getProperty(key);
if (property != null) {
propertyNames(property)
.filter(name -> name.startsWith(valueStart))
.forEach(name -> addTo.add(inValuePart.group("start") + name));
}

} else {
Matcher inKeyPart = Pattern.compile("^(<start>.*,|)(<key>[^,=]*)$").matcher(currentStart);
if (inKeyPart.matches()) {
String keyStart = inValuePart.group("key");

block.getBlockState().getProperties().stream()
.map(p -> p.getName())
.filter(name -> name.startsWith(keyStart))
.forEach(name -> addTo.add(inKeyPart.group("start") + name));
}
}
} catch (NumberInvalidException e) {
//ignore
}
}

private <T extends Comparable<T>> Stream<String> propertyNames(IProperty<T> property) {
return property.getAllowedValues()
.stream()
.map(value -> property.getName(value));
}
});

}

@Override
public Object getParameter(AIHelper helper, String[] arguments) {
try {
Block block = CommandBase.getBlockByText(null, arguments[0]);
if (DEFAULT_STATE.equals(arguments[1])) {
return block.getDefaultState();
} else {
return CommandFill.convertArgToBlockState(block, arguments[1]);
}

} catch (NumberInvalidException e) {
// Should not happen - we have an arg def for this
throw new RuntimeException(e);
} catch (InvalidBlockStateException e) {
// Should not happen - we have an arg def for this
throw new RuntimeException(e);
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,9 @@ private static ParameterBuilder getParameter(Method method,
case STRING:
builder = new StringNameBuilder(annot);
break;
case BLOCK_STATE:
builder = new BlockStateNameBuilder(annot);
break;
default:
throw new IllegalArgumentException("Unknown type: "
+ annot.type());
Expand Down Expand Up @@ -210,7 +213,7 @@ public boolean couldEvaluateStartingWith(String[] arguments2) {
return false;
}
for (int i = 0; i < arguments2.length; i++) {
if (!arguments.get(i).couldEvaluateAgainst(arguments2[i])) {
if (!arguments.get(i).couldEvaluateAgainst(Arrays.asList(arguments2).subList(0, i), arguments2[i])) {
return false;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,6 @@ public enum ParameterType {
FILE,
POSITION,
ENUM,
STRING
STRING,
BLOCK_STATE
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import net.famzangl.minecraft.minebot.ai.task.place.SneakAndPlaceAtSideTask;
import net.minecraft.block.Block;
import net.minecraft.block.BlockStairs.EnumHalf;
import net.minecraft.command.CommandFill;
import net.minecraft.init.Blocks;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,9 @@
import net.famzangl.minecraft.minebot.build.blockbuild.SlabBuildTask;
import net.famzangl.minecraft.minebot.build.blockbuild.StandingSignBuildTask;
import net.famzangl.minecraft.minebot.build.blockbuild.StandingSignBuildTask.SignDirection;
import net.minecraft.block.BlockStairs;
import net.minecraft.block.BlockStairs.EnumHalf;
import net.minecraft.block.state.IBlockState;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;

Expand All @@ -56,7 +58,7 @@ private ScheduleTaskStrategy(BuildTask task) {

@Override
protected void singleRun(AIHelper helper) {
addTask(helper, task);
helper.buildManager.addTask(task);
}
}

Expand Down Expand Up @@ -88,6 +90,22 @@ public static AIStrategy runSimple(
return new ScheduleTaskStrategy(task);
}


@AICommandInvocation()
public static AIStrategy runSimple(
AIHelper helper,
@AICommandParameter(type = ParameterType.FIXED, fixedName = "schedule", description = "") String nameArg,
@AICommandParameter(type = ParameterType.POSITION, description = "Where to place it (relative is to your current pos)") BlockPos forPosition,
@AICommandParameter(type = ParameterType.BLOCK_STATE, description = "The block", blockFilter=StairsBlockFilter.class) IBlockState blockToPlace) {
BuildNormalStairsTask task;
if (BuildNormalStairsTask.BLOCKS.contains(blockToPlace)) {
task = new BuildNormalStairsTask(forPosition, blockToPlace.getBlock(), blockToPlace.getValue(BlockStairs.FACING), blockToPlace.getValue(BlockStairs.HALF));
} else {
throw new CommandEvaluationException("Cannot build " + blockToPlace);
}
return new ScheduleTaskStrategy(task);
}

// public static final class RunColoredFilter extends BlockFilter {
// @Override
// public boolean matches(Block b) {
Expand Down Expand Up @@ -184,21 +202,21 @@ public boolean matches(BlockWithDataOrDontcare b) {

// TODO: Merge with Factory

@AICommandInvocation()
public static AIStrategy run(AIHelper helper,
@AICommandParameter(type = ParameterType.FIXED, fixedName = "schedule", description = "") String nameArg,
@AICommandParameter(type = ParameterType.POSITION, description = "Where to place it (relative is to your current pos)") BlockPos forPosition,
@AICommandParameter(type = ParameterType.BLOCK_NAME, description = "The block", blockFilter = StairsBlockFilter.class) BlockWithDataOrDontcare blockToPlace,
@AICommandParameter(type = ParameterType.ENUM, description = "The direction the stairs face") EnumFacing direction,
@AICommandParameter(type = ParameterType.ENUM, description = "Upper for inverted stairs", optional = true) EnumHalf half) {
if (BuildNormalStairsTask.BLOCKS.contains(blockToPlace)) {
addTask(helper,
new BuildNormalStairsTask(forPosition, blockToPlace.getBlock(), direction, half == null ? EnumHalf.BOTTOM : half));
} else {
throw new CommandEvaluationException("Cannot build " + blockToPlace);
}
return null;
}
// @AICommandInvocation()
// public static AIStrategy run(AIHelper helper,
// @AICommandParameter(type = ParameterType.FIXED, fixedName = "schedule", description = "") String nameArg,
// @AICommandParameter(type = ParameterType.POSITION, description = "Where to place it (relative is to your current pos)") BlockPos forPosition,
// @AICommandParameter(type = ParameterType.BLOCK_NAME, description = "The block", blockFilter = StairsBlockFilter.class) BlockWithDataOrDontcare blockToPlace,
// @AICommandParameter(type = ParameterType.ENUM, description = "The direction the stairs face") EnumFacing direction,
// @AICommandParameter(type = ParameterType.ENUM, description = "Upper for inverted stairs", optional = true) EnumHalf half) {
// if (BuildNormalStairsTask.BLOCKS.contains(blockToPlace)) {
// addTask(helper,
// new BuildNormalStairsTask(forPosition, blockToPlace.getBlock(), direction, half == null ? EnumHalf.BOTTOM : half));
// } else {
// throw new CommandEvaluationException("Cannot build " + blockToPlace);
// }
// return null;
// }

public static final class SignBlockFilter extends BlockFilter {
@Override
Expand Down Expand Up @@ -226,8 +244,4 @@ public static AIStrategy run(
throw new CommandEvaluationException("Cannot build " + blockToPlace);
}
}

private static void addTask(AIHelper helper, BuildTask blockBuildTask) {
helper.buildManager.addTask(blockBuildTask);
}
}

0 comments on commit ff8cb24

Please sign in to comment.