Skip to content

Commit

Permalink
improved splashes
Browse files Browse the repository at this point in the history
  • Loading branch information
Goby56 committed Aug 18, 2024
1 parent 1cf16e2 commit bfbc46f
Show file tree
Hide file tree
Showing 12 changed files with 97 additions and 76 deletions.
9 changes: 5 additions & 4 deletions src/main/java/com/goby56/wakes/config/WakesConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -88,13 +88,14 @@ public void setUpper(int upper) {
}

// Splash plane
public float splashPlaneWidth = 3f;
public float splashPlaneWidth = 2f;
public float splashPlaneHeight = 1.5f;
public float splashPlaneDepth = 2f;
public float splashPlaneDepth = 3f;
public float splashPlaneOffset = -0.1f;
public float splashPlaneGap = 1f;
public int splashPlaneResolution = 5;
public float maxSplashPlaneVelocity = 0.5f;
public float splashPlaneScale = 1f;
public float splashPlaneOffset = 0f;
public float splashPlaneScale = 0.8f;

public static WakesConfig loadConfig() {
Jankson jankson = Jankson.builder().build();
Expand Down
12 changes: 8 additions & 4 deletions src/main/java/com/goby56/wakes/config/YACLIntegration.java
Original file line number Diff line number Diff line change
Expand Up @@ -72,23 +72,27 @@ public static Screen createScreen(Screen parent) {
.controller(opt -> floatSlider(opt, 0.1f, 2f, 0.1f))
.build())
.option(optionOf(Float.class, "splash_plane.scale", false)
.binding(1f, () -> config.splashPlaneScale, val -> config.splashPlaneScale = val)
.binding(0.8f, () -> config.splashPlaneScale, val -> config.splashPlaneScale = val)
.controller(opt -> floatSlider(opt, 0.1f, 2f, 0.1f))
.build())
.option(optionOf(Float.class, "splash_plane.offset", false)
.binding(0f, () -> config.splashPlaneOffset, val -> config.splashPlaneOffset = val)
.binding(-0.1f, () -> config.splashPlaneOffset, val -> config.splashPlaneOffset = val)
.controller(opt -> floatSlider(opt, -1f, 1f, 0.1f))
.build())
.option(optionOf(Float.class, "splash_plane.gap", false)
.binding(1f, () -> config.splashPlaneGap, val -> config.splashPlaneGap = val)
.controller(opt -> floatSlider(opt, 0f, 2f, 0.1f))
.build())
.option(optionOf(Float.class, "splash_plane.width", false)
.binding(3f, () -> config.splashPlaneWidth, val -> config.splashPlaneWidth = val)
.binding(2f, () -> config.splashPlaneWidth, val -> config.splashPlaneWidth = val)
.controller(opt -> floatSlider(opt, 0f, 10f, 0.1f))
.build())
.option(optionOf(Float.class, "splash_plane.height", false)
.binding(1.5f, () -> config.splashPlaneHeight, val -> config.splashPlaneHeight = val)
.controller(opt -> floatSlider(opt, 0f, 10f, 0.1f))
.build())
.option(optionOf(Float.class, "splash_plane.depth", false)
.binding(2f, () -> config.splashPlaneDepth, val -> config.splashPlaneDepth = val)
.binding(3f, () -> config.splashPlaneDepth, val -> config.splashPlaneDepth = val)
.controller(opt -> floatSlider(opt, 0f, 10f, 0.1f))
.build())
.build())
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/com/goby56/wakes/duck/ProducesWake.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,6 @@ public interface ProducesWake {

void setRecentlyTeleported(boolean b);

SplashPlaneParticle getSplashPlane();

}
9 changes: 9 additions & 0 deletions src/main/java/com/goby56/wakes/mixin/WakeSpawnerMixin.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ public abstract class WakeSpawnerMixin implements ProducesWake {
@Shadow private Vec3d pos;
@Shadow private World world;

@Shadow public abstract float getYaw(float tickDelta);

@Shadow public abstract float getYaw();

@Unique private boolean onWaterSurface = false;
@Unique private Vec3d prevPosOnSurface = null;
@Unique private Vec3d numericalVelocity = Vec3d.ZERO;
Expand Down Expand Up @@ -89,6 +93,11 @@ public void setRecentlyTeleported(boolean b) {
this.hasRecentlyTeleported = b;
}

@Override
public SplashPlaneParticle getSplashPlane() {
return this.splashPlane;
}

// TODO FIX PLAYER TELEPORTATION CAUSING LONG WAKES
// @Inject(at = @At("TAIL"), method = "teleport(Lnet/minecraft/server/world/ServerWorld;DDDLjava/util/Set;FF)Z")
// private void onTeleport(ServerWorld world, double destX, double destY, double destZ, Set<PositionFlag> flags, float yaw, float pitch, CallbackInfoReturnable<Boolean> cir) {
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/com/goby56/wakes/particle/ModParticles.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@

public class ModParticles {
public static WithOwnerParticleType SPLASH_PLANE;
public static DefaultParticleType SPLASH_CLOUD = FabricParticleTypes.simple();
public static WithOwnerParticleType SPLASH_CLOUD;

public static void registerParticles() {
SPLASH_PLANE = Registry.register(Registries.PARTICLE_TYPE, new Identifier(WakesClient.MOD_ID, "splash_plane"), new WithOwnerParticleType(true));
ParticleFactoryRegistry.getInstance().register(SPLASH_PLANE, SplashPlaneParticle.Factory::new);

Registry.register(Registries.PARTICLE_TYPE, new Identifier(WakesClient.MOD_ID, "splash_cloud"), SPLASH_CLOUD);
SPLASH_CLOUD = Registry.register(Registries.PARTICLE_TYPE, new Identifier(WakesClient.MOD_ID, "splash_cloud"), new WithOwnerParticleType(true));
ParticleFactoryRegistry.getInstance().register(SPLASH_CLOUD, SplashCloudParticle.Factory::new);
}
}
17 changes: 0 additions & 17 deletions src/main/java/com/goby56/wakes/particle/WakeParticleType.java

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,58 +1,66 @@
package com.goby56.wakes.particle.custom;

import com.goby56.wakes.WakesClient;
import com.goby56.wakes.duck.ProducesWake;
import com.goby56.wakes.particle.WithOwnerParticleType;
import com.goby56.wakes.simulation.WakeNode;
import com.goby56.wakes.utils.WakesUtils;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.client.particle.*;
import net.minecraft.client.world.ClientWorld;
import net.minecraft.entity.Entity;
import net.minecraft.particle.DefaultParticleType;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import org.jetbrains.annotations.Nullable;

public class SplashCloudParticle extends SpriteBillboardParticle {
Entity owner;
final double offset;
final boolean isFromPaddles;

public SplashCloudParticle(ClientWorld world, double x, double y, double z, SpriteProvider sprites, double velocityX, double velocityY, double velocityZ) {
super(world, x, y, z, velocityX, velocityY, velocityZ);

this.velocityX += 0.001f * (world.random.nextGaussian() - 0.5f);
this.velocityY += 0.01f * Math.abs(world.random.nextGaussian() - 0.5f);
this.velocityZ += 0.001f * (world.random.nextGaussian() - 0.5f);

this.prevPosX = x;
this.prevPosY = y;
this.prevPosZ = z;

this.maxAge = 15;
this.scale *= 2;
this.maxAge = WakeNode.maxAge;
this.setSprite(sprites.getSprite(world.random));

this.offset = velocityX;
this.isFromPaddles = velocityX == 0;
this.scale = isFromPaddles ? scale * 2 : 0.3f;
}

@Override
public void tick() {
this.prevPosX = this.x;
this.prevPosY = this.y;
this.prevPosZ = this.z;
if (this.age++ >= this.maxAge) {
if (this.owner == null || (this.isFromPaddles && this.age > maxAge)) {
this.markDead();
return;
}
this.alpha = 1f - (float) this.age / this.maxAge;
if (this.isFromPaddles) {
this.age++;
return;
}

if (this.owner instanceof ProducesWake wake) {
SplashPlaneParticle splashPlane = wake.getSplashPlane();
if (splashPlane == null) {
this.markDead();
return;
}

Vec3d pos = new Vec3d(this.x, this.y, this.z);
BlockState currBlock = this.world.getBlockState(WakesUtils.vecToBlockPos(pos));
this.prevPosX = this.x;
this.prevPosY = this.y;
this.prevPosZ = this.z;

if (currBlock.isAir()) {
this.velocityY -= 0.02f;
} else if (currBlock.isOf(Blocks.WATER)) {
this.velocityY += 0.01f;
Vec3d particleOffset = new Vec3d(-splashPlane.direction.z, 0f, splashPlane.direction.x).multiply(this.offset * this.owner.getWidth() / 2f);
Vec3d pos = splashPlane.getPos().add(particleOffset).add(splashPlane.direction.multiply(-0.2f));
this.setPos(pos.x, wake.producingHeight(), pos.z);
}
this.velocityX *= 0.99f;
this.velocityY *= 0.5f;
this.velocityZ *= 0.99f;
this.move(velocityX, velocityY, velocityZ);
}

@Override
Expand All @@ -70,7 +78,11 @@ public Factory(SpriteProvider spriteSet) {
@Nullable
@Override
public Particle createParticle(DefaultParticleType parameters, ClientWorld world, double x, double y, double z, double velocityX, double velocityY, double velocityZ) {
return new SplashCloudParticle(world, x, y, z, this.sprites, velocityX, velocityY, velocityZ);
SplashCloudParticle cloud = new SplashCloudParticle(world, x, y, z, this.sprites, velocityX, velocityY, velocityZ);
if (parameters instanceof WithOwnerParticleType type) {
cloud.owner = type.owner;
}
return cloud;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import com.goby56.wakes.particle.WithOwnerParticleType;
import com.goby56.wakes.render.SplashPlaneRenderer;
import com.goby56.wakes.utils.WakesUtils;
import com.terraformersmc.modmenu.util.mod.Mod;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.MinecraftClient;
Expand All @@ -19,16 +20,23 @@
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.client.world.ClientWorld;
import net.minecraft.entity.Entity;
import net.minecraft.entity.vehicle.BoatEntity;
import net.minecraft.particle.DefaultParticleType;
import net.minecraft.util.math.*;
import org.jetbrains.annotations.Nullable;

import java.util.ArrayList;
import java.util.Random;

public class SplashPlaneParticle extends Particle {
Entity owner;
float yaw;
float prevYaw;
int ticksSinceSplash = 0;

Vec3d direction = Vec3d.ZERO;


protected SplashPlaneParticle(ClientWorld world, double x, double y, double z) {
super(world, x, y, z);
}
Expand Down Expand Up @@ -65,24 +73,16 @@ public void tick() {

private void aliveTick(ProducesWake wakeProducer) {
this.ticksSinceSplash++;

Vec3d vel = wakeProducer.getNumericalVelocity();
this.yaw = 90f - (float) (180f / Math.PI * Math.atan2(vel.z, vel.x));
Vec3d normVel = vel.normalize();
Vec3d planePos = this.owner.getPos().add(normVel.multiply(this.owner.getWidth() + WakesClient.CONFIG_INSTANCE.splashPlaneOffset));
this.setPos(planePos.x, wakeProducer.producingHeight(), planePos.z);

// TODO ADD DISTANCING OFFSET BETWEEN PLANES
int t = (int) Math.floor(WakesClient.CONFIG_INSTANCE.maxSplashPlaneVelocity / vel.horizontalLength());
if (this.ticksSinceSplash > t && WakesClient.CONFIG_INSTANCE.spawnParticles) {
this.ticksSinceSplash = 0;
Vec3d particlePos = planePos.subtract(new Vec3d(normVel.x, 0f, normVel.z).multiply(this.owner.getWidth() / 2f));
Vec3d particleOffset = new Vec3d(-normVel.z, 0f, normVel.x).multiply(this.owner.getWidth() / 2f);
Vec3d pos = particlePos.add(particleOffset);
world.addParticle(ModParticles.SPLASH_CLOUD, pos.x, wakeProducer.producingHeight(), pos.z, vel.x, vel.y ,vel.z);
pos = particlePos.add(particleOffset.multiply(-1f));
world.addParticle(ModParticles.SPLASH_CLOUD, pos.x, wakeProducer.producingHeight(), pos.z, vel.x, vel.y ,vel.z);
if (this.owner instanceof BoatEntity) {
this.yaw = -this.owner.getYaw();
} else {
Vec3d vel = wakeProducer.getNumericalVelocity();
this.yaw = 90f - (float) (180f / Math.PI * Math.atan2(vel.z, vel.x));
}
this.direction = Vec3d.fromPolar(0, -this.yaw);
Vec3d planeOffset = direction.multiply((this.owner.getWidth() + WakesClient.CONFIG_INSTANCE.splashPlaneOffset));
Vec3d planePos = this.owner.getPos().add(planeOffset);
this.setPos(planePos.x, wakeProducer.producingHeight(), planePos.z);
}

@Override
Expand All @@ -93,7 +93,7 @@ public void buildGeometry(VertexConsumer vertexConsumer, Camera camera, float ti
this.owner instanceof ClientPlayerEntity) {
return;
}

MatrixStack modelMatrix = getMatrixStackFromCamera(camera, tickDelta);
int light = this.getBrightness(tickDelta);

Expand Down Expand Up @@ -123,6 +123,10 @@ private MatrixStack getMatrixStackFromCamera(Camera camera, float tickDelta) {
return matrixStack;
}

public Vec3d getPos() {
return new Vec3d(x, y, z);
}

@Override
public ParticleTextureSheet getType() {
return ParticleTextureSheet.CUSTOM;
Expand All @@ -137,13 +141,17 @@ public Factory(SpriteProvider spriteSet) {
@Nullable
@Override
public Particle createParticle(DefaultParticleType parameters, ClientWorld world, double x, double y, double z, double velX, double velY, double velZ) {
SplashPlaneParticle wake = new SplashPlaneParticle(world, x, y, z);
SplashPlaneParticle splashPlane = new SplashPlaneParticle(world, x, y, z);
if (parameters instanceof WithOwnerParticleType type) {
wake.owner = type.owner;
wake.yaw = wake.prevYaw = type.owner.getYaw();
((ProducesWake) wake.owner).setSplashPlane(wake);
splashPlane.owner = type.owner;
splashPlane.yaw = splashPlane.prevYaw = type.owner.getYaw();
((ProducesWake) splashPlane.owner).setSplashPlane(splashPlane);
if (type.owner instanceof BoatEntity) {
world.addParticle(ModParticles.SPLASH_CLOUD.withOwner(type.owner), x, y, z, 1, 0 ,0);
world.addParticle(ModParticles.SPLASH_CLOUD.withOwner(type.owner), x, y, z, -1, 0 ,0);
}
}
return wake;
return splashPlane;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ public static <T extends Entity> void render(T entity, float yaw, float tickDelt
RenderSystem.setShaderColor(1f, 1f, 1f, 1f);
RenderSystem.enableBlend();

//if (this.owner.getVelocity().normalize().dotProduct(Vec3d.fromPolar(0, this.yaw)) <= 0) return;
matrices.push();
float velocity = (float) Math.floor(((ProducesWake) entity).getHorizontalVelocity() * 20) / 20f;
float progress = Math.min(1f, velocity / WakesClient.CONFIG_INSTANCE.maxSplashPlaneVelocity);
Expand Down Expand Up @@ -115,7 +116,7 @@ private static void renderSurface(Matrix4f matrix, Vector3f color, int light, bo
Vec3d vertex = vertices.get(i);
Vec3d normal = normals.get(i);
buffer.vertex(matrix,
(float) (s * vertex.x * WakesClient.CONFIG_INSTANCE.splashPlaneWidth),
(float) (s * (vertex.x * WakesClient.CONFIG_INSTANCE.splashPlaneWidth + WakesClient.CONFIG_INSTANCE.splashPlaneGap)),
(float) (vertex.z * WakesClient.CONFIG_INSTANCE.splashPlaneHeight),
(float) (vertex.y * WakesClient.CONFIG_INSTANCE.splashPlaneDepth))
.color(color.x, color.y, color.z, opacity)
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/com/goby56/wakes/simulation/WakeNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public class WakeNode implements Position<WakeNode>, Age<WakeNode> {
public WakeNode WEST = null;

// TODO MAKE DISAPPEARANCE DEPENDENT ON WAVE VALUES INSTEAD OF AGE/TIME (MAYBE)
public final int maxAge = 30;
public static int maxAge = 30;
public int age = 0;
private boolean dead = false;

Expand Down
2 changes: 1 addition & 1 deletion src/main/java/com/goby56/wakes/utils/WakesUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ public static void spawnPaddleSplashCloudParticle(World world, BoatEntity boat)
double x = boat.getX() + (i == 1 ? -rot.z : rot.z);
double z = boat.getZ() + (i == 1 ? rot.x : -rot.x);
Vec3d pos = new Vec3d(x, ((ProducesWake) boat).producingHeight(), z);
world.addParticle(ModParticles.SPLASH_CLOUD, pos.x, pos.y, pos.z, boat.getVelocity().x, 0f, boat.getVelocity().z);
world.addParticle(ModParticles.SPLASH_CLOUD, pos.x, pos.y, pos.z, 0, 0, 0);
}
}
}
Expand Down
1 change: 1 addition & 0 deletions src/main/resources/assets/wakes/lang/en_us.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ wakes:
width: Width
height: Height
depth: Depth
gap: Gap
cap_velocity: Velocity cap
interval:
lower: Lower
Expand Down

0 comments on commit bfbc46f

Please sign in to comment.