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.event.GlobalEventHandler;
|
||||
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.instance.Instance;
|
||||
import net.pivipi.ball.Ball;
|
||||
import net.pivipi.ball.BallKicker;
|
||||
import net.pivipi.world.Stadium;
|
||||
|
||||
public class LoginHandler {
|
||||
private final Instance spawningInstance;
|
||||
private final Stadium stadium = new Stadium();
|
||||
|
||||
public LoginHandler(Instance spawningInstance) {
|
||||
this.spawningInstance = spawningInstance;
|
||||
}
|
||||
|
||||
public void setup(GlobalEventHandler globalEventHandler) {
|
||||
globalEventHandler.addListener(
|
||||
AsyncPlayerConfigurationEvent.class,
|
||||
event -> onLogin(event)
|
||||
);
|
||||
|
||||
globalEventHandler.addListener(
|
||||
PlayerSpawnEvent.class,
|
||||
event -> onSpawn(event)
|
||||
);
|
||||
globalEventHandler.addListener(AsyncPlayerConfigurationEvent.class, event -> onLogin(event));
|
||||
globalEventHandler.addListener(PlayerDisconnectEvent.class, event -> onQuit(event));
|
||||
globalEventHandler.addListener(PlayerSpawnEvent.class, event -> onSpawn(event));
|
||||
new BallKicker(stadium).setup(globalEventHandler);
|
||||
}
|
||||
|
||||
private void onLogin(AsyncPlayerConfigurationEvent event) {
|
||||
|
@ -35,15 +34,23 @@ public class LoginHandler {
|
|||
event.setHardcore(true);
|
||||
|
||||
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) {
|
||||
Player player = event.getPlayer();
|
||||
|
||||
player.setGameMode(GameMode.CREATIVE);
|
||||
|
||||
Ball ball = new Ball();
|
||||
ball.setInstance(event.getInstance());
|
||||
ball.teleport(new Pos(0.5, 15, 0.5));
|
||||
|
||||
if (stadium.ball == null) {
|
||||
Ball ball = new Ball(stadium);
|
||||
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.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;
|
||||
|
|
|
@ -1,41 +1,57 @@
|
|||
package net.pivipi.ball;
|
||||
|
||||
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;
|
||||
|
||||
public class Ball extends Entity {
|
||||
private long lastTick;
|
||||
|
||||
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
|
||||
|
||||
this.setNoGravity(true);
|
||||
this.setGlowing(true);
|
||||
this.hasPhysics = true;
|
||||
|
||||
this.editEntityMeta(FallingBlockMeta.class, meta -> {
|
||||
meta.setBlock(block);
|
||||
});
|
||||
|
||||
this.stadium = stadium;
|
||||
}
|
||||
|
||||
public Ball() {
|
||||
this(Block.WHITE_WOOL);
|
||||
public Ball(Stadium stadium) {
|
||||
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) {
|
||||
this.lastTick = time;
|
||||
}
|
||||
|
||||
long delay = time - this.lastTick;
|
||||
|
||||
physics.applyPhysics(delay / 1000.0);
|
||||
physics.applyPhysics(delay / 1000.0, stadium.players);
|
||||
|
||||
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 {
|
||||
/**
|
||||
*
|
||||
* @param player
|
||||
* @param entity
|
||||
* @param moving the moving entity
|
||||
* @param velocity the applied velocity
|
||||
* @return null if no collision
|
||||
*/
|
||||
public static VisibleSweepResult willCollideWithPlayer(Player player, Entity moving, Vec velocity) {
|
||||
return null; // TODO
|
||||
public static VisibleSweepResult willCollideWithEntity(Entity entity, Entity moving, Vec movement) {
|
||||
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) {
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
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 Physics {
|
||||
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;
|
||||
|
||||
|
@ -16,16 +24,32 @@ public class Physics {
|
|||
this.entity = entity;
|
||||
}
|
||||
|
||||
public void applyPhysics(double delta) {
|
||||
velocity = velocity.sub(0, gravity * delta, 0);
|
||||
public void applyPhysics(double delta, Set<Player> players) {
|
||||
velocity = velocity.sub(0, gravity * delta, 0).mul(1 - (airFriction * delta), 1, 1 - (airFriction * delta));
|
||||
|
||||
VisibleSweepResult result = Collision.willCollideWithGround(5, entity, velocity);
|
||||
System.out.println(result);
|
||||
if (entity.isOnGround()) {
|
||||
//System.out.println(result.res);
|
||||
velocity = velocity.mul(0, -bounciness, 0);
|
||||
if (Collision.collidesWithGround(2, entity)) {
|
||||
entity.teleport(entity.getPosition().withY(2));
|
||||
velocity = velocity.mul(1 - (groundFriction * delta), 1, 1 - (groundFriction * delta));
|
||||
}
|
||||
|
||||
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