diff --git a/src/main/java/de/ellpeck/naturesaura/blocks/BlockSlimeSplitGenerator.java b/src/main/java/de/ellpeck/naturesaura/blocks/BlockSlimeSplitGenerator.java new file mode 100644 index 00000000..c7041786 --- /dev/null +++ b/src/main/java/de/ellpeck/naturesaura/blocks/BlockSlimeSplitGenerator.java @@ -0,0 +1,43 @@ +package de.ellpeck.naturesaura.blocks; + +import de.ellpeck.naturesaura.Helper; +import de.ellpeck.naturesaura.blocks.tiles.TileEntitySlimeSplitGenerator; +import net.minecraft.block.Blocks; +import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.monster.SlimeEntity; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.event.entity.living.LivingDamageEvent; +import net.minecraftforge.event.entity.living.LivingDeathEvent; +import net.minecraftforge.eventbus.api.EventPriority; +import net.minecraftforge.eventbus.api.SubscribeEvent; + +public class BlockSlimeSplitGenerator extends BlockContainerImpl { + public BlockSlimeSplitGenerator() { + super("slime_split_generator", TileEntitySlimeSplitGenerator::new, Properties.from(Blocks.SLIME_BLOCK).hardnessAndResistance(2)); + MinecraftForge.EVENT_BUS.register(new Events()); + } + + private static class Events { + + @SubscribeEvent + public void onLivingDeath(LivingDeathEvent event) { + LivingEntity entity = event.getEntityLiving(); + if (!(entity instanceof SlimeEntity) || entity.world.isRemote) + return; + SlimeEntity slime = (SlimeEntity) entity; + int size = slime.getSlimeSize(); + if (size <= 1) + return; + Helper.getTileEntitiesInArea(entity.world, entity.getPosition(), 8, tile -> { + if (!(tile instanceof TileEntitySlimeSplitGenerator)) + return false; + TileEntitySlimeSplitGenerator gen = (TileEntitySlimeSplitGenerator) tile; + if (gen.isBusy()) + return false; + gen.startGenerating(slime); + return true; + }); + } + + } +} diff --git a/src/main/java/de/ellpeck/naturesaura/blocks/ModBlocks.java b/src/main/java/de/ellpeck/naturesaura/blocks/ModBlocks.java index 93bddd0d..e746189b 100644 --- a/src/main/java/de/ellpeck/naturesaura/blocks/ModBlocks.java +++ b/src/main/java/de/ellpeck/naturesaura/blocks/ModBlocks.java @@ -70,6 +70,7 @@ public final class ModBlocks { public static Block LIGHT; public static Block CHORUS_GENERATOR; public static Block AURA_TIMER; + public static Block SLIME_SPLIT_GENERATOR; public static Block.Properties prop(Material material, MaterialColor color) { return Block.Properties.create(material, color); diff --git a/src/main/java/de/ellpeck/naturesaura/blocks/tiles/ModTileEntities.java b/src/main/java/de/ellpeck/naturesaura/blocks/tiles/ModTileEntities.java index 0b7b3131..fe1928b6 100644 --- a/src/main/java/de/ellpeck/naturesaura/blocks/tiles/ModTileEntities.java +++ b/src/main/java/de/ellpeck/naturesaura/blocks/tiles/ModTileEntities.java @@ -40,4 +40,5 @@ public final class ModTileEntities { public static TileEntityType AURA_CACTUS; public static TileEntityType CHORUS_GENERATOR; public static TileEntityType AURA_TIMER; + public static TileEntityType SLIME_SPLIT_GENERATOR; } diff --git a/src/main/java/de/ellpeck/naturesaura/blocks/tiles/TileEntitySlimeSplitGenerator.java b/src/main/java/de/ellpeck/naturesaura/blocks/tiles/TileEntitySlimeSplitGenerator.java new file mode 100644 index 00000000..db9f1571 --- /dev/null +++ b/src/main/java/de/ellpeck/naturesaura/blocks/tiles/TileEntitySlimeSplitGenerator.java @@ -0,0 +1,94 @@ +package de.ellpeck.naturesaura.blocks.tiles; + +import de.ellpeck.naturesaura.api.aura.chunk.IAuraChunk; +import de.ellpeck.naturesaura.chunk.AuraChunk; +import de.ellpeck.naturesaura.packet.PacketHandler; +import de.ellpeck.naturesaura.packet.PacketParticles; +import net.minecraft.entity.monster.MagmaCubeEntity; +import net.minecraft.entity.monster.SlimeEntity; +import net.minecraft.nbt.CompoundNBT; +import net.minecraft.tileentity.ITickableTileEntity; +import net.minecraft.util.math.BlockPos; + +public class TileEntitySlimeSplitGenerator extends TileEntityImpl implements ITickableTileEntity { + + private int generationTimer; + private int amountToRelease; + private int color; + + public TileEntitySlimeSplitGenerator() { + super(ModTileEntities.SLIME_SPLIT_GENERATOR); + } + + @Override + public void tick() { + if (this.world.isRemote || this.world.getGameTime() % 10 != 0) + return; + if (this.generationTimer > 0) { + int amount = this.amountToRelease * 10; + if (this.canGenerateRightNow(35, amount)) { + while (amount > 0) { + BlockPos pos = IAuraChunk.getLowestSpot(this.world, this.pos, 35, this.pos); + amount -= IAuraChunk.getAuraChunk(this.world, pos).storeAura(pos, amount); + } + PacketHandler.sendToAllAround(this.world, this.pos, 32, new PacketParticles(this.pos.getX(), this.pos.getY(), this.pos.getZ(), PacketParticles.Type.SLIME_SPLIT_GEN_CREATE, this.color)); + } + this.generationTimer -= 10; + } + } + + @Override + public boolean wantsLimitRemover() { + return true; + } + + public boolean isBusy() { + return this.generationTimer > 0; + } + + public void startGenerating(SlimeEntity slime) { + int size = slime.getSlimeSize(); + this.generationTimer = size * 30; + this.amountToRelease = (size * this.getGenerationAmount(slime)) / this.generationTimer; + this.color = this.getSlimeColor(slime); + + PacketHandler.sendToAllAround(this.world, this.pos, 32, new PacketParticles((float) slime.getPosX(), (float) slime.getPosY(), (float) slime.getPosZ(), PacketParticles.Type.SLIME_SPLIT_GEN_START, + this.pos.getX(), this.pos.getY(), this.pos.getZ(), this.color)); + } + + @Override + public void writeNBT(CompoundNBT compound, SaveType type) { + super.writeNBT(compound, type); + if (type == SaveType.TILE) { + compound.putInt("timer", this.generationTimer); + compound.putInt("amount", this.amountToRelease); + compound.putInt("color", this.color); + } + } + + @Override + public void readNBT(CompoundNBT compound, SaveType type) { + super.readNBT(compound, type); + if (type == SaveType.TILE) { + this.generationTimer = compound.getInt("timer"); + this.amountToRelease = compound.getInt("amount"); + this.color = compound.getInt("color"); + } + } + + private int getSlimeColor(SlimeEntity slime) { + if (slime instanceof MagmaCubeEntity) { + return 0x942516; + } else { + return 0x1ed921; + } + } + + private int getGenerationAmount(SlimeEntity slime) { + if (slime instanceof MagmaCubeEntity) { + return 45000; + } else { + return 25000; + } + } +} diff --git a/src/main/java/de/ellpeck/naturesaura/packet/PacketParticles.java b/src/main/java/de/ellpeck/naturesaura/packet/PacketParticles.java index 35160d76..0a63d4ac 100644 --- a/src/main/java/de/ellpeck/naturesaura/packet/PacketParticles.java +++ b/src/main/java/de/ellpeck/naturesaura/packet/PacketParticles.java @@ -534,6 +534,38 @@ public class PacketParticles { NaturesAuraAPI.instance().spawnMagicParticle(d0 + Math.cos(d24) * 5.0D, d13 - 0.4D, d18 + Math.sin(d24) * 5.0D, Math.cos(d24) * -2, 0.0D, Math.sin(d24) * -2, color, 2, 60, 0, false, true); NaturesAuraAPI.instance().spawnMagicParticle(d0 + Math.cos(d24) * 5.0D, d13 - 0.4D, d18 + Math.sin(d24) * 5.0D, Math.cos(d24) * -2.5, 0.0D, Math.sin(d24) * -2.5, color, 2, 60, 0, false, true); } + }), + SLIME_SPLIT_GEN_CREATE((message, world) -> { + for (int i = world.rand.nextInt(5) + 5; i >= 0; i--) + 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, + world.rand.nextGaussian() * 0.01F, + world.rand.nextFloat() * 0.04F + 0.02F, + world.rand.nextGaussian() * 0.01F, + message.data[0], 1F + world.rand.nextFloat() * 1.5F, 40, 0F, false, true); + }), + SLIME_SPLIT_GEN_START((message, world) -> { + int x = message.data[0]; + int y = message.data[1]; + int z = message.data[2]; + int color = message.data[3]; + for (int i = world.rand.nextInt(10) + 5; i >= 0; i--) + NaturesAuraAPI.instance().spawnMagicParticle( + message.posX + (float) world.rand.nextGaussian() * 0.5F, + message.posY + (float) world.rand.nextGaussian() * 0.5F, + message.posZ + (float) world.rand.nextGaussian() * 0.5F, + world.rand.nextGaussian() * 0.02F, + world.rand.nextFloat() * 0.04F + 0.02F, + world.rand.nextGaussian() * 0.02F, + color, world.rand.nextFloat() + 1, world.rand.nextInt(20) + 20, 0, false, true); + for (int i = world.rand.nextInt(10) + 5; i >= 0; i--) + NaturesAuraAPI.instance().spawnParticleStream( + message.posX + (float) world.rand.nextGaussian() * 0.5F, + message.posY + (float) world.rand.nextGaussian() * 0.5F, + message.posZ + (float) world.rand.nextGaussian() * 0.5F, + x + 0.5F, y + 0.5F, z + 0.5F, 0.2F, color, world.rand.nextFloat() + 1); }); public final BiConsumer action; diff --git a/src/main/java/de/ellpeck/naturesaura/reg/ModRegistry.java b/src/main/java/de/ellpeck/naturesaura/reg/ModRegistry.java index 4a57c4c8..7f5b8edb 100644 --- a/src/main/java/de/ellpeck/naturesaura/reg/ModRegistry.java +++ b/src/main/java/de/ellpeck/naturesaura/reg/ModRegistry.java @@ -142,7 +142,8 @@ public final class ModRegistry { new BlockNetherGrass(), new BlockLight(), new BlockChorusGenerator(), - new BlockAuraTimer() + new BlockAuraTimer(), + new BlockSlimeSplitGenerator() ); if (ModConfig.instance.rfConverter.get())