diff --git a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilBlock.java b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilBlock.java index 1458c6698..8e3176994 100644 --- a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilBlock.java +++ b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilBlock.java @@ -1771,4 +1771,22 @@ public class UtilBlock return false; } + public static boolean isSlab(Block block) + { + return isSlab(block.getType()); + } + + public static boolean isSlab(Material type) + { + switch (type) + { + case STEP: + case WOOD_STEP: + case STONE_SLAB2: + return true; + } + + return false; + } + } diff --git a/Plugins/Mineplex.Game.Nano/src/mineplex/game/nano/game/games/minekart/Kart.java b/Plugins/Mineplex.Game.Nano/src/mineplex/game/nano/game/games/minekart/Kart.java index 44185ac3b..e5c4a343d 100644 --- a/Plugins/Mineplex.Game.Nano/src/mineplex/game/nano/game/games/minekart/Kart.java +++ b/Plugins/Mineplex.Game.Nano/src/mineplex/game/nano/game/games/minekart/Kart.java @@ -18,7 +18,7 @@ public class Kart private int _lap, _lapCheckpoint, _lapKeyCheckpoint; - private Vector _velocity; + private Vector _velocity, _offset; private float _frontWaysInput, _sidewaysInput; private float _yaw; private DriftDirection _driftDirection; @@ -28,6 +28,8 @@ public class Kart private boolean _crashed; private long _crashedAt; + private boolean _resetting; + private long _boostAt; private long _completedAt; @@ -50,6 +52,7 @@ public class Kart _lap = 1; _velocity = new Vector(); + _offset = new Vector(); _yaw = location.getYaw(); } @@ -114,6 +117,11 @@ public class Kart return _velocity; } + public Vector getOffset() + { + return _offset; + } + public void setInput(float frontWaysInput, float sidewaysInput) { _frontWaysInput = frontWaysInput; @@ -204,6 +212,16 @@ public class Kart return _crashedAt; } + public void setResetting(boolean resetting) + { + _resetting = resetting; + } + + public boolean isResetting() + { + return _resetting; + } + public void complete() { _completedAt = System.currentTimeMillis(); diff --git a/Plugins/Mineplex.Game.Nano/src/mineplex/game/nano/game/games/minekart/KartController.java b/Plugins/Mineplex.Game.Nano/src/mineplex/game/nano/game/games/minekart/KartController.java index 2a203fb6a..4defecbdd 100644 --- a/Plugins/Mineplex.Game.Nano/src/mineplex/game/nano/game/games/minekart/KartController.java +++ b/Plugins/Mineplex.Game.Nano/src/mineplex/game/nano/game/games/minekart/KartController.java @@ -7,9 +7,11 @@ import org.bukkit.block.BlockFace; import org.bukkit.util.Vector; import mineplex.core.common.util.UtilAlg; +import mineplex.core.common.util.UtilBlock; import mineplex.core.common.util.UtilParticle; import mineplex.core.common.util.UtilParticle.ParticleType; import mineplex.core.common.util.UtilParticle.ViewDist; +import mineplex.core.world.MineplexWorld; public class KartController { @@ -41,50 +43,76 @@ public class KartController } Location location = kart.getVehicle().getLocation(); - Block next = location.getBlock(); + Block block = location.getBlock(); + Block down = block.getRelative(BlockFace.DOWN); Vector velocity = kart.getVelocity(); + boolean collision = block.getType() != Material.AIR; - if (next.getRelative(BlockFace.DOWN).getType() == Material.GOLD_BLOCK) + if (down.getType() == Material.GOLD_BLOCK) { velocity.multiply(1.1); kart.setBoost(); } + else if (down.getType() == Material.SAND) + { + if (velocity.length() > 0.2) + { + velocity.multiply(0.95); + } + } + else if (block.getType() == Material.SOUL_SAND) + { + if (velocity.length() > 0.3) + { + velocity.multiply(0.95); + } - if (next.getType() != Material.AIR) + collision = false; + } + + if (collision) { double length = velocity.length(); - if (next.getRelative(BlockFace.UP).getType() != Material.AIR) + if (block.getRelative(BlockFace.UP).getType() != Material.AIR) { if (length > 0.4) { velocity.multiply(-0.6); + velocity.setY(0.4); } else { - velocity.normalize().multiply(-0.4); + velocity = UtilAlg.getTrajectory(kart.getYaw(), 0).multiply(-0.4); + velocity.setY(0.4); + + kart.setVelocity(velocity); } - velocity.setY(0.4); kart.setCrashed(true); } - else if (next.getType() == Material.SOUL_SAND) - { - if (velocity.length() > 0.3) - { - velocity.multiply(0.95); - } - } else { + Vector offset = kart.getOffset(); double blockY = location.getY() % 1; - double y = 0.42 - (blockY / 3); - velocity.add(new Vector(0, y, 0)); + if (UtilBlock.isSlab(block) && blockY < 0.5) + { + offset.add(new Vector(0, 0.51, 0)); + } + else + { + offset.add(new Vector(0, 1.01 - blockY, 0)); + } } } } + static boolean collideOutOfBounds(Kart kart, MineplexWorld world) + { + return !UtilAlg.inBoundingBox(kart.getVehicle().getLocation(), world.getMin(), world.getMax()); + } + static void accelerate(Kart kart) { if (kart.isCrashed() || kart.getFrontWaysInput() <= 0) diff --git a/Plugins/Mineplex.Game.Nano/src/mineplex/game/nano/game/games/minekart/MineKart.java b/Plugins/Mineplex.Game.Nano/src/mineplex/game/nano/game/games/minekart/MineKart.java index af2766b7d..f0e0df622 100644 --- a/Plugins/Mineplex.Game.Nano/src/mineplex/game/nano/game/games/minekart/MineKart.java +++ b/Plugins/Mineplex.Game.Nano/src/mineplex/game/nano/game/games/minekart/MineKart.java @@ -5,26 +5,44 @@ import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; import net.minecraft.server.v1_8_R3.PacketPlayInSteerVehicle; +import org.bukkit.Color; +import org.bukkit.FireworkEffect; +import org.bukkit.FireworkEffect.Type; import org.bukkit.Location; +import org.bukkit.Material; import org.bukkit.Sound; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; +import org.bukkit.event.block.Action; +import org.bukkit.event.player.AsyncPlayerChatEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.util.Vector; 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.UtilFirework; import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilParticle; +import mineplex.core.common.util.UtilParticle.ParticleType; +import mineplex.core.common.util.UtilParticle.ViewDist; import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilShapes; import mineplex.core.common.util.UtilTextMiddle; import mineplex.core.common.util.UtilTime; +import mineplex.core.itemstack.ItemBuilder; import mineplex.core.packethandler.IPacketHandler; import mineplex.core.packethandler.PacketInfo; +import mineplex.core.recharge.Recharge; import mineplex.core.updater.UpdateType; import mineplex.core.updater.event.UpdateEvent; import mineplex.game.nano.NanoManager; @@ -40,6 +58,7 @@ public class MineKart extends SoloGame implements IPacketHandler { private static final int LAPS = 3; + private static final long RESET_KART_COOLDOWN = TimeUnit.SECONDS.toMillis(10); private int _spawnIndex; @@ -79,6 +98,11 @@ public class MineKart extends SoloGame implements IPacketHandler return Integer.compare(o2.getLapCheckpoint(), o1.getLapCheckpoint()); }; + private final ItemStack _resetItem = new ItemBuilder(Material.BARRIER) + .setTitle(C.cRedB + "Reset Kart") + .addLore("Click to reset your kart", "back on the track.") + .build(); + public MineKart(NanoManager manager) { super(manager, GameType.MINEKART, new String[] @@ -179,6 +203,13 @@ public class MineKart extends SoloGame implements IPacketHandler return; } + Location a = locations.get(0), b = locations.get(1); + + if (a.getY() == b.getY()) + { + b.add(0, 1, 0); + } + KartCheckpoint checkpoint = new KartCheckpoint(locations.get(0), locations.get(1), index, args.length > 2); _checkpoints.add(checkpoint); @@ -265,6 +296,8 @@ public class MineKart extends SoloGame implements IPacketHandler _karts.put(player, kart); _positions.add(kart); + player.getInventory().setItem(8, _resetItem); + _worldComponent.setCreatureAllowOverride(false); }, 1); } @@ -291,6 +324,11 @@ public class MineKart extends SoloGame implements IPacketHandler vehicle.setPassenger(player); } + if (kart.isResetting()) + { + return; + } + Location location = vehicle.getLocation(); KartCheckpoint checkpoint = getCheckpoint(location); @@ -317,6 +355,10 @@ public class MineKart extends SoloGame implements IPacketHandler if (lap == LAPS + 1) { kart.complete(); + UtilFirework.launchFirework(location, FireworkEffect.builder() + .with(Type.BALL_LARGE) + .withColor(Color.YELLOW) + .build(), null, 1); 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); } @@ -348,7 +390,6 @@ public class MineKart extends SoloGame implements IPacketHandler KartController.applyAirResistance(kart); - // Accelerate if (canControl) { KartController.accelerate(kart); @@ -360,13 +401,21 @@ public class MineKart extends SoloGame implements IPacketHandler KartController.collideBlock(kart); + if (vehicle.getFallDistance() > 20 || KartController.collideOutOfBounds(kart, _mineplexWorld)) + { + resetKart(kart); + return; + } + double velocityLength = kart.getVelocity().length(); - location.add(kart.getVelocity()); + location.add(kart.getVelocity()).add(kart.getOffset()); location.setDirection(kart.getVelocity()); UtilEnt.setPosition(vehicle, location); UtilEnt.CreatureLook(vehicle, kart.getYaw()); + kart.getOffset().multiply(0); + location.getWorld().playSound(location, Sound.PIG_IDLE, (float) (.1 + velocityLength / 2), (float) (.5 + velocityLength)); player.setLevel((int) (velocityLength * 100)); player.setExp(kart.getDriftPower()); @@ -375,6 +424,60 @@ public class MineKart extends SoloGame implements IPacketHandler _positions.sort(_positionSorter); } + private void resetKart(Kart kart) + { + if (kart == null || kart.isResetting()) + { + return; + } + + kart.setResetting(true); + + UtilTextMiddle.display(C.cRedB + "Resetting!", null, 0, 50, 10, kart.getDriver()); + + LivingEntity vehicle = kart.getVehicle(); + Location location = vehicle.getLocation(); + List points = UtilShapes.getLinesDistancedPoints(location, getCheckpoint(kart.getLapCheckpoint()).getCenter().add(0, 3, 0), 0.5); + + getManager().runSyncTimer(new BukkitRunnable() + { + @Override + public void run() + { + if (points.isEmpty()) + { + kart.setVelocity(new Vector()); + kart.setResetting(false); + cancel(); + return; + } + + Location location = points.remove(0); + location.setYaw(location.getYaw()); + UtilEnt.setPosition(vehicle, location); + UtilParticle.PlayParticleToAll(ParticleType.CLOUD, location, 0.3F, 0.3F, 0.3F, 0, 5, ViewDist.NORMAL); + } + }, 0, 1); + } + + @EventHandler + public void playerInteract(PlayerInteractEvent event) + { + if (event.getAction() == Action.PHYSICAL || !isLive()) + { + return; + } + + Player player = event.getPlayer(); + + if (!_resetItem.equals(player.getItemInHand()) || !Recharge.Instance.use(player, "Reset Kart", RESET_KART_COOLDOWN, true, true)) + { + return; + } + + resetKart(_karts.get(player)); + } + @EventHandler public void playerOut(PlayerStateChangeEvent event) { @@ -412,4 +515,29 @@ public class MineKart extends SoloGame implements IPacketHandler .findFirst() .orElse(null); } + + @EventHandler + public void playerChat(AsyncPlayerChatEvent event) + { + Player player = event.getPlayer(); + Kart kart = _karts.get(player); + + if (kart == null) + { + return; + } + + try + { + int index = Integer.parseInt(event.getMessage()); + player.leaveVehicle(); + + UtilEnt.setPosition(kart.getVehicle(), getCheckpoint(index).getCenter()); + player.sendMessage("Moving kart to " + index); + } + catch (NumberFormatException ex) + { + + } + } }