Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat: Bulk Digestion in Gastric Acid #150

Merged
Original file line number Diff line number Diff line change
@@ -1,16 +1,23 @@
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;
import net.minecraft.stats.Stats;
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;
Expand All @@ -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 {

Expand Down Expand Up @@ -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()};
kd8lvt marked this conversation as resolved.
Show resolved Hide resolved
if (ArrayUtils.contains(blacklistedItems,itemEntity.getItem().getItem())) return false;
return true;
}

private static DigestingRecipe cachedRecipe = null;
kd8lvt marked this conversation as resolved.
Show resolved Hide resolved
private static @Nullable DigestingRecipe getDigestionRecipe(ItemEntity itemEntity) {
if (cachedRecipe != null && cachedRecipe.getIngredient().test(itemEntity.getItem())) return cachedRecipe;
Optional<DigestingRecipe> foundRecipe = DigesterBlockEntity.RECIPE_TYPE.get().getRecipeForIngredient(itemEntity.level(), itemEntity.getItem());
if (foundRecipe.isEmpty()) return null;
cachedRecipe = foundRecipe.get();
return cachedRecipe;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ public final class ModParticleTypes {
public static final RegistryObject<SimpleParticleType> LIGHT_GREEN_GLOW = register("light_green_glow", false);
public static final RegistryObject<SimpleParticleType> HOSTILE = register("hostile", false);
public static final RegistryObject<SimpleParticleType> BIOHAZARD = register("biohazard", false);
public static final RegistryObject<SimpleParticleType> ACID_BUBBLE = register("acid_bubble", false);

private ModParticleTypes() {}

Expand Down
Original file line number Diff line number Diff line change
@@ -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);
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
53 changes: 45 additions & 8 deletions src/main/resources/mixins.biomancy.json
Original file line number Diff line number Diff line change
Expand Up @@ -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": [ ]
Expand Down