diff --git a/.classpath b/.classpath index 7a9a105..ba34eb2 100644 --- a/.classpath +++ b/.classpath @@ -14,20 +14,21 @@ + - - + - + + diff --git a/notes.txt b/notes.txt new file mode 100644 index 0000000..1c800cb --- /dev/null +++ b/notes.txt @@ -0,0 +1,4 @@ +don't forget when detecting collisions with moving players I should first check if they already overlap, if yes then push the ball out +if two players overlap with the ball then I don't know if you can combine the pushing do it if you can't push it away somehow +away I mean so like the ball has the largest possible same angle to both players +look I'm too young college how am I supposed to know things diff --git a/pom.xml b/pom.xml index 5e2a28b..3e12847 100644 --- a/pom.xml +++ b/pom.xml @@ -9,15 +9,15 @@ 0.0.1-SNAPSHOT - 17 - 17 + 21 + 21 net.minestom minestom-snapshots - 90fb708739 + d606051f1e diff --git a/src/main/java/net/pivipi/LoginHandler.java b/src/main/java/net/pivipi/LoginHandler.java index 298ae49..54e2380 100644 --- a/src/main/java/net/pivipi/LoginHandler.java +++ b/src/main/java/net/pivipi/LoginHandler.java @@ -3,6 +3,7 @@ package net.pivipi; import net.minestom.server.coordinate.Pos; import net.minestom.server.entity.GameMode; import net.minestom.server.entity.Player; +import net.minestom.server.entity.attribute.Attribute; import net.minestom.server.event.GlobalEventHandler; import net.minestom.server.event.player.AsyncPlayerConfigurationEvent; import net.minestom.server.event.player.PlayerDisconnectEvent; @@ -33,7 +34,7 @@ public class LoginHandler { event.setSpawningInstance(spawningInstance); event.setHardcore(true); - player.setRespawnPoint(new Pos(0, 5, 0)); + player.setRespawnPoint(new Pos(5, 5, 0)); stadium.players.add(player); } @@ -45,11 +46,13 @@ public class LoginHandler { Player player = event.getPlayer(); player.setGameMode(GameMode.CREATIVE); + player.getAttribute(Attribute.GENERIC_MOVEMENT_SPEED).setBaseValue(0.2); + player.getAttribute(Attribute.GENERIC_JUMP_STRENGTH).setBaseValue(0.36813); // just enough to jump a block if (stadium.ball == null) { Ball ball = new Ball(stadium); ball.setInstance(event.getInstance()); - ball.teleport(new Pos(0.5, 15, 0.5)); + ball.teleport(new Pos(0, 15, 0)); stadium.ball = ball; } } diff --git a/src/main/java/net/pivipi/Main.java b/src/main/java/net/pivipi/Main.java index 808ae53..c58be4f 100644 --- a/src/main/java/net/pivipi/Main.java +++ b/src/main/java/net/pivipi/Main.java @@ -8,14 +8,13 @@ import net.minestom.server.instance.InstanceManager; import net.minestom.server.instance.LightingChunk; import net.minestom.server.registry.DynamicRegistry.Key; import net.minestom.server.world.DimensionType; -import net.pivipi.ball.BallKicker; import net.pivipi.world.FancyDimension; import net.pivipi.world.SoccerGenerator; import net.pivipi.world.WorldConstraints; public class Main { public static void main(String[] args) { - System.setProperty("minestom.tps", "60"); + System.setProperty("minestom.tps", "100"); MinecraftServer minecraftServer = MinecraftServer.init(); diff --git a/src/main/java/net/pivipi/ball/Ball.java b/src/main/java/net/pivipi/ball/Ball.java index 6abaa6f..8f3426b 100644 --- a/src/main/java/net/pivipi/ball/Ball.java +++ b/src/main/java/net/pivipi/ball/Ball.java @@ -4,7 +4,6 @@ import net.minestom.server.coordinate.Vec; import net.minestom.server.entity.Entity; import net.minestom.server.entity.EntityType; import net.minestom.server.entity.metadata.other.FallingBlockMeta; -import net.minestom.server.event.player.PlayerDisconnectEvent; import net.minestom.server.instance.block.Block; import net.pivipi.physics.Physics; import net.pivipi.world.Stadium; @@ -19,7 +18,6 @@ public class Ball extends Entity { super(EntityType.FALLING_BLOCK); // not block display because its movement lags for some reason this.setNoGravity(true); - this.setGlowing(true); this.hasPhysics = true; this.editEntityMeta(FallingBlockMeta.class, meta -> { @@ -41,7 +39,7 @@ public class Ball extends Entity { long delay = time - this.lastTick; - physics.applyPhysics(delay / 1000.0, stadium.players); + physics.process(delay / 1000.0, stadium.players); this.lastTick = time; } diff --git a/src/main/java/net/pivipi/ball/BallKicker.java b/src/main/java/net/pivipi/ball/BallKicker.java index f25fc0f..3feb300 100644 --- a/src/main/java/net/pivipi/ball/BallKicker.java +++ b/src/main/java/net/pivipi/ball/BallKicker.java @@ -1,22 +1,13 @@ package net.pivipi.ball; -import java.awt.Event; -import java.util.HashSet; -import java.util.Set; - -import net.minestom.server.MinecraftServer; -import net.minestom.server.ServerFlag; -import net.minestom.server.collision.VisibleSweepResult; import net.minestom.server.coordinate.Point; import net.minestom.server.coordinate.Pos; import net.minestom.server.coordinate.Vec; -import net.minestom.server.entity.Entity; import net.minestom.server.entity.Player; import net.minestom.server.event.GlobalEventHandler; import net.minestom.server.event.player.PlayerMoveEvent; import net.minestom.server.event.player.PlayerStartSneakingEvent; import net.minestom.server.event.player.PlayerStopSneakingEvent; -import net.minestom.server.instance.Instance; import net.pivipi.physics.Collision; import net.pivipi.world.Stadium; @@ -26,6 +17,11 @@ public class BallKicker { // TODO apply physics settings here private long lastSneak; private int sneakStreak; + private double headHeight = 0.3; // too low head kicks will be broken too high normal kicks will be broken + private double touchStrength = 1; // when the player walks into a ball + private double headJumpStrength = 5; // when the player jumps with a ball on their head, this is multiplied by touchstrength + private double dragDownStrength = 1; // when the player touches a ball + public BallKicker(Stadium stadium) { this.stadium = stadium; } @@ -36,15 +32,66 @@ public class BallKicker { // TODO apply physics settings here globalEventHandler.addListener(PlayerStopSneakingEvent.class, event -> onStopSneaking(event)); } - private void onMove(PlayerMoveEvent event) { + private void onMove(PlayerMoveEvent event) { // is width x Player player = event.getPlayer(); + Vec movementVec = player.getPosition().sub(player.getPreviousPosition()).asVec(); + + double ballXSize = stadium.ball.getBoundingBox().width(); + double playerXSize = player.getBoundingBox().width(); + double ballZSize = stadium.ball.getBoundingBox().depth(); + double playerZSize = player.getBoundingBox().depth(); + double ballHeight = stadium.ball.getBoundingBox().height(); + double playerHeight = player.getBoundingBox().height(); + Pos ballCenterPos = stadium.ball.getPosition(); + Pos playerCenterPos = event.getNewPosition(); - Pos deltaPos = player.getPosition().sub(player.getPreviousPosition());// TODO - boolean collides = Collision.collidesWithEntity(stadium.ball, player); - if (collides) { - System.out.println(deltaPos); - stadium.ball.addPos(deltaPos.asVec()); - stadium.ball.addVelocity(deltaPos.asVec().mul(2, 2, 2)); + Pos ballPos = ballCenterPos.sub(ballXSize / 2, 0, ballZSize / 2); + Pos playerPos = playerCenterPos.sub(playerXSize / 2, 0, playerZSize / 2); + Vec ballDistance = ballCenterPos.sub(playerCenterPos).asVec(); + + + if (ballDistance.y() > 0) { + if (ballPos.y() > playerPos.y() + playerHeight) return; + } else { + if (playerPos.y() > ballPos.y() + ballHeight) return; + } + + Vec newBallOffset = new Vec(0); + double diffX = 0, diffZ = 0; + + if (ballDistance.x() > 0) { + diffX = ballPos.x() - (playerPos.x() + playerXSize); + if (diffX < 0) // collides on x+ + newBallOffset = newBallOffset.withX(-diffX); + } else { + diffX = playerPos.x() - (ballPos.x() + ballXSize); + if (diffX < 0) // collides on x- + newBallOffset = newBallOffset.withX(diffX); + } + + if (ballDistance.z() > 0) { + diffZ = ballPos.z() - (playerPos.z() + playerZSize); + if (diffZ < 0) + newBallOffset = newBallOffset.withZ(-diffZ); + } else { + diffZ = playerPos.z() - (ballPos.z() + ballZSize); + if (diffZ < 0) + newBallOffset = newBallOffset.withZ(diffZ); + ballDistance = ballDistance.withY(-dragDownStrength); + } + + if (diffX < 0 && diffZ < 0) { + if (ballPos.y() - player.getPreviousPosition().y() > playerHeight - headHeight) { // ball on head + System.out.println("jumped"); + double jumpHeight = movementVec.y(); + if (jumpHeight == 0) return; + newBallOffset = new Vec(0, jumpHeight, 0); + ballDistance = ballDistance.withY(headJumpStrength); + } + + stadium.ball.addPos(diffX < diffZ ? newBallOffset.withX(0) : newBallOffset.withZ(0)); + stadium.ball.addVelocity(ballDistance.mul(touchStrength)); + System.out.println(ballDistance); } } diff --git a/src/main/java/net/pivipi/physics/Collision.java b/src/main/java/net/pivipi/physics/Collision.java index 034bc18..826f5ed 100644 --- a/src/main/java/net/pivipi/physics/Collision.java +++ b/src/main/java/net/pivipi/physics/Collision.java @@ -5,7 +5,6 @@ import net.minestom.server.collision.SweepResult; import net.minestom.server.collision.VisibleSweepResult; import net.minestom.server.coordinate.Vec; import net.minestom.server.entity.Entity; -import net.minestom.server.entity.Player; public class Collision { /** diff --git a/src/main/java/net/pivipi/physics/Physics.java b/src/main/java/net/pivipi/physics/Physics.java index bec2910..502906a 100644 --- a/src/main/java/net/pivipi/physics/Physics.java +++ b/src/main/java/net/pivipi/physics/Physics.java @@ -6,6 +6,8 @@ import net.minestom.server.collision.VisibleSweepResult; import net.minestom.server.coordinate.Vec; import net.minestom.server.entity.Entity; import net.minestom.server.entity.Player; +import net.minestom.server.network.packet.server.play.ParticlePacket; +import net.minestom.server.particle.Particle; public class Physics { private final double gravity = 9.8; @@ -13,18 +15,47 @@ public class Physics { private final double playerHeadBounciness = 0.5; private final double playerSneakingHeadBounciness = 0.2; private final double playerBodyBounciness = 0.2; + private final double playerSneakingBodyBounciness = 0; private final double groundFriction = 0.5; private final double airFriction = 0.1; + private final double flame = 20; // flame starts at speed + private final double flameFreq = 100; // ms per flame + private final double flameIncrement = 0.5; // ms per flame decrement per speed unit + private final float flameSpread = 0.2f; + private Vec velocity = new Vec(0, 0, 0); private final Entity entity; + private int p; public Physics(Entity entity) { this.entity = entity; } - public void applyPhysics(double delta, Set players) { + public void process(double delta, Set players) { + velocity = applyPhysics(delta, players); + entity.teleport(entity.getPosition().add(velocity.mul(delta))); + + double dist = velocity.distance(0, 0, 0); + if (dist > flame) { + int f = (int) (flameFreq - (dist - flame) * flameIncrement); + p += delta * 1000; + + if (p < f) return; + else p = 0; + + float offset = 0.5f; + int count = (int) (f > delta / 1000 ? f / delta / 1000 : 1); + System.out.println(f); + System.out.println(dist); + System.out.println(count); + + entity.getInstance().sendGroupedPacket(new ParticlePacket(Particle.FLAME, false, entity.getPosition().x(), entity.getPosition().y() + 0.5, entity.getPosition().z(), offset, offset, offset, flameSpread, count)); + } + } + + public Vec applyPhysics(double delta, Set players) { velocity = velocity.sub(0, gravity * delta, 0).mul(1 - (airFriction * delta), 1, 1 - (airFriction * delta)); if (Collision.collidesWithGround(2, entity)) { @@ -39,15 +70,17 @@ public class Physics { for (Player player : players) { boolean collides = Collision.collidesWithEntity(player, entity); if (collides) { - velocity = velocity.mul(-playerBodyBounciness, player.isSneaking() ? -playerSneakingHeadBounciness : -playerHeadBounciness, -playerBodyBounciness); + if (player.isSneaking()) + velocity = velocity.mul(-playerSneakingBodyBounciness, -playerSneakingHeadBounciness, -playerSneakingBodyBounciness); + else velocity = velocity.mul(-playerBodyBounciness, -playerHeadBounciness, -playerBodyBounciness); break; } } } - entity.teleport(entity.getPosition().add(velocity.mul(delta))); - //entity.setVelocity(velocity); + return velocity; } + public void addVelocity(Vec velocity) { this.velocity = this.velocity.add(velocity); diff --git a/src/main/java/net/pivipi/world/Stadium.java b/src/main/java/net/pivipi/world/Stadium.java index 6150126..0e13d32 100644 --- a/src/main/java/net/pivipi/world/Stadium.java +++ b/src/main/java/net/pivipi/world/Stadium.java @@ -5,7 +5,6 @@ import java.util.Set; import net.minestom.server.entity.Player; import net.pivipi.ball.Ball; -import net.pivipi.ball.BallKicker; public class Stadium { public final Set players = new HashSet();