Unify experience storage in machines, Liquid XP
This commit is contained in:
parent
8fece2a517
commit
1e2c505fbd
@ -21,7 +21,8 @@ fun addMatterEntanglerRecipes(consumer: RecipeOutput) {
|
|||||||
),
|
),
|
||||||
Decimal(40),
|
Decimal(40),
|
||||||
400.0,
|
400.0,
|
||||||
ItemStack(MItems.QUANTUM_CAPACITOR, 2)
|
ItemStack(MItems.QUANTUM_CAPACITOR, 2),
|
||||||
|
experience = 15f
|
||||||
).energetic().toFinished(modLocation("quantum_capacitor"))
|
).energetic().toFinished(modLocation("quantum_capacitor"))
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -34,7 +35,8 @@ fun addMatterEntanglerRecipes(consumer: RecipeOutput) {
|
|||||||
),
|
),
|
||||||
Decimal(120),
|
Decimal(120),
|
||||||
600.0,
|
600.0,
|
||||||
ItemStack(MItems.QUANTUM_BATTERY, 2)
|
ItemStack(MItems.QUANTUM_BATTERY, 2),
|
||||||
|
experience = 20f
|
||||||
).energetic().toFinished(modLocation("quantum_battery"))
|
).energetic().toFinished(modLocation("quantum_battery"))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,6 @@ import net.minecraft.world.level.block.state.properties.Property
|
|||||||
import net.minecraft.world.level.material.MapColor
|
import net.minecraft.world.level.material.MapColor
|
||||||
import net.minecraft.world.phys.BlockHitResult
|
import net.minecraft.world.phys.BlockHitResult
|
||||||
import net.minecraft.world.phys.shapes.VoxelShape
|
import net.minecraft.world.phys.shapes.VoxelShape
|
||||||
import ru.dbotthepony.mc.otm.SERVER_IS_LIVE
|
|
||||||
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
|
||||||
@ -60,9 +59,20 @@ fun Block.getShapeForEachState(property: Property<*>, fn: (BlockState) -> VoxelS
|
|||||||
return getShapeForEachState(listOf(property), fn)
|
return getShapeForEachState(listOf(property), fn)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun interface INeighbourChangeListener {
|
||||||
|
fun neighborChanged(
|
||||||
|
state: BlockState,
|
||||||
|
level: Level,
|
||||||
|
pos: BlockPos,
|
||||||
|
neighbour: Block,
|
||||||
|
neighbourPos: BlockPos,
|
||||||
|
movedByPiston: Boolean
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
abstract class MatteryBlock @JvmOverloads constructor(
|
abstract class MatteryBlock @JvmOverloads constructor(
|
||||||
properties: Properties = DEFAULT_PROPERTIES
|
properties: Properties = DEFAULT_PROPERTIES
|
||||||
) : Block(properties) {
|
) : Block(properties), INeighbourChangeListener {
|
||||||
override fun setPlacedBy(
|
override fun setPlacedBy(
|
||||||
level: Level,
|
level: Level,
|
||||||
blockPos: BlockPos,
|
blockPos: BlockPos,
|
||||||
@ -168,7 +178,6 @@ abstract class MatteryBlock @JvmOverloads constructor(
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("OVERRIDE_DEPRECATION")
|
|
||||||
override fun neighborChanged(
|
override fun neighborChanged(
|
||||||
state: BlockState,
|
state: BlockState,
|
||||||
level: Level,
|
level: Level,
|
||||||
@ -188,8 +197,8 @@ abstract class MatteryBlock @JvmOverloads constructor(
|
|||||||
if (tile is IRedstoneControlled)
|
if (tile is IRedstoneControlled)
|
||||||
tile.redstoneControl.redstoneSignal = level.getBestNeighborSignal(pos)
|
tile.redstoneControl.redstoneSignal = level.getBestNeighborSignal(pos)
|
||||||
|
|
||||||
if (tile is MatteryBlockEntity && SERVER_IS_LIVE)
|
if (tile is MatteryBlockEntity)
|
||||||
tile.neighborChanged(neighbour, neighbourPos, movedByPiston)
|
tile.neighborChanged(state, level, pos, neighbour, neighbourPos, movedByPiston)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,154 @@
|
|||||||
|
package ru.dbotthepony.mc.otm.block.entity
|
||||||
|
|
||||||
|
import net.minecraft.core.BlockPos
|
||||||
|
import net.minecraft.core.Direction
|
||||||
|
import net.minecraft.nbt.DoubleTag
|
||||||
|
import net.minecraft.server.level.ServerLevel
|
||||||
|
import net.minecraft.server.level.ServerPlayer
|
||||||
|
import net.minecraft.world.entity.ExperienceOrb
|
||||||
|
import net.minecraft.world.level.Level
|
||||||
|
import net.minecraft.world.level.block.Block
|
||||||
|
import net.minecraft.world.level.block.entity.BlockEntity
|
||||||
|
import net.minecraft.world.level.block.state.BlockState
|
||||||
|
import net.minecraftforge.common.util.INBTSerializable
|
||||||
|
import net.minecraftforge.fluids.FluidStack
|
||||||
|
import net.minecraftforge.fluids.capability.IFluidHandler
|
||||||
|
import ru.dbotthepony.mc.otm.block.INeighbourChangeListener
|
||||||
|
import ru.dbotthepony.mc.otm.block.entity.tech.EssenceStorageBlockEntity
|
||||||
|
import ru.dbotthepony.mc.otm.core.math.plus
|
||||||
|
import ru.dbotthepony.mc.otm.registry.MFluids
|
||||||
|
import java.util.function.DoubleSupplier
|
||||||
|
|
||||||
|
class ExperienceStorage(val maxExperience: DoubleSupplier = DoubleSupplier { Double.POSITIVE_INFINITY }) : IFluidHandler, INBTSerializable<DoubleTag?>, INeighbourChangeListener {
|
||||||
|
constructor(max: Double) : this({ max })
|
||||||
|
|
||||||
|
var experience = 0.0
|
||||||
|
private set(value) {
|
||||||
|
require(value >= 0.0) { "Negative experience: $value" }
|
||||||
|
field = value
|
||||||
|
}
|
||||||
|
|
||||||
|
fun popExperience(player: ServerPlayer) {
|
||||||
|
val whole = experience.toInt()
|
||||||
|
|
||||||
|
if (whole > 0) {
|
||||||
|
experience -= whole
|
||||||
|
ExperienceOrb.award(player.level() as ServerLevel, player.position(), whole)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun storeExperience(experience: Double): Boolean {
|
||||||
|
check(experience >= 0.0) { "Invalid experience amount to store: $experience" }
|
||||||
|
val max = maxExperience.asDouble
|
||||||
|
val overflow = this.experience + experience > max
|
||||||
|
this.experience = if (overflow) max else this.experience + experience
|
||||||
|
return !overflow
|
||||||
|
}
|
||||||
|
|
||||||
|
fun storeExperience(experience: Float): Boolean {
|
||||||
|
return storeExperience(experience.toDouble())
|
||||||
|
}
|
||||||
|
|
||||||
|
fun storeExperience(experience: Double, pointOfReference: BlockEntity): Boolean {
|
||||||
|
check(experience >= 0.0) { "Invalid experience amount to store: $experience" }
|
||||||
|
this.experience += experience
|
||||||
|
|
||||||
|
for (dir in Direction.entries) {
|
||||||
|
val tile = pointOfReference.level?.getBlockEntity(pointOfReference.blockPos + dir)
|
||||||
|
|
||||||
|
if (tile is EssenceStorageBlockEntity) {
|
||||||
|
tile.experienceStored += this.experience.toLong()
|
||||||
|
this.experience %= 1.0
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val max = maxExperience.asDouble
|
||||||
|
val overflow = this.experience > max
|
||||||
|
if (overflow) this.experience = max
|
||||||
|
return !overflow
|
||||||
|
}
|
||||||
|
|
||||||
|
fun storeExperience(experience: Float, pointOfReference: BlockEntity): Boolean {
|
||||||
|
return storeExperience(experience.toDouble(), pointOfReference)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun tryTransferExperience(pointOfReference: BlockEntity) {
|
||||||
|
if (experience >= 1.0) {
|
||||||
|
for (dir in Direction.entries) {
|
||||||
|
val tile = pointOfReference.level?.getBlockEntity(pointOfReference.blockPos + dir)
|
||||||
|
|
||||||
|
if (tile is EssenceStorageBlockEntity) {
|
||||||
|
tile.experienceStored += experience.toLong()
|
||||||
|
experience %= 1.0
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun neighborChanged(state: BlockState, level: Level, pos: BlockPos, neighbour: Block, neighbourPos: BlockPos, movedByPiston: Boolean) {
|
||||||
|
if (experience >= 1.0) {
|
||||||
|
val tile = level.getBlockEntity(neighbourPos)
|
||||||
|
|
||||||
|
if (tile is EssenceStorageBlockEntity) {
|
||||||
|
tile.experienceStored += experience.toLong()
|
||||||
|
experience %= 1.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun serializeNBT(): DoubleTag {
|
||||||
|
return DoubleTag.valueOf(experience)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun deserializeNBT(nbt: DoubleTag?) {
|
||||||
|
experience = (nbt?.asDouble ?: 0.0).coerceAtLeast(0.0)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getTanks(): Int {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getFluidInTank(tank: Int): FluidStack {
|
||||||
|
if (tank != 0)
|
||||||
|
return FluidStack.EMPTY
|
||||||
|
|
||||||
|
return FluidStack(MFluids.LIQUID_XP, (experience * XP_TO_LIQUID_RATIO).toInt())
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getTankCapacity(tank: Int): Int {
|
||||||
|
return if (tank == 0) (maxExperience.asDouble * XP_TO_LIQUID_RATIO).toInt() else 0
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun isFluidValid(tank: Int, stack: FluidStack): Boolean {
|
||||||
|
return tank == 0 && stack.fluid.fluidType == MFluids.LIQUID_XP_TYPE
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun fill(resource: FluidStack, action: IFluidHandler.FluidAction): Int {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun drain(resource: FluidStack, action: IFluidHandler.FluidAction): FluidStack {
|
||||||
|
if (resource.fluid.fluidType != MFluids.LIQUID_XP_TYPE)
|
||||||
|
return FluidStack.EMPTY
|
||||||
|
|
||||||
|
return drain(resource.amount, action)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun drain(maxDrain: Int, action: IFluidHandler.FluidAction): FluidStack {
|
||||||
|
val actualDrain = maxDrain.coerceAtMost((experience * XP_TO_LIQUID_RATIO).toInt()).let { it / XP_TO_LIQUID_RATIO * XP_TO_LIQUID_RATIO }
|
||||||
|
|
||||||
|
if (actualDrain <= 0)
|
||||||
|
return FluidStack.EMPTY
|
||||||
|
|
||||||
|
if (action.execute())
|
||||||
|
experience -= actualDrain / XP_TO_LIQUID_RATIO
|
||||||
|
|
||||||
|
return FluidStack(MFluids.LIQUID_XP, actualDrain)
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val XP_TO_LIQUID_RATIO = 10
|
||||||
|
}
|
||||||
|
}
|
@ -12,7 +12,6 @@ import net.minecraft.core.Direction
|
|||||||
import net.minecraft.core.SectionPos
|
import net.minecraft.core.SectionPos
|
||||||
import net.minecraft.core.Vec3i
|
import net.minecraft.core.Vec3i
|
||||||
import net.minecraft.nbt.CompoundTag
|
import net.minecraft.nbt.CompoundTag
|
||||||
import net.minecraft.nbt.Tag
|
|
||||||
import net.minecraft.server.level.ServerLevel
|
import net.minecraft.server.level.ServerLevel
|
||||||
import net.minecraft.server.level.ServerPlayer
|
import net.minecraft.server.level.ServerPlayer
|
||||||
import net.minecraft.world.Container
|
import net.minecraft.world.Container
|
||||||
@ -28,7 +27,6 @@ import net.minecraft.world.level.chunk.LevelChunk
|
|||||||
import net.minecraft.world.phys.Vec3
|
import net.minecraft.world.phys.Vec3
|
||||||
import net.minecraftforge.common.capabilities.Capability
|
import net.minecraftforge.common.capabilities.Capability
|
||||||
import net.minecraftforge.common.capabilities.ForgeCapabilities
|
import net.minecraftforge.common.capabilities.ForgeCapabilities
|
||||||
import net.minecraftforge.common.util.INBTSerializable
|
|
||||||
import net.minecraftforge.common.util.LazyOptional
|
import net.minecraftforge.common.util.LazyOptional
|
||||||
import net.minecraftforge.energy.IEnergyStorage
|
import net.minecraftforge.energy.IEnergyStorage
|
||||||
import net.minecraftforge.event.TickEvent.LevelTickEvent
|
import net.minecraftforge.event.TickEvent.LevelTickEvent
|
||||||
@ -37,6 +35,7 @@ import net.minecraftforge.event.level.ChunkWatchEvent
|
|||||||
import net.minecraftforge.event.level.LevelEvent
|
import net.minecraftforge.event.level.LevelEvent
|
||||||
import net.minecraftforge.event.server.ServerStoppingEvent
|
import net.minecraftforge.event.server.ServerStoppingEvent
|
||||||
import ru.dbotthepony.mc.otm.SERVER_IS_LIVE
|
import ru.dbotthepony.mc.otm.SERVER_IS_LIVE
|
||||||
|
import ru.dbotthepony.mc.otm.block.INeighbourChangeListener
|
||||||
import ru.dbotthepony.mc.otm.block.RotatableMatteryBlock
|
import ru.dbotthepony.mc.otm.block.RotatableMatteryBlock
|
||||||
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
||||||
import ru.dbotthepony.mc.otm.capability.energy.IMatteryEnergyStorage
|
import ru.dbotthepony.mc.otm.capability.energy.IMatteryEnergyStorage
|
||||||
@ -65,12 +64,11 @@ import java.util.function.Supplier
|
|||||||
import java.util.stream.Stream
|
import java.util.stream.Stream
|
||||||
import kotlin.properties.ReadWriteProperty
|
import kotlin.properties.ReadWriteProperty
|
||||||
import kotlin.reflect.KProperty
|
import kotlin.reflect.KProperty
|
||||||
import kotlin.reflect.KProperty0
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Absolute barebone (lol) block entity class in Overdrive that Matters, providing bare minimum (lulmao, minecraft engine) functionality
|
* Absolute barebone (lol) block entity class in Overdrive that Matters, providing bare minimum (lulmao, minecraft engine) functionality
|
||||||
*/
|
*/
|
||||||
abstract class MatteryBlockEntity(p_155228_: BlockEntityType<*>, p_155229_: BlockPos, p_155230_: BlockState) : BlockEntity(p_155228_, p_155229_, p_155230_) {
|
abstract class MatteryBlockEntity(p_155228_: BlockEntityType<*>, p_155229_: BlockPos, p_155230_: BlockState) : BlockEntity(p_155228_, p_155229_, p_155230_), INeighbourChangeListener {
|
||||||
private var isSynchronizing = false
|
private var isSynchronizing = false
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -83,12 +81,21 @@ abstract class MatteryBlockEntity(p_155228_: BlockEntityType<*>, p_155229_: Bloc
|
|||||||
}
|
}
|
||||||
|
|
||||||
private val _droppableContainers = ObjectArraySet<Container>()
|
private val _droppableContainers = ObjectArraySet<Container>()
|
||||||
|
private val _neighbourChangeListeners = ObjectArraySet<INeighbourChangeListener>()
|
||||||
val droppableContainers: Set<Container> = Collections.unmodifiableSet(_droppableContainers)
|
val droppableContainers: Set<Container> = Collections.unmodifiableSet(_droppableContainers)
|
||||||
|
val neighbourChangeListeners: Set<INeighbourChangeListener> = Collections.unmodifiableSet(_neighbourChangeListeners)
|
||||||
|
|
||||||
protected fun addDroppableContainer(container: Container) {
|
protected fun addDroppableContainer(container: Container) {
|
||||||
_droppableContainers.add(container)
|
_droppableContainers.add(container)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected fun addNeighbourListener(listener: INeighbourChangeListener) {
|
||||||
|
if (listener === this)
|
||||||
|
throw IllegalArgumentException("are you drunk")
|
||||||
|
|
||||||
|
_neighbourChangeListeners.add(listener)
|
||||||
|
}
|
||||||
|
|
||||||
open fun beforeDroppingItems(oldBlockState: BlockState, level: Level, blockPos: BlockPos, newBlockState: BlockState, movedByPiston: Boolean) {}
|
open fun beforeDroppingItems(oldBlockState: BlockState, level: Level, blockPos: BlockPos, newBlockState: BlockState, movedByPiston: Boolean) {}
|
||||||
open fun beforeDestroyedByPlayer(level: Level, blockPos: BlockPos, blockState: BlockState, player: Player) {}
|
open fun beforeDestroyedByPlayer(level: Level, blockPos: BlockPos, blockState: BlockState, player: Player) {}
|
||||||
|
|
||||||
@ -441,7 +448,8 @@ abstract class MatteryBlockEntity(p_155228_: BlockEntityType<*>, p_155229_: Bloc
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun neighborChanged(neighbour: Block, neighbourPos: BlockPos, movedByPiston: Boolean) {
|
override fun neighborChanged(state: BlockState, level: Level, pos: BlockPos, neighbour: Block, neighbourPos: BlockPos, movedByPiston: Boolean) {
|
||||||
|
_neighbourChangeListeners.forEach { it.neighborChanged(state, level, pos, neighbour, neighbourPos, movedByPiston) }
|
||||||
val dir = vec2Dir[vecKey(neighbourPos - blockPos)] ?: return
|
val dir = vec2Dir[vecKey(neighbourPos - blockPos)] ?: return
|
||||||
_sides[blockRotation.dir2Side(dir)]!!.updateTracked()
|
_sides[blockRotation.dir2Side(dir)]!!.updateTracked()
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,8 @@ import net.minecraft.world.inventory.AbstractContainerMenu
|
|||||||
import net.minecraft.world.item.ItemStack
|
import net.minecraft.world.item.ItemStack
|
||||||
import net.minecraft.world.level.Level
|
import net.minecraft.world.level.Level
|
||||||
import net.minecraft.world.level.block.state.BlockState
|
import net.minecraft.world.level.block.state.BlockState
|
||||||
|
import net.minecraftforge.common.capabilities.ForgeCapabilities
|
||||||
|
import ru.dbotthepony.mc.otm.block.entity.ExperienceStorage
|
||||||
import ru.dbotthepony.mc.otm.block.entity.ItemJob
|
import ru.dbotthepony.mc.otm.block.entity.ItemJob
|
||||||
import ru.dbotthepony.mc.otm.block.entity.JobContainer
|
import ru.dbotthepony.mc.otm.block.entity.JobContainer
|
||||||
import ru.dbotthepony.mc.otm.block.entity.JobStatus
|
import ru.dbotthepony.mc.otm.block.entity.JobStatus
|
||||||
@ -35,7 +37,7 @@ import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
|||||||
import ru.dbotthepony.mc.otm.registry.MRecipes
|
import ru.dbotthepony.mc.otm.registry.MRecipes
|
||||||
|
|
||||||
class MatterEntanglerBlockEntity(blockPos: BlockPos, blockState: BlockState) : MatteryWorkerBlockEntity<MatterEntanglerBlockEntity.Job>(MBlockEntities.MATTER_ENTANGLER, blockPos, blockState, Job.CODEC) {
|
class MatterEntanglerBlockEntity(blockPos: BlockPos, blockState: BlockState) : MatteryWorkerBlockEntity<MatterEntanglerBlockEntity.Job>(MBlockEntities.MATTER_ENTANGLER, blockPos, blockState, Job.CODEC) {
|
||||||
class Job(itemStack: ItemStack, val matter: Decimal, ticks: Double) : ItemJob(itemStack, ticks, MachinesConfig.MATTER_ENTANGLER.energyConsumption) {
|
class Job(itemStack: ItemStack, val matter: Decimal, ticks: Double, experience: Float) : ItemJob(itemStack, ticks, MachinesConfig.MATTER_ENTANGLER.energyConsumption, experience = experience) {
|
||||||
val matterPerTick = matter / ticks
|
val matterPerTick = matter / ticks
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@ -44,6 +46,7 @@ class MatterEntanglerBlockEntity(blockPos: BlockPos, blockState: BlockState) : M
|
|||||||
ItemStack.CODEC.fieldOf("itemStack").forGetter(ItemJob::itemStack),
|
ItemStack.CODEC.fieldOf("itemStack").forGetter(ItemJob::itemStack),
|
||||||
DecimalCodec.minRange(Decimal.ZERO).fieldOf("matter").forGetter(Job::matter),
|
DecimalCodec.minRange(Decimal.ZERO).fieldOf("matter").forGetter(Job::matter),
|
||||||
Codec.DOUBLE.minRange(0.0).fieldOf("ticks").forGetter(ItemJob::ticks),
|
Codec.DOUBLE.minRange(0.0).fieldOf("ticks").forGetter(ItemJob::ticks),
|
||||||
|
Codec.FLOAT.minRange(0f).optionalFieldOf("experience", 0f).forGetter(Job::experience)
|
||||||
).apply(it, ::Job)
|
).apply(it, ::Job)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -54,6 +57,7 @@ class MatterEntanglerBlockEntity(blockPos: BlockPos, blockState: BlockState) : M
|
|||||||
val matter = ProfiledMatterStorage(MatterStorageImpl(::markDirtyFast, FlowDirection.INPUT, upgrades.matterCapacity(MachinesConfig.MATTER_ENTANGLER::matterCapacity)))
|
val matter = ProfiledMatterStorage(MatterStorageImpl(::markDirtyFast, FlowDirection.INPUT, upgrades.matterCapacity(MachinesConfig.MATTER_ENTANGLER::matterCapacity)))
|
||||||
val node = MatterNode()
|
val node = MatterNode()
|
||||||
|
|
||||||
|
val experience = ExperienceStorage(MachinesConfig.MATTER_ENTANGLER::maxExperienceStored).also(::addNeighbourListener)
|
||||||
val energyConfig = ConfigurableEnergy(energy)
|
val energyConfig = ConfigurableEnergy(energy)
|
||||||
|
|
||||||
val inputs = object : MatteryCraftingContainer(::itemContainerUpdated, 3, 3) {
|
val inputs = object : MatteryCraftingContainer(::itemContainerUpdated, 3, 3) {
|
||||||
@ -88,11 +92,14 @@ class MatterEntanglerBlockEntity(blockPos: BlockPos, blockState: BlockState) : M
|
|||||||
)
|
)
|
||||||
|
|
||||||
init {
|
init {
|
||||||
|
exposeGlobally(ForgeCapabilities.FLUID_HANDLER, experience)
|
||||||
|
|
||||||
savetables.stateful(::energy, ENERGY_KEY)
|
savetables.stateful(::energy, ENERGY_KEY)
|
||||||
savetables.stateful(::matter, MATTER_STORAGE_KEY)
|
savetables.stateful(::matter, MATTER_STORAGE_KEY)
|
||||||
savetables.stateful(::upgrades)
|
savetables.stateful(::upgrades)
|
||||||
savetables.stateful(::inputs)
|
savetables.stateful(::inputs)
|
||||||
savetables.stateful(::output)
|
savetables.stateful(::output)
|
||||||
|
savetables.stateful(::experience)
|
||||||
|
|
||||||
exposeGlobally(MatteryCapability.MATTER_NODE, node)
|
exposeGlobally(MatteryCapability.MATTER_NODE, node)
|
||||||
exposeGlobally(MatteryCapability.MATTER, matter)
|
exposeGlobally(MatteryCapability.MATTER, matter)
|
||||||
@ -128,6 +135,8 @@ class MatterEntanglerBlockEntity(blockPos: BlockPos, blockState: BlockState) : M
|
|||||||
override fun onJobFinish(status: JobStatus<Job>, id: Int) {
|
override fun onJobFinish(status: JobStatus<Job>, id: Int) {
|
||||||
if (!output.fullyAddItem(status.job.itemStack)) {
|
if (!output.fullyAddItem(status.job.itemStack)) {
|
||||||
status.noItem()
|
status.noItem()
|
||||||
|
} else {
|
||||||
|
experience.storeExperience(status.job.experience, this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -150,7 +159,8 @@ class MatterEntanglerBlockEntity(blockPos: BlockPos, blockState: BlockState) : M
|
|||||||
Job(
|
Job(
|
||||||
result,
|
result,
|
||||||
recipe.value.matter,
|
recipe.value.matter,
|
||||||
recipe.value.ticks * MachinesConfig.MATTER_ENTANGLER.workTimeMultiplier
|
recipe.value.ticks * MachinesConfig.MATTER_ENTANGLER.workTimeMultiplier,
|
||||||
|
recipe.value.experience
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,9 @@ import net.minecraft.world.inventory.AbstractContainerMenu
|
|||||||
import net.minecraft.world.item.ItemStack
|
import net.minecraft.world.item.ItemStack
|
||||||
import net.minecraft.world.item.enchantment.Enchantments
|
import net.minecraft.world.item.enchantment.Enchantments
|
||||||
import net.minecraft.world.level.block.state.BlockState
|
import net.minecraft.world.level.block.state.BlockState
|
||||||
|
import net.minecraftforge.fluids.FluidStack
|
||||||
|
import net.minecraftforge.fluids.capability.IFluidHandler
|
||||||
|
import ru.dbotthepony.mc.otm.block.entity.ExperienceStorage.Companion.XP_TO_LIQUID_RATIO
|
||||||
import ru.dbotthepony.mc.otm.block.entity.MatteryDeviceBlockEntity
|
import ru.dbotthepony.mc.otm.block.entity.MatteryDeviceBlockEntity
|
||||||
import ru.dbotthepony.mc.otm.capability.item.CombinedItemHandler
|
import ru.dbotthepony.mc.otm.capability.item.CombinedItemHandler
|
||||||
import ru.dbotthepony.mc.otm.container.HandlerFilter
|
import ru.dbotthepony.mc.otm.container.HandlerFilter
|
||||||
@ -14,8 +17,9 @@ import ru.dbotthepony.mc.otm.container.MatteryContainer
|
|||||||
import ru.dbotthepony.mc.otm.item.EssenceCapsuleItem
|
import ru.dbotthepony.mc.otm.item.EssenceCapsuleItem
|
||||||
import ru.dbotthepony.mc.otm.menu.tech.EssenceStorageMenu
|
import ru.dbotthepony.mc.otm.menu.tech.EssenceStorageMenu
|
||||||
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
||||||
|
import ru.dbotthepony.mc.otm.registry.MFluids
|
||||||
|
|
||||||
class EssenceStorageBlockEntity(blockPos: BlockPos, blockState: BlockState) : MatteryDeviceBlockEntity(MBlockEntities.ESSENCE_STORAGE, blockPos, blockState) {
|
class EssenceStorageBlockEntity(blockPos: BlockPos, blockState: BlockState) : MatteryDeviceBlockEntity(MBlockEntities.ESSENCE_STORAGE, blockPos, blockState), IFluidHandler {
|
||||||
var experienceStored = 0L
|
var experienceStored = 0L
|
||||||
set(value) {
|
set(value) {
|
||||||
require(value >= 0L) { "Negative experience: $value" }
|
require(value >= 0L) { "Negative experience: $value" }
|
||||||
@ -57,6 +61,62 @@ class EssenceStorageBlockEntity(blockPos: BlockPos, blockState: BlockState) : Ma
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
override fun getTanks(): Int {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getFluidInTank(tank: Int): FluidStack {
|
||||||
|
if (tank != 0)
|
||||||
|
return FluidStack.EMPTY
|
||||||
|
|
||||||
|
if (experienceStored >= 2_000_000_000L)
|
||||||
|
return FluidStack(MFluids.LIQUID_XP, 2_000_000_000)
|
||||||
|
|
||||||
|
return FluidStack(MFluids.LIQUID_XP, experienceStored.toInt())
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getTankCapacity(tank: Int): Int {
|
||||||
|
if (tank != 0) return 0
|
||||||
|
return Int.MAX_VALUE
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun isFluidValid(tank: Int, stack: FluidStack): Boolean {
|
||||||
|
return tank == 0 && stack.fluid.fluidType == MFluids.LIQUID_XP_TYPE
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun fill(resource: FluidStack, action: IFluidHandler.FluidAction): Int {
|
||||||
|
if (resource.fluid.fluidType != MFluids.LIQUID_XP_TYPE || resource.amount <= 0)
|
||||||
|
return 0
|
||||||
|
|
||||||
|
val actualFill = resource.amount / XP_TO_LIQUID_RATIO * XP_TO_LIQUID_RATIO
|
||||||
|
|
||||||
|
if (action.execute())
|
||||||
|
experienceStored += actualFill / XP_TO_LIQUID_RATIO
|
||||||
|
|
||||||
|
return actualFill
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun drain(resource: FluidStack, action: IFluidHandler.FluidAction): FluidStack {
|
||||||
|
if (resource.fluid.fluidType != MFluids.LIQUID_XP_TYPE)
|
||||||
|
return FluidStack.EMPTY
|
||||||
|
|
||||||
|
return drain(resource.amount, action)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun drain(maxDrain: Int, action: IFluidHandler.FluidAction): FluidStack {
|
||||||
|
val stored = experienceStored * XP_TO_LIQUID_RATIO
|
||||||
|
val actualStored = if (stored >= Int.MAX_VALUE) Int.MAX_VALUE else stored.toInt()
|
||||||
|
val actualDrain = maxDrain.coerceAtMost(actualStored).let { it / XP_TO_LIQUID_RATIO * XP_TO_LIQUID_RATIO }
|
||||||
|
|
||||||
|
if (actualDrain <= 0)
|
||||||
|
return FluidStack.EMPTY
|
||||||
|
|
||||||
|
if (action.execute())
|
||||||
|
experienceStored -= actualDrain / XP_TO_LIQUID_RATIO
|
||||||
|
|
||||||
|
return FluidStack(MFluids.LIQUID_XP, actualDrain)
|
||||||
|
}
|
||||||
|
|
||||||
override fun tick() {
|
override fun tick() {
|
||||||
super.tick()
|
super.tick()
|
||||||
|
|
||||||
|
@ -2,14 +2,12 @@ package ru.dbotthepony.mc.otm.block.entity.tech
|
|||||||
|
|
||||||
import it.unimi.dsi.fastutil.ints.IntArrayList
|
import it.unimi.dsi.fastutil.ints.IntArrayList
|
||||||
import net.minecraft.core.BlockPos
|
import net.minecraft.core.BlockPos
|
||||||
import net.minecraft.core.Direction
|
|
||||||
import net.minecraft.server.level.ServerLevel
|
|
||||||
import net.minecraft.server.level.ServerPlayer
|
|
||||||
import net.minecraft.world.entity.ExperienceOrb
|
|
||||||
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
|
||||||
import net.minecraft.world.inventory.AbstractContainerMenu
|
import net.minecraft.world.inventory.AbstractContainerMenu
|
||||||
import net.minecraft.world.level.block.state.BlockState
|
import net.minecraft.world.level.block.state.BlockState
|
||||||
|
import net.minecraftforge.common.capabilities.ForgeCapabilities
|
||||||
|
import ru.dbotthepony.mc.otm.block.entity.ExperienceStorage
|
||||||
import ru.dbotthepony.mc.otm.block.entity.JobContainer
|
import ru.dbotthepony.mc.otm.block.entity.JobContainer
|
||||||
import ru.dbotthepony.mc.otm.block.entity.JobStatus
|
import ru.dbotthepony.mc.otm.block.entity.JobStatus
|
||||||
import ru.dbotthepony.mc.otm.block.entity.ItemJob
|
import ru.dbotthepony.mc.otm.block.entity.ItemJob
|
||||||
@ -39,39 +37,7 @@ class PlatePressBlockEntity(
|
|||||||
val inputContainer = MatteryContainer(this::itemContainerUpdated, if (isTwin) 2 else 1).also(::addDroppableContainer)
|
val inputContainer = MatteryContainer(this::itemContainerUpdated, if (isTwin) 2 else 1).also(::addDroppableContainer)
|
||||||
val outputContainer = MatteryContainer(this::itemContainerUpdated, if (isTwin) 2 else 1).also(::addDroppableContainer)
|
val outputContainer = MatteryContainer(this::itemContainerUpdated, if (isTwin) 2 else 1).also(::addDroppableContainer)
|
||||||
|
|
||||||
var experience = 0.0
|
val experience = ExperienceStorage(MachinesConfig.PLATE_PRESS::maxExperienceStored).also(::addNeighbourListener)
|
||||||
private set
|
|
||||||
|
|
||||||
fun popExperience(player: ServerPlayer) {
|
|
||||||
val whole = experience.toInt()
|
|
||||||
|
|
||||||
if (whole > 0) {
|
|
||||||
experience -= whole
|
|
||||||
ExperienceOrb.award(player.level() as ServerLevel, player.position(), whole)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun tryStoreExperience(essenceStorage: EssenceStorageBlockEntity?) {
|
|
||||||
if (experience <= 0.0) return
|
|
||||||
|
|
||||||
if (essenceStorage != null) {
|
|
||||||
essenceStorage.experienceStored += experience.toLong()
|
|
||||||
experience = 0.0
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
for (dir in Direction.entries) {
|
|
||||||
val tile = level?.getBlockEntity(blockPos.relative(dir)) ?: continue
|
|
||||||
|
|
||||||
if (tile is EssenceStorageBlockEntity) {
|
|
||||||
tryStoreExperience(tile)
|
|
||||||
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val energyConfig = ConfigurableEnergy(energy)
|
val energyConfig = ConfigurableEnergy(energy)
|
||||||
val itemConfig = ConfigurableItemHandler(
|
val itemConfig = ConfigurableItemHandler(
|
||||||
input = inputContainer.handler(HandlerFilter.OnlyIn),
|
input = inputContainer.handler(HandlerFilter.OnlyIn),
|
||||||
@ -79,10 +45,12 @@ class PlatePressBlockEntity(
|
|||||||
)
|
)
|
||||||
|
|
||||||
init {
|
init {
|
||||||
|
exposeGlobally(ForgeCapabilities.FLUID_HANDLER, experience)
|
||||||
|
|
||||||
savetables.stateful(::energy, ENERGY_KEY)
|
savetables.stateful(::energy, ENERGY_KEY)
|
||||||
savetables.stateful(::inputContainer)
|
savetables.stateful(::inputContainer)
|
||||||
savetables.stateful(::outputContainer)
|
savetables.stateful(::outputContainer)
|
||||||
savetables.double(::experience)
|
savetables.stateful(::experience)
|
||||||
savetables.stateful(::upgrades)
|
savetables.stateful(::upgrades)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -100,8 +68,7 @@ class PlatePressBlockEntity(
|
|||||||
if (!outputContainer.fullyAddItem(status.job.itemStack, slots = IntArrayList.of(id)) && !outputContainer.fullyAddItem(status.job.itemStack))
|
if (!outputContainer.fullyAddItem(status.job.itemStack, slots = IntArrayList.of(id)) && !outputContainer.fullyAddItem(status.job.itemStack))
|
||||||
return status.noItem()
|
return status.noItem()
|
||||||
|
|
||||||
experience = (experience + status.experience).coerceAtMost(100.0)
|
experience.storeExperience(status.experience, this)
|
||||||
tryStoreExperience(null)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun computeNextJob(id: Int): JobContainer<ItemJob> {
|
override fun computeNextJob(id: Int): JobContainer<ItemJob> {
|
||||||
|
@ -12,6 +12,8 @@ import net.minecraft.world.item.crafting.AbstractCookingRecipe
|
|||||||
import net.minecraft.world.item.crafting.RecipeType
|
import net.minecraft.world.item.crafting.RecipeType
|
||||||
import net.minecraft.world.level.block.entity.BlockEntityType
|
import net.minecraft.world.level.block.entity.BlockEntityType
|
||||||
import net.minecraft.world.level.block.state.BlockState
|
import net.minecraft.world.level.block.state.BlockState
|
||||||
|
import net.minecraftforge.common.capabilities.ForgeCapabilities
|
||||||
|
import ru.dbotthepony.mc.otm.block.entity.ExperienceStorage
|
||||||
import ru.dbotthepony.mc.otm.block.entity.JobContainer
|
import ru.dbotthepony.mc.otm.block.entity.JobContainer
|
||||||
import ru.dbotthepony.mc.otm.block.entity.JobStatus
|
import ru.dbotthepony.mc.otm.block.entity.JobStatus
|
||||||
import ru.dbotthepony.mc.otm.block.entity.ItemJob
|
import ru.dbotthepony.mc.otm.block.entity.ItemJob
|
||||||
@ -53,6 +55,7 @@ class PoweredFurnaceBlockEntity(
|
|||||||
outputs.forEach { addDroppableContainer(it) }
|
outputs.forEach { addDroppableContainer(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val experience = ExperienceStorage(config::maxExperienceStored).also(::addNeighbourListener)
|
||||||
val energyConfig = ConfigurableEnergy(energy)
|
val energyConfig = ConfigurableEnergy(energy)
|
||||||
val itemConfig = ConfigurableItemHandler(
|
val itemConfig = ConfigurableItemHandler(
|
||||||
input = CombinedItemHandler(inputs.map { it.handler(HandlerFilter.OnlyIn) }),
|
input = CombinedItemHandler(inputs.map { it.handler(HandlerFilter.OnlyIn) }),
|
||||||
@ -60,44 +63,13 @@ class PoweredFurnaceBlockEntity(
|
|||||||
battery = batteryItemHandler
|
battery = batteryItemHandler
|
||||||
)
|
)
|
||||||
|
|
||||||
var experience = 0.0
|
|
||||||
private set
|
|
||||||
|
|
||||||
fun popExperience(player: ServerPlayer) {
|
|
||||||
val whole = experience.toInt()
|
|
||||||
|
|
||||||
if (whole > 0) {
|
|
||||||
experience -= whole
|
|
||||||
ExperienceOrb.award(player.level() as ServerLevel, player.position(), whole)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun tryStoreExperience(essenceStorage: EssenceStorageBlockEntity?) {
|
|
||||||
if (experience <= 0.0) return
|
|
||||||
|
|
||||||
if (essenceStorage != null) {
|
|
||||||
essenceStorage.experienceStored += experience.toLong()
|
|
||||||
experience = 0.0
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
for (dir in Direction.entries) {
|
|
||||||
val tile = level?.getBlockEntity(blockPos.relative(dir)) ?: continue
|
|
||||||
|
|
||||||
if (tile is EssenceStorageBlockEntity) {
|
|
||||||
tryStoreExperience(tile)
|
|
||||||
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
init {
|
init {
|
||||||
|
exposeGlobally(ForgeCapabilities.FLUID_HANDLER, experience)
|
||||||
|
|
||||||
savetables.stateful(::upgrades)
|
savetables.stateful(::upgrades)
|
||||||
savetables.stateful(::energy)
|
savetables.stateful(::energy)
|
||||||
|
|
||||||
savetables.double(::experience)
|
savetables.stateful(::experience)
|
||||||
|
|
||||||
savetables.stateful(inputs, "input")
|
savetables.stateful(inputs, "input")
|
||||||
savetables.stateful(outputs, "output")
|
savetables.stateful(outputs, "output")
|
||||||
@ -124,8 +96,7 @@ class PoweredFurnaceBlockEntity(
|
|||||||
|
|
||||||
override fun onJobFinish(status: JobStatus<ItemJob>, id: Int) {
|
override fun onJobFinish(status: JobStatus<ItemJob>, id: Int) {
|
||||||
if (outputs[id].fullyAddItem(status.job.itemStack)) {
|
if (outputs[id].fullyAddItem(status.job.itemStack)) {
|
||||||
experience += status.experience
|
experience.storeExperience(status.experience, this)
|
||||||
tryStoreExperience(null)
|
|
||||||
} else {
|
} else {
|
||||||
status.noItem()
|
status.noItem()
|
||||||
}
|
}
|
||||||
|
@ -66,24 +66,4 @@ class PlatePressBlock(properties: Properties = DEFAULT_PROPERTIES, val isTwin: B
|
|||||||
): VoxelShape {
|
): VoxelShape {
|
||||||
return shapes[state]!!
|
return shapes[state]!!
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("OVERRIDE_DEPRECATION")
|
|
||||||
override fun neighborChanged(
|
|
||||||
state: BlockState,
|
|
||||||
level: Level,
|
|
||||||
pos: BlockPos,
|
|
||||||
neighbour: Block,
|
|
||||||
neighbourPos: BlockPos,
|
|
||||||
movedByPiston: Boolean
|
|
||||||
) {
|
|
||||||
super.neighborChanged(state, level, pos, neighbour, neighbourPos, movedByPiston)
|
|
||||||
|
|
||||||
val tile = level.getBlockEntity(pos) ?: return
|
|
||||||
val neighbourTile = level.getBlockEntity(neighbourPos) ?: return
|
|
||||||
|
|
||||||
if (tile.isRemoved || neighbourTile.isRemoved) return
|
|
||||||
if (tile is PlatePressBlockEntity && neighbourTile is EssenceStorageBlockEntity) {
|
|
||||||
tile.tryStoreExperience(neighbourTile)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -61,24 +61,4 @@ class PoweredFurnaceBlock(
|
|||||||
|
|
||||||
return BlockEntityTicker { _, _, _, tile -> if (tile is PoweredFurnaceBlockEntity) tile.tick() }
|
return BlockEntityTicker { _, _, _, tile -> if (tile is PoweredFurnaceBlockEntity) tile.tick() }
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("OVERRIDE_DEPRECATION")
|
|
||||||
override fun neighborChanged(
|
|
||||||
state: BlockState,
|
|
||||||
level: Level,
|
|
||||||
pos: BlockPos,
|
|
||||||
neighbour: Block,
|
|
||||||
neighbourPos: BlockPos,
|
|
||||||
movedByPiston: Boolean
|
|
||||||
) {
|
|
||||||
super.neighborChanged(state, level, pos, neighbour, neighbourPos, movedByPiston)
|
|
||||||
|
|
||||||
val tile = level.getBlockEntity(pos) ?: return
|
|
||||||
val neighbourTile = level.getBlockEntity(neighbourPos) ?: return
|
|
||||||
|
|
||||||
if (tile.isRemoved || neighbourTile.isRemoved) return
|
|
||||||
if (tile is PoweredFurnaceBlockEntity && neighbourTile is EssenceStorageBlockEntity) {
|
|
||||||
tile.tryStoreExperience(neighbourTile)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -51,6 +51,7 @@ abstract class AbstractConfig(private val configName: String, private val type:
|
|||||||
workTimeMultiplier: Double? = 1.0,
|
workTimeMultiplier: Double? = 1.0,
|
||||||
energyConsumption: Decimal?,
|
energyConsumption: Decimal?,
|
||||||
matterCapacity: Decimal? = null,
|
matterCapacity: Decimal? = null,
|
||||||
|
maxExperience: Double? = null,
|
||||||
configurator: ForgeConfigSpec.Builder.() -> Unit = {}
|
configurator: ForgeConfigSpec.Builder.() -> Unit = {}
|
||||||
): WorkerBalanceValues {
|
): WorkerBalanceValues {
|
||||||
builder.push(name)
|
builder.push(name)
|
||||||
@ -61,6 +62,7 @@ abstract class AbstractConfig(private val configName: String, private val type:
|
|||||||
override val energyConsumption: Decimal by (if (energyConsumption == null) GetterSetter.box(Decimal.ZERO) else builder.defineDecimal("ENERGY_CONSUMPTION", energyConsumption, minimum = Decimal.ONE))
|
override val energyConsumption: Decimal by (if (energyConsumption == null) GetterSetter.box(Decimal.ZERO) else builder.defineDecimal("ENERGY_CONSUMPTION", energyConsumption, minimum = Decimal.ONE))
|
||||||
override val matterCapacity: Decimal by (if (matterCapacity == null) GetterSetter.box(Decimal.ZERO) else builder.defineDecimal("MATTER_CAPACITY", matterCapacity, minimum = Decimal.ONE))
|
override val matterCapacity: Decimal by (if (matterCapacity == null) GetterSetter.box(Decimal.ZERO) else builder.defineDecimal("MATTER_CAPACITY", matterCapacity, minimum = Decimal.ONE))
|
||||||
override val workTimeMultiplier: Double by (if (workTimeMultiplier == null) GetterSetter.box(1.0) else builder.defineInRange("WORK_TIME_MULTIPLIER", workTimeMultiplier, 0.0))
|
override val workTimeMultiplier: Double by (if (workTimeMultiplier == null) GetterSetter.box(1.0) else builder.defineInRange("WORK_TIME_MULTIPLIER", workTimeMultiplier, 0.0))
|
||||||
|
override val maxExperienceStored: Double by (if (maxExperience == null) GetterSetter.box(Double.POSITIVE_INFINITY) else builder.defineInRange("MAX_EXPERIENCE_STORED", maxExperience, 0.0))
|
||||||
}
|
}
|
||||||
|
|
||||||
configurator.invoke(builder)
|
configurator.invoke(builder)
|
||||||
|
@ -11,6 +11,7 @@ interface WorkerBalanceValues : EnergyBalanceValues {
|
|||||||
val workTimeMultiplier: Double
|
val workTimeMultiplier: Double
|
||||||
val energyConsumption: Decimal
|
val energyConsumption: Decimal
|
||||||
val matterCapacity: Decimal
|
val matterCapacity: Decimal
|
||||||
|
val maxExperienceStored: Double
|
||||||
}
|
}
|
||||||
|
|
||||||
interface VerboseEnergyBalanceValues {
|
interface VerboseEnergyBalanceValues {
|
||||||
|
@ -10,7 +10,8 @@ object MachinesConfig : AbstractConfig("machines") {
|
|||||||
MNames.PLATE_PRESS,
|
MNames.PLATE_PRESS,
|
||||||
energyStorage = Decimal(40_000),
|
energyStorage = Decimal(40_000),
|
||||||
energyThroughput = Decimal(200),
|
energyThroughput = Decimal(200),
|
||||||
energyConsumption = Decimal(15)
|
energyConsumption = Decimal(15),
|
||||||
|
maxExperience = 200.0,
|
||||||
)
|
)
|
||||||
|
|
||||||
val MATTER_ENTANGLER = workerValues(
|
val MATTER_ENTANGLER = workerValues(
|
||||||
@ -19,6 +20,7 @@ object MachinesConfig : AbstractConfig("machines") {
|
|||||||
energyThroughput = Decimal(400),
|
energyThroughput = Decimal(400),
|
||||||
energyConsumption = Decimal(120),
|
energyConsumption = Decimal(120),
|
||||||
matterCapacity = Decimal(60),
|
matterCapacity = Decimal(60),
|
||||||
|
maxExperience = 400.0,
|
||||||
)
|
)
|
||||||
|
|
||||||
val MATTER_DECOMPOSER = workerValues(
|
val MATTER_DECOMPOSER = workerValues(
|
||||||
@ -169,7 +171,8 @@ object MachinesConfig : AbstractConfig("machines") {
|
|||||||
energyStorage = Decimal(40_000),
|
energyStorage = Decimal(40_000),
|
||||||
energyThroughput = Decimal(200),
|
energyThroughput = Decimal(200),
|
||||||
energyConsumption = Decimal(20),
|
energyConsumption = Decimal(20),
|
||||||
workTimeMultiplier = 0.75
|
workTimeMultiplier = 0.75,
|
||||||
|
maxExperience = 200.0
|
||||||
)
|
)
|
||||||
|
|
||||||
val POWERED_BLAST_FURNACE = workerValues(
|
val POWERED_BLAST_FURNACE = workerValues(
|
||||||
@ -177,7 +180,8 @@ object MachinesConfig : AbstractConfig("machines") {
|
|||||||
energyStorage = Decimal(40_000),
|
energyStorage = Decimal(40_000),
|
||||||
energyThroughput = Decimal(200),
|
energyThroughput = Decimal(200),
|
||||||
energyConsumption = Decimal(20),
|
energyConsumption = Decimal(20),
|
||||||
workTimeMultiplier = 0.75
|
workTimeMultiplier = 0.75,
|
||||||
|
maxExperience = 200.0
|
||||||
)
|
)
|
||||||
|
|
||||||
val POWERED_SMOKER = workerValues(
|
val POWERED_SMOKER = workerValues(
|
||||||
@ -185,7 +189,8 @@ object MachinesConfig : AbstractConfig("machines") {
|
|||||||
energyStorage = Decimal(40_000),
|
energyStorage = Decimal(40_000),
|
||||||
energyThroughput = Decimal(200),
|
energyThroughput = Decimal(200),
|
||||||
energyConsumption = Decimal(10),
|
energyConsumption = Decimal(10),
|
||||||
workTimeMultiplier = 0.75
|
workTimeMultiplier = 0.75,
|
||||||
|
maxExperience = 200.0
|
||||||
)
|
)
|
||||||
|
|
||||||
object Upgrades {
|
object Upgrades {
|
||||||
|
@ -57,7 +57,7 @@ class MatterEntanglerMenu(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val outputs = makeSlots(tile?.output ?: SimpleContainer(1), ::OutputSlot)
|
val outputs = makeSlots(tile?.output ?: SimpleContainer(1)) { a, b -> OutputSlot(a, b) { tile?.experience?.popExperience(player as ServerPlayer) } }
|
||||||
val upgrades = makeUpgradeSlots(3, tile?.upgrades)
|
val upgrades = makeUpgradeSlots(3, tile?.upgrades)
|
||||||
|
|
||||||
private val entangling: Container = if (tile == null) object : SimpleContainer(2) {
|
private val entangling: Container = if (tile == null) object : SimpleContainer(2) {
|
||||||
|
@ -13,13 +13,13 @@ import ru.dbotthepony.mc.otm.menu.widget.ProfiledLevelGaugeWidget
|
|||||||
import ru.dbotthepony.mc.otm.menu.widget.ProgressGaugeWidget
|
import ru.dbotthepony.mc.otm.menu.widget.ProgressGaugeWidget
|
||||||
import ru.dbotthepony.mc.otm.registry.MMenus
|
import ru.dbotthepony.mc.otm.registry.MMenus
|
||||||
|
|
||||||
class PlatePressMenu @JvmOverloads constructor(
|
class PlatePressMenu(
|
||||||
containerID: Int,
|
containerID: Int,
|
||||||
inventory: Inventory,
|
inventory: Inventory,
|
||||||
tile: PlatePressBlockEntity? = null
|
tile: PlatePressBlockEntity? = null
|
||||||
) : MatteryPoweredMenu(MMenus.PLATE_PRESS, containerID, inventory, tile) {
|
) : MatteryPoweredMenu(MMenus.PLATE_PRESS, containerID, inventory, tile) {
|
||||||
val inputSlot = MatterySlot(tile?.inputContainer ?: SimpleContainer(1), 0)
|
val inputSlot = MatterySlot(tile?.inputContainer ?: SimpleContainer(1), 0)
|
||||||
val outputSlot = OutputSlot(tile?.outputContainer ?: SimpleContainer(1), 0) { tile?.popExperience(player as ServerPlayer) }
|
val outputSlot = OutputSlot(tile?.outputContainer ?: SimpleContainer(1), 0) { tile?.experience?.popExperience(player as ServerPlayer) }
|
||||||
|
|
||||||
val progressGauge = ProgressGaugeWidget(this, tile)
|
val progressGauge = ProgressGaugeWidget(this, tile)
|
||||||
val itemConfig = ItemConfigPlayerInput(this, tile?.itemConfig, allowPush = true)
|
val itemConfig = ItemConfigPlayerInput(this, tile?.itemConfig, allowPush = true)
|
||||||
|
@ -23,7 +23,7 @@ class PoweredFurnaceMenu(
|
|||||||
tile: PoweredFurnaceBlockEntity? = null
|
tile: PoweredFurnaceBlockEntity? = null
|
||||||
) : MatteryPoweredMenu(type, containerID, inventory, tile) {
|
) : MatteryPoweredMenu(type, containerID, inventory, tile) {
|
||||||
val inputSlots = makeSlots(tile?.inputs, 2, ::MatterySlot)
|
val inputSlots = makeSlots(tile?.inputs, 2, ::MatterySlot)
|
||||||
val outputSlots = makeSlots(tile?.outputs, 2) { c, s -> OutputSlot(c, s) { tile?.popExperience(player as ServerPlayer) } }
|
val outputSlots = makeSlots(tile?.outputs, 2) { c, s -> OutputSlot(c, s) { tile?.experience?.popExperience(player as ServerPlayer) } }
|
||||||
|
|
||||||
val progressGauge = immutableList(2) { ProgressGaugeWidget(this, tile?.jobEventLoops?.get(it)) }
|
val progressGauge = immutableList(2) { ProgressGaugeWidget(this, tile?.jobEventLoops?.get(it)) }
|
||||||
val itemConfig = ItemConfigPlayerInput(this, tile?.itemConfig, allowPush = true)
|
val itemConfig = ItemConfigPlayerInput(this, tile?.itemConfig, allowPush = true)
|
||||||
|
@ -15,13 +15,13 @@ import ru.dbotthepony.mc.otm.menu.widget.ProfiledLevelGaugeWidget
|
|||||||
import ru.dbotthepony.mc.otm.menu.widget.ProgressGaugeWidget
|
import ru.dbotthepony.mc.otm.menu.widget.ProgressGaugeWidget
|
||||||
import ru.dbotthepony.mc.otm.registry.MMenus
|
import ru.dbotthepony.mc.otm.registry.MMenus
|
||||||
|
|
||||||
class TwinPlatePressMenu @JvmOverloads constructor(
|
class TwinPlatePressMenu(
|
||||||
containerID: Int,
|
containerID: Int,
|
||||||
inventory: Inventory,
|
inventory: Inventory,
|
||||||
tile: PlatePressBlockEntity? = null
|
tile: PlatePressBlockEntity? = null
|
||||||
) : MatteryPoweredMenu(MMenus.TWIN_PLATE_PRESS, containerID, inventory, tile) {
|
) : MatteryPoweredMenu(MMenus.TWIN_PLATE_PRESS, containerID, inventory, tile) {
|
||||||
val inputSlots = makeSlots(tile?.inputContainer ?: SimpleContainer(2), ::MatterySlot)
|
val inputSlots = makeSlots(tile?.inputContainer ?: SimpleContainer(2), ::MatterySlot)
|
||||||
val outputSlots = makeSlots(tile?.outputContainer ?: SimpleContainer(2)) { a, b -> OutputSlot(a, b) { tile?.popExperience(player as ServerPlayer) } }
|
val outputSlots = makeSlots(tile?.outputContainer ?: SimpleContainer(2)) { a, b -> OutputSlot(a, b) { tile?.experience?.popExperience(player as ServerPlayer) } }
|
||||||
|
|
||||||
val progressGauge0 = ProgressGaugeWidget(this, tile?.jobEventLoops?.get(0))
|
val progressGauge0 = ProgressGaugeWidget(this, tile?.jobEventLoops?.get(0))
|
||||||
val progressGauge1 = ProgressGaugeWidget(this, tile?.jobEventLoops?.get(1))
|
val progressGauge1 = ProgressGaugeWidget(this, tile?.jobEventLoops?.get(1))
|
||||||
|
@ -36,6 +36,7 @@ interface IMatterEntanglerRecipe : IMatteryRecipe<CraftingContainer> {
|
|||||||
val ticks: Double
|
val ticks: Double
|
||||||
val ingredients: IIngredientMatrix
|
val ingredients: IIngredientMatrix
|
||||||
val result: ItemStack
|
val result: ItemStack
|
||||||
|
val experience: Float
|
||||||
|
|
||||||
fun preemptivelyMatches(container: CraftingContainer, level: Level): Boolean
|
fun preemptivelyMatches(container: CraftingContainer, level: Level): Boolean
|
||||||
}
|
}
|
||||||
@ -45,6 +46,7 @@ open class MatterEntanglerRecipe(
|
|||||||
override val matter: Decimal,
|
override val matter: Decimal,
|
||||||
override val ticks: Double,
|
override val ticks: Double,
|
||||||
override val result: ItemStack,
|
override val result: ItemStack,
|
||||||
|
override val experience: Float = 0f,
|
||||||
val uuidKey: String = "uuid",
|
val uuidKey: String = "uuid",
|
||||||
val fixedUuid: Optional<UUID> = Optional.empty()
|
val fixedUuid: Optional<UUID> = Optional.empty()
|
||||||
) : IMatterEntanglerRecipe {
|
) : IMatterEntanglerRecipe {
|
||||||
@ -147,6 +149,7 @@ open class MatterEntanglerRecipe(
|
|||||||
DecimalCodec.minRange(Decimal.ZERO).fieldOf("matter").forGetter(MatterEntanglerRecipe::matter),
|
DecimalCodec.minRange(Decimal.ZERO).fieldOf("matter").forGetter(MatterEntanglerRecipe::matter),
|
||||||
Codec.DOUBLE.minRange(0.0).fieldOf("ticks").forGetter(MatterEntanglerRecipe::ticks),
|
Codec.DOUBLE.minRange(0.0).fieldOf("ticks").forGetter(MatterEntanglerRecipe::ticks),
|
||||||
ItemStack.CODEC.fieldOf("result").forGetter(MatterEntanglerRecipe::result),
|
ItemStack.CODEC.fieldOf("result").forGetter(MatterEntanglerRecipe::result),
|
||||||
|
Codec.FLOAT.minRange(0f).optionalFieldOf("experience", 0f).forGetter(MatterEntanglerRecipe::experience),
|
||||||
Codec.STRING.optionalFieldOf("uuidKey", "uuid").forGetter(MatterEntanglerRecipe::uuidKey),
|
Codec.STRING.optionalFieldOf("uuidKey", "uuid").forGetter(MatterEntanglerRecipe::uuidKey),
|
||||||
UUIDUtil.STRING_CODEC.optionalFieldOf("fixedUuid").forGetter(MatterEntanglerRecipe::fixedUuid)
|
UUIDUtil.STRING_CODEC.optionalFieldOf("fixedUuid").forGetter(MatterEntanglerRecipe::fixedUuid)
|
||||||
).apply(it, ::MatterEntanglerRecipe)
|
).apply(it, ::MatterEntanglerRecipe)
|
||||||
|
@ -12,7 +12,17 @@ import net.minecraft.world.item.ItemStack
|
|||||||
import net.minecraft.world.item.TooltipFlag
|
import net.minecraft.world.item.TooltipFlag
|
||||||
import net.minecraft.world.item.crafting.RecipeType
|
import net.minecraft.world.item.crafting.RecipeType
|
||||||
import net.minecraft.world.level.BlockGetter
|
import net.minecraft.world.level.BlockGetter
|
||||||
import net.minecraft.world.level.block.*
|
import net.minecraft.world.level.block.AnvilBlock
|
||||||
|
import net.minecraft.world.level.block.Block
|
||||||
|
import net.minecraft.world.level.block.DoorBlock
|
||||||
|
import net.minecraft.world.level.block.DropExperienceBlock
|
||||||
|
import net.minecraft.world.level.block.IronBarsBlock
|
||||||
|
import net.minecraft.world.level.block.LiquidBlock
|
||||||
|
import net.minecraft.world.level.block.SlabBlock
|
||||||
|
import net.minecraft.world.level.block.SoundType
|
||||||
|
import net.minecraft.world.level.block.StairBlock
|
||||||
|
import net.minecraft.world.level.block.TrapDoorBlock
|
||||||
|
import net.minecraft.world.level.block.WallBlock
|
||||||
import net.minecraft.world.level.block.state.BlockBehaviour
|
import net.minecraft.world.level.block.state.BlockBehaviour
|
||||||
import net.minecraft.world.level.block.state.BlockState
|
import net.minecraft.world.level.block.state.BlockState
|
||||||
import net.minecraft.world.level.block.state.properties.BlockSetType
|
import net.minecraft.world.level.block.state.properties.BlockSetType
|
||||||
@ -23,32 +33,25 @@ import net.minecraftforge.eventbus.api.IEventBus
|
|||||||
import net.minecraftforge.registries.DeferredRegister
|
import net.minecraftforge.registries.DeferredRegister
|
||||||
import net.minecraftforge.registries.ForgeRegistries
|
import net.minecraftforge.registries.ForgeRegistries
|
||||||
import ru.dbotthepony.mc.otm.OverdriveThatMatters
|
import ru.dbotthepony.mc.otm.OverdriveThatMatters
|
||||||
import ru.dbotthepony.mc.otm.block.tech.AndroidStationBlock
|
|
||||||
import ru.dbotthepony.mc.otm.block.tech.BatteryBankBlock
|
|
||||||
import ru.dbotthepony.mc.otm.block.BlackHoleBlock
|
import ru.dbotthepony.mc.otm.block.BlackHoleBlock
|
||||||
import ru.dbotthepony.mc.otm.block.BlockExplosionDebugger
|
import ru.dbotthepony.mc.otm.block.BlockExplosionDebugger
|
||||||
import ru.dbotthepony.mc.otm.block.tech.BlockGravitationStabilizer
|
|
||||||
import ru.dbotthepony.mc.otm.block.tech.BlockGravitationStabilizerLens
|
|
||||||
import ru.dbotthepony.mc.otm.block.BlockSphereDebugger
|
import ru.dbotthepony.mc.otm.block.BlockSphereDebugger
|
||||||
import ru.dbotthepony.mc.otm.block.tech.ChemicalGeneratorBlock
|
|
||||||
import ru.dbotthepony.mc.otm.block.tech.EnergyCounterBlock
|
|
||||||
import ru.dbotthepony.mc.otm.block.tech.EnergyServoBlock
|
|
||||||
import ru.dbotthepony.mc.otm.block.decorative.LaboratoryLamp
|
|
||||||
import ru.dbotthepony.mc.otm.block.decorative.LaboratoryLampLight
|
|
||||||
import ru.dbotthepony.mc.otm.block.MatterCableBlock
|
import ru.dbotthepony.mc.otm.block.MatterCableBlock
|
||||||
import ru.dbotthepony.mc.otm.block.tech.PhantomAttractorBlock
|
|
||||||
import ru.dbotthepony.mc.otm.block.tech.PlatePressBlock
|
|
||||||
import ru.dbotthepony.mc.otm.block.StorageCableBlock
|
import ru.dbotthepony.mc.otm.block.StorageCableBlock
|
||||||
import ru.dbotthepony.mc.otm.block.decorative.DevChestBlock
|
import ru.dbotthepony.mc.otm.block.decorative.DevChestBlock
|
||||||
import ru.dbotthepony.mc.otm.block.decorative.EngineBlock
|
import ru.dbotthepony.mc.otm.block.decorative.EngineBlock
|
||||||
import ru.dbotthepony.mc.otm.block.decorative.FluidTankBlock
|
import ru.dbotthepony.mc.otm.block.decorative.FluidTankBlock
|
||||||
import ru.dbotthepony.mc.otm.block.decorative.HoloSignBlock
|
import ru.dbotthepony.mc.otm.block.decorative.HoloSignBlock
|
||||||
import ru.dbotthepony.mc.otm.block.decorative.InfiniteWaterSourceBlock
|
import ru.dbotthepony.mc.otm.block.decorative.InfiniteWaterSourceBlock
|
||||||
import ru.dbotthepony.mc.otm.block.matter.MatterReconstructorBlock
|
import ru.dbotthepony.mc.otm.block.decorative.LaboratoryLamp
|
||||||
|
import ru.dbotthepony.mc.otm.block.decorative.LaboratoryLampLight
|
||||||
|
import ru.dbotthepony.mc.otm.block.decorative.PainterBlock
|
||||||
import ru.dbotthepony.mc.otm.block.matter.MatterBottlerBlock
|
import ru.dbotthepony.mc.otm.block.matter.MatterBottlerBlock
|
||||||
import ru.dbotthepony.mc.otm.block.matter.MatterCapacitorBankBlock
|
import ru.dbotthepony.mc.otm.block.matter.MatterCapacitorBankBlock
|
||||||
import ru.dbotthepony.mc.otm.block.matter.MatterDecomposerBlock
|
import ru.dbotthepony.mc.otm.block.matter.MatterDecomposerBlock
|
||||||
|
import ru.dbotthepony.mc.otm.block.matter.MatterEntanglerBlock
|
||||||
import ru.dbotthepony.mc.otm.block.matter.MatterPanelBlock
|
import ru.dbotthepony.mc.otm.block.matter.MatterPanelBlock
|
||||||
|
import ru.dbotthepony.mc.otm.block.matter.MatterReconstructorBlock
|
||||||
import ru.dbotthepony.mc.otm.block.matter.MatterRecyclerBlock
|
import ru.dbotthepony.mc.otm.block.matter.MatterRecyclerBlock
|
||||||
import ru.dbotthepony.mc.otm.block.matter.MatterReplicatorBlock
|
import ru.dbotthepony.mc.otm.block.matter.MatterReplicatorBlock
|
||||||
import ru.dbotthepony.mc.otm.block.matter.MatterScannerBlock
|
import ru.dbotthepony.mc.otm.block.matter.MatterScannerBlock
|
||||||
@ -61,10 +64,17 @@ import ru.dbotthepony.mc.otm.block.storage.StorageExporterBlock
|
|||||||
import ru.dbotthepony.mc.otm.block.storage.StorageImporterBlock
|
import ru.dbotthepony.mc.otm.block.storage.StorageImporterBlock
|
||||||
import ru.dbotthepony.mc.otm.block.storage.StoragePowerSupplierBlock
|
import ru.dbotthepony.mc.otm.block.storage.StoragePowerSupplierBlock
|
||||||
import ru.dbotthepony.mc.otm.block.tech.AndroidChargerBlock
|
import ru.dbotthepony.mc.otm.block.tech.AndroidChargerBlock
|
||||||
|
import ru.dbotthepony.mc.otm.block.tech.AndroidStationBlock
|
||||||
|
import ru.dbotthepony.mc.otm.block.tech.BatteryBankBlock
|
||||||
|
import ru.dbotthepony.mc.otm.block.tech.BlockGravitationStabilizer
|
||||||
|
import ru.dbotthepony.mc.otm.block.tech.BlockGravitationStabilizerLens
|
||||||
|
import ru.dbotthepony.mc.otm.block.tech.ChemicalGeneratorBlock
|
||||||
import ru.dbotthepony.mc.otm.block.tech.CobblerBlock
|
import ru.dbotthepony.mc.otm.block.tech.CobblerBlock
|
||||||
|
import ru.dbotthepony.mc.otm.block.tech.EnergyCounterBlock
|
||||||
|
import ru.dbotthepony.mc.otm.block.tech.EnergyServoBlock
|
||||||
import ru.dbotthepony.mc.otm.block.tech.EssenceStorageBlock
|
import ru.dbotthepony.mc.otm.block.tech.EssenceStorageBlock
|
||||||
import ru.dbotthepony.mc.otm.block.decorative.PainterBlock
|
import ru.dbotthepony.mc.otm.block.tech.PhantomAttractorBlock
|
||||||
import ru.dbotthepony.mc.otm.block.matter.MatterEntanglerBlock
|
import ru.dbotthepony.mc.otm.block.tech.PlatePressBlock
|
||||||
import ru.dbotthepony.mc.otm.block.tech.PoweredFurnaceBlock
|
import ru.dbotthepony.mc.otm.block.tech.PoweredFurnaceBlock
|
||||||
import ru.dbotthepony.mc.otm.config.MachinesConfig
|
import ru.dbotthepony.mc.otm.config.MachinesConfig
|
||||||
import ru.dbotthepony.mc.otm.core.TranslatableComponent
|
import ru.dbotthepony.mc.otm.core.TranslatableComponent
|
||||||
@ -126,6 +136,8 @@ object MBlocks {
|
|||||||
val FLUID_TANK: FluidTankBlock by registry.register(MNames.FLUID_TANK) { FluidTankBlock() }
|
val FLUID_TANK: FluidTankBlock by registry.register(MNames.FLUID_TANK) { FluidTankBlock() }
|
||||||
val DEV_CHEST: DevChestBlock by registry.register(MNames.DEV_CHEST) { DevChestBlock() }
|
val DEV_CHEST: DevChestBlock by registry.register(MNames.DEV_CHEST) { DevChestBlock() }
|
||||||
|
|
||||||
|
val LIQUID_XP: LiquidBlock by registry.register("liquid_xp") { LiquidBlock(MFluids::LIQUID_XP, BlockBehaviour.Properties.of().mapColor(MapColor.EMERALD).replaceable().noCollission().strength(100.0f).pushReaction(PushReaction.DESTROY).noLootTable().liquid().sound(SoundType.EMPTY)) }
|
||||||
|
|
||||||
val TRITANIUM_ORE: Block by registry.register(MNames.TRITANIUM_ORE) { DropExperienceBlock(
|
val TRITANIUM_ORE: Block by registry.register(MNames.TRITANIUM_ORE) { DropExperienceBlock(
|
||||||
BlockBehaviour.Properties.of()
|
BlockBehaviour.Properties.of()
|
||||||
.mapColor(MapColor.STONE)
|
.mapColor(MapColor.STONE)
|
||||||
|
66
src/main/kotlin/ru/dbotthepony/mc/otm/registry/MFluids.kt
Normal file
66
src/main/kotlin/ru/dbotthepony/mc/otm/registry/MFluids.kt
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
package ru.dbotthepony.mc.otm.registry
|
||||||
|
|
||||||
|
import net.minecraft.resources.ResourceLocation
|
||||||
|
import net.minecraft.sounds.SoundEvents
|
||||||
|
import net.minecraft.world.item.Rarity
|
||||||
|
import net.minecraft.world.level.material.Fluid
|
||||||
|
import net.minecraftforge.client.extensions.common.IClientFluidTypeExtensions
|
||||||
|
import net.minecraftforge.common.SoundActions
|
||||||
|
import net.minecraftforge.eventbus.api.IEventBus
|
||||||
|
import net.minecraftforge.fluids.FluidType
|
||||||
|
import net.minecraftforge.fluids.ForgeFlowingFluid
|
||||||
|
import net.minecraftforge.registries.DeferredRegister
|
||||||
|
import net.minecraftforge.registries.ForgeRegistries
|
||||||
|
import ru.dbotthepony.mc.otm.OverdriveThatMatters
|
||||||
|
import java.util.function.Consumer
|
||||||
|
|
||||||
|
object MFluids {
|
||||||
|
private val types: DeferredRegister<FluidType> = DeferredRegister.create(ForgeRegistries.FLUID_TYPES, OverdriveThatMatters.MOD_ID)
|
||||||
|
private val fluids: DeferredRegister<Fluid> = DeferredRegister.create(ForgeRegistries.FLUIDS, OverdriveThatMatters.MOD_ID)
|
||||||
|
|
||||||
|
internal fun register(bus: IEventBus) {
|
||||||
|
types.register(bus)
|
||||||
|
fluids.register(bus)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun makeXpProps(): ForgeFlowingFluid.Properties {
|
||||||
|
return ForgeFlowingFluid.Properties(::LIQUID_XP_TYPE, ::LIQUID_XP, ::LIQUID_XP_FLOWING).bucket(MItems::LIQUID_XP_BUCKET).block(MBlocks::LIQUID_XP)
|
||||||
|
}
|
||||||
|
|
||||||
|
private val xpProps = makeXpProps()
|
||||||
|
|
||||||
|
val LIQUID_XP_TYPE: FluidType by types.register("liquid_xp") {
|
||||||
|
object : FluidType(
|
||||||
|
Properties.create()
|
||||||
|
.rarity(Rarity.UNCOMMON)
|
||||||
|
.canDrown(true)
|
||||||
|
.canExtinguish(false)
|
||||||
|
.canSwim(true)
|
||||||
|
.canHydrate(false)
|
||||||
|
.canPushEntity(true)
|
||||||
|
.canConvertToSource(false)
|
||||||
|
.fallDistanceModifier(0f)
|
||||||
|
.sound(SoundActions.BUCKET_FILL, SoundEvents.BUCKET_FILL)
|
||||||
|
.sound(SoundActions.BUCKET_EMPTY, SoundEvents.BUCKET_EMPTY)
|
||||||
|
.sound(SoundActions.FLUID_VAPORIZE, SoundEvents.FIRE_EXTINGUISH)
|
||||||
|
.descriptionId("block.overdrive_that_matters.liquid_xp")
|
||||||
|
) {
|
||||||
|
override fun initializeClient(consumer: Consumer<IClientFluidTypeExtensions>) {
|
||||||
|
val path = ResourceLocation(OverdriveThatMatters.MOD_ID, "block/ph_kitty")
|
||||||
|
|
||||||
|
consumer.accept(object : IClientFluidTypeExtensions {
|
||||||
|
override fun getStillTexture(): ResourceLocation {
|
||||||
|
return path
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getFlowingTexture(): ResourceLocation {
|
||||||
|
return path
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val LIQUID_XP: ForgeFlowingFluid.Source by fluids.register("liquid_xp") { ForgeFlowingFluid.Source(xpProps) }
|
||||||
|
val LIQUID_XP_FLOWING: ForgeFlowingFluid.Flowing by fluids.register("liquid_xp_flowing") { ForgeFlowingFluid.Flowing(xpProps) }
|
||||||
|
}
|
@ -290,6 +290,7 @@ object MItems {
|
|||||||
|
|
||||||
val FLUID_CAPSULE: FluidCapsuleItem by registry.register("fluid_capsule") { FluidCapsuleItem(ItemsConfig::FLUID_CAPSULE_CAPACITY) }
|
val FLUID_CAPSULE: FluidCapsuleItem by registry.register("fluid_capsule") { FluidCapsuleItem(ItemsConfig::FLUID_CAPSULE_CAPACITY) }
|
||||||
val FLUID_TANK: FluidTankItem by registry.register(MNames.FLUID_TANK) { FluidTankItem(MBlocks.FLUID_TANK, Item.Properties().stacksTo(1), ItemsConfig::FLUID_TANK_CAPACITY) }
|
val FLUID_TANK: FluidTankItem by registry.register(MNames.FLUID_TANK) { FluidTankItem(MBlocks.FLUID_TANK, Item.Properties().stacksTo(1), ItemsConfig::FLUID_TANK_CAPACITY) }
|
||||||
|
val LIQUID_XP_BUCKET: BucketItem by registry.register("liquid_xp_bucket") { BucketItem(MFluids::LIQUID_XP, Item.Properties().stacksTo(1).rarity(Rarity.UNCOMMON)) }
|
||||||
|
|
||||||
val TRITANIUM_COMPONENT: ForgeTier = ForgeTier(
|
val TRITANIUM_COMPONENT: ForgeTier = ForgeTier(
|
||||||
Tiers.IRON.level,
|
Tiers.IRON.level,
|
||||||
|
@ -275,6 +275,7 @@ object MRegistry {
|
|||||||
IMatterFunction.register(bus)
|
IMatterFunction.register(bus)
|
||||||
|
|
||||||
MBlocks.register(bus)
|
MBlocks.register(bus)
|
||||||
|
MFluids.register(bus)
|
||||||
MBlockEntities.register(bus)
|
MBlockEntities.register(bus)
|
||||||
MEntityTypes.register(bus)
|
MEntityTypes.register(bus)
|
||||||
MMenus.register(bus)
|
MMenus.register(bus)
|
||||||
|
Loading…
Reference in New Issue
Block a user