Multi-Region Protection Help

Discussion in 'Plugin Development' started by r0306, May 3, 2012.

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

    r0306

    Hello. I am currently working on a plugin that requires defining and protecting regions. Now before you tell me to go and use WorldGuard API instead, I have tried using the WorldGuard API but I prefer to eliminate as many plugin dependencies as possible. Therefore, I have incorporated a simple cuboid defining method into the plugin. I save the two saved coordinates inside my config.yml file and I call them up whenever I need it. However, I need to define multiple cuboid regions. I know that I would have to compare the X, Y, and Z coordinates and make sure they are in between the coordinates of the two corners but if there are 5 different regions, how would I find out which region the player is in?
     
  2. Offline

    maxp0wer789

    Make a Region Class:
    something like that
    http://pastebin.de/25897
    For each Region in your list or array check the collision with a Player.
    If a Region returns true in the check you know which Region Object it was and you get get it's ID, name or anything unique.
     
  3. Offline

    Komak57

    I think you misunderstand his query. He's looking to protect his land by cuboids in multiple worlds, not prevent players from entering the territory. I have done this method twice now. The first one did not support multi-world functionality. My newest one has. The difference between mine and yours is that in mine, 1 block is locked to a player, and then the player is allowed to build near that. As far away as they wanted with the limitation of blocks allowed to place. Yours would only be defining the locations via cuboid once. There are 2 ways you can do this. 1 is prevent access if the block is not yours, the other is to prevent access if the block is not in your cuboid. The first one has less coding, and can still work as the 2nd depending on how you implement it.

    First off, I suppose you'll only be allowing ops and such to add or remove guarded zones. This means that you will probably be adding or removing players from the allowance on a block via commands, and allowing them to do what they wish. To do this, you first need to set up your global HashMap<Block, Player>. If you ever want to dump this into a flat-file, I suggest you write your own Coordinate class containing String Worldname, Int X, Int Y, and Int Z, since you cannot serialize World (nor do you want to).

    MyLocation loc = new MyLocation(player.getWorld().getName(), block.getLocation().getBlockX(),block.getLocation().getBlockY(),block.getLocation().getBlockZ());

    With this, you would have a HashMap<MyLocation, String> protect; which would store the world, and the coordinate based block, and save it to the players name ex: protect.put(loc, Player.getName()); There are some ins and outs to getting this to work properly, as you might find it difficult to protect.get(loc); later. But since i'm only here to inform you of the mechanics, you can ask that later :3

    Now that you have a world-locked coordinate hashmap declaring which player owns it, you simply have to create a command that loops through X1-X2, Y1-Y2, Z1-Z2, and lock all of them to the declared player. Once done, write a block listener for onBlockPlace() and onBlockDestroy() and set an event.setCancelled(true); to prevent placement.

    Downsides: You also have to write an event handler for when blocks move, as sand and gravel will still fall, but may fall out of the boundry. Also, pistons can push blocks out of the boundry. Good luck!
     
  4. Offline

    maxp0wer789

    His question was: how would I find out which region the player is IN?
    Also I didn't say anything about preventing the player from entering a region.

    I would make a region Class with the origin/pivot-Location of your cuboid and your cuboids dimension(width, height, depth)(you can also add the player name to the Class to relate it to a player),
    just like I do a hitbox in any game.
    Then you can check if a Location is colliding (is within) your cuboids bounds.
    Just like I posted above.
    If you also check the worldname with your origin Location it works multiworld, and your cuboid is freely resizable with changing the dimension or the origin.

    If you want me to post the collision logic just ask.

    greetings maxp0wer

    EDIT: Object-oriented programming ftw...
     
  5. Offline

    r0306

    maxp0wer789
    Komak57

    Thank you both for your replies. However, I don't think I described my problem clearly. What I want to do is, on a BlockBreakEvent, if a player breaks the block, how would I check all my region coordinates (two per cuboid region) one by one and see if one of them matches a region? Right now, my code implements a listener that listens for block breaks. Then, I go through my config and check the list of regions. For each region I get their coordinates and loop through their x,y,z values using X2-X1,Y2-Y1,Z2-Z1 to see if the block is located inside. Then if the if returns true, I cancel the event. My config.yml right now is something like this:

    Code:
    arenalist:
    - arenaone
    - arenatwo
     
    arenaone:
    locations:
      location1:
      world: Minecraft
      x: 258
      y: 20
      z: 39
      location2:
      x: 269
      y: 25
      z: 45
     
    arenatwo:
    locations:
      location1:
      world: Minecraft
      x: 159
      y: 50
      z: 70
      location2:
      x: 30
      y: 100
      z: 50
    How would I get each of these locations and check which one matches? Do I have to convert these coordinates to a vector or can I simply check it using (x2< bloc < x1,y2 <bloc <y1, z2 <bloc <z1). Also, if I did that, would I have to check for the opposite as well? (x2>bloc > x1,y2> bloc >y1, z2 >bloc >z1) Thanks for your help. :)
     
  6. Offline

    Komak57

    player.getLocation() should get you the coordinates of your player to check if you should allow pvp (unless you have something else to do this for you).

    as far as setting the boundries, you want a HashMap<Location, Boolean> to store the block location, and its protected status. Alternatively, if you want, create a custom class MyBarrier or something that stores a String World_Name, Int X, Int Z, and you can create a HashMap<MyBarrier, Boolean> that allows your barriers to be height de-limited, then do a blockbreak event check on the block.getlocation().getX() and .getZ() to match to the hashmap HashMap.containsKey(MyBarrier); (this location has a protected value), and HashMap.get(MyBarrier); (this locations value is protected or non-protected).

    To set a cuboid, do a for(Z) { for(X) { HashMap.put(MyBarrier, true); }} to set the coordinates?

    ---
    though, based on your config file, it seems a little more difficult to call weather or not the value is within range. I suppose you would first, determine the minimum xyz and maximum xyz, then try an if (getX() => minX && getX() <= maxX) {} (repeating for Y and Z) to cancel the blockdestroy event?
     
  7. Offline

    r0306

    Thanks. I got it working now. :p
     
Thread Status:
Not open for further replies.

Share This Page