Solved entity.teleport(Location) issues

Discussion in 'Spigot Plugin Development' started by Kepling, Jan 13, 2020.

  1. Hi I'm having a really weird issue. Hopefully it's not too confusing.
    So I spawn a mob with a command that runs a public void spawns and then teleports the mob to the player.
    I have a scheduled task which is meant to teleport the mob if it's too far away, but it doesn't.

    This is the weird part, I made a command to teleport the mob. The first time I run the command it doesn't teleport the mob. But what it does do is really weird. When I run the command for the first time, the scheduled task that's meant to teleport the mob starts working. So when I run the command the second time, unlike the first time it actually teleports the mob. It's like it enables teleporting the mob.

    I'm gussing it's a glitch; Or is this how it's meant to work?
    I updated spigot to the latest version but it still acts the same.
     
  2. Code (Text):
    package me.kepling.bosses.main;

    import java.util.HashMap;
    import java.util.Iterator;
    import java.util.Random;
    import java.util.Map.Entry;
    import org.bukkit.Bukkit;
    import org.bukkit.Location;
    import org.bukkit.command.Command;
    import org.bukkit.command.CommandSender;
    import org.bukkit.craftbukkit.v1_15_R1.CraftWorld;
    import org.bukkit.entity.Entity;
    import org.bukkit.entity.LivingEntity;
    import org.bukkit.entity.Player;
    import org.bukkit.event.Listener;
    import org.bukkit.plugin.java.JavaPlugin;
    import org.bukkit.scheduler.BukkitRunnable;

    import me.kepling.bosses.bosses.MrFluffy;
    import me.kepling.bosses.bosses.MrFluffyRider;
    import net.minecraft.server.v1_15_R1.EntitySheep;
    import net.minecraft.server.v1_15_R1.EntityTypes;
    import net.minecraft.server.v1_15_R1.EntityZombieHusk;
    import net.minecraft.server.v1_15_R1.World;

    public class Main extends JavaPlugin implements Listener {

        public HashMap<Entity, Location> BossDungeonLoc = new HashMap<Entity, Location>();

        public void onEnable() {
            getServer().getPluginManager().registerEvents(this, this);

            lead();
        }

        public void onDisable() {
            for (Iterator<org.bukkit.World> it = Bukkit.getWorlds().iterator(); it.hasNext();) {
                org.bukkit.World world = it.next();

                removeCustomBosses(world);
            }
        }

        public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
            if (cmd.getName().equalsIgnoreCase("bosses")) {
                if ((sender instanceof Player)) {
                    Player player = (Player) sender;
                    Location loc = player.getLocation();
                    if (args.length == 0) {
                        if (sender.hasPermission("bosses.command")) {

                        } else {
                            player.sendMessage(
                                    "§cI'm sorry, but you do not have permission to preform this command. Please contact the server administrators if you belive that this is in error.");
                        }
                    } else if (args[0].equalsIgnoreCase("killall")) {
                        if (sender.hasPermission("bosses.killall")) {
                            removeCustomBosses(loc.getWorld());
                        } else {
                            player.sendMessage(
                                    "§cI'm sorry, but you do not have permission to preform this command. Please contact the server administrators if you belive that this is in error.");
                        }
                    } else if (args[0].equalsIgnoreCase("tp")) {
                        if (sender.hasPermission("bosses.tp")) {
                            tpBosses(player);
                        } else {
                            player.sendMessage(
                                    "§cI'm sorry, but you do not have permission to preform this command. Please contact the server administrators if you belive that this is in error.");
                        }
                    } else {
                        if (sender.hasPermission("mobs.spawn")) {

                            spawnBoss(args);

                        } else {
                            player.sendMessage(
                                    "§cI'm sorry, but you do not have permission to preform this command. Please contact the server administrators if you belive that this is in error.");
                        }
                    }
                }
            }
            return false;
        }

        public void spawnBoss(String[] args) {
            Location dungeonLoc;

            Random r = new Random();

            int locInt = r.nextInt(3);
            switch (locInt) {
            default:
                dungeonLoc = new Location(Bukkit.getServer().getWorlds().get(0), 0.5, 69, 0.5);
                break;
            case 1:
                dungeonLoc = new Location(Bukkit.getServer().getWorlds().get(0), 0.5, 69, 0.5);
                break;
            case 2:
                dungeonLoc = new Location(Bukkit.getServer().getWorlds().get(0), 0.5, 69, 0.5);
                break;
            }

            EntityTypes<EntitySheep> typeSheep = EntityTypes.SHEEP;
            EntityTypes<EntityZombieHusk> typeHusk = EntityTypes.HUSK;
            World world = ((CraftWorld) dungeonLoc.getWorld()).getHandle();
            net.minecraft.server.v1_15_R1.Entity boss;
            net.minecraft.server.v1_15_R1.Entity rider;

            switch (args[0]) {
            default:
                return;

            case "MrFluffy":
                boss = new MrFluffy(typeSheep, world);
                rider = new MrFluffyRider(typeHusk, world);
                break;
            }

            Entity bBoss = boss.getBukkitEntity();
            Entity bRider = rider.getBukkitEntity();

            bBoss.teleport(dungeonLoc);
            if (rider != null) {
                bRider.teleport(bBoss);
                rider.startRiding(boss);
            }
         
            BossDungeonLoc.put(bBoss, dungeonLoc);
        }

        public void removeCustomBosses(org.bukkit.World world) {
            for (Iterator<LivingEntity> it = world.getLivingEntities().iterator(); it.hasNext();) {
                LivingEntity entity = it.next();
                if (entity.getScoreboardTags().contains("CustomBoss")
                        || entity.getScoreboardTags().contains("CustomBossSummoned")) {
                    entity.remove();
                }
            }
        }

        public void tpBosses(Player player) {
            for (Iterator<LivingEntity> it = player.getWorld().getLivingEntities().iterator(); it.hasNext();) {
                LivingEntity entity = it.next();
                if (entity.getScoreboardTags().contains("CustomBoss")
                        || entity.getScoreboardTags().contains("CustomBossSummoned")) {
                    entity.teleport(player);
                }
            }
        }

        public void lead() {
            new BukkitRunnable() {
                public void run() {
                    for (Iterator<Entry<Entity, Location>> it = BossDungeonLoc.entrySet().iterator(); it.hasNext();) {
                        Entry<Entity, Location> next = it.next();
                        Entity boss = next.getKey();
                        Location dungeonLoc = next.getValue();

                        if (boss != null && boss.getLocation().distance(dungeonLoc) >= 15)
                            boss.teleport(dungeonLoc);
                    }
                }
            }.runTaskTimer(this, 0L, 20L);
        }

    }
     
  3. Here's an example
     
  4. You have an odd method for looping all bosses. I can't quite say what's going wrong here, but I recommend not iterating over all entities in the world.

    My advice to debug it is to leave messages. Bukkit.broadcastMessage("1") and increase the one for every potential break in the code. Make sure that it is actually following the desired path.
     
  5. Okay, I'll try that.
    I know it's dumb to iterate all entitys but I don't know another way ¯\_(ツ)_/¯
     
  6. Okay, update!
    My current aim is to find a quick fix. I'm trying to recreate what happens the first time I run the command (Allow entity to be teleported???). And running that when the mob is spawned.

    It seems that I need to iterate all LivingEntities to recreate it. I tried getting Entity from UUID and from a HashMap but both failed.
    Code (Text):
    Bukkit.broadcastMessage("try " + boss.getCustomName());
    if (boss.teleport(dungeonLoc))
    Bukkit.broadcastMessage("teleported" + boss.getCustomName());
    By failed I mean sends "try" but doesn't send "teleported".

    The weirdest thng is, for everything that got passed whatever if statements I put; They all sent the "try" message but only 2 sent the "teleport" message.
    The first: iterate all LivingEntities and no if statement
    The second: iterate all LivingEntities and if if (entity.getScoreboardTags().contains(boss.getCustomName())

    Both of which don't always narrow down to one mob :(

    Anyone have any idea why it can get to entity.teleport(Location)) and not teleport without even sending an error?
     
  7. Had to use
    import org.bukkit.craftbukkit.v1_15_R1.Entitiy;
    and
    entity.setPosition(x, y,z);