mirror of
https://github.com/GTNewHorizons/BeeBetterAtBees-GTNH.git
synced 2026-11-13 16:54:25 +00:00
Add dynamic bee tree requirement slots (#12)
This commit is contained in:
1 parent
a9a5f1e1b2
commit
1a6e8be76d
13 files changed
+382
-78
No files matched your search
+2
-2
@@ -34,6 +34,6 @@
|
||||
* For more details, see https://docs.gradle.org/8.0.1/userguide/java_library_plugin.html#sec:java_library_configurations_graph
|
||||
*/
|
||||
dependencies {
|
||||
api("com.github.GTNewHorizons:NotEnoughItems:2.8.114-GTNH:dev")
|
||||
api("com.github.GTNewHorizons:ForestryMC:4.11.31:dev")
|
||||
api("com.github.GTNewHorizons:NotEnoughItems:2.8.155-GTNH:dev")
|
||||
api("com.github.GTNewHorizons:ForestryMC:4.11.38:dev")
|
||||
}
|
||||
@@ -4,6 +4,8 @@ import codechicken.nei.api.API;
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
import hellfirepvp.beebetteratbees.client.gui.BBABGuiRecipeTreeHandler;
|
||||
import hellfirepvp.beebetteratbees.client.requirements.MutationConditionRequirementProvider;
|
||||
import hellfirepvp.beebetteratbees.client.requirements.RequirementResolvers;
|
||||
import hellfirepvp.beebetteratbees.common.CommonProxy;
|
||||
|
||||
/**
|
||||
@@ -21,6 +23,7 @@ public class ClientProxy extends CommonProxy {
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
private void registerNEIStuff() {
|
||||
RequirementResolvers.register(new MutationConditionRequirementProvider());
|
||||
BBABGuiRecipeTreeHandler handler = new BBABGuiRecipeTreeHandler();
|
||||
API.registerRecipeHandler(handler);
|
||||
API.registerUsageHandler(handler);
|
||||
|
||||
+36
-29
@@ -20,6 +20,7 @@ import forestry.api.genetics.IIndividual;
|
||||
import forestry.api.genetics.ISpeciesRoot;
|
||||
import hellfirepvp.beebetteratbees.client.gui.CachedBeeMutationTree.ChanceInfoNode;
|
||||
import hellfirepvp.beebetteratbees.client.gui.CachedBeeMutationTree.IMutationNode;
|
||||
import hellfirepvp.beebetteratbees.client.requirements.RequirementResolvers;
|
||||
import hellfirepvp.beebetteratbees.common.BeeBetterAtBees;
|
||||
import hellfirepvp.beebetteratbees.common.ModConfig;
|
||||
|
||||
@@ -65,11 +66,22 @@ public class BBABGuiRecipeTreeHandler extends AbstractTreeGUIHandler {
|
||||
public void loadCraftingRecipes(String outputId, Object... results) {
|
||||
if (speciesRoot == null) return;
|
||||
|
||||
if (outputId.equals("item")) {
|
||||
if (outputId.equals("all")) {
|
||||
loadAllRecipes();
|
||||
} else if (outputId.equals("item")) {
|
||||
loadCraftingRecipes((ItemStack) results[0]);
|
||||
}
|
||||
}
|
||||
|
||||
private void loadAllRecipes() {
|
||||
for (IBeeMutation mutation : speciesRoot.getMutations(false)) {
|
||||
if (!mutation.isSecret() || ModConfig.shouldShowSecretRecipes) {
|
||||
this.arecipes.add(new CachedBeeMutationTree(mutation));
|
||||
}
|
||||
}
|
||||
cleanupDuplicateRecipes();
|
||||
}
|
||||
|
||||
public void loadCraftingRecipes(ItemStack result) {
|
||||
if (speciesRoot == null) return;
|
||||
|
||||
@@ -118,23 +130,30 @@ public class BBABGuiRecipeTreeHandler extends AbstractTreeGUIHandler {
|
||||
Point pos = GuiDraw.getMousePosition();
|
||||
Point guiOffset = new Point(gui.guiLeft, gui.guiTop);
|
||||
Point recipeOffset = gui.getRecipePosition(recipe);
|
||||
|
||||
int relativeX = pos.x - guiOffset.x - recipeOffset.x;
|
||||
int relativeY = pos.y - guiOffset.y - recipeOffset.y;
|
||||
for (IMutationNode mutation : cachedTree.getMutationNodesToRender()) {
|
||||
if (mutation instanceof ChanceInfoNode chanceInfoNode && chanceInfoNode
|
||||
.containsPoint(pos.x - guiOffset.x - recipeOffset.x, pos.y - guiOffset.y - recipeOffset.y)) {
|
||||
if (mutation instanceof ChanceInfoNode chanceInfoNode
|
||||
&& chanceInfoNode.containsPoint(relativeX, relativeY)) {
|
||||
return new LinkedList<>(chanceInfoNode.infoLines);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return super.handleTooltip(gui, currenttip, recipe);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRecipeHeight(int recipe) {
|
||||
return ((CachedBeeMutationTree) this.arecipes.get(recipe)).getRecipeHeight();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadUsageRecipes(String inputId, Object... ingredients) {
|
||||
if (speciesRoot == null) return;
|
||||
|
||||
if (inputId.equals("item")) {
|
||||
if (inputId.equals("all")) {
|
||||
loadAllRecipes();
|
||||
} else if (inputId.equals("item")) {
|
||||
loadUsageRecipes((ItemStack) ingredients[0]);
|
||||
}
|
||||
}
|
||||
@@ -142,33 +161,21 @@ public class BBABGuiRecipeTreeHandler extends AbstractTreeGUIHandler {
|
||||
public void loadUsageRecipes(ItemStack ingredient) {
|
||||
if (speciesRoot == null) return;
|
||||
|
||||
if (!speciesRoot.isMember(ingredient)) {
|
||||
return;
|
||||
IAlleleSpecies species = null;
|
||||
if (speciesRoot.isMember(ingredient)) {
|
||||
IIndividual individual = speciesRoot.getMember(ingredient);
|
||||
var genome = individual == null ? null : individual.getGenome();
|
||||
if (genome != null) species = genome.getPrimary();
|
||||
}
|
||||
IIndividual individual = speciesRoot.getMember(ingredient);
|
||||
if (individual == null) {
|
||||
BeeBetterAtBees.log.warn("IIndividual is null searching recipe for %s", ingredient.toString());
|
||||
return;
|
||||
}
|
||||
if (individual.getGenome() == null) {
|
||||
BeeBetterAtBees.log.warn("Genome is null when searching recipe for %s", ingredient.toString());
|
||||
return;
|
||||
}
|
||||
if (individual.getGenome()
|
||||
.getPrimary() == null) {
|
||||
BeeBetterAtBees.log.warn("Species is null when searching recipe for %s", ingredient.toString());
|
||||
return;
|
||||
}
|
||||
IAlleleSpecies species = individual.getGenome()
|
||||
.getPrimary();
|
||||
|
||||
for (IBeeMutation mutation : speciesRoot.getMutations(false)) {
|
||||
if (mutation.getAllele0()
|
||||
if (mutation.isSecret() && !ModConfig.shouldShowSecretRecipes) continue;
|
||||
boolean matchesSpecies = species != null && (mutation.getAllele0()
|
||||
.equals(species)
|
||||
|| mutation.getAllele1()
|
||||
.equals(species)) {
|
||||
if (!mutation.isSecret() || ModConfig.shouldShowSecretRecipes) {
|
||||
this.arecipes.add(new CachedBeeMutationTree(mutation));
|
||||
}
|
||||
.equals(species));
|
||||
if (matchesSpecies || RequirementResolvers.matches(mutation, ingredient)) {
|
||||
this.arecipes.add(new CachedBeeMutationTree(mutation));
|
||||
}
|
||||
}
|
||||
cleanupDuplicateRecipes();
|
||||
|
||||
@@ -6,6 +6,7 @@ import java.awt.Color;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
@@ -20,6 +21,10 @@ import codechicken.nei.PositionedStack;
|
||||
import forestry.api.apiculture.IBeeMutation;
|
||||
import forestry.api.genetics.IAllele;
|
||||
import forestry.api.genetics.IAlleleSpecies;
|
||||
import hellfirepvp.beebetteratbees.client.requirements.BlockRequirement;
|
||||
import hellfirepvp.beebetteratbees.client.requirements.RequirementLayout;
|
||||
import hellfirepvp.beebetteratbees.client.requirements.RequirementResolvers;
|
||||
import hellfirepvp.beebetteratbees.client.requirements.RequirementSlot;
|
||||
import hellfirepvp.beebetteratbees.client.util.ColorUtils;
|
||||
import hellfirepvp.beebetteratbees.client.util.SimpleBinaryTree;
|
||||
import hellfirepvp.beebetteratbees.common.ModConfig;
|
||||
@@ -32,14 +37,14 @@ import hellfirepvp.beebetteratbees.common.ModConfig;
|
||||
*/
|
||||
public class CachedBeeMutationTree extends CachedRecipe {
|
||||
|
||||
protected static interface IMutationNode {
|
||||
public interface IMutationNode {
|
||||
|
||||
boolean containsPoint(int x, int y);
|
||||
|
||||
void renderNode();
|
||||
}
|
||||
|
||||
protected static class LineNode implements IMutationNode {
|
||||
public static class LineNode implements IMutationNode {
|
||||
|
||||
public final double lx;
|
||||
public final double ly;
|
||||
@@ -83,7 +88,7 @@ public class CachedBeeMutationTree extends CachedRecipe {
|
||||
}
|
||||
}
|
||||
|
||||
protected static class ChanceInfoNode implements IMutationNode {
|
||||
public static class ChanceInfoNode implements IMutationNode {
|
||||
|
||||
public final int x;
|
||||
public final int y;
|
||||
@@ -125,11 +130,7 @@ public class CachedBeeMutationTree extends CachedRecipe {
|
||||
}
|
||||
}
|
||||
|
||||
// RENDERING BB
|
||||
// X = 15 to 135 (Size: 120)
|
||||
// Y = 10 to 100 (Size: 90)
|
||||
|
||||
private static final int MIN_X = 15, MAX_X = 135;
|
||||
private static final int MIN_X = 2, MAX_X = 162;
|
||||
private static final int X_SEPERATION_THRESHOLD = 7;
|
||||
private static final int Y_OFFSET = 0;
|
||||
private static final Color LINE_BLACK = new Color(ColorUtils.neiLineBlack.getColor(), true);
|
||||
@@ -139,6 +140,7 @@ public class CachedBeeMutationTree extends CachedRecipe {
|
||||
|
||||
private static final int OFFSET_CORRECTION = 8;
|
||||
private static final int POSSIBLE_CHILD_OFFSET = 16;
|
||||
private static final int LEVEL_STEP = 50;
|
||||
|
||||
private final SimpleBinaryTree<IAllele> mutationTree;
|
||||
private final List<PositionedMutationNodeStack> evaluatedBeePositions;
|
||||
@@ -146,6 +148,7 @@ public class CachedBeeMutationTree extends CachedRecipe {
|
||||
public final boolean oversized;
|
||||
private PositionedMutationNodeStack rootStack;
|
||||
private List<IMutationNode> mutationNodesToRender = new LinkedList<>();
|
||||
private final List<RequirementSlot> requirementSlots = new ArrayList<>();
|
||||
|
||||
public CachedBeeMutationTree(IBeeMutation parentMutation) {
|
||||
// parentMutation.getTemplate() Gets results primary at array[0], secondary at array[1]
|
||||
@@ -184,7 +187,7 @@ public class CachedBeeMutationTree extends CachedRecipe {
|
||||
oversized = false;
|
||||
return; // In case the root is a leaf, there is nothing to display anyway except the root.
|
||||
}
|
||||
int yStep = 110 / maxTotalDepth;
|
||||
int yStep = LEVEL_STEP;
|
||||
|
||||
this.oversized = checkSeparationWidth(maxTotalDepth, X_SEPERATION_THRESHOLD);
|
||||
this.evaluatedMaxX = MAX_X;
|
||||
@@ -207,25 +210,17 @@ public class CachedBeeMutationTree extends CachedRecipe {
|
||||
this.evaluatedMaxX,
|
||||
iterationDepth - 1);
|
||||
|
||||
List<IBeeMutation> mutationsToRoot = getMutationsWithResult(
|
||||
mutationTree.getRoot()
|
||||
.getValue());
|
||||
float ch = -1;
|
||||
Collection<String> requirements = new LinkedList<>();
|
||||
if (!mutationsToRoot.isEmpty()) {
|
||||
IBeeMutation mut = mutationsToRoot.get(0);
|
||||
ch = mut.getBaseChance();
|
||||
try {
|
||||
requirements = mut.getSpecialConditions();
|
||||
} catch (Throwable ignored) {}
|
||||
}
|
||||
float ch = parentMutation.getBaseChance();
|
||||
Collection<String> requirements = getSpecialConditions(parentMutation);
|
||||
|
||||
this.rootStack = new PositionedMutationNodeStack(
|
||||
createStack(
|
||||
(IAlleleSpecies) mutationTree.getRoot()
|
||||
.getValue(),
|
||||
BEE_TYPE_PRINCESS),
|
||||
(MIN_X + this.evaluatedMaxX) / 2,
|
||||
(IAlleleSpecies) mutationTree.getRoot()
|
||||
.getValue(),
|
||||
(MIN_X + this.evaluatedMaxX) / 2 - OFFSET_CORRECTION,
|
||||
Y_OFFSET,
|
||||
ch,
|
||||
requirements,
|
||||
@@ -234,6 +229,38 @@ public class CachedBeeMutationTree extends CachedRecipe {
|
||||
true);
|
||||
|
||||
generateMutationNodes(rootStack);
|
||||
buildRequirementSlots(parentMutation);
|
||||
}
|
||||
|
||||
private void buildRequirementSlots(IBeeMutation parentMutation) {
|
||||
addRequirements(rootStack, RequirementResolvers.resolve(parentMutation));
|
||||
List<PositionedMutationNodeStack> orderedStacks = new ArrayList<>(evaluatedBeePositions);
|
||||
orderedStacks.sort(
|
||||
Comparator.comparingInt((PositionedMutationNodeStack stack) -> stack.rely)
|
||||
.thenComparingInt(stack -> stack.relx));
|
||||
for (PositionedMutationNodeStack stack : orderedStacks) {
|
||||
addRequirements(stack, resolveRequirements(stack.species));
|
||||
}
|
||||
}
|
||||
|
||||
private void addRequirements(PositionedMutationNodeStack stack, List<BlockRequirement> requirements) {
|
||||
if (stack == null || requirements.isEmpty()) return;
|
||||
List<RequirementSlot> placed = RequirementLayout.place(requirements, stack.relx, stack.rely);
|
||||
requirementSlots.addAll(placed);
|
||||
}
|
||||
|
||||
private List<BlockRequirement> resolveRequirements(IAllele species) {
|
||||
List<IBeeMutation> mutations = getMutationsWithResult(species);
|
||||
return mutations.isEmpty() ? Collections.emptyList() : RequirementResolvers.resolve(mutations.get(0));
|
||||
}
|
||||
|
||||
private static Collection<String> getSpecialConditions(IBeeMutation mutation) {
|
||||
try {
|
||||
Collection<String> conditions = mutation.getSpecialConditions();
|
||||
return conditions == null ? Collections.<String>emptyList() : conditions;
|
||||
} catch (Throwable ignored) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
||||
private void generateMutationNodes(PositionedMutationNodeStack nodeStack) {
|
||||
@@ -322,8 +349,8 @@ public class CachedBeeMutationTree extends CachedRecipe {
|
||||
}
|
||||
|
||||
private boolean checkSeparationWidth(int maxTotalDepth, int xSeparationThreshold) {
|
||||
double maxDivision = Math.pow(2, maxTotalDepth + 1);
|
||||
int resultingLLWidth = (int) (120 / maxDivision); // LowestLevelWidth
|
||||
int leafCount = 1 << maxTotalDepth;
|
||||
int resultingLLWidth = (MAX_X - MIN_X) / leafCount;
|
||||
return resultingLLWidth < xSeparationThreshold;
|
||||
}
|
||||
|
||||
@@ -334,19 +361,16 @@ public class CachedBeeMutationTree extends CachedRecipe {
|
||||
if (iterationMaxCount < 0 || node.getMaxFollowingDepth() <= 0) {
|
||||
List<IBeeMutation> mutationsToRoot = getMutationsWithResult(node.getValue());
|
||||
float ch = -1;
|
||||
Collection<String> requirements = new LinkedList<>();
|
||||
Collection<String> requirements = Collections.emptyList();
|
||||
if (!mutationsToRoot.isEmpty()) {
|
||||
IBeeMutation mut = mutationsToRoot.get(0);
|
||||
ch = mut.getBaseChance();
|
||||
try {
|
||||
requirements = mut.getSpecialConditions();
|
||||
} catch (Throwable tr) {
|
||||
requirements = new LinkedList<>();
|
||||
}
|
||||
ch = mutationsToRoot.get(0)
|
||||
.getBaseChance();
|
||||
requirements = getSpecialConditions(mutationsToRoot.get(0));
|
||||
}
|
||||
PositionedMutationNodeStack leaf = new PositionedMutationNodeStack( // Leaf
|
||||
createStack((IAlleleSpecies) node.getValue(), BEE_TYPE_DRONE),
|
||||
center,
|
||||
(IAlleleSpecies) node.getValue(),
|
||||
center - OFFSET_CORRECTION,
|
||||
minY,
|
||||
ch,
|
||||
requirements,
|
||||
@@ -359,20 +383,17 @@ public class CachedBeeMutationTree extends CachedRecipe {
|
||||
|
||||
List<IBeeMutation> mutations = getMutationsWithResult(node.getValue());
|
||||
float ch = -1;
|
||||
Collection<String> requirements = new LinkedList<>();
|
||||
Collection<String> requirements = Collections.emptyList();
|
||||
if (!mutations.isEmpty()) {
|
||||
IBeeMutation mut = mutations.get(0);
|
||||
ch = mut.getBaseChance();
|
||||
try {
|
||||
requirements = mut.getSpecialConditions();
|
||||
} catch (Throwable tr) {
|
||||
requirements = new LinkedList<>();
|
||||
}
|
||||
ch = mutations.get(0)
|
||||
.getBaseChance();
|
||||
requirements = getSpecialConditions(mutations.get(0));
|
||||
}
|
||||
|
||||
PositionedMutationNodeStack outNode = new PositionedMutationNodeStack(
|
||||
createStack((IAlleleSpecies) node.getValue(), BEE_TYPE_DRONE),
|
||||
center,
|
||||
(IAlleleSpecies) node.getValue(),
|
||||
center - OFFSET_CORRECTION,
|
||||
minY,
|
||||
ch,
|
||||
requirements,
|
||||
@@ -413,9 +434,24 @@ public class CachedBeeMutationTree extends CachedRecipe {
|
||||
return mutationNodesToRender;
|
||||
}
|
||||
|
||||
public List<RequirementSlot> getRequirementSlots() {
|
||||
return requirementSlots;
|
||||
}
|
||||
|
||||
public int getRecipeHeight() {
|
||||
int maxY = RequirementLayout.MIN_RECIPE_HEIGHT;
|
||||
for (RequirementSlot slot : requirementSlots) {
|
||||
maxY = Math.max(maxY, slot.rely + RequirementLayout.SLOT_SIZE + 4);
|
||||
}
|
||||
for (PositionedMutationNodeStack stack : evaluatedBeePositions) maxY = Math.max(maxY, stack.rely + 24);
|
||||
return maxY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<PositionedStack> getIngredients() {
|
||||
return new ArrayList<>(evaluatedBeePositions);
|
||||
List<PositionedStack> result = new ArrayList<>(evaluatedBeePositions);
|
||||
result.addAll(requirementSlots);
|
||||
return result;
|
||||
}
|
||||
|
||||
public static class PositionedMutationNodeStack extends PositionedStack {
|
||||
@@ -423,10 +459,11 @@ public class CachedBeeMutationTree extends CachedRecipe {
|
||||
public final boolean hasPossibleChildren;
|
||||
public final float baseChance;
|
||||
public final Collection<String> requirements;
|
||||
public final IAlleleSpecies species;
|
||||
public final PositionedMutationNodeStack leftChild, rightChild;
|
||||
|
||||
public PositionedMutationNodeStack(Object object, int x, int y, boolean genPerms, float baseChance,
|
||||
Collection<String> requirementInfo, PositionedMutationNodeStack leftChild,
|
||||
public PositionedMutationNodeStack(Object object, IAlleleSpecies species, int x, int y, boolean genPerms,
|
||||
float baseChance, Collection<String> requirementInfo, PositionedMutationNodeStack leftChild,
|
||||
PositionedMutationNodeStack rightChild, boolean hasPossibleChildren) {
|
||||
super(object, x, y, genPerms);
|
||||
this.leftChild = leftChild;
|
||||
@@ -434,9 +471,10 @@ public class CachedBeeMutationTree extends CachedRecipe {
|
||||
this.hasPossibleChildren = hasPossibleChildren;
|
||||
this.baseChance = baseChance;
|
||||
this.requirements = requirementInfo;
|
||||
this.species = species;
|
||||
}
|
||||
|
||||
public PositionedMutationNodeStack(Object object, int x, int y, float baseChance,
|
||||
public PositionedMutationNodeStack(Object object, IAlleleSpecies species, int x, int y, float baseChance,
|
||||
Collection<String> requirementInfo, PositionedMutationNodeStack leftChild,
|
||||
PositionedMutationNodeStack rightChild, boolean hasPossibleChildren) {
|
||||
super(object, x, y);
|
||||
@@ -445,6 +483,7 @@ public class CachedBeeMutationTree extends CachedRecipe {
|
||||
this.hasPossibleChildren = hasPossibleChildren;
|
||||
this.baseChance = baseChance;
|
||||
this.requirements = requirementInfo;
|
||||
this.species = species;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
package hellfirepvp.beebetteratbees.client.requirements;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
public class BlockRequirement {
|
||||
|
||||
private final List<ItemStack> candidates;
|
||||
private final String label;
|
||||
|
||||
public BlockRequirement(List<ItemStack> candidates, String label) {
|
||||
this.candidates = Collections.unmodifiableList(RequirementStacks.sanitize(candidates));
|
||||
this.label = label;
|
||||
}
|
||||
|
||||
public List<ItemStack> getCandidates() {
|
||||
return candidates;
|
||||
}
|
||||
|
||||
public String getLabel() {
|
||||
return label;
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return candidates.isEmpty();
|
||||
}
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
package hellfirepvp.beebetteratbees.client.requirements;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface IBlockRequirementProvider {
|
||||
|
||||
List<BlockRequirement> getRequirements(Object subject);
|
||||
}
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
package hellfirepvp.beebetteratbees.client.requirements;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraftforge.oredict.OreDictionary;
|
||||
|
||||
import forestry.api.genetics.IMutationCondition;
|
||||
import forestry.core.genetics.mutations.Mutation;
|
||||
import forestry.core.genetics.mutations.MutationConditionRequiresResource;
|
||||
import forestry.core.genetics.mutations.MutationConditionRequiresResourceOreDict;
|
||||
|
||||
public class MutationConditionRequirementProvider implements IBlockRequirementProvider {
|
||||
|
||||
@Override
|
||||
public List<BlockRequirement> getRequirements(Object subject) {
|
||||
if (!(subject instanceof Mutation)) return Collections.emptyList();
|
||||
List<BlockRequirement> result = new ArrayList<>();
|
||||
for (IMutationCondition condition : ((Mutation) subject).getMutationConditions()) {
|
||||
if (condition == null) continue;
|
||||
List<ItemStack> candidates = candidates(condition);
|
||||
if (!candidates.isEmpty()) result.add(new BlockRequirement(candidates, "bbab.requirement.blocks"));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private List<ItemStack> candidates(IMutationCondition condition) {
|
||||
if (condition instanceof MutationConditionRequiresResource) {
|
||||
ItemStack required = ((MutationConditionRequiresResource) condition).getBlockRequired();
|
||||
if (required == null || required.getItem() == null) return Collections.emptyList();
|
||||
return RequirementStacks.fromBlock(Block.getBlockFromItem(required.getItem()), required.getItemDamage());
|
||||
}
|
||||
if (!(condition instanceof MutationConditionRequiresResourceOreDict)) return Collections.emptyList();
|
||||
String oreName = OreDictionary
|
||||
.getOreName(((MutationConditionRequiresResourceOreDict) condition).getOreDictId());
|
||||
if (oreName == null || oreName.isEmpty()) return Collections.emptyList();
|
||||
List<ItemStack> result = new ArrayList<>();
|
||||
for (ItemStack stack : OreDictionary.getOres(oreName)) RequirementStacks.add(result, stack);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package hellfirepvp.beebetteratbees.client.requirements;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class RequirementLayout {
|
||||
|
||||
public static final int SLOT_SIZE = 18;
|
||||
public static final int SLOT_PITCH = 20;
|
||||
public static final int SLOT_GAP = 6;
|
||||
public static final int GUI_WIDTH = 166;
|
||||
public static final int MIN_RECIPE_HEIGHT = 65;
|
||||
|
||||
public static List<RequirementSlot> place(List<BlockRequirement> requirements, int beeX, int beeY) {
|
||||
List<BlockRequirement> groups = new ArrayList<>();
|
||||
for (BlockRequirement requirement : requirements)
|
||||
if (requirement != null && !requirement.isEmpty()) groups.add(requirement);
|
||||
if (groups.isEmpty()) return Collections.emptyList();
|
||||
int width = SLOT_SIZE + (groups.size() - 1) * SLOT_PITCH;
|
||||
int belowY = beeY + SLOT_SIZE + SLOT_GAP;
|
||||
int centeredX = Math.max(0, Math.min(GUI_WIDTH - width, beeX - (width - SLOT_SIZE) / 2));
|
||||
return placeRow(groups, centeredX, belowY);
|
||||
}
|
||||
|
||||
private static List<RequirementSlot> placeRow(List<BlockRequirement> groups, int x, int y) {
|
||||
int width = SLOT_SIZE + (groups.size() - 1) * SLOT_PITCH;
|
||||
if (x < 0 || y < 0 || x + width > GUI_WIDTH) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
List<RequirementSlot> result = new ArrayList<>();
|
||||
for (int index = 0; index < groups.size(); index++) {
|
||||
result.add(new RequirementSlot(groups.get(index), x + index * SLOT_PITCH, y));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
package hellfirepvp.beebetteratbees.client.requirements;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
import hellfirepvp.beebetteratbees.common.BeeBetterAtBees;
|
||||
|
||||
public class RequirementResolvers {
|
||||
|
||||
private static final List<IBlockRequirementProvider> PROVIDERS = new ArrayList<>();
|
||||
|
||||
public static void register(IBlockRequirementProvider provider) {
|
||||
if (provider != null && !PROVIDERS.contains(provider)) PROVIDERS.add(provider);
|
||||
}
|
||||
|
||||
public static List<BlockRequirement> resolve(Object subject) {
|
||||
List<BlockRequirement> result = new ArrayList<>();
|
||||
if (subject == null) return Collections.emptyList();
|
||||
for (IBlockRequirementProvider provider : PROVIDERS) {
|
||||
try {
|
||||
List<BlockRequirement> contributed = provider.getRequirements(subject);
|
||||
if (contributed != null) for (BlockRequirement requirement : contributed) {
|
||||
if (requirement != null && !requirement.isEmpty()) result.add(requirement);
|
||||
}
|
||||
} catch (Throwable error) {
|
||||
BeeBetterAtBees.log.warn("Requirement provider failed for {}", subject, error);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static boolean matches(Object subject, ItemStack ingredient) {
|
||||
if (ingredient == null) return false;
|
||||
for (BlockRequirement requirement : resolve(subject)) {
|
||||
for (ItemStack candidate : requirement.getCandidates()) {
|
||||
if (RequirementStacks.matches(candidate, ingredient)) return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package hellfirepvp.beebetteratbees.client.requirements;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import net.minecraft.util.StatCollector;
|
||||
|
||||
import codechicken.nei.PositionedStack;
|
||||
|
||||
public class RequirementSlot extends PositionedStack {
|
||||
|
||||
private final String label;
|
||||
|
||||
public RequirementSlot(BlockRequirement requirement, int x, int y) {
|
||||
super(requirement.getCandidates(), x, y);
|
||||
this.label = requirement.getLabel();
|
||||
setTooltip(Collections.singletonList(StatCollector.translateToLocal(label)));
|
||||
}
|
||||
|
||||
public String getLabel() {
|
||||
return label;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
package hellfirepvp.beebetteratbees.client.requirements;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraftforge.oredict.OreDictionary;
|
||||
|
||||
public class RequirementStacks {
|
||||
|
||||
public static List<ItemStack> fromBlock(Block block, int meta) {
|
||||
List<ItemStack> result = new ArrayList<>();
|
||||
if (block == null || block == Blocks.air) return result;
|
||||
Item item = Item.getItemFromBlock(block);
|
||||
if (item == null) return result;
|
||||
if (meta == OreDictionary.WILDCARD_VALUE) {
|
||||
addSubItems(result, item);
|
||||
}
|
||||
if (result.isEmpty()) add(result, new ItemStack(item, 1, meta == OreDictionary.WILDCARD_VALUE ? 0 : meta));
|
||||
return result;
|
||||
}
|
||||
|
||||
public static List<ItemStack> sanitize(List<ItemStack> stacks) {
|
||||
List<ItemStack> result = new ArrayList<>();
|
||||
if (stacks != null) for (ItemStack stack : stacks) add(result, stack);
|
||||
return result;
|
||||
}
|
||||
|
||||
public static void add(List<ItemStack> target, ItemStack stack) {
|
||||
if (stack == null || stack.getItem() == null) return;
|
||||
if (stack.getItemDamage() == OreDictionary.WILDCARD_VALUE) {
|
||||
int sizeBeforeExpansion = target.size();
|
||||
addSubItems(target, stack.getItem());
|
||||
if (target.size() == sizeBeforeExpansion) addExact(target, stack.getItem(), 0);
|
||||
return;
|
||||
}
|
||||
addExact(target, stack.getItem(), stack.getItemDamage());
|
||||
}
|
||||
|
||||
public static boolean matches(ItemStack candidate, ItemStack ingredient) {
|
||||
return candidate != null && ingredient != null
|
||||
&& candidate.isItemEqual(ingredient)
|
||||
&& ItemStack.areItemStackTagsEqual(candidate, ingredient);
|
||||
}
|
||||
|
||||
public static void addSubItems(List<ItemStack> target, Item item) {
|
||||
if (target == null || item == null) return;
|
||||
List<ItemStack> variants = new ArrayList<>();
|
||||
item.getSubItems(item, null, variants);
|
||||
for (ItemStack variant : variants) {
|
||||
if (variant != null && variant.getItem() != null
|
||||
&& variant.getItemDamage() != OreDictionary.WILDCARD_VALUE) {
|
||||
addExact(target, variant.getItem(), variant.getItemDamage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void addExact(List<ItemStack> target, Item item, int meta) {
|
||||
for (ItemStack existing : target) {
|
||||
if (existing.getItem() == item && existing.getItemDamage() == meta) return;
|
||||
}
|
||||
target.add(new ItemStack(item, 1, meta));
|
||||
}
|
||||
}
|
||||
@@ -1 +1,2 @@
|
||||
bbab.gui.breedtree=Bee Breeding Tree
|
||||
bbab.gui.breedtree=Bee Breeding Tree
|
||||
bbab.requirement.blocks=Required Blocks
|
||||
@@ -0,0 +1,2 @@
|
||||
bbab.gui.breedtree=蜜蜂杂交树
|
||||
bbab.requirement.blocks=需求方块
|
||||
Reference in new issue
Block a user