Unicopia/src/main/java/com/minelittlepony/unicopia/block/WeatherVaneBlock.java

140 lines
5 KiB
Java
Raw Normal View History

2022-10-12 15:46:15 +02:00
package com.minelittlepony.unicopia.block;
import org.jetbrains.annotations.Nullable;
import com.minelittlepony.unicopia.USounds;
2024-04-22 18:21:12 +02:00
import com.minelittlepony.unicopia.particle.TargetBoundParticleEffect;
import com.minelittlepony.unicopia.particle.UParticles;
2023-04-30 11:46:33 +02:00
import com.minelittlepony.unicopia.server.world.WeatherConditions;
2022-10-12 15:46:15 +02:00
import net.minecraft.block.*;
import net.minecraft.block.entity.*;
import net.minecraft.nbt.NbtCompound;
2023-06-02 21:20:30 +02:00
import net.minecraft.network.packet.Packet;
2022-10-12 15:46:15 +02:00
import net.minecraft.network.listener.ClientPlayPacketListener;
import net.minecraft.network.packet.s2c.play.BlockEntityUpdateS2CPacket;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.sound.SoundCategory;
import net.minecraft.util.math.*;
import net.minecraft.util.shape.VoxelShape;
import net.minecraft.util.shape.VoxelShapes;
import net.minecraft.world.BlockView;
import net.minecraft.world.World;
public class WeatherVaneBlock extends BlockWithEntity {
2023-10-13 21:37:00 +02:00
private static final VoxelShape SHAPE = VoxelShapes.union(
2022-10-12 15:46:15 +02:00
Block.createCuboidShape(7.5F, 0, 7.5F, 8.5F, 14, 8.5F),
Block.createCuboidShape(7, 0, 7, 9, 1, 9)
2023-10-13 21:37:00 +02:00
);
2022-10-12 15:46:15 +02:00
protected WeatherVaneBlock(Settings settings) {
super(settings);
}
@Deprecated
@Override
public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
2023-10-13 21:37:00 +02:00
return SHAPE;
2022-10-12 15:46:15 +02:00
}
@Override
public BlockEntity createBlockEntity(BlockPos pos, BlockState state) {
return new WeatherVane(pos, state);
}
@Override
@Nullable
public <T extends BlockEntity> BlockEntityTicker<T> getTicker(World world, BlockState state, BlockEntityType<T> type) {
2023-09-29 20:15:04 +02:00
return validateTicker(type, UBlockEntities.WEATHER_VANE, world.isClient ? WeatherVane::clientTick : WeatherVane::serverTick);
2022-10-12 15:46:15 +02:00
}
public static class WeatherVane extends BlockEntity {
private float angle;
private float clientAngle;
private float prevAngle;
2024-04-22 18:21:12 +02:00
private float lastAngle;
private Vec3d airflow = Vec3d.ZERO;
2022-10-12 15:46:15 +02:00
public WeatherVane(BlockPos pos, BlockState state) {
super(UBlockEntities.WEATHER_VANE, pos, state);
}
public float getAngle(float tickDelta) {
return MathHelper.lerp(tickDelta, prevAngle, clientAngle);
}
@Override
public void readNbt(NbtCompound nbt) {
angle = nbt.getFloat("angle");
2024-04-22 18:21:12 +02:00
airflow = new Vec3d(nbt.getDouble("windX"), 0, nbt.getDouble("windZ"));
2022-10-12 15:46:15 +02:00
}
@Override
protected void writeNbt(NbtCompound nbt) {
nbt.putFloat("angle", angle);
2024-04-22 18:21:12 +02:00
nbt.putDouble("windX", airflow.x);
nbt.putDouble("windZ", airflow.z);
2022-10-12 15:46:15 +02:00
}
@Override
public Packet<ClientPlayPacketListener> toUpdatePacket() {
return BlockEntityUpdateS2CPacket.create(this);
}
@Override
public NbtCompound toInitialChunkDataNbt() {
return createNbt();
}
public static void serverTick(World world, BlockPos pos, BlockState state, WeatherVane entity) {
Vec3d airflow = WeatherConditions.get(world).getWindDirection();
2024-04-22 18:21:12 +02:00
float angle = (WeatherConditions.get(world).getWindYaw() % MathHelper.PI);
2022-10-12 15:46:15 +02:00
2024-04-22 18:21:12 +02:00
entity.lastAngle = entity.prevAngle;
entity.prevAngle = entity.angle;
2022-10-12 15:46:15 +02:00
if (angle != entity.angle) {
entity.angle = angle;
2024-04-22 18:21:12 +02:00
entity.airflow = airflow;
2022-10-12 15:46:15 +02:00
entity.markDirty();
2024-04-22 18:21:12 +02:00
if (world instanceof ServerWorld sw) {
sw.getChunkManager().markForUpdate(pos);
2022-10-12 15:46:15 +02:00
}
2024-04-22 18:21:12 +02:00
if (entity.lastAngle == entity.prevAngle) {
world.playSound(null, pos.getX(), pos.getY(), pos.getZ(), USounds.BLOCK_WEATHER_VANE_ROTATE, SoundCategory.BLOCKS, 1, 0.5F + (float)world.random.nextGaussian());
}
2022-10-12 15:46:15 +02:00
}
2024-04-22 18:21:12 +02:00
2022-10-12 15:46:15 +02:00
}
public static void clientTick(World world, BlockPos pos, BlockState state, WeatherVane entity) {
entity.prevAngle = entity.clientAngle;
float angle = entity.angle + (float)Math.sin(world.getTime() / 70F) * (world.isThundering() ? 30 : 1);
float step = (Math.abs(entity.clientAngle) - Math.abs(angle)) / 7F;
if (entity.clientAngle < angle) {
entity.clientAngle += step;
} else if (entity.clientAngle > angle) {
entity.clientAngle -= step;
}
2024-04-22 18:21:12 +02:00
if (world.random.nextInt(3) == 0) {
float radius = 10;
for (int i = 0; i < 5; i++) {
world.addImportantParticle(new TargetBoundParticleEffect(UParticles.WIND, null),
world.getRandom().nextTriangular(pos.getX(), radius),
world.getRandom().nextTriangular(pos.getY(), radius),
world.getRandom().nextTriangular(pos.getZ(), radius),
entity.airflow.x / 10F, 0, entity.airflow.z / 10F
);
}
}
2022-10-12 15:46:15 +02:00
}
}
}