Skip to content

Commit

Permalink
WIP Tool actions refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
AlphaMode committed Jul 16, 2024
1 parent 6caefff commit 9a7f279
Show file tree
Hide file tree
Showing 74 changed files with 323 additions and 376 deletions.
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
/*
* Copyright (c) Forge Development LLC and contributors
* SPDX-License-Identifier: LGPL-2.1-only
*/

package io.github.fabricators_of_create.porting_lib.tool;

import com.google.common.collect.Sets;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import net.minecraft.core.BlockPos;
import net.minecraft.core.dispenser.BlockSource;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.item.ItemStack;

public class ItemAbilities {
/**
* Exposed by axes to allow querying tool behaviours
*/
public static final ItemAbility AXE_DIG = ItemAbility.get("axe_dig");

/**
* Exposed by pickaxes to allow querying tool behaviours
*/
public static final ItemAbility PICKAXE_DIG = ItemAbility.get("pickaxe_dig");

/**
* Exposed by shovels to allow querying tool behaviours
*/
public static final ItemAbility SHOVEL_DIG = ItemAbility.get("shovel_dig");

/**
* Exposed by hoes to allow querying tool behaviours
*/
public static final ItemAbility HOE_DIG = ItemAbility.get("hoe_dig");

/**
* Exposed by swords to allow querying tool behaviours
*/
public static final ItemAbility SWORD_DIG = ItemAbility.get("sword_dig");

/**
* Exposed by shears to allow querying tool behaviours
*/
public static final ItemAbility SHEARS_DIG = ItemAbility.get("shears_dig");

/**
* Passed onto {@link IBlockExtension#getToolModifiedState} when an axe wants to strip a log
*/
public static final ItemAbility AXE_STRIP = ItemAbility.get("axe_strip");

/**
* Passed onto {@link IBlockExtension#getToolModifiedState} when an axe wants to scrape oxidization off copper
*/
public static final ItemAbility AXE_SCRAPE = ItemAbility.get("axe_scrape");

/**
* Passed onto {@link IBlockExtension#getToolModifiedState} when an axe wants to remove wax out of copper
*/
public static final ItemAbility AXE_WAX_OFF = ItemAbility.get("axe_wax_off");

/**
* Passed onto {@link IBlockExtension#getToolModifiedState} when a shovel wants to turn dirt into path
*/
public static final ItemAbility SHOVEL_FLATTEN = ItemAbility.get("shovel_flatten");

/**
* Passed onto {@link IBlockExtension#getToolModifiedState} when a shovel wants to douse a campfire
*/
public static final ItemAbility SHOVEL_DOUSE = ItemAbility.get("shovel_douse");

/**
* Used during player attack to figure out if a sweep attack should be performed
*
* @see IItemExtension#getSweepHitBox
*/
public static final ItemAbility SWORD_SWEEP = ItemAbility.get("sword_sweep");

/**
* This action is exposed by shears and corresponds to a harvest action that is triggered with a right click on a block that supports such behaviour.
* Example: Right click with shears on a beehive with honey level 5 to harvest it.
*
* @see CommonHooks#tryDispenseShearsHarvestBlock(BlockSource, ItemStack, ServerLevel, BlockPos)
*/
public static final ItemAbility SHEARS_HARVEST = ItemAbility.get("shears_harvest");

/**
* This action is exposed by shears and corresponds to a harvest action that is triggered with a right click on armored wolves.
*/
public static final ItemAbility SHEARS_REMOVE_ARMOR = ItemAbility.get("shears_remove_armor");

/**
* This action is exposed by shears and corresponds to a carve action that is triggered with a right click on a block that supports such behaviour.
* Example: Right click with shears on a pumpkin to carve it.
*/
public static final ItemAbility SHEARS_CARVE = ItemAbility.get("shears_carve");

/**
* This action is exposed by shears and corresponds to a disarm action that is triggered by breaking a block that supports such behaviour.
* Example: Breaking a trip wire with shears to disarm it.
*/
public static final ItemAbility SHEARS_DISARM = ItemAbility.get("shears_disarm");

/**
* This action is exposed by shears and corresponds to a trim action that is triggered with a right click on a block that supports such behavior.
* Example: Right click with shears on a {@link net.minecraft.world.level.block.GrowingPlantHeadBlock growing plant} to stop it from growing.
*/
public static final ItemAbility SHEARS_TRIM = ItemAbility.get("shears_trim");

/**
* Passed onto {@link IBlockExtension#getToolModifiedState} when a hoe wants to turn dirt into soil
*/
public static final ItemAbility HOE_TILL = ItemAbility.get("till");

/**
* An item ability corresponding to the 'block' action of shields.
* Items should expose this item ability in order to enable damage blocking when the item is being "used".
*/
public static final ItemAbility SHIELD_BLOCK = ItemAbility.get("shield_block");

/**
* This action corresponds to right-clicking the fishing rod to reel it in after earlier casting.
* Needed for modded fishing rods so that the FishingHook entity can properly function.
*/
public static final ItemAbility FISHING_ROD_CAST = ItemAbility.get("fishing_rod_cast");

/**
* Exposed by trident-like items to allow querying tool behaviours for items that can be thrown like Tridents.
*/
public static final ItemAbility TRIDENT_THROW = ItemAbility.get("trident_throw");

/**
* Exposed by brushes to allow querying tool behaviours for items that can brush Suspicious Blocks.
*/
public static final ItemAbility BRUSH_BRUSH = ItemAbility.get("brush_brush");

/**
* Passed onto {@link IBlockExtension#getToolModifiedState} when flint and steel or fire charge want to light a campfire/candle/cake.
* Note that dispensers with flint and steel will also use this but will have no player.
*/
public static final ItemAbility FIRESTARTER_LIGHT = ItemAbility.get("firestarter_light");

// Default actions supported by each tool type
public static final Set<ItemAbility> DEFAULT_AXE_ACTIONS = of(AXE_DIG, AXE_STRIP, AXE_SCRAPE, AXE_WAX_OFF);
public static final Set<ItemAbility> DEFAULT_HOE_ACTIONS = of(HOE_DIG, HOE_TILL);
public static final Set<ItemAbility> DEFAULT_SHOVEL_ACTIONS = of(SHOVEL_DIG, SHOVEL_FLATTEN, SHOVEL_DOUSE);
public static final Set<ItemAbility> DEFAULT_PICKAXE_ACTIONS = of(PICKAXE_DIG);
public static final Set<ItemAbility> DEFAULT_SWORD_ACTIONS = of(SWORD_DIG, SWORD_SWEEP);
public static final Set<ItemAbility> DEFAULT_SHEARS_ACTIONS = of(SHEARS_DIG, SHEARS_HARVEST, SHEARS_REMOVE_ARMOR, SHEARS_CARVE, SHEARS_DISARM, SHEARS_TRIM);
public static final Set<ItemAbility> DEFAULT_SHIELD_ACTIONS = of(SHIELD_BLOCK);
public static final Set<ItemAbility> DEFAULT_FISHING_ROD_ACTIONS = of(FISHING_ROD_CAST);
public static final Set<ItemAbility> DEFAULT_TRIDENT_ACTIONS = of(TRIDENT_THROW);
public static final Set<ItemAbility> DEFAULT_BRUSH_ACTIONS = of(BRUSH_BRUSH);
public static final Set<ItemAbility> DEFAULT_FLINT_ACTIONS = of(FIRESTARTER_LIGHT);
public static final Set<ItemAbility> DEFAULT_FIRECHARGE_ACTIONS = of(FIRESTARTER_LIGHT);

private static Set<ItemAbility> of(ItemAbility... actions) {
return Stream.of(actions).collect(Collectors.toCollection(Sets::newIdentityHashSet));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package io.github.fabricators_of_create.porting_lib.tool;

import com.mojang.serialization.Codec;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public final class ItemAbility {
private static final Map<String, ItemAbility> actions = new ConcurrentHashMap<>();

public static Codec<ItemAbility> CODEC = Codec.STRING.xmap(ItemAbility::get, ItemAbility::name);

/**
* Returns all registered actions.
* This collection can be kept around, and will update itself in response to changes to the map.
* See {@link ConcurrentHashMap#values()} for details.
*/
public static Collection<ItemAbility> getActions() {
return Collections.unmodifiableCollection(actions.values());
}

/**
* Gets or creates a new ItemAbility for the given name.
*/
public static ItemAbility get(String name) {
return actions.computeIfAbsent(name, ItemAbility::new);
}

/**
* Returns the name of this item ability
*/
public String name() {
return name;
}

@Override
public String toString() {
return "ItemAbility[" + name + "]";
}

private final String name;

/**
* Use {@link #get(String)} to get or create a ItemAbility
*/
private ItemAbility(String name) {
this.name = name;
}
}
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
package io.github.fabricators_of_create.porting_lib.tool.addons;

import io.github.fabricators_of_create.porting_lib.tool.ToolAction;
import io.github.fabricators_of_create.porting_lib.tool.ToolActions;
import io.github.fabricators_of_create.porting_lib.tool.ItemAbility;
import io.github.fabricators_of_create.porting_lib.tool.ItemAbilities;
import net.minecraft.world.item.ItemStack;

public interface ToolActionItem {
/**
* Queries if an item can perform the given action.
* See {@link ToolActions} for a description of each stock action
* See {@link ItemAbilities} for a description of each stock action
* @param stack The stack being used
* @param toolAction The action being queried
* @return True if the stack can perform the action
*/
default boolean canPerformAction(ItemStack stack, ToolAction toolAction) {
default boolean canPerformAction(ItemStack stack, ItemAbility toolAction) {
return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,16 @@

import com.google.common.collect.Sets;

import io.github.fabricators_of_create.porting_lib.tool.ToolActions;
import io.github.fabricators_of_create.porting_lib.tool.loot.CanToolPerformAction;
import io.github.fabricators_of_create.porting_lib.tool.ItemAbilities;
import io.github.fabricators_of_create.porting_lib.tool.loot.CanItemPerformAbility;
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput;
import net.minecraft.Util;
import net.minecraft.advancements.critereon.ItemPredicate;
import net.minecraft.core.Holder;
import net.minecraft.core.HolderLookup;
import net.minecraft.data.CachedOutput;
import net.minecraft.data.DataProvider;
import net.minecraft.data.PackOutput;
import net.minecraft.data.loot.LootTableProvider;
import net.minecraft.data.loot.LootTableSubProvider;
import net.minecraft.data.loot.packs.VanillaLootTableProvider;
Expand Down Expand Up @@ -70,8 +70,8 @@
public final class ToolActionsLootTableProvider extends LootTableProvider {
private final List<Function<LootItemCondition, LootItemCondition.Builder>> conditionReplacers = new ArrayList<>();

public ToolActionsLootTableProvider(FabricDataOutput packOutput) {
super(packOutput, Set.of(), VanillaLootTableProvider.create(packOutput).subProviders);
public ToolActionsLootTableProvider(FabricDataOutput packOutput, CompletableFuture<HolderLookup.Provider> provider) {
super(packOutput, Set.of(), VanillaLootTableProvider.create(packOutput, provider).subProviders, provider);
}

protected void validate(Map<ResourceLocation, LootTable> map, ValidationContext validationcontext) {
Expand All @@ -81,13 +81,13 @@ protected void validate(Map<ResourceLocation, LootTable> map, ValidationContext
public List<LootTableProvider.SubProviderEntry> getTables() {
replaceLootItemCondition(condition -> {
if (condition instanceof MatchTool matchTool && checkMatchTool(matchTool, Items.SHEARS)) {
return CanToolPerformAction.canToolPerformAction(ToolActions.SHEARS_DIG);
return CanItemPerformAbility.canItemPerformAbility(ItemAbilities.SHEARS_DIG);
}
return null;
});
return this.subProviders.stream().map(entry -> {
return this.getTables().stream().map(entry -> {
// Provides new sub provider with filtering only changed loot tables and replacing condition item to condition tag
return new LootTableProvider.SubProviderEntry(() -> replaceAndFilterChangesOnly(entry.provider().get()), entry.paramSet());
return new LootTableProvider.SubProviderEntry(provider -> replaceAndFilterChangesOnly(entry.provider().apply(provider)), entry.paramSet());
}).collect(Collectors.toList());
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package io.github.fabricators_of_create.porting_lib.tool.extensions;

import io.github.fabricators_of_create.porting_lib.tool.ToolAction;
import io.github.fabricators_of_create.porting_lib.tool.ToolActions;
import io.github.fabricators_of_create.porting_lib.tool.ItemAbility;
import io.github.fabricators_of_create.porting_lib.tool.ItemAbilities;
import net.minecraft.core.BlockPos;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
Expand All @@ -14,8 +14,8 @@
public interface BlockStateExtensions {
/**
* Returns the state that this block should transform into when right-clicked by a tool.
* For example: Used to determine if {@link ToolActions#AXE_STRIP an axe can strip},
* {@link ToolActions#SHOVEL_FLATTEN a shovel can path}, or {@link ToolActions#HOE_TILL a hoe can till}.
* For example: Used to determine if {@link ItemAbilities#AXE_STRIP an axe can strip},
* {@link ItemAbilities#SHOVEL_FLATTEN a shovel can path}, or {@link ItemAbilities#HOE_TILL a hoe can till}.
* Returns {@code null} if nothing should happen.
*
* @param context The use on context that the action was performed in
Expand All @@ -24,7 +24,7 @@ public interface BlockStateExtensions {
* @return The resulting state after the action has been performed
*/
@Nullable
default BlockState getToolModifiedState(UseOnContext context, ToolAction toolAction, boolean simulate) {
default BlockState getToolModifiedState(UseOnContext context, ItemAbility toolAction, boolean simulate) {
return ((BlockState) this).getBlock().getToolModifiedState(((BlockState) this), context, toolAction, simulate);
}

Expand All @@ -41,7 +41,7 @@ default BlockState getToolModifiedState(UseOnContext context, ToolAction toolAct
* @return The resulting state after the action has been performed
*/
@Nullable
default BlockState getToolModifiedState(Level world, BlockPos pos, Player player, ItemStack stack, ToolAction toolAction) {
default BlockState getToolModifiedState(Level world, BlockPos pos, Player player, ItemStack stack, ItemAbility toolAction) {
return ((BlockState) this).getBlock().getToolModifiedState(((BlockState) this), world, pos, player, stack, toolAction);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package io.github.fabricators_of_create.porting_lib.tool.extensions;

import io.github.fabricators_of_create.porting_lib.tool.ItemAbilities;
import io.github.fabricators_of_create.porting_lib.tool.ItemAbility;

public interface ItemStackExtensions {
/**
* Queries if an item can perform the given action.
* See {@link ItemAbilities} for a description of each stock action
*
* @param itemAbility The action being queried
* @return True if the stack can perform the action
*/
default boolean canPerformAction(ItemAbility itemAbility) {
return self().getItem().canPerformAction(self(), itemAbility);
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package io.github.fabricators_of_create.porting_lib.tool.extensions;

import io.github.fabricators_of_create.porting_lib.tool.ToolAction;
import io.github.fabricators_of_create.porting_lib.tool.ItemAbility;
import net.minecraft.world.item.ItemStack;

public interface VanillaToolActionItem {
boolean port_lib$canPerformAction(ItemStack stack, ToolAction toolAction);
boolean port_lib$canPerformAction(ItemStack stack, ItemAbility toolAction);
}
Loading

0 comments on commit 9a7f279

Please sign in to comment.