mirror of
https://github.com/Ellpeck/NaturesAura.git
synced 2024-11-22 19:58:34 +01:00
some changes to the tree ritual
This commit is contained in:
parent
f2eca230e8
commit
1f8431068c
16 changed files with 444 additions and 204 deletions
|
@ -1,6 +1,10 @@
|
||||||
package de.ellpeck.naturesaura;
|
package de.ellpeck.naturesaura;
|
||||||
|
|
||||||
import net.minecraft.block.state.IBlockState;
|
import net.minecraft.block.state.IBlockState;
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.client.renderer.GlStateManager;
|
||||||
|
import net.minecraft.client.renderer.RenderHelper;
|
||||||
|
import net.minecraft.client.renderer.block.model.ItemCameraTransforms;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.tileentity.TileEntity;
|
import net.minecraft.tileentity.TileEntity;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
@ -46,21 +50,27 @@ public final class Helper {
|
||||||
return ((a & 255) << 24) | ((r & 255) << 16) | ((g & 255) << 8) | (b & 255);
|
return ((a & 255) << 24) | ((r & 255) << 16) | ((g & 255) << 8) | (b & 255);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean containsItem(List<ItemStack> list, ItemStack item) {
|
public static int getItemIndex(List<ItemStack> list, ItemStack item) {
|
||||||
for (ItemStack stack : list) {
|
for (int i = 0; i < list.size(); i++) {
|
||||||
if (stack.isItemEqual(item)) {
|
if (list.get(i).isItemEqual(item)) {
|
||||||
return true;
|
return i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean containsItem(ItemStack[] array, ItemStack item) {
|
@SideOnly(Side.CLIENT)
|
||||||
for (ItemStack stack : array) {
|
public static void renderItemInWorld(ItemStack stack) {
|
||||||
if (stack.isItemEqual(item)) {
|
if (!stack.isEmpty()) {
|
||||||
return true;
|
GlStateManager.pushMatrix();
|
||||||
|
GlStateManager.disableLighting();
|
||||||
|
GlStateManager.pushAttrib();
|
||||||
|
RenderHelper.enableStandardItemLighting();
|
||||||
|
Minecraft.getMinecraft().getRenderItem().renderItem(stack, ItemCameraTransforms.TransformType.FIXED);
|
||||||
|
RenderHelper.disableStandardItemLighting();
|
||||||
|
GlStateManager.popAttrib();
|
||||||
|
GlStateManager.enableLighting();
|
||||||
|
GlStateManager.popMatrix();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package de.ellpeck.naturesaura;
|
package de.ellpeck.naturesaura;
|
||||||
|
|
||||||
import de.ellpeck.naturesaura.blocks.ModBlocks;
|
import de.ellpeck.naturesaura.blocks.ModBlocks;
|
||||||
import de.ellpeck.naturesaura.events.TreeRitualHandler;
|
import de.ellpeck.naturesaura.events.TerrainGenEvents;
|
||||||
import de.ellpeck.naturesaura.items.ModItems;
|
import de.ellpeck.naturesaura.items.ModItems;
|
||||||
import de.ellpeck.naturesaura.packet.PacketHandler;
|
import de.ellpeck.naturesaura.packet.PacketHandler;
|
||||||
import de.ellpeck.naturesaura.proxy.IProxy;
|
import de.ellpeck.naturesaura.proxy.IProxy;
|
||||||
|
@ -9,6 +9,7 @@ import de.ellpeck.naturesaura.recipes.ModRecipes;
|
||||||
import de.ellpeck.naturesaura.reg.ModRegistry;
|
import de.ellpeck.naturesaura.reg.ModRegistry;
|
||||||
import net.minecraft.creativetab.CreativeTabs;
|
import net.minecraft.creativetab.CreativeTabs;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraftforge.common.MinecraftForge;
|
||||||
import net.minecraftforge.fml.common.Mod;
|
import net.minecraftforge.fml.common.Mod;
|
||||||
import net.minecraftforge.fml.common.Mod.EventHandler;
|
import net.minecraftforge.fml.common.Mod.EventHandler;
|
||||||
import net.minecraftforge.fml.common.SidedProxy;
|
import net.minecraftforge.fml.common.SidedProxy;
|
||||||
|
@ -44,7 +45,7 @@ public final class NaturesAura {
|
||||||
PacketHandler.init();
|
PacketHandler.init();
|
||||||
ModRegistry.preInit(event);
|
ModRegistry.preInit(event);
|
||||||
|
|
||||||
new TreeRitualHandler();
|
MinecraftForge.TERRAIN_GEN_BUS.register(new TerrainGenEvents());
|
||||||
|
|
||||||
proxy.preInit(event);
|
proxy.preInit(event);
|
||||||
}
|
}
|
||||||
|
@ -62,9 +63,4 @@ public final class NaturesAura {
|
||||||
ModRegistry.postInit(event);
|
ModRegistry.postInit(event);
|
||||||
proxy.postInit(event);
|
proxy.postInit(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler
|
|
||||||
public void serverStopped(FMLServerStoppedEvent event){
|
|
||||||
TreeRitualHandler.clear();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@ package de.ellpeck.naturesaura.blocks;
|
||||||
|
|
||||||
import de.ellpeck.naturesaura.Helper;
|
import de.ellpeck.naturesaura.Helper;
|
||||||
import de.ellpeck.naturesaura.NaturesAura;
|
import de.ellpeck.naturesaura.NaturesAura;
|
||||||
import de.ellpeck.naturesaura.events.TreeRitualHandler;
|
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;
|
||||||
|
@ -60,9 +60,9 @@ public class BlockGoldPowder extends BlockImpl implements IColorProvidingBlock {
|
||||||
@Override
|
@Override
|
||||||
public void randomDisplayTick(IBlockState stateIn, World worldIn, BlockPos pos, Random rand) {
|
public void randomDisplayTick(IBlockState stateIn, World worldIn, BlockPos pos, Random rand) {
|
||||||
if (rand.nextFloat() >= 0.8F) {
|
if (rand.nextFloat() >= 0.8F) {
|
||||||
for (BlockPos offsetToOrigin : TreeRitualHandler.GOLD_POWDER_POSITIONS) {
|
for (BlockPos offsetToOrigin : TileEntityWoodStand.GOLD_POWDER_POSITIONS) {
|
||||||
BlockPos origin = pos.subtract(offsetToOrigin);
|
BlockPos origin = pos.subtract(offsetToOrigin);
|
||||||
if (Helper.checkMultiblock(worldIn, origin, TreeRitualHandler.GOLD_POWDER_POSITIONS, ModBlocks.GOLD_POWDER.getDefaultState(), true)) {
|
if (Helper.checkMultiblock(worldIn, origin, TileEntityWoodStand.GOLD_POWDER_POSITIONS, ModBlocks.GOLD_POWDER.getDefaultState(), true)) {
|
||||||
NaturesAura.proxy.spawnMagicParticle(worldIn,
|
NaturesAura.proxy.spawnMagicParticle(worldIn,
|
||||||
pos.getX() + 0.375 + rand.nextFloat() * 0.25, pos.getY() + 0.1, pos.getZ() + 0.375 + rand.nextFloat() * 0.25,
|
pos.getX() + 0.375 + rand.nextFloat() * 0.25, pos.getY() + 0.1, pos.getZ() + 0.375 + rand.nextFloat() * 0.25,
|
||||||
rand.nextGaussian() * 0.001, rand.nextFloat() * 0.001 + 0.005, rand.nextGaussian() * 0.001,
|
rand.nextGaussian() * 0.001, rand.nextFloat() * 0.001 + 0.005, rand.nextGaussian() * 0.001,
|
||||||
|
|
|
@ -31,4 +31,9 @@ public class BlockNatureAltar extends BlockContainerImpl {
|
||||||
public boolean isOpaqueCube(IBlockState state) {
|
public boolean isOpaqueCube(IBlockState state) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isNormalCube(IBlockState state, IBlockAccess world, BlockPos pos) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,92 @@
|
||||||
|
package de.ellpeck.naturesaura.blocks;
|
||||||
|
|
||||||
|
import de.ellpeck.naturesaura.blocks.tiles.TileEntityWoodStand;
|
||||||
|
import net.minecraft.block.SoundType;
|
||||||
|
import net.minecraft.block.material.Material;
|
||||||
|
import net.minecraft.block.state.IBlockState;
|
||||||
|
import net.minecraft.entity.item.EntityItem;
|
||||||
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.tileentity.TileEntity;
|
||||||
|
import net.minecraft.util.EnumFacing;
|
||||||
|
import net.minecraft.util.EnumHand;
|
||||||
|
import net.minecraft.util.math.AxisAlignedBB;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.world.IBlockAccess;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
|
public class BlockWoodStand extends BlockContainerImpl {
|
||||||
|
|
||||||
|
private static final AxisAlignedBB BOUND_BOX = new AxisAlignedBB(3 / 16F, 0F, 3 / 16F, 13 / 16F, 13 / 16F, 13 / 16F);
|
||||||
|
|
||||||
|
public BlockWoodStand() {
|
||||||
|
super(Material.WOOD, "wood_stand", TileEntityWoodStand.class, "wood_stand");
|
||||||
|
this.setHardness(1.5F);
|
||||||
|
this.setSoundType(SoundType.WOOD);
|
||||||
|
this.setHarvestLevel("axe", 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onBlockActivated(World worldIn, BlockPos pos, IBlockState state, EntityPlayer playerIn, EnumHand hand, EnumFacing facing, float hitX, float hitY, float hitZ) {
|
||||||
|
TileEntity tile = worldIn.getTileEntity(pos);
|
||||||
|
if (tile instanceof TileEntityWoodStand) {
|
||||||
|
TileEntityWoodStand stand = (TileEntityWoodStand) tile;
|
||||||
|
if (stand.stack.isEmpty()) {
|
||||||
|
ItemStack handStack = playerIn.getHeldItem(hand);
|
||||||
|
if (!handStack.isEmpty()) {
|
||||||
|
if (!worldIn.isRemote) {
|
||||||
|
ItemStack copy = handStack.copy();
|
||||||
|
copy.setCount(1);
|
||||||
|
stand.stack = copy;
|
||||||
|
handStack.shrink(1);
|
||||||
|
stand.sendToClients();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!worldIn.isRemote) {
|
||||||
|
playerIn.addItemStackToInventory(stand.stack);
|
||||||
|
stand.stack = ItemStack.EMPTY;
|
||||||
|
stand.sendToClients();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void breakBlock(World worldIn, BlockPos pos, IBlockState state) {
|
||||||
|
if (!worldIn.isRemote) {
|
||||||
|
TileEntity tile = worldIn.getTileEntity(pos);
|
||||||
|
if (tile instanceof TileEntityWoodStand) {
|
||||||
|
TileEntityWoodStand stand = (TileEntityWoodStand) tile;
|
||||||
|
if (!stand.stack.isEmpty()) {
|
||||||
|
EntityItem item = new EntityItem(worldIn, pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5, stand.stack);
|
||||||
|
worldIn.spawnEntity(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
super.breakBlock(worldIn, pos, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AxisAlignedBB getBoundingBox(IBlockState state, IBlockAccess source, BlockPos pos) {
|
||||||
|
return BOUND_BOX;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isFullCube(IBlockState state) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isOpaqueCube(IBlockState state) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isNormalCube(IBlockState state, IBlockAccess world, BlockPos pos) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
|
@ -14,4 +14,5 @@ public final class ModBlocks {
|
||||||
public static final Block DECAYED_LEAVES = new BlockDecayedLeaves();
|
public static final Block DECAYED_LEAVES = new BlockDecayedLeaves();
|
||||||
public static final Block GOLDEN_LEAVES = new BlockGoldenLeaves();
|
public static final Block GOLDEN_LEAVES = new BlockGoldenLeaves();
|
||||||
public static final Block GOLD_POWDER = new BlockGoldPowder();
|
public static final Block GOLD_POWDER = new BlockGoldPowder();
|
||||||
|
public static final Block WOOD_STAND = new BlockWoodStand();
|
||||||
}
|
}
|
||||||
|
|
|
@ -123,12 +123,12 @@ public class TileEntityNatureAltar extends TileEntityImpl implements ITickable,
|
||||||
if (!this.cachedProviders.isEmpty()) {
|
if (!this.cachedProviders.isEmpty()) {
|
||||||
int index = rand.nextInt(this.cachedProviders.size());
|
int index = rand.nextInt(this.cachedProviders.size());
|
||||||
IAuraContainerProvider provider = this.cachedProviders.get(index);
|
IAuraContainerProvider provider = this.cachedProviders.get(index);
|
||||||
BlockPos pos = ((TileEntity) provider).getPos();
|
if (((TileEntity) provider).isInvalid()) {
|
||||||
if (this.world.getTileEntity(pos) == provider) {
|
|
||||||
int stored = this.container.storeAura(provider.container().drainAura(5, true), false);
|
int stored = this.container.storeAura(provider.container().drainAura(5, true), false);
|
||||||
if (stored > 0) {
|
if (stored > 0) {
|
||||||
provider.container().drainAura(stored, false);
|
provider.container().drainAura(stored, false);
|
||||||
|
|
||||||
|
BlockPos pos = ((TileEntity) provider).getPos();
|
||||||
PacketHandler.sendToAllAround(this.world, this.pos, 32, new PacketParticleStream(
|
PacketHandler.sendToAllAround(this.world, this.pos, 32, new PacketParticleStream(
|
||||||
pos.getX() + 0.5F, pos.getY() + 0.5F, pos.getZ() + 0.5F,
|
pos.getX() + 0.5F, pos.getY() + 0.5F, pos.getZ() + 0.5F,
|
||||||
this.pos.getX() + 0.5F, this.pos.getY() + 0.5F, this.pos.getZ() + 0.5F,
|
this.pos.getX() + 0.5F, this.pos.getY() + 0.5F, this.pos.getZ() + 0.5F,
|
||||||
|
|
|
@ -0,0 +1,158 @@
|
||||||
|
package de.ellpeck.naturesaura.blocks.tiles;
|
||||||
|
|
||||||
|
import de.ellpeck.naturesaura.Helper;
|
||||||
|
import de.ellpeck.naturesaura.blocks.ModBlocks;
|
||||||
|
import de.ellpeck.naturesaura.packet.PacketHandler;
|
||||||
|
import de.ellpeck.naturesaura.packet.PacketParticleStream;
|
||||||
|
import de.ellpeck.naturesaura.packet.PacketParticles;
|
||||||
|
import de.ellpeck.naturesaura.recipes.TreeRitualRecipe;
|
||||||
|
import net.minecraft.block.BlockLeaves;
|
||||||
|
import net.minecraft.block.BlockLog;
|
||||||
|
import net.minecraft.block.state.IBlockState;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.nbt.NBTTagCompound;
|
||||||
|
import net.minecraft.util.EnumFacing;
|
||||||
|
import net.minecraft.util.ITickable;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
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 ItemStack stack = ItemStack.EMPTY;
|
||||||
|
|
||||||
|
private BlockPos ritualPos;
|
||||||
|
private Map<TileEntityWoodStand, ItemStack> involvedStands;
|
||||||
|
private TreeRitualRecipe recipe;
|
||||||
|
private int timer;
|
||||||
|
|
||||||
|
public void setRitual(BlockPos pos, TreeRitualRecipe recipe, Map<TileEntityWoodStand, ItemStack> involvedStands) {
|
||||||
|
this.ritualPos = pos;
|
||||||
|
this.recipe = recipe;
|
||||||
|
this.involvedStands = involvedStands;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void update() {
|
||||||
|
if (!this.world.isRemote) {
|
||||||
|
if (this.ritualPos != null && this.involvedStands != null && this.recipe != null) {
|
||||||
|
if (this.isRitualOkay(this.world)) {
|
||||||
|
this.timer++;
|
||||||
|
|
||||||
|
if (this.timer % 3 == 0) {
|
||||||
|
for (TileEntityWoodStand stand : this.involvedStands.keySet()) {
|
||||||
|
PacketHandler.sendToAllAround(this.world, this.pos, 32, new PacketParticleStream(
|
||||||
|
(float) stand.pos.getX() + 0.5F, (float) stand.pos.getY() + 1.25F, (float) stand.pos.getZ() + 0.5F,
|
||||||
|
this.ritualPos.getX() + 0.5F, this.ritualPos.getY() + 2.5F, this.ritualPos.getZ() + 0.5F,
|
||||||
|
this.world.rand.nextFloat() * 0.02F + 0.02F, 0xFF00FF, this.world.rand.nextFloat() * 1F + 1F
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (this.timer % 5 == 0) {
|
||||||
|
for (BlockPos offset : TileEntityWoodStand.GOLD_POWDER_POSITIONS) {
|
||||||
|
BlockPos dustPos = this.ritualPos.add(offset);
|
||||||
|
PacketHandler.sendToAllAround(this.world, this.ritualPos, 32,
|
||||||
|
new PacketParticles(
|
||||||
|
(float) dustPos.getX() + 0.375F + this.world.rand.nextFloat() * 0.25F,
|
||||||
|
(float) dustPos.getY() + 0.1F,
|
||||||
|
(float) dustPos.getZ() + 0.375F + this.world.rand.nextFloat() * 0.25F,
|
||||||
|
(float) this.world.rand.nextGaussian() * 0.01F,
|
||||||
|
this.world.rand.nextFloat() * 0.005F + 0.01F,
|
||||||
|
(float) this.world.rand.nextGaussian() * 0.01F,
|
||||||
|
0xf4cb42, 2F, 100, 0F, false, true
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.timer >= this.recipe.time) {
|
||||||
|
this.recurseTreeDestruction(this.ritualPos, this.ritualPos);
|
||||||
|
//TODO Spawn item and stuff here, make some more nice particles probably
|
||||||
|
|
||||||
|
this.ritualPos = null;
|
||||||
|
this.involvedStands = null;
|
||||||
|
this.recipe = null;
|
||||||
|
this.timer = 0;
|
||||||
|
} else if (this.timer >= this.recipe.time / 2) {
|
||||||
|
for (TileEntityWoodStand stand : this.involvedStands.keySet()) {
|
||||||
|
//TODO Turn this into a single packet that just randomly spawns a certain amount of particles
|
||||||
|
for (int j = this.world.rand.nextInt(20) + 10; j >= 0; j--) {
|
||||||
|
PacketHandler.sendToAllAround(this.world, this.ritualPos, 32, new PacketParticles(
|
||||||
|
(float) stand.pos.getX() + 0.5F, (float) stand.pos.getY() + 1.25F, (float) stand.pos.getZ() + 0.5F,
|
||||||
|
(float) this.world.rand.nextGaussian() * 0.05F, this.world.rand.nextFloat() * 0.05F, (float) this.world.rand.nextGaussian() * 0.05F,
|
||||||
|
0xFF00FF, 1.5F, 50, 0F, false, true));
|
||||||
|
}
|
||||||
|
stand.stack = ItemStack.EMPTY;
|
||||||
|
stand.sendToClients();
|
||||||
|
}
|
||||||
|
this.involvedStands.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
this.ritualPos = null;
|
||||||
|
this.involvedStands = null;
|
||||||
|
this.recipe = null;
|
||||||
|
this.timer = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void recurseTreeDestruction(BlockPos pos, BlockPos start) {
|
||||||
|
if (pos.distanceSq(start) >= 15 * 15) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (EnumFacing facing : EnumFacing.VALUES) {
|
||||||
|
BlockPos offset = pos.offset(facing);
|
||||||
|
IBlockState state = this.world.getBlockState(offset);
|
||||||
|
if (state.getBlock() instanceof BlockLog || state.getBlock() instanceof BlockLeaves) {
|
||||||
|
this.world.setBlockToAir(offset);
|
||||||
|
//TODO Spawn particles around the block outline here, probably with the same packet as above
|
||||||
|
|
||||||
|
this.recurseTreeDestruction(offset, start);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isRitualOkay(World world) {
|
||||||
|
for (Map.Entry<TileEntityWoodStand, ItemStack> entry : this.involvedStands.entrySet()) {
|
||||||
|
TileEntityWoodStand stand = entry.getKey();
|
||||||
|
if (stand.isInvalid() || !stand.stack.isItemEqual(entry.getValue())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Helper.checkMultiblock(world, this.ritualPos, TileEntityWoodStand.GOLD_POWDER_POSITIONS, ModBlocks.GOLD_POWDER.getDefaultState(), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeNBT(NBTTagCompound compound, boolean syncing) {
|
||||||
|
super.writeNBT(compound, syncing);
|
||||||
|
compound.setTag("item", this.stack.writeToNBT(new NBTTagCompound()));
|
||||||
|
//TODO Save info about the current ritual somehow
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void readNBT(NBTTagCompound compound, boolean syncing) {
|
||||||
|
super.readNBT(compound, syncing);
|
||||||
|
this.stack = new ItemStack(compound.getCompoundTag("item"));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
package de.ellpeck.naturesaura.blocks.tiles.render;
|
||||||
|
|
||||||
|
import de.ellpeck.naturesaura.Helper;
|
||||||
|
import de.ellpeck.naturesaura.blocks.tiles.TileEntityWoodStand;
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.client.renderer.GlStateManager;
|
||||||
|
import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer;
|
||||||
|
import net.minecraft.item.ItemBlock;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
|
||||||
|
public class RenderWoodStand extends TileEntitySpecialRenderer<TileEntityWoodStand> {
|
||||||
|
@Override
|
||||||
|
public void render(TileEntityWoodStand tile, double x, double y, double z, float par5, int par6, float f) {
|
||||||
|
ItemStack stack = tile.stack;
|
||||||
|
if (!stack.isEmpty()) {
|
||||||
|
GlStateManager.pushMatrix();
|
||||||
|
GlStateManager.translate((float) x + 0.5F, (float) y + 1.125F, (float) z + 0.5F);
|
||||||
|
|
||||||
|
double boop = Minecraft.getSystemTime() / 800D;
|
||||||
|
GlStateManager.translate(0D, Math.sin(boop % (2 * Math.PI)) * 0.04, 0D);
|
||||||
|
GlStateManager.rotate((float) (((boop * 40D) % 360)), 0, 1, 0);
|
||||||
|
|
||||||
|
float scale = stack.getItem() instanceof ItemBlock ? 0.45F : 0.35F;
|
||||||
|
GlStateManager.scale(scale, scale, scale);
|
||||||
|
Helper.renderItemInWorld(stack);
|
||||||
|
|
||||||
|
GlStateManager.popMatrix();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,68 @@
|
||||||
|
package de.ellpeck.naturesaura.events;
|
||||||
|
|
||||||
|
import de.ellpeck.naturesaura.Helper;
|
||||||
|
import de.ellpeck.naturesaura.blocks.ModBlocks;
|
||||||
|
import de.ellpeck.naturesaura.blocks.tiles.TileEntityWoodStand;
|
||||||
|
import de.ellpeck.naturesaura.recipes.TreeRitualRecipe;
|
||||||
|
import net.minecraft.block.state.IBlockState;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.tileentity.TileEntity;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
import net.minecraftforge.event.terraingen.SaplingGrowTreeEvent;
|
||||||
|
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
public class TerrainGenEvents {
|
||||||
|
|
||||||
|
@SubscribeEvent
|
||||||
|
public void onTreeGrow(SaplingGrowTreeEvent event) {
|
||||||
|
World world = event.getWorld();
|
||||||
|
BlockPos pos = event.getPos();
|
||||||
|
if (!world.isRemote) {
|
||||||
|
if (Helper.checkMultiblock(world, pos, TileEntityWoodStand.GOLD_POWDER_POSITIONS, ModBlocks.GOLD_POWDER.getDefaultState(), true)) {
|
||||||
|
List<TileEntity> tileEntities = Helper.getTileEntitiesInArea(world, pos, 5);
|
||||||
|
List<TileEntityWoodStand> stands = new ArrayList<>();
|
||||||
|
List<ItemStack> usableItems = new ArrayList<>();
|
||||||
|
|
||||||
|
for (TileEntity tile : tileEntities) {
|
||||||
|
if (tile instanceof TileEntityWoodStand) {
|
||||||
|
TileEntityWoodStand stand = (TileEntityWoodStand) tile;
|
||||||
|
if (!stand.stack.isEmpty()) {
|
||||||
|
usableItems.add(stand.stack);
|
||||||
|
stands.add(stand);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
IBlockState sapling = world.getBlockState(pos);
|
||||||
|
ItemStack saplingStack = sapling.getBlock().getItem(world, pos, sapling);
|
||||||
|
if (!saplingStack.isEmpty()) {
|
||||||
|
for (TreeRitualRecipe recipe : TreeRitualRecipe.RECIPES) {
|
||||||
|
if (recipe.matchesItems(saplingStack, usableItems)) {
|
||||||
|
Map<TileEntityWoodStand, ItemStack> actuallyInvolved = new HashMap<>();
|
||||||
|
List<ItemStack> stillRequired = new ArrayList<>(Arrays.asList(recipe.items));
|
||||||
|
TileEntityWoodStand toPick = null;
|
||||||
|
|
||||||
|
for (TileEntityWoodStand stand : stands) {
|
||||||
|
int index = Helper.getItemIndex(stillRequired, stand.stack);
|
||||||
|
if (index >= 0) {
|
||||||
|
actuallyInvolved.put(stand, stand.stack);
|
||||||
|
stillRequired.remove(index);
|
||||||
|
|
||||||
|
if (toPick == null) {
|
||||||
|
toPick = stand;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
toPick.setRitual(pos, recipe, actuallyInvolved);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,178 +0,0 @@
|
||||||
package de.ellpeck.naturesaura.events;
|
|
||||||
|
|
||||||
import de.ellpeck.naturesaura.Helper;
|
|
||||||
import de.ellpeck.naturesaura.blocks.ModBlocks;
|
|
||||||
import de.ellpeck.naturesaura.packet.PacketHandler;
|
|
||||||
import de.ellpeck.naturesaura.packet.PacketParticleStream;
|
|
||||||
import de.ellpeck.naturesaura.packet.PacketParticles;
|
|
||||||
import de.ellpeck.naturesaura.recipes.TreeRitualRecipe;
|
|
||||||
import net.minecraft.block.BlockLog;
|
|
||||||
import net.minecraft.block.state.IBlockState;
|
|
||||||
import net.minecraft.entity.item.EntityItem;
|
|
||||||
import net.minecraft.item.ItemStack;
|
|
||||||
import net.minecraft.util.math.AxisAlignedBB;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
|
||||||
import net.minecraft.world.World;
|
|
||||||
import net.minecraftforge.common.MinecraftForge;
|
|
||||||
import net.minecraftforge.event.terraingen.SaplingGrowTreeEvent;
|
|
||||||
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
|
||||||
import net.minecraftforge.fml.common.gameevent.TickEvent;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
public class TreeRitualHandler {
|
|
||||||
|
|
||||||
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)
|
|
||||||
};
|
|
||||||
private static final List<ActiveRitual> ACTIVE_RITUALS = new ArrayList<>();
|
|
||||||
|
|
||||||
public TreeRitualHandler() {
|
|
||||||
MinecraftForge.TERRAIN_GEN_BUS.register(this);
|
|
||||||
MinecraftForge.EVENT_BUS.register(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@SubscribeEvent
|
|
||||||
public void onTreeGrow(SaplingGrowTreeEvent event) {
|
|
||||||
World world = event.getWorld();
|
|
||||||
BlockPos pos = event.getPos();
|
|
||||||
if (!world.isRemote) {
|
|
||||||
if (Helper.checkMultiblock(world, pos, GOLD_POWDER_POSITIONS, ModBlocks.GOLD_POWDER.getDefaultState(), true)) {
|
|
||||||
List<EntityItem> items = world.getEntitiesWithinAABB(EntityItem.class, new AxisAlignedBB(pos).grow(4, 0, 4));
|
|
||||||
List<ItemStack> usableItems = new ArrayList<>();
|
|
||||||
Set<BlockPos> usedLogs = new HashSet<>();
|
|
||||||
|
|
||||||
for (EntityItem item : items) {
|
|
||||||
BlockPos itemPos = item.getPosition();
|
|
||||||
ItemStack stack = item.getItem();
|
|
||||||
if (stack.getCount() == 1) {
|
|
||||||
if (!usedLogs.contains(itemPos) && world.getBlockState(itemPos.down()).getBlock() instanceof BlockLog) {
|
|
||||||
usedLogs.add(itemPos);
|
|
||||||
usableItems.add(stack);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
IBlockState sapling = world.getBlockState(pos);
|
|
||||||
ItemStack saplingStack = sapling.getBlock().getItem(world, pos, sapling);
|
|
||||||
if (!saplingStack.isEmpty()) {
|
|
||||||
for (TreeRitualRecipe recipe : TreeRitualRecipe.RECIPES) {
|
|
||||||
if (recipe.matchesItems(saplingStack, usableItems)) {
|
|
||||||
ActiveRitual ritual = new ActiveRitual(pos, items, recipe);
|
|
||||||
ACTIVE_RITUALS.add(ritual);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@SubscribeEvent
|
|
||||||
public void onWorldTick(TickEvent.WorldTickEvent event) {
|
|
||||||
World world = event.world;
|
|
||||||
if (!world.isRemote) {
|
|
||||||
for (int i = ACTIVE_RITUALS.size() - 1; i >= 0; i--) {
|
|
||||||
ActiveRitual ritual = ACTIVE_RITUALS.get(i);
|
|
||||||
if (ritual.isOkay(world)) {
|
|
||||||
ritual.timer++;
|
|
||||||
|
|
||||||
if (ritual.timer % 3 == 0) {
|
|
||||||
for (EntityItem item : ritual.involvedItems) {
|
|
||||||
PacketHandler.sendToAllAround(world, ritual.pos, 32, new PacketParticleStream(
|
|
||||||
(float) item.posX, (float) item.posY + 0.5F, (float) item.posZ,
|
|
||||||
ritual.pos.getX() + 0.5F, ritual.pos.getY() + 1.5F, ritual.pos.getZ() + 0.5F,
|
|
||||||
world.rand.nextFloat() * 0.05F + 0.05F, 0xFF00FF, world.rand.nextFloat() * 1F + 1F
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (ritual.timer % 5 == 0) {
|
|
||||||
for (BlockPos offset : GOLD_POWDER_POSITIONS) {
|
|
||||||
BlockPos dustPos = ritual.pos.add(offset);
|
|
||||||
PacketHandler.sendToAllAround(world, ritual.pos, 32,
|
|
||||||
new PacketParticles(
|
|
||||||
(float) dustPos.getX() + 0.375F + world.rand.nextFloat() * 0.25F,
|
|
||||||
(float) dustPos.getY() + 0.1F,
|
|
||||||
(float) dustPos.getZ() + 0.375F + world.rand.nextFloat() * 0.25F,
|
|
||||||
(float) world.rand.nextGaussian() * 0.01F,
|
|
||||||
world.rand.nextFloat() * 0.005F + 0.01F,
|
|
||||||
(float) world.rand.nextGaussian() * 0.01F,
|
|
||||||
0xf4cb42, 2F, 100, 0F, false, true
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ritual.timer >= ritual.recipe.time) {
|
|
||||||
ACTIVE_RITUALS.remove(i);
|
|
||||||
} else if (ritual.timer >= ritual.recipe.time / 2) {
|
|
||||||
for (EntityItem item : ritual.involvedItems) {
|
|
||||||
for (int j = world.rand.nextInt(20) + 10; j >= 0; j--) {
|
|
||||||
PacketHandler.sendToAllAround(world, ritual.pos, 32, new PacketParticles(
|
|
||||||
(float) item.posX, (float) item.posY + 0.5F, (float) item.posZ,
|
|
||||||
(float) world.rand.nextGaussian() * 0.05F, world.rand.nextFloat() * 0.05F, (float) world.rand.nextGaussian() * 0.05F,
|
|
||||||
0xFF00FF, 1.5F, 50, 0F, false, true));
|
|
||||||
}
|
|
||||||
item.setDead();
|
|
||||||
}
|
|
||||||
ritual.involvedItems.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
ACTIVE_RITUALS.remove(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void clear() {
|
|
||||||
ACTIVE_RITUALS.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class ActiveRitual {
|
|
||||||
|
|
||||||
private final BlockPos pos;
|
|
||||||
private final List<EntityItem> involvedItems;
|
|
||||||
private final TreeRitualRecipe recipe;
|
|
||||||
|
|
||||||
private int timer;
|
|
||||||
|
|
||||||
public ActiveRitual(BlockPos pos, List<EntityItem> involvedItems, TreeRitualRecipe recipe) {
|
|
||||||
this.pos = pos;
|
|
||||||
this.recipe = recipe;
|
|
||||||
|
|
||||||
this.involvedItems = new ArrayList<>();
|
|
||||||
for (EntityItem item : involvedItems) {
|
|
||||||
if (Helper.containsItem(this.recipe.items, item.getItem())) {
|
|
||||||
this.involvedItems.add(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isOkay(World world) {
|
|
||||||
for (EntityItem item : this.involvedItems) {
|
|
||||||
if (item.isDead || item.prevPosX != item.posX || item.prevPosY != item.posY || item.prevPosZ != item.posZ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return Helper.checkMultiblock(world, this.pos, GOLD_POWDER_POSITIONS, ModBlocks.GOLD_POWDER.getDefaultState(), true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,5 +1,7 @@
|
||||||
package de.ellpeck.naturesaura.proxy;
|
package de.ellpeck.naturesaura.proxy;
|
||||||
|
|
||||||
|
import de.ellpeck.naturesaura.blocks.tiles.TileEntityWoodStand;
|
||||||
|
import de.ellpeck.naturesaura.blocks.tiles.render.RenderWoodStand;
|
||||||
import de.ellpeck.naturesaura.events.ClientEvents;
|
import de.ellpeck.naturesaura.events.ClientEvents;
|
||||||
import de.ellpeck.naturesaura.particles.ParticleHandler;
|
import de.ellpeck.naturesaura.particles.ParticleHandler;
|
||||||
import de.ellpeck.naturesaura.particles.ParticleMagic;
|
import de.ellpeck.naturesaura.particles.ParticleMagic;
|
||||||
|
@ -16,6 +18,7 @@ import net.minecraft.util.ResourceLocation;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
import net.minecraftforge.client.model.ModelLoader;
|
import net.minecraftforge.client.model.ModelLoader;
|
||||||
import net.minecraftforge.common.MinecraftForge;
|
import net.minecraftforge.common.MinecraftForge;
|
||||||
|
import net.minecraftforge.fml.client.registry.ClientRegistry;
|
||||||
import net.minecraftforge.fml.common.event.FMLInitializationEvent;
|
import net.minecraftforge.fml.common.event.FMLInitializationEvent;
|
||||||
import net.minecraftforge.fml.common.event.FMLPostInitializationEvent;
|
import net.minecraftforge.fml.common.event.FMLPostInitializationEvent;
|
||||||
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
|
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
|
||||||
|
@ -29,7 +32,7 @@ public class ClientProxy implements IProxy {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void init(FMLInitializationEvent event) {
|
public void init(FMLInitializationEvent event) {
|
||||||
|
ClientRegistry.bindTileEntitySpecialRenderer(TileEntityWoodStand.class, new RenderWoodStand());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -25,7 +25,7 @@ public class TreeRitualRecipe {
|
||||||
public boolean matchesItems(ItemStack sapling, List<ItemStack> items) {
|
public boolean matchesItems(ItemStack sapling, List<ItemStack> items) {
|
||||||
if (this.saplingType.isItemEqual(sapling)) {
|
if (this.saplingType.isItemEqual(sapling)) {
|
||||||
for (ItemStack ingredient : this.items) {
|
for (ItemStack ingredient : this.items) {
|
||||||
if (!Helper.containsItem(items, ingredient)) {
|
if (Helper.getItemIndex(items, ingredient) < 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
{
|
||||||
|
"forge_marker": 1,
|
||||||
|
"defaults": {
|
||||||
|
"model": "naturesaura:wood_stand",
|
||||||
|
"textures": {
|
||||||
|
"texture": "minecraft:blocks/log_oak",
|
||||||
|
"top": "minecraft:blocks/log_oak_top",
|
||||||
|
"particle": "#texture"
|
||||||
|
},
|
||||||
|
"transform": "forge:default-block"
|
||||||
|
},
|
||||||
|
"variants": {
|
||||||
|
"normal": [{}],
|
||||||
|
"inventory": [{}]
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,7 +8,7 @@ tile.naturesaura.nature_altar.name=Natural Altar
|
||||||
tile.naturesaura.decayed_leaves.name=Decayed Leaves
|
tile.naturesaura.decayed_leaves.name=Decayed Leaves
|
||||||
tile.naturesaura.golden_leaves.name=Golden Leaves
|
tile.naturesaura.golden_leaves.name=Golden Leaves
|
||||||
tile.naturesaura.gold_powder.name=Gold Powder
|
tile.naturesaura.gold_powder.name=Gold Powder
|
||||||
tile.naturesaura.tree_ritual.name=Drained Dirt
|
tile.naturesaura.wood_stand.name=Wooden Stand
|
||||||
|
|
||||||
item.naturesaura.eye.name=Environmental Eye
|
item.naturesaura.eye.name=Environmental Eye
|
||||||
item.naturesaura.gold_fiber.name=Brilliant Fiber
|
item.naturesaura.gold_fiber.name=Brilliant Fiber
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
{
|
||||||
|
"elements": [
|
||||||
|
{
|
||||||
|
"from": [3, 0, 3],
|
||||||
|
"to": [13, 13, 13],
|
||||||
|
"faces": {
|
||||||
|
"down": {
|
||||||
|
"uv": [3, 3, 13, 13],
|
||||||
|
"texture": "#top",
|
||||||
|
"cullface": "down"
|
||||||
|
},
|
||||||
|
"up": {
|
||||||
|
"uv": [3, 3, 13, 13],
|
||||||
|
"texture": "#top"
|
||||||
|
},
|
||||||
|
"north": {
|
||||||
|
"uv": [3, 3, 13, 13],
|
||||||
|
"texture": "#texture",
|
||||||
|
"cullface": "north"
|
||||||
|
},
|
||||||
|
"south": {
|
||||||
|
"uv": [3, 3, 13, 13],
|
||||||
|
"texture": "#texture",
|
||||||
|
"cullface": "south"
|
||||||
|
},
|
||||||
|
"west": {
|
||||||
|
"uv": [3, 3, 13, 13],
|
||||||
|
"texture": "#texture",
|
||||||
|
"cullface": "west"
|
||||||
|
},
|
||||||
|
"east": {
|
||||||
|
"uv": [3, 3, 13, 13],
|
||||||
|
"texture": "#texture",
|
||||||
|
"cullface": "east"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
Loading…
Reference in a new issue