diff --git a/src/main/java/de/ellpeck/naturesaura/blocks/BlockFireworkGenerator.java b/src/main/java/de/ellpeck/naturesaura/blocks/BlockFireworkGenerator.java new file mode 100644 index 00000000..a8d66f99 --- /dev/null +++ b/src/main/java/de/ellpeck/naturesaura/blocks/BlockFireworkGenerator.java @@ -0,0 +1,10 @@ +package de.ellpeck.naturesaura.blocks; + +import de.ellpeck.naturesaura.blocks.tiles.TileEntityFireworkGenerator; +import net.minecraft.block.material.Material; + +public class BlockFireworkGenerator extends BlockContainerImpl { + public BlockFireworkGenerator() { + super(Material.ROCK, "firework_generator", TileEntityFireworkGenerator.class, "firework_generator"); + } +} diff --git a/src/main/java/de/ellpeck/naturesaura/blocks/ModBlocks.java b/src/main/java/de/ellpeck/naturesaura/blocks/ModBlocks.java index 5bfcedc7..7370421d 100644 --- a/src/main/java/de/ellpeck/naturesaura/blocks/ModBlocks.java +++ b/src/main/java/de/ellpeck/naturesaura/blocks/ModBlocks.java @@ -51,4 +51,5 @@ public final class ModBlocks { public static final Block GENERATOR_LIMIT_REMOVER = new BlockImpl("generator_limit_remover", Material.ROCK).setSoundType(SoundType.STONE).setHardness(2F); public static final Block ENDER_CRATE = new BlockEnderCrate(); public static final Block POWDER_PLACER = new BlockPowderPlacer(); + public static final Block FIREWORK_GENERATOR = new BlockFireworkGenerator(); } diff --git a/src/main/java/de/ellpeck/naturesaura/blocks/tiles/TileEntityFireworkGenerator.java b/src/main/java/de/ellpeck/naturesaura/blocks/tiles/TileEntityFireworkGenerator.java new file mode 100644 index 00000000..70164aa4 --- /dev/null +++ b/src/main/java/de/ellpeck/naturesaura/blocks/tiles/TileEntityFireworkGenerator.java @@ -0,0 +1,127 @@ +package de.ellpeck.naturesaura.blocks.tiles; + +import com.google.common.primitives.Ints; +import de.ellpeck.naturesaura.api.aura.chunk.IAuraChunk; +import de.ellpeck.naturesaura.packet.PacketHandler; +import de.ellpeck.naturesaura.packet.PacketParticles; +import net.minecraft.entity.item.EntityFireworkRocket; +import net.minecraft.entity.item.EntityItem; +import net.minecraft.init.Items; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTBase; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; +import net.minecraft.util.EntitySelectors; +import net.minecraft.util.ITickable; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +public class TileEntityFireworkGenerator extends TileEntityImpl implements ITickable { + + private EntityFireworkRocket trackedEntity; + private ItemStack trackedItem; + private int toRelease; + private int releaseTimer; + + @Override + public void update() { + if (!this.world.isRemote) { + if (this.world.getTotalWorldTime() % 10 == 0) { + List items = this.world.getEntitiesWithinAABB(EntityItem.class, + new AxisAlignedBB(this.pos).grow(4), EntitySelectors.IS_ALIVE); + for (EntityItem item : items) { + if (item.cannotPickup()) + continue; + ItemStack stack = item.getItem(); + if (stack.isEmpty() || stack.getItem() != Items.FIREWORKS) + continue; + if (this.trackedEntity == null && this.releaseTimer <= 0) { + EntityFireworkRocket entity = new EntityFireworkRocket(this.world, item.posX, item.posY, item.posZ, stack); + this.trackedEntity = entity; + this.trackedItem = stack; + this.world.spawnEntity(entity); + } + stack.shrink(1); + if (stack.isEmpty()) + item.setDead(); + else + item.setItem(stack); + } + } + + if (this.trackedEntity != null && this.trackedEntity.isDead) { + float generateFactor = 0; + Set usedColors = new HashSet<>(); + + NBTTagCompound compound = this.trackedItem.getTagCompound(); + NBTTagCompound fireworks = compound.getCompoundTag("Fireworks"); + + NBTTagList explosions = fireworks.getTagList("Explosions", 10); + if (!explosions.isEmpty()) { + int flightTime = fireworks.getInteger("Flight"); + generateFactor += flightTime; + + for (NBTBase base : explosions) { + NBTTagCompound explosion = (NBTTagCompound) base; + generateFactor += 1.5F; + + boolean flicker = explosion.getBoolean("Flicker"); + if (flicker) + generateFactor += 1; + + boolean trail = explosion.getBoolean("Trail"); + if (trail) + generateFactor += 8; + + byte type = explosion.getByte("Type"); + generateFactor += new float[]{0, 1, 0.5F, 20, 0.5F}[type]; + + Set colors = new HashSet<>(); + for (int color : explosion.getIntArray("Colors")) { + usedColors.add(color); + colors.add(color); + } + generateFactor += 0.75F * colors.size(); + } + } + + int toAdd = MathHelper.ceil(generateFactor * 10000F); + if (this.canGenerateRightNow(35, toAdd)) { + this.toRelease = toAdd; + this.releaseTimer = 80; + } + + List data = new ArrayList<>(); + data.add(this.pos.getX()); + data.add(this.pos.getY()); + data.add(this.pos.getZ()); + data.addAll(usedColors); + PacketHandler.sendToAllLoaded(this.world, this.pos, new PacketParticles( + (float) this.trackedEntity.posX, (float) this.trackedEntity.posY, (float) this.trackedEntity.posZ, + 24, Ints.toArray(data))); + + this.trackedEntity = null; + this.trackedItem = null; + } + + if (this.releaseTimer > 0) { + this.releaseTimer--; + if (this.releaseTimer <= 0) { + while (this.toRelease > 0) { + BlockPos spot = IAuraChunk.getLowestSpot(this.world, this.pos, 35, this.pos); + this.toRelease -= IAuraChunk.getAuraChunk(this.world, spot).storeAura(spot, this.toRelease); + } + + PacketHandler.sendToAllLoaded(this.world, this.pos, + new PacketParticles(this.pos.getX(), this.pos.getY(), this.pos.getZ(), 8)); + } + } + } + } +} diff --git a/src/main/java/de/ellpeck/naturesaura/packet/PacketParticles.java b/src/main/java/de/ellpeck/naturesaura/packet/PacketParticles.java index 7eddd4f9..629b10e1 100644 --- a/src/main/java/de/ellpeck/naturesaura/packet/PacketParticles.java +++ b/src/main/java/de/ellpeck/naturesaura/packet/PacketParticles.java @@ -169,7 +169,7 @@ public class PacketParticles implements IMessage { world.rand.nextGaussian() * 0.02F, color, world.rand.nextFloat() * 2F + 1F, 25, 0F, false, true); break; - case 8: // Flower generator aura creation + case 8: // Flower generator, firework generator aura creation for (int i = world.rand.nextInt(10) + 5; i >= 0; i--) NaturesAuraAPI.instance().spawnMagicParticle( message.posX + 0.25F + world.rand.nextFloat() * 0.5F, @@ -387,6 +387,22 @@ public class PacketParticles implements IMessage { world.rand.nextGaussian() * 0.01F, 0x5ccc30, 1F + world.rand.nextFloat() * 1.5F, 40, 0F, true, true); break; + case 24: // Firework generator + int goalX = message.data[0]; + int goalY = message.data[1]; + int goalZ = message.data[2]; + NaturesAuraAPI.instance().setParticleSpawnRange(64); + for (int i = world.rand.nextInt(30) + 30; i >= 0; i--) + NaturesAuraAPI.instance().spawnParticleStream( + message.posX + (float) world.rand.nextGaussian(), + message.posY + (float) world.rand.nextGaussian(), + message.posZ + (float) world.rand.nextGaussian(), + goalX + 0.25F + world.rand.nextFloat() * 0.5F, + goalY + 0.25F + world.rand.nextFloat() * 0.5F, + goalZ + 0.25F + world.rand.nextFloat() * 0.5F, + 0.65F, message.data[3 + world.rand.nextInt(message.data.length - 3)], 1F); + NaturesAuraAPI.instance().setParticleSpawnRange(32); + break; } } });