Compare commits

...

23 Commits

Author SHA1 Message Date
3fab525345
Merge branch '1.21' into new-container-api 2025-03-26 23:00:26 +07:00
af24f391df
Fix blocks without menu still behaving like being interacted with clientside 2025-03-26 23:00:18 +07:00
10421570be
forgor about gauge updates when container contents changes in matter capacitor bank 2025-03-26 22:51:42 +07:00
4d51ed5210
Optimize battery bank 2025-03-26 22:50:13 +07:00
39a996f79f
Fix matter capacitor bank not marking chunks as dirty 2025-03-26 22:40:44 +07:00
a26840f670
sumOfDecimal 2025-03-26 22:38:27 +07:00
5281a5aeee
Remove jvm overloads from matter capacitor bank menu 2025-03-26 22:38:18 +07:00
750f941525
Optimize matter capacitor bank 2025-03-26 22:38:02 +07:00
7405989b97
Merge branch '1.21' into new-container-api 2025-03-26 22:21:11 +07:00
140bdab59c
Fix swapped out condition checks in nextDecimal 2025-03-26 22:21:02 +07:00
c2f20a76f6
Merge branch '1.21' into new-container-api 2025-03-26 22:14:39 +07:00
a3ed886900
Fix wrong matter recycler receive values 2025-03-26 22:11:37 +07:00
1087e755ff
And now, proper random decimals implementation 2025-03-26 22:09:40 +07:00
c965bcdc82
Move decimal sampling to random utils 2025-03-26 19:36:52 +07:00
5663b262eb
Move random extensions to RandomUtils file 2025-03-26 19:34:22 +07:00
e93c766edb
Move stuff from "Decimal" to appropriate places 2025-03-26 19:16:30 +07:00
85dde24e59
Update energy counter menu code 2025-03-26 19:06:39 +07:00
4fc646a13a
Energy counter "pull" mode 2025-03-26 18:52:26 +07:00
ddcfe11780
Caused by: java.lang.NoClassDefFoundError: ru/dbotthepony/mc/otm/android/feature/LimbOverclockingFeature 2025-03-24 23:33:52 +07:00
6226621b95
god damn it 2025-03-24 18:15:53 +07:00
1bb612b07c
Fixes for last commit 2025-03-24 18:14:47 +07:00
588b9c1b7c
Put all otm registries in one place 2025-03-24 13:55:36 +07:00
fdfc406ca6
Make exopack slot upgrades be consumed in stacks, to make bulk use way less annoying 2025-03-23 01:48:33 +07:00
58 changed files with 685 additions and 507 deletions

View File

@ -631,6 +631,8 @@ private fun blocks(provider: MatteryLanguageProvider) {
add(MBlocks.ENERGY_COUNTER[null]!!, "switch", "Switch input facing") add(MBlocks.ENERGY_COUNTER[null]!!, "switch", "Switch input facing")
add(MBlocks.ENERGY_COUNTER[null]!!, "limit", "I/O Limit. -1 means no limit") add(MBlocks.ENERGY_COUNTER[null]!!, "limit", "I/O Limit. -1 means no limit")
add(MBlocks.ENERGY_COUNTER[null]!!, "display_this", "Display this information on block's screen") add(MBlocks.ENERGY_COUNTER[null]!!, "display_this", "Display this information on block's screen")
add(MBlocks.ENERGY_COUNTER[null]!!, "do_pull", "Pull energy from input side and push to output")
add(MBlocks.ENERGY_COUNTER[null]!!, "dont_pull", "Don't pull energy")
addBlock(MBlocks.CHEMICAL_GENERATOR.values, "Chemical Generator") addBlock(MBlocks.CHEMICAL_GENERATOR.values, "Chemical Generator")
addBlock(MBlocks.CHEMICAL_GENERATOR.values, "desc", "Generates power by burning solid fuels") addBlock(MBlocks.CHEMICAL_GENERATOR.values, "desc", "Generates power by burning solid fuels")

View File

@ -635,6 +635,8 @@ private fun blocks(provider: MatteryLanguageProvider) {
add(MBlocks.ENERGY_COUNTER[null]!!, "switch", "Сменить сторону входа") add(MBlocks.ENERGY_COUNTER[null]!!, "switch", "Сменить сторону входа")
add(MBlocks.ENERGY_COUNTER[null]!!, "limit", "Лимит ввода/вывода. -1 для отключения лимитов") add(MBlocks.ENERGY_COUNTER[null]!!, "limit", "Лимит ввода/вывода. -1 для отключения лимитов")
add(MBlocks.ENERGY_COUNTER[null]!!, "display_this", "Отображать эти данные на экране блока") add(MBlocks.ENERGY_COUNTER[null]!!, "display_this", "Отображать эти данные на экране блока")
add(MBlocks.ENERGY_COUNTER[null]!!, "do_pull", "Забирать энергию на входе и выталкивать её на выходе")
add(MBlocks.ENERGY_COUNTER[null]!!, "dont_pull", "Не забирать энергию на входе")
addBlock(MBlocks.CHEMICAL_GENERATOR.values, "Химический генератор") addBlock(MBlocks.CHEMICAL_GENERATOR.values, "Химический генератор")
addBlock(MBlocks.CHEMICAL_GENERATOR.values, "desc", "Генерирует энергию сжигая твёрдое топливо") addBlock(MBlocks.CHEMICAL_GENERATOR.values, "desc", "Генерирует энергию сжигая твёрдое топливо")

View File

@ -104,6 +104,8 @@ object OverdriveThatMatters {
fun loc(path: String): ResourceLocation = ResourceLocation.fromNamespaceAndPath(MOD_ID, path) fun loc(path: String): ResourceLocation = ResourceLocation.fromNamespaceAndPath(MOD_ID, path)
init { init {
MBuiltInRegistries.register(MOD_BUS)
MBlocks.register(MOD_BUS) MBlocks.register(MOD_BUS)
MFluids.register(MOD_BUS) MFluids.register(MOD_BUS)
MBlockEntities.register(MOD_BUS) MBlockEntities.register(MOD_BUS)
@ -134,9 +136,7 @@ object OverdriveThatMatters {
MOD_BUS.addListener(::registerNetworkPackets) MOD_BUS.addListener(::registerNetworkPackets)
DecimalProvider.register(MOD_BUS) DecimalProvider.register(MOD_BUS)
AndroidResearchDescription.register(MOD_BUS)
AndroidResearchDescriptions.register(MOD_BUS) AndroidResearchDescriptions.register(MOD_BUS)
AndroidResearchResult.register(MOD_BUS)
AndroidResearchResults.register(MOD_BUS) AndroidResearchResults.register(MOD_BUS)
AbstractRegistryAction.register(MOD_BUS) AbstractRegistryAction.register(MOD_BUS)

View File

@ -16,7 +16,6 @@ import net.minecraft.network.chat.Component
import net.minecraft.network.chat.ComponentSerialization import net.minecraft.network.chat.ComponentSerialization
import net.minecraft.server.level.ServerLevel import net.minecraft.server.level.ServerLevel
import net.minecraft.util.RandomSource import net.minecraft.util.RandomSource
import net.minecraft.world.Containers
import net.minecraft.world.InteractionResult import net.minecraft.world.InteractionResult
import net.minecraft.world.MenuProvider import net.minecraft.world.MenuProvider
import net.minecraft.world.entity.LivingEntity import net.minecraft.world.entity.LivingEntity
@ -36,8 +35,6 @@ import net.minecraft.world.phys.shapes.VoxelShape
import org.apache.logging.log4j.LogManager import org.apache.logging.log4j.LogManager
import ru.dbotthepony.mc.otm.block.entity.IRedstoneControlled import ru.dbotthepony.mc.otm.block.entity.IRedstoneControlled
import ru.dbotthepony.mc.otm.block.entity.MatteryBlockEntity import ru.dbotthepony.mc.otm.block.entity.MatteryBlockEntity
import ru.dbotthepony.mc.otm.block.entity.MatteryDeviceBlockEntity
import ru.dbotthepony.mc.otm.block.entity.MatteryDeviceBlockEntity.Companion
import ru.dbotthepony.mc.otm.block.entity.WorkerState import ru.dbotthepony.mc.otm.block.entity.WorkerState
import ru.dbotthepony.mc.otm.core.TooltipList import ru.dbotthepony.mc.otm.core.TooltipList
import ru.dbotthepony.mc.otm.core.TranslatableComponent import ru.dbotthepony.mc.otm.core.TranslatableComponent
@ -149,6 +146,9 @@ open class MatteryBlock(properties: Properties = DEFAULT_PROPERTIES) : Block(pro
return getShapeForEachState(ArrayList(stateDefinition.properties), mapper) return getShapeForEachState(ArrayList(stateDefinition.properties), mapper)
} }
protected open val neverOpensAMenu: Boolean
get() = false
override fun useWithoutItem( override fun useWithoutItem(
blockState: BlockState, blockState: BlockState,
level: Level, level: Level,
@ -156,18 +156,17 @@ open class MatteryBlock(properties: Properties = DEFAULT_PROPERTIES) : Block(pro
ply: Player, ply: Player,
blockHitResult: BlockHitResult blockHitResult: BlockHitResult
): InteractionResult { ): InteractionResult {
if (this is EntityBlock && !level.isClientSide) { if (!neverOpensAMenu && this is EntityBlock) {
val tile = level.getBlockEntity(blockPos) val tile = level.getBlockEntity(blockPos)
if (tile is MenuProvider) { if (tile is MenuProvider) {
ply.openMenu(tile) if (!level.isClientSide)
return InteractionResult.CONSUME ply.openMenu(tile)
return InteractionResult.sidedSuccess(level.isClientSide)
} }
} }
if (this is EntityBlock && level.isClientSide)
return InteractionResult.SUCCESS
return super.useWithoutItem(blockState, level, blockPos, ply, blockHitResult) return super.useWithoutItem(blockState, level, blockPos, ply, blockHitResult)
} }

View File

@ -39,10 +39,9 @@ class MatterCapacitorBankBlockEntity(p_155229_: BlockPos, p_155230_: BlockState)
var summ = Decimal.ZERO var summ = Decimal.ZERO
for (stack in container) for (stack in container)
if (!stack.isEmpty) stack.getCapability(MatteryCapability.MATTER_ITEM)?.let {
stack.getCapability(MatteryCapability.MATTER_ITEM)?.let { summ += it.storedMatter
summ += it.storedMatter }
}
return summ return summ
} }
@ -50,19 +49,35 @@ class MatterCapacitorBankBlockEntity(p_155229_: BlockPos, p_155230_: BlockState)
throw UnsupportedOperationException() throw UnsupportedOperationException()
} }
override val maxStoredMatter: Decimal override val maxStoredMatter: Decimal get() {
get() {
var summ = Decimal.ZERO var summ = Decimal.ZERO
for (stack in container) for (stack in container)
if (!stack.isEmpty) stack.getCapability(MatteryCapability.MATTER_ITEM)?.let {
stack.getCapability(MatteryCapability.MATTER_ITEM)?.let { summ += it.maxStoredMatter
summ += it.maxStoredMatter }
}
return summ return summ
} }
private fun updateGaugeLevel() {
var stored = Decimal.ZERO
var maxStored = Decimal.ZERO
for (stack in container) {
val cap = stack.getCapability(MatteryCapability.MATTER_ITEM) ?: continue
stored += cap.storedMatter
maxStored += cap.maxStoredMatter
}
gaugeLevel = stored.percentage(maxStored)
}
override fun tick() {
super.tick()
updateGaugeLevel()
}
override fun receiveMatter(howMuch: Decimal, simulate: Boolean): Decimal { override fun receiveMatter(howMuch: Decimal, simulate: Boolean): Decimal {
if (!howMuch.isPositive) if (!howMuch.isPositive)
return Decimal.ZERO return Decimal.ZERO
@ -72,21 +87,18 @@ class MatterCapacitorBankBlockEntity(p_155229_: BlockPos, p_155230_: BlockState)
var summ = Decimal.ZERO var summ = Decimal.ZERO
for (stack in container) { for (stack in container) {
if (!stack.isEmpty) { val it = stack.getCapability(MatteryCapability.MATTER_ITEM) ?: continue
stack.getCapability(MatteryCapability.MATTER_ITEM)?.let { val diff = it.receiveMatterChecked(howMuch, simulate)
val diff = it.receiveMatterChecked(howMuch, simulate) summ += diff
summ += diff howMuch -= diff
howMuch -= diff
}
if (howMuch.isZero) { if (howMuch.isZero) {
break break
}
} }
} }
if (summ.isPositive && !simulate) { if (!simulate && !summ.isZero) {
gaugeLevel = storedMatter.percentage(maxStoredMatter) markDirtyFast()
} }
return summ return summ
@ -101,21 +113,18 @@ class MatterCapacitorBankBlockEntity(p_155229_: BlockPos, p_155230_: BlockState)
var summ = Decimal.ZERO var summ = Decimal.ZERO
for (stack in container) { for (stack in container) {
if (!stack.isEmpty) { val it = stack.getCapability(MatteryCapability.MATTER_ITEM) ?: continue
stack.getCapability(MatteryCapability.MATTER_ITEM)?.let { val diff = it.extractMatterChecked(howMuch, simulate)
val diff = it.extractMatterChecked(howMuch, simulate) summ += diff
summ += diff howMuch -= diff
howMuch -= diff
}
if (howMuch.isZero) { if (howMuch.isZero) {
break break
}
} }
} }
if (summ.isPositive && !simulate) { if (!simulate && !summ.isZero) {
gaugeLevel = storedMatter.percentage(maxStoredMatter) markDirtyFast()
} }
return summ return summ
@ -129,7 +138,6 @@ class MatterCapacitorBankBlockEntity(p_155229_: BlockPos, p_155230_: BlockState)
super.notifyChanged(old) super.notifyChanged(old)
capacitorStatus[slot].value = item.getCapability(MatteryCapability.MATTER_ITEM) != null capacitorStatus[slot].value = item.getCapability(MatteryCapability.MATTER_ITEM) != null
gaugeLevel = storedMatter.percentage(maxStoredMatter)
} }
override fun canAutomationPlaceItem(itemStack: ItemStack): Boolean { override fun canAutomationPlaceItem(itemStack: ItemStack): Boolean {
@ -150,7 +158,12 @@ class MatterCapacitorBankBlockEntity(p_155229_: BlockPos, p_155230_: BlockState)
get() = 1 get() = 1
} }
val container = SlottedContainer.simple(BatteryBankBlockEntity.CAPACITY, ::Slot, ::markDirtyFast).also(::addDroppableContainer) private fun containerUpdated() {
markDirtyFast()
updateGaugeLevel()
}
val container = SlottedContainer.simple(BatteryBankBlockEntity.CAPACITY, ::Slot, ::containerUpdated).also(::addDroppableContainer)
val itemConfig = ConfigurableItemHandler(inputOutput = container) val itemConfig = ConfigurableItemHandler(inputOutput = container)
val capacitorStatus = immutableList(BatteryBankBlockEntity.CAPACITY) { val capacitorStatus = immutableList(BatteryBankBlockEntity.CAPACITY) {

View File

@ -24,6 +24,7 @@ import ru.dbotthepony.mc.otm.config.MachinesConfig
import ru.dbotthepony.mc.otm.container.slotted.ContainerSlot import ru.dbotthepony.mc.otm.container.slotted.ContainerSlot
import ru.dbotthepony.mc.otm.container.slotted.SlottedContainer import ru.dbotthepony.mc.otm.container.slotted.SlottedContainer
import ru.dbotthepony.mc.otm.core.math.Decimal import ru.dbotthepony.mc.otm.core.math.Decimal
import ru.dbotthepony.mc.otm.core.nextDecimal
import ru.dbotthepony.mc.otm.core.otmRandom import ru.dbotthepony.mc.otm.core.otmRandom
import ru.dbotthepony.mc.otm.graph.matter.MatterGraph import ru.dbotthepony.mc.otm.graph.matter.MatterGraph
import ru.dbotthepony.mc.otm.item.matter.MatterDustItem import ru.dbotthepony.mc.otm.item.matter.MatterDustItem
@ -137,7 +138,7 @@ class MatterRecyclerBlockEntity(blockPos: BlockPos, blockState: BlockState) : Ma
else if (matter.receiveMatter(toReceive, true) != toReceive) else if (matter.receiveMatter(toReceive, true) != toReceive)
return status.noMatter() return status.noMatter()
matter.receiveMatter(toReceive * 0.4 + level!!.otmRandom.nextDouble() * 0.6, false) matter.receiveMatter(toReceive * level!!.otmRandom.nextDecimal(BASE_RECEIVE, Decimal.ONE), false)
job.totalMatter -= toReceive job.totalMatter -= toReceive
} }
@ -151,4 +152,8 @@ class MatterRecyclerBlockEntity(blockPos: BlockPos, blockState: BlockState) : Ma
matter.extractMatter(received, false) matter.extractMatter(received, false)
} }
} }
companion object {
private val BASE_RECEIVE = Decimal("0.4")
}
} }

View File

@ -1,5 +1,6 @@
package ru.dbotthepony.mc.otm.block.entity.tech package ru.dbotthepony.mc.otm.block.entity.tech
import it.unimi.dsi.fastutil.ints.IntArrayList
import net.minecraft.core.BlockPos import net.minecraft.core.BlockPos
import net.minecraft.world.entity.player.Inventory import net.minecraft.world.entity.player.Inventory
import net.minecraft.world.entity.player.Player import net.minecraft.world.entity.player.Player
@ -12,6 +13,7 @@ import ru.dbotthepony.kommons.util.setValue
import ru.dbotthepony.kommons.util.value import ru.dbotthepony.kommons.util.value
import ru.dbotthepony.mc.otm.block.entity.MatteryDeviceBlockEntity import ru.dbotthepony.mc.otm.block.entity.MatteryDeviceBlockEntity
import ru.dbotthepony.mc.otm.capability.FlowDirection import ru.dbotthepony.mc.otm.capability.FlowDirection
import ru.dbotthepony.mc.otm.capability.MatteryCapability
import ru.dbotthepony.mc.otm.capability.energy import ru.dbotthepony.mc.otm.capability.energy
import ru.dbotthepony.mc.otm.capability.energy.IMatteryEnergyStorage import ru.dbotthepony.mc.otm.capability.energy.IMatteryEnergyStorage
import ru.dbotthepony.mc.otm.capability.energy.ProfiledEnergyStorage import ru.dbotthepony.mc.otm.capability.energy.ProfiledEnergyStorage
@ -19,10 +21,12 @@ import ru.dbotthepony.mc.otm.capability.energyStoredMattery
import ru.dbotthepony.mc.otm.capability.matteryEnergy import ru.dbotthepony.mc.otm.capability.matteryEnergy
import ru.dbotthepony.mc.otm.capability.maxEnergyStoredMattery import ru.dbotthepony.mc.otm.capability.maxEnergyStoredMattery
import ru.dbotthepony.mc.otm.capability.transcieveEnergy import ru.dbotthepony.mc.otm.capability.transcieveEnergy
import ru.dbotthepony.mc.otm.container.slotRange
import ru.dbotthepony.mc.otm.container.slotted.ContainerSlot import ru.dbotthepony.mc.otm.container.slotted.ContainerSlot
import ru.dbotthepony.mc.otm.container.slotted.FilteredContainerSlot import ru.dbotthepony.mc.otm.container.slotted.FilteredContainerSlot
import ru.dbotthepony.mc.otm.container.slotted.SlottedContainer import ru.dbotthepony.mc.otm.container.slotted.SlottedContainer
import ru.dbotthepony.mc.otm.core.immutableList import ru.dbotthepony.mc.otm.core.immutableList
import ru.dbotthepony.mc.otm.core.isNotEmpty
import ru.dbotthepony.mc.otm.core.math.Decimal import ru.dbotthepony.mc.otm.core.math.Decimal
import ru.dbotthepony.mc.otm.core.otmRandom import ru.dbotthepony.mc.otm.core.otmRandom
import ru.dbotthepony.mc.otm.core.shuffle import ru.dbotthepony.mc.otm.core.shuffle
@ -34,6 +38,8 @@ class BatteryBankBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Matte
var gaugeLevel by syncher.float() var gaugeLevel by syncher.float()
private set private set
private var containerSlotIndices = IntArray(0)
private inner class Slot(container: SlottedContainer, slot: Int) : FilteredContainerSlot(container, slot) { private inner class Slot(container: SlottedContainer, slot: Int) : FilteredContainerSlot(container, slot) {
override fun canAutomationPlaceItem(itemStack: ItemStack): Boolean { override fun canAutomationPlaceItem(itemStack: ItemStack): Boolean {
return super.canAutomationPlaceItem(itemStack) && itemStack.getCapability(Capabilities.EnergyStorage.ITEM)?.let { it.canExtract() && it.extractEnergy(Int.MAX_VALUE, true) > 0 } == true return super.canAutomationPlaceItem(itemStack) && itemStack.getCapability(Capabilities.EnergyStorage.ITEM)?.let { it.canExtract() && it.extractEnergy(Int.MAX_VALUE, true) > 0 } == true
@ -47,15 +53,30 @@ class BatteryBankBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Matte
super.notifyChanged(old) super.notifyChanged(old)
batteryStatus[slot].value = item.getCapability(Capabilities.EnergyStorage.ITEM) != null batteryStatus[slot].value = item.getCapability(Capabilities.EnergyStorage.ITEM) != null
gaugeLevel = batteryLevel.percentage(maxBatteryLevel) updateGaugeLevel()
} }
override val maxStackSize: Int override val maxStackSize: Int
get() = 1 get() = 1
} }
private fun containerUpdated() {
markDirtyFast()
val newSlots = IntArrayList()
for (i in 0 until container.containerSize) {
val stack = container[i]
if (stack.isNotEmpty && stack.energy != null)
newSlots.add(i)
}
containerSlotIndices = newSlots.toIntArray()
}
// 6 на 2 // 6 на 2
val container = SlottedContainer.simple(CAPACITY, ::Slot, ::markDirtyFast).also(::addDroppableContainer) val container = SlottedContainer.simple(CAPACITY, ::Slot, ::containerUpdated).also(::addDroppableContainer)
val batteryStatus = immutableList(CAPACITY) { syncher.boolean(false) } val batteryStatus = immutableList(CAPACITY) { syncher.boolean(false) }
val itemConfig = ConfigurableItemHandler(inputOutput = container) val itemConfig = ConfigurableItemHandler(inputOutput = container)
@ -64,10 +85,26 @@ class BatteryBankBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Matte
savetables.stateful(::container, INVENTORY_KEY) savetables.stateful(::container, INVENTORY_KEY)
} }
private val containerSlotIndices = IntArray(CAPACITY) { it } private fun updateGaugeLevel() {
var stored = Decimal.ZERO
var maxStored = Decimal.ZERO
for (stack in container) {
val cap = stack.energy ?: continue
stored += cap.energyStoredMattery
maxStored += cap.maxEnergyStoredMattery
}
gaugeLevel = stored.percentage(maxStored)
}
override fun tick() {
super.tick()
updateGaugeLevel()
}
private fun distributeEnergy(isReceiving: Boolean, howMuch: Decimal, simulate: Boolean): Decimal { private fun distributeEnergy(isReceiving: Boolean, howMuch: Decimal, simulate: Boolean): Decimal {
if (!howMuch.isPositive) if (!howMuch.isPositive || containerSlotIndices.isEmpty())
return Decimal.ZERO return Decimal.ZERO
containerSlotIndices.shuffle(level!!.otmRandom) containerSlotIndices.shuffle(level!!.otmRandom)
@ -94,7 +131,6 @@ class BatteryBankBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Matte
if (!simulate && !summ.isZero) { if (!simulate && !summ.isZero) {
markDirtyFast() markDirtyFast()
gaugeLevel = batteryLevel.percentage(maxBatteryLevel)
} }
return summ return summ
@ -118,13 +154,9 @@ class BatteryBankBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Matte
get() { get() {
var result = Decimal.ZERO var result = Decimal.ZERO
for (i in 0 until container.containerSize) { for (stack in container) {
val stack = container.getItem(i) stack.energy?.let {
result += it.energyStoredMattery
if (!stack.isEmpty) {
stack.energy?.let {
result += it.energyStoredMattery
}
} }
} }
@ -138,13 +170,9 @@ class BatteryBankBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Matte
get() { get() {
var result = Decimal.ZERO var result = Decimal.ZERO
for (i in 0 until container.containerSize) { for (stack in container) {
val stack = container.getItem(i) stack.energy?.let {
result += it.maxEnergyStoredMattery
if (!stack.isEmpty) {
stack.energy?.let {
result += it.maxEnergyStoredMattery
}
} }
} }

View File

@ -22,7 +22,7 @@ import ru.dbotthepony.mc.otm.core.chart.DecimalHistoryChart
import ru.dbotthepony.mc.otm.core.math.BlockRotation import ru.dbotthepony.mc.otm.core.math.BlockRotation
import ru.dbotthepony.mc.otm.core.math.Decimal import ru.dbotthepony.mc.otm.core.math.Decimal
import ru.dbotthepony.mc.otm.core.math.RelativeSide import ru.dbotthepony.mc.otm.core.math.RelativeSide
import ru.dbotthepony.mc.otm.core.math.getDecimal import ru.dbotthepony.mc.otm.core.nbt.getDecimal
import ru.dbotthepony.mc.otm.core.nbt.mapPresent import ru.dbotthepony.mc.otm.core.nbt.mapPresent
import ru.dbotthepony.mc.otm.core.nbt.set import ru.dbotthepony.mc.otm.core.nbt.set
import ru.dbotthepony.mc.otm.core.util.countingLazy import ru.dbotthepony.mc.otm.core.util.countingLazy
@ -31,6 +31,7 @@ import ru.dbotthepony.mc.otm.registry.game.MBlockEntities
class EnergyCounterBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : MatteryDeviceBlockEntity(MBlockEntities.ENERGY_COUNTER, p_155229_, p_155230_) { class EnergyCounterBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : MatteryDeviceBlockEntity(MBlockEntities.ENERGY_COUNTER, p_155229_, p_155230_) {
var passed by syncher.decimal() var passed by syncher.decimal()
var pullEnergyFromInput by syncher.boolean()
override val blockRotation: BlockRotation by countingLazy(blockStateChangesCounter) { override val blockRotation: BlockRotation by countingLazy(blockStateChangesCounter) {
BlockRotation.of(blockState[EnergyCounterBlock.INPUT_DIRECTION]) BlockRotation.of(blockState[EnergyCounterBlock.INPUT_DIRECTION])
@ -86,10 +87,8 @@ class EnergyCounterBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Mat
savetables.stateful(::history1h) savetables.stateful(::history1h)
savetables.stateful(::history6h) savetables.stateful(::history6h)
savetables.stateful(::history24h) savetables.stateful(::history24h)
}
override fun saveLevel(nbt: CompoundTag, registry: HolderLookup.Provider) { savetablesConfig.bool(::pullEnergyFromInput)
super.saveLevel(nbt, registry)
} }
override fun loadAdditional(nbt: CompoundTag, registry: HolderLookup.Provider) { override fun loadAdditional(nbt: CompoundTag, registry: HolderLookup.Provider) {
@ -267,6 +266,14 @@ class EnergyCounterBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Mat
override fun tick() { override fun tick() {
super.tick() super.tick()
if (pullEnergyFromInput) {
val input = inputCapability
val output = outputCapability
if (input != null && output != null)
thisTick += moveEnergy(source = input, destination = output, simulate = false)
}
lastTick = thisTick lastTick = thisTick
charts.forEach { it.add(thisTick) } charts.forEach { it.add(thisTick) }
thisTick = Decimal.ZERO thisTick = Decimal.ZERO

View File

@ -15,7 +15,7 @@ import ru.dbotthepony.mc.otm.capability.FlowDirection
import ru.dbotthepony.mc.otm.capability.extractEnergy import ru.dbotthepony.mc.otm.capability.extractEnergy
import ru.dbotthepony.mc.otm.capability.receiveEnergy import ru.dbotthepony.mc.otm.capability.receiveEnergy
import ru.dbotthepony.mc.otm.core.math.Decimal import ru.dbotthepony.mc.otm.core.math.Decimal
import ru.dbotthepony.mc.otm.core.math.getDecimal import ru.dbotthepony.mc.otm.core.nbt.getDecimal
import ru.dbotthepony.mc.otm.core.nbt.set import ru.dbotthepony.mc.otm.core.nbt.set
import ru.dbotthepony.mc.otm.registry.StatNames import ru.dbotthepony.mc.otm.registry.StatNames
import ru.dbotthepony.mc.otm.triggers.AndroidBatteryTrigger import ru.dbotthepony.mc.otm.triggers.AndroidBatteryTrigger

View File

@ -111,7 +111,19 @@ class EnergyCounterScreen(menu: EnergyCounterMenu, inventory: Inventory, title:
} }
} }
makeDeviceControls(this, frame, redstoneConfig = menu.redstone) val controls = makeDeviceControls(this, frame, redstoneConfig = menu.redstone)
controls.addButton(
BooleanButtonPanel.square18(
this,
controls,
menu.pullEnergyFromInput,
iconActive = Widgets18.LEFT_CONTROLS.push,
iconInactive = Widgets18.LEFT_CONTROLS.output,
tooltipActive = TranslatableComponent("block.overdrive_that_matters.energy_counter.do_pull"),
tooltipInactive = TranslatableComponent("block.overdrive_that_matters.energy_counter.dont_pull")
)
)
return frame return frame
} }

View File

@ -13,8 +13,8 @@ import ru.dbotthepony.mc.otm.compat.jade.JadeUids
import ru.dbotthepony.mc.otm.core.TranslatableComponent import ru.dbotthepony.mc.otm.core.TranslatableComponent
import ru.dbotthepony.mc.otm.core.getCapability import ru.dbotthepony.mc.otm.core.getCapability
import ru.dbotthepony.mc.otm.core.math.Decimal import ru.dbotthepony.mc.otm.core.math.Decimal
import ru.dbotthepony.mc.otm.core.math.getDecimal import ru.dbotthepony.mc.otm.core.nbt.getDecimal
import ru.dbotthepony.mc.otm.core.math.putDecimal import ru.dbotthepony.mc.otm.core.nbt.putDecimal
import ru.dbotthepony.mc.otm.core.util.formatMatter import ru.dbotthepony.mc.otm.core.util.formatMatter
import snownee.jade.api.BlockAccessor import snownee.jade.api.BlockAccessor
import snownee.jade.api.IBlockComponentProvider import snownee.jade.api.IBlockComponentProvider

View File

@ -13,8 +13,8 @@ import ru.dbotthepony.mc.otm.core.math.Decimal
import ru.dbotthepony.kommons.math.RGBAColor import ru.dbotthepony.kommons.math.RGBAColor
import ru.dbotthepony.mc.otm.capability.IProfiledStorage import ru.dbotthepony.mc.otm.capability.IProfiledStorage
import ru.dbotthepony.mc.otm.core.getCapability import ru.dbotthepony.mc.otm.core.getCapability
import ru.dbotthepony.mc.otm.core.math.getDecimal import ru.dbotthepony.mc.otm.core.nbt.getDecimal
import ru.dbotthepony.mc.otm.core.math.putDecimal import ru.dbotthepony.mc.otm.core.nbt.putDecimal
import ru.dbotthepony.mc.otm.core.util.formatPower import ru.dbotthepony.mc.otm.core.util.formatPower
import snownee.jade.api.* import snownee.jade.api.*
import snownee.jade.api.config.IPluginConfig import snownee.jade.api.config.IPluginConfig

View File

@ -7,7 +7,6 @@ import ru.dbotthepony.kommons.util.Delegate
import ru.dbotthepony.kommons.util.getValue import ru.dbotthepony.kommons.util.getValue
import ru.dbotthepony.mc.otm.OverdriveThatMatters import ru.dbotthepony.mc.otm.OverdriveThatMatters
import ru.dbotthepony.mc.otm.core.math.Decimal import ru.dbotthepony.mc.otm.core.math.Decimal
import ru.dbotthepony.mc.otm.core.math.defineDecimal
import ru.dbotthepony.mc.otm.core.util.WriteOnce import ru.dbotthepony.mc.otm.core.util.WriteOnce
abstract class AbstractConfig(private val configName: String, private val type: ModConfig.Type = ModConfig.Type.SERVER) { abstract class AbstractConfig(private val configName: String, private val type: ModConfig.Type = ModConfig.Type.SERVER) {

View File

@ -3,7 +3,6 @@ package ru.dbotthepony.mc.otm.config
import ru.dbotthepony.kommons.util.getValue import ru.dbotthepony.kommons.util.getValue
import ru.dbotthepony.kommons.util.setValue import ru.dbotthepony.kommons.util.setValue
import ru.dbotthepony.mc.otm.core.math.Decimal import ru.dbotthepony.mc.otm.core.math.Decimal
import ru.dbotthepony.mc.otm.core.math.defineDecimal
object CablesConfig : AbstractConfig("cables") { object CablesConfig : AbstractConfig("cables") {
enum class E(throughput: Decimal) { enum class E(throughput: Decimal) {

View File

@ -0,0 +1,58 @@
package ru.dbotthepony.mc.otm.config
import net.neoforged.neoforge.common.ModConfigSpec
import ru.dbotthepony.mc.otm.core.math.Decimal
class DecimalConfigValue(
parent: ModConfigSpec.ConfigValue<String>,
val minimum: Decimal? = null,
val maximum: Decimal? = null,
) : ObservedConfigValue<Decimal>(parent) {
override fun fromString(value: String): Decimal? {
try {
val parsed = Decimal(value)
if (minimum != null && minimum > parsed) {
return minimum
} else if (maximum != null && maximum < parsed) {
return maximum
}
return parsed
} catch (err: java.lang.NumberFormatException) {
return null
}
}
override fun toString(value: Decimal): Pair<String, Decimal> {
if (minimum != null && minimum > value) {
return minimum.toString() to minimum
} else if (maximum != null && maximum < value) {
return maximum.toString() to maximum
}
return value.toString() to value
}
}
private fun ModConfigSpec.Builder.commentRange(minimum: Decimal?, maximum: Decimal?) {
if (minimum != null && maximum != null) {
comment("Range: $minimum ~ $maximum")
} else if (minimum != null) {
comment("Range: >= $minimum")
} else if (maximum != null) {
comment("Range: <= $maximum")
}
}
fun ModConfigSpec.Builder.defineDecimal(path: String, defaultValue: Decimal, minimum: Decimal? = null, maximum: Decimal? = null): DecimalConfigValue {
commentRange(minimum, maximum)
comment("Default: $defaultValue")
return DecimalConfigValue(define(path, defaultValue.toString()), minimum, maximum)
}
fun ModConfigSpec.Builder.defineDecimal(path: List<String>, defaultValue: Decimal, minimum: Decimal? = null, maximum: Decimal? = null): DecimalConfigValue {
commentRange(minimum, maximum)
comment("Default: $defaultValue")
return DecimalConfigValue(define(path, defaultValue.toString()), minimum, maximum)
}

View File

@ -2,7 +2,6 @@ package ru.dbotthepony.mc.otm.config
import ru.dbotthepony.kommons.util.getValue import ru.dbotthepony.kommons.util.getValue
import ru.dbotthepony.mc.otm.core.math.Decimal import ru.dbotthepony.mc.otm.core.math.Decimal
import ru.dbotthepony.mc.otm.core.math.defineDecimal
object ExopackConfig : AbstractConfig("exopack") { object ExopackConfig : AbstractConfig("exopack") {
val ENERGY_CAPACITY by builder val ENERGY_CAPACITY by builder

View File

@ -2,7 +2,6 @@ package ru.dbotthepony.mc.otm.config
import ru.dbotthepony.kommons.util.getValue import ru.dbotthepony.kommons.util.getValue
import ru.dbotthepony.mc.otm.core.math.Decimal import ru.dbotthepony.mc.otm.core.math.Decimal
import ru.dbotthepony.mc.otm.core.math.defineDecimal
import ru.dbotthepony.mc.otm.registry.MNames import ru.dbotthepony.mc.otm.registry.MNames
object ItemsConfig : AbstractConfig("items") { object ItemsConfig : AbstractConfig("items") {

View File

@ -2,7 +2,6 @@ package ru.dbotthepony.mc.otm.config
import ru.dbotthepony.kommons.util.getValue import ru.dbotthepony.kommons.util.getValue
import ru.dbotthepony.mc.otm.core.math.Decimal import ru.dbotthepony.mc.otm.core.math.Decimal
import ru.dbotthepony.mc.otm.core.math.defineDecimal
import ru.dbotthepony.mc.otm.registry.MNames import ru.dbotthepony.mc.otm.registry.MNames
object MachinesConfig : AbstractConfig("machines") { object MachinesConfig : AbstractConfig("machines") {

View File

@ -2,7 +2,6 @@ package ru.dbotthepony.mc.otm.config
import ru.dbotthepony.kommons.util.getValue import ru.dbotthepony.kommons.util.getValue
import ru.dbotthepony.mc.otm.core.math.Decimal import ru.dbotthepony.mc.otm.core.math.Decimal
import ru.dbotthepony.mc.otm.core.math.defineDecimal
object PlayerConfig : AbstractConfig("player") { object PlayerConfig : AbstractConfig("player") {
init { init {

View File

@ -2,7 +2,6 @@ package ru.dbotthepony.mc.otm.config
import ru.dbotthepony.kommons.util.getValue import ru.dbotthepony.kommons.util.getValue
import ru.dbotthepony.mc.otm.core.math.Decimal import ru.dbotthepony.mc.otm.core.math.Decimal
import ru.dbotthepony.mc.otm.core.math.defineDecimal
object ServerConfig : AbstractConfig("misc") { object ServerConfig : AbstractConfig("misc") {
val LABORATORY_LAMP_LIGHT_LENGTH: Int by builder.comment("In blocks").defineInRange("LABORATORY_LAMP_LIGHT_LENGTH", 6, 1, 128) val LABORATORY_LAMP_LIGHT_LENGTH: Int by builder.comment("In blocks").defineInRange("LABORATORY_LAMP_LIGHT_LENGTH", 6, 1, 128)

View File

@ -13,7 +13,6 @@ import com.google.common.collect.ImmutableSet
import com.google.gson.JsonElement import com.google.gson.JsonElement
import com.google.gson.JsonObject import com.google.gson.JsonObject
import com.google.gson.JsonPrimitive import com.google.gson.JsonPrimitive
import it.unimi.dsi.fastutil.ints.IntList
import it.unimi.dsi.fastutil.objects.ObjectComparators import it.unimi.dsi.fastutil.objects.ObjectComparators
import net.minecraft.Util import net.minecraft.Util
import net.minecraft.core.BlockPos import net.minecraft.core.BlockPos
@ -32,7 +31,6 @@ import net.minecraft.network.chat.contents.TranslatableContents
import net.minecraft.resources.ResourceKey import net.minecraft.resources.ResourceKey
import net.minecraft.resources.ResourceLocation import net.minecraft.resources.ResourceLocation
import net.minecraft.tags.TagKey import net.minecraft.tags.TagKey
import net.minecraft.util.RandomSource
import net.minecraft.world.entity.Entity import net.minecraft.world.entity.Entity
import net.minecraft.world.item.Item import net.minecraft.world.item.Item
import net.minecraft.world.item.ItemStack import net.minecraft.world.item.ItemStack
@ -69,14 +67,11 @@ import java.util.concurrent.Callable
import java.util.concurrent.Future import java.util.concurrent.Future
import java.util.function.Consumer import java.util.function.Consumer
import java.util.function.Supplier import java.util.function.Supplier
import java.util.random.RandomGenerator
import java.util.stream.Stream import java.util.stream.Stream
import java.util.stream.StreamSupport import java.util.stream.StreamSupport
import kotlin.NoSuchElementException import kotlin.NoSuchElementException
import kotlin.enums.EnumEntries import kotlin.enums.EnumEntries
import kotlin.jvm.optionals.getOrNull import kotlin.jvm.optionals.getOrNull
import kotlin.math.ln
import kotlin.math.sqrt
import kotlin.reflect.KProperty import kotlin.reflect.KProperty
operator fun RecipeInput.get(index: Int): ItemStack = getItem(index) operator fun RecipeInput.get(index: Int): ItemStack = getItem(index)
@ -194,43 +189,6 @@ fun <T : Enum<T>> T.prev(values: Array<out T>): T {
return values[next] return values[next]
} }
fun IntArray.shuffle(random: RandomSource): IntArray {
for (i in lastIndex downTo 1) {
val j = random.nextInt(i + 1)
val copy = this[i]
this[i] = this[j]
this[j] = copy
}
return this
}
fun <L : IntList> L.shuffle(random: RandomSource): L {
for (i in lastIndex downTo 1) {
val j = random.nextInt(i + 1)
set(j, set(i, getInt(j)))
}
return this
}
fun <T, L : MutableList<T>> L.shuffle(random: RandomSource): L {
Util.shuffle(this, random)
return this
}
fun <T> List<T>.random(random: RandomGenerator): T {
if (isEmpty())
throw NoSuchElementException("This list is empty")
return get(random.nextInt(size))
}
fun <T> List<T>.random(random: RandomSource): T {
if (isEmpty())
throw NoSuchElementException("This list is empty")
return get(random.nextInt(size))
}
inline fun <T : Any> immutableList(size: Int, initializer: (index: Int) -> T): ImmutableList<T> { inline fun <T : Any> immutableList(size: Int, initializer: (index: Int) -> T): ImmutableList<T> {
require(size >= 0) { "Invalid list size $size" } require(size >= 0) { "Invalid list size $size" }
@ -644,44 +602,6 @@ infix fun FluidStack.isNotSameAs(other: FluidStack): Boolean {
return !FluidStack.isSameFluidSameComponents(this, other) && amount == other.amount return !FluidStack.isSameFluidSameComponents(this, other) && amount == other.amount
} }
data class DoublePair(val first: Double, val second: Double)
fun RandomSource.nextUUID(): UUID {
return UUID(nextLong(), nextLong())
}
// normal distribution via Marsaglia polar method
fun RandomGenerator.nextNormalDoubles(stddev: Double, mean: Double): DoublePair {
var rand1: Double
var rand2: Double
var distSqr: Double
do {
rand1 = 2.0 * nextDouble() - 1.0
rand2 = 2.0 * nextDouble() - 1.0
distSqr = rand1 * rand1 + rand2 * rand2
} while (distSqr >= 1.0 || distSqr == 0.0)
val mapping = sqrt(-2.0 * ln(distSqr) / distSqr)
return DoublePair(
rand1 * mapping * stddev + mean,
rand2 * mapping * stddev + mean
)
}
// All Mojang's random sources use MarsagliaPolarGaussian for generating normal distributed doubles
fun RandomSource.nextNormalDoubles(stddev: Double, mean: Double): DoublePair {
return DoublePair(
nextGaussian() * stddev + mean,
nextGaussian() * stddev + mean
)
}
fun RandomSource.nextNormalDouble(stddev: Double, mean: Double): Double {
return nextGaussian() * stddev + mean
}
fun <K : Any, V> SimpleCache(size: Long, freshness: Duration): Cache<K, V> { fun <K : Any, V> SimpleCache(size: Long, freshness: Duration): Cache<K, V> {
return Caffeine.newBuilder() return Caffeine.newBuilder()
.maximumSize(size) .maximumSize(size)
@ -690,21 +610,3 @@ fun <K : Any, V> SimpleCache(size: Long, freshness: Duration): Cache<K, V> {
.expireAfterWrite(freshness) .expireAfterWrite(freshness)
.build() .build()
} }
fun RandomSource.nextFloat(min: Float, max: Float): Float {
if (this is RandomGenerator)
return nextFloat(min, max)
require(max >= min) { "Min is bigger than max: $min vs $max" }
if (min == max) return min
return min + nextFloat() * (max - min)
}
fun RandomSource.nextDouble(min: Double, max: Double): Double {
if (this is RandomGenerator)
return nextDouble(min, max)
require(max >= min) { "Min is bigger than max: $min vs $max" }
if (min == max) return min
return min + nextDouble() * (max - min)
}

View File

@ -0,0 +1,221 @@
package ru.dbotthepony.mc.otm.core
import it.unimi.dsi.fastutil.ints.IntList
import net.minecraft.Util
import net.minecraft.util.RandomSource
import ru.dbotthepony.mc.otm.core.math.Decimal
import java.math.BigInteger
import java.util.*
import java.util.random.RandomGenerator
import kotlin.experimental.and
import kotlin.math.ln
import kotlin.math.sqrt
data class DoublePair(val first: Double, val second: Double)
fun RandomSource.nextUUID(): UUID {
return UUID(nextLong(), nextLong())
}
// normal distribution via Marsaglia polar method
fun RandomGenerator.nextNormalDoubles(stddev: Double, mean: Double): DoublePair {
var rand1: Double
var rand2: Double
var distSqr: Double
do {
rand1 = 2.0 * nextDouble() - 1.0
rand2 = 2.0 * nextDouble() - 1.0
distSqr = rand1 * rand1 + rand2 * rand2
} while (distSqr >= 1.0 || distSqr == 0.0)
val mapping = sqrt(-2.0 * ln(distSqr) / distSqr)
return DoublePair(
rand1 * mapping * stddev + mean,
rand2 * mapping * stddev + mean
)
}
// All Mojang's random sources use MarsagliaPolarGaussian for generating normal distributed doubles
fun RandomSource.nextNormalDoubles(stddev: Double, mean: Double): DoublePair {
return DoublePair(
nextGaussian() * stddev + mean,
nextGaussian() * stddev + mean
)
}
fun RandomSource.nextNormalDouble(stddev: Double, mean: Double): Double {
return nextGaussian() * stddev + mean
}
fun RandomSource.nextFloat(min: Float, max: Float): Float {
if (this is RandomGenerator)
return nextFloat(min, max)
require(max >= min) { "Min is bigger than max: $min vs $max" }
if (min == max) return min
return min + nextFloat() * (max - min)
}
fun RandomSource.nextDouble(min: Double, max: Double): Double {
if (this is RandomGenerator)
return nextDouble(min, max)
require(max >= min) { "Min is bigger than max: $min vs $max" }
if (min == max) return min
return min + nextDouble() * (max - min)
}
fun IntArray.shuffle(random: RandomSource): IntArray {
for (i in lastIndex downTo 1) {
val j = random.nextInt(i + 1)
val copy = this[i]
this[i] = this[j]
this[j] = copy
}
return this
}
fun <L : IntList> L.shuffle(random: RandomSource): L {
for (i in lastIndex downTo 1) {
val j = random.nextInt(i + 1)
set(j, set(i, getInt(j)))
}
return this
}
fun <T, L : MutableList<T>> L.shuffle(random: RandomSource): L {
Util.shuffle(this, random)
return this
}
fun <T> List<T>.random(random: RandomGenerator): T {
if (isEmpty())
throw NoSuchElementException("This list is empty")
return get(random.nextInt(size))
}
fun <T> List<T>.random(random: RandomSource): T {
if (isEmpty())
throw NoSuchElementException("This list is empty")
return get(random.nextInt(size))
}
class RandomByteSource(private val source: RandomSource) {
private val bytes = ByteArray(8)
private var i = 7
fun next(): Byte {
if (++i == 8) {
i = 0
var generate = source.nextLong()
for (i in 0 .. 7) {
bytes[i] = generate.toByte()
generate = generate ushr 8
}
}
return bytes[i]
}
fun next(bound: Int): Byte {
require(bound > 0) { "Bound must be positive" }
val m = bound - 1
var r = next().toInt().and(0xFF)
if (bound and m == 0) {
r = r and m
} else {
var u = r ushr 1
while (true) {
r = u % bound
if (u + m - r < 0) {
u = next().toInt().and(0xFF).ushr(1)
} else {
break
}
}
}
return r.toByte()
}
fun next(bytes: ByteArray) {
for (i in bytes.indices) {
bytes[i] = next()
}
}
}
/**
* Uniformely distributed [Decimal] value on [0,[bound]) range
*
* If [round] is `true`, will only return integers
*/
fun RandomSource.nextDecimal(bound: Decimal, round: Boolean = false): Decimal {
if (round)
require(bound >= Decimal.ONE) { "Bound must be 1 or bigger, $bound given" }
else
require(bound > Decimal.ZERO) { "Bound must be positive, $bound given" }
require(bound.isFinite) { "Bound must be finite" }
val bytes = RandomByteSource(this)
if (round) {
val thisBytes = bound.whole.toByteArray()
val generateBytes = ByteArray(thisBytes.size)
bytes.next(generateBytes)
generateBytes[0] = generateBytes[0].and(127)
if (generateBytes[0] >= thisBytes[0]) {
generateBytes[0] = bytes.next(thisBytes[0].toInt().and(127))
}
return Decimal(BigInteger(generateBytes))
} else {
val thisBytes = bound.mag.toByteArray()
val generateBytes = ByteArray(thisBytes.size)
bytes.next(generateBytes)
generateBytes[0] = generateBytes[0].and(127)
if (generateBytes[0] >= thisBytes[0]) {
generateBytes[0] = bytes.next(thisBytes[0].toInt().and(127))
}
return Decimal.raw(BigInteger(generateBytes))
}
}
/**
* Uniformely distributed [Decimal] value on [[origin],[bound]) range
*
* If [round] is `true`, will only return integers
*/
fun RandomSource.nextDecimal(origin: Decimal, bound: Decimal, round: Boolean = false): Decimal {
require(origin < bound) { "Origin must be less than bound: $origin < $bound" }
require(origin.isFinite) { "Origin must be finite" }
require(bound.isFinite) { "Bound must be finite" }
return origin + nextDecimal(bound - origin, round)
}
/**
* Uniformely distributed [Decimal] value on [0,1) range
*/
fun RandomSource.nextDecimal(): Decimal {
return nextDecimal(Decimal.ZERO, Decimal.ONE)
}
fun RandomSource.nextVariance(value: Decimal, round: Boolean = false): Decimal {
return nextDecimal(-value / 2, value / 2, round)
}

View File

@ -4,6 +4,7 @@ import it.unimi.dsi.fastutil.ints.IntCollection
import it.unimi.dsi.fastutil.ints.IntIterable import it.unimi.dsi.fastutil.ints.IntIterable
import it.unimi.dsi.fastutil.ints.IntIterator import it.unimi.dsi.fastutil.ints.IntIterator
import it.unimi.dsi.fastutil.ints.IntSortedSet import it.unimi.dsi.fastutil.ints.IntSortedSet
import ru.dbotthepony.mc.otm.core.math.Decimal
fun IntRange.asIterable(): IntIterable { fun IntRange.asIterable(): IntIterable {
return IntIterable { return IntIterable {
@ -52,3 +53,15 @@ fun IntSortedSet.ktIterator(fromElement: Int): kotlin.collections.IntIterator {
} }
} }
} }
inline fun <T> Iterable<T>.sumOfDecimal(selector: (T) -> Decimal): Decimal {
var result = Decimal.ZERO
forEach { result += selector(it) }
return result
}
inline fun <T> Iterator<T>.sumOfDecimal(selector: (T) -> Decimal): Decimal {
var result = Decimal.ZERO
forEach { result += selector(it) }
return result
}

View File

@ -1,17 +1,9 @@
package ru.dbotthepony.mc.otm.core.math package ru.dbotthepony.mc.otm.core.math
import net.minecraft.nbt.ByteArrayTag import net.minecraft.nbt.ByteArrayTag
import net.minecraft.nbt.CompoundTag
import net.minecraft.nbt.StringTag import net.minecraft.nbt.StringTag
import net.minecraft.nbt.Tag import net.minecraft.nbt.Tag
import net.minecraft.network.FriendlyByteBuf import net.minecraft.network.FriendlyByteBuf
import net.minecraft.util.RandomSource
import net.neoforged.neoforge.common.ModConfigSpec
import ru.dbotthepony.mc.otm.config.ObservedConfigValue
import ru.dbotthepony.mc.otm.core.util.readVarIntLE
import ru.dbotthepony.mc.otm.core.util.writeVarIntLE
import java.io.InputStream
import java.io.OutputStream
import java.math.BigDecimal import java.math.BigDecimal
import java.math.BigInteger import java.math.BigInteger
import java.math.MathContext import java.math.MathContext
@ -47,6 +39,8 @@ sealed class Decimal : Number(), Comparable<Decimal> {
*/ */
abstract val fractional: BigInteger abstract val fractional: BigInteger
abstract internal val mag: BigInteger
/** /**
* *Signed* normalized (-1,1) fractional part of this Decimal, as [Float] * *Signed* normalized (-1,1) fractional part of this Decimal, as [Float]
*/ */
@ -189,7 +183,7 @@ sealed class Decimal : Number(), Comparable<Decimal> {
return toBigDecmial().divide(divisor.toBigDecmial(), PERCENTAGE_CONTEXT).toFloat() return toBigDecmial().divide(divisor.toBigDecmial(), PERCENTAGE_CONTEXT).toFloat()
} }
private class Regular(val mag: BigInteger, marker: Nothing?) : Decimal() { private class Regular(override val mag: BigInteger, marker: Nothing?) : Decimal() {
constructor(value: BigInteger) : this(value * PRECISION_POW_BI, null) constructor(value: BigInteger) : this(value * PRECISION_POW_BI, null)
constructor(value: BigDecimal) : this(value.setScale(PRECISION, RoundingMode.HALF_UP).unscaledValue(), null) constructor(value: BigDecimal) : this(value.setScale(PRECISION, RoundingMode.HALF_UP).unscaledValue(), null)
constructor(value: Float) : this(BigDecimal.valueOf(value.toDouble())) constructor(value: Float) : this(BigDecimal.valueOf(value.toDouble()))
@ -711,6 +705,9 @@ sealed class Decimal : Number(), Comparable<Decimal> {
} }
private object PositiveInfinity : Decimal() { private object PositiveInfinity : Decimal() {
override val mag: BigInteger
get() = throw UnsupportedOperationException()
private fun readResolve(): Any = PositiveInfinity private fun readResolve(): Any = PositiveInfinity
override val isInfinite: Boolean override val isInfinite: Boolean
@ -960,6 +957,9 @@ sealed class Decimal : Number(), Comparable<Decimal> {
} }
private object NegativeInfinity : Decimal() { private object NegativeInfinity : Decimal() {
override val mag: BigInteger
get() = throw UnsupportedOperationException()
private fun readResolve(): Any = NegativeInfinity private fun readResolve(): Any = NegativeInfinity
override val isInfinite: Boolean override val isInfinite: Boolean
@ -1203,6 +1203,9 @@ sealed class Decimal : Number(), Comparable<Decimal> {
} }
private object Zero : Decimal() { private object Zero : Decimal() {
override val mag: BigInteger
get() = BigInteger.ZERO
private fun readResolve(): Any = Zero private fun readResolve(): Any = Zero
override val isInfinite: Boolean override val isInfinite: Boolean
@ -1603,28 +1606,6 @@ sealed class Decimal : Number(), Comparable<Decimal> {
} }
} }
fun FriendlyByteBuf.readDecimal() = Decimal.read(this)
fun FriendlyByteBuf.writeDecimal(value: Decimal) = value.write(this)
fun InputStream.readDecimal(): Decimal {
val size = readVarIntLE()
require(size >= 0) { "Negative payload size: $size" }
val bytes = ByteArray(size)
read(bytes)
return Decimal.fromByteArray(bytes)
}
fun OutputStream.writeDecimal(value: Decimal) {
val bytes = value.toByteArray()
writeVarIntLE(bytes.size)
write(bytes)
}
fun CompoundTag.getDecimal(key: String) = Decimal.deserializeNBT(this[key])
fun CompoundTag.putDecimal(key: String, value: Decimal) = put(key, value.serializeNBT())
operator fun CompoundTag.set(key: String, value: Decimal) = putDecimal(key, value)
fun Float.toDecimal() = Decimal(this) fun Float.toDecimal() = Decimal(this)
fun Double.toDecimal() = Decimal(this) fun Double.toDecimal() = Decimal(this)
fun Int.toDecimal() = Decimal(this) fun Int.toDecimal() = Decimal(this)
@ -1633,70 +1614,3 @@ fun Short.toDecimal() = Decimal(this)
fun Long.toDecimal() = Decimal(this) fun Long.toDecimal() = Decimal(this)
fun Decimal.toDecimal() = this fun Decimal.toDecimal() = this
class DecimalConfigValue(
parent: ModConfigSpec.ConfigValue<String>,
val minimum: Decimal? = null,
val maximum: Decimal? = null,
) : ObservedConfigValue<Decimal>(parent) {
override fun fromString(value: String): Decimal? {
try {
val parsed = Decimal(value)
if (minimum != null && minimum > parsed) {
return minimum
} else if (maximum != null && maximum < parsed) {
return maximum
}
return parsed
} catch (err: java.lang.NumberFormatException) {
return null
}
}
override fun toString(value: Decimal): Pair<String, Decimal> {
if (minimum != null && minimum > value) {
return minimum.toString() to minimum
} else if (maximum != null && maximum < value) {
return maximum.toString() to maximum
}
return value.toString() to value
}
}
private fun ModConfigSpec.Builder.commentRange(minimum: Decimal?, maximum: Decimal?) {
if (minimum != null && maximum != null) {
comment("Range: $minimum ~ $maximum")
} else if (minimum != null) {
comment("Range: >= $minimum")
} else if (maximum != null) {
comment("Range: <= $maximum")
}
}
fun ModConfigSpec.Builder.defineDecimal(path: String, defaultValue: Decimal, minimum: Decimal? = null, maximum: Decimal? = null): DecimalConfigValue {
commentRange(minimum, maximum)
comment("Default: $defaultValue")
return DecimalConfigValue(define(path, defaultValue.toString()), minimum, maximum)
}
fun ModConfigSpec.Builder.defineDecimal(path: List<String>, defaultValue: Decimal, minimum: Decimal? = null, maximum: Decimal? = null): DecimalConfigValue {
commentRange(minimum, maximum)
comment("Default: $defaultValue")
return DecimalConfigValue(define(path, defaultValue.toString()), minimum, maximum)
}
fun RandomSource.nextDecimal(min: Decimal, max: Decimal, round: Boolean = false): Decimal {
val value = nextDouble()
return if (round) {
Decimal((min + (max - min) * value).whole)
} else {
min + (max - min) * value
}
}
fun RandomSource.nextVariance(value: Decimal, round: Boolean = false): Decimal {
return nextDecimal(-value / 2, value / 2, round)
}

View File

@ -20,6 +20,7 @@ import net.minecraft.nbt.ShortTag
import net.minecraft.nbt.StringTag import net.minecraft.nbt.StringTag
import net.minecraft.nbt.Tag import net.minecraft.nbt.Tag
import net.minecraft.world.item.ItemStack import net.minecraft.world.item.ItemStack
import ru.dbotthepony.mc.otm.core.math.Decimal
import ru.dbotthepony.mc.otm.core.util.readBinaryJson import ru.dbotthepony.mc.otm.core.util.readBinaryJson
import ru.dbotthepony.mc.otm.core.util.writeBinaryJson import ru.dbotthepony.mc.otm.core.util.writeBinaryJson
import java.util.UUID import java.util.UUID
@ -125,3 +126,7 @@ fun CompoundTag.getJson(key: String, sizeLimit: NbtAccounter = NbtAccounter(1 sh
fun CompoundTag.getBoolean(index: String, orElse: Boolean): Boolean { fun CompoundTag.getBoolean(index: String, orElse: Boolean): Boolean {
return (this[index] as? NumericTag)?.asInt?.let { it > 0 } ?: orElse return (this[index] as? NumericTag)?.asInt?.let { it > 0 } ?: orElse
} }
fun CompoundTag.getDecimal(key: String) = Decimal.deserializeNBT(this[key])
fun CompoundTag.putDecimal(key: String, value: Decimal) = put(key, value.serializeNBT())
operator fun CompoundTag.set(key: String, value: Decimal) = putDecimal(key, value)

View File

@ -5,12 +5,14 @@ import net.minecraft.core.registries.BuiltInRegistries
import net.minecraft.nbt.CompoundTag import net.minecraft.nbt.CompoundTag
import net.minecraft.nbt.NbtAccounter import net.minecraft.nbt.NbtAccounter
import net.minecraft.nbt.NbtIo import net.minecraft.nbt.NbtIo
import net.minecraft.network.FriendlyByteBuf
import net.minecraft.network.chat.Component import net.minecraft.network.chat.Component
import net.minecraft.resources.ResourceLocation import net.minecraft.resources.ResourceLocation
import net.minecraft.world.item.Item import net.minecraft.world.item.Item
import net.minecraft.world.item.ItemStack import net.minecraft.world.item.ItemStack
import net.minecraft.world.level.material.Fluid import net.minecraft.world.level.material.Fluid
import net.neoforged.neoforge.fluids.FluidStack import net.neoforged.neoforge.fluids.FluidStack
import ru.dbotthepony.mc.otm.core.math.Decimal
import java.io.* import java.io.*
import java.math.BigDecimal import java.math.BigDecimal
import java.math.BigInteger import java.math.BigInteger
@ -238,3 +240,20 @@ fun OutputStream.writeBinaryString(input: String) {
writeVarIntLE(bytes.size) writeVarIntLE(bytes.size)
write(bytes) write(bytes)
} }
fun FriendlyByteBuf.readDecimal() = Decimal.read(this)
fun FriendlyByteBuf.writeDecimal(value: Decimal) = value.write(this)
fun InputStream.readDecimal(): Decimal {
val size = readVarIntLE()
require(size >= 0) { "Negative payload size: $size" }
val bytes = ByteArray(size)
read(bytes)
return Decimal.fromByteArray(bytes)
}
fun OutputStream.writeDecimal(value: Decimal) {
val bytes = value.toByteArray()
writeVarIntLE(bytes.size)
write(bytes)
}

View File

@ -38,8 +38,8 @@ import ru.dbotthepony.mc.otm.core.ResourceLocation
import ru.dbotthepony.mc.otm.core.TextComponent import ru.dbotthepony.mc.otm.core.TextComponent
import ru.dbotthepony.mc.otm.core.TranslatableComponent import ru.dbotthepony.mc.otm.core.TranslatableComponent
import ru.dbotthepony.mc.otm.core.math.Decimal import ru.dbotthepony.mc.otm.core.math.Decimal
import ru.dbotthepony.mc.otm.core.math.readDecimal import ru.dbotthepony.mc.otm.core.util.readDecimal
import ru.dbotthepony.mc.otm.core.math.writeDecimal import ru.dbotthepony.mc.otm.core.util.writeDecimal
import ru.dbotthepony.mc.otm.core.readBlockType import ru.dbotthepony.mc.otm.core.readBlockType
import ru.dbotthepony.mc.otm.core.registryName import ru.dbotthepony.mc.otm.core.registryName
import ru.dbotthepony.mc.otm.core.util.formatPower import ru.dbotthepony.mc.otm.core.util.formatPower

View File

@ -7,12 +7,12 @@ import com.mojang.serialization.codecs.RecordCodecBuilder
import net.minecraft.util.RandomSource import net.minecraft.util.RandomSource
import net.neoforged.bus.api.IEventBus import net.neoforged.bus.api.IEventBus
import ru.dbotthepony.mc.otm.OverdriveThatMatters import ru.dbotthepony.mc.otm.OverdriveThatMatters
import ru.dbotthepony.mc.otm.core.ResourceLocation
import ru.dbotthepony.mc.otm.core.math.Decimal import ru.dbotthepony.mc.otm.core.math.Decimal
import ru.dbotthepony.mc.otm.core.math.nextDecimal import ru.dbotthepony.mc.otm.core.nextDecimal
import ru.dbotthepony.mc.otm.data.codec.DecimalCodec import ru.dbotthepony.mc.otm.data.codec.DecimalCodec
import ru.dbotthepony.mc.otm.registry.MBuiltInRegistries
import ru.dbotthepony.mc.otm.registry.MDeferredRegister import ru.dbotthepony.mc.otm.registry.MDeferredRegister
import ru.dbotthepony.mc.otm.registry.RegistryDelegate import ru.dbotthepony.mc.otm.registry.MRegistries
fun interface SampledDecimal { fun interface SampledDecimal {
fun sample(source: RandomSource): Decimal fun sample(source: RandomSource): Decimal
@ -28,33 +28,25 @@ abstract class DecimalProvider : SampledDecimal {
abstract val type: Type<*> abstract val type: Type<*>
companion object { companion object {
private val registryHolder = RegistryDelegate<Type<*>>("decimal_provider_type") {
defaultKey(ResourceLocation(OverdriveThatMatters.MOD_ID, "zero"))
}
val CODEC: Codec<DecimalProvider> by lazy { val CODEC: Codec<DecimalProvider> by lazy {
Codec Codec
.either(DecimalCodec, registry.byNameCodec().dispatch({ it.type }, { it.codec })) .either(DecimalCodec, MBuiltInRegistries.DECIMAL_PROVIDER_TYPE.byNameCodec().dispatch({ it.type }, { it.codec }))
.xmap( .xmap(
{ c -> c.map(::ConstantDecimal, { it }) }, { c -> c.map(::ConstantDecimal, { it }) },
{ if (it.type === ConstantDecimal) Either.left(it.minValue) else Either.right(it) } { if (it.type === ConstantDecimal) Either.left(it.minValue) else Either.right(it) }
) )
} }
val registry by registryHolder private val registrar = MDeferredRegister(MRegistries.DECIMAL_PROVIDER_TYPE, OverdriveThatMatters.MOD_ID)
val registryKey get() = registryHolder.key
private val registror = MDeferredRegister(registryKey, OverdriveThatMatters.MOD_ID)
init { init {
registror.register("zero") { ConstantDecimal.Zero } registrar.register("zero") { ConstantDecimal.Zero }
registror.register("constant") { ConstantDecimal } registrar.register("constant") { ConstantDecimal }
registror.register("uniform") { UniformDecimal } registrar.register("uniform") { UniformDecimal }
} }
internal fun register(bus: IEventBus) { internal fun register(bus: IEventBus) {
bus.addListener(registryHolder::build) registrar.register(bus)
registror.register(bus)
} }
} }
} }

View File

@ -38,11 +38,10 @@ import ru.dbotthepony.mc.otm.core.TranslatableComponent
import ru.dbotthepony.mc.otm.core.collect.filter import ru.dbotthepony.mc.otm.core.collect.filter
import ru.dbotthepony.mc.otm.core.isNotEmpty import ru.dbotthepony.mc.otm.core.isNotEmpty
import ru.dbotthepony.mc.otm.core.math.Decimal import ru.dbotthepony.mc.otm.core.math.Decimal
import ru.dbotthepony.mc.otm.core.math.getDecimal import ru.dbotthepony.mc.otm.core.nbt.getDecimal
import ru.dbotthepony.mc.otm.core.math.readDecimal import ru.dbotthepony.mc.otm.core.util.readDecimal
import ru.dbotthepony.mc.otm.core.math.set
import ru.dbotthepony.mc.otm.core.math.writeDecimal
import ru.dbotthepony.mc.otm.core.nbt.set import ru.dbotthepony.mc.otm.core.nbt.set
import ru.dbotthepony.mc.otm.core.util.writeDecimal
import ru.dbotthepony.mc.otm.core.nextUUID import ru.dbotthepony.mc.otm.core.nextUUID
import ru.dbotthepony.mc.otm.core.util.formatPower import ru.dbotthepony.mc.otm.core.util.formatPower
import ru.dbotthepony.mc.otm.isClientThread import ru.dbotthepony.mc.otm.isClientThread

View File

@ -20,6 +20,9 @@ import ru.dbotthepony.mc.otm.client.minecraft
import ru.dbotthepony.mc.otm.core.TranslatableComponent import ru.dbotthepony.mc.otm.core.TranslatableComponent
import ru.dbotthepony.mc.otm.core.isExplosion import ru.dbotthepony.mc.otm.core.isExplosion
import ru.dbotthepony.mc.otm.core.isFire import ru.dbotthepony.mc.otm.core.isFire
import ru.dbotthepony.mc.otm.core.isNotEmpty
import ru.dbotthepony.mc.otm.core.nextUUID
import ru.dbotthepony.mc.otm.core.otmRandom
import ru.dbotthepony.mc.otm.registry.game.MItems import ru.dbotthepony.mc.otm.registry.game.MItems
import ru.dbotthepony.mc.otm.runIfClient import ru.dbotthepony.mc.otm.runIfClient
import ru.dbotthepony.mc.otm.triggers.ExopackSlotsExpandedTrigger import ru.dbotthepony.mc.otm.triggers.ExopackSlotsExpandedTrigger
@ -35,7 +38,7 @@ abstract class AbstractExopackSlotUpgradeItem(properties: Properties = defaultPr
} }
override fun getUseDuration(p_41454_: ItemStack, p_344979_: LivingEntity): Int { override fun getUseDuration(p_41454_: ItemStack, p_344979_: LivingEntity): Int {
return 30 return 20
} }
override fun appendHoverText( override fun appendHoverText(
@ -76,7 +79,7 @@ abstract class AbstractExopackSlotUpgradeItem(properties: Properties = defaultPr
} }
override fun use(p_41432_: Level, player: Player, hand: InteractionHand): InteractionResultHolder<ItemStack> { override fun use(p_41432_: Level, player: Player, hand: InteractionHand): InteractionResultHolder<ItemStack> {
val matteryPlayer = player.matteryPlayer ?: return super.use(p_41432_, player, hand) val matteryPlayer = player.matteryPlayer
val uuid = uuid(player.getItemInHand(hand)) val uuid = uuid(player.getItemInHand(hand))
@ -98,25 +101,32 @@ abstract class AbstractExopackSlotUpgradeItem(properties: Properties = defaultPr
return super.finishUsingItem(itemStack, level, player) return super.finishUsingItem(itemStack, level, player)
} }
if (!player.abilities.instabuild) var allowedUses = itemStack.count
itemStack.shrink(1)
if (player is ServerPlayer) { while (allowedUses > 0) {
if (uuid != null) { if (!player.abilities.instabuild)
if (ServerConfig.INFINITE_EXOSUIT_UPGRADES && uuid in matteryPlayer.exopackSlotModifier) { itemStack.shrink(1)
matteryPlayer.exopackSlotModifier[UUID.randomUUID()] = slotCount
allowedUses--
if (player is ServerPlayer) {
if (uuid != null) {
if (ServerConfig.INFINITE_EXOSUIT_UPGRADES && uuid in matteryPlayer.exopackSlotModifier) {
matteryPlayer.exopackSlotModifier[level.otmRandom.nextUUID()] = slotCount
} else {
matteryPlayer.exopackSlotModifier[uuid] = slotCount
allowedUses = 0
}
} else { } else {
matteryPlayer.exopackSlotModifier[uuid] = slotCount matteryPlayer.exopackSlotModifier[level.otmRandom.nextUUID()] = slotCount
} }
} else {
matteryPlayer.exopackSlotModifier[UUID.randomUUID()] = slotCount
}
ExopackSlotsExpandedTrigger.trigger(player, slotCount, matteryPlayer.exopackContainer.containerSize) ExopackSlotsExpandedTrigger.trigger(player, slotCount, matteryPlayer.exopackContainer.containerSize)
player.displayClientMessage(TranslatableComponent("otm.exopack_upgrades.slots_upgraded", slotCount).withStyle(ChatFormatting.DARK_GREEN), false) player.displayClientMessage(TranslatableComponent("otm.exopack_upgrades.slots_upgraded", slotCount).withStyle(ChatFormatting.DARK_GREEN), false)
if (this === MItems.ExopackUpgrades.INVENTORY_UPGRADE_ENDER_DRAGON) { if (this === MItems.ExopackUpgrades.INVENTORY_UPGRADE_ENDER_DRAGON) {
MItems.ExopackUpgrades.ENDER_UPGRADE.finishUsingItem(ItemStack(MItems.ExopackUpgrades.INVENTORY_UPGRADE_ENDER_DRAGON), level, player) MItems.ExopackUpgrades.ENDER_UPGRADE.finishUsingItem(ItemStack(MItems.ExopackUpgrades.INVENTORY_UPGRADE_ENDER_DRAGON), level, player)
}
} }
} }

View File

@ -60,7 +60,7 @@ class ExopackUpgradeItem(
} }
override fun use(p_41432_: Level, player: Player, hand: InteractionHand): InteractionResultHolder<ItemStack> { override fun use(p_41432_: Level, player: Player, hand: InteractionHand): InteractionResultHolder<ItemStack> {
if (player.matteryPlayer?.hasExopack == true && !type.prop.get(player.matteryPlayer!!)) { if (player.matteryPlayer.hasExopack && !type.prop.get(player.matteryPlayer)) {
player.startUsingItem(hand) player.startUsingItem(hand)
return InteractionResultHolder.consume(player.getItemInHand(hand)) return InteractionResultHolder.consume(player.getItemInHand(hand))
} }
@ -70,7 +70,7 @@ class ExopackUpgradeItem(
override fun finishUsingItem(itemStack: ItemStack, level: Level, player: LivingEntity): ItemStack { override fun finishUsingItem(itemStack: ItemStack, level: Level, player: LivingEntity): ItemStack {
if (player !is Player) return super.finishUsingItem(itemStack, level, player) if (player !is Player) return super.finishUsingItem(itemStack, level, player)
val mattery = player.matteryPlayer ?: return super.finishUsingItem(itemStack, level, player) val mattery = player.matteryPlayer
if (!mattery.hasExopack || type.prop.get(mattery)) { if (!mattery.hasExopack || type.prop.get(mattery)) {
return super.finishUsingItem(itemStack, level, player) return super.finishUsingItem(itemStack, level, player)

View File

@ -29,9 +29,9 @@ import ru.dbotthepony.mc.otm.player.matteryPlayer
import ru.dbotthepony.mc.otm.core.ResourceLocation import ru.dbotthepony.mc.otm.core.ResourceLocation
import ru.dbotthepony.mc.otm.core.damageType import ru.dbotthepony.mc.otm.core.damageType
import ru.dbotthepony.mc.otm.core.math.Decimal import ru.dbotthepony.mc.otm.core.math.Decimal
import ru.dbotthepony.mc.otm.core.math.DecimalConfigValue import ru.dbotthepony.mc.otm.config.DecimalConfigValue
import ru.dbotthepony.mc.otm.core.math.defineDecimal import ru.dbotthepony.mc.otm.config.defineDecimal
import ru.dbotthepony.mc.otm.core.math.nextVariance import ru.dbotthepony.mc.otm.core.nextVariance
import ru.dbotthepony.mc.otm.core.otmRandom import ru.dbotthepony.mc.otm.core.otmRandom
import ru.dbotthepony.mc.otm.core.util.WriteOnce import ru.dbotthepony.mc.otm.core.util.WriteOnce
import ru.dbotthepony.mc.otm.item.MatteryItem import ru.dbotthepony.mc.otm.item.MatteryItem

View File

@ -29,9 +29,9 @@ import ru.dbotthepony.mc.otm.player.matteryPlayer
import ru.dbotthepony.mc.otm.core.ResourceLocation import ru.dbotthepony.mc.otm.core.ResourceLocation
import ru.dbotthepony.mc.otm.core.damageType import ru.dbotthepony.mc.otm.core.damageType
import ru.dbotthepony.mc.otm.core.math.Decimal import ru.dbotthepony.mc.otm.core.math.Decimal
import ru.dbotthepony.mc.otm.core.math.DecimalConfigValue import ru.dbotthepony.mc.otm.config.DecimalConfigValue
import ru.dbotthepony.mc.otm.core.math.defineDecimal import ru.dbotthepony.mc.otm.config.defineDecimal
import ru.dbotthepony.mc.otm.core.math.nextVariance import ru.dbotthepony.mc.otm.core.nextVariance
import ru.dbotthepony.mc.otm.core.otmRandom import ru.dbotthepony.mc.otm.core.otmRandom
import ru.dbotthepony.mc.otm.core.util.WriteOnce import ru.dbotthepony.mc.otm.core.util.WriteOnce
import ru.dbotthepony.mc.otm.item.MatteryItem import ru.dbotthepony.mc.otm.item.MatteryItem

View File

@ -13,8 +13,9 @@ import net.minecraft.tags.TagKey
import net.minecraft.world.item.Item import net.minecraft.world.item.Item
import net.neoforged.bus.api.IEventBus import net.neoforged.bus.api.IEventBus
import ru.dbotthepony.mc.otm.OverdriveThatMatters import ru.dbotthepony.mc.otm.OverdriveThatMatters
import ru.dbotthepony.mc.otm.registry.MBuiltInRegistries
import ru.dbotthepony.mc.otm.registry.MDeferredRegister import ru.dbotthepony.mc.otm.registry.MDeferredRegister
import ru.dbotthepony.mc.otm.registry.RegistryDelegate import ru.dbotthepony.mc.otm.registry.MRegistries
import java.util.* import java.util.*
abstract class AbstractRegistryAction( abstract class AbstractRegistryAction(
@ -99,12 +100,7 @@ abstract class AbstractRegistryAction(
} }
companion object { companion object {
private val registryDelegate = RegistryDelegate<Type<*>>("matter_registry_action") { sync(false) } private val registrar = MDeferredRegister(MRegistries.MATTER_REGISTRY_ACTION, OverdriveThatMatters.MOD_ID)
val registryKey get() = registryDelegate.key
val registry by registryDelegate
private val registrar = MDeferredRegister(registryKey, OverdriveThatMatters.MOD_ID)
init { init {
registrar.register("insert") { InsertAction.Companion } registrar.register("insert") { InsertAction.Companion }
@ -116,11 +112,10 @@ abstract class AbstractRegistryAction(
internal fun register(bus: IEventBus) { internal fun register(bus: IEventBus) {
registrar.register(bus) registrar.register(bus)
bus.addListener(registryDelegate::build)
} }
val CODEC: Codec<AbstractRegistryAction> by lazy { val CODEC: Codec<AbstractRegistryAction> by lazy {
registry.byNameCodec().dispatch({ it.type }, { it.codec }) MBuiltInRegistries.MATTER_REGISTRY_ACTION.byNameCodec().dispatch({ it.type }, { it.codec })
} }
} }
} }

View File

@ -15,6 +15,7 @@ import net.minecraft.world.item.Item
import ru.dbotthepony.mc.otm.core.math.Decimal import ru.dbotthepony.mc.otm.core.math.Decimal
import ru.dbotthepony.mc.otm.data.codec.DecimalCodec import ru.dbotthepony.mc.otm.data.codec.DecimalCodec
import ru.dbotthepony.mc.otm.data.codec.PredicatedCodecList import ru.dbotthepony.mc.otm.data.codec.PredicatedCodecList
import ru.dbotthepony.mc.otm.registry.MBuiltInRegistries
import java.util.Optional import java.util.Optional
import java.util.function.Predicate import java.util.function.Predicate
@ -29,8 +30,8 @@ class ComputeAction(
it.group( it.group(
DecimalCodec.fieldOf("matter").forGetter(Constant::matter), DecimalCodec.fieldOf("matter").forGetter(Constant::matter),
Codec.DOUBLE.fieldOf("complexity").forGetter(Constant::complexity), Codec.DOUBLE.fieldOf("complexity").forGetter(Constant::complexity),
IMatterFunction.registry.byNameCodec().fieldOf("matterFunction").forGetter(Constant::matterFunction), MBuiltInRegistries.MATTER_FUNCTION.byNameCodec().fieldOf("matterFunction").forGetter(Constant::matterFunction),
IMatterFunction.registry.byNameCodec().fieldOf("complexityFunction").forGetter(Constant::complexityFunction), MBuiltInRegistries.MATTER_FUNCTION.byNameCodec().fieldOf("complexityFunction").forGetter(Constant::complexityFunction),
).apply(it, ::Constant) ).apply(it, ::Constant)
} to Predicate { true } } to Predicate { true }
} }
@ -40,7 +41,7 @@ class ComputeAction(
it.group( it.group(
DecimalCodec.fieldOf("matter").forGetter(Constant::matter), DecimalCodec.fieldOf("matter").forGetter(Constant::matter),
Codec.DOUBLE.fieldOf("complexity").forGetter(Constant::complexity), Codec.DOUBLE.fieldOf("complexity").forGetter(Constant::complexity),
IMatterFunction.registry.byNameCodec().fieldOf("function").forGetter(Constant::matterFunction), MBuiltInRegistries.MATTER_FUNCTION.byNameCodec().fieldOf("function").forGetter(Constant::matterFunction),
).apply(it) { a, b, c -> Constant(a, b, c, c) } ).apply(it) { a, b, c -> Constant(a, b, c, c) }
} to Predicate { it.matterFunction == it.complexityFunction } } to Predicate { it.matterFunction == it.complexityFunction }
} }
@ -49,8 +50,8 @@ class ComputeAction(
RecordCodecBuilder.create<Constant> { RecordCodecBuilder.create<Constant> {
it.group( it.group(
DecimalCodec.fieldOf("value").forGetter(Constant::matter), DecimalCodec.fieldOf("value").forGetter(Constant::matter),
IMatterFunction.registry.byNameCodec().fieldOf("matterFunction").forGetter(Constant::matterFunction), MBuiltInRegistries.MATTER_FUNCTION.byNameCodec().fieldOf("matterFunction").forGetter(Constant::matterFunction),
IMatterFunction.registry.byNameCodec().fieldOf("complexityFunction").forGetter(Constant::complexityFunction), MBuiltInRegistries.MATTER_FUNCTION.byNameCodec().fieldOf("complexityFunction").forGetter(Constant::complexityFunction),
).apply(it) { a, b, c -> Constant(a, a.toDouble(), b, c) } ).apply(it) { a, b, c -> Constant(a, a.toDouble(), b, c) }
} to Predicate { it.matter == Decimal(it.complexity.toString()) } } to Predicate { it.matter == Decimal(it.complexity.toString()) }
} }
@ -59,7 +60,7 @@ class ComputeAction(
RecordCodecBuilder.create<Constant> { RecordCodecBuilder.create<Constant> {
it.group( it.group(
DecimalCodec.fieldOf("value").forGetter(Constant::matter), DecimalCodec.fieldOf("value").forGetter(Constant::matter),
IMatterFunction.registry.byNameCodec().fieldOf("function").forGetter(Constant::matterFunction), MBuiltInRegistries.MATTER_FUNCTION.byNameCodec().fieldOf("function").forGetter(Constant::matterFunction),
).apply(it) { a, b -> Constant(a, a.toDouble(), b, b) } ).apply(it) { a, b -> Constant(a, a.toDouble(), b, b) }
} to Predicate { it.matter == Decimal(it.complexity.toString()) && it.matterFunction == it.complexityFunction } } to Predicate { it.matter == Decimal(it.complexity.toString()) && it.matterFunction == it.complexityFunction }
} }
@ -68,7 +69,7 @@ class ComputeAction(
RecordCodecBuilder.create<Constant> { RecordCodecBuilder.create<Constant> {
it.group( it.group(
Codec.DOUBLE.fieldOf("complexity").forGetter(Constant::complexity), Codec.DOUBLE.fieldOf("complexity").forGetter(Constant::complexity),
IMatterFunction.registry.byNameCodec().fieldOf("function").forGetter(Constant::complexityFunction), MBuiltInRegistries.MATTER_FUNCTION.byNameCodec().fieldOf("function").forGetter(Constant::complexityFunction),
).apply(it) { a, b -> Constant(Decimal.ZERO, a.toDouble(), IMatterFunction.NOOP, b) } ).apply(it) { a, b -> Constant(Decimal.ZERO, a.toDouble(), IMatterFunction.NOOP, b) }
} to Predicate { it.matterFunction == IMatterFunction.NOOP } } to Predicate { it.matterFunction == IMatterFunction.NOOP }
} }
@ -77,7 +78,7 @@ class ComputeAction(
RecordCodecBuilder.create<Constant> { RecordCodecBuilder.create<Constant> {
it.group( it.group(
Codec.DOUBLE.fieldOf("complexity").forGetter(Constant::complexity), Codec.DOUBLE.fieldOf("complexity").forGetter(Constant::complexity),
IMatterFunction.registry.byNameCodec().fieldOf("complexityFunction").forGetter(Constant::complexityFunction), MBuiltInRegistries.MATTER_FUNCTION.byNameCodec().fieldOf("complexityFunction").forGetter(Constant::complexityFunction),
).apply(it) { a, b -> Constant(Decimal.ZERO, a.toDouble(), IMatterFunction.NOOP, b) } ).apply(it) { a, b -> Constant(Decimal.ZERO, a.toDouble(), IMatterFunction.NOOP, b) }
} to Predicate { it.matterFunction == IMatterFunction.NOOP } } to Predicate { it.matterFunction == IMatterFunction.NOOP }
} }
@ -86,7 +87,7 @@ class ComputeAction(
RecordCodecBuilder.create<Constant> { RecordCodecBuilder.create<Constant> {
it.group( it.group(
DecimalCodec.fieldOf("matter").forGetter(Constant::matter), DecimalCodec.fieldOf("matter").forGetter(Constant::matter),
IMatterFunction.registry.byNameCodec().fieldOf("function").forGetter(Constant::matterFunction), MBuiltInRegistries.MATTER_FUNCTION.byNameCodec().fieldOf("function").forGetter(Constant::matterFunction),
).apply(it) { a, b -> Constant(a, 0.0, b, IMatterFunction.NOOP) } ).apply(it) { a, b -> Constant(a, 0.0, b, IMatterFunction.NOOP) }
} to Predicate { it.complexityFunction == IMatterFunction.NOOP } } to Predicate { it.complexityFunction == IMatterFunction.NOOP }
} }
@ -95,7 +96,7 @@ class ComputeAction(
RecordCodecBuilder.create<Constant> { RecordCodecBuilder.create<Constant> {
it.group( it.group(
DecimalCodec.fieldOf("matter").forGetter(Constant::matter), DecimalCodec.fieldOf("matter").forGetter(Constant::matter),
IMatterFunction.registry.byNameCodec().fieldOf("matterFunction").forGetter(Constant::matterFunction), MBuiltInRegistries.MATTER_FUNCTION.byNameCodec().fieldOf("matterFunction").forGetter(Constant::matterFunction),
).apply(it) { a, b -> Constant(a, 0.0, b, IMatterFunction.NOOP) } ).apply(it) { a, b -> Constant(a, 0.0, b, IMatterFunction.NOOP) }
} to Predicate { it.complexityFunction == IMatterFunction.NOOP } } to Predicate { it.complexityFunction == IMatterFunction.NOOP }
} }
@ -182,7 +183,7 @@ class ComputeAction(
RecordCodecBuilder.create { RecordCodecBuilder.create {
it.group( it.group(
TargetCodec.fieldOf("id").forGetter(Value::id), TargetCodec.fieldOf("id").forGetter(Value::id),
IMatterFunction.registry.byNameCodec().fieldOf("function").forGetter(Value::matterFunction), MBuiltInRegistries.MATTER_FUNCTION.byNameCodec().fieldOf("function").forGetter(Value::matterFunction),
).apply(it, ::Value) ).apply(it, ::Value)
} }
} }
@ -191,8 +192,8 @@ class ComputeAction(
RecordCodecBuilder.create { RecordCodecBuilder.create {
it.group( it.group(
TargetCodec.fieldOf("id").forGetter(Value::id), TargetCodec.fieldOf("id").forGetter(Value::id),
IMatterFunction.registry.byNameCodec().fieldOf("matterFunction").forGetter(Value::matterFunction), MBuiltInRegistries.MATTER_FUNCTION.byNameCodec().fieldOf("matterFunction").forGetter(Value::matterFunction),
IMatterFunction.registry.byNameCodec().fieldOf("complexityFunction").forGetter(Value::complexityFunction), MBuiltInRegistries.MATTER_FUNCTION.byNameCodec().fieldOf("complexityFunction").forGetter(Value::complexityFunction),
).apply(it, ::Value) ).apply(it, ::Value)
} }
} }

View File

@ -7,7 +7,7 @@ import ru.dbotthepony.mc.otm.matter.SimpleMatterFunction.DecimalFunction
import ru.dbotthepony.mc.otm.matter.SimpleMatterFunction.DoubleFunction import ru.dbotthepony.mc.otm.matter.SimpleMatterFunction.DoubleFunction
import ru.dbotthepony.mc.otm.matter.SimpleMatterFunction.IntFunction import ru.dbotthepony.mc.otm.matter.SimpleMatterFunction.IntFunction
import ru.dbotthepony.mc.otm.registry.MDeferredRegister import ru.dbotthepony.mc.otm.registry.MDeferredRegister
import ru.dbotthepony.mc.otm.registry.RegistryDelegate import ru.dbotthepony.mc.otm.registry.MRegistries
interface IMatterFunction { interface IMatterFunction {
fun updateValue(self: Int, other: Int): Int fun updateValue(self: Int, other: Int): Int
@ -15,12 +15,7 @@ interface IMatterFunction {
fun updateValue(self: Double, other: Double): Double fun updateValue(self: Double, other: Double): Double
companion object : IMatterFunction { companion object : IMatterFunction {
private val registryDelegate = RegistryDelegate<IMatterFunction>("matter_function") { sync(false) } private val registrar = MDeferredRegister(MRegistries.MATTER_FUNCTION, OverdriveThatMatters.MOD_ID)
val registryKey get() = registryDelegate.key
val registry by registryDelegate
private val registrar = MDeferredRegister(registryKey, OverdriveThatMatters.MOD_ID)
init { init {
registrar.register("noop") { this } registrar.register("noop") { this }
@ -38,7 +33,6 @@ interface IMatterFunction {
internal fun register(bus: IEventBus) { internal fun register(bus: IEventBus) {
registrar.register(bus) registrar.register(bus)
bus.addListener(registryDelegate::build)
} }
override fun updateValue(self: Int, other: Int): Int { override fun updateValue(self: Int, other: Int): Int {

View File

@ -2,8 +2,8 @@ package ru.dbotthepony.mc.otm.matter
import net.minecraft.network.FriendlyByteBuf import net.minecraft.network.FriendlyByteBuf
import ru.dbotthepony.mc.otm.core.math.Decimal import ru.dbotthepony.mc.otm.core.math.Decimal
import ru.dbotthepony.mc.otm.core.math.readDecimal import ru.dbotthepony.mc.otm.core.util.readDecimal
import ru.dbotthepony.mc.otm.core.math.writeDecimal import ru.dbotthepony.mc.otm.core.util.writeDecimal
import ru.dbotthepony.mc.otm.core.util.readDouble import ru.dbotthepony.mc.otm.core.util.readDouble
import ru.dbotthepony.mc.otm.core.util.writeDouble import ru.dbotthepony.mc.otm.core.util.writeDouble
import java.io.InputStream import java.io.InputStream

View File

@ -103,8 +103,9 @@ import ru.dbotthepony.mc.otm.core.writeItemType
import ru.dbotthepony.mc.otm.matter.MatterManager.Finder import ru.dbotthepony.mc.otm.matter.MatterManager.Finder
import ru.dbotthepony.mc.otm.milliTime import ru.dbotthepony.mc.otm.milliTime
import ru.dbotthepony.mc.otm.onceServer import ru.dbotthepony.mc.otm.onceServer
import ru.dbotthepony.mc.otm.registry.MBuiltInRegistries
import ru.dbotthepony.mc.otm.registry.MDeferredRegister import ru.dbotthepony.mc.otm.registry.MDeferredRegister
import ru.dbotthepony.mc.otm.registry.RegistryDelegate import ru.dbotthepony.mc.otm.registry.MRegistries
import ru.dbotthepony.mc.otm.secondTime import ru.dbotthepony.mc.otm.secondTime
import ru.dbotthepony.mc.otm.storage.ItemStorageStack import ru.dbotthepony.mc.otm.storage.ItemStorageStack
import ru.dbotthepony.mc.otm.storage.StorageStack import ru.dbotthepony.mc.otm.storage.StorageStack
@ -398,12 +399,10 @@ object MatterManager {
} }
private object Resolver : SimpleJsonResourceReloadListener(GsonBuilder().setPrettyPrinting().disableHtmlEscaping().create(), FINDER_DIRECTORY) { private object Resolver : SimpleJsonResourceReloadListener(GsonBuilder().setPrettyPrinting().disableHtmlEscaping().create(), FINDER_DIRECTORY) {
val delegate = RegistryDelegate<Finder>("recipe_finder") { sync(false) }
var ready = false var ready = false
private set private set
val registrar = MDeferredRegister(delegate.key, OverdriveThatMatters.MOD_ID) val registrar = MDeferredRegister(MRegistries.RECIPE_FINDER, OverdriveThatMatters.MOD_ID)
init { init {
registrar.register("simple") { registrar.register("simple") {
@ -640,11 +639,11 @@ object MatterManager {
val location = (json["type"] ?: throw JsonSyntaxException("Missing resolver type")).let { ResourceLocation.tryParse(it.asString) } ?: throw JsonSyntaxException("Invalid resolver type: ${json["type"]}") val location = (json["type"] ?: throw JsonSyntaxException("Missing resolver type")).let { ResourceLocation.tryParse(it.asString) } ?: throw JsonSyntaxException("Invalid resolver type: ${json["type"]}")
if (!recipeFinders.containsKey(location)) { if (!MBuiltInRegistries.RECIPE_FINDER.containsKey(location)) {
throw JsonParseException("Resolver type $location does not exist (in $key)") throw JsonParseException("Resolver type $location does not exist (in $key)")
} }
val resolver = recipeFinders.get(location) ?: throw ConcurrentModificationException() val resolver = MBuiltInRegistries.RECIPE_FINDER.get(location) ?: throw ConcurrentModificationException()
builder.put(key, resolver to json) builder.put(key, resolver to json)
} }
@ -1496,20 +1495,6 @@ object MatterManager {
return Registry.direct(value) return Registry.direct(value)
} }
/**
* Access recipe finders registry
*
* @throws IllegalStateException if calling too early
*/
@JvmStatic val recipeFinders get() = Resolver.delegate.get()
/**
* Access recipe finders registry key
*
* Use this with your [DeferredRegister]
*/
@JvmStatic val recipeFindersKey get() = Resolver.delegate.key
private val commentary = Reference2ObjectOpenHashMap<Item, ArrayList<Component>>() private val commentary = Reference2ObjectOpenHashMap<Item, ArrayList<Component>>()
@JvmStatic @JvmStatic
@ -1534,7 +1519,6 @@ object MatterManager {
} }
internal fun initialize(bus: IEventBus) { internal fun initialize(bus: IEventBus) {
bus.addListener(Resolver.delegate::build)
Resolver.registrar.register(bus) Resolver.registrar.register(bus)
} }

View File

@ -11,6 +11,7 @@ import net.minecraft.world.item.Item
import ru.dbotthepony.mc.otm.core.math.Decimal import ru.dbotthepony.mc.otm.core.math.Decimal
import ru.dbotthepony.mc.otm.data.codec.DecimalCodec import ru.dbotthepony.mc.otm.data.codec.DecimalCodec
import ru.dbotthepony.mc.otm.data.codec.simpleCodec import ru.dbotthepony.mc.otm.data.codec.simpleCodec
import ru.dbotthepony.mc.otm.registry.MBuiltInRegistries
class UpdateAction( class UpdateAction(
id: Either<ResourceLocation, TagKey<Item>>, id: Either<ResourceLocation, TagKey<Item>>,
@ -22,7 +23,7 @@ class UpdateAction(
data class MatterFunction(val function: IMatterFunction, val value: Decimal) { data class MatterFunction(val function: IMatterFunction, val value: Decimal) {
companion object { companion object {
val CODEC: Codec<MatterFunction> by lazy { val CODEC: Codec<MatterFunction> by lazy {
simpleCodec(::MatterFunction, MatterFunction::function, IMatterFunction.registry.byNameCodec(), MatterFunction::value, DecimalCodec) simpleCodec(::MatterFunction, MatterFunction::function, MBuiltInRegistries.MATTER_FUNCTION.byNameCodec(), MatterFunction::value, DecimalCodec)
} }
} }
} }
@ -30,7 +31,7 @@ class UpdateAction(
data class ComplexityFunction(val function: IMatterFunction, val value: Double) { data class ComplexityFunction(val function: IMatterFunction, val value: Double) {
companion object { companion object {
val CODEC: Codec<ComplexityFunction> by lazy { val CODEC: Codec<ComplexityFunction> by lazy {
simpleCodec(::ComplexityFunction, ComplexityFunction::function, IMatterFunction.registry.byNameCodec(), ComplexityFunction::value, Codec.DOUBLE) simpleCodec(::ComplexityFunction, ComplexityFunction::function, MBuiltInRegistries.MATTER_FUNCTION.byNameCodec(), ComplexityFunction::value, Codec.DOUBLE)
} }
} }
} }
@ -38,7 +39,7 @@ class UpdateAction(
data class PriorityFunction(val function: IMatterFunction, val value: Int) { data class PriorityFunction(val function: IMatterFunction, val value: Int) {
companion object { companion object {
val CODEC: Codec<PriorityFunction> by lazy { val CODEC: Codec<PriorityFunction> by lazy {
simpleCodec(::PriorityFunction, PriorityFunction::function, IMatterFunction.registry.byNameCodec(), PriorityFunction::value, Codec.INT) simpleCodec(::PriorityFunction, PriorityFunction::function, MBuiltInRegistries.MATTER_FUNCTION.byNameCodec(), PriorityFunction::value, Codec.INT)
} }
} }
} }

View File

@ -12,7 +12,7 @@ import ru.dbotthepony.mc.otm.menu.widget.LevelGaugeWidget
import ru.dbotthepony.mc.otm.menu.widget.ProfiledLevelGaugeWidget import ru.dbotthepony.mc.otm.menu.widget.ProfiledLevelGaugeWidget
import ru.dbotthepony.mc.otm.registry.game.MMenus import ru.dbotthepony.mc.otm.registry.game.MMenus
class MatterCapacitorBankMenu @JvmOverloads constructor( class MatterCapacitorBankMenu(
p_38852_: Int, p_38852_: Int,
inventory: Inventory, inventory: Inventory,
tile: MatterCapacitorBankBlockEntity? = null tile: MatterCapacitorBankBlockEntity? = null

View File

@ -12,19 +12,21 @@ import ru.dbotthepony.mc.otm.core.chart.DecimalHistoryChart
import ru.dbotthepony.mc.otm.core.math.Decimal import ru.dbotthepony.mc.otm.core.math.Decimal
import ru.dbotthepony.mc.otm.core.math.toDecimal import ru.dbotthepony.mc.otm.core.math.toDecimal
import ru.dbotthepony.mc.otm.menu.MatteryMenu import ru.dbotthepony.mc.otm.menu.MatteryMenu
import ru.dbotthepony.mc.otm.menu.input.BooleanInputWithFeedback
import ru.dbotthepony.mc.otm.menu.input.EnumInputWithFeedback import ru.dbotthepony.mc.otm.menu.input.EnumInputWithFeedback
import ru.dbotthepony.mc.otm.menu.input.IntInputWithFeedback import ru.dbotthepony.mc.otm.menu.input.IntInputWithFeedback
import ru.dbotthepony.mc.otm.registry.game.MMenus import ru.dbotthepony.mc.otm.registry.game.MMenus
import java.math.BigDecimal import java.math.BigDecimal
import java.util.function.Supplier
class EnergyCounterMenu( class EnergyCounterMenu(
p_38852_: Int, p_38852_: Int,
inventory: Inventory, inventory: Inventory,
tile: EnergyCounterBlockEntity? = null tile: EnergyCounterBlockEntity? = null
) : MatteryMenu(MMenus.ENERGY_COUNTER, p_38852_, inventory, tile) { ) : MatteryMenu(MMenus.ENERGY_COUNTER, p_38852_, inventory, tile) {
var passed by mSynchronizer.decimal() var passed by mSynchronizer.computedDecimal { tile?.passed ?: Decimal.ZERO }
var lastTick by mSynchronizer.decimal() var lastTick by mSynchronizer.computedDecimal { tile?.lastTick ?: Decimal.ZERO }
var maxIO by mSynchronizer.decimal() var maxIO by mSynchronizer.computedDecimal { tile?.ioLimit ?: Decimal.ZERO }
val history5s = tile?.history5s ?: DecimalHistoryChart(1, 100) val history5s = tile?.history5s ?: DecimalHistoryChart(1, 100)
val history15s = tile?.history15s ?: DecimalHistoryChart(3, 100) val history15s = tile?.history15s ?: DecimalHistoryChart(3, 100)
@ -34,6 +36,8 @@ class EnergyCounterMenu(
val history6h = tile?.history6h ?: DecimalHistoryChart(720 * 6, 100) val history6h = tile?.history6h ?: DecimalHistoryChart(720 * 6, 100)
val history24h = tile?.history24h ?: DecimalHistoryChart(720 * 24, 100) val history24h = tile?.history24h ?: DecimalHistoryChart(720 * 24, 100)
val pullEnergyFromInput = BooleanInputWithFeedback(this, tile?.let { it::pullEnergyFromInput })
init { init {
mSynchronizer.add(history5s) mSynchronizer.add(history5s)
mSynchronizer.add(history15s) mSynchronizer.add(history15s)
@ -59,7 +63,7 @@ class EnergyCounterMenu(
} }
} }
var inputDirection: Direction by mSynchronizer.enum(Direction.UP) val inputDirection: Direction by mSynchronizer.computedEnum { tile?.blockState?.getValue(EnergyCounterBlock.INPUT_DIRECTION) ?: Direction.UP}
val maxIOInput = decimalInput { val maxIOInput = decimalInput {
if (tile is EnergyCounterBlockEntity) { if (tile is EnergyCounterBlockEntity) {
@ -70,20 +74,4 @@ class EnergyCounterMenu(
} }
} }
} }
override fun beforeBroadcast() {
super.beforeBroadcast()
if (tile is EnergyCounterBlockEntity) {
passed = tile.passed
lastTick = tile.lastTick
inputDirection = tile.blockState.getValue(EnergyCounterBlock.INPUT_DIRECTION)
maxIO = tile.ioLimit?.toDecimal() ?: -Decimal.ONE
}
}
companion object {
private val MINUS_ONE = -BigDecimal.ONE
}
} }

View File

@ -26,13 +26,14 @@ import ru.dbotthepony.mc.otm.core.readComponent
import ru.dbotthepony.mc.otm.core.writeComponent import ru.dbotthepony.mc.otm.core.writeComponent
import ru.dbotthepony.mc.otm.menu.tech.AndroidStationMenu import ru.dbotthepony.mc.otm.menu.tech.AndroidStationMenu
import ru.dbotthepony.mc.otm.onceServer import ru.dbotthepony.mc.otm.onceServer
import ru.dbotthepony.mc.otm.registry.MBuiltInRegistries
import ru.dbotthepony.mc.otm.registry.game.AndroidFeatures import ru.dbotthepony.mc.otm.registry.game.AndroidFeatures
import ru.dbotthepony.mc.otm.registry.MRegistry import ru.dbotthepony.mc.otm.registry.MRegistry
import ru.dbotthepony.mc.otm.registry.game.MSoundEvents import ru.dbotthepony.mc.otm.registry.game.MSoundEvents
class AndroidFeatureSyncPacket(val type: AndroidFeatureType<*>, val data: ByteArrayList) : CustomPacketPayload { class AndroidFeatureSyncPacket(val type: AndroidFeatureType<*>, val data: ByteArrayList) : CustomPacketPayload {
fun write(buff: RegistryFriendlyByteBuf) { fun write(buff: RegistryFriendlyByteBuf) {
buff.writeInt(MRegistry.ANDROID_FEATURES.getId(type)) buff.writeInt(MBuiltInRegistries.ANDROID_FEATURE.getId(type))
buff.writeBytes(data.elements(), 0, data.size) buff.writeBytes(data.elements(), 0, data.size)
} }
@ -58,7 +59,7 @@ class AndroidFeatureSyncPacket(val type: AndroidFeatureType<*>, val data: ByteAr
fun read(buff: RegistryFriendlyByteBuf): AndroidFeatureSyncPacket { fun read(buff: RegistryFriendlyByteBuf): AndroidFeatureSyncPacket {
return AndroidFeatureSyncPacket( return AndroidFeatureSyncPacket(
MRegistry.ANDROID_FEATURES.byIdOrThrow(buff.readInt()), MBuiltInRegistries.ANDROID_FEATURE.byIdOrThrow(buff.readInt()),
ByteArrayList.wrap(ByteArray(buff.readableBytes()).also { buff.readBytes(it) }) ByteArrayList.wrap(ByteArray(buff.readableBytes()).also { buff.readBytes(it) })
) )
} }
@ -140,7 +141,7 @@ class AndroidResearchRequestPacket(val type: AndroidResearchType) : CustomPacket
class AndroidFeatureRemovePacket(val type: AndroidFeatureType<*>) : CustomPacketPayload { class AndroidFeatureRemovePacket(val type: AndroidFeatureType<*>) : CustomPacketPayload {
fun write(buff: FriendlyByteBuf) { fun write(buff: FriendlyByteBuf) {
buff.writeInt(MRegistry.ANDROID_FEATURES.getId(type)) buff.writeInt(MBuiltInRegistries.ANDROID_FEATURE.getId(type))
} }
fun play(context: IPayloadContext) { fun play(context: IPayloadContext) {
@ -164,7 +165,7 @@ class AndroidFeatureRemovePacket(val type: AndroidFeatureType<*>) : CustomPacket
StreamCodec.ofMember(AndroidFeatureRemovePacket::write, ::read) StreamCodec.ofMember(AndroidFeatureRemovePacket::write, ::read)
fun read(buff: FriendlyByteBuf): AndroidFeatureRemovePacket { fun read(buff: FriendlyByteBuf): AndroidFeatureRemovePacket {
return AndroidFeatureRemovePacket(MRegistry.ANDROID_FEATURES.byIdOrThrow(buff.readInt())) return AndroidFeatureRemovePacket(MBuiltInRegistries.ANDROID_FEATURE.byIdOrThrow(buff.readInt()))
} }
} }
} }
@ -219,7 +220,7 @@ class PlayerIterationPacket(val iteration: Int, val deathLog: List<Pair<Int, Com
class SwitchAndroidFeaturePacket(val type: AndroidFeatureType<*>, val newState: Boolean) : CustomPacketPayload { class SwitchAndroidFeaturePacket(val type: AndroidFeatureType<*>, val newState: Boolean) : CustomPacketPayload {
fun write(buff: FriendlyByteBuf) { fun write(buff: FriendlyByteBuf) {
buff.writeInt(MRegistry.ANDROID_FEATURES.getId(type)) buff.writeInt(MBuiltInRegistries.ANDROID_FEATURE.getId(type))
buff.writeBoolean(newState) buff.writeBoolean(newState)
} }
@ -259,14 +260,14 @@ class SwitchAndroidFeaturePacket(val type: AndroidFeatureType<*>, val newState:
StreamCodec.ofMember(SwitchAndroidFeaturePacket::write, ::read) StreamCodec.ofMember(SwitchAndroidFeaturePacket::write, ::read)
fun read(buff: FriendlyByteBuf): SwitchAndroidFeaturePacket { fun read(buff: FriendlyByteBuf): SwitchAndroidFeaturePacket {
return SwitchAndroidFeaturePacket(MRegistry.ANDROID_FEATURES.byIdOrThrow(buff.readInt()), buff.readBoolean()) return SwitchAndroidFeaturePacket(MBuiltInRegistries.ANDROID_FEATURE.byIdOrThrow(buff.readInt()), buff.readBoolean())
} }
} }
} }
class ActivateAndroidFeaturePacket(val type: AndroidFeatureType<*>) : CustomPacketPayload { class ActivateAndroidFeaturePacket(val type: AndroidFeatureType<*>) : CustomPacketPayload {
fun write(buff: FriendlyByteBuf) { fun write(buff: FriendlyByteBuf) {
buff.writeInt(MRegistry.ANDROID_FEATURES.getId(type)) buff.writeInt(MBuiltInRegistries.ANDROID_FEATURE.getId(type))
} }
fun play(context: IPayloadContext) { fun play(context: IPayloadContext) {
@ -298,7 +299,7 @@ class ActivateAndroidFeaturePacket(val type: AndroidFeatureType<*>) : CustomPack
StreamCodec.ofMember(ActivateAndroidFeaturePacket::write, ::read) StreamCodec.ofMember(ActivateAndroidFeaturePacket::write, ::read)
fun read(buff: FriendlyByteBuf): ActivateAndroidFeaturePacket { fun read(buff: FriendlyByteBuf): ActivateAndroidFeaturePacket {
return ActivateAndroidFeaturePacket(MRegistry.ANDROID_FEATURES.byIdOrThrow(buff.readInt())) return ActivateAndroidFeaturePacket(MBuiltInRegistries.ANDROID_FEATURE.byIdOrThrow(buff.readInt()))
} }
} }
} }

View File

@ -9,8 +9,8 @@ import net.minecraft.resources.ResourceLocation
import net.minecraft.world.level.block.Block import net.minecraft.world.level.block.Block
import net.minecraft.world.level.block.state.BlockState import net.minecraft.world.level.block.state.BlockState
import ru.dbotthepony.kommons.math.RGBAColor import ru.dbotthepony.kommons.math.RGBAColor
import ru.dbotthepony.mc.otm.core.math.readDecimal import ru.dbotthepony.mc.otm.core.util.readDecimal
import ru.dbotthepony.mc.otm.core.math.writeDecimal import ru.dbotthepony.mc.otm.core.util.writeDecimal
import ru.dbotthepony.mc.otm.core.readBlockType import ru.dbotthepony.mc.otm.core.readBlockType
import ru.dbotthepony.mc.otm.core.readItemType import ru.dbotthepony.mc.otm.core.readItemType
import ru.dbotthepony.mc.otm.core.writeBlockType import ru.dbotthepony.mc.otm.core.writeBlockType

View File

@ -270,6 +270,10 @@ class SynchableGroup : Observer, ISynchable, Iterable<ISynchable> {
return add(ListenableDelegate.maskSmart(value, getter, setter), MatteryStreamCodec.Enum(value::class.java)) return add(ListenableDelegate.maskSmart(value, getter, setter), MatteryStreamCodec.Enum(value::class.java))
} }
inline fun <reified E : Enum<E>> computedEnum(value: Supplier<E>): SynchableDelegate<E> {
return computed(value, MatteryStreamCodec.Enum(E::class.java))
}
fun decimal(value: Decimal = Decimal.ZERO, setter: DelegateSetter<Decimal> = DelegateSetter.passthrough(), getter: DelegateGetter<Decimal> = DelegateGetter.passthrough()): SynchableDelegate<Decimal> { fun decimal(value: Decimal = Decimal.ZERO, setter: DelegateSetter<Decimal> = DelegateSetter.passthrough(), getter: DelegateGetter<Decimal> = DelegateGetter.passthrough()): SynchableDelegate<Decimal> {
return add(ListenableDelegate.maskSmart(value, getter, setter), StreamCodecs.DECIMAL) return add(ListenableDelegate.maskSmart(value, getter, setter), StreamCodecs.DECIMAL)
} }

View File

@ -14,8 +14,7 @@ import ru.dbotthepony.mc.otm.config.IFoodRegenerationValues
import ru.dbotthepony.mc.otm.config.PlayerConfig import ru.dbotthepony.mc.otm.config.PlayerConfig
import ru.dbotthepony.mc.otm.core.damageType import ru.dbotthepony.mc.otm.core.damageType
import ru.dbotthepony.mc.otm.core.math.Decimal import ru.dbotthepony.mc.otm.core.math.Decimal
import ru.dbotthepony.mc.otm.core.math.getDecimal import ru.dbotthepony.mc.otm.core.nbt.getDecimal
import ru.dbotthepony.mc.otm.core.math.set
import ru.dbotthepony.mc.otm.core.nbt.set import ru.dbotthepony.mc.otm.core.nbt.set
import ru.dbotthepony.mc.otm.registry.MDamageTypes import ru.dbotthepony.mc.otm.registry.MDamageTypes
import kotlin.math.max import kotlin.math.max

View File

@ -104,6 +104,7 @@ import ru.dbotthepony.mc.otm.menu.ExopackInventoryMenu
import ru.dbotthepony.mc.otm.menu.IItemStackSortingSettings import ru.dbotthepony.mc.otm.menu.IItemStackSortingSettings
import ru.dbotthepony.mc.otm.network.* import ru.dbotthepony.mc.otm.network.*
import ru.dbotthepony.mc.otm.network.SmokeParticlesPacket.Companion.makeSmoke import ru.dbotthepony.mc.otm.network.SmokeParticlesPacket.Companion.makeSmoke
import ru.dbotthepony.mc.otm.registry.MBuiltInRegistries
import ru.dbotthepony.mc.otm.registry.game.AndroidFeatures import ru.dbotthepony.mc.otm.registry.game.AndroidFeatures
import ru.dbotthepony.mc.otm.registry.MDamageTypes import ru.dbotthepony.mc.otm.registry.MDamageTypes
import ru.dbotthepony.mc.otm.registry.game.MItems import ru.dbotthepony.mc.otm.registry.game.MItems
@ -971,7 +972,7 @@ class MatteryPlayer(val ply: Player) {
research.clear() research.clear()
for (featureTag in tag.getCompoundList("features")) { for (featureTag in tag.getCompoundList("features")) {
val feature = MRegistry.ANDROID_FEATURES.get(ResourceLocation.parse(featureTag.getString("id"))) val feature = MBuiltInRegistries.ANDROID_FEATURE.get(ResourceLocation.parse(featureTag.getString("id")))
if (feature?.isApplicable(this) == true) { if (feature?.isApplicable(this) == true) {
val instance = feature.create(this) val instance = feature.create(this)

View File

@ -6,6 +6,7 @@ import net.minecraft.network.chat.MutableComponent
import net.minecraft.network.chat.contents.TranslatableContents import net.minecraft.network.chat.contents.TranslatableContents
import ru.dbotthepony.mc.otm.player.MatteryPlayer import ru.dbotthepony.mc.otm.player.MatteryPlayer
import ru.dbotthepony.mc.otm.core.getKeyNullable import ru.dbotthepony.mc.otm.core.getKeyNullable
import ru.dbotthepony.mc.otm.registry.MBuiltInRegistries
import ru.dbotthepony.mc.otm.registry.MRegistry import ru.dbotthepony.mc.otm.registry.MRegistry
open class AndroidFeatureType<T : AndroidFeature> { open class AndroidFeatureType<T : AndroidFeature> {
@ -26,7 +27,7 @@ open class AndroidFeatureType<T : AndroidFeature> {
open fun isApplicable(android: MatteryPlayer) = true open fun isApplicable(android: MatteryPlayer) = true
val registryName by lazy { val registryName by lazy {
MRegistry.ANDROID_FEATURES.getKeyNullable(this) MBuiltInRegistries.ANDROID_FEATURE.getKeyNullable(this)
} }
open val displayContents: ComponentContents by lazy { open val displayContents: ComponentContents by lazy {

View File

@ -13,11 +13,12 @@ import ru.dbotthepony.mc.otm.config.PlayerConfig
import ru.dbotthepony.mc.otm.core.TextComponent import ru.dbotthepony.mc.otm.core.TextComponent
import ru.dbotthepony.mc.otm.core.TranslatableComponent import ru.dbotthepony.mc.otm.core.TranslatableComponent
import ru.dbotthepony.mc.otm.core.util.formatPower import ru.dbotthepony.mc.otm.core.util.formatPower
import ru.dbotthepony.mc.otm.registry.MBuiltInRegistries
import ru.dbotthepony.mc.otm.registry.MDeferredRegister import ru.dbotthepony.mc.otm.registry.MDeferredRegister
import ru.dbotthepony.mc.otm.registry.RegistryDelegate import ru.dbotthepony.mc.otm.registry.MRegistries
object AndroidResearchDescriptions { object AndroidResearchDescriptions {
private val registrar = MDeferredRegister(AndroidResearchDescription.registryKey, OverdriveThatMatters.MOD_ID) private val registrar = MDeferredRegister(MRegistries.ANDROID_RESEARCH_DESCRIPTION, OverdriveThatMatters.MOD_ID)
init { init {
registrar.register("plain") { PlainAndroidResearchDescription } registrar.register("plain") { PlainAndroidResearchDescription }
@ -140,17 +141,8 @@ interface AndroidResearchDescription {
val type: Type<*> val type: Type<*>
companion object { companion object {
private val delegate = RegistryDelegate<Type<*>>("android_research_description") {}
val registry by delegate
val registryKey get() = delegate.key
val CODEC: Codec<AndroidResearchDescription> by lazy { val CODEC: Codec<AndroidResearchDescription> by lazy {
registry.byNameCodec().dispatch({ it.type }, { it.codec }) MBuiltInRegistries.ANDROID_RESEARCH_DESCRIPTION.byNameCodec().dispatch({ it.type }, { it.codec })
}
internal fun register(bus: IEventBus) {
bus.addListener(delegate::build)
} }
fun singleton(callback: (research: AndroidResearch) -> Component): Singleton { fun singleton(callback: (research: AndroidResearch) -> Component): Singleton {

View File

@ -7,13 +7,14 @@ import net.minecraft.resources.ResourceLocation
import net.neoforged.bus.api.IEventBus import net.neoforged.bus.api.IEventBus
import org.apache.logging.log4j.LogManager import org.apache.logging.log4j.LogManager
import ru.dbotthepony.mc.otm.OverdriveThatMatters import ru.dbotthepony.mc.otm.OverdriveThatMatters
import ru.dbotthepony.mc.otm.registry.MBuiltInRegistries
import ru.dbotthepony.mc.otm.registry.game.AndroidFeatures import ru.dbotthepony.mc.otm.registry.game.AndroidFeatures
import ru.dbotthepony.mc.otm.registry.MDeferredRegister import ru.dbotthepony.mc.otm.registry.MDeferredRegister
import ru.dbotthepony.mc.otm.registry.MRegistries
import ru.dbotthepony.mc.otm.registry.MRegistry import ru.dbotthepony.mc.otm.registry.MRegistry
import ru.dbotthepony.mc.otm.registry.RegistryDelegate
object AndroidResearchResults { object AndroidResearchResults {
private val registrar = MDeferredRegister(AndroidResearchResult.registryKey, OverdriveThatMatters.MOD_ID) private val registrar = MDeferredRegister(MRegistries.ANDROID_RESEARCH_RESULT, OverdriveThatMatters.MOD_ID)
init { init {
registrar.register("feature") { AndroidResearchResult.Feature } registrar.register("feature") { AndroidResearchResult.Feature }
@ -71,7 +72,7 @@ interface AndroidResearchResult {
* Adds specific android feature [id] to target, does nothing if target already has specified feature * Adds specific android feature [id] to target, does nothing if target already has specified feature
*/ */
class Feature(val id: ResourceLocation, val optional: Boolean = false) : AndroidResearchResult { class Feature(val id: ResourceLocation, val optional: Boolean = false) : AndroidResearchResult {
val feature = MRegistry.ANDROID_FEATURES.get(id) ?: if (optional) null else throw NoSuchElementException("Unknown android feature $id") val feature = MBuiltInRegistries.ANDROID_FEATURE.get(id) ?: if (optional) null else throw NoSuchElementException("Unknown android feature $id")
override val type: Type<*> override val type: Type<*>
get() = Companion get() = Companion
@ -101,7 +102,7 @@ interface AndroidResearchResult {
*/ */
class FeatureLevel(val id: ResourceLocation, val optional: Boolean = false, val levels: Int = 1) : class FeatureLevel(val id: ResourceLocation, val optional: Boolean = false, val levels: Int = 1) :
AndroidResearchResult { AndroidResearchResult {
val feature = MRegistry.ANDROID_FEATURES.get(id) ?: if (optional) null else throw NoSuchElementException("Unknown android feature $id") val feature = MBuiltInRegistries.ANDROID_FEATURE.get(id) ?: if (optional) null else throw NoSuchElementException("Unknown android feature $id")
override val type: Type<*> override val type: Type<*>
get() = Companion get() = Companion
@ -153,17 +154,9 @@ interface AndroidResearchResult {
companion object { companion object {
private val LOGGER = LogManager.getLogger() private val LOGGER = LogManager.getLogger()
private val delegate = RegistryDelegate<Type<*>>("android_research_result") {}
val registry by delegate
val registryKey get() = delegate.key
val CODEC: Codec<AndroidResearchResult> by lazy { val CODEC: Codec<AndroidResearchResult> by lazy {
registry.byNameCodec().dispatch({ it.type }, { it.codec }) MBuiltInRegistries.ANDROID_RESEARCH_RESULT.byNameCodec().dispatch({ it.type }, { it.codec })
}
internal fun register(bus: IEventBus) {
bus.addListener(delegate::build)
} }
} }
} }

View File

@ -0,0 +1,57 @@
package ru.dbotthepony.mc.otm.registry
import net.minecraft.core.Registry
import net.minecraft.resources.ResourceKey
import net.neoforged.bus.api.IEventBus
import net.neoforged.neoforge.registries.NewRegistryEvent
import net.neoforged.neoforge.registries.RegistryBuilder
import ru.dbotthepony.mc.otm.OverdriveThatMatters
import ru.dbotthepony.mc.otm.core.ResourceLocation
import kotlin.reflect.KProperty
object MBuiltInRegistries {
private val delegates = ArrayList<Delegate<*>>()
private class Delegate<T : Any>(private val key: ResourceKey<Registry<T>>, private val configurator: RegistryBuilder<T>.() -> Unit = {}) {
init {
delegates.add(this)
}
private var _value: Registry<T>? = null
operator fun getValue(thisRef: Any, property: KProperty<*>): Registry<T> {
return _value ?: throw IllegalStateException("Tried to access uninitialized registry ${key.location()}")
}
fun build(event: NewRegistryEvent) {
if (_value != null) {
throw IllegalStateException("Already created registry ${key.location()}!")
}
_value = RegistryBuilder(key).let {
configurator.invoke(it)
event.create(it)
}
}
}
val DECIMAL_PROVIDER_TYPE by Delegate(MRegistries.DECIMAL_PROVIDER_TYPE) {
defaultKey(ResourceLocation(OverdriveThatMatters.MOD_ID, "zero"))
}
val MATTER_REGISTRY_ACTION by Delegate(MRegistries.MATTER_REGISTRY_ACTION)
val MATTER_FUNCTION by Delegate(MRegistries.MATTER_FUNCTION) {
defaultKey(ResourceLocation(OverdriveThatMatters.MOD_ID, "noop"))
}
val RECIPE_FINDER by Delegate(MRegistries.RECIPE_FINDER)
val ANDROID_RESEARCH_DESCRIPTION by Delegate(MRegistries.ANDROID_RESEARCH_DESCRIPTION)
val ANDROID_RESEARCH_RESULT by Delegate(MRegistries.ANDROID_RESEARCH_RESULT)
val ANDROID_FEATURE by Delegate(MRegistries.ANDROID_FEATURE) { sync(true) }
val STACK_TYPE by Delegate(MRegistries.STACK_TYPE)
internal fun register(bus: IEventBus) {
delegates.forEach { bus.addListener(it::build) }
}
}

View File

@ -0,0 +1,29 @@
package ru.dbotthepony.mc.otm.registry
import net.minecraft.core.Registry
import net.minecraft.resources.ResourceKey
import ru.dbotthepony.mc.otm.OverdriveThatMatters
import ru.dbotthepony.mc.otm.core.ResourceLocation
import ru.dbotthepony.mc.otm.data.world.DecimalProvider
import ru.dbotthepony.mc.otm.matter.AbstractRegistryAction
import ru.dbotthepony.mc.otm.matter.IMatterFunction
import ru.dbotthepony.mc.otm.matter.MatterManager
import ru.dbotthepony.mc.otm.player.android.AndroidFeatureType
import ru.dbotthepony.mc.otm.player.android.AndroidResearchDescription
import ru.dbotthepony.mc.otm.player.android.AndroidResearchResult
import ru.dbotthepony.mc.otm.storage.StorageStack
object MRegistries {
private fun <T> k(name: String): ResourceKey<Registry<T>> {
return ResourceKey.createRegistryKey(ResourceLocation(OverdriveThatMatters.MOD_ID, name))
}
val DECIMAL_PROVIDER_TYPE = k<DecimalProvider.Type<*>>("decimal_provider_type")
val MATTER_REGISTRY_ACTION = k<AbstractRegistryAction.Type<*>>("matter_registry_action")
val MATTER_FUNCTION = k<IMatterFunction>("matter_function")
val RECIPE_FINDER = k<MatterManager.Finder>("recipe_finder")
val ANDROID_RESEARCH_DESCRIPTION = k<AndroidResearchDescription.Type<*>>("android_research_description")
val ANDROID_RESEARCH_RESULT = k<AndroidResearchResult.Type<*>>("android_research_result")
val ANDROID_FEATURE = k<AndroidFeatureType<*>>("android_feature")
val STACK_TYPE = k<StorageStack.Type<*>>("stack_type")
}

View File

@ -53,11 +53,6 @@ import ru.dbotthepony.mc.otm.registry.objects.IBlockItemRegistryAcceptor
import ru.dbotthepony.mc.otm.registry.objects.StripedColoredDecorativeBlock import ru.dbotthepony.mc.otm.registry.objects.StripedColoredDecorativeBlock
object MRegistry : IBlockItemRegistryAcceptor { object MRegistry : IBlockItemRegistryAcceptor {
private val features = RegistryDelegate<AndroidFeatureType<*>>("android_features") { sync(true) }
val ANDROID_FEATURES by features
val ANDROID_FEATURES_LOCATION get() = features.location
val ANDROID_FEATURES_KEY get() = features.key
val DYE_ORDER: ImmutableList<DyeColor> = ImmutableList.of( val DYE_ORDER: ImmutableList<DyeColor> = ImmutableList.of(
DyeColor.BLACK, DyeColor.BLACK,
DyeColor.BLUE, DyeColor.BLUE,
@ -251,7 +246,6 @@ object MRegistry : IBlockItemRegistryAcceptor {
} }
internal fun initialize(bus: IEventBus) { internal fun initialize(bus: IEventBus) {
bus.addListener(features::build)
bus.addListener(this::initializeClient) bus.addListener(this::initializeClient)
bus.addListener(this::initializeCommon) bus.addListener(this::initializeCommon)
bus.addListener(MStats::registerVanilla) bus.addListener(MStats::registerVanilla)

View File

@ -1,45 +0,0 @@
package ru.dbotthepony.mc.otm.registry
import net.minecraft.core.Registry
import net.minecraft.resources.ResourceKey
import net.neoforged.neoforge.registries.NewRegistryEvent
import net.neoforged.neoforge.registries.RegistryBuilder
import ru.dbotthepony.mc.otm.OverdriveThatMatters
import ru.dbotthepony.mc.otm.core.ResourceLocation
import java.util.function.Supplier
import kotlin.properties.ReadOnlyProperty
import kotlin.reflect.KProperty
class RegistryDelegate<T>(key: String, private val configurator: RegistryBuilder<T>.() -> Unit = {}) : ReadOnlyProperty<Any, Registry<T>>, Supplier<Registry<T>>, Lazy<Registry<T>> {
private var _value: Registry<T>? = null
override val value: Registry<T>
get() = get()
override fun isInitialized(): Boolean {
return _value != null
}
val location = ResourceLocation(OverdriveThatMatters.MOD_ID, key)
val key: ResourceKey<Registry<T>> = ResourceKey.createRegistryKey(location)
override fun get(): Registry<T> {
val value = _value ?: throw IllegalStateException("Tried to access uninitialized registry $location")
return value
}
override fun getValue(thisRef: Any, property: KProperty<*>): Registry<T> {
return get()
}
fun build(event: NewRegistryEvent) {
if (_value != null) {
throw IllegalStateException("Already built registry $location!")
}
_value = RegistryBuilder(key).let {
configurator.invoke(it)
event.create(it)
}
}
}

View File

@ -18,10 +18,11 @@ import ru.dbotthepony.mc.otm.player.android.feature.StepAssistFeature
import ru.dbotthepony.mc.otm.player.android.feature.SwimBoostersFeature import ru.dbotthepony.mc.otm.player.android.feature.SwimBoostersFeature
import ru.dbotthepony.mc.otm.registry.MDeferredRegister import ru.dbotthepony.mc.otm.registry.MDeferredRegister
import ru.dbotthepony.mc.otm.registry.MNames import ru.dbotthepony.mc.otm.registry.MNames
import ru.dbotthepony.mc.otm.registry.MRegistries
import ru.dbotthepony.mc.otm.registry.MRegistry import ru.dbotthepony.mc.otm.registry.MRegistry
object AndroidFeatures { object AndroidFeatures {
private val registry = MDeferredRegister(MRegistry.ANDROID_FEATURES_KEY) private val registry = MDeferredRegister(MRegistries.ANDROID_FEATURE)
val AIR_BAGS by registry.register(MNames.AIR_BAGS) { AndroidFeatureType(::DummyAndroidFeature) } val AIR_BAGS by registry.register(MNames.AIR_BAGS) { AndroidFeatureType(::DummyAndroidFeature) }
val STEP_ASSIST by registry.register(MNames.STEP_ASSIST) { AndroidFeatureType(::StepAssistFeature) } val STEP_ASSIST by registry.register(MNames.STEP_ASSIST) { AndroidFeatureType(::StepAssistFeature) }

View File

@ -5,14 +5,13 @@ import net.minecraft.network.RegistryFriendlyByteBuf
import net.minecraft.world.item.ItemStack import net.minecraft.world.item.ItemStack
import net.neoforged.bus.api.IEventBus import net.neoforged.bus.api.IEventBus
import ru.dbotthepony.mc.otm.OverdriveThatMatters import ru.dbotthepony.mc.otm.OverdriveThatMatters
import ru.dbotthepony.mc.otm.core.getValue
import ru.dbotthepony.mc.otm.core.math.Decimal import ru.dbotthepony.mc.otm.core.math.Decimal
import ru.dbotthepony.mc.otm.core.readBigInteger import ru.dbotthepony.mc.otm.core.readBigInteger
import ru.dbotthepony.mc.otm.core.readItem import ru.dbotthepony.mc.otm.core.readItem
import ru.dbotthepony.mc.otm.core.writeBigInteger import ru.dbotthepony.mc.otm.core.writeBigInteger
import ru.dbotthepony.mc.otm.core.writeItem import ru.dbotthepony.mc.otm.core.writeItem
import ru.dbotthepony.mc.otm.registry.MDeferredRegister import ru.dbotthepony.mc.otm.registry.MDeferredRegister
import ru.dbotthepony.mc.otm.registry.RegistryDelegate import ru.dbotthepony.mc.otm.registry.MRegistries
import java.math.BigInteger import java.math.BigInteger
abstract class StorageStack<S : StorageStack<S>>(val count: BigInteger) { abstract class StorageStack<S : StorageStack<S>>(val count: BigInteger) {
@ -110,11 +109,7 @@ abstract class StorageStack<S : StorageStack<S>>(val count: BigInteger) {
return o?.hashCodeWithoutCount() ?: 0 return o?.hashCodeWithoutCount() ?: 0
} }
private val delegate = RegistryDelegate<Type<*>>("stack_type") {} private val registrar = MDeferredRegister(MRegistries.STACK_TYPE, OverdriveThatMatters.MOD_ID)
val REGISTRY by delegate
val REGISTRY_KEY by delegate::key
private val registrar = MDeferredRegister(REGISTRY_KEY, OverdriveThatMatters.MOD_ID)
val ITEMS: Type<ItemStorageStack> by registrar.register("items") { val ITEMS: Type<ItemStorageStack> by registrar.register("items") {
SimpleType( SimpleType(
@ -131,7 +126,6 @@ abstract class StorageStack<S : StorageStack<S>>(val count: BigInteger) {
} }
internal fun register(bus: IEventBus) { internal fun register(bus: IEventBus) {
bus.addListener(delegate::build)
registrar.register(bus) registrar.register(bus)
} }
} }

View File

@ -15,6 +15,7 @@ import ru.dbotthepony.mc.otm.player.MatteryPlayer
import ru.dbotthepony.mc.otm.player.matteryPlayer import ru.dbotthepony.mc.otm.player.matteryPlayer
import ru.dbotthepony.mc.otm.core.ResourceLocation import ru.dbotthepony.mc.otm.core.ResourceLocation
import ru.dbotthepony.mc.otm.data.codec.SingletonCodec import ru.dbotthepony.mc.otm.data.codec.SingletonCodec
import ru.dbotthepony.mc.otm.registry.MBuiltInRegistries
import ru.dbotthepony.mc.otm.registry.MRegistry import ru.dbotthepony.mc.otm.registry.MRegistry
import java.util.Optional import java.util.Optional
import java.util.function.Predicate import java.util.function.Predicate
@ -76,7 +77,7 @@ object KillAsAndroidTrigger : MCriterionTrigger<KillAsAndroidTrigger.Instance>(R
} }
class Has(val name: ResourceLocation) : FeaturePredicate() { class Has(val name: ResourceLocation) : FeaturePredicate() {
private val resolved by lazy { MRegistry.ANDROID_FEATURES.get(name) } private val resolved by lazy { MBuiltInRegistries.ANDROID_FEATURE.get(name) }
override val type: PredicateType override val type: PredicateType
get() = PredicateType.HAS get() = PredicateType.HAS

View File

@ -1,6 +1,5 @@
package ru.dbotthepony.mc.otm.worldgen.feature package ru.dbotthepony.mc.otm.worldgen.feature
import com.mojang.serialization.Codec
import com.mojang.serialization.codecs.RecordCodecBuilder import com.mojang.serialization.codecs.RecordCodecBuilder
import net.minecraft.world.level.levelgen.feature.Feature import net.minecraft.world.level.levelgen.feature.Feature
import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext
@ -8,7 +7,7 @@ import net.minecraft.world.level.levelgen.feature.configurations.FeatureConfigur
import ru.dbotthepony.mc.otm.block.entity.blackhole.BlackHoleBlockEntity import ru.dbotthepony.mc.otm.block.entity.blackhole.BlackHoleBlockEntity
import ru.dbotthepony.mc.otm.config.ServerConfig import ru.dbotthepony.mc.otm.config.ServerConfig
import ru.dbotthepony.mc.otm.core.math.Decimal import ru.dbotthepony.mc.otm.core.math.Decimal
import ru.dbotthepony.mc.otm.core.math.nextDecimal import ru.dbotthepony.mc.otm.core.nextDecimal
import ru.dbotthepony.mc.otm.data.codec.DecimalCodec import ru.dbotthepony.mc.otm.data.codec.DecimalCodec
import ru.dbotthepony.mc.otm.registry.game.MBlocks import ru.dbotthepony.mc.otm.registry.game.MBlocks

View File

@ -18,7 +18,7 @@ function initializeCoreMod() {
if (insn.getOpcode() == Opcodes.BIPUSH) { if (insn.getOpcode() == Opcodes.BIPUSH) {
node.instructions.insert(insn, new MethodInsnNode( node.instructions.insert(insn, new MethodInsnNode(
Opcodes.INVOKESTATIC, Opcodes.INVOKESTATIC,
'ru/dbotthepony/mc/otm/android/feature/LimbOverclockingFeature', 'ru/dbotthepony/mc/otm/player/android/feature/LimbOverclockingFeature',
'getBrushCooldown', 'getBrushCooldown',
'(Lnet/minecraft/world/entity/LivingEntity;)I' '(Lnet/minecraft/world/entity/LivingEntity;)I'
)) ))
@ -31,7 +31,7 @@ function initializeCoreMod() {
if (insn.getOpcode() == Opcodes.ICONST_5) { if (insn.getOpcode() == Opcodes.ICONST_5) {
node.instructions.insert(insn, new MethodInsnNode( node.instructions.insert(insn, new MethodInsnNode(
Opcodes.INVOKESTATIC, Opcodes.INVOKESTATIC,
'ru/dbotthepony/mc/otm/android/feature/LimbOverclockingFeature', 'ru/dbotthepony/mc/otm/player/android/feature/LimbOverclockingFeature',
'getBrushTick', 'getBrushTick',
'(Lnet/minecraft/world/entity/LivingEntity;)I' '(Lnet/minecraft/world/entity/LivingEntity;)I'
)) ))
@ -59,7 +59,7 @@ function initializeCoreMod() {
if (insn.getOpcode() == Opcodes.LDC && insn.cst == 10) { if (insn.getOpcode() == Opcodes.LDC && insn.cst == 10) {
node.instructions.insert(insn, new MethodInsnNode( node.instructions.insert(insn, new MethodInsnNode(
Opcodes.INVOKESTATIC, Opcodes.INVOKESTATIC,
'ru/dbotthepony/mc/otm/android/feature/LimbOverclockingFeature', 'ru/dbotthepony/mc/otm/player/android/feature/LimbOverclockingFeature',
'getBrushableBlockCooldown', 'getBrushableBlockCooldown',
'(Lnet/minecraft/world/entity/player/Player;)J' '(Lnet/minecraft/world/entity/player/Player;)J'
)) ))