orient programming to object
This commit is contained in:
parent
7acdda21fa
commit
a0a4619755
10 changed files with 222 additions and 55 deletions
2
pom.xml
2
pom.xml
|
@ -17,7 +17,7 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>net.minestom</groupId>
|
<groupId>net.minestom</groupId>
|
||||||
<artifactId>minestom-snapshots</artifactId>
|
<artifactId>minestom-snapshots</artifactId>
|
||||||
<version>d606051f1e</version>
|
<version>7dd1792096</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.slf4j</groupId>
|
<groupId>org.slf4j</groupId>
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package net.pivipi;
|
package net.pivipi;
|
||||||
|
|
||||||
import net.minestom.server.coordinate.Pos;
|
import net.minestom.server.coordinate.Pos;
|
||||||
|
import net.minestom.server.coordinate.Vec;
|
||||||
import net.minestom.server.entity.GameMode;
|
import net.minestom.server.entity.GameMode;
|
||||||
import net.minestom.server.entity.Player;
|
import net.minestom.server.entity.Player;
|
||||||
import net.minestom.server.entity.attribute.Attribute;
|
import net.minestom.server.entity.attribute.Attribute;
|
||||||
|
@ -9,23 +10,24 @@ import net.minestom.server.event.player.AsyncPlayerConfigurationEvent;
|
||||||
import net.minestom.server.event.player.PlayerDisconnectEvent;
|
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.BallKicker;
|
import net.pivipi.ball.BallKicker;
|
||||||
import net.pivipi.world.Stadium;
|
import net.pivipi.game.Game;
|
||||||
|
import net.pivipi.game.Stadium;
|
||||||
|
|
||||||
public class LoginHandler {
|
public class LoginHandler {
|
||||||
private final Instance spawningInstance;
|
private final Instance spawningInstance;
|
||||||
private final Stadium stadium = new Stadium();
|
private final Game game;
|
||||||
|
|
||||||
public LoginHandler(Instance spawningInstance) {
|
public LoginHandler(Instance spawningInstance) {
|
||||||
this.spawningInstance = spawningInstance;
|
this.spawningInstance = spawningInstance;
|
||||||
|
this.game = new Game(new Stadium(spawningInstance, new Vec(-50, 64, -50), new Vec(100)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setup(GlobalEventHandler globalEventHandler) {
|
public void setup(GlobalEventHandler globalEventHandler) {
|
||||||
globalEventHandler.addListener(AsyncPlayerConfigurationEvent.class, event -> onLogin(event));
|
globalEventHandler.addListener(AsyncPlayerConfigurationEvent.class, event -> onLogin(event));
|
||||||
globalEventHandler.addListener(PlayerDisconnectEvent.class, event -> onQuit(event));
|
globalEventHandler.addListener(PlayerDisconnectEvent.class, event -> onQuit(event));
|
||||||
globalEventHandler.addListener(PlayerSpawnEvent.class, event -> onSpawn(event));
|
globalEventHandler.addListener(PlayerSpawnEvent.class, event -> onSpawn(event));
|
||||||
new BallKicker(stadium).setup(globalEventHandler);
|
new BallKicker(game.stadium).setup(globalEventHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onLogin(AsyncPlayerConfigurationEvent event) {
|
private void onLogin(AsyncPlayerConfigurationEvent event) {
|
||||||
|
@ -35,11 +37,11 @@ public class LoginHandler {
|
||||||
event.setHardcore(true);
|
event.setHardcore(true);
|
||||||
|
|
||||||
player.setRespawnPoint(new Pos(0, 67, 0));
|
player.setRespawnPoint(new Pos(0, 67, 0));
|
||||||
stadium.players.add(player);
|
game.addPlayer(player);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onQuit(PlayerDisconnectEvent event) {
|
private void onQuit(PlayerDisconnectEvent event) {
|
||||||
stadium.players.remove(event.getPlayer());
|
game.removePlayer(event.getPlayer());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onSpawn(PlayerSpawnEvent event) {
|
private void onSpawn(PlayerSpawnEvent event) {
|
||||||
|
@ -49,11 +51,6 @@ public class LoginHandler {
|
||||||
player.getAttribute(Attribute.GENERIC_MOVEMENT_SPEED).setBaseValue(0.2);
|
player.getAttribute(Attribute.GENERIC_MOVEMENT_SPEED).setBaseValue(0.2);
|
||||||
player.getAttribute(Attribute.GENERIC_JUMP_STRENGTH).setBaseValue(0.36813); // just enough to jump a block
|
player.getAttribute(Attribute.GENERIC_JUMP_STRENGTH).setBaseValue(0.36813); // just enough to jump a block
|
||||||
|
|
||||||
if (stadium.ball == null) {
|
game.startWarmup();
|
||||||
Ball ball = new Ball(stadium);
|
|
||||||
ball.setInstance(event.getInstance());
|
|
||||||
ball.teleport(new Pos(0, 90, 5));
|
|
||||||
stadium.ball = ball;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ package net.pivipi;
|
||||||
|
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
import net.minestom.server.instance.InstanceManager;
|
import net.minestom.server.instance.InstanceManager;
|
||||||
|
import net.minestom.server.timer.ExecutionType;
|
||||||
import net.minestom.server.timer.SchedulerManager;
|
import net.minestom.server.timer.SchedulerManager;
|
||||||
import net.minestom.server.timer.TaskSchedule;
|
import net.minestom.server.timer.TaskSchedule;
|
||||||
|
|
||||||
|
@ -19,7 +20,7 @@ public class Stats implements Runnable {
|
||||||
|
|
||||||
public void start(SchedulerManager schedulerManager) {
|
public void start(SchedulerManager schedulerManager) {
|
||||||
//this.benchmarkManager = MinecraftServer.getBenchmarkManager();
|
//this.benchmarkManager = MinecraftServer.getBenchmarkManager();
|
||||||
schedulerManager.scheduleTask(this, TaskSchedule.immediate(), TaskSchedule.tick(tickDelay));
|
schedulerManager.scheduleTask(this, TaskSchedule.immediate(), TaskSchedule.tick(tickDelay), ExecutionType.TICK_END);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -29,14 +30,11 @@ public class Stats implements Runnable {
|
||||||
lastRun = now;
|
lastRun = now;
|
||||||
|
|
||||||
double mspt = (double)delay / tickDelay;
|
double mspt = (double)delay / tickDelay;
|
||||||
double tps = 1000 / mspt;
|
long memUsed = (runtime.totalMemory() - runtime.freeMemory()) / 1024 / 1024;
|
||||||
|
|
||||||
long memAllocated = runtime.totalMemory() / 1024 / 1024;
|
|
||||||
long memUsed = memAllocated - runtime.freeMemory() / 1024 / 1024;
|
|
||||||
|
|
||||||
Component footer = Component.text("%.3f MSPT | %.3f TPS | %dMB / %dMB".formatted(mspt, tps, memUsed, memAllocated));
|
Component footer = Component.text("%.3f MSPT | %dMB".formatted(mspt, memUsed));
|
||||||
|
|
||||||
instanceManager.getInstances().forEach(instance -> {
|
instanceManager.getInstances().forEach(instance -> { // TODO make this async
|
||||||
instance.getPlayers().forEach(player -> {
|
instance.getPlayers().forEach(player -> {
|
||||||
player.sendPlayerListFooter(footer);
|
player.sendPlayerListFooter(footer);
|
||||||
});
|
});
|
||||||
|
|
|
@ -6,8 +6,8 @@ import net.minestom.server.entity.EntityType;
|
||||||
import net.minestom.server.entity.Player;
|
import net.minestom.server.entity.Player;
|
||||||
import net.minestom.server.entity.metadata.other.FallingBlockMeta;
|
import net.minestom.server.entity.metadata.other.FallingBlockMeta;
|
||||||
import net.minestom.server.instance.block.Block;
|
import net.minestom.server.instance.block.Block;
|
||||||
|
import net.pivipi.game.Stadium;
|
||||||
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;
|
||||||
|
|
|
@ -10,9 +10,9 @@ import net.minestom.server.event.player.PlayerHandAnimationEvent;
|
||||||
import net.minestom.server.event.player.PlayerStartSneakingEvent;
|
import net.minestom.server.event.player.PlayerStartSneakingEvent;
|
||||||
import net.minestom.server.event.player.PlayerStopSneakingEvent;
|
import net.minestom.server.event.player.PlayerStopSneakingEvent;
|
||||||
import net.minestom.server.instance.block.Block;
|
import net.minestom.server.instance.block.Block;
|
||||||
|
import net.pivipi.game.Stadium;
|
||||||
import net.pivipi.physics.Collision;
|
import net.pivipi.physics.Collision;
|
||||||
import net.pivipi.physics.CollisionData;
|
import net.pivipi.physics.CollisionData;
|
||||||
import net.pivipi.world.Stadium;
|
|
||||||
|
|
||||||
public class BallKicker { // TODO apply physics settings here
|
public class BallKicker { // TODO apply physics settings here
|
||||||
public final Stadium stadium;
|
public final Stadium stadium;
|
||||||
|
|
104
src/main/java/net/pivipi/game/Game.java
Normal file
104
src/main/java/net/pivipi/game/Game.java
Normal file
|
@ -0,0 +1,104 @@
|
||||||
|
package net.pivipi.game;
|
||||||
|
|
||||||
|
import net.minestom.server.coordinate.Pos;
|
||||||
|
import net.minestom.server.entity.Player;
|
||||||
|
import net.pivipi.ball.Ball;
|
||||||
|
|
||||||
|
public class Game {
|
||||||
|
public final Stadium stadium;
|
||||||
|
|
||||||
|
public boolean started; // true even if warmup
|
||||||
|
public boolean warmup;
|
||||||
|
public boolean paused; // is game paused
|
||||||
|
public long startedTime; // fine until year 292272993 but trust me it will pass in an Instant
|
||||||
|
public long lostTime; // how much ms the game was paused for
|
||||||
|
public long addedTime; // also called stoppage time, cosmetic since a person decides when to end the match
|
||||||
|
|
||||||
|
private long pauseStart;
|
||||||
|
|
||||||
|
public Game(Stadium stadium) {
|
||||||
|
this.stadium = stadium;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public boolean addPlayer(Player player) {
|
||||||
|
return stadium.players.add(player);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean removePlayer(Player player) {
|
||||||
|
return stadium.players.remove(player);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* starts warmup
|
||||||
|
* @return true if the game was not running
|
||||||
|
*/
|
||||||
|
public boolean startWarmup() {
|
||||||
|
if (!started && !warmup) return false;
|
||||||
|
|
||||||
|
this.started = true;
|
||||||
|
this.warmup = true;
|
||||||
|
this.startedTime = System.currentTimeMillis();
|
||||||
|
|
||||||
|
Ball ball = new Ball(stadium);
|
||||||
|
ball.setInstance(stadium.instance);
|
||||||
|
ball.teleport(new Pos(stadium.max.sub(stadium.size.div(2))));
|
||||||
|
stadium.ball = ball;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* starts the game
|
||||||
|
* @return true if the game was not running or if there was warmup
|
||||||
|
*/
|
||||||
|
public boolean start() {
|
||||||
|
if (started && !warmup) return false;
|
||||||
|
|
||||||
|
this.started = true;
|
||||||
|
this.warmup = false;
|
||||||
|
this.startedTime = System.currentTimeMillis();
|
||||||
|
// TODO
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ends the game
|
||||||
|
* @return true if the game was running
|
||||||
|
*/
|
||||||
|
public boolean end() {
|
||||||
|
if (!started) return false;
|
||||||
|
|
||||||
|
this.started = false;
|
||||||
|
this.warmup = false;
|
||||||
|
// TODO
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean pause() {
|
||||||
|
if (paused) return false;
|
||||||
|
|
||||||
|
pauseStart = System.currentTimeMillis();
|
||||||
|
paused = true;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean unpause() {
|
||||||
|
if (!paused) return false;
|
||||||
|
|
||||||
|
lostTime += System.currentTimeMillis() - pauseStart;
|
||||||
|
paused = false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* suggests how much added time
|
||||||
|
* basically rounds down lost time to minutes
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public long suggestAddedTime() {
|
||||||
|
return (lostTime / 60000) * 60000;
|
||||||
|
}
|
||||||
|
}
|
47
src/main/java/net/pivipi/game/PhysicsSettings.java
Normal file
47
src/main/java/net/pivipi/game/PhysicsSettings.java
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
package net.pivipi.game;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
|
||||||
|
public class PhysicsSettings {
|
||||||
|
public double gravity = 9.8;
|
||||||
|
public double blockBounciness = 0.5;
|
||||||
|
public double playerHeadBounciness = 0.5;
|
||||||
|
public double playerSneakingHeadBounciness = 0.2;
|
||||||
|
public double playerBodyBounciness = 0.2;
|
||||||
|
public double playerSneakingBodyBounciness = 0;
|
||||||
|
public double playerCarryStrength = 2;
|
||||||
|
public double headJumpStrength = 5;
|
||||||
|
public double headNodStep = 20;
|
||||||
|
public double jumpStrength = 20;
|
||||||
|
public double groundFriction = 0.5;
|
||||||
|
public double airFriction = 0.1;
|
||||||
|
|
||||||
|
public String setByString(String key, String valueStr) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
Field field = this.getClass().getDeclaredField(key);
|
||||||
|
Type type = field.getAnnotatedType().getType();
|
||||||
|
Object value;
|
||||||
|
|
||||||
|
if (type.equals(double.class)) {
|
||||||
|
value = Double.valueOf(valueStr);
|
||||||
|
} else {
|
||||||
|
return "This property is not changeable because I can't yet handle type " + type.getTypeName();
|
||||||
|
}
|
||||||
|
|
||||||
|
field.setAccessible(true);
|
||||||
|
field.set(this, value);
|
||||||
|
|
||||||
|
return field.getName() + " is now " + value.toString();
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
return "Not a decimal number: " + valueStr;
|
||||||
|
} catch (NoSuchFieldException e) {
|
||||||
|
return "Invalid key: " + key;
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
return "Invalid value: " + valueStr;
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
return "This property is not changeable";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
42
src/main/java/net/pivipi/game/Stadium.java
Normal file
42
src/main/java/net/pivipi/game/Stadium.java
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
package net.pivipi.game;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import net.minestom.server.coordinate.Vec;
|
||||||
|
import net.minestom.server.entity.Player;
|
||||||
|
import net.minestom.server.instance.Instance;
|
||||||
|
import net.pivipi.ball.Ball;
|
||||||
|
|
||||||
|
public class Stadium {
|
||||||
|
public final Set<Player> players = new HashSet<Player>();
|
||||||
|
public Ball ball; // TODO public?
|
||||||
|
|
||||||
|
/**
|
||||||
|
* the instance where this stadium is
|
||||||
|
*/
|
||||||
|
public final Instance instance;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* the lower corner pos
|
||||||
|
*/
|
||||||
|
public final Vec pos;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* the stadium size
|
||||||
|
*/
|
||||||
|
public final Vec size;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* the max corner pos that is pos + size
|
||||||
|
*/
|
||||||
|
public final Vec max;
|
||||||
|
|
||||||
|
|
||||||
|
public Stadium(Instance instance, Vec pos, Vec size) {
|
||||||
|
this.instance = instance;
|
||||||
|
this.pos = pos;
|
||||||
|
this.size = size;
|
||||||
|
this.max = pos.add(size);
|
||||||
|
}
|
||||||
|
}
|
|
@ -9,27 +9,18 @@ import net.minestom.server.entity.Entity;
|
||||||
import net.minestom.server.entity.Player;
|
import net.minestom.server.entity.Player;
|
||||||
import net.minestom.server.network.packet.server.play.ParticlePacket;
|
import net.minestom.server.network.packet.server.play.ParticlePacket;
|
||||||
import net.minestom.server.particle.Particle;
|
import net.minestom.server.particle.Particle;
|
||||||
|
import net.pivipi.game.PhysicsSettings;
|
||||||
|
|
||||||
public class Physics {
|
public class Physics {
|
||||||
private final double gravity = 9.8;
|
private PhysicsSettings settings;
|
||||||
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 playerSneakingBodyBounciness = 0;
|
|
||||||
private final double playerCarryStrength = 2;
|
|
||||||
private final double headJumpStrength = 5;
|
|
||||||
private final double headNodStep = 20;
|
|
||||||
private final double jumpStrength = 20;
|
|
||||||
private final double groundFriction = 0.5;
|
|
||||||
private final double airFriction = 0.1;
|
|
||||||
private final int groundY = 64;
|
|
||||||
|
|
||||||
private final double flame = 20; // flame starts at speed
|
private final double flame = 20; // flame starts at speed
|
||||||
private final double flameFreq = 100; // ms per flame
|
private final double flameFreq = 100; // ms per flame
|
||||||
private final double flameIncrement = 0.5; // ms per flame decrement per speed unit
|
private final double flameIncrement = 0.5; // ms per flame decrement per speed unit
|
||||||
private final float flameSpread = 0.2f;
|
private final float flameSpread = 0.2f;
|
||||||
|
|
||||||
|
private final int groundY = 64; // this should be removed when block collisions
|
||||||
|
|
||||||
private Vec velocity = new Vec(0, 0, 0);
|
private Vec velocity = new Vec(0, 0, 0);
|
||||||
|
|
||||||
private final Entity entity;
|
private final Entity entity;
|
||||||
|
@ -59,12 +50,12 @@ public class Physics {
|
||||||
}
|
}
|
||||||
|
|
||||||
private Vec applyPhysics(double delta, Set<Player> players) {
|
private Vec applyPhysics(double delta, Set<Player> players) {
|
||||||
velocity = velocity.sub(0, gravity * delta, 0).mul(1 - (airFriction * delta), 1, 1 - (airFriction * delta));
|
velocity = velocity.sub(0, settings.gravity * delta, 0).mul(1 - (settings.airFriction * delta), 1, 1 - (settings.airFriction * delta));
|
||||||
ArrayList<CollisionData> collisions = new ArrayList<>();
|
ArrayList<CollisionData> collisions = new ArrayList<>();
|
||||||
|
|
||||||
if (Collision.collidesWithGround(groundY, entity)) {
|
if (Collision.collidesWithGround(groundY, entity)) {
|
||||||
entity.teleport(entity.getPosition().withY(groundY));
|
entity.teleport(entity.getPosition().withY(groundY));
|
||||||
velocity = velocity.mul(1 - (groundFriction * delta), -blockBounciness, 1 - (groundFriction * delta));
|
velocity = velocity.mul(1 - (settings.groundFriction * delta), -settings.blockBounciness, 1 - (settings.groundFriction * delta));
|
||||||
} else {
|
} else {
|
||||||
for (Player player : players) {
|
for (Player player : players) {
|
||||||
CollisionData collisionData = new CollisionData();
|
CollisionData collisionData = new CollisionData();
|
||||||
|
@ -103,17 +94,17 @@ public class Physics {
|
||||||
if (movementPos.y() > 0) {
|
if (movementPos.y() > 0) {
|
||||||
double headPitchDiff = Math.abs(movementPos.pitch());
|
double headPitchDiff = Math.abs(movementPos.pitch());
|
||||||
System.out.println(headPitchDiff);
|
System.out.println(headPitchDiff);
|
||||||
addVelocity(player.getPosition().direction().mul(headPitchDiff / headNodStep).withY(headJumpStrength));
|
addVelocity(player.getPosition().direction().mul(headPitchDiff / settings.headNodStep).withY(settings.headJumpStrength));
|
||||||
} else velocity = velocity.mul(1, player.isSneaking() ? -playerSneakingHeadBounciness : -playerHeadBounciness, 1);
|
} else velocity = velocity.mul(1, player.isSneaking() ? -settings.playerSneakingHeadBounciness : -settings.playerHeadBounciness, 1);
|
||||||
entity.teleport(entity.getPosition().withY(y -> y + headOffsetY));
|
entity.teleport(entity.getPosition().withY(y -> y + headOffsetY));
|
||||||
} else {
|
} else {
|
||||||
entity.teleport(entity.getPosition().add(offset.mul(1.1))); // magic value to make some space in case of desync
|
entity.teleport(entity.getPosition().add(offset.mul(1.1))); // magic value to make some space in case of desync
|
||||||
double bodyBounciness = player.isSneaking() ? -playerSneakingBodyBounciness : -playerBodyBounciness;
|
double bodyBounciness = player.isSneaking() ? -settings.playerSneakingBodyBounciness : -settings.playerBodyBounciness;
|
||||||
|
|
||||||
velocity = velocity
|
velocity = velocity
|
||||||
.withX(x -> oppositeX ? x * bodyBounciness : x + movementPos.x() * playerCarryStrength)
|
.withX(x -> oppositeX ? x * bodyBounciness : x + movementPos.x() * settings.playerCarryStrength)
|
||||||
.withY(y -> collisionData.distance.y() < 1.0 ? movementPos.y() * jumpStrength : y) // magic value legs
|
.withY(y -> collisionData.distance.y() < 1.0 ? movementPos.y() * settings.jumpStrength : y) // magic value legs
|
||||||
.withZ(z -> oppositeZ ? z * bodyBounciness : z + movementPos.z() * playerCarryStrength);
|
.withZ(z -> oppositeZ ? z * bodyBounciness : z + movementPos.z() * settings.playerCarryStrength);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,12 +0,0 @@
|
||||||
package net.pivipi.world;
|
|
||||||
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import net.minestom.server.entity.Player;
|
|
||||||
import net.pivipi.ball.Ball;
|
|
||||||
|
|
||||||
public class Stadium {
|
|
||||||
public final Set<Player> players = new HashSet<Player>();
|
|
||||||
public Ball ball;
|
|
||||||
}
|
|
Loading…
Reference in a new issue