All Downloads are FREE. Search and download functionalities are using the official Maven repository.

walkmc.extensions.Locations.kt Maven / Gradle / Ivy

@file:Suppress("NOTHING_TO_INLINE")

package walkmc.extensions

import org.bukkit.*
import org.bukkit.block.*
import org.bukkit.entity.*
import org.bukkit.util.*
import walkmc.*
import walkmc.serializer.tag.impl.*
import kotlin.math.*

/**
 * Gets the local storage of this location. Used to declare permanent data.
 */
val Location.localStorage: CompoundTag
	get() = LocationLocalStorage.getOrPut(this) { CompoundTag() }

/**
 * Gets the local storage of the location represented by this block. Used to declare permanent data.
 */
val Block.localStorage: CompoundTag
	get() = location.localStorage

/**
 * Gets the local storage of this location. Used to declare temporary data.
 */
val Location.sessionStorage: Storage
	get() = LocationSessionStorage.getOrPut(this) { Storage() }

/**
 * Gets the local storage of the location represented by this block. Used to declare temporary data.
 */
val Block.sessionStorage: Storage
	get() = location.sessionStorage

/**
 * Spawns the specified entity in generic type with this location and returns the entity.
 */
inline fun  Location.spawn(): T = world.spawn(this, T::class.java)

/**
 * Converts this location to a plain string text.
 */
@Deprecated("Changed function name", ReplaceWith("stringify"))
fun Location.toText(fully: Boolean = false): String {
	return if (fully)
		"${world.name}:$x:$y:$z:$yaw:$pitch"
	else
		"${world.name}:$blockX:$blockY:$blockZ"
}

/**
 * Converts this location to a plain string text.
 */
fun Location.stringify(fully: Boolean = false): String = toText(fully)

/**
 * Returns all nearby entities with this location as central.
 */
fun Location.getNearbyEntities(x: Double, y: Double, z: Double) =
	world.getNearbyEntities(this, x, y, z).toList()


/**
 * Generates a circle shape path as this location to center.
 */
fun Location.generateCirclePath(radius: Double, amount: Int): List = buildList {
	val increment = (2 * PI) / amount
	for (i in 0 until amount) {
		val angle = i * increment
		val x = x + (radius * cos(angle))
		val z = z + (radius * sin(angle))
		add(Location(world, x, y, z))
	}
}

/**
 * Generates a sphere shape path as this location to center.
 */
fun Location.generateSpherePath(radius: Double, points: Int): List = buildList {
	val phi = PI * (3.0 - sqrt(5.0))
	for (i in 0 until points) {
		val y = 1.0 - i.toDouble() / (points.toDouble() - 1.0) * 2.0
		val theta = phi * i
		val r = radius * sqrt(1.0 - y * y)
		val x = r * cos(theta)
		val z = r * sin(theta)
		add(getRelative(x, y, z))
	}
}

/**
 * Generates a line shape path as this location to center.
 */
fun Location.generateLinePath(end: Location, points: Int): List = buildList {
	val increment = end.toVector().subtract(toVector()).divide(Vector(points - 1, points - 1, points - 1))
	for (i in 0 until points) {
		add(clone().add(increment.clone().multiply(i)))
	}
}

/**
 * Generates a quadrilateral shape path as this location to center.
 */
fun Location.generateQuadPath(
	width: Double,
	length: Double,
	pointsWidth: Int = 1,
	pointsLength: Int = 1,
): List = buildList {
	val offset = clone().subtract(width / 2, 0.0, length / 2)
	val widthIncrement = width / pointsWidth
	val lengthIncrement = length / pointsLength
	for (x in 0 until pointsWidth) {
		for (z in 0 until pointsLength) {
			add(offset.clone().add(x * widthIncrement, 0.0, z * lengthIncrement))
		}
	}
}

/**
 * Generates a cubic shape path as this location to center.
 */
fun Location.generateCubePath(
	width: Double,
	length: Double,
	heigth: Double,
	pointsWidth: Int = 1,
	pointsLength: Int = 1,
	pointsHeigth: Int = 1,
): List = buildList {
	val heightIncrement = heigth / pointsHeigth
	for (y in 0 until pointsHeigth) {
		addAll([email protected](width, length, pointsWidth, pointsLength))
		[email protected](0.0, heightIncrement, 0.0)
	}
}

/**
 * Sends a particle to a player at this location.
 */
inline fun Location.playParticle(player: Player, particle: Particle, amount: Int = 1) {
	particle.play(player, this, amount)
}

/**
 * Sends a particle to all players of this location world at this location.
 */
inline fun Location.playParticle(particle: Particle, amount: Int = 1) {
	particle.play(this, amount)
}

/**
 * Plays a sound at this location.
 */
inline fun Location.playSound(sound: Sound, volume: Float = 1f, pitch: Float = 1f) {
	world.playSound(this, sound, volume, pitch)
}

/**
 * Returns the relative location of this location by the specified coordinates.
 */
fun Location.getRelative(x: Double, y: Double, z: Double) = Location(world, this.x + x, this.y + y, this.z + z)

/**
 * Returns the relative location of this location by the specified coordinates.
 */
fun Location.getRelative(x: Int, y: Int, z: Int) = Location(world, this.x + x, this.y + y, this.z + z)

/**
 * Returns the relative location of this location by the specified face and distance.
 */
fun Location.getRelative(face: BlockFace, distance: Double = 1.0) =
	getRelative(face.modX * distance, face.modY * distance, face.modZ * distance)

/**
 * Gets the up relative location of this location.
 */
fun Location.up(distance: Double = 1.0) = getRelative(0.0, distance, 0.0)

/**
 * Gets the down relative location of this location.
 */
fun Location.down(distance: Double = 1.0) = getRelative(0.0, -distance, 0.0)

/**
 * Gets the south relative location of this location.
 */
fun Location.south(distance: Double = 1.0) = getRelative(BlockFace.SOUTH, distance)

/**
 * Gets the north relative location of this location.
 */
fun Location.north(distance: Double = 1.0) = getRelative(BlockFace.NORTH, distance)

/**
 * Gets the east relative location of this location.
 */
fun Location.east(distance: Double = 1.0) = getRelative(BlockFace.EAST, distance)

/**
 * Gets the west relative location of this location.
 */
fun Location.west(distance: Double = 1.0) = getRelative(BlockFace.WEST, distance)

/**
 * Gets the south west relative location of this location.
 */
fun Location.southwest(distance: Double = 1.0) = getRelative(BlockFace.SOUTH_WEST, distance)

/**
 * Gets the north west relative location of this location.
 */
fun Location.northwest(distance: Double = 1.0) = getRelative(BlockFace.NORTH_WEST, distance)

/**
 * Gets the south east relative location of this location.
 */
fun Location.southeast(distance: Double = 1.0) = getRelative(BlockFace.SOUTH_EAST, distance)

/**
 * Gets the north east relative location of this location.
 */
fun Location.northeast(distance: Double = 1.0) = getRelative(BlockFace.NORTH_EAST, distance)




© 2015 - 2025 Weber Informatics LLC | Privacy Policy