combustible generator but no screen
This commit is contained in:
@@ -2,15 +2,11 @@ package org.neoflock.neocomputers.block
|
|||||||
|
|
||||||
import net.minecraft.core.BlockPos
|
import net.minecraft.core.BlockPos
|
||||||
import net.minecraft.network.chat.ChatType
|
import net.minecraft.network.chat.ChatType
|
||||||
import net.minecraft.network.chat.Component
|
|
||||||
import net.minecraft.network.chat.OutgoingChatMessage
|
import net.minecraft.network.chat.OutgoingChatMessage
|
||||||
import net.minecraft.network.chat.PlayerChatMessage
|
import net.minecraft.network.chat.PlayerChatMessage
|
||||||
import net.minecraft.server.level.ServerPlayer
|
import net.minecraft.server.level.ServerPlayer
|
||||||
import net.minecraft.world.InteractionResult
|
import net.minecraft.world.InteractionResult
|
||||||
import net.minecraft.world.entity.player.Player
|
import net.minecraft.world.entity.player.Player
|
||||||
import net.minecraft.world.item.Item
|
|
||||||
import net.minecraft.world.item.ItemStack
|
|
||||||
import net.minecraft.world.item.TooltipFlag
|
|
||||||
import net.minecraft.world.level.Level
|
import net.minecraft.world.level.Level
|
||||||
import net.minecraft.world.level.block.entity.BlockEntity
|
import net.minecraft.world.level.block.entity.BlockEntity
|
||||||
import net.minecraft.world.level.block.state.BlockState
|
import net.minecraft.world.level.block.state.BlockState
|
||||||
@@ -25,7 +21,7 @@ class CapacitorEntity(pos: BlockPos, state: BlockState) : NodeBlockEntity(BlockE
|
|||||||
val capacity: Long = 20000
|
val capacity: Long = 20000
|
||||||
|
|
||||||
override val node = object : Networking.Node() {
|
override val node = object : Networking.Node() {
|
||||||
override fun getPowerRole() = PowerRole.PRODUCER
|
override fun getPowerRole() = PowerRole.STORAGE
|
||||||
override fun getEnergy() = amountStored
|
override fun getEnergy() = amountStored
|
||||||
override fun getEnergyCapacity() = capacity
|
override fun getEnergyCapacity() = capacity
|
||||||
override fun giveEnergy(amount: Long): Long {
|
override fun giveEnergy(amount: Long): Long {
|
||||||
|
|||||||
@@ -1,12 +1,23 @@
|
|||||||
package org.neoflock.neocomputers.block
|
package org.neoflock.neocomputers.block
|
||||||
|
|
||||||
|
import net.minecraft.client.resources.sounds.Sound
|
||||||
import net.minecraft.core.BlockPos
|
import net.minecraft.core.BlockPos
|
||||||
|
import net.minecraft.network.chat.ChatType
|
||||||
|
import net.minecraft.network.chat.OutgoingChatMessage
|
||||||
|
import net.minecraft.network.chat.PlayerChatMessage
|
||||||
|
import net.minecraft.server.level.ServerPlayer
|
||||||
|
import net.minecraft.world.InteractionResult
|
||||||
|
import net.minecraft.world.entity.player.Player
|
||||||
import net.minecraft.world.level.Level
|
import net.minecraft.world.level.Level
|
||||||
|
import net.minecraft.world.level.block.Block
|
||||||
import net.minecraft.world.level.block.EntityBlock
|
import net.minecraft.world.level.block.EntityBlock
|
||||||
|
import net.minecraft.world.level.block.FurnaceBlock
|
||||||
import net.minecraft.world.level.block.entity.BlockEntity
|
import net.minecraft.world.level.block.entity.BlockEntity
|
||||||
import net.minecraft.world.level.block.entity.BlockEntityTicker
|
import net.minecraft.world.level.block.entity.BlockEntityTicker
|
||||||
import net.minecraft.world.level.block.entity.BlockEntityType
|
import net.minecraft.world.level.block.entity.BlockEntityType
|
||||||
|
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.phys.BlockHitResult
|
||||||
import org.neoflock.neocomputers.entity.BlockEntities
|
import org.neoflock.neocomputers.entity.BlockEntities
|
||||||
import org.neoflock.neocomputers.entity.SolarGeneratorBlockEntity
|
import org.neoflock.neocomputers.entity.SolarGeneratorBlockEntity
|
||||||
import org.neoflock.neocomputers.entity.CombustionGeneratorBlockEntity
|
import org.neoflock.neocomputers.entity.CombustionGeneratorBlockEntity
|
||||||
@@ -30,7 +41,8 @@ class SolarGeneratorBlock : BaseBlock(), EntityBlock {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class CombustionGeneratorBlock : BaseBlock(), EntityBlock {
|
// TODO: make it glow when burning
|
||||||
|
class CombustionGeneratorBlock : Block(BlockBehaviour.Properties.of()), EntityBlock {
|
||||||
override fun newBlockEntity(blockPos: BlockPos, blockState: BlockState): BlockEntity {
|
override fun newBlockEntity(blockPos: BlockPos, blockState: BlockState): BlockEntity {
|
||||||
return CombustionGeneratorBlockEntity(blockPos, blockState)
|
return CombustionGeneratorBlockEntity(blockPos, blockState)
|
||||||
}
|
}
|
||||||
@@ -43,8 +55,28 @@ class CombustionGeneratorBlock : BaseBlock(), EntityBlock {
|
|||||||
return object : BlockEntityTicker<T> {
|
return object : BlockEntityTicker<T> {
|
||||||
override fun tick(level: Level, blockPos: BlockPos, blockState: BlockState, blockEntity: T) {
|
override fun tick(level: Level, blockPos: BlockPos, blockState: BlockState, blockEntity: T) {
|
||||||
if(blockEntity !is CombustionGeneratorBlockEntity) return;
|
if(blockEntity !is CombustionGeneratorBlockEntity) return;
|
||||||
blockEntity.giveSolarPower();
|
blockEntity.burnFuelForEnergy();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun useWithoutItem(
|
||||||
|
blockState: BlockState,
|
||||||
|
level: Level,
|
||||||
|
blockPos: BlockPos,
|
||||||
|
player: Player,
|
||||||
|
blockHitResult: BlockHitResult
|
||||||
|
): InteractionResult? {
|
||||||
|
if(!level.isClientSide()) {
|
||||||
|
val sp = player as ServerPlayer
|
||||||
|
val ent = level.getBlockEntity(blockPos, BlockEntities.COMBUSTGEN_ENTITY.get())
|
||||||
|
if(ent.isPresent) {
|
||||||
|
val bust = ent.get()
|
||||||
|
val fuel = bust.stacks[0]
|
||||||
|
val msg = PlayerChatMessage.system("${fuel.displayName.string} x ${fuel.count} (${bust.node.getEnergy()} / ${bust.node.getEnergyCapacity()} J)")
|
||||||
|
sp.sendChatMessage(OutgoingChatMessage.create(msg), false, ChatType.bind(ChatType.CHAT, player))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return InteractionResult.SUCCESS;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,5 +60,6 @@ object BlockEntities {
|
|||||||
|
|
||||||
fun registerPowerBlocks() {
|
fun registerPowerBlocks() {
|
||||||
PowerManager.registerPowerBlockEntity(CAPACITOR_ENTITY.get())
|
PowerManager.registerPowerBlockEntity(CAPACITOR_ENTITY.get())
|
||||||
|
PowerManager.registerPowerBlockEntity(COMBUSTGEN_ENTITY.get())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,20 +1,72 @@
|
|||||||
package org.neoflock.neocomputers.entity
|
package org.neoflock.neocomputers.entity
|
||||||
|
|
||||||
import net.minecraft.core.BlockPos
|
import net.minecraft.core.BlockPos
|
||||||
import net.minecraft.world.level.block.entity.BlockEntity
|
import net.minecraft.core.NonNullList
|
||||||
import net.minecraft.world.level.block.entity.BlockEntityType
|
import net.minecraft.world.entity.player.Player
|
||||||
|
import net.minecraft.world.item.ItemStack
|
||||||
import net.minecraft.world.level.block.state.BlockState
|
import net.minecraft.world.level.block.state.BlockState
|
||||||
import org.neoflock.neocomputers.block.NodeBlockEntity
|
import org.neoflock.neocomputers.block.NodeBlockEntity
|
||||||
|
import org.neoflock.neocomputers.network.Networking
|
||||||
|
import org.neoflock.neocomputers.network.PowerRole
|
||||||
|
import org.neoflock.neocomputers.utils.GenericContainer
|
||||||
|
import org.neoflock.neocomputers.utils.ContainerUtils
|
||||||
|
import kotlin.math.min
|
||||||
|
|
||||||
class CombustionGeneratorBlockEntity(blockPos: BlockPos, blockState: BlockState) : BlockEntity(BlockEntities.COMBUSTGEN_ENTITY.get(), blockPos, blockState) {
|
class CombustionGeneratorBlockEntity(blockPos: BlockPos, blockState: BlockState) : NodeBlockEntity(BlockEntities.COMBUSTGEN_ENTITY.get(), blockPos, blockState), GenericContainer {
|
||||||
val energyPerTick: Long = 50
|
val energyPerTick: Long = 50
|
||||||
|
|
||||||
fun giveSolarPower() {
|
var energy: Long = 0
|
||||||
if(level?.isDay == true) {
|
val maxEnergy: Long = 50000
|
||||||
val below = level?.getBlockEntity(blockPos.below())
|
var burningTimeRemaining: Int = 0
|
||||||
if(below is NodeBlockEntity) {
|
|
||||||
below.node.giveEnergy(energyPerTick)
|
override val node = object : Networking.Node() {
|
||||||
}
|
override fun getPowerRole() = PowerRole.GENERATOR
|
||||||
|
override fun getEnergy() = energy
|
||||||
|
override fun getEnergyCapacity() = maxEnergy
|
||||||
|
override fun withdrawEnergy(amount: Long): Long {
|
||||||
|
val taken = min(amount, energy)
|
||||||
|
energy -= taken
|
||||||
|
return taken
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun giveEnergy(amount: Long): Long {
|
||||||
|
val given = min(amount, maxEnergy - energy)
|
||||||
|
energy += given
|
||||||
|
return given
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val stacks: NonNullList<ItemStack> = NonNullList<ItemStack>.withSize(1, ItemStack.EMPTY)
|
||||||
|
|
||||||
|
override fun canPlaceItem(i: Int, itemStack: ItemStack): Boolean {
|
||||||
|
return ContainerUtils.isBurningFuel(itemStack)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getItems(): NonNullList<ItemStack> = stacks
|
||||||
|
|
||||||
|
override fun stillValid(player: Player): Boolean {
|
||||||
|
return !this.isRemoved
|
||||||
|
}
|
||||||
|
|
||||||
|
fun burnFuelForEnergy() {
|
||||||
|
// TODO: give us a block state tag for active
|
||||||
|
|
||||||
|
// keep combusting and shi
|
||||||
|
if(burningTimeRemaining > 0) {
|
||||||
|
burningTimeRemaining--
|
||||||
|
node.giveEnergy(energyPerTick)
|
||||||
|
setChanged()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// no point
|
||||||
|
if(node.getEnergy() >= node.getEnergyCapacity()) return;
|
||||||
|
|
||||||
|
// :fire:
|
||||||
|
val fuel = stacks[0]
|
||||||
|
if(fuel.isEmpty) return
|
||||||
|
|
||||||
|
burningTimeRemaining = ContainerUtils.getBurningTime(fuel) ?: 0
|
||||||
|
fuel.count--
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -2,7 +2,6 @@ package org.neoflock.neocomputers.network
|
|||||||
|
|
||||||
import net.minecraft.core.BlockPos
|
import net.minecraft.core.BlockPos
|
||||||
import org.neoflock.neocomputers.NeoComputers
|
import org.neoflock.neocomputers.NeoComputers
|
||||||
import java.lang.ref.WeakReference
|
|
||||||
import kotlin.math.min
|
import kotlin.math.min
|
||||||
import kotlin.math.pow
|
import kotlin.math.pow
|
||||||
import kotlin.math.sqrt
|
import kotlin.math.sqrt
|
||||||
@@ -11,9 +10,12 @@ enum class PowerRole {
|
|||||||
// consumes energy, wants to be fully charged
|
// consumes energy, wants to be fully charged
|
||||||
// does not give energy to network nodes
|
// does not give energy to network nodes
|
||||||
CONSUMER,
|
CONSUMER,
|
||||||
// produces/stores energy, will not care to charge itself
|
// stores energy, will not care to charge itself
|
||||||
// will happily give energy to network nodes
|
// will happily give energy to network nodes
|
||||||
PRODUCER,
|
STORAGE,
|
||||||
|
// only produces energy, thus obviously charges itself
|
||||||
|
// also happily gives energy
|
||||||
|
GENERATOR,
|
||||||
}
|
}
|
||||||
|
|
||||||
object Networking {
|
object Networking {
|
||||||
@@ -56,7 +58,7 @@ object Networking {
|
|||||||
open fun withdrawEnergy(amount: Long): Long = 0
|
open fun withdrawEnergy(amount: Long): Long = 0
|
||||||
|
|
||||||
open fun getEnergyCapacity(): Long = 0
|
open fun getEnergyCapacity(): Long = 0
|
||||||
fun getChargerNodes(): Set<Node> = getReachable().filter { it.getPowerRole() == PowerRole.PRODUCER }.toSet()
|
fun getChargerNodes(): Set<Node> = getReachable().filter { it.getPowerRole() != PowerRole.CONSUMER }.toSet()
|
||||||
fun totalEnergyInConnections(): Long = getChargerNodes().fold(0) { acc, node -> acc + node.getEnergy() }
|
fun totalEnergyInConnections(): Long = getChargerNodes().fold(0) { acc, node -> acc + node.getEnergy() }
|
||||||
fun maxEnergyInConnections(): Long = getChargerNodes().fold(0) { acc, node -> acc + node.getEnergyCapacity() }
|
fun maxEnergyInConnections(): Long = getChargerNodes().fold(0) { acc, node -> acc + node.getEnergyCapacity() }
|
||||||
|
|
||||||
@@ -78,6 +80,7 @@ object Networking {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PLEASE only call if consumer, in the name of all that is holy
|
||||||
fun tryToChargeFully() {
|
fun tryToChargeFully() {
|
||||||
var remaining = getEnergyCapacity() - getEnergy()
|
var remaining = getEnergyCapacity() - getEnergy()
|
||||||
if(remaining <= 0) return
|
if(remaining <= 0) return
|
||||||
@@ -95,8 +98,55 @@ object Networking {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// only call if storage
|
||||||
|
fun balanceStorage() {
|
||||||
|
for(battery in getReachable()) {
|
||||||
|
if(battery.getPowerRole() != PowerRole.STORAGE) continue
|
||||||
|
// its so if for example we have a battery with 2x the capacity
|
||||||
|
// we don't try to even the energy between them since that's just bad
|
||||||
|
// and might pointless delete energy over time
|
||||||
|
val capacityRatio = getEnergyCapacity().toDouble() / battery.getEnergyCapacity()
|
||||||
|
|
||||||
|
val meaningfulSurplus = (battery.getEnergy() * capacityRatio - getEnergy()).toLong()
|
||||||
|
|
||||||
|
if(meaningfulSurplus <= 0) {
|
||||||
|
// WE'RE greedy (or negligible surplus)? Do nothing
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// steal from this greedy mf
|
||||||
|
val toSteal = meaningfulSurplus / 2
|
||||||
|
if(toSteal == 0L) continue // broke storahh
|
||||||
|
|
||||||
|
val stolen = battery.withdrawEnergy(toSteal)
|
||||||
|
if(giveEnergy(stolen) < stolen) {
|
||||||
|
NeoComputers.LOGGER.warn("LOSING ENERGY IN NODE $this!!!! THIS IS REALLY BAD!!!")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// rob the generators
|
||||||
|
fun stealGeneratorPower() {
|
||||||
|
var remaining = getEnergyCapacity() - getEnergy()
|
||||||
|
|
||||||
|
for(generator in getReachable()) {
|
||||||
|
if(generator.getPowerRole() != PowerRole.GENERATOR) continue
|
||||||
|
// rob this mf
|
||||||
|
val robbed = generator.withdrawEnergy(remaining)
|
||||||
|
val taken = giveEnergy(robbed)
|
||||||
|
if(taken < robbed) {
|
||||||
|
NeoComputers.LOGGER.warn("energy caught being DELETED in the big 26")
|
||||||
|
}
|
||||||
|
remaining -= taken
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
open fun tick() {
|
open fun tick() {
|
||||||
if(getPowerRole() == PowerRole.CONSUMER) tryToChargeFully()
|
if(getPowerRole() == PowerRole.CONSUMER) tryToChargeFully()
|
||||||
|
if(getPowerRole() == PowerRole.STORAGE) {
|
||||||
|
stealGeneratorPower()
|
||||||
|
balanceStorage()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// processes a received message
|
// processes a received message
|
||||||
open fun received(message: Message) {}
|
open fun received(message: Message) {}
|
||||||
|
|||||||
@@ -17,9 +17,10 @@ object PowerManager {
|
|||||||
entity, dir -> object : EnergyStorage {
|
entity, dir -> object : EnergyStorage {
|
||||||
override fun getAmount() = entity.node.getEnergy()
|
override fun getAmount() = entity.node.getEnergy()
|
||||||
override fun getCapacity() = entity.node.getEnergyCapacity()
|
override fun getCapacity() = entity.node.getEnergyCapacity()
|
||||||
override fun supportsExtraction() = entity.node.getPowerRole() == PowerRole.PRODUCER
|
override fun supportsExtraction() = entity.node.getPowerRole() != PowerRole.CONSUMER
|
||||||
override fun supportsInsertion(): Boolean = entity.node.getEnergyCapacity() > 0
|
override fun supportsInsertion() = entity.node.getPowerRole() != PowerRole.GENERATOR
|
||||||
override fun extract(maxAmount: Long, transaction: TransactionContext?): Long {
|
override fun extract(maxAmount: Long, transaction: TransactionContext?): Long {
|
||||||
|
if(entity.node.getPowerRole() == PowerRole.CONSUMER) return 0
|
||||||
val taken = entity.node.withdrawEnergy(maxAmount)
|
val taken = entity.node.withdrawEnergy(maxAmount)
|
||||||
transaction?.addCloseCallback {
|
transaction?.addCloseCallback {
|
||||||
ctx, res -> if(res.wasAborted() || !res.wasCommitted()) entity.node.giveEnergy(taken)
|
ctx, res -> if(res.wasAborted() || !res.wasCommitted()) entity.node.giveEnergy(taken)
|
||||||
@@ -27,9 +28,10 @@ object PowerManager {
|
|||||||
return taken
|
return taken
|
||||||
}
|
}
|
||||||
override fun insert(maxAmount: Long, transaction: TransactionContext?): Long {
|
override fun insert(maxAmount: Long, transaction: TransactionContext?): Long {
|
||||||
|
if(entity.node.getPowerRole() == PowerRole.GENERATOR) return 0
|
||||||
val given = entity.node.giveEnergy(maxAmount)
|
val given = entity.node.giveEnergy(maxAmount)
|
||||||
transaction?.addCloseCallback {
|
transaction?.addCloseCallback { ctx, res ->
|
||||||
ctx, res -> if(res.wasAborted() || !res.wasCommitted()) entity.node.withdrawEnergy(given)
|
if (res.wasAborted() || !res.wasCommitted()) entity.node.withdrawEnergy(given)
|
||||||
}
|
}
|
||||||
return given
|
return given
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package org.neoflock.neocomputers.utils
|
||||||
|
|
||||||
|
import dev.architectury.registry.fuel.FuelRegistry
|
||||||
|
import net.minecraft.world.item.ItemStack
|
||||||
|
|
||||||
|
// mewhenthe, aka e, will have me publicly executed for this code
|
||||||
|
object ContainerUtils {
|
||||||
|
fun getBurningTime(itemStack: ItemStack): Int? {
|
||||||
|
val time = FuelRegistry.get(itemStack)
|
||||||
|
if(time == 0) return null
|
||||||
|
return time
|
||||||
|
}
|
||||||
|
|
||||||
|
fun isBurningFuel(itemStack: ItemStack) = getBurningTime(itemStack) != null
|
||||||
|
}
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
package org.neoflock.neocomputers.utils
|
||||||
|
|
||||||
|
// based off the ImplementedContainer of https://docs.fabricmc.net/develop/blocks/block-containers
|
||||||
|
import net.minecraft.world.Container;
|
||||||
|
import net.minecraft.core.NonNullList;
|
||||||
|
import net.minecraft.world.ContainerHelper
|
||||||
|
import net.minecraft.world.item.ItemStack
|
||||||
|
|
||||||
|
// Common container interface, assumes the entire purpose is purely raw item storage
|
||||||
|
interface GenericContainer : Container {
|
||||||
|
fun getItems(): NonNullList<ItemStack>
|
||||||
|
|
||||||
|
override fun getContainerSize(): Int {
|
||||||
|
return getItems().size
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun isEmpty(): Boolean {
|
||||||
|
return getItems().all { it.isEmpty }
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getItem(i: Int): ItemStack {
|
||||||
|
return getItems()[i]
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun removeItem(slot: Int, count: Int): ItemStack {
|
||||||
|
val res = ContainerHelper.removeItem(getItems(), slot, count)
|
||||||
|
if (!res.isEmpty) setChanged()
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setItem(slot: Int, itemStack: ItemStack) {
|
||||||
|
getItems()[slot] = itemStack
|
||||||
|
|
||||||
|
// in case of bullshit
|
||||||
|
if(itemStack.count > itemStack.maxStackSize) {
|
||||||
|
// rip items
|
||||||
|
itemStack.count = itemStack.maxStackSize
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun removeItemNoUpdate(i: Int): ItemStack {
|
||||||
|
return ContainerHelper.takeItem(getItems(), i)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun clearContent() {
|
||||||
|
getItems().clear()
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user