diff --git a/src/main/java/com/minelittlepony/unicopia/client/UnicopiaClient.java b/src/main/java/com/minelittlepony/unicopia/client/UnicopiaClient.java index a5a1d7b6..94567e24 100644 --- a/src/main/java/com/minelittlepony/unicopia/client/UnicopiaClient.java +++ b/src/main/java/com/minelittlepony/unicopia/client/UnicopiaClient.java @@ -20,6 +20,7 @@ import com.minelittlepony.unicopia.entity.player.PlayerCamera; import com.minelittlepony.unicopia.entity.player.Pony; import com.minelittlepony.unicopia.network.handler.ClientNetworkHandlerImpl; import com.minelittlepony.unicopia.server.world.WeatherConditions; +import com.minelittlepony.unicopia.util.Lerp; import net.fabricmc.api.ClientModInitializer; import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; @@ -37,6 +38,10 @@ import net.minecraft.util.math.BlockPos; public class UnicopiaClient implements ClientModInitializer { + @Nullable + private Float originalRainGradient; + private final Lerp rainGradient = new Lerp(0); + public static Optional getCamera() { PlayerEntity player = MinecraftClient.getInstance().player; @@ -64,12 +69,6 @@ public class UnicopiaClient implements ClientModInitializer { return 0.6F; } - @Nullable - private Float originalRainGradient; - private float prevRainGradient; - private float rainGradient; - private float targetRainGradient; - @Override public void onInitializeClient() { InteractionManager.INSTANCE = new ClientInteractionManager(); @@ -99,20 +98,35 @@ public class UnicopiaClient implements ClientModInitializer { BlockPos pos = MinecraftClient.getInstance().getCameraEntity().getBlockPos(); float tickDelta = MinecraftClient.getInstance().getTickDelta(); + Float targetRainGradient = getTargetRainGradient(world, pos, tickDelta); + + if (targetRainGradient != null) { + rainGradient.update(targetRainGradient, 2000); + } + + float gradient = rainGradient.getValue(); + if (!rainGradient.isFinished()) { + world.setRainGradient(gradient); + world.setThunderGradient(gradient); + } + } + + private Float getTargetRainGradient(ClientWorld world, BlockPos pos, float tickDelta) { if (WeatherConditions.get(world).isInRangeOfStorm(pos)) { if (originalRainGradient == null) { originalRainGradient = world.getRainGradient(tickDelta); } - world.setRainGradient(1); - world.setThunderGradient(1); - } else { - if (originalRainGradient != null) { - targetRainGradient = originalRainGradient; - world.setRainGradient(originalRainGradient); - world.setThunderGradient(0); - originalRainGradient = null; - } + + return 1F; } + + if (originalRainGradient != null) { + Float f = originalRainGradient; + originalRainGradient = null; + return f; + } + + return null; } private void onScreenInit(Screen screen, ButtonList buttons) { diff --git a/src/main/java/com/minelittlepony/unicopia/server/world/WeatherConditions.java b/src/main/java/com/minelittlepony/unicopia/server/world/WeatherConditions.java index a0eff03e..a935f474 100644 --- a/src/main/java/com/minelittlepony/unicopia/server/world/WeatherConditions.java +++ b/src/main/java/com/minelittlepony/unicopia/server/world/WeatherConditions.java @@ -137,7 +137,16 @@ public class WeatherConditions extends PersistentState implements Tickable { public boolean inRange(BlockPos pos) { final StormCloudEntity cloud = this.cloud.get(); - return cloud != null && cloud.getBlockPos().isWithinDistance(pos, cloud.getSizeInBlocks()); + if (cloud == null) { + return false; + } + BlockPos cloudPos = cloud.getBlockPos(); + if (pos.getY() > cloudPos.getY() + cloud.getHeight()) { + return false; + } + float radius = cloud.getSizeInBlocks(); + return (cloudPos.getX() - pos.getX()) <= radius + && (cloudPos.getZ() - pos.getZ()) <= radius; } public boolean shouldRemove() { diff --git a/src/main/java/com/minelittlepony/unicopia/util/Lerp.java b/src/main/java/com/minelittlepony/unicopia/util/Lerp.java new file mode 100644 index 00000000..fda8e654 --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/util/Lerp.java @@ -0,0 +1,47 @@ +package com.minelittlepony.unicopia.util; + +import net.minecraft.util.Util; +import net.minecraft.util.math.MathHelper; + +public class Lerp { + private long duration; + + private long startTime; + private float start; + private float end; + + private boolean finished = true; + + public Lerp(float initial) { + end = initial; + } + + public boolean update(float newTarget, long changeDuration) { + if (MathHelper.approximatelyEquals(end, newTarget)) { + return false; + } + start = getValue(); + startTime = Util.getMeasuringTimeMs(); + end = newTarget; + duration = changeDuration; + finished = false; + return true; + } + + public float getValue() { + if (finished) { + return end; + } + float delta = getDelta(); + finished = delta >= 1F; + return MathHelper.lerp(delta, start, end); + } + + public boolean isFinished() { + return finished; + } + + private float getDelta() { + return MathHelper.clamp((float)(Util.getMeasuringTimeMs() - startTime) / (float)duration, 0, 1); + } +}