mirror of
https://github.com/MinecraftForge/MinecraftForge
synced 2026-08-22 04:26:10 -04:00
Merge 45a5990fba into 2bfa53b05a
This commit is contained in:
commit
cb3c9366ad
12 changed files with 241 additions and 15 deletions
|
|
@ -9,3 +9,29 @@
|
|||
}
|
||||
|
||||
public float func_150893_a(ItemStack p_150893_1_, BlockState p_150893_2_) {
|
||||
@@ -33,12 +33,12 @@
|
||||
World world = p_195939_1_.func_195991_k();
|
||||
BlockPos blockpos = p_195939_1_.func_195995_a();
|
||||
BlockState blockstate = world.func_180495_p(blockpos);
|
||||
- Block block = field_203176_a.get(blockstate.func_177230_c());
|
||||
+ BlockState block = blockstate.getToolModifiedState(world, blockpos, p_195939_1_.func_195999_j(), p_195939_1_.func_195996_i(), net.minecraftforge.common.ToolType.AXE);
|
||||
if (block != null) {
|
||||
PlayerEntity playerentity = p_195939_1_.func_195999_j();
|
||||
world.func_184133_a(playerentity, blockpos, SoundEvents.field_203255_y, SoundCategory.BLOCKS, 1.0F, 1.0F);
|
||||
if (!world.field_72995_K) {
|
||||
- world.func_180501_a(blockpos, block.func_176223_P().func_206870_a(RotatedPillarBlock.field_176298_M, blockstate.func_177229_b(RotatedPillarBlock.field_176298_M)), 11);
|
||||
+ world.func_180501_a(blockpos, block, 11);
|
||||
if (playerentity != null) {
|
||||
p_195939_1_.func_195996_i().func_222118_a(1, playerentity, (p_220040_1_) -> {
|
||||
p_220040_1_.func_213334_d(p_195939_1_.func_221531_n());
|
||||
@@ -51,4 +51,10 @@
|
||||
return ActionResultType.PASS;
|
||||
}
|
||||
}
|
||||
+
|
||||
+ @javax.annotation.Nullable
|
||||
+ public static BlockState getAxeStrippingState(BlockState originalState) {
|
||||
+ Block block = field_203176_a.get(originalState.func_177230_c());
|
||||
+ return block != null ? block.func_176223_P().func_206870_a(RotatedPillarBlock.field_176298_M, originalState.func_177229_b(RotatedPillarBlock.field_176298_M)) : null;
|
||||
+ }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,13 +1,33 @@
|
|||
--- a/net/minecraft/item/HoeItem.java
|
||||
+++ b/net/minecraft/item/HoeItem.java
|
||||
@@ -31,7 +31,9 @@
|
||||
@@ -24,15 +24,17 @@
|
||||
protected static final Map<Block, BlockState> field_195973_b = Maps.newHashMap(ImmutableMap.of(Blocks.field_196658_i, Blocks.field_150458_ak.func_176223_P(), Blocks.field_185774_da, Blocks.field_150458_ak.func_176223_P(), Blocks.field_150346_d, Blocks.field_150458_ak.func_176223_P(), Blocks.field_196660_k, Blocks.field_150346_d.func_176223_P()));
|
||||
|
||||
public HoeItem(IItemTier p_i48488_1_, float p_i48488_2_, Item.Properties p_i48488_3_) {
|
||||
- super(p_i48488_1_, p_i48488_3_);
|
||||
+ super(p_i48488_1_, p_i48488_3_.addToolType(net.minecraftforge.common.ToolType.HOE, p_i48488_1_.func_200925_d()));
|
||||
this.field_185072_b = p_i48488_2_;
|
||||
}
|
||||
|
||||
public ActionResultType func_195939_a(ItemUseContext p_195939_1_) {
|
||||
World world = p_195939_1_.func_195991_k();
|
||||
BlockPos blockpos = p_195939_1_.func_195995_a();
|
||||
- if (p_195939_1_.func_196000_l() != Direction.DOWN && world.func_180495_p(blockpos.func_177984_a()).func_196958_f()) {
|
||||
- BlockState blockstate = field_195973_b.get(world.func_180495_p(blockpos).func_177230_c());
|
||||
+ int hook = net.minecraftforge.event.ForgeEventFactory.onHoeUse(p_195939_1_);
|
||||
+ if (hook != 0) return hook > 0 ? ActionResultType.SUCCESS : ActionResultType.FAIL;
|
||||
+ if (p_195939_1_.func_196000_l() != Direction.DOWN && world.func_175623_d(blockpos.func_177984_a())) {
|
||||
BlockState blockstate = field_195973_b.get(world.func_180495_p(blockpos).func_177230_c());
|
||||
+ BlockState blockstate = world.func_180495_p(blockpos).getToolModifiedState(world, blockpos, p_195939_1_.func_195999_j(), p_195939_1_.func_195996_i(), net.minecraftforge.common.ToolType.HOE);
|
||||
if (blockstate != null) {
|
||||
PlayerEntity playerentity = p_195939_1_.func_195999_j();
|
||||
world.func_184133_a(playerentity, blockpos, SoundEvents.field_187693_cj, SoundCategory.BLOCKS, 1.0F, 1.0F);
|
||||
@@ -68,4 +70,9 @@
|
||||
|
||||
return multimap;
|
||||
}
|
||||
+
|
||||
+ @javax.annotation.Nullable
|
||||
+ public static BlockState getHoeTillingState(BlockState originalState) {
|
||||
+ return field_195973_b.get(originalState.func_177230_c());
|
||||
+ }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,12 +9,24 @@
|
|||
}
|
||||
|
||||
public boolean func_150897_b(BlockState p_150897_1_) {
|
||||
@@ -32,7 +32,7 @@
|
||||
@@ -32,8 +32,8 @@
|
||||
public ActionResultType func_195939_a(ItemUseContext p_195939_1_) {
|
||||
World world = p_195939_1_.func_195991_k();
|
||||
BlockPos blockpos = p_195939_1_.func_195995_a();
|
||||
- if (p_195939_1_.func_196000_l() != Direction.DOWN && world.func_180495_p(blockpos.func_177984_a()).func_196958_f()) {
|
||||
+ if (p_195939_1_.func_196000_l() != Direction.DOWN && world.func_180495_p(blockpos.func_177984_a()).isAir(world, blockpos.func_177984_a())) {
|
||||
BlockState blockstate = field_195955_e.get(world.func_180495_p(blockpos).func_177230_c());
|
||||
- BlockState blockstate = field_195955_e.get(world.func_180495_p(blockpos).func_177230_c());
|
||||
+ if (p_195939_1_.func_196000_l() != Direction.DOWN && world.func_175623_d(blockpos.func_177984_a())) {
|
||||
+ BlockState blockstate = world.func_180495_p(blockpos).getToolModifiedState(world, blockpos, p_195939_1_.func_195999_j(), p_195939_1_.func_195996_i(), net.minecraftforge.common.ToolType.SHOVEL);
|
||||
if (blockstate != null) {
|
||||
PlayerEntity playerentity = p_195939_1_.func_195999_j();
|
||||
world.func_184133_a(playerentity, blockpos, SoundEvents.field_187771_eN, SoundCategory.BLOCKS, 1.0F, 1.0F);
|
||||
@@ -52,4 +52,9 @@
|
||||
|
||||
return ActionResultType.PASS;
|
||||
}
|
||||
+
|
||||
+ @javax.annotation.Nullable
|
||||
+ public static BlockState getShovelPathingState(BlockState originalState) {
|
||||
+ return field_195955_e.get(originalState.func_177230_c());
|
||||
+ }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,8 +5,10 @@
|
|||
|
||||
package net.minecraftforge.common;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.IWorldReader;
|
||||
import net.minecraft.util.Direction;
|
||||
|
||||
// TODO 1.16: This should not be an enum. Change it to something that functions similarly to ToolType
|
||||
public enum PlantType implements IExtensibleEnum
|
||||
|
|
@ -21,11 +23,11 @@ public enum PlantType implements IExtensibleEnum
|
|||
|
||||
/**
|
||||
* Getting a custom {@link PlantType}, or an existing one if it has the same name as that one. Your plant should implement {@link IPlantable}
|
||||
* and return this custom type in {@link IPlantable#getPlantType(IBlockAccess, BlockPos)}.
|
||||
* and return this custom type in {@link IPlantable#getPlantType(IWorldReader, BlockPos)}.
|
||||
*
|
||||
* <p>If your new plant grows on blocks like any one of them above, never create a new {@link PlantType}.
|
||||
* This enumeration is only functioning in
|
||||
* {@link net.minecraft.block.Block#canSustainPlant(IBlockState, IWorldReader, BlockPos, EnumFacing, IPlantable)},
|
||||
* {@link net.minecraft.block.Block#canSustainPlant(BlockState, IWorldReader, BlockPos, Direction, IPlantable)},
|
||||
* which you are supposed to override this function in your new block and create a new plant type to grow on that block.
|
||||
*
|
||||
* <p>You can create an instance of your plant type in your API and let your/others mods access it. It will be faster than calling this method.
|
||||
|
|
|
|||
|
|
@ -6,25 +6,31 @@
|
|||
package net.minecraftforge.common;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
public final class ToolType
|
||||
{
|
||||
private static final Pattern VALID_NAME = Pattern.compile("[^a-z_]"); //Only a-z and _ are allowed, meaning names must be lower case. And use _ to separate words.
|
||||
private static final Map<String, ToolType> values = Maps.newHashMap();
|
||||
private static final Map<String, ToolType> VALUES = new ConcurrentHashMap<>();
|
||||
|
||||
public static final ToolType AXE = get("axe");
|
||||
public static final ToolType HOE = get("hoe");
|
||||
public static final ToolType PICKAXE = get("pickaxe");
|
||||
public static final ToolType SHOVEL = get("shovel");
|
||||
|
||||
|
||||
/**
|
||||
* Gets the ToolType for the specified name, or creates a new one if none for that name does yet exist.
|
||||
* This method can be called during parallel loading
|
||||
*/
|
||||
public static ToolType get(String name)
|
||||
{
|
||||
if (VALID_NAME.matcher(name).find())
|
||||
throw new IllegalArgumentException("ToolType.create() called with invalid name: " + name);
|
||||
return values.computeIfAbsent(name, k -> new ToolType(name));
|
||||
return VALUES.computeIfAbsent(name, k ->
|
||||
{
|
||||
if (VALID_NAME.matcher(name).find())
|
||||
throw new IllegalArgumentException("ToolType.get() called with invalid name: " + name);
|
||||
return new ToolType(name);
|
||||
});
|
||||
}
|
||||
|
||||
private final String name;
|
||||
|
|
|
|||
|
|
@ -38,6 +38,9 @@ import net.minecraft.entity.player.PlayerEntity;
|
|||
import net.minecraft.entity.projectile.WitherSkullEntity;
|
||||
import net.minecraft.fluid.IFluidState;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.item.HoeItem;
|
||||
import net.minecraft.item.ShovelItem;
|
||||
import net.minecraft.item.AxeItem;
|
||||
import net.minecraft.potion.Effects;
|
||||
import net.minecraft.item.DyeColor;
|
||||
import net.minecraft.item.Item;
|
||||
|
|
@ -1048,4 +1051,24 @@ public interface IForgeBlock
|
|||
{
|
||||
return getBlock().isIn(BlockTags.FENCES) || getBlock().isIn(BlockTags.WALLS) || getBlock() instanceof FenceGateBlock;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the state that this block should transform into when right clicked by a tool.
|
||||
* For example: Used to determine if an axe can strip, a shovel can path, or a hoe can till.
|
||||
* Return null if vanilla behavior should be disabled.
|
||||
*
|
||||
* @param state The current state
|
||||
* @param world The world
|
||||
* @param pos The block position in world
|
||||
* @param player The player clicking the block
|
||||
* @param stack The stack being used by the player
|
||||
* @return The resulting state after the action has been performed
|
||||
*/
|
||||
@Nullable
|
||||
default BlockState getToolModifiedState(BlockState state, World world, BlockPos pos, PlayerEntity player, ItemStack stack, ToolType toolType)
|
||||
{
|
||||
if (toolType == ToolType.AXE) return AxeItem.getAxeStrippingState(state);
|
||||
else if(toolType == ToolType.HOE) return HoeItem.getHoeTillingState(state);
|
||||
else return toolType == ToolType.SHOVEL ? ShovelItem.getShovelPathingState(state) : null;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ import javax.annotation.Nullable;
|
|||
|
||||
import net.minecraft.block.*;
|
||||
import net.minecraft.client.particle.ParticleManager;
|
||||
import net.minecraft.client.renderer.ActiveRenderInfo;
|
||||
import net.minecraft.client.renderer.model.IBakedModel;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.MobEntity;
|
||||
|
|
@ -890,4 +891,23 @@ public interface IForgeBlockState
|
|||
{
|
||||
return getBlockState().getBlock().collisionExtendsVertically(getBlockState(), world, pos, collidingEntity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the state that this block should transform into when right clicked by a tool.
|
||||
* For example: Used to determine if an axe can strip, a shovel can path, or a hoe can till.
|
||||
* Return null if vanilla behavior should be disabled.
|
||||
*
|
||||
* @param world The world
|
||||
* @param pos The block position in world
|
||||
* @param player The player clicking the block
|
||||
* @param stack The stack being used by the player
|
||||
* @param toolType The tool type to be considered when performing the action
|
||||
* @return The resulting state after the action has been performed
|
||||
*/
|
||||
@Nullable
|
||||
default BlockState getToolModifiedState(World world, BlockPos pos, PlayerEntity player, ItemStack stack, ToolType toolType)
|
||||
{
|
||||
BlockState eventState = net.minecraftforge.event.ForgeEventFactory.onToolUse(getBlockState(), world, pos, player, stack, toolType);
|
||||
return eventState != getBlockState() ? eventState : getBlockState().getBlock().getToolModifiedState(getBlockState(), world, pos, player, stack, toolType);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -63,6 +63,7 @@ import net.minecraftforge.client.event.ClientChatReceivedEvent;
|
|||
import net.minecraftforge.client.event.RenderBlockOverlayEvent;
|
||||
import net.minecraftforge.client.event.RenderBlockOverlayEvent.OverlayType;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.common.ToolType;
|
||||
import net.minecraftforge.common.capabilities.CapabilityDispatcher;
|
||||
import net.minecraftforge.common.capabilities.ICapabilityProvider;
|
||||
import net.minecraftforge.common.util.BlockSnapshot;
|
||||
|
|
@ -101,6 +102,7 @@ import net.minecraftforge.event.entity.player.SleepingTimeCheckEvent;
|
|||
import net.minecraftforge.event.entity.player.UseHoeEvent;
|
||||
import net.minecraftforge.event.furnace.FurnaceFuelBurnTimeEvent;
|
||||
import net.minecraftforge.event.world.BlockEvent;
|
||||
import net.minecraftforge.event.world.BlockEvent.BlockToolInteractEvent;
|
||||
import net.minecraftforge.event.world.BlockEvent.CreateFluidSourceEvent;
|
||||
import net.minecraftforge.event.world.BlockEvent.EntityMultiPlaceEvent;
|
||||
import net.minecraftforge.event.world.BlockEvent.EntityPlaceEvent;
|
||||
|
|
@ -324,6 +326,8 @@ public class ForgeEventFactory
|
|||
return MinecraftForge.EVENT_BUS.post(event) ? "" : event.getMessage();
|
||||
}
|
||||
|
||||
//TODO: 1.17 Remove
|
||||
@Deprecated
|
||||
public static int onHoeUse(ItemUseContext context)
|
||||
{
|
||||
UseHoeEvent event = new UseHoeEvent(context);
|
||||
|
|
@ -336,6 +340,13 @@ public class ForgeEventFactory
|
|||
return 0;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static BlockState onToolUse(BlockState originalState, World world, BlockPos pos, PlayerEntity player, ItemStack stack, ToolType toolType)
|
||||
{
|
||||
BlockToolInteractEvent event = new BlockToolInteractEvent(world, pos, originalState, player, stack, toolType);
|
||||
return MinecraftForge.EVENT_BUS.post(event) ? null : event.getFinalState();
|
||||
}
|
||||
|
||||
public static int onApplyBonemeal(@Nonnull PlayerEntity player, @Nonnull World world, @Nonnull BlockPos pos, @Nonnull BlockState state, @Nonnull ItemStack stack)
|
||||
{
|
||||
BonemealEvent event = new BonemealEvent(player, world, pos, state, stack);
|
||||
|
|
|
|||
|
|
@ -19,9 +19,12 @@ import javax.annotation.Nonnull;
|
|||
* and damage the hoe.
|
||||
*
|
||||
* setResult(ALLOW) is the same as the old setHandled();
|
||||
*
|
||||
* TODO: 1.17 Remove
|
||||
*/
|
||||
@Cancelable
|
||||
@HasResult
|
||||
@Deprecated
|
||||
public class UseHoeEvent extends PlayerEvent
|
||||
{
|
||||
private final ItemUseContext context;;
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ import net.minecraft.util.Direction;
|
|||
import net.minecraft.world.IWorld;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.ForgeHooks;
|
||||
import net.minecraftforge.common.ToolType;
|
||||
import net.minecraftforge.common.util.BlockSnapshot;
|
||||
import net.minecraftforge.eventbus.api.Cancelable;
|
||||
import net.minecraftforge.eventbus.api.Event;
|
||||
|
|
@ -430,4 +431,68 @@ public class BlockEvent extends Event
|
|||
return size;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fired when when this block is right clicked by a tool to change its state.
|
||||
* For example: Used to determine if an axe can strip, a shovel can path, or a hoe can till.
|
||||
*
|
||||
* This event is {@link Cancelable}. If canceled, this will prevent the tool
|
||||
* from changing the block's state.
|
||||
*/
|
||||
@Cancelable
|
||||
public static final class BlockToolInteractEvent extends BlockEvent
|
||||
{
|
||||
|
||||
private final PlayerEntity player;
|
||||
private final ItemStack stack;
|
||||
private final ToolType toolType;
|
||||
private BlockState state;
|
||||
|
||||
public BlockToolInteractEvent(IWorld world, BlockPos pos, BlockState originalState, PlayerEntity player, ItemStack stack, ToolType toolType)
|
||||
{
|
||||
super(world, pos, originalState);
|
||||
this.player = player;
|
||||
this.stack = stack;
|
||||
this.state = originalState;
|
||||
this.toolType = toolType;
|
||||
}
|
||||
|
||||
/**Gets the player using the tool.*/
|
||||
public PlayerEntity getPlayer()
|
||||
{
|
||||
return player;
|
||||
}
|
||||
|
||||
/**Gets the tool being used.*/
|
||||
public ItemStack getHeldItemStack()
|
||||
{
|
||||
return stack;
|
||||
}
|
||||
|
||||
/**Gets the current type of the tool being compared against.*/
|
||||
public ToolType getToolType()
|
||||
{
|
||||
return toolType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the transformed state after tool use.
|
||||
* If not set, will return the original state.
|
||||
* This will be bypassed if canceled returning null instead.
|
||||
* */
|
||||
public void setFinalState(BlockState finalState)
|
||||
{
|
||||
this.state = finalState;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the transformed state after tool use.
|
||||
* If setFinalState not called, will return the original state.
|
||||
* This will be bypassed if canceled returning null instead.
|
||||
* */
|
||||
public BlockState getFinalState()
|
||||
{
|
||||
return state;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,36 @@
|
|||
package net.minecraftforge.debug.block;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.event.world.BlockEvent.BlockToolInteractEvent;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
|
||||
@Mod("tool_interact_test")
|
||||
public class ToolInteractTest
|
||||
{
|
||||
|
||||
private static final Logger LOGGER = LogManager.getLogger();
|
||||
|
||||
public ToolInteractTest()
|
||||
{
|
||||
MinecraftForge.EVENT_BUS.addListener(this::onToolInteraction);
|
||||
}
|
||||
|
||||
private void onToolInteraction(final BlockToolInteractEvent event)
|
||||
{
|
||||
//Test 1: No Changes, just test if event is called. State and Final State should be the same
|
||||
LOGGER.info("BlockState {} is modified to {} at position {} by {} with {}", event.getState(), event.getFinalState(), event.getPos(), event.getPlayer(), event.getHeldItemStack());
|
||||
|
||||
//Test 2: Canceling, nothing in game should change
|
||||
/*event.setCanceled(true);
|
||||
LOGGER.info("Event has been canceled: {}", event.isCanceled());
|
||||
*/
|
||||
|
||||
//Test 3: Altering
|
||||
/*event.setFinalState(Blocks.ACACIA_FENCE.getDefaultState());
|
||||
LOGGER.info("BlockState {} is modified to {} at position {} by {} with {}", event.getState(), event.getFinalState(), event.getPos(), event.getPlayer(), event.getHeldItemStack());
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
|
@ -72,4 +72,6 @@ loaderVersion="[28,)"
|
|||
[[mods]]
|
||||
modId="stencil_backport_test"
|
||||
[[mods]]
|
||||
modId="forge_spawnegg_test"
|
||||
modId="forge_spawnegg_test"
|
||||
[[mods]]
|
||||
modId="tool_interact_test"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue