Clean up collisions a lot

This commit is contained in:
Sam 2018-09-12 23:57:34 +01:00 committed by Alexander Meech
parent 9526bc2eb5
commit 7508eca03f
4 changed files with 210 additions and 18 deletions

View File

@ -1771,4 +1771,22 @@ public class UtilBlock
return false; 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;
}
} }

View File

@ -18,7 +18,7 @@ public class Kart
private int _lap, _lapCheckpoint, _lapKeyCheckpoint; private int _lap, _lapCheckpoint, _lapKeyCheckpoint;
private Vector _velocity; private Vector _velocity, _offset;
private float _frontWaysInput, _sidewaysInput; private float _frontWaysInput, _sidewaysInput;
private float _yaw; private float _yaw;
private DriftDirection _driftDirection; private DriftDirection _driftDirection;
@ -28,6 +28,8 @@ public class Kart
private boolean _crashed; private boolean _crashed;
private long _crashedAt; private long _crashedAt;
private boolean _resetting;
private long _boostAt; private long _boostAt;
private long _completedAt; private long _completedAt;
@ -50,6 +52,7 @@ public class Kart
_lap = 1; _lap = 1;
_velocity = new Vector(); _velocity = new Vector();
_offset = new Vector();
_yaw = location.getYaw(); _yaw = location.getYaw();
} }
@ -114,6 +117,11 @@ public class Kart
return _velocity; return _velocity;
} }
public Vector getOffset()
{
return _offset;
}
public void setInput(float frontWaysInput, float sidewaysInput) public void setInput(float frontWaysInput, float sidewaysInput)
{ {
_frontWaysInput = frontWaysInput; _frontWaysInput = frontWaysInput;
@ -204,6 +212,16 @@ public class Kart
return _crashedAt; return _crashedAt;
} }
public void setResetting(boolean resetting)
{
_resetting = resetting;
}
public boolean isResetting()
{
return _resetting;
}
public void complete() public void complete()
{ {
_completedAt = System.currentTimeMillis(); _completedAt = System.currentTimeMillis();

View File

@ -7,9 +7,11 @@ import org.bukkit.block.BlockFace;
import org.bukkit.util.Vector; import org.bukkit.util.Vector;
import mineplex.core.common.util.UtilAlg; import mineplex.core.common.util.UtilAlg;
import mineplex.core.common.util.UtilBlock;
import mineplex.core.common.util.UtilParticle; import mineplex.core.common.util.UtilParticle;
import mineplex.core.common.util.UtilParticle.ParticleType; import mineplex.core.common.util.UtilParticle.ParticleType;
import mineplex.core.common.util.UtilParticle.ViewDist; import mineplex.core.common.util.UtilParticle.ViewDist;
import mineplex.core.world.MineplexWorld;
public class KartController public class KartController
{ {
@ -41,50 +43,76 @@ public class KartController
} }
Location location = kart.getVehicle().getLocation(); Location location = kart.getVehicle().getLocation();
Block next = location.getBlock(); Block block = location.getBlock();
Block down = block.getRelative(BlockFace.DOWN);
Vector velocity = kart.getVelocity(); 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); velocity.multiply(1.1);
kart.setBoost(); 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(); double length = velocity.length();
if (next.getRelative(BlockFace.UP).getType() != Material.AIR) if (block.getRelative(BlockFace.UP).getType() != Material.AIR)
{ {
if (length > 0.4) if (length > 0.4)
{ {
velocity.multiply(-0.6); velocity.multiply(-0.6);
velocity.setY(0.4);
} }
else 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); kart.setCrashed(true);
} }
else if (next.getType() == Material.SOUL_SAND)
{
if (velocity.length() > 0.3)
{
velocity.multiply(0.95);
}
}
else else
{ {
Vector offset = kart.getOffset();
double blockY = location.getY() % 1; 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) static void accelerate(Kart kart)
{ {
if (kart.isCrashed() || kart.getFrontWaysInput() <= 0) if (kart.isCrashed() || kart.getFrontWaysInput() <= 0)

View File

@ -5,26 +5,44 @@ import java.util.Comparator;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import net.minecraft.server.v1_8_R3.PacketPlayInSteerVehicle; 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.Location;
import org.bukkit.Material;
import org.bukkit.Sound; import org.bukkit.Sound;
import org.bukkit.entity.LivingEntity; import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; 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.C;
import mineplex.core.common.util.F; import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilAlg; import mineplex.core.common.util.UtilAlg;
import mineplex.core.common.util.UtilEnt; import mineplex.core.common.util.UtilEnt;
import mineplex.core.common.util.UtilFirework;
import mineplex.core.common.util.UtilMath; 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.UtilPlayer;
import mineplex.core.common.util.UtilShapes;
import mineplex.core.common.util.UtilTextMiddle; import mineplex.core.common.util.UtilTextMiddle;
import mineplex.core.common.util.UtilTime; import mineplex.core.common.util.UtilTime;
import mineplex.core.itemstack.ItemBuilder;
import mineplex.core.packethandler.IPacketHandler; import mineplex.core.packethandler.IPacketHandler;
import mineplex.core.packethandler.PacketInfo; import mineplex.core.packethandler.PacketInfo;
import mineplex.core.recharge.Recharge;
import mineplex.core.updater.UpdateType; import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent; import mineplex.core.updater.event.UpdateEvent;
import mineplex.game.nano.NanoManager; 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 int LAPS = 3;
private static final long RESET_KART_COOLDOWN = TimeUnit.SECONDS.toMillis(10);
private int _spawnIndex; private int _spawnIndex;
@ -79,6 +98,11 @@ public class MineKart extends SoloGame implements IPacketHandler
return Integer.compare(o2.getLapCheckpoint(), o1.getLapCheckpoint()); 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) public MineKart(NanoManager manager)
{ {
super(manager, GameType.MINEKART, new String[] super(manager, GameType.MINEKART, new String[]
@ -179,6 +203,13 @@ public class MineKart extends SoloGame implements IPacketHandler
return; 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); KartCheckpoint checkpoint = new KartCheckpoint(locations.get(0), locations.get(1), index, args.length > 2);
_checkpoints.add(checkpoint); _checkpoints.add(checkpoint);
@ -265,6 +296,8 @@ public class MineKart extends SoloGame implements IPacketHandler
_karts.put(player, kart); _karts.put(player, kart);
_positions.add(kart); _positions.add(kart);
player.getInventory().setItem(8, _resetItem);
_worldComponent.setCreatureAllowOverride(false); _worldComponent.setCreatureAllowOverride(false);
}, 1); }, 1);
} }
@ -291,6 +324,11 @@ public class MineKart extends SoloGame implements IPacketHandler
vehicle.setPassenger(player); vehicle.setPassenger(player);
} }
if (kart.isResetting())
{
return;
}
Location location = vehicle.getLocation(); Location location = vehicle.getLocation();
KartCheckpoint checkpoint = getCheckpoint(location); KartCheckpoint checkpoint = getCheckpoint(location);
@ -317,6 +355,10 @@ public class MineKart extends SoloGame implements IPacketHandler
if (lap == LAPS + 1) if (lap == LAPS + 1)
{ {
kart.complete(); 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); 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); addSpectator(player, false, true);
} }
@ -348,7 +390,6 @@ public class MineKart extends SoloGame implements IPacketHandler
KartController.applyAirResistance(kart); KartController.applyAirResistance(kart);
// Accelerate
if (canControl) if (canControl)
{ {
KartController.accelerate(kart); KartController.accelerate(kart);
@ -360,13 +401,21 @@ public class MineKart extends SoloGame implements IPacketHandler
KartController.collideBlock(kart); KartController.collideBlock(kart);
if (vehicle.getFallDistance() > 20 || KartController.collideOutOfBounds(kart, _mineplexWorld))
{
resetKart(kart);
return;
}
double velocityLength = kart.getVelocity().length(); double velocityLength = kart.getVelocity().length();
location.add(kart.getVelocity()); location.add(kart.getVelocity()).add(kart.getOffset());
location.setDirection(kart.getVelocity()); location.setDirection(kart.getVelocity());
UtilEnt.setPosition(vehicle, location); UtilEnt.setPosition(vehicle, location);
UtilEnt.CreatureLook(vehicle, kart.getYaw()); UtilEnt.CreatureLook(vehicle, kart.getYaw());
kart.getOffset().multiply(0);
location.getWorld().playSound(location, Sound.PIG_IDLE, (float) (.1 + velocityLength / 2), (float) (.5 + velocityLength)); location.getWorld().playSound(location, Sound.PIG_IDLE, (float) (.1 + velocityLength / 2), (float) (.5 + velocityLength));
player.setLevel((int) (velocityLength * 100)); player.setLevel((int) (velocityLength * 100));
player.setExp(kart.getDriftPower()); player.setExp(kart.getDriftPower());
@ -375,6 +424,60 @@ public class MineKart extends SoloGame implements IPacketHandler
_positions.sort(_positionSorter); _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<Location> 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 @EventHandler
public void playerOut(PlayerStateChangeEvent event) public void playerOut(PlayerStateChangeEvent event)
{ {
@ -412,4 +515,29 @@ public class MineKart extends SoloGame implements IPacketHandler
.findFirst() .findFirst()
.orElse(null); .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)
{
}
}
} }