[Feature] Equipment Sets can be configured to build Smithing Recipes

This commit is contained in:
Frank 2023-06-03 19:14:46 +02:00
parent 1a7f3cf793
commit f8e4f29da4
8 changed files with 125 additions and 48 deletions

View file

@ -5,6 +5,7 @@ import org.betterx.bclib.api.v2.levelgen.structures.BCLStructure;
import org.betterx.bclib.complexmaterials.WoodenComplexMaterial; import org.betterx.bclib.complexmaterials.WoodenComplexMaterial;
import org.betterx.bclib.complexmaterials.set.wood.WoodSlots; import org.betterx.bclib.complexmaterials.set.wood.WoodSlots;
import org.betterx.bclib.items.complex.EquipmentSet; import org.betterx.bclib.items.complex.EquipmentSet;
import org.betterx.bclib.items.complex.EquipmentSlot;
import net.minecraft.advancements.*; import net.minecraft.advancements.*;
import net.minecraft.advancements.critereon.*; import net.minecraft.advancements.critereon.*;
@ -355,7 +356,7 @@ public class AdvancementManager {
// //
public Builder addEquipmentSetSlotCriterion(EquipmentSet set, String slot) { public Builder addEquipmentSetSlotCriterion(EquipmentSet set, EquipmentSlot slot) {
return addInventoryChangedCriterion( return addInventoryChangedCriterion(
set.baseName + "_" + slot, set.baseName + "_" + slot,
set.getSlot(slot) set.getSlot(slot)

View file

@ -12,23 +12,38 @@ import net.minecraft.world.item.*;
import net.minecraft.world.level.ItemLike; import net.minecraft.world.level.ItemLike;
import java.util.function.Function; import java.util.function.Function;
import org.jetbrains.annotations.Nullable;
public class EquipmentDescription<I extends Item> { public class EquipmentDescription<I extends Item> {
private final Function<Tier, I> creator; private final Function<Tier, I> creator;
private I item; private I item;
public final org.betterx.bclib.items.complex.EquipmentSlot slot;
public EquipmentDescription(Function<Tier, I> creator) { public EquipmentDescription(org.betterx.bclib.items.complex.EquipmentSlot slot, Function<Tier, I> creator) {
this.creator = creator; this.creator = creator;
this.slot = slot;
} }
public void init(ResourceLocation id, ItemRegistry itemsRegistry, Tier material, ItemLike stick) { public void init(
ResourceLocation id,
ItemRegistry itemsRegistry,
Tier material,
ItemLike stick,
@Nullable EquipmentSet sourceSet
) {
item = creator.apply(material); item = creator.apply(material);
itemsRegistry.registerTool(id, item); itemsRegistry.registerTool(id, item);
addRecipe(id, item, material, stick); addRecipe(id, item, material, stick, sourceSet);
} }
public void addRecipe(ResourceLocation id, Item tool, Tier material, ItemLike stick) { public void addRecipe(
ResourceLocation id,
Item tool,
Tier material,
ItemLike stick,
@Nullable EquipmentSet sourceSet
) {
if (material == null) return; if (material == null) return;
var repair = material.getRepairIngredient(); var repair = material.getRepairIngredient();
if (repair == null) return; if (repair == null) return;
@ -36,6 +51,16 @@ public class EquipmentDescription<I extends Item> {
if (repairItems == null || repairItems.length == 0) return; if (repairItems == null || repairItems.length == 0) return;
final ItemLike ingot = repairItems[0].getItem(); final ItemLike ingot = repairItems[0].getItem();
if (material instanceof SmithingSet smit && smit.getSmithingTemplateItem() != null && sourceSet != null) {
var builder = BCLRecipeBuilder
.smithing(id, tool)
.setTemplate(smit.getSmithingTemplateItem())
.setPrimaryInput(sourceSet.getSlot(this.slot))
.setAdditionAndUnlock(ingot)
.setCategory(slot.category());
builder.build();
} else {
var builder = BCLRecipeBuilder.crafting(id, tool) var builder = BCLRecipeBuilder.crafting(id, tool)
.addMaterial('#', ingot) .addMaterial('#', ingot)
.setCategory(RecipeCategory.TOOLS); .setCategory(RecipeCategory.TOOLS);
@ -44,6 +69,7 @@ public class EquipmentDescription<I extends Item> {
builder builder
.setGroup(id.getPath()) .setGroup(id.getPath())
.build(); .build();
}
} }

View file

@ -2,6 +2,7 @@ package org.betterx.bclib.items.complex;
import org.betterx.bclib.registry.ItemRegistry; import org.betterx.bclib.registry.ItemRegistry;
import net.minecraft.data.recipes.RecipeCategory;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.Item; import net.minecraft.world.item.Item;
import net.minecraft.world.item.Tier; import net.minecraft.world.item.Tier;
@ -106,11 +107,11 @@ public abstract class EquipmentSet {
} }
public interface ItemDescriptorCreator<I extends Item> { public interface ItemDescriptorCreator<I extends Item> {
EquipmentDescription<I> build(Item base, Function<Tier, I> creator); EquipmentDescription<I> build(EquipmentSlot slot, Item base, Function<Tier, I> creator);
} }
public interface DescriptorCreator<I extends Item> { public interface DescriptorCreator<I extends Item> {
EquipmentDescription<I> build(Function<Tier, I> creator); EquipmentDescription<I> build(EquipmentSlot slot, Function<Tier, I> creator);
} }
public interface ItemCreator<I extends Item> { public interface ItemCreator<I extends Item> {
@ -118,7 +119,7 @@ public abstract class EquipmentSet {
} }
public static class SetValues { public static class SetValues {
private final Map<String, Float> values; private final Map<EquipmentSlot, Float> values;
private SetValues() { private SetValues() {
values = new HashMap<>(); values = new HashMap<>();
@ -135,17 +136,17 @@ public abstract class EquipmentSet {
return v; return v;
} }
public SetValues add(String slot, float value) { public SetValues add(EquipmentSlot slot, float value) {
values.put(slot, value); values.put(slot, value);
return this; return this;
} }
public SetValues offset(String slot, float offset) { public SetValues offset(EquipmentSlot slot, float offset) {
values.put(slot, get(slot) + offset); values.put(slot, get(slot) + offset);
return this; return this;
} }
public float get(String slot) { public float get(EquipmentSlot slot) {
return values.getOrDefault(slot, 0.0f); return values.getOrDefault(slot, 0.0f);
} }
} }
@ -155,31 +156,22 @@ public abstract class EquipmentSet {
public final String modID; public final String modID;
public final ItemLike stick; public final ItemLike stick;
public static final String PICKAXE_SLOT = "pickaxe"; public static final EquipmentSlot PICKAXE_SLOT = new EquipmentSlot("pickaxe", RecipeCategory.TOOLS);
public static final String AXE_SLOT = "axe"; public static final EquipmentSlot AXE_SLOT = new EquipmentSlot("axe", RecipeCategory.TOOLS);
public static final String SHOVEL_SLOT = "shovel"; public static final EquipmentSlot SHOVEL_SLOT = new EquipmentSlot("shovel", RecipeCategory.TOOLS);
public static final String SWORD_SLOT = "sword"; public static final EquipmentSlot SWORD_SLOT = new EquipmentSlot("sword", RecipeCategory.COMBAT);
public static final String HOE_SLOT = "hoe"; public static final EquipmentSlot HOE_SLOT = new EquipmentSlot("hoe", RecipeCategory.TOOLS);
public static final String SHEARS_SLOT = "shears"; public static final EquipmentSlot SHEARS_SLOT = new EquipmentSlot("shears", RecipeCategory.TOOLS);
public static final String HELMET_SLOT = "helmet"; public static final EquipmentSlot HELMET_SLOT = new EquipmentSlot("helmet", RecipeCategory.COMBAT);
public static final String CHESTPLATE_SLOT = "chestplate"; public static final EquipmentSlot CHESTPLATE_SLOT = new EquipmentSlot("chestplate", RecipeCategory.COMBAT);
public static final String LEGGINGS_SLOT = "leggings"; public static final EquipmentSlot LEGGINGS_SLOT = new EquipmentSlot("leggings", RecipeCategory.COMBAT);
public static final String BOOTS_SLOT = "boots"; public static final EquipmentSlot BOOTS_SLOT = new EquipmentSlot("boots", RecipeCategory.COMBAT);
public final SetValues attackDamage; public final SetValues attackDamage;
public final SetValues attackSpeed; public final SetValues attackSpeed;
private final Map<String, EquipmentDescription<?>> descriptions = new HashMap<>(); private final Map<EquipmentSlot, EquipmentDescription<?>> descriptions = new HashMap<>();
protected final EquipmentSet sourceSet;
@Deprecated(forRemoval = true)
public EquipmentSet(
Tier material,
String modID,
String baseName,
ItemLike stick
) {
this(material, modID, baseName, stick, AttackDamage.IRON_LEVEL, AttackSpeed.IRON_LEVEL);
}
public EquipmentSet( public EquipmentSet(
Tier material, Tier material,
@ -188,6 +180,18 @@ public abstract class EquipmentSet {
ItemLike stick, ItemLike stick,
SetValues attackDamage, SetValues attackDamage,
SetValues attackSpeed SetValues attackSpeed
) {
this(material, modID, baseName, stick, null, attackDamage, attackSpeed);
}
public EquipmentSet(
Tier material,
String modID,
String baseName,
ItemLike stick,
EquipmentSet sourceSet,
SetValues attackDamage,
SetValues attackSpeed
) { ) {
this.material = material; this.material = material;
this.baseName = baseName; this.baseName = baseName;
@ -195,27 +199,30 @@ public abstract class EquipmentSet {
this.stick = stick; this.stick = stick;
this.attackDamage = attackDamage; this.attackDamage = attackDamage;
this.attackSpeed = attackSpeed; this.attackSpeed = attackSpeed;
this.sourceSet = sourceSet;
} }
protected <I extends Item> void add(String slot, EquipmentDescription<I> desc) { protected <I extends Item> void add(EquipmentSlot slot, EquipmentDescription<I> desc) {
descriptions.put(slot, desc); descriptions.put(slot, desc);
} }
protected <I extends Item> void add( protected <I extends Item> void add(
String slot, EquipmentSlot slot,
EquipmentSet baseSet, EquipmentSet baseSet,
ItemDescriptorCreator<I> descriptor, ItemDescriptorCreator<I> descriptor,
ItemCreator<I> item ItemCreator<I> item
) { ) {
EquipmentDescription<I> desc = descriptor.build( EquipmentDescription<I> desc = descriptor.build(
slot,
baseSet.getSlot(slot), baseSet.getSlot(slot),
(tier) -> item.build(tier, this.attackDamage.get(slot), this.attackSpeed.get(slot)) (tier) -> item.build(tier, this.attackDamage.get(slot), this.attackSpeed.get(slot))
); );
descriptions.put(slot, desc); descriptions.put(slot, desc);
} }
protected <I extends Item> void add(String slot, DescriptorCreator<I> descriptor, ItemCreator<I> item) { protected <I extends Item> void add(EquipmentSlot slot, DescriptorCreator<I> descriptor, ItemCreator<I> item) {
EquipmentDescription<I> desc = descriptor.build( EquipmentDescription<I> desc = descriptor.build(
slot,
(tier) -> item.build(tier, this.attackDamage.get(slot), this.attackSpeed.get(slot)) (tier) -> item.build(tier, this.attackDamage.get(slot), this.attackSpeed.get(slot))
); );
descriptions.put(slot, desc); descriptions.put(slot, desc);
@ -225,17 +232,17 @@ public abstract class EquipmentSet {
public EquipmentSet init(ItemRegistry itemsRegistry) { public EquipmentSet init(ItemRegistry itemsRegistry) {
for (var desc : descriptions.entrySet()) { for (var desc : descriptions.entrySet()) {
desc.getValue() desc.getValue()
.init(buildID(desc), itemsRegistry, material, stick); .init(buildID(desc), itemsRegistry, material, stick, sourceSet);
} }
return this; return this;
} }
@NotNull @NotNull
protected ResourceLocation buildID(Map.Entry<String, EquipmentDescription<?>> desc) { protected ResourceLocation buildID(Map.Entry<EquipmentSlot, EquipmentDescription<?>> desc) {
return new ResourceLocation(modID, baseName + "_" + desc.getKey()); return new ResourceLocation(modID, baseName + "_" + desc.getKey().name());
} }
public <I extends Item> I getSlot(String slot) { public <I extends Item> I getSlot(EquipmentSlot slot) {
return (I) descriptions.get(slot).getItem(); return (I) descriptions.get(slot).getItem();
} }
} }

View file

@ -0,0 +1,6 @@
package org.betterx.bclib.items.complex;
import net.minecraft.data.recipes.RecipeCategory;
public record EquipmentSlot(String name, RecipeCategory category) {
}

View file

@ -0,0 +1,7 @@
package org.betterx.bclib.items.complex;
import net.minecraft.world.item.SmithingTemplateItem;
public interface SmithingSet {
SmithingTemplateItem getSmithingTemplateItem();
}

View file

@ -57,6 +57,12 @@ public class SmithingRecipeBuilder extends AbstractUnlockableRecipeBuilder<Smith
return this; return this;
} }
public SmithingRecipeBuilder setAdditionAndUnlock(ItemLike item) {
this.addon = Ingredient.of(item);
this.unlockedBy(item);
return this;
}
@Override @Override
protected boolean checkRecipe() { protected boolean checkRecipe() {

View file

@ -12,7 +12,30 @@ public class SmithingTemplates {
public static final ChatFormatting TITLE_FORMAT = ChatFormatting.GRAY; public static final ChatFormatting TITLE_FORMAT = ChatFormatting.GRAY;
public static final ChatFormatting DESCRIPTION_FORMAT = ChatFormatting.BLUE; public static final ChatFormatting DESCRIPTION_FORMAT = ChatFormatting.BLUE;
public static final ResourceLocation EMPTY_SLOT_HELMET = new ResourceLocation("item/empty_armor_slot_helmet");
public static final ResourceLocation EMPTY_SLOT_CHESTPLATE = new ResourceLocation("item/empty_armor_slot_chestplate");
public static final ResourceLocation EMPTY_SLOT_LEGGINGS = new ResourceLocation("item/empty_armor_slot_leggings");
public static final ResourceLocation EMPTY_SLOT_BOOTS = new ResourceLocation("item/empty_armor_slot_boots");
public static final ResourceLocation EMPTY_SLOT_HOE = new ResourceLocation("item/empty_slot_hoe");
public static final ResourceLocation EMPTY_SLOT_AXE = new ResourceLocation("item/empty_slot_axe");
public static final ResourceLocation EMPTY_SLOT_SWORD = new ResourceLocation("item/empty_slot_sword");
public static final ResourceLocation EMPTY_SLOT_SHOVEL = new ResourceLocation("item/empty_slot_shovel");
public static final ResourceLocation EMPTY_SLOT_PICKAXE = new ResourceLocation("item/empty_slot_pickaxe");
public static final ResourceLocation EMPTY_SLOT_INGOT = new ResourceLocation("item/empty_slot_ingot"); public static final ResourceLocation EMPTY_SLOT_INGOT = new ResourceLocation("item/empty_slot_ingot");
public static final ResourceLocation EMPTY_SLOT_REDSTONE_DUST = new ResourceLocation("item/empty_slot_redstone_dust");
public static final ResourceLocation EMPTY_SLOT_DIAMOND = new ResourceLocation("item/empty_slot_diamond");
public static final List<ResourceLocation> ARMOR_AND_TOOLS = List.of(
EMPTY_SLOT_HELMET,
EMPTY_SLOT_SWORD,
EMPTY_SLOT_CHESTPLATE,
EMPTY_SLOT_PICKAXE,
EMPTY_SLOT_LEGGINGS,
EMPTY_SLOT_AXE,
EMPTY_SLOT_BOOTS,
EMPTY_SLOT_HOE,
EMPTY_SLOT_SHOVEL
);
public static Builder create(ResourceLocation id) { public static Builder create(ResourceLocation id) {
return new Builder(id); return new Builder(id);

View file

@ -35,3 +35,4 @@ accessible method net/minecraft/world/level/block/Blocks never (Lnet/minecraft/w
#Fields #Fields
accessible field net/minecraft/world/entity/ai/village/poi/PoiTypes TYPE_BY_STATE Ljava/util/Map; accessible field net/minecraft/world/entity/ai/village/poi/PoiTypes TYPE_BY_STATE Ljava/util/Map;
accessible field net/minecraft/world/level/block/entity/RandomizableContainerBlockEntity lootTable Lnet/minecraft/resources/ResourceLocation;