Finish up MineKart

This commit is contained in:
Sam 2018-09-12 17:35:33 +01:00 committed by Alexander Meech
parent e716c9b2ea
commit 4b09c66cdc
4 changed files with 300 additions and 57 deletions

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}
}

View File

@ -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()