From 87b7b41d26bf6e7e3de9855b7b75419095c935f5 Mon Sep 17 00:00:00 2001 From: doctor4t Date: Mon, 30 Dec 2024 01:13:05 +0100 Subject: [PATCH] Rewrite and readd underwater chest and endchest bubbles --- .../core/index/EffectiveParticles.java | 2 +- .../UnderwaterOpenChestBubbleSpawner.java | 116 +----------------- ...UnderwaterOpenEnderChestBubbleSpawner.java | 114 +---------------- .../core/particle/BubbleParticle.java | 28 +++-- .../core/particle/EndBubbleParticle.java | 12 +- .../effective/core/utils/EffectiveUtils.java | 100 +++++++++++++++ .../effective/particles/end_bubble.json | 5 + 7 files changed, 141 insertions(+), 236 deletions(-) create mode 100644 src/client/resources/assets/effective/particles/end_bubble.json diff --git a/src/client/java/org/ladysnake/effective/core/index/EffectiveParticles.java b/src/client/java/org/ladysnake/effective/core/index/EffectiveParticles.java index 389c0d55..27965a3e 100644 --- a/src/client/java/org/ladysnake/effective/core/index/EffectiveParticles.java +++ b/src/client/java/org/ladysnake/effective/core/index/EffectiveParticles.java @@ -46,6 +46,6 @@ private static void registerFactories() { ParticleFactoryRegistry.getInstance().register(RIPPLE, RippleParticle.Factory::new); ParticleFactoryRegistry.getInstance().register(GLOW_RIPPLE, GlowRippleParticle.Factory::new); ParticleFactoryRegistry.getInstance().register(BUBBLE, BubbleParticle.Factory::new); - ParticleFactoryRegistry.getInstance().register(END_BUBBLE, BubbleParticle.Factory::new); + ParticleFactoryRegistry.getInstance().register(END_BUBBLE, EndBubbleParticle.Factory::new); } } diff --git a/src/client/java/org/ladysnake/effective/core/mixin/chest_bubbles/UnderwaterOpenChestBubbleSpawner.java b/src/client/java/org/ladysnake/effective/core/mixin/chest_bubbles/UnderwaterOpenChestBubbleSpawner.java index 1bc7e59f..aefac532 100644 --- a/src/client/java/org/ladysnake/effective/core/mixin/chest_bubbles/UnderwaterOpenChestBubbleSpawner.java +++ b/src/client/java/org/ladysnake/effective/core/mixin/chest_bubbles/UnderwaterOpenChestBubbleSpawner.java @@ -3,12 +3,15 @@ import net.minecraft.block.*; import net.minecraft.block.entity.BlockEntity; import net.minecraft.block.entity.ChestBlockEntity; +import net.minecraft.block.entity.EnderChestBlockEntity; import net.minecraft.block.entity.LidOpenable; import net.minecraft.block.enums.ChestType; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; import net.minecraft.world.World; import org.ladysnake.effective.core.EffectiveConfig; +import org.ladysnake.effective.core.index.EffectiveParticles; +import org.ladysnake.effective.core.utils.EffectiveUtils; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; @@ -21,118 +24,7 @@ private static void clientTick(World world, BlockPos pos, BlockState state, Ches boolean bl = world != null; if (EffectiveConfig.underwaterOpenChestBubbles && bl && world.random.nextInt(2) == 0) { - BlockState blockState = blockEntity.getCachedState(); - ChestType chestType = blockState.contains(ChestBlock.CHEST_TYPE) ? blockState.get(ChestBlock.CHEST_TYPE) : ChestType.SINGLE; - Direction facing = blockState.contains(ChestBlock.FACING) ? blockState.get(ChestBlock.FACING) : Direction.NORTH; - Block block = blockState.getBlock(); - if (block instanceof AbstractChestBlock && world.isWater(blockEntity.getPos()) && world.isWater(blockEntity.getPos().offset(Direction.UP, 1))) { - AbstractChestBlock abstractChestBlock = (AbstractChestBlock) block; - boolean doubleChest = chestType != ChestType.SINGLE; - - DoubleBlockProperties.PropertySource propertySource; - propertySource = abstractChestBlock.getBlockEntitySource(blockState, world, blockEntity.getPos(), true); - - float openFactor = propertySource.apply(ChestBlock.getAnimationProgressRetriever(blockEntity)).get(1.0f); - - if (openFactor > 0) { - if (doubleChest) { - if (chestType == ChestType.LEFT) { - float xOffset = 0f; - float zOffset = 0f; - float xOffsetRand = 0f; - float zOffsetRand = 0f; - - if (facing == Direction.NORTH) { - xOffset = 1f; - zOffset = .5f; - xOffsetRand = (world.random.nextFloat() - world.random.nextFloat()) * .8f; - zOffsetRand = (world.random.nextFloat() - world.random.nextFloat()) * .3f; - } else if (facing == Direction.SOUTH) { - xOffset = 0f; - zOffset = .5f; - xOffsetRand = (world.random.nextFloat() - world.random.nextFloat()) * .8f; - zOffsetRand = (world.random.nextFloat() - world.random.nextFloat()) * .3f; - } else if (facing == Direction.EAST) { - xOffset = .5f; - zOffset = 1f; - xOffsetRand = (world.random.nextFloat() - world.random.nextFloat()) * .3f; - zOffsetRand = (world.random.nextFloat() - world.random.nextFloat()) * .8f; - } else if (facing == Direction.WEST) { - xOffset = .5f; - zOffset = 0f; - xOffsetRand = (world.random.nextFloat() - world.random.nextFloat()) * .3f; - zOffsetRand = (world.random.nextFloat() - world.random.nextFloat()) * .8f; - } - - for (int i = 0; i < 1 + world.random.nextInt(3); i++) { - spawnBubble(world, blockEntity.getPos().getX() + xOffset + xOffsetRand, blockEntity.getPos().getY() + .5f, blockEntity.getPos().getZ() + zOffset + zOffsetRand, block == Blocks.ENDER_CHEST); - } - - if (openFactor <= .6f) { - spawnClosingBubble(world, blockEntity.getPos().getX() + xOffset, blockEntity.getPos().getY() + .5f, blockEntity.getPos().getZ() + zOffset, facing, true, block == Blocks.ENDER_CHEST); - } - } - } else { - for (int i = 0; i < 1 + world.random.nextInt(3); i++) { - spawnBubble(world, blockEntity.getPos().getX() + .5f + (world.random.nextFloat() - world.random.nextFloat()) * .3f, blockEntity.getPos().getY() + .5f, blockEntity.getPos().getZ() + .5f + (world.random.nextFloat() - world.random.nextFloat()) * .3f, block == Blocks.ENDER_CHEST); - } - - if (openFactor <= .6f) { - spawnClosingBubble(world, blockEntity.getPos().getX() + .5f, blockEntity.getPos().getY() + .5f, blockEntity.getPos().getZ() + .5f, facing, false, block == Blocks.ENDER_CHEST); - } - } - } - } + EffectiveUtils.doUnderwaterChestLogic(world, blockEntity); } } - - private static void spawnBubble(World world, float x, float y, float z, boolean endChest) { -// float bubbleSize = .05f + world.random.nextFloat() * .05f; -// WorldParticleBuilder.create(Effective.BUBBLE) -// .enableForcedSpawn() -// .setLightLevel(endChest ? LightmapTextureManager.MAX_LIGHT_COORDINATE : -1) -// .setScaleData(GenericParticleData.create(bubbleSize).build()) -// .setTransparencyData(GenericParticleData.create(1f).build()) -// .enableNoClip() -// .setLifetime(60 + world.random.nextInt(60)) -// .setMotion(0f, bubbleSize, 0f) -// .setRenderType(ParticleTextureSheet.PARTICLE_SHEET_TRANSLUCENT) -// .setColorData(ColorParticleData.create(new Color(endChest ? 0x00FF90 : 0xFFFFFF), new Color(endChest ? 0x00FF90 : 0xFFFFFF)).build()) -// .spawn(world, x, y, z); - } - - private static void spawnClosingBubble(World world, float x, float y, float z, Direction direction, boolean doubleChest, boolean endChest) { -// for (int i = 0; i < (doubleChest ? 10 : 5); i++) { -// float velX = .5f; -// float velZ = .5f; -// if (direction == Direction.NORTH) { -// velX = (world.random.nextFloat() - world.random.nextFloat()) / (doubleChest ? 2.5f : 5f); -// velZ = -.05f - (world.random.nextFloat() / 5f); -// } else if (direction == Direction.SOUTH) { -// velX = (world.random.nextFloat() - world.random.nextFloat()) / (doubleChest ? 2.5f : 5f); -// velZ = .05f + (world.random.nextFloat() / 5f); -// } else if (direction == Direction.EAST) { -// velX = .05f + (world.random.nextFloat() / 5f); -// velZ = (world.random.nextFloat() - world.random.nextFloat()) / (doubleChest ? 2.5f : 5f); -// } else if (direction == Direction.WEST) { -// velX = -.05f - (world.random.nextFloat() / 5f); -// velZ = (world.random.nextFloat() - world.random.nextFloat()) / (doubleChest ? 2.5f : 5f); -// } -// WorldParticleBuilder.create(Effective.BUBBLE) -// .enableForcedSpawn() -// .setLightLevel(endChest ? LightmapTextureManager.MAX_LIGHT_COORDINATE : -1) -// .setScaleData(GenericParticleData.create(.05f + world.random.nextFloat() * .05f).build()) -// .setTransparencyData(GenericParticleData.create(1f).build()) -// .enableNoClip() -// .setLifetime(60 + world.random.nextInt(60)) -// .addTickActor(new LinearForcedMotionImpl( -// new Vector3f(velX, .1f - (world.random.nextFloat() * .1f), velZ), -// new Vector3f(0f, .1f, 0f), -// 10f -// )) -// .setRenderType(ParticleTextureSheet.PARTICLE_SHEET_TRANSLUCENT) -// .setColorData(ColorParticleData.create(new Color(endChest ? 0x00FF90 : 0xFFFFFF), new Color(endChest ? 0x00FF90 : 0xFFFFFF)).build()) -// .spawn(world, x, y, z); -// } - } } diff --git a/src/client/java/org/ladysnake/effective/core/mixin/chest_bubbles/UnderwaterOpenEnderChestBubbleSpawner.java b/src/client/java/org/ladysnake/effective/core/mixin/chest_bubbles/UnderwaterOpenEnderChestBubbleSpawner.java index a9d4c51e..46e44680 100644 --- a/src/client/java/org/ladysnake/effective/core/mixin/chest_bubbles/UnderwaterOpenEnderChestBubbleSpawner.java +++ b/src/client/java/org/ladysnake/effective/core/mixin/chest_bubbles/UnderwaterOpenEnderChestBubbleSpawner.java @@ -10,6 +10,7 @@ import net.minecraft.util.math.Direction; import net.minecraft.world.World; import org.ladysnake.effective.core.EffectiveConfig; +import org.ladysnake.effective.core.utils.EffectiveUtils; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; @@ -22,118 +23,7 @@ private static void clientTick(World world, BlockPos pos, BlockState state, Ende boolean bl = world != null; if (EffectiveConfig.underwaterOpenChestBubbles && bl && world.random.nextInt(2) == 0) { - BlockState blockState = blockEntity.getCachedState(); - ChestType chestType = blockState.contains(ChestBlock.CHEST_TYPE) ? blockState.get(ChestBlock.CHEST_TYPE) : ChestType.SINGLE; - Direction facing = blockState.contains(ChestBlock.FACING) ? blockState.get(ChestBlock.FACING) : Direction.NORTH; - Block block = blockState.getBlock(); - if (block instanceof AbstractChestBlock && world.isWater(blockEntity.getPos()) && world.isWater(blockEntity.getPos().offset(Direction.UP, 1))) { - AbstractChestBlock abstractChestBlock = (AbstractChestBlock) block; - boolean doubleChest = chestType != ChestType.SINGLE; - - DoubleBlockProperties.PropertySource propertySource; - propertySource = abstractChestBlock.getBlockEntitySource(blockState, world, blockEntity.getPos(), true); - - float openFactor = propertySource.apply(ChestBlock.getAnimationProgressRetriever(blockEntity)).get(1.0f); - - if (openFactor > 0) { - if (doubleChest) { - if (chestType == ChestType.LEFT) { - float xOffset = 0f; - float zOffset = 0f; - float xOffsetRand = 0f; - float zOffsetRand = 0f; - - if (facing == Direction.NORTH) { - xOffset = 1f; - zOffset = .5f; - xOffsetRand = (world.random.nextFloat() - world.random.nextFloat()) * .8f; - zOffsetRand = (world.random.nextFloat() - world.random.nextFloat()) * .3f; - } else if (facing == Direction.SOUTH) { - xOffset = 0f; - zOffset = .5f; - xOffsetRand = (world.random.nextFloat() - world.random.nextFloat()) * .8f; - zOffsetRand = (world.random.nextFloat() - world.random.nextFloat()) * .3f; - } else if (facing == Direction.EAST) { - xOffset = .5f; - zOffset = 1f; - xOffsetRand = (world.random.nextFloat() - world.random.nextFloat()) * .3f; - zOffsetRand = (world.random.nextFloat() - world.random.nextFloat()) * .8f; - } else if (facing == Direction.WEST) { - xOffset = .5f; - zOffset = 0f; - xOffsetRand = (world.random.nextFloat() - world.random.nextFloat()) * .3f; - zOffsetRand = (world.random.nextFloat() - world.random.nextFloat()) * .8f; - } - - for (int i = 0; i < 1 + world.random.nextInt(3); i++) { - spawnBubble(world, blockEntity.getPos().getX() + xOffset + xOffsetRand, blockEntity.getPos().getY() + .5f, blockEntity.getPos().getZ() + zOffset + zOffsetRand, block == Blocks.ENDER_CHEST); - } - - if (openFactor <= .6f) { - spawnClosingBubble(world, blockEntity.getPos().getX() + xOffset, blockEntity.getPos().getY() + .5f, blockEntity.getPos().getZ() + zOffset, facing, true, block == Blocks.ENDER_CHEST); - } - } - } else { - for (int i = 0; i < 1 + world.random.nextInt(3); i++) { - spawnBubble(world, blockEntity.getPos().getX() + .5f + (world.random.nextFloat() - world.random.nextFloat()) * .3f, blockEntity.getPos().getY() + .5f, blockEntity.getPos().getZ() + .5f + (world.random.nextFloat() - world.random.nextFloat()) * .3f, block == Blocks.ENDER_CHEST); - } - - if (openFactor <= .6f) { - spawnClosingBubble(world, blockEntity.getPos().getX() + .5f, blockEntity.getPos().getY() + .5f, blockEntity.getPos().getZ() + .5f, facing, false, block == Blocks.ENDER_CHEST); - } - } - } - } + EffectiveUtils.doUnderwaterChestLogic(world, blockEntity); } } - - private static void spawnBubble(World world, float x, float y, float z, boolean endChest) { -// float bubbleSize = .05f + world.random.nextFloat() * .05f; -// WorldParticleBuilder.create(Effective.BUBBLE) -// .enableForcedSpawn() -// .setLightLevel(endChest ? LightmapTextureManager.MAX_LIGHT_COORDINATE : -1) -// .setScaleData(GenericParticleData.create(bubbleSize).build()) -// .setTransparencyData(GenericParticleData.create(1f).build()) -// .enableNoClip() -// .setLifetime(60 + world.random.nextInt(60)) -// .setMotion(0f, bubbleSize, 0f) -// .setRenderType(ParticleTextureSheet.PARTICLE_SHEET_TRANSLUCENT) -// .setColorData(ColorParticleData.create(new Color(endChest ? 0x00FF90 : 0xFFFFFF), new Color(endChest ? 0x00FF90 : 0xFFFFFF)).build()) -// .spawn(world, x, y, z); - } - - private static void spawnClosingBubble(World world, float x, float y, float z, Direction direction, boolean doubleChest, boolean endChest) { -// for (int i = 0; i < (doubleChest ? 10 : 5); i++) { -// float velX = .5f; -// float velZ = .5f; -// if (direction == Direction.NORTH) { -// velX = (world.random.nextFloat() - world.random.nextFloat()) / (doubleChest ? 2.5f : 5f); -// velZ = -.05f - (world.random.nextFloat() / 5f); -// } else if (direction == Direction.SOUTH) { -// velX = (world.random.nextFloat() - world.random.nextFloat()) / (doubleChest ? 2.5f : 5f); -// velZ = .05f + (world.random.nextFloat() / 5f); -// } else if (direction == Direction.EAST) { -// velX = .05f + (world.random.nextFloat() / 5f); -// velZ = (world.random.nextFloat() - world.random.nextFloat()) / (doubleChest ? 2.5f : 5f); -// } else if (direction == Direction.WEST) { -// velX = -.05f - (world.random.nextFloat() / 5f); -// velZ = (world.random.nextFloat() - world.random.nextFloat()) / (doubleChest ? 2.5f : 5f); -// } -// WorldParticleBuilder.create(Effective.BUBBLE) -// .enableForcedSpawn() -// .setLightLevel(endChest ? LightmapTextureManager.MAX_LIGHT_COORDINATE : -1) -// .setScaleData(GenericParticleData.create(.05f + world.random.nextFloat() * .05f).build()) -// .setTransparencyData(GenericParticleData.create(1f).build()) -// .enableNoClip() -// .setLifetime(60 + world.random.nextInt(60)) -// .addTickActor(new LinearForcedMotionImpl( -// new Vector3f(velX, .1f - (world.random.nextFloat() * .1f), velZ), -// new Vector3f(0f, .1f, 0f), -// 10f -// )) -// .setRenderType(ParticleTextureSheet.PARTICLE_SHEET_TRANSLUCENT) -// .setColorData(ColorParticleData.create(new Color(endChest ? 0x00FF90 : 0xFFFFFF), new Color(endChest ? 0x00FF90 : 0xFFFFFF)).build()) -// .spawn(world, x, y, z); -// } - } } diff --git a/src/client/java/org/ladysnake/effective/core/particle/BubbleParticle.java b/src/client/java/org/ladysnake/effective/core/particle/BubbleParticle.java index 6d747569..26e2c83b 100644 --- a/src/client/java/org/ladysnake/effective/core/particle/BubbleParticle.java +++ b/src/client/java/org/ladysnake/effective/core/particle/BubbleParticle.java @@ -8,18 +8,16 @@ import net.minecraft.util.math.BlockPos; public class BubbleParticle extends SpriteBillboardParticle { - private final SpriteProvider spriteProvider; - public BubbleParticle(ClientWorld world, double x, double y, double z, double velocityX, double velocityY, double velocityZ, SpriteProvider spriteProvider) { super(world, x, y, z, velocityX, velocityY, velocityZ); this.velocityX = velocityX; this.velocityY = velocityY; this.velocityZ = velocityZ; + this.velocityMultiplier = .9f; - this.spriteProvider = spriteProvider; - this.maxAge = 500; - this.scale = .05f; + this.maxAge = 60 + world.random.nextInt(60); + this.scale = .05f + world.random.nextFloat() * .05f; this.setSpriteForAge(spriteProvider); } @@ -29,10 +27,24 @@ public ParticleTextureSheet getType() { } public void tick() { - super.tick(); - - if (!world.isWater(BlockPos.ofFloored(this.x, this.y, this.z))) { + this.prevPosX = this.x; + this.prevPosY = this.y; + this.prevPosZ = this.z; + if (this.age++ >= this.maxAge || !world.isWater(BlockPos.ofFloored(this.x, this.y, this.z))) { this.markDead(); + } else { + this.move(this.velocityX, this.velocityY, this.velocityZ); + if (this.ascending && this.y == this.prevPosY) { + this.velocityX *= 1.1; + this.velocityZ *= 1.1; + } + + this.velocityX = this.velocityX * (double)this.velocityMultiplier; + this.velocityZ = this.velocityZ * (double)this.velocityMultiplier; + if (this.onGround) { + this.velocityX *= 0.7F; + this.velocityZ *= 0.7F; + } } } diff --git a/src/client/java/org/ladysnake/effective/core/particle/EndBubbleParticle.java b/src/client/java/org/ladysnake/effective/core/particle/EndBubbleParticle.java index a5b4cc41..9c33b924 100644 --- a/src/client/java/org/ladysnake/effective/core/particle/EndBubbleParticle.java +++ b/src/client/java/org/ladysnake/effective/core/particle/EndBubbleParticle.java @@ -5,6 +5,7 @@ import net.minecraft.client.particle.Particle; import net.minecraft.client.particle.ParticleFactory; import net.minecraft.client.particle.SpriteProvider; +import net.minecraft.client.render.LightmapTextureManager; import net.minecraft.client.world.ClientWorld; import net.minecraft.particle.SimpleParticleType; @@ -12,9 +13,14 @@ public class EndBubbleParticle extends BubbleParticle { public EndBubbleParticle(ClientWorld world, double x, double y, double z, double velocityX, double velocityY, double velocityZ, SpriteProvider spriteProvider) { super(world, x, y, z, velocityX, velocityY, velocityZ, spriteProvider); - this.red = 0; - this.green = 1; - this.blue = 1; + this.red = 0f; + this.green = 1f; + this.blue = 0.56f; + } + + @Override + protected int getBrightness(float tint) { + return LightmapTextureManager.MAX_LIGHT_COORDINATE; } @Environment(EnvType.CLIENT) diff --git a/src/client/java/org/ladysnake/effective/core/utils/EffectiveUtils.java b/src/client/java/org/ladysnake/effective/core/utils/EffectiveUtils.java index 8c183bb6..b68c6c48 100644 --- a/src/client/java/org/ladysnake/effective/core/utils/EffectiveUtils.java +++ b/src/client/java/org/ladysnake/effective/core/utils/EffectiveUtils.java @@ -1,10 +1,17 @@ package org.ladysnake.effective.core.utils; import net.fabricmc.fabric.api.tag.convention.v2.ConventionalBiomeTags; +import net.minecraft.block.*; +import net.minecraft.block.entity.BlockEntity; +import net.minecraft.block.entity.ChestBlockEntity; +import net.minecraft.block.entity.EnderChestBlockEntity; +import net.minecraft.block.entity.LidOpenable; +import net.minecraft.block.enums.ChestType; import net.minecraft.entity.passive.AllayEntity; import net.minecraft.particle.SimpleParticleType; import net.minecraft.registry.tag.BlockTags; import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Direction; import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.random.Random; import net.minecraft.world.LightType; @@ -86,4 +93,97 @@ public static boolean hasStoneAbove(World world, BlockPos pos) { public static float getRandomFloatOrNegative(Random random) { return random.nextFloat() * 2f - 1f; } + + + public static void doUnderwaterChestLogic(World world, BlockEntity blockEntity) { + if (blockEntity instanceof LidOpenable lidOpenable) { + BlockState blockState = blockEntity.getCachedState(); + ChestType chestType = blockState.contains(ChestBlock.CHEST_TYPE) ? blockState.get(ChestBlock.CHEST_TYPE) : ChestType.SINGLE; + Direction facing = blockState.contains(ChestBlock.FACING) ? blockState.get(ChestBlock.FACING) : Direction.NORTH; + Block block = blockState.getBlock(); + if (block instanceof AbstractChestBlock && world.isWater(blockEntity.getPos()) && world.isWater(blockEntity.getPos().offset(Direction.UP, 1))) { + AbstractChestBlock abstractChestBlock = (AbstractChestBlock) block; + boolean doubleChest = chestType != ChestType.SINGLE; + + DoubleBlockProperties.PropertySource propertySource; + propertySource = abstractChestBlock.getBlockEntitySource(blockState, world, blockEntity.getPos(), true); + + float openFactor = propertySource.apply(ChestBlock.getAnimationProgressRetriever(lidOpenable)).get(1.0f); + + if (openFactor > 0) { + if (doubleChest) { + if (chestType == ChestType.LEFT) { + float xOffset = 0f; + float zOffset = 0f; + float xOffsetRand = 0f; + float zOffsetRand = 0f; + + if (facing == Direction.NORTH) { + xOffset = 1f; + zOffset = .5f; + xOffsetRand = (world.random.nextFloat() - world.random.nextFloat()) * .8f; + zOffsetRand = (world.random.nextFloat() - world.random.nextFloat()) * .3f; + } else if (facing == Direction.SOUTH) { + xOffset = 0f; + zOffset = .5f; + xOffsetRand = (world.random.nextFloat() - world.random.nextFloat()) * .8f; + zOffsetRand = (world.random.nextFloat() - world.random.nextFloat()) * .3f; + } else if (facing == Direction.EAST) { + xOffset = .5f; + zOffset = 1f; + xOffsetRand = (world.random.nextFloat() - world.random.nextFloat()) * .3f; + zOffsetRand = (world.random.nextFloat() - world.random.nextFloat()) * .8f; + } else if (facing == Direction.WEST) { + xOffset = .5f; + zOffset = 0f; + xOffsetRand = (world.random.nextFloat() - world.random.nextFloat()) * .3f; + zOffsetRand = (world.random.nextFloat() - world.random.nextFloat()) * .8f; + } + + for (int i = 0; i < 1 + world.random.nextInt(3); i++) { + spawnBubble(world, blockEntity.getPos().getX() + xOffset + xOffsetRand, blockEntity.getPos().getY() + .5f, blockEntity.getPos().getZ() + zOffset + zOffsetRand, block == Blocks.ENDER_CHEST); + } + + if (openFactor <= .6f) { + spawnClosingBubble(world, blockEntity.getPos().getX() + xOffset, blockEntity.getPos().getY() + .5f, blockEntity.getPos().getZ() + zOffset, facing, true, block == Blocks.ENDER_CHEST); + } + } + } else { + for (int i = 0; i < 1 + world.random.nextInt(3); i++) { + spawnBubble(world, blockEntity.getPos().getX() + .5f + (world.random.nextFloat() - world.random.nextFloat()) * .3f, blockEntity.getPos().getY() + .5f, blockEntity.getPos().getZ() + .5f + (world.random.nextFloat() - world.random.nextFloat()) * .3f, block == Blocks.ENDER_CHEST); + } + + if (openFactor <= .6f) { + spawnClosingBubble(world, blockEntity.getPos().getX() + .5f, blockEntity.getPos().getY() + .5f, blockEntity.getPos().getZ() + .5f, facing, false, block == Blocks.ENDER_CHEST); + } + } + } + } + } + } + + public static void spawnBubble(World world, float x, float y, float z, boolean endChest) { + world.addParticle(endChest ? EffectiveParticles.END_BUBBLE : EffectiveParticles.BUBBLE, x, y, z, 0f, .05f + world.random.nextFloat() * .05f, 0f); + } + + public static void spawnClosingBubble(World world, float x, float y, float z, Direction direction, boolean doubleChest, boolean endChest) { + for (int i = 0; i < (doubleChest ? 10 : 5); i++) { + float velX = .5f; + float velZ = .5f; + if (direction == Direction.NORTH) { + velX = (world.random.nextFloat() - world.random.nextFloat()) / (doubleChest ? 2.5f : 5f); + velZ = -.05f - (world.random.nextFloat() / 5f); + } else if (direction == Direction.SOUTH) { + velX = (world.random.nextFloat() - world.random.nextFloat()) / (doubleChest ? 2.5f : 5f); + velZ = .05f + (world.random.nextFloat() / 5f); + } else if (direction == Direction.EAST) { + velX = .05f + (world.random.nextFloat() / 5f); + velZ = (world.random.nextFloat() - world.random.nextFloat()) / (doubleChest ? 2.5f : 5f); + } else if (direction == Direction.WEST) { + velX = -.05f - (world.random.nextFloat() / 5f); + velZ = (world.random.nextFloat() - world.random.nextFloat()) / (doubleChest ? 2.5f : 5f); + } + world.addParticle(endChest ? EffectiveParticles.END_BUBBLE : EffectiveParticles.BUBBLE, x, y, z, velX, .1f - (world.random.nextFloat() * .1f), velZ); + } + } } diff --git a/src/client/resources/assets/effective/particles/end_bubble.json b/src/client/resources/assets/effective/particles/end_bubble.json new file mode 100644 index 00000000..21bb4eeb --- /dev/null +++ b/src/client/resources/assets/effective/particles/end_bubble.json @@ -0,0 +1,5 @@ +{ + "textures": [ + "minecraft:bubble" + ] +}