diff --git a/src/main/java/tenor/Bot.java b/src/main/java/tenor/Bot.java new file mode 100644 index 00000000..a3e44a0b --- /dev/null +++ b/src/main/java/tenor/Bot.java @@ -0,0 +1,26 @@ +/* + * 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; + +public class Bot { + public final BotTaskRegistry taskRegistry = new BotTaskRegistry(this); + + public int getCurrentQuantityInInventory(String item) { + throw new UnsupportedOperationException("oppa"); + } +} diff --git a/src/main/java/tenor/BotTaskRegistry.java b/src/main/java/tenor/BotTaskRegistry.java new file mode 100644 index 00000000..925f4bad --- /dev/null +++ b/src/main/java/tenor/BotTaskRegistry.java @@ -0,0 +1,115 @@ +/* + * 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.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class BotTaskRegistry { + Bot target; + + Map, ITask> singletonRegistry; // GetToCraftingTableTask + + Map, Map>> itemBased; // MineTask, AquireItemTask + + List> allOthers; // AquireCraftingItems + + List> totalList; // everything from all lists + + public BotTaskRegistry(Bot parent) { + this.target = parent; + this.singletonRegistry = new HashMap<>(); + this.itemBased = new HashMap<>(); + this.allOthers = new ArrayList<>(); + this.totalList = new ArrayList<>(); + } + + public void register(ITask task) { + if (task.bot() != target) { + throw new IllegalStateException(); + } + if (totalList.contains(task)) { + throw new IllegalStateException(); + } + totalList.add(task); + allOthers.add(task); + } + + public void registerSingleton(ITask task) { + if (!totalList.contains(task)) { + throw new IllegalStateException(); + } + if (!allOthers.contains(task)) { + throw new IllegalStateException(); + } + if (singletonRegistry.containsKey(task.getClass())) { + throw new IllegalStateException(); + } + allOthers.remove(task); + singletonRegistry.put(task.getClass(), task); + } + + public > T getSingleton(Class klass) { + if (singletonRegistry.containsKey(klass)) { + return (T) singletonRegistry.get(klass); + } + try { + T result = klass.getConstructor(Bot.class).newInstance(target); + if (!singletonRegistry.containsKey(klass)) { + throw new IllegalStateException(); + } + return result; + } catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) { + throw new IllegalStateException(e); + } + } + + public void registerItemBased(ITask task, String key) { + if (!totalList.contains(task)) { + throw new IllegalStateException(); + } + if (!allOthers.contains(task)) { + throw new IllegalStateException(); + } + Map> specificMap = itemBased.computeIfAbsent(task.getClass(), x -> new HashMap<>()); + if (specificMap.containsKey(key)) { + throw new IllegalStateException(); + } + allOthers.remove(task); + specificMap.put(key, task); + } + + public > T getItemBased(Class klass, String key) { + Map> specificMap = itemBased.computeIfAbsent(klass, x -> new HashMap<>()); + if (specificMap.containsKey(key)) { + return (T) specificMap.get(key); + } + try { + T result = klass.getConstructor(Bot.class, String.class).newInstance(target, key); + if (!specificMap.containsKey(key)) { + throw new IllegalStateException(); + } + return result; + } catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) { + throw new IllegalStateException(e); + } + } +} diff --git a/src/main/java/tenor/IQuantizedTask.java b/src/main/java/tenor/IQuantizedTask.java index 0b8e76ed..7894e717 100644 --- a/src/main/java/tenor/IQuantizedTask.java +++ b/src/main/java/tenor/IQuantizedTask.java @@ -35,13 +35,9 @@ public interface IQuantizedTask extends ITask { default IQuantizedChildTaskRelationship createRelationshipToParent(ITaskNodeBase parent) { if (parent instanceof IQuantizedTask) { - return new QuantizedToQuantizedTaskRelationship((QuantizedTaskNode) parent, this, parent.type()); + return new QuantizedToQuantizedTaskRelationship((IQuantizedTaskNode) parent, this); } else { throw new UnsupportedOperationException("SingularToQuantized must be constructed manually since it needs a quantity"); } } - - default QuantizedToQuantizedTaskRelationship createRelationshipToParent(QuantizedTaskNode parent) { - return new QuantizedToQuantizedTaskRelationship(parent, this, parent.type()); - } } diff --git a/src/main/java/tenor/ISingularTask.java b/src/main/java/tenor/ISingularTask.java index df00f58e..8eba0d07 100644 --- a/src/main/java/tenor/ISingularTask.java +++ b/src/main/java/tenor/ISingularTask.java @@ -24,9 +24,9 @@ public interface ISingularTask extends ITask { default ISingularChildTaskRelationship createRelationshipToParent(ITaskNodeBase parent) { if (parent instanceof IQuantizedTask) { - return new QuantizedToSingularTaskRelationship((QuantizedTaskNode) parent, this, parent.type()); + return new QuantizedToSingularTaskRelationship((IQuantizedTaskNode) parent, this); } else { - return new SingularToSingularTaskRelationship((SingularTaskNode) parent, this, parent.type()); + return new SingularToSingularTaskRelationship((ISingularTaskNode) parent, this); } } } diff --git a/src/main/java/tenor/ITask.java b/src/main/java/tenor/ITask.java index 231770b3..214225c4 100644 --- a/src/main/java/tenor/ITask.java +++ b/src/main/java/tenor/ITask.java @@ -30,4 +30,10 @@ public interface ITask default void addParent(ITaskNodeBase parent) { addParent(createRelationshipToParent(parent)); } + + Bot bot(); + + default BotTaskRegistry registry() { + return bot().taskRegistry; + } } diff --git a/src/main/java/tenor/QuantizedTaskLeaf.java b/src/main/java/tenor/QuantizedTaskLeaf.java index c053b997..dc9ab8e8 100644 --- a/src/main/java/tenor/QuantizedTaskLeaf.java +++ b/src/main/java/tenor/QuantizedTaskLeaf.java @@ -18,4 +18,7 @@ package tenor; public abstract class QuantizedTaskLeaf extends TaskLeaf implements IQuantizedTask { + public QuantizedTaskLeaf(Bot bot) { + super(bot); + } } diff --git a/src/main/java/tenor/QuantizedTaskNode.java b/src/main/java/tenor/QuantizedTaskNode.java index 6d0a7d6d..0a3cb315 100644 --- a/src/main/java/tenor/QuantizedTaskNode.java +++ b/src/main/java/tenor/QuantizedTaskNode.java @@ -18,8 +18,7 @@ package tenor; public abstract class QuantizedTaskNode extends TaskNode implements IQuantizedTaskNode { - - public QuantizedTaskNode(DependencyType type) { - super(type); + public QuantizedTaskNode(Bot bot, DependencyType type) { + super(bot, type); } } diff --git a/src/main/java/tenor/QuantizedToQuantizedTaskRelationship.java b/src/main/java/tenor/QuantizedToQuantizedTaskRelationship.java index ebb65a64..321c832d 100644 --- a/src/main/java/tenor/QuantizedToQuantizedTaskRelationship.java +++ b/src/main/java/tenor/QuantizedToQuantizedTaskRelationship.java @@ -21,8 +21,8 @@ public class QuantizedToQuantizedTaskRelationship extends TaskRelationship implements IQuantizedChildTaskRelationship, IQuantizedParentTaskRelationship { - public QuantizedToQuantizedTaskRelationship(IQuantizedTaskNode parent, IQuantizedTask child, DependencyType type) { - super(parent, child, type); + public QuantizedToQuantizedTaskRelationship(IQuantizedTaskNode parent, IQuantizedTask child) { + super(parent, child); } @Override diff --git a/src/main/java/tenor/QuantizedToSingularTaskRelationship.java b/src/main/java/tenor/QuantizedToSingularTaskRelationship.java index 06858f28..574348b7 100644 --- a/src/main/java/tenor/QuantizedToSingularTaskRelationship.java +++ b/src/main/java/tenor/QuantizedToSingularTaskRelationship.java @@ -21,8 +21,8 @@ public class QuantizedToSingularTaskRelationship extends TaskRelationship implements ISingularChildTaskRelationship, IQuantizedParentTaskRelationship { - public QuantizedToSingularTaskRelationship(IQuantizedTaskNode parent, ISingularTask child, DependencyType type) { - super(parent, child, type); + public QuantizedToSingularTaskRelationship(IQuantizedTaskNode parent, ISingularTask child) { + super(parent, child); } @Override diff --git a/src/main/java/tenor/SingularTaskLeaf.java b/src/main/java/tenor/SingularTaskLeaf.java index 89104c8d..b4c3021b 100644 --- a/src/main/java/tenor/SingularTaskLeaf.java +++ b/src/main/java/tenor/SingularTaskLeaf.java @@ -18,4 +18,7 @@ package tenor; public abstract class SingularTaskLeaf extends TaskLeaf implements ISingularTask { + public SingularTaskLeaf(Bot bot) { + super(bot); + } } \ No newline at end of file diff --git a/src/main/java/tenor/SingularTaskNode.java b/src/main/java/tenor/SingularTaskNode.java index 51c30acf..da4ab0b0 100644 --- a/src/main/java/tenor/SingularTaskNode.java +++ b/src/main/java/tenor/SingularTaskNode.java @@ -19,7 +19,7 @@ package tenor; public abstract class SingularTaskNode extends TaskNode implements ISingularTaskNode { - public SingularTaskNode(DependencyType type) { - super(type); + public SingularTaskNode(Bot bot, DependencyType type) { + super(bot, type); } } diff --git a/src/main/java/tenor/SingularToQuantizedTaskRelationship.java b/src/main/java/tenor/SingularToQuantizedTaskRelationship.java index 75ec1544..0dac6b8f 100644 --- a/src/main/java/tenor/SingularToQuantizedTaskRelationship.java +++ b/src/main/java/tenor/SingularToQuantizedTaskRelationship.java @@ -23,8 +23,8 @@ public class SingularToQuantizedTaskRelationship public int quantityRequired; - public SingularToQuantizedTaskRelationship(ISingularTaskNode parent, IQuantizedTask child, DependencyType type, int quantityRequired) { - super(parent, child, type); + public SingularToQuantizedTaskRelationship(ISingularTaskNode parent, IQuantizedTask child, int quantityRequired) { + super(parent, child); this.quantityRequired = quantityRequired; } diff --git a/src/main/java/tenor/SingularToSingularTaskRelationship.java b/src/main/java/tenor/SingularToSingularTaskRelationship.java index bbf10d5a..3f17b7a4 100644 --- a/src/main/java/tenor/SingularToSingularTaskRelationship.java +++ b/src/main/java/tenor/SingularToSingularTaskRelationship.java @@ -21,8 +21,8 @@ public class SingularToSingularTaskRelationship extends TaskRelationship implements ISingularChildTaskRelationship, ISingularParentTaskRelationship { - public SingularToSingularTaskRelationship(ISingularTaskNode parent, ISingularTask child, DependencyType type) { - super(parent, child, type); + public SingularToSingularTaskRelationship(ISingularTaskNode parent, ISingularTask child) { + super(parent, child); } @Override diff --git a/src/main/java/tenor/Task.java b/src/main/java/tenor/Task.java index 854257de..1eb1ab24 100644 --- a/src/main/java/tenor/Task.java +++ b/src/main/java/tenor/Task.java @@ -17,11 +17,24 @@ package tenor; +import java.util.ArrayList; import java.util.List; public abstract class Task implements ITask { - List parentRelationships; + public final Bot bot; + + private final List parentRelationships = new ArrayList<>(); + + public Task(Bot bot) { + this.bot = bot; + registry().register(this); + } + + @Override + public Bot bot() { + return bot; + } @Override public List parentTasks() { diff --git a/src/main/java/tenor/TaskLeaf.java b/src/main/java/tenor/TaskLeaf.java index c79c5a93..d2a5ab57 100644 --- a/src/main/java/tenor/TaskLeaf.java +++ b/src/main/java/tenor/TaskLeaf.java @@ -18,4 +18,7 @@ package tenor; public abstract class TaskLeaf extends Task { + public TaskLeaf(Bot bot) { + super(bot); + } } diff --git a/src/main/java/tenor/TaskNode.java b/src/main/java/tenor/TaskNode.java index 5e4467d6..f4b4033d 100644 --- a/src/main/java/tenor/TaskNode.java +++ b/src/main/java/tenor/TaskNode.java @@ -17,14 +17,16 @@ package tenor; +import java.util.ArrayList; import java.util.List; public abstract class TaskNode extends Task implements ITaskNodeBase { - List childRelationships; + private final List childRelationships = new ArrayList<>(); public final DependencyType type; - public TaskNode(DependencyType type) { + public TaskNode(Bot bot, DependencyType type) { + super(bot); this.type = type; } diff --git a/src/main/java/tenor/TaskRelationship.java b/src/main/java/tenor/TaskRelationship.java index c0a0ddc6..65809a32 100644 --- a/src/main/java/tenor/TaskRelationship.java +++ b/src/main/java/tenor/TaskRelationship.java @@ -23,11 +23,11 @@ public class TaskRelationship

implemen public final C child; public final DependencyType type; - public TaskRelationship(P parent, C child, DependencyType type) { + public TaskRelationship(P parent, C child) { this.parent = parent; this.child = child; - this.type = type; - if (parent.type() != type) { + this.type = parent.type(); + if (parent.bot() != child.bot()) { throw new IllegalArgumentException(); } } diff --git a/src/main/java/tenor/game/ActuallyCraftTask.java b/src/main/java/tenor/game/ActuallyCraftTask.java index cf5f38ce..024eb08a 100644 --- a/src/main/java/tenor/game/ActuallyCraftTask.java +++ b/src/main/java/tenor/game/ActuallyCraftTask.java @@ -25,6 +25,7 @@ public class ActuallyCraftTask extends SingularTaskLeaf implements ISingleParent public final CraftingTask parent; public ActuallyCraftTask(CraftingTask parent) { + super(parent.bot); this.parent = parent; addParent(parent); } diff --git a/src/main/java/tenor/game/AquireCraftingItems.java b/src/main/java/tenor/game/AquireCraftingItems.java index 5e64a3b2..3e803159 100644 --- a/src/main/java/tenor/game/AquireCraftingItems.java +++ b/src/main/java/tenor/game/AquireCraftingItems.java @@ -24,7 +24,7 @@ public class AquireCraftingItems extends QuantizedTaskNode implements IClaimProv final CraftingTask parent; public AquireCraftingItems(CraftingTask parent) { - super(DependencyType.PARALLEL_ALL); + super(parent.bot, DependencyType.PARALLEL_ALL); this.parent = parent; addParent(parent); } diff --git a/src/main/java/tenor/game/AquireItemTask.java b/src/main/java/tenor/game/AquireItemTask.java index 8c64bf1d..abe138e8 100644 --- a/src/main/java/tenor/game/AquireItemTask.java +++ b/src/main/java/tenor/game/AquireItemTask.java @@ -26,9 +26,12 @@ import java.util.Map; public class AquireItemTask extends QuantizedTaskNode implements IClaimProvider, IQuantizedDependentCostCalculator { HashMap allocation; // allocation of what tasks have claim over what items in our inventory i guess + String item; - public AquireItemTask() { - super(DependencyType.ANY_ONE_OF); + public AquireItemTask(Bot bot, String item) { + super(bot, DependencyType.ANY_ONE_OF); + this.item = item; + registry().registerItemBased(this, item); } @Override @@ -37,11 +40,16 @@ public class AquireItemTask extends QuantizedTaskNode implements IClaimProvider, } public void reallocate() { + int amountToAllocate = getCurrentQuantityInInventory(); + if (amountToAllocate == cachedCurrentQuantity()) { + // no change + return; + } List parents = parentTasks(); allocation = null; HashMap tmp = new HashMap<>(); - int amountToAllocate = getCurrentQuantityInInventory(); + int[] newAmounts = ScarceParentPriorityAllocator.priorityAllocation(amountToAllocate, parents).parentAllocationQuantity; for (int i = 0; i < parents.size(); i++) { tmp.put(parents.get(i), newAmounts[i]); @@ -50,7 +58,11 @@ public class AquireItemTask extends QuantizedTaskNode implements IClaimProvider, } public int getCurrentQuantityInInventory() { - throw new UnsupportedOperationException("oppa"); + return bot.getCurrentQuantityInInventory(item); + } + + public int cachedCurrentQuantity() { + return allocation.entrySet().stream().mapToInt(Map.Entry::getValue).sum(); } @Override @@ -63,7 +75,7 @@ public class AquireItemTask extends QuantizedTaskNode implements IClaimProvider, // 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 - int curr = allocation.entrySet().stream().mapToInt(Map.Entry::getValue).sum(); + int curr = cachedCurrentQuantity(); return priority().value(quantity + curr) - priority().value(curr); } diff --git a/src/main/java/tenor/game/CraftingTask.java b/src/main/java/tenor/game/CraftingTask.java index 1afe6811..a6c3ff32 100644 --- a/src/main/java/tenor/game/CraftingTask.java +++ b/src/main/java/tenor/game/CraftingTask.java @@ -34,9 +34,9 @@ public class CraftingTask extends QuantizedTaskNode implements ISingleParentQuan final AquireItemTask parent; public CraftingTask(AquireItemTask parent) { - super(DependencyType.SERIAL); + super(parent.bot, DependencyType.SERIAL); this.inputs = new AquireCraftingItems(this); // this adds the relationship - this.step2 = GetToCraftingTableTask.INSTANCE; + this.step2 = registry().getSingleton(GetToCraftingTableTask.class); step2.addParent(this); this.step3 = new ActuallyCraftTask(this); diff --git a/src/main/java/tenor/game/GetToCraftingTableTask.java b/src/main/java/tenor/game/GetToCraftingTableTask.java index c826077c..75d43eab 100644 --- a/src/main/java/tenor/game/GetToCraftingTableTask.java +++ b/src/main/java/tenor/game/GetToCraftingTableTask.java @@ -17,11 +17,16 @@ package tenor.game; +import tenor.Bot; import tenor.ISingularChildTaskRelationship; import tenor.SingularTaskLeaf; public class GetToCraftingTableTask extends SingularTaskLeaf { - public static final GetToCraftingTableTask INSTANCE = new GetToCraftingTableTask(); // ? idk + + public GetToCraftingTableTask(Bot bot) { + super(bot); + registry().registerSingleton(this); + } @Override public double cost() { diff --git a/src/main/java/tenor/game/MineTask.java b/src/main/java/tenor/game/MineTask.java index d57e90fd..6895e7be 100644 --- a/src/main/java/tenor/game/MineTask.java +++ b/src/main/java/tenor/game/MineTask.java @@ -23,9 +23,12 @@ import tenor.QuantizedTaskLeaf; public class MineTask extends QuantizedTaskLeaf implements ISingleParentQuantizedPriorityAllocator { + // TODO shared claims of block locations in the world across all mine tasks across all bots + final AquireItemTask parent; public MineTask(AquireItemTask parent) { + super(parent.bot); this.parent = parent; addParent(parent); }