Slice and splice classes
This commit is contained in:
parent
b1bd0aa2b5
commit
11f876ab57
@ -11,7 +11,8 @@ import ru.dbotthepony.mc.otm.core.TranslatableComponent
|
||||
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
|
||||
import ru.dbotthepony.mc.otm.matter.IMatterItem
|
||||
import ru.dbotthepony.mc.otm.core.set
|
||||
import ru.dbotthepony.mc.otm.matter.MatterManager
|
||||
import ru.dbotthepony.mc.otm.matter.IMatterValue
|
||||
import ru.dbotthepony.mc.otm.matter.MatterValue
|
||||
|
||||
class MatterDustItem : Item(Properties().tab(OverdriveThatMatters.INSTANCE.CREATIVE_TAB).stacksTo(64)), IMatterItem {
|
||||
private fun matter(stack: ItemStack): ImpreciseFraction {
|
||||
@ -22,9 +23,9 @@ class MatterDustItem : Item(Properties().tab(OverdriveThatMatters.INSTANCE.CREAT
|
||||
stack.orCreateTag["matter"] = matter.serializeNBT()
|
||||
}
|
||||
|
||||
override fun getMatterValue(stack: ItemStack): MatterManager.IMatterValue? {
|
||||
override fun getMatterValue(stack: ItemStack): IMatterValue? {
|
||||
val value = stack.tag?.get("matter") ?: return null
|
||||
return MatterManager.MatterValue(ImpreciseFraction.deserializeNBT(value), 0.0)
|
||||
return MatterValue(ImpreciseFraction.deserializeNBT(value), 0.0)
|
||||
}
|
||||
|
||||
override fun canDecompose(stack: ItemStack) = false
|
||||
|
@ -0,0 +1,148 @@
|
||||
package ru.dbotthepony.mc.otm.matter
|
||||
|
||||
import com.google.gson.JsonObject
|
||||
import com.google.gson.JsonParseException
|
||||
import com.google.gson.JsonPrimitive
|
||||
import com.google.gson.JsonSyntaxException
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.tags.ItemTags
|
||||
import net.minecraft.tags.TagKey
|
||||
import net.minecraft.world.item.Item
|
||||
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
|
||||
import ru.dbotthepony.mc.otm.core.set
|
||||
|
||||
sealed class AbstractRegistryAction {
|
||||
sealed class Condition {
|
||||
abstract fun test(): Boolean
|
||||
}
|
||||
|
||||
class CombinedCondition(val conditions: Collection<Condition>) : Condition() {
|
||||
override fun test(): Boolean {
|
||||
return conditions.all { it.test() }
|
||||
}
|
||||
}
|
||||
|
||||
val errorOnFailure: Boolean
|
||||
val tag: TagKey<Item>?
|
||||
val key: ResourceLocation?
|
||||
val matter: ImpreciseFraction?
|
||||
val complexity: Double?
|
||||
val priority: Int?
|
||||
|
||||
constructor(json: JsonObject) {
|
||||
errorOnFailure = json["error_on_failure"]?.asBoolean ?: false
|
||||
priority = json["priority"]?.asInt
|
||||
|
||||
val id = json["id"]?.asString ?: throw JsonParseException("Missing `id` value")
|
||||
|
||||
if (id.startsWith("#")) {
|
||||
if (id.startsWith("#:")) {
|
||||
throw JsonSyntaxException("Invalid `id` value: $id")
|
||||
}
|
||||
|
||||
tag = ItemTags.create(
|
||||
ResourceLocation.tryParse(id.substring(1)) ?: throw JsonSyntaxException("Invalid `id` value: $id")
|
||||
)
|
||||
key = null
|
||||
} else {
|
||||
key = ResourceLocation.tryParse(id) ?: throw JsonSyntaxException("Invalid `id` value: $id")
|
||||
tag = null
|
||||
}
|
||||
|
||||
try {
|
||||
matter = json["matter"]?.asString?.let(::ImpreciseFraction)
|
||||
|
||||
if (matter != null && !matter.isPositive) {
|
||||
throw JsonParseException("Can't have non-positive matter value. To remove an entry from registry please use 'delete' action instead.")
|
||||
}
|
||||
} catch(err: NumberFormatException) {
|
||||
throw JsonParseException("Invalid `matter` field: ${json["matter"]}", err)
|
||||
}
|
||||
|
||||
try {
|
||||
complexity = json["complexity"]?.asString?.toDouble()
|
||||
|
||||
if (complexity != null && complexity <= 0.0) {
|
||||
throw JsonParseException("Can't have non-positive complexity. To remove an entry from registry please use 'delete' action instead.")
|
||||
}
|
||||
} catch(err: NumberFormatException) {
|
||||
throw JsonParseException("Invalid `complexity` field: ${json["complexity"]}", err)
|
||||
}
|
||||
}
|
||||
|
||||
constructor(
|
||||
tag: TagKey<Item>,
|
||||
matter: ImpreciseFraction?,
|
||||
complexity: Double?,
|
||||
priority: Int? = null,
|
||||
errorOnFailure: Boolean = false
|
||||
) {
|
||||
this.tag = tag
|
||||
this.key = null
|
||||
this.matter = matter
|
||||
this.complexity = complexity
|
||||
this.priority = priority
|
||||
this.errorOnFailure = errorOnFailure
|
||||
|
||||
if (matter != null && !matter.isPositive) {
|
||||
throw IllegalArgumentException("Can't have non-positive matter value. To remove an entry from registry please use 'delete' action instead.")
|
||||
}
|
||||
|
||||
if (complexity != null && complexity <= 0.0) {
|
||||
throw IllegalArgumentException("Can't have non-positive complexity. To remove an entry from registry please use 'delete' action instead.")
|
||||
}
|
||||
}
|
||||
|
||||
constructor(
|
||||
key: ResourceLocation,
|
||||
matter: ImpreciseFraction?,
|
||||
complexity: Double?,
|
||||
priority: Int? = null,
|
||||
errorOnFailure: Boolean = false
|
||||
) {
|
||||
this.tag = null
|
||||
this.key = key
|
||||
this.matter = matter
|
||||
this.complexity = complexity
|
||||
this.priority = priority
|
||||
this.errorOnFailure = errorOnFailure
|
||||
|
||||
if (matter != null && !matter.isPositive) {
|
||||
throw IllegalArgumentException("Can't have non-positive matter value. To remove an entry from registry please use 'delete' action instead.")
|
||||
}
|
||||
|
||||
if (complexity != null && complexity <= 0.0) {
|
||||
throw IllegalArgumentException("Can't have non-positive complexity. To remove an entry from registry please use 'delete' action instead.")
|
||||
}
|
||||
}
|
||||
|
||||
fun checkConditions(): Boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
abstract fun update(registry: MutableCollection<MatterManager.MutableEntry>, modifier: ResourceLocation)
|
||||
|
||||
protected inline fun fail(reason: () -> String) {
|
||||
if (errorOnFailure) {
|
||||
throw JsonParseException(reason.invoke())
|
||||
}
|
||||
}
|
||||
|
||||
open fun toJson(): JsonObject {
|
||||
return JsonObject().also {
|
||||
if (key != null)
|
||||
it["id"] = JsonPrimitive(key.toString())
|
||||
else
|
||||
it["id"] = JsonPrimitive("#${tag!!.location}")
|
||||
|
||||
if (priority != null)
|
||||
it["priority"] = priority
|
||||
|
||||
if (matter != null)
|
||||
it["matter"] = matter.toString()
|
||||
|
||||
if (complexity != null)
|
||||
it["complexity"] = complexity
|
||||
}
|
||||
}
|
||||
}
|
60
src/main/kotlin/ru/dbotthepony/mc/otm/matter/DeleteAction.kt
Normal file
60
src/main/kotlin/ru/dbotthepony/mc/otm/matter/DeleteAction.kt
Normal file
@ -0,0 +1,60 @@
|
||||
package ru.dbotthepony.mc.otm.matter
|
||||
|
||||
import com.google.gson.JsonObject
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.tags.TagKey
|
||||
import net.minecraft.world.item.Item
|
||||
import ru.dbotthepony.mc.otm.core.set
|
||||
|
||||
class DeleteAction : AbstractRegistryAction {
|
||||
constructor(
|
||||
tag: TagKey<Item>,
|
||||
errorOnFailure: Boolean = false,
|
||||
) : super(tag = tag, errorOnFailure = errorOnFailure, matter = null, complexity = null)
|
||||
|
||||
constructor(
|
||||
key: ResourceLocation,
|
||||
errorOnFailure: Boolean = false,
|
||||
) : super(key = key, errorOnFailure = errorOnFailure, matter = null, complexity = null)
|
||||
|
||||
constructor(json: JsonObject) : super(json)
|
||||
|
||||
override fun toJson(): JsonObject {
|
||||
return super.toJson().also {
|
||||
it["action"] = "delete"
|
||||
}
|
||||
}
|
||||
|
||||
override fun update(registry: MutableCollection<MatterManager.MutableEntry>, modifier: ResourceLocation) {
|
||||
if (!checkConditions()) {
|
||||
return
|
||||
}
|
||||
|
||||
check(matter == null) { "Delete action can't have matter value (for $modifier)" }
|
||||
check(complexity == null) { "Delete action can't have complexity value (for $modifier)" }
|
||||
|
||||
if (key != null) {
|
||||
val iterator = registry.iterator()
|
||||
|
||||
for (value in iterator) {
|
||||
if (value is MatterManager.MutableKeyEntry && value.key == key) {
|
||||
iterator.remove()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
fail { "Could not find matter value with key $key" }
|
||||
} else {
|
||||
val iterator = registry.iterator()
|
||||
|
||||
for (value in iterator) {
|
||||
if (value is MatterManager.MutableTagEntry && value.tag == tag) {
|
||||
iterator.remove()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
fail { "Could not find matter value with tag $tag" }
|
||||
}
|
||||
}
|
||||
}
|
@ -3,7 +3,7 @@ package ru.dbotthepony.mc.otm.matter
|
||||
import net.minecraft.world.item.ItemStack
|
||||
|
||||
interface IMatterItem {
|
||||
fun getMatterValue(stack: ItemStack): MatterManager.IMatterValue?
|
||||
fun getMatterValue(stack: ItemStack): IMatterValue?
|
||||
fun hasMatterValue(stack: ItemStack) = getMatterValue(stack) != null
|
||||
fun canDecompose(stack: ItemStack): Boolean
|
||||
}
|
||||
|
43
src/main/kotlin/ru/dbotthepony/mc/otm/matter/IMatterValue.kt
Normal file
43
src/main/kotlin/ru/dbotthepony/mc/otm/matter/IMatterValue.kt
Normal file
@ -0,0 +1,43 @@
|
||||
package ru.dbotthepony.mc.otm.matter
|
||||
|
||||
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
|
||||
|
||||
interface IMatterValue : Comparable<IMatterValue> {
|
||||
val matter: ImpreciseFraction
|
||||
val complexity: Double
|
||||
|
||||
val hasMatterValue: Boolean get() = matter.isPositive && complexity > 0.0
|
||||
|
||||
operator fun plus(other: IMatterValue): IMatterValue {
|
||||
return MatterValue(matter + other.matter, complexity + other.complexity)
|
||||
}
|
||||
|
||||
operator fun minus(other: IMatterValue): IMatterValue {
|
||||
return MatterValue(matter - other.matter, complexity - other.complexity)
|
||||
}
|
||||
|
||||
override fun compareTo(other: IMatterValue): Int {
|
||||
val matterComparison = matter.compareTo(other.matter)
|
||||
|
||||
if (matterComparison == 0) {
|
||||
return complexity.compareTo(other.complexity)
|
||||
}
|
||||
|
||||
return matterComparison
|
||||
}
|
||||
|
||||
/**
|
||||
* ZERO
|
||||
*/
|
||||
companion object : IMatterValue {
|
||||
override val matter: ImpreciseFraction
|
||||
get() = ImpreciseFraction.ZERO
|
||||
override val complexity: Double
|
||||
get() = 0.0
|
||||
}
|
||||
}
|
||||
|
||||
data class MatterValue(
|
||||
override val matter: ImpreciseFraction,
|
||||
override val complexity: Double
|
||||
) : IMatterValue
|
161
src/main/kotlin/ru/dbotthepony/mc/otm/matter/InsertAction.kt
Normal file
161
src/main/kotlin/ru/dbotthepony/mc/otm/matter/InsertAction.kt
Normal file
@ -0,0 +1,161 @@
|
||||
package ru.dbotthepony.mc.otm.matter
|
||||
|
||||
import com.google.gson.JsonObject
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.tags.TagKey
|
||||
import net.minecraft.world.item.Item
|
||||
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
|
||||
import ru.dbotthepony.mc.otm.core.probablyParallelStream
|
||||
import ru.dbotthepony.mc.otm.core.set
|
||||
|
||||
class InsertAction : AbstractRegistryAction {
|
||||
val replaceIfExists: Boolean
|
||||
val comparePriority: Boolean
|
||||
|
||||
constructor(
|
||||
key: ResourceLocation,
|
||||
matter: ImpreciseFraction?,
|
||||
complexity: Double?,
|
||||
priority: Int? = null,
|
||||
errorOnFailure: Boolean = false,
|
||||
replaceIfExists: Boolean = false,
|
||||
comparePriority: Boolean = true,
|
||||
) : super(key = key, matter = matter, complexity = complexity, priority = priority, errorOnFailure = errorOnFailure) {
|
||||
this.replaceIfExists = replaceIfExists
|
||||
this.comparePriority = comparePriority
|
||||
}
|
||||
|
||||
constructor(
|
||||
tag: TagKey<Item>,
|
||||
matter: ImpreciseFraction?,
|
||||
complexity: Double?,
|
||||
priority: Int? = null,
|
||||
errorOnFailure: Boolean = false,
|
||||
replaceIfExists: Boolean = false,
|
||||
comparePriority: Boolean = true,
|
||||
) : super(tag = tag, matter = matter, complexity = complexity, priority = priority, errorOnFailure = errorOnFailure) {
|
||||
this.replaceIfExists = replaceIfExists
|
||||
this.comparePriority = comparePriority
|
||||
}
|
||||
|
||||
constructor(json: JsonObject) : super(json) {
|
||||
this.replaceIfExists = json["replace_if_exists"]?.asBoolean ?: false
|
||||
this.comparePriority = json["compare_priority"]?.asBoolean ?: true
|
||||
}
|
||||
|
||||
override fun toJson(): JsonObject {
|
||||
checkNotNull(matter) { "Missing matter value, which is required for insert action" }
|
||||
checkNotNull(complexity) { "Missing complexity value, which is required for insert action" }
|
||||
|
||||
return super.toJson().also {
|
||||
it["action"] = "insert"
|
||||
it["replace_if_exists"] = replaceIfExists
|
||||
it["compare_priority"] = comparePriority
|
||||
}
|
||||
}
|
||||
|
||||
override fun update(registry: MutableCollection<MatterManager.MutableEntry>, modifier: ResourceLocation) {
|
||||
checkNotNull(matter) { "Missing matter value, which is required for insert action (for $modifier)" }
|
||||
checkNotNull(complexity) { "Missing complexity value, which is required for insert action (for $modifier)" }
|
||||
|
||||
check(!comparePriority || priority != null) { "If compare_priority is true then priority must not be null (for $modifier)" }
|
||||
|
||||
if (!checkConditions()) {
|
||||
return
|
||||
}
|
||||
|
||||
if (key != null) {
|
||||
if (replaceIfExists) {
|
||||
// search & replace in parallel, if possible
|
||||
val replaced = registry.probablyParallelStream().anyMatch {
|
||||
if (it is MatterManager.MutableKeyEntry && it.key == key) {
|
||||
if (!comparePriority || it.priority < priority!!) {
|
||||
it.matter = matter
|
||||
it.complexity = complexity
|
||||
it.priority = priority ?: 0
|
||||
it.modificationChain.clear()
|
||||
it.modificationChain.add(modifier)
|
||||
}
|
||||
|
||||
return@anyMatch true
|
||||
} else {
|
||||
return@anyMatch false
|
||||
}
|
||||
}
|
||||
|
||||
if (!replaced) {
|
||||
registry.add(
|
||||
MatterManager.MutableKeyEntry(
|
||||
key,
|
||||
mutableListOf(modifier),
|
||||
matter,
|
||||
complexity,
|
||||
priority ?: 0
|
||||
)
|
||||
)
|
||||
}
|
||||
} else {
|
||||
if (registry.probablyParallelStream().anyMatch { it is MatterManager.MutableKeyEntry && it.key == key }) {
|
||||
fail { "Value with key $key already exists" }
|
||||
return
|
||||
}
|
||||
|
||||
registry.add(
|
||||
MatterManager.MutableKeyEntry(
|
||||
key,
|
||||
mutableListOf(modifier),
|
||||
matter,
|
||||
complexity,
|
||||
priority ?: 0
|
||||
)
|
||||
)
|
||||
}
|
||||
} else {
|
||||
if (replaceIfExists) {
|
||||
// search & replace in parallel, if possible
|
||||
val replaced = registry.probablyParallelStream().anyMatch {
|
||||
if (it is MatterManager.MutableTagEntry && it.tag == tag) {
|
||||
if (!comparePriority || it.priority < priority!!) {
|
||||
it.matter = matter
|
||||
it.complexity = complexity
|
||||
it.priority = priority ?: 0
|
||||
it.modificationChain.clear()
|
||||
it.modificationChain.add(modifier)
|
||||
}
|
||||
|
||||
return@anyMatch true
|
||||
} else {
|
||||
return@anyMatch false
|
||||
}
|
||||
}
|
||||
|
||||
if (!replaced) {
|
||||
registry.add(
|
||||
MatterManager.MutableTagEntry(
|
||||
tag!!,
|
||||
mutableListOf(modifier),
|
||||
matter,
|
||||
complexity,
|
||||
priority ?: 0
|
||||
)
|
||||
)
|
||||
}
|
||||
} else {
|
||||
if (registry.probablyParallelStream().anyMatch { it is MatterManager.MutableTagEntry && it.tag == tag }) {
|
||||
fail { "Value with tag $tag already exists" }
|
||||
return
|
||||
}
|
||||
|
||||
registry.add(
|
||||
MatterManager.MutableTagEntry(
|
||||
tag!!,
|
||||
mutableListOf(modifier),
|
||||
matter,
|
||||
complexity,
|
||||
priority ?: 0
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -18,7 +18,7 @@ open class MatterDataProvider(protected val dataGenerator: DataGenerator, val na
|
||||
constructor(event: GatherDataEvent) : this(event.generator, event.modContainer.namespace)
|
||||
|
||||
protected val pathProvider: DataGenerator.PathProvider = dataGenerator.createPathProvider(DataGenerator.Target.DATA_PACK, MatterManager.DIRECTORY)
|
||||
protected val actions = LinkedHashMap<ResourceLocation, MatterManager.AbstractRegistryAction>()
|
||||
protected val actions = LinkedHashMap<ResourceLocation, AbstractRegistryAction>()
|
||||
|
||||
sealed class Configuration(val name: ResourceLocation) {
|
||||
var errorOnFailure: Boolean = false
|
||||
@ -54,20 +54,20 @@ open class MatterDataProvider(protected val dataGenerator: DataGenerator, val na
|
||||
check(complexity == null || (complexity ?: throw ConcurrentModificationException()) >= 0.0) { "Invalid matter value: ${matter ?: throw ConcurrentModificationException()}" }
|
||||
}
|
||||
|
||||
abstract fun build(): MatterManager.AbstractRegistryAction
|
||||
abstract fun build(): AbstractRegistryAction
|
||||
}
|
||||
|
||||
class InsertConfiguration(name: ResourceLocation) : Configuration(name) {
|
||||
var replaceIfExists: Boolean = false
|
||||
var comparePriority: Boolean = false
|
||||
|
||||
override fun build(): MatterManager.InsertAction {
|
||||
override fun build(): InsertAction {
|
||||
checkKeyTag()
|
||||
checkMatterValues()
|
||||
check(matter != null && complexity != null) { "You must define both matter value and complexity for $name" }
|
||||
|
||||
if (key != null) {
|
||||
return MatterManager.InsertAction(
|
||||
return InsertAction(
|
||||
key = key ?: throw ConcurrentModificationException(),
|
||||
matter = matter,
|
||||
complexity = complexity,
|
||||
@ -77,7 +77,7 @@ open class MatterDataProvider(protected val dataGenerator: DataGenerator, val na
|
||||
comparePriority = comparePriority
|
||||
)
|
||||
} else {
|
||||
return MatterManager.InsertAction(
|
||||
return InsertAction(
|
||||
tag = tag ?: throw ConcurrentModificationException(),
|
||||
matter = matter,
|
||||
complexity = complexity,
|
||||
@ -91,19 +91,19 @@ open class MatterDataProvider(protected val dataGenerator: DataGenerator, val na
|
||||
}
|
||||
|
||||
class DeleteConfiguration(name: ResourceLocation) : Configuration(name) {
|
||||
override fun build(): MatterManager.DeleteAction {
|
||||
override fun build(): DeleteAction {
|
||||
checkKeyTag()
|
||||
|
||||
check(matter == null) { "Delete action can't have matter value" }
|
||||
check(complexity == null) { "Delete action can't have complexity value" }
|
||||
|
||||
if (key != null) {
|
||||
return MatterManager.DeleteAction(
|
||||
return DeleteAction(
|
||||
key = key ?: throw ConcurrentModificationException(),
|
||||
errorOnFailure = errorOnFailure,
|
||||
)
|
||||
} else {
|
||||
return MatterManager.DeleteAction(
|
||||
return DeleteAction(
|
||||
tag = tag ?: throw ConcurrentModificationException(),
|
||||
errorOnFailure = errorOnFailure,
|
||||
)
|
||||
@ -112,29 +112,29 @@ open class MatterDataProvider(protected val dataGenerator: DataGenerator, val na
|
||||
}
|
||||
|
||||
class UpdateConfiguration(name: ResourceLocation) : Configuration(name) {
|
||||
val matterFunctions = ArrayList<MatterManager.UpdateAction.BoundFunction<ImpreciseFraction>>()
|
||||
val complexityFunctions = ArrayList<MatterManager.UpdateAction.BoundFunction<Double>>()
|
||||
val priorityFunctions = ArrayList<MatterManager.UpdateAction.BoundFunction<Int>>()
|
||||
val matterFunctions = ArrayList<UpdateAction.BoundFunction<ImpreciseFraction>>()
|
||||
val complexityFunctions = ArrayList<UpdateAction.BoundFunction<Double>>()
|
||||
val priorityFunctions = ArrayList<UpdateAction.BoundFunction<Int>>()
|
||||
|
||||
fun addMatterFunction(function: MatterManager.UpdateAction.Function, value: ImpreciseFraction): UpdateConfiguration {
|
||||
matterFunctions.add(MatterManager.UpdateAction.BoundFunction(function, value))
|
||||
fun addMatterFunction(function: UpdateAction.Function, value: ImpreciseFraction): UpdateConfiguration {
|
||||
matterFunctions.add(UpdateAction.BoundFunction(function, value))
|
||||
matter = null
|
||||
return this
|
||||
}
|
||||
|
||||
fun addComplexityFunction(function: MatterManager.UpdateAction.Function, value: Double): UpdateConfiguration {
|
||||
complexityFunctions.add(MatterManager.UpdateAction.BoundFunction(function, value))
|
||||
fun addComplexityFunction(function: UpdateAction.Function, value: Double): UpdateConfiguration {
|
||||
complexityFunctions.add(UpdateAction.BoundFunction(function, value))
|
||||
matter = null
|
||||
return this
|
||||
}
|
||||
|
||||
fun addPriorityFunction(function: MatterManager.UpdateAction.Function, value: Int): UpdateConfiguration {
|
||||
priorityFunctions.add(MatterManager.UpdateAction.BoundFunction(function, value))
|
||||
fun addPriorityFunction(function: UpdateAction.Function, value: Int): UpdateConfiguration {
|
||||
priorityFunctions.add(UpdateAction.BoundFunction(function, value))
|
||||
matter = null
|
||||
return this
|
||||
}
|
||||
|
||||
override fun build(): MatterManager.UpdateAction {
|
||||
override fun build(): UpdateAction {
|
||||
check(!(matterFunctions.isNotEmpty() && matter != null)) { "Can't have both matter value and matter value functions be defined at the same time" }
|
||||
check(!(complexityFunctions.isNotEmpty() && complexity != null)) { "Can't have both complexity and complexity functions be defined at the same time" }
|
||||
check(!(priorityFunctions.isNotEmpty() && priority != null)) { "Can't have both priority and priority functions be defined at the same time" }
|
||||
@ -149,7 +149,7 @@ open class MatterDataProvider(protected val dataGenerator: DataGenerator, val na
|
||||
checkKeyTag()
|
||||
|
||||
if (key != null) {
|
||||
return MatterManager.UpdateAction(
|
||||
return UpdateAction(
|
||||
key = key ?: throw ConcurrentModificationException(),
|
||||
matter = matter,
|
||||
complexity = complexity,
|
||||
@ -160,7 +160,7 @@ open class MatterDataProvider(protected val dataGenerator: DataGenerator, val na
|
||||
priorityFunctions = priorityFunctions
|
||||
)
|
||||
} else {
|
||||
return MatterManager.UpdateAction(
|
||||
return UpdateAction(
|
||||
tag = tag ?: throw ConcurrentModificationException(),
|
||||
matter = matter,
|
||||
complexity = complexity,
|
||||
@ -735,7 +735,7 @@ open class MatterDataProvider(protected val dataGenerator: DataGenerator, val na
|
||||
}
|
||||
}
|
||||
|
||||
fun insert(name: ResourceLocation, configurator: InsertConfiguration.() -> Unit): MatterManager.InsertAction {
|
||||
fun insert(name: ResourceLocation, configurator: InsertConfiguration.() -> Unit): InsertAction {
|
||||
check(!actions.containsKey(name)) { "Already has action with name $name" }
|
||||
val config = InsertConfiguration(name)
|
||||
configurator.invoke(config)
|
||||
@ -744,7 +744,7 @@ open class MatterDataProvider(protected val dataGenerator: DataGenerator, val na
|
||||
return built
|
||||
}
|
||||
|
||||
fun delete(name: ResourceLocation, configurator: DeleteConfiguration.() -> Unit): MatterManager.DeleteAction {
|
||||
fun delete(name: ResourceLocation, configurator: DeleteConfiguration.() -> Unit): DeleteAction {
|
||||
check(!actions.containsKey(name)) { "Already has action with name $name" }
|
||||
val config = DeleteConfiguration(name)
|
||||
configurator.invoke(config)
|
||||
@ -753,7 +753,7 @@ open class MatterDataProvider(protected val dataGenerator: DataGenerator, val na
|
||||
return built
|
||||
}
|
||||
|
||||
fun update(name: ResourceLocation, configurator: UpdateConfiguration.() -> Unit): MatterManager.UpdateAction {
|
||||
fun update(name: ResourceLocation, configurator: UpdateConfiguration.() -> Unit): UpdateAction {
|
||||
check(!actions.containsKey(name)) { "Already has action with name $name" }
|
||||
val config = UpdateConfiguration(name)
|
||||
configurator.invoke(config)
|
||||
@ -774,42 +774,42 @@ open class MatterDataProvider(protected val dataGenerator: DataGenerator, val na
|
||||
}
|
||||
}
|
||||
|
||||
fun insert(name: ItemLike, configurator: InsertConfiguration.() -> Unit): MatterManager.InsertAction {
|
||||
fun insert(name: ItemLike, configurator: InsertConfiguration.() -> Unit): InsertAction {
|
||||
return insert(updateLocation(name.asItem().registryName ?: throw NullPointerException("${name.asItem()} does not have registry name!"), "item/")) {
|
||||
key = name.asItem().registryName ?: throw ConcurrentModificationException()
|
||||
configurator.invoke(this)
|
||||
}
|
||||
}
|
||||
|
||||
fun delete(name: ItemLike, configurator: DeleteConfiguration.() -> Unit): MatterManager.DeleteAction {
|
||||
fun delete(name: ItemLike, configurator: DeleteConfiguration.() -> Unit): DeleteAction {
|
||||
return delete(updateLocation(name.asItem().registryName ?: throw NullPointerException("${name.asItem()} does not have registry name!"), "item/")) {
|
||||
key = name.asItem().registryName ?: throw ConcurrentModificationException()
|
||||
configurator.invoke(this)
|
||||
}
|
||||
}
|
||||
|
||||
fun update(name: ItemLike, configurator: UpdateConfiguration.() -> Unit): MatterManager.UpdateAction {
|
||||
fun update(name: ItemLike, configurator: UpdateConfiguration.() -> Unit): UpdateAction {
|
||||
return update(updateLocation(name.asItem().registryName ?: throw NullPointerException("${name.asItem()} does not have registry name!"), "item/")) {
|
||||
key = name.asItem().registryName ?: throw ConcurrentModificationException()
|
||||
configurator.invoke(this)
|
||||
}
|
||||
}
|
||||
|
||||
fun insert(name: TagKey<Item>, configurator: InsertConfiguration.() -> Unit): MatterManager.InsertAction {
|
||||
fun insert(name: TagKey<Item>, configurator: InsertConfiguration.() -> Unit): InsertAction {
|
||||
return insert(updateLocation(name.location, "tag/")) {
|
||||
tag = name
|
||||
configurator.invoke(this)
|
||||
}
|
||||
}
|
||||
|
||||
fun delete(name: TagKey<Item>, configurator: DeleteConfiguration.() -> Unit): MatterManager.DeleteAction {
|
||||
fun delete(name: TagKey<Item>, configurator: DeleteConfiguration.() -> Unit): DeleteAction {
|
||||
return delete(updateLocation(name.location, "tag/")) {
|
||||
tag = name
|
||||
configurator.invoke(this)
|
||||
}
|
||||
}
|
||||
|
||||
fun update(name: TagKey<Item>, configurator: UpdateConfiguration.() -> Unit): MatterManager.UpdateAction {
|
||||
fun update(name: TagKey<Item>, configurator: UpdateConfiguration.() -> Unit): UpdateAction {
|
||||
return update(updateLocation(name.location, "tag/")) {
|
||||
tag = name
|
||||
configurator.invoke(this)
|
||||
@ -886,8 +886,8 @@ open class MatterDataProvider(protected val dataGenerator: DataGenerator, val na
|
||||
*/
|
||||
protected open fun addActions() {}
|
||||
|
||||
protected val added = ArrayList<MatterManager.AbstractRegistryAction>()
|
||||
val addedView: List<MatterManager.AbstractRegistryAction> = Collections.unmodifiableList(added)
|
||||
protected val added = ArrayList<AbstractRegistryAction>()
|
||||
val addedView: List<AbstractRegistryAction> = Collections.unmodifiableList(added)
|
||||
|
||||
final override fun run(output: CachedOutput) {
|
||||
addActions()
|
||||
|
@ -2,21 +2,16 @@ package ru.dbotthepony.mc.otm.matter
|
||||
|
||||
import com.google.common.collect.ImmutableList
|
||||
import com.google.gson.GsonBuilder
|
||||
import com.google.gson.JsonArray
|
||||
import com.google.gson.JsonElement
|
||||
import com.google.gson.JsonObject
|
||||
import com.google.gson.JsonParseException
|
||||
import com.google.gson.JsonPrimitive
|
||||
import com.google.gson.JsonSyntaxException
|
||||
import com.mojang.blaze3d.platform.InputConstants
|
||||
import it.unimi.dsi.fastutil.objects.Reference2ObjectFunction
|
||||
import it.unimi.dsi.fastutil.objects.Reference2ObjectOpenHashMap
|
||||
import net.minecraft.ChatFormatting
|
||||
import net.minecraft.client.Minecraft
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.server.packs.resources.ResourceManager
|
||||
import net.minecraft.server.packs.resources.SimpleJsonResourceReloadListener
|
||||
import net.minecraft.tags.ItemTags
|
||||
import net.minecraft.tags.TagKey
|
||||
import net.minecraft.util.profiling.ProfilerFiller
|
||||
import net.minecraft.world.item.Item
|
||||
@ -36,14 +31,9 @@ import ru.dbotthepony.mc.otm.core.ImpreciseFraction
|
||||
import ru.dbotthepony.mc.otm.core.TranslatableComponent
|
||||
import ru.dbotthepony.mc.otm.core.formatMatterFull
|
||||
import ru.dbotthepony.mc.otm.core.formatSiComponent
|
||||
import ru.dbotthepony.mc.otm.core.integerDivisionDown
|
||||
import ru.dbotthepony.mc.otm.core.integerDivisionUp
|
||||
import ru.dbotthepony.mc.otm.core.isZero
|
||||
import ru.dbotthepony.mc.otm.core.orNull
|
||||
import ru.dbotthepony.mc.otm.core.probablyParallelStream
|
||||
import ru.dbotthepony.mc.otm.core.registryName
|
||||
import ru.dbotthepony.mc.otm.core.set
|
||||
import ru.dbotthepony.mc.otm.data.stream
|
||||
import ru.dbotthepony.mc.otm.storage.ItemStackWrapper
|
||||
import java.math.BigInteger
|
||||
import java.util.Collections
|
||||
@ -53,599 +43,6 @@ import kotlin.math.pow
|
||||
object MatterManager : SimpleJsonResourceReloadListener(GsonBuilder().setPrettyPrinting().disableHtmlEscaping().create(), "otm_matter") {
|
||||
const val DIRECTORY = "otm_matter"
|
||||
|
||||
sealed class AbstractRegistryAction {
|
||||
sealed class Condition {
|
||||
abstract fun test(): Boolean
|
||||
}
|
||||
|
||||
class CombinedCondition(val conditions: Collection<Condition>) : Condition() {
|
||||
override fun test(): Boolean {
|
||||
return conditions.all { it.test() }
|
||||
}
|
||||
}
|
||||
|
||||
val errorOnFailure: Boolean
|
||||
val tag: TagKey<Item>?
|
||||
val key: ResourceLocation?
|
||||
val matter: ImpreciseFraction?
|
||||
val complexity: Double?
|
||||
val priority: Int?
|
||||
|
||||
constructor(json: JsonObject) {
|
||||
errorOnFailure = json["error_on_failure"]?.asBoolean ?: false
|
||||
priority = json["priority"]?.asInt
|
||||
|
||||
val id = json["id"]?.asString ?: throw JsonParseException("Missing `id` value")
|
||||
|
||||
if (id.startsWith("#")) {
|
||||
if (id.startsWith("#:")) {
|
||||
throw JsonSyntaxException("Invalid `id` value: $id")
|
||||
}
|
||||
|
||||
tag = ItemTags.create(ResourceLocation.tryParse(id.substring(1)) ?: throw JsonSyntaxException("Invalid `id` value: $id"))
|
||||
key = null
|
||||
} else {
|
||||
key = ResourceLocation.tryParse(id) ?: throw JsonSyntaxException("Invalid `id` value: $id")
|
||||
tag = null
|
||||
}
|
||||
|
||||
try {
|
||||
matter = json["matter"]?.asString?.let(::ImpreciseFraction)
|
||||
|
||||
if (matter != null && !matter.isPositive) {
|
||||
throw JsonParseException("Can't have non-positive matter value. To remove an entry from registry please use 'delete' action instead.")
|
||||
}
|
||||
} catch(err: NumberFormatException) {
|
||||
throw JsonParseException("Invalid `matter` field: ${json["matter"]}", err)
|
||||
}
|
||||
|
||||
try {
|
||||
complexity = json["complexity"]?.asString?.toDouble()
|
||||
|
||||
if (complexity != null && complexity <= 0.0) {
|
||||
throw JsonParseException("Can't have non-positive complexity. To remove an entry from registry please use 'delete' action instead.")
|
||||
}
|
||||
} catch(err: NumberFormatException) {
|
||||
throw JsonParseException("Invalid `complexity` field: ${json["complexity"]}", err)
|
||||
}
|
||||
}
|
||||
|
||||
constructor(
|
||||
tag: TagKey<Item>,
|
||||
matter: ImpreciseFraction?,
|
||||
complexity: Double?,
|
||||
priority: Int? = null,
|
||||
errorOnFailure: Boolean = false
|
||||
) {
|
||||
this.tag = tag
|
||||
this.key = null
|
||||
this.matter = matter
|
||||
this.complexity = complexity
|
||||
this.priority = priority
|
||||
this.errorOnFailure = errorOnFailure
|
||||
|
||||
if (matter != null && !matter.isPositive) {
|
||||
throw IllegalArgumentException("Can't have non-positive matter value. To remove an entry from registry please use 'delete' action instead.")
|
||||
}
|
||||
|
||||
if (complexity != null && complexity <= 0.0) {
|
||||
throw IllegalArgumentException("Can't have non-positive complexity. To remove an entry from registry please use 'delete' action instead.")
|
||||
}
|
||||
}
|
||||
|
||||
constructor(
|
||||
key: ResourceLocation,
|
||||
matter: ImpreciseFraction?,
|
||||
complexity: Double?,
|
||||
priority: Int? = null,
|
||||
errorOnFailure: Boolean = false
|
||||
) {
|
||||
this.tag = null
|
||||
this.key = key
|
||||
this.matter = matter
|
||||
this.complexity = complexity
|
||||
this.priority = priority
|
||||
this.errorOnFailure = errorOnFailure
|
||||
|
||||
if (matter != null && !matter.isPositive) {
|
||||
throw IllegalArgumentException("Can't have non-positive matter value. To remove an entry from registry please use 'delete' action instead.")
|
||||
}
|
||||
|
||||
if (complexity != null && complexity <= 0.0) {
|
||||
throw IllegalArgumentException("Can't have non-positive complexity. To remove an entry from registry please use 'delete' action instead.")
|
||||
}
|
||||
}
|
||||
|
||||
fun checkConditions(): Boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
abstract fun update(registry: MutableCollection<MutableEntry>, modifier: ResourceLocation)
|
||||
|
||||
protected inline fun fail(reason: () -> String) {
|
||||
if (errorOnFailure) {
|
||||
throw JsonParseException(reason.invoke())
|
||||
}
|
||||
}
|
||||
|
||||
open fun toJson(): JsonObject {
|
||||
return JsonObject().also {
|
||||
if (key != null)
|
||||
it["id"] = JsonPrimitive(key.toString())
|
||||
else
|
||||
it["id"] = JsonPrimitive("#${tag!!.location}")
|
||||
|
||||
if (priority != null)
|
||||
it["priority"] = priority
|
||||
|
||||
if (matter != null)
|
||||
it["matter"] = matter.toString()
|
||||
|
||||
if (complexity != null)
|
||||
it["complexity"] = complexity
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class InsertAction : AbstractRegistryAction {
|
||||
val replaceIfExists: Boolean
|
||||
val comparePriority: Boolean
|
||||
|
||||
constructor(
|
||||
key: ResourceLocation,
|
||||
matter: ImpreciseFraction?,
|
||||
complexity: Double?,
|
||||
priority: Int? = null,
|
||||
errorOnFailure: Boolean = false,
|
||||
replaceIfExists: Boolean = false,
|
||||
comparePriority: Boolean = true,
|
||||
) : super(key = key, matter = matter, complexity = complexity, priority = priority, errorOnFailure = errorOnFailure) {
|
||||
this.replaceIfExists = replaceIfExists
|
||||
this.comparePriority = comparePriority
|
||||
}
|
||||
|
||||
constructor(
|
||||
tag: TagKey<Item>,
|
||||
matter: ImpreciseFraction?,
|
||||
complexity: Double?,
|
||||
priority: Int? = null,
|
||||
errorOnFailure: Boolean = false,
|
||||
replaceIfExists: Boolean = false,
|
||||
comparePriority: Boolean = true,
|
||||
) : super(tag = tag, matter = matter, complexity = complexity, priority = priority, errorOnFailure = errorOnFailure) {
|
||||
this.replaceIfExists = replaceIfExists
|
||||
this.comparePriority = comparePriority
|
||||
}
|
||||
|
||||
constructor(json: JsonObject) : super(json) {
|
||||
this.replaceIfExists = json["replace_if_exists"]?.asBoolean ?: false
|
||||
this.comparePriority = json["compare_priority"]?.asBoolean ?: true
|
||||
}
|
||||
|
||||
override fun toJson(): JsonObject {
|
||||
checkNotNull(matter) { "Missing matter value, which is required for insert action" }
|
||||
checkNotNull(complexity) { "Missing complexity value, which is required for insert action" }
|
||||
|
||||
return super.toJson().also {
|
||||
it["action"] = "insert"
|
||||
it["replace_if_exists"] = replaceIfExists
|
||||
it["compare_priority"] = comparePriority
|
||||
}
|
||||
}
|
||||
|
||||
override fun update(registry: MutableCollection<MutableEntry>, modifier: ResourceLocation) {
|
||||
checkNotNull(matter) { "Missing matter value, which is required for insert action (for $modifier)" }
|
||||
checkNotNull(complexity) { "Missing complexity value, which is required for insert action (for $modifier)" }
|
||||
|
||||
check(!comparePriority || priority != null) { "If compare_priority is true then priority must not be null (for $modifier)" }
|
||||
|
||||
if (!checkConditions()) {
|
||||
return
|
||||
}
|
||||
|
||||
if (key != null) {
|
||||
if (replaceIfExists) {
|
||||
// search & replace in parallel, if possible
|
||||
val replaced = registry.probablyParallelStream().anyMatch {
|
||||
if (it is MutableKeyEntry && it.key == key) {
|
||||
if (!comparePriority || it.priority < priority!!) {
|
||||
it.matter = matter
|
||||
it.complexity = complexity
|
||||
it.priority = priority ?: 0
|
||||
it.modificationChain.clear()
|
||||
it.modificationChain.add(modifier)
|
||||
}
|
||||
|
||||
return@anyMatch true
|
||||
} else {
|
||||
return@anyMatch false
|
||||
}
|
||||
}
|
||||
|
||||
if (!replaced) {
|
||||
registry.add(MutableKeyEntry(key, mutableListOf(modifier), matter, complexity, priority ?: 0))
|
||||
}
|
||||
} else {
|
||||
if (registry.probablyParallelStream().anyMatch { it is MutableKeyEntry && it.key == key }) {
|
||||
fail { "Value with key $key already exists" }
|
||||
return
|
||||
}
|
||||
|
||||
registry.add(MutableKeyEntry(key, mutableListOf(modifier), matter, complexity, priority ?: 0))
|
||||
}
|
||||
} else {
|
||||
if (replaceIfExists) {
|
||||
// search & replace in parallel, if possible
|
||||
val replaced = registry.probablyParallelStream().anyMatch {
|
||||
if (it is MutableTagEntry && it.tag == tag) {
|
||||
if (!comparePriority || it.priority < priority!!) {
|
||||
it.matter = matter
|
||||
it.complexity = complexity
|
||||
it.priority = priority ?: 0
|
||||
it.modificationChain.clear()
|
||||
it.modificationChain.add(modifier)
|
||||
}
|
||||
|
||||
return@anyMatch true
|
||||
} else {
|
||||
return@anyMatch false
|
||||
}
|
||||
}
|
||||
|
||||
if (!replaced) {
|
||||
registry.add(MutableTagEntry(tag!!, mutableListOf(modifier), matter, complexity, priority ?: 0))
|
||||
}
|
||||
} else {
|
||||
if (registry.probablyParallelStream().anyMatch { it is MutableTagEntry && it.tag == tag }) {
|
||||
fail { "Value with tag $tag already exists" }
|
||||
return
|
||||
}
|
||||
|
||||
registry.add(MutableTagEntry(tag!!, mutableListOf(modifier), matter, complexity, priority ?: 0))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class DeleteAction : AbstractRegistryAction {
|
||||
constructor(
|
||||
tag: TagKey<Item>,
|
||||
errorOnFailure: Boolean = false,
|
||||
) : super(tag = tag, errorOnFailure = errorOnFailure, matter = null, complexity = null)
|
||||
|
||||
constructor(
|
||||
key: ResourceLocation,
|
||||
errorOnFailure: Boolean = false,
|
||||
) : super(key = key, errorOnFailure = errorOnFailure, matter = null, complexity = null)
|
||||
|
||||
constructor(json: JsonObject) : super(json)
|
||||
|
||||
override fun toJson(): JsonObject {
|
||||
return super.toJson().also {
|
||||
it["action"] = "delete"
|
||||
}
|
||||
}
|
||||
|
||||
override fun update(registry: MutableCollection<MutableEntry>, modifier: ResourceLocation) {
|
||||
if (!checkConditions()) {
|
||||
return
|
||||
}
|
||||
|
||||
check(matter == null) { "Delete action can't have matter value (for $modifier)" }
|
||||
check(complexity == null) { "Delete action can't have complexity value (for $modifier)" }
|
||||
|
||||
if (key != null) {
|
||||
val iterator = registry.iterator()
|
||||
|
||||
for (value in iterator) {
|
||||
if (value is MutableKeyEntry && value.key == key) {
|
||||
iterator.remove()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
fail { "Could not find matter value with key $key" }
|
||||
} else {
|
||||
val iterator = registry.iterator()
|
||||
|
||||
for (value in iterator) {
|
||||
if (value is MutableTagEntry && value.tag == tag) {
|
||||
iterator.remove()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
fail { "Could not find matter value with tag $tag" }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class UpdateAction : AbstractRegistryAction {
|
||||
enum class Function {
|
||||
ADD {
|
||||
override fun updateValue(self: Int, other: Int): Int = self + other
|
||||
override fun updateValue(self: ImpreciseFraction, other: ImpreciseFraction): ImpreciseFraction = self + other
|
||||
override fun updateValue(self: Double, other: Double): Double = self + other
|
||||
},
|
||||
SUBTRACT {
|
||||
override fun updateValue(self: Int, other: Int): Int = self - other
|
||||
override fun updateValue(self: ImpreciseFraction, other: ImpreciseFraction): ImpreciseFraction = self - other
|
||||
override fun updateValue(self: Double, other: Double): Double = self - other
|
||||
},
|
||||
MULTIPLY {
|
||||
override fun updateValue(self: Int, other: Int): Int = self * other
|
||||
override fun updateValue(self: ImpreciseFraction, other: ImpreciseFraction): ImpreciseFraction = self * other
|
||||
override fun updateValue(self: Double, other: Double): Double = self * other
|
||||
},
|
||||
DIVIDE {
|
||||
override fun updateValue(self: Int, other: Int): Int = self / other
|
||||
override fun updateValue(self: ImpreciseFraction, other: ImpreciseFraction): ImpreciseFraction = self / other
|
||||
override fun updateValue(self: Double, other: Double): Double = self / other
|
||||
},
|
||||
DIVIDE_UP {
|
||||
override fun updateValue(self: Int, other: Int): Int = integerDivisionUp(self, other)
|
||||
override fun updateValue(self: ImpreciseFraction, other: ImpreciseFraction): ImpreciseFraction = throw JsonParseException("Integer division up is available only for integers")
|
||||
override fun updateValue(self: Double, other: Double): Double = throw JsonParseException("Integer division up is available only for integers")
|
||||
},
|
||||
DIVIDE_DOWN {
|
||||
override fun updateValue(self: Int, other: Int): Int = integerDivisionDown(self, other)
|
||||
override fun updateValue(self: ImpreciseFraction, other: ImpreciseFraction): ImpreciseFraction = throw JsonParseException("Integer division down is available only for integers")
|
||||
override fun updateValue(self: Double, other: Double): Double = throw JsonParseException("Integer division down is available only for integers")
|
||||
},
|
||||
MODULO {
|
||||
override fun updateValue(self: Int, other: Int): Int = self % other
|
||||
override fun updateValue(self: ImpreciseFraction, other: ImpreciseFraction): ImpreciseFraction = self % other
|
||||
override fun updateValue(self: Double, other: Double): Double = self % other
|
||||
},
|
||||
AT_LEAST {
|
||||
override fun updateValue(self: Int, other: Int): Int = self.coerceAtLeast(other)
|
||||
override fun updateValue(self: ImpreciseFraction, other: ImpreciseFraction): ImpreciseFraction = self.coerceAtLeast(other)
|
||||
override fun updateValue(self: Double, other: Double): Double = self.coerceAtLeast(other)
|
||||
},
|
||||
AT_MOST {
|
||||
override fun updateValue(self: Int, other: Int): Int = self.coerceAtMost(other)
|
||||
override fun updateValue(self: ImpreciseFraction, other: ImpreciseFraction): ImpreciseFraction = self.coerceAtMost(other)
|
||||
override fun updateValue(self: Double, other: Double): Double = self.coerceAtMost(other)
|
||||
},
|
||||
;
|
||||
|
||||
protected abstract fun updateValue(self: Int, other: Int): Int
|
||||
protected abstract fun updateValue(self: ImpreciseFraction, other: ImpreciseFraction): ImpreciseFraction
|
||||
protected abstract fun updateValue(self: Double, other: Double): Double
|
||||
|
||||
fun <T : Number> updateValue(self: T, other: T): T {
|
||||
return when (self) {
|
||||
is ImpreciseFraction -> updateValue(self, other)
|
||||
is Double -> updateValue(self, other)
|
||||
is Int -> updateValue(self, other)
|
||||
else -> throw RuntimeException("Unknown number type: ${self::class.qualifiedName}")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class BoundFunction<T : Number>(val function: Function, val value: T) {
|
||||
fun apply(self: T): T {
|
||||
return function.updateValue(self, value)
|
||||
}
|
||||
|
||||
fun toJson(): JsonObject {
|
||||
return JsonObject().also {
|
||||
it["type"] = function.name
|
||||
|
||||
if (value is Int || value is Double)
|
||||
it["value"] = value
|
||||
else
|
||||
it["value"] = value.toString()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
inline fun <reified T : Number> getValue(value: JsonElement): T {
|
||||
return when (T::class) {
|
||||
ImpreciseFraction::class -> ImpreciseFraction(value.asString) as T
|
||||
Double::class -> value.asDouble as T
|
||||
Int::class -> value.asInt as T
|
||||
else -> throw RuntimeException("Unknown number type: ${T::class.qualifiedName}")
|
||||
}
|
||||
}
|
||||
|
||||
inline fun <reified T : Number> deserializeFunctionTree(input: JsonElement?, name: String): List<BoundFunction<T>> {
|
||||
if (input == null) {
|
||||
return listOf()
|
||||
}
|
||||
|
||||
if (input !is JsonArray) {
|
||||
throw JsonParseException("Expected $name to be JsonArray, ${input::class.qualifiedName} given")
|
||||
}
|
||||
|
||||
return input.stream().map {
|
||||
if (it !is JsonObject) {
|
||||
throw JsonParseException("All elements in function tree must be JsonObjects, ${it::class.qualifiedName} given")
|
||||
}
|
||||
|
||||
val type = it["type"]?.asString ?: throw JsonParseException("Invalid `type` value in function object")
|
||||
val value = it["value"] ?: throw JsonParseException("Missing `value` value in function object")
|
||||
|
||||
val parsedValue: T = getValue(value)
|
||||
val fn: Function
|
||||
|
||||
try {
|
||||
fn = Function.valueOf(type.uppercase())
|
||||
} catch (err: NoSuchElementException) {
|
||||
throw JsonParseException("No such function: $type", err)
|
||||
}
|
||||
|
||||
return@map BoundFunction(fn, parsedValue)
|
||||
}.collect(ImmutableList.toImmutableList())
|
||||
}
|
||||
|
||||
fun <T : Number> apply(value: T, funcs: Collection<BoundFunction<T>>): T {
|
||||
if (funcs.isEmpty()) {
|
||||
return value
|
||||
}
|
||||
|
||||
var newValue = value
|
||||
|
||||
for (func in funcs) {
|
||||
newValue = func.apply(newValue)
|
||||
}
|
||||
|
||||
return newValue
|
||||
}
|
||||
}
|
||||
|
||||
val matterFunctions: List<BoundFunction<ImpreciseFraction>>
|
||||
val complexityFunctions: List<BoundFunction<Double>>
|
||||
val priorityFunctions: List<BoundFunction<Int>>
|
||||
|
||||
constructor(json: JsonObject) : super(json) {
|
||||
matterFunctions = deserializeFunctionTree(json["matter_functions"], "matter_functions")
|
||||
complexityFunctions = deserializeFunctionTree(json["complexity_functions"], "complexity_functions")
|
||||
priorityFunctions = deserializeFunctionTree(json["priority_functions"], "priority_functions")
|
||||
}
|
||||
|
||||
constructor(
|
||||
tag: TagKey<Item>,
|
||||
matter: ImpreciseFraction? = null,
|
||||
complexity: Double? = null,
|
||||
priority: Int? = null,
|
||||
errorOnFailure: Boolean = false,
|
||||
matterFunctions: List<BoundFunction<ImpreciseFraction>> = ImmutableList.of(),
|
||||
complexityFunctions: List<BoundFunction<Double>> = ImmutableList.of(),
|
||||
priorityFunctions: List<BoundFunction<Int>> = ImmutableList.of(),
|
||||
) : super(tag = tag, matter = matter, complexity = complexity, priority = priority, errorOnFailure = errorOnFailure) {
|
||||
check(matter != null || complexity != null || priority != null || matterFunctions.isNotEmpty() || complexityFunctions.isNotEmpty() || priorityFunctions.isNotEmpty()) {
|
||||
"Can't update existing entries without anything specified"
|
||||
}
|
||||
|
||||
this.matterFunctions = ImmutableList.copyOf(matterFunctions)
|
||||
this.complexityFunctions = ImmutableList.copyOf(complexityFunctions)
|
||||
this.priorityFunctions = ImmutableList.copyOf(priorityFunctions)
|
||||
}
|
||||
|
||||
constructor(
|
||||
key: ResourceLocation,
|
||||
matter: ImpreciseFraction? = null,
|
||||
complexity: Double? = null,
|
||||
priority: Int? = null,
|
||||
errorOnFailure: Boolean = false,
|
||||
matterFunctions: List<BoundFunction<ImpreciseFraction>> = ImmutableList.of(),
|
||||
complexityFunctions: List<BoundFunction<Double>> = ImmutableList.of(),
|
||||
priorityFunctions: List<BoundFunction<Int>> = ImmutableList.of(),
|
||||
) : super(key = key, matter = matter, complexity = complexity, priority = priority, errorOnFailure = errorOnFailure) {
|
||||
check(matter != null || complexity != null || priority != null || matterFunctions.isNotEmpty() || complexityFunctions.isNotEmpty() || priorityFunctions.isNotEmpty()) {
|
||||
"Can't update existing entries without anything specified"
|
||||
}
|
||||
|
||||
this.matterFunctions = ImmutableList.copyOf(matterFunctions)
|
||||
this.complexityFunctions = ImmutableList.copyOf(complexityFunctions)
|
||||
this.priorityFunctions = ImmutableList.copyOf(priorityFunctions)
|
||||
}
|
||||
|
||||
override fun toJson(): JsonObject {
|
||||
return super.toJson().also {
|
||||
it["action"] = "update"
|
||||
|
||||
if (matterFunctions.isNotEmpty()) {
|
||||
it["matter_functions"] = JsonArray().also {
|
||||
for (fn in matterFunctions) {
|
||||
it.add(fn.toJson())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (complexityFunctions.isNotEmpty()) {
|
||||
it["complexity_functions"] = JsonArray().also {
|
||||
for (fn in complexityFunctions) {
|
||||
it.add(fn.toJson())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (priorityFunctions.isNotEmpty()) {
|
||||
it["priority_functions"] = JsonArray().also {
|
||||
for (fn in priorityFunctions) {
|
||||
it.add(fn.toJson())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun apply(value: MutableEntry, modifier: ResourceLocation) {
|
||||
if (matterFunctions.isNotEmpty())
|
||||
value.matter = apply(value.matter, matterFunctions)
|
||||
else if (matter != null)
|
||||
value.matter = matter
|
||||
|
||||
if (complexityFunctions.isNotEmpty())
|
||||
value.complexity = apply(value.complexity, complexityFunctions)
|
||||
else if (complexity != null)
|
||||
value.complexity = complexity
|
||||
|
||||
if (priorityFunctions.isNotEmpty())
|
||||
value.priority = apply(value.priority, priorityFunctions)
|
||||
else if (priority != null)
|
||||
value.priority = priority
|
||||
|
||||
value.modificationChain.add(modifier)
|
||||
}
|
||||
|
||||
override fun update(registry: MutableCollection<MutableEntry>, modifier: ResourceLocation) {
|
||||
if(!(
|
||||
matter != null ||
|
||||
complexity != null ||
|
||||
priority != null ||
|
||||
matterFunctions.isNotEmpty() ||
|
||||
complexityFunctions.isNotEmpty() ||
|
||||
priorityFunctions.isNotEmpty()
|
||||
)) {
|
||||
throw JsonParseException("Can't update existing entries without anything specified (for $modifier)")
|
||||
}
|
||||
|
||||
if (matter != null && matterFunctions.isNotEmpty()) {
|
||||
throw JsonParseException("Can't have both matter and matter functions specified at the same time (for $modifier)")
|
||||
}
|
||||
|
||||
if (complexity != null && complexityFunctions.isNotEmpty()) {
|
||||
throw JsonParseException("Can't have both complexity and complexity functions specified at the same time (for $modifier)")
|
||||
}
|
||||
|
||||
if (priority != null && priorityFunctions.isNotEmpty()) {
|
||||
throw JsonParseException("Can't have both priority and priority functions specified at the same time (for $modifier)")
|
||||
}
|
||||
|
||||
if (!checkConditions()) {
|
||||
return
|
||||
}
|
||||
|
||||
if (key != null) {
|
||||
val iterator = registry.iterator()
|
||||
|
||||
for (value in iterator) {
|
||||
if (value is MutableKeyEntry && value.key == key) {
|
||||
apply(value, modifier)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
fail { "Could not find matter value with key $key" }
|
||||
} else {
|
||||
val iterator = registry.iterator()
|
||||
|
||||
for (value in iterator) {
|
||||
if (value is MutableTagEntry && value.tag == tag) {
|
||||
apply(value, modifier)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
fail { "Could not find matter value with tag $tag" }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sealed class MutableEntry(
|
||||
val modificationChain: MutableList<ResourceLocation>,
|
||||
var matter: ImpreciseFraction,
|
||||
@ -679,46 +76,6 @@ object MatterManager : SimpleJsonResourceReloadListener(GsonBuilder().setPrettyP
|
||||
}
|
||||
}
|
||||
|
||||
interface IMatterValue : Comparable<IMatterValue> {
|
||||
val matter: ImpreciseFraction
|
||||
val complexity: Double
|
||||
|
||||
val hasMatterValue: Boolean get() = matter.isPositive && complexity > 0.0
|
||||
|
||||
operator fun plus(other: IMatterValue): IMatterValue {
|
||||
return MatterValue(matter + other.matter, complexity + other.complexity)
|
||||
}
|
||||
|
||||
operator fun minus(other: IMatterValue): IMatterValue {
|
||||
return MatterValue(matter - other.matter, complexity - other.complexity)
|
||||
}
|
||||
|
||||
override fun compareTo(other: IMatterValue): Int {
|
||||
val matterComparison = matter.compareTo(other.matter)
|
||||
|
||||
if (matterComparison == 0) {
|
||||
return complexity.compareTo(other.complexity)
|
||||
}
|
||||
|
||||
return matterComparison
|
||||
}
|
||||
|
||||
/**
|
||||
* ZERO
|
||||
*/
|
||||
companion object : IMatterValue {
|
||||
override val matter: ImpreciseFraction
|
||||
get() = ImpreciseFraction.ZERO
|
||||
override val complexity: Double
|
||||
get() = 0.0
|
||||
}
|
||||
}
|
||||
|
||||
data class MatterValue(
|
||||
override val matter: ImpreciseFraction,
|
||||
override val complexity: Double
|
||||
) : IMatterValue
|
||||
|
||||
sealed class Entry(
|
||||
val modificationChain: List<ResourceLocation>,
|
||||
final override val matter: ImpreciseFraction,
|
||||
|
@ -220,14 +220,14 @@ object RecipeResolverManager : SimpleJsonResourceReloadListener(GsonBuilder().se
|
||||
}
|
||||
}
|
||||
|
||||
fun getDetermined(index: Item): MatterManager.IMatterValue {
|
||||
return determinedValues[index] ?: MatterManager.IMatterValue.Companion
|
||||
fun getDetermined(index: Item): IMatterValue {
|
||||
return determinedValues[index] ?: IMatterValue.Companion
|
||||
}
|
||||
|
||||
private var input2Recipes: Map<Item, Collection<ResolvedRecipe>> = mapOf()
|
||||
private var output2Recipes: Map<Item, Collection<ResolvedRecipe>> = mapOf()
|
||||
|
||||
private val determinedValues = Reference2ObjectOpenHashMap<Item, MatterManager.IMatterValue>()
|
||||
private val determinedValues = Reference2ObjectOpenHashMap<Item, IMatterValue>()
|
||||
private val commentary = Reference2ObjectOpenHashMap<Item, Component>()
|
||||
private val seenItems = ArrayDeque<Item>()
|
||||
|
||||
@ -235,8 +235,8 @@ object RecipeResolverManager : SimpleJsonResourceReloadListener(GsonBuilder().se
|
||||
return commentary[item]?.copy()
|
||||
}
|
||||
|
||||
private data class Result(val type: Type, val value: MatterManager.IMatterValue? = null) {
|
||||
constructor(value: MatterManager.IMatterValue) : this(Type.RESOLVED, value)
|
||||
private data class Result(val type: Type, val value: IMatterValue? = null) {
|
||||
constructor(value: IMatterValue) : this(Type.RESOLVED, value)
|
||||
|
||||
val isSkipped get() = type === Type.SKIPPED
|
||||
val isMissing get() = type === Type.MISSING
|
||||
@ -280,7 +280,7 @@ object RecipeResolverManager : SimpleJsonResourceReloadListener(GsonBuilder().se
|
||||
var accumulatedComplexity: Double? = null
|
||||
|
||||
inputsLoop@ for ((i, inputs) in recipe.inputs.withIndex()) {
|
||||
var minimal: MatterManager.IMatterValue? = null
|
||||
var minimal: IMatterValue? = null
|
||||
var minimalMultiplier = 0.0
|
||||
|
||||
for (input in inputs) {
|
||||
@ -341,7 +341,7 @@ object RecipeResolverManager : SimpleJsonResourceReloadListener(GsonBuilder().se
|
||||
return Result.MISSING
|
||||
}
|
||||
|
||||
val result = MatterManager.MatterValue(minimalMatter, minimalComplexity)
|
||||
val result = MatterValue(minimalMatter, minimalComplexity)
|
||||
|
||||
changes = true
|
||||
determinedValues[item] = result
|
||||
@ -357,7 +357,7 @@ object RecipeResolverManager : SimpleJsonResourceReloadListener(GsonBuilder().se
|
||||
return getResult
|
||||
}
|
||||
|
||||
var value: MatterManager.IMatterValue? = MatterManager.getDirect(item)
|
||||
var value: IMatterValue? = MatterManager.getDirect(item)
|
||||
|
||||
if (value?.hasMatterValue == true) {
|
||||
return Result(value)
|
||||
|
309
src/main/kotlin/ru/dbotthepony/mc/otm/matter/UpdateAction.kt
Normal file
309
src/main/kotlin/ru/dbotthepony/mc/otm/matter/UpdateAction.kt
Normal file
@ -0,0 +1,309 @@
|
||||
package ru.dbotthepony.mc.otm.matter
|
||||
|
||||
import com.google.common.collect.ImmutableList
|
||||
import com.google.gson.JsonArray
|
||||
import com.google.gson.JsonElement
|
||||
import com.google.gson.JsonObject
|
||||
import com.google.gson.JsonParseException
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.tags.TagKey
|
||||
import net.minecraft.world.item.Item
|
||||
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
|
||||
import ru.dbotthepony.mc.otm.core.integerDivisionDown
|
||||
import ru.dbotthepony.mc.otm.core.integerDivisionUp
|
||||
import ru.dbotthepony.mc.otm.core.set
|
||||
import ru.dbotthepony.mc.otm.data.stream
|
||||
|
||||
class UpdateAction : AbstractRegistryAction {
|
||||
enum class Function {
|
||||
ADD {
|
||||
override fun updateValue(self: Int, other: Int): Int = self + other
|
||||
override fun updateValue(self: ImpreciseFraction, other: ImpreciseFraction): ImpreciseFraction = self + other
|
||||
override fun updateValue(self: Double, other: Double): Double = self + other
|
||||
},
|
||||
SUBTRACT {
|
||||
override fun updateValue(self: Int, other: Int): Int = self - other
|
||||
override fun updateValue(self: ImpreciseFraction, other: ImpreciseFraction): ImpreciseFraction = self - other
|
||||
override fun updateValue(self: Double, other: Double): Double = self - other
|
||||
},
|
||||
MULTIPLY {
|
||||
override fun updateValue(self: Int, other: Int): Int = self * other
|
||||
override fun updateValue(self: ImpreciseFraction, other: ImpreciseFraction): ImpreciseFraction = self * other
|
||||
override fun updateValue(self: Double, other: Double): Double = self * other
|
||||
},
|
||||
DIVIDE {
|
||||
override fun updateValue(self: Int, other: Int): Int = self / other
|
||||
override fun updateValue(self: ImpreciseFraction, other: ImpreciseFraction): ImpreciseFraction = self / other
|
||||
override fun updateValue(self: Double, other: Double): Double = self / other
|
||||
},
|
||||
DIVIDE_UP {
|
||||
override fun updateValue(self: Int, other: Int): Int = integerDivisionUp(self, other)
|
||||
override fun updateValue(self: ImpreciseFraction, other: ImpreciseFraction): ImpreciseFraction = throw JsonParseException(
|
||||
"Integer division up is available only for integers"
|
||||
)
|
||||
override fun updateValue(self: Double, other: Double): Double = throw JsonParseException(
|
||||
"Integer division up is available only for integers"
|
||||
)
|
||||
},
|
||||
DIVIDE_DOWN {
|
||||
override fun updateValue(self: Int, other: Int): Int = integerDivisionDown(self, other)
|
||||
override fun updateValue(self: ImpreciseFraction, other: ImpreciseFraction): ImpreciseFraction = throw JsonParseException(
|
||||
"Integer division down is available only for integers"
|
||||
)
|
||||
override fun updateValue(self: Double, other: Double): Double = throw JsonParseException(
|
||||
"Integer division down is available only for integers"
|
||||
)
|
||||
},
|
||||
MODULO {
|
||||
override fun updateValue(self: Int, other: Int): Int = self % other
|
||||
override fun updateValue(self: ImpreciseFraction, other: ImpreciseFraction): ImpreciseFraction = self % other
|
||||
override fun updateValue(self: Double, other: Double): Double = self % other
|
||||
},
|
||||
AT_LEAST {
|
||||
override fun updateValue(self: Int, other: Int): Int = self.coerceAtLeast(other)
|
||||
override fun updateValue(self: ImpreciseFraction, other: ImpreciseFraction): ImpreciseFraction = self.coerceAtLeast(other)
|
||||
override fun updateValue(self: Double, other: Double): Double = self.coerceAtLeast(other)
|
||||
},
|
||||
AT_MOST {
|
||||
override fun updateValue(self: Int, other: Int): Int = self.coerceAtMost(other)
|
||||
override fun updateValue(self: ImpreciseFraction, other: ImpreciseFraction): ImpreciseFraction = self.coerceAtMost(other)
|
||||
override fun updateValue(self: Double, other: Double): Double = self.coerceAtMost(other)
|
||||
},
|
||||
;
|
||||
|
||||
protected abstract fun updateValue(self: Int, other: Int): Int
|
||||
protected abstract fun updateValue(self: ImpreciseFraction, other: ImpreciseFraction): ImpreciseFraction
|
||||
protected abstract fun updateValue(self: Double, other: Double): Double
|
||||
|
||||
fun <T : Number> updateValue(self: T, other: T): T {
|
||||
return when (self) {
|
||||
is ImpreciseFraction -> updateValue(self, other)
|
||||
is Double -> updateValue(self, other)
|
||||
is Int -> updateValue(self, other)
|
||||
else -> throw RuntimeException("Unknown number type: ${self::class.qualifiedName}")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class BoundFunction<T : Number>(val function: Function, val value: T) {
|
||||
fun apply(self: T): T {
|
||||
return function.updateValue(self, value)
|
||||
}
|
||||
|
||||
fun toJson(): JsonObject {
|
||||
return JsonObject().also {
|
||||
it["type"] = function.name
|
||||
|
||||
if (value is Int || value is Double)
|
||||
it["value"] = value
|
||||
else
|
||||
it["value"] = value.toString()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
inline fun <reified T : Number> getValue(value: JsonElement): T {
|
||||
return when (T::class) {
|
||||
ImpreciseFraction::class -> ImpreciseFraction(value.asString) as T
|
||||
Double::class -> value.asDouble as T
|
||||
Int::class -> value.asInt as T
|
||||
else -> throw RuntimeException("Unknown number type: ${T::class.qualifiedName}")
|
||||
}
|
||||
}
|
||||
|
||||
inline fun <reified T : Number> deserializeFunctionTree(input: JsonElement?, name: String): List<BoundFunction<T>> {
|
||||
if (input == null) {
|
||||
return listOf()
|
||||
}
|
||||
|
||||
if (input !is JsonArray) {
|
||||
throw JsonParseException("Expected $name to be JsonArray, ${input::class.qualifiedName} given")
|
||||
}
|
||||
|
||||
return input.stream().map {
|
||||
if (it !is JsonObject) {
|
||||
throw JsonParseException("All elements in function tree must be JsonObjects, ${it::class.qualifiedName} given")
|
||||
}
|
||||
|
||||
val type = it["type"]?.asString ?: throw JsonParseException("Invalid `type` value in function object")
|
||||
val value = it["value"] ?: throw JsonParseException("Missing `value` value in function object")
|
||||
|
||||
val parsedValue: T = getValue(value)
|
||||
val fn: Function
|
||||
|
||||
try {
|
||||
fn = Function.valueOf(type.uppercase())
|
||||
} catch (err: NoSuchElementException) {
|
||||
throw JsonParseException("No such function: $type", err)
|
||||
}
|
||||
|
||||
return@map BoundFunction(fn, parsedValue)
|
||||
}.collect(ImmutableList.toImmutableList())
|
||||
}
|
||||
|
||||
fun <T : Number> apply(value: T, funcs: Collection<BoundFunction<T>>): T {
|
||||
if (funcs.isEmpty()) {
|
||||
return value
|
||||
}
|
||||
|
||||
var newValue = value
|
||||
|
||||
for (func in funcs) {
|
||||
newValue = func.apply(newValue)
|
||||
}
|
||||
|
||||
return newValue
|
||||
}
|
||||
}
|
||||
|
||||
val matterFunctions: List<BoundFunction<ImpreciseFraction>>
|
||||
val complexityFunctions: List<BoundFunction<Double>>
|
||||
val priorityFunctions: List<BoundFunction<Int>>
|
||||
|
||||
constructor(json: JsonObject) : super(json) {
|
||||
matterFunctions = deserializeFunctionTree(json["matter_functions"], "matter_functions")
|
||||
complexityFunctions = deserializeFunctionTree(json["complexity_functions"], "complexity_functions")
|
||||
priorityFunctions = deserializeFunctionTree(json["priority_functions"], "priority_functions")
|
||||
}
|
||||
|
||||
constructor(
|
||||
tag: TagKey<Item>,
|
||||
matter: ImpreciseFraction? = null,
|
||||
complexity: Double? = null,
|
||||
priority: Int? = null,
|
||||
errorOnFailure: Boolean = false,
|
||||
matterFunctions: List<BoundFunction<ImpreciseFraction>> = ImmutableList.of(),
|
||||
complexityFunctions: List<BoundFunction<Double>> = ImmutableList.of(),
|
||||
priorityFunctions: List<BoundFunction<Int>> = ImmutableList.of(),
|
||||
) : super(tag = tag, matter = matter, complexity = complexity, priority = priority, errorOnFailure = errorOnFailure) {
|
||||
check(matter != null || complexity != null || priority != null || matterFunctions.isNotEmpty() || complexityFunctions.isNotEmpty() || priorityFunctions.isNotEmpty()) {
|
||||
"Can't update existing entries without anything specified"
|
||||
}
|
||||
|
||||
this.matterFunctions = ImmutableList.copyOf(matterFunctions)
|
||||
this.complexityFunctions = ImmutableList.copyOf(complexityFunctions)
|
||||
this.priorityFunctions = ImmutableList.copyOf(priorityFunctions)
|
||||
}
|
||||
|
||||
constructor(
|
||||
key: ResourceLocation,
|
||||
matter: ImpreciseFraction? = null,
|
||||
complexity: Double? = null,
|
||||
priority: Int? = null,
|
||||
errorOnFailure: Boolean = false,
|
||||
matterFunctions: List<BoundFunction<ImpreciseFraction>> = ImmutableList.of(),
|
||||
complexityFunctions: List<BoundFunction<Double>> = ImmutableList.of(),
|
||||
priorityFunctions: List<BoundFunction<Int>> = ImmutableList.of(),
|
||||
) : super(key = key, matter = matter, complexity = complexity, priority = priority, errorOnFailure = errorOnFailure) {
|
||||
check(matter != null || complexity != null || priority != null || matterFunctions.isNotEmpty() || complexityFunctions.isNotEmpty() || priorityFunctions.isNotEmpty()) {
|
||||
"Can't update existing entries without anything specified"
|
||||
}
|
||||
|
||||
this.matterFunctions = ImmutableList.copyOf(matterFunctions)
|
||||
this.complexityFunctions = ImmutableList.copyOf(complexityFunctions)
|
||||
this.priorityFunctions = ImmutableList.copyOf(priorityFunctions)
|
||||
}
|
||||
|
||||
override fun toJson(): JsonObject {
|
||||
return super.toJson().also {
|
||||
it["action"] = "update"
|
||||
|
||||
if (matterFunctions.isNotEmpty()) {
|
||||
it["matter_functions"] = JsonArray().also {
|
||||
for (fn in matterFunctions) {
|
||||
it.add(fn.toJson())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (complexityFunctions.isNotEmpty()) {
|
||||
it["complexity_functions"] = JsonArray().also {
|
||||
for (fn in complexityFunctions) {
|
||||
it.add(fn.toJson())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (priorityFunctions.isNotEmpty()) {
|
||||
it["priority_functions"] = JsonArray().also {
|
||||
for (fn in priorityFunctions) {
|
||||
it.add(fn.toJson())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun apply(value: MatterManager.MutableEntry, modifier: ResourceLocation) {
|
||||
if (matterFunctions.isNotEmpty())
|
||||
value.matter = apply(value.matter, matterFunctions)
|
||||
else if (matter != null)
|
||||
value.matter = matter
|
||||
|
||||
if (complexityFunctions.isNotEmpty())
|
||||
value.complexity = apply(value.complexity, complexityFunctions)
|
||||
else if (complexity != null)
|
||||
value.complexity = complexity
|
||||
|
||||
if (priorityFunctions.isNotEmpty())
|
||||
value.priority = apply(value.priority, priorityFunctions)
|
||||
else if (priority != null)
|
||||
value.priority = priority
|
||||
|
||||
value.modificationChain.add(modifier)
|
||||
}
|
||||
|
||||
override fun update(registry: MutableCollection<MatterManager.MutableEntry>, modifier: ResourceLocation) {
|
||||
if(!(
|
||||
matter != null ||
|
||||
complexity != null ||
|
||||
priority != null ||
|
||||
matterFunctions.isNotEmpty() ||
|
||||
complexityFunctions.isNotEmpty() ||
|
||||
priorityFunctions.isNotEmpty()
|
||||
)) {
|
||||
throw JsonParseException("Can't update existing entries without anything specified (for $modifier)")
|
||||
}
|
||||
|
||||
if (matter != null && matterFunctions.isNotEmpty()) {
|
||||
throw JsonParseException("Can't have both matter and matter functions specified at the same time (for $modifier)")
|
||||
}
|
||||
|
||||
if (complexity != null && complexityFunctions.isNotEmpty()) {
|
||||
throw JsonParseException("Can't have both complexity and complexity functions specified at the same time (for $modifier)")
|
||||
}
|
||||
|
||||
if (priority != null && priorityFunctions.isNotEmpty()) {
|
||||
throw JsonParseException("Can't have both priority and priority functions specified at the same time (for $modifier)")
|
||||
}
|
||||
|
||||
if (!checkConditions()) {
|
||||
return
|
||||
}
|
||||
|
||||
if (key != null) {
|
||||
val iterator = registry.iterator()
|
||||
|
||||
for (value in iterator) {
|
||||
if (value is MatterManager.MutableKeyEntry && value.key == key) {
|
||||
apply(value, modifier)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
fail { "Could not find matter value with key $key" }
|
||||
} else {
|
||||
val iterator = registry.iterator()
|
||||
|
||||
for (value in iterator) {
|
||||
if (value is MatterManager.MutableTagEntry && value.tag == tag) {
|
||||
apply(value, modifier)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
fail { "Could not find matter value with tag $tag" }
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user