mirror of
https://github.com/MinecraftForge/MinecraftForge.git
synced 2026-11-12 16:27:47 +00:00
Add Shears ToolActions (#7997)
Make shear interactions extend to subclasses Add Shears actions for beehive harvesting, pumpkin carving and trip wire disarming
This commit is contained in:
1 parent
c5a1c90366
commit
a336e443f7
31 files changed
+231
-161
No files matched your search
@@ -36,6 +36,7 @@ import net.minecraftforge.client.ForgeHooksClient;
|
||||
import net.minecraftforge.common.capabilities.RegisterCapabilitiesEvent;
|
||||
import net.minecraftforge.common.data.ExistingFileHelper;
|
||||
import net.minecraftforge.common.data.ForgeFluidTagsProvider;
|
||||
import net.minecraftforge.common.loot.CanToolPerformAction;
|
||||
import net.minecraftforge.common.loot.GlobalLootModifierSerializer;
|
||||
import net.minecraftforge.common.loot.LootTableIdCondition;
|
||||
import net.minecraftforge.eventbus.api.IEventBus;
|
||||
@@ -314,5 +315,6 @@ public class ForgeMod implements WorldPersistenceHooks.WorldPersistenceHook
|
||||
{
|
||||
// Ignore the event itself: this is done only not to statically initialize our custom LootConditionType
|
||||
Registry.register(Registry.LOOT_CONDITION_TYPE, new ResourceLocation("forge:loot_table_id"), LootTableIdCondition.LOOT_TABLE_ID);
|
||||
Registry.register(Registry.LOOT_CONDITION_TYPE, new ResourceLocation("forge:can_tool_perform_action"), CanToolPerformAction.LOOT_CONDITION_TYPE);
|
||||
}
|
||||
}
|
||||
@@ -54,6 +54,11 @@ public class ToolActions
|
||||
*/
|
||||
public static final ToolAction SWORD_DIG = ToolAction.get("sword_dig");
|
||||
|
||||
/**
|
||||
* Exposed by shears to allow querying tool behaviours
|
||||
*/
|
||||
public static final ToolAction SHEARS_DIG = ToolAction.get("shears_dig");
|
||||
|
||||
/**
|
||||
* Passed onto {@link IForgeBlock#getToolModifiedState} when an axe wants to strip a log
|
||||
*/
|
||||
@@ -80,7 +85,25 @@ public class ToolActions
|
||||
* @see {@link IForgeItem#getSweepHitBox}
|
||||
*/
|
||||
public static final ToolAction SWORD_SWEEP = ToolAction.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
|
||||
*/
|
||||
public static final ToolAction SHEARS_HARVEST = ToolAction.get("shears_harvest");
|
||||
|
||||
/**
|
||||
* 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 o a pumpkin to carve it
|
||||
*/
|
||||
public static final ToolAction SHEARS_CARVE = ToolAction.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 ToolAction SHEARS_DISARM = ToolAction.get("shears_disarm");
|
||||
|
||||
///**
|
||||
// * Passed onto {@link IForgeBlock#getToolModifiedState} when a hoe wants to turn dirt into soil
|
||||
// */
|
||||
@@ -88,9 +111,14 @@ public class ToolActions
|
||||
|
||||
|
||||
// Default actions supported by each tool type
|
||||
public static final Set<ToolAction> DEFAULT_AXE_ACTIONS = Stream.of(AXE_DIG, AXE_STRIP, AXE_SCRAPE, AXE_WAX_OFF).collect(Collectors.toCollection(Sets::newIdentityHashSet));
|
||||
public static final Set<ToolAction> DEFAULT_HOE_ACTIONS = Stream.of(HOE_DIG /* TODO: , HOE_TILL */).collect(Collectors.toCollection(Sets::newIdentityHashSet));
|
||||
public static final Set<ToolAction> DEFAULT_SHOVEL_ACTIONS = Stream.of(SHOVEL_DIG, SHOVEL_FLATTEN).collect(Collectors.toCollection(Sets::newIdentityHashSet));
|
||||
public static final Set<ToolAction> DEFAULT_PICKAXE_ACTIONS = Stream.of(PICKAXE_DIG).collect(Collectors.toCollection(Sets::newIdentityHashSet));
|
||||
public static final Set<ToolAction> DEFAULT_SWORD_ACTIONS = Stream.of(SWORD_DIG, SWORD_SWEEP).collect(Collectors.toCollection(Sets::newIdentityHashSet));
|
||||
public static final Set<ToolAction> DEFAULT_AXE_ACTIONS = of(AXE_DIG, AXE_STRIP, AXE_SCRAPE, AXE_WAX_OFF);
|
||||
public static final Set<ToolAction> DEFAULT_HOE_ACTIONS = of(HOE_DIG /* TODO: , HOE_TILL */);
|
||||
public static final Set<ToolAction> DEFAULT_SHOVEL_ACTIONS = of(SHOVEL_DIG, SHOVEL_FLATTEN);
|
||||
public static final Set<ToolAction> DEFAULT_PICKAXE_ACTIONS = of(PICKAXE_DIG);
|
||||
public static final Set<ToolAction> DEFAULT_SWORD_ACTIONS = of(SWORD_DIG, SWORD_SWEEP);
|
||||
public static final Set<ToolAction> DEFAULT_SHEARS_ACTIONS = of(SHEARS_DIG, SHEARS_HARVEST, SHEARS_CARVE, SHEARS_DISARM);
|
||||
|
||||
private static Set<ToolAction> of(ToolAction... actions) {
|
||||
return Stream.of(actions).collect(Collectors.toCollection(Sets::newIdentityHashSet));
|
||||
}
|
||||
}
|
||||
@@ -25,13 +25,14 @@ import net.minecraft.data.DataGenerator;
|
||||
import net.minecraft.data.loot.LootTableProvider;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.Items;
|
||||
import net.minecraft.tags.Tag;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.level.storage.loot.predicates.AlternativeLootItemCondition;
|
||||
import net.minecraft.world.level.storage.loot.predicates.LootItemCondition;
|
||||
import net.minecraft.world.level.storage.loot.predicates.InvertedLootItemCondition;
|
||||
import net.minecraft.world.level.storage.loot.predicates.MatchTool;
|
||||
import net.minecraftforge.common.Tags;
|
||||
import net.minecraftforge.common.ToolAction;
|
||||
import net.minecraftforge.common.ToolActions;
|
||||
import net.minecraftforge.common.loot.CanToolPerformAction;
|
||||
import net.minecraftforge.fml.util.ObfuscationReflectionHelper;
|
||||
|
||||
import java.util.List;
|
||||
@@ -50,7 +51,7 @@ import net.minecraft.world.level.storage.loot.entries.LootPoolEntryContainer;
|
||||
import net.minecraft.world.level.storage.loot.parameters.LootContextParamSet;
|
||||
|
||||
/**
|
||||
* Currently used only for replacing shears item to shears tag
|
||||
* Currently used only for replacing shears item to shears_dig tool action
|
||||
*/
|
||||
public final class ForgeLootTableProvider extends LootTableProvider {
|
||||
|
||||
@@ -73,13 +74,13 @@ public final class ForgeLootTableProvider extends LootTableProvider {
|
||||
|
||||
private Consumer<BiConsumer<ResourceLocation, LootTable.Builder>> replaceAndFilterChangesOnly(Consumer<BiConsumer<ResourceLocation, LootTable.Builder>> consumer) {
|
||||
return (newConsumer) -> consumer.accept((resourceLocation, builder) -> {
|
||||
if (findAndReplaceInLootTableBuilder(builder, Items.SHEARS, Tags.Items.SHEARS)) {
|
||||
if (findAndReplaceInLootTableBuilder(builder, Items.SHEARS, ToolActions.SHEARS_DIG)) {
|
||||
newConsumer.accept(resourceLocation, builder);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private boolean findAndReplaceInLootTableBuilder(LootTable.Builder builder, Item from, Tag.Named<Item> to) {
|
||||
private boolean findAndReplaceInLootTableBuilder(LootTable.Builder builder, Item from, ToolAction toolAction) {
|
||||
List<LootPool> lootPools = ObfuscationReflectionHelper.getPrivateValue(LootTable.Builder.class, builder, "f_7915" + "6_");
|
||||
boolean found = false;
|
||||
|
||||
@@ -88,7 +89,7 @@ public final class ForgeLootTableProvider extends LootTableProvider {
|
||||
}
|
||||
|
||||
for (LootPool lootPool : lootPools) {
|
||||
if (findAndReplaceInLootPool(lootPool, from, to)) {
|
||||
if (findAndReplaceInLootPool(lootPool, from, toolAction)) {
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
@@ -96,7 +97,7 @@ public final class ForgeLootTableProvider extends LootTableProvider {
|
||||
return found;
|
||||
}
|
||||
|
||||
private boolean findAndReplaceInLootPool(LootPool lootPool, Item from, Tag.Named<Item> to) {
|
||||
private boolean findAndReplaceInLootPool(LootPool lootPool, Item from, ToolAction toolAction) {
|
||||
List<LootPoolEntryContainer> lootEntries = ObfuscationReflectionHelper.getPrivateValue(LootPool.class, lootPool, "f_7902" +"3_");
|
||||
List<LootItemCondition> lootConditions = ObfuscationReflectionHelper.getPrivateValue(LootPool.class, lootPool, "f_7902" + "4_");
|
||||
boolean found = false;
|
||||
@@ -107,7 +108,7 @@ public final class ForgeLootTableProvider extends LootTableProvider {
|
||||
|
||||
for (LootPoolEntryContainer lootEntry : lootEntries) {
|
||||
if (lootEntry instanceof CompositeEntryBase) {
|
||||
if (findAndReplaceInParentedLootEntry((CompositeEntryBase) lootEntry, from, to)) {
|
||||
if (findAndReplaceInParentedLootEntry((CompositeEntryBase) lootEntry, from, toolAction)) {
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
@@ -120,15 +121,15 @@ public final class ForgeLootTableProvider extends LootTableProvider {
|
||||
for (int i = 0; i < lootConditions.size(); i++) {
|
||||
LootItemCondition lootCondition = lootConditions.get(i);
|
||||
if (lootCondition instanceof MatchTool && checkMatchTool((MatchTool) lootCondition, from)) {
|
||||
lootConditions.set(i, MatchTool.toolMatches(ItemPredicate.Builder.item().of(to)).build());
|
||||
lootConditions.set(i, CanToolPerformAction.canToolPerformAction(toolAction).build());
|
||||
found = true;
|
||||
} else if (lootCondition instanceof InvertedLootItemCondition) {
|
||||
LootItemCondition invLootCondition = ObfuscationReflectionHelper.getPrivateValue(InvertedLootItemCondition.class, (InvertedLootItemCondition) lootCondition, "f_8168" + "1_");
|
||||
|
||||
if (invLootCondition instanceof MatchTool && checkMatchTool((MatchTool) invLootCondition, from)) {
|
||||
lootConditions.set(i, InvertedLootItemCondition.invert(MatchTool.toolMatches(ItemPredicate.Builder.item().of(to))).build());
|
||||
lootConditions.set(i, InvertedLootItemCondition.invert(CanToolPerformAction.canToolPerformAction(toolAction)).build());
|
||||
found = true;
|
||||
} else if (invLootCondition instanceof AlternativeLootItemCondition && findAndReplaceInAlternative((AlternativeLootItemCondition) invLootCondition, from, to)) {
|
||||
} else if (invLootCondition instanceof AlternativeLootItemCondition && findAndReplaceInAlternative((AlternativeLootItemCondition) invLootCondition, from, toolAction)) {
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
@@ -137,7 +138,7 @@ public final class ForgeLootTableProvider extends LootTableProvider {
|
||||
return found;
|
||||
}
|
||||
|
||||
private boolean findAndReplaceInParentedLootEntry(CompositeEntryBase entry, Item from, Tag.Named<Item> to) {
|
||||
private boolean findAndReplaceInParentedLootEntry(CompositeEntryBase entry, Item from, ToolAction toolAction) {
|
||||
LootPoolEntryContainer[] lootEntries = ObfuscationReflectionHelper.getPrivateValue(CompositeEntryBase.class, entry, "f_7942" + "8_");
|
||||
boolean found = false;
|
||||
|
||||
@@ -146,7 +147,7 @@ public final class ForgeLootTableProvider extends LootTableProvider {
|
||||
}
|
||||
|
||||
for (LootPoolEntryContainer lootEntry : lootEntries) {
|
||||
if (findAndReplaceInLootEntry(lootEntry, from, to)) {
|
||||
if (findAndReplaceInLootEntry(lootEntry, from, toolAction)) {
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
@@ -154,7 +155,7 @@ public final class ForgeLootTableProvider extends LootTableProvider {
|
||||
return found;
|
||||
}
|
||||
|
||||
private boolean findAndReplaceInLootEntry(LootPoolEntryContainer entry, Item from, Tag.Named<Item> to) {
|
||||
private boolean findAndReplaceInLootEntry(LootPoolEntryContainer entry, Item from, ToolAction toolAction) {
|
||||
LootItemCondition[] lootConditions = ObfuscationReflectionHelper.getPrivateValue(LootPoolEntryContainer.class, entry, "f_7963" + "6_");
|
||||
boolean found = false;
|
||||
|
||||
@@ -163,10 +164,10 @@ public final class ForgeLootTableProvider extends LootTableProvider {
|
||||
}
|
||||
|
||||
for (int i = 0; i < lootConditions.length; i++) {
|
||||
if (lootConditions[i] instanceof AlternativeLootItemCondition && findAndReplaceInAlternative((AlternativeLootItemCondition) lootConditions[i], from, to)) {
|
||||
if (lootConditions[i] instanceof AlternativeLootItemCondition && findAndReplaceInAlternative((AlternativeLootItemCondition) lootConditions[i], from, toolAction)) {
|
||||
found = true;
|
||||
} else if (lootConditions[i] instanceof MatchTool && checkMatchTool((MatchTool) lootConditions[i], from)) {
|
||||
lootConditions[i] = MatchTool.toolMatches(ItemPredicate.Builder.item().of(to)).build();
|
||||
lootConditions[i] = CanToolPerformAction.canToolPerformAction(toolAction).build();
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
@@ -174,7 +175,7 @@ public final class ForgeLootTableProvider extends LootTableProvider {
|
||||
return found;
|
||||
}
|
||||
|
||||
private boolean findAndReplaceInAlternative(AlternativeLootItemCondition alternative, Item from, Tag.Named<Item> to) {
|
||||
private boolean findAndReplaceInAlternative(AlternativeLootItemCondition alternative, Item from, ToolAction toolAction) {
|
||||
LootItemCondition[] lootConditions = ObfuscationReflectionHelper.getPrivateValue(AlternativeLootItemCondition.class, alternative, "f_8146" + "8_");
|
||||
boolean found = false;
|
||||
|
||||
@@ -184,7 +185,7 @@ public final class ForgeLootTableProvider extends LootTableProvider {
|
||||
|
||||
for (int i = 0; i < lootConditions.length; i++) {
|
||||
if (lootConditions[i] instanceof MatchTool && checkMatchTool((MatchTool) lootConditions[i], from)) {
|
||||
lootConditions[i] = MatchTool.toolMatches(ItemPredicate.Builder.item().of(to)).build();
|
||||
lootConditions[i] = CanToolPerformAction.canToolPerformAction(toolAction).build();
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
package net.minecraftforge.common.loot;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.gson.JsonDeserializationContext;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonSerializationContext;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.storage.loot.LootContext;
|
||||
import net.minecraft.world.level.storage.loot.parameters.LootContextParam;
|
||||
import net.minecraft.world.level.storage.loot.parameters.LootContextParams;
|
||||
import net.minecraft.world.level.storage.loot.predicates.LootItemCondition;
|
||||
import net.minecraft.world.level.storage.loot.predicates.LootItemConditionType;
|
||||
import net.minecraftforge.common.ToolAction;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* This LootItemCondition "forge:can_tool_perform_action" can be used to check if a tool can perform a given ToolAction.
|
||||
*/
|
||||
public class CanToolPerformAction implements LootItemCondition {
|
||||
|
||||
public static final LootItemConditionType LOOT_CONDITION_TYPE = new LootItemConditionType(new CanToolPerformAction.Serializer());
|
||||
|
||||
final ToolAction action;
|
||||
|
||||
public CanToolPerformAction(ToolAction action) {
|
||||
this.action = action;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public LootItemConditionType getType() {
|
||||
return LOOT_CONDITION_TYPE;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public Set<LootContextParam<?>> getReferencedContextParams() {
|
||||
return ImmutableSet.of(LootContextParams.TOOL);
|
||||
}
|
||||
|
||||
public boolean test(LootContext lootContext) {
|
||||
ItemStack itemstack = lootContext.getParamOrNull(LootContextParams.TOOL);
|
||||
return itemstack != null && itemstack.canPerformAction(this.action);
|
||||
}
|
||||
|
||||
public static LootItemCondition.Builder canToolPerformAction(ToolAction action) {
|
||||
return () -> new CanToolPerformAction(action);
|
||||
}
|
||||
|
||||
public static class Serializer implements net.minecraft.world.level.storage.loot.Serializer<CanToolPerformAction> {
|
||||
public void serialize(JsonObject json, CanToolPerformAction itemCondition, @Nonnull JsonSerializationContext context) {
|
||||
json.addProperty("action", itemCondition.action.name());
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public CanToolPerformAction deserialize(JsonObject json, @Nonnull JsonDeserializationContext context) {
|
||||
return new CanToolPerformAction(ToolAction.get(json.get("action").getAsString()));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in new issue
Block a user