Power consumption by android station when doing stuff in it

This commit is contained in:
DBotThePony 2022-09-04 16:19:46 +07:00
parent b010bcdd5d
commit ae8a9296f7
Signed by: DBot
GPG Key ID: DCC23B5715498507
7 changed files with 306 additions and 31 deletions

View File

@ -363,7 +363,7 @@ object DataGen {
} }
with(itemModelProvider) { with(itemModelProvider) {
block(MItems.ANDROID_STATION) block(MItems.ANDROID_STATION, "android_station_working")
block(MItems.BATTERY_BANK) block(MItems.BATTERY_BANK)
block(MItems.MATTER_CAPACITOR_BANK) block(MItems.MATTER_CAPACITOR_BANK)
block(MItems.PATTERN_STORAGE) block(MItems.PATTERN_STORAGE)

View File

@ -200,6 +200,7 @@ private fun misc(provider: MatteryLanguageProvider) {
misc("3d2d.gravitation_stabilizer.mass", "Singularity mass: %s") misc("3d2d.gravitation_stabilizer.mass", "Singularity mass: %s")
misc("3d2d.gravitation_stabilizer.strength", "Gravitation strength: %s") misc("3d2d.gravitation_stabilizer.strength", "Gravitation strength: %s")
misc("android_station.research.low_power", "Android Station is low on power! Can't research!")
misc("android_station.research.researched", "Researched!") misc("android_station.research.researched", "Researched!")
misc("android_station.research.can_be_researched", "Ready to research!") misc("android_station.research.can_be_researched", "Ready to research!")
misc("android_station.research.can_not_be_researched", "Can't research!") misc("android_station.research.can_not_be_researched", "Can't research!")
@ -207,6 +208,10 @@ private fun misc(provider: MatteryLanguageProvider) {
misc("android_station.research.item", "Requires %s x%s") misc("android_station.research.item", "Requires %s x%s")
misc("android_station.research.missing_predecessors", "%s needs to be researched first") misc("android_station.research.missing_predecessors", "%s needs to be researched first")
misc("android_station.low_power_0", "Not enough power; Can't swap parts")
misc("android_station.low_power_1", "Low power; Can't research")
misc("android_station.power_ok", "Power OK")
misc("filter.yes", "Yes") misc("filter.yes", "Yes")
misc("filter.no", "No") misc("filter.no", "No")

View File

@ -29,7 +29,7 @@ class AndroidStationBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
override val defaultDisplayName: Component override val defaultDisplayName: Component
get() = MACHINE_NAME get() = MACHINE_NAME
override val energy = object : WorkerEnergyStorage(this@AndroidStationBlockEntity, STORAGE, MAX_IO) { override val energy = object : WorkerEnergyStorage(this@AndroidStationBlockEntity, STORAGE, MAX_IO, null) {
override fun extractEnergyInner(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction { override fun extractEnergyInner(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction {
return super.extractEnergyInner(howMuch, simulate).also { return super.extractEnergyInner(howMuch, simulate).also {
if (!simulate && this.batteryLevel.isZero) { if (!simulate && this.batteryLevel.isZero) {
@ -93,7 +93,9 @@ class AndroidStationBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
companion object { companion object {
private val MACHINE_NAME = TranslatableComponent("block.overdrive_that_matters.android_station") private val MACHINE_NAME = TranslatableComponent("block.overdrive_that_matters.android_station")
private val STORAGE = ImpreciseFraction(100_000) val STORAGE = ImpreciseFraction(100_000)
private val MAX_IO = ImpreciseFraction(250) val MAX_IO = ImpreciseFraction.valueOf(250)
val ENERGY_PER_OPERATION = ImpreciseFraction.valueOf(2048)
val ENERGY_PER_RESEARCH = ImpreciseFraction.valueOf(16384)
} }
} }

View File

@ -12,6 +12,7 @@ import net.minecraft.world.entity.player.Inventory
import ru.dbotthepony.mc.otm.core.TranslatableComponent import ru.dbotthepony.mc.otm.core.TranslatableComponent
import ru.dbotthepony.mc.otm.android.AndroidResearch import ru.dbotthepony.mc.otm.android.AndroidResearch
import ru.dbotthepony.mc.otm.android.AndroidResearchType import ru.dbotthepony.mc.otm.android.AndroidResearchType
import ru.dbotthepony.mc.otm.block.entity.AndroidStationBlockEntity
import ru.dbotthepony.mc.otm.capability.MatteryPlayerCapability import ru.dbotthepony.mc.otm.capability.MatteryPlayerCapability
import ru.dbotthepony.mc.otm.capability.MatteryCapability import ru.dbotthepony.mc.otm.capability.MatteryCapability
import ru.dbotthepony.mc.otm.client.playGuiClickSound import ru.dbotthepony.mc.otm.client.playGuiClickSound
@ -258,7 +259,6 @@ private class AndroidResearchButton(
AndroidStationScreen.BUTTON_SIZE.toFloat(), AndroidStationScreen.BUTTON_SIZE.toFloat(),
AndroidStationScreen.BUTTON_SIZE.toFloat() AndroidStationScreen.BUTTON_SIZE.toFloat()
) { ) {
init { init {
setDockMargin(2f, 2f, 2f, 2f) setDockMargin(2f, 2f, 2f, 2f)
} }
@ -377,7 +377,7 @@ private class AndroidResearchButton(
override fun mouseClickedInner(x: Double, y: Double, button: Int): Boolean { override fun mouseClickedInner(x: Double, y: Double, button: Int): Boolean {
if (button == InputConstants.MOUSE_BUTTON_LEFT) { if (button == InputConstants.MOUSE_BUTTON_LEFT) {
if (node.canResearch && !node.isResearched) { if (node.canResearch && !node.isResearched && (parent?.screen as AndroidStationScreen).menu.powerWidget.level >= AndroidStationBlockEntity.ENERGY_PER_RESEARCH) {
MatteryPlayerNetworkChannel.sendToServer(AndroidResearchRequestPacket(node.type)) MatteryPlayerNetworkChannel.sendToServer(AndroidResearchRequestPacket(node.type))
} }
@ -391,12 +391,22 @@ private class AndroidResearchButton(
if (isHovered) { if (isHovered) {
val list = ArrayList<Component>().also { it.addAll(node.screenTooltipLines) } val list = ArrayList<Component>().also { it.addAll(node.screenTooltipLines) }
val enoughPower = (parent?.screen as AndroidStationScreen).menu.powerWidget.level >= AndroidStationBlockEntity.ENERGY_PER_RESEARCH
if (node.isResearched) { if (node.isResearched) {
list.add(TranslatableComponent("otm.android_station.research.researched").withStyle(ChatFormatting.DARK_AQUA)) list.add(TranslatableComponent("otm.android_station.research.researched").withStyle(ChatFormatting.DARK_AQUA))
} else if (node.canResearch) { } else if (node.canResearch) {
list.add(TranslatableComponent("otm.android_station.research.can_be_researched").withStyle(ChatFormatting.DARK_GREEN)) list.add(TranslatableComponent("otm.android_station.research.can_be_researched").withStyle(ChatFormatting.DARK_GREEN))
if (!enoughPower) {
list.add(TranslatableComponent("otm.android_station.research.low_power").withStyle(ChatFormatting.DARK_RED))
}
} else { } else {
list.add(TranslatableComponent("otm.android_station.research.can_not_be_researched").withStyle(ChatFormatting.DARK_RED)) list.add(TranslatableComponent("otm.android_station.research.can_not_be_researched").withStyle(ChatFormatting.DARK_RED))
if (!enoughPower) {
list.add(TranslatableComponent("otm.android_station.research.low_power").withStyle(ChatFormatting.DARK_RED))
}
} }
screen.renderComponentTooltip(stack, list, mouse_x.toInt(), mouse_y.toInt()) screen.renderComponentTooltip(stack, list, mouse_x.toInt(), mouse_y.toInt())
@ -599,7 +609,29 @@ class AndroidStationScreen constructor(p_97741_: AndroidStationMenu, p_97742_: I
} }
override fun makeMainFrame(): FramePanel { override fun makeMainFrame(): FramePanel {
val frame = FramePanel(this, 200f, 100f, title) val frame = FramePanel(this, 200f, 108f, title)
object : Label(this@AndroidStationScreen, frame, height = 11f, shadow = true) {
init {
dock = Dock.BOTTOM
dockTop = 2f
}
override fun innerRender(stack: PoseStack, mouseX: Float, mouseY: Float, partialTick: Float) {
if (menu.powerWidget.level >= AndroidStationBlockEntity.ENERGY_PER_RESEARCH) {
text = POWER_OK
color = RGBAColor.LIGHT_GREEN
} else if (menu.powerWidget.level >= AndroidStationBlockEntity.ENERGY_PER_OPERATION) {
text = LOW_POWER_1
color = RGBAColor.DARK_RED
} else {
text = LOW_POWER_0
color = RGBAColor.RED
}
super.innerRender(stack, mouseX, mouseY, partialTick)
}
}
val stripLeft = EditablePanel(this, frame, width = AbstractSlotPanel.SIZE) val stripLeft = EditablePanel(this, frame, width = AbstractSlotPanel.SIZE)
@ -652,5 +684,9 @@ class AndroidStationScreen constructor(p_97741_: AndroidStationMenu, p_97742_: I
val CAN_BE_RESEARCHED = RGBAColor(150, 200, 150) val CAN_BE_RESEARCHED = RGBAColor(150, 200, 150)
val CAN_NOT_BE_RESEARCHED = RGBAColor(200, 150, 150) val CAN_NOT_BE_RESEARCHED = RGBAColor(200, 150, 150)
val ALREADY_BLOCKED = RGBAColor(105, 79, 79) val ALREADY_BLOCKED = RGBAColor(105, 79, 79)
private val LOW_POWER_0 = TranslatableComponent("otm.android_station.low_power_0")
private val LOW_POWER_1 = TranslatableComponent("otm.android_station.low_power_1")
private val POWER_OK = TranslatableComponent("otm.android_station.power_ok")
} }
} }

View File

@ -1,48 +1,133 @@
package ru.dbotthepony.mc.otm.menu package ru.dbotthepony.mc.otm.menu
import com.google.common.collect.ImmutableList import com.google.common.collect.ImmutableList
import net.minecraft.server.level.ServerPlayer
import net.minecraft.world.Container
import net.minecraft.world.SimpleContainer import net.minecraft.world.SimpleContainer
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.Slot
import net.minecraft.world.item.ItemStack import net.minecraft.world.item.ItemStack
import net.minecraftforge.common.capabilities.ForgeCapabilities
import ru.dbotthepony.mc.otm.block.entity.AndroidStationBlockEntity import ru.dbotthepony.mc.otm.block.entity.AndroidStationBlockEntity
import ru.dbotthepony.mc.otm.capability.MatteryPlayerCapability import ru.dbotthepony.mc.otm.capability.MatteryPlayerCapability
import ru.dbotthepony.mc.otm.capability.MatteryCapability import ru.dbotthepony.mc.otm.capability.energy
import ru.dbotthepony.mc.otm.capability.matteryEnergy
import ru.dbotthepony.mc.otm.capability.matteryPlayer
import ru.dbotthepony.mc.otm.registry.MMenus import ru.dbotthepony.mc.otm.registry.MMenus
import java.util.*
private class AndroidStationContainer(player: Player) : SimpleContainer(1) { import kotlin.reflect.KMutableProperty0
var android: MatteryPlayerCapability? = null
init {
player.getCapability(MatteryCapability.MATTERY_PLAYER).ifPresent {
android = it
setItem(0, it.batteryItemStack)
}
}
}
private class AndroidBatterySlot(container: AndroidStationContainer, index: Int) : BatterySlot(container, index) {
val android: MatteryPlayerCapability? = container.android
override fun set(stack: ItemStack) {
super.set(stack)
android?.batteryItemStack = stack
}
}
class AndroidStationMenu @JvmOverloads constructor( class AndroidStationMenu @JvmOverloads constructor(
containerID: Int, containerID: Int,
inventory: Inventory, inventory: Inventory,
tile: AndroidStationBlockEntity? = null tile: AndroidStationBlockEntity? = null
) : MatteryPoweredMenu(MMenus.ANDROID_STATION, containerID, inventory, tile) { ) : MatteryPoweredMenu(MMenus.ANDROID_STATION, containerID, inventory, tile) {
val androidBattery: MatterySlot = AndroidBatterySlot(AndroidStationContainer(inventory.player), 0) private fun container(target: (MatteryPlayerCapability) -> KMutableProperty0<ItemStack>): Container {
if (ply is ServerPlayer)
return PartContainer(target.invoke(ply.matteryPlayer ?: throw NullPointerException("OTM player capability is missing")))
else
return SimpleContainer(1)
}
override val storageSlots = listOf(addSlot(androidBattery)) private inner class PartContainer(parent: KMutableProperty0<ItemStack>) : Container {
private var item by parent
override fun clearContent() {
setItem(0, ItemStack.EMPTY)
}
override fun getContainerSize(): Int {
return 1
}
override fun isEmpty(): Boolean {
return item.isEmpty
}
override fun getItem(p_18941_: Int): ItemStack {
if (p_18941_ != 0)
return ItemStack.EMPTY
return item
}
override fun removeItem(p_18942_: Int, p_18943_: Int): ItemStack {
if (p_18942_ != 0 || powerWidget.level < AndroidStationBlockEntity.ENERGY_PER_OPERATION || item.isEmpty)
return ItemStack.EMPTY
(tile as AndroidStationBlockEntity).energy.extractEnergyInner(AndroidStationBlockEntity.ENERGY_PER_OPERATION, false)
return removeItemNoUpdate(p_18942_)
}
override fun removeItemNoUpdate(p_18951_: Int): ItemStack {
if (p_18951_ != 0)
return ItemStack.EMPTY
val old = item.copy()
item = ItemStack.EMPTY
return old
}
override fun setItem(p_18944_: Int, p_18945_: ItemStack) {
if (p_18944_ != 0)
return
item = p_18945_
}
override fun setChanged() {
// no op
}
override fun stillValid(p_18946_: Player): Boolean {
return true
}
override fun getMaxStackSize(): Int {
return 1
}
}
private inner class AndroidSlot(container: Container, private val condition: (ItemStack) -> Boolean) : MatterySlot(container, 0) {
override fun mayPickup(p_40228_: Player): Boolean {
if (tile is AndroidStationBlockEntity) {
return tile.energy.batteryLevel >= AndroidStationBlockEntity.ENERGY_PER_OPERATION
}
return powerWidget.level >= AndroidStationBlockEntity.ENERGY_PER_OPERATION
}
override fun mayPlace(p_40231_: ItemStack): Boolean {
if (tile is AndroidStationBlockEntity) {
return tile.energy.batteryLevel >= AndroidStationBlockEntity.ENERGY_PER_OPERATION && condition.invoke(p_40231_)
}
return powerWidget.level >= AndroidStationBlockEntity.ENERGY_PER_OPERATION && condition.invoke(p_40231_)
}
}
val androidBattery: MatterySlot = AndroidSlot(container { it::batteryItemStack }) {
it.getCapability(ForgeCapabilities.ENERGY).isPresent
}
override val storageSlots: ImmutableList<Slot>
val armorSlots = makeArmorSlots() val armorSlots = makeArmorSlots()
init { init {
armorSlots.forEach(this::addSlot) armorSlots.forEach(this::addSlot)
addInventorySlots() addInventorySlots()
addSlot(androidBattery)
val builder = ImmutableList.builder<Slot>()
builder.addAll(armorSlots)
builder.add(androidBattery)
storageSlots = builder.build()
}
override fun stillValid(player: Player): Boolean {
return super.stillValid(player) && player.matteryPlayer?.isAndroid == true
} }
} }

View File

@ -0,0 +1,147 @@
{
"parent": "block/cube_all",
"render_type": "translucent",
"textures": {
"0": "overdrive_that_matters:block/android_station",
"particle": "overdrive_that_matters:block/android_station"
},
"elements": [
{
"name": "platform",
"from": [0, 7, 0],
"to": [16, 9, 16],
"faces": {
"north": {"uv": [8, 4, 16, 4.5], "texture": "#0"},
"east": {"uv": [0, 4, 8, 4.5], "texture": "#0"},
"south": {"uv": [8, 4, 16, 4.5], "texture": "#0"},
"west": {"uv": [0, 4, 8, 4.5], "texture": "#0"},
"up": {"uv": [8, 0, 16, 4], "texture": "#0"},
"down": {"uv": [8, 4.5, 16, 8.5], "texture": "#0"}
}
},
{
"name": "base",
"from": [0, 0, 0],
"to": [16, 4, 16],
"faces": {
"north": {"uv": [0, 8.5, 8, 9.5], "texture": "#0"},
"east": {"uv": [0, 8.5, 8, 9.5], "texture": "#0"},
"south": {"uv": [8, 8.5, 16, 9.5], "texture": "#0"},
"west": {"uv": [8, 8.5, 16, 9.5], "texture": "#0"},
"up": {"uv": [8, 4.5, 16, 8.5], "texture": "#0"},
"down": {"uv": [8, 9.5, 16, 13.5], "texture": "#0"}
}
},
{
"name": "body",
"from": [2, 4, 2],
"to": [14, 7, 14],
"faces": {
"north": {"uv": [1, 0, 7, 0.75], "texture": "#0"},
"east": {"uv": [1, 0, 7, 0.75], "texture": "#0"},
"south": {"uv": [1, 0, 7, 0.75], "texture": "#0"},
"west": {"uv": [1, 0, 7, 0.75], "texture": "#0"},
"up": {"uv": [9, 5, 15, 8], "texture": "#0"},
"down": {"uv": [9, 5, 15, 8], "texture": "#0"}
}
},
{
"name": "frame",
"from": [1, 4, 13],
"to": [3, 7, 15],
"faces": {
"north": {"uv": [7, 0, 8, 0.75], "texture": "#0"},
"east": {"uv": [0, 0, 1, 0.75], "texture": "#0"},
"south": {"uv": [7, 0, 8, 0.75], "texture": "#0"},
"west": {"uv": [0, 0, 1, 0.75], "texture": "#0"},
"up": {"uv": [0, 0, 1, 0.58182], "texture": "#0"},
"down": {"uv": [0, 0, 1, 0.58182], "texture": "#0"}
}
},
{
"name": "frame",
"from": [13, 4, 13],
"to": [15, 7, 15],
"faces": {
"north": {"uv": [0, 0, 1, 0.75], "texture": "#0"},
"east": {"uv": [7, 0, 8, 0.75], "texture": "#0"},
"south": {"uv": [0, 0, 1, 0.75], "texture": "#0"},
"west": {"uv": [0, 0, 1, 0.75], "texture": "#0"},
"up": {"uv": [0, 0, 1, 0.58182], "texture": "#0"},
"down": {"uv": [0, 0, 1, 0.58182], "texture": "#0"}
}
},
{
"name": "frame",
"from": [13, 4, 1],
"to": [15, 7, 3],
"faces": {
"north": {"uv": [7, 0, 8, 0.75], "texture": "#0"},
"east": {"uv": [0, 0, 1, 0.75], "texture": "#0"},
"south": {"uv": [7, 0, 8, 0.75], "texture": "#0"},
"west": {"uv": [0, 0, 1, 0.75], "texture": "#0"},
"up": {"uv": [0, 0, 1, 0.58182], "texture": "#0"},
"down": {"uv": [0, 0, 1, 0.58182], "texture": "#0"}
}
},
{
"name": "frame",
"from": [1, 4, 1],
"to": [3, 7, 3],
"faces": {
"north": {"uv": [0, 0, 1, 0.75], "texture": "#0"},
"east": {"uv": [0, 0, 1, 0.75], "texture": "#0"},
"south": {"uv": [0, 0, 1, 0.75], "texture": "#0"},
"west": {"uv": [7, 0, 8, 0.75], "texture": "#0"},
"up": {"uv": [0, 0, 1, 0.58182], "texture": "#0"},
"down": {"uv": [0, 0, 1, 0.58182], "texture": "#0"}
}
},
{
"from": [-1, 10, -1],
"to": [17, 10, 17],
"faces": {
"north": {"uv": [0, 0, 8, 0], "texture": "#missing"},
"east": {"uv": [0, 0, 8, 0], "texture": "#missing"},
"south": {"uv": [0, 0, 8, 0], "texture": "#missing"},
"west": {"uv": [0, 0, 8, 0], "texture": "#missing"},
"up": {"uv": [0, 9.5, 8, 13.5], "texture": "#0"},
"down": {"uv": [0, 9.5, 8, 13.5], "texture": "#0"}
}
}
],
"display": {
"thirdperson_righthand": {
"rotation": [75, 45, 0],
"translation": [0, 2.5, 0],
"scale": [0.375, 0.375, 0.375]
},
"thirdperson_lefthand": {
"rotation": [75, 45, 0],
"translation": [0, 2.5, 0],
"scale": [0.375, 0.375, 0.375]
},
"firstperson_righthand": {
"rotation": [0, 45, 0],
"scale": [0.4, 0.4, 0.4]
},
"firstperson_lefthand": {
"rotation": [0, 225, 0],
"scale": [0.4, 0.4, 0.4]
},
"ground": {
"translation": [0, 3, 0],
"scale": [0.25, 0.25, 0.25]
},
"gui": {
"rotation": [30, 225, 0],
"scale": [0.625, 0.625, 0.625]
},
"head": {
"translation": [0, 13, 0]
},
"fixed": {
"scale": [0.5, 0.5, 0.5]
}
}
}