commit
This commit is contained in:
parent
810240a80d
commit
d6d0ad0a85
7 changed files with 190 additions and 32 deletions
|
@ -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,6 +34,11 @@ 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) {
|
||||||
|
@ -42,8 +46,11 @@ public class LoginHandler {
|
||||||
|
|
||||||
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
|
||||||
|
|
||||||
public Ball(Block block) {
|
private final Physics physics = new Physics(this);
|
||||||
|
public final Stadium stadium;
|
||||||
|
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
87
src/main/java/net/pivipi/ball/BallKicker.java
Normal file
87
src/main/java/net/pivipi/ball/BallKicker.java
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
13
src/main/java/net/pivipi/world/Stadium.java
Normal file
13
src/main/java/net/pivipi/world/Stadium.java
Normal 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;
|
||||||
|
}
|
Loading…
Reference in a new issue