mirror of
https://github.com/FabricMC/fabric.git
synced 2024-11-14 19:25:23 -05:00
Add Client After Block Break Event (#3367)
* Add clientside after block break event * Update tests * Checkstyle, of course * Update Javadoc * New Event * Checkstyle 2 electric boogaloo * Remove block entity parameter * Refactor ClientPlayerBlockBreakEvents * Update Javadoc
This commit is contained in:
parent
06274a4716
commit
389931eb7a
6 changed files with 111 additions and 12 deletions
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.api.event.client.player;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.client.network.ClientPlayerEntity;
|
||||
import net.minecraft.client.world.ClientWorld;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
|
||||
import net.fabricmc.fabric.api.event.Event;
|
||||
import net.fabricmc.fabric.api.event.EventFactory;
|
||||
|
||||
/**
|
||||
* Contains client side events triggered by block breaking.
|
||||
*
|
||||
* <p>For preventing block breaking client side and other purposes, see {@link net.fabricmc.fabric.api.event.player.AttackBlockCallback}.
|
||||
* For server side block break events, see {@link net.fabricmc.fabric.api.event.player.PlayerBlockBreakEvents}.
|
||||
*/
|
||||
public class ClientPlayerBlockBreakEvents {
|
||||
/**
|
||||
* Callback after a block is broken client side.
|
||||
*
|
||||
* <p>Only called client side. For server side see {@link net.fabricmc.fabric.api.event.player.PlayerBlockBreakEvents#AFTER}
|
||||
*/
|
||||
public static final Event<After> AFTER = EventFactory.createArrayBacked(After.class,
|
||||
(listeners) -> (world, player, pos, state) -> {
|
||||
for (After event : listeners) {
|
||||
event.afterBlockBreak(world, player, pos, state);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
@FunctionalInterface
|
||||
public interface After {
|
||||
/**
|
||||
* Called after a block is successfully broken.
|
||||
*
|
||||
* @param world the world where the block was broken
|
||||
* @param player the player who broke the block
|
||||
* @param pos the position where the block was broken
|
||||
* @param state the block state <strong>before</strong> the block was broken
|
||||
*/
|
||||
void afterBlockBreak(ClientWorld world, ClientPlayerEntity player, BlockPos pos, BlockState state);
|
||||
}
|
||||
}
|
|
@ -24,7 +24,9 @@ import org.spongepowered.asm.mixin.injection.At;
|
|||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.network.ClientPlayNetworkHandler;
|
||||
import net.minecraft.client.network.ClientPlayerEntity;
|
||||
|
@ -46,7 +48,9 @@ import net.minecraft.util.hit.BlockHitResult;
|
|||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.world.GameMode;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import net.fabricmc.fabric.api.event.client.player.ClientPlayerBlockBreakEvents;
|
||||
import net.fabricmc.fabric.api.event.player.AttackBlockCallback;
|
||||
import net.fabricmc.fabric.api.event.player.AttackEntityCallback;
|
||||
import net.fabricmc.fabric.api.event.player.UseBlockCallback;
|
||||
|
@ -90,6 +94,11 @@ public abstract class ClientPlayerInteractionManagerMixin {
|
|||
}
|
||||
}
|
||||
|
||||
@Inject(method = "breakBlock", at = @At(value = "INVOKE", target = "Lnet/minecraft/block/Block;onBroken(Lnet/minecraft/world/WorldAccess;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;)V"), locals = LocalCapture.CAPTURE_FAILHARD)
|
||||
private void fabric$onBlockBroken(BlockPos pos, CallbackInfoReturnable<Boolean> cir, World world, BlockState blockState) {
|
||||
ClientPlayerBlockBreakEvents.AFTER.invoker().afterBlockBreak(client.world, client.player, pos, blockState);
|
||||
}
|
||||
|
||||
@Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayerInteractionManager;sendSequencedPacket(Lnet/minecraft/client/world/ClientWorld;Lnet/minecraft/client/network/SequencedPacketCreator;)V"), method = "interactBlock", cancellable = true)
|
||||
public void interactBlock(ClientPlayerEntity player, Hand hand, BlockHitResult blockHitResult, CallbackInfoReturnable<ActionResult> info) {
|
||||
// hook interactBlock between the world border check and the actual block interaction to invoke the use block event first
|
||||
|
@ -141,5 +150,5 @@ public abstract class ClientPlayerInteractionManagerMixin {
|
|||
}
|
||||
|
||||
@Shadow
|
||||
public abstract void sendSequencedPacket(ClientWorld clientWorld, SequencedPacketCreator supplier);
|
||||
protected abstract void sendSequencedPacket(ClientWorld clientWorld, SequencedPacketCreator supplier);
|
||||
}
|
||||
|
|
|
@ -27,6 +27,9 @@ import net.minecraft.world.World;
|
|||
import net.fabricmc.fabric.api.event.Event;
|
||||
import net.fabricmc.fabric.api.event.EventFactory;
|
||||
|
||||
/**
|
||||
* Contains server side events triggered by block breaking.
|
||||
*/
|
||||
public final class PlayerBlockBreakEvents {
|
||||
private PlayerBlockBreakEvents() { }
|
||||
|
||||
|
@ -53,10 +56,11 @@ public final class PlayerBlockBreakEvents {
|
|||
);
|
||||
|
||||
/**
|
||||
* Callback after a block is broken.
|
||||
* Callback after a block is broken server side.
|
||||
*
|
||||
* <p>Only called on a logical server.
|
||||
* <p>Only called on a logical server. For client side see {@link net.fabricmc.fabric.api.event.client.player.ClientPlayerBlockBreakEvents#AFTER}
|
||||
*/
|
||||
@SuppressWarnings("JavadocReference")
|
||||
public static final Event<After> AFTER = EventFactory.createArrayBacked(After.class,
|
||||
(listeners) -> (world, player, pos, state, entity) -> {
|
||||
for (After event : listeners) {
|
||||
|
|
|
@ -29,16 +29,10 @@ public class PlayerBreakBlockTests implements ModInitializer {
|
|||
|
||||
@Override
|
||||
public void onInitialize() {
|
||||
PlayerBlockBreakEvents.BEFORE.register(((world, player, pos, state, entity) -> {
|
||||
return state.getBlock() != Blocks.BEDROCK;
|
||||
}));
|
||||
PlayerBlockBreakEvents.BEFORE.register(((world, player, pos, state, entity) -> state.getBlock() != Blocks.BEDROCK));
|
||||
|
||||
PlayerBlockBreakEvents.CANCELED.register(((world, player, pos, state, entity) -> {
|
||||
LOGGER.info("Block break event canceled at " + pos.getX() + ", " + pos.getY() + ", " + pos.getZ());
|
||||
}));
|
||||
PlayerBlockBreakEvents.CANCELED.register(((world, player, pos, state, entity) -> LOGGER.info("Block break event canceled at {}, {}, {} (client-side = {})", pos.getX(), pos.getY(), pos.getZ(), world.isClient())));
|
||||
|
||||
PlayerBlockBreakEvents.AFTER.register(((world, player, pos, state, entity) -> {
|
||||
LOGGER.info("Block broken at " + pos.getX() + ", " + pos.getY() + ", " + pos.getZ());
|
||||
}));
|
||||
PlayerBlockBreakEvents.AFTER.register(((world, player, pos, state, entity) -> LOGGER.info("Block broken at {}, {}, {} (client-side = {})", pos.getX(), pos.getY(), pos.getZ(), world.isClient())));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
],
|
||||
"client": [
|
||||
"net.fabricmc.fabric.test.client.event.interaction.ClientPreAttackTests",
|
||||
"net.fabricmc.fabric.test.client.event.interaction.ClientPlayerBlockBreakTests",
|
||||
"net.fabricmc.fabric.test.client.event.interaction.PlayerPickBlockTests"
|
||||
]
|
||||
}
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.test.client.event.interaction;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import net.fabricmc.api.ClientModInitializer;
|
||||
import net.fabricmc.fabric.api.event.client.player.ClientPlayerBlockBreakEvents;
|
||||
|
||||
public class ClientPlayerBlockBreakTests implements ClientModInitializer {
|
||||
public static final Logger LOGGER = LoggerFactory.getLogger(ClientPlayerBlockBreakTests.class);
|
||||
|
||||
@Override
|
||||
public void onInitializeClient() {
|
||||
ClientPlayerBlockBreakEvents.AFTER.register(((world, player, pos, state) -> LOGGER.info("Block broken at {}, {}, {} (client-side = {})", pos.getX(), pos.getY(), pos.getZ(), world.isClient())));
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue