Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ parchment_version=1.20.1:2023.09.03
quilt_mappings_version=23
yarn_mappings=1.20.1+build.10

loader_version=0.15.11
loader_version=0.16.14

modmenu_version=7.2.2

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import com.bibireden.data_attributes.config.functions.AttributeFunction
import com.bibireden.data_attributes.config.models.OverridesConfigModel.AttributeOverride
import com.bibireden.data_attributes.data.EntityAttributeData
import com.bibireden.data_attributes.config.entities.EntityTypeData
import com.bibireden.data_attributes.config.entry.DatapackCaches
import com.bibireden.data_attributes.endec.Endecs
import com.bibireden.data_attributes.ext.keyOf
import com.bibireden.data_attributes.mutable.MutableEntityAttribute
Expand All @@ -33,7 +34,7 @@ import net.minecraft.util.Identifier
class AttributeConfigManager(var data: Data = Data(), private val handler: AttributeContainerHandler = AttributeContainerHandler()) {
var updateFlag: Int = 0

var defaults: DefaultAttributesReloadListener.Cache = DefaultAttributesReloadListener.Cache()
var defaults: DatapackCaches = LinkedHashMap()

@JvmRecord
data class Tuple<T>(val livingEntity: Class<out LivingEntity>, val value: T)
Expand Down Expand Up @@ -111,9 +112,11 @@ class AttributeConfigManager(var data: Data = Data(), private val handler: Attri
* This applies the data immediately afterward.
*/
fun update() {
this.data.overrides = ConfigMerger.mergeOverrides(defaults.overrides.entries)
this.data.functions = ConfigMerger.mergeFunctions(defaults.functions.entries)
this.data.entity_types = ConfigMerger.mergeEntityTypes(defaults.types.entries)
for (cache in defaults.values) {
this.data.overrides = ConfigMerger.mergeOverrides(cache.overrides.entries)
this.data.functions = ConfigMerger.mergeFunctions(cache.functions.entries)
this.data.entity_types = ConfigMerger.mergeEntityTypes(cache.types.entries)
}

this.onDataUpdate()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import com.bibireden.data_attributes.ui.colors.ColorCodes
import com.bibireden.data_attributes.ui.config.providers.AttributeFunctionProvider
import com.bibireden.data_attributes.ui.config.providers.AttributeOverrideProvider
import com.bibireden.data_attributes.ui.config.providers.EntityTypesProvider
import com.bibireden.data_attributes.ui.config.providers.EntityTypesProviderV2
import com.google.common.base.Predicate
import io.wispforest.owo.config.ui.OptionComponentFactory
import io.wispforest.owo.ui.component.Components
Expand All @@ -18,12 +17,12 @@ import net.minecraft.text.Text
import net.minecraft.util.Identifier

object DataAttributesConfigProviders {
fun <T> registryEntryToText(id: Identifier, registry: Registry<T>, representation: (T) -> String, isDefault: Boolean = false): MutableText {
fun <T> registryEntryToText(id: Identifier, registry: Registry<T>, representation: (T) -> String, isReadonly: Boolean = false): MutableText {
val entry = registry[id]
val text = Text.empty()
if (entry != null) {
text.append(Text.translatable(representation(entry)).append(" "))
.setStyle(Style.EMPTY.withColor(if (isDefault) 0x84de56 else 0xE7C14B))
.setStyle(Style.EMPTY.withColor(if (isReadonly) 0x65bde3 else 0xE7C14B))
}
text.append(Text.literal("($id)").also { t ->
t.setStyle(
Expand All @@ -44,7 +43,7 @@ object DataAttributesConfigProviders {
}

val ENTITY_TYPES_FACTORY = OptionComponentFactory { _, option ->
return@OptionComponentFactory EntityTypesProviderV2(option).let { OptionComponentFactory.Result(it, it) }
return@OptionComponentFactory EntityTypesProvider(option).let { OptionComponentFactory.Result(it, it) }
}

fun textBoxComponent(txt: Text, obj: Any, predicate: Predicate<String>? = null, onChange: ((String) -> Unit)? = null, textBoxID: String? = null): FlowLayout {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,22 @@ import kotlinx.serialization.json.Json
import kotlinx.serialization.json.decodeFromStream
import net.fabricmc.fabric.api.resource.SimpleResourceReloadListener
import net.minecraft.registry.Registries
import net.minecraft.resource.Resource
import net.minecraft.resource.ResourceManager
import net.minecraft.util.Identifier
import net.minecraft.util.profiler.Profiler
import java.util.concurrent.CompletableFuture
import java.util.concurrent.Executor

typealias DatapackCaches = LinkedHashMap<Identifier, DefaultAttributesReloadListener.Cache>

/**
* A listener meant to compile [Pack]'s based on load order for preference
* and then be applied to the manager.
*/
@OptIn(ExperimentalSerializationApi::class)
class DefaultAttributesReloadListener : SimpleResourceReloadListener<DefaultAttributesReloadListener.Cache> {
var data: Cache = Cache()
class DefaultAttributesReloadListener : SimpleResourceReloadListener<DatapackCaches> {
var caches: DatapackCaches = LinkedHashMap()

@Serializable
data class Overrides(var entries: LinkedHashMap<Identifier, AttributeOverride> = LinkedHashMap())
Expand All @@ -36,8 +39,12 @@ class DefaultAttributesReloadListener : SimpleResourceReloadListener<DefaultAttr
@Serializable
data class EntityTypes(var entries: LinkedHashMap<Identifier, LinkedHashMap<Identifier, EntityTypeEntry>> = LinkedHashMap())

@Serializable
data class Cache(val overrides: Overrides = Overrides(), val functions: Functions = Functions(), val types: EntityTypes = EntityTypes())
data class Cache(
val resource: Resource,
val overrides: Overrides = Overrides(),
val functions: Functions = Functions(),
val types: EntityTypes = EntityTypes()
)

companion object {
const val DIRECTORY = DataAttributes.MOD_ID
Expand All @@ -47,60 +54,67 @@ class DefaultAttributesReloadListener : SimpleResourceReloadListener<DefaultAttr

override fun getFabricId(): Identifier = DataAttributes.id(DIRECTORY)

override fun load(manager: ResourceManager, profiler: Profiler, executor: Executor): CompletableFuture<Cache> {
override fun load(manager: ResourceManager, profiler: Profiler, executor: Executor): CompletableFuture<DatapackCaches> {
return CompletableFuture.supplyAsync {
val cache = Cache()

readOverrides(manager, cache)
readFunctions(manager, cache)
readEntityTypes(manager, cache)

// Filtering before applying the cache.
cache.overrides.entries = LinkedHashMap(cache.overrides.entries.filter { (id, _) -> Registries.ATTRIBUTE.containsId(id) })
cache.functions.entries.forEach { (id, functions) ->
if (!Registries.ATTRIBUTE.containsId(id)) {
cache.functions.entries.remove(id)
return@forEach
val caches: DatapackCaches = LinkedHashMap()

readOverrides(manager, caches)
readFunctions(manager, caches)
readEntityTypes(manager, caches)

// Filtering before applying the caches.
for (cache in caches.values) {
cache.overrides.entries = LinkedHashMap(cache.overrides.entries.filter { (id, _) -> Registries.ATTRIBUTE.containsId(id) })
cache.functions.entries.forEach { (id, functions) ->
if (!Registries.ATTRIBUTE.containsId(id)) {
cache.functions.entries.remove(id)
return@forEach
}
cache.functions.entries[id] = LinkedHashMap(functions.filter { (id2) -> Registries.ATTRIBUTE.containsId(id2) })
}
cache.functions.entries[id] = LinkedHashMap(functions.filter { (id2) -> Registries.ATTRIBUTE.containsId(id2) })
}
cache.types.entries.forEach { (id, data) ->
if (!Registries.ENTITY_TYPE.containsId(id)) {
cache.types.entries.remove(id)
return@forEach
cache.types.entries.forEach { (id, data) ->
if (!Registries.ENTITY_TYPE.containsId(id)) {
cache.types.entries.remove(id)
return@forEach
}
cache.types.entries[id] = LinkedHashMap(data.filter { (id2) -> Registries.ATTRIBUTE.containsId(id2) })
}
cache.types.entries[id] = LinkedHashMap(data.filter { (id2) -> Registries.ATTRIBUTE.containsId(id2) })
}

cache
caches
}
}

override fun apply(cache: Cache, manager: ResourceManager, profiler: Profiler, executor: Executor): CompletableFuture<Void> {
return CompletableFuture.runAsync { DataAttributes.MANAGER.defaults = cache }
override fun apply(caches: DatapackCaches, manager: ResourceManager, profiler: Profiler, executor: Executor): CompletableFuture<Void> {
return CompletableFuture.runAsync { DataAttributes.MANAGER.defaults = caches }
}

private fun computeResourceToCache(caches: DatapackCaches, id: Identifier, resource: Resource): Cache {
return caches.computeIfAbsent(Identifier.of(id.namespace, "pack")!!) { Cache(resource) }
}

private fun readOverrides(manager: ResourceManager, cache: Cache) {
private fun readOverrides(manager: ResourceManager, caches: DatapackCaches) {
val path = "$DIRECTORY/overrides"

manager.findResources(path, ::isPathJson).forEach { (id, res) ->
manager.findResources(path, ::isPathJson).forEach { (resId, res) ->
try {
Json.decodeFromStream<Overrides>(res.inputStream).entries.forEach { (id, entry) ->
cache.overrides.entries.computeIfAbsent(id) { entry }
computeResourceToCache(caches, resId, res).overrides.entries.computeIfAbsent(id) { entry }
}
}
catch (why: Exception) {
DataAttributes.LOGGER.error("Failed to parse overrides@$id :: {}", why.message)
DataAttributes.LOGGER.error("Failed to parse overrides@$resId :: {}", why.message)
}
}
}

private fun readFunctions(manager: ResourceManager, cache: Cache) {
private fun readFunctions(manager: ResourceManager, caches: DatapackCaches) {
val path = "$DIRECTORY/functions"

manager.findResources(path, ::isPathJson).forEach { (id, res) ->
manager.findResources(path, ::isPathJson).forEach { (resId, res) ->
try {
Json.decodeFromStream<Functions>(res.inputStream).entries.forEach { (id, entry) ->
val cache = computeResourceToCache(caches, resId, res)
val presentEntry = cache.functions.entries[id]
if (presentEntry == null) {
cache.functions.entries[id] = entry
Expand All @@ -114,17 +128,18 @@ class DefaultAttributesReloadListener : SimpleResourceReloadListener<DefaultAttr
}
}
catch (why: Exception) {
DataAttributes.LOGGER.error("Failed to parse functions@$id :: {}", why.message)
DataAttributes.LOGGER.error("Failed to parse functions@$resId :: {}", why.message)
}
}
}

private fun readEntityTypes(manager: ResourceManager, cache: Cache) {
private fun readEntityTypes(manager: ResourceManager, caches: DatapackCaches) {
val path = "$DIRECTORY/entity_types"

manager.findResources(path, ::isPathJson).forEach { (id, res) ->
manager.findResources(path, ::isPathJson).forEach { (resId, res) ->
try {
Json.decodeFromStream<EntityTypes>(res.inputStream).entries.forEach { (id, entry) ->
val cache = computeResourceToCache(caches, resId, res)
val presentEntry = cache.types.entries[id]
if (presentEntry == null) {
cache.types.entries[id] = entry
Expand All @@ -138,7 +153,7 @@ class DefaultAttributesReloadListener : SimpleResourceReloadListener<DefaultAttr
}
}
catch (why: Exception) {
DataAttributes.LOGGER.error("Failed to parse entity-types@$id :: {}", why.message)
DataAttributes.LOGGER.error("Failed to parse entity-types@$resId :: {}", why.message)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
package com.bibireden.data_attributes.config.functions

import com.bibireden.data_attributes.api.attribute.StackingBehavior
import com.bibireden.data_attributes.api.attribute.AttributeFormat
import com.bibireden.data_attributes.endec.Endecs
import com.bibireden.data_attributes.serde.IdentifierSerializer
import io.wispforest.endec.Endec
import io.wispforest.endec.impl.StructEndecBuilder
import kotlinx.serialization.Serializable
Expand All @@ -15,19 +12,14 @@ import net.minecraft.util.Identifier
* the [StackingBehavior] of the function which will determine if the given [getValue] will be an additive or multiplicative one.
* */
@Serializable
data class AttributeFunction(
var enabled: Boolean,
var behavior: StackingBehavior,
var value: Double
) {
@Suppress("UNUSED")
data class AttributeFunction(var enabled: Boolean, var behavior: StackingBehavior, var value: Double) {
constructor() : this(true, StackingBehavior.Add, 0.0)

companion object {
@JvmField
val ENDEC = StructEndecBuilder.of(
val ENDEC: Endec<AttributeFunction> = StructEndecBuilder.of(
Endec.BOOLEAN.optionalFieldOf("enabled", { it.enabled }, true),
Endec.STRING.xmap(StackingBehavior::of) { x -> x.name.uppercase() }.fieldOf("behavior") { it.behavior },
Endec.STRING.xmap(StackingBehavior::of) { it.name.uppercase() }.fieldOf("behavior") { it.behavior },
Endec.DOUBLE.fieldOf("value") { it.value },
::AttributeFunction
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.bibireden.data_attributes.config.functions

import com.bibireden.data_attributes.endec.Endecs
import com.bibireden.data_attributes.ext.keyOf
import io.wispforest.endec.Endec
import net.minecraft.entity.attribute.EntityAttribute
import net.minecraft.util.Identifier

Expand All @@ -13,6 +14,6 @@ data class AttributeFunctionConfig(
) {
companion object {
@JvmField
val ENDEC = Endecs.IDENTIFIER.keyOf(Endecs.IDENTIFIER.keyOf(AttributeFunction.ENDEC)).xmap(::AttributeFunctionConfig) { it.data }
val ENDEC: Endec<AttributeFunctionConfig> = Endecs.IDENTIFIER.keyOf(Endecs.IDENTIFIER.keyOf(AttributeFunction.ENDEC)).xmap(::AttributeFunctionConfig) { it.data }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import com.bibireden.data_attributes.DataAttributes
import io.wispforest.owo.config.Option.SyncMode
import io.wispforest.owo.config.annotation.Config
import io.wispforest.owo.config.annotation.Sync
import net.minecraft.util.Identifier

@Suppress("UNUSED")
@Config(name = DataAttributes.MOD_ID, wrapperName = "DataAttributesConfig")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import com.bibireden.data_attributes.config.models.OverridesConfigModel.Attribut
import com.bibireden.data_attributes.endec.Endecs
import com.bibireden.data_attributes.ext.keyOf
import com.bibireden.data_attributes.mutable.MutableEntityAttribute
import io.wispforest.endec.Endec
import io.wispforest.endec.impl.StructEndecBuilder
import net.minecraft.entity.attribute.EntityAttribute
import net.minecraft.registry.Registries
Expand All @@ -20,7 +21,7 @@ class EntityAttributeData(val override: AttributeOverride? = null, val functions

companion object {
@JvmField
val ENDEC = StructEndecBuilder.of(
val ENDEC: Endec<EntityAttributeData> = StructEndecBuilder.of(
AttributeOverride.ENDEC.nullableOf().fieldOf("override") { it.override },
Endecs.IDENTIFIER.keyOf(AttributeFunction.ENDEC).fieldOf("functions") { it.functions },
::EntityAttributeData,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.bibireden.data_attributes.identifier

import net.minecraft.util.Identifier

object Identifiers {
fun unknown(): Identifier = Identifier.of("minecraft", "unknown")!!
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package com.bibireden.data_attributes.serde

import blue.endless.jankson.Jankson
import blue.endless.jankson.JsonObject
import blue.endless.jankson.JsonPrimitive
import com.bibireden.data_attributes.config.functions.AttributeFunction
import com.bibireden.data_attributes.config.functions.AttributeFunctionConfig
import com.bibireden.data_attributes.config.entities.EntityTypeData
Expand Down
10 changes: 10 additions & 0 deletions src/main/kotlin/com/bibireden/data_attributes/ui/button/Buttons.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.bibireden.data_attributes.ui.button

import com.bibireden.data_attributes.ui.renderers.ButtonRenderers
import io.wispforest.owo.ui.component.ButtonComponent
import io.wispforest.owo.ui.component.Components
import net.minecraft.text.Text

object Buttons {
fun add(onPress: (ButtonComponent) -> Unit): ButtonComponent = Components.button(Text.translatable("text.config.data_attributes.buttons.add"), onPress).renderer(ButtonRenderers.STANDARD)
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,6 @@ interface AttributeConfigComponent<T> {
val registry: Registry<T>
val registryEntry: T? get() = registry[identifier]

/** If this [Identifier] currently exists in the backing field. */
val isDefault: Boolean

/** If the given entry is currently registered. */
val isRegistered: Boolean
get() = registryEntry != null
Expand Down
Loading
Loading