blob: 779d7d28c02662cffd107e11bb4cb0fecd1db640 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.apache.nlpcraft.examples.minecraft
import org.apache.nlpcraft.examples.minecraft.MinecraftValueLoader.Companion.dumps
import org.apache.nlpcraft.model.*
import java.util.*
/**
* Special processor to support 'fillIntent' intent processing.
*/
class MinecraftFillMatchProcessor {
internal data class Coordinate(val x: Int = 0, val y: Int = 0, val z: Int = 0) {
override fun toString(): String {
return "$x $y $z"
}
fun relative(): String {
return "~$x ~$y ~$z"
}
fun relativeRotated(): String {
return "^$x ^$y ^$z"
}
}
companion object {
fun process(
@NCIntentTerm("shape") shape: NCToken,
@NCIntentTerm("block") blockToken: NCToken,
@NCIntentTerm("len") length: Optional<NCToken>,
@NCIntentTerm("position") position: NCToken
): NCResult {
val (from, to) = resultCoordinates(transformLength(length), shape.id)
val block = dumps["item"]!![blockToken.value]!!
val player = findPlayer(position)
val positionCoordinate = positionCoordinate(position)
return NCResult.text(
"execute at $player positioned ${positionCoordinate.relative()} rotated 0 0 run " +
"fill ${from.relativeRotated()} ${to.relativeRotated()} $block"
)
}
private fun resultCoordinates(length: Int, shape: String): Pair<Coordinate, Coordinate> {
return when (shape) {
"line" -> Coordinate(-length / 2) to
Coordinate((length - 1) / 2)
"square" -> Coordinate(-length / 2, 0, -length / 2) to
Coordinate((length - 1) / 2, 0, (length - 1) / 2)
"cube" -> Coordinate(-length / 2, -length / 2, -length / 2) to
Coordinate((length - 1) / 2, (length - 1) / 2, (length - 1) / 2)
else -> throw NCRejection("Unsupported shape")
}
}
private fun positionCoordinate(position: NCToken): Coordinate {
return when (position.id) {
"position:player" -> Coordinate()
"position:front" -> Coordinate(0, 0, transformLength(Optional.of(position), 10))
else -> throw NCRejection("Unsupported position")
}
}
private fun transformLength(length: Optional<NCToken>, default: Int = 5): Int {
return length.flatMap { x ->
x.partTokens.stream()
.filter { it.id == "nlpcraft:num" }
.findAny()
.map { it.meta<Double>("nlpcraft:num:from").toInt() }
}.orElse(default)
}
private fun findPlayer(position: NCToken): String {
val part = position.partTokens.stream()
.filter { it.id == "mc:player" }
.findAny()
.orElseThrow { AssertionError("Player wasn't found") }
return if (part.lemma == "i" || part.lemma == "my") "@p" else part.originalText ?: "@p"
}
}
}