diff --git a/gradle.properties b/gradle.properties index 64b1c93d..2dff6ea3 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,7 +4,7 @@ kotlin.code.style=official kotlin.version=2.0.10 # Minecraft version -minecraft.version=24w35a +minecraft.version=24w36a # Gradle optimization flags org.gradle.caching=true diff --git a/kore/src/main/kotlin/io/github/ayfri/kore/arguments/EquipmentSlot.kt b/kore/src/main/kotlin/io/github/ayfri/kore/arguments/EquipmentSlot.kt new file mode 100644 index 00000000..4b8f0e8b --- /dev/null +++ b/kore/src/main/kotlin/io/github/ayfri/kore/arguments/EquipmentSlot.kt @@ -0,0 +1,19 @@ +package io.github.ayfri.kore.arguments + +import io.github.ayfri.kore.serializers.LowercaseSerializer +import kotlinx.serialization.Serializable + +@Serializable(EquipmentSlot.Companion.EquipmentSlotSerializer::class) +enum class EquipmentSlot { + HEAD, + CHEST, + LEGS, + FEET, + BODY, + MAINHAND, + OFFHAND; + + companion object { + data object EquipmentSlotSerializer : LowercaseSerializer(entries) + } +} \ No newline at end of file diff --git a/kore/src/main/kotlin/io/github/ayfri/kore/arguments/components/types/EquippableComponent.kt b/kore/src/main/kotlin/io/github/ayfri/kore/arguments/components/types/EquippableComponent.kt new file mode 100644 index 00000000..1336aae9 --- /dev/null +++ b/kore/src/main/kotlin/io/github/ayfri/kore/arguments/components/types/EquippableComponent.kt @@ -0,0 +1,41 @@ +package io.github.ayfri.kore.arguments.components.types + +import io.github.ayfri.kore.arguments.EquipmentSlot +import io.github.ayfri.kore.arguments.components.ComponentsScope +import io.github.ayfri.kore.arguments.types.EntityTypeOrTagArgument +import io.github.ayfri.kore.arguments.types.resources.ModelArgument +import io.github.ayfri.kore.arguments.types.resources.SoundEventArgument +import io.github.ayfri.kore.generated.ComponentTypes +import io.github.ayfri.kore.serializers.InlinableList +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class EquippableComponent( + var slot: EquipmentSlot, + @SerialName("equip_sound") + var equipSound: SoundEventArgument? = null, + var model: ModelArgument, + @SerialName("allowed_entities") + var allowedEntities: InlinableList? = null, + var dispensable: Boolean? = null, +) : Component() + +fun ComponentsScope.equippable( + slot: EquipmentSlot, + model: ModelArgument, + init: EquippableComponent.() -> Unit = {}, +) = apply { + this[ComponentTypes.EQUIPPABLE] = EquippableComponent(slot, model = model).apply(init) +} + +fun ComponentsScope.equippable( + slot: EquipmentSlot, + model: String, + namespace: String = "minecraft", + init: EquippableComponent.() -> Unit = {}, +) = equippable(slot, ModelArgument(model, namespace), init) + +fun EquippableComponent.allowedEntities(vararg entities: EntityTypeOrTagArgument) = apply { + allowedEntities = entities.toList() +} diff --git a/kore/src/main/kotlin/io/github/ayfri/kore/arguments/components/types/GliderComponent.kt b/kore/src/main/kotlin/io/github/ayfri/kore/arguments/components/types/GliderComponent.kt new file mode 100644 index 00000000..d81aee8a --- /dev/null +++ b/kore/src/main/kotlin/io/github/ayfri/kore/arguments/components/types/GliderComponent.kt @@ -0,0 +1,12 @@ +package io.github.ayfri.kore.arguments.components.types + +import io.github.ayfri.kore.arguments.components.ComponentsScope +import io.github.ayfri.kore.generated.ComponentTypes +import kotlinx.serialization.Serializable + +@Serializable +data object GliderComponent : Component() + +fun ComponentsScope.glider() = apply { + this[ComponentTypes.GLIDER] = GliderComponent +} \ No newline at end of file diff --git a/kore/src/main/kotlin/io/github/ayfri/kore/arguments/components/types/ItemModelComponent.kt b/kore/src/main/kotlin/io/github/ayfri/kore/arguments/components/types/ItemModelComponent.kt new file mode 100644 index 00000000..c710dc64 --- /dev/null +++ b/kore/src/main/kotlin/io/github/ayfri/kore/arguments/components/types/ItemModelComponent.kt @@ -0,0 +1,25 @@ +package io.github.ayfri.kore.arguments.components.types + +import io.github.ayfri.kore.arguments.components.ComponentsScope +import io.github.ayfri.kore.arguments.types.resources.ItemArgument +import io.github.ayfri.kore.arguments.types.resources.ModelArgument +import io.github.ayfri.kore.generated.ComponentTypes +import io.github.ayfri.kore.serializers.InlineSerializer +import kotlinx.serialization.Serializable + +@Serializable(with = ItemModelComponent.Companion.ItemModelComponentSerializer::class) +data class ItemModelComponent(var model: ModelArgument) : Component() { + companion object { + object ItemModelComponentSerializer : InlineSerializer( + ModelArgument.serializer(), + ItemModelComponent::model + ) + } +} + +fun ComponentsScope.itemModel(model: ModelArgument) = apply { + this[ComponentTypes.ITEM_MODEL] = ItemModelComponent(model) +} + +fun ComponentsScope.itemModel(model: String, namespace: String = "minecraft") = itemModel(ModelArgument(model, namespace)) +fun ComponentsScope.itemModel(model: ItemArgument) = itemModel(ModelArgument(model.asId().substringAfter(":"), model.namespace)) diff --git a/kore/src/main/kotlin/io/github/ayfri/kore/arguments/components/types/TooltipStyleComponent.kt b/kore/src/main/kotlin/io/github/ayfri/kore/arguments/components/types/TooltipStyleComponent.kt new file mode 100644 index 00000000..fa4ec371 --- /dev/null +++ b/kore/src/main/kotlin/io/github/ayfri/kore/arguments/components/types/TooltipStyleComponent.kt @@ -0,0 +1,23 @@ +package io.github.ayfri.kore.arguments.components.types + +import io.github.ayfri.kore.arguments.components.ComponentsScope +import io.github.ayfri.kore.arguments.types.resources.ModelArgument +import io.github.ayfri.kore.generated.ComponentTypes +import io.github.ayfri.kore.serializers.InlineSerializer +import kotlinx.serialization.Serializable + +@Serializable(with = TooltipStyleComponent.Companion.TooltipStyleComponentSerializer::class) +data class TooltipStyleComponent(var model: ModelArgument) : Component() { + companion object { + object TooltipStyleComponentSerializer : InlineSerializer( + ModelArgument.serializer(), + TooltipStyleComponent::model + ) + } +} + +fun ComponentsScope.tooltipStyle(model: ModelArgument) = apply { + this[ComponentTypes.TOOLTIP_STYLE] = TooltipStyleComponent(model) +} + +fun ComponentsScope.tooltipStyle(model: String, namespace: String = "minecraft") = tooltipStyle(ModelArgument(model, namespace)) \ No newline at end of file diff --git a/kore/src/main/kotlin/io/github/ayfri/kore/arguments/types/resources/ModelArgument.kt b/kore/src/main/kotlin/io/github/ayfri/kore/arguments/types/resources/ModelArgument.kt new file mode 100644 index 00000000..c0e55379 --- /dev/null +++ b/kore/src/main/kotlin/io/github/ayfri/kore/arguments/types/resources/ModelArgument.kt @@ -0,0 +1,17 @@ +package io.github.ayfri.kore.arguments.types.resources + +import io.github.ayfri.kore.arguments.Argument +import io.github.ayfri.kore.arguments.types.ResourceLocationArgument +import kotlinx.serialization.Serializable + +@Serializable(with = Argument.ArgumentSerializer::class) +interface ModelArgument : ResourceLocationArgument { + companion object { + operator fun invoke(model: String, namespace: String = "minecraft") = object : ModelArgument { + override val name = model + override val namespace = namespace + } + } +} + +fun model(model: String, namespace: String = "minecraft") = ModelArgument(model, namespace) \ No newline at end of file diff --git a/kore/src/main/kotlin/io/github/ayfri/kore/features/predicates/sub/entityspecific/Player.kt b/kore/src/main/kotlin/io/github/ayfri/kore/features/predicates/sub/entityspecific/Player.kt index 01120e8b..998ce2b3 100644 --- a/kore/src/main/kotlin/io/github/ayfri/kore/features/predicates/sub/entityspecific/Player.kt +++ b/kore/src/main/kotlin/io/github/ayfri/kore/features/predicates/sub/entityspecific/Player.kt @@ -9,6 +9,18 @@ import io.github.ayfri.kore.features.predicates.sub.Entity import io.github.ayfri.kore.features.predicates.sub.Statistic import kotlinx.serialization.Serializable + +@Serializable +data class Input( + var forward: Boolean? = null, + var backward: Boolean? = null, + var left: Boolean? = null, + var right: Boolean? = null, + var jump: Boolean? = null, + var sneak: Boolean? = null, + var sprint: Boolean? = null, +) + @Serializable data class Player( var lookingAt: Entity? = null, @@ -17,6 +29,7 @@ data class Player( var level: IntRangeOrIntJson? = null, var recipes: Map? = null, var stats: Map? = null, + var input: Input? = null, ) : EntityTypeSpecific() fun Entity.playerTypeSpecific(block: Player.() -> Unit = {}) = apply { @@ -46,3 +59,7 @@ fun MutableMap.statistic(statistic: StatisticArgum fun Player.recipes(vararg recipes: RecipeArgument, block: MutableMap.() -> Unit = {}) { this.recipes = (this.recipes ?: mutableMapOf()) + buildMap(block) + recipes.associateWith { true } } + +fun Player.input(block: Input.() -> Unit = {}) { + input = Input().apply(block) +} diff --git a/kore/src/test/kotlin/io/github/ayfri/kore/arguments/Components.kt b/kore/src/test/kotlin/io/github/ayfri/kore/arguments/Components.kt index a39aa993..deae39a9 100644 --- a/kore/src/test/kotlin/io/github/ayfri/kore/arguments/Components.kt +++ b/kore/src/test/kotlin/io/github/ayfri/kore/arguments/Components.kt @@ -254,6 +254,15 @@ fun componentsTests() { } entityDataTest.asString() assertsIs """minecraft:stone_sword[entity_data={test:"test"}]""" + val equippableTest = stoneSword { + equippable(EquipmentSlot.HEAD, "model") { + allowedEntities(EntityTypes.PLAYER) + dispensable = true + equipSound = SoundEvents.Item.Armor.EQUIP_IRON + } + } + equippableTest.asString() assertsIs """minecraft:stone_sword[equippable={slot:"head",equip_sound:"minecraft:item.armor.equip_iron",model:"minecraft:model",allowed_entities:"minecraft:player",dispensable:1b}]""" + val fireResistantTest = stoneSword { fireResistant() } @@ -297,6 +306,11 @@ fun componentsTests() { } foodTest.asString() assertsIs """minecraft:cooked_beef[food={nutrition:10.0f,saturation:1.0f,can_always_eat:1b}]""" + val gliderTest = Items.ELYTRA { + glider() + } + gliderTest.asString() assertsIs """minecraft:elytra[glider={}]""" + val hideAdditionalTooltipTest = stoneSword { hideAdditionalTooltip() } @@ -317,6 +331,13 @@ fun componentsTests() { } intangibleProjectileTest.asString() assertsIs """minecraft:crossbow[intangible_projectile={}]""" + val itemModelTest = stone { + itemModel("test") + } + itemModelTest.asString() assertsIs """minecraft:stone[item_model="minecraft:test"]""" + itemModelTest.components!!.itemModel(Items.DIAMOND) + itemModelTest.asString() assertsIs """minecraft:stone[item_model="minecraft:diamond"]""" + val itemNameTest = stoneSword { itemName(textComponent("test")) } @@ -485,6 +506,11 @@ fun componentsTests() { } toolTest.asString() assertsIs """minecraft:stone_sword[tool={rules:[{blocks:["#minecraft:base_stone_overworld","#minecraft:overworld_carver_replaceables","minecraft:hay_block"],speed:0.5f,correct_for_drops:1b}],default_mining_speed:2.0f}]""" + val tooltipStyleTest = stoneSword { + tooltipStyle("model") + } + tooltipStyleTest.asString() assertsIs """minecraft:stone_sword[tooltip_style="minecraft:model"]""" + val trimTest = Items.DIAMOND_CHESTPLATE { trim(TrimPatterns.SHAPER, TrimMaterials.DIAMOND) } diff --git a/kore/src/test/kotlin/io/github/ayfri/kore/arguments/components/ComponentTests.kt b/kore/src/test/kotlin/io/github/ayfri/kore/arguments/components/ComponentTests.kt deleted file mode 100644 index 0519ecba..00000000 --- a/kore/src/test/kotlin/io/github/ayfri/kore/arguments/components/ComponentTests.kt +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/kore/src/test/kotlin/io/github/ayfri/kore/features/PredicateEntityTypeSpecificTests.kt b/kore/src/test/kotlin/io/github/ayfri/kore/features/PredicateEntityTypeSpecificTests.kt index aeb53439..9d7d73c8 100644 --- a/kore/src/test/kotlin/io/github/ayfri/kore/features/PredicateEntityTypeSpecificTests.kt +++ b/kore/src/test/kotlin/io/github/ayfri/kore/features/PredicateEntityTypeSpecificTests.kt @@ -245,6 +245,15 @@ fun DataPack.predicateEntityTypeSpecificTests() { recipes { this[Recipes.BOW] = true } + input { + forward = true + backward = false + left = true + right = false + jump = true + sneak = false + sprint = true + } } } } @@ -260,6 +269,15 @@ fun DataPack.predicateEntityTypeSpecificTests() { ], "recipes": { "minecraft:bow": true + }, + "input": { + "forward": true, + "backward": false, + "left": true, + "right": false, + "jump": true, + "sneak": false, + "sprint": true } } }