improve target properties

This commit is contained in:
Bixilon 2022-05-19 18:39:42 +02:00
parent 2f390e8393
commit 30bfd53466
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
34 changed files with 399 additions and 66 deletions

View File

@ -59,5 +59,9 @@ class DoubleParser(
fun CommandReader.readDouble(): Double? {
return readNumeric()?.toDoubleOrNull()
}
fun CommandReader.readRequiredDouble(): Double {
readResult { readDouble() }.let { return it.result ?: throw DoubleParseError(this, it) }
}
}
}

View File

@ -59,5 +59,9 @@ class FloatParser(
fun CommandReader.readFloat(): Float? {
return readNumeric()?.toFloatOrNull()
}
fun CommandReader.readRequiredFloat(): Float {
readResult { readFloat() }.let { return it.result ?: throw FloatParseError(this, it) }
}
}
}

View File

@ -59,5 +59,9 @@ class IntParser(
fun CommandReader.readInt(): Int? {
return readNumeric(decimal = false)?.toIntOrNull()
}
fun CommandReader.readRequiredInt(): Int {
readResult { readInt() }.let { return it.result ?: throw IntParseError(this, it) }
}
}
}

View File

@ -59,5 +59,9 @@ class LongParser(
fun CommandReader.readLong(): Long? {
return readNumeric(decimal = false)?.toLongOrNull()
}
fun CommandReader.readRequiredLong(): Long {
readResult { readLong() }.let { return it.result ?: throw LongParseError(this, it) }
}
}
}

View File

@ -30,7 +30,7 @@ object BooleanParser : BrigadierParser<Boolean>, ArgumentParserFactory<BooleanPa
override val placeholder = ChatComponent.of("<boolean>")
override fun parse(reader: CommandReader): Boolean {
reader.readResult { reader.readBoolean() }.let { return it.result ?: throw BooleanParseError(reader, it) }
return reader.readRequiredBoolean()
}
fun CommandReader.readBoolean(): Boolean? {
@ -41,6 +41,11 @@ object BooleanParser : BrigadierParser<Boolean>, ArgumentParserFactory<BooleanPa
}
}
fun CommandReader.readRequiredBoolean(): Boolean {
readResult { readBoolean() }.let { return it.result ?: throw BooleanParseError(this, it) }
}
override fun getSuggestions(reader: CommandReader): List<Boolean> {
val text = reader.readResult { reader.readUnquotedString() }
if (text.result == null) {

View File

@ -24,7 +24,7 @@ import de.bixilon.minosoft.protocol.protocol.PlayInByteBuffer
import de.bixilon.minosoft.util.KUtil.toResourceLocation
class FloatRangeParser(
val defaultMin: Boolean = true,
val defaultMin: Float? = -Float.MAX_VALUE,
) : ArgumentParser<FloatRange> {
override val examples: List<Any> = listOf(1.0f, "1.0..10")
override val placeholder = ChatComponent.of("<float..float>")
@ -45,13 +45,13 @@ class FloatRangeParser(
override fun read(buffer: PlayInByteBuffer) = FloatRangeParser()
fun CommandReader.readFloatRange(defaultMin: Boolean = true): FloatRange? {
fun CommandReader.readFloatRange(defaultMin: Float?): FloatRange? {
val (first, second) = readRange { readFloat() } ?: return null
if (first == null) {
return null
}
if (second == null) {
return FloatRange(min = if (defaultMin) -Float.MAX_VALUE else first, max = first)
return FloatRange(min = defaultMin ?: first, max = first)
}
return FloatRange(min = first, max = second)
}

View File

@ -24,7 +24,7 @@ import de.bixilon.minosoft.protocol.protocol.PlayInByteBuffer
import de.bixilon.minosoft.util.KUtil.toResourceLocation
class IntRangeParser(
val defaultMin: Boolean = true,
val defaultMin: Int? = Int.MIN_VALUE,
) : ArgumentParser<IntRange> {
override val examples: List<Any> = listOf(1, "1..10")
override val placeholder = ChatComponent.of("<int..int>")
@ -45,17 +45,13 @@ class IntRangeParser(
override fun read(buffer: PlayInByteBuffer) = IntRangeParser()
fun CommandReader.readIntRange(defaultMin: Boolean = true): IntRange? {
fun CommandReader.readIntRange(defaultMin: Int?): IntRange? {
val (first, second) = readRange { readInt() } ?: return null
if (first == null) {
return null
}
if (second == null) {
return if (defaultMin) {
Int.MIN_VALUE..first
} else {
first..first
}
return (defaultMin ?: first)..first
}
return first..second
}

View File

@ -13,6 +13,7 @@
package de.bixilon.minosoft.commands.parser.minecraft.target
import de.bixilon.kotlinglm.vec3.Vec3d
import de.bixilon.kutil.enums.EnumUtil
import de.bixilon.kutil.enums.ValuesEnum
import de.bixilon.minosoft.commands.parser.minecraft.target.targets.selector.properties.sort.Sorting
@ -29,8 +30,8 @@ enum class TargetSelectors(
;
fun sort(selected: MutableList<Entity>) {
sorting.sort(selected)
fun sort(center: Vec3d, selected: MutableList<Entity>) {
sorting.sort(center, selected)
}
companion object : ValuesEnum<TargetSelectors> {

View File

@ -18,5 +18,5 @@ import de.bixilon.minosoft.data.world.WorldEntities
interface EntityTarget {
fun getEntities(entities: WorldEntities): List<Entity>
fun getEntities(executor: Entity?, entities: WorldEntities): List<Entity>
}

View File

@ -21,7 +21,7 @@ class NameEntityTarget(
val name: String,
) : EntityTarget {
override fun getEntities(entities: WorldEntities): List<Entity> {
override fun getEntities(executor: Entity?, entities: WorldEntities): List<Entity> {
var entity: Entity? = null
entities.lock.acquire()
for (entry in entities) {

View File

@ -22,7 +22,7 @@ class UUIDEntityTarget(
val uuid: UUID,
) : EntityTarget {
override fun getEntities(entities: WorldEntities): List<Entity> {
override fun getEntities(executor: Entity?, entities: WorldEntities): List<Entity> {
val entity = entities[uuid] ?: return emptyList()
return listOf(entity)
}

View File

@ -13,10 +13,13 @@
package de.bixilon.minosoft.commands.parser.minecraft.target.targets.selector
import de.bixilon.kutil.cast.CastUtil.nullCast
import de.bixilon.kotlinglm.vec3.Vec3d
import de.bixilon.minosoft.commands.parser.minecraft.target.TargetSelectors
import de.bixilon.minosoft.commands.parser.minecraft.target.targets.EntityTarget
import de.bixilon.minosoft.commands.parser.minecraft.target.targets.selector.properties.TargetProperty
import de.bixilon.minosoft.commands.parser.minecraft.target.targets.selector.properties.position.center.XCenterProperty
import de.bixilon.minosoft.commands.parser.minecraft.target.targets.selector.properties.position.center.YCenterProperty
import de.bixilon.minosoft.commands.parser.minecraft.target.targets.selector.properties.position.center.ZCenterProperty
import de.bixilon.minosoft.commands.parser.minecraft.target.targets.selector.properties.sort.SortProperty
import de.bixilon.minosoft.data.entities.entities.Entity
import de.bixilon.minosoft.data.world.WorldEntities
@ -26,7 +29,7 @@ class SelectorEntityTarget(
val properties: Map<String, TargetProperty>,
) : EntityTarget {
override fun getEntities(entities: WorldEntities): List<Entity> {
override fun getEntities(executor: Entity?, entities: WorldEntities): List<Entity> {
val selected: MutableList<Entity> = mutableListOf()
entities.lock.acquire()
for (entity in entities) {
@ -34,12 +37,22 @@ class SelectorEntityTarget(
}
entities.lock.release()
properties[SortProperty.name]?.nullCast<SortProperty>()?.sort(selected) ?: selector.sort(selected)
val selectorProperties = SelectorProperties(
entities = selected,
center = executor?.position ?: Vec3d(),
executor = executor,
)
properties[XCenterProperty.name]?.updateProperties(selectorProperties)
properties[YCenterProperty.name]?.updateProperties(selectorProperties)
properties[ZCenterProperty.name]?.updateProperties(selectorProperties)
properties[SortProperty.name]?.updateProperties(selectorProperties) ?: selector.sort(selectorProperties.center, selectorProperties.entities)
val output: MutableList<Entity> = mutableListOf()
entityLoop@ for (entity in selected) {
entityLoop@ for (entity in selectorProperties.entities) {
for (property in properties.values) {
if (!property.passes(output, entity)) {
if (!property.passes(selectorProperties, entity)) {
continue@entityLoop
}
}

View File

@ -11,25 +11,13 @@
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.commands.parser.minecraft.target
package de.bixilon.minosoft.commands.parser.minecraft.target.targets.selector
import de.bixilon.minosoft.commands.parser.minecraft.target.targets.selector.properties.sort.Sorting
import de.bixilon.kotlinglm.vec3.Vec3d
import de.bixilon.minosoft.data.entities.entities.Entity
@Deprecated("")
data class TargetPropertiesLEGACY(
var x: Double?,
var y: Double?,
var z: Double?,
var volumeX: Double?,
var volumeY: Double?,
var volumeZ: Double?,
var scores: Any?, // ToDo
var tag: Any?, // ToDo
var team: Any?, // ToDo,
var sort: Sorting?,
var limit: Int? = null,
var level: IntRange? = null,
var nbt: Any? = null, // ToDo
var advancements: Any? = null, // ToDo
var predicate: Any? = null, // ToDo
data class SelectorProperties(
val entities: MutableList<Entity>,
val center: Vec3d,
val executor: Entity?,
)

View File

@ -14,6 +14,7 @@
package de.bixilon.minosoft.commands.parser.minecraft.target.targets.selector.properties
import de.bixilon.minosoft.commands.errors.ExpectedArgumentError
import de.bixilon.minosoft.commands.parser.minecraft.target.targets.selector.SelectorProperties
import de.bixilon.minosoft.commands.parser.minosoft.enums.EnumParser
import de.bixilon.minosoft.commands.util.CommandReader
import de.bixilon.minosoft.data.abilities.Gamemodes
@ -25,7 +26,7 @@ class GamemodeProperty(
val negated: Boolean,
) : TargetProperty {
override fun passes(selected: List<Entity>, entity: Entity): Boolean {
override fun passes(properties: SelectorProperties, entity: Entity): Boolean {
if (entity !is PlayerEntity) {
return false
}

View File

@ -13,28 +13,25 @@
package de.bixilon.minosoft.commands.parser.minecraft.target.targets.selector.properties
import de.bixilon.minosoft.commands.parser.minecraft.range._int.IntRangeParser
import de.bixilon.minosoft.commands.parser.minecraft.target.targets.selector.SelectorProperties
import de.bixilon.minosoft.commands.util.CommandReader
import de.bixilon.minosoft.data.entities.entities.Entity
class DistanceProperty(
val min: Double = 0.0,
val max: Double = Double.MAX_VALUE,
class LevelProperty(
val range: IntRange,
) : TargetProperty {
init {
check(min >= 0.0) { "Minimum distance can not be below 0" }
check(max >= min) { "Maximum distance can not be smaller than minimum distance" }
}
override fun passes(selected: List<Entity>, entity: Entity): Boolean {
override fun passes(properties: SelectorProperties, entity: Entity): Boolean {
TODO()
}
companion object : TargetPropertyFactory<DistanceProperty> {
override val name: String = "distance"
companion object : TargetPropertyFactory<LevelProperty> {
override val name: String = "level"
private val parser = IntRangeParser()
override fun read(reader: CommandReader): DistanceProperty {
TODO("Not yet implemented")
override fun read(reader: CommandReader): LevelProperty {
return LevelProperty(parser.parse(reader))
}
}
}

View File

@ -0,0 +1,37 @@
/*
* Minosoft
* Copyright (C) 2020-2022 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.commands.parser.minecraft.target.targets.selector.properties
import de.bixilon.minosoft.commands.parser.brigadier._int.IntParser.Companion.readRequiredInt
import de.bixilon.minosoft.commands.parser.minecraft.target.targets.selector.SelectorProperties
import de.bixilon.minosoft.commands.util.CommandReader
import de.bixilon.minosoft.data.entities.entities.Entity
class LimitProperty(
val limit: Int,
) : TargetProperty {
override fun passes(properties: SelectorProperties, entity: Entity): Boolean {
return properties.entities.size < limit
}
companion object : TargetPropertyFactory<LimitProperty> {
override val name: String = "limit"
override fun read(reader: CommandReader): LimitProperty {
return LimitProperty(reader.readRequiredInt())
}
}
}

View File

@ -14,6 +14,7 @@
package de.bixilon.minosoft.commands.parser.minecraft.target.targets.selector.properties
import de.bixilon.minosoft.commands.errors.ExpectedArgumentError
import de.bixilon.minosoft.commands.parser.minecraft.target.targets.selector.SelectorProperties
import de.bixilon.minosoft.commands.util.CommandReader
import de.bixilon.minosoft.data.entities.entities.Entity
@ -22,7 +23,7 @@ class NameProperty(
val negated: Boolean,
) : TargetProperty {
override fun passes(selected: List<Entity>, entity: Entity): Boolean {
override fun passes(properties: SelectorProperties, entity: Entity): Boolean {
// ToDo: Check player name?
if (negated) {
return entity.customName?.message != name

View File

@ -13,6 +13,10 @@
package de.bixilon.minosoft.commands.parser.minecraft.target.targets.selector.properties
import de.bixilon.minosoft.commands.parser.minecraft.target.targets.selector.properties.position.center.XCenterProperty
import de.bixilon.minosoft.commands.parser.minecraft.target.targets.selector.properties.position.center.YCenterProperty
import de.bixilon.minosoft.commands.parser.minecraft.target.targets.selector.properties.position.center.ZCenterProperty
import de.bixilon.minosoft.commands.parser.minecraft.target.targets.selector.properties.position.distance.DistanceProperty
import de.bixilon.minosoft.commands.parser.minecraft.target.targets.selector.properties.rotation.PitchRotation
import de.bixilon.minosoft.commands.parser.minecraft.target.targets.selector.properties.rotation.YawRotation
import de.bixilon.minosoft.commands.parser.minecraft.target.targets.selector.properties.sort.SortProperty
@ -22,6 +26,10 @@ object TargetProperties {
init {
register(XCenterProperty)
register(YCenterProperty)
register(ZCenterProperty)
register(SortProperty)
register(PitchRotation)
register(YawRotation)
@ -29,6 +37,21 @@ object TargetProperties {
register(GamemodeProperty)
register(NameProperty)
register(TypeProperty)
register(LimitProperty)
register(LevelProperty)
// ToDo
/*
var volumeX: Double?,
var volumeY: Double?,
var volumeZ: Double?,
var scores: Any?,
var tag: Any?,
var team: Any?,
var nbt: Any? = null,
var advancements: Any? = null,
var predicate: Any? = null,
*/
}
fun register(factory: TargetPropertyFactory<*>) {

View File

@ -13,9 +13,12 @@
package de.bixilon.minosoft.commands.parser.minecraft.target.targets.selector.properties
import de.bixilon.minosoft.commands.parser.minecraft.target.targets.selector.SelectorProperties
import de.bixilon.minosoft.data.entities.entities.Entity
interface TargetProperty {
fun passes(selected: List<Entity>, entity: Entity): Boolean
fun passes(properties: SelectorProperties, entity: Entity): Boolean
fun updateProperties(properties: SelectorProperties) = Unit
}

View File

@ -18,6 +18,5 @@ import de.bixilon.minosoft.commands.util.CommandReader
interface TargetPropertyFactory<T : TargetProperty> {
val name: String
fun read(reader: CommandReader): T
}

View File

@ -14,6 +14,7 @@
package de.bixilon.minosoft.commands.parser.minecraft.target.targets.selector.properties
import de.bixilon.minosoft.commands.errors.ExpectedArgumentError
import de.bixilon.minosoft.commands.parser.minecraft.target.targets.selector.SelectorProperties
import de.bixilon.minosoft.commands.util.CommandReader
import de.bixilon.minosoft.data.entities.entities.Entity
import de.bixilon.minosoft.data.registries.ResourceLocation
@ -23,7 +24,7 @@ class TypeProperty(
val negated: Boolean,
) : TargetProperty {
override fun passes(selected: List<Entity>, entity: Entity): Boolean {
override fun passes(properties: SelectorProperties, entity: Entity): Boolean {
if (negated) {
return entity.type.resourceLocation != type
}

View File

@ -0,0 +1,34 @@
/*
* Minosoft
* Copyright (C) 2020-2022 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.commands.parser.minecraft.target.targets.selector.properties.position.center
import de.bixilon.minosoft.commands.parser.minecraft.target.targets.selector.SelectorProperties
import de.bixilon.minosoft.commands.parser.minecraft.target.targets.selector.properties.TargetProperty
import de.bixilon.minosoft.data.Axes
import de.bixilon.minosoft.data.entities.entities.Entity
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3Util.set
abstract class CenterProperty(
val axis: Axes,
val value: Double,
) : TargetProperty {
override fun passes(properties: SelectorProperties, entity: Entity): Boolean {
return true
}
override fun updateProperties(properties: SelectorProperties) {
properties.center[axis] = value
}
}

View File

@ -0,0 +1,34 @@
/*
* Minosoft
* Copyright (C) 2020-2022 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.commands.parser.minecraft.target.targets.selector.properties.position.center
import de.bixilon.minosoft.commands.parser.brigadier._double.DoubleParseError
import de.bixilon.minosoft.commands.parser.brigadier._double.DoubleParser.Companion.readDouble
import de.bixilon.minosoft.commands.parser.minecraft.target.targets.selector.properties.TargetPropertyFactory
import de.bixilon.minosoft.commands.util.CommandReader
import de.bixilon.minosoft.data.Axes
class XCenterProperty(
value: Double,
) : CenterProperty(Axes.X, value) {
companion object : TargetPropertyFactory<XCenterProperty> {
override val name: String = "x"
override fun read(reader: CommandReader): XCenterProperty {
val value = reader.readResult { reader.readDouble() }.let { return@let it.result ?: throw DoubleParseError(reader, it) }
return XCenterProperty(value)
}
}
}

View File

@ -0,0 +1,35 @@
/*
* Minosoft
* Copyright (C) 2020-2022 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.commands.parser.minecraft.target.targets.selector.properties.position.center
import de.bixilon.minosoft.commands.parser.brigadier._double.DoubleParseError
import de.bixilon.minosoft.commands.parser.brigadier._double.DoubleParser.Companion.readDouble
import de.bixilon.minosoft.commands.parser.minecraft.target.targets.selector.properties.TargetPropertyFactory
import de.bixilon.minosoft.commands.util.CommandReader
import de.bixilon.minosoft.data.Axes
class YCenterProperty(
value: Double,
) : CenterProperty(Axes.Y, value) {
companion object : TargetPropertyFactory<YCenterProperty> {
override val name: String = "y"
override fun read(reader: CommandReader): YCenterProperty {
val value = reader.readResult { reader.readDouble() }.let { return@let it.result ?: throw DoubleParseError(reader, it) }
return YCenterProperty(value)
}
}
}

View File

@ -0,0 +1,35 @@
/*
* Minosoft
* Copyright (C) 2020-2022 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.commands.parser.minecraft.target.targets.selector.properties.position.center
import de.bixilon.minosoft.commands.parser.brigadier._double.DoubleParseError
import de.bixilon.minosoft.commands.parser.brigadier._double.DoubleParser.Companion.readDouble
import de.bixilon.minosoft.commands.parser.minecraft.target.targets.selector.properties.TargetPropertyFactory
import de.bixilon.minosoft.commands.util.CommandReader
import de.bixilon.minosoft.data.Axes
class ZCenterProperty(
value: Double,
) : CenterProperty(Axes.Z, value) {
companion object : TargetPropertyFactory<ZCenterProperty> {
override val name: String = "z"
override fun read(reader: CommandReader): ZCenterProperty {
val value = reader.readResult { reader.readDouble() }.let { return@let it.result ?: throw DoubleParseError(reader, it) }
return ZCenterProperty(value)
}
}
}

View File

@ -0,0 +1,54 @@
/*
* Minosoft
* Copyright (C) 2020-2022 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.commands.parser.minecraft.target.targets.selector.properties.position.distance
import de.bixilon.minosoft.commands.parser.minecraft.range._float.FloatRange
import de.bixilon.minosoft.commands.parser.minecraft.range._float.FloatRangeParser
import de.bixilon.minosoft.commands.parser.minecraft.target.targets.selector.SelectorProperties
import de.bixilon.minosoft.commands.parser.minecraft.target.targets.selector.properties.TargetProperty
import de.bixilon.minosoft.commands.parser.minecraft.target.targets.selector.properties.TargetPropertyFactory
import de.bixilon.minosoft.commands.util.CommandReader
import de.bixilon.minosoft.data.entities.entities.Entity
class DistanceProperty(
val range: FloatRange,
) : TargetProperty {
init {
check(range.min >= 0.0) { "Minimum distance can not be below 0" }
check(range.max >= range.min) { "Maximum distance can not be smaller than minimum distance" }
}
override fun passes(properties: SelectorProperties, entity: Entity): Boolean {
val entityPosition = entity.position
return (entityPosition - properties.center).length().toFloat() in range
}
companion object : TargetPropertyFactory<DistanceProperty> {
override val name: String = "distance"
private val parser = FloatRangeParser(0.0f)
override fun read(reader: CommandReader): DistanceProperty {
val range = reader.readResult { parser.parse(reader) }
if (range.result.min < 0.0f) {
throw InvalidMinDistanceError(reader, range)
}
if (range.result.max < range.result.min) {
throw MinGreaterThanMaxDistanceError(reader, range)
}
return DistanceProperty(range.result)
}
}
}

View File

@ -0,0 +1,24 @@
/*
* Minosoft
* Copyright (C) 2020-2022 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.commands.parser.minecraft.target.targets.selector.properties.position.distance
import de.bixilon.minosoft.commands.errors.parser.ParserError
import de.bixilon.minosoft.commands.parser.minecraft.range._float.FloatRange
import de.bixilon.minosoft.commands.util.CommandReader
import de.bixilon.minosoft.commands.util.ReadResult
class InvalidMinDistanceError(
reader: CommandReader,
result: ReadResult<FloatRange>,
) : ParserError(reader, result)

View File

@ -0,0 +1,24 @@
/*
* Minosoft
* Copyright (C) 2020-2022 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.commands.parser.minecraft.target.targets.selector.properties.position.distance
import de.bixilon.minosoft.commands.errors.parser.ParserError
import de.bixilon.minosoft.commands.parser.minecraft.range._float.FloatRange
import de.bixilon.minosoft.commands.util.CommandReader
import de.bixilon.minosoft.commands.util.ReadResult
class MinGreaterThanMaxDistanceError(
reader: CommandReader,
result: ReadResult<FloatRange>,
) : ParserError(reader, result)

View File

@ -32,7 +32,7 @@ class PitchRotation(
const val MIN = -90.0f
const val MAX = 90.0f
override val name: String = "x_rotation"
private val parser = FloatRangeParser(false)
private val parser = FloatRangeParser(null)
override fun read(reader: CommandReader): YawRotation {
val range = reader.readResult { parser.parse(reader) }

View File

@ -14,6 +14,7 @@
package de.bixilon.minosoft.commands.parser.minecraft.target.targets.selector.properties.rotation
import de.bixilon.minosoft.commands.parser.minecraft.range._float.FloatRange
import de.bixilon.minosoft.commands.parser.minecraft.target.targets.selector.SelectorProperties
import de.bixilon.minosoft.commands.parser.minecraft.target.targets.selector.properties.TargetProperty
import de.bixilon.minosoft.data.entities.EntityRotation
import de.bixilon.minosoft.data.entities.entities.Entity
@ -24,7 +25,7 @@ interface RotationProperty : TargetProperty {
fun getValue(rotation: EntityRotation): Double
override fun passes(selected: List<Entity>, entity: Entity): Boolean {
override fun passes(properties: SelectorProperties, entity: Entity): Boolean {
val rotation = getValue(entity.rotation)
return rotation.toFloat() in range

View File

@ -31,7 +31,7 @@ class YawRotation(
const val MIN = -180.0f
const val MAX = 180.0f
override val name: String = "y_rotation"
private val parser = FloatRangeParser(false)
private val parser = FloatRangeParser(null)
override fun read(reader: CommandReader): YawRotation {
val range = reader.readResult { parser.parse(reader) }

View File

@ -13,6 +13,7 @@
package de.bixilon.minosoft.commands.parser.minecraft.target.targets.selector.properties.sort
import de.bixilon.minosoft.commands.parser.minecraft.target.targets.selector.SelectorProperties
import de.bixilon.minosoft.commands.parser.minecraft.target.targets.selector.properties.TargetProperty
import de.bixilon.minosoft.commands.parser.minecraft.target.targets.selector.properties.TargetPropertyFactory
import de.bixilon.minosoft.commands.parser.minosoft.enums.EnumParser
@ -23,14 +24,15 @@ class SortProperty(
val sorting: Sorting,
) : TargetProperty {
override fun passes(selected: List<Entity>, entity: Entity): Boolean {
override fun passes(properties: SelectorProperties, entity: Entity): Boolean {
return true
}
fun sort(selected: MutableList<Entity>) {
sorting.sort(selected)
override fun updateProperties(properties: SelectorProperties) {
sorting.sort(properties.center, properties.entities)
}
companion object : TargetPropertyFactory<SortProperty> {
override val name: String = "sort"
private val parser = EnumParser(Sorting)

View File

@ -13,6 +13,7 @@
package de.bixilon.minosoft.commands.parser.minecraft.target.targets.selector.properties.sort
import de.bixilon.kotlinglm.vec3.Vec3d
import de.bixilon.kutil.enums.EnumUtil
import de.bixilon.kutil.enums.ValuesEnum
import de.bixilon.minosoft.data.entities.entities.Entity
@ -25,8 +26,13 @@ enum class Sorting {
;
fun sort(selected: MutableList<Entity>) {
sort(selected)
fun sort(center: Vec3d, selected: MutableList<Entity>) {
when (this) {
NEAREST -> selected.sortBy { (center - it.position).length2() }
FURTHEST -> selected.sortBy { -(center - it.position).length2() }
RANDOM -> selected.shuffle()
ARBITRARY -> selected.sortBy { it.id ?: 0 }
}
}
companion object : ValuesEnum<Sorting> {

View File

@ -14,11 +14,14 @@
package de.bixilon.minosoft.commands.stack
import de.bixilon.kutil.cast.CastUtil.nullCast
import de.bixilon.minosoft.data.entities.entities.Entity
class CommandStack {
private val stack: MutableList<StackEntry> = mutableListOf()
val size: Int get() = stack.size
var executor: Entity? = null
@Suppress("NON_PUBLIC_CALL_FROM_PUBLIC_INLINE")
inline operator fun <reified T> get(name: String): T? {
return getAny(name).nullCast()