This commit is contained in:
Minecon724 2024-07-05 15:13:16 +02:00
parent 810240a80d
commit d6d0ad0a85
Signed by: Minecon724
GPG key ID: 3CCC4D267742C8E8
7 changed files with 190 additions and 32 deletions

View file

@ -5,27 +5,26 @@ import net.minestom.server.entity.GameMode;
import net.minestom.server.entity.Player; import net.minestom.server.entity.Player;
import net.minestom.server.event.GlobalEventHandler; import net.minestom.server.event.GlobalEventHandler;
import net.minestom.server.event.player.AsyncPlayerConfigurationEvent; import net.minestom.server.event.player.AsyncPlayerConfigurationEvent;
import net.minestom.server.event.player.PlayerDisconnectEvent;
import net.minestom.server.event.player.PlayerSpawnEvent; import net.minestom.server.event.player.PlayerSpawnEvent;
import net.minestom.server.instance.Instance; import net.minestom.server.instance.Instance;
import net.pivipi.ball.Ball; import net.pivipi.ball.Ball;
import net.pivipi.ball.BallKicker;
import net.pivipi.world.Stadium;
public class LoginHandler { public class LoginHandler {
private final Instance spawningInstance; private final Instance spawningInstance;
private final Stadium stadium = new Stadium();
public LoginHandler(Instance spawningInstance) { public LoginHandler(Instance spawningInstance) {
this.spawningInstance = spawningInstance; this.spawningInstance = spawningInstance;
} }
public void setup(GlobalEventHandler globalEventHandler) { public void setup(GlobalEventHandler globalEventHandler) {
globalEventHandler.addListener( globalEventHandler.addListener(AsyncPlayerConfigurationEvent.class, event -> onLogin(event));
AsyncPlayerConfigurationEvent.class, globalEventHandler.addListener(PlayerDisconnectEvent.class, event -> onQuit(event));
event -> onLogin(event) globalEventHandler.addListener(PlayerSpawnEvent.class, event -> onSpawn(event));
); new BallKicker(stadium).setup(globalEventHandler);
globalEventHandler.addListener(
PlayerSpawnEvent.class,
event -> onSpawn(event)
);
} }
private void onLogin(AsyncPlayerConfigurationEvent event) { private void onLogin(AsyncPlayerConfigurationEvent event) {
@ -35,15 +34,23 @@ public class LoginHandler {
event.setHardcore(true); event.setHardcore(true);
player.setRespawnPoint(new Pos(0, 5, 0)); player.setRespawnPoint(new Pos(0, 5, 0));
stadium.players.add(player);
}
private void onQuit(PlayerDisconnectEvent event) {
stadium.players.remove(event.getPlayer());
} }
private void onSpawn(PlayerSpawnEvent event) { private void onSpawn(PlayerSpawnEvent event) {
Player player = event.getPlayer(); Player player = event.getPlayer();
player.setGameMode(GameMode.CREATIVE); player.setGameMode(GameMode.CREATIVE);
Ball ball = new Ball(); if (stadium.ball == null) {
ball.setInstance(event.getInstance()); Ball ball = new Ball(stadium);
ball.teleport(new Pos(0.5, 15, 0.5)); ball.setInstance(event.getInstance());
ball.teleport(new Pos(0.5, 15, 0.5));
stadium.ball = ball;
}
} }
} }

View file

@ -8,6 +8,7 @@ import net.minestom.server.instance.InstanceManager;
import net.minestom.server.instance.LightingChunk; import net.minestom.server.instance.LightingChunk;
import net.minestom.server.registry.DynamicRegistry.Key; import net.minestom.server.registry.DynamicRegistry.Key;
import net.minestom.server.world.DimensionType; import net.minestom.server.world.DimensionType;
import net.pivipi.ball.BallKicker;
import net.pivipi.world.FancyDimension; import net.pivipi.world.FancyDimension;
import net.pivipi.world.SoccerGenerator; import net.pivipi.world.SoccerGenerator;
import net.pivipi.world.WorldConstraints; import net.pivipi.world.WorldConstraints;

View file

@ -1,41 +1,57 @@
package net.pivipi.ball; package net.pivipi.ball;
import net.minestom.server.coordinate.Vec;
import net.minestom.server.entity.Entity; import net.minestom.server.entity.Entity;
import net.minestom.server.entity.EntityType; import net.minestom.server.entity.EntityType;
import net.minestom.server.entity.metadata.other.FallingBlockMeta; import net.minestom.server.entity.metadata.other.FallingBlockMeta;
import net.minestom.server.event.player.PlayerDisconnectEvent;
import net.minestom.server.instance.block.Block; import net.minestom.server.instance.block.Block;
import net.pivipi.physics.Physics; import net.pivipi.physics.Physics;
import net.pivipi.world.Stadium;
public class Ball extends Entity { public class Ball extends Entity {
private long lastTick; private long lastTick;
private final Physics physics = new Physics(this); private final Physics physics = new Physics(this);
public final Stadium stadium;
public Ball(Block block) { public Ball(Block block, Stadium stadium) {
super(EntityType.FALLING_BLOCK); // not block display because its movement lags for some reason super(EntityType.FALLING_BLOCK); // not block display because its movement lags for some reason
this.setNoGravity(true); this.setNoGravity(true);
this.setGlowing(true); this.setGlowing(true);
this.hasPhysics = true;
this.editEntityMeta(FallingBlockMeta.class, meta -> { this.editEntityMeta(FallingBlockMeta.class, meta -> {
meta.setBlock(block); meta.setBlock(block);
}); });
this.stadium = stadium;
} }
public Ball() { public Ball(Stadium stadium) {
this(Block.WHITE_WOOL); this(Block.WHITE_WOOL, stadium);
} }
public void tick(long time) { // I don't know if change that to update public void update(long time) {
if (this.lastTick == 0) { if (this.lastTick == 0) {
this.lastTick = time; this.lastTick = time;
} }
long delay = time - this.lastTick; long delay = time - this.lastTick;
physics.applyPhysics(delay / 1000.0); physics.applyPhysics(delay / 1000.0, stadium.players);
this.lastTick = time; this.lastTick = time;
} }
public void addVelocity(Vec velocity) {
physics.addVelocity(velocity);
}
public void addPos(Vec vec) {
this.teleport(this.getPosition().add(vec));
}
} }

View file

@ -0,0 +1,87 @@
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;
public class BallKicker { // TODO apply physics settings here
public final Stadium stadium;
private long lastSneak;
private int sneakStreak;
public BallKicker(Stadium stadium) {
this.stadium = stadium;
}
public void setup(GlobalEventHandler globalEventHandler) {
globalEventHandler.addListener(PlayerMoveEvent.class, event -> onMove(event));
globalEventHandler.addListener(PlayerStartSneakingEvent.class, event -> onSneak(event));
globalEventHandler.addListener(PlayerStopSneakingEvent.class, event -> onStopSneaking(event));
}
private void onMove(PlayerMoveEvent event) {
Player player = event.getPlayer();
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));
}
}
private void onStopSneaking(PlayerStopSneakingEvent event) {
Player player = event.getPlayer();
Pos deltaPos = new Pos(0, 0.3, 0);
boolean collides = Collision.collidesWithEntity(stadium.ball, player);
if (collides) {
System.out.println(deltaPos);
stadium.ball.addPos(deltaPos.asVec());
stadium.ball.addVelocity(deltaPos.asVec().mul(10));
}
}
private void onSneak(PlayerStartSneakingEvent event) {
long now = System.currentTimeMillis();
long sneakDelay = now - lastSneak;
lastSneak = now;
if (sneakDelay < 500) {
if (++sneakStreak > 5) {
Player player = event.getPlayer();
Point targetPos = player.getTargetBlockPosition(10);
if (targetPos == null) targetPos = player.getPosition();
targetPos = targetPos.add(0, 5, 0);
Ball ball = new Ball(stadium);
ball.setInstance(event.getInstance());
ball.teleport(new Pos(targetPos));
stadium.ball.remove();
stadium.ball = ball;
sneakStreak = 0;
}
} else {
sneakStreak = 0;
}
}
}

View file

@ -10,13 +10,15 @@ import net.minestom.server.entity.Player;
public class Collision { public class Collision {
/** /**
* *
* @param player * @param entity
* @param moving the moving entity * @param moving the moving entity
* @param velocity the applied velocity * @param velocity the applied velocity
* @return null if no collision * @return null if no collision
*/ */
public static VisibleSweepResult willCollideWithPlayer(Player player, Entity moving, Vec velocity) { public static VisibleSweepResult willCollideWithEntity(Entity entity, Entity moving, Vec movement) {
return null; // TODO SweepResult sweepResult = new SweepResult(1, 0, 0, 0, null, 0, 0, 0);
boolean collided = entity.getBoundingBox().intersectBoxSwept(moving.getPosition(), movement, entity.getPosition(), moving.getBoundingBox(), sweepResult);
return collided ? new VisibleSweepResult(sweepResult) : null;
} }
/** /**
@ -27,7 +29,15 @@ public class Collision {
*/ */
public static VisibleSweepResult willCollideWithGround(double groundY, Entity moving, Vec movement) { public static VisibleSweepResult willCollideWithGround(double groundY, Entity moving, Vec movement) {
SweepResult sweepResult = new SweepResult(1, 0, 0, 0, null, 0, 0, 0); SweepResult sweepResult = new SweepResult(1, 0, 0, 0, null, 0, 0, 0);
boolean collided = new BoundingBox(10, 10, 1).intersectBoxSwept(moving.getPosition(), movement, moving.getPosition().withY(groundY).sub(5, 0, 5), moving.getBoundingBox(), sweepResult); boolean collided = new BoundingBox(10, 1, 10).intersectBoxSwept(moving.getPosition(), movement, moving.getPosition().withY(groundY - 1).sub(5, 0, 5), moving.getBoundingBox(), sweepResult);
return collided ? new VisibleSweepResult(sweepResult) : null; return collided ? new VisibleSweepResult(sweepResult) : null;
} }
public static boolean collidesWithEntity(Entity entity1, Entity entity2) {
return entity1.getBoundingBox().intersectEntity(entity1.getPosition(), entity2);
}
public static boolean collidesWithGround(double groundY, Entity entity) {
return new BoundingBox(10, 1, 10).intersectEntity(entity.getPosition().withY(groundY - 1).sub(5, 0, 5), entity);
}
} }

View file

@ -1,14 +1,22 @@
package net.pivipi.physics; package net.pivipi.physics;
import java.util.Set;
import net.minestom.server.collision.VisibleSweepResult; import net.minestom.server.collision.VisibleSweepResult;
import net.minestom.server.coordinate.Vec; import net.minestom.server.coordinate.Vec;
import net.minestom.server.entity.Entity; import net.minestom.server.entity.Entity;
import net.minestom.server.entity.Player;
public class Physics { public class Physics {
private final double gravity = 9.8; private final double gravity = 9.8;
private final double bounciness = 1; private final double blockBounciness = 0.5;
private final double playerHeadBounciness = 0.5;
private final double playerSneakingHeadBounciness = 0.2;
private final double playerBodyBounciness = 0.2;
private final double groundFriction = 0.5;
private final double airFriction = 0.1;
private Vec velocity = new Vec(5, 0, 5); private Vec velocity = new Vec(0, 0, 0);
private final Entity entity; private final Entity entity;
@ -16,16 +24,32 @@ public class Physics {
this.entity = entity; this.entity = entity;
} }
public void applyPhysics(double delta) { public void applyPhysics(double delta, Set<Player> players) {
velocity = velocity.sub(0, gravity * delta, 0); velocity = velocity.sub(0, gravity * delta, 0).mul(1 - (airFriction * delta), 1, 1 - (airFriction * delta));
VisibleSweepResult result = Collision.willCollideWithGround(5, entity, velocity); if (Collision.collidesWithGround(2, entity)) {
System.out.println(result); entity.teleport(entity.getPosition().withY(2));
if (entity.isOnGround()) { velocity = velocity.mul(1 - (groundFriction * delta), 1, 1 - (groundFriction * delta));
//System.out.println(result.res);
velocity = velocity.mul(0, -bounciness, 0);
} }
entity.setVelocity(velocity); VisibleSweepResult result = Collision.willCollideWithGround(2, entity, velocity.mul(delta));
if (result != null) {
velocity = velocity.mul(1, -blockBounciness, 1);
} else {
for (Player player : players) {
boolean collides = Collision.collidesWithEntity(player, entity);
if (collides) {
velocity = velocity.mul(-playerBodyBounciness, player.isSneaking() ? -playerSneakingHeadBounciness : -playerHeadBounciness, -playerBodyBounciness);
break;
}
}
}
entity.teleport(entity.getPosition().add(velocity.mul(delta)));
//entity.setVelocity(velocity);
}
public void addVelocity(Vec velocity) {
this.velocity = this.velocity.add(velocity);
} }
} }

View file

@ -0,0 +1,13 @@
package net.pivipi.world;
import java.util.HashSet;
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<Player> players = new HashSet<Player>();
public Ball ball;
}