mirror of
https://github.com/Creators-of-Create/Create.git
synced 2024-11-12 21:12:33 +01:00
Add CustomUseEffectsItem
- Add CustomUseEffectsItem interface implemented on items to control use effects behavior - Replace SandPaperEffectsHandler and SandPaperSoundMixin - Fix broken polishing particles when no items in other hand (polishing last item)
This commit is contained in:
parent
7b4f9f924f
commit
3129672f3a
7 changed files with 107 additions and 108 deletions
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,10 +1,12 @@
|
||||||
package com.simibubi.create.content.curiosities.tools;
|
package com.simibubi.create.content.curiosities.tools;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
import javax.annotation.ParametersAreNonnullByDefault;
|
import javax.annotation.ParametersAreNonnullByDefault;
|
||||||
|
|
||||||
import com.simibubi.create.AllSoundEvents;
|
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.item.render.SimpleCustomRenderer;
|
||||||
import com.simibubi.create.foundation.utility.VecHelper;
|
import com.simibubi.create.foundation.utility.VecHelper;
|
||||||
|
|
||||||
|
@ -40,7 +42,7 @@ import net.minecraftforge.common.util.FakePlayer;
|
||||||
|
|
||||||
@MethodsReturnNonnullByDefault
|
@MethodsReturnNonnullByDefault
|
||||||
@ParametersAreNonnullByDefault
|
@ParametersAreNonnullByDefault
|
||||||
public class SandPaperItem extends Item {
|
public class SandPaperItem extends Item implements CustomUseEffectsItem {
|
||||||
|
|
||||||
public SandPaperItem(Properties properties) {
|
public SandPaperItem(Properties properties) {
|
||||||
super(properties.durability(8));
|
super(properties.durability(8));
|
||||||
|
@ -200,6 +202,27 @@ public class SandPaperItem extends Item {
|
||||||
return toolAction == ToolActions.AXE_SCRAPE || toolAction == ToolActions.AXE_WAX_OFF;
|
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
|
@Override
|
||||||
public SoundEvent getEatingSound() {
|
public SoundEvent getEatingSound() {
|
||||||
return AllSoundEvents.SANDING_SHORT.getMainEvent();
|
return AllSoundEvents.SANDING_SHORT.getMainEvent();
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
|
@ -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<Boolean> 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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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<Boolean> cir) {
|
|
||||||
ItemStack using = this.getUseItem();
|
|
||||||
Item item = using.getItem();
|
|
||||||
if (item instanceof SandPaperItem) {
|
|
||||||
cir.setReturnValue(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -43,3 +43,5 @@ public net.minecraft.client.renderer.ItemInHandRenderer f_109301_ # offHandItem
|
||||||
|
|
||||||
# PaletteResize
|
# PaletteResize
|
||||||
public net.minecraft.world.level.chunk.PaletteResize
|
public net.minecraft.world.level.chunk.PaletteResize
|
||||||
|
|
||||||
|
public net.minecraft.world.entity.LivingEntity m_21060_(Lnet/minecraft/world/item/ItemStack;I)V # spawnItemParticles
|
||||||
|
|
|
@ -5,8 +5,8 @@
|
||||||
"compatibilityLevel": "JAVA_16",
|
"compatibilityLevel": "JAVA_16",
|
||||||
"refmap": "create.refmap.json",
|
"refmap": "create.refmap.json",
|
||||||
"mixins": [
|
"mixins": [
|
||||||
"PlayerListMixin",
|
"CustomItemUseEffectsMixin",
|
||||||
"SandPaperSoundMixin"
|
"PlayerListMixin"
|
||||||
],
|
],
|
||||||
"client": [
|
"client": [
|
||||||
"BreakProgressMixin",
|
"BreakProgressMixin",
|
||||||
|
|
Loading…
Reference in a new issue