diff --git a/gradle.properties b/gradle.properties index 4e550858a..83c6e4378 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,7 +4,7 @@ org.gradle.daemon=false # Dependency Version minecraftVersion=1.18.2 forgeVersion=40.2.0 -lodestoneVersion=1.4.2.501 +lodestoneVersion=1.4.2.504 forgegradleVersion=5.1.53 mixingradleVersion=0.7-SNAPSHOT librarianVersion=1.+ diff --git a/src/main/java/com/sammy/malum/common/block/curiosities/weeping_well/VoidConduitBlockEntity.java b/src/main/java/com/sammy/malum/common/block/curiosities/weeping_well/VoidConduitBlockEntity.java index 2649ff35d..9687327b9 100644 --- a/src/main/java/com/sammy/malum/common/block/curiosities/weeping_well/VoidConduitBlockEntity.java +++ b/src/main/java/com/sammy/malum/common/block/curiosities/weeping_well/VoidConduitBlockEntity.java @@ -5,6 +5,7 @@ import com.sammy.malum.registry.common.block.*; import com.sammy.malum.registry.common.item.*; import com.sammy.malum.visual_effects.*; +import com.sammy.malum.visual_effects.networked.*; import com.sammy.malum.visual_effects.networked.data.*; import net.minecraft.core.*; import net.minecraft.nbt.*; @@ -13,27 +14,13 @@ import net.minecraft.util.*; import net.minecraft.world.entity.item.*; import net.minecraft.world.item.*; -import net.minecraft.world.level.*; -import net.minecraft.world.level.block.*; import net.minecraft.world.level.block.state.*; import net.minecraft.world.phys.*; -import net.minecraft.world.phys.shapes.*; import team.lodestar.lodestone.helpers.*; -import team.lodestar.lodestone.setup.*; import team.lodestar.lodestone.systems.blockentity.*; -import team.lodestar.lodestone.systems.easing.*; -import team.lodestar.lodestone.systems.particle.*; -import team.lodestar.lodestone.systems.particle.builder.*; -import team.lodestar.lodestone.systems.particle.data.*; -import team.lodestar.lodestone.systems.particle.data.color.*; -import team.lodestar.lodestone.systems.particle.data.spin.*; -import team.lodestar.lodestone.systems.particle.render_types.*; -import team.lodestar.lodestone.systems.particle.world.*; -import java.awt.*; import java.util.List; import java.util.*; -import java.util.stream.*; public class VoidConduitBlockEntity extends LodestoneBlockEntity { @@ -79,6 +66,9 @@ public void load(CompoundTag compound) { @Override public void tick() { super.tick(); + if (lingeringRadiance > 0) { + lingeringRadiance--; + } if (level instanceof ServerLevel serverLevel) { if (serverLevel.getGameTime() % 100L == 0) { level.playSound(null, worldPosition, SoundRegistry.UNCANNY_VALLEY.get(), SoundSource.HOSTILE, 1f, Mth.nextFloat(level.getRandom(), 0.55f, 1.75f)); @@ -93,6 +83,7 @@ public void tick() { progress++; if (progress >= 80) { int resultingProgress = 60; + ParticleEffectType particleEffectType = ParticleEffectTypeRegistry.WEEPING_WELL_REACTS; ItemStack stack = eatenItems.get(eatenItems.size()-1); if (stack.getItem().equals(ItemRegistry.BLIGHTED_GUNK.get())) { resultingProgress +=streak/2f; @@ -103,12 +94,13 @@ public void tick() { else { Item result = spitOutItem(stack); if (result.equals(ItemRegistry.FUSED_CONSCIOUSNESS.get())) { - lingeringRadiance = 3600; + lingeringRadiance = 200; + particleEffectType = ParticleEffectTypeRegistry.WEEPING_WELL_EMITS_RADIANCE; } } progress = resultingProgress; eatenItems.remove(eatenItems.size()-1); - ParticleEffectTypeRegistry.WEEPING_WELL_REACTS.createPositionedEffect(level, new PositionEffectData(worldPosition.getX()+0.5f, worldPosition.getY()+0.75f, worldPosition.getZ()+0.5f)); + particleEffectType.createPositionedEffect(level, new PositionEffectData(worldPosition.getX()+0.5f, worldPosition.getY()+0.6f, worldPosition.getZ()+0.5f)); BlockHelper.updateAndNotifyState(level, worldPosition); } if (eatenItems.isEmpty()) { @@ -120,8 +112,11 @@ else if (streak != 0) { } } else { - WeepingWellParticleEffects.passiveWeepingWellParticles(this); - WeepingWellParticleEffects.radiantWeepingWellParticles(this); + if (lingeringRadiance == 0) { + WeepingWellParticleEffects.passiveWeepingWellParticles(this); + } else { + RadiantParticleEffects.radiantWeepingWellParticles(this); + } } } diff --git a/src/main/java/com/sammy/malum/common/block/ether/EtherBlockEntity.java b/src/main/java/com/sammy/malum/common/block/ether/EtherBlockEntity.java index 9a568f448..b7399a446 100644 --- a/src/main/java/com/sammy/malum/common/block/ether/EtherBlockEntity.java +++ b/src/main/java/com/sammy/malum/common/block/ether/EtherBlockEntity.java @@ -160,7 +160,7 @@ public void tick() { .setRandomOffset(0.15f, 0.2f) .addMotion(0, 0.0035f, 0) .setRandomMotion(0.001f, 0.005f) - .addActor(p -> p.setParticleMotion(p.getParticleSpeed().scale(0.985f-level.random.nextFloat() * 0.04f))) + .addTickActor(p -> p.setParticleMotion(p.getParticleSpeed().scale(0.985f-level.random.nextFloat() * 0.04f))) .enableNoClip() .setDiscardFunction(SimpleParticleOptions.ParticleDiscardFunctionType.ENDING_CURVE_INVISIBLE) .spawn(level, x, y, z); @@ -173,7 +173,7 @@ public void tick() { .setRandomOffset(0.1f, 0.225f) .addMotion(0, velocity / 2f, 0) .setRandomMotion(0, 0.015f) - .addActor(p -> p.setParticleMotion(p.getParticleSpeed().scale(0.97f-level.random.nextFloat() * 0.025f))) + .addTickActor(p -> p.setParticleMotion(p.getParticleSpeed().scale(0.97f-level.random.nextFloat() * 0.025f))) .enableNoClip() .setDiscardFunction(SimpleParticleOptions.ParticleDiscardFunctionType.ENDING_CURVE_INVISIBLE) .spawn(level, x, y, z); diff --git a/src/main/java/com/sammy/malum/common/packets/particle/curiosities/rite/generic/MajorEntityEffectParticlePacket.java b/src/main/java/com/sammy/malum/common/packets/particle/curiosities/rite/generic/MajorEntityEffectParticlePacket.java index b1b42a228..d35fda847 100644 --- a/src/main/java/com/sammy/malum/common/packets/particle/curiosities/rite/generic/MajorEntityEffectParticlePacket.java +++ b/src/main/java/com/sammy/malum/common/packets/particle/curiosities/rite/generic/MajorEntityEffectParticlePacket.java @@ -42,7 +42,7 @@ public void execute(Supplier context) { .enableNoClip() .setRandomOffset(0.2f, 0.2f) .setRandomMotion(0.02f) - .addActor(p -> p.setParticleMotion(p.getParticleSpeed().scale(0.95f))) + .addTickActor(p -> p.setParticleMotion(p.getParticleSpeed().scale(0.95f))) .repeat(level, posX, posY, posZ, 8); } WorldParticleBuilder.create(LodestoneParticleRegistry.WISP_PARTICLE) @@ -54,7 +54,7 @@ public void execute(Supplier context) { .enableNoClip() .setRandomOffset(0.05f, 0.05f) .setRandomMotion(0.05f) - .addActor(p -> p.setParticleMotion(p.getParticleSpeed().scale(0.5f))) + .addTickActor(p -> p.setParticleMotion(p.getParticleSpeed().scale(0.5f))) .repeat(level, posX, posY, posZ, 12); WorldParticleBuilder.create(LodestoneParticleRegistry.SMOKE_PARTICLE) @@ -66,7 +66,7 @@ public void execute(Supplier context) { .enableNoClip() .setRandomOffset(0.15f, 0.15f) .setRandomMotion(0.015f, 0.015f) - .addActor(p -> p.setParticleMotion(p.getParticleSpeed().scale(0.92f))) + .addTickActor(p -> p.setParticleMotion(p.getParticleSpeed().scale(0.92f))) .repeat(level, posX, posY, posZ, 20); } diff --git a/src/main/java/com/sammy/malum/visual_effects/ItemCrumbleParticleEffects.java b/src/main/java/com/sammy/malum/visual_effects/ItemCrumbleParticleEffects.java index 287d18485..611ce13fe 100644 --- a/src/main/java/com/sammy/malum/visual_effects/ItemCrumbleParticleEffects.java +++ b/src/main/java/com/sammy/malum/visual_effects/ItemCrumbleParticleEffects.java @@ -37,7 +37,7 @@ public static ParticleEffectSpawner spawnGlowingItemCr final Consumer slowDown = p -> p.setParticleMotion(p.getParticleSpeed().scale(0.925f)); int lifetime = RandomHelper.randomBetween(rand, 30, 40); final ItemCrumbParticleBuilder worldParticleBuilder = makeCrumbles(rand, stack, spinData, lifetime, slowDown); - final WorldParticleBuilder bloomParticleBuilder = SpiritLightSpecs.spiritBloom(level, spiritType, spinData, lifetime).addActor(slowDown); + final WorldParticleBuilder bloomParticleBuilder = SpiritLightSpecs.spiritBloom(level, spiritType, spinData, lifetime).addTickActor(slowDown); return new ParticleEffectSpawner<>(level, pos, worldParticleBuilder, bloomParticleBuilder); } @@ -49,6 +49,6 @@ public static ItemCrumbParticleBuilder makeCrumbles(Random rand, ItemStack stack .setLifetime(lifetime) .setDiscardFunction(SimpleParticleOptions.ParticleDiscardFunctionType.ENDING_CURVE_INVISIBLE) .setRenderType(ParticleRenderType.TERRAIN_SHEET) - .addActor(slowDown); + .addTickActor(slowDown); } } diff --git a/src/main/java/com/sammy/malum/visual_effects/RadiantParticleEffects.java b/src/main/java/com/sammy/malum/visual_effects/RadiantParticleEffects.java new file mode 100644 index 000000000..580effe0e --- /dev/null +++ b/src/main/java/com/sammy/malum/visual_effects/RadiantParticleEffects.java @@ -0,0 +1,138 @@ +package com.sammy.malum.visual_effects; + +import com.sammy.malum.common.block.curiosities.weeping_well.*; +import com.sammy.malum.visual_effects.networked.data.*; +import net.minecraft.core.*; +import net.minecraft.world.level.*; +import net.minecraft.world.phys.*; +import team.lodestar.lodestone.helpers.*; +import team.lodestar.lodestone.setup.*; +import team.lodestar.lodestone.systems.easing.*; +import team.lodestar.lodestone.systems.particle.*; +import team.lodestar.lodestone.systems.particle.builder.*; +import team.lodestar.lodestone.systems.particle.data.*; +import team.lodestar.lodestone.systems.particle.data.color.*; +import team.lodestar.lodestone.systems.particle.data.spin.*; +import team.lodestar.lodestone.systems.particle.render_types.*; + +import java.awt.*; +import java.util.*; +import java.util.List; +import java.util.function.*; + +import static com.sammy.malum.visual_effects.WeepingWellParticleEffects.getWeepingWellSmokeColor; + +public class RadiantParticleEffects { + public static final java.util.List RADIANT_COLORS = List.of( + new Color(179, 35, 218), + new Color(224, 210, 68), + new Color(42, 146, 218)); + + public static void spitOutWeepingWellRadiance(Level level, PositionEffectData positionEffectData) { + double posX = positionEffectData.posX; + double posY = positionEffectData.posY; + double posZ = positionEffectData.posZ; + Vec3 pos = new Vec3(posX, posY, posZ); + Random rand = level.random; + Consumer spawnBehavior = p -> p.tickParticle(2); + for (int i = 0; i < 64; i++) { + Color color = RADIANT_COLORS.get((i % 12) / 4); + final ColorParticleData colorData = ColorParticleData.create(color.brighter(), color).setCoefficient(0.5f).build(); + float xVelocity = RandomHelper.randomBetween(rand, 0f, 0.15f) * (rand.nextBoolean() ? 1 : -1); + float yVelocity = RandomHelper.randomBetween(rand, 0.5f, 1f); + float zVelocity = RandomHelper.randomBetween(rand, 0f, 0.15f) * (rand.nextBoolean() ? 1 : -1); + float gravityStrength = RandomHelper.randomBetween(rand, 0.75f, 1f); + if (rand.nextFloat() < 0.85f) { + var sparkParticles = WeepingWellParticleEffects.weepingWellSparks(level, pos, colorData, LodestoneWorldParticleRenderType.ADDITIVE); + sparkParticles.getBuilder() + .addSpawnActor(spawnBehavior) + .disableNoClip() + .setGravityStrength(gravityStrength/2f) + .setMotion(xVelocity, yVelocity, zVelocity) + .modifyData(SparkParticleBuilder::getTransparencyData, d -> d.multiplyValue(2f)) + .modifyData(SparkParticleBuilder::getScaleData, d -> d.multiplyValue(1.5f)); + sparkParticles.getBloomBuilder() + .addSpawnActor(spawnBehavior) + .disableNoClip() + .setGravityStrength(gravityStrength/2f) + .setMotion(xVelocity, yVelocity, zVelocity) + .modifyData(WorldParticleBuilder::getTransparencyData, d -> d.multiplyValue(1.25f)); + sparkParticles.spawnParticles(); + } + if (rand.nextFloat() < 0.85f) { + xVelocity *= 1.25f; + yVelocity *= 0.75f; + zVelocity *= 1.25f; + var lightSpecs = WeepingWellParticleEffects.weepingWellSpecs(level, pos, colorData, LodestoneWorldParticleRenderType.ADDITIVE); + lightSpecs.getBuilder() + .addSpawnActor(spawnBehavior) + .disableNoClip() + .setGravityStrength(gravityStrength) + .setMotion(xVelocity, yVelocity, zVelocity) + .modifyData(WorldParticleBuilder::getScaleData, d -> d.multiplyValue(1.5f)); + lightSpecs.getBloomBuilder() + .addSpawnActor(spawnBehavior) + .disableNoClip() + .setGravityStrength(gravityStrength) + .setMotion(xVelocity, yVelocity, zVelocity) + .modifyData(WorldParticleBuilder::getTransparencyData, d -> d.multiplyValue(1.25f)); + lightSpecs.spawnParticles(); + } + } + int spinOffset = rand.nextInt(360); + for (int i = 0; i < 3; i++) { + int lifeDelay = 4 * i; + Color color = RADIANT_COLORS.get((int) ((level.getGameTime() % 3 + i) % 3)); + final ColorParticleData colorData = ColorParticleData.create(color.brighter(), color).setCoefficient(0.5f).build(); + int spinDirection = (rand.nextBoolean() ? 1 : -1); + WorldParticleBuilder.create(LodestoneParticleRegistry.SPARKLE_PARTICLE) + .setTransparencyData(GenericParticleData.create(0.1f, 0.4f, 0).setEasing(Easing.QUAD_IN, Easing.CIRC_IN).build()) + .setSpinData(SpinParticleData.create((0.125f + rand.nextFloat() * 0.075f) * spinDirection).setSpinOffset(spinOffset).build()) + .setScaleData(GenericParticleData.create(3f, 5f, 0.6f).setEasing(Easing.QUARTIC_OUT, Easing.SINE_IN).build()) + .setColorData(colorData) + .setLifeDelay(lifeDelay) + .setLifetime(25+lifeDelay) + .setRandomOffset(0.6f) + .enableNoClip() + .setRandomMotion(0.02f, 0.02f) + .setDiscardFunction(SimpleParticleOptions.ParticleDiscardFunctionType.ENDING_CURVE_INVISIBLE) + .repeat(level, posX, posY+0.25f, posZ, 5); + + } + for (int i = 0; i < 27; i++) { + int finalI = 4+i; + Color color = RADIANT_COLORS.get(((int) (level.getGameTime()-27+i) % 27) / 9); + final ColorParticleData colorData = ColorParticleData.create(color.brighter(), color).setCoefficient(0.5f).build(); + var squares = WeepingWellParticleEffects.weepingWellSquare(level, pos, colorData); + squares.getBuilder().addSpawnActor(p -> p.tickParticle(finalI)); + squares.spawnParticles(); + } + } + + public static void radiantWeepingWellParticles(VoidConduitBlockEntity voidConduit) { + Level level = voidConduit.getLevel(); + Random rand = level.random; + Color color = RADIANT_COLORS.get(((int) level.getGameTime() % 27) / 9); + final BlockPos blockPos = voidConduit.getBlockPos(); + final ColorParticleData colorData = ColorParticleData.create(color.brighter(), color).setCoefficient(0.5f).build(); + if (level.getGameTime() % 3L == 0) { + WeepingWellParticleEffects.weepingWellSquare(level, new Vec3(blockPos.getX()+0.5f, blockPos.getY()+0.75f, blockPos.getZ()+0.5f), colorData).spawnParticles(); + } + + final float acceleration = RandomHelper.randomBetween(rand, 0.002f, 0.02f); + final long gameTime = level.getGameTime(); + final Consumer behavior = p -> { + if (level.getGameTime() < gameTime + 5) { + p.setParticleMotion(p.getParticleSpeed().add(0, acceleration, 0)); + } + }; + if (level.getGameTime() % 2L == 0) { + int rotation = (int) ((level.getGameTime() / 2f) % 16); + Vec3 offsetPosition = DataHelper.rotatingRadialOffset(new Vec3(blockPos.getX() + 0.5f, blockPos.getY() + 0.75f, blockPos.getZ() + 0.5f), 1.1f, rotation, 16, voidConduit.getLevel().getGameTime(), 640); + var lightSpecs = WeepingWellParticleEffects.weepingWellSpecs(level, offsetPosition, colorData, LodestoneWorldParticleRenderType.ADDITIVE); + lightSpecs.getBuilder().addTickActor(behavior); + lightSpecs.getBloomBuilder().addTickActor(behavior); + lightSpecs.spawnParticles(); + } + } +} diff --git a/src/main/java/com/sammy/malum/visual_effects/SparkParticleEffects.java b/src/main/java/com/sammy/malum/visual_effects/SparkParticleEffects.java index 3e8a74748..0cdf95864 100644 --- a/src/main/java/com/sammy/malum/visual_effects/SparkParticleEffects.java +++ b/src/main/java/com/sammy/malum/visual_effects/SparkParticleEffects.java @@ -20,8 +20,11 @@ public class SparkParticleEffects { public static ParticleEffectSpawner spiritMotionSparks(Level level, Vec3 pos, MalumSpiritType spiritType) { + return spiritMotionSparks(level, pos, spiritType.createMainColorData(1.25f).build(), spiritType.createBloomColorData().build()); + } + + public static ParticleEffectSpawner spiritMotionSparks(Level level, Vec3 pos, ColorParticleData colorData, ColorParticleData bloomColorData) { Random rand = level.getRandom(); - final ColorParticleData colorData = spiritType.createMainColorData(1.25f).build(); final SpinParticleData spinData = SpinParticleData.createRandomDirection(rand, nextFloat(rand, 0.05f, 0.1f)).randomSpinOffset(rand).build(); final Consumer slowDown = p -> p.setParticleMotion(p.getParticleSpeed().scale(0.95f)); int lifetime = RandomHelper.randomBetween(rand, 10, 20); @@ -32,8 +35,8 @@ public static ParticleEffectSpawner spiritMotionSparks(Lev .setColorData(colorData) .setLifetime(lifetime) .enableNoClip() - .addActor(slowDown); - final WorldParticleBuilder bloomParticleBuilder = SpiritLightSpecs.spiritBloom(level, spiritType, spinData, lifetime).addActor(slowDown); + .addTickActor(slowDown); + final WorldParticleBuilder bloomParticleBuilder = SpiritLightSpecs.spiritBloom(level, bloomColorData, spinData, lifetime).addTickActor(slowDown); return new ParticleEffectSpawner<>(level, pos, sparkParticleBuilder, bloomParticleBuilder); } diff --git a/src/main/java/com/sammy/malum/visual_effects/SpiritAltarParticleEffects.java b/src/main/java/com/sammy/malum/visual_effects/SpiritAltarParticleEffects.java index d082e9d05..dde409233 100644 --- a/src/main/java/com/sammy/malum/visual_effects/SpiritAltarParticleEffects.java +++ b/src/main/java/com/sammy/malum/visual_effects/SpiritAltarParticleEffects.java @@ -112,17 +112,17 @@ public static void eatItemParticles(SpiritAltarBlockEntity altar, MalumItemHolde }; var lightSpecs = spiritLightSpecs(level, offsetPosition, cyclingSpiritType); lightSpecs.getBuilder().act(b -> b - .addActor(behavior) + .addTickActor(behavior) .multiplyLifetime(2.5f) .modifyData(b::getScaleData, d -> d.multiplyValue(RandomHelper.randomBetween(random, 1f, 2f)))); lightSpecs.getBloomBuilder().act(b -> b - .addActor(behavior) + .addTickActor(behavior) .multiplyLifetime(2f) .modifyData(b::getScaleData, d -> d.multiplyValue(RandomHelper.randomBetween(random, 0.6f, 1.5f)))); lightSpecs.spawnParticles(); var crumbles = ItemCrumbleParticleEffects.spawnItemCrumbs(level, holderTargetPos, stack); - crumbles.getBuilder().multiplyLifetime(1 + i / 16f).addActor(behavior); + crumbles.getBuilder().multiplyLifetime(1 + i / 16f).addTickActor(behavior); crumbles.spawnParticles(); crumbles.getBuilder().setRandomOffset(0.2f); crumbles.spawnParticles(); @@ -136,7 +136,7 @@ public static void eatItemParticles(SpiritAltarBlockEntity altar, MalumItemHolde } }; var crumbles = ItemCrumbleParticleEffects.spawnItemCrumbs(level, holderTargetPos, stack); - crumbles.getBuilder().addActor(behavior); + crumbles.getBuilder().addTickActor(behavior); if (i % 2 == 0) { crumbles.spawnParticles(); } @@ -156,10 +156,10 @@ public static void craftItemParticles(SpiritAltarBlockEntity altar, ColorEffectD Vec3 targetPos = altar.getCentralItemOffset().add(altarPos.getX(),altarPos.getY(), altarPos.getZ()); for (int i = 0; i < 2; i++) { - MalumSpiritType cyclingSpiritType = colorData.getCyclingColorRecord().spiritType(); - SpiritLightSpecs.coolLookingShinyThing(level, targetPos, cyclingSpiritType); + SpiritLightSpecs.coolLookingShinyThing(level, targetPos, activeSpiritType); } for (int i = 0; i < 24; i++) { + int lifeDelay = i / 8; MalumSpiritType cyclingSpiritType = colorData.getCyclingColorRecord().spiritType(); float xVelocity = RandomHelper.randomBetween(random, Easing.CUBIC_OUT, -0.075f, 0.075f); float yVelocity = RandomHelper.randomBetween(random, 0.2f, 0.5f); @@ -169,12 +169,14 @@ public static void craftItemParticles(SpiritAltarBlockEntity altar, ColorEffectD var sparkParticles = SparkParticleEffects.spiritMotionSparks(level, targetPos, cyclingSpiritType); sparkParticles.getBuilder() .disableNoClip() + .setLifeDelay(lifeDelay) .multiplyLifetime(2) .setGravityStrength(gravityStrength) .setMotion(xVelocity, yVelocity, zVelocity) .modifyData(SparkParticleBuilder::getScaleData, d -> d.multiplyValue(2f)); sparkParticles.getBloomBuilder() .disableNoClip() + .setLifeDelay(lifeDelay) .multiplyLifetime(2) .setGravityStrength(gravityStrength) .setMotion(xVelocity, yVelocity, zVelocity) @@ -188,13 +190,14 @@ public static void craftItemParticles(SpiritAltarBlockEntity altar, ColorEffectD var lightSpecs = SpiritLightSpecs.spiritLightSpecs(level, targetPos, cyclingSpiritType); lightSpecs.getBuilder() .disableNoClip() + .setLifeDelay(lifeDelay) .multiplyLifetime(4) .setGravityStrength(gravityStrength) - .multiplyLifetime(0.8f) .setMotion(xVelocity, yVelocity, zVelocity) .modifyData(WorldParticleBuilder::getScaleData, d -> d.multiplyValue(2.5f)); lightSpecs.getBloomBuilder() .disableNoClip() + .setLifeDelay(lifeDelay) .multiplyLifetime(4) .setGravityStrength(gravityStrength) .setMotion(xVelocity, yVelocity, zVelocity) @@ -205,7 +208,7 @@ public static void craftItemParticles(SpiritAltarBlockEntity altar, ColorEffectD for (int i = 0; i < 8; i++) { int finalI = i; Vec3 offsetPosition = DataHelper.rotatingRadialOffset(targetPos, 0.6f, i, 8, gameTime, 160); - Consumer behavior = b -> b.addActor(p -> { + Consumer behavior = b -> b.addTickActor(p -> { if (level.getGameTime() > gameTime + finalI * 4 && level.getGameTime() < gameTime + (finalI + 4) * 4) { p.setParticleMotion(p.getParticleSpeed().add(0, 0.015f, 0)); } @@ -241,7 +244,7 @@ public static void runewoodObeliskParticles(RunewoodObeliskBlockEntity obelisk, Vec3 velocity = targetPos.subtract(startPos).normalize().scale(RandomHelper.randomBetween(random, 0.01f, 0.02f)); double yOffset = Math.sin((gameTime % 360) / 30f) * 0.1f; Vec3 offsetPosition = DataHelper.rotatingRadialOffset(startPos.add(0, yOffset, 0), 0.45f, 0, 1, gameTime, 30); - Consumer behavior = b -> b.addActor(p -> { + Consumer behavior = b -> b.addTickActor(p -> { if (gameTime % 6L == 0) { p.setParticleMotion(p.getParticleSpeed().scale(1.05f)); } diff --git a/src/main/java/com/sammy/malum/visual_effects/SpiritLightSpecs.java b/src/main/java/com/sammy/malum/visual_effects/SpiritLightSpecs.java index 684eb29e4..5faf75635 100644 --- a/src/main/java/com/sammy/malum/visual_effects/SpiritLightSpecs.java +++ b/src/main/java/com/sammy/malum/visual_effects/SpiritLightSpecs.java @@ -88,8 +88,8 @@ public static ParticleEffectSpawner spiritLightSpecs(Level .setColorData(colorData) .setLifetime(lifetime) .enableNoClip() - .addActor(slowDown); - final WorldParticleBuilder bloomParticleBuilder = SpiritLightSpecs.spiritBloom(level, bloomColorData, spinData, lifetime).addActor(slowDown); + .addTickActor(slowDown); + final WorldParticleBuilder bloomParticleBuilder = SpiritLightSpecs.spiritBloom(level, bloomColorData, spinData, lifetime).addTickActor(slowDown); return new ParticleEffectSpawner<>(level, pos, worldParticleBuilder, bloomParticleBuilder); } diff --git a/src/main/java/com/sammy/malum/visual_effects/WeepingWellParticleEffects.java b/src/main/java/com/sammy/malum/visual_effects/WeepingWellParticleEffects.java index 62e9fe2f0..cccb79cca 100644 --- a/src/main/java/com/sammy/malum/visual_effects/WeepingWellParticleEffects.java +++ b/src/main/java/com/sammy/malum/visual_effects/WeepingWellParticleEffects.java @@ -1,8 +1,8 @@ package com.sammy.malum.visual_effects; import com.sammy.malum.common.block.curiosities.weeping_well.*; -import com.sammy.malum.common.entity.nitrate.*; import com.sammy.malum.registry.client.*; +import com.sammy.malum.visual_effects.networked.data.*; import net.minecraft.core.*; import net.minecraft.world.level.*; import net.minecraft.world.level.block.*; @@ -20,19 +20,12 @@ import java.awt.*; import java.util.*; -import java.util.List; import java.util.function.*; -import static com.sammy.malum.common.entity.nitrate.VividNitrateEntity.COLOR_FUNCTION; import static com.sammy.malum.visual_effects.SpiritLightSpecs.spiritLightSpecs; public class WeepingWellParticleEffects { - public static final List RADIANT_COLORS = List.of( - new Color(179, 35, 218), - new Color(224, 210, 68), - new Color(42, 146, 218)); - private static final VoxelShape WELL_SHAPE = Block.box(-16.0D, 11.0D, -16.0D, 32.0D, 13.0D, 32.0D); private static final GenericParticleData SMOKE_TRANSPARENCY = GenericParticleData.create(0, 0.2f, 0f).setEasing(Easing.SINE_IN, Easing.SINE_OUT).build(); @@ -41,6 +34,82 @@ public static Color getWeepingWellSmokeColor(Random rand) { return new Color((int) (12 * colorMultiplier), (int) (3 * colorMultiplier), (int) (12 * colorMultiplier)); } + public static void spitOutItemParticles(Level level, PositionEffectData positionEffectData) { + double posX = positionEffectData.posX; + double posY = positionEffectData.posY; + double posZ = positionEffectData.posZ; + Vec3 pos = new Vec3(posX, posY, posZ); + Random rand = level.random; + Color color = getWeepingWellSmokeColor(rand); + ColorParticleData colorData = ColorParticleData.create(color, color.darker()).setCoefficient(0.5f).build(); + Consumer spawnBehavior = p -> p.tickParticle(2); + for (int i = 0; i < 64; i++) { + float xVelocity = RandomHelper.randomBetween(rand, 0f, 0.15f) * (rand.nextBoolean() ? 1 : -1); + float yVelocity = RandomHelper.randomBetween(rand, 0.5f, 1f); + float zVelocity = RandomHelper.randomBetween(rand, 0f, 0.15f) * (rand.nextBoolean() ? 1 : -1); + float gravityStrength = RandomHelper.randomBetween(rand, 0.75f, 1f); + if (rand.nextFloat() < 0.85f) { + var sparkParticles = weepingWellSparks(level, pos, colorData, LodestoneWorldParticleRenderType.LUMITRANSPARENT); + sparkParticles.getBuilder() + .addSpawnActor(spawnBehavior) + .disableNoClip() + .setGravityStrength(gravityStrength/2f) + .setMotion(xVelocity, yVelocity, zVelocity) + .modifyData(SparkParticleBuilder::getTransparencyData, d -> d.multiplyValue(2f)) + .modifyData(SparkParticleBuilder::getScaleData, d -> d.multiplyValue(1.5f)); + sparkParticles.getBloomBuilder() + .addSpawnActor(spawnBehavior) + .disableNoClip() + .setGravityStrength(gravityStrength/2f) + .setMotion(xVelocity, yVelocity, zVelocity) + .modifyData(WorldParticleBuilder::getTransparencyData, d -> d.multiplyValue(1.25f)); + sparkParticles.spawnParticles(); + } + if (rand.nextFloat() < 0.85f) { + xVelocity *= 1.25f; + yVelocity *= 0.75f; + zVelocity *= 1.25f; + var lightSpecs = weepingWellSpecs(level, pos, colorData, LodestoneWorldParticleRenderType.LUMITRANSPARENT); + lightSpecs.getBuilder() + .addSpawnActor(spawnBehavior) + .disableNoClip() + .setGravityStrength(gravityStrength) + .setMotion(xVelocity, yVelocity, zVelocity) + .modifyData(WorldParticleBuilder::getScaleData, d -> d.multiplyValue(2.5f)); + lightSpecs.getBloomBuilder() + .addSpawnActor(spawnBehavior) + .disableNoClip() + .setGravityStrength(gravityStrength) + .setMotion(xVelocity, yVelocity, zVelocity) + .modifyData(WorldParticleBuilder::getTransparencyData, d -> d.multiplyValue(1.25f)); + lightSpecs.spawnParticles(); + } + } + int spinOffset = rand.nextInt(360); + for (int i = 0; i < 4; i++) { + int spinDirection = (rand.nextBoolean() ? 1 : -1); + float scaleMultiplier = (float) (1+Math.pow(rand.nextFloat(), 2)); + WorldParticleBuilder.create(LodestoneParticleRegistry.SPARKLE_PARTICLE) + .setTransparencyData(GenericParticleData.create(0.7f, 0.5f, 0).setEasing(Easing.SINE_IN, Easing.CIRC_IN).build()) + .setSpinData(SpinParticleData.create((0.125f + rand.nextFloat() * 0.075f) * spinDirection).setSpinOffset(spinOffset).build()) + .setScaleData(GenericParticleData.create(2.4f*scaleMultiplier, 0.8f, 0).setEasing(Easing.QUAD_IN, Easing.SINE_IN).build()) + .setColorData(colorData) + .setLifetime(25) + .setRandomOffset(0.6f) + .enableNoClip() + .setRandomMotion(0.02f, 0.02f) + .setDiscardFunction(SimpleParticleOptions.ParticleDiscardFunctionType.ENDING_CURVE_INVISIBLE) + .setRenderType(LodestoneWorldParticleRenderType.LUMITRANSPARENT) + .repeat(level, posX, posY+0.25f, posZ, 5); + } + for (int i = 0; i < 8; i++) { + int finalI = 4+i/2; + var squares = weepingWellSquare(level, pos, colorData); + squares.getBuilder().multiplyLifetime(0.5f).addSpawnActor(p -> p.tickParticle(finalI)); + squares.spawnParticles(); + } + } + public static void passiveWeepingWellParticles(VoidConduitBlockEntity voidConduit) { Level level = voidConduit.getLevel(); if (level.getGameTime() % 6L == 0) { @@ -73,56 +142,37 @@ public static void passiveWeepingWellParticles(VoidConduitBlockEntity voidCondui }; for (int i = 0; i < 2; i++) { var lightSpecs = weepingWellSpecs(level, offsetPosition); - lightSpecs.getBuilder().addActor(behavior); - lightSpecs.getBloomBuilder().addActor(behavior); + lightSpecs.getBuilder().addTickActor(behavior); + lightSpecs.getBloomBuilder().addTickActor(behavior); lightSpecs.spawnParticles(); } } } } - public static void radiantWeepingWellParticles(VoidConduitBlockEntity voidConduit) { - Level level = voidConduit.getLevel(); - Random rand = level.random; - Color color = RADIANT_COLORS.get(((int) level.getGameTime() % 27) / 9); - final BlockPos blockPos = voidConduit.getBlockPos(); - final ColorParticleData colorData = ColorParticleData.create(color.brighter(), color).setCoefficient(0.5f).build(); - if (level.getGameTime() % 3L == 0) { - final GenericParticleData scaleData = GenericParticleData.create(0.1f, RandomHelper.randomBetween(rand, 1.7f, 1.8f), 0.5f).setEasing(Easing.SINE_OUT, Easing.SINE_IN).setCoefficient(RandomHelper.randomBetween(rand, 1f, 1.25f)).build(); - final Consumer slowDown = p -> p.setParticleMotion(p.getParticleSpeed().scale(0.95f)); - float yMotion = RandomHelper.randomBetween(rand, 0.04f, 0.06f); - Vec3 motion = new Vec3(0f, yMotion, 0f); - DirectionalParticleBuilder.create(ParticleRegistry.SQUARE) - .setTransparencyData(GenericParticleData.create(0.9f, 0.05f, 0f).setEasing(Easing.CUBIC_OUT, Easing.EXPO_IN).build()) - .setScaleData(scaleData) - .setColorData(colorData) - .setLifetime(100) - .setMotion(motion) - .setDirection(motion.normalize()) - .enableNoClip() - .setSpritePicker(SimpleParticleOptions.ParticleSpritePicker.RANDOM_SPRITE) - .addActor(slowDown) - .spawn(level, blockPos.getX() + 0.5f, blockPos.getY() + 0.75f, blockPos.getZ() + 0.5f) - .setTransparencyData(GenericParticleData.create(0.1f, 0.6f, 0f).setEasing(Easing.CUBIC_OUT, Easing.EXPO_OUT).build()) - .setRenderType(LodestoneWorldParticleRenderType.LUMITRANSPARENT) - .spawn(level, blockPos.getX() + 0.5f, blockPos.getY() + 0.65f, blockPos.getZ() + 0.5f); - } - final float acceleration = RandomHelper.randomBetween(rand, 0.002f, 0.02f); - final long gameTime = level.getGameTime(); - final Consumer behavior = p -> { - if (level.getGameTime() < gameTime + 5) { - p.setParticleMotion(p.getParticleSpeed().add(0, acceleration, 0)); - } - }; - if (level.getGameTime() % 2L == 0) { - int rotation = (int) ((level.getGameTime() / 2f) % 16); - Vec3 offsetPosition = DataHelper.rotatingRadialOffset(new Vec3(blockPos.getX() + 0.5f, blockPos.getY() + 0.75f, blockPos.getZ() + 0.5f), 1.1f, rotation, 16, voidConduit.getLevel().getGameTime(), 640); - var lightSpecs = weepingWellSpecs(level, offsetPosition, colorData, LodestoneWorldParticleRenderType.ADDITIVE); - lightSpecs.getBuilder().addActor(behavior); - lightSpecs.getBloomBuilder().addActor(behavior); - lightSpecs.spawnParticles(); - } + public static ParticleEffectSpawner weepingWellSparks(Level level, Vec3 pos) { + Random rand = level.random; + Color color = getWeepingWellSmokeColor(rand); + ColorParticleData colorData = ColorParticleData.create(color, color.darker()).setCoefficient(0.5f).build(); + return weepingWellSparks(level, pos, colorData, LodestoneWorldParticleRenderType.LUMITRANSPARENT); + } + public static ParticleEffectSpawner weepingWellSparks(Level level, Vec3 pos, ColorParticleData colorData, LodestoneWorldParticleRenderType renderType) { + Random rand = level.random; + var lightSpecs = SparkParticleEffects.spiritMotionSparks(level, pos, colorData, colorData); + lightSpecs.getBuilder().act(b -> b + .setRenderType(renderType) + .multiplyLifetime(6f) + .modifyData(b::getLengthData, d -> d.multiplyValue(RandomHelper.randomBetween(rand, 1.75f, 2.5f))) + .modifyData(b::getTransparencyData, d -> d.multiplyValue(RandomHelper.randomBetween(rand, 0.75f, 1f))) + .modifyData(b::getScaleData, d -> d.multiplyValue(RandomHelper.randomBetween(rand, 1.5f, 3.5f)))); + lightSpecs.getBloomBuilder().act(b -> b + .setRenderType(renderType) + .multiplyLifetime(6f) + .setTransparencyData(GenericParticleData.create(0f, 0.75f, 0.25f).build()) + .setDiscardFunction(SimpleParticleOptions.ParticleDiscardFunctionType.ENDING_CURVE_INVISIBLE) + .modifyData(b::getScaleData, d -> d.multiplyValue(RandomHelper.randomBetween(rand, 1f, 1.25f)))); + return lightSpecs; } public static ParticleEffectSpawner weepingWellSpecs(Level level, Vec3 pos) { @@ -147,4 +197,28 @@ public static ParticleEffectSpawner weepingWellSpecs(Level .modifyData(b::getScaleData, d -> d.multiplyValue(RandomHelper.randomBetween(rand, 1f, 1.25f)))); return lightSpecs; } + public static ParticleEffectSpawner weepingWellSquare(Level level, Vec3 pos, ColorParticleData colorData) { + Random rand = level.random; + final GenericParticleData scaleData = GenericParticleData.create(0.1f, RandomHelper.randomBetween(rand, 1.7f, 1.8f), 0.5f).setEasing(Easing.SINE_OUT, Easing.SINE_IN).setCoefficient(RandomHelper.randomBetween(rand, 1f, 1.25f)).build(); + final Consumer behavior = p -> p.setParticleMotion(p.getParticleSpeed().scale(0.95f)); + float yMotion = RandomHelper.randomBetween(rand, 0.04f, 0.06f); + Vec3 motion = new Vec3(0f, yMotion, 0f); + var squares = DirectionalParticleBuilder.create(ParticleRegistry.SQUARE) + .setTransparencyData(GenericParticleData.create(0.9f, 0.05f, 0f).setEasing(Easing.CUBIC_OUT, Easing.EXPO_IN).build()) + .setScaleData(scaleData) + .setColorData(colorData) + .setLifetime(100) + .setMotion(motion) + .setDirection(motion.normalize()) + .enableNoClip() + .setSpritePicker(SimpleParticleOptions.ParticleSpritePicker.RANDOM_SPRITE) + .addTickActor(behavior); + Consumer squareSpawner = b -> b + .spawn(level, pos.x, pos.y, pos.z) + .setTransparencyData(GenericParticleData.create(0.1f, 0.6f, 0f).setEasing(Easing.CUBIC_OUT, Easing.EXPO_OUT).build()) + .setRenderType(LodestoneWorldParticleRenderType.LUMITRANSPARENT) + .spawn(level, pos.x, pos.y, pos.z); + + return new ParticleEffectSpawner<>(squares, squareSpawner); + } } diff --git a/src/main/java/com/sammy/malum/visual_effects/networked/generic/DrippingSmokeParticleEffect.java b/src/main/java/com/sammy/malum/visual_effects/networked/generic/DrippingSmokeParticleEffect.java index c2a0114bb..e6ba29d44 100644 --- a/src/main/java/com/sammy/malum/visual_effects/networked/generic/DrippingSmokeParticleEffect.java +++ b/src/main/java/com/sammy/malum/visual_effects/networked/generic/DrippingSmokeParticleEffect.java @@ -53,7 +53,7 @@ public Supplier get() { .setRandomOffset(0.2f, 0.4f) .setRandomMotion(0.02f) .addMotion(0, -0.0075f - random.nextFloat() * 0.01f, 0) - .addActor(actorFunction.apply(0.015f)) + .addTickActor(actorFunction.apply(0.015f)) .repeat(level, posX, posY, posZ, (int) (3 * intensity)); } for (int i = 0; i < 2; i++) { @@ -69,7 +69,7 @@ public Supplier get() { .setRandomOffset(0.2f, 0.4f) .setRandomMotion(0.01f, 0) .addMotion(0, -0.03f - random.nextFloat() * 0.015f, 0) - .addActor(actorFunction.apply(0.04f)) + .addTickActor(actorFunction.apply(0.04f)) .repeat(level, posX, posY, posZ, (int) (2 * intensity)); } }; diff --git a/src/main/java/com/sammy/malum/visual_effects/networked/generic/HexingSmokeParticleEffect.java b/src/main/java/com/sammy/malum/visual_effects/networked/generic/HexingSmokeParticleEffect.java index f44bd240b..80e230fa7 100644 --- a/src/main/java/com/sammy/malum/visual_effects/networked/generic/HexingSmokeParticleEffect.java +++ b/src/main/java/com/sammy/malum/visual_effects/networked/generic/HexingSmokeParticleEffect.java @@ -49,7 +49,7 @@ public Supplier get() { .enableNoClip() .setRandomOffset(0.2f, 0.2f) .setRandomMotion(0.02f) - .addActor(p -> p.setParticleMotion(p.getParticleSpeed().scale(0.95f))) + .addTickActor(p -> p.setParticleMotion(p.getParticleSpeed().scale(0.95f))) .repeat(level, posX, posY, posZ, (int) (4*intensity)); } WorldParticleBuilder.create(LodestoneParticleRegistry.WISP_PARTICLE) @@ -61,7 +61,7 @@ public Supplier get() { .enableNoClip() .setRandomOffset(0.05f, 0.05f) .setRandomMotion(0.05f) - .addActor(p -> p.setParticleMotion(p.getParticleSpeed().scale(0.5f))) + .addTickActor(p -> p.setParticleMotion(p.getParticleSpeed().scale(0.5f))) .repeat(level, posX, posY, posZ, (int) (6*intensity)); WorldParticleBuilder.create(LodestoneParticleRegistry.SMOKE_PARTICLE) .setTransparencyData(GenericParticleData.create(0, 0.05f, 0).build()) @@ -72,7 +72,7 @@ public Supplier get() { .enableNoClip() .setRandomOffset(0.15f, 0.15f) .setRandomMotion(0.015f, 0.015f) - .addActor(p -> p.setParticleMotion(p.getParticleSpeed().scale(0.92f))) + .addTickActor(p -> p.setParticleMotion(p.getParticleSpeed().scale(0.92f))) .repeat(level, posX, posY, posZ, (int) (10*intensity)); }; } diff --git a/src/main/java/com/sammy/malum/visual_effects/networked/weeping_well/WeepingWellRadianceParticleEffect.java b/src/main/java/com/sammy/malum/visual_effects/networked/weeping_well/WeepingWellRadianceParticleEffect.java index 9f4cb1ac6..2acce5cb4 100644 --- a/src/main/java/com/sammy/malum/visual_effects/networked/weeping_well/WeepingWellRadianceParticleEffect.java +++ b/src/main/java/com/sammy/malum/visual_effects/networked/weeping_well/WeepingWellRadianceParticleEffect.java @@ -1,19 +1,9 @@ package com.sammy.malum.visual_effects.networked.weeping_well; +import com.sammy.malum.visual_effects.*; import com.sammy.malum.visual_effects.networked.*; -import net.minecraft.util.*; import net.minecraftforge.api.distmarker.*; -import team.lodestar.lodestone.helpers.*; -import team.lodestar.lodestone.setup.*; -import team.lodestar.lodestone.systems.easing.*; -import team.lodestar.lodestone.systems.particle.*; -import team.lodestar.lodestone.systems.particle.builder.*; -import team.lodestar.lodestone.systems.particle.data.*; -import team.lodestar.lodestone.systems.particle.data.color.*; -import team.lodestar.lodestone.systems.particle.data.spin.*; -import team.lodestar.lodestone.systems.particle.render_types.*; -import java.awt.*; import java.util.function.*; public class WeepingWellRadianceParticleEffect extends ParticleEffectType { @@ -26,9 +16,7 @@ public WeepingWellRadianceParticleEffect(String id) { @Override public Supplier get() { return () -> (level, random, positionData, colorData, nbtData) -> { - double posX = positionData.posX; - double posY = positionData.posY; - double posZ = positionData.posZ; + RadiantParticleEffects.spitOutWeepingWellRadiance(level, positionData); }; } } \ No newline at end of file diff --git a/src/main/java/com/sammy/malum/visual_effects/networked/weeping_well/WeepingWellReactionParticleEffect.java b/src/main/java/com/sammy/malum/visual_effects/networked/weeping_well/WeepingWellReactionParticleEffect.java index 3c667d03f..0e68033ac 100644 --- a/src/main/java/com/sammy/malum/visual_effects/networked/weeping_well/WeepingWellReactionParticleEffect.java +++ b/src/main/java/com/sammy/malum/visual_effects/networked/weeping_well/WeepingWellReactionParticleEffect.java @@ -1,5 +1,6 @@ package com.sammy.malum.visual_effects.networked.weeping_well; +import com.sammy.malum.visual_effects.*; import com.sammy.malum.visual_effects.networked.*; import net.minecraft.util.*; import net.minecraftforge.api.distmarker.*; @@ -26,51 +27,7 @@ public WeepingWellReactionParticleEffect(String id) { @Override public Supplier get() { return () -> (level, random, positionData, colorData, nbtData) -> { - double posX = positionData.posX; - double posY = positionData.posY; - double posZ = positionData.posZ; - for (int i = 0; i < 8; i++) { - float multiplier = Mth.nextFloat(random, 0.1f, 1.5f); - Color color = new Color((int)(12*multiplier), (int)(4*multiplier), (int)(14*multiplier)); - int spinDirection = (random.nextBoolean() ? 1 : -1); - int spinOffset = random.nextInt(360); - float motionMultiplier = (float) (1+Math.pow(random.nextFloat()+i*0.2f, 2)); - float extraMotion = 0.2f * motionMultiplier * ((8 - i) / 8f); - WorldParticleBuilder.create(LodestoneParticleRegistry.TWINKLE_PARTICLE) - .setTransparencyData(GenericParticleData.create(0.2f, 1f, 0).build()) - .setSpinData(SpinParticleData.create(0.9f * spinDirection, 0).setSpinOffset(spinOffset).setCoefficient(1.25f).setEasing(Easing.CUBIC_IN).build()) - .setScaleData(GenericParticleData.create(0.075f, 0.25f, 0).setCoefficient(0.8f).setEasing(Easing.QUINTIC_OUT, Easing.EXPO_IN_OUT).build()) - .setColorData(ColorParticleData.create(ColorHelper.brighter(color, 2), color).build()) - .setLifetime(30) - .enableNoClip() - .setRandomOffset(0.85f) - .setGravityStrength(1.1f) - .addMotion(0, 0.3f + random.nextFloat() * 0.15f * motionMultiplier, 0) - .disableNoClip() - .setRandomMotion(extraMotion, extraMotion) - .setDiscardFunction(SimpleParticleOptions.ParticleDiscardFunctionType.ENDING_CURVE_INVISIBLE) - .setRenderType(LodestoneWorldParticleRenderType.LUMITRANSPARENT) - .repeat(level, posX, posY, posZ, 6); - } - int spinOffset = random.nextInt(360); - for (int i = 0; i < 4; i++) { - float multiplier = Mth.nextFloat(random, 0.1f, 1.5f); - Color color = new Color((int)(4*multiplier), (int)(2*multiplier), (int)(4*multiplier)); - int spinDirection = (random.nextBoolean() ? 1 : -1); - float scaleMultiplier = (float) (1+Math.pow(random.nextFloat(), 2)); - WorldParticleBuilder.create(LodestoneParticleRegistry.SPARKLE_PARTICLE) - .setTransparencyData(GenericParticleData.create(0.7f, 0.5f, 0).setEasing(Easing.SINE_IN, Easing.CIRC_IN).build()) - .setSpinData(SpinParticleData.create((0.125f + random.nextFloat() * 0.075f) * spinDirection).setSpinOffset(spinOffset).build()) - .setScaleData(GenericParticleData.create(1.8f*scaleMultiplier, 0.6f, 0).setEasing(Easing.EXPO_OUT, Easing.SINE_IN).build()) - .setColorData(ColorParticleData.create(color.brighter(), color.darker()).build()) - .setLifetime(25) - .setRandomOffset(0.6f) - .enableNoClip() - .setRandomMotion(0.02f, 0.02f) - .setDiscardFunction(SimpleParticleOptions.ParticleDiscardFunctionType.ENDING_CURVE_INVISIBLE) - .setRenderType(LodestoneWorldParticleRenderType.LUMITRANSPARENT) - .repeat(level, posX, posY, posZ, 5); - } + WeepingWellParticleEffects.spitOutItemParticles(level, positionData); }; } } \ No newline at end of file