package net.knarcraft.stargate; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.World; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; import org.bukkit.block.data.BlockData; import org.bukkit.block.data.type.Sign; import org.bukkit.block.data.type.WallSign; /* * stargate - A portal plugin for Bukkit * Copyright (C) 2011 Shaun (sturmeh) * Copyright (C) 2011 Dinnerbone * Copyright (C) 2011, 2012 Steven "Drakia" Scott * Copyright (C) 2021 Kristian Knarvik *

* This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. *

* This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. *

* You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ /** * This class represents a block location * *

The BlockLocation class is basically a Location with some extra functionality. * Warning: Because of differences in the equals methods between Location and BlockLocation, a BlockLocation which * equals another BlockLocation does not necessarily equal the name BlockLocation if treated as a Location.

*/ public class BlockLocation extends Location { private BlockLocation parent = null; /** * Creates a new block location * @param world

The world the block exists in

* @param x

The x coordinate of the block

* @param y

The y coordinate of the block

* @param z

The z coordinate of the block

*/ public BlockLocation(World world, int x, int y, int z) { super(world, x, y, z); } /** * Copies a craftbukkit block * @param block

The block to

*/ public BlockLocation(Block block) { super(block.getWorld(), block.getX(), block.getY(), block.getZ()); } /** * Gets a block from a string * @param world

The world the block exists in

* @param string

A comma separated list of z, y and z coordinates as integers

*/ public BlockLocation(World world, String string) { super(world, Integer.parseInt(string.split(",")[0]), Integer.parseInt(string.split(",")[1]), Integer.parseInt(string.split(",")[2])); } /** * Makes a new block in a relative position to this block * @param x

The x position relative to this block's position

* @param y

The y position relative to this block's position

* @param z

The z position relative to this block's position

* @return

A new block location

*/ public BlockLocation makeRelative(int x, int y, int z) { return (BlockLocation) this.clone().add(x, y, z); } /** * Makes a location relative to the block location * @param x

The x position relative to this block's position

* @param y

The y position relative to this block's position

* @param z

The z position relative to this block's position

* @param rotX

The x rotation of the location

* @param rotY

The y rotation of the location

* @return

A new location

*/ public Location makeRelativeLoc(double x, double y, double z, float rotX, float rotY) { Location newLocation = this.clone(); newLocation.setYaw(rotX); newLocation.setPitch(rotY); return newLocation.add(x, y, z); } /** * Makes a block location relative to the current location according to given parameters * @param right

* @param depth

The y position relative to the current position

* @param distance

The distance away from the previous location to the new location

* @param modX

x modifier. Defines movement along the x-axis. 0 for no movement

* @param modY

* @param modZ

z modifier. Defines movement along the z-axis. 0 for no movement

* @return A new location relative to this block location */ public BlockLocation modRelative(int right, int depth, int distance, int modX, int modY, int modZ) { return makeRelative(-right * modX + distance * modZ, -depth * modY, -right * modZ + -distance * modX); } /** * Makes a location relative to the current location according to given parameters * @param right

* @param depth

The y position relative to the current position

* @param distance

The distance away from the previous location to the new location

* @param rotX

The yaw of the location

* @param rotY

Unused

* @param modX

x modifier. Defines movement along the x-axis. 0 for no movement

* @param modY

Unused

* @param modZ

z modifier. Defines movement along the z-axis. 0 for no movement

* @return A new location relative to this block location */ public Location modRelativeLoc(double right, double depth, double distance, float rotX, float rotY, int modX, int modY, int modZ) { return makeRelativeLoc(0.5 + -right * modX + distance * modZ, depth, 0.5 + -right * modZ + -distance * modX, rotX, 0); } /** * Sets the type for the block at this location * @param type

The new block material type

*/ public void setType(Material type) { this.getBlock().setType(type); } /** * Gets the type for the block at this location * @return

The block material type

*/ public Material getType() { return this.getBlock().getType(); } /** * Gets the location representing this block location * @return

The location representing this block location

*/ public Location getLocation() { return this.clone(); } /** * Gets this block location's parent block * @return

This block location's parent block

*/ public Block getParent() { if (parent == null) { findParent(); } if (parent == null) { return null; } return parent.getBlock(); } /** * Tries to find the parent block location * *

If this block location is a sign, the parent is the block location of the block the sign is connected to.

*/ private void findParent() { int offsetX = 0; int offsetY = 0; int offsetZ = 0; BlockData blockData = getBlock().getBlockData(); if (blockData instanceof WallSign) { BlockFace facing = ((WallSign) blockData).getFacing().getOppositeFace(); offsetX = facing.getModX(); offsetZ = facing.getModZ(); } else if (blockData instanceof Sign) { offsetY = -1; } else { return; } parent = this.makeRelative(offsetX, offsetY, offsetZ); } @Override public String toString() { return String.valueOf(this.getBlockX()) + ',' + this.getBlockY() + ',' + this.getBlockZ(); } @Override public int hashCode() { int result = 18; result = result * 27 + this.getBlockX(); result = result * 27 + this.getBlockY(); result = result * 27 + this.getBlockZ(); if (this.getWorld() != null) { result = result * 27 + this.getWorld().getName().hashCode(); } return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; BlockLocation blockLocation = (BlockLocation) obj; World thisWorld = this.getWorld(); World otherWorld = blockLocation.getWorld(); boolean worldsEqual = (thisWorld == null && otherWorld == null) || ((thisWorld != null && otherWorld != null) && thisWorld == otherWorld); return blockLocation.getBlockX() == this.getBlockX() && blockLocation.getBlockY() == this.getBlockY() && blockLocation.getBlockZ() == this.getBlockZ() && worldsEqual; } }