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();