diff --git a/src/main/java/de/ellpeck/naturesaura/InternalHooks.java b/src/main/java/de/ellpeck/naturesaura/InternalHooks.java index 4d78c35c..3086af5f 100644 --- a/src/main/java/de/ellpeck/naturesaura/InternalHooks.java +++ b/src/main/java/de/ellpeck/naturesaura/InternalHooks.java @@ -84,7 +84,7 @@ public class InternalHooks implements NaturesAuraAPI.IInternalHooks { Vec3d dir = new Vec3d(endX - startX, endY - startY, endZ - startZ); double length = dir.length(); if (length > 0) { - dir.normalize(); + dir = dir.normalize(); this.spawnMagicParticle(startX, startY, startZ, dir.x * speed, dir.y * speed, dir.z * speed, color, scale, (int) (length / speed), 0F, false, false); diff --git a/src/main/java/de/ellpeck/naturesaura/blocks/tiles/TileEntityFieldCreator.java b/src/main/java/de/ellpeck/naturesaura/blocks/tiles/TileEntityFieldCreator.java index e2b4e6a5..3456e327 100644 --- a/src/main/java/de/ellpeck/naturesaura/blocks/tiles/TileEntityFieldCreator.java +++ b/src/main/java/de/ellpeck/naturesaura/blocks/tiles/TileEntityFieldCreator.java @@ -10,22 +10,19 @@ import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.entity.item.ItemFrameEntity; import net.minecraft.item.ItemStack; -import net.minecraft.item.ShearsItem; +import net.minecraft.item.Items; import net.minecraft.nbt.CompoundNBT; import net.minecraft.tileentity.ITickableTileEntity; import net.minecraft.tileentity.TileEntity; -import net.minecraft.util.NonNullList; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.Vec3d; import net.minecraft.world.server.ServerWorld; import net.minecraft.world.storage.loot.LootContext; import net.minecraft.world.storage.loot.LootParameters; -import net.minecraftforge.common.IShearable; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.common.util.FakePlayer; import net.minecraftforge.common.util.FakePlayerFactory; -import net.minecraftforge.event.ForgeEventFactory; import net.minecraftforge.event.world.BlockEvent; import java.util.List; @@ -97,7 +94,7 @@ public class TileEntityFieldCreator extends TileEntityImpl implements ITickableT if (this.world.getGameTime() % 40 == 0) chunk.drainAura(spot, 100); - boolean shears = this.shears() || creator.shears(); + ItemStack tool = this.getToolUsed(creator); Vec3d dist = new Vec3d( this.pos.getX() - connectedPos.getX(), this.pos.getY() - connectedPos.getY(), @@ -105,7 +102,7 @@ public class TileEntityFieldCreator extends TileEntityImpl implements ITickableT ); double length = dist.length(); Vec3d normal = new Vec3d(dist.x / length, dist.y / length, dist.z / length); - for (int i = MathHelper.floor(length); i > 0; i--) { + for (float i = MathHelper.floor(length); i > 0; i -= 0.5F) { Vec3d scaled = normal.scale(i); BlockPos pos = connectedPos.add( MathHelper.floor(scaled.x + 0.5F), @@ -120,38 +117,38 @@ public class TileEntityFieldCreator extends TileEntityImpl implements ITickableT if (!block.isAir(state, this.world, pos) && state.getBlockHardness(this.world, pos) >= 0F) { FakePlayer fake = FakePlayerFactory.getMinecraft((ServerWorld) this.world); if (!MinecraftForge.EVENT_BUS.post(new BlockEvent.BreakEvent(this.world, pos, state, fake))) { - boolean shearBlock = shears && block instanceof IShearable; - List drops; - if (shearBlock && ((IShearable) block).isShearable(ItemStack.EMPTY, this.world, pos)) - drops = ((IShearable) block).onSheared(ItemStack.EMPTY, this.world, pos, 0); - else { - drops = state.getDrops(new LootContext.Builder((ServerWorld) this.world) - .withParameter(LootParameters.POSITION, pos) - .withParameter(LootParameters.BLOCK_STATE, state)); - } - float chance = ForgeEventFactory.fireBlockHarvesting((NonNullList) drops, this.world, pos, state, 0, 1, false, fake); - if (chance > 0 && this.world.rand.nextFloat() <= chance) { - this.world.destroyBlock(pos, false); - for (ItemStack stack : drops) - Block.spawnAsEntity(this.world, pos, stack); - - chunk.drainAura(spot, shearBlock ? 1000 : 300); - this.sendParticles(); - } + List drops = state.getDrops(new LootContext.Builder((ServerWorld) this.world) + .withParameter(LootParameters.POSITION, pos) + .withParameter(LootParameters.BLOCK_STATE, state) + .withParameter(LootParameters.TOOL, tool == null ? new ItemStack(Items.DIAMOND_PICKAXE) : tool) + .withNullableParameter(LootParameters.BLOCK_ENTITY, this.world.getTileEntity(pos))); + this.world.destroyBlock(pos, false); + for (ItemStack stack : drops) + Block.spawnAsEntity(this.world, pos, stack); + chunk.drainAura(spot, tool != null ? 1000 : 300); + this.sendParticles(); } } } } } - public boolean shears() { + private ItemStack getToolUsed(TileEntityFieldCreator other) { + ItemStack myTool = this.getMyTool(); + ItemStack otherTool = other.getMyTool(); + if (myTool != null && otherTool != null) + return this.world.rand.nextBoolean() ? myTool : otherTool; + return myTool; + } + + private ItemStack getMyTool() { List frames = Helper.getAttachedItemFrames(this.world, this.pos); for (ItemFrameEntity frame : frames) { ItemStack stack = frame.getDisplayedItem(); - if (!stack.isEmpty() && stack.getItem() instanceof ShearsItem) - return true; + if (!stack.isEmpty()) + return stack; } - return false; + return null; } private void sendParticles() { diff --git a/src/main/java/de/ellpeck/naturesaura/blocks/tiles/TileEntityFurnaceHeater.java b/src/main/java/de/ellpeck/naturesaura/blocks/tiles/TileEntityFurnaceHeater.java index 76893f4a..fc63cb1f 100644 --- a/src/main/java/de/ellpeck/naturesaura/blocks/tiles/TileEntityFurnaceHeater.java +++ b/src/main/java/de/ellpeck/naturesaura/blocks/tiles/TileEntityFurnaceHeater.java @@ -1,21 +1,29 @@ package de.ellpeck.naturesaura.blocks.tiles; +import de.ellpeck.naturesaura.Helper; +import de.ellpeck.naturesaura.NaturesAura; import de.ellpeck.naturesaura.api.aura.chunk.IAuraChunk; import de.ellpeck.naturesaura.api.aura.type.IAuraType; import de.ellpeck.naturesaura.blocks.BlockFurnaceHeater; import de.ellpeck.naturesaura.packet.PacketHandler; import de.ellpeck.naturesaura.packet.PacketParticleStream; +import net.minecraft.block.AbstractFurnaceBlock; import net.minecraft.item.ItemStack; +import net.minecraft.item.crafting.AbstractCookingRecipe; +import net.minecraft.item.crafting.IRecipeType; import net.minecraft.nbt.CompoundNBT; -import net.minecraft.tileentity.FurnaceTileEntity; -import net.minecraft.tileentity.ITickableTileEntity; -import net.minecraft.tileentity.TileEntity; -import net.minecraft.tileentity.TileEntityType; +import net.minecraft.tileentity.*; import net.minecraft.util.Direction; +import net.minecraft.util.IIntArray; import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; +import net.minecraftforge.fml.common.ObfuscationReflectionHelper; + +import java.lang.reflect.Field; public class TileEntityFurnaceHeater extends TileEntityImpl implements ITickableTileEntity { + private static final Field FURNACE_DATA_FIELD = ObfuscationReflectionHelper.findField(AbstractFurnaceTileEntity.class, "field_214013_b"); public boolean isActive; public TileEntityFurnaceHeater() { @@ -30,20 +38,29 @@ public class TileEntityFurnaceHeater extends TileEntityImpl implements ITickable Direction facing = this.world.getBlockState(this.pos).get(BlockFurnaceHeater.FACING); BlockPos tilePos = this.pos.offset(facing.getOpposite()); TileEntity tile = this.world.getTileEntity(tilePos); - if (tile instanceof FurnaceTileEntity) { - FurnaceTileEntity furnace = (FurnaceTileEntity) tile; - if (isReady(furnace)) { - // TODO furnace heater - /* int time = furnace.getField(0); - if (time <= 0) - FurnaceBlock.setState(true, this.world, furnace.getPos()); - furnace.setField(0, 200); + if (tile instanceof AbstractFurnaceTileEntity) { + AbstractFurnaceTileEntity furnace = (AbstractFurnaceTileEntity) tile; + if (this.isReady(furnace)) { + IIntArray data; + try { + data = (IIntArray) FURNACE_DATA_FIELD.get(furnace); + } catch (IllegalAccessException e) { + NaturesAura.LOGGER.fatal("Couldn't reflect furnace field", e); + return; + } + + int burnTime = data.get(0); + if (burnTime <= 0) + this.world.setBlockState(tilePos, this.world.getBlockState(tilePos).with(AbstractFurnaceBlock.LIT, true)); + + int totalCookTime = data.get(3); + data.set(0, totalCookTime); //if set higher than 199, it'll never finish because the furnace does ++ and then == - furnace.setField(2, Math.min(199, furnace.getField(2) + 5));*/ + data.set(2, Math.min(totalCookTime - 1, data.get(2) + 5)); BlockPos spot = IAuraChunk.getHighestSpot(this.world, this.pos, 20, this.pos); IAuraChunk chunk = IAuraChunk.getAuraChunk(this.world, spot); - //chunk.drainAura(spot, MathHelper.ceil((200 - time) * 16.6F)); + chunk.drainAura(spot, MathHelper.ceil((totalCookTime - burnTime) * 16.6F)); did = true; if (this.world.getGameTime() % 15 == 0) { @@ -67,23 +84,32 @@ public class TileEntityFurnaceHeater extends TileEntityImpl implements ITickable } } - private static boolean isReady(FurnaceTileEntity furnace) { + private boolean isReady(AbstractFurnaceTileEntity furnace) { if (!furnace.getStackInSlot(1).isEmpty()) return false; ItemStack input = furnace.getStackInSlot(0); if (!input.isEmpty()) { - /*ItemStack output = FurnaceRecipes.instance().getSmeltingResult(input); - if (output.isEmpty())*/ - return false; - - /*ItemStack currOutput = furnace.getStackInSlot(2); - return currOutput.isEmpty() || - Helper.areItemsEqual(currOutput, output, true) && currOutput.getCount() + output.getCount() <= output.getMaxStackSize();*/ + AbstractCookingRecipe recipe = this.world.getRecipeManager().getRecipe(getRecipeType(furnace), furnace, this.world).orElse(null); + if (recipe == null) + return false; + ItemStack output = recipe.getRecipeOutput(); + ItemStack currOutput = furnace.getStackInSlot(2); + return currOutput.isEmpty() || Helper.areItemsEqual(currOutput, output, true) && currOutput.getCount() + output.getCount() <= output.getMaxStackSize(); } else return false; } + private static IRecipeType getRecipeType(AbstractFurnaceTileEntity furnace) { + if (furnace instanceof BlastFurnaceTileEntity) { + return IRecipeType.BLASTING; + } else if (furnace instanceof SmokerTileEntity) { + return IRecipeType.SMOKING; + } else { + return IRecipeType.SMELTING; + } + } + @Override public void writeNBT(CompoundNBT compound, SaveType type) { super.writeNBT(compound, type); diff --git a/src/main/java/de/ellpeck/naturesaura/blocks/tiles/TileEntityPlacer.java b/src/main/java/de/ellpeck/naturesaura/blocks/tiles/TileEntityPlacer.java index ddcdd3ba..963638a9 100644 --- a/src/main/java/de/ellpeck/naturesaura/blocks/tiles/TileEntityPlacer.java +++ b/src/main/java/de/ellpeck/naturesaura/blocks/tiles/TileEntityPlacer.java @@ -9,12 +9,16 @@ import net.minecraft.block.BlockState; import net.minecraft.block.Blocks; import net.minecraft.entity.item.ItemFrameEntity; import net.minecraft.item.ItemStack; +import net.minecraft.item.ItemUseContext; import net.minecraft.tileentity.ITickableTileEntity; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.Direction; import net.minecraft.util.Hand; import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.BlockRayTraceResult; +import net.minecraft.util.math.Vec3d; import net.minecraft.world.server.ServerWorld; +import net.minecraftforge.common.ForgeHooks; import net.minecraftforge.common.util.FakePlayer; import net.minecraftforge.common.util.FakePlayerFactory; import net.minecraftforge.items.CapabilityItemHandler; @@ -110,7 +114,8 @@ public class TileEntityPlacer extends TileEntityImpl implements ITickableTileEnt FakePlayer fake = FakePlayerFactory.getMinecraft((ServerWorld) this.world); fake.inventory.mainInventory.set(fake.inventory.currentItem, stack); - fake.interactionManager.processRightClick(fake, this.world, fake.getHeldItemMainhand(), Hand.MAIN_HAND); + BlockRayTraceResult ray = new BlockRayTraceResult(new Vec3d(pos).add(0.5F, 0.5F, 0.5F), Direction.UP, pos, false); + ForgeHooks.onPlaceItemIntoWorld(new ItemUseContext(fake, Hand.MAIN_HAND, ray)); return fake.getHeldItemMainhand().copy(); } diff --git a/src/main/java/de/ellpeck/naturesaura/compat/jei/AltarCategory.java b/src/main/java/de/ellpeck/naturesaura/compat/jei/AltarCategory.java index 24d6f91b..b3ea17c6 100644 --- a/src/main/java/de/ellpeck/naturesaura/compat/jei/AltarCategory.java +++ b/src/main/java/de/ellpeck/naturesaura/compat/jei/AltarCategory.java @@ -1,8 +1,10 @@ package de.ellpeck.naturesaura.compat.jei; +import com.google.common.collect.ImmutableList; import de.ellpeck.naturesaura.NaturesAura; import de.ellpeck.naturesaura.api.recipes.AltarRecipe; import de.ellpeck.naturesaura.blocks.ModBlocks; +import mezz.jei.api.constants.VanillaTypes; import mezz.jei.api.gui.IRecipeLayout; import mezz.jei.api.gui.drawable.IDrawable; import mezz.jei.api.gui.ingredient.IGuiItemStackGroup; @@ -53,7 +55,12 @@ public class AltarCategory implements IRecipeCategory { @Override public void setIngredients(AltarRecipe altarRecipe, IIngredients iIngredients) { - + ImmutableList.Builder builder = ImmutableList.builder(); + builder.add(altarRecipe.input.getMatchingStacks()); + if (altarRecipe.catalyst != Ingredient.EMPTY) + builder.add(altarRecipe.catalyst.getMatchingStacks()); + iIngredients.setInputs(VanillaTypes.ITEM, builder.build()); + iIngredients.setOutput(VanillaTypes.ITEM, altarRecipe.output); } @Override diff --git a/src/main/java/de/ellpeck/naturesaura/compat/jei/AnimalSpawnerCategory.java b/src/main/java/de/ellpeck/naturesaura/compat/jei/AnimalSpawnerCategory.java index e26ef42e..4e9345b7 100644 --- a/src/main/java/de/ellpeck/naturesaura/compat/jei/AnimalSpawnerCategory.java +++ b/src/main/java/de/ellpeck/naturesaura/compat/jei/AnimalSpawnerCategory.java @@ -1,7 +1,9 @@ package de.ellpeck.naturesaura.compat.jei; +import com.google.common.collect.ImmutableList; import de.ellpeck.naturesaura.NaturesAura; import de.ellpeck.naturesaura.api.recipes.AnimalSpawnerRecipe; +import mezz.jei.api.constants.VanillaTypes; import mezz.jei.api.gui.IRecipeLayout; import mezz.jei.api.gui.drawable.IDrawable; import mezz.jei.api.gui.ingredient.IGuiItemStackGroup; @@ -9,7 +11,12 @@ import mezz.jei.api.helpers.IGuiHelper; import mezz.jei.api.ingredients.IIngredients; import mezz.jei.api.recipe.category.IRecipeCategory; import net.minecraft.client.resources.I18n; +import net.minecraft.entity.EntityType; +import net.minecraft.item.ItemStack; +import net.minecraft.item.SpawnEggItem; +import net.minecraft.item.crafting.Ingredient; import net.minecraft.util.ResourceLocation; +import net.minecraftforge.registries.ForgeRegistries; import java.util.Arrays; @@ -48,7 +55,13 @@ public class AnimalSpawnerCategory implements IRecipeCategory builder = ImmutableList.builder(); + for (Ingredient ing : animalSpawnerRecipe.ingredients) + builder.add(ing.getMatchingStacks()); + iIngredients.setInputs(VanillaTypes.ITEM, builder.build()); + EntityType entry = ForgeRegistries.ENTITIES.getValue(animalSpawnerRecipe.entity); + iIngredients.setOutput(VanillaTypes.ITEM, new ItemStack(SpawnEggItem.getEgg(entry))); } @Override diff --git a/src/main/java/de/ellpeck/naturesaura/compat/jei/OfferingCategory.java b/src/main/java/de/ellpeck/naturesaura/compat/jei/OfferingCategory.java index c7611927..7a2942b4 100644 --- a/src/main/java/de/ellpeck/naturesaura/compat/jei/OfferingCategory.java +++ b/src/main/java/de/ellpeck/naturesaura/compat/jei/OfferingCategory.java @@ -1,8 +1,9 @@ package de.ellpeck.naturesaura.compat.jei; +import com.google.common.collect.ImmutableList; import de.ellpeck.naturesaura.NaturesAura; import de.ellpeck.naturesaura.api.recipes.OfferingRecipe; -import de.ellpeck.naturesaura.compat.jei.JEINaturesAuraPlugin; +import mezz.jei.api.constants.VanillaTypes; import mezz.jei.api.gui.IRecipeLayout; import mezz.jei.api.gui.drawable.IDrawable; import mezz.jei.api.gui.ingredient.IGuiItemStackGroup; @@ -10,6 +11,7 @@ import mezz.jei.api.helpers.IGuiHelper; import mezz.jei.api.ingredients.IIngredients; import mezz.jei.api.recipe.category.IRecipeCategory; import net.minecraft.client.resources.I18n; +import net.minecraft.item.ItemStack; import net.minecraft.util.ResourceLocation; import java.util.Arrays; @@ -49,7 +51,10 @@ public class OfferingCategory implements IRecipeCategory { @Override public void setIngredients(OfferingRecipe offeringRecipe, IIngredients iIngredients) { - + iIngredients.setInputs(VanillaTypes.ITEM, ImmutableList.builder() + .add(offeringRecipe.input.getMatchingStacks()) + .add(offeringRecipe.startItem.getMatchingStacks()).build()); + iIngredients.setOutput(VanillaTypes.ITEM, offeringRecipe.output); } @Override diff --git a/src/main/java/de/ellpeck/naturesaura/compat/jei/TreeRitualCategory.java b/src/main/java/de/ellpeck/naturesaura/compat/jei/TreeRitualCategory.java index ad82aa1b..a6d1c476 100644 --- a/src/main/java/de/ellpeck/naturesaura/compat/jei/TreeRitualCategory.java +++ b/src/main/java/de/ellpeck/naturesaura/compat/jei/TreeRitualCategory.java @@ -1,8 +1,9 @@ package de.ellpeck.naturesaura.compat.jei; +import com.google.common.collect.ImmutableList; import de.ellpeck.naturesaura.NaturesAura; import de.ellpeck.naturesaura.api.recipes.TreeRitualRecipe; -import de.ellpeck.naturesaura.compat.jei.JEINaturesAuraPlugin; +import mezz.jei.api.constants.VanillaTypes; import mezz.jei.api.gui.IRecipeLayout; import mezz.jei.api.gui.drawable.IDrawable; import mezz.jei.api.gui.ingredient.IGuiItemStackGroup; @@ -10,6 +11,8 @@ import mezz.jei.api.helpers.IGuiHelper; import mezz.jei.api.ingredients.IIngredients; import mezz.jei.api.recipe.category.IRecipeCategory; import net.minecraft.client.resources.I18n; +import net.minecraft.item.ItemStack; +import net.minecraft.item.crafting.Ingredient; import net.minecraft.util.ResourceLocation; import java.util.Arrays; @@ -49,7 +52,12 @@ public class TreeRitualCategory implements IRecipeCategory { @Override public void setIngredients(TreeRitualRecipe treeRitualRecipe, IIngredients iIngredients) { - + ImmutableList.Builder builder = ImmutableList.builder(); + for (Ingredient ing : treeRitualRecipe.ingredients) + builder.add(ing.getMatchingStacks()); + builder.add(treeRitualRecipe.saplingType.getMatchingStacks()); + iIngredients.setInputs(VanillaTypes.ITEM, builder.build()); + iIngredients.setOutput(VanillaTypes.ITEM, treeRitualRecipe.result); } @Override diff --git a/src/main/java/de/ellpeck/naturesaura/entities/EntityEffectInhibitor.java b/src/main/java/de/ellpeck/naturesaura/entities/EntityEffectInhibitor.java index 49df8612..3d83c28e 100644 --- a/src/main/java/de/ellpeck/naturesaura/entities/EntityEffectInhibitor.java +++ b/src/main/java/de/ellpeck/naturesaura/entities/EntityEffectInhibitor.java @@ -2,7 +2,6 @@ package de.ellpeck.naturesaura.entities; import com.google.common.collect.ListMultimap; import de.ellpeck.naturesaura.Helper; -import de.ellpeck.naturesaura.NaturesAura; import de.ellpeck.naturesaura.api.NaturesAuraAPI; import de.ellpeck.naturesaura.api.misc.IWorldData; import de.ellpeck.naturesaura.api.render.IVisualizable; @@ -112,7 +111,7 @@ public class EntityEffectInhibitor extends Entity implements IVisualizable { super.tick(); if (this.world.isRemote) { if (this.world.getGameTime() % 5 == 0) { - NaturesAura.proxy.spawnMagicParticle( + NaturesAuraAPI.instance().spawnMagicParticle( this.posX + this.world.rand.nextGaussian() * 0.1F, this.posY, this.posZ + this.world.rand.nextGaussian() * 0.1F, diff --git a/src/main/resources/assets/naturesaura/lang/en_us.json b/src/main/resources/assets/naturesaura/lang/en_us.json index fbaa0b25..8ffd61bc 100644 --- a/src/main/resources/assets/naturesaura/lang/en_us.json +++ b/src/main/resources/assets/naturesaura/lang/en_us.json @@ -100,10 +100,10 @@ "item.naturesaura.ender_access": "Ender Ocular", "item.naturesaura.cave_finder": "Staff of Shadows", "item.naturesaura.aura_trove": "Aura Trove", - "container.naturesaura.tree_ritual": "Ritual of the Forest", - "container.naturesaura.altar": "Natural Altar Infusion", - "container.naturesaura.offering": "Offering to the Gods", - "container.naturesaura.animal_spawner": "Altar of Birthing", + "container.naturesaura:tree_ritual.name": "Ritual of the Forest", + "container.naturesaura:altar.name": "Natural Altar Infusion", + "container.naturesaura:offering.name": "Offering to the Gods", + "container.naturesaura:animal_spawner.name": "Altar of Birthing", "info.naturesaura.aura_in_area": "Aura Around", "info.naturesaura.book.landing": "$(aura) is a complicated matter, and creating, collecting and making use of it can be difficult.$(br)The $(item)Book of Natural Aura$() contains all the information one requires to do so.", "info.naturesaura.book.subtitle": "The guide to Nature's Aura",