forked from FabricMC/fabric
[0.2.0] add pick item callback (#82)
This commit is contained in:
parent
403d0c5a96
commit
b5b9f82997
6 changed files with 200 additions and 0 deletions
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018 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.block;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.hit.HitResult;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.BlockView;
|
||||
|
||||
public interface ContextSensitivePickable {
|
||||
ItemStack getPickStack(BlockState state, BlockView view, BlockPos pos, /* nullable */ PlayerEntity player, /* nullable */ HitResult result);
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018 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.entity;
|
||||
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.hit.HitResult;
|
||||
|
||||
public interface ContextSensitivePickable {
|
||||
ItemStack getPickStack(/* nullable */ PlayerEntity player, /* nullable */ HitResult result);
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018 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.fabricmc.fabric.api.event.Event;
|
||||
import net.fabricmc.fabric.api.event.EventFactory;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.hit.HitResult;
|
||||
|
||||
/**
|
||||
* This interaction event is called on the CLIENT SIDE ONLY when the player
|
||||
* attempts to pick up an item.
|
||||
*
|
||||
* Use {@link Container} to change the picked stack. Return true if you
|
||||
* wish for execution to continue, return false to cancel the item picking
|
||||
* operation (for example, if you want to route to the server side, etc.)
|
||||
*/
|
||||
public interface ClientPickItemCallback {
|
||||
public static final class Container {
|
||||
private ItemStack stack;
|
||||
|
||||
public Container(ItemStack stack) {
|
||||
this.stack = stack;
|
||||
}
|
||||
|
||||
public ItemStack getStack() {
|
||||
return stack;
|
||||
}
|
||||
|
||||
public void setStack(ItemStack stack) {
|
||||
this.stack = stack;
|
||||
}
|
||||
}
|
||||
|
||||
public static final Event<ClientPickItemCallback> EVENT = EventFactory.arrayBacked(ClientPickItemCallback.class,
|
||||
(listeners) -> (player, result, container) -> {
|
||||
for (ClientPickItemCallback event : listeners) {
|
||||
if (!event.pick(player, result, container)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
);
|
||||
|
||||
boolean pick(PlayerEntity player, HitResult result, Container container);
|
||||
}
|
|
@ -17,10 +17,18 @@
|
|||
package net.fabricmc.fabric.impl;
|
||||
|
||||
import net.fabricmc.api.ClientModInitializer;
|
||||
import net.fabricmc.fabric.api.block.ContextSensitivePickable;
|
||||
import net.fabricmc.fabric.api.event.client.player.ClientPickItemCallback;
|
||||
import net.fabricmc.fabric.api.network.ClientSidePacketRegistry;
|
||||
import net.fabricmc.fabric.impl.client.gui.ScreenProviderRegistryImpl;
|
||||
import net.fabricmc.fabric.impl.registry.RegistrySyncManager;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.util.hit.BlockHitResult;
|
||||
import net.minecraft.util.hit.EntityHitResult;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.BlockView;
|
||||
|
||||
public class FabricAPIClientInitializer implements ClientModInitializer {
|
||||
@Override
|
||||
|
@ -30,6 +38,26 @@ public class FabricAPIClientInitializer implements ClientModInitializer {
|
|||
RegistrySyncManager.receivePacket(ctx, buf, !MinecraftClient.getInstance().isInSingleplayer());
|
||||
});
|
||||
|
||||
ClientPickItemCallback.EVENT.register(((player, result, container) -> {
|
||||
if (result instanceof BlockHitResult) {
|
||||
BlockView view = player.getEntityWorld();
|
||||
BlockPos pos = ((BlockHitResult) result).getBlockPos();
|
||||
BlockState state = view.getBlockState(pos);
|
||||
|
||||
if (state.getBlock() instanceof ContextSensitivePickable) {
|
||||
container.setStack(((ContextSensitivePickable) state.getBlock()).getPickStack(state, view, pos, player, result));
|
||||
}
|
||||
} else if (result instanceof EntityHitResult) {
|
||||
Entity entity = ((EntityHitResult) result).getEntity();
|
||||
|
||||
if (entity instanceof net.fabricmc.fabric.api.entity.ContextSensitivePickable) {
|
||||
container.setStack(((net.fabricmc.fabric.api.entity.ContextSensitivePickable) entity).getPickStack(player, result));
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}));
|
||||
|
||||
((ScreenProviderRegistryImpl) ScreenProviderRegistryImpl.INSTANCE).init();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018 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.mixin.events.playerinteraction;
|
||||
|
||||
import net.fabricmc.fabric.api.event.client.player.ClientPickItemCallback;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
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.CallbackInfo;
|
||||
|
||||
@Mixin(MinecraftClient.class)
|
||||
public class MixinMinecraftClient {
|
||||
private boolean fabric_itemPickCancelled;
|
||||
|
||||
@ModifyVariable(at = @At(value = "INVOKE", target = "Lnet/minecraft/item/ItemStack;isEmpty()Z", ordinal = 2), method = "doItemPick", ordinal = 0)
|
||||
public ItemStack modifyItemPick(ItemStack stack) {
|
||||
ClientPickItemCallback.Container ctr = new ClientPickItemCallback.Container(stack);
|
||||
//noinspection ConstantConditions
|
||||
MinecraftClient client = (MinecraftClient) (Object) this;
|
||||
|
||||
boolean toContinue = ClientPickItemCallback.EVENT.invoker().pick(client.player, client.hitResult, ctr);
|
||||
if (!toContinue) {
|
||||
fabric_itemPickCancelled = true;
|
||||
return ItemStack.EMPTY;
|
||||
} else {
|
||||
fabric_itemPickCancelled = false;
|
||||
return ctr.getStack();
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/item/ItemStack;isEmpty()Z", ordinal = 2), method = "doItemPick", cancellable = true)
|
||||
public void cancelItemPick(CallbackInfo info) {
|
||||
if (fabric_itemPickCancelled) {
|
||||
fabric_itemPickCancelled = false;
|
||||
info.cancel();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -16,6 +16,7 @@
|
|||
"client.render.MixinItemColorMap",
|
||||
"client.texture.MixinSpriteAtlasTexture",
|
||||
"events.playerinteraction.MixinClientPlayerInteractionManager",
|
||||
"events.playerinteraction.MixinMinecraftClient",
|
||||
"events.tick.MixinMinecraftClient",
|
||||
"networking.MixinClientPlayNetworkHandler",
|
||||
"registry.client.MixinBlockColorMap",
|
||||
|
|
Loading…
Reference in a new issue