Skip to content

Commit

Permalink
Merge branch 'rework-itembehavior' into features
Browse files Browse the repository at this point in the history
  • Loading branch information
NichtStudioCode committed Jul 15, 2023
2 parents 0dc1d63 + 0554d0e commit 25182eb
Show file tree
Hide file tree
Showing 53 changed files with 1,704 additions and 1,490 deletions.
23 changes: 15 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,25 @@
[![Banner](https://i.imgur.com/HiDAPmf.png)](https://hangar.papermc.io/xenondevs/Nova)

<p align="center">
<a href="https://www.spigotmc.org/resources/93648/reviews">
<img src="https://img.shields.io/spiget/rating/93648">
<a href="https://github.com/xenondevs/Nova/stargazers">
<img src="https://img.shields.io/github/stars/xenondevs/Nova">
</a>
<a href="https://www.spigotmc.org/resources/93648/">
<img src="https://img.shields.io/spiget/downloads/93648">
<a href="https://github.com/xenondevs/Nova/actions/workflows/ci.yml">
<img src="https://img.shields.io/github/actions/workflow/status/xenondevs/Nova/ci.yml">
</a>
<a href="https://www.spigotmc.org/resources/93648/">
<img src="https://img.shields.io/spiget/tested-versions/93648">
<a href="">
<img alt="Modrinth Game Versions" src="https://img.shields.io/modrinth/game-versions/nova-framework">
</a>
</p>
<p align="center">
<a href="https://hangar.papermc.io/xenondevs/Nova">
<img src="https://img.shields.io/modrinth/v/nova-framework?color=0552eb&label=Hangar">
</a>
<a href="https://modrinth.com/plugin/nova-framework">
<img src="https://img.shields.io/modrinth/v/nova-framework?label=Modrinth">
</a>
</p>


# Nova

Expand All @@ -19,8 +28,6 @@ With Nova, developers don't have to deal with resource pack tricks, data seriali
just focus in adding content to the game.
As a server administrator, you can choose from a set of Nova addons, which will add content to the game.

You can find Nova on: [SpigotMC](https://www.spigotmc.org/resources/93648/) | [Hangar](https://hangar.papermc.io/xenondevs/Nova) | [Modrinth](https://modrinth.com/plugin/nova-framework)

## Features

* Custom items
Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
version = 0.14.2
version = 0.14.3
kotlin.daemon.jvmargs=-Xmx2g
org.gradle.jvmargs=-Xmx2g
2 changes: 1 addition & 1 deletion gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
format.version = "1.1"

[versions]
cbf = "0.5"
cbf = "0.7"
invui = "1.12"
kotlin = "1.8.22"
ktor = "2.3.1"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ interface ItemRegistry : AddonGetter {

fun registerItem(
name: String,
vararg behaviors: ItemBehaviorHolder<*>,
vararg behaviors: ItemBehaviorHolder,
localizedName: String = "item.${addon.description.id}.$name",
isHidden: Boolean = false
): NovaItem {
Expand All @@ -37,7 +37,7 @@ interface ItemRegistry : AddonGetter {

fun registerItem(
block: NovaBlock,
vararg behaviors: ItemBehaviorHolder<*>,
vararg behaviors: ItemBehaviorHolder,
localizedName: String = block.localizedName,
isHidden: Boolean = false
): NovaItem {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import xyz.xenondevs.nova.item.NovaItem
import kotlin.reflect.KType
import kotlin.reflect.typeOf

abstract class ConfigAccess(private val configReceiver: () -> YamlConfiguration) {
open class ConfigAccess(private val configReceiver: () -> YamlConfiguration) {

val cfg: YamlConfiguration
get() = configReceiver()
Expand All @@ -20,11 +20,11 @@ abstract class ConfigAccess(private val configReceiver: () -> YamlConfiguration)

constructor(item: NovaItem) : this({ NovaConfig[item] })

protected inline fun <reified T : Any> getEntry(key: String): Provider<T> {
inline fun <reified T : Any> getEntry(key: String): Provider<T> {
return RequiredConfigEntryAccessor<T>(key, typeOf<T>()).also(ConfigEntryAccessor<*>::reload)
}

protected inline fun <reified T : Any> getEntry(key: String, vararg fallbackKeys: String): Provider<T> {
inline fun <reified T : Any> getEntry(key: String, vararg fallbackKeys: String): Provider<T> {
val type = typeOf<T>()
var provider: Provider<T?> = NullableConfigEntryAccessor(key, type)
fallbackKeys.forEach { provider = provider.orElse(NullableConfigEntryAccessor(it, type)) }
Expand All @@ -33,32 +33,35 @@ abstract class ConfigAccess(private val configReceiver: () -> YamlConfiguration)
.also(Provider<*>::update)
}

protected inline fun <reified T : Any> getOptionalEntry(key: String): Provider<T?> {
inline fun <reified T : Any> getOptionalEntry(key: String): Provider<T?> {
return NullableConfigEntryAccessor<T>(key, typeOf<T>()).also(Provider<*>::update)
}

protected inline fun <reified T : Any> getOptionalEntry(key: String, vararg fallbackKeys: String): Provider<T?> {
inline fun <reified T : Any> getOptionalEntry(key: String, vararg fallbackKeys: String): Provider<T?> {
val type = typeOf<T>()
var provider: Provider<T?> = NullableConfigEntryAccessor(key, type)
fallbackKeys.forEach { provider = provider.orElse(NullableConfigEntryAccessor(it, type)) }
return provider.also(Provider<*>::update)
}

protected inner class RequiredConfigEntryAccessor<T : Any>(key: String, type: KType) : ConfigEntryAccessor<T>(key, type) {
@PublishedApi
internal inner class RequiredConfigEntryAccessor<T : Any>(key: String, type: KType) : ConfigEntryAccessor<T>(key, type) {
override fun loadValue(): T {
check(key in cfg) { "No such config entry: $key" }
return cfg.getDeserialized(key, type)!!
}
}

protected inner class NullableConfigEntryAccessor<T : Any>(key: String, type: KType) : ConfigEntryAccessor<T?>(key, type) {
@PublishedApi
internal inner class NullableConfigEntryAccessor<T : Any>(key: String, type: KType) : ConfigEntryAccessor<T?>(key, type) {
override fun loadValue(): T? {
return cfg.getDeserialized(key, type)
}
}

@Suppress("LeakingThis")
protected abstract class ConfigEntryAccessor<T>(protected val key: String, protected val type: KType) : Provider<T>(), Reloadable {
@PublishedApi
internal abstract class ConfigEntryAccessor<T>(protected val key: String, protected val type: KType) : Provider<T>(), Reloadable {

init {
NovaConfig.reloadables += this
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import net.minecraft.world.item.enchantment.Enchantment
import net.minecraft.world.item.enchantment.EnchantmentHelper
import net.minecraft.world.level.Level
import xyz.xenondevs.nova.item.behavior.Damageable
import xyz.xenondevs.nova.util.item.DamageableUtils
import xyz.xenondevs.nova.util.item.novaItem
import xyz.xenondevs.nova.util.nmsCopy
import kotlin.math.max
Expand All @@ -26,7 +25,7 @@ internal class RepairItemRecipe(id: ResourceLocation) : MojangRepairItemRecipe(i
if (itemStack.isEmpty)
continue

if (!secondStackFound && DamageableUtils.isDamageable(itemStack) && itemStack.count == 1) {
if (!secondStackFound && Damageable.isDamageable(itemStack) && itemStack.count == 1) {
if (firstStack == null) {
firstStack = itemStack
} else if (isSameItem(firstStack, itemStack)) {
Expand All @@ -49,8 +48,8 @@ internal class RepairItemRecipe(id: ResourceLocation) : MojangRepairItemRecipe(i
require(items.size == 2) { "Item size is not 2" }
val novaItem = items[0].novaItem
if (novaItem != null) {
val damageable = novaItem.getBehavior(Damageable::class)!!
val maxDurability = damageable.options.durability
val damageable = novaItem.getBehavior(Damageable::class)
val maxDurability = damageable.maxDurability

val itemStackA = items[0]
val itemStackB = items[1]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,12 @@ import xyz.xenondevs.cbf.io.ByteReader
import xyz.xenondevs.cbf.io.ByteWriter
import xyz.xenondevs.nova.addon.Addon
import xyz.xenondevs.nova.util.name
import java.util.*
import kotlin.reflect.KType
import kotlin.reflect.typeOf

class NamespacedCompound internal constructor(
private val map: HashMap<String, Compound>
private val map: MutableMap<String, Compound>
) {

val keys: Set<ResourceLocation>
Expand Down Expand Up @@ -152,6 +153,13 @@ class NamespacedCompound internal constructor(
}


fun putAll(other: NamespacedCompound) {
for ((namespace, otherCompound) in other.map) {
val compound = map.getOrPut(namespace, ::Compound)
compound.putAll(otherCompound)
}
}

fun copy(): NamespacedCompound = NamespacedCompound(map.mapValuesTo(HashMap()) { (_, value) -> value.copy() })

fun isEmpty(): Boolean = map.isNotEmpty()
Expand All @@ -169,6 +177,12 @@ class NamespacedCompound internal constructor(
return builder.toString().replace("\n", "\n ") + "\n}"
}

companion object {

val EMPTY = NamespacedCompound(Collections.unmodifiableMap(HashMap()))

}

internal object NamespacedCompoundBinaryAdapter : BinaryAdapter<NamespacedCompound> {

override fun write(obj: NamespacedCompound, type: KType, writer: ByteWriter) {
Expand Down
6 changes: 3 additions & 3 deletions nova/src/main/kotlin/xyz/xenondevs/nova/item/DefaultItems.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
package xyz.xenondevs.nova.item

import net.minecraft.resources.ResourceLocation
import xyz.xenondevs.nova.initialize.InternalInitStage
import xyz.xenondevs.nova.initialize.InternalInit
import xyz.xenondevs.nova.initialize.InternalInitStage
import xyz.xenondevs.nova.item.behavior.ItemBehaviorHolder
import xyz.xenondevs.nova.item.behavior.impl.WrenchBehavior
import xyz.xenondevs.nova.item.logic.ItemLogic
Expand Down Expand Up @@ -137,7 +137,7 @@ object DefaultBlockOverlays {

private fun registerCoreItem(
name: String,
vararg itemBehaviors: ItemBehaviorHolder<*>,
vararg itemBehaviors: ItemBehaviorHolder,
localizedName: String = "item.nova.$name",
isHidden: Boolean = false
): NovaItem = register(NovaItem(
Expand All @@ -150,7 +150,7 @@ private fun registerCoreItem(
private fun registerUnnamedHiddenCoreItem(
name: String,
localizedName: String = "",
vararg itemBehaviors: ItemBehaviorHolder<*>
vararg itemBehaviors: ItemBehaviorHolder
): NovaItem = register(NovaItem(
ResourceLocation("nova", name),
localizedName,
Expand Down
26 changes: 19 additions & 7 deletions nova/src/main/kotlin/xyz/xenondevs/nova/item/NovaItem.kt
Original file line number Diff line number Diff line change
Expand Up @@ -109,26 +109,38 @@ class NovaItem internal constructor(
/**
* Checks whether this [NovaItem] has an [ItemBehavior] of the reified type [T], or a subclass of it.
*/
inline fun <reified T : ItemBehavior> hasBehavior(): Boolean =
inline fun <reified T : Any> hasBehavior(): Boolean =
hasBehavior(T::class)

/**
* Checks whether this [NovaItem] has an [ItemBehavior] of the specified class [behavior], or a subclass of it.
*/
fun <T : ItemBehavior> hasBehavior(behavior: KClass<T>): Boolean =
fun <T : Any> hasBehavior(behavior: KClass<T>): Boolean =
logic.hasBehavior(behavior)

/**
* Gets the [ItemBehavior] instance of the reified type [T], or a subclass of it.
* Gets the first [ItemBehavior] that is an instance of [T], or null if there is none.
*/
inline fun <reified T : ItemBehavior> getBehavior(): T? =
inline fun <reified T : Any> getBehaviorOrNull(): T? =
getBehaviorOrNull(T::class)

/**
* Gets the first [ItemBehavior] that is an instance of [behavior], or null if there is none.
*/
fun <T : Any> getBehaviorOrNull(behavior: KClass<T>): T? =
logic.getBehaviorOrNull(behavior)

/**
* Gets the first [ItemBehavior] that is an instance of [T], or throws an [IllegalStateException] if there is none.
*/
inline fun <reified T : Any> getBehavior(): T =
getBehavior(T::class)

/**
* Gets the [ItemBehavior] instance of the specified class [behavior], or a subclass of it.
* Gets the first [ItemBehavior] that is an instance of [behavior], or throws an [IllegalStateException] if there is none.
*/
fun <T : ItemBehavior> getBehavior(behavior: KClass<T>): T? =
logic.getBehavior(behavior)
fun <T : Any> getBehavior(behavior: KClass<T>): T =
getBehaviorOrNull(behavior) ?: throw IllegalStateException("Item $id does not have a behavior of type ${behavior.simpleName}")

override fun toString() = id.toString()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import xyz.xenondevs.nova.world.block.NovaTileEntityBlock

class NovaItemBuilder internal constructor(id: ResourceLocation): RegistryElementBuilder<NovaItem>(NovaRegistries.ITEM, id) {

private var logic: MutableList<ItemBehaviorHolder<*>> = ArrayList()
private var logic: MutableList<ItemBehaviorHolder> = ArrayList()
private var localizedName = "item.${id.namespace}.${id.name}"
private var maxStackSize = 64
private var craftingRemainingItem: ItemBuilder? = null
Expand All @@ -35,12 +35,12 @@ class NovaItemBuilder internal constructor(id: ResourceLocation): RegistryElemen
return this
}

fun behaviors(vararg itemBehaviors: ItemBehaviorHolder<*>): NovaItemBuilder {
fun behaviors(vararg itemBehaviors: ItemBehaviorHolder): NovaItemBuilder {
this.logic = itemBehaviors.toMutableList()
return this
}

fun addBehavior(vararg itemBehaviors: ItemBehaviorHolder<*>): NovaItemBuilder {
fun addBehavior(vararg itemBehaviors: ItemBehaviorHolder): NovaItemBuilder {
this.logic += itemBehaviors
return this
}
Expand Down Expand Up @@ -86,7 +86,7 @@ class NovaItemBuilder internal constructor(id: ResourceLocation): RegistryElemen
this.block = block
localizedName(block.localizedName)
if (block is NovaTileEntityBlock)
behaviors(TileEntityItemBehavior())
behaviors(TileEntityItemBehavior)
}
}

Expand Down
Loading

0 comments on commit 25182eb

Please sign in to comment.