1111import mekanism .common .config .MekanismConfig ;
1212import mekanism .common .item .gear .ItemMekaTool ;
1313import mekanism .common .registries .MekanismModules ;
14+ import net .minecraft .advancements .CriteriaTriggers ;
1415import net .minecraft .core .BlockPos ;
1516import net .minecraft .core .Direction ;
1617import net .minecraft .core .dispenser .BlockSource ;
1718import net .minecraft .server .level .ServerLevel ;
18- import net .minecraft .sounds .SoundEvents ;
19- import net .minecraft .sounds .SoundSource ;
20- import net .minecraft .tags .BlockTags ;
19+ import net .minecraft .server .level .ServerPlayer ;
2120import net .minecraft .world .InteractionHand ;
2221import net .minecraft .world .InteractionResult ;
2322import net .minecraft .world .entity .Entity ;
2423import net .minecraft .world .entity .LivingEntity ;
2524import net .minecraft .world .entity .player .Player ;
2625import net .minecraft .world .item .ItemStack ;
27- import net .minecraft .world .item .Items ;
26+ import net .minecraft .world .item .context . UseOnContext ;
2827import net .minecraft .world .level .Level ;
29- import net .minecraft .world .level .block .BeehiveBlock ;
30- import net .minecraft .world .level .block .Block ;
31- import net .minecraft .world .level .block .Blocks ;
32- import net .minecraft .world .level .block .CarvedPumpkinBlock ;
3328import net .minecraft .world .level .block .DispenserBlock ;
34- import net .minecraft .world .level .block .entity .BeehiveBlockEntity ;
3529import net .minecraft .world .level .block .state .BlockState ;
3630import net .minecraft .world .level .gameevent .GameEvent ;
3731import net .minecraft .world .phys .AABB ;
32+ import net .neoforged .neoforge .common .CommonHooks ;
3833import net .neoforged .neoforge .common .IShearable ;
3934import net .neoforged .neoforge .common .ItemAbilities ;
4035import net .neoforged .neoforge .common .ItemAbility ;
@@ -64,6 +59,8 @@ public boolean canPerformAction(IModule<ModuleShearingUnit> module, IModuleConta
6459 //Note: If for some reason we are installed on something that is not the Meka-Tool don't stop the action from being enabled
6560 // as it may not actually require energy
6661 return !(stack .getItem () instanceof ItemMekaTool ) || ItemMekaTool .hasEnergyForDigAction (container , module .getEnergyContainer (stack ));
62+ } else if (action == ItemAbilities .SHEARS_TRIM ) {
63+ return module .hasEnoughEnergy (stack , MekanismConfig .gear .mekaToolEnergyUsageShearTrim );
6764 }
6865 return ItemAbilities .DEFAULT_SHEARS_ACTIONS .contains (action );
6966 }
@@ -82,38 +79,45 @@ public InteractionResult onInteract(IModule<ModuleShearingUnit> module, Player p
8279 return InteractionResult .PASS ;
8380 }
8481
82+ @ NotNull
83+ @ Override
84+ public InteractionResult onItemUse (IModule <ModuleShearingUnit > module , UseOnContext context ) {
85+ long cost = MekanismConfig .gear .mekaToolEnergyUsageShearTrim .get ();
86+ ItemStack stack = context .getItemInHand ();
87+ IEnergyContainer energyContainer = module .getEnergyContainer (stack );
88+ if (cost == 0L || energyContainer != null && energyContainer .getEnergy () >= cost ) {
89+ //Copy of ShearsItem#useOn
90+ Level level = context .getLevel ();
91+ BlockPos blockpos = context .getClickedPos ();
92+ BlockState state = level .getBlockState (blockpos );
93+ BlockState trimmedState = state .getToolModifiedState (context , ItemAbilities .SHEARS_TRIM , false );
94+ if (trimmedState != null ) {
95+ if (context .getPlayer () instanceof ServerPlayer player ) {
96+ CriteriaTriggers .ITEM_USED_ON_BLOCK .trigger (player , blockpos , stack );
97+ }
98+ level .setBlockAndUpdate (blockpos , trimmedState );
99+ level .gameEvent (GameEvent .BLOCK_CHANGE , blockpos , GameEvent .Context .of (context .getPlayer (), trimmedState ));
100+ if (cost > 0 ) {
101+ energyContainer .extract (cost , Action .EXECUTE , AutomationType .MANUAL );
102+ }
103+ return InteractionResult .sidedSuccess (level .isClientSide );
104+ }
105+ }
106+ return InteractionResult .PASS ;
107+ }
108+
85109 @ NotNull
86110 @ Override
87111 public ModuleDispenseResult onDispense (IModule <ModuleShearingUnit > module , IModuleContainer moduleContainer , ItemStack stack , BlockSource source ) {
88112 ServerLevel world = source .level ();
89113 Direction facing = source .state ().getValue (DispenserBlock .FACING );
90114 BlockPos pos = source .pos ().relative (facing );
91- if (tryShearBlock ( world , pos , facing . getOpposite () ) || tryShearLivingEntity (module .getEnergyContainer (stack ), world , pos , stack )) {
115+ if (CommonHooks . tryDispenseShearsHarvestBlock ( source , stack , world , pos ) || tryShearLivingEntity (module .getEnergyContainer (stack ), world , pos , stack )) {
92116 return ModuleDispenseResult .HANDLED ;
93117 }
94118 return ModuleDispenseResult .FAIL_PREVENT_DROP ;
95119 }
96120
97- //Slightly modified copy of ShearsDispenseItemBehavior#tryShearBeehive modified to not crash if the tag has a block that isn't a
98- // beehive block instance in it, and also to support shearing pumpkins via the dispenser
99- private boolean tryShearBlock (ServerLevel world , BlockPos pos , Direction sideClicked ) {
100- BlockState state = world .getBlockState (pos );
101- if (state .is (BlockTags .BEEHIVES ) && state .getBlock () instanceof BeehiveBlock beehive && state .getValue (BeehiveBlock .HONEY_LEVEL ) >= 5 ) {
102- world .playSound (null , pos , SoundEvents .BEEHIVE_SHEAR , SoundSource .BLOCKS , 1.0F , 1.0F );
103- BeehiveBlock .dropHoneycomb (world , pos );
104- beehive .releaseBeesAndResetHoneyLevel (world , state , pos , null , BeehiveBlockEntity .BeeReleaseStatus .BEE_RELEASED );
105- return true ;
106- } else if (state .is (Blocks .PUMPKIN )) {
107- //Carve pumpkin - copy from Pumpkin Block's onBlockActivated
108- Direction side = sideClicked .getAxis () == Direction .Axis .Y ? Direction .NORTH : sideClicked ;
109- world .playSound (null , pos , SoundEvents .PUMPKIN_CARVE , SoundSource .BLOCKS , 1 , 1 );
110- world .setBlock (pos , Blocks .CARVED_PUMPKIN .defaultBlockState ().setValue (CarvedPumpkinBlock .FACING , side ), Block .UPDATE_ALL_IMMEDIATE );
111- Block .popResource (world , pos , new ItemStack (Items .PUMPKIN_SEEDS , 4 ));
112- return true ;
113- }
114- return false ;
115- }
116-
117121 //Modified copy of ShearsDispenseItemBehavior#tryShearLivingEntity to work with IForgeShearable
118122 private boolean tryShearLivingEntity (@ Nullable IEnergyContainer energyContainer , ServerLevel world , BlockPos pos , ItemStack stack ) {
119123 long cost = MekanismConfig .gear .mekaToolEnergyUsageShearEntity .get ();
0 commit comments