diff --git a/src/main/java/de/ellpeck/naturesaura/InternalHooks.java b/src/main/java/de/ellpeck/naturesaura/InternalHooks.java index 59a3eae0..f478dfdf 100644 --- a/src/main/java/de/ellpeck/naturesaura/InternalHooks.java +++ b/src/main/java/de/ellpeck/naturesaura/InternalHooks.java @@ -12,6 +12,7 @@ import net.minecraft.world.chunk.Chunk; import net.minecraftforge.items.IItemHandler; import org.apache.commons.lang3.mutable.MutableInt; import org.apache.commons.lang3.mutable.MutableObject; +import org.lwjgl.util.vector.Vector3f; import java.util.function.BiConsumer; @@ -46,8 +47,21 @@ public class InternalHooks implements NaturesAuraAPI.IInternalHooks { } @Override - public void spawnMagicParticle(World world, double posX, double posY, double posZ, double motionX, double motionY, double motionZ, int color, float scale, int maxAge, float gravity, boolean collision, boolean fade) { - NaturesAura.proxy.spawnMagicParticle(world, posX, posY, posZ, motionX, motionY, motionZ, color, scale, maxAge, gravity, collision, fade); + public void spawnMagicParticle(double posX, double posY, double posZ, double motionX, double motionY, double motionZ, int color, float scale, int maxAge, float gravity, boolean collision, boolean fade) { + NaturesAura.proxy.spawnMagicParticle(posX, posY, posZ, motionX, motionY, motionZ, color, scale, maxAge, gravity, collision, fade); + } + + @Override + public void spawnParticleStream(float startX, float startY, float startZ, float endX, float endY, float endZ, float speed, int color, float scale) { + Vector3f dir = new Vector3f(endX - startX, endY - startY, endZ - startZ); + if (dir.length() > 0) { + int maxAge = (int) (dir.length() / speed); + dir.normalise(); + + this.spawnMagicParticle(startX, startY, startZ, + dir.x * speed, dir.y * speed, dir.z * speed, + color, scale, maxAge, 0F, false, false); + } } @Override diff --git a/src/main/java/de/ellpeck/naturesaura/ModConfig.java b/src/main/java/de/ellpeck/naturesaura/ModConfig.java index 43270bc7..4cf19b51 100644 --- a/src/main/java/de/ellpeck/naturesaura/ModConfig.java +++ b/src/main/java/de/ellpeck/naturesaura/ModConfig.java @@ -21,6 +21,9 @@ public final class ModConfig { @Comment("Additional blocks that the Herbivorous Absorber can consume to generate Aura. Each entry needs to be formatted as modid:block[prop1=value1,...] where block state properties are optional") public String[] additionalHerbivorousAbsorberFlowers = new String[0]; + + @Comment("The amount of blocks that can be between two Aura Field Creators for them to be connectable and work together") + public int fieldCreatorRange = 8; } public static class Client { diff --git a/src/main/java/de/ellpeck/naturesaura/api/NaturesAuraAPI.java b/src/main/java/de/ellpeck/naturesaura/api/NaturesAuraAPI.java index 15c9ee03..34e6ff1e 100644 --- a/src/main/java/de/ellpeck/naturesaura/api/NaturesAuraAPI.java +++ b/src/main/java/de/ellpeck/naturesaura/api/NaturesAuraAPI.java @@ -141,7 +141,6 @@ public final class NaturesAuraAPI { * you want to send it from the server side, you need to create your own * packet. * - * @param world The world to spawn the particle in * @param posX The x position * @param posY The y position * @param posZ The z position @@ -157,7 +156,26 @@ public final class NaturesAuraAPI { * @param fade If the particle should slowly fade out or suddenly * disappear */ - void spawnMagicParticle(World world, double posX, double posY, double posZ, double motionX, double motionY, double motionZ, int color, float scale, int maxAge, float gravity, boolean collision, boolean fade); + void spawnMagicParticle(double posX, double posY, double posZ, double motionX, double motionY, double motionZ, int color, float scale, int maxAge, float gravity, boolean collision, boolean fade); + + /** + * This method can be used to spawn the magic particle effect used by + * Nature's Aura. The particle will be created to spawn at the start + * position and move towards the end position, dying when it reaches it. + * It will not have an effect on the client side, so if you want to send + * it from the server side, you need to create your own packet. + * + * @param startX The start x + * @param startY The start y + * @param startZ The start z + * @param endX The end x + * @param endY The end y + * @param endZ The end z + * @param speed The speed at which the particle should go + * @param color The color of the particle + * @param scale The scale of the particle + */ + void spawnParticleStream(float startX, float startY, float startZ, float endX, float endY, float endZ, float speed, int color, float scale); /** * @see IAuraChunk#getSpotsInArea(World, BlockPos, int, BiConsumer) diff --git a/src/main/java/de/ellpeck/naturesaura/api/internal/StubHooks.java b/src/main/java/de/ellpeck/naturesaura/api/internal/StubHooks.java index ff660be3..77b41ce4 100644 --- a/src/main/java/de/ellpeck/naturesaura/api/internal/StubHooks.java +++ b/src/main/java/de/ellpeck/naturesaura/api/internal/StubHooks.java @@ -15,7 +15,12 @@ public class StubHooks implements NaturesAuraAPI.IInternalHooks { } @Override - public void spawnMagicParticle(World world, double posX, double posY, double posZ, double motionX, double motionY, double motionZ, int color, float scale, int maxAge, float gravity, boolean collision, boolean fade) { + public void spawnMagicParticle(double posX, double posY, double posZ, double motionX, double motionY, double motionZ, int color, float scale, int maxAge, float gravity, boolean collision, boolean fade) { + + } + + @Override + public void spawnParticleStream(float startX, float startY, float startZ, float endX, float endY, float endZ, float speed, int color, float scale) { } diff --git a/src/main/java/de/ellpeck/naturesaura/blocks/BlockAncientLeaves.java b/src/main/java/de/ellpeck/naturesaura/blocks/BlockAncientLeaves.java index f0b447d1..4d489a1c 100644 --- a/src/main/java/de/ellpeck/naturesaura/blocks/BlockAncientLeaves.java +++ b/src/main/java/de/ellpeck/naturesaura/blocks/BlockAncientLeaves.java @@ -133,7 +133,7 @@ public class BlockAncientLeaves extends BlockLeaves implements TileEntity tile = worldIn.getTileEntity(pos); if (tile instanceof TileEntityAncientLeaves) { if (((TileEntityAncientLeaves) tile).getAuraContainer(null).getStoredAura() > 0) { - NaturesAuraAPI.instance().spawnMagicParticle(worldIn, + NaturesAuraAPI.instance().spawnMagicParticle( pos.getX() + rand.nextDouble(), pos.getY(), pos.getZ() + rand.nextDouble(), 0F, 0F, 0F, 0xc46df9, rand.nextFloat() * 2F + 0.5F, diff --git a/src/main/java/de/ellpeck/naturesaura/blocks/BlockContainerImpl.java b/src/main/java/de/ellpeck/naturesaura/blocks/BlockContainerImpl.java index d1bc367a..19d1a43f 100644 --- a/src/main/java/de/ellpeck/naturesaura/blocks/BlockContainerImpl.java +++ b/src/main/java/de/ellpeck/naturesaura/blocks/BlockContainerImpl.java @@ -5,6 +5,7 @@ import de.ellpeck.naturesaura.blocks.tiles.TileEntityImpl; import de.ellpeck.naturesaura.reg.IModItem; import de.ellpeck.naturesaura.reg.IModelProvider; import de.ellpeck.naturesaura.reg.ModRegistry; +import net.minecraft.block.Block; import net.minecraft.block.BlockContainer; import net.minecraft.block.material.Material; import net.minecraft.block.state.IBlockState; @@ -117,4 +118,30 @@ public class BlockContainerImpl extends BlockContainer implements IModItem, IMod if (tile instanceof TileEntityImpl) ((TileEntityImpl) tile).loadDataOnPlace(stack); } + + @Override + public void onBlockAdded(World worldIn, BlockPos pos, IBlockState state) { + this.updateRedstoneState(worldIn, pos); + } + + @Override + public void neighborChanged(IBlockState state, World worldIn, BlockPos pos, Block blockIn, BlockPos fromPos) { + this.updateRedstoneState(worldIn, pos); + } + + private void updateRedstoneState(World world, BlockPos pos) { + if (!world.isRemote) { + TileEntity tile = world.getTileEntity(pos); + if (tile instanceof TileEntityImpl) { + TileEntityImpl impl = (TileEntityImpl) tile; + boolean powered = world.getRedstonePowerFromNeighbors(pos) > 0; + boolean wasPowered = impl.isRedstonePowered; + if (powered && !wasPowered) { + impl.isRedstonePowered = true; + } else if (!powered && wasPowered) { + impl.isRedstonePowered = false; + } + } + } + } } \ No newline at end of file diff --git a/src/main/java/de/ellpeck/naturesaura/blocks/BlockFieldCreator.java b/src/main/java/de/ellpeck/naturesaura/blocks/BlockFieldCreator.java new file mode 100644 index 00000000..27538ff1 --- /dev/null +++ b/src/main/java/de/ellpeck/naturesaura/blocks/BlockFieldCreator.java @@ -0,0 +1,90 @@ +package de.ellpeck.naturesaura.blocks; + +import de.ellpeck.naturesaura.NaturesAura; +import de.ellpeck.naturesaura.api.NaturesAuraAPI; +import de.ellpeck.naturesaura.blocks.tiles.TileEntityFieldCreator; +import net.minecraft.block.SoundType; +import net.minecraft.block.material.Material; +import net.minecraft.block.state.IBlockState; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.EnumHand; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.text.TextComponentTranslation; +import net.minecraft.world.World; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +import java.util.Random; + +public class BlockFieldCreator extends BlockContainerImpl { + public BlockFieldCreator() { + super(Material.ROCK, "field_creator", TileEntityFieldCreator.class, "field_creator"); + this.setSoundType(SoundType.STONE); + this.setHardness(2F); + } + + @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 TileEntityFieldCreator) { + if (!worldIn.isRemote) { + String key = NaturesAura.MOD_ID + ":field_creator_pos"; + NBTTagCompound compound = playerIn.getEntityData(); + if (!playerIn.isSneaking() && compound.hasKey(key)) { + BlockPos stored = BlockPos.fromLong(compound.getLong(key)); + TileEntityFieldCreator creator = (TileEntityFieldCreator) tile; + if (!pos.equals(stored)) { + if (creator.isCloseEnough(stored)) { + TileEntity otherTile = worldIn.getTileEntity(stored); + if (otherTile instanceof TileEntityFieldCreator) { + creator.connectionOffset = stored.subtract(pos); + creator.isMain = true; + creator.sendToClients(); + + TileEntityFieldCreator otherCreator = (TileEntityFieldCreator) otherTile; + otherCreator.connectionOffset = pos.subtract(stored); + otherCreator.sendToClients(); + + compound.removeTag(key); + playerIn.sendStatusMessage(new TextComponentTranslation("info." + NaturesAura.MOD_ID + ".connected"), true); + } else + playerIn.sendStatusMessage(new TextComponentTranslation("info." + NaturesAura.MOD_ID + ".stored_pos_gone"), true); + } else + playerIn.sendStatusMessage(new TextComponentTranslation("info." + NaturesAura.MOD_ID + ".too_far"), true); + } else + playerIn.sendStatusMessage(new TextComponentTranslation("info." + NaturesAura.MOD_ID + ".same_position"), true); + } else { + compound.setLong(key, pos.toLong()); + playerIn.sendStatusMessage(new TextComponentTranslation("info." + NaturesAura.MOD_ID + ".stored_pos"), true); + } + } + return true; + } else + return false; + } + + @Override + @SideOnly(Side.CLIENT) + public void randomDisplayTick(IBlockState stateIn, World worldIn, BlockPos pos, Random rand) { + TileEntity tile = worldIn.getTileEntity(pos); + if (tile instanceof TileEntityFieldCreator) { + TileEntityFieldCreator creator = (TileEntityFieldCreator) tile; + if (creator.isCharged) { + BlockPos connected = creator.getConnectedPos(); + if (connected != null) + NaturesAuraAPI.instance().spawnParticleStream( + pos.getX() + rand.nextFloat(), + pos.getY() + rand.nextFloat(), + pos.getZ() + rand.nextFloat(), + connected.getX() + rand.nextFloat(), + connected.getY() + rand.nextFloat(), + connected.getZ() + rand.nextFloat(), + 0.65F, 0x4245f4, 1F + ); + } + } + } +} diff --git a/src/main/java/de/ellpeck/naturesaura/blocks/BlockFurnaceHeater.java b/src/main/java/de/ellpeck/naturesaura/blocks/BlockFurnaceHeater.java index 87138f12..72240e99 100644 --- a/src/main/java/de/ellpeck/naturesaura/blocks/BlockFurnaceHeater.java +++ b/src/main/java/de/ellpeck/naturesaura/blocks/BlockFurnaceHeater.java @@ -60,7 +60,7 @@ public class BlockFurnaceHeater extends BlockContainerImpl { z = facing.getXOffset() != 0 ? (0.35F + rand.nextFloat() * 0.3F) : facing.getZOffset() < 0 ? 1 : 0; } - NaturesAuraAPI.instance().spawnMagicParticle(worldIn, + NaturesAuraAPI.instance().spawnMagicParticle( pos.getX() + x, pos.getY() + y, pos.getZ() + z, (rand.nextFloat() * 0.016F + 0.01F) * facing.getXOffset(), (rand.nextFloat() * 0.016F + 0.01F) * facing.getYOffset(), diff --git a/src/main/java/de/ellpeck/naturesaura/blocks/BlockGoldenLeaves.java b/src/main/java/de/ellpeck/naturesaura/blocks/BlockGoldenLeaves.java index 3108f0bd..2f886c8d 100644 --- a/src/main/java/de/ellpeck/naturesaura/blocks/BlockGoldenLeaves.java +++ b/src/main/java/de/ellpeck/naturesaura/blocks/BlockGoldenLeaves.java @@ -67,7 +67,7 @@ public class BlockGoldenLeaves extends BlockLeaves implements @SideOnly(Side.CLIENT) public void randomDisplayTick(IBlockState stateIn, World worldIn, BlockPos pos, Random rand) { if (stateIn.getValue(STAGE) == HIGHEST_STAGE && rand.nextFloat() >= 0.75F) - NaturesAuraAPI.instance().spawnMagicParticle(worldIn, + NaturesAuraAPI.instance().spawnMagicParticle( pos.getX() + rand.nextFloat(), pos.getY() + rand.nextFloat(), pos.getZ() + rand.nextFloat(), diff --git a/src/main/java/de/ellpeck/naturesaura/blocks/ModBlocks.java b/src/main/java/de/ellpeck/naturesaura/blocks/ModBlocks.java index 579a5cf7..894a38e6 100644 --- a/src/main/java/de/ellpeck/naturesaura/blocks/ModBlocks.java +++ b/src/main/java/de/ellpeck/naturesaura/blocks/ModBlocks.java @@ -31,4 +31,5 @@ public final class ModBlocks { public static final Block FLOWER_GENERATOR = new BlockFlowerGenerator(); public static final Block PLACER = new BlockPlacer(); public static final Block HOPPER_UPGRADE = new BlockHopperUpgrade(); + public static final Block FIELD_CREATOR = new BlockFieldCreator(); } diff --git a/src/main/java/de/ellpeck/naturesaura/blocks/tiles/TileEntityFieldCreator.java b/src/main/java/de/ellpeck/naturesaura/blocks/tiles/TileEntityFieldCreator.java new file mode 100644 index 00000000..9ced3c8a --- /dev/null +++ b/src/main/java/de/ellpeck/naturesaura/blocks/tiles/TileEntityFieldCreator.java @@ -0,0 +1,187 @@ +package de.ellpeck.naturesaura.blocks.tiles; + +import de.ellpeck.naturesaura.ModConfig; +import de.ellpeck.naturesaura.api.aura.chunk.IAuraChunk; +import de.ellpeck.naturesaura.api.aura.type.IAuraType; +import de.ellpeck.naturesaura.packet.PacketHandler; +import de.ellpeck.naturesaura.packet.PacketParticleStream; +import net.minecraft.block.Block; +import net.minecraft.block.BlockLiquid; +import net.minecraft.block.state.IBlockState; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.ITickable; +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.WorldServer; +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 net.minecraftforge.fluids.IFluidBlock; + +public class TileEntityFieldCreator extends TileEntityImpl implements ITickable { + + public BlockPos connectionOffset; + public boolean isMain; + public boolean isCharged; + private int chargeTimer; + + @Override + public void update() { + if (this.world.isRemote || this.world.getTotalWorldTime() % 10 != 0) + return; + + BlockPos connectedPos = this.getConnectedPos(); + if (connectedPos == null) + return; + + TileEntity other = this.world.getTileEntity(connectedPos); + if (!this.isCloseEnough(connectedPos) + || !(other instanceof TileEntityFieldCreator) + || !this.pos.equals(((TileEntityFieldCreator) other).getConnectedPos())) { + this.connectionOffset = null; + this.chargeTimer = 0; + this.isCharged = false; + this.isMain = false; + this.sendToClients(); + return; + } + + if (!this.isMain) + return; + + TileEntityFieldCreator creator = (TileEntityFieldCreator) other; + if (!this.isRedstonePowered && !creator.isRedstonePowered) { + this.chargeTimer = 0; + if (this.isCharged) { + this.isCharged = false; + this.sendToClients(); + creator.isCharged = false; + creator.sendToClients(); + } + return; + } + + BlockPos spot = IAuraChunk.getHighestSpot(this.world, this.pos, 32, this.pos); + IAuraChunk chunk = IAuraChunk.getAuraChunk(this.world, spot); + + if (!this.isCharged) { + this.chargeTimer += 10; + if (this.chargeTimer >= 150) { + this.chargeTimer = 0; + + this.isCharged = true; + this.sendToClients(); + creator.isCharged = true; + creator.sendToClients(); + } + + chunk.drainAura(spot, 15); + this.sendParticles(); + } else { + if (this.world.getTotalWorldTime() % 20 == 0) + chunk.drainAura(spot, 1); + + Vec3d dist = new Vec3d( + this.pos.getX() - connectedPos.getX(), + this.pos.getY() - connectedPos.getY(), + this.pos.getZ() - connectedPos.getZ() + ); + 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--) { + Vec3d scaled = normal.scale(i); + BlockPos pos = connectedPos.add( + MathHelper.floor(scaled.x + 0.5F), + MathHelper.floor(scaled.y + 0.5F), + MathHelper.floor(scaled.z + 0.5F)); + + if (pos.equals(this.pos) || pos.equals(connectedPos)) + continue; + + IBlockState state = this.world.getBlockState(pos); + Block block = state.getBlock(); + if (!block.isAir(state, this.world, pos) + && !(block instanceof BlockLiquid) && !(block instanceof IFluidBlock) + && state.getBlockHardness(this.world, pos) >= 0F) { + + FakePlayer fake = FakePlayerFactory.getMinecraft((WorldServer) this.world); + if (!MinecraftForge.EVENT_BUS.post(new BlockEvent.BreakEvent(this.world, pos, state, fake))) { + NonNullList drops = NonNullList.create(); + block.getDrops(drops, this.world, pos, state, 0); + float chance = ForgeEventFactory.fireBlockHarvesting(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, 5); + this.sendParticles(); + } + } + } + } + } + } + + private void sendParticles() { + for (int j = 0; j < 2; j++) { + BlockPos p = j == 0 ? this.pos : this.getConnectedPos(); + PacketHandler.sendToAllAround(this.world, p, 32, new PacketParticleStream( + p.getX() + (float) this.world.rand.nextGaussian() * 3F, + p.getY() + 1 + this.world.rand.nextFloat() * 3F, + p.getZ() + (float) this.world.rand.nextGaussian() * 3F, + p.getX() + this.world.rand.nextFloat(), + p.getY() + this.world.rand.nextFloat(), + p.getZ() + this.world.rand.nextFloat(), + this.world.rand.nextFloat() * 0.07F + 0.07F, IAuraType.forWorld(this.world).getColor(), this.world.rand.nextFloat() + 0.5F + )); + } + } + + public boolean isCloseEnough(BlockPos pos) { + int range = ModConfig.general.fieldCreatorRange + 1; + return this.pos.distanceSq(pos) <= range * range; + } + + public BlockPos getConnectedPos() { + if (this.connectionOffset == null) + return null; + return this.pos.add(this.connectionOffset); + } + + @Override + public void writeNBT(NBTTagCompound compound, SaveType type) { + super.writeNBT(compound, type); + if (type != SaveType.BLOCK) { + if (this.connectionOffset != null) + compound.setLong("connection", this.connectionOffset.toLong()); + compound.setBoolean("main", this.isMain); + compound.setBoolean("charged", this.isCharged); + + if (type == SaveType.TILE) + compound.setInteger("timer", this.chargeTimer); + } + } + + @Override + public void readNBT(NBTTagCompound compound, SaveType type) { + super.readNBT(compound, type); + if (type != SaveType.BLOCK) { + if (compound.hasKey("connection")) + this.connectionOffset = BlockPos.fromLong(compound.getLong("connection")); + else + this.connectionOffset = null; + this.isMain = compound.getBoolean("main"); + this.isCharged = compound.getBoolean("charged"); + + if (type == SaveType.TILE) + this.chargeTimer = compound.getInteger("timer"); + } + } +} 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 775440f3..9416ad88 100644 --- a/src/main/java/de/ellpeck/naturesaura/blocks/tiles/TileEntityFurnaceHeater.java +++ b/src/main/java/de/ellpeck/naturesaura/blocks/tiles/TileEntityFurnaceHeater.java @@ -2,6 +2,7 @@ package de.ellpeck.naturesaura.blocks.tiles; import de.ellpeck.naturesaura.Helper; 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; @@ -51,7 +52,7 @@ public class TileEntityFurnaceHeater extends TileEntityImpl implements ITickable tilePos.getX() + this.world.rand.nextFloat(), tilePos.getY() + this.world.rand.nextFloat(), tilePos.getZ() + this.world.rand.nextFloat(), - this.world.rand.nextFloat() * 0.07F + 0.07F, 0x89cc37, this.world.rand.nextFloat() + 0.5F + this.world.rand.nextFloat() * 0.07F + 0.07F, IAuraType.forWorld(this.world).getColor(), this.world.rand.nextFloat() + 0.5F )); } } diff --git a/src/main/java/de/ellpeck/naturesaura/blocks/tiles/TileEntityImpl.java b/src/main/java/de/ellpeck/naturesaura/blocks/tiles/TileEntityImpl.java index 203c8be1..befc31a2 100644 --- a/src/main/java/de/ellpeck/naturesaura/blocks/tiles/TileEntityImpl.java +++ b/src/main/java/de/ellpeck/naturesaura/blocks/tiles/TileEntityImpl.java @@ -23,6 +23,9 @@ import net.minecraftforge.items.IItemHandlerModifiable; import javax.annotation.Nullable; public class TileEntityImpl extends TileEntity { + + public boolean isRedstonePowered; + @Override public boolean shouldRefresh(World world, BlockPos pos, IBlockState oldState, IBlockState newState) { return oldState.getBlock() != newState.getBlock(); @@ -40,13 +43,17 @@ public class TileEntityImpl extends TileEntity { } public void writeNBT(NBTTagCompound compound, SaveType type) { - if (type != SaveType.BLOCK) + if (type != SaveType.BLOCK) { super.writeToNBT(compound); + compound.setBoolean("redstone", this.isRedstonePowered); + } } public void readNBT(NBTTagCompound compound, SaveType type) { - if (type != SaveType.BLOCK) + if (type != SaveType.BLOCK) { super.readFromNBT(compound); + this.isRedstonePowered = compound.getBoolean("redstone"); + } } @Override diff --git a/src/main/java/de/ellpeck/naturesaura/blocks/tiles/TileEntityNatureAltar.java b/src/main/java/de/ellpeck/naturesaura/blocks/tiles/TileEntityNatureAltar.java index 77cc11c6..2b855535 100644 --- a/src/main/java/de/ellpeck/naturesaura/blocks/tiles/TileEntityNatureAltar.java +++ b/src/main/java/de/ellpeck/naturesaura/blocks/tiles/TileEntityNatureAltar.java @@ -152,22 +152,22 @@ public class TileEntityNatureAltar extends TileEntityImpl implements ITickable { if (rand.nextFloat() >= 0.7F) { int fourths = this.container.getMaxAura() / 4; if (this.container.getStoredAura() > 0) { - NaturesAuraAPI.instance().spawnMagicParticle(this.world, + NaturesAuraAPI.instance().spawnMagicParticle( this.pos.getX() - 4F + rand.nextFloat(), this.pos.getY() + 3F, this.pos.getZ() + rand.nextFloat(), 0F, 0F, 0F, this.container.getAuraColor(), rand.nextFloat() * 3F + 1F, rand.nextInt(100) + 50, -0.05F, true, true); } if (this.container.getStoredAura() >= fourths) { - NaturesAuraAPI.instance().spawnMagicParticle(this.world, + NaturesAuraAPI.instance().spawnMagicParticle( this.pos.getX() + 4F + rand.nextFloat(), this.pos.getY() + 3F, this.pos.getZ() + rand.nextFloat(), 0F, 0F, 0F, this.container.getAuraColor(), rand.nextFloat() * 3F + 1F, rand.nextInt(100) + 50, -0.05F, true, true); } if (this.container.getStoredAura() >= fourths * 2) { - NaturesAuraAPI.instance().spawnMagicParticle(this.world, + NaturesAuraAPI.instance().spawnMagicParticle( this.pos.getX() + rand.nextFloat(), this.pos.getY() + 3F, this.pos.getZ() - 4F + rand.nextFloat(), 0F, 0F, 0F, this.container.getAuraColor(), rand.nextFloat() * 3F + 1F, rand.nextInt(100) + 50, -0.05F, true, true); } if (this.container.getStoredAura() >= fourths * 3) { - NaturesAuraAPI.instance().spawnMagicParticle(this.world, + NaturesAuraAPI.instance().spawnMagicParticle( this.pos.getX() + rand.nextFloat(), this.pos.getY() + 3F, this.pos.getZ() + 4F + rand.nextFloat(), 0F, 0F, 0F, this.container.getAuraColor(), rand.nextFloat() * 3F + 1F, rand.nextInt(100) + 50, -0.05F, true, true); } diff --git a/src/main/java/de/ellpeck/naturesaura/packet/PacketParticleStream.java b/src/main/java/de/ellpeck/naturesaura/packet/PacketParticleStream.java index 2892a37d..833ed626 100644 --- a/src/main/java/de/ellpeck/naturesaura/packet/PacketParticleStream.java +++ b/src/main/java/de/ellpeck/naturesaura/packet/PacketParticleStream.java @@ -3,13 +3,11 @@ package de.ellpeck.naturesaura.packet; import de.ellpeck.naturesaura.NaturesAura; import de.ellpeck.naturesaura.api.NaturesAuraAPI; import io.netty.buffer.ByteBuf; -import net.minecraft.client.Minecraft; import net.minecraftforge.fml.common.network.simpleimpl.IMessage; import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler; import net.minecraftforge.fml.common.network.simpleimpl.MessageContext; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; -import org.lwjgl.util.vector.Vector3f; public class PacketParticleStream implements IMessage { @@ -72,21 +70,10 @@ public class PacketParticleStream implements IMessage { @Override @SideOnly(Side.CLIENT) public IMessage onMessage(PacketParticleStream message, MessageContext ctx) { - NaturesAura.proxy.scheduleTask(() -> { - Vector3f dir = new Vector3f( - message.endX - message.startX, - message.endY - message.startY, - message.endZ - message.startZ); - if (dir.length() > 0) { - int maxAge = (int) (dir.length() / message.speed); - dir.normalise(); - - NaturesAuraAPI.instance().spawnMagicParticle(Minecraft.getMinecraft().world, - message.startX, message.startY, message.startZ, - dir.x * message.speed, dir.y * message.speed, dir.z * message.speed, - message.color, message.scale, maxAge, 0F, false, false); - } - }); + NaturesAura.proxy.scheduleTask(() -> NaturesAuraAPI.instance().spawnParticleStream( + message.startX, message.startY, message.startZ, + message.endX, message.endY, message.endZ, + message.speed, message.color, message.scale)); return null; } diff --git a/src/main/java/de/ellpeck/naturesaura/packet/PacketParticles.java b/src/main/java/de/ellpeck/naturesaura/packet/PacketParticles.java index 078d44a7..a2e5b2ea 100644 --- a/src/main/java/de/ellpeck/naturesaura/packet/PacketParticles.java +++ b/src/main/java/de/ellpeck/naturesaura/packet/PacketParticles.java @@ -75,7 +75,7 @@ public class PacketParticles implements IMessage { Multiblocks.TREE_RITUAL.forEach(pos, 'G', (dustPos, matcher) -> { IBlockState state = world.getBlockState(dustPos); AxisAlignedBB box = state.getBoundingBox(world, dustPos); - NaturesAuraAPI.instance().spawnMagicParticle(world, + NaturesAuraAPI.instance().spawnMagicParticle( dustPos.getX() + box.minX + (box.maxX - box.minX) * world.rand.nextFloat(), dustPos.getY() + 0.1F, dustPos.getZ() + box.minZ + (box.maxZ - box.minZ) * world.rand.nextFloat(), @@ -88,7 +88,7 @@ public class PacketParticles implements IMessage { break; case 1: // Tree ritual: Consuming item for (int i = world.rand.nextInt(20) + 10; i >= 0; i--) { - NaturesAuraAPI.instance().spawnMagicParticle(world, + NaturesAuraAPI.instance().spawnMagicParticle( message.posX + 0.5F, message.posY + 0.9F, message.posZ + 0.5F, (float) world.rand.nextGaussian() * 0.04F, world.rand.nextFloat() * 0.04F, (float) world.rand.nextGaussian() * 0.04F, 0x89cc37, 1.5F, 25, 0F, false, true); @@ -96,7 +96,7 @@ public class PacketParticles implements IMessage { break; case 2: // Tree ritual: Tree disappearing for (int i = world.rand.nextInt(5) + 3; i >= 0; i--) { - NaturesAuraAPI.instance().spawnMagicParticle(world, + NaturesAuraAPI.instance().spawnMagicParticle( message.posX + world.rand.nextFloat(), message.posY + world.rand.nextFloat(), message.posZ + world.rand.nextFloat(), 0F, 0F, 0F, 0x33FF33, 1F, 50, 0F, false, true); @@ -104,7 +104,7 @@ public class PacketParticles implements IMessage { break; case 3: // Tree ritual: Spawn result item for (int i = world.rand.nextInt(10) + 10; i >= 0; i--) { - NaturesAuraAPI.instance().spawnMagicParticle(world, + NaturesAuraAPI.instance().spawnMagicParticle( message.posX, message.posY, message.posZ, world.rand.nextGaussian() * 0.1F, world.rand.nextGaussian() * 0.1F, world.rand.nextGaussian() * 0.1F, 0x89cc37, 2F, 100, 0F, true, true); @@ -112,7 +112,7 @@ public class PacketParticles implements IMessage { break; case 4: // Nature altar: Conversion for (int i = world.rand.nextInt(5) + 2; i >= 0; i--) { - NaturesAuraAPI.instance().spawnMagicParticle(world, + NaturesAuraAPI.instance().spawnMagicParticle( message.posX + 0.25F + world.rand.nextFloat() * 0.5F, message.posY + 0.9F + 0.25F * world.rand.nextFloat(), message.posZ + 0.25F + world.rand.nextFloat() * 0.5F, @@ -124,7 +124,7 @@ public class PacketParticles implements IMessage { int color = message.data[0]; boolean disperse = message.data[1] > 0; for (int i = world.rand.nextInt(5) + 5; i >= 0; i--) { - NaturesAuraAPI.instance().spawnMagicParticle(world, + NaturesAuraAPI.instance().spawnMagicParticle( message.posX + world.rand.nextFloat(), message.posY + 1.1F, message.posZ + world.rand.nextFloat(), @@ -134,7 +134,7 @@ public class PacketParticles implements IMessage { if (disperse) for (int x = -1; x <= 1; x += 2) for (int z = -1; z <= 1; z += 2) { - NaturesAuraAPI.instance().spawnMagicParticle(world, + NaturesAuraAPI.instance().spawnMagicParticle( message.posX + x * 3 + 0.5F, message.posY + 2.5, message.posZ + z * 3 + 0.5F, @@ -147,7 +147,7 @@ public class PacketParticles implements IMessage { break; case 6: // Plant boost effect for (int i = world.rand.nextInt(20) + 15; i >= 0; i--) - NaturesAuraAPI.instance().spawnMagicParticle(world, + NaturesAuraAPI.instance().spawnMagicParticle( message.posX + world.rand.nextFloat(), message.posY + 0.25F + world.rand.nextFloat() * 0.5F, message.posZ + world.rand.nextFloat(), @@ -158,7 +158,7 @@ public class PacketParticles implements IMessage { case 7: // Flower generator consumation color = message.data[0]; for (int i = world.rand.nextInt(10) + 10; i >= 0; i--) - NaturesAuraAPI.instance().spawnMagicParticle(world, + NaturesAuraAPI.instance().spawnMagicParticle( message.posX + 0.25F + world.rand.nextFloat() * 0.5F, message.posY + 0.25F + world.rand.nextFloat() * 0.5F, message.posZ + 0.25F + world.rand.nextFloat() * 0.5F, @@ -169,7 +169,7 @@ public class PacketParticles implements IMessage { break; case 8: // Flower generator aura creation for (int i = world.rand.nextInt(10) + 5; i >= 0; i--) - NaturesAuraAPI.instance().spawnMagicParticle(world, + NaturesAuraAPI.instance().spawnMagicParticle( message.posX + 0.25F + world.rand.nextFloat() * 0.5F, message.posY + 1.01F, message.posZ + 0.25F + world.rand.nextFloat() * 0.5F, @@ -183,7 +183,7 @@ public class PacketParticles implements IMessage { boolean side = world.rand.nextBoolean(); float x = side ? world.rand.nextFloat() : (world.rand.nextBoolean() ? 1.1F : -0.1F); float z = !side ? world.rand.nextFloat() : (world.rand.nextBoolean() ? 1.1F : -0.1F); - NaturesAuraAPI.instance().spawnMagicParticle(world, + NaturesAuraAPI.instance().spawnMagicParticle( message.posX + x, message.posY + 0.1F + world.rand.nextFloat() * 0.98F, message.posZ + z, 0F, 0F, 0F, 0xad7a37, world.rand.nextFloat() + 1F, 50, 0F, true, true); @@ -191,7 +191,7 @@ public class PacketParticles implements IMessage { break; case 10: // Hopper upgrade picking up for (int i = world.rand.nextInt(20) + 10; i >= 0; i--) - NaturesAuraAPI.instance().spawnMagicParticle(world, + NaturesAuraAPI.instance().spawnMagicParticle( message.posX, message.posY + 0.45F, message.posZ, world.rand.nextGaussian() * 0.015F, world.rand.nextGaussian() * 0.015F, @@ -201,7 +201,7 @@ public class PacketParticles implements IMessage { case 11: // Shockwave creator particles for (int i = 0; i < 360; i += 2) { double rad = Math.toRadians(i); - NaturesAuraAPI.instance().spawnMagicParticle(world, + NaturesAuraAPI.instance().spawnMagicParticle( message.posX, message.posY + 0.01F, message.posZ, (float) Math.sin(rad) * 0.65F, 0F, diff --git a/src/main/java/de/ellpeck/naturesaura/proxy/ClientProxy.java b/src/main/java/de/ellpeck/naturesaura/proxy/ClientProxy.java index 04ef186f..bb60f861 100644 --- a/src/main/java/de/ellpeck/naturesaura/proxy/ClientProxy.java +++ b/src/main/java/de/ellpeck/naturesaura/proxy/ClientProxy.java @@ -4,7 +4,6 @@ import de.ellpeck.naturesaura.blocks.tiles.TileEntityNatureAltar; import de.ellpeck.naturesaura.blocks.tiles.TileEntityWoodStand; import de.ellpeck.naturesaura.blocks.tiles.render.RenderNatureAltar; import de.ellpeck.naturesaura.blocks.tiles.render.RenderWoodStand; -import de.ellpeck.naturesaura.compat.Compat; import de.ellpeck.naturesaura.events.ClientEvents; import de.ellpeck.naturesaura.particles.ParticleHandler; import de.ellpeck.naturesaura.particles.ParticleMagic; @@ -19,7 +18,6 @@ import net.minecraft.client.renderer.color.ItemColors; import net.minecraft.client.renderer.entity.RenderPlayer; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; -import net.minecraft.world.World; import net.minecraftforge.client.model.ModelLoader; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.fml.client.registry.ClientRegistry; @@ -77,8 +75,11 @@ public class ClientProxy implements IProxy { } @Override - public void spawnMagicParticle(World world, double posX, double posY, double posZ, double motionX, double motionY, double motionZ, int color, float scale, int maxAge, float gravity, boolean collision, boolean fade) { - ParticleHandler.spawnParticle(() -> new ParticleMagic(world, posX, posY, posZ, motionX, motionY, motionZ, color, scale, maxAge, gravity, collision, fade), posX, posY, posZ, 32); + public void spawnMagicParticle(double posX, double posY, double posZ, double motionX, double motionY, double motionZ, int color, float scale, int maxAge, float gravity, boolean collision, boolean fade) { + ParticleHandler.spawnParticle(() -> new ParticleMagic(Minecraft.getMinecraft().world, + posX, posY, posZ, + motionX, motionY, motionZ, + color, scale, maxAge, gravity, collision, fade), posX, posY, posZ, 32); } @Override diff --git a/src/main/java/de/ellpeck/naturesaura/proxy/IProxy.java b/src/main/java/de/ellpeck/naturesaura/proxy/IProxy.java index 80a5d8f5..31f4fbfc 100644 --- a/src/main/java/de/ellpeck/naturesaura/proxy/IProxy.java +++ b/src/main/java/de/ellpeck/naturesaura/proxy/IProxy.java @@ -23,7 +23,7 @@ public interface IProxy { void addColorProvidingBlock(IColorProvidingBlock block); - void spawnMagicParticle(World world, double posX, double posY, double posZ, double motionX, double motionY, double motionZ, int color, float scale, int maxAge, float gravity, boolean collision, boolean fade); + void spawnMagicParticle(double posX, double posY, double posZ, double motionX, double motionY, double motionZ, int color, float scale, int maxAge, float gravity, boolean collision, boolean fade); void scheduleTask(Runnable runnable); } diff --git a/src/main/java/de/ellpeck/naturesaura/proxy/ServerProxy.java b/src/main/java/de/ellpeck/naturesaura/proxy/ServerProxy.java index 0e8d5086..6ad77fd2 100644 --- a/src/main/java/de/ellpeck/naturesaura/proxy/ServerProxy.java +++ b/src/main/java/de/ellpeck/naturesaura/proxy/ServerProxy.java @@ -43,7 +43,7 @@ public class ServerProxy implements IProxy { } @Override - public void spawnMagicParticle(World world, double posX, double posY, double posZ, double motionX, double motionY, double motionZ, int color, float scale, int maxAge, float gravity, boolean collision, boolean fade) { + public void spawnMagicParticle(double posX, double posY, double posZ, double motionX, double motionY, double motionZ, int color, float scale, int maxAge, float gravity, boolean collision, boolean fade) { } diff --git a/src/main/resources/assets/naturesaura/lang/en_US.lang b/src/main/resources/assets/naturesaura/lang/en_US.lang index b072bd82..9b94ad16 100644 --- a/src/main/resources/assets/naturesaura/lang/en_US.lang +++ b/src/main/resources/assets/naturesaura/lang/en_US.lang @@ -56,6 +56,11 @@ container.naturesaura.altar.name=Natural Altar Infusion 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 +info.naturesaura.stored_pos=You jotted down the position +info.naturesaura.connected=You made a connection +info.naturesaura.same_position=This seems to be the position from your notes... +info.naturesaura.too_far=The distance seems too great... +info.naturesaura.stored_pos_gone=Your notes seem out of date... advancement.naturesaura.root=Nature's Aura advancement.naturesaura.root.desc=Becoming a magical botanist