From ccd42ce3d1236f4ef86ae935a3c92ac63e6c0132 Mon Sep 17 00:00:00 2001 From: kd8lvt Date: Wed, 2 Oct 2024 17:33:13 -0400 Subject: [PATCH 1/6] Feat: Bulk Digestion in Gastric Acid --- .../biomancy/init/AcidInteractions.java | 59 +++++++++++++++++++ .../biomancy/mixin/ItemEntityMixin.java | 20 +++++++ src/main/resources/mixins.biomancy.json | 53 ++++++++++++++--- 3 files changed, 124 insertions(+), 8 deletions(-) create mode 100644 src/main/java/com/github/elenterius/biomancy/mixin/ItemEntityMixin.java diff --git a/src/main/java/com/github/elenterius/biomancy/init/AcidInteractions.java b/src/main/java/com/github/elenterius/biomancy/init/AcidInteractions.java index 852372496..5d0d0ecaa 100644 --- a/src/main/java/com/github/elenterius/biomancy/init/AcidInteractions.java +++ b/src/main/java/com/github/elenterius/biomancy/init/AcidInteractions.java @@ -1,9 +1,15 @@ package com.github.elenterius.biomancy.init; +import com.github.elenterius.biomancy.block.digester.DigesterBlockEntity; +import com.github.elenterius.biomancy.crafting.recipe.DigestingRecipe; import com.github.elenterius.biomancy.init.tags.ModBlockTags; +import com.github.elenterius.biomancy.inventory.BehavioralInventory; import com.github.elenterius.biomancy.util.CombatUtil; +import net.minecraft.core.Direction; import net.minecraft.core.cauldron.CauldronInteraction; +import net.minecraft.core.dispenser.DefaultDispenseItemBehavior; import net.minecraft.core.particles.ParticleTypes; +import net.minecraft.nbt.CompoundTag; import net.minecraft.sounds.SoundEvent; import net.minecraft.sounds.SoundEvents; import net.minecraft.sounds.SoundSource; @@ -11,6 +17,7 @@ import net.minecraft.util.RandomSource; import net.minecraft.world.InteractionResult; import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.item.ItemEntity; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemUtils; @@ -29,6 +36,7 @@ import java.util.Map; import java.util.Objects; +import java.util.Optional; public final class AcidInteractions { @@ -157,4 +165,55 @@ else if (livingEntity.tickCount % 10 == 0 && livingEntity.getRandom().nextFloat( } } + private static final String TIMER_KEY = "biomancy:digestion_timer"; + private static final float EFFICIENCY = 0.8f; + public static void tryDigest(ItemEntity itemEntity) { + if (!digestible(itemEntity)) return; + CompoundTag data = itemEntity.getPersistentData(); + if (data.contains(TIMER_KEY) && data.getInt(TIMER_KEY) < 100) { + data.putInt(TIMER_KEY,data.getInt(TIMER_KEY)+1); + //TODO: Bubble particles? Couldn't get it working for some reason. + // Copied the addParticle call from handleEntityInsideAcid and it said no. + } else if (data.contains(TIMER_KEY) && data.getInt(TIMER_KEY) >= 100){ + digestIntoNutrientPasteStacks(itemEntity); + itemEntity.getPersistentData().remove(TIMER_KEY); + } else { + data.putInt(TIMER_KEY,1); + } + } + + private static void digestIntoNutrientPasteStacks(ItemEntity itemEntity) { + if (getDigestionRecipe(itemEntity).isEmpty()) return; + DigestingRecipe recipe = getDigestionRecipe(itemEntity).get(); + BehavioralInventory inv = BehavioralInventory.createServerContents(1,player->false,()->{}); + inv.insertItemStack(itemEntity.getItem()); + ItemStack resultStack = recipe.assemble(inv,itemEntity.level().registryAccess()); + int amt = (int)Math.floor(resultStack.getCount()*itemEntity.getItem().getCount()*EFFICIENCY); + if (amt > 64) amt = splitIntoStacks(itemEntity,resultStack); + itemEntity.setItem(new ItemStack(ModItems.NUTRIENT_PASTE.get(), amt)); + itemEntity.playSound(SoundEvents.PLAYER_BURP); + } + + private static int splitIntoStacks(ItemEntity itemEntity, ItemStack resultStack) { + int numItems = (int)Math.floor(resultStack.getCount()*itemEntity.getItem().getCount()*EFFICIENCY); + Level level = itemEntity.level(); + while (numItems > 64) { + DefaultDispenseItemBehavior.spawnItem(level,new ItemStack(ModItems.NUTRIENT_PASTE.get(),64),1, Direction.UP, itemEntity.position()); + numItems -= 64; + } + return numItems; + } + + @SuppressWarnings("RedundantIfStatement") + private static boolean digestible(ItemEntity itemEntity) { + if (!itemEntity.isInFluidType(ModFluids.ACID_TYPE.get()) && !itemEntity.level().getBlockState(itemEntity.blockPosition()).is(ModBlocks.ACID_CAULDRON.get())) return false; + if (itemEntity.getItem().is(ModItems.NUTRIENT_PASTE.get())) return false; + if (getDigestionRecipe(itemEntity).isEmpty()) return false; + return true; + } + + private static Optional getDigestionRecipe(ItemEntity itemEntity) { + return DigesterBlockEntity.RECIPE_TYPE.get().getRecipeForIngredient(itemEntity.level(), itemEntity.getItem()); + } + } diff --git a/src/main/java/com/github/elenterius/biomancy/mixin/ItemEntityMixin.java b/src/main/java/com/github/elenterius/biomancy/mixin/ItemEntityMixin.java new file mode 100644 index 000000000..c2c11659e --- /dev/null +++ b/src/main/java/com/github/elenterius/biomancy/mixin/ItemEntityMixin.java @@ -0,0 +1,20 @@ +package com.github.elenterius.biomancy.mixin; + +import com.github.elenterius.biomancy.init.AcidInteractions; +import net.minecraft.world.entity.item.ItemEntity; +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.callback.CallbackInfo; + +@Mixin(ItemEntity.class) +public class ItemEntityMixin { + @Unique + @Inject(at=@At("TAIL"),method={"tick()V"}) + public void biomancy$tick(CallbackInfo ci) { + ItemEntity self = (ItemEntity)((Object)this); //I hate casting like this on so many levels + if (self.level().isClientSide()) return; + AcidInteractions.tryDigest(self); + } +} \ No newline at end of file diff --git a/src/main/resources/mixins.biomancy.json b/src/main/resources/mixins.biomancy.json index b75a101cc..a580f0e76 100644 --- a/src/main/resources/mixins.biomancy.json +++ b/src/main/resources/mixins.biomancy.json @@ -8,16 +8,53 @@ "defaultRequire": 1 }, "mixins": [ - "accessor.AgeableMobAccessor", "accessor.ArmorStandAccessor", "accessor.BiomeAccessor", "accessor.CreeperAccessor", "accessor.DamageSourceAccessor", - "accessor.EntityAccessor", "accessor.IntegerPropertyAccessor", "accessor.LivingEntityAccessor", "accessor.MobEffectInstanceAccessor", - "accessor.MobEntityAccessor", "accessor.ServerLevelAccessor", "accessor.SheepAccessor", "accessor.SlimeAccessor", "accessor.SuspiciousStewItemAccessor", - "accessor.SwordItemMixinAccessor", "accessor.TadpoleAccessor", "accessor.TextureSlotAccessor", "accessor.ZombieVillagerMixinAccessor", - "AnimalMixin", "AreaEffectCloudMixin", "ArrowMixin", "ChickenMixin", "CowMixin", "FlowingFluidMixin", "LivingEntityMixin", "MobEffectInstanceMixin", - "PhantomMixin", "PigMixin", "PlayerMixin", "ServerLevelMixin", "SheepMixin", "ThrownPotionMixin", "UnbreakingEnchantmentMixin", "WallBlockMixin", - "BlockMixin", "NodeEvaluatorMixin", "SignBlockEntityMixin", "ServerGamePacketListenerImplMixin", "VillagerMixin", "VillagerMakeLoveMixin" + "AnimalMixin", + "AreaEffectCloudMixin", + "ArrowMixin", + "BlockMixin", + "ChickenMixin", + "CowMixin", + "FlowingFluidMixin", + "ItemEntityMixin", + "LivingEntityMixin", + "MobEffectInstanceMixin", + "NodeEvaluatorMixin", + "PhantomMixin", + "PigMixin", + "PlayerMixin", + "ServerGamePacketListenerImplMixin", + "ServerLevelMixin", + "SheepMixin", + "SignBlockEntityMixin", + "ThrownPotionMixin", + "UnbreakingEnchantmentMixin", + "VillagerMakeLoveMixin", + "VillagerMixin", + "WallBlockMixin", + "accessor.AgeableMobAccessor", + "accessor.ArmorStandAccessor", + "accessor.BiomeAccessor", + "accessor.CreeperAccessor", + "accessor.DamageSourceAccessor", + "accessor.EntityAccessor", + "accessor.IntegerPropertyAccessor", + "accessor.LivingEntityAccessor", + "accessor.MobEffectInstanceAccessor", + "accessor.MobEntityAccessor", + "accessor.ServerLevelAccessor", + "accessor.SheepAccessor", + "accessor.SlimeAccessor", + "accessor.SuspiciousStewItemAccessor", + "accessor.SwordItemMixinAccessor", + "accessor.TadpoleAccessor", + "accessor.TextureSlotAccessor", + "accessor.ZombieVillagerMixinAccessor" ], "client": [ - "accessor.RecipeCollectionAccessor", "client.ClientPackListenerMixin", "client.ClientRecipeBookMixin", "client.GuiGraphicsMixin", + "accessor.RecipeCollectionAccessor", + "client.ClientPackListenerMixin", + "client.ClientRecipeBookMixin", + "client.GuiGraphicsMixin", "client.PlayerRendererMixin" ], "server": [ ] From 5c99b8be1b013df190a58064ad4d6328293494ad Mon Sep 17 00:00:00 2001 From: kd8lvt Date: Fri, 4 Oct 2024 13:45:56 -0400 Subject: [PATCH 2/6] Feat: Bulk Digestion in Gastric Acid (Implement requested changes) --- .../biomancy/init/AcidInteractions.java | 59 ++++++++++-------- .../biomancy/init/ModParticleTypes.java | 1 + .../biomancy/mixin/ItemEntityMixin.java | 21 +++++-- .../textures/particle/acid_bubble.png | Bin 0 -> 147 bytes 4 files changed, 48 insertions(+), 33 deletions(-) create mode 100644 src/main/resources/assets/biomancy/textures/particle/acid_bubble.png diff --git a/src/main/java/com/github/elenterius/biomancy/init/AcidInteractions.java b/src/main/java/com/github/elenterius/biomancy/init/AcidInteractions.java index 5d0d0ecaa..9c69235e5 100644 --- a/src/main/java/com/github/elenterius/biomancy/init/AcidInteractions.java +++ b/src/main/java/com/github/elenterius/biomancy/init/AcidInteractions.java @@ -32,6 +32,7 @@ import net.minecraft.world.level.gameevent.GameEvent; import net.minecraft.world.phys.Vec3; import net.minecraftforge.common.SoundActions; +import org.apache.commons.lang3.ArrayUtils; import org.jetbrains.annotations.Nullable; import java.util.Map; @@ -167,53 +168,57 @@ else if (livingEntity.tickCount % 10 == 0 && livingEntity.getRandom().nextFloat( private static final String TIMER_KEY = "biomancy:digestion_timer"; private static final float EFFICIENCY = 0.8f; - public static void tryDigest(ItemEntity itemEntity) { - if (!digestible(itemEntity)) return; + public static void tryDigest(ItemEntity itemEntity, boolean onClient) { + DigestingRecipe recipe = getDigestionRecipe(itemEntity); + if (!digestible(itemEntity,recipe)) return; CompoundTag data = itemEntity.getPersistentData(); - if (data.contains(TIMER_KEY) && data.getInt(TIMER_KEY) < 100) { - data.putInt(TIMER_KEY,data.getInt(TIMER_KEY)+1); - //TODO: Bubble particles? Couldn't get it working for some reason. - // Copied the addParticle call from handleEntityInsideAcid and it said no. - } else if (data.contains(TIMER_KEY) && data.getInt(TIMER_KEY) >= 100){ - digestIntoNutrientPasteStacks(itemEntity); + if (data.contains(TIMER_KEY) && data.getInt(TIMER_KEY) < 10) { + data.putInt(TIMER_KEY, data.getInt(TIMER_KEY) + 1); + } else if (data.contains(TIMER_KEY) && data.getInt(TIMER_KEY) >= 10 && !onClient){ + digestIntoNutrientPasteStacks(itemEntity,recipe); itemEntity.getPersistentData().remove(TIMER_KEY); } else { data.putInt(TIMER_KEY,1); } } - private static void digestIntoNutrientPasteStacks(ItemEntity itemEntity) { - if (getDigestionRecipe(itemEntity).isEmpty()) return; - DigestingRecipe recipe = getDigestionRecipe(itemEntity).get(); - BehavioralInventory inv = BehavioralInventory.createServerContents(1,player->false,()->{}); - inv.insertItemStack(itemEntity.getItem()); - ItemStack resultStack = recipe.assemble(inv,itemEntity.level().registryAccess()); - int amt = (int)Math.floor(resultStack.getCount()*itemEntity.getItem().getCount()*EFFICIENCY); - if (amt > 64) amt = splitIntoStacks(itemEntity,resultStack); - itemEntity.setItem(new ItemStack(ModItems.NUTRIENT_PASTE.get(), amt)); + private static void digestIntoNutrientPasteStacks(ItemEntity itemEntity, DigestingRecipe recipe) { + BehavioralInventory tempInventory = BehavioralInventory.createServerContents(1,player->false,()->{}); + tempInventory.insertItemStack(itemEntity.getItem()); + ItemStack resultStack = recipe.assemble(tempInventory,itemEntity.level().registryAccess()); + int totalToOutput = (int)Math.floor(resultStack.getCount()*itemEntity.getItem().getCount()*EFFICIENCY); + if (totalToOutput > 64) totalToOutput = splitIntoStacks(itemEntity,totalToOutput); + itemEntity.setItem(new ItemStack(ModItems.NUTRIENT_PASTE.get(), totalToOutput)); itemEntity.playSound(SoundEvents.PLAYER_BURP); } - private static int splitIntoStacks(ItemEntity itemEntity, ItemStack resultStack) { - int numItems = (int)Math.floor(resultStack.getCount()*itemEntity.getItem().getCount()*EFFICIENCY); + private static int splitIntoStacks(ItemEntity itemEntity, int numToSplit) { Level level = itemEntity.level(); - while (numItems > 64) { + while (numToSplit > 64) { DefaultDispenseItemBehavior.spawnItem(level,new ItemStack(ModItems.NUTRIENT_PASTE.get(),64),1, Direction.UP, itemEntity.position()); - numItems -= 64; + numToSplit -= 64; } - return numItems; + return numToSplit; } + @SuppressWarnings("RedundantIfStatement") - private static boolean digestible(ItemEntity itemEntity) { + private static boolean digestible(ItemEntity itemEntity, @Nullable DigestingRecipe recipe) { + if (recipe == null) return false; if (!itemEntity.isInFluidType(ModFluids.ACID_TYPE.get()) && !itemEntity.level().getBlockState(itemEntity.blockPosition()).is(ModBlocks.ACID_CAULDRON.get())) return false; - if (itemEntity.getItem().is(ModItems.NUTRIENT_PASTE.get())) return false; - if (getDigestionRecipe(itemEntity).isEmpty()) return false; + //Inside method to prevent missing registry object errors during init + Item[] blacklistedItems = {ModItems.NUTRIENT_PASTE.get(),ModItems.NUTRIENT_BAR.get(),ModItems.LIVING_FLESH.get()}; + if (ArrayUtils.contains(blacklistedItems,itemEntity.getItem().getItem())) return false; return true; } - private static Optional getDigestionRecipe(ItemEntity itemEntity) { - return DigesterBlockEntity.RECIPE_TYPE.get().getRecipeForIngredient(itemEntity.level(), itemEntity.getItem()); + private static DigestingRecipe cachedRecipe = null; + private static @Nullable DigestingRecipe getDigestionRecipe(ItemEntity itemEntity) { + if (cachedRecipe != null && cachedRecipe.getIngredient().test(itemEntity.getItem())) return cachedRecipe; + Optional foundRecipe = DigesterBlockEntity.RECIPE_TYPE.get().getRecipeForIngredient(itemEntity.level(), itemEntity.getItem()); + if (foundRecipe.isEmpty()) return null; + cachedRecipe = foundRecipe.get(); + return cachedRecipe; } } diff --git a/src/main/java/com/github/elenterius/biomancy/init/ModParticleTypes.java b/src/main/java/com/github/elenterius/biomancy/init/ModParticleTypes.java index 33af249c2..e673047f4 100644 --- a/src/main/java/com/github/elenterius/biomancy/init/ModParticleTypes.java +++ b/src/main/java/com/github/elenterius/biomancy/init/ModParticleTypes.java @@ -21,6 +21,7 @@ public final class ModParticleTypes { public static final RegistryObject LIGHT_GREEN_GLOW = register("light_green_glow", false); public static final RegistryObject HOSTILE = register("hostile", false); public static final RegistryObject BIOHAZARD = register("biohazard", false); + public static final RegistryObject ACID_BUBBLE = register("acid_bubble", false); private ModParticleTypes() {} diff --git a/src/main/java/com/github/elenterius/biomancy/mixin/ItemEntityMixin.java b/src/main/java/com/github/elenterius/biomancy/mixin/ItemEntityMixin.java index c2c11659e..8b4a261cb 100644 --- a/src/main/java/com/github/elenterius/biomancy/mixin/ItemEntityMixin.java +++ b/src/main/java/com/github/elenterius/biomancy/mixin/ItemEntityMixin.java @@ -1,20 +1,29 @@ package com.github.elenterius.biomancy.mixin; import com.github.elenterius.biomancy.init.AcidInteractions; +import com.github.elenterius.biomancy.init.ModParticleTypes; +import net.minecraft.util.RandomSource; import net.minecraft.world.entity.item.ItemEntity; +import net.minecraft.world.phys.Vec3; 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.callback.CallbackInfo; @Mixin(ItemEntity.class) -public class ItemEntityMixin { - @Unique +public abstract class ItemEntityMixin { @Inject(at=@At("TAIL"),method={"tick()V"}) - public void biomancy$tick(CallbackInfo ci) { + private void onTick(CallbackInfo ci) { ItemEntity self = (ItemEntity)((Object)this); //I hate casting like this on so many levels - if (self.level().isClientSide()) return; - AcidInteractions.tryDigest(self); + if (self.isRemoved()) return; + boolean onClient = self.level().isClientSide(); + + if (onClient) { + Vec3 pos = self.position(); + RandomSource random = self.level().getRandom(); + self.level().addParticle(ModParticleTypes.ACID_BUBBLE.get(), pos.x + random.nextGaussian(), pos.y, pos.z + random.nextGaussian(), random.nextGaussian(), 0.1, random.nextGaussian()); + } + if (self.getAge() % 10 != 0) return; //Only fire once every 10 ticks + AcidInteractions.tryDigest(self,onClient); } } \ No newline at end of file diff --git a/src/main/resources/assets/biomancy/textures/particle/acid_bubble.png b/src/main/resources/assets/biomancy/textures/particle/acid_bubble.png new file mode 100644 index 0000000000000000000000000000000000000000..cdd12ea88d2f267b0a281a5d72b55ab52383c484 GIT binary patch literal 147 zcmeAS@N?(olHy`uVBq!ia0vp^93afW3?x5a^xFxf7>k44ofy`glX(f`@C5jTxB}@< z|NqbUKSS}q;+)T?{eXOyk|4iehX4QnZ`O6_0P%Fr7JbMnI}hQc_Z4 p#sMBSjb_F}44Y>t*r+M+GO)=p=-vrid=IFB!PC{xWt~$(699)9D? literal 0 HcmV?d00001 From b074e68d04b7bc57de0fa0356c9bad6493f8851b Mon Sep 17 00:00:00 2001 From: kd8lvt Date: Wed, 2 Oct 2024 17:33:13 -0400 Subject: [PATCH 3/6] Feat: Bulk Digestion in Gastric Acid --- .../biomancy/init/AcidInteractions.java | 64 ++++++++++++++++++ .../biomancy/init/ModParticleTypes.java | 1 + .../biomancy/mixin/ItemEntityMixin.java | 29 ++++++++ .../textures/particle/acid_bubble.png | Bin 0 -> 147 bytes src/main/resources/mixins.biomancy.json | 53 ++++++++++++--- 5 files changed, 139 insertions(+), 8 deletions(-) create mode 100644 src/main/java/com/github/elenterius/biomancy/mixin/ItemEntityMixin.java create mode 100644 src/main/resources/assets/biomancy/textures/particle/acid_bubble.png diff --git a/src/main/java/com/github/elenterius/biomancy/init/AcidInteractions.java b/src/main/java/com/github/elenterius/biomancy/init/AcidInteractions.java index 852372496..9c69235e5 100644 --- a/src/main/java/com/github/elenterius/biomancy/init/AcidInteractions.java +++ b/src/main/java/com/github/elenterius/biomancy/init/AcidInteractions.java @@ -1,9 +1,15 @@ package com.github.elenterius.biomancy.init; +import com.github.elenterius.biomancy.block.digester.DigesterBlockEntity; +import com.github.elenterius.biomancy.crafting.recipe.DigestingRecipe; import com.github.elenterius.biomancy.init.tags.ModBlockTags; +import com.github.elenterius.biomancy.inventory.BehavioralInventory; import com.github.elenterius.biomancy.util.CombatUtil; +import net.minecraft.core.Direction; import net.minecraft.core.cauldron.CauldronInteraction; +import net.minecraft.core.dispenser.DefaultDispenseItemBehavior; import net.minecraft.core.particles.ParticleTypes; +import net.minecraft.nbt.CompoundTag; import net.minecraft.sounds.SoundEvent; import net.minecraft.sounds.SoundEvents; import net.minecraft.sounds.SoundSource; @@ -11,6 +17,7 @@ import net.minecraft.util.RandomSource; import net.minecraft.world.InteractionResult; import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.item.ItemEntity; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemUtils; @@ -25,10 +32,12 @@ import net.minecraft.world.level.gameevent.GameEvent; import net.minecraft.world.phys.Vec3; import net.minecraftforge.common.SoundActions; +import org.apache.commons.lang3.ArrayUtils; import org.jetbrains.annotations.Nullable; import java.util.Map; import java.util.Objects; +import java.util.Optional; public final class AcidInteractions { @@ -157,4 +166,59 @@ else if (livingEntity.tickCount % 10 == 0 && livingEntity.getRandom().nextFloat( } } + private static final String TIMER_KEY = "biomancy:digestion_timer"; + private static final float EFFICIENCY = 0.8f; + public static void tryDigest(ItemEntity itemEntity, boolean onClient) { + DigestingRecipe recipe = getDigestionRecipe(itemEntity); + if (!digestible(itemEntity,recipe)) return; + CompoundTag data = itemEntity.getPersistentData(); + if (data.contains(TIMER_KEY) && data.getInt(TIMER_KEY) < 10) { + data.putInt(TIMER_KEY, data.getInt(TIMER_KEY) + 1); + } else if (data.contains(TIMER_KEY) && data.getInt(TIMER_KEY) >= 10 && !onClient){ + digestIntoNutrientPasteStacks(itemEntity,recipe); + itemEntity.getPersistentData().remove(TIMER_KEY); + } else { + data.putInt(TIMER_KEY,1); + } + } + + private static void digestIntoNutrientPasteStacks(ItemEntity itemEntity, DigestingRecipe recipe) { + BehavioralInventory tempInventory = BehavioralInventory.createServerContents(1,player->false,()->{}); + tempInventory.insertItemStack(itemEntity.getItem()); + ItemStack resultStack = recipe.assemble(tempInventory,itemEntity.level().registryAccess()); + int totalToOutput = (int)Math.floor(resultStack.getCount()*itemEntity.getItem().getCount()*EFFICIENCY); + if (totalToOutput > 64) totalToOutput = splitIntoStacks(itemEntity,totalToOutput); + itemEntity.setItem(new ItemStack(ModItems.NUTRIENT_PASTE.get(), totalToOutput)); + itemEntity.playSound(SoundEvents.PLAYER_BURP); + } + + private static int splitIntoStacks(ItemEntity itemEntity, int numToSplit) { + Level level = itemEntity.level(); + while (numToSplit > 64) { + DefaultDispenseItemBehavior.spawnItem(level,new ItemStack(ModItems.NUTRIENT_PASTE.get(),64),1, Direction.UP, itemEntity.position()); + numToSplit -= 64; + } + return numToSplit; + } + + + @SuppressWarnings("RedundantIfStatement") + private static boolean digestible(ItemEntity itemEntity, @Nullable DigestingRecipe recipe) { + if (recipe == null) return false; + if (!itemEntity.isInFluidType(ModFluids.ACID_TYPE.get()) && !itemEntity.level().getBlockState(itemEntity.blockPosition()).is(ModBlocks.ACID_CAULDRON.get())) return false; + //Inside method to prevent missing registry object errors during init + Item[] blacklistedItems = {ModItems.NUTRIENT_PASTE.get(),ModItems.NUTRIENT_BAR.get(),ModItems.LIVING_FLESH.get()}; + if (ArrayUtils.contains(blacklistedItems,itemEntity.getItem().getItem())) return false; + return true; + } + + private static DigestingRecipe cachedRecipe = null; + private static @Nullable DigestingRecipe getDigestionRecipe(ItemEntity itemEntity) { + if (cachedRecipe != null && cachedRecipe.getIngredient().test(itemEntity.getItem())) return cachedRecipe; + Optional foundRecipe = DigesterBlockEntity.RECIPE_TYPE.get().getRecipeForIngredient(itemEntity.level(), itemEntity.getItem()); + if (foundRecipe.isEmpty()) return null; + cachedRecipe = foundRecipe.get(); + return cachedRecipe; + } + } diff --git a/src/main/java/com/github/elenterius/biomancy/init/ModParticleTypes.java b/src/main/java/com/github/elenterius/biomancy/init/ModParticleTypes.java index 33af249c2..e673047f4 100644 --- a/src/main/java/com/github/elenterius/biomancy/init/ModParticleTypes.java +++ b/src/main/java/com/github/elenterius/biomancy/init/ModParticleTypes.java @@ -21,6 +21,7 @@ public final class ModParticleTypes { public static final RegistryObject LIGHT_GREEN_GLOW = register("light_green_glow", false); public static final RegistryObject HOSTILE = register("hostile", false); public static final RegistryObject BIOHAZARD = register("biohazard", false); + public static final RegistryObject ACID_BUBBLE = register("acid_bubble", false); private ModParticleTypes() {} diff --git a/src/main/java/com/github/elenterius/biomancy/mixin/ItemEntityMixin.java b/src/main/java/com/github/elenterius/biomancy/mixin/ItemEntityMixin.java new file mode 100644 index 000000000..8b4a261cb --- /dev/null +++ b/src/main/java/com/github/elenterius/biomancy/mixin/ItemEntityMixin.java @@ -0,0 +1,29 @@ +package com.github.elenterius.biomancy.mixin; + +import com.github.elenterius.biomancy.init.AcidInteractions; +import com.github.elenterius.biomancy.init.ModParticleTypes; +import net.minecraft.util.RandomSource; +import net.minecraft.world.entity.item.ItemEntity; +import net.minecraft.world.phys.Vec3; +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; + +@Mixin(ItemEntity.class) +public abstract class ItemEntityMixin { + @Inject(at=@At("TAIL"),method={"tick()V"}) + private void onTick(CallbackInfo ci) { + ItemEntity self = (ItemEntity)((Object)this); //I hate casting like this on so many levels + if (self.isRemoved()) return; + boolean onClient = self.level().isClientSide(); + + if (onClient) { + Vec3 pos = self.position(); + RandomSource random = self.level().getRandom(); + self.level().addParticle(ModParticleTypes.ACID_BUBBLE.get(), pos.x + random.nextGaussian(), pos.y, pos.z + random.nextGaussian(), random.nextGaussian(), 0.1, random.nextGaussian()); + } + if (self.getAge() % 10 != 0) return; //Only fire once every 10 ticks + AcidInteractions.tryDigest(self,onClient); + } +} \ No newline at end of file diff --git a/src/main/resources/assets/biomancy/textures/particle/acid_bubble.png b/src/main/resources/assets/biomancy/textures/particle/acid_bubble.png new file mode 100644 index 0000000000000000000000000000000000000000..cdd12ea88d2f267b0a281a5d72b55ab52383c484 GIT binary patch literal 147 zcmeAS@N?(olHy`uVBq!ia0vp^93afW3?x5a^xFxf7>k44ofy`glX(f`@C5jTxB}@< z|NqbUKSS}q;+)T?{eXOyk|4iehX4QnZ`O6_0P%Fr7JbMnI}hQc_Z4 p#sMBSjb_F}44Y>t*r+M+GO)=p=-vrid=IFB!PC{xWt~$(699)9D? literal 0 HcmV?d00001 diff --git a/src/main/resources/mixins.biomancy.json b/src/main/resources/mixins.biomancy.json index b75a101cc..a580f0e76 100644 --- a/src/main/resources/mixins.biomancy.json +++ b/src/main/resources/mixins.biomancy.json @@ -8,16 +8,53 @@ "defaultRequire": 1 }, "mixins": [ - "accessor.AgeableMobAccessor", "accessor.ArmorStandAccessor", "accessor.BiomeAccessor", "accessor.CreeperAccessor", "accessor.DamageSourceAccessor", - "accessor.EntityAccessor", "accessor.IntegerPropertyAccessor", "accessor.LivingEntityAccessor", "accessor.MobEffectInstanceAccessor", - "accessor.MobEntityAccessor", "accessor.ServerLevelAccessor", "accessor.SheepAccessor", "accessor.SlimeAccessor", "accessor.SuspiciousStewItemAccessor", - "accessor.SwordItemMixinAccessor", "accessor.TadpoleAccessor", "accessor.TextureSlotAccessor", "accessor.ZombieVillagerMixinAccessor", - "AnimalMixin", "AreaEffectCloudMixin", "ArrowMixin", "ChickenMixin", "CowMixin", "FlowingFluidMixin", "LivingEntityMixin", "MobEffectInstanceMixin", - "PhantomMixin", "PigMixin", "PlayerMixin", "ServerLevelMixin", "SheepMixin", "ThrownPotionMixin", "UnbreakingEnchantmentMixin", "WallBlockMixin", - "BlockMixin", "NodeEvaluatorMixin", "SignBlockEntityMixin", "ServerGamePacketListenerImplMixin", "VillagerMixin", "VillagerMakeLoveMixin" + "AnimalMixin", + "AreaEffectCloudMixin", + "ArrowMixin", + "BlockMixin", + "ChickenMixin", + "CowMixin", + "FlowingFluidMixin", + "ItemEntityMixin", + "LivingEntityMixin", + "MobEffectInstanceMixin", + "NodeEvaluatorMixin", + "PhantomMixin", + "PigMixin", + "PlayerMixin", + "ServerGamePacketListenerImplMixin", + "ServerLevelMixin", + "SheepMixin", + "SignBlockEntityMixin", + "ThrownPotionMixin", + "UnbreakingEnchantmentMixin", + "VillagerMakeLoveMixin", + "VillagerMixin", + "WallBlockMixin", + "accessor.AgeableMobAccessor", + "accessor.ArmorStandAccessor", + "accessor.BiomeAccessor", + "accessor.CreeperAccessor", + "accessor.DamageSourceAccessor", + "accessor.EntityAccessor", + "accessor.IntegerPropertyAccessor", + "accessor.LivingEntityAccessor", + "accessor.MobEffectInstanceAccessor", + "accessor.MobEntityAccessor", + "accessor.ServerLevelAccessor", + "accessor.SheepAccessor", + "accessor.SlimeAccessor", + "accessor.SuspiciousStewItemAccessor", + "accessor.SwordItemMixinAccessor", + "accessor.TadpoleAccessor", + "accessor.TextureSlotAccessor", + "accessor.ZombieVillagerMixinAccessor" ], "client": [ - "accessor.RecipeCollectionAccessor", "client.ClientPackListenerMixin", "client.ClientRecipeBookMixin", "client.GuiGraphicsMixin", + "accessor.RecipeCollectionAccessor", + "client.ClientPackListenerMixin", + "client.ClientRecipeBookMixin", + "client.GuiGraphicsMixin", "client.PlayerRendererMixin" ], "server": [ ] From 118499bca28aa142a9901a57308619c90274eb4f Mon Sep 17 00:00:00 2001 From: kd8lvt Date: Wed, 9 Oct 2024 23:08:54 -0400 Subject: [PATCH 4/6] Feat: Bulk Digestion in Gastric Acid Implement requested changes Note: Particles (even Vanilla ones) don't render under/through Acid without Fabulous graphics enabled. Likely related to [#151](https://github.com/Elenterius/Biomancy/issues/151) --- .../particles/ModParticleSpriteProvider.java | 1 + .../datagen/tags/ModItemTagsProvider.java | 5 + .../client/particle/ParticleProviders.java | 14 ++ .../client/particle/VanillaDripParticle.java | 37 ++++++ .../biomancy/init/AcidInteractions.java | 123 +++++++++++------- .../init/client/ClientSetupHandler.java | 1 + .../biomancy/init/tags/ModItemTags.java | 2 + .../biomancy/mixin/ItemEntityMixin.java | 17 +-- 8 files changed, 138 insertions(+), 62 deletions(-) diff --git a/src/datagen/java/com/github/elenterius/biomancy/datagen/particles/ModParticleSpriteProvider.java b/src/datagen/java/com/github/elenterius/biomancy/datagen/particles/ModParticleSpriteProvider.java index 002be4c5f..d3fe91567 100644 --- a/src/datagen/java/com/github/elenterius/biomancy/datagen/particles/ModParticleSpriteProvider.java +++ b/src/datagen/java/com/github/elenterius/biomancy/datagen/particles/ModParticleSpriteProvider.java @@ -24,6 +24,7 @@ public void registerParticles() { addParticle(ModParticleTypes.LIGHT_GREEN_GLOW, "minecraft:glow"); addParticle(ModParticleTypes.HOSTILE, "biomancy:hostile"); addParticle(ModParticleTypes.BIOHAZARD, "biomancy:biohazard"); + addParticle(ModParticleTypes.ACID_BUBBLE, "biomancy:acid_bubble"); } } diff --git a/src/datagen/java/com/github/elenterius/biomancy/datagen/tags/ModItemTagsProvider.java b/src/datagen/java/com/github/elenterius/biomancy/datagen/tags/ModItemTagsProvider.java index 0967b01c9..5a7c4e10d 100644 --- a/src/datagen/java/com/github/elenterius/biomancy/datagen/tags/ModItemTagsProvider.java +++ b/src/datagen/java/com/github/elenterius/biomancy/datagen/tags/ModItemTagsProvider.java @@ -108,6 +108,11 @@ private void addBiomancyTags() { .addTag(Tags.Items.ARMORS, Tags.Items.TOOLS) .addTag(Tags.Items.ORES_NETHERITE_SCRAP, Tags.Items.INGOTS_NETHERITE, Tags.Items.STORAGE_BLOCKS_NETHERITE) .addTag(forgeTag("shulker_boxes")); + + createTag(ModItemTags.CANNOT_BE_DIGESTED_IN_ACID) + .add(ModItems.NUTRIENT_PASTE.get()) + .add(ModItems.NUTRIENT_BAR.get()) + .add(ModItems.LIVING_FLESH.get()); } private void addMinecraftTags() { diff --git a/src/main/java/com/github/elenterius/biomancy/client/particle/ParticleProviders.java b/src/main/java/com/github/elenterius/biomancy/client/particle/ParticleProviders.java index 164b28571..14c462545 100644 --- a/src/main/java/com/github/elenterius/biomancy/client/particle/ParticleProviders.java +++ b/src/main/java/com/github/elenterius/biomancy/client/particle/ParticleProviders.java @@ -64,4 +64,18 @@ public Particle createParticle(SimpleParticleType type, ClientLevel level, doubl } } + @OnlyIn(Dist.CLIENT) + public static class AcidBubbleProvider implements ParticleProvider { + protected final SpriteSet sprite; + + public AcidBubbleProvider(SpriteSet sprites) { + sprite = sprites; + } + + public Particle createParticle(SimpleParticleType type, ClientLevel level, double x, double y, double z, double xSpeed, double ySpeed, double zSpeed) { + VanillaDripParticle.AcidBubbleParticle particle = new VanillaDripParticle.AcidBubbleParticle(level, x, y, z, xSpeed, ySpeed, zSpeed); + particle.pickSprite(sprite); + return particle; + } + } } diff --git a/src/main/java/com/github/elenterius/biomancy/client/particle/VanillaDripParticle.java b/src/main/java/com/github/elenterius/biomancy/client/particle/VanillaDripParticle.java index cc330d292..d2ed45b5a 100644 --- a/src/main/java/com/github/elenterius/biomancy/client/particle/VanillaDripParticle.java +++ b/src/main/java/com/github/elenterius/biomancy/client/particle/VanillaDripParticle.java @@ -1,5 +1,6 @@ package com.github.elenterius.biomancy.client.particle; +import com.github.elenterius.biomancy.init.ModFluids; import net.minecraft.client.multiplayer.ClientLevel; import net.minecraft.client.particle.ParticleRenderType; import net.minecraft.client.particle.TextureSheetParticle; @@ -188,4 +189,40 @@ protected void postMoveUpdate() { } } + @OnlyIn(Dist.CLIENT) + protected static class AcidBubbleParticle extends TextureSheetParticle { //Almost an exact copy of the vanilla BubbleParticle because it can't be extended + AcidBubbleParticle(ClientLevel level, double x, double y, double z, double xSpeed, double ySpeed, double zSpeed) { + super(level, x, y, z); + this.setSize(0.02F, 0.02F); + this.quadSize *= this.random.nextFloat() * 0.6F + 0.2F; + this.xd = xSpeed * (double)0.2F + (Math.random() * 2.0D - 1.0D) * (double)0.02F; + this.yd = ySpeed * (double)0.2F + (Math.random() * 2.0D - 1.0D) * (double)0.02F; + this.zd = zSpeed * (double)0.2F + (Math.random() * 2.0D - 1.0D) * (double)0.02F; + this.lifetime = (int)(8.0D / (Math.random() * 0.8D + 0.2D)); + } + + public void tick() { + this.xo = this.x; + this.yo = this.y; + this.zo = this.z; + if (this.lifetime-- <= 0) { + this.remove(); + } else { + this.yd += 0.002D; + this.move(this.xd, this.yd, this.zd); + this.xd *= 0.85F; + this.yd *= 0.85F; + this.zd *= 0.85F; + if (!this.level.getFluidState(BlockPos.containing(this.x, this.y, this.z)).is(ModFluids.ACID.get())) { + this.remove(); + } + + } + } + + public ParticleRenderType getRenderType() { + return ParticleRenderType.PARTICLE_SHEET_OPAQUE; + } + } + } diff --git a/src/main/java/com/github/elenterius/biomancy/init/AcidInteractions.java b/src/main/java/com/github/elenterius/biomancy/init/AcidInteractions.java index 9c69235e5..3178f98e2 100644 --- a/src/main/java/com/github/elenterius/biomancy/init/AcidInteractions.java +++ b/src/main/java/com/github/elenterius/biomancy/init/AcidInteractions.java @@ -3,6 +3,7 @@ import com.github.elenterius.biomancy.block.digester.DigesterBlockEntity; import com.github.elenterius.biomancy.crafting.recipe.DigestingRecipe; import com.github.elenterius.biomancy.init.tags.ModBlockTags; +import com.github.elenterius.biomancy.init.tags.ModItemTags; import com.github.elenterius.biomancy.inventory.BehavioralInventory; import com.github.elenterius.biomancy.util.CombatUtil; import net.minecraft.core.Direction; @@ -10,6 +11,7 @@ import net.minecraft.core.dispenser.DefaultDispenseItemBehavior; import net.minecraft.core.particles.ParticleTypes; import net.minecraft.nbt.CompoundTag; +import net.minecraft.resources.ResourceLocation; import net.minecraft.sounds.SoundEvent; import net.minecraft.sounds.SoundEvents; import net.minecraft.sounds.SoundSource; @@ -32,7 +34,6 @@ import net.minecraft.world.level.gameevent.GameEvent; import net.minecraft.world.phys.Vec3; import net.minecraftforge.common.SoundActions; -import org.apache.commons.lang3.ArrayUtils; import org.jetbrains.annotations.Nullable; import java.util.Map; @@ -166,59 +167,85 @@ else if (livingEntity.tickCount % 10 == 0 && livingEntity.getRandom().nextFloat( } } - private static final String TIMER_KEY = "biomancy:digestion_timer"; - private static final float EFFICIENCY = 0.8f; - public static void tryDigest(ItemEntity itemEntity, boolean onClient) { - DigestingRecipe recipe = getDigestionRecipe(itemEntity); - if (!digestible(itemEntity,recipe)) return; - CompoundTag data = itemEntity.getPersistentData(); - if (data.contains(TIMER_KEY) && data.getInt(TIMER_KEY) < 10) { - data.putInt(TIMER_KEY, data.getInt(TIMER_KEY) + 1); - } else if (data.contains(TIMER_KEY) && data.getInt(TIMER_KEY) >= 10 && !onClient){ - digestIntoNutrientPasteStacks(itemEntity,recipe); - itemEntity.getPersistentData().remove(TIMER_KEY); - } else { - data.putInt(TIMER_KEY,1); + public static final class InWorldItemDigesting { + //NBT Tag keys + public static final String BASE_DATA_KEY = "biomancy:acid_digestion"; + public static final String TIMER_KEY = "timer"; + public static final String RECIPE_KEY = "recipe"; + //Balancing multiplier applied to the output of any found recipes. + public static final double EFFICIENCY = 0.8; + //How many times tryDigestSubmergedItem should be called on a digestible item before it is processed. + //This is not directly ticks, as submerged items are only actually processed every 10 ticks. + public static final int DELAY = 10; + + public static void tryDigestSubmergedItem(ItemEntity itemEntity) { + if (!digestible(itemEntity)) return; + ItemStack stack = itemEntity.getItem(); + CompoundTag entityData = itemEntity.getPersistentData(); + CompoundTag digestionData = getOrCreateDigestionData(entityData); + if (itemEntity.level().isClientSide && digestionData.getInt(TIMER_KEY) > 0) { + Vec3 pos = itemEntity.position(); + RandomSource random = itemEntity.level().getRandom(); + itemEntity.level().addParticle(ModParticleTypes.ACID_BUBBLE.get(),pos.x,pos.y,pos.z,random.nextGaussian()/100,Math.abs(random.nextGaussian()/50),random.nextGaussian()/100); + itemEntity.level().addParticle(ParticleTypes.SMOKE,pos.x,pos.y,pos.z,random.nextGaussian()/100,Math.abs(random.nextGaussian()/100),random.nextGaussian()/100); + return; + } + + if (itemEntity.getAge() % 10 != 0) return; //Only tick digestion every 10 ticks. + Optional optionalRecipe = getDigestionRecipe(itemEntity, stack, digestionData); + + if (optionalRecipe.isEmpty()) return; + if (optionalRecipe.get().getId() != ResourceLocation.tryParse(digestionData.getString(RECIPE_KEY))) { + digestionData.putString(RECIPE_KEY, optionalRecipe.get().getId().toString()); + } + + int currentDigestionTime = digestionData.getInt(TIMER_KEY); + if (currentDigestionTime < DELAY) { + digestionData.putInt(TIMER_KEY, currentDigestionTime + 1); + entityData.put(BASE_DATA_KEY,digestionData); + } else { + digestIntoNutrientPasteStacks(itemEntity, optionalRecipe.get()); + itemEntity.getPersistentData().remove(BASE_DATA_KEY); + } } - } - private static void digestIntoNutrientPasteStacks(ItemEntity itemEntity, DigestingRecipe recipe) { - BehavioralInventory tempInventory = BehavioralInventory.createServerContents(1,player->false,()->{}); - tempInventory.insertItemStack(itemEntity.getItem()); - ItemStack resultStack = recipe.assemble(tempInventory,itemEntity.level().registryAccess()); - int totalToOutput = (int)Math.floor(resultStack.getCount()*itemEntity.getItem().getCount()*EFFICIENCY); - if (totalToOutput > 64) totalToOutput = splitIntoStacks(itemEntity,totalToOutput); - itemEntity.setItem(new ItemStack(ModItems.NUTRIENT_PASTE.get(), totalToOutput)); - itemEntity.playSound(SoundEvents.PLAYER_BURP); - } + public static CompoundTag getOrCreateDigestionData(CompoundTag entityData) { + if (entityData.contains(BASE_DATA_KEY)) return entityData.getCompound(BASE_DATA_KEY); + return new CompoundTag(); + } - private static int splitIntoStacks(ItemEntity itemEntity, int numToSplit) { - Level level = itemEntity.level(); - while (numToSplit > 64) { - DefaultDispenseItemBehavior.spawnItem(level,new ItemStack(ModItems.NUTRIENT_PASTE.get(),64),1, Direction.UP, itemEntity.position()); - numToSplit -= 64; + public static void digestIntoNutrientPasteStacks(ItemEntity itemEntity, DigestingRecipe recipe) { + BehavioralInventory tempInventory = BehavioralInventory.createServerContents(1, player -> false, () -> {}); + tempInventory.insertItemStack(itemEntity.getItem()); + ItemStack resultStack = recipe.assemble(tempInventory, itemEntity.level().registryAccess()); + int totalToOutput = (int) Math.floor(resultStack.getCount() * itemEntity.getItem().getCount() * EFFICIENCY); + if (totalToOutput > 64) totalToOutput = splitIntoStacks(itemEntity, totalToOutput); + itemEntity.setItem(new ItemStack(ModItems.NUTRIENT_PASTE.get(), totalToOutput)); + itemEntity.playSound(SoundEvents.PLAYER_BURP); } - return numToSplit; - } + public static int splitIntoStacks(ItemEntity itemEntity, int numToSplit) { + Level level = itemEntity.level(); + while (numToSplit > 64) { + DefaultDispenseItemBehavior.spawnItem(level, new ItemStack(ModItems.NUTRIENT_PASTE.get(), 64), 1, Direction.UP, itemEntity.position()); + numToSplit -= 64; + } + return numToSplit; + } - @SuppressWarnings("RedundantIfStatement") - private static boolean digestible(ItemEntity itemEntity, @Nullable DigestingRecipe recipe) { - if (recipe == null) return false; - if (!itemEntity.isInFluidType(ModFluids.ACID_TYPE.get()) && !itemEntity.level().getBlockState(itemEntity.blockPosition()).is(ModBlocks.ACID_CAULDRON.get())) return false; - //Inside method to prevent missing registry object errors during init - Item[] blacklistedItems = {ModItems.NUTRIENT_PASTE.get(),ModItems.NUTRIENT_BAR.get(),ModItems.LIVING_FLESH.get()}; - if (ArrayUtils.contains(blacklistedItems,itemEntity.getItem().getItem())) return false; - return true; - } + @SuppressWarnings("RedundantIfStatement") //Let me write readable code please, thanks + public static boolean digestible(ItemEntity itemEntity) { + if (!itemEntity.isInFluidType(ModFluids.ACID_TYPE.get()) && !itemEntity.level().getBlockState(itemEntity.blockPosition()).is(ModBlocks.ACID_CAULDRON.get())) return false; + if (itemEntity.getItem().is(ModItemTags.CANNOT_BE_DIGESTED_IN_ACID)) return false; + return true; + } - private static DigestingRecipe cachedRecipe = null; - private static @Nullable DigestingRecipe getDigestionRecipe(ItemEntity itemEntity) { - if (cachedRecipe != null && cachedRecipe.getIngredient().test(itemEntity.getItem())) return cachedRecipe; - Optional foundRecipe = DigesterBlockEntity.RECIPE_TYPE.get().getRecipeForIngredient(itemEntity.level(), itemEntity.getItem()); - if (foundRecipe.isEmpty()) return null; - cachedRecipe = foundRecipe.get(); - return cachedRecipe; + private static Optional getDigestionRecipe(ItemEntity itemEntity, ItemStack stack, CompoundTag digestionData) { + Optional recipe = Optional.empty(); + ResourceLocation lastRecipeId = ResourceLocation.tryParse(digestionData.getString(RECIPE_KEY)); + if (lastRecipeId != null) recipe = DigesterBlockEntity.RECIPE_TYPE.get().getRecipeById(itemEntity.level(), lastRecipeId); + if (recipe.isEmpty()) recipe = DigesterBlockEntity.RECIPE_TYPE.get().getRecipeForIngredient(itemEntity.level(), stack); + return recipe; //If it's still empty, there's no recipe that matches the item stack. + } } - } diff --git a/src/main/java/com/github/elenterius/biomancy/init/client/ClientSetupHandler.java b/src/main/java/com/github/elenterius/biomancy/init/client/ClientSetupHandler.java index 5afebb12e..a8dea9893 100644 --- a/src/main/java/com/github/elenterius/biomancy/init/client/ClientSetupHandler.java +++ b/src/main/java/com/github/elenterius/biomancy/init/client/ClientSetupHandler.java @@ -149,6 +149,7 @@ public static void registerParticles(final RegisterParticleProvidersEvent event) event.registerSpriteSet(ModParticleTypes.LIGHT_GREEN_GLOW.get(), sprites -> new CustomGlowParticle.TwoColorProvider(sprites, 0x53ff53, 0x64e986)); event.registerSpriteSet(ModParticleTypes.HOSTILE.get(), CustomGlowParticle.GenericProvider::new); event.registerSpriteSet(ModParticleTypes.BIOHAZARD.get(), sprites -> new CustomGlowParticle.TwoColorProvider(sprites, 0xab274f, 0x7e2a43)); + event.registerSpriteSet(ModParticleTypes.ACID_BUBBLE.get(), ParticleProviders.AcidBubbleProvider::new); } @SubscribeEvent diff --git a/src/main/java/com/github/elenterius/biomancy/init/tags/ModItemTags.java b/src/main/java/com/github/elenterius/biomancy/init/tags/ModItemTags.java index 9afd06e5d..0a1be5cd5 100644 --- a/src/main/java/com/github/elenterius/biomancy/init/tags/ModItemTags.java +++ b/src/main/java/com/github/elenterius/biomancy/init/tags/ModItemTags.java @@ -19,6 +19,8 @@ public final class ModItemTags { public static final TagKey SUGARS = tag("sugars"); + public static final TagKey CANNOT_BE_DIGESTED_IN_ACID = tag("cannot_be_digested_in_acid"); + private ModItemTags() {} private static TagKey tag(String name) { diff --git a/src/main/java/com/github/elenterius/biomancy/mixin/ItemEntityMixin.java b/src/main/java/com/github/elenterius/biomancy/mixin/ItemEntityMixin.java index 8b4a261cb..b7437583d 100644 --- a/src/main/java/com/github/elenterius/biomancy/mixin/ItemEntityMixin.java +++ b/src/main/java/com/github/elenterius/biomancy/mixin/ItemEntityMixin.java @@ -1,10 +1,7 @@ package com.github.elenterius.biomancy.mixin; import com.github.elenterius.biomancy.init.AcidInteractions; -import com.github.elenterius.biomancy.init.ModParticleTypes; -import net.minecraft.util.RandomSource; import net.minecraft.world.entity.item.ItemEntity; -import net.minecraft.world.phys.Vec3; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; @@ -14,16 +11,8 @@ public abstract class ItemEntityMixin { @Inject(at=@At("TAIL"),method={"tick()V"}) private void onTick(CallbackInfo ci) { - ItemEntity self = (ItemEntity)((Object)this); //I hate casting like this on so many levels - if (self.isRemoved()) return; - boolean onClient = self.level().isClientSide(); - - if (onClient) { - Vec3 pos = self.position(); - RandomSource random = self.level().getRandom(); - self.level().addParticle(ModParticleTypes.ACID_BUBBLE.get(), pos.x + random.nextGaussian(), pos.y, pos.z + random.nextGaussian(), random.nextGaussian(), 0.1, random.nextGaussian()); - } - if (self.getAge() % 10 != 0) return; //Only fire once every 10 ticks - AcidInteractions.tryDigest(self,onClient); + ItemEntity itemEntity = (ItemEntity)((Object)this); //I hate casting like this on so many levels -Kd + if (itemEntity.isRemoved()) return; + AcidInteractions.InWorldItemDigesting.tryDigestSubmergedItem(itemEntity); } } \ No newline at end of file From 0e2930aa622c78f42042ee4e625a866a7f5ddb09 Mon Sep 17 00:00:00 2001 From: kd8lvt Date: Wed, 9 Oct 2024 23:09:03 -0400 Subject: [PATCH 5/6] Feat: Bulk Digestion in Gastric Acid Implement requested changes Note: Particles (even Vanilla ones) don't render under/through Acid without Fabulous graphics enabled. Likely related to [#151](https://github.com/Elenterius/Biomancy/issues/151) --- .../resources/assets/biomancy/particles/acid_bubble.json | 5 +++++ .../biomancy/tags/items/cannot_be_digested_in_acid.json | 7 +++++++ 2 files changed, 12 insertions(+) create mode 100644 src/generated/resources/assets/biomancy/particles/acid_bubble.json create mode 100644 src/generated/resources/data/biomancy/tags/items/cannot_be_digested_in_acid.json diff --git a/src/generated/resources/assets/biomancy/particles/acid_bubble.json b/src/generated/resources/assets/biomancy/particles/acid_bubble.json new file mode 100644 index 000000000..ba68a0297 --- /dev/null +++ b/src/generated/resources/assets/biomancy/particles/acid_bubble.json @@ -0,0 +1,5 @@ +{ + "textures": [ + "biomancy:acid_bubble" + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/biomancy/tags/items/cannot_be_digested_in_acid.json b/src/generated/resources/data/biomancy/tags/items/cannot_be_digested_in_acid.json new file mode 100644 index 000000000..6ca09093e --- /dev/null +++ b/src/generated/resources/data/biomancy/tags/items/cannot_be_digested_in_acid.json @@ -0,0 +1,7 @@ +{ + "values": [ + "biomancy:nutrient_paste", + "biomancy:nutrient_bar", + "biomancy:living_flesh" + ] +} \ No newline at end of file From e9928b8774d1367221e96f6e6066ee5cc34ef302 Mon Sep 17 00:00:00 2001 From: kd8lvt Date: Wed, 9 Oct 2024 23:08:54 -0400 Subject: [PATCH 6/6] Feat: Bulk Digestion in Gastric Acid Implement requested changes Note: Particles (even Vanilla ones) don't render under/through Acid without Fabulous graphics enabled. Likely related to [#151](https://github.com/Elenterius/Biomancy/issues/151) --- .../particles/ModParticleSpriteProvider.java | 1 + .../datagen/tags/ModItemTagsProvider.java | 5 + .../biomancy/particles/acid_bubble.json | 5 + .../items/cannot_be_digested_in_acid.json | 7 + .../client/particle/ParticleProviders.java | 14 ++ .../client/particle/VanillaDripParticle.java | 37 ++++++ .../biomancy/init/AcidInteractions.java | 123 +++++++++++------- .../init/client/ClientSetupHandler.java | 1 + .../biomancy/init/tags/ModItemTags.java | 2 + .../biomancy/mixin/ItemEntityMixin.java | 17 +-- 10 files changed, 150 insertions(+), 62 deletions(-) create mode 100644 src/generated/resources/assets/biomancy/particles/acid_bubble.json create mode 100644 src/generated/resources/data/biomancy/tags/items/cannot_be_digested_in_acid.json diff --git a/src/datagen/java/com/github/elenterius/biomancy/datagen/particles/ModParticleSpriteProvider.java b/src/datagen/java/com/github/elenterius/biomancy/datagen/particles/ModParticleSpriteProvider.java index 002be4c5f..d3fe91567 100644 --- a/src/datagen/java/com/github/elenterius/biomancy/datagen/particles/ModParticleSpriteProvider.java +++ b/src/datagen/java/com/github/elenterius/biomancy/datagen/particles/ModParticleSpriteProvider.java @@ -24,6 +24,7 @@ public void registerParticles() { addParticle(ModParticleTypes.LIGHT_GREEN_GLOW, "minecraft:glow"); addParticle(ModParticleTypes.HOSTILE, "biomancy:hostile"); addParticle(ModParticleTypes.BIOHAZARD, "biomancy:biohazard"); + addParticle(ModParticleTypes.ACID_BUBBLE, "biomancy:acid_bubble"); } } diff --git a/src/datagen/java/com/github/elenterius/biomancy/datagen/tags/ModItemTagsProvider.java b/src/datagen/java/com/github/elenterius/biomancy/datagen/tags/ModItemTagsProvider.java index 0967b01c9..5a7c4e10d 100644 --- a/src/datagen/java/com/github/elenterius/biomancy/datagen/tags/ModItemTagsProvider.java +++ b/src/datagen/java/com/github/elenterius/biomancy/datagen/tags/ModItemTagsProvider.java @@ -108,6 +108,11 @@ private void addBiomancyTags() { .addTag(Tags.Items.ARMORS, Tags.Items.TOOLS) .addTag(Tags.Items.ORES_NETHERITE_SCRAP, Tags.Items.INGOTS_NETHERITE, Tags.Items.STORAGE_BLOCKS_NETHERITE) .addTag(forgeTag("shulker_boxes")); + + createTag(ModItemTags.CANNOT_BE_DIGESTED_IN_ACID) + .add(ModItems.NUTRIENT_PASTE.get()) + .add(ModItems.NUTRIENT_BAR.get()) + .add(ModItems.LIVING_FLESH.get()); } private void addMinecraftTags() { diff --git a/src/generated/resources/assets/biomancy/particles/acid_bubble.json b/src/generated/resources/assets/biomancy/particles/acid_bubble.json new file mode 100644 index 000000000..ba68a0297 --- /dev/null +++ b/src/generated/resources/assets/biomancy/particles/acid_bubble.json @@ -0,0 +1,5 @@ +{ + "textures": [ + "biomancy:acid_bubble" + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/biomancy/tags/items/cannot_be_digested_in_acid.json b/src/generated/resources/data/biomancy/tags/items/cannot_be_digested_in_acid.json new file mode 100644 index 000000000..6ca09093e --- /dev/null +++ b/src/generated/resources/data/biomancy/tags/items/cannot_be_digested_in_acid.json @@ -0,0 +1,7 @@ +{ + "values": [ + "biomancy:nutrient_paste", + "biomancy:nutrient_bar", + "biomancy:living_flesh" + ] +} \ No newline at end of file diff --git a/src/main/java/com/github/elenterius/biomancy/client/particle/ParticleProviders.java b/src/main/java/com/github/elenterius/biomancy/client/particle/ParticleProviders.java index 164b28571..14c462545 100644 --- a/src/main/java/com/github/elenterius/biomancy/client/particle/ParticleProviders.java +++ b/src/main/java/com/github/elenterius/biomancy/client/particle/ParticleProviders.java @@ -64,4 +64,18 @@ public Particle createParticle(SimpleParticleType type, ClientLevel level, doubl } } + @OnlyIn(Dist.CLIENT) + public static class AcidBubbleProvider implements ParticleProvider { + protected final SpriteSet sprite; + + public AcidBubbleProvider(SpriteSet sprites) { + sprite = sprites; + } + + public Particle createParticle(SimpleParticleType type, ClientLevel level, double x, double y, double z, double xSpeed, double ySpeed, double zSpeed) { + VanillaDripParticle.AcidBubbleParticle particle = new VanillaDripParticle.AcidBubbleParticle(level, x, y, z, xSpeed, ySpeed, zSpeed); + particle.pickSprite(sprite); + return particle; + } + } } diff --git a/src/main/java/com/github/elenterius/biomancy/client/particle/VanillaDripParticle.java b/src/main/java/com/github/elenterius/biomancy/client/particle/VanillaDripParticle.java index cc330d292..d2ed45b5a 100644 --- a/src/main/java/com/github/elenterius/biomancy/client/particle/VanillaDripParticle.java +++ b/src/main/java/com/github/elenterius/biomancy/client/particle/VanillaDripParticle.java @@ -1,5 +1,6 @@ package com.github.elenterius.biomancy.client.particle; +import com.github.elenterius.biomancy.init.ModFluids; import net.minecraft.client.multiplayer.ClientLevel; import net.minecraft.client.particle.ParticleRenderType; import net.minecraft.client.particle.TextureSheetParticle; @@ -188,4 +189,40 @@ protected void postMoveUpdate() { } } + @OnlyIn(Dist.CLIENT) + protected static class AcidBubbleParticle extends TextureSheetParticle { //Almost an exact copy of the vanilla BubbleParticle because it can't be extended + AcidBubbleParticle(ClientLevel level, double x, double y, double z, double xSpeed, double ySpeed, double zSpeed) { + super(level, x, y, z); + this.setSize(0.02F, 0.02F); + this.quadSize *= this.random.nextFloat() * 0.6F + 0.2F; + this.xd = xSpeed * (double)0.2F + (Math.random() * 2.0D - 1.0D) * (double)0.02F; + this.yd = ySpeed * (double)0.2F + (Math.random() * 2.0D - 1.0D) * (double)0.02F; + this.zd = zSpeed * (double)0.2F + (Math.random() * 2.0D - 1.0D) * (double)0.02F; + this.lifetime = (int)(8.0D / (Math.random() * 0.8D + 0.2D)); + } + + public void tick() { + this.xo = this.x; + this.yo = this.y; + this.zo = this.z; + if (this.lifetime-- <= 0) { + this.remove(); + } else { + this.yd += 0.002D; + this.move(this.xd, this.yd, this.zd); + this.xd *= 0.85F; + this.yd *= 0.85F; + this.zd *= 0.85F; + if (!this.level.getFluidState(BlockPos.containing(this.x, this.y, this.z)).is(ModFluids.ACID.get())) { + this.remove(); + } + + } + } + + public ParticleRenderType getRenderType() { + return ParticleRenderType.PARTICLE_SHEET_OPAQUE; + } + } + } diff --git a/src/main/java/com/github/elenterius/biomancy/init/AcidInteractions.java b/src/main/java/com/github/elenterius/biomancy/init/AcidInteractions.java index 9c69235e5..3178f98e2 100644 --- a/src/main/java/com/github/elenterius/biomancy/init/AcidInteractions.java +++ b/src/main/java/com/github/elenterius/biomancy/init/AcidInteractions.java @@ -3,6 +3,7 @@ import com.github.elenterius.biomancy.block.digester.DigesterBlockEntity; import com.github.elenterius.biomancy.crafting.recipe.DigestingRecipe; import com.github.elenterius.biomancy.init.tags.ModBlockTags; +import com.github.elenterius.biomancy.init.tags.ModItemTags; import com.github.elenterius.biomancy.inventory.BehavioralInventory; import com.github.elenterius.biomancy.util.CombatUtil; import net.minecraft.core.Direction; @@ -10,6 +11,7 @@ import net.minecraft.core.dispenser.DefaultDispenseItemBehavior; import net.minecraft.core.particles.ParticleTypes; import net.minecraft.nbt.CompoundTag; +import net.minecraft.resources.ResourceLocation; import net.minecraft.sounds.SoundEvent; import net.minecraft.sounds.SoundEvents; import net.minecraft.sounds.SoundSource; @@ -32,7 +34,6 @@ import net.minecraft.world.level.gameevent.GameEvent; import net.minecraft.world.phys.Vec3; import net.minecraftforge.common.SoundActions; -import org.apache.commons.lang3.ArrayUtils; import org.jetbrains.annotations.Nullable; import java.util.Map; @@ -166,59 +167,85 @@ else if (livingEntity.tickCount % 10 == 0 && livingEntity.getRandom().nextFloat( } } - private static final String TIMER_KEY = "biomancy:digestion_timer"; - private static final float EFFICIENCY = 0.8f; - public static void tryDigest(ItemEntity itemEntity, boolean onClient) { - DigestingRecipe recipe = getDigestionRecipe(itemEntity); - if (!digestible(itemEntity,recipe)) return; - CompoundTag data = itemEntity.getPersistentData(); - if (data.contains(TIMER_KEY) && data.getInt(TIMER_KEY) < 10) { - data.putInt(TIMER_KEY, data.getInt(TIMER_KEY) + 1); - } else if (data.contains(TIMER_KEY) && data.getInt(TIMER_KEY) >= 10 && !onClient){ - digestIntoNutrientPasteStacks(itemEntity,recipe); - itemEntity.getPersistentData().remove(TIMER_KEY); - } else { - data.putInt(TIMER_KEY,1); + public static final class InWorldItemDigesting { + //NBT Tag keys + public static final String BASE_DATA_KEY = "biomancy:acid_digestion"; + public static final String TIMER_KEY = "timer"; + public static final String RECIPE_KEY = "recipe"; + //Balancing multiplier applied to the output of any found recipes. + public static final double EFFICIENCY = 0.8; + //How many times tryDigestSubmergedItem should be called on a digestible item before it is processed. + //This is not directly ticks, as submerged items are only actually processed every 10 ticks. + public static final int DELAY = 10; + + public static void tryDigestSubmergedItem(ItemEntity itemEntity) { + if (!digestible(itemEntity)) return; + ItemStack stack = itemEntity.getItem(); + CompoundTag entityData = itemEntity.getPersistentData(); + CompoundTag digestionData = getOrCreateDigestionData(entityData); + if (itemEntity.level().isClientSide && digestionData.getInt(TIMER_KEY) > 0) { + Vec3 pos = itemEntity.position(); + RandomSource random = itemEntity.level().getRandom(); + itemEntity.level().addParticle(ModParticleTypes.ACID_BUBBLE.get(),pos.x,pos.y,pos.z,random.nextGaussian()/100,Math.abs(random.nextGaussian()/50),random.nextGaussian()/100); + itemEntity.level().addParticle(ParticleTypes.SMOKE,pos.x,pos.y,pos.z,random.nextGaussian()/100,Math.abs(random.nextGaussian()/100),random.nextGaussian()/100); + return; + } + + if (itemEntity.getAge() % 10 != 0) return; //Only tick digestion every 10 ticks. + Optional optionalRecipe = getDigestionRecipe(itemEntity, stack, digestionData); + + if (optionalRecipe.isEmpty()) return; + if (optionalRecipe.get().getId() != ResourceLocation.tryParse(digestionData.getString(RECIPE_KEY))) { + digestionData.putString(RECIPE_KEY, optionalRecipe.get().getId().toString()); + } + + int currentDigestionTime = digestionData.getInt(TIMER_KEY); + if (currentDigestionTime < DELAY) { + digestionData.putInt(TIMER_KEY, currentDigestionTime + 1); + entityData.put(BASE_DATA_KEY,digestionData); + } else { + digestIntoNutrientPasteStacks(itemEntity, optionalRecipe.get()); + itemEntity.getPersistentData().remove(BASE_DATA_KEY); + } } - } - private static void digestIntoNutrientPasteStacks(ItemEntity itemEntity, DigestingRecipe recipe) { - BehavioralInventory tempInventory = BehavioralInventory.createServerContents(1,player->false,()->{}); - tempInventory.insertItemStack(itemEntity.getItem()); - ItemStack resultStack = recipe.assemble(tempInventory,itemEntity.level().registryAccess()); - int totalToOutput = (int)Math.floor(resultStack.getCount()*itemEntity.getItem().getCount()*EFFICIENCY); - if (totalToOutput > 64) totalToOutput = splitIntoStacks(itemEntity,totalToOutput); - itemEntity.setItem(new ItemStack(ModItems.NUTRIENT_PASTE.get(), totalToOutput)); - itemEntity.playSound(SoundEvents.PLAYER_BURP); - } + public static CompoundTag getOrCreateDigestionData(CompoundTag entityData) { + if (entityData.contains(BASE_DATA_KEY)) return entityData.getCompound(BASE_DATA_KEY); + return new CompoundTag(); + } - private static int splitIntoStacks(ItemEntity itemEntity, int numToSplit) { - Level level = itemEntity.level(); - while (numToSplit > 64) { - DefaultDispenseItemBehavior.spawnItem(level,new ItemStack(ModItems.NUTRIENT_PASTE.get(),64),1, Direction.UP, itemEntity.position()); - numToSplit -= 64; + public static void digestIntoNutrientPasteStacks(ItemEntity itemEntity, DigestingRecipe recipe) { + BehavioralInventory tempInventory = BehavioralInventory.createServerContents(1, player -> false, () -> {}); + tempInventory.insertItemStack(itemEntity.getItem()); + ItemStack resultStack = recipe.assemble(tempInventory, itemEntity.level().registryAccess()); + int totalToOutput = (int) Math.floor(resultStack.getCount() * itemEntity.getItem().getCount() * EFFICIENCY); + if (totalToOutput > 64) totalToOutput = splitIntoStacks(itemEntity, totalToOutput); + itemEntity.setItem(new ItemStack(ModItems.NUTRIENT_PASTE.get(), totalToOutput)); + itemEntity.playSound(SoundEvents.PLAYER_BURP); } - return numToSplit; - } + public static int splitIntoStacks(ItemEntity itemEntity, int numToSplit) { + Level level = itemEntity.level(); + while (numToSplit > 64) { + DefaultDispenseItemBehavior.spawnItem(level, new ItemStack(ModItems.NUTRIENT_PASTE.get(), 64), 1, Direction.UP, itemEntity.position()); + numToSplit -= 64; + } + return numToSplit; + } - @SuppressWarnings("RedundantIfStatement") - private static boolean digestible(ItemEntity itemEntity, @Nullable DigestingRecipe recipe) { - if (recipe == null) return false; - if (!itemEntity.isInFluidType(ModFluids.ACID_TYPE.get()) && !itemEntity.level().getBlockState(itemEntity.blockPosition()).is(ModBlocks.ACID_CAULDRON.get())) return false; - //Inside method to prevent missing registry object errors during init - Item[] blacklistedItems = {ModItems.NUTRIENT_PASTE.get(),ModItems.NUTRIENT_BAR.get(),ModItems.LIVING_FLESH.get()}; - if (ArrayUtils.contains(blacklistedItems,itemEntity.getItem().getItem())) return false; - return true; - } + @SuppressWarnings("RedundantIfStatement") //Let me write readable code please, thanks + public static boolean digestible(ItemEntity itemEntity) { + if (!itemEntity.isInFluidType(ModFluids.ACID_TYPE.get()) && !itemEntity.level().getBlockState(itemEntity.blockPosition()).is(ModBlocks.ACID_CAULDRON.get())) return false; + if (itemEntity.getItem().is(ModItemTags.CANNOT_BE_DIGESTED_IN_ACID)) return false; + return true; + } - private static DigestingRecipe cachedRecipe = null; - private static @Nullable DigestingRecipe getDigestionRecipe(ItemEntity itemEntity) { - if (cachedRecipe != null && cachedRecipe.getIngredient().test(itemEntity.getItem())) return cachedRecipe; - Optional foundRecipe = DigesterBlockEntity.RECIPE_TYPE.get().getRecipeForIngredient(itemEntity.level(), itemEntity.getItem()); - if (foundRecipe.isEmpty()) return null; - cachedRecipe = foundRecipe.get(); - return cachedRecipe; + private static Optional getDigestionRecipe(ItemEntity itemEntity, ItemStack stack, CompoundTag digestionData) { + Optional recipe = Optional.empty(); + ResourceLocation lastRecipeId = ResourceLocation.tryParse(digestionData.getString(RECIPE_KEY)); + if (lastRecipeId != null) recipe = DigesterBlockEntity.RECIPE_TYPE.get().getRecipeById(itemEntity.level(), lastRecipeId); + if (recipe.isEmpty()) recipe = DigesterBlockEntity.RECIPE_TYPE.get().getRecipeForIngredient(itemEntity.level(), stack); + return recipe; //If it's still empty, there's no recipe that matches the item stack. + } } - } diff --git a/src/main/java/com/github/elenterius/biomancy/init/client/ClientSetupHandler.java b/src/main/java/com/github/elenterius/biomancy/init/client/ClientSetupHandler.java index 5afebb12e..a8dea9893 100644 --- a/src/main/java/com/github/elenterius/biomancy/init/client/ClientSetupHandler.java +++ b/src/main/java/com/github/elenterius/biomancy/init/client/ClientSetupHandler.java @@ -149,6 +149,7 @@ public static void registerParticles(final RegisterParticleProvidersEvent event) event.registerSpriteSet(ModParticleTypes.LIGHT_GREEN_GLOW.get(), sprites -> new CustomGlowParticle.TwoColorProvider(sprites, 0x53ff53, 0x64e986)); event.registerSpriteSet(ModParticleTypes.HOSTILE.get(), CustomGlowParticle.GenericProvider::new); event.registerSpriteSet(ModParticleTypes.BIOHAZARD.get(), sprites -> new CustomGlowParticle.TwoColorProvider(sprites, 0xab274f, 0x7e2a43)); + event.registerSpriteSet(ModParticleTypes.ACID_BUBBLE.get(), ParticleProviders.AcidBubbleProvider::new); } @SubscribeEvent diff --git a/src/main/java/com/github/elenterius/biomancy/init/tags/ModItemTags.java b/src/main/java/com/github/elenterius/biomancy/init/tags/ModItemTags.java index 9afd06e5d..0a1be5cd5 100644 --- a/src/main/java/com/github/elenterius/biomancy/init/tags/ModItemTags.java +++ b/src/main/java/com/github/elenterius/biomancy/init/tags/ModItemTags.java @@ -19,6 +19,8 @@ public final class ModItemTags { public static final TagKey SUGARS = tag("sugars"); + public static final TagKey CANNOT_BE_DIGESTED_IN_ACID = tag("cannot_be_digested_in_acid"); + private ModItemTags() {} private static TagKey tag(String name) { diff --git a/src/main/java/com/github/elenterius/biomancy/mixin/ItemEntityMixin.java b/src/main/java/com/github/elenterius/biomancy/mixin/ItemEntityMixin.java index 8b4a261cb..b7437583d 100644 --- a/src/main/java/com/github/elenterius/biomancy/mixin/ItemEntityMixin.java +++ b/src/main/java/com/github/elenterius/biomancy/mixin/ItemEntityMixin.java @@ -1,10 +1,7 @@ package com.github.elenterius.biomancy.mixin; import com.github.elenterius.biomancy.init.AcidInteractions; -import com.github.elenterius.biomancy.init.ModParticleTypes; -import net.minecraft.util.RandomSource; import net.minecraft.world.entity.item.ItemEntity; -import net.minecraft.world.phys.Vec3; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; @@ -14,16 +11,8 @@ public abstract class ItemEntityMixin { @Inject(at=@At("TAIL"),method={"tick()V"}) private void onTick(CallbackInfo ci) { - ItemEntity self = (ItemEntity)((Object)this); //I hate casting like this on so many levels - if (self.isRemoved()) return; - boolean onClient = self.level().isClientSide(); - - if (onClient) { - Vec3 pos = self.position(); - RandomSource random = self.level().getRandom(); - self.level().addParticle(ModParticleTypes.ACID_BUBBLE.get(), pos.x + random.nextGaussian(), pos.y, pos.z + random.nextGaussian(), random.nextGaussian(), 0.1, random.nextGaussian()); - } - if (self.getAge() % 10 != 0) return; //Only fire once every 10 ticks - AcidInteractions.tryDigest(self,onClient); + ItemEntity itemEntity = (ItemEntity)((Object)this); //I hate casting like this on so many levels -Kd + if (itemEntity.isRemoved()) return; + AcidInteractions.InWorldItemDigesting.tryDigestSubmergedItem(itemEntity); } } \ No newline at end of file