> {
+ /**
+ * The set of providers to be registered.
+ */
+ val registry: CatalyxProviderRegistry
+
+ /**
+ * Register all enabled providers with the given event.
+ *
+ * @param event The registry event.
+ */
+ fun registerProvider(event: RegistryEvent.Register)
+
+ @SideOnly(Side.CLIENT)
+ fun registerModel(event: ModelRegistryEvent)
+
+ @SideOnly(Side.CLIENT)
+ fun bakeModel(event: ModelBakeEvent)
+
+ @SideOnly(Side.CLIENT)
+ fun stitchTexture(event: TextureStitchEvent.Pre)
+}
diff --git a/src/main/kotlin/org/ender_development/catalyx/api/v1/registry/IProvider.kt b/src/main/kotlin/org/ender_development/catalyx/api/v1/registry/IProvider.kt
new file mode 100644
index 0000000..e3799d5
--- /dev/null
+++ b/src/main/kotlin/org/ender_development/catalyx/api/v1/registry/IProvider.kt
@@ -0,0 +1,106 @@
+package org.ender_development.catalyx.api.v1.registry
+
+import net.minecraft.block.Block
+import net.minecraft.client.renderer.block.model.ModelResourceLocation
+import net.minecraft.item.Item
+import net.minecraft.item.ItemBlock
+import net.minecraft.util.ResourceLocation
+import net.minecraftforge.client.event.ModelRegistryEvent
+import net.minecraftforge.client.model.ModelLoader
+import net.minecraftforge.event.RegistryEvent
+import net.minecraftforge.fml.relauncher.Side
+import net.minecraftforge.fml.relauncher.SideOnly
+import net.minecraftforge.registries.IForgeRegistryEntry
+
+/**
+ * A provider of items or blocks to be registered.
+ */
+interface IProvider> {
+ /**
+ * The instance provided by this provider.
+ */
+ val instance: T
+
+ /**
+ * Whether this provider is enabled and should be registered.
+ */
+ fun isEnabled() =
+ true
+
+ /**
+ * Register this provider's item/block with the given event.
+ * This will only be called when the provider is [enabled][isEnabled].
+ *
+ * @param event The registry event.
+ */
+ fun register(event: RegistryEvent.Register) =
+ event.registry.register(instance)
+
+ /**
+ * Register this provider's model, this comes with a default implementation.
+ *
+ * @param event The registry event.
+ */
+ @SideOnly(Side.CLIENT)
+ fun registerModel(event: ModelRegistryEvent)
+
+ /**
+ * [ResourceLocation] of the model parent
+ */
+ val modelParent: ResourceLocation
+
+ /**
+ * [ResourceLocation] of the model file
+ */
+ val modelLocation: ResourceLocation
+
+ /**
+ * [ResourceLocation] of the texture file
+ */
+ val textureLocation: ResourceLocation
+}
+
+interface IItemProvider : IProvider- {
+ @SideOnly(Side.CLIENT)
+ override fun registerModel(event: ModelRegistryEvent) =
+ ModelLoader.setCustomModelResourceLocation(instance, 0, ModelResourceLocation(instance.registryName!!, "inventory"))
+
+ override val modelParent: ResourceLocation
+ get() = ResourceLocation("minecraft", "item/generated")
+
+ override val modelLocation: ResourceLocation
+ get() = ResourceLocation(instance.registryName!!.namespace, "item/${instance.registryName!!.path}")
+
+ override val textureLocation: ResourceLocation
+ get() = ResourceLocation(instance.registryName!!.namespace, "items/${instance.registryName!!.path}")
+}
+
+interface IBlockProvider : IProvider {
+ /**
+ * Override this instead of [registerItemBlock] if you only want to change the registered Item associated with this Block (like with a [org.ender_development.catalyx.core.items.TooltipItemBlock])
+ */
+ val item: Item
+ get() = ItemBlock(instance).setRegistryName(instance.registryName)
+
+ /**
+ * Register the Item for this Block with the given event.
+ * This will only be called, when the provider is [enabled][isEnabled].
+ *
+ * @param event The registry event for Items.
+ */
+ fun registerItemBlock(event: RegistryEvent.Register
- ) =
+ event.registry.register(item)
+
+ @SideOnly(Side.CLIENT)
+ override fun registerModel(event: ModelRegistryEvent) =
+ ModelLoader.setCustomModelResourceLocation(item, 0, ModelResourceLocation(item.registryName!!, "inventory"))
+
+ override val textureLocation: ResourceLocation
+ get() = ResourceLocation(instance.registryName!!.namespace, "blocks/${instance.registryName!!.path}")
+
+ override val modelLocation: ResourceLocation
+ get() = ResourceLocation(instance.registryName!!.namespace, "block/${instance.registryName!!.path}")
+
+ override val modelParent: ResourceLocation
+ get() = ResourceLocation("minecraft", "block/cube_all")
+}
diff --git a/src/main/kotlin/org/ender_development/catalyx/api/v1/registry/Registry.kt b/src/main/kotlin/org/ender_development/catalyx/api/v1/registry/Registry.kt
new file mode 100644
index 0000000..1ddc22e
--- /dev/null
+++ b/src/main/kotlin/org/ender_development/catalyx/api/v1/registry/Registry.kt
@@ -0,0 +1,31 @@
+package org.ender_development.catalyx.api.v1.registry
+
+import net.minecraft.block.Block
+import net.minecraft.item.Item
+import org.ender_development.catalyx.core.registry.CatalyxBlockRegistry
+import org.ender_development.catalyx.core.registry.CatalyxItemRegistry
+import org.ender_development.catalyx.core.registry.CatalyxProviderRegistry
+
+/**
+ * API-Status: NOT-FROZEN
+ * Beware
+ */
+
+
+object Registry {
+ /**
+ * Factory for a new [CatalyxProviderRegistry]
+ */
+ fun > newCatalyxProviderRegistry(): ICatalyxProviderRegistry =
+ CatalyxProviderRegistry()
+
+ /**
+ * Contains the Catalyx implementation of the [ICatalyxRegistry] for [Item]
+ */
+ val catalyxItemRegistry: ICatalyxRegistry
- = CatalyxItemRegistry
+
+ /**
+ * Contains the Catalyx implementation of the [ICatalyxRegistry] for [Block]
+ */
+ val catalyxBlockRegistry: ICatalyxRegistry = CatalyxBlockRegistry
+}
diff --git a/src/main/kotlin/org/ender_development/catalyx/api/v1/utils/Utils.kt b/src/main/kotlin/org/ender_development/catalyx/api/v1/utils/Utils.kt
new file mode 100644
index 0000000..874f920
--- /dev/null
+++ b/src/main/kotlin/org/ender_development/catalyx/api/v1/utils/Utils.kt
@@ -0,0 +1,53 @@
+package org.ender_development.catalyx.api.v1.utils
+
+import net.minecraft.tileentity.TileEntity
+import net.minecraftforge.fluids.Fluid
+import net.minecraftforge.fluids.FluidStack
+import net.minecraftforge.fluids.FluidTank
+import org.ender_development.catalyx.api.v1.utils.interfaces.IBlockPosUtils
+import org.ender_development.catalyx.api.v1.utils.interfaces.IEnvironmentUtils
+import org.ender_development.catalyx.core.utils.BlockPosUtils
+import org.ender_development.catalyx.core.utils.EnvironmentUtils
+
+object Utils {
+ val blockPos: IBlockPosUtils = BlockPosUtils
+
+ val environment: IEnvironmentUtils = EnvironmentUtils
+
+ // TODO find an abstraction
+ /**
+ * [This can't be an extension as of right now there is no way to create a static extension of a JVM class.](https://youtrack.jetbrains.com/issue/KT-11968)
+ */
+ @Suppress("ClassName")
+ object fluidTank {
+ inline fun create(tile: TileEntity, capacity: Int, canFill: Boolean, canDrain: Boolean, crossinline onContentsChangedCallback: () -> Unit) =
+ object : FluidTank(capacity) {
+ init {
+ setTileEntity(tile)
+ setCanFill(canFill)
+ setCanDrain(canDrain)
+ }
+
+ override fun onContentsChanged() =
+ onContentsChangedCallback()
+ }
+
+ inline fun create(tile: TileEntity, capacity: Int, canFill: Boolean, canDrain: Boolean, vararg fluidWhitelist: Fluid, crossinline onContentsChangedCallback: () -> Unit) =
+ object : FluidTank(capacity) {
+ init {
+ setTileEntity(tile)
+ setCanFill(canFill)
+ setCanDrain(canDrain)
+ }
+
+ override fun onContentsChanged() =
+ onContentsChangedCallback()
+
+ override fun canFillFluidType(fluid: FluidStack?) =
+ fluid != null && fluidWhitelist.any { fluid.fluid === it }
+
+ override fun canDrainFluidType(fluid: FluidStack?) =
+ canFillFluidType(fluid)
+ }
+ }
+}
diff --git a/src/main/kotlin/org/ender_development/catalyx/core/utils/math/BlockPosUtils.kt b/src/main/kotlin/org/ender_development/catalyx/api/v1/utils/interfaces/IBlockPosUtils.kt
similarity index 53%
rename from src/main/kotlin/org/ender_development/catalyx/core/utils/math/BlockPosUtils.kt
rename to src/main/kotlin/org/ender_development/catalyx/api/v1/utils/interfaces/IBlockPosUtils.kt
index 94402a0..e3c84dc 100644
--- a/src/main/kotlin/org/ender_development/catalyx/core/utils/math/BlockPosUtils.kt
+++ b/src/main/kotlin/org/ender_development/catalyx/api/v1/utils/interfaces/IBlockPosUtils.kt
@@ -1,11 +1,8 @@
-package org.ender_development.catalyx.core.utils.math
+package org.ender_development.catalyx.api.v1.utils.interfaces
import net.minecraft.util.math.BlockPos
-import org.ender_development.catalyx.core.utils.extensions.minus
-import org.ender_development.catalyx.core.utils.extensions.plus
-import org.ender_development.catalyx.core.utils.extensions.rotateY
-object BlockPosUtils {
+interface IBlockPosUtils {
/**
* Creates a wall shape centered at [center] with radius [r] and height [h].
*
@@ -17,23 +14,7 @@ object BlockPosUtils {
* @param shrink Reduces wall width by shrink blocks on its far end to avoid corner overlaps.
* @return A [Pair] of [BlockPos] representing the minimum and maximum corners of the wall.
*/
- fun wall(center: BlockPos, r: Int, h: Int, offset: Int = 0, degrees: Int = 0, shrink: Int = 0): Pair {
- val baseOrigin = BlockPos(center.x - r, center.y, center.z + r + offset)
- val v1 = BlockPos(2 * r - shrink, 0, 0)
- val v2 = BlockPos(0, h, 0)
-
- val origin = (baseOrigin - center).rotateY(degrees) + center
- val v1Rot = v1.rotateY(degrees)
-
- val corners = listOf(
- origin,
- origin + v1Rot,
- origin + v2,
- origin + v1Rot + v2
- )
-
- return BlockPos(corners.minOf { it.x }, corners.minOf { it.y }, corners.minOf { it.z }) to BlockPos(corners.maxOf { it.x }, corners.maxOf { it.y }, corners.maxOf { it.z })
- }
+ fun wall(center: BlockPos, r: Int, h: Int, offset: Int = 0, degrees: Int = 0, shrink: Int = 0): Pair
/**
* Creates a hollow cuboid shape centered at [center] with radius [r] and height [h].
@@ -43,10 +24,7 @@ object BlockPosUtils {
* @param r The radius from the center to the edges of the cuboid.
* @param h The height of the cuboid.
* @param offset An optional vertical offset to apply to the base of the cuboid.
- * @return A [List] of [Pair]`s` of [BlockPos] representing the minimum and maximum corners of each wall.
+ * @return A length 4 array of [Pair]s of [BlockPos] representing the minimum and maximum corners of each wall, see [BlockPosUtils#wall][wall].
*/
- fun hollowCuboid(center: BlockPos, r: Int, h: Int, offset: Int = 1, shrink: Int = 1) =
- (0..3).map {
- wall(center, r, h, offset, it * 90, shrink)
- }
+ fun hollowCuboid(center: BlockPos, r: Int, h: Int, offset: Int = 1, shrink: Int = 1): Array>
}
diff --git a/src/main/kotlin/org/ender_development/catalyx/api/v1/utils/interfaces/IEnvironmentUtils.kt b/src/main/kotlin/org/ender_development/catalyx/api/v1/utils/interfaces/IEnvironmentUtils.kt
new file mode 100644
index 0000000..48f08ef
--- /dev/null
+++ b/src/main/kotlin/org/ender_development/catalyx/api/v1/utils/interfaces/IEnvironmentUtils.kt
@@ -0,0 +1,17 @@
+package org.ender_development.catalyx.api.v1.utils.interfaces
+
+/**
+ * Utility object for checking the current environment - side (client or server) and deobfuscation.
+ */
+interface IEnvironmentUtils {
+ val isClient: Boolean
+ val isServer: Boolean
+ val isDedicatedClient: Boolean
+ val isDedicatedServer: Boolean
+
+ /**
+ * Whether you're in a deobfuscated (dev) environment
+ * @see [CoreModManager:208][net.minecraftforge.fml.relauncher.CoreModManager]
+ */
+ val isDeobfuscated: Boolean
+}
diff --git a/src/main/kotlin/org/ender_development/catalyx/core/utils/validation/CommonValidators.kt b/src/main/kotlin/org/ender_development/catalyx/api/v1/validation/CommonValidators.kt
similarity index 58%
rename from src/main/kotlin/org/ender_development/catalyx/core/utils/validation/CommonValidators.kt
rename to src/main/kotlin/org/ender_development/catalyx/api/v1/validation/CommonValidators.kt
index 6ea7edd..b684fc9 100644
--- a/src/main/kotlin/org/ender_development/catalyx/core/utils/validation/CommonValidators.kt
+++ b/src/main/kotlin/org/ender_development/catalyx/api/v1/validation/CommonValidators.kt
@@ -1,5 +1,11 @@
-package org.ender_development.catalyx.core.utils.validation
-
+package org.ender_development.catalyx.api.v1.validation
+
+import net.minecraft.item.ItemStack
+import org.ender_development.catalyx.api.v1.common.extensions.toBlock
+import org.ender_development.catalyx.api.v1.common.extensions.toBlockState
+import org.ender_development.catalyx.api.v1.common.extensions.toItem
+import org.ender_development.catalyx.api.v1.common.extensions.toStack
+import org.ender_development.catalyx.api.v1.validation.interfaces.IValidator
import org.ender_development.catalyx.core.config.ConfigParser
@Suppress("UNUSED")
@@ -34,12 +40,12 @@ object CommonValidators {
fun atMost(value: Number): IValidator =
IValidator { it != null && it.toDouble() <= value.toDouble() }
- fun oneOf(vararg values: T): IValidator =
- IValidator { it != null && values.contains(it) }
+ fun oneOf(vararg allowed: T): IValidator =
+ IValidator { it != null && it in allowed }
fun listAll(elementValidator: IValidator): IValidator
?> =
IValidator { list ->
- list != null && list.all { elementValidator.validate(it) }
+ list != null && list.all(elementValidator::validate)
}
fun mapAll(keyValidator: IValidator, valueValidator: IValidator): IValidator