Changing a players walk speed as well as jump height.

Discussion in 'Plugin Development' started by zeeveener, Oct 4, 2012.

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

    zeeveener

    I am working on creating a plugin that allows you to run faster and jump higher depending on what boots you have on. I have the basics down I think, but I run into a problem once I start testing it.

    I use the following code to change the speed. It is placed inside a PlayerMoveEvent:
    Code:java
    1. Vector dir = player.getLocation().getDirection().multiply(0.7);
    2. player.setVelocity(dir);

    However, that causes a loop to run which basically auto-runs the player in the very rough direction that I look at. I don't want that...

    I tried using the following code instead of the above:
    Code:java
    1. Vector current = player.getVelocity();
    2. Vector dir = current.multiply(0.7);
    3. player.setVelocity(dir);

    I tried entering 0.7 and 1.25 in the above one but both seem to slow the movement speed down the same amount. They don't cause the loop though...

    Can anyone help me figure this out? And after that we will be moving onto the jump height...

    For any who "require" the full PlayerMoveEvent, here you go.
    Show Spoiler
    Code:java
    1. @EventHandler
    2. public void onMove(PlayerMoveEvent e){
    3. Player p = e.getPlayer();
    4. if(!as.isEnabled() || !SkillManager.playerHasSkill(p, as)){
    5. return;
    6. }
    7. Location to = e.getTo();
    8. Location from = e.getFrom();
    9. if(from.getBlockY() < to.getBlockY()){
    10. ExperienceManager.addExpFast(p, as, ac.exp.get("Jump"));
    11. if(ac.getBooleanValue("SuperJump.Enabled", false) && ExperienceManager.getLevel(p, as) >= ac.getIntegerValue("SuperJump.Level", 10)){
    12. if(ac.getBooleanValue("SuperJump.MustWearChainBoots", true)){
    13. if(p.getInventory().getBoots() != null && p.getInventory().getBoots().getType() == Material.CHAINMAIL_BOOTS){
    14. double y = ac.getDoubleValue("SuperJump.Modifier", 0.75);
    15. int x = -2;
    16. int z = -2;
    17. Vector v = new Vector();
    18. v.setX(x*0/10);
    19. v.setY(y);
    20. v.setZ(z*0/10);
    21. p.setVelocity(v);
    22. }
    23. }else{
    24. double y = ac.getDoubleValue("SuperJump.Modifier", 0.75);
    25. int x = -2;
    26. int z = -2;
    27. Vector v = new Vector();
    28. v.setX(x*0/10);
    29. v.setY(y);
    30. v.setZ(z*0/10);
    31. p.setVelocity(v);
    32. }
    33. }
    34. }
    35. if(ac.getBooleanValue("SuperSpeed.Enabled", false) && ExperienceManager.getLevel(p, as) >= ac.getIntegerValue("SuperSpeed.Level", 10)){
    36. if(p.getInventory().getBoots() != null && p.getInventory().getBoots().getType() == Material.LEATHER_BOOTS){
    37. Vector cur = p.getVelocity();
    38. Vector dir = cur.multiply(ac.getDoubleValue("SuperSpeed.Modifiers.LeatherBoots", 1.25));
    39. p.setVelocity(dir);
    40. }else if(p.getInventory().getBoots() != null && p.getInventory().getBoots().getType() == Material.IRON_BOOTS){
    41. Vector dir = p.getLocation().getDirection().multiply(ac.getDoubleValue("SuperSpeed.Modifiers.IronBoots", 0.8));
    42. p.setVelocity(dir);
    43. }else if(p.getInventory().getBoots() != null && p.getInventory().getBoots().getType() == Material.GOLD_BOOTS){
    44. Vector dir = p.getLocation().getDirection().multiply(ac.getDoubleValue("SuperSpeed.Modifiers.GoldBoots", 0.9));
    45. p.setVelocity(dir);
    46. }else if(p.getInventory().getBoots() != null && p.getInventory().getBoots().getType() == Material.DIAMOND_BOOTS){
    47. Vector dir = p.getLocation().getDirection().multiply(ac.getDoubleValue("SuperSpeed.Modifiers.DiamondBoots", 1.0));
    48. p.setVelocity(dir);
    49. }else{
    50. return;
    51. }
    52. }else{
    53. return;
    54. }
    55. }
     
  2. Offline

    bergerkiller

    zeeveener
    Yep, the same problems I had when I tried to do it. You actually need a sort of input from the player, as the player move event does not accurately show what the player 'wants'. You can look at the old and new velocity:
    • If it became more or is equal, keep running
    • If it became less, stop running and stop changing the velocity
    This way, when a player stops holding the 'W' key, the velocity should become less and would allow you to stop running. If velocity fails, try measuring the distance using the from and to location. If this distance becomes more/equal/less you can deal with it too.

    You have to map the velocity in a hashmap then, though.
     
  3. Offline

    Icyene

    This may or may not be helpful, but if it works it would be better than listening to a PlayerMove:

    Use reflection to get the variable 'bw' inside entity. Get EntityPlayer from org.bukkit.player, and call bw.set(ePlayer, 0.8). bw is the variable for speed. Not sure if it applies for all entities, or if it can only be called on init, but it would be worth a shot.
     
  4. Offline

    zeeveener

    Your method would require some sort of time measurement though right as the PlayerMoveEvent is fired even when a player merely turns around. I thought about it but I am not sure how I could reliably measure a set distance. Simply because a player can move forward, and backward, sideways and vertical.
    Also, how do I record what a player is pressing? Is there an event for that?

    We are diving into unknown territory for me with that. Could you please give me a quick example of how I would alter a "bw" for an entity?
     
  5. Offline

    bergerkiller

    zeeveener
    There is no event, but player move events are never fired more than once per tick. It is enough to keep track of the old and new values, as the time interval is always one tick. If it is not one tick, it doesn't matter, as the player is standing still then.

    And no, player movement is entirely controlled by the client. It sends player move update packets. Technically, players do not have a velocity, because they simply teleport from point to point. That is why I mentioned using the offset or distance between from and to. I recommend not using getVelocity on the player; it just doesn't work.
     
  6. Offline

    Icyene

    This should work for most entities, not sure if it will work for players, as bergerkiller stated.

    Code:Java
    1.  
    2. Field speed = net.minecraft.server.Entity.class.getDeclaredField("bw");
    3. ....
    4. double fastness = 0.8; //Not sure if bw is a double or not
    5. EntityPlayer enp = yourPlayer.getHandle();
    6. speed.set(enp, speed); //Use reflection to set it for the EntityPlayer
    7.  


    I cannot guarantee this will work, but it might.
     
  7. Offline

    zeeveener

    It doesn't because there is no field bw, Bw, bW, BW in Entity or EntityPlayer. I listed them all out and there actually isn't, but there is an int in the EntityPlayer. I have to add a cast to the player object:
    Code:java
    1. EntityPlayer enp = (EntityPlayer) p;
    2. int bw = enp.bW;


    EDIT: CraftPlayer cannot be cast to EntityPlayer

    Bumping so I can get some more help.

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: May 29, 2016
  8. Offline

    Icyene

    Ah, bw is only in things that extends EntityCreature.... There is

    Code:Java
    1.  
    2. Player p;
    3. p.setWalkSpeed(float);
    4.  


    though. In the normal Bukkit API, too. There is also a .setFlightSpeed.
     
  9. Offline

    JjPwN1

    Code:
    player.addPotionEffect(new PotionEffect(PotionEffectType.SPEED, 200, 1));
    //200 = Ticks he has speed potion
    //1 = Level of potion
    player.addPotionEffect(new PotionEffect(PotionEffectType.JUMP, 200, 1));
     
Thread Status:
Not open for further replies.

Share This Page