diff --git a/src/tenor/java/tenor/QuantizedTaskPriorityAllocationCache.java b/src/tenor/java/tenor/QuantizedTaskPriorityAllocationCache.java
new file mode 100644
index 00000000..48941c57
--- /dev/null
+++ b/src/tenor/java/tenor/QuantizedTaskPriorityAllocationCache.java
@@ -0,0 +1,112 @@
+/*
+ * This file is part of Baritone.
+ *
+ * Baritone 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.
+ *
+ * Baritone 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 Baritone. If not, see .
+ */
+
+package tenor;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public abstract class QuantizedTaskPriorityAllocationCache extends QuantizedTaskNode {
+
+ private final Map allocationByQuantity;
+
+ public QuantizedTaskPriorityAllocationCache(Bot bot, DependencyType type) {
+ super(bot, type);
+ this.allocationByQuantity = new HashMap<>();
+ }
+
+ @Override
+ public final double priorityAllocatedTo(IQuantizedParentTaskRelationship child, int quantity) {
+ return allocationByQuantity.computeIfAbsent(quantity, this::allocationStrategy).allocatedTo(child);
+ }
+
+ protected Allocation allocationStrategy(int quantity) { // overridable
+ double amount = effectiveAllocationSize(quantity);
+ Allocation alloc = new Allocation(amount);
+ List children = childTasks();
+ if (children.size() < 2) {
+ return new Allocation(amount).distributeEqually(); // 0 or 1 cannot be anything but equal distribution
+ }
+ double[] costs = new double[children.size()];
+ for (int i = 0; i < costs.length; i++) {
+ costs[i] = children.get(i).cost().value(quantity);
+ }
+ switch (type) {
+ case ANY_ONE_OF:
+ // by default, give it all to the lowest cost
+ // this is stable
+ int lowestInd = 0;
+ for (int i = 1; i < costs.length; i++) {
+ if (costs[i] < costs[lowestInd]) {
+ lowestInd = i;
+ }
+ }
+ alloc.givePriority(lowestInd, alloc.unallocated());
+ return alloc;
+ default:
+ throw new UnsupportedOperationException("Not implemented yet");
+ }
+ }
+
+ protected double effectiveAllocationSize(int quantity) { // overridable
+ return priority().value(quantity);
+ }
+
+ protected class Allocation {
+ private final double[] priorities;
+ private final double total;
+
+ public Allocation(double total) {
+ this.priorities = new double[childTasks().size()];
+ this.total = total;
+ }
+
+ public double unallocated() {
+ return total - allocated();
+ }
+
+ public double allocated() {
+ double sum = 0;
+ for (double d : priorities) {
+ sum += d;
+ }
+ return sum;
+ }
+
+ public Allocation distributeEqually() {
+ int count = priorities.length;
+ double toDistribute = unallocated();
+ double priorityToEach = toDistribute / count;
+ for (int i = 0; i < count; i++) {
+ priorities[i] += priorityToEach;
+ }
+ return this;
+ }
+
+ public void givePriority(int childTaskIndex, double amount) {
+ if (amount > unallocated()) {
+ throw new IllegalStateException("not enough space");
+ }
+ priorities[childTaskIndex] += amount;
+ }
+
+ public double allocatedTo(IQuantizedParentTaskRelationship childRelationship) {
+ return priorities[childTasks().indexOf(childRelationship)];
+ }
+ }
+}
diff --git a/src/tenor/java/tenor/TaskNode.java b/src/tenor/java/tenor/TaskNode.java
index f4b4033d..efee099a 100644
--- a/src/tenor/java/tenor/TaskNode.java
+++ b/src/tenor/java/tenor/TaskNode.java
@@ -28,6 +28,9 @@ public abstract class TaskNode allocation; // allocation of what tasks have claim over what items in our inventory i guess
String item;
@@ -62,7 +61,7 @@ public class AquireItemTask extends QuantizedTaskNode implements IClaimProvider,
}
public int cachedCurrentQuantity() {
- return allocation.entrySet().stream().mapToInt(Map.Entry::getValue).sum();
+ return allocation.values().stream().mapToInt(x -> x).sum();
}
@Override
@@ -71,7 +70,7 @@ public class AquireItemTask extends QuantizedTaskNode implements IClaimProvider,
}
@Override
- public double priorityAllocatedTo(IQuantizedParentTaskRelationship child, int quantity) {
+ public double effectiveAllocationSize(int quantity) {
// how much of our priority would go to this child if it could provide us with quantity of the item we need
// here's the thing honey, we *already have* some, so you're really asking what's the priority of getting quantity MORE
diff --git a/src/tenor/java/tenor/game/DoCraft.java b/src/tenor/java/tenor/game/DoCraft.java
index ea49408c..50f4e0af 100644
--- a/src/tenor/java/tenor/game/DoCraft.java
+++ b/src/tenor/java/tenor/game/DoCraft.java
@@ -20,7 +20,7 @@ package tenor.game;
import tenor.ISingleParentSingularPriorityAllocator;
import tenor.SingularTaskLeaf;
-public class DoCraft extends SingularTaskLeaf implements ISingleParentSingularPriorityAllocator {
+public class DoCraft extends SingularTaskLeaf implements ISingleParentSingularPriorityAllocator { // TODO this should be quantized!
public final CraftingTask parent;
@@ -32,6 +32,8 @@ public class DoCraft extends SingularTaskLeaf implements ISingleParentSingularPr
@Override
public double cost() {
- return 420;
+ // this is a dummy task to represent actually completing the crafting, given that we have all the ingredients and are at a crafting table
+ // it's effectively free, so let's say it takes 1 second (20 ticks)
+ return 20D;
}
}
diff --git a/src/tenor/java/tenor/game/DoMine.java b/src/tenor/java/tenor/game/DoMine.java
index 1562e69a..3ca95d3a 100644
--- a/src/tenor/java/tenor/game/DoMine.java
+++ b/src/tenor/java/tenor/game/DoMine.java
@@ -22,9 +22,9 @@ import tenor.ISingleParentQuantizedPriorityAllocator;
import tenor.QuantizedTaskLeaf;
public class DoMine extends QuantizedTaskLeaf implements ISingleParentQuantizedPriorityAllocator {
- final MineTask parent;
+ final MineWithToolTask parent;
- public DoMine(MineTask parent) {
+ public DoMine(MineWithToolTask parent) {
super(parent.bot);
this.parent = parent;
addParent(parent);
diff --git a/src/tenor/java/tenor/game/GetToCraftingTableTask.java b/src/tenor/java/tenor/game/GetToCraftingTableTask.java
index 75d43eab..dcb00a2e 100644
--- a/src/tenor/java/tenor/game/GetToCraftingTableTask.java
+++ b/src/tenor/java/tenor/game/GetToCraftingTableTask.java
@@ -17,20 +17,26 @@
package tenor.game;
-import tenor.Bot;
-import tenor.ISingularChildTaskRelationship;
-import tenor.SingularTaskLeaf;
+import tenor.*;
public class GetToCraftingTableTask extends SingularTaskLeaf {
+ private final ComputationRequest craftingTable;
+
public GetToCraftingTableTask(Bot bot) {
super(bot);
registry().registerSingleton(this);
+ this.craftingTable = ComputationRequestManager.INSTANCE.getByGoal(this, "GoalGetToBlock crafting_table"); // idk
}
@Override
public double cost() {
- return 69;
+ Double d = craftingTable.cost();
+ if (d == null) {
+ // unknown, has not been calculated yet either way
+ return 1000D; // estimate
+ }
+ return d;
}
@Override
diff --git a/src/tenor/java/tenor/game/MineTask.java b/src/tenor/java/tenor/game/MineTask.java
index 8969f28a..1ec3be0b 100644
--- a/src/tenor/java/tenor/game/MineTask.java
+++ b/src/tenor/java/tenor/game/MineTask.java
@@ -17,31 +17,41 @@
package tenor.game;
-import tenor.*;
+import tenor.DependencyType;
+import tenor.IQuantizedDependentCostCalculator;
+import tenor.ISingleParentQuantizedPriorityAllocator;
+import tenor.QuantizedTaskPriorityAllocationCache;
-public class MineTask extends QuantizedTaskNode implements ISingleParentQuantizedPriorityAllocator {
+public class MineTask extends QuantizedTaskPriorityAllocationCache implements ISingleParentQuantizedPriorityAllocator, IQuantizedDependentCostCalculator {
// TODO shared claims of block locations in the world across all mine tasks across all bots
final AquireItemTask parent;
-
- final DoMine doMine;
+ final MineWithToolTask[] children;
public MineTask(AquireItemTask parent) {
super(parent.bot, DependencyType.ANY_ONE_OF);
this.parent = parent;
addParent(parent);
- this.doMine = new DoMine(this);
+ String[] tools = getToolsCapableOfMining(parent.item);
+ children = new MineWithToolTask[tools.length];
+ for (int i = 0; i < children.length; i++) {
+ children[i] = new MineWithToolTask(this, tools[i]);
+ }
}
- @Override
- public IQuantityRelationship cost() {
- return x -> x * 324232;
- }
-
- @Override
- public double priorityAllocatedTo(IQuantizedParentTaskRelationship child, int quantity) {
- return 0;
+ static String[] getToolsCapableOfMining(String block) {
+ switch (block) {
+ case "iron_ore":
+ return new String[]{"stone_pickaxe"};
+ case "stone":
+ case "cobblestone":
+ return new String[]{"wooden_pickaxe"};
+ case "log":
+ return new String[]{"hand"};
+ default:
+ throw new IllegalStateException(block);
+ }
}
}
diff --git a/src/tenor/java/tenor/game/MineWithToolTask.java b/src/tenor/java/tenor/game/MineWithToolTask.java
index e687aedb..6412653c 100644
--- a/src/tenor/java/tenor/game/MineWithToolTask.java
+++ b/src/tenor/java/tenor/game/MineWithToolTask.java
@@ -17,5 +17,28 @@
package tenor.game;
-public class MineWithToolTask {
+import tenor.DependencyType;
+import tenor.IQuantizedDependentCostCalculator;
+import tenor.ISingleParentQuantizedPriorityAllocator;
+import tenor.QuantizedTaskPriorityAllocationCache;
+
+public class MineWithToolTask extends QuantizedTaskPriorityAllocationCache implements ISingleParentQuantizedPriorityAllocator, IQuantizedDependentCostCalculator {
+
+ public final String tool;
+ MineTask parent;
+
+ AquireItemTask aquireTool;
+ // TODO locate task?
+ DoMine doMine;
+
+
+ public MineWithToolTask(MineTask parent, String tool) {
+ super(parent.bot, DependencyType.SERIAL);
+ this.tool = tool;
+ this.parent = parent;
+ addParent(parent);
+ this.aquireTool = registry().getItemBased(AquireItemTask.class, tool);
+ aquireTool.addParent(this); // we aren't constructing this, so need to add us as a parent manually
+ this.doMine = new DoMine(this);
+ }
}