mirror of
https://github.com/Sollace/Unicopia.git
synced 2024-11-27 15:17:59 +01:00
Rain no longer appears above clouds (mostly)
This commit is contained in:
parent
883b8f4755
commit
24ca3bf39d
6 changed files with 168 additions and 50 deletions
|
@ -21,7 +21,6 @@ import com.minelittlepony.unicopia.container.*;
|
|||
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.server.world.ZapAppleStageStore;
|
||||
import com.minelittlepony.unicopia.util.Lerp;
|
||||
|
||||
|
@ -38,7 +37,6 @@ import net.minecraft.client.world.ClientWorld;
|
|||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.resource.ResourceType;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
|
||||
|
@ -55,9 +53,8 @@ public class UnicopiaClient implements ClientModInitializer {
|
|||
return Pony.of(MinecraftClient.getInstance().player);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private Float originalRainGradient;
|
||||
private final Lerp rainGradient = new Lerp(0);
|
||||
private final Lerp thunderGradient = new Lerp(0);
|
||||
|
||||
public final Lerp tangentalSkyAngle = new Lerp(0, true);
|
||||
public final Lerp skyAngle = new Lerp(0, true);
|
||||
|
@ -157,38 +154,22 @@ public class UnicopiaClient implements ClientModInitializer {
|
|||
}
|
||||
|
||||
private void onWorldTick(ClientWorld world) {
|
||||
BlockPos pos = MinecraftClient.getInstance().getCameraEntity().getBlockPos();
|
||||
/*BlockPos pos = MinecraftClient.getInstance().getCameraEntity().getBlockPos();
|
||||
float tickDelta = MinecraftClient.getInstance().getTickDelta();
|
||||
|
||||
Float targetRainGradient = getTargetRainGradient(world, pos, tickDelta);
|
||||
Float targetRainGradient = ((WeatherAccess)world).isInRangeOfStorm(pos) ? (Float)1F : ((WeatherAccess)world).isBelowCloudLayer(pos) ? null : (Float)0F;
|
||||
Float targetThunderGradient = ((WeatherAccess)world).isInRangeOfStorm(pos) ? (Float)1F : null;
|
||||
|
||||
if (targetRainGradient != null) {
|
||||
rainGradient.update(targetRainGradient, 2000);
|
||||
}
|
||||
((WeatherAccess)world).setWeatherOverride(null, null);
|
||||
rainGradient.update(targetRainGradient == null ? world.getRainGradient(tickDelta) : targetRainGradient, 2000);
|
||||
|
||||
float gradient = rainGradient.getValue();
|
||||
if (!rainGradient.isFinished()) {
|
||||
world.setRainGradient(gradient);
|
||||
world.setThunderGradient(gradient);
|
||||
}
|
||||
}
|
||||
((WeatherAccess)world).setWeatherOverride(1F, null);
|
||||
thunderGradient.update(targetThunderGradient == null ? world.getThunderGradient(tickDelta) : targetThunderGradient, 2000);
|
||||
|
||||
private Float getTargetRainGradient(ClientWorld world, BlockPos pos, float tickDelta) {
|
||||
if (WeatherConditions.get(world).isInRangeOfStorm(pos)) {
|
||||
if (originalRainGradient == null) {
|
||||
originalRainGradient = world.getRainGradient(tickDelta);
|
||||
}
|
||||
|
||||
return 1F;
|
||||
}
|
||||
|
||||
if (originalRainGradient != null) {
|
||||
Float f = originalRainGradient;
|
||||
originalRainGradient = null;
|
||||
return f;
|
||||
}
|
||||
|
||||
return null;
|
||||
((WeatherAccess)world).setWeatherOverride(
|
||||
rainGradient.isFinished() ? targetRainGradient : (Float)rainGradient.getValue(),
|
||||
thunderGradient.isFinished() ? targetThunderGradient : (Float)thunderGradient.getValue()
|
||||
);*/
|
||||
}
|
||||
|
||||
private void onScreenInit(Screen screen, ButtonList buttons) {
|
||||
|
|
|
@ -691,7 +691,7 @@ public class PlayerPhysics extends EntityPhysics<PlayerEntity> implements Tickab
|
|||
if (entity.getWorld().hasRain(entity.getBlockPos())) {
|
||||
applyTurbulance(velocity);
|
||||
} else {
|
||||
float targetUpdraft = (float)WeatherConditions.getUpdraft(new BlockPos.Mutable().set(entity.getBlockPos()), entity.getWorld()) / 3F;
|
||||
float targetUpdraft = WeatherConditions.THERMAL_FIELD.getValue(entity.getWorld(), new BlockPos.Mutable().set(entity.getBlockPos())) / 3F;
|
||||
targetUpdraft *= 1 + motion;
|
||||
if (isGravityNegative()) {
|
||||
targetUpdraft *= -1;
|
||||
|
|
|
@ -1,21 +1,32 @@
|
|||
package com.minelittlepony.unicopia.mixin;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
import com.minelittlepony.unicopia.entity.duck.RotatedView;
|
||||
import com.minelittlepony.unicopia.server.world.BlockDestructionManager;
|
||||
import com.minelittlepony.unicopia.server.world.WeatherAccess;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.WorldAccess;
|
||||
|
||||
@Mixin(World.class)
|
||||
abstract class MixinWorld implements WorldAccess, BlockDestructionManager.Source, RotatedView {
|
||||
|
||||
abstract class MixinWorld implements WorldAccess, BlockDestructionManager.Source, RotatedView, WeatherAccess {
|
||||
private final Supplier<BlockDestructionManager> destructions = BlockDestructionManager.create((World)(Object)this);
|
||||
|
||||
@Nullable
|
||||
private Float rainGradientOverride;
|
||||
@Nullable
|
||||
private Float thunderGradientOverride;
|
||||
|
||||
private boolean mirrorEntityStatuses;
|
||||
|
||||
@Override
|
||||
|
@ -28,11 +39,36 @@ abstract class MixinWorld implements WorldAccess, BlockDestructionManager.Source
|
|||
return destructions.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setWeatherOverride(Float rain, Float thunder) {
|
||||
rainGradientOverride = rain;
|
||||
thunderGradientOverride = thunder;
|
||||
}
|
||||
|
||||
@Inject(method = "sendEntityStatus(Lnet/minecraft/entity/Entity;B)V", at = @At("HEAD"))
|
||||
private void onSendEntityStatus(Entity entity, byte status, CallbackInfo info) {
|
||||
if (mirrorEntityStatuses) {
|
||||
entity.handleStatus(status);
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(method = "getThunderGradient", at = @At("HEAD"), cancellable = true)
|
||||
private void onGetThunderGradient(float delta, CallbackInfoReturnable<Float> info) {
|
||||
if (thunderGradientOverride != null) {
|
||||
info.setReturnValue(thunderGradientOverride * ((World)(Object)this).getRainGradient(delta));
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(method = "getRainGradient", at = @At("HEAD"), cancellable = true)
|
||||
private void onGetRainGradient(float delta, CallbackInfoReturnable<Float> info) {
|
||||
if (rainGradientOverride != null) {
|
||||
info.setReturnValue(rainGradientOverride);
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(method = "hasRain", at = @At("RETURN"), cancellable = true)
|
||||
private void onHasRain(BlockPos pos, CallbackInfoReturnable<Boolean> info) {
|
||||
info.setReturnValue((info.getReturnValue() && isBelowCloudLayer(pos)) || isInRangeOfStorm(pos));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -15,6 +15,8 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
|||
|
||||
import com.minelittlepony.unicopia.client.ClientBlockDestructionManager;
|
||||
import com.minelittlepony.unicopia.client.UnicopiaClient;
|
||||
import com.minelittlepony.unicopia.server.world.WeatherAccess;
|
||||
|
||||
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
|
||||
import net.minecraft.client.render.BlockBreakingInfo;
|
||||
import net.minecraft.client.render.Camera;
|
||||
|
@ -22,7 +24,10 @@ import net.minecraft.client.render.WorldRenderer;
|
|||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.client.world.ClientWorld;
|
||||
import net.minecraft.resource.SynchronousResourceReloader;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.RotationAxis;
|
||||
import net.minecraft.world.biome.Biome;
|
||||
import net.minecraft.world.biome.Biome.Precipitation;
|
||||
|
||||
@Mixin(value = WorldRenderer.class, priority = 1001)
|
||||
abstract class MixinWorldRenderer implements SynchronousResourceReloader, AutoCloseable, ClientBlockDestructionManager.Source {
|
||||
|
@ -80,4 +85,13 @@ abstract class MixinWorldRenderer implements SynchronousResourceReloader, AutoCl
|
|||
matrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(UnicopiaClient.getInstance().getSkyAngleDelta(tickDelta)));
|
||||
matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(UnicopiaClient.getInstance().tangentalSkyAngle.getValue()));
|
||||
}
|
||||
|
||||
@Redirect(method = "renderWeather", at = @At(value = "INVOKE", target = "net/minecraft/world/biome/Biome.getPrecipitation(Lnet/minecraft/util/math/BlockPos;)Lnet/minecraft/world/biome/Biome$Precipitation;"))
|
||||
private Biome.Precipitation modifyPrecipitation(Biome biome, BlockPos pos) {
|
||||
Biome.Precipitation precipitation = biome.getPrecipitation(pos);
|
||||
if (!((WeatherAccess)world).isBelowClientCloudLayer(pos)) {
|
||||
return Precipitation.NONE;
|
||||
}
|
||||
return precipitation;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,89 @@
|
|||
package com.minelittlepony.unicopia.server.world;
|
||||
|
||||
import com.minelittlepony.unicopia.block.cloud.CloudLike;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.util.math.ChunkSectionPos;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.chunk.Chunk;
|
||||
|
||||
public interface WeatherAccess {
|
||||
void setWeatherOverride(Float rain, Float thunder);
|
||||
|
||||
default boolean isInRangeOfStorm(BlockPos pos) {
|
||||
return WeatherConditions.get((World)this).isInRangeOfStorm(pos);
|
||||
}
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
default boolean isBelowClientCloudLayer(BlockPos pos) {
|
||||
|
||||
int range = MinecraftClient.isFancyGraphicsOrBetter() ? 10 : 5;
|
||||
|
||||
if (pos.getY() < 230 - range) {
|
||||
return true;
|
||||
}
|
||||
|
||||
Chunk chunk = ((World)this).getChunk(pos);
|
||||
int topSection = chunk.getHighestNonEmptySection();
|
||||
|
||||
if (topSection > -1) {
|
||||
int sectionBottomY = ChunkSectionPos.getBlockCoord(topSection);
|
||||
if (sectionBottomY >= pos.getY() - 16) {
|
||||
BlockPos.Mutable mutable = pos.mutableCopy();
|
||||
BlockPos.Mutable probeMutable = pos.mutableCopy();
|
||||
int maxDistance = 16;
|
||||
|
||||
while (((World)this).isInBuildLimit(mutable)) {
|
||||
if (--maxDistance <= 0) break;
|
||||
if (!((World)this).isAir(probeMutable.setY(mutable.getY() + range))) {
|
||||
|
||||
mutable.set(pos);
|
||||
maxDistance = 16;
|
||||
|
||||
while (((World)this).isInBuildLimit(mutable)) {
|
||||
if (--maxDistance <= 0) break;
|
||||
if (((World)this).getBlockState(probeMutable.setY(mutable.getY())).getBlock() instanceof CloudLike) {
|
||||
return false;
|
||||
}
|
||||
mutable.move(Direction.DOWN);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
mutable.move(Direction.UP);
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
default boolean isBelowCloudLayer(BlockPos pos) {
|
||||
if (pos.getY() < 230) {
|
||||
return true;
|
||||
}
|
||||
|
||||
Chunk chunk = ((World)this).getChunk(pos);
|
||||
int topSection = chunk.getHighestNonEmptySection();
|
||||
|
||||
if (topSection > -1) {
|
||||
int sectionBottomY = ChunkSectionPos.getBlockCoord(topSection);
|
||||
if (sectionBottomY >= pos.getY() - 16) {
|
||||
BlockPos.Mutable mutable = pos.mutableCopy();
|
||||
int maxDistance = 32;
|
||||
|
||||
while (((World)this).isInBuildLimit(mutable)) {
|
||||
if (--maxDistance <= 0) break;
|
||||
if (!((World)this).isAir(mutable)) {
|
||||
return true;
|
||||
}
|
||||
mutable.move(Direction.UP);
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -23,8 +23,21 @@ import net.minecraft.world.PersistentState;
|
|||
import net.minecraft.world.World;
|
||||
|
||||
public class WeatherConditions extends PersistentState implements Tickable {
|
||||
public static final double FIRE_UPDRAFT = 0.13;
|
||||
public static final double SAND_UPDRAFT = 0.03;
|
||||
public static final double SOUL_SAND_UPDRAFT = -0.03;
|
||||
public static final double ICE_UPDRAFT = 0;
|
||||
public static final double VOID_UPDRAFT = -0.23;
|
||||
|
||||
public static final float MAX_UPDRAFT_HEIGHT = 20;
|
||||
public static final float MAX_TERRAIN_HEIGHT = 50;
|
||||
public static final float MAX_WIND_HEIGHT = 70;
|
||||
|
||||
public static final Plane HEIGHT_MAP_FIELD = (world, pos) -> world.getTopY(Heightmap.Type.WORLD_SURFACE_WG, pos.getX(), pos.getZ());
|
||||
public static final Plane THERMAL_FIELD = (world, pos) -> (float)getUpdraft(pos, world);
|
||||
public static final Plane THERMAL_FIELD = (world, pos) -> {
|
||||
double factor = 1 - getScaledDistanceFromTerrain(pos, world, MAX_UPDRAFT_HEIGHT);
|
||||
return (float)(factor * getMaterialSurfaceTemperature(pos, world));
|
||||
};
|
||||
public static final Plane LOCAL_ALTITUDE_FIELD = (world, pos) -> {
|
||||
if (!world.isAir(pos)) {
|
||||
return 0;
|
||||
|
@ -36,16 +49,6 @@ public class WeatherConditions extends PersistentState implements Tickable {
|
|||
return y - pos.getY();
|
||||
};
|
||||
|
||||
public static final double FIRE_UPDRAFT = 0.13;
|
||||
public static final double SAND_UPDRAFT = 0.03;
|
||||
public static final double SOUL_SAND_UPDRAFT = -0.03;
|
||||
public static final double ICE_UPDRAFT = 0;
|
||||
public static final double VOID_UPDRAFT = -0.23;
|
||||
|
||||
public static final float MAX_UPDRAFT_HEIGHT = 20;
|
||||
public static final float MAX_TERRAIN_HEIGHT = 50;
|
||||
public static final float MAX_WIND_HEIGHT = 70;
|
||||
|
||||
private static final Identifier ID = Unicopia.id("weather_conditions");
|
||||
|
||||
public static WeatherConditions get(World world) {
|
||||
|
@ -176,11 +179,6 @@ public class WeatherConditions extends PersistentState implements Tickable {
|
|||
.multiply(windFactor);
|
||||
}
|
||||
|
||||
public static double getUpdraft(BlockPos.Mutable pos, World world) {
|
||||
double factor = 1 - getScaledDistanceFromTerrain(pos, world, MAX_UPDRAFT_HEIGHT);
|
||||
return factor * getMaterialSurfaceTemperature(pos, world);
|
||||
}
|
||||
|
||||
private static float getScaledDistanceFromTerrain(BlockPos.Mutable pos, World world, float maxDistance) {
|
||||
return Math.min(maxDistance, LOCAL_ALTITUDE_FIELD.getValue(world, pos)) / maxDistance;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue