Skip to content

Commit

Permalink
feat: allow baseMaterial and itemPredicates.customModelData to inheri…
Browse files Browse the repository at this point in the history
…t from set.item component
  • Loading branch information
Boy0000 committed Oct 19, 2024
1 parent 2c2a65c commit 9eca258
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 37 deletions.
Original file line number Diff line number Diff line change
@@ -1,82 +1,111 @@
package com.mineinabyss.geary.papermc.features.items.resourcepacks

import com.mineinabyss.idofront.serialization.*
import com.mineinabyss.idofront.serialization.KeySerializer
import com.mineinabyss.idofront.serialization.MaterialByNameSerializer
import com.mineinabyss.idofront.serialization.ModelTexturesSerializer
import com.mineinabyss.idofront.serialization.ModelTexturesSurrogate
import kotlinx.serialization.EncodeDefault
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import net.kyori.adventure.key.Key
import org.bukkit.Material
import org.bukkit.inventory.ItemStack
import team.unnamed.creative.model.ItemOverride
import team.unnamed.creative.model.ItemPredicate

@Serializable
@SerialName("geary:resourcepack")
data class ResourcePackContent(
val baseMaterial: @Serializable(MaterialByNameSerializer::class) Material,
@EncodeDefault(EncodeDefault.Mode.NEVER) val baseMaterial: @Serializable(MaterialByNameSerializer::class) Material? = null,
val model: @Serializable(KeySerializer::class) Key? = null,
val parentModel: @Serializable(KeySerializer::class) Key = Key.key("minecraft:item/generated"),
val textures: @Serializable(ModelTexturesSerializer::class) ModelTexturesSurrogate = ModelTexturesSurrogate(),
val itemPredicates: ItemPredicates
val itemPredicates: ItemPredicates = ItemPredicates(customModelData = null)
) {

init {
require(model != null || textures.layers.isNotEmpty() || textures.variables.isNotEmpty()) { "ResourcePackContent must contain atleast a model or texture reference" }
}

fun itemOverrides(modelKey: Key): List<ItemOverride> {
fun itemOverrides(modelKey: Key, itemStack: ItemStack?): List<ItemOverride> {
val overrides = mutableListOf<ItemOverride>()
val cmdPredicate = itemPredicates.customModelData(itemStack)

// Shields
(itemPredicates.blockingModel ?: itemPredicates.blockingTexture?.let { modelKey.plus("_blocking") })?.let {
overrides.add(ItemOverride.of(it, itemPredicates.customModelData(), ItemPredicate.blocking()))
overrides.add(ItemOverride.of(it, cmdPredicate, ItemPredicate.blocking()))
}
// Elytras
(itemPredicates.brokenModel ?: itemPredicates.brokenTexture?.let { modelKey.plus("_broken") })?.let {
overrides.add(ItemOverride.of(it, itemPredicates.customModelData(), ItemPredicate.broken()))
overrides.add(ItemOverride.of(it, cmdPredicate, ItemPredicate.broken()))
}
// Fishing Rods
overrides.add(ItemOverride.of(modelKey, itemPredicates.customModelData()))
overrides.add(ItemOverride.of(modelKey, cmdPredicate))
(itemPredicates.castModel ?: itemPredicates.castTexture?.let { modelKey.plus("_cast") })?.let {
overrides.add(ItemOverride.of(it, itemPredicates.customModelData(), ItemPredicate.cast()))
overrides.add(ItemOverride.of(it, cmdPredicate, ItemPredicate.cast()))
}
// Charged Crossbow
(itemPredicates.chargedModel ?: itemPredicates.chargedTexture?.let { modelKey.plus("_charged") })?.let {
overrides.add(ItemOverride.of(it, itemPredicates.customModelData(), ItemPredicate.charged()))
overrides.add(ItemOverride.of(it, cmdPredicate, ItemPredicate.charged()))
}
// Charged Crossbow with Firework
(itemPredicates.fireworkModel ?: itemPredicates.fireworkTexture?.let { modelKey.plus("_firework") })?.let {
overrides.add(ItemOverride.of(it, itemPredicates.customModelData(), ItemPredicate.firework()))
overrides.add(ItemOverride.of(it, cmdPredicate, ItemPredicate.firework()))
}
// Lefthanded-players
(itemPredicates.lefthandedModel ?: itemPredicates.lefthandedTexture?.let { modelKey.plus("_lefthanded") })?.let {
overrides.add(ItemOverride.of(it, itemPredicates.customModelData(), ItemPredicate.lefthanded()))
(itemPredicates.lefthandedModel
?: itemPredicates.lefthandedTexture?.let { modelKey.plus("_lefthanded") })?.let {
overrides.add(ItemOverride.of(it, cmdPredicate, ItemPredicate.lefthanded()))
}
// Tridents
(itemPredicates.throwingModel ?: itemPredicates.throwingTexture?.let { modelKey.plus("_throwing") })?.let {
overrides.add(ItemOverride.of(it, itemPredicates.customModelData(), ItemPredicate.throwing()))
overrides.add(ItemOverride.of(it, cmdPredicate, ItemPredicate.throwing()))
}

fun Map<Key, Float>.predicateModel(suffix: String, action: (Map.Entry<Key, Float>) -> ItemOverride) = this.toList().mapIndexed { index, (_, damage) -> modelKey.plus("_${suffix}_$index") to damage.coerceIn(0f..1f) }.toMap().map(action).forEach(overrides::add)
fun Map<Key, Float>.predicateModel(suffix: String, action: (Map.Entry<Key, Float>) -> ItemOverride) =
this.toList()
.mapIndexed { index, (_, damage) -> modelKey.plus("_${suffix}_$index") to damage.coerceIn(0f..1f) }
.toMap().map(action).forEach(overrides::add)
// Compasses
itemPredicates.angleModels.takeUnless { it.isEmpty() } ?: itemPredicates.angleTextures.predicateModel("angle") { (key, angle) ->
ItemOverride.of(key, itemPredicates.customModelData(), ItemPredicate.angle(angle))
}
itemPredicates.angleModels.takeUnless { it.isEmpty() }
?: itemPredicates.angleTextures.predicateModel("angle") { (key, angle) ->
ItemOverride.of(key, cmdPredicate, ItemPredicate.angle(angle))
}
// Cooldown remaining on an item
itemPredicates.cooldownModels.takeUnless { it.isEmpty() } ?: itemPredicates.cooldownTextures.predicateModel("cooldown") { (key, damage) ->
ItemOverride.of(key, itemPredicates.customModelData(), ItemPredicate.damaged(), ItemPredicate.cooldown(damage))
}
itemPredicates.cooldownModels.takeUnless { it.isEmpty() }
?: itemPredicates.cooldownTextures.predicateModel("cooldown") { (key, damage) ->
ItemOverride.of(
key,
cmdPredicate,
ItemPredicate.damaged(),
ItemPredicate.cooldown(damage)
)
}
// Durability of an item
itemPredicates.damageModels.takeUnless { it.isEmpty() } ?: itemPredicates.damageTextures.predicateModel("damage") { (key, damage) ->
ItemOverride.of(key, itemPredicates.customModelData(), ItemPredicate.damaged(), ItemPredicate.damage(damage))
}
itemPredicates.damageModels.takeUnless { it.isEmpty() }
?: itemPredicates.damageTextures.predicateModel("damage") { (key, damage) ->
ItemOverride.of(
key,
cmdPredicate,
ItemPredicate.damaged(),
ItemPredicate.damage(damage)
)
}
// Bows & Crossbows
itemPredicates.pullingModels.takeUnless { it.isEmpty() } ?: itemPredicates.pullingTextures.predicateModel("pulling") { (key, pulling) ->
ItemOverride.of(key, itemPredicates.customModelData(), ItemPredicate.pulling(), ItemPredicate.pull(pulling))
}
itemPredicates.pullingModels.takeUnless { it.isEmpty() }
?: itemPredicates.pullingTextures.predicateModel("pulling") { (key, pulling) ->
ItemOverride.of(
key,
cmdPredicate,
ItemPredicate.pulling(),
ItemPredicate.pull(pulling)
)
}
// Clocks
itemPredicates.timeModels.takeUnless { it.isEmpty() } ?: itemPredicates.timeTextures.predicateModel("time") { (key, time) ->
ItemOverride.of(key, itemPredicates.customModelData(), ItemPredicate.time(time))
}
itemPredicates.timeModels.takeUnless { it.isEmpty() }
?: itemPredicates.timeTextures.predicateModel("time") { (key, time) ->
ItemOverride.of(key, cmdPredicate, ItemPredicate.time(time))
}

return overrides
}
Expand All @@ -85,7 +114,7 @@ data class ResourcePackContent(

@Serializable
data class ItemPredicates(
val customModelData: Int,
@EncodeDefault(EncodeDefault.Mode.NEVER) val customModelData: Int? = null,
@EncodeDefault(EncodeDefault.Mode.NEVER) val blockingModel: @Serializable(KeySerializer::class) Key? = null,
@EncodeDefault(EncodeDefault.Mode.NEVER) val blockingTexture: @Serializable(KeySerializer::class) Key? = null,
@EncodeDefault(EncodeDefault.Mode.NEVER) val brokenModel: @Serializable(KeySerializer::class) Key? = null,
Expand All @@ -112,6 +141,9 @@ data class ResourcePackContent(
@EncodeDefault(EncodeDefault.Mode.NEVER) val timeModels: Map<@Serializable(KeySerializer::class) Key, Float> = emptyMap(),
@EncodeDefault(EncodeDefault.Mode.NEVER) val timeTextures: Map<@Serializable(KeySerializer::class) Key, Float> = emptyMap(),
) {
fun customModelData(): ItemPredicate = ItemPredicate.customModelData(customModelData)
fun customModelData(itemStack: ItemStack?): ItemPredicate = ItemPredicate.customModelData(
customModelData ?: itemStack?.itemMeta?.customModelData
?: error("No CustomModelData specified in ResourcePackContent or SerializableItemStack")
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.mineinabyss.geary.papermc.features.items.resourcepacks

import com.mineinabyss.geary.modules.geary
import com.mineinabyss.geary.papermc.gearyPaper
import com.mineinabyss.geary.papermc.tracking.items.gearyItems
import com.mineinabyss.geary.prefabs.PrefabKey
import com.mineinabyss.geary.prefabs.configuration.components.Prefab
import com.mineinabyss.geary.systems.builders.cache
Expand All @@ -16,16 +17,20 @@ import team.unnamed.creative.model.ModelTextures
class ResourcePackGenerator {

private val resourcePackQuery = geary.cache(ResourcePackQuery())
private val includedPackPath = gearyPaper.config.resourcePack.includedPackPath.takeUnless(String::isEmpty)?.let { gearyPaper.plugin.dataFolder.resolve(it) }
private val includedPackPath = gearyPaper.config.resourcePack.includedPackPath.takeUnless(String::isEmpty)
?.let { gearyPaper.plugin.dataFolder.resolve(it) }
private val resourcePack = includedPackPath?.let(ResourcePacks::readToResourcePack) ?: ResourcePack.resourcePack()

fun generateResourcePack() {
if (!gearyPaper.config.resourcePack.generate) return
val resourcePackFile = gearyPaper.plugin.dataFolder.resolve(gearyPaper.config.resourcePack.outputPath)
resourcePackFile.deleteRecursively()

resourcePackQuery.forEach { (prefabKey, resourcePackContent) ->
val vanillaModelKey = ResourcePacks.vanillaKeyForMaterial(resourcePackContent.baseMaterial)
resourcePackQuery.forEach { (prefabKey, resourcePackContent, itemStack) ->
val vanillaModelKey = ResourcePacks.vanillaKeyForMaterial(
resourcePackContent.baseMaterial ?: itemStack?.type
?: error("No baseMaterial defined in either ResourcePackContent or SerializableItemStack")
)
val defaultVanillaModel = ((resourcePack.model(vanillaModelKey)
?: ResourcePacks.defaultVanillaResourcePack?.model(vanillaModelKey)))
?.toBuilder() ?: Model.model().key(vanillaModelKey)
Expand All @@ -35,14 +40,14 @@ class ResourcePackGenerator {

// If a model is defined we assume it exists in the resourcepack already, and just add the override to the vanilla model
if (resourcePackContent.model != null) {
resourcePackContent.itemOverrides(resourcePackContent.model.key())
resourcePackContent.itemOverrides(resourcePackContent.model.key(), itemStack)
.forEach(defaultVanillaModel::addOverride)
} else { // If it only has textures we need to generate the model ourselves and add it
val model = Model.model()
.key(Key.key(prefabKey.namespace, prefabKey.key))
.parent(resourcePackContent.parentModel.key())
.textures(resourcePackContent.textures.modelTextures).build()
resourcePackContent.itemOverrides(model.key()).forEach(defaultVanillaModel::addOverride)
resourcePackContent.itemOverrides(model.key(), itemStack).forEach(defaultVanillaModel::addOverride)
model.let(ResourcePacks::ensureVanillaModelProperties)
.let(ResourcePacks::ensureItemOverridesSorted)
.addTo(resourcePack)
Expand Down Expand Up @@ -88,13 +93,15 @@ class ResourcePackGenerator {
class ResourcePackQuery : GearyQuery() {
private val prefabKey by get<PrefabKey>()
private val resourcePackContent by get<ResourcePackContent>()
//private val itemstack by get<SerializableItemStack>().orNull()

override fun ensure() = this {
has<Prefab>()
}

operator fun component1() = prefabKey
operator fun component2() = resourcePackContent
operator fun component3() = gearyItems.itemProvider.serializePrefabToItemStack(prefabKey)
}
}
}
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#Sat Oct 12 15:51:43 EDT 2024
group=com.mineinabyss
idofrontVersion=0.25.9
idofrontVersion=0.25.16
kotlin.code.style=official
version=0.30

0 comments on commit 9eca258

Please sign in to comment.