Solved Any tips on preventing minecart derail during high speed turns?

Discussion in 'Plugin Development' started by Surfdudeboy, May 31, 2014.

Thread Status:
Not open for further replies.
  1. Offline

    Surfdudeboy

    I'm using the following code to increase the max speed of a minecart that passes over a powered rail.
    Code:java
    1. @EventHandler
    2. public void onCartMove(VehicleMoveEvent event){
    3. Vehicle vehicle = event.getVehicle();
    4. if(vehicle.getPassenger() != null && vehicle instanceof org.bukkit.entity.Minecart){
    5. Entity passenger = vehicle.getPassenger();
    6. org.bukkit.entity.Minecart cart = (org.bukkit.entity.Minecart) event.getVehicle();
    7. Location loc = cart.getLocation();
    8. Vector vel = cart.getVelocity();
    9. if(loc.getBlock().getType() == Material.POWERED_RAIL){
    10. cart.setMaxSpeed(1.0D); // default maxspeed is 0.4D
    11. vel.multiply(1.25);
    12. cart.setVelocity(vel);
    13. }
    14. }
    15. }
    16. }

    Unfortunately, whenever the speedy minecart goes around a turn it derails at a 45 degree angle. I've tried for a few hours to fix it with minimal success. Does anyone know how to solve this issue? It would be very much appreciated :)
     
  2. Offline

    Bammerbom

    Surfdudeboy Did you already try to cancel VehicleDestroyEvent?
     
  3. Offline

    Surfdudeboy

    Bammerbom
    I haven't. I'll try that although I have my doubts.
    ---
    Edit: No dice.
     
  4. Offline

    Phasesaber

    In one of the recent snapshots, minecarts were sped up a ton (which got removed cause everyone hated it), and people made special turns that helped it not derail, I'd look at some of those designs.
     
  5. Offline

    Necrodoom

    The only thing I can think of is lowering the max speed, since getting when a minecart derails is quite difficult.
     
  6. Offline

    Surfdudeboy

    Necrodoom Phasesaber Bammerbom
    I think I found the solution: Detect if a hill/curve is near and then slow down the cart. I'll post code after I tweak it to perfection.
     
  7. Surfdudeboy
    The minecart derailing feature has been removed in Minecraft 1.8
     
  8. Offline

    Surfdudeboy

    The Gaming Grunts
    Are you saying that in 1.8 minecarts wont derail at high speed? :D

    Nevermind, you were mistaken. Communication error. I'm talking about 1.7.9 . The extra speed feature from 14w11a is being undone because the Engine can't handle it. (You don't say.) The derailing bug will persist in 1.8.
     
  9. Offline

    Surfdudeboy

    The Gaming Grunts@Bammerbom Phasesaber Necrodoom
    Ah. now we are on the same page.

    Anyways here is how I am preventing my high speed carts from flying off corners or stopping on hills:
    Code:java
    1. static Main plugin;
    2. private HashMap<UUID,Double> previousSpeed = new HashMap<UUID,Double>();
    3. private ArrayList<UUID> hasNotPassed = new ArrayList<UUID>();
    4. private final double MAX_SPEED = 3D;
    5. private final double BOOSTER_MULTIPLIER = 1.25D;
    6. @EventHandler
    7. public void onCartMove(VehicleMoveEvent event){
    8. Vehicle vehicle = event.getVehicle();
    9. if(vehicle.getPassenger() != null && vehicle instanceof org.bukkit.entity.Minecart){ //Is a minecart and has a pasenger?
    10. org.bukkit.entity.Minecart cart = (org.bukkit.entity.Minecart) event.getVehicle();
    11. Location loc = cart.getLocation();
    12. Vector vel = cart.getVelocity();
    13. Rails rail = null;
    14. try{ rail = (Rails)cart.getLocation().getBlock().getState().getData();
    15. }catch (ClassCastException e){return;}
    16. UUID id = cart.getUniqueId();
    17. Double currentSpeed = vel.length();
    18. if(rail.getItemType() == Material.POWERED_RAIL && !hasNotPassed.contains(id)){ //Makes carts go fast. Checks for being slowed down.
    19. cart.setMaxSpeed(MAX_SPEED);
    20. vel.multiply(BOOSTER_MULTIPLIER);
    21. cart.setVelocity(vel);
    22. }
    23. Double pSpeed = null;
    24. try {
    25. pSpeed = previousSpeed.get(id);
    26. pSpeed = null;}
    27. Location testLoc = loc;
    28. int dist = (int) MAX_SPEED;
    29. if(!hasNotPassed.contains(id)){
    30. for(int i = 1; i<dist ; i++){
    31. testLoc.add(vel.normalize().multiply(i));
    32. Rails testRail;
    33. try{
    34. testRail = (Rails) testLoc.getBlock().getState().getData();
    35. }catch (ClassCastException e){
    36. break;}
    37.  
    38. if(testRail != null){
    39.  
    40. if((testRail.isCurve() || testRail.isOnSlope())){// all of this code tests if there is a curve or slope slightly ahead of the cart.
    41. previousSpeed.put(id, currentSpeed);
    42. hasNotPassed.add(id);
    43. cart.setMaxSpeed(0.4D);
    44. return;
    45. }
    46. }
    47. }
    48. }
    49. if(rail.isCurve() || rail.isOnSlope()){//when it passes over the hill or curve, flag it as having passed it.
    50. hasNotPassed.remove(id);
    51. cart.setMaxSpeed(0.4D);
    52. }
    53.  
    54. else if(pSpeed != null && !hasNotPassed.contains(id) && !rail.isCurve() && !rail.isOnSlope()){ //If it is passed, set it back to its origional speed.
    55. cart.setMaxSpeed(MAX_SPEED);
    56. Vector newVel = cart.getVelocity().normalize().multiply(pSpeed);
    57. cart.setVelocity(newVel);
    58. previousSpeed.remove(id);
    59. }
    60. }
    61. }


    The only issue is that it is fairly costly in terms of CPU cycles. I went from 1% CPU use to 3% as I rode a rail. I never derail though ^-^

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jul 1, 2016
  10. Offline

    gabizou

    Surfdudeboy maybe have a quick check if the block change is >1? I don't know the VehicleMoveEvent itself, but it saves time when handling PlayerMoveEvent.
     
  11. Offline

    Surfdudeboy

Thread Status:
Not open for further replies.

Share This Page