Added unstable clouds

This commit is contained in:
Sollace 2023-10-19 01:41:22 +01:00
parent ea94092b2c
commit c04161eb91
No known key found for this signature in database
GPG key ID: E52FACE7B5C773DB
6 changed files with 179 additions and 33 deletions

View file

@ -11,6 +11,7 @@ import com.minelittlepony.unicopia.block.cloud.PoreousCloudBlock;
import com.minelittlepony.unicopia.block.cloud.CloudBlock;
import com.minelittlepony.unicopia.block.cloud.SoggyCloudBlock;
import com.minelittlepony.unicopia.block.cloud.SoggyCloudSlabBlock;
import com.minelittlepony.unicopia.block.cloud.UnstableCloudBlock;
import com.minelittlepony.unicopia.item.UItems;
import com.minelittlepony.unicopia.item.group.ItemGroupRegistry;
import com.minelittlepony.unicopia.server.world.UTreeGen;
@ -133,6 +134,7 @@ public interface UBlocks {
Block CLOUD = register("cloud", new PoreousCloudBlock(Settings.create().mapColor(MapColor.OFF_WHITE).hardness(0.3F).resistance(0).sounds(BlockSoundGroup.WOOL), true, () -> UBlocks.SOGGY_CLOUD));
Block CLOUD_SLAB = register("cloud_slab", new CloudSlabBlock(Settings.copy(CLOUD), true, () -> UBlocks.SOGGY_CLOUD_SLAB));
Block UNSTABLE_CLOUD = register("unstable_cloud", new UnstableCloudBlock(Settings.copy(CLOUD)));
SoggyCloudBlock SOGGY_CLOUD = register("soggy_cloud", new SoggyCloudBlock(Settings.copy(CLOUD), () -> UBlocks.CLOUD));
SoggyCloudSlabBlock SOGGY_CLOUD_SLAB = register("soggy_cloud_slab", new SoggyCloudSlabBlock(Settings.copy(CLOUD), () -> UBlocks.CLOUD_SLAB));
Block DENSE_CLOUD = register("dense_cloud", new CloudBlock(Settings.create().mapColor(MapColor.GRAY).hardness(0.5F).resistance(0).sounds(BlockSoundGroup.WOOL), false));

View file

@ -0,0 +1,73 @@
package com.minelittlepony.unicopia.block.cloud;
import java.util.Optional;
import com.minelittlepony.unicopia.particle.LightningBoltParticleEffect;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.entity.Entity;
import net.minecraft.particle.ParticleTypes;
import net.minecraft.sound.SoundCategory;
import net.minecraft.sound.SoundEvents;
import net.minecraft.state.StateManager;
import net.minecraft.state.property.IntProperty;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Box;
import net.minecraft.util.math.random.Random;
import net.minecraft.world.World;
public class UnstableCloudBlock extends CloudBlock {
private static final int MAX_CHARGE = 6;
private static final IntProperty CHARGE = IntProperty.of("charge", 0, MAX_CHARGE);
public UnstableCloudBlock(Settings settings) {
super(settings, false);
setDefaultState(getDefaultState().with(CHARGE, 0));
}
@Override
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
builder.add(CHARGE);
}
@Override
public void randomDisplayTick(BlockState state, World world, BlockPos pos, Random random) {
int charge = state.get(CHARGE);
if (charge > 0) {
world.addParticle(new LightningBoltParticleEffect(true, 10, 1, 0.6F + (charge / (float)MAX_CHARGE) * 0.4F, Optional.empty()), pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5, 0, 0, 0);
}
}
@Override
public void onLandedUpon(World world, BlockState state, BlockPos pos, Entity entity, float fallDistance) {
super.onLandedUpon(world, state, pos, entity, fallDistance);
for (int i = 0; i < 9; i++) {
world.addParticle(ParticleTypes.CLOUD, pos.getX() + world.random.nextFloat(), pos.getY() + world.random.nextFloat(), pos.getZ() + world.random.nextFloat(), 0, 0, 0);
}
world.playSound(null, pos, SoundEvents.BLOCK_WOOL_HIT, SoundCategory.BLOCKS, 1, 1);
if (state.get(CHARGE) < MAX_CHARGE) {
world.setBlockState(pos, state.cycle(CHARGE));
} else {
world.setBlockState(pos, state.with(CHARGE, 0));
BlockPos shockPosition = pos.add(world.random.nextInt(10) - 5, -world.random.nextInt(10), world.random.nextInt(10) - 5);
world.addImportantParticle(
new LightningBoltParticleEffect(false, 10, 6, 0.3F, Optional.of(shockPosition.toCenterPos())),
true,
pos.getX() + 0.5, pos.getY(), pos.getZ() + 0.5,
0, 0, 0
);
world.getOtherEntities(null, new Box(shockPosition).expand(2)).forEach(e -> {
e.damage(entity.getDamageSources().lightningBolt(), 1);
});
if (world.isAir(shockPosition) && world.getBlockState(shockPosition.down()).isBurnable()) {
world.setBlockState(shockPosition, Blocks.FIRE.getDefaultState());
}
}
}
}

View file

@ -21,7 +21,7 @@ import net.minecraft.util.math.Vec3d;
public class LightningBoltParticle extends AbstractGeometryBasedParticle {
private final List<List<Vector3f>> branches = new ArrayList<>();
private final List<Bolt> branches = new ArrayList<>();
private final LightningBoltParticleEffect effect;
@ -37,42 +37,73 @@ public class LightningBoltParticle extends AbstractGeometryBasedParticle {
return;
}
if (age % effect.changeFrequency() == 0) {
if (effect.changeFrequency() > 0 && age % effect.changeFrequency() == 0) {
branches.clear();
}
if (branches.isEmpty()) {
int totalBranches = 2 + world.random.nextInt(6);
while (branches.size() < totalBranches) {
branches.add(generateBranch());
}
if (branches.isEmpty()) {
effect.pathEndPoint().ifPresentOrElse(endpoint -> {
branches.add(generateTrunk(endpoint.subtract(x, y, z).toVector3f()));
}, () -> {
int totalBranches = 2 + world.random.nextInt(effect.maxBranches());
while (branches.size() < totalBranches) {
branches.add(generateBranch());
}
});
if (!effect.silent()) {
world.playSound(x, y, z, USounds.Vanilla.ENTITY_LIGHTNING_BOLT_THUNDER, SoundCategory.WEATHER, 10000, 8, true);
}
}
world.setLightningTicksLeft(2);
if (effect.pathEndPoint().isEmpty() && !effect.silent()) {
world.setLightningTicksLeft(2);
}
}
private List<Vector3f> generateBranch() {
private Bolt generateTrunk(Vector3f end) {
Vector3f start = new Vector3f(0, 0, 0);
int kinks = 2 + world.random.nextInt(effect.maxBranches());
Vector3f segmentLength = end.sub(start, new Vector3f()).mul(1F/kinks);
float deviation = effect.maxDeviation();
List<Vector3f> nodes = new ArrayList<>();
nodes.add(start);
for (int i = 0; i < kinks - 1; i++) {
start = start.add(segmentLength, new Vector3f()).add(
(float)world.random.nextTriangular(0, deviation),
0,
(float)world.random.nextTriangular(0, deviation)
);
nodes.add(start);
}
nodes.add(end);
return new Bolt(true, nodes);
}
private Bolt generateBranch() {
Vector3f startPos = new Vector3f(0, 0, 0);
int intendedLength = 2 + world.random.nextInt(6);
int intendedLength = 2 + world.random.nextInt(effect.maxBranches());
float deviation = effect.maxDeviation();
List<Vector3f> nodes = new ArrayList<>();
while (nodes.size() < intendedLength) {
startPos = startPos.add(
(float)world.random.nextTriangular(0.1F, 3),
(float)world.random.nextTriangular(0.1F, 3),
(float)world.random.nextTriangular(0.1F, 3)
(float)world.random.nextTriangular(0F, deviation),
(float)world.random.nextTriangular(0F, deviation),
(float)world.random.nextTriangular(0F, deviation),
new Vector3f()
);
nodes.add(startPos);
}
return nodes;
return new Bolt(false, nodes);
}
@Override
@ -89,10 +120,15 @@ public class LightningBoltParticle extends AbstractGeometryBasedParticle {
float z = (float)(MathHelper.lerp(tickDelta, prevPosZ, this.z) - cam.getZ());
Vector3f origin = new Vector3f(x, y, z);
Vector3f from = new Vector3f();
Vector3f to = new Vector3f();
for (List<Vector3f> branch : branches) {
for (int i = 0; i < branch.size(); i++) {
renderBranch(buffer, i == 0 ? origin : new Vector3f(branch.get(i - 1).add(x, y, z)), new Vector3f(branch.get(i).add(x, y, z)));
for (Bolt branch : branches) {
for (int i = 0; i < branch.nodes().size(); i++) {
renderBranch(buffer,
branch.isTrunk() ? 0.05125F : world.random.nextFloat() / 30 + 0.01F,
i == 0 ? origin : branch.nodes().get(i - 1).add(x, y, z, from), branch.nodes().get(i).add(x, y, z, to)
);
}
}
@ -101,14 +137,28 @@ public class LightningBoltParticle extends AbstractGeometryBasedParticle {
RenderSystem.enableCull();
}
private void renderBranch(VertexConsumer buffer, Vector3f from, Vector3f to) {
float thickness = world.random.nextFloat() / 30 + 0.01F;
private void renderBranch(VertexConsumer buffer, float thickness, Vector3f from, Vector3f to) {
renderQuad(buffer, new Vector3f[]{
new Vector3f(from.x - thickness, from.y, from.z),
new Vector3f(to.x - thickness, to.y, to.z),
new Vector3f(to.x + thickness, to.y, to.z),
new Vector3f(from.x + thickness, from.y, from.z),
new Vector3f(from.x - thickness, from.y, from.z + thickness),
new Vector3f(to.x - thickness, to.y, to.z + thickness),
new Vector3f(to.x + thickness, to.y, to.z + thickness),
new Vector3f(from.x + thickness, from.y, from.z + thickness),
new Vector3f(from.x - thickness, from.y, from.z - thickness),
new Vector3f(to.x - thickness, to.y, to.z - thickness),
new Vector3f(to.x + thickness, to.y, to.z - thickness),
new Vector3f(from.x + thickness, from.y, from.z - thickness),
new Vector3f(from.x - thickness, from.y, from.z - thickness),
new Vector3f(to.x - thickness, to.y, to.z - thickness),
new Vector3f(to.x - thickness, to.y, to.z + thickness),
new Vector3f(from.x - thickness, from.y, from.z + thickness),
new Vector3f(from.x + thickness, from.y, from.z - thickness),
new Vector3f(to.x + thickness, to.y, to.z - thickness),
new Vector3f(to.x + thickness, to.y, to.z + thickness),
new Vector3f(from.x + thickness, from.y, from.z + thickness)
/*,
new Vector3f(from.x - thickness, from.y - thickness * 2, from.z),
new Vector3f(to.x - thickness, to.y - thickness * 2, to.z),
@ -118,12 +168,18 @@ public class LightningBoltParticle extends AbstractGeometryBasedParticle {
new Vector3f(from.x, from.y - thickness, from.z + thickness),
new Vector3f(to.x, to.y - thickness, to.z + thickness),
new Vector3f(to.x, to.y + thickness, to.z + thickness),
new Vector3f(from.x, from.y + thickness, from.z + thickness),
new Vector3f(from.x, from.y + thickness, from.z + thickness)
,
new Vector3f(from.x - thickness * 2, from.y - thickness, from.z + thickness),
new Vector3f(to.x - thickness * 2, to.y - thickness, to.z + thickness),
new Vector3f(to.x - thickness * 2, to.y + thickness, to.z + thickness),
new Vector3f(from.x - thickness * 2, from.y + thickness, from.z + thickness)
new Vector3f(from.x - thickness * 2, from.y + thickness, from.z + thickness)*/
}, 0.3F, 1);
}
record Bolt(boolean isTrunk, List<Vector3f> nodes) {
}
}

View file

@ -149,6 +149,7 @@ public interface UItems {
Item DENSE_CLOUD = register("dense_cloud", new CloudBlockItem(UBlocks.DENSE_CLOUD, new Item.Settings()), ItemGroups.NATURAL);
Item DENSE_CLOUD_SLAB = register("dense_cloud_slab", new CloudBlockItem(UBlocks.DENSE_CLOUD_SLAB, new Item.Settings()), ItemGroups.NATURAL);
Item CLOUD_PILLAR = register("cloud_pillar", new CloudBlockItem(UBlocks.CLOUD_PILLAR, new Item.Settings()), ItemGroups.NATURAL);
Item UNSTABLE_CLOUD = register("unstable_cloud", new CloudBlockItem(UBlocks.UNSTABLE_CLOUD, new Item.Settings()), ItemGroups.NATURAL);
AmuletItem PEGASUS_AMULET = register("pegasus_amulet", new PegasusAmuletItem(new FabricItemSettings()
.maxCount(1)

View file

@ -1,27 +1,38 @@
package com.minelittlepony.unicopia.particle;
import java.util.Optional;
import com.mojang.brigadier.StringReader;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import net.minecraft.network.PacketByteBuf;
import net.minecraft.particle.ParticleEffect;
import net.minecraft.particle.ParticleType;
import net.minecraft.util.math.Vec3d;
public record LightningBoltParticleEffect (
boolean silent,
int changeFrequency,
int maxBranchLength
int maxBranches,
float maxDeviation,
Optional<Vec3d> pathEndPoint
) implements ParticleEffect {
public static final LightningBoltParticleEffect DEFAULT = new LightningBoltParticleEffect(false, 10, 6);
public static final LightningBoltParticleEffect DEFAULT = new LightningBoltParticleEffect(false, 10, 6, 3, Optional.empty());
@SuppressWarnings("deprecation")
public static final ParticleEffect.Factory<LightningBoltParticleEffect> FACTORY = ParticleFactoryHelper.of(LightningBoltParticleEffect::new, LightningBoltParticleEffect::new);
protected LightningBoltParticleEffect(ParticleType<LightningBoltParticleEffect> particleType, StringReader reader) throws CommandSyntaxException {
this(ParticleFactoryHelper.readBoolean(reader), ParticleFactoryHelper.readInt(reader), ParticleFactoryHelper.readInt(reader));
this(
ParticleFactoryHelper.readBoolean(reader),
ParticleFactoryHelper.readInt(reader),
ParticleFactoryHelper.readInt(reader),
ParticleFactoryHelper.readFloat(reader),
ParticleFactoryHelper.readOptional(reader, ParticleFactoryHelper::readVector)
);
}
protected LightningBoltParticleEffect(ParticleType<LightningBoltParticleEffect> particleType, PacketByteBuf buf) {
this(buf.readBoolean(), buf.readInt(), buf.readInt());
this(buf.readBoolean(), buf.readInt(), buf.readInt(), buf.readFloat(), buf.readOptional(ParticleFactoryHelper::readVector));
}
@Override
@ -33,12 +44,14 @@ public record LightningBoltParticleEffect (
public void write(PacketByteBuf buffer) {
buffer.writeBoolean(silent);
buffer.writeInt(changeFrequency);
buffer.writeInt(maxBranchLength);
buffer.writeInt(maxBranches);
buffer.writeFloat(maxDeviation);
buffer.writeOptional(pathEndPoint, ParticleFactoryHelper::writeVector);
}
@Override
public String asString() {
return String.format("%s %s %s", silent, changeFrequency, maxBranchLength);
return String.format("%s %s %s %s", silent, changeFrequency, maxBranches, maxDeviation);
}
}

View file

@ -221,6 +221,7 @@
"block.unicopia.cloud_slab": "Cloud Slab",
"block.unicopia.soggy_cloud": "Soggy Cloud",
"block.unicopia.soggy_cloud_slab": "Soggy Cloud Slab",
"block.unicopia.unstable_cloud": "Unstable Cloud",
"block.unicopia.cloud_pillar": "Cloud Pillar",
"block.unicopia.dense_cloud": "Dense Cloud",
"block.unicopia.dense_cloud_slab": "Dense Cloud Slab",