Added windflow, and made turbulance global + certain blocks produce an updraft that pegasi can ride up or down

This commit is contained in:
Sollace 2022-10-09 18:07:04 +02:00
parent 42cbe2b51f
commit a0933d8424
3 changed files with 145 additions and 5 deletions

View file

@ -0,0 +1,129 @@
package com.minelittlepony.unicopia.block.data;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.tag.BlockTags;
import net.minecraft.util.math.*;
import net.minecraft.world.Heightmap.Type;
import net.minecraft.world.World;
public class WeatherConditions {
public static final TwoDimensionalField HEIGHT_MAP_FIELD = (world, pos) -> {
return world.getTopY(Type.WORLD_SURFACE_WG, pos.getX(), pos.getZ());
};
public static final TwoDimensionalField THERMAL_FIELD = (world, pos) -> {
return world.getBiome(pos).value().getTemperature() + (float)getUpdraft(pos, world);
};
public static final TwoDimensionalField LOCAL_ALTITUDE_FIELD = (world, pos) -> {
if (!world.isAir(pos)) {
return 0;
}
return pos.getY() - getSurfaceBelow(pos, world);
};
public static final double FIRE_UPDRAFT = 0.3;
public static final double SAND_UPDRAFT = 0.13;
public static final double SOUL_SAND_UPDRAFT = -0.13;
public static final double ICE_UPDRAFT = -0.10;
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 Vec3d getAirflow(BlockPos pos, World world) {
BlockPos.Mutable probedPosition = new BlockPos.Mutable();
final float terrainFactor = Math.min(MAX_TERRAIN_HEIGHT, LOCAL_ALTITUDE_FIELD.getValue(world, probedPosition.set(pos))) / MAX_TERRAIN_HEIGHT;
Vec3d terrainGradient = LOCAL_ALTITUDE_FIELD.computeAverage(world, pos, probedPosition).multiply(1 - terrainFactor);
Vec3d thermalGradient = THERMAL_FIELD.computeAverage(world, pos, probedPosition).multiply(terrainFactor);
return terrainGradient.add(thermalGradient).normalize().add(0, getUpdraft(probedPosition.set(pos), world), 0);
}
public static double getUpdraft(BlockPos.Mutable pos, World world) {
final float ratio = 1 - Math.min(MAX_UPDRAFT_HEIGHT, pos.getY() - getSurfaceBelow(pos, world)) / MAX_UPDRAFT_HEIGHT;
BlockState state = world.getBlockState(pos);
if (state.isAir()) {
return VOID_UPDRAFT * ratio;
}
if (state.isOf(Blocks.SOUL_SAND) || state.isOf(Blocks.SOUL_SOIL)) {
return SOUL_SAND_UPDRAFT * ratio;
}
if (state.isOf(Blocks.LAVA) || state.isOf(Blocks.LAVA_CAULDRON)
|| state.isIn(BlockTags.FIRE)
|| state.isIn(BlockTags.CAMPFIRES)
|| state.isOf(Blocks.MAGMA_BLOCK)) {
return FIRE_UPDRAFT * ratio;
}
if (state.isIn(BlockTags.SAND)) {
return SAND_UPDRAFT * ratio;
}
if (state.isIn(BlockTags.SNOW) || state.isIn(BlockTags.ICE)) {
return ICE_UPDRAFT * ratio;
}
return 0;
}
private static int getSurfaceBelow(BlockPos.Mutable pos, World world) {
do {
pos.move(Direction.DOWN);
} while (world.isAir(pos) && world.isInBuildLimit(pos));
return pos.getY();
}
public interface TwoDimensionalField {
float getValue(World world, BlockPos.Mutable pos);
default Vec3d computedAverage(World world, BlockPos pos) {
return computeAverage(world, pos, new BlockPos.Mutable());
}
default Vec3d computeAverage(World world, BlockPos pos, BlockPos.Mutable probedPosition) {
float e = getValue(world, probedPosition.set(pos));
// A(-1,-1) B( 0,-1) C( 1,-1)
// D(-1, 0) E( 0, 0) F( 1, 0)
// G(-1, 1) H( 0, 1) I( 1, 1)
int projectionDistance = 4;
// DEF
Vec3d def = new Vec3d(-average(
getValue(world, probedPosition.set(pos.getX() - projectionDistance, pos.getY(), pos.getZ())) - e,
e - getValue(world, probedPosition.set(pos.getX() + projectionDistance, pos.getY(), pos.getZ()))
), 0, 0).normalize();
// BEH
Vec3d beh = new Vec3d(0, 0, -average(
getValue(world, probedPosition.set(pos.getX(), pos.getY(), pos.getZ() - projectionDistance)) - e,
e - getValue(world, probedPosition.set(pos.getX(), pos.getY(), pos.getZ() + projectionDistance))
)).normalize();
// AEI
double diagMag = average(
getValue(world, probedPosition.set(pos.getX() - projectionDistance, pos.getY(), pos.getZ() - projectionDistance)) - e,
e - getValue(world, probedPosition.set(pos.getX() + projectionDistance, pos.getY(), pos.getZ() + projectionDistance))
);
Vec3d aei = new Vec3d(0.5 * diagMag, 0, 0.5 * diagMag).normalize();
// GEC
diagMag = average(
getValue(world, probedPosition.set(pos.getX() - projectionDistance, pos.getY(), pos.getZ() + projectionDistance)) - e,
e - getValue(world, probedPosition.set(pos.getX() + projectionDistance, pos.getY(), pos.getZ() - projectionDistance))
);
Vec3d gec = new Vec3d(0.5 * diagMag, 0, 0.5 * diagMag).normalize();
return beh.add(def).add(aei).add(gec).normalize();
}
private static float average(float a, float b) {
return (a + b) / 2F;
}
}
}

View file

@ -5,6 +5,7 @@ import com.minelittlepony.unicopia.ability.magic.SpellPredicate;
import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType;
import com.minelittlepony.unicopia.advancement.UCriteria;
import com.minelittlepony.unicopia.block.data.ModificationType;
import com.minelittlepony.unicopia.block.data.WeatherConditions;
import com.minelittlepony.unicopia.client.minelittlepony.MineLPDelegate;
import com.minelittlepony.unicopia.client.render.PlayerPoser.Animation;
import com.minelittlepony.unicopia.entity.*;
@ -32,6 +33,7 @@ import net.minecraft.particle.ParticleTypes;
import net.minecraft.sound.SoundCategory;
import net.minecraft.sound.SoundEvents;
import net.minecraft.util.math.*;
import net.minecraft.util.math.random.Random;
public class PlayerPhysics extends EntityPhysics<PlayerEntity> implements Tickable, Motion, NbtSerialisable {
private static final int MAX_WALL_HIT_CALLDOWN = 30;
@ -336,6 +338,8 @@ public class PlayerPhysics extends EntityPhysics<PlayerEntity> implements Tickab
if (entity.world.hasRain(entity.getBlockPos())) {
applyTurbulance(velocity);
} else {
velocity.y += WeatherConditions.getUpdraft(new BlockPos.Mutable().set(entity.getBlockPos()), entity.world);
}
if (type.isAvian()) {
@ -551,8 +555,16 @@ public class PlayerPhysics extends EntityPhysics<PlayerEntity> implements Tickab
}
private void applyTurbulance(MutableVector velocity) {
float glance = 360 * entity.world.random.nextFloat();
float forward = 0.015F * entity.world.random.nextFloat() * entity.world.getRainGradient(1);
Vec3d wind = WeatherConditions.getAirflow(entity.getBlockPos(), entity.world).multiply(0.04);
velocity.x += wind.x;
velocity.y += wind.y;
velocity.z += wind.z;
Random rng = Random.create(entity.world.getTime());
float glance = 360 * rng.nextFloat();
float forward = 0.015F * rng.nextFloat() * entity.world.getRainGradient(1);
if (entity.world.random.nextInt(30) == 0) {
forward *= 10;
@ -564,12 +576,12 @@ public class PlayerPhysics extends EntityPhysics<PlayerEntity> implements Tickab
forward *= 100;
}
if (entity.world.isThundering() && entity.world.random.nextInt(60) == 0) {
if (entity.world.isThundering() && rng.nextInt(60) == 0) {
velocity.y += forward * 3 * getGravitySignum();
}
if (forward >= 1) {
entity.world.playSound(null, entity.getBlockPos(), USounds.AMBIENT_WIND_GUST, SoundCategory.AMBIENT, 3, 1);
SoundEmitter.playSoundAt(entity, USounds.AMBIENT_WIND_GUST, SoundCategory.AMBIENT, 3, 1);
}
forward = Math.min(forward, 7);

View file

@ -25,7 +25,6 @@ import com.minelittlepony.unicopia.network.datasync.EffectSync;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.Entity.RemovalReason;
import net.minecraft.entity.damage.DamageSource;
import net.minecraft.entity.data.DataTracker;
import net.minecraft.entity.data.TrackedData;