mirror of
https://github.com/Ellpeck/NaturesAura.git
synced 2024-11-22 19:58:34 +01:00
change to Patchouli multiblocks and add visualization
This commit is contained in:
parent
7225e7801a
commit
5462d101a1
12 changed files with 209 additions and 282 deletions
|
@ -46,16 +46,6 @@ public final class Helper {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean checkMultiblock(World world, BlockPos pos, BlockPos[] positions, IBlockState state, boolean blockOnly) {
|
|
||||||
for (BlockPos offset : positions) {
|
|
||||||
IBlockState current = world.getBlockState(pos.add(offset));
|
|
||||||
if (blockOnly ? current.getBlock() != state.getBlock() : current != state) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@SideOnly(Side.CLIENT)
|
@SideOnly(Side.CLIENT)
|
||||||
public static int blendColors(int c1, int c2, float ratio) {
|
public static int blendColors(int c1, int c2, float ratio) {
|
||||||
int a = (int) ((c1 >> 24 & 0xFF) * ratio + (c2 >> 24 & 0xFF) * (1 - ratio));
|
int a = (int) ((c1 >> 24 & 0xFF) * ratio + (c2 >> 24 & 0xFF) * (1 - ratio));
|
||||||
|
|
|
@ -7,6 +7,7 @@ import de.ellpeck.naturesaura.aura.chunk.AuraChunk;
|
||||||
import de.ellpeck.naturesaura.aura.container.IAuraContainer;
|
import de.ellpeck.naturesaura.aura.container.IAuraContainer;
|
||||||
import de.ellpeck.naturesaura.aura.item.IAuraRecharge;
|
import de.ellpeck.naturesaura.aura.item.IAuraRecharge;
|
||||||
import de.ellpeck.naturesaura.blocks.ModBlocks;
|
import de.ellpeck.naturesaura.blocks.ModBlocks;
|
||||||
|
import de.ellpeck.naturesaura.blocks.Multiblocks;
|
||||||
import de.ellpeck.naturesaura.commands.CommandAura;
|
import de.ellpeck.naturesaura.commands.CommandAura;
|
||||||
import de.ellpeck.naturesaura.compat.Compat;
|
import de.ellpeck.naturesaura.compat.Compat;
|
||||||
import de.ellpeck.naturesaura.events.CommonEvents;
|
import de.ellpeck.naturesaura.events.CommonEvents;
|
||||||
|
@ -63,6 +64,7 @@ public final class NaturesAura {
|
||||||
Compat.init();
|
Compat.init();
|
||||||
PacketHandler.init();
|
PacketHandler.init();
|
||||||
ModRegistry.preInit(event);
|
ModRegistry.preInit(event);
|
||||||
|
new Multiblocks();
|
||||||
|
|
||||||
MinecraftForge.TERRAIN_GEN_BUS.register(new TerrainGenEvents());
|
MinecraftForge.TERRAIN_GEN_BUS.register(new TerrainGenEvents());
|
||||||
MinecraftForge.EVENT_BUS.register(new CommonEvents());
|
MinecraftForge.EVENT_BUS.register(new CommonEvents());
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
package de.ellpeck.naturesaura.blocks;
|
package de.ellpeck.naturesaura.blocks;
|
||||||
|
|
||||||
import de.ellpeck.naturesaura.Helper;
|
|
||||||
import de.ellpeck.naturesaura.NaturesAura;
|
import de.ellpeck.naturesaura.NaturesAura;
|
||||||
import de.ellpeck.naturesaura.blocks.tiles.TileEntityWoodStand;
|
|
||||||
import de.ellpeck.naturesaura.reg.IColorProvidingBlock;
|
import de.ellpeck.naturesaura.reg.IColorProvidingBlock;
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
import net.minecraft.block.SoundType;
|
import net.minecraft.block.SoundType;
|
||||||
|
@ -16,6 +14,7 @@ import net.minecraft.init.Blocks;
|
||||||
import net.minecraft.util.BlockRenderLayer;
|
import net.minecraft.util.BlockRenderLayer;
|
||||||
import net.minecraft.util.EnumFacing;
|
import net.minecraft.util.EnumFacing;
|
||||||
import net.minecraft.util.IStringSerializable;
|
import net.minecraft.util.IStringSerializable;
|
||||||
|
import net.minecraft.util.Rotation;
|
||||||
import net.minecraft.util.math.AxisAlignedBB;
|
import net.minecraft.util.math.AxisAlignedBB;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.world.IBlockAccess;
|
import net.minecraft.world.IBlockAccess;
|
||||||
|
@ -57,25 +56,6 @@ public class BlockGoldPowder extends BlockImpl implements IColorProvidingBlock {
|
||||||
this.setHardness(0F);
|
this.setHardness(0F);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void randomDisplayTick(IBlockState stateIn, World worldIn, BlockPos pos, Random rand) {
|
|
||||||
if (rand.nextFloat() >= 0.9F) {
|
|
||||||
for (BlockPos offsetToOrigin : TileEntityWoodStand.GOLD_POWDER_POSITIONS) {
|
|
||||||
BlockPos origin = pos.subtract(offsetToOrigin);
|
|
||||||
if (Helper.checkMultiblock(worldIn, origin, TileEntityWoodStand.GOLD_POWDER_POSITIONS, ModBlocks.GOLD_POWDER.getDefaultState(), true)) {
|
|
||||||
AxisAlignedBB box = this.getBoundingBox(stateIn, worldIn, pos);
|
|
||||||
NaturesAura.proxy.spawnMagicParticle(worldIn,
|
|
||||||
pos.getX() + box.minX + (box.maxX - box.minX) * rand.nextFloat(),
|
|
||||||
pos.getY() + 0.05F,
|
|
||||||
pos.getZ() + box.minZ + (box.maxZ - box.minZ) * rand.nextFloat(),
|
|
||||||
rand.nextGaussian() * 0.001, rand.nextFloat() * 0.001 + 0.005, rand.nextGaussian() * 0.001,
|
|
||||||
0xf4cb42, 1F, 50, 0F, false, true);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected BlockStateContainer createBlockState() {
|
protected BlockStateContainer createBlockState() {
|
||||||
return new BlockStateContainer(this, NORTH, EAST, SOUTH, WEST);
|
return new BlockStateContainer(this, NORTH, EAST, SOUTH, WEST);
|
||||||
|
|
64
src/main/java/de/ellpeck/naturesaura/blocks/Multiblocks.java
Normal file
64
src/main/java/de/ellpeck/naturesaura/blocks/Multiblocks.java
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
package de.ellpeck.naturesaura.blocks;
|
||||||
|
|
||||||
|
import de.ellpeck.naturesaura.NaturesAura;
|
||||||
|
import net.minecraft.block.Block;
|
||||||
|
import net.minecraft.block.BlockLog;
|
||||||
|
import net.minecraft.block.BlockSapling;
|
||||||
|
import net.minecraft.block.BlockStoneBrick;
|
||||||
|
import net.minecraft.block.BlockStoneBrick.EnumType;
|
||||||
|
import net.minecraft.init.Blocks;
|
||||||
|
import net.minecraft.util.ResourceLocation;
|
||||||
|
import net.minecraft.util.Rotation;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
import vazkii.patchouli.common.multiblock.Multiblock;
|
||||||
|
import vazkii.patchouli.common.multiblock.Multiblock.StateMatcher;
|
||||||
|
import vazkii.patchouli.common.multiblock.MultiblockRegistry;
|
||||||
|
|
||||||
|
public final class Multiblocks {
|
||||||
|
|
||||||
|
public static final Multiblock ALTAR = MultiblockRegistry.registerMultiblock(
|
||||||
|
new ResourceLocation(NaturesAura.MOD_ID, "altar"),
|
||||||
|
new Multiblock(new String[][]{
|
||||||
|
{" M ", " ", " ", " ", "M M", " ", " ", " ", " M "},
|
||||||
|
{" B ", " ", " ", " ", "B B", " ", " ", " ", " B "},
|
||||||
|
{" B ", " ", " M M ", " ", "B 0 B", " ", " M M ", " ", " B "},
|
||||||
|
{" ", " WBW ", " WBW ", " WWCWCWW ", " BBW WBB ", " WWCWCWW ", " WBW ", " WBW ", " "}},
|
||||||
|
'C', Blocks.STONEBRICK.getDefaultState().withProperty(BlockStoneBrick.VARIANT, EnumType.CHISELED),
|
||||||
|
'B', Blocks.STONEBRICK.getDefaultState(),
|
||||||
|
'W', Blocks.PLANKS,
|
||||||
|
'M', Blocks.STONEBRICK.getDefaultState().withProperty(BlockStoneBrick.VARIANT, EnumType.MOSSY),
|
||||||
|
'0', ModBlocks.NATURE_ALTAR,
|
||||||
|
' ', StateMatcher.ANY)
|
||||||
|
).setSymmetrical(true);
|
||||||
|
public static final Multiblock TREE_RITUAL = MultiblockRegistry.registerMultiblock(
|
||||||
|
new ResourceLocation(NaturesAura.MOD_ID, "tree_ritual"),
|
||||||
|
new Multiblock(new String[][]{
|
||||||
|
{" W ", " W W ", " GGG ", " GG GG ", "W G 0 G W", " GG GG ", " GGG ", " W W ", " W "}},
|
||||||
|
'W', ModBlocks.WOOD_STAND,
|
||||||
|
'G', ModBlocks.GOLD_POWDER,
|
||||||
|
'0', StateMatcher.fromPredicate(Blocks.SAPLING, state -> state.getBlock() instanceof BlockSapling || state.getBlock() instanceof BlockLog),
|
||||||
|
' ', StateMatcher.ANY)
|
||||||
|
).setSymmetrical(true);
|
||||||
|
|
||||||
|
public static boolean validateLoosely(Multiblock mb, World world, BlockPos pos, Block ignored) {
|
||||||
|
return validateLoosely(mb, pos,
|
||||||
|
(start, x, y, z, matcher) -> matcher.displayState.getBlock() == ignored || mb.test(world, start, x, y, z, Rotation.NONE));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean validateLoosely(Multiblock mb, BlockPos pos, LooseValidator validator) {
|
||||||
|
BlockPos start = pos.add(-mb.offX, -mb.offY, -mb.offZ);
|
||||||
|
for (int x = 0; x < mb.sizeX; x++)
|
||||||
|
for (int y = 0; y < mb.sizeY; y++)
|
||||||
|
for (int z = 0; z < mb.sizeZ; z++) {
|
||||||
|
if (!validator.works(start, x, y, z, mb.stateTargets[x][y][z])) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private interface LooseValidator {
|
||||||
|
boolean works(BlockPos start, int x, int y, int z, StateMatcher matcher);
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,14 +6,12 @@ import de.ellpeck.naturesaura.aura.Capabilities;
|
||||||
import de.ellpeck.naturesaura.aura.chunk.AuraChunk;
|
import de.ellpeck.naturesaura.aura.chunk.AuraChunk;
|
||||||
import de.ellpeck.naturesaura.aura.container.BasicAuraContainer;
|
import de.ellpeck.naturesaura.aura.container.BasicAuraContainer;
|
||||||
import de.ellpeck.naturesaura.aura.container.IAuraContainer;
|
import de.ellpeck.naturesaura.aura.container.IAuraContainer;
|
||||||
|
import de.ellpeck.naturesaura.blocks.Multiblocks;
|
||||||
import de.ellpeck.naturesaura.packet.PacketHandler;
|
import de.ellpeck.naturesaura.packet.PacketHandler;
|
||||||
import de.ellpeck.naturesaura.packet.PacketParticleStream;
|
import de.ellpeck.naturesaura.packet.PacketParticleStream;
|
||||||
import de.ellpeck.naturesaura.packet.PacketParticles;
|
import de.ellpeck.naturesaura.packet.PacketParticles;
|
||||||
import de.ellpeck.naturesaura.recipes.AltarRecipe;
|
import de.ellpeck.naturesaura.recipes.AltarRecipe;
|
||||||
import net.minecraft.block.BlockStoneBrick;
|
|
||||||
import net.minecraft.block.BlockStoneBrick.EnumType;
|
|
||||||
import net.minecraft.block.state.IBlockState;
|
import net.minecraft.block.state.IBlockState;
|
||||||
import net.minecraft.init.Blocks;
|
|
||||||
import net.minecraft.init.SoundEvents;
|
import net.minecraft.init.SoundEvents;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.nbt.NBTTagCompound;
|
import net.minecraft.nbt.NBTTagCompound;
|
||||||
|
@ -29,71 +27,6 @@ import java.util.Random;
|
||||||
|
|
||||||
public class TileEntityNatureAltar extends TileEntityImpl implements ITickable {
|
public class TileEntityNatureAltar extends TileEntityImpl implements ITickable {
|
||||||
|
|
||||||
private static final BlockPos[] BRICK_POSITIONS = new BlockPos[]{
|
|
||||||
new BlockPos(-2, -1, 0),
|
|
||||||
new BlockPos(-3, -1, 0),
|
|
||||||
new BlockPos(-4, 0, 0),
|
|
||||||
new BlockPos(-4, 1, 0),
|
|
||||||
|
|
||||||
new BlockPos(2, -1, 0),
|
|
||||||
new BlockPos(3, -1, 0),
|
|
||||||
new BlockPos(4, 0, 0),
|
|
||||||
new BlockPos(4, 1, 0),
|
|
||||||
|
|
||||||
new BlockPos(0, -1, -2),
|
|
||||||
new BlockPos(0, -1, -3),
|
|
||||||
new BlockPos(0, 0, -4),
|
|
||||||
new BlockPos(0, 1, -4),
|
|
||||||
|
|
||||||
new BlockPos(0, -1, 2),
|
|
||||||
new BlockPos(0, -1, 3),
|
|
||||||
new BlockPos(0, 0, 4),
|
|
||||||
new BlockPos(0, 1, 4)
|
|
||||||
};
|
|
||||||
private static final BlockPos[] MOSSY_POSITIONS = new BlockPos[]{
|
|
||||||
new BlockPos(-4, 2, 0),
|
|
||||||
new BlockPos(4, 2, 0),
|
|
||||||
new BlockPos(0, 2, -4),
|
|
||||||
new BlockPos(0, 2, 4),
|
|
||||||
|
|
||||||
new BlockPos(-2, 0, -2),
|
|
||||||
new BlockPos(2, 0, -2),
|
|
||||||
new BlockPos(2, 0, 2),
|
|
||||||
new BlockPos(-2, 0, 2)
|
|
||||||
};
|
|
||||||
private static final BlockPos[] CHISELED_POSITIONS = new BlockPos[]{
|
|
||||||
new BlockPos(1, -1, 1),
|
|
||||||
new BlockPos(-1, -1, 1),
|
|
||||||
new BlockPos(-1, -1, -1),
|
|
||||||
new BlockPos(1, -1, -1)
|
|
||||||
};
|
|
||||||
private static final BlockPos[] WOOD_POSITIONS = new BlockPos[]{
|
|
||||||
new BlockPos(-1, -1, 0),
|
|
||||||
new BlockPos(1, -1, 0),
|
|
||||||
new BlockPos(0, -1, -1),
|
|
||||||
new BlockPos(0, -1, 1),
|
|
||||||
|
|
||||||
new BlockPos(-2, -1, -1),
|
|
||||||
new BlockPos(-3, -1, -1),
|
|
||||||
new BlockPos(-2, -1, 1),
|
|
||||||
new BlockPos(-3, -1, 1),
|
|
||||||
|
|
||||||
new BlockPos(2, -1, -1),
|
|
||||||
new BlockPos(3, -1, -1),
|
|
||||||
new BlockPos(2, -1, 1),
|
|
||||||
new BlockPos(3, -1, 1),
|
|
||||||
|
|
||||||
new BlockPos(-1, -1, -2),
|
|
||||||
new BlockPos(-1, -1, -3),
|
|
||||||
new BlockPos(1, -1, -2),
|
|
||||||
new BlockPos(1, -1, -3),
|
|
||||||
|
|
||||||
new BlockPos(-1, -1, 2),
|
|
||||||
new BlockPos(-1, -1, 3),
|
|
||||||
new BlockPos(1, -1, 2),
|
|
||||||
new BlockPos(1, -1, 3),
|
|
||||||
};
|
|
||||||
|
|
||||||
public final ItemStackHandler items = new ItemStackHandlerNA(1, this, true) {
|
public final ItemStackHandler items = new ItemStackHandlerNA(1, this, true) {
|
||||||
@Override
|
@Override
|
||||||
public int getSlotLimit(int slot) {
|
public int getSlotLimit(int slot) {
|
||||||
|
@ -125,10 +58,7 @@ public class TileEntityNatureAltar extends TileEntityImpl implements ITickable {
|
||||||
|
|
||||||
if (!this.world.isRemote) {
|
if (!this.world.isRemote) {
|
||||||
if (this.world.getTotalWorldTime() % 40 == 0) {
|
if (this.world.getTotalWorldTime() % 40 == 0) {
|
||||||
boolean fine = this.check(BRICK_POSITIONS, Blocks.STONEBRICK.getDefaultState(), false)
|
boolean fine = Multiblocks.ALTAR.validate(this.world, this.pos);
|
||||||
&& this.check(MOSSY_POSITIONS, Blocks.STONEBRICK.getDefaultState().withProperty(BlockStoneBrick.VARIANT, EnumType.MOSSY), false)
|
|
||||||
&& this.check(CHISELED_POSITIONS, Blocks.STONEBRICK.getDefaultState().withProperty(BlockStoneBrick.VARIANT, EnumType.CHISELED), false)
|
|
||||||
&& this.check(WOOD_POSITIONS, Blocks.PLANKS.getDefaultState(), true);
|
|
||||||
if (fine != this.structureFine) {
|
if (fine != this.structureFine) {
|
||||||
this.structureFine = fine;
|
this.structureFine = fine;
|
||||||
this.sendToClients();
|
this.sendToClients();
|
||||||
|
@ -238,10 +168,6 @@ public class TileEntityNatureAltar extends TileEntityImpl implements ITickable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean check(BlockPos[] positions, IBlockState state, boolean blockOnly) {
|
|
||||||
return Helper.checkMultiblock(this.world, this.pos, positions, state, blockOnly);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void writeNBT(NBTTagCompound compound, boolean syncing) {
|
public void writeNBT(NBTTagCompound compound, boolean syncing) {
|
||||||
super.writeNBT(compound, syncing);
|
super.writeNBT(compound, syncing);
|
||||||
|
|
|
@ -2,50 +2,31 @@ package de.ellpeck.naturesaura.blocks.tiles;
|
||||||
|
|
||||||
import de.ellpeck.naturesaura.Helper;
|
import de.ellpeck.naturesaura.Helper;
|
||||||
import de.ellpeck.naturesaura.blocks.ModBlocks;
|
import de.ellpeck.naturesaura.blocks.ModBlocks;
|
||||||
|
import de.ellpeck.naturesaura.blocks.Multiblocks;
|
||||||
import de.ellpeck.naturesaura.packet.PacketHandler;
|
import de.ellpeck.naturesaura.packet.PacketHandler;
|
||||||
import de.ellpeck.naturesaura.packet.PacketParticleStream;
|
import de.ellpeck.naturesaura.packet.PacketParticleStream;
|
||||||
import de.ellpeck.naturesaura.packet.PacketParticles;
|
import de.ellpeck.naturesaura.packet.PacketParticles;
|
||||||
|
import de.ellpeck.naturesaura.recipes.TreeRitualRecipe;
|
||||||
import net.minecraft.block.BlockLeaves;
|
import net.minecraft.block.BlockLeaves;
|
||||||
import net.minecraft.block.BlockLog;
|
import net.minecraft.block.BlockLog;
|
||||||
import net.minecraft.block.state.IBlockState;
|
import net.minecraft.block.state.IBlockState;
|
||||||
import net.minecraft.entity.item.EntityItem;
|
import net.minecraft.entity.item.EntityItem;
|
||||||
import net.minecraft.init.SoundEvents;
|
import net.minecraft.init.SoundEvents;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.nbt.NBTBase;
|
|
||||||
import net.minecraft.nbt.NBTTagCompound;
|
import net.minecraft.nbt.NBTTagCompound;
|
||||||
import net.minecraft.nbt.NBTTagList;
|
|
||||||
import net.minecraft.tileentity.TileEntity;
|
import net.minecraft.tileentity.TileEntity;
|
||||||
import net.minecraft.util.EnumFacing;
|
import net.minecraft.util.*;
|
||||||
import net.minecraft.util.ITickable;
|
|
||||||
import net.minecraft.util.SoundCategory;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraftforge.items.IItemHandlerModifiable;
|
import net.minecraftforge.items.IItemHandlerModifiable;
|
||||||
import net.minecraftforge.items.ItemStackHandler;
|
import net.minecraftforge.items.ItemStackHandler;
|
||||||
|
import org.apache.commons.lang3.mutable.MutableBoolean;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.ArrayList;
|
||||||
import java.util.Map;
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public class TileEntityWoodStand extends TileEntityImpl implements ITickable {
|
public class TileEntityWoodStand extends TileEntityImpl implements ITickable {
|
||||||
|
|
||||||
public static final BlockPos[] GOLD_POWDER_POSITIONS = new BlockPos[]{
|
|
||||||
new BlockPos(-2, 0, 0),
|
|
||||||
new BlockPos(2, 0, 0),
|
|
||||||
new BlockPos(0, 0, -2),
|
|
||||||
new BlockPos(0, 0, 2),
|
|
||||||
new BlockPos(-1, 0, -1),
|
|
||||||
new BlockPos(-1, 0, 1),
|
|
||||||
new BlockPos(1, 0, 1),
|
|
||||||
new BlockPos(1, 0, -1),
|
|
||||||
new BlockPos(2, 0, -1),
|
|
||||||
new BlockPos(2, 0, 1),
|
|
||||||
new BlockPos(-2, 0, -1),
|
|
||||||
new BlockPos(-2, 0, 1),
|
|
||||||
new BlockPos(1, 0, 2),
|
|
||||||
new BlockPos(-1, 0, 2),
|
|
||||||
new BlockPos(1, 0, -2),
|
|
||||||
new BlockPos(-1, 0, -2)
|
|
||||||
};
|
|
||||||
|
|
||||||
public final ItemStackHandler items = new ItemStackHandlerNA(1, this, true) {
|
public final ItemStackHandler items = new ItemStackHandlerNA(1, this, true) {
|
||||||
@Override
|
@Override
|
||||||
public int getSlotLimit(int slot) {
|
public int getSlotLimit(int slot) {
|
||||||
|
@ -53,86 +34,86 @@ public class TileEntityWoodStand extends TileEntityImpl implements ITickable {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private TreeRitualRecipe recipe;
|
||||||
private BlockPos ritualPos;
|
private BlockPos ritualPos;
|
||||||
private Map<BlockPos, ItemStack> involvedStands;
|
|
||||||
private ItemStack output;
|
|
||||||
private int totalTime;
|
|
||||||
private int timer;
|
private int timer;
|
||||||
|
|
||||||
public void setRitual(BlockPos pos, ItemStack output, int totalTime, Map<BlockPos, ItemStack> involvedStands) {
|
public void setRitual(BlockPos pos, TreeRitualRecipe recipe) {
|
||||||
this.ritualPos = pos;
|
this.ritualPos = pos;
|
||||||
this.output = output;
|
this.recipe = recipe;
|
||||||
this.totalTime = totalTime;
|
|
||||||
this.involvedStands = involvedStands;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update() {
|
public void update() {
|
||||||
if (!this.world.isRemote) {
|
if (!this.world.isRemote) {
|
||||||
if (this.ritualPos != null && this.involvedStands != null && this.output != null && this.totalTime > 0) {
|
if (this.ritualPos != null && this.recipe != null) {
|
||||||
if (this.isRitualOkay()) {
|
if (this.world.getTotalWorldTime() % 5 == 0) {
|
||||||
this.timer++;
|
if (this.isRitualOkay()) {
|
||||||
|
boolean wasOverHalf = this.timer >= this.recipe.time / 2;
|
||||||
|
this.timer += 5;
|
||||||
|
boolean isOverHalf = this.timer >= this.recipe.time / 2;
|
||||||
|
|
||||||
|
if (!isOverHalf)
|
||||||
|
Multiblocks.TREE_RITUAL.forEach(this.world, this.ritualPos, Rotation.NONE, 'W', pos -> {
|
||||||
|
TileEntity tile = this.world.getTileEntity(pos);
|
||||||
|
if (tile instanceof TileEntityWoodStand && !((TileEntityWoodStand) tile).items.getStackInSlot(0).isEmpty()) {
|
||||||
|
PacketHandler.sendToAllAround(this.world, this.pos, 32, new PacketParticleStream(
|
||||||
|
(float) pos.getX() + 0.2F + this.world.rand.nextFloat() * 0.6F,
|
||||||
|
(float) pos.getY() + 0.85F,
|
||||||
|
(float) pos.getZ() + 0.2F + this.world.rand.nextFloat() * 0.6F,
|
||||||
|
this.ritualPos.getX() + 0.5F, this.ritualPos.getY() + this.world.rand.nextFloat() * 3F + 2F, this.ritualPos.getZ() + 0.5F,
|
||||||
|
this.world.rand.nextFloat() * 0.02F + 0.02F, 0x89cc37, this.world.rand.nextFloat() * 1F + 1F
|
||||||
|
));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
if (this.timer % 5 == 0 && this.timer < this.totalTime / 2) {
|
|
||||||
for (BlockPos pos : this.involvedStands.keySet()) {
|
|
||||||
PacketHandler.sendToAllAround(this.world, this.pos, 32, new PacketParticleStream(
|
|
||||||
(float) pos.getX() + 0.2F + this.world.rand.nextFloat() * 0.6F,
|
|
||||||
(float) pos.getY() + 0.85F,
|
|
||||||
(float) pos.getZ() + 0.2F + this.world.rand.nextFloat() * 0.6F,
|
|
||||||
this.ritualPos.getX() + 0.5F, this.ritualPos.getY() + this.world.rand.nextFloat() * 3F + 2F, this.ritualPos.getZ() + 0.5F,
|
|
||||||
this.world.rand.nextFloat() * 0.02F + 0.02F, 0x89cc37, this.world.rand.nextFloat() * 1F + 1F
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (this.timer % 5 == 0) {
|
|
||||||
PacketHandler.sendToAllAround(this.world, this.ritualPos, 32,
|
PacketHandler.sendToAllAround(this.world, this.ritualPos, 32,
|
||||||
new PacketParticles(this.ritualPos.getX(), this.ritualPos.getY(), this.ritualPos.getZ(), 0));
|
new PacketParticles(this.ritualPos.getX(), this.ritualPos.getY(), this.ritualPos.getZ(), 0));
|
||||||
}
|
|
||||||
|
|
||||||
if (this.timer >= this.totalTime) {
|
if (this.timer >= this.recipe.time) {
|
||||||
this.recurseTreeDestruction(this.ritualPos, this.ritualPos);
|
this.recurseTreeDestruction(this.ritualPos, this.ritualPos);
|
||||||
for (BlockPos offset : GOLD_POWDER_POSITIONS) {
|
Multiblocks.TREE_RITUAL.forEach(this.world, this.ritualPos, Rotation.NONE, 'G',
|
||||||
this.world.setBlockToAir(this.ritualPos.add(offset));
|
pos -> this.world.setBlockToAir(pos));
|
||||||
|
|
||||||
|
EntityItem item = new EntityItem(this.world,
|
||||||
|
this.ritualPos.getX() + 0.5, this.ritualPos.getY() + 4.5, this.ritualPos.getZ() + 0.5,
|
||||||
|
this.recipe.result.copy());
|
||||||
|
this.world.spawnEntity(item);
|
||||||
|
|
||||||
|
PacketHandler.sendToAllAround(this.world, this.pos, 32,
|
||||||
|
new PacketParticles((float) item.posX, (float) item.posY, (float) item.posZ, 3));
|
||||||
|
this.world.playSound(null, this.pos.getX() + 0.5, this.pos.getY() + 0.5, this.pos.getZ() + 0.5,
|
||||||
|
SoundEvents.ENTITY_ENDERMEN_TELEPORT, SoundCategory.BLOCKS, 0.65F, 1F);
|
||||||
|
|
||||||
|
this.ritualPos = null;
|
||||||
|
this.recipe = null;
|
||||||
|
this.timer = 0;
|
||||||
|
} else if (isOverHalf && !wasOverHalf) {
|
||||||
|
Multiblocks.TREE_RITUAL.forEach(this.world, this.ritualPos, Rotation.NONE, 'W', pos -> {
|
||||||
|
TileEntity tile = this.world.getTileEntity(pos);
|
||||||
|
if (tile instanceof TileEntityWoodStand) {
|
||||||
|
TileEntityWoodStand stand = (TileEntityWoodStand) tile;
|
||||||
|
if (!stand.items.getStackInSlot(0).isEmpty()) {
|
||||||
|
PacketHandler.sendToAllAround(this.world, this.pos, 32,
|
||||||
|
new PacketParticles(stand.pos.getX(), stand.pos.getY(), stand.pos.getZ(), 1));
|
||||||
|
this.world.playSound(null, stand.pos.getX() + 0.5, stand.pos.getY() + 0.5, stand.pos.getZ() + 0.5,
|
||||||
|
SoundEvents.BLOCK_WOOD_STEP, SoundCategory.BLOCKS, 0.5F, 1F);
|
||||||
|
|
||||||
|
stand.items.setStackInSlot(0, ItemStack.EMPTY);
|
||||||
|
stand.sendToClients();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
EntityItem item = new EntityItem(this.world,
|
|
||||||
this.ritualPos.getX() + 0.5, this.ritualPos.getY() + 4.5, this.ritualPos.getZ() + 0.5,
|
|
||||||
this.output.copy());
|
|
||||||
this.world.spawnEntity(item);
|
|
||||||
|
|
||||||
PacketHandler.sendToAllAround(this.world, this.pos, 32,
|
|
||||||
new PacketParticles((float) item.posX, (float) item.posY, (float) item.posZ, 3));
|
|
||||||
this.world.playSound(null, this.pos.getX() + 0.5, this.pos.getY() + 0.5, this.pos.getZ() + 0.5,
|
|
||||||
SoundEvents.ENTITY_ENDERMEN_TELEPORT, SoundCategory.BLOCKS, 0.65F, 1F);
|
|
||||||
|
|
||||||
this.ritualPos = null;
|
this.ritualPos = null;
|
||||||
this.involvedStands = null;
|
this.recipe = null;
|
||||||
this.output = null;
|
|
||||||
this.totalTime = 0;
|
|
||||||
this.timer = 0;
|
this.timer = 0;
|
||||||
} else if (this.timer == this.totalTime / 2) {
|
|
||||||
for (BlockPos pos : this.involvedStands.keySet()) {
|
|
||||||
TileEntityWoodStand stand = (TileEntityWoodStand) this.world.getTileEntity(pos);
|
|
||||||
|
|
||||||
PacketHandler.sendToAllAround(this.world, this.pos, 32, new PacketParticles(stand.pos.getX(), stand.pos.getY(), stand.pos.getZ(), 1));
|
|
||||||
this.world.playSound(null, stand.pos.getX() + 0.5, stand.pos.getY() + 0.5, stand.pos.getZ() + 0.5,
|
|
||||||
SoundEvents.BLOCK_WOOD_STEP, SoundCategory.BLOCKS, 0.5F, 1F);
|
|
||||||
|
|
||||||
stand.items.setStackInSlot(0, ItemStack.EMPTY);
|
|
||||||
stand.sendToClients();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
|
||||||
this.ritualPos = null;
|
|
||||||
this.involvedStands = null;
|
|
||||||
this.output = null;
|
|
||||||
this.totalTime = 0;
|
|
||||||
this.timer = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void recurseTreeDestruction(BlockPos pos, BlockPos start) {
|
private void recurseTreeDestruction(BlockPos pos, BlockPos start) {
|
||||||
|
@ -155,20 +136,29 @@ public class TileEntityWoodStand extends TileEntityImpl implements ITickable {
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isRitualOkay() {
|
private boolean isRitualOkay() {
|
||||||
for (int i = 0; i < 3; i++) {
|
if (!Multiblocks.validateLoosely(Multiblocks.TREE_RITUAL, this.world, this.ritualPos, ModBlocks.WOOD_STAND)) {
|
||||||
IBlockState state = this.world.getBlockState(this.ritualPos.up(i));
|
return false;
|
||||||
if (!(state.getBlock() instanceof BlockLog)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
for (Map.Entry<BlockPos, ItemStack> entry : this.involvedStands.entrySet()) {
|
if (this.timer < this.recipe.time / 2) {
|
||||||
TileEntity tile = this.world.getTileEntity(entry.getKey());
|
List<ItemStack> required = new ArrayList<>(Arrays.asList(this.recipe.items));
|
||||||
if (!(tile instanceof TileEntityWoodStand)
|
MutableBoolean tooMuch = new MutableBoolean();
|
||||||
|| (this.timer < this.totalTime / 2 && !((TileEntityWoodStand) tile).items.getStackInSlot(0).isItemEqual(entry.getValue()))) {
|
Multiblocks.TREE_RITUAL.forEach(this.world, this.ritualPos, Rotation.NONE, 'W', pos -> {
|
||||||
return false;
|
TileEntity tile = this.world.getTileEntity(pos);
|
||||||
}
|
if (tile instanceof TileEntityWoodStand) {
|
||||||
}
|
ItemStack stack = ((TileEntityWoodStand) tile).items.getStackInSlot(0);
|
||||||
return Helper.checkMultiblock(this.world, this.ritualPos, TileEntityWoodStand.GOLD_POWDER_POSITIONS, ModBlocks.GOLD_POWDER.getDefaultState(), true);
|
if (!stack.isEmpty()) {
|
||||||
|
int index = Helper.getItemIndex(required, stack);
|
||||||
|
if (index >= 0) {
|
||||||
|
required.remove(index);
|
||||||
|
} else {
|
||||||
|
tooMuch.setTrue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return tooMuch.isFalse() && required.isEmpty();
|
||||||
|
} else
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -177,20 +167,10 @@ public class TileEntityWoodStand extends TileEntityImpl implements ITickable {
|
||||||
compound.setTag("items", this.items.serializeNBT());
|
compound.setTag("items", this.items.serializeNBT());
|
||||||
|
|
||||||
if (!syncing) {
|
if (!syncing) {
|
||||||
if (this.ritualPos != null && this.involvedStands != null && this.output != null && this.totalTime > 0) {
|
if (this.ritualPos != null && this.recipe != null) {
|
||||||
compound.setLong("ritual_pos", this.ritualPos.toLong());
|
compound.setLong("ritual_pos", this.ritualPos.toLong());
|
||||||
compound.setInteger("timer", this.timer);
|
compound.setInteger("timer", this.timer);
|
||||||
compound.setInteger("total_time", this.totalTime);
|
compound.setString("recipe", this.recipe.name.toString());
|
||||||
compound.setTag("output", this.output.writeToNBT(new NBTTagCompound()));
|
|
||||||
|
|
||||||
NBTTagList list = new NBTTagList();
|
|
||||||
for (Map.Entry<BlockPos, ItemStack> entry : this.involvedStands.entrySet()) {
|
|
||||||
NBTTagCompound tag = new NBTTagCompound();
|
|
||||||
tag.setLong("pos", entry.getKey().toLong());
|
|
||||||
tag.setTag("item", entry.getValue().writeToNBT(new NBTTagCompound()));
|
|
||||||
list.appendTag(tag);
|
|
||||||
}
|
|
||||||
compound.setTag("stands", list);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -201,21 +181,10 @@ public class TileEntityWoodStand extends TileEntityImpl implements ITickable {
|
||||||
this.items.deserializeNBT(compound.getCompoundTag("items"));
|
this.items.deserializeNBT(compound.getCompoundTag("items"));
|
||||||
|
|
||||||
if (!syncing) {
|
if (!syncing) {
|
||||||
if (compound.hasKey("ritual_pos") && compound.hasKey("stands") && compound.hasKey("output") && compound.hasKey("total_time")) {
|
if (compound.hasKey("recipe")) {
|
||||||
this.ritualPos = BlockPos.fromLong(compound.getLong("ritual_pos"));
|
this.ritualPos = BlockPos.fromLong(compound.getLong("ritual_pos"));
|
||||||
this.timer = compound.getInteger("timer");
|
this.timer = compound.getInteger("timer");
|
||||||
this.totalTime = compound.getInteger("total_time");
|
this.recipe = TreeRitualRecipe.RECIPES.get(new ResourceLocation(compound.getString("recipe")));
|
||||||
this.output = new ItemStack(compound.getCompoundTag("output"));
|
|
||||||
|
|
||||||
this.involvedStands = new HashMap<>();
|
|
||||||
NBTTagList list = compound.getTagList("stands", 10);
|
|
||||||
for (NBTBase base : list) {
|
|
||||||
NBTTagCompound tag = (NBTTagCompound) base;
|
|
||||||
this.involvedStands.put(
|
|
||||||
BlockPos.fromLong(tag.getLong("pos")),
|
|
||||||
new ItemStack(tag.getCompoundTag("item"))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,16 +2,23 @@ package de.ellpeck.naturesaura.events;
|
||||||
|
|
||||||
import de.ellpeck.naturesaura.Helper;
|
import de.ellpeck.naturesaura.Helper;
|
||||||
import de.ellpeck.naturesaura.blocks.ModBlocks;
|
import de.ellpeck.naturesaura.blocks.ModBlocks;
|
||||||
|
import de.ellpeck.naturesaura.blocks.Multiblocks;
|
||||||
import de.ellpeck.naturesaura.blocks.tiles.TileEntityWoodStand;
|
import de.ellpeck.naturesaura.blocks.tiles.TileEntityWoodStand;
|
||||||
import de.ellpeck.naturesaura.recipes.TreeRitualRecipe;
|
import de.ellpeck.naturesaura.recipes.TreeRitualRecipe;
|
||||||
import net.minecraft.block.state.IBlockState;
|
import net.minecraft.block.state.IBlockState;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.tileentity.TileEntity;
|
||||||
|
import net.minecraft.util.Rotation;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
import net.minecraftforge.event.terraingen.SaplingGrowTreeEvent;
|
import net.minecraftforge.event.terraingen.SaplingGrowTreeEvent;
|
||||||
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
||||||
|
import org.apache.commons.lang3.mutable.MutableBoolean;
|
||||||
|
import org.apache.commons.lang3.mutable.MutableObject;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public class TerrainGenEvents {
|
public class TerrainGenEvents {
|
||||||
|
|
||||||
|
@ -20,44 +27,38 @@ public class TerrainGenEvents {
|
||||||
World world = event.getWorld();
|
World world = event.getWorld();
|
||||||
BlockPos pos = event.getPos();
|
BlockPos pos = event.getPos();
|
||||||
if (!world.isRemote) {
|
if (!world.isRemote) {
|
||||||
if (Helper.checkMultiblock(world, pos, TileEntityWoodStand.GOLD_POWDER_POSITIONS, ModBlocks.GOLD_POWDER.getDefaultState(), true)) {
|
if (Multiblocks.validateLoosely(Multiblocks.TREE_RITUAL, world, pos, ModBlocks.WOOD_STAND)) {
|
||||||
List<TileEntityWoodStand> stands = new ArrayList<>();
|
|
||||||
List<ItemStack> usableItems = new ArrayList<>();
|
|
||||||
Helper.getTileEntitiesInArea(world, pos, 5, tile -> {
|
|
||||||
if (tile instanceof TileEntityWoodStand) {
|
|
||||||
TileEntityWoodStand stand = (TileEntityWoodStand) tile;
|
|
||||||
ItemStack stack = stand.items.getStackInSlot(0);
|
|
||||||
if (!stack.isEmpty()) {
|
|
||||||
usableItems.add(stack);
|
|
||||||
stands.add(stand);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
IBlockState sapling = world.getBlockState(pos);
|
IBlockState sapling = world.getBlockState(pos);
|
||||||
ItemStack saplingStack = sapling.getBlock().getItem(world, pos, sapling);
|
ItemStack saplingStack = sapling.getBlock().getItem(world, pos, sapling);
|
||||||
if (!saplingStack.isEmpty()) {
|
if (!saplingStack.isEmpty()) {
|
||||||
for (TreeRitualRecipe recipe : TreeRitualRecipe.RECIPES.values()) {
|
for (TreeRitualRecipe recipe : TreeRitualRecipe.RECIPES.values()) {
|
||||||
if (recipe.matchesItems(saplingStack, usableItems)) {
|
if (recipe.saplingType.isItemEqual(saplingStack)) {
|
||||||
Map<BlockPos, ItemStack> actuallyInvolved = new HashMap<>();
|
List<ItemStack> required = new ArrayList<>(Arrays.asList(recipe.items));
|
||||||
List<ItemStack> stillRequired = new ArrayList<>(Arrays.asList(recipe.items));
|
MutableBoolean tooMuch = new MutableBoolean();
|
||||||
TileEntityWoodStand toPick = null;
|
MutableObject<TileEntityWoodStand> toPick = new MutableObject<>();
|
||||||
|
|
||||||
for (TileEntityWoodStand stand : stands) {
|
Multiblocks.TREE_RITUAL.forEach(world, pos, Rotation.NONE, 'W', tilePos -> {
|
||||||
ItemStack stack = stand.items.getStackInSlot(0);
|
TileEntity tile = world.getTileEntity(tilePos);
|
||||||
int index = Helper.getItemIndex(stillRequired, stack);
|
if (tile instanceof TileEntityWoodStand) {
|
||||||
if (index >= 0) {
|
TileEntityWoodStand stand = (TileEntityWoodStand) tile;
|
||||||
actuallyInvolved.put(stand.getPos(), stack);
|
ItemStack stack = stand.items.getStackInSlot(0);
|
||||||
stillRequired.remove(index);
|
if (!stack.isEmpty()) {
|
||||||
|
int index = Helper.getItemIndex(required, stack);
|
||||||
|
if (index >= 0) {
|
||||||
|
required.remove(index);
|
||||||
|
|
||||||
if (toPick == null) {
|
if (toPick.getValue() == null) {
|
||||||
toPick = stand;
|
toPick.setValue(stand);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
tooMuch.setTrue();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
if (stillRequired.isEmpty()) {
|
if (tooMuch.isFalse() && required.isEmpty()) {
|
||||||
toPick.setRitual(pos, recipe.result, recipe.time, actuallyInvolved);
|
toPick.getValue().setRitual(pos, recipe);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
package de.ellpeck.naturesaura.packet;
|
package de.ellpeck.naturesaura.packet;
|
||||||
|
|
||||||
import de.ellpeck.naturesaura.NaturesAura;
|
import de.ellpeck.naturesaura.NaturesAura;
|
||||||
import de.ellpeck.naturesaura.blocks.tiles.TileEntityWoodStand;
|
import de.ellpeck.naturesaura.blocks.Multiblocks;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import net.minecraft.block.state.IBlockState;
|
import net.minecraft.block.state.IBlockState;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.util.Rotation;
|
||||||
import net.minecraft.util.math.AxisAlignedBB;
|
import net.minecraft.util.math.AxisAlignedBB;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
@ -59,8 +60,7 @@ public class PacketParticles implements IMessage {
|
||||||
switch (message.type) {
|
switch (message.type) {
|
||||||
case 0: // Tree ritual: Gold powder
|
case 0: // Tree ritual: Gold powder
|
||||||
BlockPos pos = new BlockPos(message.posX, message.posY, message.posZ);
|
BlockPos pos = new BlockPos(message.posX, message.posY, message.posZ);
|
||||||
for (BlockPos offset : TileEntityWoodStand.GOLD_POWDER_POSITIONS) {
|
Multiblocks.TREE_RITUAL.forEach(world, pos, Rotation.NONE, 'G', dustPos -> {
|
||||||
BlockPos dustPos = pos.add(offset);
|
|
||||||
IBlockState state = world.getBlockState(dustPos);
|
IBlockState state = world.getBlockState(dustPos);
|
||||||
AxisAlignedBB box = state.getBoundingBox(world, dustPos);
|
AxisAlignedBB box = state.getBoundingBox(world, dustPos);
|
||||||
NaturesAura.proxy.spawnMagicParticle(world,
|
NaturesAura.proxy.spawnMagicParticle(world,
|
||||||
|
@ -71,7 +71,7 @@ public class PacketParticles implements IMessage {
|
||||||
world.rand.nextFloat() * 0.005F + 0.01F,
|
world.rand.nextFloat() * 0.005F + 0.01F,
|
||||||
(float) world.rand.nextGaussian() * 0.01F,
|
(float) world.rand.nextGaussian() * 0.01F,
|
||||||
0xf4cb42, 2F, 100, 0F, false, true);
|
0xf4cb42, 2F, 100, 0F, false, true);
|
||||||
}
|
});
|
||||||
break;
|
break;
|
||||||
case 1: // Tree ritual: Consuming item
|
case 1: // Tree ritual: Consuming item
|
||||||
for (int i = world.rand.nextInt(20) + 10; i >= 0; i--) {
|
for (int i = world.rand.nextInt(20) + 10; i >= 0; i--) {
|
||||||
|
|
|
@ -23,7 +23,7 @@ public final class ModRecipes {
|
||||||
new ItemStack(Blocks.STONE),
|
new ItemStack(Blocks.STONE),
|
||||||
new ItemStack(Blocks.STONE),
|
new ItemStack(Blocks.STONE),
|
||||||
new ItemStack(ModItems.GOLD_LEAF),
|
new ItemStack(ModItems.GOLD_LEAF),
|
||||||
new ItemStack(Items.DIAMOND)).add();
|
new ItemStack(Items.GOLD_INGOT)).add();
|
||||||
new TreeRitualRecipe(new ResourceLocation(NaturesAura.MOD_ID, "ancient_sapling"),
|
new TreeRitualRecipe(new ResourceLocation(NaturesAura.MOD_ID, "ancient_sapling"),
|
||||||
new ItemStack(Blocks.SAPLING), new ItemStack(ModBlocks.ANCIENT_SAPLING), 200,
|
new ItemStack(Blocks.SAPLING), new ItemStack(ModBlocks.ANCIENT_SAPLING), 200,
|
||||||
new ItemStack(Blocks.SAPLING),
|
new ItemStack(Blocks.SAPLING),
|
||||||
|
|
|
@ -1,11 +1,9 @@
|
||||||
package de.ellpeck.naturesaura.recipes;
|
package de.ellpeck.naturesaura.recipes;
|
||||||
|
|
||||||
import de.ellpeck.naturesaura.Helper;
|
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.util.ResourceLocation;
|
import net.minecraft.util.ResourceLocation;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public class TreeRitualRecipe {
|
public class TreeRitualRecipe {
|
||||||
|
@ -26,19 +24,6 @@ public class TreeRitualRecipe {
|
||||||
this.time = time;
|
this.time = time;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean matchesItems(ItemStack sapling, List<ItemStack> items) {
|
|
||||||
if (this.saplingType.isItemEqual(sapling)) {
|
|
||||||
for (ItemStack ingredient : this.items) {
|
|
||||||
if (Helper.getItemIndex(items, ingredient) < 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public TreeRitualRecipe add() {
|
public TreeRitualRecipe add() {
|
||||||
RECIPES.put(this.name, this);
|
RECIPES.put(this.name, this);
|
||||||
return this;
|
return this;
|
||||||
|
|
|
@ -9,6 +9,11 @@
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"text": "A rudimentary, yet effective way of collecting $(aura) early on is the $(item)Natural Altar$(). After creating the setup shown on the following page, the altar will start slowly draining $(aura) in the vicinity. However, it is not strong enough to cause major damage, making it only drain until there is none left in the area.$(br)The collected $(aura) can then be used in several ways, $(l:using/altar)infusing items$() for instance."
|
"text": "A rudimentary, yet effective way of collecting $(aura) early on is the $(item)Natural Altar$(). After creating the setup shown on the following page, the altar will start slowly draining $(aura) in the vicinity. However, it is not strong enough to cause major damage, making it only drain until there is none left in the area.$(br)The collected $(aura) can then be used in several ways, $(l:using/altar)infusing items$() for instance."
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"type": "multiblock",
|
||||||
|
"multiblock": "naturesaura:altar",
|
||||||
|
"text": "How to assemble the $(item)Natural Altar$()"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"type": "naturesaura:tree_ritual",
|
"type": "naturesaura:tree_ritual",
|
||||||
"text": "Creating the $(item)Natural Altar$() using the $(l:practices/tree_ritual)Ritual of the Forest$()",
|
"text": "Creating the $(item)Natural Altar$() using the $(l:practices/tree_ritual)Ritual of the Forest$()",
|
||||||
|
|
|
@ -11,7 +11,12 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"text": "To construct this $(thing)ritual$(), one has to place $(item)Gold Powder$() in the configuration shown on the next page, with some $(item)Wooden Stands$() around that which will hold the ingredients in whichever configuration seems visually pleasing.$(br)Then, the correct $(item)Sapling$() must be placed in the middle, and, either through some kind of fertilizer, or through the inevitability of time, its growth will cause the ritual to start."
|
"text": "To construct this $(thing)ritual$(), one has to place $(item)Gold Powder$() in the configuration shown on the next page, with some $(item)Wooden Stands$() around that which will hold the ingredients.$(br)Then, the correct $(item)Sapling$() must be placed in the middle, and, either through some kind of fertilizer, or through the inevitability of time, its growth will cause the ritual to start."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "multiblock",
|
||||||
|
"multiblock": "naturesaura:tree_ritual",
|
||||||
|
"text": "Preparing the $(item)Ritual of the Forest$(). It is not required to have all $(item)Wood Stands$() present."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "crafting",
|
"type": "crafting",
|
||||||
|
|
Loading…
Reference in a new issue