Search code examples
javabukkit

Bukkit : Read out Custom Name String / Extract Integer


I am currently working on a little RPG-Plugin, and at the moment I am trying to read out the Level of a mob which is summoned via the following code:

public static void summonMob(EntityType entTy, int level, World w, Location loc) {

    Entity en = w.spawnEntity(loc, entTy);
    en.setCustomName(ChatColor.RED + "Experiment One " + ChatColor.DARK_GRAY + "> " + ChatColor.GREEN + level
            + ChatColor.DARK_GRAY + " <");
}

And then called in the onEnable() for testing:

summonMob(EntityType.ZOMBIE, 1, w, new Location(w, 238, 45, 1349));

The "test-mob" was summoned with the Level 1, I am trying to read out this information in the following event:

@EventHandler
public void onEntityDeath(EntityDeathEvent e) {
    if (e.getEntity().getKiller() instanceof Player) {

        Player p = e.getEntity().getKiller();

        if (e.getEntity().getCustomName() != null) {

            int mobLevel = Integer
                    .parseInt(ChatColor.stripColor(e.getEntity().getCustomName().replaceAll("[^\\d.]", "")
                            .replaceAll("[^\\p{L}\\p{Nd}]+", "").replaceAll("\\s+", "")));
            p.sendMessage("You've slain a Level " + mobLevel + " enemie!");
        }
    }

}

The problem is, although all non-digits are removed from the custom name, the final integer always adds two times the "8", making 818 out of 1, and 8208 out of 20.

I've probably missed something simple here, and it would be great if someone could help me out.


Solution

  • While storing a mobs level inside its name, it can make its extraction hard when using it. A better solution may be using Bukkit's Metadatable system.

    This system is really easy to use and can be done with the following:

    When you spawn you mob, you attach a value to the mob in the following way:

    en.setMetadata("level", new FixedMetadataValue(level));
    

    When the mob is slaim, you can easily extract the value back by doing:

    List<MetadataValue> data = e.getEntity().getMetadata("level");
    if(data.isEmpty()) return;
    int level = data.get(0).asInt();
    

    That way, you don't need to do complex string regexes to get your level back.