diff --git a/src/main/java/com/simibubi/create/content/curiosities/tools/SandPaperEffectsHandler.java b/src/main/java/com/simibubi/create/content/curiosities/tools/SandPaperEffectsHandler.java deleted file mode 100644 index 4b2d01ecb..000000000 --- a/src/main/java/com/simibubi/create/content/curiosities/tools/SandPaperEffectsHandler.java +++ /dev/null @@ -1,54 +0,0 @@ -package com.simibubi.create.content.curiosities.tools; - -import java.util.Random; - -import net.minecraft.core.particles.ItemParticleOption; -import net.minecraft.core.particles.ParticleTypes; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.world.InteractionHand; -import net.minecraft.world.entity.LivingEntity; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.phys.Vec3; - -public class SandPaperEffectsHandler { - public static void onUseTick(LivingEntity entity, Random random) { - - spawnItemParticles(entity, random); - - if (shouldPlaySound(entity)) - entity.playSound(entity.getEatingSound(entity.getUseItem()), 0.9F + 0.2F * random.nextFloat(), random.nextFloat() * 0.2F + 0.9F); - } - - private static boolean shouldPlaySound(LivingEntity entity) { - // after 6 ticks play the sound every 7th - return (getTicksUsed(entity) - 6) % 7 == 0; - } - - private static int getTicksUsed(LivingEntity entity) { - int useDuration = entity.getUseItem() - .getUseDuration(); - return useDuration - entity.getUseItemRemainingTicks(); - } - - private static void spawnItemParticles(LivingEntity entity, Random random) { - ItemStack sanding = entity.getItemInHand(getNonInteractionHand(entity)); - - Vec3 vec3 = new Vec3(((double)random.nextFloat() - 0.5D) * 0.1D, Math.random() * 0.1D + 0.1D, 0.0D); - vec3 = vec3.xRot(-entity.getXRot() * ((float)Math.PI / 180F)); - vec3 = vec3.yRot(-entity.getYRot() * ((float)Math.PI / 180F)); - double d0 = (double)(-random.nextFloat()) * 0.6D - 0.3D; - Vec3 vec31 = new Vec3(((double)random.nextFloat() - 0.5D) * 0.3D, d0, 0.6D); - vec31 = vec31.xRot(-entity.getXRot() * ((float)Math.PI / 180F)); - vec31 = vec31.yRot(-entity.getYRot() * ((float)Math.PI / 180F)); - vec31 = vec31.add(entity.getX(), entity.getEyeY(), entity.getZ()); - if (entity.level instanceof ServerLevel) //Forge: Fix MC-2518 spawnParticle is nooped on server, need to use server specific variant - ((ServerLevel)entity.level).sendParticles(new ItemParticleOption(ParticleTypes.ITEM, sanding), vec31.x, vec31.y, vec31.z, 1, vec3.x, vec3.y + 0.05D, vec3.z, 0.0D); - else - entity.level.addParticle(new ItemParticleOption(ParticleTypes.ITEM, sanding), vec31.x, vec31.y, vec31.z, vec3.x, vec3.y + 0.05D, vec3.z); - - } - - private static InteractionHand getNonInteractionHand(LivingEntity entity) { - return entity.getUsedItemHand() == InteractionHand.MAIN_HAND ? InteractionHand.OFF_HAND : InteractionHand.MAIN_HAND; - } -} diff --git a/src/main/java/com/simibubi/create/content/curiosities/tools/SandPaperItem.java b/src/main/java/com/simibubi/create/content/curiosities/tools/SandPaperItem.java index 0476b5459..10db29bdd 100644 --- a/src/main/java/com/simibubi/create/content/curiosities/tools/SandPaperItem.java +++ b/src/main/java/com/simibubi/create/content/curiosities/tools/SandPaperItem.java @@ -1,10 +1,12 @@ package com.simibubi.create.content.curiosities.tools; +import java.util.Random; import java.util.function.Consumer; import javax.annotation.ParametersAreNonnullByDefault; import com.simibubi.create.AllSoundEvents; +import com.simibubi.create.foundation.item.CustomUseEffectsItem; import com.simibubi.create.foundation.item.render.SimpleCustomRenderer; import com.simibubi.create.foundation.utility.VecHelper; @@ -40,7 +42,7 @@ import net.minecraftforge.common.util.FakePlayer; @MethodsReturnNonnullByDefault @ParametersAreNonnullByDefault -public class SandPaperItem extends Item { +public class SandPaperItem extends Item implements CustomUseEffectsItem { public SandPaperItem(Properties properties) { super(properties.durability(8)); @@ -200,6 +202,27 @@ public class SandPaperItem extends Item { return toolAction == ToolActions.AXE_SCRAPE || toolAction == ToolActions.AXE_WAX_OFF; } + @Override + public Boolean shouldTriggerUseEffects(ItemStack stack, LivingEntity entity) { + // Trigger every tick so that we have more fine grain control over the animation + return true; + } + + @Override + public boolean triggerUseEffects(ItemStack stack, LivingEntity entity, int count, Random random) { + CompoundTag tag = stack.getOrCreateTag(); + if (tag.contains("Polishing")) { + ItemStack polishing = ItemStack.of(tag.getCompound("Polishing")); + entity.spawnItemParticles(polishing, 1); + } + + // After 6 ticks play the sound every 7th + if ((entity.getTicksUsingItem() - 6) % 7 == 0) + entity.playSound(entity.getEatingSound(stack), 0.9F + 0.2F * random.nextFloat(), random.nextFloat() * 0.2F + 0.9F); + + return true; + } + @Override public SoundEvent getEatingSound() { return AllSoundEvents.SANDING_SHORT.getMainEvent(); diff --git a/src/main/java/com/simibubi/create/foundation/item/CustomUseEffectsItem.java b/src/main/java/com/simibubi/create/foundation/item/CustomUseEffectsItem.java new file mode 100644 index 000000000..ac9d79156 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/item/CustomUseEffectsItem.java @@ -0,0 +1,30 @@ +package com.simibubi.create.foundation.item; + +import java.util.Random; + +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.item.ItemStack; + +public interface CustomUseEffectsItem { + /** + * Called to determine if use effects should be applied for this item. + * + * @param stack The ItemStack being used. + * @param entity The LivingEntity using the item. + * @return null for default behavior, or boolean to override default behavior + */ + default Boolean shouldTriggerUseEffects(ItemStack stack, LivingEntity entity) { + return null; + } + + /** + * Called when use effects should be applied for this item. + * + * @param stack The ItemStack being used. + * @param entity The LivingEntity using the item. + * @param count The amount of times effects should be applied. Can safely be ignored. + * @param random The LivingEntity's Random. + * @return if the default behavior should be cancelled or not + */ + boolean triggerUseEffects(ItemStack stack, LivingEntity entity, int count, Random random); +} diff --git a/src/main/java/com/simibubi/create/foundation/mixin/CustomItemUseEffectsMixin.java b/src/main/java/com/simibubi/create/foundation/mixin/CustomItemUseEffectsMixin.java new file mode 100644 index 000000000..b1eb2c6f9 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/mixin/CustomItemUseEffectsMixin.java @@ -0,0 +1,49 @@ +package com.simibubi.create.foundation.mixin; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +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 com.simibubi.create.foundation.item.CustomUseEffectsItem; + +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.Level; + +@Mixin(LivingEntity.class) +public abstract class CustomItemUseEffectsMixin extends Entity { + private CustomItemUseEffectsMixin(EntityType entityType, Level level) { + super(entityType, level); + } + + @Shadow + public abstract ItemStack getUseItem(); + + @Inject(method = "shouldTriggerItemUseEffects()Z", at = @At("HEAD"), cancellable = true) + private void onShouldTriggerUseEffects(CallbackInfoReturnable cir) { + ItemStack using = getUseItem(); + Item item = using.getItem(); + if (item instanceof CustomUseEffectsItem handler) { + Boolean result = handler.shouldTriggerUseEffects(using, (LivingEntity) (Object) this); + if (result != null) { + cir.setReturnValue(result); + } + } + } + + @Inject(method = "triggerItemUseEffects(Lnet/minecraft/world/item/ItemStack;I)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/item/ItemStack;getUseAnimation()Lnet/minecraft/world/item/UseAnim;", ordinal = 0), cancellable = true) + private void onTriggerUseEffects(ItemStack stack, int count, CallbackInfo ci) { + Item item = stack.getItem(); + if (item instanceof CustomUseEffectsItem handler) { + if (handler.triggerUseEffects(stack, (LivingEntity) (Object) this, count, random)) { + ci.cancel(); + } + } + } +} diff --git a/src/main/java/com/simibubi/create/foundation/mixin/SandPaperSoundMixin.java b/src/main/java/com/simibubi/create/foundation/mixin/SandPaperSoundMixin.java deleted file mode 100644 index 0a9f63718..000000000 --- a/src/main/java/com/simibubi/create/foundation/mixin/SandPaperSoundMixin.java +++ /dev/null @@ -1,51 +0,0 @@ -package com.simibubi.create.foundation.mixin; - -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -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 com.simibubi.create.content.curiosities.tools.SandPaperEffectsHandler; -import com.simibubi.create.content.curiosities.tools.SandPaperItem; - -import net.minecraft.world.entity.Entity; -import net.minecraft.world.entity.EntityType; -import net.minecraft.world.entity.LivingEntity; -import net.minecraft.world.item.Item; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.level.Level; - -@Mixin(LivingEntity.class) -public abstract class SandPaperSoundMixin extends Entity { - - @Shadow - public abstract ItemStack getUseItem(); - - private SandPaperSoundMixin(EntityType pEntityType, Level pLevel) { - super(pEntityType, pLevel); - } - - @Inject(method = "triggerItemUseEffects", cancellable = true, - at = @At(value = "INVOKE", target = "Lnet/minecraft/world/item/ItemStack;getUseAnimation()Lnet/minecraft/world/item/UseAnim;", ordinal = 0)) - private void onTriggerUseEffects(ItemStack pStack, int pCount, CallbackInfo ci) { - LivingEntity self = (LivingEntity) (Object) this; - - Item item = pStack.getItem(); - if (item instanceof SandPaperItem) { - SandPaperEffectsHandler.onUseTick(self, this.random); - ci.cancel(); - } - } - - // Trigger every tick for sandpaper, so that we have more fine grain control over the animation - @Inject(method = "shouldTriggerItemUseEffects", cancellable = true, at = @At("HEAD")) - private void alwaysTriggerUseEffects(CallbackInfoReturnable cir) { - ItemStack using = this.getUseItem(); - Item item = using.getItem(); - if (item instanceof SandPaperItem) { - cir.setReturnValue(true); - } - } -} diff --git a/src/main/resources/META-INF/accesstransformer.cfg b/src/main/resources/META-INF/accesstransformer.cfg index 071bd9273..a400d248b 100644 --- a/src/main/resources/META-INF/accesstransformer.cfg +++ b/src/main/resources/META-INF/accesstransformer.cfg @@ -43,3 +43,5 @@ public net.minecraft.client.renderer.ItemInHandRenderer f_109301_ # offHandItem # PaletteResize public net.minecraft.world.level.chunk.PaletteResize + +public net.minecraft.world.entity.LivingEntity m_21060_(Lnet/minecraft/world/item/ItemStack;I)V # spawnItemParticles diff --git a/src/main/resources/create.mixins.json b/src/main/resources/create.mixins.json index d23a75275..63f484c4d 100644 --- a/src/main/resources/create.mixins.json +++ b/src/main/resources/create.mixins.json @@ -5,8 +5,8 @@ "compatibilityLevel": "JAVA_16", "refmap": "create.refmap.json", "mixins": [ - "PlayerListMixin", - "SandPaperSoundMixin" + "CustomItemUseEffectsMixin", + "PlayerListMixin" ], "client": [ "BreakProgressMixin",