Skip to content

Commit

Permalink
Add smithing template item builder and type. Fixes #767 (#768)
Browse files Browse the repository at this point in the history
  • Loading branch information
ChiefArug authored Jan 15, 2024
1 parent 8579e6b commit dd3a9ad
Show file tree
Hide file tree
Showing 4 changed files with 340 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
import dev.latvian.mods.kubejs.item.custom.RecordItemJS;
import dev.latvian.mods.kubejs.item.custom.ShearsItemBuilder;
import dev.latvian.mods.kubejs.item.custom.ShovelItemBuilder;
import dev.latvian.mods.kubejs.item.custom.SmithingTemplateItemBuilder;
import dev.latvian.mods.kubejs.item.custom.SwordItemBuilder;
import dev.latvian.mods.kubejs.item.ingredient.IngredientJS;
import dev.latvian.mods.kubejs.level.gen.filter.biome.BiomeFilter;
Expand Down Expand Up @@ -215,6 +216,7 @@ public void init() {
RegistryInfo.ITEM.addType("leggings", ArmorItemBuilder.Leggings.class, ArmorItemBuilder.Leggings::new);
RegistryInfo.ITEM.addType("boots", ArmorItemBuilder.Boots.class, ArmorItemBuilder.Boots::new);
RegistryInfo.ITEM.addType("music_disc", RecordItemJS.Builder.class, RecordItemJS.Builder::new);
RegistryInfo.ITEM.addType("smithing_template", SmithingTemplateItemBuilder.class, SmithingTemplateItemBuilder::new);

RegistryInfo.FLUID.addType("basic", FluidBuilder.class, FluidBuilder::new);
RegistryInfo.ENCHANTMENT.addType("basic", EnchantmentBuilder.class, EnchantmentBuilder::new);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,266 @@
package dev.latvian.mods.kubejs.item.custom;

import dev.latvian.mods.kubejs.client.LangEventJS;
import dev.latvian.mods.kubejs.item.ItemBuilder;
import dev.latvian.mods.kubejs.typings.Info;
import net.minecraft.ChatFormatting;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.MutableComponent;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.SmithingTemplateItem;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

// shotgun import because we do actually use 90% of the static things in there
import static net.minecraft.world.item.SmithingTemplateItem.*;

@SuppressWarnings({"unused", "UnusedReturnValue"})
public class SmithingTemplateItemBuilder extends ItemBuilder {

private static final List<ResourceLocation> ARMOR_ICONS = SmithingTemplateItem.createTrimmableArmorIconList();
private static final List<ResourceLocation> INGOTS_AND_CRYSTALS_ICONS = SmithingTemplateItem.createTrimmableMaterialIconList();
private static final List<ResourceLocation> EQUIPMENT_ICONS = SmithingTemplateItem.createNetheriteUpgradeIconList();
private static final List<ResourceLocation> TOOL_ICONS = List.of(EMPTY_SLOT_HOE, EMPTY_SLOT_AXE, EMPTY_SLOT_SWORD, EMPTY_SLOT_SHOVEL, EMPTY_SLOT_PICKAXE);
private static final List<ResourceLocation> CRYSTAL_ICONS = List.of(EMPTY_SLOT_REDSTONE_DUST, EMPTY_SLOT_QUARTZ, EMPTY_SLOT_EMERALD, EMPTY_SLOT_DIAMOND, EMPTY_SLOT_LAPIS_LAZULI, EMPTY_SLOT_AMETHYST_SHARD);

private final Map<String, String> translations = new HashMap<>();
public Component appliesToText = Component.literal("set with .appliesToDescription(string) on your smithing_template type item").withStyle(ChatFormatting.BLUE);
public Component ingredientsText = Component.literal("set with .ingredientsDescription(string) on your smithing_template type item").withStyle(ChatFormatting.BLUE);
public Component appliesToSlotDescriptionText = Component.literal("set with .appliesToSlotDescription(string) on your smithing_template type item");
public Component ingredientSlotDescriptionText = Component.literal("set with .ingredientsSlotDescription(string) on your smithing_template type item");
public final List<ResourceLocation> appliesToEmptyIcons = new ArrayList<>();
public final List<ResourceLocation> ingredientsSlotEmptyIcons = new ArrayList<>();

public SmithingTemplateItemBuilder(ResourceLocation i) {
super(i);
}

@Info("""
Sets the description text that shows in the item tooltip to describe what it can be applied to.
Using 'Armor' or 'Diamond Equipment' will use the vanilla language keys so it is translated into other languages automatically.
THIS IS PURELY VISUAL
If you wish to apply non standard formatting (like change the colour) set the `ingredientsText` field.
""")
public SmithingTemplateItemBuilder appliesTo(String text) {
appliesToText = switch (text) {
// reuse the existing translation keys if they match
case "Armor" -> SmithingTemplateItem.ARMOR_TRIM_APPLIES_TO;
case "Diamond Equipment" -> SmithingTemplateItem.NETHERITE_UPGRADE_APPLIES_TO;
default -> defaultTranslateableTooltipComponent(text, "applies_to", true);
};
return this;
}

@Info("""
Sets the description text that shows in the item tooltip to describe what ingredients can be added.
Using 'Ingots & Crystals' or 'Netherite Ingot' will use the vanilla language keys so it is translated into other languages automatically.
THIS IS PURELY VISUAL
If you wish to apply non standard formatting (like change the colour) set the `ingredientsText` field.
""")
public SmithingTemplateItemBuilder ingredients(String text) {
ingredientsText = switch (text) {
// reuse the existing translation keys if they match
case "Ingots and Crystals", "Ingots & Crystals" -> SmithingTemplateItem.ARMOR_TRIM_INGREDIENTS;
case "Netherite Ingot" -> SmithingTemplateItem.NETHERITE_UPGRADE_INGREDIENTS;
default -> defaultTranslateableTooltipComponent(text, "ingredients", true);
};
return this;
}

@Info("""
Sets the description text that shows when you hover over the base item slot when this item is put in smithing table as a template.
Using 'Add a piece of armor' or 'Add diamond armor, weapon, or tool' will use the vanilla language keys so it is translated into other languages automatically.
If you wish to apply non standard formatting (like change the colour) set the `appliesToSlotDescriptionText` field.
""")
public SmithingTemplateItemBuilder appliesToSlotDescription(String text) {
appliesToSlotDescriptionText = switch (text) {
// reuse the existing translation keys if they match
case "Add a piece of armor" -> SmithingTemplateItem.ARMOR_TRIM_BASE_SLOT_DESCRIPTION;
case "Add diamond armor, weapon, or tool" -> SmithingTemplateItem.NETHERITE_UPGRADE_BASE_SLOT_DESCRIPTION;
default -> defaultTranslateableTooltipComponent(text, "base_slot_description", false);
};
return this;
}

@Info("""
Sets the description text that shows when you hover over the ingredient slot when this item is put in smithing table as a template.
Using 'Add ingot or crystal' or 'Add Netherite Ingot' will use the vanilla language keys so it is translated into other languages automatically.
If you wish to apply non standard formatting (like change the colour) set the `ingredientSlotDescriptionText` field.
""")
public SmithingTemplateItemBuilder ingredientsSlotDescription(String text) {
ingredientSlotDescriptionText = switch (text) {
// reuse the existing translation keys if they match
case "Add ingot or crystal" -> SmithingTemplateItem.ARMOR_TRIM_BASE_SLOT_DESCRIPTION;
case "Add Netherite Ingot" -> SmithingTemplateItem.NETHERITE_UPGRADE_BASE_SLOT_DESCRIPTION;
default -> defaultTranslateableTooltipComponent(text, "ingredient_slot_description", false);
};
return this;
}

@Info("Adds the specified texture location to the list of base slot icons that the smithing table cycles through when this smithing template is put in.")
public SmithingTemplateItemBuilder addAppliesToSlotIcon(ResourceLocation location) {
appliesToEmptyIcons.add(location);
return this;
}

@Info("Adds the specified texture location to the list of ingredient slot icons that the smithing table cycles through when this smithing template is put in")
public SmithingTemplateItemBuilder addIngredientsSlotIcon(ResourceLocation location) {
ingredientsSlotEmptyIcons.add(location);
return this;
}

@Info("Adds all armor icons to the list of base slot icons that the smithing table cycles through when this smithing template is put in")
public SmithingTemplateItemBuilder armorIcons() {
appliesToEmptyIcons.addAll(ARMOR_ICONS);
return this;
}

@Info("Adds all armor and basic tool icons to the list of base slot icons that the smithing table cycles through when this smithing template is put in")
public SmithingTemplateItemBuilder equipmentIcons() {
appliesToEmptyIcons.addAll(EQUIPMENT_ICONS);
return this;
}

@Info("Adds all basic tool icons to the list of base slot icons that the smithing table cycles through when this smithing template is put in")
public SmithingTemplateItemBuilder toolIcons() {
appliesToEmptyIcons.addAll(TOOL_ICONS);
return this;
}

@Info("Adds an ingot, dust, diamond, emerald, quartz, lapis lazuli and amethyst shard icons to the list of ingredient slot icons that the smithing table cycles through when this smithing template is put in")
public SmithingTemplateItemBuilder ingotAndCrystalIcons() {
ingredientsSlotEmptyIcons.addAll(INGOTS_AND_CRYSTALS_ICONS);
return this;
}

@Info("Adds a dust, diamond, emerald, quartz, lapis lazuli and amethyst shard icons to the list of ingredient slot icons that the smithing table cycles through when this smithing template is put in")
public SmithingTemplateItemBuilder crystalIcons() {
ingredientsSlotEmptyIcons.addAll(CRYSTAL_ICONS);
return this;
}

@Info("Adds an ingot to the list of ingredient slot icons that the smithing table cycles through when this smithing template is put in")
public SmithingTemplateItemBuilder ingotIcon() {
return addIngredientsSlotIcon(EMPTY_SLOT_INGOT);
}

@Info("Adds a dust to the list of ingredient slot icons that the smithing table cycles through when this smithing template is put in")
public SmithingTemplateItemBuilder dustIcon() {
return addIngredientsSlotIcon(EMPTY_SLOT_REDSTONE_DUST);
}

@Info("Adds an amethyst shard to the list of ingredient slot icons that the smithing table cycles through when this smithing template is put in")
public SmithingTemplateItemBuilder shardIcon() {
return addIngredientsSlotIcon(EMPTY_SLOT_AMETHYST_SHARD);
}

@Info("Adds a diamond to the list of ingredient slot icons that the smithing table cycles through when this smithing template is put in")
public SmithingTemplateItemBuilder diamondIcon() {
return addIngredientsSlotIcon(EMPTY_SLOT_DIAMOND);
}

@Info("Adds an emerald to the list of ingredient slot icons that the smithing table cycles through when this smithing template is put in")
public SmithingTemplateItemBuilder emeraldIcon() {
return addIngredientsSlotIcon(EMPTY_SLOT_EMERALD);
}

@Info("Adds a quartz to the list of ingredient slot icons that the smithing table cycles through when this smithing template is put in")
public SmithingTemplateItemBuilder quartzIcon() {
return addIngredientsSlotIcon(EMPTY_SLOT_QUARTZ);
}

@Info("Adds a lapis lazuli to the list of ingredient slot icons that the smithing table cycles through when this smithing template is put in")
public SmithingTemplateItemBuilder lapisIcon() {
return addIngredientsSlotIcon(EMPTY_SLOT_LAPIS_LAZULI);
}

@Info("Adds a sword to the list of base item slot icons that the smithing table cycles through when this smithing template is put in")
public SmithingTemplateItemBuilder swordIcon() {
return addAppliesToSlotIcon(EMPTY_SLOT_SWORD);
}

@Info("Adds a shovel to the list of base item slot icons that the smithing table cycles through when this smithing template is put in")
public SmithingTemplateItemBuilder shovelIcon() {
return addAppliesToSlotIcon(EMPTY_SLOT_SHOVEL);
}

@Info("Adds a axe to the list of base item slot icons that the smithing table cycles through when this smithing template is put in")
public SmithingTemplateItemBuilder axeIcon() {
return addAppliesToSlotIcon(EMPTY_SLOT_AXE);
}

@Info("Adds a pickaxe to the list of base item slot icons that the smithing table cycles through when this smithing template is put in")
public SmithingTemplateItemBuilder pickaxeIcon() {
return addAppliesToSlotIcon(EMPTY_SLOT_PICKAXE);
}

@Info("Adds a hoe to the list of base item slot icons that the smithing table cycles through when this smithing template is put in")
public SmithingTemplateItemBuilder hoeIcon() {
return addAppliesToSlotIcon(EMPTY_SLOT_HOE);
}

@Info("Adds a helmet to the list of base item slot icons that the smithing table cycles through when this smithing template is put in")
public SmithingTemplateItemBuilder helmetIcon() {
return addAppliesToSlotIcon(EMPTY_SLOT_HELMET);
}

@Info("Adds a chestplate to the list of base item slot icons that the smithing table cycles through when this smithing template is put in")
public SmithingTemplateItemBuilder chestplateIcon() {
return addAppliesToSlotIcon(EMPTY_SLOT_CHESTPLATE);
}

@Info("Adds leggings to the list of base item slot icons that the smithing table cycles through when this smithing template is put in")
public SmithingTemplateItemBuilder leggingsIcon() {
return addAppliesToSlotIcon(EMPTY_SLOT_LEGGINGS);
}

@Info("Adds boots to the list of base item slot icons that the smithing table cycles through when this smithing template is put in")
public SmithingTemplateItemBuilder bootsIcon() {
return addAppliesToSlotIcon(EMPTY_SLOT_BOOTS);
}

private Component defaultTranslateableTooltipComponent(String text, String type, boolean tooltipDescription) {
String translationKey = makeTooltipDescriptionId(type);
translations.put(translationKey, text);
MutableComponent component = Component.translatable(translationKey);
if (tooltipDescription) component.withStyle(DESCRIPTION_FORMAT);
return component;
}

private String makeTooltipDescriptionId(String type) {
return getTranslationKeyGroup() + '.' + id.getNamespace() + ".smithing_template." + id.getPath() + '.' + type;
}

@Override // override so we can add @Info
@Info("""
Sets the name for this smithing template.
Note that the normal display name for all smithing templates is the same and cannot be changed, this instead sets the name in the tooltip (see vanilla smithing templates for what this looks like).
This will be overridden by a lang file if it exists.
""")
public SmithingTemplateItemBuilder displayName(Component name) {
super.displayName(name.copy().withStyle(TITLE_FORMAT));
return this;
}

@Override
public void generateLang(LangEventJS lang) {
// call super as we still use the display name for the 'upgrade description'
// we don't use a custom lang key for that as vanillas format depends on it being an upgrade or trim, and we don't know which it is
super.generateLang(lang);
lang.addAll(id.getNamespace(), translations);
}

@Override
public SmithingTemplateItem createObject() {
return new SmithingTemplateItem(appliesToText, ingredientsText, Objects.requireNonNullElse(displayName, Component.translatable(getBuilderTranslationKey()).withStyle(TITLE_FORMAT)), appliesToSlotDescriptionText, ingredientSlotDescriptionText, appliesToEmptyIcons, ingredientsSlotEmptyIcons);
}
}
37 changes: 36 additions & 1 deletion common/src/main/resources/kubejs.accesswidener
Original file line number Diff line number Diff line change
Expand Up @@ -81,4 +81,39 @@ accessible field net/minecraft/world/entity/item/ItemEntity LIFETIME I
accessible field net/minecraft/world/entity/item/ItemEntity age I

# client stuff
accessible class net/minecraft/client/gui/components/AbstractSelectionList$Entry
accessible class net/minecraft/client/gui/components/AbstractSelectionList$Entry

# smithing table text components and icons
accessible field net/minecraft/world/item/SmithingTemplateItem APPLIES_TO_TITLE Lnet/minecraft/network/chat/Component;
accessible field net/minecraft/world/item/SmithingTemplateItem INGREDIENTS_TITLE Lnet/minecraft/network/chat/Component;
accessible field net/minecraft/world/item/SmithingTemplateItem ARMOR_TRIM_ADDITIONS_SLOT_DESCRIPTION Lnet/minecraft/network/chat/Component;
accessible field net/minecraft/world/item/SmithingTemplateItem ARMOR_TRIM_BASE_SLOT_DESCRIPTION Lnet/minecraft/network/chat/Component;
accessible field net/minecraft/world/item/SmithingTemplateItem ARMOR_TRIM_INGREDIENTS Lnet/minecraft/network/chat/Component;
accessible field net/minecraft/world/item/SmithingTemplateItem ARMOR_TRIM_APPLIES_TO Lnet/minecraft/network/chat/Component;
accessible field net/minecraft/world/item/SmithingTemplateItem NETHERITE_UPGRADE Lnet/minecraft/network/chat/Component;
accessible field net/minecraft/world/item/SmithingTemplateItem NETHERITE_UPGRADE_APPLIES_TO Lnet/minecraft/network/chat/Component;
accessible field net/minecraft/world/item/SmithingTemplateItem NETHERITE_UPGRADE_ADDITIONS_SLOT_DESCRIPTION Lnet/minecraft/network/chat/Component;
accessible field net/minecraft/world/item/SmithingTemplateItem NETHERITE_UPGRADE_BASE_SLOT_DESCRIPTION Lnet/minecraft/network/chat/Component;
accessible field net/minecraft/world/item/SmithingTemplateItem NETHERITE_UPGRADE_INGREDIENTS Lnet/minecraft/network/chat/Component;
accessible method net/minecraft/world/item/SmithingTemplateItem createTrimmableArmorIconList ()Ljava/util/List;
accessible method net/minecraft/world/item/SmithingTemplateItem createNetheriteUpgradeIconList ()Ljava/util/List;
accessible method net/minecraft/world/item/SmithingTemplateItem createTrimmableMaterialIconList ()Ljava/util/List;
accessible method net/minecraft/world/item/SmithingTemplateItem createNetheriteUpgradeMaterialList ()Ljava/util/List;
accessible field net/minecraft/world/item/SmithingTemplateItem EMPTY_SLOT_HELMET Lnet/minecraft/resources/ResourceLocation;
accessible field net/minecraft/world/item/SmithingTemplateItem EMPTY_SLOT_CHESTPLATE Lnet/minecraft/resources/ResourceLocation;
accessible field net/minecraft/world/item/SmithingTemplateItem EMPTY_SLOT_LEGGINGS Lnet/minecraft/resources/ResourceLocation;
accessible field net/minecraft/world/item/SmithingTemplateItem EMPTY_SLOT_BOOTS Lnet/minecraft/resources/ResourceLocation;
accessible field net/minecraft/world/item/SmithingTemplateItem EMPTY_SLOT_HOE Lnet/minecraft/resources/ResourceLocation;
accessible field net/minecraft/world/item/SmithingTemplateItem EMPTY_SLOT_AXE Lnet/minecraft/resources/ResourceLocation;
accessible field net/minecraft/world/item/SmithingTemplateItem EMPTY_SLOT_SWORD Lnet/minecraft/resources/ResourceLocation;
accessible field net/minecraft/world/item/SmithingTemplateItem EMPTY_SLOT_SHOVEL Lnet/minecraft/resources/ResourceLocation;
accessible field net/minecraft/world/item/SmithingTemplateItem EMPTY_SLOT_PICKAXE Lnet/minecraft/resources/ResourceLocation;
accessible field net/minecraft/world/item/SmithingTemplateItem EMPTY_SLOT_INGOT Lnet/minecraft/resources/ResourceLocation;
accessible field net/minecraft/world/item/SmithingTemplateItem EMPTY_SLOT_REDSTONE_DUST Lnet/minecraft/resources/ResourceLocation;
accessible field net/minecraft/world/item/SmithingTemplateItem EMPTY_SLOT_QUARTZ Lnet/minecraft/resources/ResourceLocation;
accessible field net/minecraft/world/item/SmithingTemplateItem EMPTY_SLOT_EMERALD Lnet/minecraft/resources/ResourceLocation;
accessible field net/minecraft/world/item/SmithingTemplateItem EMPTY_SLOT_DIAMOND Lnet/minecraft/resources/ResourceLocation;
accessible field net/minecraft/world/item/SmithingTemplateItem EMPTY_SLOT_LAPIS_LAZULI Lnet/minecraft/resources/ResourceLocation;
accessible field net/minecraft/world/item/SmithingTemplateItem EMPTY_SLOT_AMETHYST_SHARD Lnet/minecraft/resources/ResourceLocation;
accessible field net/minecraft/world/item/SmithingTemplateItem DESCRIPTION_FORMAT Lnet/minecraft/ChatFormatting;
accessible field net/minecraft/world/item/SmithingTemplateItem TITLE_FORMAT Lnet/minecraft/ChatFormatting;
Loading

0 comments on commit dd3a9ad

Please sign in to comment.