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),
|
||||
400.0,
|
||||
ItemStack(MItems.QUANTUM_CAPACITOR, 2)
|
||||
ItemStack(MItems.QUANTUM_CAPACITOR, 2),
|
||||
experience = 15f
|
||||
).energetic().toFinished(modLocation("quantum_capacitor"))
|
||||
)
|
||||
|
||||
@ -34,7 +35,8 @@ fun addMatterEntanglerRecipes(consumer: RecipeOutput) {
|
||||
),
|
||||
Decimal(120),
|
||||
600.0,
|
||||
ItemStack(MItems.QUANTUM_BATTERY, 2)
|
||||
ItemStack(MItems.QUANTUM_BATTERY, 2),
|
||||
experience = 20f
|
||||
).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.phys.BlockHitResult
|
||||
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.MatteryBlockEntity
|
||||
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)
|
||||
}
|
||||
|
||||
fun interface INeighbourChangeListener {
|
||||
fun neighborChanged(
|
||||
state: BlockState,
|
||||
level: Level,
|
||||
pos: BlockPos,
|
||||
neighbour: Block,
|
||||
neighbourPos: BlockPos,
|
||||
movedByPiston: Boolean
|
||||
)
|
||||
}
|
||||
|
||||
abstract class MatteryBlock @JvmOverloads constructor(
|
||||
properties: Properties = DEFAULT_PROPERTIES
|
||||
) : Block(properties) {
|
||||
) : Block(properties), INeighbourChangeListener {
|
||||
override fun setPlacedBy(
|
||||
level: Level,
|
||||
blockPos: BlockPos,
|
||||
@ -168,7 +178,6 @@ abstract class MatteryBlock @JvmOverloads constructor(
|
||||
return null
|
||||
}
|
||||
|
||||
@Suppress("OVERRIDE_DEPRECATION")
|
||||
override fun neighborChanged(
|
||||
state: BlockState,
|
||||
level: Level,
|
||||
@ -188,8 +197,8 @@ abstract class MatteryBlock @JvmOverloads constructor(
|
||||
if (tile is IRedstoneControlled)
|
||||
tile.redstoneControl.redstoneSignal = level.getBestNeighborSignal(pos)
|
||||
|
||||
if (tile is MatteryBlockEntity && SERVER_IS_LIVE)
|
||||
tile.neighborChanged(neighbour, neighbourPos, movedByPiston)
|
||||
if (tile is MatteryBlockEntity)
|
||||
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.Vec3i
|
||||
import net.minecraft.nbt.CompoundTag
|
||||
import net.minecraft.nbt.Tag
|
||||
import net.minecraft.server.level.ServerLevel
|
||||
import net.minecraft.server.level.ServerPlayer
|
||||
import net.minecraft.world.Container
|
||||
@ -28,7 +27,6 @@ import net.minecraft.world.level.chunk.LevelChunk
|
||||
import net.minecraft.world.phys.Vec3
|
||||
import net.minecraftforge.common.capabilities.Capability
|
||||
import net.minecraftforge.common.capabilities.ForgeCapabilities
|
||||
import net.minecraftforge.common.util.INBTSerializable
|
||||
import net.minecraftforge.common.util.LazyOptional
|
||||
import net.minecraftforge.energy.IEnergyStorage
|
||||
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.server.ServerStoppingEvent
|
||||
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.capability.MatteryCapability
|
||||
import ru.dbotthepony.mc.otm.capability.energy.IMatteryEnergyStorage
|
||||
@ -65,12 +64,11 @@ import java.util.function.Supplier
|
||||
import java.util.stream.Stream
|
||||
import kotlin.properties.ReadWriteProperty
|
||||
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
|
||||
*/
|
||||
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
|
||||
|
||||
/**
|
||||
@ -83,12 +81,21 @@ abstract class MatteryBlockEntity(p_155228_: BlockEntityType<*>, p_155229_: Bloc
|
||||
}
|
||||
|
||||
private val _droppableContainers = ObjectArraySet<Container>()
|
||||
private val _neighbourChangeListeners = ObjectArraySet<INeighbourChangeListener>()
|
||||
val droppableContainers: Set<Container> = Collections.unmodifiableSet(_droppableContainers)
|
||||
val neighbourChangeListeners: Set<INeighbourChangeListener> = Collections.unmodifiableSet(_neighbourChangeListeners)
|
||||
|
||||
protected fun addDroppableContainer(container: 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 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
|
||||
_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.level.Level
|
||||
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.JobContainer
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
companion object {
|
||||
@ -44,6 +46,7 @@ class MatterEntanglerBlockEntity(blockPos: BlockPos, blockState: BlockState) : M
|
||||
ItemStack.CODEC.fieldOf("itemStack").forGetter(ItemJob::itemStack),
|
||||
DecimalCodec.minRange(Decimal.ZERO).fieldOf("matter").forGetter(Job::matter),
|
||||
Codec.DOUBLE.minRange(0.0).fieldOf("ticks").forGetter(ItemJob::ticks),
|
||||
Codec.FLOAT.minRange(0f).optionalFieldOf("experience", 0f).forGetter(Job::experience)
|
||||
).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 node = MatterNode()
|
||||
|
||||
val experience = ExperienceStorage(MachinesConfig.MATTER_ENTANGLER::maxExperienceStored).also(::addNeighbourListener)
|
||||
val energyConfig = ConfigurableEnergy(energy)
|
||||
|
||||
val inputs = object : MatteryCraftingContainer(::itemContainerUpdated, 3, 3) {
|
||||
@ -88,11 +92,14 @@ class MatterEntanglerBlockEntity(blockPos: BlockPos, blockState: BlockState) : M
|
||||
)
|
||||
|
||||
init {
|
||||
exposeGlobally(ForgeCapabilities.FLUID_HANDLER, experience)
|
||||
|
||||
savetables.stateful(::energy, ENERGY_KEY)
|
||||
savetables.stateful(::matter, MATTER_STORAGE_KEY)
|
||||
savetables.stateful(::upgrades)
|
||||
savetables.stateful(::inputs)
|
||||
savetables.stateful(::output)
|
||||
savetables.stateful(::experience)
|
||||
|
||||
exposeGlobally(MatteryCapability.MATTER_NODE, node)
|
||||
exposeGlobally(MatteryCapability.MATTER, matter)
|
||||
@ -128,6 +135,8 @@ class MatterEntanglerBlockEntity(blockPos: BlockPos, blockState: BlockState) : M
|
||||
override fun onJobFinish(status: JobStatus<Job>, id: Int) {
|
||||
if (!output.fullyAddItem(status.job.itemStack)) {
|
||||
status.noItem()
|
||||
} else {
|
||||
experience.storeExperience(status.job.experience, this)
|
||||
}
|
||||
}
|
||||
|
||||
@ -150,7 +159,8 @@ class MatterEntanglerBlockEntity(blockPos: BlockPos, blockState: BlockState) : M
|
||||
Job(
|
||||
result,
|
||||
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.enchantment.Enchantments
|
||||
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.capability.item.CombinedItemHandler
|
||||
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.menu.tech.EssenceStorageMenu
|
||||
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
|
||||
set(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() {
|
||||
super.tick()
|
||||
|
||||
|
@ -2,14 +2,12 @@ package ru.dbotthepony.mc.otm.block.entity.tech
|
||||
|
||||
import it.unimi.dsi.fastutil.ints.IntArrayList
|
||||
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.Player
|
||||
import net.minecraft.world.inventory.AbstractContainerMenu
|
||||
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.JobStatus
|
||||
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 outputContainer = MatteryContainer(this::itemContainerUpdated, if (isTwin) 2 else 1).also(::addDroppableContainer)
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val experience = ExperienceStorage(MachinesConfig.PLATE_PRESS::maxExperienceStored).also(::addNeighbourListener)
|
||||
val energyConfig = ConfigurableEnergy(energy)
|
||||
val itemConfig = ConfigurableItemHandler(
|
||||
input = inputContainer.handler(HandlerFilter.OnlyIn),
|
||||
@ -79,10 +45,12 @@ class PlatePressBlockEntity(
|
||||
)
|
||||
|
||||
init {
|
||||
exposeGlobally(ForgeCapabilities.FLUID_HANDLER, experience)
|
||||
|
||||
savetables.stateful(::energy, ENERGY_KEY)
|
||||
savetables.stateful(::inputContainer)
|
||||
savetables.stateful(::outputContainer)
|
||||
savetables.double(::experience)
|
||||
savetables.stateful(::experience)
|
||||
savetables.stateful(::upgrades)
|
||||
}
|
||||
|
||||
@ -100,8 +68,7 @@ class PlatePressBlockEntity(
|
||||
if (!outputContainer.fullyAddItem(status.job.itemStack, slots = IntArrayList.of(id)) && !outputContainer.fullyAddItem(status.job.itemStack))
|
||||
return status.noItem()
|
||||
|
||||
experience = (experience + status.experience).coerceAtMost(100.0)
|
||||
tryStoreExperience(null)
|
||||
experience.storeExperience(status.experience, this)
|
||||
}
|
||||
|
||||
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.level.block.entity.BlockEntityType
|
||||
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.JobStatus
|
||||
import ru.dbotthepony.mc.otm.block.entity.ItemJob
|
||||
@ -53,6 +55,7 @@ class PoweredFurnaceBlockEntity(
|
||||
outputs.forEach { addDroppableContainer(it) }
|
||||
}
|
||||
|
||||
val experience = ExperienceStorage(config::maxExperienceStored).also(::addNeighbourListener)
|
||||
val energyConfig = ConfigurableEnergy(energy)
|
||||
val itemConfig = ConfigurableItemHandler(
|
||||
input = CombinedItemHandler(inputs.map { it.handler(HandlerFilter.OnlyIn) }),
|
||||
@ -60,44 +63,13 @@ class PoweredFurnaceBlockEntity(
|
||||
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 {
|
||||
exposeGlobally(ForgeCapabilities.FLUID_HANDLER, experience)
|
||||
|
||||
savetables.stateful(::upgrades)
|
||||
savetables.stateful(::energy)
|
||||
|
||||
savetables.double(::experience)
|
||||
savetables.stateful(::experience)
|
||||
|
||||
savetables.stateful(inputs, "input")
|
||||
savetables.stateful(outputs, "output")
|
||||
@ -124,8 +96,7 @@ class PoweredFurnaceBlockEntity(
|
||||
|
||||
override fun onJobFinish(status: JobStatus<ItemJob>, id: Int) {
|
||||
if (outputs[id].fullyAddItem(status.job.itemStack)) {
|
||||
experience += status.experience
|
||||
tryStoreExperience(null)
|
||||
experience.storeExperience(status.experience, this)
|
||||
} else {
|
||||
status.noItem()
|
||||
}
|
||||
|
@ -66,24 +66,4 @@ class PlatePressBlock(properties: Properties = DEFAULT_PROPERTIES, val isTwin: B
|
||||
): VoxelShape {
|
||||
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() }
|
||||
}
|
||||
|
||||
@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,
|
||||
energyConsumption: Decimal?,
|
||||
matterCapacity: Decimal? = null,
|
||||
maxExperience: Double? = null,
|
||||
configurator: ForgeConfigSpec.Builder.() -> Unit = {}
|
||||
): WorkerBalanceValues {
|
||||
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 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 maxExperienceStored: Double by (if (maxExperience == null) GetterSetter.box(Double.POSITIVE_INFINITY) else builder.defineInRange("MAX_EXPERIENCE_STORED", maxExperience, 0.0))
|
||||
}
|
||||
|
||||
configurator.invoke(builder)
|
||||
|
@ -11,6 +11,7 @@ interface WorkerBalanceValues : EnergyBalanceValues {
|
||||
val workTimeMultiplier: Double
|
||||
val energyConsumption: Decimal
|
||||
val matterCapacity: Decimal
|
||||
val maxExperienceStored: Double
|
||||
}
|
||||
|
||||
interface VerboseEnergyBalanceValues {
|
||||
|
@ -10,7 +10,8 @@ object MachinesConfig : AbstractConfig("machines") {
|
||||
MNames.PLATE_PRESS,
|
||||
energyStorage = Decimal(40_000),
|
||||
energyThroughput = Decimal(200),
|
||||
energyConsumption = Decimal(15)
|
||||
energyConsumption = Decimal(15),
|
||||
maxExperience = 200.0,
|
||||
)
|
||||
|
||||
val MATTER_ENTANGLER = workerValues(
|
||||
@ -19,6 +20,7 @@ object MachinesConfig : AbstractConfig("machines") {
|
||||
energyThroughput = Decimal(400),
|
||||
energyConsumption = Decimal(120),
|
||||
matterCapacity = Decimal(60),
|
||||
maxExperience = 400.0,
|
||||
)
|
||||
|
||||
val MATTER_DECOMPOSER = workerValues(
|
||||
@ -169,7 +171,8 @@ object MachinesConfig : AbstractConfig("machines") {
|
||||
energyStorage = Decimal(40_000),
|
||||
energyThroughput = Decimal(200),
|
||||
energyConsumption = Decimal(20),
|
||||
workTimeMultiplier = 0.75
|
||||
workTimeMultiplier = 0.75,
|
||||
maxExperience = 200.0
|
||||
)
|
||||
|
||||
val POWERED_BLAST_FURNACE = workerValues(
|
||||
@ -177,7 +180,8 @@ object MachinesConfig : AbstractConfig("machines") {
|
||||
energyStorage = Decimal(40_000),
|
||||
energyThroughput = Decimal(200),
|
||||
energyConsumption = Decimal(20),
|
||||
workTimeMultiplier = 0.75
|
||||
workTimeMultiplier = 0.75,
|
||||
maxExperience = 200.0
|
||||
)
|
||||
|
||||
val POWERED_SMOKER = workerValues(
|
||||
@ -185,7 +189,8 @@ object MachinesConfig : AbstractConfig("machines") {
|
||||
energyStorage = Decimal(40_000),
|
||||
energyThroughput = Decimal(200),
|
||||
energyConsumption = Decimal(10),
|
||||
workTimeMultiplier = 0.75
|
||||
workTimeMultiplier = 0.75,
|
||||
maxExperience = 200.0
|
||||
)
|
||||
|
||||
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)
|
||||
|
||||
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.registry.MMenus
|
||||
|
||||
class PlatePressMenu @JvmOverloads constructor(
|
||||
class PlatePressMenu(
|
||||
containerID: Int,
|
||||
inventory: Inventory,
|
||||
tile: PlatePressBlockEntity? = null
|
||||
) : MatteryPoweredMenu(MMenus.PLATE_PRESS, containerID, inventory, tile) {
|
||||
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 itemConfig = ItemConfigPlayerInput(this, tile?.itemConfig, allowPush = true)
|
||||
|
@ -23,7 +23,7 @@ class PoweredFurnaceMenu(
|
||||
tile: PoweredFurnaceBlockEntity? = null
|
||||
) : MatteryPoweredMenu(type, containerID, inventory, tile) {
|
||||
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 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.registry.MMenus
|
||||
|
||||
class TwinPlatePressMenu @JvmOverloads constructor(
|
||||
class TwinPlatePressMenu(
|
||||
containerID: Int,
|
||||
inventory: Inventory,
|
||||
tile: PlatePressBlockEntity? = null
|
||||
) : MatteryPoweredMenu(MMenus.TWIN_PLATE_PRESS, containerID, inventory, tile) {
|
||||
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 progressGauge1 = ProgressGaugeWidget(this, tile?.jobEventLoops?.get(1))
|
||||
|
@ -36,6 +36,7 @@ interface IMatterEntanglerRecipe : IMatteryRecipe<CraftingContainer> {
|
||||
val ticks: Double
|
||||
val ingredients: IIngredientMatrix
|
||||
val result: ItemStack
|
||||
val experience: Float
|
||||
|
||||
fun preemptivelyMatches(container: CraftingContainer, level: Level): Boolean
|
||||
}
|
||||
@ -45,6 +46,7 @@ open class MatterEntanglerRecipe(
|
||||
override val matter: Decimal,
|
||||
override val ticks: Double,
|
||||
override val result: ItemStack,
|
||||
override val experience: Float = 0f,
|
||||
val uuidKey: String = "uuid",
|
||||
val fixedUuid: Optional<UUID> = Optional.empty()
|
||||
) : IMatterEntanglerRecipe {
|
||||
@ -147,6 +149,7 @@ open class MatterEntanglerRecipe(
|
||||
DecimalCodec.minRange(Decimal.ZERO).fieldOf("matter").forGetter(MatterEntanglerRecipe::matter),
|
||||
Codec.DOUBLE.minRange(0.0).fieldOf("ticks").forGetter(MatterEntanglerRecipe::ticks),
|
||||
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),
|
||||
UUIDUtil.STRING_CODEC.optionalFieldOf("fixedUuid").forGetter(MatterEntanglerRecipe::fixedUuid)
|
||||
).apply(it, ::MatterEntanglerRecipe)
|
||||
|
@ -12,7 +12,17 @@ import net.minecraft.world.item.ItemStack
|
||||
import net.minecraft.world.item.TooltipFlag
|
||||
import net.minecraft.world.item.crafting.RecipeType
|
||||
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.BlockState
|
||||
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.ForgeRegistries
|
||||
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.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.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.tech.PhantomAttractorBlock
|
||||
import ru.dbotthepony.mc.otm.block.tech.PlatePressBlock
|
||||
import ru.dbotthepony.mc.otm.block.StorageCableBlock
|
||||
import ru.dbotthepony.mc.otm.block.decorative.DevChestBlock
|
||||
import ru.dbotthepony.mc.otm.block.decorative.EngineBlock
|
||||
import ru.dbotthepony.mc.otm.block.decorative.FluidTankBlock
|
||||
import ru.dbotthepony.mc.otm.block.decorative.HoloSignBlock
|
||||
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.MatterCapacitorBankBlock
|
||||
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.MatterReconstructorBlock
|
||||
import ru.dbotthepony.mc.otm.block.matter.MatterRecyclerBlock
|
||||
import ru.dbotthepony.mc.otm.block.matter.MatterReplicatorBlock
|
||||
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.StoragePowerSupplierBlock
|
||||
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.EnergyCounterBlock
|
||||
import ru.dbotthepony.mc.otm.block.tech.EnergyServoBlock
|
||||
import ru.dbotthepony.mc.otm.block.tech.EssenceStorageBlock
|
||||
import ru.dbotthepony.mc.otm.block.decorative.PainterBlock
|
||||
import ru.dbotthepony.mc.otm.block.matter.MatterEntanglerBlock
|
||||
import ru.dbotthepony.mc.otm.block.tech.PhantomAttractorBlock
|
||||
import ru.dbotthepony.mc.otm.block.tech.PlatePressBlock
|
||||
import ru.dbotthepony.mc.otm.block.tech.PoweredFurnaceBlock
|
||||
import ru.dbotthepony.mc.otm.config.MachinesConfig
|
||||
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 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(
|
||||
BlockBehaviour.Properties.of()
|
||||
.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_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(
|
||||
Tiers.IRON.level,
|
||||
|
@ -275,6 +275,7 @@ object MRegistry {
|
||||
IMatterFunction.register(bus)
|
||||
|
||||
MBlocks.register(bus)
|
||||
MFluids.register(bus)
|
||||
MBlockEntities.register(bus)
|
||||
MEntityTypes.register(bus)
|
||||
MMenus.register(bus)
|
||||
|
Loading…
Reference in New Issue
Block a user