Help with getting location of block in schematic after its rotated and pasted

Discussion in 'WorldEdit' started by Robotnik, Aug 26, 2017.

  1. Robotnik

    Robotnik New Member

    If someone can help me solve this I'll literally buy you a beer :p

    I've been spending days trying to figure out the solution to this problem and have had no luck, so I'm opening up the source to it in hopes someone can help me out

    Basically, the way it works is the plugin spawns schematics in the world, and will randomly rotate them and fill up chests with loot and modify spawners. This requires storing the location of the chests and spawners of the schematic in a config file, and then calculating the location of those chests after a schematic has been pasted and rotated in order to modify their contents.

    I have been able to correctly locate the location of these chests and spawners when the schematic has been pasted but has NOT been rotated.

    I however cannot seem to correctly calculate the location of these chests and spawners when the schematic is rotated in the clipboard before being pasted.

    currently the code which calculates the location of the chests and blocks of the schematic in the world after being pasted looks like this

    Code (Text):


    //offset is the schematics offset
    //offset is sometimes a decimal ending in .9999, so need to always round up when converting to int
    int OffsetX = (int) Math.ceil(offset.getX());
    int OffsetY = (int) Math.ceil(offset.getY());
    int OffsetZ = (int) Math.ceil(offset.getZ());

    //ConfigX and ConfigZ are the location of a chest or spawner within the schematic, stored in a config file
    int ConfigX = BlockdataConfig.getInt("Blocks.BlockNBT" + i + ".x");
    int ConfigZ = BlockdataConfig.getInt("Blocks.BlockNBT" + i + ".z");

    //pastepotion is a vector which is where the schematic is pasted using the CuboidClipboard paste method
    //x y and z are supposed to be the location of the chest or spawner in the world after the schematic has been rotated and pasted
    if (rotation == 0) {
                    x = pasteposition.getBlockX() + OffsetX + ConfigX;
                    z = pasteposition.getBlockZ() + OffsetZ + ConfigZ;
                } else if (rotation == 90) {
                    x = (pasteposition.getBlockX() + OffsetX) + ConfigX;
                    z = (pasteposition.getBlockZ() - OffsetZ) - ConfigZ;
                } else if (rotation == 180) {
                    x = (pasteposition.getBlockX() - OffsetX) - ConfigX;
                    z = (pasteposition.getBlockZ() - OffsetZ) - ConfigZ;
                } else if (rotation == 270) {
                    x = (pasteposition.getBlockX() - OffsetX) - ConfigX;
                    z = (pasteposition.getBlockZ() + OffsetZ) + ConfigZ;
                }
    }
     
    The result is, when the block is rotated it finds the wrong position for the chest. Its usually close to where the schematic is posted, but I have not been able to find any pattern to find a solution that works


    The full code for the class can be found here (Its kinda messy but I try to comment everything as much as possible)

    http://gitlab.the-outpost.me/robotn...aster/src/WorldSchematics/SpawnSchematic.java
    The method can be found on line 391
    Last edited: Aug 26, 2017
  2. wizjany

    wizjany Administrator Developer

    ClipboardHolder.getTransform().apply(Vector)?
    Don't forget to apply the transform to the original point and offset too. See https://github.com/sk89q/WorldEdit/commit/28d45870e2490481713bd941dfc9f7bc211b8b15
    That's the code that does the selection after pasting when you do //paste -s. So if you have the original location within the clipboard, apply the transform to that position and then add it to the transformed origin + offset.

    your source code is closed btw, wants me to log in.
  3. Robotnik

    Robotnik New Member

    Fixed the link, you shouldnt need to log in now to view it.
  4. Robotnik

    Robotnik New Member

    I gave a try at using Transform().apply(Vector), it works when the schematic is not rotated, but still gets the wrong position when the schematic is rotated

    Basically I'm now using the following code to try and handle the position when the schematic is rotated

    Code (Text):
               
    //the location of the spawner or chest in the world
    Vector blockXYZ = new Vector();

    //apply the transform to the x y z of the location of the spawner inside the schematic
    configOffset = transform.apply(configOffset);

    //apply the transform to the x y z of the offset
    SchematicOffset = transform.apply(SchematicOffset);

    //add up all the vectors to calculate the position of the spawner or chest in the world
    //pasteposition is the location in the world where the schematic was pasted
    blockXYZ = blockXYZ.add(pasteposition);
    blockXYZ = blockXYZ.add(SchematicOffset);
    blockXYZ = blockXYZ.add(configOffset);

     
    It seems to be applying the transformations right according to console

    Code (Text):
    1:25:55] [Server thread/INFO]: [WorldSchematics2] [Debug - SchematicSpawning] ==Spawning Debug Info==
    [21:25:55] [Server thread/INFO]: [WorldSchematics2] [Debug - SchematicSpawning] Schematic spawn position: -272 4 -311
    [21:25:55] [Server thread/INFO]: [WorldSchematics2] [Debug - SchematicSpawning] Rotation = 270
    [21:25:55] [Server thread/INFO]: [WorldSchematics2] Schematic passed all checks. Spawned schematic at: -272 4 -311
    [21:25:55] [Server thread/INFO]: [WorldSchematics2] [Debug - SchematicSpawning] Applying Blockdata to the Schematic
    [21:25:55] [Server thread/INFO]: [WorldSchematics2] [Debug - SchematicSpawning] rotation of schematic is 270
    [21:25:55] [Server thread/INFO]: [WorldSchematics2] [Debug - SchematicSpawning] configOffset xy before transform= 3 1 4
    [21:25:55] [Server thread/INFO]: [WorldSchematics2] [Debug - SchematicSpawning] configOffset xy after transform= -4 1 3
    [21:25:55] [Server thread/INFO]: [WorldSchematics2] [Debug - SchematicSpawning] SchematicOffset xy after transform= -4 0 0
    [21:25:55] [Server thread/INFO]: [WorldSchematics2] [Debug - SchematicSpawning] SchematicOffset xy after transform= 0 0 -4
    [21:25:55] [Server thread/INFO]: [WorldSchematics2] [Debug - SchematicSpawning] Testing NBT Block settings
    [21:25:55] [Server thread/INFO]: [WorldSchematics2] [Debug - SchematicSpawning] NBT Block XYZ in world = -276 5 -312. Block type is AIR
    but its still off from where the location of the chest actually is in the world

    I teleported to the spot where the plugin thinks where the chest is located ( -276 5 -312)

    [​IMG]

    But its actually here, at -268 6 -312

    [​IMG]
  5. wizjany

    wizjany Administrator Developer

    assuming my math and counting is right, the configOffset looks correct: http://i.imgur.com/q67sq4i.png
    however, i'm also assuming that the tnt block is your true origin (seems to be -272 4 -311 from your debug), and i have no idea what the "schematicoffset" is.
    also, if I go from your tnt (assuming -272 4 -311) and add the offset i got (-4 1 3), i would expect -276 5 -308, but you got -276 5 -312. that extra 0 0 -4 is the schematicoffset, which i again am not sure what it represents, but it seems extraneous.
    on the other hand, the actual chest is 8 blocks off in the x axis, not the z axis. that seems to imply that you actually added 4 to the origin instead of subtracting it...