From 60536c4be51400d2c8b3c5e12a445768bb8a869d Mon Sep 17 00:00:00 2001 From: solonovamax Date: Mon, 7 Oct 2024 00:12:22 -0400 Subject: [PATCH] Add other changes from #59 that I didn't know where else to put Signed-off-by: solonovamax --- .../AbstractContainerScreenAccessor.java | 14 ++++ .../core/inventory/ContainerExtensions.kt | 50 ++++++++++++++ .../net/silkmc/silk/core/recipe/Ingredient.kt | 21 ++++++ .../silk/core/screen/ScreenExtensions.kt | 10 +++ .../silk/core/server/ServerExtensions.kt | 25 ++++++- .../silkmc/silk/core/world/WorldExtensions.kt | 67 +++++++++++++++++++ .../src/main/resources/silk-core.mixins.json | 29 ++++---- 7 files changed, 201 insertions(+), 15 deletions(-) create mode 100644 silk-core/src/main/java/net/silkmc/silk/core/mixin/client/AbstractContainerScreenAccessor.java create mode 100644 silk-core/src/main/kotlin/net/silkmc/silk/core/inventory/ContainerExtensions.kt create mode 100644 silk-core/src/main/kotlin/net/silkmc/silk/core/recipe/Ingredient.kt create mode 100644 silk-core/src/main/kotlin/net/silkmc/silk/core/screen/ScreenExtensions.kt create mode 100644 silk-core/src/main/kotlin/net/silkmc/silk/core/world/WorldExtensions.kt diff --git a/silk-core/src/main/java/net/silkmc/silk/core/mixin/client/AbstractContainerScreenAccessor.java b/silk-core/src/main/java/net/silkmc/silk/core/mixin/client/AbstractContainerScreenAccessor.java new file mode 100644 index 00000000..96178398 --- /dev/null +++ b/silk-core/src/main/java/net/silkmc/silk/core/mixin/client/AbstractContainerScreenAccessor.java @@ -0,0 +1,14 @@ +package net.silkmc.silk.core.mixin.client; + +import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; +import net.minecraft.world.inventory.Slot; +import org.jetbrains.annotations.Nullable; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +@Mixin(AbstractContainerScreen.class) +public interface AbstractContainerScreenAccessor { + @Accessor + @Nullable + Slot getHoveredSlot(); +} diff --git a/silk-core/src/main/kotlin/net/silkmc/silk/core/inventory/ContainerExtensions.kt b/silk-core/src/main/kotlin/net/silkmc/silk/core/inventory/ContainerExtensions.kt new file mode 100644 index 00000000..617433e0 --- /dev/null +++ b/silk-core/src/main/kotlin/net/silkmc/silk/core/inventory/ContainerExtensions.kt @@ -0,0 +1,50 @@ +@file:Suppress("unused") + +package net.silkmc.silk.core.inventory + +import net.minecraft.core.Holder +import net.minecraft.core.HolderSet +import net.minecraft.tags.TagKey +import net.minecraft.world.Container +import net.minecraft.world.item.Item +import net.minecraft.world.item.ItemStack + +operator fun Container.get(slot: Int): ItemStack = getItem(slot) + +operator fun Container.set(slot: Int, stack: ItemStack) = setItem(slot, stack) + +operator fun Container.iterator(): Iterator = ContainerIterator(this) + +operator fun Container.contains(item: Item): Boolean { + return hasAnyMatching { other -> !other.isEmpty && ItemStack.isSameItemSameComponents(other, item.defaultInstance) } +} + +operator fun Container.contains(stack: ItemStack): Boolean { + return hasAnyMatching { other -> !other.isEmpty && ItemStack.isSameItemSameComponents(other, stack) } +} + +operator fun Container.contains(tag: TagKey): Boolean { + return hasAnyMatching { itemStack -> !itemStack.isEmpty && itemStack.`is`(tag) } +} + +operator fun Container.contains(item: Holder): Boolean { + return hasAnyMatching { itemStack -> !itemStack.isEmpty && itemStack.`is`(item) } +} + +operator fun Container.contains(item: HolderSet): Boolean { + return hasAnyMatching { itemStack -> !itemStack.isEmpty && itemStack.`is`(item) } +} + +operator fun Container.contains(predicate: (ItemStack) -> Boolean): Boolean { + return hasAnyMatching(predicate) +} + +private class ContainerIterator(private val container: Container) : Iterator { + var pos = 0 + + override fun hasNext() = pos <= container.containerSize + + override fun next(): ItemStack { + return container[pos++] + } +} diff --git a/silk-core/src/main/kotlin/net/silkmc/silk/core/recipe/Ingredient.kt b/silk-core/src/main/kotlin/net/silkmc/silk/core/recipe/Ingredient.kt new file mode 100644 index 00000000..a57f75eb --- /dev/null +++ b/silk-core/src/main/kotlin/net/silkmc/silk/core/recipe/Ingredient.kt @@ -0,0 +1,21 @@ +@file:Suppress("unused") + +package net.silkmc.silk.core.recipe + +import net.minecraft.tags.TagKey +import net.minecraft.world.item.Item +import net.minecraft.world.item.ItemStack +import net.minecraft.world.item.crafting.Ingredient +import net.minecraft.world.level.ItemLike + +fun ingredientOf(vararg items: ItemLike): Ingredient { + return Ingredient.of(*items) +} + +fun ingredientOf(vararg items: ItemStack): Ingredient { + return Ingredient.of(*items) +} + +fun ingredientOf(items: TagKey): Ingredient { + return Ingredient.of(items) +} diff --git a/silk-core/src/main/kotlin/net/silkmc/silk/core/screen/ScreenExtensions.kt b/silk-core/src/main/kotlin/net/silkmc/silk/core/screen/ScreenExtensions.kt new file mode 100644 index 00000000..fdc76bbb --- /dev/null +++ b/silk-core/src/main/kotlin/net/silkmc/silk/core/screen/ScreenExtensions.kt @@ -0,0 +1,10 @@ +@file:Suppress("unused") + +package net.silkmc.silk.core.screen + +import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen +import net.minecraft.world.inventory.Slot +import net.silkmc.silk.core.mixin.client.AbstractContainerScreenAccessor + +val AbstractContainerScreen<*>.focusedSlot: Slot? + get() = (this as AbstractContainerScreenAccessor).hoveredSlot diff --git a/silk-core/src/main/kotlin/net/silkmc/silk/core/server/ServerExtensions.kt b/silk-core/src/main/kotlin/net/silkmc/silk/core/server/ServerExtensions.kt index f9ec9a74..691f19f6 100644 --- a/silk-core/src/main/kotlin/net/silkmc/silk/core/server/ServerExtensions.kt +++ b/silk-core/src/main/kotlin/net/silkmc/silk/core/server/ServerExtensions.kt @@ -1,7 +1,13 @@ +@file:Suppress("unused") + package net.silkmc.silk.core.server import net.minecraft.commands.CommandSourceStack +import net.minecraft.core.registries.Registries +import net.minecraft.resources.ResourceKey +import net.minecraft.resources.ResourceLocation import net.minecraft.server.MinecraftServer +import net.minecraft.server.level.ServerLevel import net.minecraft.server.level.ServerPlayer import java.nio.file.Path import kotlin.io.path.absolute @@ -33,8 +39,7 @@ val MinecraftServer.players: List get() = playerList.players /** - * Returns the current run directory of the server as an - * absolute [Path]. + * Returns the current run directory of the server as an absolute [Path]. */ @Deprecated( message = "Minecraft now offers a 'serverDirectory' property, use that instead.", @@ -42,3 +47,19 @@ val MinecraftServer.players: List ) val MinecraftServer.serverPath: Path get() = serverDirectory.absolute() + +/** + * Retrieves the level for an associated with an id is present + * + * @param id The id of the level to check + * @return The level + */ +fun MinecraftServer.getLevel(id: ResourceLocation): ServerLevel? = getLevel(ResourceKey.create(Registries.DIMENSION, id)) + +/** + * Checks if the level associated with an id is present + * + * @param id The id of the level to check + * @return If the level is present + */ +fun MinecraftServer.hasLevel(id: ResourceLocation): Boolean = getLevel(id) != null diff --git a/silk-core/src/main/kotlin/net/silkmc/silk/core/world/WorldExtensions.kt b/silk-core/src/main/kotlin/net/silkmc/silk/core/world/WorldExtensions.kt new file mode 100644 index 00000000..3c9d06ee --- /dev/null +++ b/silk-core/src/main/kotlin/net/silkmc/silk/core/world/WorldExtensions.kt @@ -0,0 +1,67 @@ +@file:Suppress("unused") + +package net.silkmc.silk.core.world + +import net.minecraft.world.entity.Entity +import net.minecraft.world.entity.EntitySelector +import net.minecraft.world.level.CollisionGetter +import net.minecraft.world.level.EntityGetter +import net.minecraft.world.level.Level +import net.minecraft.world.level.entity.EntityTypeTest +import net.minecraft.world.phys.AABB +import net.minecraft.world.phys.shapes.VoxelShape +import net.silkmc.silk.core.kotlin.asKotlinRandom +import kotlin.random.Random + +val Level.kotlinRandom: Random + get() = random.asKotlinRandom() + +fun CollisionGetter.entityCollisions( + entity: Entity? = null, + box: AABB, +): List { + return getEntityCollisions(entity, box) +} + +fun CollisionGetter.collisions( + entity: Entity? = null, + box: AABB, +): Iterable { + return getCollisions(entity, box) +} + +fun CollisionGetter.blockCollisions( + entity: Entity? = null, + box: AABB, +): Iterable { + return getBlockCollisions(entity, box) +} + +fun EntityGetter.entityCollisions( + entity: Entity? = null, + box: AABB, +): List { + return getEntityCollisions(entity, box) +} + +fun EntityGetter.entities( + except: Entity? = null, + box: AABB, + predicate: (Entity) -> Boolean = EntitySelector.NO_SPECTATORS::test, +): List { + return getEntities(except, box, predicate) +} + +inline fun EntityGetter.entitiesByType( + box: AABB, + noinline predicate: (T) -> Boolean = EntitySelector.NO_SPECTATORS::test, +): List { + return getEntities(EntityTypeTest.forClass(T::class.java), box, predicate) +} + +inline fun EntityGetter.entitiesByClass( + box: AABB, + noinline predicate: (T) -> Boolean = EntitySelector.NO_SPECTATORS::test, +): List { + return getEntitiesOfClass(T::class.java, box, predicate) +} diff --git a/silk-core/src/main/resources/silk-core.mixins.json b/silk-core/src/main/resources/silk-core.mixins.json index ec54db7e..3fe64a95 100644 --- a/silk-core/src/main/resources/silk-core.mixins.json +++ b/silk-core/src/main/resources/silk-core.mixins.json @@ -1,15 +1,18 @@ { - "package": "net.silkmc.silk.core.mixin", - "required": true, - "compatibilityLevel": "JAVA_21", - "mixins": [ - "block.AbstractBlockAccessor", - "entity.MixinEntity", - "entity.MixinLivingEntity", - "server.MixinMinecraftServer", - "server.MixinPlayerList", - "server.MixinServerConfigurationPacketListenerImpl", - "server.MixinServerGamePacketListenerImpl", - "server.MixinServerLoginPacketListenerImpl" - ] + "package": "net.silkmc.silk.core.mixin", + "required": true, + "compatibilityLevel": "JAVA_21", + "mixins": [ + "block.AbstractBlockAccessor", + "entity.MixinEntity", + "entity.MixinLivingEntity", + "server.MixinMinecraftServer", + "server.MixinPlayerList", + "server.MixinServerConfigurationPacketListenerImpl", + "server.MixinServerGamePacketListenerImpl", + "server.MixinServerLoginPacketListenerImpl" + ], + "client": [ + "client.AbstractContainerScreenAccessor" + ] }