Skip to content

Commit

Permalink
Implement tool definition module for changng interactions
Browse files Browse the repository at this point in the history
By default, most tools allow any interaction modifier to act
Slimestaffs support both left and right click interaction, they use a worktable recipe to choose which interaction on a per modifier basis
Shields support left click interaction, and also have a single right click modifier for blocking. They use a more restricted version of the module
  • Loading branch information
KnightMiner committed Feb 2, 2023
1 parent e660a36 commit 56844a7
Show file tree
Hide file tree
Showing 30 changed files with 433 additions and 28 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"type": "tconstruct:modifier_set_worktable",
"data_key": "tconstruct:attack_modifiers",
"tools": {
"tag": "tconstruct:modifiable/interactable/dual"
},
"inputs": [
{
"item": "minecraft:lever"
},
{
"item": "minecraft:lever"
}
],
"modifier_predicate": {
"type": "tconstruct:tag",
"tag": "tconstruct:dual_interaction"
},
"add_to_set": false,
"allow_traits": false
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"type": "tconstruct:modifier_set_worktable",
"data_key": "tconstruct:attack_modifiers",
"tools": {
"tag": "tconstruct:modifiable/interactable/dual"
},
"inputs": [
{
"item": "minecraft:lever"
}
],
"modifier_predicate": {
"type": "tconstruct:tag",
"tag": "tconstruct:dual_interaction"
},
"add_to_set": true,
"allow_traits": false
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
{
"type": "tconstruct:modifier_set_worktable",
"data_key": "tconstruct:invisible_modifiers",
"tools": {
"tag": "tconstruct:modifiable"
},
"inputs": [
{
"type": "forge:partial_nbt",
Expand All @@ -15,5 +18,6 @@
"tag": "tconstruct:invisible_ink_blacklist"
}
},
"add_to_set": true
"add_to_set": true,
"allow_traits": false
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
{
"type": "tconstruct:modifier_set_worktable",
"data_key": "tconstruct:invisible_modifiers",
"tools": {
"tag": "tconstruct:modifiable"
},
"inputs": [
{
"tag": "forge:milk",
Expand All @@ -18,5 +21,6 @@
"tag": "tconstruct:invisible_ink_blacklist"
}
},
"add_to_set": false
"add_to_set": false,
"allow_traits": false
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"replace": false,
"values": [
"tconstruct:crossbow",
"tconstruct:longbow"
"tconstruct:longbow",
"#tconstruct:modifiable/interactable/dual"
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"replace": false,
"values": [
"#tconstruct:modifiable/one_handed",
"#tconstruct:modifiable/two_handed"
"#tconstruct:modifiable/two_handed",
"#tconstruct:modifiable/interactable/dual"
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"replace": false,
"values": [
"tconstruct:bucketing",
"tconstruct:glowing",
"tconstruct:firestarter",
"tconstruct:stripping",
"tconstruct:tilling",
"tconstruct:pathing",
"tconstruct:shears",
"tconstruct:harvest",
{
"id": "tconstruct:pockets",
"required": false
}
]
}
4 changes: 4 additions & 0 deletions src/main/java/slimeknights/tconstruct/common/TinkerTags.java
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,8 @@ private static void init() {}
public static final TagKey<Item> INTERACTABLE_LEFT = tag("modifiable/interactable/left");
/** Tools that can interact when worn as armor */
public static final TagKey<Item> INTERACTABLE_ARMOR = tag("modifiable/interactable/armor");
/** Tools that can interact on left click or right click */
public static final TagKey<Item> INTERACTABLE_DUAL = tag("modifiable/interactable/dual");

/** Items in this tag support the @link ToolStats#ATTACK_DAMAGE} stat. Should not be added to directly typically, use {@link #MELEE} or {@link #CHESTPLATES}
* TODO 1.19: rename to "modifiable/melee" */
Expand Down Expand Up @@ -503,6 +505,8 @@ private static void init() {}
public static final TagKey<Modifier> EXTRACT_MODIFIER_BLACKLIST = tag("extract_blacklist/tools");
/** Blacklist for modifiers that cannot be extracted via the slotless recipe */
public static final TagKey<Modifier> EXTRACT_SLOTLESS_BLACKLIST = tag("extract_blacklist/slotless");
/** Modifiers that can be used on both left and right click. Does not care about armor modifiers */
public static final TagKey<Modifier> DUAL_INTERACTION = tag("dual_interaction");

private static TagKey<Modifier> tag(String name) {
return ModifierManager.getTag(TConstruct.getResource(name));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
import static slimeknights.tconstruct.common.TinkerTags.Items.HELMETS;
import static slimeknights.tconstruct.common.TinkerTags.Items.INTERACTABLE;
import static slimeknights.tconstruct.common.TinkerTags.Items.INTERACTABLE_ARMOR;
import static slimeknights.tconstruct.common.TinkerTags.Items.INTERACTABLE_DUAL;
import static slimeknights.tconstruct.common.TinkerTags.Items.INTERACTABLE_LEFT;
import static slimeknights.tconstruct.common.TinkerTags.Items.INTERACTABLE_RIGHT;
import static slimeknights.tconstruct.common.TinkerTags.Items.LEGGINGS;
Expand Down Expand Up @@ -260,7 +261,8 @@ private void addTools() {
this.tag(MELEE_OR_UNARMED).addTag(MELEE).addTag(UNARMED);
this.tag(UNARMED).addTag(CHESTPLATES);
// migrating one handed and two handed to interactable right
this.tag(INTERACTABLE_RIGHT).addTags(ONE_HANDED, TWO_HANDED);
this.tag(INTERACTABLE_RIGHT).addTags(ONE_HANDED, TWO_HANDED, INTERACTABLE_DUAL);
this.tag(INTERACTABLE_LEFT).addTag(INTERACTABLE_DUAL);
// interactable armor is mostly so some mod could disable all chestplate interactions in one swing
this.tag(INTERACTABLE_ARMOR).addTag(CHESTPLATES);
// left and right handed are held, but not armor
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,14 @@ protected void addTags() {
.add(TinkerModifiers.embellishment.getId(), TinkerModifiers.dyed.getId(), TinkerModifiers.creativeSlot.getId(), TinkerModifiers.statOverride.getId());
// blacklist modifiers that are not really slotless, they just have a slotless recipe
tag(TinkerTags.Modifiers.EXTRACT_SLOTLESS_BLACKLIST).add(ModifierIds.luck, ModifierIds.toolBelt);

// modifiers in this tag support both left click and right click interaction
tag(TinkerTags.Modifiers.DUAL_INTERACTION)
.add(TinkerModifiers.bucketing.getId(),
TinkerModifiers.glowing.getId(), TinkerModifiers.firestarter.getId(),
TinkerModifiers.stripping.getId(), TinkerModifiers.tilling.getId(), TinkerModifiers.pathing.getId(),
TinkerModifiers.shears.getId(), TinkerModifiers.harvest.getId())
.addOptional(ModifierIds.pockets);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@
public class TinkerHooks {
private TinkerHooks() {}

public static void init() {}


/* General */

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package slimeknights.tconstruct.library.modifiers.dynamic;

import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
Expand All @@ -17,6 +18,8 @@
import slimeknights.tconstruct.library.modifiers.impl.InventoryModifier;
import slimeknights.tconstruct.library.modifiers.util.ModifierHookMap.Builder;
import slimeknights.tconstruct.library.tools.capability.ToolInventoryCapability;
import slimeknights.tconstruct.library.tools.definition.module.ToolModuleHooks;
import slimeknights.tconstruct.library.tools.definition.module.interaction.DualOptionInteraction;
import slimeknights.tconstruct.library.tools.nbt.IToolStackView;

public class InventoryMenuModifier extends InventoryModifier implements KeybindInteractModifierHook, GeneralInteractionModifierHook {
Expand All @@ -36,14 +39,19 @@ public int getPriority() {
return 75; // run latest so the keybind does not prevent shield strap or tool belt
}

@Override
public Component getDisplayName(IToolStackView tool, int level) {
return DualOptionInteraction.formatModifierName(tool, this, super.getDisplayName(tool, level));
}

@Override
public boolean startInteract(IToolStackView tool, ModifierEntry modifier, Player player, EquipmentSlot slot, TooltipKey keyModifier) {
return ToolInventoryCapability.tryOpenContainer(player.getItemBySlot(slot), tool, player, slot).consumesAction();
}

@Override
public InteractionResult onToolUse(IToolStackView tool, ModifierEntry modifier, Player player, InteractionHand hand, InteractionSource source) {
if (player.isCrouching()) {
if (player.isCrouching() && tool.getDefinitionData().getModule(ToolModuleHooks.INTERACTION).canInteract(tool, modifier.getId(), source)) {
EquipmentSlot slot = source.getSlot(hand);
return ToolInventoryCapability.tryOpenContainer(player.getItemBySlot(slot), tool, player, slot);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,39 +2,43 @@

import lombok.Getter;
import lombok.RequiredArgsConstructor;
import net.minecraft.core.Registry;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.crafting.Ingredient;
import net.minecraft.world.level.Level;
import slimeknights.mantle.recipe.ingredient.SizedIngredient;
import slimeknights.mantle.util.RegistryHelper;
import slimeknights.tconstruct.common.TinkerTags;
import slimeknights.tconstruct.library.modifiers.ModifierEntry;
import slimeknights.tconstruct.library.recipe.ITinkerableContainer;
import slimeknights.tconstruct.library.recipe.modifiers.ModifierRecipeLookup;
import slimeknights.tconstruct.library.recipe.modifiers.adding.ModifierRecipe;
import slimeknights.tconstruct.library.tools.item.IModifiableDisplay;
import slimeknights.tconstruct.library.tools.nbt.IToolStackView;

import javax.annotation.Nullable;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import static slimeknights.tconstruct.library.recipe.modifiers.adding.IDisplayModifierRecipe.MAP_TOOL_FOR_RENDERING;

/** Default implementation of modifier worktable recipes, taking a list of inputs */
@RequiredArgsConstructor
public abstract class AbstractWorktableRecipe implements IModifierWorktableRecipe {
@Getter
private final ResourceLocation id;
protected final Ingredient toolRequirement;
protected final List<SizedIngredient> inputs;

/* JEI */
@Nullable
protected List<ItemStack> tools;

public AbstractWorktableRecipe(ResourceLocation id, List<SizedIngredient> inputs) {
this(id, Ingredient.of(TinkerTags.Items.MODIFIABLE), inputs);
}

@Override
public boolean matches(ITinkerableContainer inv, Level world) {
if (!inv.getTinkerableStack().is(TinkerTags.Items.MODIFIABLE)) {
if (!toolRequirement.test(inv.getTinkerableStack())) {
return false;
}
return ModifierRecipe.checkMatch(inv, inputs);
Expand All @@ -60,7 +64,7 @@ public void updateInputs(IToolStackView result, ITinkerableContainer.Mutable inv
@Override
public List<ItemStack> getInputTools() {
if (tools == null) {
tools = RegistryHelper.getTagValueStream(Registry.ITEM, TinkerTags.Items.DURABILITY).map(MAP_TOOL_FOR_RENDERING).toList();
tools = Arrays.stream(toolRequirement.getItems()).map(stack -> IModifiableDisplay.getDisplayStack(stack.getItem())).toList();
}
return tools;
}
Expand Down

0 comments on commit 56844a7

Please sign in to comment.