Upgrade system, conditional quickmove slots, frame panel close button
This commit is contained in:
parent
6690ca03c4
commit
9dcf24cae7
@ -603,6 +603,18 @@ private fun items(provider: MatteryLanguageProvider) {
|
|||||||
|
|
||||||
add(MItems.ZPM_BATTERY, "Zero Point Module")
|
add(MItems.ZPM_BATTERY, "Zero Point Module")
|
||||||
add(MItems.ZPM_BATTERY, "description", "Can be found in hands of those who travel between dimensions, if they ever reached different reality of origin of these constructs...")
|
add(MItems.ZPM_BATTERY, "description", "Can be found in hands of those who travel between dimensions, if they ever reached different reality of origin of these constructs...")
|
||||||
|
|
||||||
|
add(MItems.CreativeUpgrades.SPEED, "Creative Speed Upgrade")
|
||||||
|
add(MItems.CreativeUpgrades.ENERGY_CONSUMPTION, "Creative Energy Consumption Upgrade")
|
||||||
|
add(MItems.CreativeUpgrades.ENERGY_STORAGE, "Creative Energy Storage Upgrade")
|
||||||
|
add(MItems.CreativeUpgrades.ENERGY_STORAGE_FLAT, "Creative Energy Storage Upgrade (Flat)")
|
||||||
|
add(MItems.CreativeUpgrades.ENERGY_STORAGE_FLAT_SMALL, "Creative Energy Storage Upgrade (Flat Small)")
|
||||||
|
add(MItems.CreativeUpgrades.ENERGY_THROUGHPUT, "Creative Energy Throughput Upgrade")
|
||||||
|
add(MItems.CreativeUpgrades.ENERGY_THROUGHPUT_FLAT, "Creative Energy Throughput Upgrade (Flat)")
|
||||||
|
add(MItems.CreativeUpgrades.ENERGY_THROUGHPUT_FLAT_SMALL, "Creative Energy Throughput Upgrade (Flat Small)")
|
||||||
|
add(MItems.CreativeUpgrades.FAILSAFE, "Creative Failsafe Upgrade")
|
||||||
|
add(MItems.CreativeUpgrades.FAILURE, "Creative Failure Upgrade")
|
||||||
|
add(MItems.CreativeUpgrades.PROCESSING_ITEMS, "Creative Item Processing Upgrade")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -688,6 +700,27 @@ private fun gui(provider: MatteryLanguageProvider) {
|
|||||||
gui("side_mode.pull", "Pull")
|
gui("side_mode.pull", "Pull")
|
||||||
gui("side_mode.push", "Push")
|
gui("side_mode.push", "Push")
|
||||||
|
|
||||||
|
gui("upgrades", "Upgrades")
|
||||||
|
gui("upgrades.current", "Active upgrades:")
|
||||||
|
gui("upgrade.speed", "Operation speed: %s%%")
|
||||||
|
gui("upgrade.processing_items", "Items processed per cycle: +%s")
|
||||||
|
gui("upgrade.energy_storage_flat", "Energy capacity: +%s")
|
||||||
|
gui("upgrade.energy_storage", "Energy capacity: +%s%%")
|
||||||
|
gui("upgrade.energy_consumed", "Energy consumption: %s%%")
|
||||||
|
gui("upgrade.energy_throughput_flat", "Energy throughput: +%s")
|
||||||
|
gui("upgrade.energy_throughput", "Energy throughput: +%s%%")
|
||||||
|
gui("upgrade.failsafe", "Failure chance: %s%%")
|
||||||
|
|
||||||
|
gui("upgrade_type.list", "Upgrade classification:")
|
||||||
|
gui("upgrade_type.allowed", "Allowed upgrades:")
|
||||||
|
gui("upgrade_type.allowed_none", "No possible upgrades at the moment.")
|
||||||
|
gui("upgrade_type.speed", "Speed")
|
||||||
|
gui("upgrade_type.processing", "Processing")
|
||||||
|
gui("upgrade_type.energy_storage", "Energy Storage")
|
||||||
|
gui("upgrade_type.energy_consumption", "Energy Consumption")
|
||||||
|
gui("upgrade_type.energy_throughput", "Energy Throughput")
|
||||||
|
gui("upgrade_type.failsafe", "Failsafe")
|
||||||
|
|
||||||
gui("balance_inputs", "Balance input slots")
|
gui("balance_inputs", "Balance input slots")
|
||||||
|
|
||||||
gui("sorting.default", "Default sorting")
|
gui("sorting.default", "Default sorting")
|
||||||
|
@ -607,6 +607,18 @@ private fun items(provider: MatteryLanguageProvider) {
|
|||||||
|
|
||||||
add(MItems.ZPM_BATTERY, "Модуль нулевой точки")
|
add(MItems.ZPM_BATTERY, "Модуль нулевой точки")
|
||||||
add(MItems.ZPM_BATTERY, "description", "Может быть найден у тех, кто путешествует между измерениями, если, конечно, они смогли достигнуть вселенной, где данные устройства были созиданы...")
|
add(MItems.ZPM_BATTERY, "description", "Может быть найден у тех, кто путешествует между измерениями, если, конечно, они смогли достигнуть вселенной, где данные устройства были созиданы...")
|
||||||
|
|
||||||
|
add(MItems.CreativeUpgrades.SPEED, "Творческое улучшение скорости")
|
||||||
|
add(MItems.CreativeUpgrades.ENERGY_CONSUMPTION, "Творческое улучшение энергоэффективности")
|
||||||
|
add(MItems.CreativeUpgrades.ENERGY_STORAGE, "Творческое улучшение энергохраналища")
|
||||||
|
add(MItems.CreativeUpgrades.ENERGY_STORAGE_FLAT, "Творческое улучшение энергохраналища (простое)")
|
||||||
|
add(MItems.CreativeUpgrades.ENERGY_STORAGE_FLAT_SMALL, "Творческое улучшение энергохраналища (малое простое)")
|
||||||
|
add(MItems.CreativeUpgrades.ENERGY_THROUGHPUT, "Творческое улучшение энергоканала")
|
||||||
|
add(MItems.CreativeUpgrades.ENERGY_THROUGHPUT_FLAT, "Творческое улучшение энергоканала (простое)")
|
||||||
|
add(MItems.CreativeUpgrades.ENERGY_THROUGHPUT_FLAT_SMALL, "Творческое улучшение энергоканала (малое простое)")
|
||||||
|
add(MItems.CreativeUpgrades.FAILSAFE, "Творческое улучшение отказоустойчивости")
|
||||||
|
add(MItems.CreativeUpgrades.FAILURE, "Творческое улучшение краха")
|
||||||
|
add(MItems.CreativeUpgrades.PROCESSING_ITEMS, "Творческое улучшение обработки")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -692,6 +704,27 @@ private fun gui(provider: MatteryLanguageProvider) {
|
|||||||
gui("side_mode.pull", "Автоматическое вытягивание")
|
gui("side_mode.pull", "Автоматическое вытягивание")
|
||||||
gui("side_mode.push", "Автоматическое выталкивание")
|
gui("side_mode.push", "Автоматическое выталкивание")
|
||||||
|
|
||||||
|
gui("upgrades", "Улучшения")
|
||||||
|
gui("upgrades.current", "Активные улучшения:")
|
||||||
|
gui("upgrade.speed", "Скорость работы: %s%%")
|
||||||
|
gui("upgrade.processing_items", "Работы за цикл: +%s")
|
||||||
|
gui("upgrade.energy_storage_flat", "Хранилище энергии: +%s")
|
||||||
|
gui("upgrade.energy_storage", "Хранилище энергии: +%s%%")
|
||||||
|
gui("upgrade.energy_consumed", "Потребление энергии: %s%%")
|
||||||
|
gui("upgrade.energy_throughput_flat", "Пропускная способность энергии: +%s")
|
||||||
|
gui("upgrade.energy_throughput", "Пропускная способность энергии: +%s%%")
|
||||||
|
gui("upgrade.failsafe", "Шанс неудачи: %s%%")
|
||||||
|
|
||||||
|
gui("upgrade_type.list", "Классификация улучшения:")
|
||||||
|
gui("upgrade_type.allowed", "Допустимые улучшения:")
|
||||||
|
gui("upgrade_type.allowed_none", "На данный момент нет допустимых улучшений.")
|
||||||
|
gui("upgrade_type.speed", "Скорость")
|
||||||
|
gui("upgrade_type.processing", "Обработка")
|
||||||
|
gui("upgrade_type.energy_storage", "Энергохранилище")
|
||||||
|
gui("upgrade_type.energy_consumption", "Энергоэффективность")
|
||||||
|
gui("upgrade_type.energy_throughput", "Энергоканал")
|
||||||
|
gui("upgrade_type.failsafe", "Отказоустойчивость")
|
||||||
|
|
||||||
gui("balance_inputs", "Балансировать входные слоты")
|
gui("balance_inputs", "Балансировать входные слоты")
|
||||||
|
|
||||||
gui("sorting.default", "Сортировка по умолчанию")
|
gui("sorting.default", "Сортировка по умолчанию")
|
||||||
|
@ -112,6 +112,8 @@ fun addTags(tagsProvider: TagsProvider) {
|
|||||||
tagsProvider.items.forge("shears").add(MItems.TRITANIUM_SHEARS)
|
tagsProvider.items.forge("shears").add(MItems.TRITANIUM_SHEARS)
|
||||||
tagsProvider.items.forge("shields").add(MItems.TRITANIUM_SHIELD)
|
tagsProvider.items.forge("shields").add(MItems.TRITANIUM_SHIELD)
|
||||||
|
|
||||||
|
tagsProvider.items.Appender(MItemTags.UPGRADES).add(MItems.CreativeUpgrades.LIST)
|
||||||
|
|
||||||
tagsProvider.blocks.Appender(BlockTags.STAIRS)
|
tagsProvider.blocks.Appender(BlockTags.STAIRS)
|
||||||
.add(MRegistry.FLOOR_TILES_STAIRS.blocks.values)
|
.add(MRegistry.FLOOR_TILES_STAIRS.blocks.values)
|
||||||
.add(MRegistry.TRITANIUM_STAIRS.allBlocks.values)
|
.add(MRegistry.TRITANIUM_STAIRS.allBlocks.values)
|
||||||
|
@ -63,6 +63,10 @@ public class MatteryCapability {
|
|||||||
@NotNull
|
@NotNull
|
||||||
public static final Capability<ICurio> CURIOS_ITEM = CapabilityManager.get(new CapabilityToken<>() {});
|
public static final Capability<ICurio> CURIOS_ITEM = CapabilityManager.get(new CapabilityToken<>() {});
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
@NotNull
|
||||||
|
public static final Capability<IMatteryUpgrade> UPGRADE = CapabilityManager.get(new CapabilityToken<>() {});
|
||||||
|
|
||||||
public static void register(RegisterCapabilitiesEvent event) {
|
public static void register(RegisterCapabilitiesEvent event) {
|
||||||
event.register(IMatteryEnergyStorage.class);
|
event.register(IMatteryEnergyStorage.class);
|
||||||
event.register(MatteryPlayerCapability.class);
|
event.register(MatteryPlayerCapability.class);
|
||||||
@ -72,5 +76,6 @@ public class MatteryCapability {
|
|||||||
event.register(IReplicationTaskProvider.class);
|
event.register(IReplicationTaskProvider.class);
|
||||||
event.register(IMatteryDrive.class);
|
event.register(IMatteryDrive.class);
|
||||||
event.register(StorageNode.class);
|
event.register(StorageNode.class);
|
||||||
|
event.register(IMatteryUpgrade.class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,9 @@ package ru.dbotthepony.mc.otm.block.entity
|
|||||||
import net.minecraft.nbt.CompoundTag
|
import net.minecraft.nbt.CompoundTag
|
||||||
import net.minecraft.world.item.ItemStack
|
import net.minecraft.world.item.ItemStack
|
||||||
import net.minecraftforge.common.util.INBTSerializable
|
import net.minecraftforge.common.util.INBTSerializable
|
||||||
|
import ru.dbotthepony.mc.otm.capability.IMatteryUpgrade
|
||||||
import ru.dbotthepony.mc.otm.capability.energy.IMatteryEnergyStorage
|
import ru.dbotthepony.mc.otm.capability.energy.IMatteryEnergyStorage
|
||||||
|
import ru.dbotthepony.mc.otm.config.MachinesConfig
|
||||||
import ru.dbotthepony.mc.otm.core.math.Decimal
|
import ru.dbotthepony.mc.otm.core.math.Decimal
|
||||||
import ru.dbotthepony.mc.otm.core.math.getDecimal
|
import ru.dbotthepony.mc.otm.core.math.getDecimal
|
||||||
import ru.dbotthepony.mc.otm.core.math.set
|
import ru.dbotthepony.mc.otm.core.math.set
|
||||||
@ -153,6 +155,7 @@ abstract class MachineJobEventLoop<JobType : IMachineJob> : INBTSerializable<Com
|
|||||||
protected abstract val energy: IMatteryEnergyStorage?
|
protected abstract val energy: IMatteryEnergyStorage?
|
||||||
protected abstract val isBlockedByRedstone: Boolean
|
protected abstract val isBlockedByRedstone: Boolean
|
||||||
protected abstract fun deserializeJob(nbt: CompoundTag): JobType?
|
protected abstract fun deserializeJob(nbt: CompoundTag): JobType?
|
||||||
|
protected abstract val upgrades: IMatteryUpgrade?
|
||||||
|
|
||||||
var currentJob: JobType? = null
|
var currentJob: JobType? = null
|
||||||
set(value) {
|
set(value) {
|
||||||
@ -263,7 +266,8 @@ abstract class MachineJobEventLoop<JobType : IMachineJob> : INBTSerializable<Com
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var availableTicks = ticks
|
val upgrades = upgrades ?: IMatteryUpgrade.Companion
|
||||||
|
var availableTicks = ticks * (1.0 + upgrades.speedBonus.coerceIn(MachinesConfig.Upgrades.MIN_SPEED, MachinesConfig.Upgrades.MAX_SPEED))
|
||||||
val energy = energy
|
val energy = energy
|
||||||
|
|
||||||
while (!isIdling && weakGreaterThan(availableTicks, 0.0) && throttleTicks <= 0) {
|
while (!isIdling && weakGreaterThan(availableTicks, 0.0) && throttleTicks <= 0) {
|
||||||
@ -299,18 +303,23 @@ abstract class MachineJobEventLoop<JobType : IMachineJob> : INBTSerializable<Com
|
|||||||
idleTicksAnim = 0
|
idleTicksAnim = 0
|
||||||
|
|
||||||
if (weakLessThan(workTicks, currentJob.ticks)) {
|
if (weakLessThan(workTicks, currentJob.ticks)) {
|
||||||
val ticksLeft = currentJob.ticks - workTicks
|
val ticksLeft = (currentJob.ticks - workTicks).coerceAtMost(availableTicks)
|
||||||
val ticksAdvanced: Double
|
val ticksAdvanced: Double
|
||||||
|
|
||||||
var requiredPower: Decimal? = null
|
var requiredPower: Decimal? = null
|
||||||
var extractedPower: Decimal? = null
|
var extractedPower: Decimal? = null
|
||||||
|
|
||||||
if (currentJob.powerUsage.isZero) {
|
if (currentJob.powerUsage.isZero) {
|
||||||
ticksAdvanced = availableTicks.coerceAtMost(ticksLeft)
|
ticksAdvanced = ticksLeft
|
||||||
} else {
|
} else {
|
||||||
requiredPower = currentJob.powerUsage * ticksLeft.coerceAtMost(availableTicks)
|
requiredPower = currentJob.powerUsage * (Decimal.ONE + upgrades.energyConsumed.coerceIn(MachinesConfig.Upgrades.MIN_ENERGY, MachinesConfig.Upgrades.MAX_ENERGY)) * ticksLeft.coerceAtMost(availableTicks)
|
||||||
|
|
||||||
|
if (requiredPower.isPositive) {
|
||||||
extractedPower = energy!!.extractEnergy(requiredPower, true)
|
extractedPower = energy!!.extractEnergy(requiredPower, true)
|
||||||
ticksAdvanced = (extractedPower / requiredPower).toDouble().coerceAtMost(ticksLeft).coerceAtMost(availableTicks)
|
ticksAdvanced = (extractedPower / requiredPower).toDouble().coerceIn(0.0, ticksLeft)
|
||||||
|
} else {
|
||||||
|
ticksAdvanced = ticksLeft
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (weakEqualDoubles(ticksAdvanced, 0.0)) {
|
if (weakEqualDoubles(ticksAdvanced, 0.0)) {
|
||||||
|
@ -11,9 +11,11 @@ import net.minecraft.world.level.BlockGetter
|
|||||||
import net.minecraft.world.level.block.Block
|
import net.minecraft.world.level.block.Block
|
||||||
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 ru.dbotthepony.mc.otm.capability.IMatteryUpgrade
|
||||||
import ru.dbotthepony.mc.otm.capability.energy.IMatteryEnergyStorage
|
import ru.dbotthepony.mc.otm.capability.energy.IMatteryEnergyStorage
|
||||||
import ru.dbotthepony.mc.otm.capability.energy.WorkerEnergyStorage
|
import ru.dbotthepony.mc.otm.capability.energy.WorkerEnergyStorage
|
||||||
import ru.dbotthepony.mc.otm.capability.matteryEnergy
|
import ru.dbotthepony.mc.otm.capability.matteryEnergy
|
||||||
|
import ru.dbotthepony.mc.otm.container.UpgradeContainer
|
||||||
import ru.dbotthepony.mc.otm.core.immutableList
|
import ru.dbotthepony.mc.otm.core.immutableList
|
||||||
import ru.dbotthepony.mc.otm.core.math.Decimal
|
import ru.dbotthepony.mc.otm.core.math.Decimal
|
||||||
import ru.dbotthepony.mc.otm.core.nbt.getCompoundList
|
import ru.dbotthepony.mc.otm.core.nbt.getCompoundList
|
||||||
@ -30,7 +32,7 @@ abstract class MatteryWorkerBlockEntity<JobType : IMachineJob>(
|
|||||||
blockPos: BlockPos,
|
blockPos: BlockPos,
|
||||||
blockState: BlockState,
|
blockState: BlockState,
|
||||||
val jobDeserializer: (tag: CompoundTag) -> JobType?,
|
val jobDeserializer: (tag: CompoundTag) -> JobType?,
|
||||||
maxJobs: Int = 1
|
maxJobs: Int = 1,
|
||||||
) : MatteryPoweredBlockEntity(type, blockPos, blockState) {
|
) : MatteryPoweredBlockEntity(type, blockPos, blockState) {
|
||||||
val jobEventLoops: ImmutableList<MachineJobEventLoop<JobType>> = immutableList(maxJobs) { id ->
|
val jobEventLoops: ImmutableList<MachineJobEventLoop<JobType>> = immutableList(maxJobs) { id ->
|
||||||
object : MachineJobEventLoop<JobType>() {
|
object : MachineJobEventLoop<JobType>() {
|
||||||
@ -38,6 +40,8 @@ abstract class MatteryWorkerBlockEntity<JobType : IMachineJob>(
|
|||||||
get() = matteryEnergy
|
get() = matteryEnergy
|
||||||
override val isBlockedByRedstone: Boolean
|
override val isBlockedByRedstone: Boolean
|
||||||
get() = redstoneControl.isBlockedByRedstone
|
get() = redstoneControl.isBlockedByRedstone
|
||||||
|
override val upgrades: IMatteryUpgrade?
|
||||||
|
get() = this@MatteryWorkerBlockEntity.upgrades
|
||||||
|
|
||||||
override fun deserializeJob(nbt: CompoundTag): JobType? {
|
override fun deserializeJob(nbt: CompoundTag): JobType? {
|
||||||
return jobDeserializer.invoke(nbt)
|
return jobDeserializer.invoke(nbt)
|
||||||
@ -61,6 +65,8 @@ abstract class MatteryWorkerBlockEntity<JobType : IMachineJob>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
open val upgrades: IMatteryUpgrade? get() = null
|
||||||
|
|
||||||
var balanceInputs = false
|
var balanceInputs = false
|
||||||
|
|
||||||
init {
|
init {
|
||||||
|
@ -12,11 +12,14 @@ 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.MachineItemJob
|
import ru.dbotthepony.mc.otm.block.entity.MachineItemJob
|
||||||
import ru.dbotthepony.mc.otm.block.entity.MatteryWorkerBlockEntity
|
import ru.dbotthepony.mc.otm.block.entity.MatteryWorkerBlockEntity
|
||||||
|
import ru.dbotthepony.mc.otm.capability.IMatteryUpgrade
|
||||||
|
import ru.dbotthepony.mc.otm.capability.UpgradeType
|
||||||
import ru.dbotthepony.mc.otm.capability.energy.ProfiledEnergyStorage
|
import ru.dbotthepony.mc.otm.capability.energy.ProfiledEnergyStorage
|
||||||
import ru.dbotthepony.mc.otm.capability.energy.WorkerEnergyStorage
|
import ru.dbotthepony.mc.otm.capability.energy.WorkerEnergyStorage
|
||||||
import ru.dbotthepony.mc.otm.config.MachinesConfig
|
import ru.dbotthepony.mc.otm.config.MachinesConfig
|
||||||
import ru.dbotthepony.mc.otm.container.MatteryContainer
|
import ru.dbotthepony.mc.otm.container.MatteryContainer
|
||||||
import ru.dbotthepony.mc.otm.container.HandlerFilter
|
import ru.dbotthepony.mc.otm.container.HandlerFilter
|
||||||
|
import ru.dbotthepony.mc.otm.container.UpgradeContainer
|
||||||
import ru.dbotthepony.mc.otm.container.balance
|
import ru.dbotthepony.mc.otm.container.balance
|
||||||
import ru.dbotthepony.mc.otm.core.math.Decimal
|
import ru.dbotthepony.mc.otm.core.math.Decimal
|
||||||
import ru.dbotthepony.mc.otm.menu.tech.PlatePressMenu
|
import ru.dbotthepony.mc.otm.menu.tech.PlatePressMenu
|
||||||
@ -29,7 +32,8 @@ class PlatePressBlockEntity(
|
|||||||
p_155230_: BlockState,
|
p_155230_: BlockState,
|
||||||
val isTwin: Boolean = false,
|
val isTwin: Boolean = false,
|
||||||
) : MatteryWorkerBlockEntity<MachineItemJob>(if (isTwin) MBlockEntities.TWIN_PLATE_PRESS else MBlockEntities.PLATE_PRESS, p_155229_, p_155230_, ::MachineItemJob, if (isTwin) 2 else 1) {
|
) : MatteryWorkerBlockEntity<MachineItemJob>(if (isTwin) MBlockEntities.TWIN_PLATE_PRESS else MBlockEntities.PLATE_PRESS, p_155229_, p_155230_, ::MachineItemJob, if (isTwin) 2 else 1) {
|
||||||
val energy = ProfiledEnergyStorage(WorkerEnergyStorage(this::setChangedLight, MachinesConfig.PLATE_PRESS))
|
override val upgrades = UpgradeContainer(this::setChangedLight, if (isTwin) 4 else 3, UpgradeType.BASIC)
|
||||||
|
val energy = ProfiledEnergyStorage(WorkerEnergyStorage(this::setChangedLight, upgrades.transform(MachinesConfig.PLATE_PRESS)))
|
||||||
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)
|
||||||
|
|
||||||
@ -55,6 +59,7 @@ class PlatePressBlockEntity(
|
|||||||
savetable(::inputContainer)
|
savetable(::inputContainer)
|
||||||
savetable(::outputContainer)
|
savetable(::outputContainer)
|
||||||
savetables.double(::experience)
|
savetables.double(::experience)
|
||||||
|
savetables.stateful(::upgrades)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun createMenu(containerID: Int, inventory: Inventory, ply: Player): AbstractContainerMenu {
|
override fun createMenu(containerID: Int, inventory: Inventory, ply: Player): AbstractContainerMenu {
|
||||||
|
200
src/main/kotlin/ru/dbotthepony/mc/otm/capability/Upgrades.kt
Normal file
200
src/main/kotlin/ru/dbotthepony/mc/otm/capability/Upgrades.kt
Normal file
@ -0,0 +1,200 @@
|
|||||||
|
package ru.dbotthepony.mc.otm.capability
|
||||||
|
|
||||||
|
import net.minecraft.ChatFormatting
|
||||||
|
import net.minecraft.network.chat.Component
|
||||||
|
import ru.dbotthepony.mc.otm.client.ShiftPressedCond
|
||||||
|
import ru.dbotthepony.mc.otm.config.MachinesConfig
|
||||||
|
import ru.dbotthepony.mc.otm.core.TextComponent
|
||||||
|
import ru.dbotthepony.mc.otm.core.TranslatableComponent
|
||||||
|
import ru.dbotthepony.mc.otm.core.immutableSet
|
||||||
|
import ru.dbotthepony.mc.otm.core.math.Decimal
|
||||||
|
import ru.dbotthepony.mc.otm.core.util.formatPower
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Upgrades merge by sum of their effects
|
||||||
|
*
|
||||||
|
* Values which are otherwise not stated to allow negatives or not, Do allow negative values.
|
||||||
|
*/
|
||||||
|
interface IMatteryUpgrade {
|
||||||
|
/**
|
||||||
|
* Type(s) this upgrade represent
|
||||||
|
*/
|
||||||
|
val upgradeTypes: Set<UpgradeType> get() = setOf()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* [speedBonus] of `1.0` means that machine doubles the speed (performs twice the amount of
|
||||||
|
* work ticks per work cycle).
|
||||||
|
*/
|
||||||
|
val speedBonus: Double get() = 0.0
|
||||||
|
|
||||||
|
/**
|
||||||
|
* **CAN NOT be negative.**
|
||||||
|
*
|
||||||
|
* [processingItems] of `4` means machine will accept at most 5 (1 + 4) of items per job.
|
||||||
|
*/
|
||||||
|
val processingItems: Int get() = 0
|
||||||
|
|
||||||
|
/**
|
||||||
|
* **CAM NOT be negative.**
|
||||||
|
*
|
||||||
|
* Added directly over regular energy storage capacity.
|
||||||
|
*/
|
||||||
|
val energyStorageFlat: Decimal get() = Decimal.ZERO
|
||||||
|
|
||||||
|
/**
|
||||||
|
* **CAM NOT be negative.**
|
||||||
|
*/
|
||||||
|
val energyStorage: Decimal get() = Decimal.ZERO
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Value of `1` means power consumption is doubled, `2` is tripled, `-0.5` is halved.
|
||||||
|
*/
|
||||||
|
val energyConsumed: Decimal get() = Decimal.ZERO
|
||||||
|
|
||||||
|
/**
|
||||||
|
* **CAN NOT be negative.**
|
||||||
|
*
|
||||||
|
* Added directly over regular throughput
|
||||||
|
*/
|
||||||
|
val energyThroughputFlat: Decimal get() = Decimal.ZERO
|
||||||
|
|
||||||
|
/**
|
||||||
|
* **CAN NOT be negative.**
|
||||||
|
*
|
||||||
|
* Value of `1` means power throughput is doubled, `2` is tripled, and so on.
|
||||||
|
*/
|
||||||
|
val energyThroughput: Decimal get() = Decimal.ZERO
|
||||||
|
|
||||||
|
/**
|
||||||
|
* **CAN NOT be negative.**
|
||||||
|
*
|
||||||
|
* **Merged by multiplication**
|
||||||
|
*/
|
||||||
|
val failureMultiplier: Double get() = 1.0
|
||||||
|
|
||||||
|
companion object : IMatteryUpgrade
|
||||||
|
}
|
||||||
|
|
||||||
|
fun IMatteryUpgrade.addUpgradeTooltipLines(tooltips: MutableCollection<Component>) {
|
||||||
|
if (upgradeTypes.isNotEmpty() && ShiftPressedCond.asBoolean) {
|
||||||
|
tooltips.add(TranslatableComponent("otm.gui.upgrade_type.list").withStyle(ChatFormatting.GRAY))
|
||||||
|
|
||||||
|
for (upgrade in upgradeTypes) {
|
||||||
|
tooltips.add(upgrade.component.copy().withStyle(ChatFormatting.GRAY))
|
||||||
|
}
|
||||||
|
|
||||||
|
tooltips.add(TextComponent(""))
|
||||||
|
}
|
||||||
|
|
||||||
|
if (speedBonus >= 0.01) {
|
||||||
|
tooltips.add(TranslatableComponent("otm.gui.upgrade.speed", TextComponent("+" + (speedBonus.coerceIn(MachinesConfig.Upgrades.MIN_SPEED, MachinesConfig.Upgrades.MAX_SPEED) * 100.0).toInt().toString()).withStyle(ChatFormatting.DARK_GREEN)).withStyle(ChatFormatting.GRAY))
|
||||||
|
} else if (speedBonus <= -0.01) {
|
||||||
|
tooltips.add(TranslatableComponent("otm.gui.upgrade.speed", TextComponent((speedBonus.coerceIn(MachinesConfig.Upgrades.MIN_SPEED, MachinesConfig.Upgrades.MAX_SPEED) * 100.0).toInt().toString()).withStyle(ChatFormatting.DARK_RED)).withStyle(ChatFormatting.GRAY))
|
||||||
|
}
|
||||||
|
|
||||||
|
if (processingItems != 0) {
|
||||||
|
tooltips.add(TranslatableComponent("otm.gui.upgrade.processing_items", TextComponent("+$processingItems").withStyle(ChatFormatting.DARK_GREEN)).withStyle(ChatFormatting.GRAY))
|
||||||
|
}
|
||||||
|
|
||||||
|
if (energyStorageFlat != Decimal.ZERO) {
|
||||||
|
tooltips.add(TranslatableComponent("otm.gui.upgrade.energy_storage_flat", energyStorageFlat.formatPower(formatAsReadable = ShiftPressedCond).copy().withStyle(ChatFormatting.DARK_GREEN)).withStyle(ChatFormatting.GRAY))
|
||||||
|
}
|
||||||
|
|
||||||
|
if (energyStorage != Decimal.ZERO) {
|
||||||
|
tooltips.add(TranslatableComponent("otm.gui.upgrade.energy_storage", TextComponent((energyStorage * 100).toString(0)).withStyle(ChatFormatting.DARK_GREEN)).withStyle(ChatFormatting.GRAY))
|
||||||
|
}
|
||||||
|
|
||||||
|
if (energyConsumed > Decimal.ONE) {
|
||||||
|
tooltips.add(TranslatableComponent("otm.gui.upgrade.energy_consumed", TextComponent("+" + (energyConsumed.coerceIn(MachinesConfig.Upgrades.MIN_ENERGY, MachinesConfig.Upgrades.MAX_ENERGY) * 100).toString(0)).withStyle(ChatFormatting.DARK_RED)).withStyle(ChatFormatting.GRAY))
|
||||||
|
} else if (energyConsumed < Decimal.MINUS_ONE) {
|
||||||
|
tooltips.add(TranslatableComponent("otm.gui.upgrade.energy_consumed", TextComponent((energyConsumed.coerceIn(MachinesConfig.Upgrades.MIN_ENERGY, MachinesConfig.Upgrades.MAX_ENERGY) * 100).toString(0)).withStyle(ChatFormatting.DARK_GREEN)).withStyle(ChatFormatting.GRAY))
|
||||||
|
}
|
||||||
|
|
||||||
|
if (energyThroughputFlat != Decimal.ZERO) {
|
||||||
|
tooltips.add(TranslatableComponent("otm.gui.upgrade.energy_throughput_flat", energyThroughputFlat.formatPower(formatAsReadable = ShiftPressedCond).copy().withStyle(ChatFormatting.DARK_GREEN)).withStyle(ChatFormatting.GRAY))
|
||||||
|
}
|
||||||
|
|
||||||
|
if (energyThroughput != Decimal.ZERO) {
|
||||||
|
tooltips.add(TranslatableComponent("otm.gui.upgrade.energy_throughput", TextComponent((energyThroughput * 100).toString(0)).withStyle(ChatFormatting.DARK_GREEN)).withStyle(ChatFormatting.GRAY))
|
||||||
|
}
|
||||||
|
|
||||||
|
if (failureMultiplier >= 1.01) {
|
||||||
|
tooltips.add(TranslatableComponent("otm.gui.upgrade.failsafe", TextComponent("+" + ((failureMultiplier - 1) * 100).toInt().toString()).withStyle(ChatFormatting.DARK_RED)).withStyle(ChatFormatting.GRAY))
|
||||||
|
} else if (failureMultiplier <= 0.99) {
|
||||||
|
tooltips.add(TranslatableComponent("otm.gui.upgrade.failsafe", TextComponent(((failureMultiplier.coerceAtLeast(0.0) - 1) * 100).toInt().toString()).withStyle(ChatFormatting.DARK_GREEN)).withStyle(ChatFormatting.GRAY))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun IMatteryUpgrade.getUpgradeTooltipLines(): MutableList<Component> {
|
||||||
|
return ArrayList<Component>().also { addUpgradeTooltipLines(it) }
|
||||||
|
}
|
||||||
|
|
||||||
|
enum class UpgradeType {
|
||||||
|
SPEED,
|
||||||
|
PROCESSING,
|
||||||
|
ENERGY_STORAGE,
|
||||||
|
ENERGY_CONSUMPTION,
|
||||||
|
ENERGY_THROUGHPUT,
|
||||||
|
FAILSAFE;
|
||||||
|
|
||||||
|
val localeId = "otm.gui.upgrade_type.${name.lowercase()}"
|
||||||
|
val component: Component get() = TranslatableComponent(localeId)
|
||||||
|
|
||||||
|
val flag = 1 shl (ordinal + 1)
|
||||||
|
fun set() = sets[flag]
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val cached = values()
|
||||||
|
|
||||||
|
private val sets = Array(2 shl cached.size) {
|
||||||
|
immutableSet {
|
||||||
|
for (u in values()) if (it.and(u.flag) != 0) accept(u)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmField
|
||||||
|
val ALL = set(*values())
|
||||||
|
@JvmField
|
||||||
|
val BASIC = set(SPEED, ENERGY_STORAGE, ENERGY_CONSUMPTION, ENERGY_THROUGHPUT)
|
||||||
|
|
||||||
|
fun set(vararg types: UpgradeType): Set<UpgradeType> {
|
||||||
|
var flags = 0
|
||||||
|
for (v in types) flags = flags or v.flag
|
||||||
|
return sets[flags]
|
||||||
|
}
|
||||||
|
|
||||||
|
fun set(): Set<UpgradeType> {
|
||||||
|
return sets[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
fun set(
|
||||||
|
type0: UpgradeType,
|
||||||
|
): Set<UpgradeType> = sets[type0.flag]
|
||||||
|
|
||||||
|
fun set(
|
||||||
|
type0: UpgradeType,
|
||||||
|
type1: UpgradeType,
|
||||||
|
): Set<UpgradeType> = sets[type0.flag or type1.flag]
|
||||||
|
|
||||||
|
fun set(
|
||||||
|
type0: UpgradeType,
|
||||||
|
type1: UpgradeType,
|
||||||
|
type2: UpgradeType,
|
||||||
|
): Set<UpgradeType> = sets[type0.flag or type1.flag or type2.flag]
|
||||||
|
|
||||||
|
fun set(
|
||||||
|
type0: UpgradeType,
|
||||||
|
type1: UpgradeType,
|
||||||
|
type2: UpgradeType,
|
||||||
|
type3: UpgradeType,
|
||||||
|
): Set<UpgradeType> = sets[type0.flag or type1.flag or type2.flag or type3.flag]
|
||||||
|
|
||||||
|
fun set(
|
||||||
|
type0: UpgradeType,
|
||||||
|
type1: UpgradeType,
|
||||||
|
type2: UpgradeType,
|
||||||
|
type3: UpgradeType,
|
||||||
|
type4: UpgradeType,
|
||||||
|
): Set<UpgradeType> = sets[type0.flag or type1.flag or type2.flag or type3.flag or type4.flag]
|
||||||
|
}
|
||||||
|
}
|
@ -59,7 +59,7 @@ object Widgets18 {
|
|||||||
val PATTERN_SLOT_BACKGROUND = slotBgGrid.next()
|
val PATTERN_SLOT_BACKGROUND = slotBgGrid.next()
|
||||||
val MATTER_CAPACITOR_SLOT_BACKGROUND = slotBgGrid.next()
|
val MATTER_CAPACITOR_SLOT_BACKGROUND = slotBgGrid.next()
|
||||||
|
|
||||||
private val controlsGrid = WidgetLocation.SIDE_CONTROLS.grid(rows = 7, columns = 9)
|
private val controlsGrid = WidgetLocation.SIDE_CONTROLS.grid(rows = 8, columns = 9)
|
||||||
|
|
||||||
val BATTERY_ONLY = controlsGrid.next()
|
val BATTERY_ONLY = controlsGrid.next()
|
||||||
val ITEMS_CONFIGURATION = controlsGrid.next()
|
val ITEMS_CONFIGURATION = controlsGrid.next()
|
||||||
@ -160,4 +160,6 @@ object Widgets18 {
|
|||||||
put(RelativeSide.FRONT, FRONT_CONTROLS)
|
put(RelativeSide.FRONT, FRONT_CONTROLS)
|
||||||
put(RelativeSide.BACK, BACK_CONTROLS)
|
put(RelativeSide.BACK, BACK_CONTROLS)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val UPGRADES = controlsGrid.next()
|
||||||
}
|
}
|
||||||
|
@ -319,7 +319,10 @@ abstract class MatteryScreen<T : MatteryMenu>(menu: T, inventory: Inventory, tit
|
|||||||
* @return FramePanel created, or null
|
* @return FramePanel created, or null
|
||||||
*/
|
*/
|
||||||
protected open fun makeMainFrame(): FramePanel<MatteryScreen<*>>? {
|
protected open fun makeMainFrame(): FramePanel<MatteryScreen<*>>? {
|
||||||
return FramePanel(this, null, 0f, 0f, DEFAULT_FRAME_WIDTH, DEFAULT_FRAME_HEIGHT, getTitle())
|
return FramePanel(this, null, 0f, 0f, DEFAULT_FRAME_WIDTH, DEFAULT_FRAME_HEIGHT, getTitle()).also {
|
||||||
|
it.onClose { onClose() }
|
||||||
|
it.makeCloseButton()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override fun recalculateQuickCraftRemaining() {
|
public override fun recalculateQuickCraftRemaining() {
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
package ru.dbotthepony.mc.otm.client.screen.panels
|
package ru.dbotthepony.mc.otm.client.screen.panels
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableList
|
import com.google.common.collect.ImmutableList
|
||||||
|
import com.mojang.blaze3d.platform.InputConstants
|
||||||
import com.mojang.blaze3d.systems.RenderSystem
|
import com.mojang.blaze3d.systems.RenderSystem
|
||||||
import com.mojang.blaze3d.vertex.PoseStack
|
import com.mojang.blaze3d.vertex.PoseStack
|
||||||
|
import it.unimi.dsi.fastutil.ints.IntAVLTreeSet
|
||||||
import it.unimi.dsi.fastutil.objects.ReferenceArraySet
|
import it.unimi.dsi.fastutil.objects.ReferenceArraySet
|
||||||
import net.minecraft.client.gui.ComponentPath
|
import net.minecraft.client.gui.ComponentPath
|
||||||
import net.minecraft.client.gui.Font
|
import net.minecraft.client.gui.Font
|
||||||
@ -23,6 +25,7 @@ import ru.dbotthepony.mc.otm.client.render.currentScissorRect
|
|||||||
import ru.dbotthepony.mc.otm.client.render.popScissorRect
|
import ru.dbotthepony.mc.otm.client.render.popScissorRect
|
||||||
import ru.dbotthepony.mc.otm.client.render.pushScissorRect
|
import ru.dbotthepony.mc.otm.client.render.pushScissorRect
|
||||||
import ru.dbotthepony.mc.otm.client.screen.MatteryScreen
|
import ru.dbotthepony.mc.otm.client.screen.MatteryScreen
|
||||||
|
import ru.dbotthepony.mc.otm.client.screen.panels.button.AbstractButtonPanel
|
||||||
import ru.dbotthepony.mc.otm.client.screen.panels.input.QueryUserPanel
|
import ru.dbotthepony.mc.otm.client.screen.panels.input.QueryUserPanel
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import kotlin.collections.ArrayList
|
import kotlin.collections.ArrayList
|
||||||
@ -417,6 +420,7 @@ open class EditablePanel<out S : Screen> @JvmOverloads constructor(
|
|||||||
return field
|
return field
|
||||||
}
|
}
|
||||||
|
|
||||||
|
field = null
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -965,7 +969,7 @@ open class EditablePanel<out S : Screen> @JvmOverloads constructor(
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isHovered) {
|
if (isHovered || this is AbstractButtonPanel<*> && isPressed) {
|
||||||
val tooltip = tooltip
|
val tooltip = tooltip
|
||||||
val tooltipList = tooltipList
|
val tooltipList = tooltipList
|
||||||
|
|
||||||
@ -1186,10 +1190,6 @@ open class EditablePanel<out S : Screen> @JvmOverloads constructor(
|
|||||||
this.height = height
|
this.height = height
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
|
||||||
private val LOGGER = LogManager.getLogger()!!
|
|
||||||
}
|
|
||||||
|
|
||||||
protected open fun visibilityChanges(new: Boolean, old: Boolean) {
|
protected open fun visibilityChanges(new: Boolean, old: Boolean) {
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -1589,7 +1589,7 @@ open class EditablePanel<out S : Screen> @JvmOverloads constructor(
|
|||||||
fun keyPressed(key: Int, scancode: Int, mods: Int): Boolean {
|
fun keyPressed(key: Int, scancode: Int, mods: Int): Boolean {
|
||||||
if (!isVisible() || !acceptKeyboardInput) return false
|
if (!isVisible() || !acceptKeyboardInput) return false
|
||||||
if (!isEverFocused()) return false
|
if (!isEverFocused()) return false
|
||||||
if (flashAnyBlocker(true)) return true
|
if (flashAnyBlocker(key !in ignoreFlashKeys)) return true
|
||||||
if (isFocusedThis) return keyPressedInternal(key, scancode, mods)
|
if (isFocusedThis) return keyPressedInternal(key, scancode, mods)
|
||||||
|
|
||||||
for (child in visibleChildrenInternal) {
|
for (child in visibleChildrenInternal) {
|
||||||
@ -1737,4 +1737,21 @@ open class EditablePanel<out S : Screen> @JvmOverloads constructor(
|
|||||||
fun queryUser(title: Component, text: Collection<Component>, onConfirm: Runnable, onCancel: Runnable? = null): QueryUserPanel<S> {
|
fun queryUser(title: Component, text: Collection<Component>, onConfirm: Runnable, onCancel: Runnable? = null): QueryUserPanel<S> {
|
||||||
return QueryUserPanel(screen, title, text, onConfirm, onCancel).also { blockingWindow = it }
|
return QueryUserPanel(screen, title, text, onConfirm, onCancel).also { blockingWindow = it }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val LOGGER = LogManager.getLogger()!!
|
||||||
|
|
||||||
|
private val ignoreFlashKeys = IntAVLTreeSet()
|
||||||
|
|
||||||
|
init {
|
||||||
|
ignoreFlashKeys.add(InputConstants.KEY_LEFT)
|
||||||
|
ignoreFlashKeys.add(InputConstants.KEY_RIGHT)
|
||||||
|
ignoreFlashKeys.add(InputConstants.KEY_UP)
|
||||||
|
ignoreFlashKeys.add(InputConstants.KEY_DOWN)
|
||||||
|
ignoreFlashKeys.add(InputConstants.KEY_RCONTROL)
|
||||||
|
ignoreFlashKeys.add(InputConstants.KEY_LCONTROL)
|
||||||
|
ignoreFlashKeys.add(InputConstants.KEY_RSHIFT)
|
||||||
|
ignoreFlashKeys.add(InputConstants.KEY_LSHIFT)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,8 @@ import net.minecraft.network.chat.Component
|
|||||||
import org.lwjgl.opengl.GL30
|
import org.lwjgl.opengl.GL30
|
||||||
import ru.dbotthepony.mc.otm.client.playGuiClickSound
|
import ru.dbotthepony.mc.otm.client.playGuiClickSound
|
||||||
import ru.dbotthepony.mc.otm.client.render.*
|
import ru.dbotthepony.mc.otm.client.render.*
|
||||||
|
import ru.dbotthepony.mc.otm.client.screen.panels.button.AbstractButtonPanel
|
||||||
|
import ru.dbotthepony.mc.otm.client.screen.panels.button.ButtonPanel
|
||||||
|
|
||||||
open class FramePanel<out S : Screen>(
|
open class FramePanel<out S : Screen>(
|
||||||
screen: S,
|
screen: S,
|
||||||
@ -123,6 +125,30 @@ open class FramePanel<out S : Screen>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inner class CloseButton : AbstractButtonPanel<S>(screen, this@FramePanel, this@FramePanel.width - CLOSE_BUTTON.width, 0f, CLOSE_BUTTON.width, CLOSE_BUTTON.height) {
|
||||||
|
override fun onClick(mouseButton: Int) {
|
||||||
|
close()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun innerRender(graphics: GuiGraphics, mouseX: Float, mouseY: Float, partialTick: Float) {
|
||||||
|
if (isPressed) {
|
||||||
|
CLOSE_BUTTON_PRESSED.render(graphics, 0f, 0f, width, height)
|
||||||
|
} else if (isHovered) {
|
||||||
|
CLOSE_BUTTON_HOVERED.render(graphics, 0f, 0f, width, height)
|
||||||
|
} else {
|
||||||
|
CLOSE_BUTTON.render(graphics, 0f, 0f, width, height)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onRemoved() {
|
||||||
|
super.onRemoved()
|
||||||
|
|
||||||
|
if (closeButton == this) {
|
||||||
|
closeButton = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected val tabs: java.util.ArrayList<Tab> = ArrayList()
|
protected val tabs: java.util.ArrayList<Tab> = ArrayList()
|
||||||
|
|
||||||
override fun performLayout() {
|
override fun performLayout() {
|
||||||
@ -131,13 +157,29 @@ open class FramePanel<out S : Screen>(
|
|||||||
tab.initial = i == 0
|
tab.initial = i == 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
closeButton?.setPos(width - CLOSE_BUTTON.width, 0f)
|
||||||
|
|
||||||
super.performLayout()
|
super.performLayout()
|
||||||
}
|
}
|
||||||
|
|
||||||
protected var dragging = false
|
protected var dragging = false
|
||||||
|
protected var closeButton: CloseButton? = null
|
||||||
|
|
||||||
var closeOnEscape = false
|
var closeOnEscape = false
|
||||||
|
|
||||||
|
fun makeCloseButton() {
|
||||||
|
if (closeButton == null)
|
||||||
|
closeButton = CloseButton()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds close button and makes panel [close] when user presses ESC with this panel focused
|
||||||
|
*/
|
||||||
|
fun behaveAsWindow() {
|
||||||
|
closeOnEscape = true
|
||||||
|
makeCloseButton()
|
||||||
|
}
|
||||||
|
|
||||||
init {
|
init {
|
||||||
setDockPadding(PADDING, if (title != null) PADDING_TOP else PADDING, PADDING, PADDING)
|
setDockPadding(PADDING, if (title != null) PADDING_TOP else PADDING, PADDING, PADDING)
|
||||||
}
|
}
|
||||||
@ -187,9 +229,24 @@ open class FramePanel<out S : Screen>(
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected val closeCallbacks = ArrayList<Runnable>()
|
||||||
|
|
||||||
|
fun onClose(callback: Runnable) {
|
||||||
|
closeCallbacks.add(callback)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Usually just calls [remove]
|
||||||
|
*/
|
||||||
|
open fun close() {
|
||||||
|
if (isRemoved) return
|
||||||
|
remove()
|
||||||
|
closeCallbacks.forEach { it.run() }
|
||||||
|
}
|
||||||
|
|
||||||
override fun keyPressedInternal(key: Int, scancode: Int, mods: Int): Boolean {
|
override fun keyPressedInternal(key: Int, scancode: Int, mods: Int): Boolean {
|
||||||
if (key == InputConstants.KEY_ESCAPE && closeOnEscape) {
|
if (key == InputConstants.KEY_ESCAPE && closeOnEscape) {
|
||||||
remove()
|
close()
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -262,6 +319,10 @@ open class FramePanel<out S : Screen>(
|
|||||||
val TAB_LEFT_CONNECTION = WidgetLocation.MISC.sprite(x = 33f, y = 0f, width = 3f, height = 5f)
|
val TAB_LEFT_CONNECTION = WidgetLocation.MISC.sprite(x = 33f, y = 0f, width = 3f, height = 5f)
|
||||||
val TAB_BACKGROUND = WidgetLocation.MISC.sprite(x = 30f, y = 6f, width = 6f, height = 6f)
|
val TAB_BACKGROUND = WidgetLocation.MISC.sprite(x = 30f, y = 6f, width = 6f, height = 6f)
|
||||||
|
|
||||||
|
val CLOSE_BUTTON = WidgetLocation.MISC.sprite(x = 51f, y = 0f, width = 13f, height = 11f)
|
||||||
|
val CLOSE_BUTTON_HOVERED = WidgetLocation.MISC.sprite(x = 51f, y = 11f, width = 13f, height = 11f)
|
||||||
|
val CLOSE_BUTTON_PRESSED = WidgetLocation.MISC.sprite(x = 51f, y = 22f, width = 13f, height = 11f)
|
||||||
|
|
||||||
const val TAB_HEIGHT = 28f
|
const val TAB_HEIGHT = 28f
|
||||||
const val TAB_WIDTH = 28f
|
const val TAB_WIDTH = 28f
|
||||||
const val TAB_HEIGHT_ACTIVE = 32f
|
const val TAB_HEIGHT_ACTIVE = 32f
|
||||||
|
@ -3,26 +3,38 @@ package ru.dbotthepony.mc.otm.client.screen.panels.button
|
|||||||
import com.mojang.blaze3d.platform.InputConstants
|
import com.mojang.blaze3d.platform.InputConstants
|
||||||
import net.minecraft.ChatFormatting
|
import net.minecraft.ChatFormatting
|
||||||
import net.minecraft.client.gui.GuiGraphics
|
import net.minecraft.client.gui.GuiGraphics
|
||||||
|
import net.minecraft.network.chat.Component
|
||||||
import ru.dbotthepony.mc.otm.block.entity.MatteryDeviceBlockEntity
|
import ru.dbotthepony.mc.otm.block.entity.MatteryDeviceBlockEntity
|
||||||
import ru.dbotthepony.mc.otm.block.entity.RedstoneSetting
|
import ru.dbotthepony.mc.otm.block.entity.RedstoneSetting
|
||||||
import ru.dbotthepony.mc.otm.capability.FlowDirection
|
import ru.dbotthepony.mc.otm.capability.FlowDirection
|
||||||
|
import ru.dbotthepony.mc.otm.capability.addUpgradeTooltipLines
|
||||||
import ru.dbotthepony.mc.otm.client.isCtrlDown
|
import ru.dbotthepony.mc.otm.client.isCtrlDown
|
||||||
import ru.dbotthepony.mc.otm.client.isShiftDown
|
import ru.dbotthepony.mc.otm.client.isShiftDown
|
||||||
import ru.dbotthepony.mc.otm.client.minecraft
|
import ru.dbotthepony.mc.otm.client.minecraft
|
||||||
import ru.dbotthepony.mc.otm.client.render.AbstractMatterySprite
|
import ru.dbotthepony.mc.otm.client.render.AbstractMatterySprite
|
||||||
import ru.dbotthepony.mc.otm.client.render.Widgets18
|
import ru.dbotthepony.mc.otm.client.render.Widgets18
|
||||||
import ru.dbotthepony.mc.otm.client.screen.MatteryScreen
|
import ru.dbotthepony.mc.otm.client.screen.MatteryScreen
|
||||||
|
import ru.dbotthepony.mc.otm.client.screen.panels.Dock
|
||||||
|
import ru.dbotthepony.mc.otm.client.screen.panels.DockResizeMode
|
||||||
import ru.dbotthepony.mc.otm.client.screen.panels.EditablePanel
|
import ru.dbotthepony.mc.otm.client.screen.panels.EditablePanel
|
||||||
import ru.dbotthepony.mc.otm.client.screen.panels.FramePanel
|
import ru.dbotthepony.mc.otm.client.screen.panels.FramePanel
|
||||||
|
import ru.dbotthepony.mc.otm.client.screen.panels.slot.AbstractSlotPanel
|
||||||
|
import ru.dbotthepony.mc.otm.client.screen.panels.slot.SlotPanel
|
||||||
|
import ru.dbotthepony.mc.otm.client.screen.panels.util.GridPanel
|
||||||
import ru.dbotthepony.mc.otm.core.GetterSetter
|
import ru.dbotthepony.mc.otm.core.GetterSetter
|
||||||
|
import ru.dbotthepony.mc.otm.core.TextComponent
|
||||||
import ru.dbotthepony.mc.otm.core.TranslatableComponent
|
import ru.dbotthepony.mc.otm.core.TranslatableComponent
|
||||||
import ru.dbotthepony.mc.otm.core.math.RelativeSide
|
import ru.dbotthepony.mc.otm.core.math.RelativeSide
|
||||||
|
import ru.dbotthepony.mc.otm.core.value
|
||||||
|
import ru.dbotthepony.mc.otm.menu.UpgradeSlots
|
||||||
import ru.dbotthepony.mc.otm.menu.input.BooleanInputWithFeedback
|
import ru.dbotthepony.mc.otm.menu.input.BooleanInputWithFeedback
|
||||||
import ru.dbotthepony.mc.otm.menu.input.EnergyConfigPlayerInput
|
import ru.dbotthepony.mc.otm.menu.input.EnergyConfigPlayerInput
|
||||||
import ru.dbotthepony.mc.otm.menu.input.FluidConfigPlayerInput
|
import ru.dbotthepony.mc.otm.menu.input.FluidConfigPlayerInput
|
||||||
import ru.dbotthepony.mc.otm.menu.input.IPlayerInputWithFeedback
|
import ru.dbotthepony.mc.otm.menu.input.IPlayerInputWithFeedback
|
||||||
import ru.dbotthepony.mc.otm.menu.input.ItemConfigPlayerInput
|
import ru.dbotthepony.mc.otm.menu.input.ItemConfigPlayerInput
|
||||||
import java.util.function.Predicate
|
import java.util.function.Predicate
|
||||||
|
import kotlin.math.ceil
|
||||||
|
import kotlin.math.pow
|
||||||
|
|
||||||
private fun <S : MatteryScreen<*>> makeRedstoneSettingButton(
|
private fun <S : MatteryScreen<*>> makeRedstoneSettingButton(
|
||||||
screen: S,
|
screen: S,
|
||||||
@ -212,6 +224,7 @@ private fun <S : MatteryScreen<*>> makeItemHandlerControlPanel(
|
|||||||
moveButtons(front, back, left, right, top, bottom)
|
moveButtons(front, back, left, right, top, bottom)
|
||||||
screen.addPanel(frame)
|
screen.addPanel(frame)
|
||||||
frame.requestFocus()
|
frame.requestFocus()
|
||||||
|
frame.closeOnEscape = true
|
||||||
|
|
||||||
return frame
|
return frame
|
||||||
}
|
}
|
||||||
@ -240,6 +253,7 @@ private fun <S : MatteryScreen<*>> makeEnergyConfigPanel(
|
|||||||
moveButtons(front, back, left, right, top, bottom)
|
moveButtons(front, back, left, right, top, bottom)
|
||||||
screen.addPanel(frame)
|
screen.addPanel(frame)
|
||||||
frame.requestFocus()
|
frame.requestFocus()
|
||||||
|
frame.closeOnEscape = true
|
||||||
|
|
||||||
return frame
|
return frame
|
||||||
}
|
}
|
||||||
@ -268,6 +282,7 @@ private fun <S : MatteryScreen<*>> makeFluidConfigPanel(
|
|||||||
moveButtons(front, back, left, right, top, bottom)
|
moveButtons(front, back, left, right, top, bottom)
|
||||||
screen.addPanel(frame)
|
screen.addPanel(frame)
|
||||||
frame.requestFocus()
|
frame.requestFocus()
|
||||||
|
frame.closeOnEscape = true
|
||||||
|
|
||||||
return frame
|
return frame
|
||||||
}
|
}
|
||||||
@ -281,12 +296,17 @@ class DeviceControls<out S : MatteryScreen<*>>(
|
|||||||
val energyConfig: EnergyConfigPlayerInput? = null,
|
val energyConfig: EnergyConfigPlayerInput? = null,
|
||||||
val fluidConfig: FluidConfigPlayerInput? = null,
|
val fluidConfig: FluidConfigPlayerInput? = null,
|
||||||
val balanceInputs: BooleanInputWithFeedback? = null,
|
val balanceInputs: BooleanInputWithFeedback? = null,
|
||||||
|
val upgrades: UpgradeSlots? = null,
|
||||||
) : EditablePanel<S>(screen, parent, x = parent.width + 3f, height = 0f, width = 0f) {
|
) : EditablePanel<S>(screen, parent, x = parent.width + 3f, height = 0f, width = 0f) {
|
||||||
val itemConfigButton: LargeRectangleButtonPanel<S>?
|
val itemConfigButton: LargeRectangleButtonPanel<S>?
|
||||||
val energyConfigButton: LargeRectangleButtonPanel<S>?
|
val energyConfigButton: LargeRectangleButtonPanel<S>?
|
||||||
val fluidConfigButton: LargeRectangleButtonPanel<S>?
|
val fluidConfigButton: LargeRectangleButtonPanel<S>?
|
||||||
val redstoneControlsButton: LargeEnumRectangleButtonPanel<S, RedstoneSetting>?
|
val redstoneControlsButton: LargeEnumRectangleButtonPanel<S, RedstoneSetting>?
|
||||||
val balanceInputsButton: LargeBooleanRectangleButtonPanel<S>?
|
val balanceInputsButton: LargeBooleanRectangleButtonPanel<S>?
|
||||||
|
val upgradesButton: LargeRectangleButtonPanel<S>?
|
||||||
|
|
||||||
|
private var upgradeWindow: FramePanel<S>? = null
|
||||||
|
|
||||||
private var nextY = 0f
|
private var nextY = 0f
|
||||||
|
|
||||||
fun <P : EditablePanel<@UnsafeVariance S>> addButton(button: P): P {
|
fun <P : EditablePanel<@UnsafeVariance S>> addButton(button: P): P {
|
||||||
@ -310,6 +330,82 @@ class DeviceControls<out S : MatteryScreen<*>>(
|
|||||||
redstoneControlsButton = null
|
redstoneControlsButton = null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (upgrades != null) {
|
||||||
|
upgradesButton = addButton(object : LargeRectangleButtonPanel<S>(
|
||||||
|
screen, this@DeviceControls,
|
||||||
|
skinElement = Widgets18.UPGRADES
|
||||||
|
) {
|
||||||
|
init {
|
||||||
|
tooltip = TranslatableComponent("otm.gui.upgrades")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun tickInner() {
|
||||||
|
super.tickInner()
|
||||||
|
|
||||||
|
tooltipList = ArrayList<Component>().also {
|
||||||
|
it.add(TranslatableComponent("otm.gui.upgrades"))
|
||||||
|
it.add(TextComponent(""))
|
||||||
|
|
||||||
|
if (upgrades.allowedTypes.isEmpty()) {
|
||||||
|
it.add(TranslatableComponent("otm.gui.upgrade_type.allowed_none").withStyle(ChatFormatting.DARK_GRAY))
|
||||||
|
} else {
|
||||||
|
it.add(TranslatableComponent("otm.gui.upgrade_type.allowed").withStyle(ChatFormatting.GRAY))
|
||||||
|
|
||||||
|
for (upgrade in upgrades.allowedTypes) {
|
||||||
|
it.add(upgrade.component.copy().withStyle(ChatFormatting.GRAY))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val i = it.size
|
||||||
|
upgrades.currentStats.addUpgradeTooltipLines(it)
|
||||||
|
|
||||||
|
if (it.size != i) {
|
||||||
|
it.add(i, TranslatableComponent("otm.gui.upgrades.current").withStyle(ChatFormatting.GRAY))
|
||||||
|
it.add(i, TextComponent(""))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onClick(mouseButton: Int) {
|
||||||
|
if (mouseButton == InputConstants.MOUSE_BUTTON_LEFT) {
|
||||||
|
if (upgradeWindow != null && !upgradeWindow!!.isRemoved) {
|
||||||
|
upgradeWindow!!.toScreenCenter()
|
||||||
|
upgradeWindow!!.popup()
|
||||||
|
} else {
|
||||||
|
val square = ceil(upgrades.slots.size.toDouble().pow(0.5)).toInt()
|
||||||
|
val size = square * AbstractSlotPanel.SIZE
|
||||||
|
|
||||||
|
upgradeWindow = FramePanel(screen, (size + 40f).coerceAtLeast(120f), 30f + size, TranslatableComponent("otm.gui.upgrades")).also { frame ->
|
||||||
|
val grid = GridPanel(screen, frame, width = AbstractSlotPanel.SIZE * square, height = AbstractSlotPanel.SIZE * square, columns = square, rows = square)
|
||||||
|
|
||||||
|
for (slot in upgrades.slots) {
|
||||||
|
SlotPanel(screen, grid, slot)
|
||||||
|
}
|
||||||
|
|
||||||
|
grid.dock = Dock.FILL
|
||||||
|
grid.dockResize = DockResizeMode.NONE
|
||||||
|
|
||||||
|
screen.addPanel(frame)
|
||||||
|
|
||||||
|
val parentFrame = this@DeviceControls.parent!!
|
||||||
|
|
||||||
|
frame.behaveAsWindow()
|
||||||
|
frame.setPos(parentFrame.absoluteX + parentFrame.width / 2f - frame.width / 2f, parentFrame.absoluteY + parentFrame.height / 2f - frame.height / 2f)
|
||||||
|
frame.popup()
|
||||||
|
|
||||||
|
upgrades.openState.value = true
|
||||||
|
frame.onClose { upgrades.openState.value = false }
|
||||||
|
|
||||||
|
parentFrame.blockingWindow = frame
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
upgradesButton = null
|
||||||
|
}
|
||||||
|
|
||||||
if (balanceInputs != null) {
|
if (balanceInputs != null) {
|
||||||
balanceInputsButton = addButton(LargeBooleanRectangleButtonPanel(
|
balanceInputsButton = addButton(LargeBooleanRectangleButtonPanel(
|
||||||
screen, this,
|
screen, this,
|
||||||
@ -396,8 +492,9 @@ fun <S : MatteryScreen<*>> makeDeviceControls(
|
|||||||
energyConfig: EnergyConfigPlayerInput? = null,
|
energyConfig: EnergyConfigPlayerInput? = null,
|
||||||
fluidConfig: FluidConfigPlayerInput? = null,
|
fluidConfig: FluidConfigPlayerInput? = null,
|
||||||
balanceInputs: BooleanInputWithFeedback? = null,
|
balanceInputs: BooleanInputWithFeedback? = null,
|
||||||
|
upgrades: UpgradeSlots? = null,
|
||||||
): DeviceControls<S> {
|
): DeviceControls<S> {
|
||||||
return DeviceControls(screen, parent, extra = extra, redstoneConfig = redstoneConfig,
|
return DeviceControls(screen, parent, extra = extra, redstoneConfig = redstoneConfig,
|
||||||
itemConfig = itemConfig, energyConfig = energyConfig, fluidConfig = fluidConfig,
|
itemConfig = itemConfig, energyConfig = energyConfig, fluidConfig = fluidConfig,
|
||||||
balanceInputs = balanceInputs)
|
balanceInputs = balanceInputs, upgrades = upgrades)
|
||||||
}
|
}
|
||||||
|
@ -63,6 +63,7 @@ open class QueryUserPanel<out S: Screen>(
|
|||||||
this.width = maxWidth.coerceAtLeast(bottom.children.stream().mapToDouble { it.width.toDouble() }.sum().toFloat() + 2f) + PADDING * 2f
|
this.width = maxWidth.coerceAtLeast(bottom.children.stream().mapToDouble { it.width.toDouble() }.sum().toFloat() + 2f) + PADDING * 2f
|
||||||
|
|
||||||
toScreenCenter()
|
toScreenCenter()
|
||||||
|
behaveAsWindow()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun keyPressedInternal(key: Int, scancode: Int, mods: Int): Boolean {
|
override fun keyPressedInternal(key: Int, scancode: Int, mods: Int): Boolean {
|
||||||
|
@ -636,7 +636,7 @@ class AndroidStationScreen constructor(p_97741_: AndroidStationMenu, p_97742_: I
|
|||||||
researchCanvas.setDockMargin(4f, 4f, 4f, 4f)
|
researchCanvas.setDockMargin(4f, 4f, 4f, 4f)
|
||||||
|
|
||||||
research!!.toScreenCenter()
|
research!!.toScreenCenter()
|
||||||
research!!.closeOnEscape = true
|
research!!.behaveAsWindow()
|
||||||
addPanel(research!!)
|
addPanel(research!!)
|
||||||
research!!.requestFocus()
|
research!!.requestFocus()
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,6 @@ import ru.dbotthepony.mc.otm.client.screen.panels.FramePanel
|
|||||||
import ru.dbotthepony.mc.otm.client.screen.panels.button.makeDeviceControls
|
import ru.dbotthepony.mc.otm.client.screen.panels.button.makeDeviceControls
|
||||||
import ru.dbotthepony.mc.otm.client.screen.panels.slot.SlotPanel
|
import ru.dbotthepony.mc.otm.client.screen.panels.slot.SlotPanel
|
||||||
import ru.dbotthepony.mc.otm.client.screen.widget.ProgressGaugePanel
|
import ru.dbotthepony.mc.otm.client.screen.widget.ProgressGaugePanel
|
||||||
import ru.dbotthepony.mc.otm.client.screen.widget.WidePowerGaugePanel
|
|
||||||
import ru.dbotthepony.mc.otm.client.screen.widget.WideProfiledPowerGaugePanel
|
import ru.dbotthepony.mc.otm.client.screen.widget.WideProfiledPowerGaugePanel
|
||||||
import ru.dbotthepony.mc.otm.menu.tech.PlatePressMenu
|
import ru.dbotthepony.mc.otm.menu.tech.PlatePressMenu
|
||||||
|
|
||||||
@ -24,7 +23,7 @@ class PlatePressScreen(menu: PlatePressMenu, inventory: Inventory, title: Compon
|
|||||||
ProgressGaugePanel(this, frame, menu.progressGauge, 78f, PROGRESS_ARROW_TOP)
|
ProgressGaugePanel(this, frame, menu.progressGauge, 78f, PROGRESS_ARROW_TOP)
|
||||||
SlotPanel(this, frame, menu.outputSlot, 104f, PROGRESS_SLOT_TOP)
|
SlotPanel(this, frame, menu.outputSlot, 104f, PROGRESS_SLOT_TOP)
|
||||||
|
|
||||||
makeDeviceControls(this, frame, redstoneConfig = menu.redstoneConfig, energyConfig = menu.energyConfig, itemConfig = menu.itemConfig)
|
makeDeviceControls(this, frame, redstoneConfig = menu.redstoneConfig, energyConfig = menu.energyConfig, itemConfig = menu.itemConfig, upgrades = menu.upgrades)
|
||||||
|
|
||||||
return frame
|
return frame
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,7 @@ class TwinPlatePressScreen(menu: TwinPlatePressMenu, inventory: Inventory, title
|
|||||||
ProgressGaugePanel(this, frame, menu.progressGauge1, 78f, PROGRESS_ARROW_TOP + 10f)
|
ProgressGaugePanel(this, frame, menu.progressGauge1, 78f, PROGRESS_ARROW_TOP + 10f)
|
||||||
SlotPanel(this, frame, menu.outputSlots[1], 104f, PROGRESS_SLOT_TOP + 10f)
|
SlotPanel(this, frame, menu.outputSlots[1], 104f, PROGRESS_SLOT_TOP + 10f)
|
||||||
|
|
||||||
makeDeviceControls(this, frame, redstoneConfig = menu.redstoneConfig, energyConfig = menu.energyConfig, itemConfig = menu.itemConfig, balanceInputs = menu.balanceInputs)
|
makeDeviceControls(this, frame, redstoneConfig = menu.redstoneConfig, energyConfig = menu.energyConfig, itemConfig = menu.itemConfig, balanceInputs = menu.balanceInputs, upgrades = menu.upgrades)
|
||||||
|
|
||||||
return frame
|
return frame
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,7 @@ import ru.dbotthepony.mc.otm.block.entity.tech.AndroidStationBlockEntity
|
|||||||
import ru.dbotthepony.mc.otm.block.entity.tech.ChemicalGeneratorBlockEntity
|
import ru.dbotthepony.mc.otm.block.entity.tech.ChemicalGeneratorBlockEntity
|
||||||
import ru.dbotthepony.mc.otm.capability.energy.BlockEnergyStorageImpl
|
import ru.dbotthepony.mc.otm.capability.energy.BlockEnergyStorageImpl
|
||||||
import ru.dbotthepony.mc.otm.core.math.Decimal
|
import ru.dbotthepony.mc.otm.core.math.Decimal
|
||||||
|
import ru.dbotthepony.mc.otm.core.math.defineDecimal
|
||||||
import ru.dbotthepony.mc.otm.registry.MNames
|
import ru.dbotthepony.mc.otm.registry.MNames
|
||||||
|
|
||||||
object MachinesConfig : AbstractConfig("machines") {
|
object MachinesConfig : AbstractConfig("machines") {
|
||||||
@ -42,4 +43,34 @@ object MachinesConfig : AbstractConfig("machines") {
|
|||||||
}
|
}
|
||||||
|
|
||||||
val ANDROID_CHARGER = BlockEnergyStorageImpl.makeConfigEntry(builder, MNames.ANDROID_CHARGER, capacity = Decimal(400_000), throughput = Decimal(8192)) { AndroidCharger }
|
val ANDROID_CHARGER = BlockEnergyStorageImpl.makeConfigEntry(builder, MNames.ANDROID_CHARGER, capacity = Decimal(400_000), throughput = Decimal(8192)) { AndroidCharger }
|
||||||
|
|
||||||
|
object Upgrades {
|
||||||
|
init {
|
||||||
|
builder.push("UPGRADES")
|
||||||
|
}
|
||||||
|
|
||||||
|
val MIN_SPEED: Double by builder
|
||||||
|
.comment("Minimal combined upgrade speed percentage (upgrades can't decrease machine speed below this)")
|
||||||
|
.defineInRange("MIN_SPEED", -0.8, -1.0, Double.MAX_VALUE)
|
||||||
|
|
||||||
|
val MAX_SPEED: Double by builder
|
||||||
|
.comment("Maximal combined upgrade speed percentage")
|
||||||
|
.defineInRange("MAX_SPEED", Double.MAX_VALUE, 0.0, Double.MAX_VALUE)
|
||||||
|
|
||||||
|
val MIN_ENERGY by builder
|
||||||
|
.comment("Minimal combined energy consumption percentage (upgrades can't decrease machine energy consumption below this)")
|
||||||
|
.defineDecimal("MIN_ENERGY", Decimal(-0.8), Decimal(-1.0))
|
||||||
|
|
||||||
|
val MAX_ENERGY by builder
|
||||||
|
.comment("Maximal combined energy consumption percentage")
|
||||||
|
.defineDecimal("MAX_ENERGY", Decimal.LONG_MAX_VALUE, Decimal.ZERO)
|
||||||
|
|
||||||
|
init {
|
||||||
|
builder.pop()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
Upgrades
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,54 @@
|
|||||||
|
package ru.dbotthepony.mc.otm.container
|
||||||
|
|
||||||
|
import ru.dbotthepony.mc.otm.capability.IMatteryUpgrade
|
||||||
|
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
||||||
|
import ru.dbotthepony.mc.otm.capability.UpgradeType
|
||||||
|
import ru.dbotthepony.mc.otm.config.ConciseBalanceValues
|
||||||
|
import ru.dbotthepony.mc.otm.config.VerboseBalanceValues
|
||||||
|
import ru.dbotthepony.mc.otm.core.isNotEmpty
|
||||||
|
import ru.dbotthepony.mc.otm.core.math.Decimal
|
||||||
|
import kotlin.math.pow
|
||||||
|
|
||||||
|
open class UpgradeContainer(slotCount: Int, open val allowedUpgrades: Set<UpgradeType> = UpgradeType.ALL, watcher: Runnable = Runnable {}) : MatteryContainer(watcher, slotCount), IMatteryUpgrade {
|
||||||
|
constructor(watcher: Runnable, slotCount: Int, allowedUpgrades: Set<UpgradeType>) : this(slotCount, allowedUpgrades, watcher)
|
||||||
|
|
||||||
|
final override val upgradeTypes: Set<UpgradeType>
|
||||||
|
get() = setOf()
|
||||||
|
|
||||||
|
override val speedBonus: Double
|
||||||
|
get() = stream().filter { it.isNotEmpty }.mapToDouble { it.getCapability(MatteryCapability.UPGRADE).map { it.speedBonus }.orElse(0.0) * it.count }.sum()
|
||||||
|
override val processingItems: Int
|
||||||
|
get() = stream().filter { it.isNotEmpty }.mapToInt { it.getCapability(MatteryCapability.UPGRADE).map { it.processingItems }.orElse(0).coerceAtLeast(0) * it.count }.sum()
|
||||||
|
override val energyStorageFlat: Decimal
|
||||||
|
get() = stream().filter { it.isNotEmpty }.map { it.getCapability(MatteryCapability.UPGRADE).map { it.energyStorageFlat }.orElse(Decimal.ZERO).moreThanZero() * it.count }.reduce(Decimal.ZERO, Decimal::plus)
|
||||||
|
override val energyStorage: Decimal
|
||||||
|
get() = stream().filter { it.isNotEmpty }.map { it.getCapability(MatteryCapability.UPGRADE).map { it.energyStorage }.orElse(Decimal.ZERO).moreThanZero() * it.count }.reduce(Decimal.ZERO, Decimal::plus)
|
||||||
|
override val energyConsumed: Decimal
|
||||||
|
get() = stream().filter { it.isNotEmpty }.map { it.getCapability(MatteryCapability.UPGRADE).map { it.energyConsumed }.orElse(Decimal.ZERO) * it.count }.reduce(Decimal.ZERO, Decimal::plus)
|
||||||
|
override val failureMultiplier: Double
|
||||||
|
get() = stream().filter { it.isNotEmpty }.mapToDouble { it.getCapability(MatteryCapability.UPGRADE).map { it.failureMultiplier }.orElse(1.0).coerceAtLeast(0.0).pow(it.count.toDouble()) }.reduce(1.0) { a, b -> a * b }
|
||||||
|
override val energyThroughputFlat: Decimal
|
||||||
|
get() = stream().filter { it.isNotEmpty }.map { it.getCapability(MatteryCapability.UPGRADE).map { it.energyThroughputFlat }.orElse(Decimal.ZERO).moreThanZero() * it.count }.reduce(Decimal.ZERO, Decimal::plus)
|
||||||
|
override val energyThroughput: Decimal
|
||||||
|
get() = stream().filter { it.isNotEmpty }.map { it.getCapability(MatteryCapability.UPGRADE).map { it.energyThroughput }.orElse(Decimal.ZERO).moreThanZero() * it.count }.reduce(Decimal.ZERO, Decimal::plus)
|
||||||
|
|
||||||
|
fun transform(values: ConciseBalanceValues): ConciseBalanceValues {
|
||||||
|
return object : ConciseBalanceValues {
|
||||||
|
override val capacity: Decimal
|
||||||
|
get() = values.capacity * (energyStorage + Decimal.ONE) + energyStorageFlat
|
||||||
|
override val throughput: Decimal
|
||||||
|
get() = values.throughput * (energyThroughput + Decimal.ONE) + energyThroughputFlat
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun transform(values: VerboseBalanceValues): VerboseBalanceValues {
|
||||||
|
return object : VerboseBalanceValues {
|
||||||
|
override val capacity: Decimal
|
||||||
|
get() = values.capacity * (energyStorage + Decimal.ONE) + energyStorageFlat
|
||||||
|
override val receive: Decimal
|
||||||
|
get() = values.receive * (energyThroughput + Decimal.ONE) + energyThroughputFlat
|
||||||
|
override val extract: Decimal
|
||||||
|
get() = values.extract * (energyThroughput + Decimal.ONE) + energyThroughputFlat
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -91,8 +91,8 @@ inline fun <T> LazyOptional<T>.ifPresentK(lambda: (T) -> Unit) {
|
|||||||
|
|
||||||
val ItemStack.tagNotNull: CompoundTag get() = orCreateTag
|
val ItemStack.tagNotNull: CompoundTag get() = orCreateTag
|
||||||
|
|
||||||
val FluidStack.isNotEmpty get() = !isEmpty
|
inline val FluidStack.isNotEmpty get() = !isEmpty
|
||||||
val ItemStack.isNotEmpty get() = !isEmpty
|
inline val ItemStack.isNotEmpty get() = !isEmpty
|
||||||
|
|
||||||
inline var Entity.position: Vec3
|
inline var Entity.position: Vec3
|
||||||
get() = position()
|
get() = position()
|
||||||
|
@ -0,0 +1,41 @@
|
|||||||
|
package ru.dbotthepony.mc.otm.core.collect
|
||||||
|
|
||||||
|
import java.util.EnumMap
|
||||||
|
import java.util.function.BooleanSupplier
|
||||||
|
import java.util.stream.Stream
|
||||||
|
|
||||||
|
class ConditionalEnumSet<T : Enum<T>>private constructor(private val backing: EnumMap<T, BooleanSupplier>, marker: Unit) : Set<T> {
|
||||||
|
constructor(clazz: Class<T>) : this(EnumMap(clazz), Unit)
|
||||||
|
constructor(map: Map<T, BooleanSupplier>) : this(EnumMap(map), Unit)
|
||||||
|
|
||||||
|
override val size: Int
|
||||||
|
get() = backing.values.stream().filter { it.asBoolean }.count().toInt()
|
||||||
|
|
||||||
|
override fun contains(element: T): Boolean {
|
||||||
|
return backing[element]?.asBoolean ?: false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun containsAll(elements: Collection<T>): Boolean {
|
||||||
|
return elements.all { contains(it) }
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun isEmpty(): Boolean {
|
||||||
|
return backing.isEmpty() || backing.values.none { it.asBoolean }
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun stream(): Stream<T> {
|
||||||
|
return backing.entries.stream().filter { it.value.asBoolean }.map { it.key }
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun iterator(): Iterator<T> {
|
||||||
|
return backing.entries.iterator().filter { it.value.asBoolean }.map { it.key }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun add(value: T, condition: BooleanSupplier) {
|
||||||
|
backing[value] = condition
|
||||||
|
}
|
||||||
|
|
||||||
|
fun remove(value: T): Boolean {
|
||||||
|
return backing.remove(value) != null
|
||||||
|
}
|
||||||
|
}
|
@ -1,68 +1,57 @@
|
|||||||
package ru.dbotthepony.mc.otm.core.collect
|
package ru.dbotthepony.mc.otm.core.collect
|
||||||
|
|
||||||
|
import it.unimi.dsi.fastutil.objects.Object2ObjectLinkedOpenHashMap
|
||||||
|
import java.util.function.BooleanSupplier
|
||||||
import java.util.stream.Stream
|
import java.util.stream.Stream
|
||||||
|
|
||||||
class ConditionalSet<T> : AbstractSet<T> {
|
class ConditionalSet<E : Any> : Set<E> {
|
||||||
// method without boxing
|
private val backing = Object2ObjectLinkedOpenHashMap<E, BooleanSupplier>()
|
||||||
fun interface Condition {
|
|
||||||
fun check(): Boolean
|
override val size: Int
|
||||||
|
get() = backing.values.stream().filter { it.asBoolean }.count().toInt()
|
||||||
|
|
||||||
|
override fun contains(element: E): Boolean {
|
||||||
|
return backing[element]?.asBoolean ?: false
|
||||||
}
|
}
|
||||||
|
|
||||||
private val getters: Array<Pair<Condition, T>>
|
override fun containsAll(elements: Collection<E>): Boolean {
|
||||||
|
return elements.all { contains(it) }
|
||||||
constructor(vararg getters: Pair<Condition, T>) : super() {
|
|
||||||
this.getters = Array(getters.size) { getters[it] }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(getters: List<Pair<Condition, T>>) : super() {
|
override fun isEmpty(): Boolean {
|
||||||
this.getters = Array(getters.size) { getters[it] }
|
return backing.isEmpty() || backing.values.stream().noneMatch { it.asBoolean }
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(getters: Stream<Pair<Condition, T>>) : super() {
|
override fun stream(): Stream<E> {
|
||||||
this.getters = getters.toArray { arrayOfNulls<Pair<Condition, T>>(it) }
|
return backing.entries.stream().filter { it.value.asBoolean }.map { it.key }
|
||||||
}
|
}
|
||||||
|
|
||||||
override val size: Int get() {
|
override fun iterator(): Iterator<E> {
|
||||||
var i = 0
|
return backing.entries.iterator().filter { it.value.asBoolean }.map { it.key }
|
||||||
|
|
||||||
for (pair in getters) {
|
|
||||||
if (pair.first.check()) {
|
|
||||||
i++
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return i
|
fun add(element: E, condition: BooleanSupplier): Boolean {
|
||||||
|
if (element in backing) return false
|
||||||
|
backing[element] = condition
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun iterator(): Iterator<T> {
|
fun addFirst(element: E, condition: BooleanSupplier): Boolean {
|
||||||
return object : Iterator<T> {
|
if (element in backing) return false
|
||||||
val parent = getters.iterator()
|
backing.putAndMoveToFirst(element, condition)
|
||||||
private var pair: Pair<Condition, T>? = null
|
return true
|
||||||
|
|
||||||
private fun search() {
|
|
||||||
for (pair in parent) {
|
|
||||||
if (pair.first.check()) {
|
|
||||||
this.pair = pair
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.pair = null
|
fun replace(element: E, condition: BooleanSupplier) {
|
||||||
|
backing[element] = condition
|
||||||
}
|
}
|
||||||
|
|
||||||
init {
|
fun replaceFirst(element: E, condition: BooleanSupplier) {
|
||||||
search()
|
backing.remove(element)
|
||||||
|
backing.putAndMoveToFirst(element, condition)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun hasNext(): Boolean {
|
fun remove(element: E): Boolean {
|
||||||
return pair != null
|
return backing.remove(element) != null
|
||||||
}
|
|
||||||
|
|
||||||
override fun next(): T {
|
|
||||||
val pair = pair ?: throw NoSuchElementException()
|
|
||||||
search()
|
|
||||||
return pair.second
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
51
src/main/kotlin/ru/dbotthepony/mc/otm/item/SimpleUpgrade.kt
Normal file
51
src/main/kotlin/ru/dbotthepony/mc/otm/item/SimpleUpgrade.kt
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
package ru.dbotthepony.mc.otm.item
|
||||||
|
|
||||||
|
import net.minecraft.core.Direction
|
||||||
|
import net.minecraft.nbt.CompoundTag
|
||||||
|
import net.minecraft.network.chat.Component
|
||||||
|
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.minecraftforge.common.capabilities.Capability
|
||||||
|
import net.minecraftforge.common.capabilities.ICapabilityProvider
|
||||||
|
import net.minecraftforge.common.util.LazyOptional
|
||||||
|
import ru.dbotthepony.mc.otm.capability.IMatteryUpgrade
|
||||||
|
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
||||||
|
import ru.dbotthepony.mc.otm.capability.UpgradeType
|
||||||
|
import ru.dbotthepony.mc.otm.capability.addUpgradeTooltipLines
|
||||||
|
import ru.dbotthepony.mc.otm.core.TextComponent
|
||||||
|
import ru.dbotthepony.mc.otm.core.math.Decimal
|
||||||
|
|
||||||
|
class SimpleUpgrade(
|
||||||
|
properties: Properties,
|
||||||
|
override val upgradeTypes: Set<UpgradeType>,
|
||||||
|
override val speedBonus: Double = 0.0,
|
||||||
|
override val processingItems: Int = 0,
|
||||||
|
override val energyStorageFlat: Decimal = Decimal.ZERO,
|
||||||
|
override val energyStorage: Decimal = Decimal.ZERO,
|
||||||
|
override val energyConsumed: Decimal = Decimal.ZERO,
|
||||||
|
override val energyThroughputFlat: Decimal = Decimal.ZERO,
|
||||||
|
override val energyThroughput: Decimal = Decimal.ZERO,
|
||||||
|
override val failureMultiplier: Double = 1.0,
|
||||||
|
) : Item(properties), IMatteryUpgrade, ICapabilityProvider {
|
||||||
|
private val resolver = LazyOptional.of { this }
|
||||||
|
|
||||||
|
override fun <T : Any?> getCapability(cap: Capability<T>, side: Direction?): LazyOptional<T> {
|
||||||
|
if (cap === MatteryCapability.UPGRADE) {
|
||||||
|
return resolver.cast()
|
||||||
|
}
|
||||||
|
|
||||||
|
return LazyOptional.empty()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun appendHoverText(p_41421_: ItemStack, p_41422_: Level?, p_41423_: MutableList<Component>, p_41424_: TooltipFlag) {
|
||||||
|
super.appendHoverText(p_41421_, p_41422_, p_41423_, p_41424_)
|
||||||
|
addUpgradeTooltipLines(p_41423_)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun initCapabilities(stack: ItemStack, nbt: CompoundTag?): ICapabilityProvider {
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -11,6 +11,7 @@ import net.minecraft.network.FriendlyByteBuf
|
|||||||
import net.minecraft.resources.ResourceLocation
|
import net.minecraft.resources.ResourceLocation
|
||||||
import net.minecraft.server.level.ServerPlayer
|
import net.minecraft.server.level.ServerPlayer
|
||||||
import net.minecraft.world.Container
|
import net.minecraft.world.Container
|
||||||
|
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.AbstractContainerMenu
|
import net.minecraft.world.inventory.AbstractContainerMenu
|
||||||
@ -23,6 +24,9 @@ import net.minecraft.world.item.enchantment.EnchantmentHelper.hasBindingCurse
|
|||||||
import net.minecraft.world.level.block.entity.BlockEntity
|
import net.minecraft.world.level.block.entity.BlockEntity
|
||||||
import net.minecraftforge.network.NetworkEvent
|
import net.minecraftforge.network.NetworkEvent
|
||||||
import net.minecraftforge.network.PacketDistributor
|
import net.minecraftforge.network.PacketDistributor
|
||||||
|
import ru.dbotthepony.mc.otm.capability.IMatteryUpgrade
|
||||||
|
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
||||||
|
import ru.dbotthepony.mc.otm.capability.UpgradeType
|
||||||
import ru.dbotthepony.mc.otm.capability.matteryPlayer
|
import ru.dbotthepony.mc.otm.capability.matteryPlayer
|
||||||
import ru.dbotthepony.mc.otm.client.minecraft
|
import ru.dbotthepony.mc.otm.client.minecraft
|
||||||
import ru.dbotthepony.mc.otm.compat.cos.cosmeticArmorSlots
|
import ru.dbotthepony.mc.otm.compat.cos.cosmeticArmorSlots
|
||||||
@ -31,7 +35,12 @@ import ru.dbotthepony.mc.otm.compat.curios.isCurioSlot
|
|||||||
import ru.dbotthepony.mc.otm.container.ItemFilter
|
import ru.dbotthepony.mc.otm.container.ItemFilter
|
||||||
import ru.dbotthepony.mc.otm.container.ItemFilterNetworkSlot
|
import ru.dbotthepony.mc.otm.container.ItemFilterNetworkSlot
|
||||||
import ru.dbotthepony.mc.otm.container.MatteryContainer
|
import ru.dbotthepony.mc.otm.container.MatteryContainer
|
||||||
|
import ru.dbotthepony.mc.otm.container.UpgradeContainer
|
||||||
import ru.dbotthepony.mc.otm.core.GetterSetter
|
import ru.dbotthepony.mc.otm.core.GetterSetter
|
||||||
|
import ru.dbotthepony.mc.otm.core.collect.ConditionalEnumSet
|
||||||
|
import ru.dbotthepony.mc.otm.core.collect.ConditionalSet
|
||||||
|
import ru.dbotthepony.mc.otm.core.immutableList
|
||||||
|
import ru.dbotthepony.mc.otm.core.math.Decimal
|
||||||
import ru.dbotthepony.mc.otm.core.util.BigDecimalValueCodec
|
import ru.dbotthepony.mc.otm.core.util.BigDecimalValueCodec
|
||||||
import ru.dbotthepony.mc.otm.core.util.BinaryStringCodec
|
import ru.dbotthepony.mc.otm.core.util.BinaryStringCodec
|
||||||
import ru.dbotthepony.mc.otm.core.util.BooleanValueCodec
|
import ru.dbotthepony.mc.otm.core.util.BooleanValueCodec
|
||||||
@ -49,10 +58,14 @@ import ru.dbotthepony.mc.otm.network.packetHandled
|
|||||||
import ru.dbotthepony.mc.otm.network.sender
|
import ru.dbotthepony.mc.otm.network.sender
|
||||||
import ru.dbotthepony.mc.otm.network.synchronizer.FieldSynchronizer
|
import ru.dbotthepony.mc.otm.network.synchronizer.FieldSynchronizer
|
||||||
import ru.dbotthepony.mc.otm.network.synchronizer.IField
|
import ru.dbotthepony.mc.otm.network.synchronizer.IField
|
||||||
|
import ru.dbotthepony.mc.otm.network.synchronizer.IMutableBooleanField
|
||||||
import java.io.DataInputStream
|
import java.io.DataInputStream
|
||||||
import java.io.DataOutputStream
|
import java.io.DataOutputStream
|
||||||
import java.math.BigDecimal
|
import java.math.BigDecimal
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
import java.util.function.BooleanSupplier
|
||||||
|
import java.util.function.DoubleSupplier
|
||||||
|
import java.util.function.IntSupplier
|
||||||
import java.util.function.Predicate
|
import java.util.function.Predicate
|
||||||
import java.util.function.Supplier
|
import java.util.function.Supplier
|
||||||
|
|
||||||
@ -63,6 +76,17 @@ data class EquipmentSlots(
|
|||||||
val curiosSlots: List<PlayerSlot<Slot, Slot>>
|
val curiosSlots: List<PlayerSlot<Slot, Slot>>
|
||||||
)
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* [openState] **is clientside only**, attempting to use it on server will result
|
||||||
|
* in classloading exceptions.
|
||||||
|
*/
|
||||||
|
data class UpgradeSlots(
|
||||||
|
val slots: List<MatterySlot>,
|
||||||
|
val allowedTypes: Set<UpgradeType>,
|
||||||
|
val openState: GetterSetter<Boolean>,
|
||||||
|
val currentStats: IMatteryUpgrade
|
||||||
|
)
|
||||||
|
|
||||||
abstract class MatteryMenu @JvmOverloads protected constructor(
|
abstract class MatteryMenu @JvmOverloads protected constructor(
|
||||||
menuType: MenuType<*>?,
|
menuType: MenuType<*>?,
|
||||||
containerId: Int,
|
containerId: Int,
|
||||||
@ -382,7 +406,7 @@ abstract class MatteryMenu @JvmOverloads protected constructor(
|
|||||||
return player.distanceToSqr(pos.x.toDouble() + 0.5, pos.y.toDouble() + 0.5, pos.z.toDouble() + 0.5) <= 64.0
|
return player.distanceToSqr(pos.x.toDouble() + 0.5, pos.y.toDouble() + 0.5, pos.z.toDouble() + 0.5) <= 64.0
|
||||||
}
|
}
|
||||||
|
|
||||||
private val externalSlots = ArrayList<Slot>()
|
private val externalSlots = ConditionalSet<Slot>()
|
||||||
private val quickMoveMapping = Reference2ObjectOpenHashMap<Slot, ReferenceArrayList<Collection<Slot>>>()
|
private val quickMoveMapping = Reference2ObjectOpenHashMap<Slot, ReferenceArrayList<Collection<Slot>>>()
|
||||||
|
|
||||||
override fun addSlot(pSlot: Slot): Slot {
|
override fun addSlot(pSlot: Slot): Slot {
|
||||||
@ -412,11 +436,17 @@ abstract class MatteryMenu @JvmOverloads protected constructor(
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds slot to "storage slots" list (utilized by quick move) and calls [addSlot]
|
* Adds slot to "storage slots" list (utilized by quick move) and calls [addSlot]
|
||||||
|
*
|
||||||
|
* [condition] allows to specify when slot is invisible on GUI (hence being ignored by quick move)
|
||||||
*/
|
*/
|
||||||
protected fun <T : Slot> addStorageSlot(slot: T, addMapping: Boolean = true): T {
|
protected fun <T : Slot> addStorageSlot(slot: T, addMapping: Boolean = true, prepend: Boolean = false, condition: BooleanSupplier = BooleanSupplier { true }): T {
|
||||||
if (slot !in externalSlots) {
|
if (slot !in externalSlots) {
|
||||||
addSlot(slot)
|
addSlot(slot)
|
||||||
externalSlots.add(slot)
|
|
||||||
|
if (prepend)
|
||||||
|
externalSlots.replaceFirst(slot, condition)
|
||||||
|
else
|
||||||
|
externalSlots.replace(slot, condition)
|
||||||
|
|
||||||
if (addMapping) {
|
if (addMapping) {
|
||||||
mapQuickMove(slot, equipmentSlots)
|
mapQuickMove(slot, equipmentSlots)
|
||||||
@ -446,8 +476,8 @@ abstract class MatteryMenu @JvmOverloads protected constructor(
|
|||||||
mapQuickMove(slot, externalSlots, prepend = prepend)
|
mapQuickMove(slot, externalSlots, prepend = prepend)
|
||||||
}
|
}
|
||||||
|
|
||||||
protected fun mapQuickMove(slot: Slot, target: Collection<Slot>, prepend: Boolean = false) {
|
protected fun mapQuickMove(slot: Slot, target: Collection<Slot>, prepend: Boolean = false, condition: BooleanSupplier = BooleanSupplier { true }) {
|
||||||
val listing = quickMoveMapping.computeIfAbsent(slot, Reference2ObjectFunction { ReferenceArrayList(1) })
|
val listing = quickMoveMapping.computeIfAbsent(slot, Reference2ObjectFunction { ReferenceArrayList(1) /* ReferenceArrayList ибо мы используем его в некотором смысле как множество */ })
|
||||||
listing.remove(target)
|
listing.remove(target)
|
||||||
|
|
||||||
if (prepend)
|
if (prepend)
|
||||||
@ -715,6 +745,56 @@ abstract class MatteryMenu @JvmOverloads protected constructor(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun makeUpgradeSlots(count: Int, container: UpgradeContainer?): UpgradeSlots {
|
||||||
|
if (container != null) {
|
||||||
|
require(count == container.containerSize) { "Upgrade container size ${container.containerSize} does not match with provided size $count" }
|
||||||
|
}
|
||||||
|
|
||||||
|
val allowedTypes = EnumMap<UpgradeType, IMutableBooleanField>(UpgradeType::class.java)
|
||||||
|
|
||||||
|
for (value in UpgradeType.ALL) {
|
||||||
|
allowedTypes[value] = mSynchronizer.bool()
|
||||||
|
|
||||||
|
if (container != null) {
|
||||||
|
allowedTypes[value]!!.boolean = value in container.allowedUpgrades
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val syncContainer = container ?: SimpleContainer(count)
|
||||||
|
|
||||||
|
var isOpen = false
|
||||||
|
val input = PlayerInput(BooleanValueCodec, allowSpectators = true, handler = { isOpen = it })
|
||||||
|
|
||||||
|
return UpgradeSlots(
|
||||||
|
slots = immutableList(count) {
|
||||||
|
object : MatterySlot(syncContainer, it) {
|
||||||
|
init {
|
||||||
|
mapQuickMoveToInventory(this)
|
||||||
|
addStorageSlot(this, prepend = true, condition = { isOpen })
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun mayPlace(itemStack: ItemStack): Boolean {
|
||||||
|
return super.mayPlace(itemStack) && itemStack.getCapability(MatteryCapability.UPGRADE).map { it.upgradeTypes.any { allowedTypes[it]!!.boolean } }.orElse(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
allowedTypes = ConditionalEnumSet(allowedTypes),
|
||||||
|
openState = GetterSetter.of({ isOpen }, { input.input(it); isOpen = it }),
|
||||||
|
currentStats = object : IMatteryUpgrade {
|
||||||
|
override val upgradeTypes: Set<UpgradeType> = setOf()
|
||||||
|
override val speedBonus: Double by mSynchronizer.computedDouble(DoubleSupplier { container?.speedBonus ?: 0.0 }).property
|
||||||
|
override val processingItems: Int by mSynchronizer.computedInt(IntSupplier { container?.processingItems ?: 0 }).property
|
||||||
|
override val energyStorageFlat: Decimal by mSynchronizer.computedDecimal { container?.energyStorageFlat ?: Decimal.ZERO }
|
||||||
|
override val energyStorage: Decimal by mSynchronizer.computedDecimal { container?.energyStorage ?: Decimal.ZERO }
|
||||||
|
override val energyConsumed: Decimal by mSynchronizer.computedDecimal { container?.energyConsumed ?: Decimal.ZERO }
|
||||||
|
override val energyThroughputFlat: Decimal by mSynchronizer.computedDecimal { container?.energyThroughputFlat ?: Decimal.ZERO }
|
||||||
|
override val energyThroughput: Decimal by mSynchronizer.computedDecimal { container?.energyThroughput ?: Decimal.ZERO }
|
||||||
|
override val failureMultiplier: Double by mSynchronizer.computedDouble(DoubleSupplier { container?.failureMultiplier ?: 1.0 }).property
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
val TEXTURE_EMPTY_SLOTS: List<ResourceLocation> = ImmutableList.of(
|
val TEXTURE_EMPTY_SLOTS: List<ResourceLocation> = ImmutableList.of(
|
||||||
InventoryMenu.EMPTY_ARMOR_SLOT_BOOTS,
|
InventoryMenu.EMPTY_ARMOR_SLOT_BOOTS,
|
||||||
|
@ -10,6 +10,7 @@ import ru.dbotthepony.mc.otm.capability.FlowDirection
|
|||||||
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
||||||
import ru.dbotthepony.mc.otm.capability.energy
|
import ru.dbotthepony.mc.otm.capability.energy
|
||||||
import ru.dbotthepony.mc.otm.client.minecraft
|
import ru.dbotthepony.mc.otm.client.minecraft
|
||||||
|
import ru.dbotthepony.mc.otm.container.UpgradeContainer
|
||||||
import ru.dbotthepony.mc.otm.core.GetterSetter
|
import ru.dbotthepony.mc.otm.core.GetterSetter
|
||||||
import ru.dbotthepony.mc.otm.core.immutableList
|
import ru.dbotthepony.mc.otm.core.immutableList
|
||||||
import ru.dbotthepony.mc.otm.runOnClient
|
import ru.dbotthepony.mc.otm.runOnClient
|
||||||
|
@ -26,6 +26,8 @@ class PlatePressMenu @JvmOverloads constructor(
|
|||||||
val energyConfig = EnergyConfigPlayerInput(this, tile?.energyConfig, allowPull = true)
|
val energyConfig = EnergyConfigPlayerInput(this, tile?.energyConfig, allowPull = true)
|
||||||
val profiledEnergy = ProfiledLevelGaugeWidget(this, tile?.energy, energyWidget)
|
val profiledEnergy = ProfiledLevelGaugeWidget(this, tile?.energy, energyWidget)
|
||||||
|
|
||||||
|
val upgrades = makeUpgradeSlots(3, tile?.upgrades)
|
||||||
|
|
||||||
init {
|
init {
|
||||||
addStorageSlot(inputSlot)
|
addStorageSlot(inputSlot)
|
||||||
addStorageSlot(outputSlot)
|
addStorageSlot(outputSlot)
|
||||||
|
@ -31,6 +31,8 @@ class TwinPlatePressMenu @JvmOverloads constructor(
|
|||||||
|
|
||||||
val balanceInputs = BooleanInputWithFeedback(this)
|
val balanceInputs = BooleanInputWithFeedback(this)
|
||||||
|
|
||||||
|
val upgrades = makeUpgradeSlots(4, tile?.upgrades)
|
||||||
|
|
||||||
init {
|
init {
|
||||||
if (tile != null) {
|
if (tile != null) {
|
||||||
balanceInputs.with(tile::balanceInputs)
|
balanceInputs.with(tile::balanceInputs)
|
||||||
|
@ -130,6 +130,7 @@ private fun CreativeModeTab.Output.fluids(value: Item) {
|
|||||||
private fun addMainCreativeTabItems(consumer: CreativeModeTab.Output) {
|
private fun addMainCreativeTabItems(consumer: CreativeModeTab.Output) {
|
||||||
with(consumer) {
|
with(consumer) {
|
||||||
accept(MItems.MACHINES)
|
accept(MItems.MACHINES)
|
||||||
|
accept(MItems.CreativeUpgrades.LIST)
|
||||||
|
|
||||||
accept(MRegistry.CARGO_CRATES.item)
|
accept(MRegistry.CARGO_CRATES.item)
|
||||||
accept(MItems.HOLO_SIGN)
|
accept(MItems.HOLO_SIGN)
|
||||||
|
@ -4,7 +4,6 @@ package ru.dbotthepony.mc.otm.registry
|
|||||||
import net.minecraft.ChatFormatting
|
import net.minecraft.ChatFormatting
|
||||||
import net.minecraft.network.chat.Component
|
import net.minecraft.network.chat.Component
|
||||||
import net.minecraft.resources.ResourceLocation
|
import net.minecraft.resources.ResourceLocation
|
||||||
import net.minecraft.world.entity.EquipmentSlot
|
|
||||||
import net.minecraft.world.food.FoodProperties
|
import net.minecraft.world.food.FoodProperties
|
||||||
import net.minecraft.world.item.*
|
import net.minecraft.world.item.*
|
||||||
import net.minecraft.world.item.crafting.Ingredient
|
import net.minecraft.world.item.crafting.Ingredient
|
||||||
@ -15,9 +14,11 @@ 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.capability.UpgradeType
|
||||||
import ru.dbotthepony.mc.otm.config.ItemsConfig
|
import ru.dbotthepony.mc.otm.config.ItemsConfig
|
||||||
import ru.dbotthepony.mc.otm.core.collect.SupplierList
|
import ru.dbotthepony.mc.otm.core.collect.SupplierList
|
||||||
import ru.dbotthepony.mc.otm.core.TranslatableComponent
|
import ru.dbotthepony.mc.otm.core.TranslatableComponent
|
||||||
|
import ru.dbotthepony.mc.otm.core.math.Decimal
|
||||||
import ru.dbotthepony.mc.otm.item.*
|
import ru.dbotthepony.mc.otm.item.*
|
||||||
import ru.dbotthepony.mc.otm.item.exopack.ExoPackCraftingUpgradeItem
|
import ru.dbotthepony.mc.otm.item.exopack.ExoPackCraftingUpgradeItem
|
||||||
import ru.dbotthepony.mc.otm.item.exopack.ExoPackProbeItem
|
import ru.dbotthepony.mc.otm.item.exopack.ExoPackProbeItem
|
||||||
@ -160,6 +161,38 @@ object MItems {
|
|||||||
TRITANIUM_ANVIL = SupplierList(props)
|
TRITANIUM_ANVIL = SupplierList(props)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
object CreativeUpgrades {
|
||||||
|
val SPEED: SimpleUpgrade by registry.register("creative_speed_upgrade") { SimpleUpgrade(Item.Properties().rarity(Rarity.EPIC), UpgradeType.SPEED.set(), speedBonus = 1.0) }
|
||||||
|
val ENERGY_CONSUMPTION: SimpleUpgrade by registry.register("creative_energy_consumption_upgrade") { SimpleUpgrade(Item.Properties().rarity(Rarity.EPIC), UpgradeType.ENERGY_CONSUMPTION.set(), energyConsumed = Decimal.MINUS_ONE) }
|
||||||
|
val ENERGY_STORAGE: SimpleUpgrade by registry.register("creative_energy_storage_upgrade") { SimpleUpgrade(Item.Properties().rarity(Rarity.EPIC), UpgradeType.ENERGY_STORAGE.set(), energyStorage = Decimal.ONE) }
|
||||||
|
val ENERGY_STORAGE_FLAT: SimpleUpgrade by registry.register("creative_energy_storage_flat_upgrade") { SimpleUpgrade(Item.Properties().rarity(Rarity.EPIC), UpgradeType.ENERGY_STORAGE.set(), energyStorageFlat = Decimal.LONG_MAX_VALUE) }
|
||||||
|
val ENERGY_STORAGE_FLAT_SMALL: SimpleUpgrade by registry.register("creative_energy_storage_flat2_upgrade") { SimpleUpgrade(Item.Properties().rarity(Rarity.EPIC), UpgradeType.ENERGY_STORAGE.set(), energyStorageFlat = Decimal.INT_MAX_VALUE) }
|
||||||
|
val ENERGY_THROUGHPUT: SimpleUpgrade by registry.register("creative_energy_throughput_upgrade") { SimpleUpgrade(Item.Properties().rarity(Rarity.EPIC), UpgradeType.ENERGY_THROUGHPUT.set(), energyThroughput = Decimal.ONE) }
|
||||||
|
val ENERGY_THROUGHPUT_FLAT: SimpleUpgrade by registry.register("creative_energy_throughput_flat_upgrade") { SimpleUpgrade(Item.Properties().rarity(Rarity.EPIC), UpgradeType.ENERGY_THROUGHPUT.set(), energyThroughputFlat = Decimal.LONG_MAX_VALUE) }
|
||||||
|
val ENERGY_THROUGHPUT_FLAT_SMALL: SimpleUpgrade by registry.register("creative_energy_throughput_flat2_upgrade") { SimpleUpgrade(Item.Properties().rarity(Rarity.EPIC), UpgradeType.ENERGY_THROUGHPUT.set(), energyThroughputFlat = Decimal.INT_MAX_VALUE) }
|
||||||
|
val FAILSAFE: SimpleUpgrade by registry.register("creative_failsafe_upgrade") { SimpleUpgrade(Item.Properties().rarity(Rarity.EPIC), UpgradeType.FAILSAFE.set(), failureMultiplier = 0.0) }
|
||||||
|
val FAILURE: SimpleUpgrade by registry.register("creative_failure_upgrade") { SimpleUpgrade(Item.Properties().rarity(Rarity.EPIC), UpgradeType.FAILSAFE.set(), failureMultiplier = 2.0) }
|
||||||
|
val PROCESSING_ITEMS: SimpleUpgrade by registry.register("creative_processing_upgrade") { SimpleUpgrade(Item.Properties().rarity(Rarity.EPIC), UpgradeType.PROCESSING.set(), processingItems = 1) }
|
||||||
|
|
||||||
|
val LIST = SupplierList(
|
||||||
|
::SPEED,
|
||||||
|
::ENERGY_CONSUMPTION,
|
||||||
|
::ENERGY_STORAGE,
|
||||||
|
::ENERGY_STORAGE_FLAT,
|
||||||
|
::ENERGY_STORAGE_FLAT_SMALL,
|
||||||
|
::ENERGY_THROUGHPUT,
|
||||||
|
::ENERGY_THROUGHPUT_FLAT,
|
||||||
|
::ENERGY_THROUGHPUT_FLAT_SMALL,
|
||||||
|
::FAILSAFE,
|
||||||
|
::FAILURE,
|
||||||
|
::PROCESSING_ITEMS,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
CreativeUpgrades
|
||||||
|
}
|
||||||
|
|
||||||
val MATTER_DUST: Item by registry.register(MNames.MATTER_DUST) { MatterDustItem() }
|
val MATTER_DUST: Item by registry.register(MNames.MATTER_DUST) { MatterDustItem() }
|
||||||
|
|
||||||
val TRITANIUM_ORE_CLUMP: Item by registry.register(MNames.TRITANIUM_ORE_CLUMP) { Item(DEFAULT_PROPERTIES) }
|
val TRITANIUM_ORE_CLUMP: Item by registry.register(MNames.TRITANIUM_ORE_CLUMP) { Item(DEFAULT_PROPERTIES) }
|
||||||
|
@ -25,6 +25,7 @@ object MItemTags {
|
|||||||
val CARGO_CRATES: TagKey<Item> = ItemTags.create(ResourceLocation(OverdriveThatMatters.MOD_ID, "cargo_crates"))
|
val CARGO_CRATES: TagKey<Item> = ItemTags.create(ResourceLocation(OverdriveThatMatters.MOD_ID, "cargo_crates"))
|
||||||
val MINECART_CARGO_CRATES: TagKey<Item> = ItemTags.create(ResourceLocation(OverdriveThatMatters.MOD_ID, "minecart_cargo_crates"))
|
val MINECART_CARGO_CRATES: TagKey<Item> = ItemTags.create(ResourceLocation(OverdriveThatMatters.MOD_ID, "minecart_cargo_crates"))
|
||||||
val INDUSTRIAL_GLASS: TagKey<Item> = ItemTags.create(ResourceLocation(OverdriveThatMatters.MOD_ID, "industrial_glass"))
|
val INDUSTRIAL_GLASS: TagKey<Item> = ItemTags.create(ResourceLocation(OverdriveThatMatters.MOD_ID, "industrial_glass"))
|
||||||
|
val UPGRADES: TagKey<Item> = ItemTags.create(ResourceLocation(OverdriveThatMatters.MOD_ID, "upgrades"))
|
||||||
|
|
||||||
val CRAFTING_TABLES: TagKey<Item> = ItemTags.create(ResourceLocation("forge", "crafting_tables"))
|
val CRAFTING_TABLES: TagKey<Item> = ItemTags.create(ResourceLocation("forge", "crafting_tables"))
|
||||||
|
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 468 B After Width: | Height: | Size: 1.3 KiB |
Binary file not shown.
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 2.9 KiB |
Binary file not shown.
Loading…
Reference in New Issue
Block a user