Finish up MineKart
This commit is contained in:
parent
e716c9b2ea
commit
4b09c66cdc
|
@ -97,6 +97,7 @@ public class GameCompassComponent extends GameComponent<Game>
|
|||
|
||||
double dist = UtilMath.offset(player, closest);
|
||||
|
||||
player.setCompassTarget(closest.getLocation());
|
||||
UtilTextBottom.display(C.cWhiteB + "Target: " + closestTeam.getChatColour() + closest.getName() + C.cWhiteB + " Distance: " + closestTeam.getChatColour() + _distanceFormat.format(dist), player);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package mineplex.game.nano.game.games.minekart;
|
||||
|
||||
import org.bukkit.DyeColor;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.Sheep;
|
||||
import org.bukkit.util.Vector;
|
||||
|
@ -14,7 +14,7 @@ public class Kart
|
|||
{
|
||||
|
||||
private final Player _driver;
|
||||
private final LivingEntity _vehicle;
|
||||
private final Sheep _vehicle;
|
||||
|
||||
private int _lap, _lapCheckpoint, _lapKeyCheckpoint;
|
||||
|
||||
|
@ -28,6 +28,8 @@ public class Kart
|
|||
private boolean _crashed;
|
||||
private long _crashedAt;
|
||||
|
||||
private long _completedAt;
|
||||
|
||||
Kart(Player driver)
|
||||
{
|
||||
_driver = driver;
|
||||
|
@ -39,6 +41,8 @@ public class Kart
|
|||
UtilEnt.ghost(_vehicle, true, false);
|
||||
UtilEnt.setFakeHead(_vehicle, true);
|
||||
|
||||
_vehicle.setColor(DyeColor.RED);
|
||||
|
||||
_vehicle.setPassenger(driver);
|
||||
|
||||
_lap = 1;
|
||||
|
@ -57,11 +61,17 @@ public class Kart
|
|||
return _driver;
|
||||
}
|
||||
|
||||
public LivingEntity getVehicle()
|
||||
public Sheep getVehicle()
|
||||
{
|
||||
return _vehicle;
|
||||
}
|
||||
|
||||
public Location getParticleLocation()
|
||||
{
|
||||
Location location = _vehicle.getLocation().add(0, 0.3, 0);
|
||||
return location.subtract(location.getDirection().multiply(0.4));
|
||||
}
|
||||
|
||||
public void setLap(int lap)
|
||||
{
|
||||
_lap = lap;
|
||||
|
@ -154,15 +164,21 @@ public class Kart
|
|||
_driftPower = 0;
|
||||
}
|
||||
|
||||
public boolean canBoost()
|
||||
{
|
||||
return UtilTime.elapsed(_driftLast, 500);
|
||||
}
|
||||
|
||||
public boolean isBoosting()
|
||||
{
|
||||
return !UtilTime.elapsed(_driftLast, 1000);
|
||||
return !UtilTime.elapsed(_driftLast, 1200);
|
||||
}
|
||||
|
||||
public void setCrashed(boolean crashed)
|
||||
{
|
||||
_crashed = crashed;
|
||||
_driftDirection = null;
|
||||
_driftPower = 0;
|
||||
_driftLast = 0;
|
||||
|
||||
if (crashed)
|
||||
|
@ -180,4 +196,14 @@ public class Kart
|
|||
{
|
||||
return _crashedAt;
|
||||
}
|
||||
|
||||
public void complete()
|
||||
{
|
||||
_completedAt = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
public long getCompletedAt()
|
||||
{
|
||||
return _completedAt;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,9 +2,14 @@ package mineplex.game.nano.game.games.minekart;
|
|||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import mineplex.core.common.util.UtilAlg;
|
||||
import mineplex.core.common.util.UtilParticle;
|
||||
import mineplex.core.common.util.UtilParticle.ParticleType;
|
||||
import mineplex.core.common.util.UtilParticle.ViewDist;
|
||||
|
||||
public class KartController
|
||||
{
|
||||
|
@ -14,73 +19,152 @@ public class KartController
|
|||
LEFT, RIGHT
|
||||
}
|
||||
|
||||
void applyAirDrag(Kart kart)
|
||||
void applyAirResistance(Kart kart)
|
||||
{
|
||||
if (kart.getFrontWaysInput() != 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
Vector velocity = kart.getVelocity();
|
||||
|
||||
Vector velocity = kart.getVelocity().multiply(0.95);
|
||||
|
||||
if (velocity.length() < 0.05)
|
||||
if (kart.getFrontWaysInput() == 0 && velocity.length() < 0.1)
|
||||
{
|
||||
velocity.multiply(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
velocity.multiply(1 - (Math.log(velocity.length() + 1) / 50));
|
||||
}
|
||||
}
|
||||
|
||||
void collideBlock(Kart kart)
|
||||
{
|
||||
Location location = kart.getVehicle().getLocation().add(0, 0.5, 0);
|
||||
|
||||
kart.getDriver().sendMessage("y=" + kart.getVehicle().getLocation().getY() % 1);
|
||||
|
||||
if (location.getBlock().getType() != Material.AIR)
|
||||
{
|
||||
kart.getVelocity().multiply(-1);
|
||||
kart.getVelocity().setY(0.5);
|
||||
kart.setCrashed(true);
|
||||
}
|
||||
}
|
||||
|
||||
void accelerate(Kart kart)
|
||||
{
|
||||
if (kart.isCrashed())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Vector velocity = kart.getVelocity();
|
||||
Vector facing = UtilAlg.getTrajectory(kart.getYaw(), 0).multiply(0.03 * kart.getFrontWaysInput());
|
||||
velocity.add(facing);
|
||||
Location location = kart.getVehicle().getLocation();
|
||||
Block next = location.getBlock();
|
||||
|
||||
if (next.getType() != Material.AIR)
|
||||
{
|
||||
Vector velocity = kart.getVelocity();
|
||||
double length = velocity.length();
|
||||
|
||||
if (next.getRelative(BlockFace.UP).getType() != Material.AIR)
|
||||
{
|
||||
if (length > 0.4)
|
||||
{
|
||||
velocity.multiply(-0.6);
|
||||
}
|
||||
else
|
||||
{
|
||||
velocity.normalize().multiply(-0.4);
|
||||
}
|
||||
|
||||
velocity.setY(0.4);
|
||||
kart.setCrashed(true);
|
||||
}
|
||||
else if (next.getType() == Material.SOUL_SAND)
|
||||
{
|
||||
if (velocity.length() > 0.3)
|
||||
{
|
||||
velocity.multiply(0.95);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
double blockY = location.getY() % 1;
|
||||
double y = 0.42 - (blockY / 3);
|
||||
|
||||
velocity.add(new Vector(0, y, 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void turn(Kart kart)
|
||||
void accelerate(Kart kart)
|
||||
{
|
||||
double velocityLength = kart.getVelocity().length();
|
||||
|
||||
if (velocityLength < 0.1)
|
||||
if (kart.isCrashed() || kart.getFrontWaysInput() <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
float velocityInverse = (float) (2 - velocityLength);
|
||||
float rotation = 3 * kart.getSidewaysInput() * velocityInverse;
|
||||
Vector velocity = kart.getVelocity();
|
||||
|
||||
kart.setYaw(kart.getYaw() - rotation);
|
||||
if (velocity.lengthSquared() == 0)
|
||||
{
|
||||
kart.setVelocity(UtilAlg.getTrajectory(kart.getYaw(), 0).multiply(0.001 * kart.getFrontWaysInput()));
|
||||
}
|
||||
|
||||
Vector acceleration = new Vector(velocity.getX(), 0, velocity.getZ());
|
||||
|
||||
if (acceleration.lengthSquared() > 0)
|
||||
{
|
||||
acceleration.normalize();
|
||||
}
|
||||
|
||||
velocity.add(acceleration.multiply(0.01));
|
||||
}
|
||||
|
||||
void brake(Kart kart)
|
||||
{
|
||||
if (kart.getFrontWaysInput() >= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
kart.getVelocity().multiply(0.95);
|
||||
}
|
||||
|
||||
void turn(Kart kart)
|
||||
{
|
||||
Vector velocity = kart.getVelocity();
|
||||
double speed = velocity.length();
|
||||
|
||||
if (speed < 0.05)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
float velocityInverse = (float) (2 - speed);
|
||||
float newYaw = kart.getYaw() - (3 * kart.getSidewaysInput() * velocityInverse);
|
||||
|
||||
kart.setYaw(newYaw);
|
||||
|
||||
Vector turn = UtilAlg.getTrajectory(newYaw, 0);
|
||||
|
||||
turn.subtract(new Vector(velocity.getX(), 0, velocity.getZ()).normalize()).multiply(0.033);
|
||||
|
||||
velocity.add(turn);
|
||||
|
||||
speed = (speed + (velocity.length() * 3)) / 4;
|
||||
|
||||
velocity.normalize().multiply(speed);
|
||||
}
|
||||
|
||||
void drift(Kart kart)
|
||||
{
|
||||
if (kart.getDriftDirection() != null && kart.getVelocity().lengthSquared() > 0)
|
||||
if (kart.isBoosting())
|
||||
{
|
||||
float power = 0.05F * (kart.getDriftDirection() == DriftDirection.LEFT ? kart.getSidewaysInput() : -kart.getSidewaysInput());
|
||||
|
||||
kart.setDriftPower(kart.getDriftPower() + power);
|
||||
UtilParticle.PlayParticleToAll(ParticleType.FLAME, kart.getParticleLocation(), null, 0.1F, 2, ViewDist.NORMAL);
|
||||
}
|
||||
else if (kart.getDriftPower() > 0.2)
|
||||
|
||||
if (!kart.canBoost())
|
||||
{
|
||||
Vector facing = UtilAlg.getTrajectory(kart.getYaw(), 0).multiply(kart.getVelocity().length() + (kart.getDriftPower() / 2));
|
||||
return;
|
||||
}
|
||||
|
||||
if (kart.getDriftDirection() != null && kart.getVelocity().length() > 0.1)
|
||||
{
|
||||
float power = kart.getDriftPower() + (0.05F * (kart.getDriftDirection() == DriftDirection.LEFT ? kart.getSidewaysInput() : -kart.getSidewaysInput()));
|
||||
|
||||
if (power > 0.3)
|
||||
{
|
||||
UtilParticle.PlayParticleToAll(ParticleType.FIREWORKS_SPARK, kart.getParticleLocation(), null, 0.1F, power > 0.6 ? 2 : 1, ViewDist.NORMAL);
|
||||
}
|
||||
|
||||
kart.setDriftPower(power);
|
||||
}
|
||||
else if (kart.getDriftPower() > 0.3)
|
||||
{
|
||||
Vector facing = UtilAlg.getTrajectory(kart.getYaw(), 0).multiply(0.5 + (kart.getDriftPower() * 0.6));
|
||||
kart.setVelocity(facing);
|
||||
kart.setDriftLast();
|
||||
}
|
||||
|
@ -90,7 +174,7 @@ public class KartController
|
|||
}
|
||||
}
|
||||
|
||||
void applyTopSpeed(Kart kart)
|
||||
void applyTopSpeed(Kart kart, int position)
|
||||
{
|
||||
if (kart.isCrashed())
|
||||
{
|
||||
|
@ -99,14 +183,11 @@ public class KartController
|
|||
|
||||
Vector velocity = kart.getVelocity();
|
||||
double length = velocity.length();
|
||||
double max = kart.isBoosting() ? 1.5 : 0.7;
|
||||
double max = kart.isBoosting() ? 1.5 : 0.7 + (position / 100F);
|
||||
|
||||
if (length > max)
|
||||
{
|
||||
kart.setVelocity(velocity.clone()
|
||||
.setY(0)
|
||||
.normalize()
|
||||
.multiply(max));
|
||||
velocity.multiply(0.98);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ import java.util.Comparator;
|
|||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import net.minecraft.server.v1_8_R3.PacketPlayInSteerVehicle;
|
||||
|
||||
|
@ -14,15 +15,20 @@ import org.bukkit.entity.LivingEntity;
|
|||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
|
||||
import mineplex.core.common.util.C;
|
||||
import mineplex.core.common.util.F;
|
||||
import mineplex.core.common.util.UtilAlg;
|
||||
import mineplex.core.common.util.UtilEnt;
|
||||
import mineplex.core.common.util.UtilMath;
|
||||
import mineplex.core.common.util.UtilPlayer;
|
||||
import mineplex.core.common.util.UtilTextMiddle;
|
||||
import mineplex.core.common.util.UtilTime;
|
||||
import mineplex.core.packethandler.IPacketHandler;
|
||||
import mineplex.core.packethandler.PacketInfo;
|
||||
import mineplex.core.updater.UpdateType;
|
||||
import mineplex.core.updater.event.UpdateEvent;
|
||||
import mineplex.game.nano.NanoManager;
|
||||
import mineplex.game.nano.game.GamePlacements;
|
||||
import mineplex.game.nano.game.GameType;
|
||||
import mineplex.game.nano.game.SoloGame;
|
||||
import mineplex.game.nano.game.event.PlayerGameApplyEvent;
|
||||
|
@ -33,14 +39,47 @@ import mineplex.game.nano.game.games.minekart.KartController.DriftDirection;
|
|||
public class MineKart extends SoloGame implements IPacketHandler
|
||||
{
|
||||
|
||||
private static final int LAPS = 3;
|
||||
|
||||
private int _spawnIndex;
|
||||
|
||||
private final List<KartCheckpoint> _checkpoints, _keyCheckpoints;
|
||||
private Location _faceLocation;
|
||||
|
||||
private final Map<Player, Kart> _karts;
|
||||
private final List<Kart> _positions;
|
||||
private final KartController _controller;
|
||||
|
||||
private final Comparator<Kart> _positionSorter = (o1, o2) ->
|
||||
{
|
||||
boolean o1Complete = o1.getCompletedAt() != 0, o2Complete = o2.getCompletedAt() != 0;
|
||||
|
||||
if (o1Complete && o2Complete)
|
||||
{
|
||||
return Long.compare(o1.getCompletedAt(), o2.getCompletedAt());
|
||||
}
|
||||
else if (o1Complete)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else if (o2Complete)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (o1.getLap() != o2.getLap())
|
||||
{
|
||||
return Integer.compare(o2.getLap(), o1.getLap());
|
||||
}
|
||||
|
||||
if (o1.getLapKeyCheckpoint() != o2.getLapKeyCheckpoint())
|
||||
{
|
||||
return Integer.compare(o2.getLapKeyCheckpoint(), o1.getLapKeyCheckpoint());
|
||||
}
|
||||
|
||||
return Integer.compare(o2.getLapCheckpoint(), o1.getLapCheckpoint());
|
||||
};
|
||||
|
||||
public MineKart(NanoManager manager)
|
||||
{
|
||||
super(manager, GameType.MINEKART, new String[]
|
||||
|
@ -51,13 +90,72 @@ public class MineKart extends SoloGame implements IPacketHandler
|
|||
_checkpoints = new ArrayList<>();
|
||||
_keyCheckpoints = new ArrayList<>();
|
||||
_karts = new HashMap<>();
|
||||
_positions = new ArrayList<>();
|
||||
_controller = new KartController();
|
||||
|
||||
_teamComponent.setAdjustSpawnYaw(false);
|
||||
|
||||
_damageComponent.setDamage(false);
|
||||
|
||||
_playerComponent.setHideParticles(true);
|
||||
|
||||
manager.getPacketHandler().addPacketHandler(this, PacketPlayInSteerVehicle.class);
|
||||
|
||||
_scoreboardComponent.setSidebar((player, scoreboard) ->
|
||||
{
|
||||
scoreboard.writeNewLine();
|
||||
|
||||
scoreboard.write(C.cYellowB + "Racers");
|
||||
|
||||
if (getState() == GameState.Prepare || _positions.isEmpty())
|
||||
{
|
||||
scoreboard.write(getAllPlayers().size() + " Players");
|
||||
}
|
||||
else
|
||||
{
|
||||
scoreboard.writeNewLine();
|
||||
|
||||
boolean hasShownPlayer = false;
|
||||
|
||||
for (int i = 0; i < Math.min(_positions.size(), hasShownPlayer ? 11 : 9); i++)
|
||||
{
|
||||
Kart kart = _positions.get(i);
|
||||
Player other = kart.getDriver();
|
||||
|
||||
if (player.equals(other))
|
||||
{
|
||||
hasShownPlayer = true;
|
||||
}
|
||||
|
||||
scoreboard.write(kart.getLap() + " " + (player.equals(other) ? C.cGreen : (UtilPlayer.isSpectator(other) ? C.cGray + C.Strike : C.cYellow)) + other.getName());
|
||||
}
|
||||
|
||||
if (!hasShownPlayer)
|
||||
{
|
||||
Kart kart = null;
|
||||
|
||||
for (Kart other : _positions)
|
||||
{
|
||||
if (player.equals(other.getDriver()))
|
||||
{
|
||||
kart = other;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (kart != null)
|
||||
{
|
||||
scoreboard.writeNewLine();
|
||||
|
||||
scoreboard.write(kart.getLap() + " " + C.cGreen + player.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
scoreboard.writeNewLine();
|
||||
|
||||
scoreboard.draw();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -99,6 +197,12 @@ public class MineKart extends SoloGame implements IPacketHandler
|
|||
_keyCheckpoints.sort(Comparator.comparingInt(KartCheckpoint::getIndex));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean endGame()
|
||||
{
|
||||
return getAlivePlayers().isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disable()
|
||||
{
|
||||
|
@ -161,6 +265,7 @@ public class MineKart extends SoloGame implements IPacketHandler
|
|||
|
||||
Kart kart = new Kart(player);
|
||||
_karts.put(player, kart);
|
||||
_positions.add(kart);
|
||||
|
||||
_worldComponent.setCreatureAllowOverride(false);
|
||||
}, 1);
|
||||
|
@ -178,6 +283,11 @@ public class MineKart extends SoloGame implements IPacketHandler
|
|||
{
|
||||
LivingEntity vehicle = kart.getVehicle();
|
||||
|
||||
if (!vehicle.isValid())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (vehicle.getPassenger() == null || !vehicle.getPassenger().equals(player))
|
||||
{
|
||||
vehicle.setPassenger(player);
|
||||
|
@ -202,9 +312,25 @@ public class MineKart extends SoloGame implements IPacketHandler
|
|||
|
||||
if (checkpoint.getIndex() == 0 && kart.getLapKeyCheckpoint() == _keyCheckpoints.size() - 1)
|
||||
{
|
||||
kart.setLap(kart.getLap() + 1);
|
||||
int lap = kart.getLap() + 1;
|
||||
|
||||
kart.setLapKeyCheckpoint(0);
|
||||
player.sendMessage("Lap = " + kart.getLap());
|
||||
|
||||
if (lap == LAPS + 1)
|
||||
{
|
||||
kart.complete();
|
||||
announce(F.main(getManager().getName(), F.name(player.getName()) + " completed the race in " + F.time(UtilTime.MakeStr(kart.getCompletedAt() - getStateTime())) + "!"), Sound.FIREWORK_BLAST);
|
||||
addSpectator(player, false, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
kart.setLap(lap);
|
||||
|
||||
boolean finalLap = lap == LAPS;
|
||||
|
||||
UtilTextMiddle.display(C.cYellowB + "Lap " + lap, finalLap ? C.cAquaB + "FINAL LAP" : "", 10, 40, 10, player);
|
||||
player.sendMessage(F.main(getManager().getName(), "Lap " + F.count(lap) + (finalLap ? F.color(" FINAL LAP", C.cAquaB) : "") + "!"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -215,28 +341,27 @@ public class MineKart extends SoloGame implements IPacketHandler
|
|||
if (UtilTime.elapsed(kart.getCrashedAt(), 1000) && UtilEnt.isGrounded(kart.getVehicle()))
|
||||
{
|
||||
kart.setCrashed(false);
|
||||
player.sendMessage("setCrashed(false)");
|
||||
}
|
||||
else
|
||||
{
|
||||
player.sendMessage("canControl = false");
|
||||
canControl = false;
|
||||
}
|
||||
}
|
||||
|
||||
_controller.applyAirDrag(kart);
|
||||
|
||||
_controller.collideBlock(kart);
|
||||
_controller.applyAirResistance(kart);
|
||||
|
||||
// Accelerate
|
||||
if (canControl)
|
||||
{
|
||||
_controller.turn(kart);
|
||||
_controller.accelerate(kart);
|
||||
_controller.brake(kart);
|
||||
_controller.drift(kart);
|
||||
_controller.applyTopSpeed(kart);
|
||||
_controller.turn(kart);
|
||||
_controller.applyTopSpeed(kart, _positions.indexOf(kart));
|
||||
}
|
||||
|
||||
_controller.collideBlock(kart);
|
||||
|
||||
double velocityLength = kart.getVelocity().length();
|
||||
|
||||
location.add(kart.getVelocity());
|
||||
|
@ -248,6 +373,8 @@ public class MineKart extends SoloGame implements IPacketHandler
|
|||
player.setLevel((int) (velocityLength * 100));
|
||||
player.setExp(kart.getDriftPower());
|
||||
});
|
||||
|
||||
_positions.sort(_positionSorter);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
|
@ -264,6 +391,14 @@ public class MineKart extends SoloGame implements IPacketHandler
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public GamePlacements getGamePlacements()
|
||||
{
|
||||
return GamePlacements.fromTeamPlacements(_positions.stream()
|
||||
.map(Kart::getDriver)
|
||||
.collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
public KartCheckpoint getCheckpoint(int index)
|
||||
{
|
||||
return _checkpoints.stream()
|
||||
|
|
Loading…
Reference in New Issue