Novice Help Request: Rotate World with an Array and For Loop

Discussion in 'Plugin Development' started by Live4Redline, Dec 17, 2014.

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

    Live4Redline

    I've been at java for several months now and have done several personal plugins and several 1.8 updates to others. So I know enough to get around and handle things but i am still learning.

    I'm working on another plugin now and I've been reading up and looking at examples but I'm having trouble with something that i feel should be simple.

    I'm looking at Array's, For Loops and Iterators and i feel i understand the primes but I'm having issues putting it in use in combination with each other based on the examples I have at hand. Some of the reading material and examples may be depreciated in 1.8 and its confusing me.

    Bases: Trying to run a loop that picks a world or all worlds, runs its checks and commands and then restarts the loop, and either changes the world to the next world on the .getWorlds list to run the same checks and commands again or simply just keeps cycling. Basic check each world for entity stuff and if true do something about it.

    This is the example I found that a friend gave me to use but unfortunately it is depreciated and honestly... i don't see how it ever worked, cause the continue; makes "Entity e" un-reachible. So somethings wrong with it I'm guessing.
    Code:
      public void run()
      {
        Iterator localIterator2;
        for (Iterator localIterator1 = Bukkit.getWorlds().iterator(); localIterator1.hasNext(); localIterator2.hasNext())
        {
          World w = (World)localIterator1.next();
          localIterator2 = w.getEntities().iterator(); continue;Entity e = (Entity)localIterator2.next();
          if ((exampleEntity) && ((e instanceof LivingEntity)) &&...
    So I've tried several other things some more embarrassing then others, with no success. I can get the code to not have any errors but the plugin throws errors at the console while run.

    Code:
    ArrayList cannot be cast to org.bukkit.entity.Entity
    and others...

    So I read some other material and changed it to this... which also didn't work.

    Code:
      public void run()
      {
        for (Object element1 : Bukkit.getWorlds()) {
          World w = (World)element1;
          Object element2 = w.getEntities();
          Entity e = (Entity)(element2);
         
          if ((exampleEntity) && ((e instanceof LivingEntity)) &&...
    So I read more, and The Java Tutorials tell me to use this format for the For statment...

    Code:
    for (initialization; termination; increment) {
        statement(s)
    }
    But Ive tried several alterations of this format and I feel like i may have stepped off in the wrong direction somewhere and im asking if someone wouldn't mind getting back where I need to be.
     
  2. Offline

    mythbusterma

    @Live4Redline

    What is the end result of this code supposed to be, exactly?
     
    Live4Redline likes this.
  3. Offline

    Skionz

    @Live4Redline
    This is an enhanced for loop
    Code:
    for(String line : list) {
    It doesn't really matter which format you use. The enhanced for was introduced in Java 5 I believe, so don't use it if you want to support servers running Java 4; however, I doubt there are many.
     
    Live4Redline likes this.
  4. Offline

    mythbusterma

    @Skionz

    Minecraft was built using Java 6, there are no servers that have Java 5 or below.
     
    Live4Redline likes this.
  5. Offline

    Live4Redline

    It can be either way, i need to run a loop that picks all worlds, checks entities on said worlds and issues the statments if needed to said worlds and then restarts the loop. OR, runs a loop that picks a world, and every time it restarts the loop, it moves on to the next world. I need the statments to effect all worlds available on the server.

    Ya, the current format was depreciated and asked me to change it to an enhanced for loop. Is the enhanced for loop where i want to focus or....?
     
    Last edited: Dec 17, 2014
  6. Offline

    Skionz

    @Live4Redline I didn't know Java 6 was used for Minecraft so it really does not matter which you use. Also I am pretty sure you can only deprecate a method, class, or field.
     
    Live4Redline likes this.
  7. Offline

    Live4Redline

    Your right, its giving me suppresswarnings for it and I assumed... its not deprecate.
     
  8. Offline

    Webbeh

    I'd do it this way :

    Code:
    static bool checking=false;
    
    doChecks() {
      checking = true;
      for(World w : Bukkit.getWorlds())
      {
        //Do your checks there.
       }
      checking = false;
    }
    
    new Runnable(Every second) {
       if(!checking) { doChecks };
    }
    
     
    Live4Redline likes this.
  9. Offline

    Live4Redline

    That seems easy enough and not nearly as complicated as it seemed. Now the question, how do i cast the entities so i can check them? I keep getting "ArrayList cannot be cast to org.bukkit.entity.Entity". I tried a few things and searching up a way to do it, with no luck.

    I've tried a few things, and i cant seem to get it right...

    Code:
    {
        for(World w : Bukkit.getWorlds())
        {
          Entity e = (Entity) w.getEntities();
    
          if ((checkEntity) && ((e instanceof LivingEntity)) && (!(e instanceof HumanEntity)))
          {
            if (e.getTicksLived() >.....
    Also gave this a try but i was just guessing....
    Code:
      {
        for(Entity e : ((World) Bukkit.getWorlds()).getEntities())
        {
    
          if ((checkEntity) && ((e instanceof LivingEntity)) && (!(e instanceof HumanEntity)))
          {
            if (e.getTicksLived() >.....
    I then hit google up and started trying other things but i cant find a method to cast the entities while inside the For statement.

    I want to get all the entities of all the worlds and check them.
     
  10. Offline

    Webbeh

    World.getEntities() returns an ArrayList<Entity>.

    Use a for loop on them :

    for(Entity e : w.getEntities())
    {
    ...
    }
     
    Live4Redline likes this.
  11. Offline

    Skionz

    The method you are using is deprecated. Not the enhanced for loop.
     
    Live4Redline likes this.
  12. Offline

    Live4Redline

    FYI, I'd like to say thanks for the help. I appreciate it.

    Ok so, this is the circle I've been fighting. Your completely correct and i love the fact that i now know which of the formats are also correct but correct me if i'm wrong...

    This gives me a list of the worlds, but I'm unable to call the entities from the worlds from inside the For statement...
    Code:
      for(World w : Bukkit.getWorlds())
      {

    This right here WORKS, it gives me a world and the entities of that world but it is however only one world. How do i go about calling all the worlds [and] [or] rotate them so it will eventually call them.
    Code:
      {
        World w = Bukkit.getWorld("world");  //only one world selected
        for(Entity e : w.getEntities()) 
        {

    Can I do a For statement inside of another For statement and still call the parent For statement? Do i want to make an array and cycle through the array? Whats the best option to do this?
     
  13. Offline

    Skionz

    @Live4Redline Yes you can put a for loop inside another for loop. This is known as a nested for loop.
     
    Live4Redline likes this.
  14. Offline

    Live4Redline

    A nested loop hu, nice. So if i can still call the parent For loop example "World", from inside the child loop "Entities", to perform my checks, then I should be able to wrap up the rest of this class pretty quickly. Awesome.

    Gonna call it a night and give that a try tomorrow then. Ill let you guys know how it turns out and thanks again for everything Webbeh, Skionz, and Mythbusterma. I appreciate it. =)
     
    Skionz likes this.
  15. Offline

    Live4Redline

    @Skionz @Webbeh @mythbusterma

    I worked on it some more the next day, got stuck again, took a break and figured it out today. Thanks again guys.

    In addition to learning how to do a proper "nested loop" I was pulling from two different libraries which was messing up my tests. Its all sorted out and seems to be working like I wanted. Thanks again!

    I ended with something like this...
    Code:
      public void run()
      {
        for(World w : Bukkit.getWorlds())
        {
          for(Entity e : w.getEntities())
          {
            if ((checkHorse) && (e instanceof Horse))
            {
              if (e.getTicksLived() > horsekilltime) {
                e.remove();
              }
            }
          }
        }
      }
    I do have another question however... I added some console messages to sort through my issues and I notice that it appears to be be checking the WORLD and ENTITIES several times before it moves on too the IF statements, and then spams again after the IF statements. The final code has several entity checks which all seem to be working like i wanted, but is there something I should be putting at the end after the final IF, or is this a result of how I am tasking the "public void run"?

    This is what i'm seeing in console... keep in mind its crude and the four messages are only in the line of code once so each repeat is it running the loop again i'm guessing. Is this normal????
    Code:
    [18:06:59] [Server thread/INFO]: [31mGOT THE WORLDS![0m
    [18:06:59] [Server thread/INFO]: [31mGOT ENTITIES OF THE WORLDS![0m
    [18:06:59] [Server thread/INFO]: [31mGOT ENTITIES OF THE WORLDS![0m
    [18:06:59] [Server thread/INFO]: [31mGOT ENTITIES OF THE WORLDS![0m
    [18:06:59] [Server thread/INFO]: [31mGOT ENTITIES OF THE WORLDS![0m
    [18:06:59] [Server thread/INFO]: [31mGOT ENTITIES OF THE WORLDS![0m
    [18:06:59] [Server thread/INFO]: [33mChecked HORSES[0m
    [18:06:59] [Server thread/INFO]: [32mHORSES Ticks = TRUE and Removed![0m
    [18:06:59] [Server thread/INFO]: [31mGOT ENTITIES OF THE WORLDS![0m
    [18:06:59] [Server thread/INFO]: [33mChecked HORSES[0m
    [18:06:59] [Server thread/INFO]: [33mHORSES Ticks = FALSE[0m
    [18:06:59] [Server thread/INFO]: [31mGOT ENTITIES OF THE WORLDS![0m
    [18:06:59] [Server thread/INFO]: [31mGOT ENTITIES OF THE WORLDS![0m
    [18:06:59] [Server thread/INFO]: [31mGOT THE WORLDS![0m
    [18:06:59] [Server thread/INFO]: [31mGOT THE WORLDS![0m
    [18:06:59] [Server thread/INFO]: [31mGOT THE WORLDS![0m
    [18:06:59] [Server thread/INFO]: [31mGOT THE WORLDS![0m
    [18:06:59] [Server thread/INFO]: [31mGOT THE WORLDS![0m
    [18:06:59] [Server thread/INFO]: [31mGOT THE WORLDS![0m
    [18:06:59] [Server thread/INFO]: [31mGOT THE WORLDS![0m
    [18:06:59] [Server thread/INFO]: [31mGOT THE WORLDS![0m
    [18:06:59] [Server thread/INFO]: [31mGOT THE WORLDS![0m
    [18:06:59] [Server thread/INFO]: [31mGOT ENTITIES OF THE WORLDS![0m
     
  16. Offline

    1Rogue

    This is just a guess, but are you the only one on the server? It might be removing entities from the world you're on, and then going through the other worlds and not finding any entities. (If you use a for-loop on an empty collection, no code inside the loop will run).

    Also just a speed tip: instead of "e instanceOf Horse", compare the entity type:
    Code:java
    1. e.getType() == EntityType.HORSE


    While your way was perfectly correct, it's a bit faster comparing the ordinals of enums rather than class comparisons, and you want as much speed as possible when using a loop!
     
  17. Offline

    Live4Redline

    Thanks, @1Rogue

    I was the only one on at the time of testing so that makes since. I also updated everything to your suggestion and it works great. I really appreciate the tip and wisdom. =)
     
    1Rogue likes this.
Thread Status:
Not open for further replies.

Share This Page