[Still Not Solved] Teleport horses with you if you are sitting on them?

Discussion in 'Spigot Plugin Development' started by TheMrJezza, May 30, 2015.

  1. A few months ago I put in a plugin request at bukkit.org for a plugin that would teleport the horse a player is sitting on when that player teleports anywhere. So if a player did /home for example while they were sitting on a horse, that player would teleport home and they would be sitting on the horse because the horse would have teleported with them. 2 people tried to make this plugin for me, both versions didn't work. Since then I have gotten some knowledge at making plugins so I tried to make this plugin myself. But just like the other versions, it didn't work. I can't see any errors in my code that would make this fail, but then again, my coding knowledge is still very little. Also there have been 3 attempts at this and none of them worked. So I'm going to put my code on this thread, if anyone can see why it isn't working or knows a better way to achieve this, please tell me.
    Thank you -TheMrJezza

    Code (Text):
    package me.TheMrJezza;

    import org.bukkit.Bukkit;
    import org.bukkit.entity.EntityType;
    import org.bukkit.entity.Horse;
    import org.bukkit.entity.Player;
    import org.bukkit.event.EventHandler;
    import org.bukkit.event.Listener;
    import org.bukkit.event.player.PlayerTeleportEvent;
    import org.bukkit.plugin.java.JavaPlugin;

    public class HorseTP extends JavaPlugin implements Listener {
        public void onEnable() {
            Bukkit.getServer().getPluginManager().registerEvents(this, this);
        }

        @EventHandler
        public void playerTeleport(PlayerTeleportEvent e) {
            Player player = (Player) e.getPlayer();
            Horse horse = (Horse) player.getVehicle();
            if (player.isInsideVehicle()) {
                if (player.getVehicle().getType() == EntityType.HORSE) {
                    if ((player.hasPermission("horsetp.use")) || ((player.isOp()))) {
                        if ((e.getCause() == PlayerTeleportEvent.TeleportCause.END_PORTAL)
                                || (e.getCause() == PlayerTeleportEvent.TeleportCause.ENDER_PEARL)
                                || (e.getCause() == PlayerTeleportEvent.TeleportCause.NETHER_PORTAL)
                                || (e.getCause() == PlayerTeleportEvent.TeleportCause.COMMAND)) {
                            player.sendMessage("It Worked!");
                            player.teleport(e.getTo());
                            horse.teleport(player);
                            horse.setOwner(player);
                            horse.setPassenger(player);
                            return;
                        }
                    }
                }
                return;
            }
        }
    }
     
  2. I think if you teleport the horse to the new location and then set the player as it's passenger, the player should autmatically teleport there. I haven't tested this myself however, so I might be wrong.
     
  3. @bo0tzz In the code I have put
    Code (Text):
    horse.teleport(player);
    horse.setOwner(player);
    horse.setPassenger(player);
    Is this what you mean?
     
  4. I guess that'd have the same effect :p What is the actual issue though - does the teleport not happen, does the player not sit on the horse? Some clarification would help ^^
     
  5. @bo0tzz The horse won't teleport, the player does though

    Edit: This is the same issue in all of the attempts and tries at this plugin
     
  6. Are there any errors in the log? Also try logging some debug messages, such as the boolean that Horse#teleport() returns.
     
  7. I wouldn't know how to start with debugging, I have never done it, the StackTrace (console) has no errors. I think the error is in this part of the code:
    Code (Text):
    if ((e.getCause() == PlayerTeleportEvent.TeleportCause.END_PORTAL)
                                || (e.getCause() == PlayerTeleportEvent.TeleportCause.ENDER_PEARL)
                                || (e.getCause() == PlayerTeleportEvent.TeleportCause.NETHER_PORTAL)
                                || (e.getCause() == PlayerTeleportEvent.TeleportCause.COMMAND)) {
    but if I remove this, the "It Worked!" message just spams the chat. I'll try to find the TeleportCause that spams the chat and go from there.
     
  8. This should work:

    horse.eject();
    horse.teleport(location);
    horse.setOwner(player);
    horse.setPassenger(player);

    This will throw the player from the horse, teleport the horse and then teleport the player. This happens fast enough to seem fluid to the player ;)
     
  9. before you teleport horses to the destination, you need to make sure that the chunk is loaded.
     
    • Like Like x 1
  10. You can teleport Entitys in not loaded chunks, as long as you still have a reference to them. As you teleport the player right after the horse you dont have to worry about this. Although it may be a good idea to still do this as the chunks nearby then appear faster to the teleported player.
     
  11. if the chunk is not loaded, you will lose your horse.... been there, done that...
     
  12. Ok, i think the thread starter can try this out :)
     
  13. @Friwi
    so for
    Code (Text):
    horse.eject();
    horse.teleport(location);
    horse.setOwner(player);
    horse.setPassenger(player);
    would I just change location to player.getLocation() since the player is already there?

    Edit: Or would I have to some how get the destination?
     
  14. I actually just tested using an ender pearl to tp while on a horse, it tp's the horse to you, but you aren't sitting on it. But from this I have learned that the problem is
    Code (Text):
    (e.getCause() == PlayerTeleportEvent.TeleportCause.COMMAND)) {
    so instead of TeleportCause.COMMAND, what do you think I should put in place of COMMAND?

    Edit: This might not be possible for some reason, I can send a player a message when they teleport using a command and it works, but the only thing that won't work is teleporting a horse.
     
    #14 TheMrJezza, May 30, 2015
    Last edited: May 30, 2015
  15. Nope. The player gets teleported by setting it as passenger.
     
  16. @Friwi Bukkit can see if you are on a horse, bukkit can see if you teleport because of a command, it can't see both at the same time. I need a way for it to see both. Any ideas?
     
  17. Like this?:

    Code (Text):
        @EventHandler
        public void onPlayerTeleport(PlayerTeleportEvent e){
           //Check the teleport cause
           if(e.getCause()==TeleportCause.COMMAND){
              //Check if player is riding sth.
              if(e.getPlayer().getVehicle() != null){
                  //Get the vehicle
                  Entity vehicle = e.getPlayer().getVehicle();
                  //Get out of the vehicle
                  vehicle.eject();
                  //Load target chunk as suggested above
                  if(!e.getTo().getChunk().isLoaded())e.getTo().getChunk().load();
                  //Teleport the vehicle
                  vehicle.teleport(e.getTo());
                  //Teleport the player. This has to be done to ensure that the player and the target
                  //destination are on the same world
                  e.getPlayer().teleport(e.getTo());
                  //Let the player ride his vehicle again
                  vehicle.setPassenger(e.getPlayer());
              }
           }
        }
     
  18. Getting in and out of vehicles is seen as teleporting, so if you get on the horse, you teleport on it, you use something like /tp while on a horse, it looks at like this: because you used a command to tp away, you tp'd with a command, but then it check again because you also got off the horse.. and like I said, getting off a horse is seen as teleporting, so it checks again... so the first check sees the command, the second one sees the horse.

    I need it to work off one check, and I need the check to see both the command and horse. Its gonna turn out to be a NMS (net.minecraft.server) code issue I think. Unless, I can get the horse that a player is sitting on, store it with something like a UUID, then when the player teleports, tp the horse with the UUID to the player.

    Edit: @Friwi And also the code from your last post didn't work either.. Its a real problem to try and solve...
     
    #18 TheMrJezza, May 30, 2015
    Last edited: May 30, 2015
  19. Try handling this with the CommandPreProcessEvent.
     
  20. @Friwi I have never heard of that event, it sounds good though so...