-
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Add ComponentTank * Add ComponentBlockEntity * fx patched components * Clean up merge * resolve some comments * add helpers * split up utils, switch to abstract val for initial components
- Loading branch information
1 parent
80b3a9e
commit 1b3d43a
Showing
12 changed files
with
324 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
40 changes: 40 additions & 0 deletions
40
src/main/java/earth/terrarium/techarium/mixin/common/BlockEntityMixin.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
package earth.terrarium.techarium.mixin.common; | ||
|
||
import com.llamalad7.mixinextras.sugar.Local; | ||
import earth.terrarium.techarium.common.blocks.entities.ComponentBlockEntity; | ||
import net.minecraft.core.component.DataComponentMap; | ||
import net.minecraft.core.component.DataComponentPatch; | ||
import net.minecraft.world.level.block.entity.BlockEntity; | ||
import org.spongepowered.asm.mixin.Mixin; | ||
import org.spongepowered.asm.mixin.injection.At; | ||
import org.spongepowered.asm.mixin.injection.Inject; | ||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; | ||
|
||
@Mixin(BlockEntity.class) | ||
public abstract class BlockEntityMixin { | ||
|
||
@Inject(method = "lambda$loadWithComponents$1", at = @At("HEAD"), cancellable = true) | ||
private void loadWithComponents(DataComponentMap components, CallbackInfo ci) { | ||
Object thisObject = this; | ||
//noinspection ConstantValue | ||
if (!(thisObject instanceof ComponentBlockEntity be)) return; | ||
ci.cancel(); | ||
be.setComponents(components); | ||
} | ||
|
||
@Inject( | ||
method = "applyComponents", | ||
at = @At( | ||
value = "INVOKE", | ||
target = "Lnet/minecraft/core/component/DataComponentPatch;split()Lnet/minecraft/core/component/DataComponentPatch$SplitResult;" | ||
), | ||
cancellable = true | ||
) | ||
private void applyComponents(CallbackInfo ci, @Local(ordinal = 1) DataComponentPatch components) { | ||
Object thisObject = this; | ||
//noinspection ConstantValue | ||
if (!(thisObject instanceof ComponentBlockEntity be)) return; | ||
ci.cancel(); | ||
be.applyComponents(components); | ||
} | ||
} |
7 changes: 2 additions & 5 deletions
7
src/main/kotlin/earth/terrarium/techarium/common/Techarium.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,19 +1,16 @@ | ||
package earth.terrarium.techarium.common | ||
|
||
import earth.terrarium.techarium.common.registries.ModBlockEntityTypes | ||
import earth.terrarium.techarium.common.registries.ModBlocks | ||
import earth.terrarium.techarium.common.registries.initializeRegistries | ||
import net.neoforged.bus.api.IEventBus | ||
import net.neoforged.fml.ModContainer | ||
import net.neoforged.fml.common.Mod | ||
import software.bernie.geckolib.GeckoLib | ||
|
||
@Mod(TechariumConstants.MOD_ID) | ||
class Techarium(modBus: IEventBus, mod: ModContainer) { | ||
|
||
init { | ||
println("Hello, ${mod.modInfo.displayName} v${mod.modInfo.version} (common)") | ||
|
||
ModBlocks.registry.init() | ||
ModBlockEntityTypes.registry.init() | ||
initializeRegistries() | ||
} | ||
} |
44 changes: 44 additions & 0 deletions
44
src/main/kotlin/earth/terrarium/techarium/common/blocks/entities/ComponentBlockEntity.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
package earth.terrarium.techarium.common.blocks.entities | ||
|
||
import net.minecraft.core.BlockPos | ||
import net.minecraft.core.component.DataComponentMap | ||
import net.minecraft.core.component.DataComponentPatch | ||
import net.minecraft.core.component.DataComponentType | ||
import net.minecraft.core.component.PatchedDataComponentMap | ||
import net.minecraft.world.level.block.entity.BlockEntity | ||
import net.minecraft.world.level.block.entity.BlockEntityType | ||
import net.minecraft.world.level.block.state.BlockState | ||
import net.neoforged.neoforge.common.MutableDataComponentHolder | ||
|
||
abstract class ComponentBlockEntity( | ||
type: BlockEntityType<*>, | ||
pos: BlockPos, | ||
state: BlockState | ||
) : BlockEntity(type, pos, state), MutableDataComponentHolder { | ||
|
||
abstract val initialComponents: DataComponentMap | ||
|
||
override fun getComponents(): DataComponentMap = this.components() | ||
|
||
private fun <R> editComponents(action: PatchedDataComponentMap.() -> R): R { | ||
val patched = components as? PatchedDataComponentMap ?: PatchedDataComponentMap(initialComponents).apply { setAll(components) } | ||
val value = patched.let(action) | ||
super.setComponents(patched) | ||
return value | ||
} | ||
|
||
override fun <T> set(componentType: DataComponentType<in T>, value: T?): T? = | ||
editComponents { set(componentType, value) } | ||
|
||
override fun <T> remove(type: DataComponentType<out T>): T? = | ||
editComponents { remove(type) } | ||
|
||
override fun applyComponents(patch: DataComponentPatch) = | ||
editComponents { applyPatch(patch) } | ||
|
||
override fun applyComponents(components: DataComponentMap) = | ||
editComponents { setAll(components) } | ||
|
||
override fun setComponents(components: DataComponentMap) = | ||
editComponents { setAll(components) } | ||
} |
90 changes: 90 additions & 0 deletions
90
...main/kotlin/earth/terrarium/techarium/common/capabilities/blocks/ComponentFluidHandler.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
package earth.terrarium.techarium.common.capabilities.blocks | ||
|
||
import earth.terrarium.techarium.common.registries.ModComponents | ||
import earth.terrarium.techarium.common.utils.ComponentSlot | ||
import earth.terrarium.techarium.common.utils.default | ||
import net.neoforged.neoforge.attachment.AttachmentType | ||
import net.neoforged.neoforge.attachment.IAttachmentHolder | ||
import net.neoforged.neoforge.common.MutableDataComponentHolder | ||
import net.neoforged.neoforge.fluids.FluidStack | ||
import net.neoforged.neoforge.fluids.capability.IFluidHandler | ||
|
||
typealias FluidValidator = (FluidStack) -> Boolean | ||
|
||
open class ComponentFluidHandler protected constructor( | ||
private val slot: ComponentSlot, | ||
private val getter: () -> FluidStack, | ||
private val setter: (FluidStack) -> Unit, | ||
holder: MutableDataComponentHolder, | ||
private val validator: FluidValidator = { true } | ||
) : IFluidHandler { | ||
|
||
private val data: Map<ComponentSlot, Int> by ModComponents.tankCapacity.default(emptyMap(), holder) | ||
|
||
private val capacity: Int get() = data[slot] ?: 0 | ||
private val amount: Int get() = fluid.amount | ||
private val remaining: Int get() = capacity - amount | ||
|
||
private var fluid: FluidStack | ||
get() = getter() | ||
set(value) = setter(value) | ||
|
||
override fun getTanks() = 1 | ||
override fun getTankCapacity(tank: Int) = capacity | ||
override fun getFluidInTank(tank: Int) = fluid | ||
override fun isFluidValid(tank: Int, stack: FluidStack) = validator(stack) | ||
|
||
override fun fill(resource: FluidStack, action: IFluidHandler.FluidAction): Int { | ||
if (resource.isEmpty || !isFluidValid(0, resource)) return 0 | ||
val amount = resource.amount.coerceAtMost(remaining) | ||
if (amount == 0) return 0 | ||
if (fluid.isEmpty) { | ||
if (action.execute()) { | ||
fluid = resource.copyWithAmount(amount) | ||
} | ||
return amount | ||
} | ||
if (FluidStack.isSameFluidSameComponents(fluid, resource)) { | ||
if (action.execute()) { | ||
fluid.amount += amount | ||
} | ||
return amount | ||
} | ||
return 0 | ||
} | ||
|
||
override fun drain(resource: FluidStack, action: IFluidHandler.FluidAction): FluidStack { | ||
if (resource.isEmpty || !FluidStack.isSameFluidSameComponents(fluid, resource)) return FluidStack.EMPTY | ||
return drain(resource.amount, action) | ||
} | ||
|
||
override fun drain(maxDrain: Int, action: IFluidHandler.FluidAction): FluidStack { | ||
val amount = maxDrain.coerceAtMost(amount) | ||
if (amount == 0) return FluidStack.EMPTY | ||
val fluid = fluid.copyWithAmount(amount) | ||
if (action.execute()) { | ||
fluid.amount -= amount | ||
} | ||
return fluid | ||
} | ||
|
||
companion object { | ||
|
||
fun create( | ||
slot: ComponentSlot, | ||
getter: () -> FluidStack, | ||
setter: (FluidStack) -> Unit, | ||
holder: MutableDataComponentHolder, | ||
validator: FluidValidator = { true } | ||
) = ComponentFluidHandler(slot, getter, setter, holder, validator) | ||
|
||
fun <T> create( | ||
slot: ComponentSlot, | ||
type: AttachmentType<FluidStack>, | ||
holder: T, | ||
validator: FluidValidator = { true } | ||
) | ||
where T : MutableDataComponentHolder, T : IAttachmentHolder = | ||
create(slot, { holder.getData(type) }, { holder.setData(type, it) }, holder, validator) | ||
} | ||
} |
27 changes: 27 additions & 0 deletions
27
src/main/kotlin/earth/terrarium/techarium/common/registries/ModComponents.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
package earth.terrarium.techarium.common.registries | ||
|
||
import com.mojang.serialization.Codec | ||
import com.teamresourceful.bytecodecs.base.ByteCodec | ||
import com.teamresourceful.resourcefullib.common.registry.ResourcefulRegistries | ||
import com.teamresourceful.resourcefullib.common.registry.ResourcefulRegistry | ||
import com.teamresourceful.resourcefullibkt.common.component | ||
import com.teamresourceful.resourcefullibkt.common.getValue | ||
import com.teamresourceful.resourcefullibkt.common.persistent | ||
import com.teamresourceful.resourcefullibkt.common.synced | ||
import earth.terrarium.techarium.common.TechariumConstants | ||
import earth.terrarium.techarium.common.utils.ComponentSlot | ||
import net.minecraft.core.component.DataComponentType | ||
import net.minecraft.core.registries.BuiltInRegistries | ||
|
||
object ModComponents { | ||
|
||
val registry: ResourcefulRegistry<DataComponentType<*>> = | ||
ResourcefulRegistries.create(BuiltInRegistries.DATA_COMPONENT_TYPE, TechariumConstants.MOD_ID) | ||
|
||
val tankCapacity: DataComponentType<Map<ComponentSlot, Int>> by registry.register("tank_capacity") { | ||
component { | ||
persistent = Codec.unboundedMap(ComponentSlot.CODEC, Codec.INT) | ||
synced = ByteCodec.mapOf(ComponentSlot.BYTE_CODEC, ByteCodec.INT) | ||
} | ||
} | ||
} |
7 changes: 7 additions & 0 deletions
7
src/main/kotlin/earth/terrarium/techarium/common/registries/RegistryHandler.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package earth.terrarium.techarium.common.registries | ||
|
||
internal fun initializeRegistries() { | ||
ModComponents.registry.init() | ||
ModBlocks.registry.init() | ||
ModBlockEntityTypes.registry.init() | ||
} |
33 changes: 33 additions & 0 deletions
33
src/main/kotlin/earth/terrarium/techarium/common/utils/AttachmentUtils.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
package earth.terrarium.techarium.common.utils | ||
|
||
import net.neoforged.neoforge.attachment.AttachmentHolder | ||
import net.neoforged.neoforge.attachment.AttachmentType | ||
import kotlin.properties.ReadWriteProperty | ||
import kotlin.reflect.KProperty | ||
|
||
operator fun <T : Any> AttachmentHolder.get(key: AttachmentType<T>): T = this.getData(key) | ||
operator fun <T : Any> AttachmentHolder.set(key: AttachmentType<T>, value: T) = this.setData(key, value) | ||
operator fun <T : Any> AttachmentHolder.minusAssign(key: AttachmentType<T>) { | ||
this.removeData(key) | ||
} | ||
|
||
operator fun <T : Any> AttachmentType<T>.getValue(thisRef: AttachmentHolder, property: KProperty<*>): T = thisRef[this] | ||
operator fun <T : Any> AttachmentType<T>.setValue(thisRef: AttachmentHolder, property: KProperty<*>, value: T) { | ||
thisRef[this] = value | ||
} | ||
|
||
class OptionalAttachmentDelegate<T : Any>(private val key: AttachmentType<T>) : | ||
ReadWriteProperty<AttachmentHolder, T?> { | ||
override operator fun getValue(thisRef: AttachmentHolder, property: KProperty<*>): T? = | ||
thisRef.getExistingData(key).orElse(null) | ||
|
||
override operator fun setValue(thisRef: AttachmentHolder, property: KProperty<*>, value: T?) { | ||
if (value == null) { | ||
thisRef -= key | ||
} else { | ||
thisRef[key] = value | ||
} | ||
} | ||
} | ||
|
||
fun <T : Any> AttachmentType<T>.optional() = OptionalAttachmentDelegate(this) |
16 changes: 16 additions & 0 deletions
16
src/main/kotlin/earth/terrarium/techarium/common/utils/ComponentSlot.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package earth.terrarium.techarium.common.utils | ||
|
||
import com.mojang.serialization.Codec | ||
import com.teamresourceful.bytecodecs.base.ByteCodec | ||
import com.teamresourceful.resourcefullib.common.codecs.EnumCodec | ||
|
||
enum class ComponentSlot { | ||
INPUT, | ||
OUTPUT, | ||
; | ||
|
||
companion object { | ||
val CODEC: Codec<ComponentSlot> = EnumCodec.of(ComponentSlot::class.java) | ||
val BYTE_CODEC: ByteCodec<ComponentSlot> = ByteCodec.ofEnum(ComponentSlot::class.java) | ||
} | ||
} |
42 changes: 42 additions & 0 deletions
42
src/main/kotlin/earth/terrarium/techarium/common/utils/ComponentUtils.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
package earth.terrarium.techarium.common.utils | ||
|
||
import net.minecraft.core.component.DataComponentMap | ||
import net.minecraft.core.component.DataComponentType | ||
import net.neoforged.neoforge.common.MutableDataComponentHolder | ||
import kotlin.reflect.KProperty | ||
|
||
class ComponentDelegate<T : Any>(private val key: DataComponentType<T>, private val default: T) { | ||
operator fun getValue(thisRef: MutableDataComponentHolder, property: KProperty<*>): T = thisRef[key] ?: default | ||
operator fun setValue(thisRef: MutableDataComponentHolder, property: KProperty<*>, value: T) { | ||
thisRef[key] = value | ||
} | ||
} | ||
|
||
class ComponentDelegateWithHolder<T : Any>( | ||
private val holder: MutableDataComponentHolder, | ||
private val key: DataComponentType<T>, | ||
private val default: T | ||
) { | ||
operator fun getValue(thisRef: Any, property: KProperty<*>): T = holder[key] ?: default | ||
operator fun setValue(thisRef: Any, property: KProperty<*>, value: T) { | ||
holder[key] = value | ||
} | ||
} | ||
|
||
operator fun <T : Any> DataComponentType<T>.getValue(thisRef: MutableDataComponentHolder, property: KProperty<*>): T? = | ||
thisRef[this] | ||
|
||
operator fun <T : Any> DataComponentType<T>.setValue( | ||
thisRef: MutableDataComponentHolder, | ||
property: KProperty<*>, | ||
value: T? | ||
) { | ||
thisRef[this] = value | ||
} | ||
|
||
fun <T : Any> DataComponentType<T>.default(default: T) = ComponentDelegate(this, default) | ||
fun <T : Any> DataComponentType<T>.default(default: T, holder: MutableDataComponentHolder) = | ||
ComponentDelegateWithHolder(holder, this, default) | ||
|
||
fun buildComponentMap(builder: DataComponentMap.Builder.() -> Unit): DataComponentMap = | ||
DataComponentMap.builder().apply(builder).build() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
{ | ||
"required": true, | ||
"minVersion": "0.8", | ||
"package": "earth.terrarium.techarium.mixin", | ||
"compatibilityLevel": "JAVA_21", | ||
"client": [ | ||
], | ||
"mixins": [ "common.BlockEntityMixin" ], | ||
"injectors": { | ||
"defaultRequire": 1 | ||
} | ||
} |