Skip to content

Commit

Permalink
Add /minebot stack command, make /minebot tunnel | craft | store | re…
Browse files Browse the repository at this point in the history
…sume | respawn | clear compatible to 1.15
  • Loading branch information
michaelzangl committed May 17, 2020
1 parent b55add2 commit f4326ab
Show file tree
Hide file tree
Showing 48 changed files with 1,018 additions and 668 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import net.famzangl.minecraft.minebot.ai.command.AIChatController;
import net.famzangl.minecraft.minebot.ai.command.IAIControllable;
import net.famzangl.minecraft.minebot.ai.command.SafeStrategyRule;
import net.famzangl.minecraft.minebot.ai.command.StackBuilder;
import net.famzangl.minecraft.minebot.ai.net.MinebotNetHandler;
import net.famzangl.minecraft.minebot.ai.net.NetworkHelper;
import net.famzangl.minecraft.minebot.ai.path.world.BlockBoundsCache;
Expand Down Expand Up @@ -58,6 +59,8 @@
*
*/
public class AIController extends AIHelper implements IAIControllable {
private final StackBuilder stackBuilder = new StackBuilder();

private final class UngrabMouseHelper extends MouseHelper {
public UngrabMouseHelper(Minecraft minecraftIn) {
super(minecraftIn);
Expand Down Expand Up @@ -87,26 +90,6 @@ public void ungrabMouse() {
InputMappings.getInputByName("key.keyboard.u").getKeyCode(), "Command Mod");

static {
// final KeyBinding mine = new KeyBinding("Farm ores",
// Keyboard.getKeyIndex("K"), "Command Mod");
// final KeyBinding lumberjack = new KeyBinding("Farm wood",
// Keyboard.getKeyIndex("J"), "Command Mod");
// final KeyBinding build_rail = new KeyBinding("Build Minecart tracks",
// Keyboard.getKeyIndex("H"), "Command Mod");
// final KeyBinding mobfarm = new KeyBinding("Farm mobs",
// Keyboard.getKeyIndex("M"), "Command Mod");
// final KeyBinding plant = new KeyBinding("Plant seeds",
// Keyboard.getKeyIndex("P"), "Command Mod");
// uses.put(mine, new MineStrategy());
// uses.put(lumberjack, new LumberjackStrategy());
// uses.put(build_rail, new LayRailStrategy());
// uses.put(mobfarm, new EnchantStrategy());
// uses.put(plant, new PlantStrategy());
// ClientRegistry.registerKeyBinding(mine);
// ClientRegistry.registerKeyBinding(lumberjack);
// ClientRegistry.registerKeyBinding(build_rail);
// ClientRegistry.registerKeyBinding(mobfarm);
// ClientRegistry.registerKeyBinding(plant);
ClientRegistry.registerKeyBinding(stop);
ClientRegistry.registerKeyBinding(ungrab);
}
Expand Down Expand Up @@ -400,31 +383,15 @@ public int requestUseStrategy(AIStrategy strategy) {

@Override
public int requestUseStrategy(AIStrategy strategy, SafeStrategyRule rule) {
LOGGER.trace(MARKER_STRATEGY, "Request to use strategy " + strategy + " using saferule " + rule);

requestedStrategy = makeSafe(strategy, rule);

return 1;
}
private AIStrategy makeSafe(AIStrategy strategy, SafeStrategyRule safeRule) {
if (safeRule == SafeStrategyRule.NONE) {
return strategy;
if (stackBuilder.collect(strategy, rule)) {
// We are in strack building mode (/minebot stack), only schedule strategy
LOGGER.debug(MARKER_STRATEGY, "Scheduled strategy for stack: {}", strategy);
AIChatController.addChatLine("Strategy scheduled. To start, use: /minebot stack done");
} else {
final StrategyStack stack = new StrategyStack();
stack.addStrategy(new AbortOnDeathStrategy());
if (safeRule == SafeStrategyRule.DEFEND_MINING) {
stack.addStrategy(new DoNotSuffocateStrategy());
}
stack.addStrategy(new DamageTakenStrategy());
stack.addStrategy(new PlayerComesActionStrategy());
stack.addStrategy(new CreeperComesActionStrategy());
stack.addStrategy(new EatStrategy());
if (safeRule == SafeStrategyRule.DEFEND_MINING) {
stack.addStrategy(new PlaceTorchStrategy());
}
stack.addStrategy(strategy);
return new StackStrategy(stack);
LOGGER.debug(MARKER_STRATEGY, "Request to use strategy {} using saferule {}", strategy, rule);
requestedStrategy = rule.makeSafe(strategy);
}
return 1;
}

// @SubscribeEvent
Expand Down Expand Up @@ -461,4 +428,9 @@ public NetworkHelper getNetworkHelper() {
return networkHelper;
}


@Override
public StackBuilder getStackBuilder() {
return stackBuilder;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
import net.minecraft.util.Direction;
import net.minecraft.util.MovementInput;
import net.minecraft.util.math.*;
import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.LightType;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.Marker;
Expand Down Expand Up @@ -117,8 +117,9 @@ private static double randBetween(double a, double b) {

protected void invalidateChunkCache() {
if (minecraftWorld == null
|| getMinecraft().world != minecraftWorld.getBackingWorld()) {
if (getMinecraft().world == null) {
|| getMinecraft().world != minecraftWorld.getBackingWorld()
|| getMinecraft().player != minecraftWorld.getBackingPlayer()) {
if (getMinecraft().world == null || getMinecraft().player == null) {
minecraftWorld = null;
} else {
minecraftWorld = new WorldData(
Expand Down Expand Up @@ -1036,9 +1037,7 @@ public static Direction getDirectionFor(BlockPos delta) {

// TODO: Move this to WorldData
public int getLightAt(BlockPos pos) {
final Chunk chunk = getMinecraft().world.getChunk(
pos.getX() >> 4, pos.getZ() >> 4);
return chunk.getLightValue(pos);
return getMinecraft().world.getLightFor(LightType.BLOCK, pos);
}

public void setActiveMapReader(MapReader activeMapReader) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ public class PathFinderField implements Comparator<Integer> {
*/
private int[] field;
private long startTime;
protected int statsVisited;

public PathFinderField() {
}
Expand Down Expand Up @@ -235,6 +236,7 @@ protected boolean searchSomethingAround(int cx, int cy, int cz) {
} else {
currentDest = null;
}
statsVisited = 0;
isRunning = true;
}
LOGGER.trace(MARKER_PATH, "Start path finding.");
Expand Down Expand Up @@ -288,6 +290,7 @@ protected boolean searchSomethingAround(int cx, int cy, int cz) {
}
}
setVisited(currentNode);
statsVisited++;
}
if (pqEmpty()) {
if (currentDest != null) {
Expand Down Expand Up @@ -343,7 +346,7 @@ protected int distanceFor(int from, int to) {
}

protected void noPathFound() {
LOGGER.info(MARKER_PATH, "Path finder did not find a path.");
LOGGER.info(MARKER_PATH, "Path finder did not find a path. Positions visited: {}", statsVisited);
}

private void planPathTo(int currentNode, int origX, int origY, int origZ) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,11 @@ public int requestUseStrategy(AIStrategy strategy) {
return 0;
}

@Override
public StackBuilder getStackBuilder() {
throw new UnsupportedOperationException("Cannot use /minebot stack in scripts");
}

public AIStrategy get() {
if (strategy == null) {
throw new IllegalStateException("No strategy has been set");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,4 +53,9 @@ default int requestUseStrategy(AIStrategy strategy, SafeStrategyRule rule) {
return requestUseStrategy(strategy);
}

/**
* The stack builder. Used for stacking tasks on the command line
* @return A stack builder instance
*/
StackBuilder getStackBuilder();
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,44 @@
*******************************************************************************/
package net.famzangl.minecraft.minebot.ai.command;

import net.famzangl.minecraft.minebot.ai.strategy.*;

public enum SafeStrategyRule {
NONE,
DEFEND,
DEFEND_MINING
NONE {
@Override
public AIStrategy makeSafe(AIStrategy strategy) {
// NOP
return strategy;
}
},
DEFEND {
@Override
public AIStrategy makeSafe(AIStrategy strategy) {
final StrategyStack stack = new StrategyStack();
stack.addStrategy(new AbortOnDeathStrategy());
stack.addStrategy(new DamageTakenStrategy());
stack.addStrategy(new PlayerComesActionStrategy());
stack.addStrategy(new CreeperComesActionStrategy());
stack.addStrategy(new EatStrategy());
stack.addStrategy(strategy);
return new StackStrategy(stack);
}
},
DEFEND_MINING {
@Override
public AIStrategy makeSafe(AIStrategy strategy) {
final StrategyStack stack = new StrategyStack();
stack.addStrategy(new AbortOnDeathStrategy());
stack.addStrategy(new DoNotSuffocateStrategy());
stack.addStrategy(new DamageTakenStrategy());
stack.addStrategy(new PlayerComesActionStrategy());
stack.addStrategy(new CreeperComesActionStrategy());
stack.addStrategy(new EatStrategy());
stack.addStrategy(new PlaceTorchStrategy());
stack.addStrategy(strategy);
return new StackStrategy(stack);
}
};

public abstract AIStrategy makeSafe(AIStrategy strategy);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package net.famzangl.minecraft.minebot.ai.command;

import net.famzangl.minecraft.minebot.ai.strategy.AIStrategy;
import net.famzangl.minecraft.minebot.ai.strategy.StackStrategy;
import net.famzangl.minecraft.minebot.ai.strategy.StrategyStack;

import java.util.ArrayList;

/**
* Schedule a stack of strategies and start using them
*/
public class StackBuilder {

private boolean collecting;
private ArrayList<AIStrategy> collected = new ArrayList<>();
private SafeStrategyRule hardestSafeRule = SafeStrategyRule.NONE;

public void startCollecting() {
this.collecting = true;
collected.clear();
hardestSafeRule = SafeStrategyRule.NONE;
}

public boolean collect(AIStrategy strategy, SafeStrategyRule rule) {
if (collecting) {
collected.add(strategy);
if (rule.ordinal() > hardestSafeRule.ordinal()) {
hardestSafeRule = rule;
}
return true;
} else {
return false;
}
}

public AIStrategy getStrategy() {
collecting = false;
StrategyStack stack = new StrategyStack();
collected.forEach(stack::addStrategy);

collected.clear(); // < to save memory
return new StackStrategy(stack);
}

public void abort() {
collecting = false;
collected.clear(); // < to save memory
}

public boolean hasCollectedAnyStrategies() {
return !collected.isEmpty();
}

public boolean isCollecting() {
return collecting;
}

public SafeStrategyRule getSafeRule() {
return hardestSafeRule;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,66 +16,32 @@
*******************************************************************************/
package net.famzangl.minecraft.minebot.ai.commands;

import net.famzangl.minecraft.minebot.ai.AIHelper;
import net.famzangl.minecraft.minebot.ai.command.AICommand;
import net.famzangl.minecraft.minebot.ai.command.AICommandInvocation;
import net.famzangl.minecraft.minebot.ai.command.AICommandParameter;
import net.famzangl.minecraft.minebot.ai.command.AICommandParameter.BlockFilter;
import net.famzangl.minecraft.minebot.ai.command.ParameterType;
import net.famzangl.minecraft.minebot.ai.path.world.BlockSet;
import net.famzangl.minecraft.minebot.ai.path.world.BlockSets;
import net.famzangl.minecraft.minebot.ai.strategy.AIStrategy;
import com.mojang.brigadier.arguments.IntegerArgumentType;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import net.famzangl.minecraft.minebot.ai.command.IAIControllable;
import net.famzangl.minecraft.minebot.ai.command.SafeStrategyRule;
import net.famzangl.minecraft.minebot.ai.strategy.CraftStrategy;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.command.arguments.ItemArgument;

@AICommand(helpText = "Crafts items of the given type.", name = "minebot")
public class CommandCraft {

/**
* Blocks that can not be crafted.
*/
private static final BlockSet simpleBlocks = BlockSet.builder().add(
Blocks.BREWING_STAND, Blocks.NETHER_WART,
Blocks.CAULDRON, Blocks.FLOWER_POT, Blocks.WHEAT, Blocks.SUGAR_CANE,
Blocks.CAKE, Blocks.SKELETON_SKULL, Blocks.SKELETON_WALL_SKULL, Blocks.WITHER_SKELETON_SKULL,
Blocks.WITHER_SKELETON_WALL_SKULL, Blocks.PISTON_HEAD,
Blocks.MOVING_PISTON, Blocks.REDSTONE_WIRE,
Blocks.PUMPKIN_STEM,
Blocks.TRIPWIRE,
Blocks.MELON_STEM,
Blocks.REDSTONE_WIRE,
Blocks.IRON_DOOR)
.add(BlockSets.AIR)
.add(BlockSets.WALL_SIGN)
.add(BlockSets.WOOL)
.add(BlockSets.BED)
.add(BlockSets.WOODEN_DOR).build().invert();
public static void register(LiteralArgumentBuilder<IAIControllable> dispatcher) {
dispatcher.then(
Commands.literal("craft")
.then(Commands.optional(
Commands.argument("type", ItemArgument.item()),
__ -> 1,
"count",
IntegerArgumentType.integer(1, 64),
Integer.class,
(builder, count) ->
builder.executes(
context -> context.getSource().requestUseStrategy(new CraftStrategy(count.get(context),
ItemArgument.getItem(context, "type").getItem()), SafeStrategyRule.DEFEND)
)
)
)

public static final class MyBlockFilter extends BlockFilter {
@Override
public boolean matches(BlockState b) {
return simpleBlocks.contains(b);
}
);
}

@AICommandInvocation()
public static AIStrategy run(
AIHelper helper,
@AICommandParameter(type = ParameterType.FIXED, fixedName = "craft", description = "") String nameArg,
@AICommandParameter(type = ParameterType.NUMBER, description = "Item count") int itemCount,
@AICommandParameter(type = ParameterType.BLOCK_STATE, description = "Block", blockFilter = MyBlockFilter.class) BlockState itemType) {
return new CraftStrategy(itemCount, itemType);
}

/* TODO
@AICommandInvocation()
public static AIStrategy run(
AIHelper helper,
@AICommandParameter(type = ParameterType.FIXED, fixedName = "craft", description = "") String nameArg,
@AICommandParameter(type = ParameterType.NUMBER, description = "Item count") int itemCount,
@AICommandParameter(type = ParameterType.NUMBER, description = "Item type") int itemType,
@AICommandParameter(type = ParameterType.NUMBER, description = "Item subtype", optional = true) Integer itemSubtype) {
return new CraftStrategy(itemCount, itemType, itemSubtype == null ? 0 : itemSubtype);
} */
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.context.CommandContext;
import net.famzangl.minecraft.minebot.ai.command.AICommand;
import net.famzangl.minecraft.minebot.ai.command.CommandEvaluationException;
import net.famzangl.minecraft.minebot.ai.command.IAIControllable;
import net.famzangl.minecraft.minebot.ai.command.SafeStrategyRule;
import net.famzangl.minecraft.minebot.ai.path.FillAreaPathfinder;
Expand All @@ -43,11 +42,7 @@ public static void register(LiteralArgumentBuilder<IAIControllable> dispatcher,
.executes(
context -> {
BlockCuboid<WorldData> area = CommandClearArea.getArea(context.getSource().getAiHelper());
if (area != null) {
return requestUseStrategy(context, area);
} else {
throw new CommandEvaluationException("No area has been set yet. Set an area to fill using /minebot posN");
}
return requestUseStrategy(context, area);
}
)
)
Expand Down
Loading

0 comments on commit f4326ab

Please sign in to comment.