Compare... Integers?

Discussion in 'Plugin Development' started by LartTyler, Sep 12, 2011.

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

    LartTyler

    Ok, so I had a similar issue with comparing two strings earlier on, and the forum was amazing in solving my problem quickly, and explaining why my original method wouldn't work. Now, I have a problem that is all too similar....

    I have a player's location (or rather the block they're standing on) stored in an integer array, from[], and to[]. The goal of the method is to determine which direction the player is moving, regardless of the way they were facing.

    Here's the code:
    Code:
    public Integer getDirection(Location locFrom, Location locTo) {
            Integer[] from = {locFrom.getBlockX(), locFrom.getBlockZ()};
            Integer[] to = {locTo.getBlockX(), locTo.getBlockZ()};
            Integer direction = null;
    
            for (Integer i = 0; i < 2; i++) {
                ifDebug("from[" + i + "] = " + from[i]);
                ifDebug("  to[" + i + "] = " + to[i]);
            }
    
            if (from[0] > to[0] && from[1] == to[1]) {
                direction = 1;
            } else if (from[1] > to[1] && from[0] == to[0]) {
                direction = 2;
            } else if (from[0] < to[0] && from[1] == to[1]) {
                direction = 3;
            } else if (from[1] < to[1] && from[0] == to[0]) {
                direction = 0;
            }
    
            ifDebug("getDirection(...) returning '" + direction + "'.");
            return direction;
        }
    Now, as you can see, when the method runs, it outputs all the variables to the console via ifDebug. I can see that comparisons would work, but for some reason, all I ever get back is null.

    Here's the debug output:
    Code:
    16:31:01 [INFO] <DayJobs> from[0] = 47
    16:31:01 [INFO] <DayJobs>   to[0] = 48
    16:31:01 [INFO] <DayJobs> from[1] = 135
    16:31:01 [INFO] <DayJobs>   to[1] = 135
    16:31:01 [INFO] <DayJobs> getDirection(...) returning 'null'.
    In that example, the third comparison, if (from[0] < to[0] && from[1] == to[1]), should work, but the output, and the stack trace, both say otherwise. Any thoughts?


    Thanks in advance,
    Tyler
     
  2. Offline

    nisovin

    You're using Integers, which are objects. Using == on an object will only return true if it is the exact same object. You should just be using int, which can be compared with == and will act as you expect.
     
  3. Offline

    LartTyler

    Seriously? That makes no sense at all :p Ahaha Java is so confusing. I never thought to even consider using a more primitive data type. I'm coming from VB, so something like that would have never occurred to me. Thank you so much! :)

    Tyler
     
  4. Offline

    Sagacious_Zed Bukkit Docs

    Well there is int the primitive. Then there is Integer the object. This arrangement is mainly do to the fact that java primitives are not objects. So if speed is important, and it is, you want to use the primitive, but sometimes you need the flexibility of objects, and this an object class of the primitive is provided.

    for your reading
    http://illegalargumentexception.blogspot.com/2008/08/java-int-versus-integer.html
     
  5. Offline

    LartTyler

    Hmm... So, given the following code:
    Code:
    public int getDirection(Location locFrom, Location locTo) {
            int[] from = {locFrom.getBlockX(), locFrom.getBlockZ()};
            int[] to = {locTo.getBlockX(), locTo.getBlockZ()};
            int direction = -1;
    
            if (from[0] > to[0] && from[1] == to[1]) {
                direction = 1;
            } else if (from[1] > to[1] && from[0] == to[0]) {
                direction = 2;
            } else if (from[0] < to[0] && from[1] == to[1]) {
                direction = 3;
            } else if (from[1] < to[1] && from[0] == to[0]) {
                direction = 0;
            }
    
            return direction;
        }
    Should things not be working now? No matter the value, one of those four SHOULD evaluate to true, but I always get -1 back. Perhaps there's something I'm missing?

    And thank you, Sagacious_Zed, that was extremely helpful :) It's one thing to know how to fix a bug, but it's a thousand times more helpful to know why the bug occurred in the first place.
     
  6. Offline

    ALFONSO

    Probably not the reason for not working at all but how would this handle diagonal movement (where neither fromx and tox or fromz and toz are equal)?
     
  7. Offline

    Slash1987

    what if to[0]==from[0] && to[1]==from[1]?
     
  8. Offline

    LartTyler

    No, it wouldn't, and I know I already have to work out that limitation. I wanted to get this working first though, then build off of it to add direction movement detection. I've been running up against a wall all week trying to figure out a good way to get the direction a player is moving, and this has been the most promising so far, but even it isn't perfect. If you have any better suggestions, I'm certainly willing to listen.
     
  9. Offline

    Slash1987

    just try for now to add <= && >=
    The reason why you're getting -1 all the time is that none of the condition is true(and it's possible).
    So you need to consider every direction, not just North,South,East and West.
     
  10. Offline

    ALFONSO

    I think Slash1987 has a point there. Since you cast the position to ints and by that losing at lot precision its quite possible for both positions to almost always be the same when being called from onPlayerMove. Maybe try doubles instead of ints.

    Edit: I see you are using getBlockX and getBlockZ. If that is actually called from onPlayerMove like i suspected you should use getX and getZ i think.
     
  11. Offline

    Slash1987

    @ALFONSO with double he could get a direction even from a minimal lateral movement, so int it's ok.
    But he needs to suppose that someone could walk N, NE, NW, W, E, S, SW and SE. So 8 directions instead of 4. That's why he's getting always a -1 direction
     
  12. Offline

    LartTyler

    Code:
    public int getDirection(Location locFrom, Location locTo) {
            int direction = -1;
    
            if (locFrom.getX() > locTo.getX() && locFrom.getBlockZ() == locTo.getBlockZ()) {
                direction = 1;
            } else if (locFrom.getZ() > locTo.getZ() && locFrom.getBlockX() == locTo.getBlockX()) {
                direction = 2;
            } else if (locFrom.getX() < locTo.getX() && locFrom.getBlockZ() == locTo.getBlockZ()) {
                direction = 3;
            } else if (locFrom.getZ() < locTo.getZ() && locFrom.getBlockX() == locTo.getBlockX()) {
                direction = 0;
            }
    
            return direction;
        }
    As you suggested Slash, I changed the method to the above. That seems to work much better, using the double values and the block integers together. In testing, it only missed getting the correct direction once out of many tries.

    One last question, and it's a bit off topic. Is there something wrong with using:
    Code:
    Location newLoc = ev.getTo();
     
     switch (common.getDirection(ev.getFrom(), ev.getTo())) {
     case 0:
         newLoc.setZ(newLoc.getZ() - 1.5d);
         break;
     case 1:
         newLoc.setX(newLoc.getX() + 1.5d);
         break;
     case 2:
         newLoc.setZ(newLoc.getZ() + 1.5d);
         break;
     case 3:
         newLoc.setX(newLoc.getX() - 1.5d);
         break;
     default:
         common.ifDebug("Error: Could not determine '" + ev.getPlayer().getDisplayName() + "'s direction.");                        
     }
     
     ev.getPlayer().getLocation().setX(newLoc.getX());
     ev.getPlayer().getLocation().setY(newLoc.getY());
     ev.getPlayer().getLocation().setZ(newLoc.getZ());
    
    To get a player's location, then modify based on the direction they're moving? I try this, but nothing happens in terms of moving the player.
     
  13. Offline

    Slash1987

    @LartTyler
    well, i think you need to teleport the player to the new location, not to modify an instance of a possibly old location (whe you catch the event the player could have changed it's loc several times)
     
  14. Offline

    LartTyler

    Isn't that the point of using the ev.getPlayer()....? Shouldn't that give me the full Player instance, which means tacking on the getLocation().setX(...), or what ever the case may be, should give me the most current Location? Unless of course I'm mistaken. I know I got it to work earlier, but I accidentally deleted the code thinking I wouldn't need it :p
     
  15. Offline

    Slash1987

    Mine was just a supposition. Still haven't tried that before. My advise is to implement all 8 directions, should make your plugin more efficient(we are in a 3d world, don't we?)
     
  16. Offline

    LartTyler

    The code I posted above that uses the double values instead of the integers works for that, it seems. I have no real way to tell for sure until I can figure out moving a player, but it hasn't returned -1 for me since I modified it.
     
  17. Offline

    ALFONSO

    Edit: Sorry im tired and my logic is full of holes. Ignore me, sorry :D
     
  18. Offline

    LartTyler

    Got it, that fixed it all :) Thanks everyone!!!

    Tyler
     
  19. Offline

    ALFONSO

    Glad it worked. Even with me blabbering half baked stuff all the time ;)
     
  20. Offline

    LartTyler

    Lol :p Nah, really, you had made a good point, before you deleted it :p

    Thanks again everyone, it's great to have some help with this stuff :)
     
Thread Status:
Not open for further replies.

Share This Page