separate block and item-on-block interaction again cause it causing issues but still use the callback

This commit is contained in:
Flemmli97 2022-01-12 18:34:19 +01:00
parent 3047269bfc
commit f67fc9fd28
6 changed files with 96 additions and 14 deletions

View File

@ -24,7 +24,6 @@ import net.minecraft.world.entity.item.ItemEntity;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
import net.minecraft.world.entity.projectile.Projectile; import net.minecraft.world.entity.projectile.Projectile;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.context.UseOnContext;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.DoorBlock; import net.minecraft.world.level.block.DoorBlock;
import net.minecraft.world.level.block.LecternBlock; import net.minecraft.world.level.block.LecternBlock;
@ -115,13 +114,11 @@ public class BlockInteractEvents {
return InteractionResult.FAIL; return InteractionResult.FAIL;
} }
} }
InteractionResult res = ItemInteractEvents.onItemUseBlock(new UseOnContext(player, hand, hitResult)); boolean shift = player.isSecondaryUseActive() || stack.isEmpty();
if (claim.canInteract(player, PermissionRegistry.INTERACTBLOCK, hitResult.getBlockPos(), false) || res == InteractionResult.FAIL) { boolean res = claim.canInteract(player, PermissionRegistry.INTERACTBLOCK, hitResult.getBlockPos(), shift);
if (res == InteractionResult.FAIL) if (!res && shift)
PlayerClaimData.get(player).addDisplayClaim(claim, EnumDisplayType.MAIN, player.blockPosition().getY()); PlayerClaimData.get(player).addDisplayClaim(claim, EnumDisplayType.MAIN, player.blockPosition().getY());
return res; return res ? InteractionResult.PASS : InteractionResult.FAIL;
}
return InteractionResult.PASS;
} }
return InteractionResult.PASS; return InteractionResult.PASS;
} }

View File

@ -26,6 +26,13 @@ import net.fabricmc.fabric.api.networking.v1.ServerPlayConnectionEvents;
import net.fabricmc.loader.api.FabricLoader; import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.MinecraftServer; import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.context.UseOnContext;
import net.minecraft.world.level.Level;
import net.minecraft.world.phys.BlockHitResult;
public class FlanFabric implements ModInitializer { public class FlanFabric implements ModInitializer {
@ -36,7 +43,7 @@ public class FlanFabric implements ModInitializer {
PlayerBlockBreakEvents.BEFORE.register(BlockInteractEvents::breakBlocks); PlayerBlockBreakEvents.BEFORE.register(BlockInteractEvents::breakBlocks);
AttackBlockCallback.EVENT.register(BlockInteractEvents::startBreakBlocks); AttackBlockCallback.EVENT.register(BlockInteractEvents::startBreakBlocks);
UseBlockCallback.EVENT.addPhaseOrdering(EventPhase, Event.DEFAULT_PHASE); UseBlockCallback.EVENT.addPhaseOrdering(EventPhase, Event.DEFAULT_PHASE);
UseBlockCallback.EVENT.register(EventPhase, BlockInteractEvents::useBlocks); UseBlockCallback.EVENT.register(EventPhase, FlanFabric::useBlocks);
UseEntityCallback.EVENT.register(EntityInteractEvents::useAtEntity); UseEntityCallback.EVENT.register(EntityInteractEvents::useAtEntity);
AttackEntityCallback.EVENT.register(EntityInteractEvents::attackEntity); AttackEntityCallback.EVENT.register(EntityInteractEvents::attackEntity);
UseItemCallback.EVENT.register(ItemInteractEvents::useItem); UseItemCallback.EVENT.register(ItemInteractEvents::useItem);
@ -63,4 +70,13 @@ public class FlanFabric implements ModInitializer {
public static void serverFinishLoad(MinecraftServer server) { public static void serverFinishLoad(MinecraftServer server) {
PlayerDataHandler.deleteInactivePlayerData(server); PlayerDataHandler.deleteInactivePlayerData(server);
} }
public static InteractionResult useBlocks(Player p, Level world, InteractionHand hand, BlockHitResult hitResult) {
if (p instanceof ServerPlayer serverPlayer) {
ItemUseBlockFlags flags = ItemUseBlockFlags.fromPlayer(serverPlayer);
flags.stopCanUseBlocks(BlockInteractEvents.useBlocks(p, world, hand, hitResult) == InteractionResult.FAIL);
flags.stopCanUseItems(ItemInteractEvents.onItemUseBlock(new UseOnContext(p, hand, hitResult)) == InteractionResult.FAIL);
}
return InteractionResult.PASS;
}
} }

View File

@ -0,0 +1,14 @@
package io.github.flemmli97.flan.fabric;
import net.minecraft.server.level.ServerPlayer;
public interface ItemUseBlockFlags {
void stopCanUseBlocks(boolean flag);
void stopCanUseItems(boolean flag);
static ItemUseBlockFlags fromPlayer(ServerPlayer player) {
return (ItemUseBlockFlags) player.gameMode;
}
}

View File

@ -0,0 +1,50 @@
package io.github.flemmli97.flan.fabric.mixin;
import io.github.flemmli97.flan.fabric.ItemUseBlockFlags;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.server.level.ServerPlayerGameMode;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
import net.minecraft.world.phys.BlockHitResult;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.ModifyVariable;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(ServerPlayerGameMode.class)
public abstract class ServerPlayerGameModeMixin implements ItemUseBlockFlags {
@Unique
private boolean stopInteractBlock;
@Unique
private boolean stopInteractItemBlock;
@ModifyVariable(method = "useItemOn", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/item/ItemStack;copy()Lnet/minecraft/world/item/ItemStack;"), ordinal = 1)
private boolean stopBlockUse(boolean orig) {
if (this.stopInteractBlock)
return true;
return orig;
}
@Inject(method = "useItemOn", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerPlayerGameMode;isCreative()Z"), cancellable = true)
private void stopItemOnBlock(ServerPlayer serverPlayer, Level level, ItemStack itemStack, InteractionHand interactionHand, BlockHitResult blockHitResult, CallbackInfoReturnable<InteractionResult> info) {
if (this.stopInteractItemBlock) {
info.setReturnValue(InteractionResult.PASS);
info.cancel();
}
}
@Override
public void stopCanUseBlocks(boolean flag) {
this.stopInteractBlock = flag;
}
@Override
public void stopCanUseItems(boolean flag) {
this.stopInteractItemBlock = flag;
}
}

View File

@ -17,7 +17,8 @@
"FabricFireMixin", "FabricFireMixin",
"LightningHitMixin", "LightningHitMixin",
"WorldSaveHandlerMixin", "WorldSaveHandlerMixin",
"PlayerManagerMixin" "PlayerManagerMixin",
"ServerPlayerGameModeMixin"
], ],
"server": [ "server": [
], ],

View File

@ -1,11 +1,14 @@
package io.github.flemmli97.flan.forgeevent; package io.github.flemmli97.flan.forgeevent;
import io.github.flemmli97.flan.event.BlockInteractEvents; import io.github.flemmli97.flan.event.BlockInteractEvents;
import io.github.flemmli97.flan.event.ItemInteractEvents;
import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.InteractionResult; import net.minecraft.world.InteractionResult;
import net.minecraft.world.item.context.UseOnContext;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.minecraftforge.event.entity.player.PlayerInteractEvent; import net.minecraftforge.event.entity.player.PlayerInteractEvent;
import net.minecraftforge.event.world.BlockEvent; import net.minecraftforge.event.world.BlockEvent;
import net.minecraftforge.eventbus.api.Event;
public class BlockInteractEventsForge { public class BlockInteractEventsForge {
@ -25,9 +28,10 @@ public class BlockInteractEventsForge {
public static void useBlocks(PlayerInteractEvent.RightClickBlock event) { public static void useBlocks(PlayerInteractEvent.RightClickBlock event) {
InteractionResult res = BlockInteractEvents.useBlocks(event.getPlayer(), event.getWorld(), event.getHand(), event.getHitVec()); InteractionResult res = BlockInteractEvents.useBlocks(event.getPlayer(), event.getWorld(), event.getHand(), event.getHitVec());
if (res != InteractionResult.PASS) { if(res == InteractionResult.FAIL)
event.setCancellationResult(res); event.setUseBlock(Event.Result.DENY);
event.setCanceled(true); res = ItemInteractEvents.onItemUseBlock(new UseOnContext(event.getPlayer(), event.getHand(), event.getHitVec()));
} if(res == InteractionResult.FAIL)
event.setUseItem(Event.Result.DENY);
} }
} }