diff --git a/fabric-entity-events-v1/src/client/java/net/fabricmc/fabric/api/entity/event/client/ClientPlayerEvents.java b/fabric-entity-events-v1/src/client/java/net/fabricmc/fabric/api/entity/event/client/ClientPlayerEvents.java new file mode 100644 index 0000000000..fb6f798ac0 --- /dev/null +++ b/fabric-entity-events-v1/src/client/java/net/fabricmc/fabric/api/entity/event/client/ClientPlayerEvents.java @@ -0,0 +1,43 @@ +/* + * 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.entity.event.client; + +import net.minecraft.client.network.ClientPlayerEntity; + +import net.fabricmc.fabric.api.event.Event; +import net.fabricmc.fabric.api.event.EventFactory; + +public final class ClientPlayerEvents { + /** + * An event that is called when a player is moving during using an item. + */ + public static final Event MODIFY_PLAYER_MOVEMENT_DURING_USINGITEM = EventFactory.createArrayBacked(ModifyPlayerMovementDuringUsingitem.class, callbacks -> player -> { + for (ModifyPlayerMovementDuringUsingitem callback : callbacks) { + callback.modifyPlayerMovementDuringUsingitem(player); + } + }); + + @FunctionalInterface + public interface ModifyPlayerMovementDuringUsingitem { + /** + * Called when a player is moving during using an item. + * + * @param player the player is moving during using an item. + */ + void modifyPlayerMovementDuringUsingitem(ClientPlayerEntity player); + } +} diff --git a/fabric-entity-events-v1/src/client/java/net/fabricmc/fabric/mixin/client/entity/event/ClientPlayerMixin.java b/fabric-entity-events-v1/src/client/java/net/fabricmc/fabric/mixin/client/entity/event/ClientPlayerMixin.java new file mode 100644 index 0000000000..18e785332b --- /dev/null +++ b/fabric-entity-events-v1/src/client/java/net/fabricmc/fabric/mixin/client/entity/event/ClientPlayerMixin.java @@ -0,0 +1,38 @@ +/* + * 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.mixin.client.entity.event; + +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.callback.CallbackInfo; + +import net.minecraft.client.network.ClientPlayerEntity; + +import net.fabricmc.fabric.api.entity.event.client.ClientPlayerEvents; + +@Mixin(ClientPlayerEntity.class) +abstract class ClientPlayerMixin { + @Inject(method = "tickMovement", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayerEntity;isUsingItem()Z")) + private void beforeTickMovement(CallbackInfo ci) { + ClientPlayerEntity player = (ClientPlayerEntity) (Object) this; + + if (player.isUsingItem() && !player.hasVehicle() && (player.input.movementForward != 0.0F || player.input.movementSideways != 0.0F)) { + ClientPlayerEvents.MODIFY_PLAYER_MOVEMENT_DURING_USINGITEM.invoker().modifyPlayerMovementDuringUsingitem(player); + } + } +} diff --git a/fabric-entity-events-v1/src/client/resources/fabric-entity-events-v1.client.mixins.json b/fabric-entity-events-v1/src/client/resources/fabric-entity-events-v1.client.mixins.json index c4866c6e99..c86d331963 100644 --- a/fabric-entity-events-v1/src/client/resources/fabric-entity-events-v1.client.mixins.json +++ b/fabric-entity-events-v1/src/client/resources/fabric-entity-events-v1.client.mixins.json @@ -3,7 +3,8 @@ "package": "net.fabricmc.fabric.mixin.client.entity.event", "compatibilityLevel": "JAVA_17", "client": [ - "elytra.ClientPlayerEntityMixin" + "elytra.ClientPlayerEntityMixin", + "ClientPlayerMixin" ], "injectors": { "defaultRequire": 1, diff --git a/fabric-entity-events-v1/src/testmodClient/java/net/fabricmc/fabric/test/entity/event/client/EntityEventTestsClient.java b/fabric-entity-events-v1/src/testmodClient/java/net/fabricmc/fabric/test/entity/event/client/EntityEventTestsClient.java index ef9c828c1a..11d4024706 100644 --- a/fabric-entity-events-v1/src/testmodClient/java/net/fabricmc/fabric/test/entity/event/client/EntityEventTestsClient.java +++ b/fabric-entity-events-v1/src/testmodClient/java/net/fabricmc/fabric/test/entity/event/client/EntityEventTestsClient.java @@ -16,17 +16,34 @@ package net.fabricmc.fabric.test.entity.event.client; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import net.minecraft.entity.EquipmentSlot; +import net.minecraft.item.Items; import net.fabricmc.api.ClientModInitializer; import net.fabricmc.fabric.api.client.rendering.v1.LivingEntityFeatureRenderEvents; +import net.fabricmc.fabric.api.entity.event.client.ClientPlayerEvents; import net.fabricmc.fabric.test.entity.event.EntityEventTests; public class EntityEventTestsClient implements ClientModInitializer { + private static final Logger LOGGER = LoggerFactory.getLogger(EntityEventTestsClient.class); + @Override public void onInitializeClient() { LivingEntityFeatureRenderEvents.ALLOW_CAPE_RENDER.register(player -> { return !player.getEquippedStack(EquipmentSlot.CHEST).isOf(EntityEventTests.DIAMOND_ELYTRA); }); + + ClientPlayerEvents.MODIFY_PLAYER_MOVEMENT_DURING_USINGITEM.register(player -> { + LOGGER.info("Player {} is moving during using item.", player); + + if (player.getMainHandStack().isOf(Items.BOW) && player.getEquippedStack(EquipmentSlot.FEET).isOf(Items.DIAMOND_BOOTS)) { + LOGGER.info("Player {} can move without slowdown becase of diamond boots on feet.", player); + player.input.movementForward *= 5F; + player.input.movementSideways *= 5F; + } + }); } }