From ced6d1b59c5fb38075ab8d9bc8c6e428fe09b918 Mon Sep 17 00:00:00 2001 From: Matthias <12-build@web.de> Date: Thu, 11 Jan 2024 22:00:29 +0100 Subject: [PATCH] added a recipe api + integrated into Item and Entity --- settings.gradle.kts | 2 +- .../addon/entity/behaviour/BehaviourEntity.kt | 21 ++++ .../entity/behaviour/BehaviourEntityImpl.kt | 13 +++ .../lop/devtools/monstera/addon/item/Item.kt | 26 +++++ .../monstera/addon/recipes/CraftingRecipe.kt | 101 ++++++++++++++++++ .../monstera/files/beh/recipes/BehRecipe.kt | 43 +++++++- .../files/beh/recipes/BehRecipeUnlock.kt | 97 +++++++++++++++++ .../com/lop/devtools/monstera/Integration.kt | 4 + 8 files changed, 304 insertions(+), 3 deletions(-) create mode 100644 src/main/kotlin/com/lop/devtools/monstera/addon/recipes/CraftingRecipe.kt create mode 100644 src/main/kotlin/com/lop/devtools/monstera/files/beh/recipes/BehRecipeUnlock.kt diff --git a/settings.gradle.kts b/settings.gradle.kts index 433b5da..913d4f4 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1 +1 @@ -rootProject.name = "monstera" \ No newline at end of file +rootProject.name = "Monstera" diff --git a/src/main/kotlin/com/lop/devtools/monstera/addon/entity/behaviour/BehaviourEntity.kt b/src/main/kotlin/com/lop/devtools/monstera/addon/entity/behaviour/BehaviourEntity.kt index cd47e61..3724239 100644 --- a/src/main/kotlin/com/lop/devtools/monstera/addon/entity/behaviour/BehaviourEntity.kt +++ b/src/main/kotlin/com/lop/devtools/monstera/addon/entity/behaviour/BehaviourEntity.kt @@ -4,6 +4,7 @@ import com.lop.devtools.monstera.addon.entity.Entity import com.lop.devtools.monstera.addon.entity.behaviour.components.OverwriteComponents import com.lop.devtools.monstera.addon.molang.Molang import com.lop.devtools.monstera.addon.molang.Query +import com.lop.devtools.monstera.addon.recipes.CraftingRecipe import com.lop.devtools.monstera.files.animcontroller.AnimController import com.lop.devtools.monstera.files.animcontroller.AnimationControllers import com.lop.devtools.monstera.files.beh.animations.BehAnimation @@ -19,6 +20,7 @@ interface BehaviourEntity: OverwriteComponents, AnimationControllerExtensions { val unsafeRawEntity: BehEntity val unsafeRawAnimations: BehAnimations val unsafeRawControllers: AnimationControllers + val unsafeRawCraftingRecipe: CraftingRecipe /** * add a runtimeIdentifier like guardian @@ -163,6 +165,25 @@ interface BehaviourEntity: OverwriteComponents, AnimationControllerExtensions { */ fun properties(data: EntityProperties.() -> Unit) + /** + * creates a recipe for the crafting table + * + * ``` + * craftingRecipe { + * craftingPattern( + * t("","minecraft:diamond","minecraft:diamond"), + * t("","minecraft:diamond",""), + * t("","minecraft:stick","") + * ) + * unlock { + * item("minecraft:wood", count = 3, data = 2) + * context() + * } + * } + * ``` + */ + fun craftingRecipe(data: CraftingRecipe.() -> Unit) + /** * internal function for building the beh files */ diff --git a/src/main/kotlin/com/lop/devtools/monstera/addon/entity/behaviour/BehaviourEntityImpl.kt b/src/main/kotlin/com/lop/devtools/monstera/addon/entity/behaviour/BehaviourEntityImpl.kt index f61d076..9149a69 100644 --- a/src/main/kotlin/com/lop/devtools/monstera/addon/entity/behaviour/BehaviourEntityImpl.kt +++ b/src/main/kotlin/com/lop/devtools/monstera/addon/entity/behaviour/BehaviourEntityImpl.kt @@ -4,6 +4,7 @@ import com.lop.devtools.monstera.addon.entity.Entity import com.lop.devtools.monstera.addon.entity.behaviour.components.OverwriteComponentsImpl import com.lop.devtools.monstera.addon.molang.Molang import com.lop.devtools.monstera.addon.molang.Query +import com.lop.devtools.monstera.addon.recipes.CraftingRecipe import com.lop.devtools.monstera.files.animcontroller.AnimController import com.lop.devtools.monstera.files.animcontroller.AnimStateComponent import com.lop.devtools.monstera.files.beh.animations.BehAnimation @@ -108,6 +109,10 @@ abstract class BehaviourEntityImpl( } } + override fun craftingRecipe(data: CraftingRecipe.() -> Unit) { + unsafeRawCraftingRecipe.apply(data) + } + override fun AnimStateComponent.controller(name: String, query: Query, data: AnimController.() -> Unit) { controller("${unsafeParent.name}.$name", query) animController(name, Query.False, data) @@ -141,5 +146,13 @@ abstract class BehaviourEntityImpl( unsafeParent.name, unsafeParent.addon.config.paths.behAnimController ) + + if(!unsafeRawCraftingRecipe.unsafe.isEmpty()) { + unsafeRawCraftingRecipe.unsafe.build( + unsafeParent.name, + unsafeParent.getIdentifier() + "_spawn_egg", + unsafeParent.addon + ) + } } } \ No newline at end of file diff --git a/src/main/kotlin/com/lop/devtools/monstera/addon/item/Item.kt b/src/main/kotlin/com/lop/devtools/monstera/addon/item/Item.kt index 1080fc4..e4886cb 100644 --- a/src/main/kotlin/com/lop/devtools/monstera/addon/item/Item.kt +++ b/src/main/kotlin/com/lop/devtools/monstera/addon/item/Item.kt @@ -1,6 +1,7 @@ package com.lop.devtools.monstera.addon.item import com.lop.devtools.monstera.addon.Addon +import com.lop.devtools.monstera.addon.recipes.CraftingRecipe import com.lop.devtools.monstera.files.beh.item.BehItem import com.lop.devtools.monstera.files.beh.item.BehItemComponents import com.lop.devtools.monstera.files.getUniqueFileName @@ -11,6 +12,7 @@ class Item(val name: String, val displayName: String, private val addon: Addon) private val behItem = BehItem() private val resItem = ResItem() private var category: String = "equipment" + private val craftingRecipe: CraftingRecipe = CraftingRecipe() fun category(category: String = "Equipment") { this.category = category @@ -53,11 +55,35 @@ class Item(val name: String, val displayName: String, private val addon: Addon) behItem.components(components) } + /** + * creates a recipe for the crafting table + * + * ``` + * craftingRecipe { + * craftingPattern( + * t("","minecraft:diamond","minecraft:diamond"), + * t("","minecraft:diamond",""), + * t("","minecraft:stick","") + * ) + * unlock { + * item("minecraft:wood", count = 3, data = 2) + * context() + * } + * } + * ``` + */ + fun craftingRecipe(data: CraftingRecipe.() -> Unit) { + craftingRecipe.apply(data) + } + fun build() { behItem.description(identifier(), category) behItem.unsafe.build(name, addon.config.paths.behItems) resItem.description(identifier(), category, displayName) resItem.unsafe.build(name, addon.config.paths.resItem) + + if(!craftingRecipe.unsafe.isEmpty()) + craftingRecipe.unsafe.build(name, identifier(), addon) } } \ No newline at end of file diff --git a/src/main/kotlin/com/lop/devtools/monstera/addon/recipes/CraftingRecipe.kt b/src/main/kotlin/com/lop/devtools/monstera/addon/recipes/CraftingRecipe.kt new file mode 100644 index 0000000..249a6cf --- /dev/null +++ b/src/main/kotlin/com/lop/devtools/monstera/addon/recipes/CraftingRecipe.kt @@ -0,0 +1,101 @@ +package com.lop.devtools.monstera.addon.recipes + +import com.lop.devtools.monstera.addon.Addon +import com.lop.devtools.monstera.addon.api.MonsteraFile +import com.lop.devtools.monstera.addon.api.MonsteraUnsafe +import com.lop.devtools.monstera.files.beh.recipes.BehRecipe +import com.lop.devtools.monstera.files.beh.recipes.BehRecipeUnlock +import com.lop.devtools.monstera.files.beh.recipes.RecipeTags + +class CraftingRecipe: MonsteraFile { + override val unsafe = Unsafe() + + inner class Unsafe: MonsteraUnsafe { + val rawRecipe = BehRecipe() + val keyPattern = mutableMapOf() + + fun isEmpty() = keyPattern.isEmpty() + + fun build(name: String, identifier: String, addon: Addon, resultItem: String = identifier) { + rawRecipe.identifier = identifier + rawRecipe.result(resultItem) + rawRecipe.keys { + keyPattern.forEach { (id, key) -> + key(key, id) + } + } + rawRecipe.unsafe.build(name, addon.config.paths.behRecipe) + } + } + + + /** + * add a pattern for the crafting table to the recipe + * + * ``` + * craftingPattern( + * t("","minecraft:diamond","minecraft:diamond"), + * t("","minecraft:diamond",""), + * t("","minecraft:stick","") + * ) + * ``` + */ + fun craftingPattern( + t1: Triple, + t2: Triple, + t3: Triple, + ) { + unsafe.rawRecipe.tags = arrayListOf(RecipeTags.CRAFTING_TABLE) + unsafe.rawRecipe.pattern = arrayListOf( + tripleToPattern(t1), + tripleToPattern(t2), + tripleToPattern(t3) + ) + } + + /** + * @param data define how this item will be unlocked in the recipe book + * + * ``` + * unlock { + * item("minecraft:wood", count = 3, data = 2) + * context() + * } + * ``` + */ + fun unlock(data: BehRecipeUnlock.() -> Unit) { + unsafe.rawRecipe.unlock(data) + } + + fun t(i1: String, i2: String, i3: String) = Triple(i1, i2, i3) + + private fun tripleToPattern(t: Triple): String { + var patternString = "" + patternString += compilePattern(t.first) + patternString += compilePattern(t.second) + patternString += compilePattern(t.third) + return patternString + } + + private fun compilePattern(t: String): String { + if(unsafe.keyPattern.containsKey(t)) + return unsafe.keyPattern[t]!! + + val ret = when(unsafe.keyPattern.size) { + 0 -> "F" + 1 -> "G" + 2 -> "H" + 3 -> "I" + 4 -> "J" + 5 -> "K" + 6 -> "L" + 7 -> "M" + 8 -> "N" + else -> "O" + } + + unsafe.keyPattern[t] = ret + + return ret + } +} \ No newline at end of file diff --git a/src/main/kotlin/com/lop/devtools/monstera/files/beh/recipes/BehRecipe.kt b/src/main/kotlin/com/lop/devtools/monstera/files/beh/recipes/BehRecipe.kt index b991fdd..7c1b572 100644 --- a/src/main/kotlin/com/lop/devtools/monstera/files/beh/recipes/BehRecipe.kt +++ b/src/main/kotlin/com/lop/devtools/monstera/files/beh/recipes/BehRecipe.kt @@ -2,14 +2,16 @@ package com.lop.devtools.monstera.files.beh.recipes import com.lop.devtools.monstera.addon.api.MonsteraFile import com.lop.devtools.monstera.addon.api.MonsteraUnsafeMap +import com.lop.devtools.monstera.files.MonsteraBuilder +import java.nio.file.Path -class BehRecipe: MonsteraFile { +class BehRecipe : MonsteraFile { /** * unsafe to use variables, used for plugins/ libraries */ override val unsafe = Unsafe() - inner class Unsafe: MonsteraUnsafeMap { + inner class Unsafe : MonsteraUnsafeMap { /** * access to all defined data */ @@ -27,10 +29,40 @@ class BehRecipe: MonsteraFile { reagent?.let { unsafe.general["reagent"] = it } return unsafe.general } + + fun build( + filename: String, + path: Path, + version: String = "1.17.41" + ) { + val sanFile = filename + .removeSuffix(".json") + .replace("-", "_") + .replace(" ", "_") + MonsteraBuilder.buildTo( + path, "$sanFile.json", mutableMapOf( + "format_version" to version, + "minecraft:recipe_shaped" to getData() + ) + ) + } } + var identifier: String? = null var tags: ArrayList? = null + set(value) { + if (field == null || value == null) + field = value + else + field?.let { field!!.addAll(it) } + } var pattern: ArrayList? = null + set(value) { + if (field == null || value == null) + field = value + else + field?.let { field!!.addAll(it) } + } var inputBrewingStand: String? = null var reagent: String? = null @@ -68,6 +100,13 @@ class BehRecipe: MonsteraFile { } } + /** + * @param data define how this item will be unlocked in the recipe book + */ + fun unlock(data: BehRecipeUnlock.() -> Unit) { + unsafe.general["unlock"] = BehRecipeUnlock().apply(data).unsafe.getData() + } + /** * 1 * diff --git a/src/main/kotlin/com/lop/devtools/monstera/files/beh/recipes/BehRecipeUnlock.kt b/src/main/kotlin/com/lop/devtools/monstera/files/beh/recipes/BehRecipeUnlock.kt new file mode 100644 index 0000000..7224242 --- /dev/null +++ b/src/main/kotlin/com/lop/devtools/monstera/files/beh/recipes/BehRecipeUnlock.kt @@ -0,0 +1,97 @@ +package com.lop.devtools.monstera.files.beh.recipes + +import com.lop.devtools.monstera.addon.api.MonsteraFile +import com.lop.devtools.monstera.addon.api.MonsteraUnsafeList +import com.lop.devtools.monstera.addon.molang.Molang + +class BehRecipeUnlock : MonsteraFile { + override val unsafe = Unsafe() + + inner class Unsafe : MonsteraUnsafeList { + val general = mutableListOf() + + override fun getData(): List { + return general + } + } + + /** + * @param identifier tells the recipe what item the player needs in their inventory in order for this recipe to be + * unlocked + */ + fun item(identifier: String) { + unsafe.general.add(mutableMapOf("item" to identifier)) + } + + /** + * @param identifier tells the recipe what item the player needs in their inventory in order for this recipe to be + * unlocked + * @param count the count of the item the player needs in their inventory + */ + fun item(identifier: String, count: Int) { + unsafe.general.add( + mutableMapOf( + "item" to identifier, + "count" to count + ) + ) + } + + /** + * @param identifier tells the recipe what item the player needs in their inventory in order for this recipe to be + * unlocked + * @param count the count of the item the player needs in their inventory + * @param data the data id of the item, can also be applied to the identifier like 'minecraft:planks:2' + */ + fun item(identifier: String, count: Int, data: Int) { + unsafe.general.add( + mutableMapOf( + "item" to identifier, + "data" to data, + "count" to count + ) + ) + } + + /** + * @param identifier tells the recipe what item the player needs in their inventory in order for this recipe to be + * unlocked + * @param count the count of the item the player needs in their inventory + * @param data the data id of the item, can also be applied to the identifier like 'minecraft:planks:2' as a query + * only known query is 'q.get_actor_info_id('minecraft:chicken')' + */ + fun item(identifier: String, count: Int, data: String) { + unsafe.general.add( + mutableMapOf( + "item" to identifier, + "data" to data, + "count" to count + ) + ) + } + + /** + * @param identifier tells the recipe what item the player needs in their inventory in order for this recipe to be + * unlocked + * @param count the count of the item the player needs in their inventory + * @param data the data id of the item, can also be applied to the identifier like 'minecraft:planks:2' as a query + * only known query is 'q.get_actor_info_id('minecraft:chicken')' + */ + fun item(identifier: String, count: Int, data: Molang) { + unsafe.general.add( + mutableMapOf( + "item" to identifier, + "data" to data, + "count" to count + ) + ) + } + + /** + * @param event is used to determine what event unlocks this recipe. "PlayerInWater" will unlock this recipe when + * the player enters water. This is also the only known context for recipes. + */ + fun context(event: String = "PlayerInWater") { + unsafe.general.add(mutableMapOf("context" to event)) + } +} \ No newline at end of file diff --git a/src/test/kotlin/com/lop/devtools/monstera/Integration.kt b/src/test/kotlin/com/lop/devtools/monstera/Integration.kt index 14d273d..679f74d 100644 --- a/src/test/kotlin/com/lop/devtools/monstera/Integration.kt +++ b/src/test/kotlin/com/lop/devtools/monstera/Integration.kt @@ -26,6 +26,10 @@ fun main() { default("ab") } } + + craftingRecipe { + + } } resource { components {