Exopack smelting, RenderGravity, IGUIRenderable

This commit is contained in:
DBotThePony 2023-07-08 00:51:37 +07:00
parent 311af4f8d9
commit 3cacf7f11f
Signed by: DBot
GPG Key ID: DCC23B5715498507
38 changed files with 804 additions and 326 deletions

View File

@ -148,6 +148,7 @@ private fun misc(provider: MatteryLanguageProvider) {
gui("exopack_upgrades.already_activated", "Upgrade is already active!") gui("exopack_upgrades.already_activated", "Upgrade is already active!")
gui("exopack_upgrades.slots_upgrade", "Using this will permanently grant %s slots in your Exopack inventory.") gui("exopack_upgrades.slots_upgrade", "Using this will permanently grant %s slots in your Exopack inventory.")
gui("exopack_upgrades.crafting_upgrade", "Using this will permanently grant 3x3 crafting grid in your Exopack inventory.") gui("exopack_upgrades.crafting_upgrade", "Using this will permanently grant 3x3 crafting grid in your Exopack inventory.")
gui("exopack_upgrades.smelting_upgrade", "Using this will permanently grant smelter in your Exopack inventory.")
gui("crude_battery.replace_in_world", "Simplistic nature of this battery allows to replace your energy source in the field without using Android Station.") gui("crude_battery.replace_in_world", "Simplistic nature of this battery allows to replace your energy source in the field without using Android Station.")
gui("crude_battery.replace_in_world_warning", "This operation is very unstable and can cause extreme damage to your systems!") gui("crude_battery.replace_in_world_warning", "This operation is very unstable and can cause extreme damage to your systems!")
@ -158,6 +159,7 @@ private fun misc(provider: MatteryLanguageProvider) {
misc("exopack_upgrades.slots_upgraded", "Your Exopack has permanently gained %s slots") misc("exopack_upgrades.slots_upgraded", "Your Exopack has permanently gained %s slots")
misc("exopack_upgrades.crafting_upgraded", "Your Exopack has permanently gained 3x3 crafting grid") misc("exopack_upgrades.crafting_upgraded", "Your Exopack has permanently gained 3x3 crafting grid")
misc("exopack_upgrades.smelting_installed", "Your Exopack has permanently gained smelting module")
misc("exopack.granted1", "As you keep pressing on the fingerprint reader, probe disappears.") misc("exopack.granted1", "As you keep pressing on the fingerprint reader, probe disappears.")
misc("exopack.granted2", "After a moment, you are getting pierced into back multiple times...") misc("exopack.granted2", "After a moment, you are getting pierced into back multiple times...")
@ -474,6 +476,7 @@ private fun items(provider: MatteryLanguageProvider) {
add(MItems.EXOPACK_PROBE, "Exopack Probe") add(MItems.EXOPACK_PROBE, "Exopack Probe")
add(MItems.ExopackUpgrades.INVENTORY_UPGRADE_CREATIVE, "Creative Exopack Inventory Upgrade") add(MItems.ExopackUpgrades.INVENTORY_UPGRADE_CREATIVE, "Creative Exopack Inventory Upgrade")
add(MItems.ExopackUpgrades.CRAFTING_UPGRADE, "Exopack Crafting Upgrade") add(MItems.ExopackUpgrades.CRAFTING_UPGRADE, "Exopack Crafting Upgrade")
add(MItems.ExopackUpgrades.SMELTING_UPGRADE, "Exopack Smelting Module")
add(MItems.ExopackUpgrades.INVENTORY_UPGRADE_WITHER, "Superdense Packing Upgrade") add(MItems.ExopackUpgrades.INVENTORY_UPGRADE_WITHER, "Superdense Packing Upgrade")
add(MItems.ExopackUpgrades.INVENTORY_UPGRADE_WITHER, "description", "Utilizes similar principle that exhibit Nether Stars") add(MItems.ExopackUpgrades.INVENTORY_UPGRADE_WITHER, "description", "Utilizes similar principle that exhibit Nether Stars")

View File

@ -155,7 +155,8 @@ private fun misc(provider: MatteryLanguageProvider) {
gui("exopack_upgrades.already_activated", "Улучшение уже активно!") gui("exopack_upgrades.already_activated", "Улучшение уже активно!")
gui("exopack_upgrades.slots_upgrade", "Активируя данное улучшение даст %s слотов в вашем экзопаке.") gui("exopack_upgrades.slots_upgrade", "Активируя данное улучшение даст %s слотов в вашем экзопаке.")
gui("exopack_upgrades.crafting_upgrade", "Активируя данное улучшение даст 3x3 сетку создания в вашем экзопаке.") gui("exopack_upgrades.crafting_upgrade", "Активация данного улучшения даст 3x3 сетку создания в вашем экзопаке.")
gui("exopack_upgrades.smelting_upgrade", "Активация данного улучшения даст плавильню в вашем экзопаке.")
gui("crude_battery.replace_in_world", "Простота устройства данного аккумулятора позволяет вам заменить .") gui("crude_battery.replace_in_world", "Простота устройства данного аккумулятора позволяет вам заменить .")
gui("crude_battery.replace_in_world_warning", "Данная операция крайне рискованная и может нанести огромный урон вашим системам!") gui("crude_battery.replace_in_world_warning", "Данная операция крайне рискованная и может нанести огромный урон вашим системам!")
@ -164,8 +165,9 @@ private fun misc(provider: MatteryLanguageProvider) {
misc("battery.single_use", "Единоразовая батарейка, не может быть перезаряжена.") misc("battery.single_use", "Единоразовая батарейка, не может быть перезаряжена.")
misc("exopack_upgrades.slots_upgraded", "Ваш Экзопак был расширен на %s слотов") misc("exopack_upgrades.slots_upgraded", "Ваш экзопак был расширен на %s слотов")
misc("exopack_upgrades.crafting_upgraded", "Ваш Экзопак получил 3x3 сетку создания") misc("exopack_upgrades.crafting_upgraded", "Ваш экзопак получил 3x3 сетку создания")
misc("exopack_upgrades.smelting_upgraded", "Ваш экзопак получил плавильню")
misc("exopack.granted1", "После некоторого времени нажатия на сканер отпечатка, маяк исчезает.") misc("exopack.granted1", "После некоторого времени нажатия на сканер отпечатка, маяк исчезает.")
misc("exopack.granted2", "Через мгновение, вашу спину пронзают множество раз...") misc("exopack.granted2", "Через мгновение, вашу спину пронзают множество раз...")
@ -478,6 +480,7 @@ private fun items(provider: MatteryLanguageProvider) {
add(MItems.EXOPACK_PROBE, "Маяк экзопака") add(MItems.EXOPACK_PROBE, "Маяк экзопака")
add(MItems.ExopackUpgrades.INVENTORY_UPGRADE_CREATIVE, "Творческое обновление инвентаря экзопака") add(MItems.ExopackUpgrades.INVENTORY_UPGRADE_CREATIVE, "Творческое обновление инвентаря экзопака")
add(MItems.ExopackUpgrades.CRAFTING_UPGRADE, "Обновление сетки крафта экзопака") add(MItems.ExopackUpgrades.CRAFTING_UPGRADE, "Обновление сетки крафта экзопака")
add(MItems.ExopackUpgrades.SMELTING_UPGRADE, "Модуль плавильни экзопака")
add(MItems.ExopackUpgrades.INVENTORY_UPGRADE_WITHER, "Обновление сверхмассивной упаковки") add(MItems.ExopackUpgrades.INVENTORY_UPGRADE_WITHER, "Обновление сверхмассивной упаковки")
add(MItems.ExopackUpgrades.INVENTORY_UPGRADE_WITHER, "description", "Использует те же принципы, которыми обладают звёзды незера") add(MItems.ExopackUpgrades.INVENTORY_UPGRADE_WITHER, "description", "Использует те же принципы, которыми обладают звёзды незера")

View File

@ -40,6 +40,7 @@ import ru.dbotthepony.mc.otm.compat.mekanism.MekanismHooks;
import ru.dbotthepony.mc.otm.compat.mekanism.QIOKt; import ru.dbotthepony.mc.otm.compat.mekanism.QIOKt;
import ru.dbotthepony.mc.otm.config.AndroidConfig; import ru.dbotthepony.mc.otm.config.AndroidConfig;
import ru.dbotthepony.mc.otm.config.ClientConfig; import ru.dbotthepony.mc.otm.config.ClientConfig;
import ru.dbotthepony.mc.otm.config.ExopackConfig;
import ru.dbotthepony.mc.otm.config.ItemsConfig; import ru.dbotthepony.mc.otm.config.ItemsConfig;
import ru.dbotthepony.mc.otm.config.MachinesConfig; import ru.dbotthepony.mc.otm.config.MachinesConfig;
import ru.dbotthepony.mc.otm.config.ServerCompatConfig; import ru.dbotthepony.mc.otm.config.ServerCompatConfig;
@ -140,6 +141,7 @@ public final class OverdriveThatMatters {
ServerConfig.INSTANCE.register(); ServerConfig.INSTANCE.register();
ServerCompatConfig.INSTANCE.register(); ServerCompatConfig.INSTANCE.register();
AndroidConfig.INSTANCE.register(); AndroidConfig.INSTANCE.register();
ExopackConfig.INSTANCE.register();
ItemsConfig.INSTANCE.register(); ItemsConfig.INSTANCE.register();
MachinesConfig.INSTANCE.register(); MachinesConfig.INSTANCE.register();
ToolsConfig.INSTANCE.register(); ToolsConfig.INSTANCE.register();
@ -167,7 +169,7 @@ public final class OverdriveThatMatters {
EVENT_BUS.addListener(EventPriority.NORMAL, MatteryPlayerCapability.Companion::onPlayerCloneEvent); EVENT_BUS.addListener(EventPriority.NORMAL, MatteryPlayerCapability.Companion::onPlayerCloneEvent);
EVENT_BUS.addListener(EventPriority.NORMAL, MatteryPlayerCapability.Companion::onStartTracking); EVENT_BUS.addListener(EventPriority.NORMAL, MatteryPlayerCapability.Companion::onStartTracking);
EVENT_BUS.addListener(EventPriority.NORMAL, MatteryPlayerCapability.Companion::onStopTracking); EVENT_BUS.addListener(EventPriority.NORMAL, MatteryPlayerCapability.Companion::onStopTracking);
EVENT_BUS.addListener(EventPriority.NORMAL, MatteryPlayerCapability.MPCommands::addCommands); EVENT_BUS.addListener(EventPriority.NORMAL, MatteryPlayerCapability.Companion::addCommands);
EVENT_BUS.addListener(EventPriority.NORMAL, ExplosionQueue.Companion::onWorldTick); EVENT_BUS.addListener(EventPriority.NORMAL, ExplosionQueue.Companion::onWorldTick);
EVENT_BUS.addListener(EventPriority.NORMAL, AbstractWeaponItem.Companion::tick); EVENT_BUS.addListener(EventPriority.NORMAL, AbstractWeaponItem.Companion::tick);

View File

@ -10,6 +10,7 @@ import net.minecraft.nbt.ListTag
import net.minecraft.nbt.StringTag import net.minecraft.nbt.StringTag
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.server.level.ServerLevel
import net.minecraft.server.level.ServerPlayer import net.minecraft.server.level.ServerPlayer
import net.minecraft.tags.TagKey import net.minecraft.tags.TagKey
import net.minecraft.world.Difficulty import net.minecraft.world.Difficulty
@ -19,15 +20,14 @@ import net.minecraft.world.effect.MobEffectInstance
import net.minecraft.world.effect.MobEffects import net.minecraft.world.effect.MobEffects
import net.minecraft.world.entity.Entity import net.minecraft.world.entity.Entity
import net.minecraft.world.entity.LivingEntity import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.MobSpawnType
import net.minecraft.world.entity.boss.wither.WitherBoss import net.minecraft.world.entity.boss.wither.WitherBoss
import net.minecraft.world.entity.monster.Phantom
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.InventoryMenu
import net.minecraft.world.item.ItemStack import net.minecraft.world.item.ItemStack
import net.minecraft.world.item.Items import net.minecraft.world.item.Items
import net.minecraft.world.item.ProjectileWeaponItem import net.minecraft.world.item.ProjectileWeaponItem
import net.minecraft.world.item.crafting.RecipeManager
import net.minecraft.world.item.crafting.RecipeType
import net.minecraft.world.item.enchantment.EnchantmentHelper.hasVanishingCurse import net.minecraft.world.item.enchantment.EnchantmentHelper.hasVanishingCurse
import net.minecraft.world.level.GameRules import net.minecraft.world.level.GameRules
import net.minecraft.world.level.Level import net.minecraft.world.level.Level
@ -47,8 +47,10 @@ import net.minecraftforge.event.entity.living.LivingDeathEvent
import net.minecraftforge.event.entity.living.LivingHurtEvent import net.minecraftforge.event.entity.living.LivingHurtEvent
import net.minecraftforge.event.entity.living.MobEffectEvent import net.minecraftforge.event.entity.living.MobEffectEvent
import net.minecraftforge.event.entity.player.PlayerEvent import net.minecraftforge.event.entity.player.PlayerEvent
import net.minecraftforge.eventbus.api.Cancelable
import net.minecraftforge.eventbus.api.Event import net.minecraftforge.eventbus.api.Event
import net.minecraftforge.registries.ForgeRegistries import net.minecraftforge.registries.ForgeRegistries
import net.minecraftforge.server.command.EnumArgument
import org.apache.logging.log4j.LogManager import org.apache.logging.log4j.LogManager
import ru.dbotthepony.mc.otm.* import ru.dbotthepony.mc.otm.*
import ru.dbotthepony.mc.otm.android.AndroidFeature import ru.dbotthepony.mc.otm.android.AndroidFeature
@ -56,12 +58,18 @@ import ru.dbotthepony.mc.otm.android.AndroidFeatureType
import ru.dbotthepony.mc.otm.android.AndroidResearch import ru.dbotthepony.mc.otm.android.AndroidResearch
import ru.dbotthepony.mc.otm.android.AndroidResearchManager import ru.dbotthepony.mc.otm.android.AndroidResearchManager
import ru.dbotthepony.mc.otm.android.AndroidResearchType import ru.dbotthepony.mc.otm.android.AndroidResearchType
import ru.dbotthepony.mc.otm.android.AndroidSwitchableFeature import ru.dbotthepony.mc.otm.block.entity.JobContainer
import ru.dbotthepony.mc.otm.capability.energy.AndroidPowerSource import ru.dbotthepony.mc.otm.block.entity.JobStatus
import ru.dbotthepony.mc.otm.block.entity.MachineItemJob
import ru.dbotthepony.mc.otm.block.entity.MachineJobEventLoop
import ru.dbotthepony.mc.otm.capability.energy.BatteryBackedEnergyStorage
import ru.dbotthepony.mc.otm.capability.energy.IMatteryEnergyStorage
import ru.dbotthepony.mc.otm.capability.energy.ProfiledEnergyStorage
import ru.dbotthepony.mc.otm.capability.energy.extractEnergyExact import ru.dbotthepony.mc.otm.capability.energy.extractEnergyExact
import ru.dbotthepony.mc.otm.capability.energy.receiveEnergyExact import ru.dbotthepony.mc.otm.capability.energy.receiveEnergyExact
import ru.dbotthepony.mc.otm.client.minecraft import ru.dbotthepony.mc.otm.client.minecraft
import ru.dbotthepony.mc.otm.config.AndroidConfig import ru.dbotthepony.mc.otm.config.AndroidConfig
import ru.dbotthepony.mc.otm.config.ExopackConfig
import ru.dbotthepony.mc.otm.container.MatteryContainer import ru.dbotthepony.mc.otm.container.MatteryContainer
import ru.dbotthepony.mc.otm.container.stream import ru.dbotthepony.mc.otm.container.stream
import ru.dbotthepony.mc.otm.core.* import ru.dbotthepony.mc.otm.core.*
@ -95,6 +103,7 @@ import java.util.stream.Stream
import kotlin.collections.ArrayDeque import kotlin.collections.ArrayDeque
import kotlin.collections.ArrayList import kotlin.collections.ArrayList
import kotlin.collections.HashMap import kotlin.collections.HashMap
import kotlin.reflect.KMutableProperty1
@Suppress("unused") @Suppress("unused")
class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, INBTSerializable<CompoundTag> { class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, INBTSerializable<CompoundTag> {
@ -103,10 +112,8 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, INBTSerial
* *
* Cancelling it is probably not a good idea, but you can do it anyway. * Cancelling it is probably not a good idea, but you can do it anyway.
*/ */
@Cancelable
data class PreTick(val capability: MatteryPlayerCapability) : Event() { data class PreTick(val capability: MatteryPlayerCapability) : Event() {
override fun isCancelable() = true
override fun hasResult() = false
val player get() = capability.ply val player get() = capability.ply
val level: Level get() = capability.ply.level() val level: Level get() = capability.ply.level()
} }
@ -115,9 +122,6 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, INBTSerial
* This event is fired on main event bus after ticking logic took place. * This event is fired on main event bus after ticking logic took place.
*/ */
data class PostTick(val capability: MatteryPlayerCapability) : Event() { data class PostTick(val capability: MatteryPlayerCapability) : Event() {
override fun isCancelable() = false
override fun hasResult() = false
val player get() = capability.ply val player get() = capability.ply
val level: Level get() = capability.ply.level() val level: Level get() = capability.ply.level()
} }
@ -127,10 +131,6 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, INBTSerial
* (both in [Inventory] and [MatteryPlayerCapability] exopack due to inventory filters or no free space). * (both in [Inventory] and [MatteryPlayerCapability] exopack due to inventory filters or no free space).
*/ */
data class ItemStackLeftoverEvent(val stack: ItemStack, val capability: MatteryPlayerCapability) : Event() { data class ItemStackLeftoverEvent(val stack: ItemStack, val capability: MatteryPlayerCapability) : Event() {
override fun isCancelable() = false
override fun hasResult() = false
override fun setResult(value: Result) {}
val player get() = capability.ply val player get() = capability.ply
val level: Level get() = capability.ply.level() val level: Level get() = capability.ply.level()
} }
@ -149,25 +149,26 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, INBTSerial
/** /**
* For fields that need to be synchronized only to owning player * For fields that need to be synchronized only to owning player
* *
* Please mind if you really need to use this in your mod; * Please mind when you use this in your mod;
* any differences in field order/types/etc will break *everything* * any differences in field order/types/etc between client and server
* * will break *everything*
*/ */
val synchronizer = FieldSynchronizer() val synchronizer = FieldSynchronizer()
/**
* For data to be stored and loaded from NBT automatically
*/
val savetables = Savetables()
/** /**
* For fields that need to be synchronized to everyone * For fields that need to be synchronized to everyone
* *
* Please mind if you really need to use this in your mod; * Please mind when you use this in your mod;
* any differences in field order/types/etc will break *everything* * any differences in field order/types/etc between client and server
* will break *everything*
*/ */
val publicSynchronizer = FieldSynchronizer() val publicSynchronizer = FieldSynchronizer()
/**
* For data to be stored to and loaded from NBT automatically
*/
val savetables = Savetables()
/** /**
* Whenever player has Exopack * Whenever player has Exopack
*/ */
@ -238,7 +239,7 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, INBTSerial
* Whenever Exopack has 3x3 crafting grid upgrade installed * Whenever Exopack has 3x3 crafting grid upgrade installed
*/ */
var isExoPackCraftingUpgraded by publicSynchronizer.bool(setter = setter@{ value, access, _ -> var isExoPackCraftingUpgraded by publicSynchronizer.bool(setter = setter@{ value, access, _ ->
if (value != access.read()) { if (value != access.readBoolean()) {
access.write(value) access.write(value)
_exoPackMenu = null _exoPackMenu = null
} }
@ -324,16 +325,91 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, INBTSerial
* * But they can be harmed using harm potion * * But they can be harmed using harm potion
* * Can't be poisoned (with default datapack) * * Can't be poisoned (with default datapack)
* * CAN be withered (with default datapack) * * CAN be withered (with default datapack)
* * Ignored by the Wither but not by Wither Skeletons
* * Can't drown
* * etc * * etc
* *
* Android-immune (de)buffs are specified in `data/overdrive_that_matters/tags/mob_effect/android_immune_effects.json` * Android-immune (de)buffs are specified in `data/overdrive_that_matters/tags/mob_effect/android_immune_effects.json`
*/ */
var isAndroid by publicSynchronizer.bool().property var isAndroid by publicSynchronizer.bool().property
/**
* Whenever player has exosuit smelting upgrade
*/
var isExoPackSmeltingInstalled by synchronizer.bool(setter = { value, access, _ ->
if (value != access.readBoolean()) {
access.write(value)
_exoPackMenu = null
}
}).property
inner class SmelterBelt(index: Int) : MachineJobEventLoop<MachineItemJob>() {
override val energy: IMatteryEnergyStorage
get() = exoPackEnergy
override val isBlockedByRedstone: Boolean
get() = false
override fun deserializeJob(nbt: CompoundTag): MachineItemJob {
return MachineItemJob(nbt)
}
override val upgrades: IMatteryUpgrade?
get() = null
override fun jobUpdated(new: MachineItemJob?, old: MachineItemJob?) {}
override fun onJobFinish(job: MachineItemJob): JobStatus {
if (output.fullyAddItem(job.itemStack)) {
exoPackSmelterExperience += job.experience
return JobStatus.SUCCESS
} else {
return JobStatus.FAILURE_ITEM
}
}
private val cache = RecipeManager.createCheck(RecipeType.SMELTING)
override fun computeNextJob(): JobContainer<MachineItemJob> {
val level = ply.level() as? ServerLevel ?: return JobContainer.failure()
val recipe = cache.getRecipeFor(input, level)
if (recipe.isEmpty) {
return JobContainer.noItem()
} else {
val actual = recipe.get()
val item = actual.assemble(input, level.registryAccess())
input[0].shrink(1)
input.setChanged(0)
return JobContainer.success(MachineItemJob(item, actual.cookingTime.toDouble(), ExopackConfig.FURNACE_POWER_CONSUMPTION, actual.experience))
}
}
val input = MatteryContainer({ notify(IdleReason.ITEM) }, 1)
val output = MatteryContainer({ notify(IdleReason.ITEM) }, 1)
init {
savetables.stateful(::input, "exopack_smelter_input_$index")
savetables.stateful(::output, "exopack_smelter_output_$index")
savetables.stateful(this, "exopack_smelter_worker_$index")
}
}
val smelter0 = SmelterBelt(0)
val smelter1 = SmelterBelt(1)
val smelter2 = SmelterBelt(2)
val smelters = listOf(smelter0, smelter1, smelter2)
var exoPackSmelterExperience = 0f
/** /**
* [IMatteryEnergyStorage] instance, representing Android' battery charge * [IMatteryEnergyStorage] instance, representing Android' battery charge
*/ */
val androidEnergy = AndroidPowerSource(ply, synchronizer, AndroidConfig.ANDROID_MAX_ENERGY, AndroidConfig.ANDROID_MAX_ENERGY) val androidEnergy = BatteryBackedEnergyStorage(ply, synchronizer, AndroidConfig.ANDROID_MAX_ENERGY, AndroidConfig.ANDROID_MAX_ENERGY)
/**
* [IMatteryEnergyStorage] instance, representing Exopack battery charge
*/
val exoPackEnergy = ProfiledEnergyStorage(BatteryBackedEnergyStorage(ply, synchronizer, Decimal.ZERO, ExopackConfig.ENERGY_CAPACITY))
init { init {
savetables.int(::ticksIExist) savetables.int(::ticksIExist)
@ -355,6 +431,9 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, INBTSerial
savetables.stateful(::exoPackSlotModifier, "exoSuitSlotCountModifiers") savetables.stateful(::exoPackSlotModifier, "exoSuitSlotCountModifiers")
savetables.stateful(::exoPackContainer, "exoSuitContainer") savetables.stateful(::exoPackContainer, "exoSuitContainer")
savetables.stateful(::androidEnergy) savetables.stateful(::androidEnergy)
savetables.stateful(::exoPackEnergy)
savetables.float(::exoPackSmelterExperience)
savetables.bool(::isExoPackSmeltingInstalled)
} }
fun invalidateNetworkState() { fun invalidateNetworkState() {
@ -642,7 +721,7 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, INBTSerial
return featureMap[feature] as T? return featureMap[feature] as T?
} }
internal fun onHurt(event: LivingHurtEvent) { private fun onHurt(event: LivingHurtEvent) {
if (isAndroid) { if (isAndroid) {
for (feature in featureMap.values) { for (feature in featureMap.values) {
feature.onHurt(event) feature.onHurt(event)
@ -654,7 +733,7 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, INBTSerial
} }
} }
internal fun onAttack(event: LivingAttackEvent) { private fun onAttack(event: LivingAttackEvent) {
if (isAndroid) { if (isAndroid) {
for (feature in featureMap.values) { for (feature in featureMap.values) {
feature.onAttack(event) feature.onAttack(event)
@ -862,6 +941,14 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, INBTSerial
} }
} }
if (hasExoPack) {
exoPackEnergy.parent.tick()
if (!ply.isSpectator && isExoPackSmeltingInstalled) {
smelters.forEach { it.think() }
}
}
if (isAndroid) { if (isAndroid) {
androidEnergy.tick() androidEnergy.tick()
@ -1194,19 +1281,22 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, INBTSerial
return stack.isEmpty return stack.isEmpty
} }
object MPCommands { enum class UpgradeType(val prop: KMutableProperty1<MatteryPlayerCapability, Boolean>) {
@JvmStatic CRAFTING(MatteryPlayerCapability::isExoPackCraftingUpgraded),
SMELTING(MatteryPlayerCapability::isExoPackSmeltingInstalled);
}
@Suppress("unused")
companion object {
private fun setExoPack(players: Collection<Player>, hasExoPack: Boolean): Int { private fun setExoPack(players: Collection<Player>, hasExoPack: Boolean): Int {
for (player in players) { for (player in players) {
if (player.containerMenu is InventoryMenu || player.containerMenu is ExoPackInventoryMenu) player.closeContainer()
player.matteryPlayer?.hasExoPack = hasExoPack player.matteryPlayer?.hasExoPack = hasExoPack
player.matteryPlayer?._exoPackMenu = null
} }
return players.size return players.size
} }
@JvmStatic
private fun makeAndroid(players: Collection<Player>): Int { private fun makeAndroid(players: Collection<Player>): Int {
for (player in players) { for (player in players) {
player.matteryPlayer?.becomeAndroid() player.matteryPlayer?.becomeAndroid()
@ -1215,7 +1305,6 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, INBTSerial
return players.size return players.size
} }
@JvmStatic
private fun makeHuman(players: Collection<Player>): Int { private fun makeHuman(players: Collection<Player>): Int {
for (player in players) { for (player in players) {
player.matteryPlayer?.becomeHumane() player.matteryPlayer?.becomeHumane()
@ -1224,38 +1313,51 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, INBTSerial
return players.size return players.size
} }
@JvmStatic private fun setUpgrade(players: Collection<Player>, type: UpgradeType, state: Boolean): Int {
for (player in players) {
player.matteryPlayer?.let { type.prop.set(it, state) }
}
return players.size
}
fun addCommands(event: RegisterCommandsEvent) { fun addCommands(event: RegisterCommandsEvent) {
event.dispatcher.register( event.dispatcher.register(
Commands.literal("exopack") Commands.literal("exopack")
.requires { it.hasPermission(Commands.LEVEL_GAMEMASTERS) } .requires { it.hasPermission(Commands.LEVEL_GAMEMASTERS) }
.then(Commands.literal("add") .then(Commands.literal("add")
.executes { setExoPack(Collections.singleton(it.source.playerOrException), true) } .executes { setExoPack(listOf(it.source.playerOrException), true) }
.then(Commands.argument("targets", EntityArgument.players()).executes { setExoPack(EntityArgument.getPlayers(it, "targets"), true) }) .then(Commands.argument("targets", EntityArgument.players()).executes { setExoPack(EntityArgument.getPlayers(it, "targets"), true) })
) )
.then(Commands.literal("remove") .then(Commands.literal("remove")
.executes { setExoPack(Collections.singleton(it.source.playerOrException), false) } .executes { setExoPack(listOf(it.source.playerOrException), false) }
.then(Commands.argument("targets", EntityArgument.players()).executes { setExoPack(EntityArgument.getPlayers(it, "targets"), false) }) .then(Commands.argument("targets", EntityArgument.players()).executes { setExoPack(EntityArgument.getPlayers(it, "targets"), false) })
) )
.then(Commands.literal("upgrade")
.then(Commands.argument("type", EnumArgument.enumArgument(UpgradeType::class.java))
.then(Commands.literal("add")
.executes { setUpgrade(listOf(it.source.playerOrException), it.getArgument("type", UpgradeType::class.java), true) }
.then(Commands.argument("targets", EntityArgument.players()).executes { setUpgrade(EntityArgument.getPlayers(it, "targets"), it.getArgument("type", UpgradeType::class.java), true) }))
.then(Commands.literal("remove")
.executes { setUpgrade(listOf(it.source.playerOrException), it.getArgument("type", UpgradeType::class.java), false) }
.then(Commands.argument("targets", EntityArgument.players()).executes { setUpgrade(EntityArgument.getPlayers(it, "targets"), it.getArgument("type", UpgradeType::class.java), false) })))
)
) )
event.dispatcher.register( event.dispatcher.register(
Commands.literal("android") Commands.literal("android")
.requires { it.hasPermission(Commands.LEVEL_GAMEMASTERS) } .requires { it.hasPermission(Commands.LEVEL_GAMEMASTERS) }
.then(Commands.literal("on") .then(Commands.literal("on")
.executes { makeAndroid(Collections.singleton(it.source.playerOrException)) } .executes { makeAndroid(listOf(it.source.playerOrException)) }
.then(Commands.argument("targets", EntityArgument.players()).executes { makeAndroid(EntityArgument.getPlayers(it, "targets")) }) .then(Commands.argument("targets", EntityArgument.players()).executes { makeAndroid(EntityArgument.getPlayers(it, "targets")) })
) )
.then(Commands.literal("off") .then(Commands.literal("off")
.executes { makeHuman(Collections.singleton(it.source.playerOrException)) } .executes { makeHuman(listOf(it.source.playerOrException)) }
.then(Commands.argument("targets", EntityArgument.players()).executes { makeHuman(EntityArgument.getPlayers(it, "targets")) }) .then(Commands.argument("targets", EntityArgument.players()).executes { makeHuman(EntityArgument.getPlayers(it, "targets")) })
) )
) )
} }
}
@Suppress("unused")
companion object {
private fun stackStacks(it: ItemStack, stack: ItemStack): Boolean { private fun stackStacks(it: ItemStack, stack: ItemStack): Boolean {
if ( if (
!it.isEmpty && !it.isEmpty &&
@ -1353,7 +1455,7 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, INBTSerial
mattery.iteration++ mattery.iteration++
mattery.shouldSendIteration = true mattery.shouldSendIteration = true
mattery.deathLog.addLast(ply.tickCount to ply.combatTracker.deathMessage) mattery.deathLog.addLast(ply.tickCount to ply.combatTracker.deathMessage)
mattery.androidEnergy.batteryLevel = mattery.androidEnergy.batteryLevel.coerceAtLeast(Decimal(20_000)) // если смерть была от разряда батареи, то предотвращаем софтлок mattery.androidEnergy.batteryLevel = mattery.androidEnergy.batteryLevel.coerceAtLeast(AndroidConfig.ANDROID_MAX_ENERGY * Decimal("0.2")) // если смерть была от разряда батареи, то предотвращаем софтлок
while (mattery.deathLog.size > 6) { while (mattery.deathLog.size > 6) {
mattery.deathLog.removeFirst() mattery.deathLog.removeFirst()

View File

@ -4,6 +4,7 @@ import net.minecraft.nbt.CompoundTag
import net.minecraft.server.level.ServerPlayer import net.minecraft.server.level.ServerPlayer
import net.minecraft.world.entity.player.Player import net.minecraft.world.entity.player.Player
import net.minecraft.world.item.ItemStack import net.minecraft.world.item.ItemStack
import net.minecraft.world.ticks.ContainerSingleItem
import net.minecraftforge.common.capabilities.ForgeCapabilities import net.minecraftforge.common.capabilities.ForgeCapabilities
import net.minecraftforge.common.util.INBTSerializable import net.minecraftforge.common.util.INBTSerializable
import ru.dbotthepony.mc.otm.capability.FlowDirection import ru.dbotthepony.mc.otm.capability.FlowDirection
@ -18,19 +19,19 @@ import ru.dbotthepony.mc.otm.network.synchronizer.FieldSynchronizer
import ru.dbotthepony.mc.otm.registry.StatNames import ru.dbotthepony.mc.otm.registry.StatNames
import ru.dbotthepony.mc.otm.triggers.AndroidBatteryTrigger import ru.dbotthepony.mc.otm.triggers.AndroidBatteryTrigger
class AndroidPowerSource( class BatteryBackedEnergyStorage(
private val ply: Player, private val ply: Player,
synchronizer: FieldSynchronizer, synchronizer: FieldSynchronizer,
initialCharge: Decimal, initialCharge: Decimal,
maxCharge: Decimal maxCharge: Decimal
) : IMatteryEnergyStorage, INBTSerializable<CompoundTag?> { ) : IMatteryEnergyStorage, INBTSerializable<CompoundTag?>, ContainerSingleItem {
override val energyFlow: FlowDirection override val energyFlow: FlowDirection
get() = FlowDirection.INPUT get() = FlowDirection.INPUT
private var battery by synchronizer.decimal(initialCharge) private var battery by synchronizer.decimal(initialCharge)
private var maxBattery by synchronizer.decimal(maxCharge) private var maxBattery by synchronizer.decimal(maxCharge)
var item by synchronizer.item(setter = setter@{ value, access, setByRemote -> var item by synchronizer.item(setter = setter@{ value, access, _ ->
access.write(value) access.write(value)
if (ply is ServerPlayer) { if (ply is ServerPlayer) {
@ -38,6 +39,29 @@ class AndroidPowerSource(
} }
}) })
override fun getItem(slot: Int): ItemStack {
require(slot == 0) { "Invalid slot $slot" }
return item
}
override fun removeItem(slot: Int, count: Int): ItemStack {
require(slot == 0) { "Invalid slot $slot" }
return item.split(count)
}
override fun setItem(slot: Int, stack: ItemStack) {
require(slot == 0) { "Invalid slot $slot" }
item = stack
}
override fun setChanged() {
}
override fun stillValid(p_18946_: Player): Boolean {
return true
}
override fun serializeNBT(): CompoundTag { override fun serializeNBT(): CompoundTag {
return CompoundTag().also { return CompoundTag().also {
it["battery"] = battery.serializeNBT() it["battery"] = battery.serializeNBT()

View File

@ -13,7 +13,7 @@ import ru.dbotthepony.mc.otm.OverdriveThatMatters
import ru.dbotthepony.mc.otm.android.AndroidFeature import ru.dbotthepony.mc.otm.android.AndroidFeature
import ru.dbotthepony.mc.otm.android.AndroidSwitchableFeature import ru.dbotthepony.mc.otm.android.AndroidSwitchableFeature
import ru.dbotthepony.mc.otm.capability.matteryPlayer import ru.dbotthepony.mc.otm.capability.matteryPlayer
import ru.dbotthepony.mc.otm.client.render.TextAlign import ru.dbotthepony.mc.otm.client.render.RenderGravity
import ru.dbotthepony.mc.otm.client.render.drawAligned import ru.dbotthepony.mc.otm.client.render.drawAligned
import ru.dbotthepony.mc.otm.client.render.drawArc import ru.dbotthepony.mc.otm.client.render.drawArc
import ru.dbotthepony.mc.otm.core.math.RGBAColor import ru.dbotthepony.mc.otm.core.math.RGBAColor
@ -257,15 +257,15 @@ object AndroidMenuKeyMapping : KeyMapping("key.otm.android_menu", KeyConflictCon
val shift = size * 0.6f val shift = size * 0.6f
feature.renderIcon(event.guiGraphics, -iconSize / 2f + shift * cos, -shift * sin - iconSize / 2f, iconSize, iconSize) feature.renderIcon(event.guiGraphics, -iconSize / 2f + shift * cos, -shift * sin - iconSize / 2f, iconSize, iconSize)
event.guiGraphics.drawAligned(minecraft.font, feature.type.displayName, TextAlign.CENTER_CENTER, shift * cos + 1f, -shift * sin - iconSize / 1.5f + 1f, 0) event.guiGraphics.drawAligned(minecraft.font, feature.type.displayName, RenderGravity.CENTER_CENTER, shift * cos + 1f, -shift * sin - iconSize / 1.5f + 1f, 0)
event.guiGraphics.drawAligned(minecraft.font, feature.type.displayName, TextAlign.CENTER_CENTER, shift * cos, -shift * sin - iconSize / 1.5f, if (feature.isActive) RGBAColor.DARK_GREEN else RGBAColor.DARK_RED) event.guiGraphics.drawAligned(minecraft.font, feature.type.displayName, RenderGravity.CENTER_CENTER, shift * cos, -shift * sin - iconSize / 1.5f, if (feature.isActive) RGBAColor.DARK_GREEN else RGBAColor.DARK_RED)
if (feature.isOnCooldown && feature.cooldownPercent > 0.0f) { if (feature.isOnCooldown && feature.cooldownPercent > 0.0f) {
RenderSystem.setShaderColor(1f, 1f, 1f, 0.5f) RenderSystem.setShaderColor(1f, 1f, 1f, 0.5f)
drawArc(event.guiGraphics, shift * cos, -shift * sin, iconSize / 2f, 0f, PI / 2.0, PI / 2.0 + PI * 2.0 * feature.cooldownPercent.toDouble()) drawArc(event.guiGraphics, shift * cos, -shift * sin, iconSize / 2f, 0f, PI / 2.0, PI / 2.0 + PI * 2.0 * feature.cooldownPercent.toDouble())
RenderSystem.setShaderColor(1f, 1f, 1f, 1f) RenderSystem.setShaderColor(1f, 1f, 1f, 1f)
event.guiGraphics.drawAligned(minecraft.font, formatTickDuration(feature.cooldown), TextAlign.CENTER_CENTER, shift * cos, -shift * sin + iconSize / 1.5f, RGBAColor.WHITE) event.guiGraphics.drawAligned(minecraft.font, formatTickDuration(feature.cooldown), RenderGravity.CENTER_CENTER, shift * cos, -shift * sin + iconSize / 1.5f, RGBAColor.WHITE)
} }
} }
@ -302,7 +302,7 @@ object AndroidMenuKeyMapping : KeyMapping("key.otm.android_menu", KeyConflictCon
drawArc(event.guiGraphics, x, y, COOLDOWN_ICON_SIZE / 2f, 0f, PI / 2.0, PI / 2.0 + PI * 2.0 * feature.cooldownPercent, alignAtCenter = false) drawArc(event.guiGraphics, x, y, COOLDOWN_ICON_SIZE / 2f, 0f, PI / 2.0, PI / 2.0 + PI * 2.0 * feature.cooldownPercent, alignAtCenter = false)
RenderSystem.setShaderColor(1f, 1f, 1f, 1f) RenderSystem.setShaderColor(1f, 1f, 1f, 1f)
event.guiGraphics.drawAligned(font, formatTickDuration(feature.cooldown), TextAlign.TOP_CENTER, x + COOLDOWN_ICON_SIZE / 2f, y + COOLDOWN_ICON_SIZE + 1f, RGBAColor.WHITE) event.guiGraphics.drawAligned(font, formatTickDuration(feature.cooldown), RenderGravity.TOP_CENTER, x + COOLDOWN_ICON_SIZE / 2f, y + COOLDOWN_ICON_SIZE + 1f, RGBAColor.WHITE)
x += COOLDOWN_ICON_SIZE + COOLDOWN_ICON_MARGIN x += COOLDOWN_ICON_SIZE + COOLDOWN_ICON_MARGIN
} }

View File

@ -160,8 +160,8 @@ object MatteryGUI {
val text = TranslatableComponent("otm.iteration", iteration) val text = TranslatableComponent("otm.iteration", iteration)
minecraft.font.drawAligned(stack, text, TextAlign.CENTER_CENTER, x + 1f, y + 1f, RGBAColor.BLACK) minecraft.font.drawAligned(stack, text, RenderGravity.CENTER_CENTER, x + 1f, y + 1f, RGBAColor.BLACK)
minecraft.font.drawAligned(stack, text, TextAlign.CENTER_CENTER, x, y, RGBAColor.WHITE) minecraft.font.drawAligned(stack, text, RenderGravity.CENTER_CENTER, x, y, RGBAColor.WHITE)
stack.scale(0.35f, 0.35f, 0.35f) stack.scale(0.35f, 0.35f, 0.35f)
@ -177,8 +177,8 @@ object MatteryGUI {
for (i in deathLog.indices.reversed()) { for (i in deathLog.indices.reversed()) {
val component = deathLog[i] val component = deathLog[i]
minecraft.font.drawAligned(stack, component.second, TextAlign.CENTER_CENTER, x + 1f, y + 1f, RGBAColor.BLACK) minecraft.font.drawAligned(stack, component.second, RenderGravity.CENTER_CENTER, x + 1f, y + 1f, RGBAColor.BLACK)
minecraft.font.drawAligned(stack, component.second, TextAlign.CENTER_CENTER, x, y, RGBAColor(color, color, color)) minecraft.font.drawAligned(stack, component.second, RenderGravity.CENTER_CENTER, x, y, RGBAColor(color, color, color))
y += minecraft.font.lineHeight y += minecraft.font.lineHeight
color = (color - 0x20).coerceAtLeast(0x0) color = (color - 0x20).coerceAtLeast(0x0)
@ -249,8 +249,8 @@ object MatteryGUI {
val formattedPower = mattery.androidEnergy.batteryLevel.formatPower() val formattedPower = mattery.androidEnergy.batteryLevel.formatPower()
event.guiGraphics.drawScaledAligned(gui.font, formattedPower, 0.5f, TextAlign.CENTER_LEFT, left + 83f, top + 4f, RGBAColor.BLACK.toInt()) event.guiGraphics.drawScaledAligned(gui.font, formattedPower, 0.5f, RenderGravity.CENTER_LEFT, left + 83f, top + 4f, RGBAColor.BLACK.toInt())
event.guiGraphics.drawScaledAligned(gui.font, formattedPower, 0.5f, TextAlign.CENTER_LEFT, left + 82f, top + 3f, RGBAColor.YELLOW.toInt()) event.guiGraphics.drawScaledAligned(gui.font, formattedPower, 0.5f, RenderGravity.CENTER_LEFT, left + 82f, top + 3f, RGBAColor.YELLOW.toInt())
} }
} }
@ -325,8 +325,8 @@ object MatteryGUI {
if (ply.absorptionAmount > 0) if (ply.absorptionAmount > 0)
formattedHealth = "%d+%d/%d".format(ply.health.toInt(), ply.absorptionAmount.toInt(), ply.maxHealth.toInt()) formattedHealth = "%d+%d/%d".format(ply.health.toInt(), ply.absorptionAmount.toInt(), ply.maxHealth.toInt())
event.guiGraphics.drawScaledAligned(minecraft.font, formattedHealth, 0.5f, TextAlign.CENTER_RIGHT, left - 4f, top + 4f, RGBAColor.BLACK.toInt()) event.guiGraphics.drawScaledAligned(minecraft.font, formattedHealth, 0.5f, RenderGravity.CENTER_RIGHT, left - 4f, top + 4f, RGBAColor.BLACK.toInt())
event.guiGraphics.drawScaledAligned(minecraft.font, formattedHealth, 0.5f, TextAlign.CENTER_RIGHT, left - 5f, top + 3f, getHealthColorForPlayer(ply)) event.guiGraphics.drawScaledAligned(minecraft.font, formattedHealth, 0.5f, RenderGravity.CENTER_RIGHT, left - 5f, top + 3f, getHealthColorForPlayer(ply))
} }
} }

View File

@ -17,7 +17,7 @@ import ru.dbotthepony.mc.otm.core.math.RGBAColor
import ru.dbotthepony.mc.otm.core.math.linearInterpolation import ru.dbotthepony.mc.otm.core.math.linearInterpolation
import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.ConcurrentHashMap
sealed class AbstractMatterySprite { sealed class AbstractMatterySprite : IGUIRenderable {
/** /**
* Expected image width in pixels, used in calculations * Expected image width in pixels, used in calculations
* and as default width argument in render methods * and as default width argument in render methods
@ -76,7 +76,6 @@ sealed class AbstractMatterySprite {
renderRaw(stack, x, y, width, height, winding) renderRaw(stack, x, y, width, height, winding)
} }
@JvmOverloads
fun render( fun render(
graphics: GuiGraphics, graphics: GuiGraphics,
x: Float = 0f, x: Float = 0f,
@ -88,6 +87,14 @@ sealed class AbstractMatterySprite {
render(graphics.pose(), x, y, width, height, winding) render(graphics.pose(), x, y, width, height, winding)
} }
override fun render(guiGraphics: GuiGraphics, x: Float, y: Float, width: Float, height: Float) {
return render(guiGraphics, x, y, width, height, winding)
}
override fun render(guiGraphics: GuiGraphics, x: Float, y: Float, gravity: RenderGravity) {
return render(guiGraphics, gravity.x(x, width), gravity.y(y, height), width, height, winding)
}
@JvmOverloads @JvmOverloads
fun render( fun render(
stack: PoseStack, stack: PoseStack,

View File

@ -20,7 +20,6 @@ import ru.dbotthepony.mc.otm.core.math.rotateAroundThis
import ru.dbotthepony.mc.otm.core.math.times import ru.dbotthepony.mc.otm.core.math.times
import ru.dbotthepony.mc.otm.core.math.translation import ru.dbotthepony.mc.otm.core.math.translation
import ru.dbotthepony.mc.otm.core.math.unaryMinus import ru.dbotthepony.mc.otm.core.math.unaryMinus
import kotlin.math.roundToInt
val tesselator: Tesselator get() = Tesselator.getInstance() val tesselator: Tesselator get() = Tesselator.getInstance()
@ -63,20 +62,6 @@ fun PoseStack.translation(): Vector3f {
inline val PoseStack.last: PoseStack.Pose get() = last() inline val PoseStack.last: PoseStack.Pose get() = last()
inline val PoseStack.Pose.pose: Matrix4f get() = pose() inline val PoseStack.Pose.pose: Matrix4f get() = pose()
enum class TextAlign {
TOP_LEFT,
TOP_CENTER,
TOP_RIGHT,
CENTER_LEFT,
CENTER_CENTER,
CENTER_RIGHT,
BOTTOM_LEFT,
BOTTOM_CENTER,
BOTTOM_RIGHT,
}
private fun Font.drawScaledDuckTyped(poseStack: PoseStack, text: Any, scale: Float, x: Float, y: Float, color: Int): Int { private fun Font.drawScaledDuckTyped(poseStack: PoseStack, text: Any, scale: Float, x: Float, y: Float, color: Int): Int {
val translation = poseStack.translation() val translation = poseStack.translation()
@ -152,27 +137,15 @@ private fun Font.widthDuckTyped(text: Any): Int {
} }
} }
private fun Font.drawAlignedDuckTyped(poseStack: PoseStack, text: Any, align: TextAlign, x: Float, y: Float, color: Int): Int { private fun Font.drawAlignedDuckTyped(poseStack: PoseStack, text: Any, align: RenderGravity, x: Float, y: Float, color: Int): Int {
return when (align) { return drawDuckTyped(poseStack, text, align.x(x, widthDuckTyped(text)), align.y(y, lineHeight), color)
TextAlign.TOP_LEFT -> drawDuckTyped(poseStack, text, x, y, color)
TextAlign.TOP_CENTER -> drawDuckTyped(poseStack, text, (x - widthDuckTyped(text) / 2f), y, color)
TextAlign.TOP_RIGHT -> drawDuckTyped(poseStack, text, (x - widthDuckTyped(text)), y, color)
TextAlign.CENTER_LEFT -> drawDuckTyped(poseStack, text, x, (y - lineHeight / 2f), color)
TextAlign.CENTER_CENTER -> drawDuckTyped(poseStack, text, (x - widthDuckTyped(text) / 2f), (y - lineHeight / 2f), color)
TextAlign.CENTER_RIGHT -> drawDuckTyped(poseStack, text, (x - widthDuckTyped(text)), (y - lineHeight / 2f), color)
TextAlign.BOTTOM_LEFT -> drawDuckTyped(poseStack, text, x, (y - lineHeight), color)
TextAlign.BOTTOM_CENTER -> drawDuckTyped(poseStack, text, (x - widthDuckTyped(text) / 2f), (y - lineHeight), color)
TextAlign.BOTTOM_RIGHT -> drawDuckTyped(poseStack, text, (x - widthDuckTyped(text)), (y - lineHeight), color)
}
} }
private fun Font.drawAlignedDuckTyped( private fun Font.drawAlignedDuckTyped(
poseStack: PoseStack, poseStack: PoseStack,
buffer: MultiBufferSource, buffer: MultiBufferSource,
text: Any, text: Any,
align: TextAlign, align: RenderGravity,
x: Float, x: Float,
y: Float, y: Float,
color: Int, color: Int,
@ -181,25 +154,13 @@ private fun Font.drawAlignedDuckTyped(
packedLightCoords: Int = 15728880, packedLightCoords: Int = 15728880,
effectColor: Int = 0 effectColor: Int = 0
): Int { ): Int {
return when (align) { return drawDuckTyped(poseStack, buffer, text, align.x(x, widthDuckTyped(text)), align.y(y, lineHeight), color, drawShadow, displayMode, packedLightCoords, effectColor)
TextAlign.TOP_LEFT -> drawDuckTyped(poseStack, buffer, text, x, y, color, drawShadow, displayMode, packedLightCoords, effectColor)
TextAlign.TOP_CENTER -> drawDuckTyped(poseStack, buffer, text, (x - widthDuckTyped(text) / 2f), y, color, drawShadow, displayMode, packedLightCoords, effectColor)
TextAlign.TOP_RIGHT -> drawDuckTyped(poseStack, buffer, text, (x - widthDuckTyped(text)), y, color, drawShadow, displayMode, packedLightCoords, effectColor)
TextAlign.CENTER_LEFT -> drawDuckTyped(poseStack, buffer, text, x, (y - lineHeight / 2f), color, drawShadow, displayMode, packedLightCoords, effectColor)
TextAlign.CENTER_CENTER -> drawDuckTyped(poseStack, buffer, text, (x - widthDuckTyped(text) / 2f), (y - lineHeight / 2f), color, drawShadow, displayMode, packedLightCoords, effectColor)
TextAlign.CENTER_RIGHT -> drawDuckTyped(poseStack, buffer, text, (x - widthDuckTyped(text)), (y - lineHeight / 2f), color, drawShadow, displayMode, packedLightCoords, effectColor)
TextAlign.BOTTOM_LEFT -> drawDuckTyped(poseStack, buffer, text, x, (y - lineHeight), color, drawShadow, displayMode, packedLightCoords, effectColor)
TextAlign.BOTTOM_CENTER -> drawDuckTyped(poseStack, buffer, text, (x - widthDuckTyped(text) / 2f), (y - lineHeight), color, drawShadow, displayMode, packedLightCoords, effectColor)
TextAlign.BOTTOM_RIGHT -> drawDuckTyped(poseStack, buffer, text, (x - widthDuckTyped(text)), (y - lineHeight), color, drawShadow, displayMode, packedLightCoords, effectColor)
}
} }
private fun GuiGraphics.drawAlignedDuckTyped( private fun GuiGraphics.drawAlignedDuckTyped(
font: Font, font: Font,
text: Any, text: Any,
align: TextAlign, align: RenderGravity,
x: Float, x: Float,
y: Float, y: Float,
color: Int, color: Int,
@ -208,39 +169,13 @@ private fun GuiGraphics.drawAlignedDuckTyped(
packedLightCoords: Int = 15728880, packedLightCoords: Int = 15728880,
effectColor: Int = 0 effectColor: Int = 0
): Int { ): Int {
val width = when (align) { val width = font.drawDuckTyped(pose(), bufferSource(), text, align.x(x, font.widthDuckTyped(text)), align.y(y, font.lineHeight), color, drawShadow, displayMode, packedLightCoords, effectColor)
TextAlign.TOP_LEFT -> font.drawDuckTyped(pose(), bufferSource(), text, x, y, color, drawShadow, displayMode, packedLightCoords, effectColor)
TextAlign.TOP_CENTER -> font.drawDuckTyped(pose(), bufferSource(), text, (x - font.widthDuckTyped(text) / 2f), y, color, drawShadow, displayMode, packedLightCoords, effectColor)
TextAlign.TOP_RIGHT -> font.drawDuckTyped(pose(), bufferSource(), text, (x - font.widthDuckTyped(text)), y, color, drawShadow, displayMode, packedLightCoords, effectColor)
TextAlign.CENTER_LEFT -> font.drawDuckTyped(pose(), bufferSource(), text, x, (y - font.lineHeight / 2f), color, drawShadow, displayMode, packedLightCoords, effectColor)
TextAlign.CENTER_CENTER -> font.drawDuckTyped(pose(), bufferSource(), text, (x - font.widthDuckTyped(text) / 2f), (y - font.lineHeight / 2f), color, drawShadow, displayMode, packedLightCoords, effectColor)
TextAlign.CENTER_RIGHT -> font.drawDuckTyped(pose(), bufferSource(), text, (x - font.widthDuckTyped(text)), (y - font.lineHeight / 2f), color, drawShadow, displayMode, packedLightCoords, effectColor)
TextAlign.BOTTOM_LEFT -> font.drawDuckTyped(pose(), bufferSource(), text, x, (y - font.lineHeight), color, drawShadow, displayMode, packedLightCoords, effectColor)
TextAlign.BOTTOM_CENTER -> font.drawDuckTyped(pose(), bufferSource(), text, (x - font.widthDuckTyped(text) / 2f), (y - font.lineHeight), color, drawShadow, displayMode, packedLightCoords, effectColor)
TextAlign.BOTTOM_RIGHT -> font.drawDuckTyped(pose(), bufferSource(), text, (x - font.widthDuckTyped(text)), (y - font.lineHeight), color, drawShadow, displayMode, packedLightCoords, effectColor)
}
flush() flush()
return width return width
} }
private fun Font.drawScaledAlignedDuckTyped(poseStack: PoseStack, text: Any, scale: Float, align: TextAlign, x: Float, y: Float, color: Int): Int { private fun Font.drawScaledAlignedDuckTyped(poseStack: PoseStack, text: Any, scale: Float, align: RenderGravity, x: Float, y: Float, color: Int): Int {
return when (align) { return drawScaledDuckTyped(poseStack, text, scale, align.x(x, widthDuckTyped(text)), align.y(y, lineHeight * scale), color)
TextAlign.TOP_LEFT -> drawScaledDuckTyped(poseStack, text, scale, x, y, color)
TextAlign.TOP_CENTER -> drawScaledDuckTyped(poseStack, text, scale, (x - widthDuckTyped(text) * scale / 2f), y, color)
TextAlign.TOP_RIGHT -> drawScaledDuckTyped(poseStack, text, scale, (x - widthDuckTyped(text) * scale), y, color)
TextAlign.CENTER_LEFT -> drawScaledDuckTyped(poseStack, text, scale, x, (y - lineHeight / 2f * scale), color)
TextAlign.CENTER_CENTER -> drawScaledDuckTyped(poseStack, text, scale, (x - widthDuckTyped(text) * scale / 2f), (y - lineHeight * scale / 2f), color)
TextAlign.CENTER_RIGHT -> drawScaledDuckTyped(poseStack, text, scale, (x - widthDuckTyped(text) * scale), (y - lineHeight * scale / 2f), color)
TextAlign.BOTTOM_LEFT -> drawScaledDuckTyped(poseStack, text, scale, x, (y - lineHeight * scale), color)
TextAlign.BOTTOM_CENTER -> drawScaledDuckTyped(poseStack, text, scale, (x - widthDuckTyped(text) * scale / 2f), (y - lineHeight * scale), color)
TextAlign.BOTTOM_RIGHT -> drawScaledDuckTyped(poseStack, text, scale, (x - widthDuckTyped(text) * scale), (y - lineHeight * scale), color)
}
} }
private fun Font.drawScaledAlignedDuckTyped( private fun Font.drawScaledAlignedDuckTyped(
@ -248,7 +183,7 @@ private fun Font.drawScaledAlignedDuckTyped(
buffer: MultiBufferSource, buffer: MultiBufferSource,
text: Any, text: Any,
scale: Float, scale: Float,
align: TextAlign, align: RenderGravity,
x: Float, x: Float,
y: Float, y: Float,
color: Int, color: Int,
@ -257,26 +192,14 @@ private fun Font.drawScaledAlignedDuckTyped(
packedLightCoords: Int = 15728880, packedLightCoords: Int = 15728880,
effectColor: Int = 0 effectColor: Int = 0
): Int { ): Int {
return when (align) { return drawScaledDuckTyped(poseStack, buffer, text, scale, align.x(x, widthDuckTyped(text) * scale), align.y(y, lineHeight * scale), color, drawShadow, displayMode, packedLightCoords, effectColor)
TextAlign.TOP_LEFT -> drawScaledDuckTyped(poseStack, buffer, text, scale, x, y, color, drawShadow, displayMode, packedLightCoords, effectColor)
TextAlign.TOP_CENTER -> drawScaledDuckTyped(poseStack, buffer, text, scale, (x - widthDuckTyped(text) * scale / 2f), y, color, drawShadow, displayMode, packedLightCoords, effectColor)
TextAlign.TOP_RIGHT -> drawScaledDuckTyped(poseStack, buffer, text, scale, (x - widthDuckTyped(text) * scale), y, color, drawShadow, displayMode, packedLightCoords, effectColor)
TextAlign.CENTER_LEFT -> drawScaledDuckTyped(poseStack, buffer, text, scale, x, (y - lineHeight / 2f * scale), color, drawShadow, displayMode, packedLightCoords, effectColor)
TextAlign.CENTER_CENTER -> drawScaledDuckTyped(poseStack, buffer, text, scale, (x - widthDuckTyped(text) * scale / 2f), (y - lineHeight * scale / 2f), color, drawShadow, displayMode, packedLightCoords, effectColor)
TextAlign.CENTER_RIGHT -> drawScaledDuckTyped(poseStack, buffer, text, scale, (x - widthDuckTyped(text) * scale), (y - lineHeight * scale / 2f), color, drawShadow, displayMode, packedLightCoords, effectColor)
TextAlign.BOTTOM_LEFT -> drawScaledDuckTyped(poseStack, buffer, text, scale, x, (y - lineHeight * scale), color, drawShadow, displayMode, packedLightCoords, effectColor)
TextAlign.BOTTOM_CENTER -> drawScaledDuckTyped(poseStack, buffer, text, scale, (x - widthDuckTyped(text) * scale / 2f), (y - lineHeight * scale), color, drawShadow, displayMode, packedLightCoords, effectColor)
TextAlign.BOTTOM_RIGHT -> drawScaledDuckTyped(poseStack, buffer, text, scale, (x - widthDuckTyped(text) * scale), (y - lineHeight * scale), color, drawShadow, displayMode, packedLightCoords, effectColor)
}
} }
private fun GuiGraphics.drawScaledAlignedDuckTyped( private fun GuiGraphics.drawScaledAlignedDuckTyped(
font: Font, font: Font,
text: Any, text: Any,
scale: Float, scale: Float,
align: TextAlign, align: RenderGravity,
x: Float, x: Float,
y: Float, y: Float,
color: Int, color: Int,
@ -285,69 +208,55 @@ private fun GuiGraphics.drawScaledAlignedDuckTyped(
packedLightCoords: Int = 15728880, packedLightCoords: Int = 15728880,
effectColor: Int = 0 effectColor: Int = 0
): Int { ): Int {
val width = when (align) { val width = font.drawScaledDuckTyped(pose(), bufferSource(), text, scale, align.x(x, font.widthDuckTyped(text) * scale), align.y(y, font.lineHeight * scale), color, drawShadow, displayMode, packedLightCoords, effectColor)
TextAlign.TOP_LEFT -> font.drawScaledDuckTyped(pose(), bufferSource(), text, scale, x, y, color, drawShadow, displayMode, packedLightCoords, effectColor)
TextAlign.TOP_CENTER -> font.drawScaledDuckTyped(pose(), bufferSource(), text, scale, (x - font.widthDuckTyped(text) * scale / 2f), y, color, drawShadow, displayMode, packedLightCoords, effectColor)
TextAlign.TOP_RIGHT -> font.drawScaledDuckTyped(pose(), bufferSource(), text, scale, (x - font.widthDuckTyped(text) * scale), y, color, drawShadow, displayMode, packedLightCoords, effectColor)
TextAlign.CENTER_LEFT -> font.drawScaledDuckTyped(pose(), bufferSource(), text, scale, x, (y - font.lineHeight / 2f * scale), color, drawShadow, displayMode, packedLightCoords, effectColor)
TextAlign.CENTER_CENTER -> font.drawScaledDuckTyped(pose(), bufferSource(), text, scale, (x - font.widthDuckTyped(text) * scale / 2f), (y - font.lineHeight * scale / 2f), color, drawShadow, displayMode, packedLightCoords, effectColor)
TextAlign.CENTER_RIGHT -> font.drawScaledDuckTyped(pose(), bufferSource(), text, scale, (x - font.widthDuckTyped(text) * scale), (y - font.lineHeight * scale / 2f), color, drawShadow, displayMode, packedLightCoords, effectColor)
TextAlign.BOTTOM_LEFT -> font.drawScaledDuckTyped(pose(), bufferSource(), text, scale, x, (y - font.lineHeight * scale), color, drawShadow, displayMode, packedLightCoords, effectColor)
TextAlign.BOTTOM_CENTER -> font.drawScaledDuckTyped(pose(), bufferSource(), text, scale, (x - font.widthDuckTyped(text) * scale / 2f), (y - font.lineHeight * scale), color, drawShadow, displayMode, packedLightCoords, effectColor)
TextAlign.BOTTOM_RIGHT -> font.drawScaledDuckTyped(pose(), bufferSource(), text, scale, (x - font.widthDuckTyped(text) * scale), (y - font.lineHeight * scale), color, drawShadow, displayMode, packedLightCoords, effectColor)
}
flush() flush()
return width return width
} }
fun Font.drawAligned(poseStack: PoseStack, text: String, align: TextAlign, x: Float, y: Float, color: Int) = drawAlignedDuckTyped(poseStack, text, align, x, y, color) fun Font.drawAligned(poseStack: PoseStack, text: String, align: RenderGravity, x: Float, y: Float, color: Int) = drawAlignedDuckTyped(poseStack, text, align, x, y, color)
fun Font.drawAligned(poseStack: PoseStack, text: Component, align: TextAlign, x: Float, y: Float, color: Int) = drawAlignedDuckTyped(poseStack, text, align, x, y, color) fun Font.drawAligned(poseStack: PoseStack, text: Component, align: RenderGravity, x: Float, y: Float, color: Int) = drawAlignedDuckTyped(poseStack, text, align, x, y, color)
fun Font.drawAligned(poseStack: PoseStack, text: FormattedCharSequence, align: TextAlign, x: Float, y: Float, color: Int) = drawAlignedDuckTyped(poseStack, text, align, x, y, color) fun Font.drawAligned(poseStack: PoseStack, text: FormattedCharSequence, align: RenderGravity, x: Float, y: Float, color: Int) = drawAlignedDuckTyped(poseStack, text, align, x, y, color)
fun Font.drawAligned(poseStack: PoseStack, text: String, align: TextAlign, x: Float, y: Float, color: RGBAColor) = drawAligned(poseStack, text, align, x, y, color.toInt()) fun Font.drawAligned(poseStack: PoseStack, text: String, align: RenderGravity, x: Float, y: Float, color: RGBAColor) = drawAligned(poseStack, text, align, x, y, color.toInt())
fun Font.drawAligned(poseStack: PoseStack, text: Component, align: TextAlign, x: Float, y: Float, color: RGBAColor) = drawAligned(poseStack, text, align, x, y, color.toInt()) fun Font.drawAligned(poseStack: PoseStack, text: Component, align: RenderGravity, x: Float, y: Float, color: RGBAColor) = drawAligned(poseStack, text, align, x, y, color.toInt())
fun Font.drawAligned(poseStack: PoseStack, text: FormattedCharSequence, align: TextAlign, x: Float, y: Float, color: RGBAColor) = drawAligned(poseStack, text, align, x, y, color.toInt()) fun Font.drawAligned(poseStack: PoseStack, text: FormattedCharSequence, align: RenderGravity, x: Float, y: Float, color: RGBAColor) = drawAligned(poseStack, text, align, x, y, color.toInt())
fun Font.drawScaledAligned(poseStack: PoseStack, text: String, scale: Float, align: TextAlign, x: Float, y: Float, color: Int) = drawScaledAlignedDuckTyped(poseStack, text, scale, align, x, y, color) fun Font.drawScaledAligned(poseStack: PoseStack, text: String, scale: Float, align: RenderGravity, x: Float, y: Float, color: Int) = drawScaledAlignedDuckTyped(poseStack, text, scale, align, x, y, color)
fun Font.drawScaledAligned(poseStack: PoseStack, text: Component, scale: Float, align: TextAlign, x: Float, y: Float, color: Int) = drawScaledAlignedDuckTyped(poseStack, text, scale, align, x, y, color) fun Font.drawScaledAligned(poseStack: PoseStack, text: Component, scale: Float, align: RenderGravity, x: Float, y: Float, color: Int) = drawScaledAlignedDuckTyped(poseStack, text, scale, align, x, y, color)
fun Font.drawScaledAligned(poseStack: PoseStack, text: FormattedCharSequence, scale: Float, align: TextAlign, x: Float, y: Float, color: Int) = drawScaledAlignedDuckTyped(poseStack, text, scale, align, x, y, color) fun Font.drawScaledAligned(poseStack: PoseStack, text: FormattedCharSequence, scale: Float, align: RenderGravity, x: Float, y: Float, color: Int) = drawScaledAlignedDuckTyped(poseStack, text, scale, align, x, y, color)
fun Font.drawScaledAligned(poseStack: PoseStack, text: String, scale: Float, align: TextAlign, x: Float, y: Float, color: RGBAColor) = drawScaledAligned(poseStack, text, scale, align, x, y, color.toInt()) fun Font.drawScaledAligned(poseStack: PoseStack, text: String, scale: Float, align: RenderGravity, x: Float, y: Float, color: RGBAColor) = drawScaledAligned(poseStack, text, scale, align, x, y, color.toInt())
fun Font.drawScaledAligned(poseStack: PoseStack, text: Component, scale: Float, align: TextAlign, x: Float, y: Float, color: RGBAColor) = drawScaledAligned(poseStack, text, scale, align, x, y, color.toInt()) fun Font.drawScaledAligned(poseStack: PoseStack, text: Component, scale: Float, align: RenderGravity, x: Float, y: Float, color: RGBAColor) = drawScaledAligned(poseStack, text, scale, align, x, y, color.toInt())
fun Font.drawScaledAligned(poseStack: PoseStack, text: FormattedCharSequence, scale: Float, align: TextAlign, x: Float, y: Float, color: RGBAColor) = drawScaledAligned(poseStack, text, scale, align, x, y, color.toInt()) fun Font.drawScaledAligned(poseStack: PoseStack, text: FormattedCharSequence, scale: Float, align: RenderGravity, x: Float, y: Float, color: RGBAColor) = drawScaledAligned(poseStack, text, scale, align, x, y, color.toInt())
fun Font.drawAligned(poseStack: PoseStack, buffer: MultiBufferSource, text: String, align: TextAlign, x: Float, y: Float, color: Int, drawShadow: Boolean = false, displayMode: Font.DisplayMode = Font.DisplayMode.NORMAL, packedLightCoords: Int = 15728880, effectColor: Int = 0) = drawAlignedDuckTyped(poseStack, buffer, text, align, x, y, color, drawShadow, displayMode, packedLightCoords, effectColor) fun Font.drawAligned(poseStack: PoseStack, buffer: MultiBufferSource, text: String, align: RenderGravity, x: Float, y: Float, color: Int, drawShadow: Boolean = false, displayMode: Font.DisplayMode = Font.DisplayMode.NORMAL, packedLightCoords: Int = 15728880, effectColor: Int = 0) = drawAlignedDuckTyped(poseStack, buffer, text, align, x, y, color, drawShadow, displayMode, packedLightCoords, effectColor)
fun Font.drawAligned(poseStack: PoseStack, buffer: MultiBufferSource, text: Component, align: TextAlign, x: Float, y: Float, color: Int, drawShadow: Boolean = false, displayMode: Font.DisplayMode = Font.DisplayMode.NORMAL, packedLightCoords: Int = 15728880, effectColor: Int = 0) = drawAlignedDuckTyped(poseStack, buffer, text, align, x, y, color, drawShadow, displayMode, packedLightCoords, effectColor) fun Font.drawAligned(poseStack: PoseStack, buffer: MultiBufferSource, text: Component, align: RenderGravity, x: Float, y: Float, color: Int, drawShadow: Boolean = false, displayMode: Font.DisplayMode = Font.DisplayMode.NORMAL, packedLightCoords: Int = 15728880, effectColor: Int = 0) = drawAlignedDuckTyped(poseStack, buffer, text, align, x, y, color, drawShadow, displayMode, packedLightCoords, effectColor)
fun Font.drawAligned(poseStack: PoseStack, buffer: MultiBufferSource, text: FormattedCharSequence, align: TextAlign, x: Float, y: Float, color: Int, drawShadow: Boolean = false, displayMode: Font.DisplayMode = Font.DisplayMode.NORMAL, packedLightCoords: Int = 15728880, effectColor: Int = 0) = drawAlignedDuckTyped(poseStack, buffer, text, align, x, y, color, drawShadow, displayMode, packedLightCoords, effectColor) fun Font.drawAligned(poseStack: PoseStack, buffer: MultiBufferSource, text: FormattedCharSequence, align: RenderGravity, x: Float, y: Float, color: Int, drawShadow: Boolean = false, displayMode: Font.DisplayMode = Font.DisplayMode.NORMAL, packedLightCoords: Int = 15728880, effectColor: Int = 0) = drawAlignedDuckTyped(poseStack, buffer, text, align, x, y, color, drawShadow, displayMode, packedLightCoords, effectColor)
fun Font.drawAligned(poseStack: PoseStack, buffer: MultiBufferSource, text: String, align: TextAlign, x: Float, y: Float, color: RGBAColor, drawShadow: Boolean = false, displayMode: Font.DisplayMode = Font.DisplayMode.NORMAL, packedLightCoords: Int = 15728880, effectColor: Int = 0) = drawAligned(poseStack, buffer, text, align, x, y, color.toInt(), drawShadow, displayMode, packedLightCoords, effectColor) fun Font.drawAligned(poseStack: PoseStack, buffer: MultiBufferSource, text: String, align: RenderGravity, x: Float, y: Float, color: RGBAColor, drawShadow: Boolean = false, displayMode: Font.DisplayMode = Font.DisplayMode.NORMAL, packedLightCoords: Int = 15728880, effectColor: Int = 0) = drawAligned(poseStack, buffer, text, align, x, y, color.toInt(), drawShadow, displayMode, packedLightCoords, effectColor)
fun Font.drawAligned(poseStack: PoseStack, buffer: MultiBufferSource, text: Component, align: TextAlign, x: Float, y: Float, color: RGBAColor, drawShadow: Boolean = false, displayMode: Font.DisplayMode = Font.DisplayMode.NORMAL, packedLightCoords: Int = 15728880, effectColor: Int = 0) = drawAligned(poseStack, buffer, text, align, x, y, color.toInt(), drawShadow, displayMode, packedLightCoords, effectColor) fun Font.drawAligned(poseStack: PoseStack, buffer: MultiBufferSource, text: Component, align: RenderGravity, x: Float, y: Float, color: RGBAColor, drawShadow: Boolean = false, displayMode: Font.DisplayMode = Font.DisplayMode.NORMAL, packedLightCoords: Int = 15728880, effectColor: Int = 0) = drawAligned(poseStack, buffer, text, align, x, y, color.toInt(), drawShadow, displayMode, packedLightCoords, effectColor)
fun Font.drawAligned(poseStack: PoseStack, buffer: MultiBufferSource, text: FormattedCharSequence, align: TextAlign, x: Float, y: Float, color: RGBAColor, drawShadow: Boolean = false, displayMode: Font.DisplayMode = Font.DisplayMode.NORMAL, packedLightCoords: Int = 15728880, effectColor: Int = 0) = drawAligned(poseStack, buffer, text, align, x, y, color.toInt(), drawShadow, displayMode, packedLightCoords, effectColor) fun Font.drawAligned(poseStack: PoseStack, buffer: MultiBufferSource, text: FormattedCharSequence, align: RenderGravity, x: Float, y: Float, color: RGBAColor, drawShadow: Boolean = false, displayMode: Font.DisplayMode = Font.DisplayMode.NORMAL, packedLightCoords: Int = 15728880, effectColor: Int = 0) = drawAligned(poseStack, buffer, text, align, x, y, color.toInt(), drawShadow, displayMode, packedLightCoords, effectColor)
fun Font.drawScaledAligned(poseStack: PoseStack, buffer: MultiBufferSource, text: String, scale: Float, align: TextAlign, x: Float, y: Float, color: Int, drawShadow: Boolean = false, displayMode: Font.DisplayMode = Font.DisplayMode.NORMAL, packedLightCoords: Int = 15728880, effectColor: Int = 0,) = drawScaledAlignedDuckTyped(poseStack, buffer, text, scale, align, x, y, color, drawShadow, displayMode, packedLightCoords, effectColor) fun Font.drawScaledAligned(poseStack: PoseStack, buffer: MultiBufferSource, text: String, scale: Float, align: RenderGravity, x: Float, y: Float, color: Int, drawShadow: Boolean = false, displayMode: Font.DisplayMode = Font.DisplayMode.NORMAL, packedLightCoords: Int = 15728880, effectColor: Int = 0,) = drawScaledAlignedDuckTyped(poseStack, buffer, text, scale, align, x, y, color, drawShadow, displayMode, packedLightCoords, effectColor)
fun Font.drawScaledAligned(poseStack: PoseStack, buffer: MultiBufferSource, text: Component, scale: Float, align: TextAlign, x: Float, y: Float, color: Int, drawShadow: Boolean = false, displayMode: Font.DisplayMode = Font.DisplayMode.NORMAL, packedLightCoords: Int = 15728880, effectColor: Int = 0,) = drawScaledAlignedDuckTyped(poseStack, buffer, text, scale, align, x, y, color, drawShadow, displayMode, packedLightCoords, effectColor) fun Font.drawScaledAligned(poseStack: PoseStack, buffer: MultiBufferSource, text: Component, scale: Float, align: RenderGravity, x: Float, y: Float, color: Int, drawShadow: Boolean = false, displayMode: Font.DisplayMode = Font.DisplayMode.NORMAL, packedLightCoords: Int = 15728880, effectColor: Int = 0,) = drawScaledAlignedDuckTyped(poseStack, buffer, text, scale, align, x, y, color, drawShadow, displayMode, packedLightCoords, effectColor)
fun Font.drawScaledAligned(poseStack: PoseStack, buffer: MultiBufferSource, text: FormattedCharSequence, scale: Float, align: TextAlign, x: Float, y: Float, color: Int, drawShadow: Boolean = false, displayMode: Font.DisplayMode = Font.DisplayMode.NORMAL, packedLightCoords: Int = 15728880, effectColor: Int = 0,) = drawScaledAlignedDuckTyped(poseStack, buffer, text, scale, align, x, y, color, drawShadow, displayMode, packedLightCoords, effectColor) fun Font.drawScaledAligned(poseStack: PoseStack, buffer: MultiBufferSource, text: FormattedCharSequence, scale: Float, align: RenderGravity, x: Float, y: Float, color: Int, drawShadow: Boolean = false, displayMode: Font.DisplayMode = Font.DisplayMode.NORMAL, packedLightCoords: Int = 15728880, effectColor: Int = 0,) = drawScaledAlignedDuckTyped(poseStack, buffer, text, scale, align, x, y, color, drawShadow, displayMode, packedLightCoords, effectColor)
fun Font.drawScaledAligned(poseStack: PoseStack, buffer: MultiBufferSource, text: String, scale: Float, align: TextAlign, x: Float, y: Float, drawShadow: Boolean = false, displayMode: Font.DisplayMode = Font.DisplayMode.NORMAL, packedLightCoords: Int = 15728880, effectColor: Int = 0, color: RGBAColor) = drawScaledAligned(poseStack, buffer, text, scale, align, x, y, color.toInt(), drawShadow, displayMode, packedLightCoords, effectColor) fun Font.drawScaledAligned(poseStack: PoseStack, buffer: MultiBufferSource, text: String, scale: Float, align: RenderGravity, x: Float, y: Float, drawShadow: Boolean = false, displayMode: Font.DisplayMode = Font.DisplayMode.NORMAL, packedLightCoords: Int = 15728880, effectColor: Int = 0, color: RGBAColor) = drawScaledAligned(poseStack, buffer, text, scale, align, x, y, color.toInt(), drawShadow, displayMode, packedLightCoords, effectColor)
fun Font.drawScaledAligned(poseStack: PoseStack, buffer: MultiBufferSource, text: Component, scale: Float, align: TextAlign, x: Float, y: Float, drawShadow: Boolean = false, displayMode: Font.DisplayMode = Font.DisplayMode.NORMAL, packedLightCoords: Int = 15728880, effectColor: Int = 0, color: RGBAColor) = drawScaledAligned(poseStack, buffer, text, scale, align, x, y, color.toInt(), drawShadow, displayMode, packedLightCoords, effectColor) fun Font.drawScaledAligned(poseStack: PoseStack, buffer: MultiBufferSource, text: Component, scale: Float, align: RenderGravity, x: Float, y: Float, drawShadow: Boolean = false, displayMode: Font.DisplayMode = Font.DisplayMode.NORMAL, packedLightCoords: Int = 15728880, effectColor: Int = 0, color: RGBAColor) = drawScaledAligned(poseStack, buffer, text, scale, align, x, y, color.toInt(), drawShadow, displayMode, packedLightCoords, effectColor)
fun Font.drawScaledAligned(poseStack: PoseStack, buffer: MultiBufferSource, text: FormattedCharSequence, scale: Float, align: TextAlign, x: Float, y: Float, drawShadow: Boolean = false, displayMode: Font.DisplayMode = Font.DisplayMode.NORMAL, packedLightCoords: Int = 15728880, effectColor: Int = 0, color: RGBAColor) = drawScaledAligned(poseStack, buffer, text, scale, align, x, y, color.toInt(), drawShadow, displayMode, packedLightCoords, effectColor) fun Font.drawScaledAligned(poseStack: PoseStack, buffer: MultiBufferSource, text: FormattedCharSequence, scale: Float, align: RenderGravity, x: Float, y: Float, drawShadow: Boolean = false, displayMode: Font.DisplayMode = Font.DisplayMode.NORMAL, packedLightCoords: Int = 15728880, effectColor: Int = 0, color: RGBAColor) = drawScaledAligned(poseStack, buffer, text, scale, align, x, y, color.toInt(), drawShadow, displayMode, packedLightCoords, effectColor)
fun GuiGraphics.drawAligned(font: Font, text: String, align: TextAlign, x: Float, y: Float, color: Int) = drawAlignedDuckTyped(font, text, align, x, y, color) fun GuiGraphics.drawAligned(font: Font, text: String, align: RenderGravity, x: Float, y: Float, color: Int) = drawAlignedDuckTyped(font, text, align, x, y, color)
fun GuiGraphics.drawAligned(font: Font, text: Component, align: TextAlign, x: Float, y: Float, color: Int) = drawAlignedDuckTyped(font, text, align, x, y, color) fun GuiGraphics.drawAligned(font: Font, text: Component, align: RenderGravity, x: Float, y: Float, color: Int) = drawAlignedDuckTyped(font, text, align, x, y, color)
fun GuiGraphics.drawAligned(font: Font, text: FormattedCharSequence, align: TextAlign, x: Float, y: Float, color: Int) = drawAlignedDuckTyped(font, text, align, x, y, color) fun GuiGraphics.drawAligned(font: Font, text: FormattedCharSequence, align: RenderGravity, x: Float, y: Float, color: Int) = drawAlignedDuckTyped(font, text, align, x, y, color)
fun GuiGraphics.drawAligned(font: Font, text: String, align: TextAlign, x: Float, y: Float, color: RGBAColor) = drawAligned(font, text, align, x, y, color.toInt()) fun GuiGraphics.drawAligned(font: Font, text: String, align: RenderGravity, x: Float, y: Float, color: RGBAColor) = drawAligned(font, text, align, x, y, color.toInt())
fun GuiGraphics.drawAligned(font: Font, text: Component, align: TextAlign, x: Float, y: Float, color: RGBAColor) = drawAligned(font, text, align, x, y, color.toInt()) fun GuiGraphics.drawAligned(font: Font, text: Component, align: RenderGravity, x: Float, y: Float, color: RGBAColor) = drawAligned(font, text, align, x, y, color.toInt())
fun GuiGraphics.drawAligned(font: Font, text: FormattedCharSequence, align: TextAlign, x: Float, y: Float, color: RGBAColor) = drawAligned(font, text, align, x, y, color.toInt()) fun GuiGraphics.drawAligned(font: Font, text: FormattedCharSequence, align: RenderGravity, x: Float, y: Float, color: RGBAColor) = drawAligned(font, text, align, x, y, color.toInt())
fun GuiGraphics.drawScaledAligned(font: Font, text: String, scale: Float, align: TextAlign, x: Float, y: Float, color: Int) = drawScaledAlignedDuckTyped(font, text, scale, align, x, y, color) fun GuiGraphics.drawScaledAligned(font: Font, text: String, scale: Float, align: RenderGravity, x: Float, y: Float, color: Int) = drawScaledAlignedDuckTyped(font, text, scale, align, x, y, color)
fun GuiGraphics.drawScaledAligned(font: Font, text: Component, scale: Float, align: TextAlign, x: Float, y: Float, color: Int) = drawScaledAlignedDuckTyped(font, text, scale, align, x, y, color) fun GuiGraphics.drawScaledAligned(font: Font, text: Component, scale: Float, align: RenderGravity, x: Float, y: Float, color: Int) = drawScaledAlignedDuckTyped(font, text, scale, align, x, y, color)
fun GuiGraphics.drawScaledAligned(font: Font, text: FormattedCharSequence, scale: Float, align: TextAlign, x: Float, y: Float, color: Int) = drawScaledAlignedDuckTyped(font, text, scale, align, x, y, color) fun GuiGraphics.drawScaledAligned(font: Font, text: FormattedCharSequence, scale: Float, align: RenderGravity, x: Float, y: Float, color: Int) = drawScaledAlignedDuckTyped(font, text, scale, align, x, y, color)
fun GuiGraphics.drawScaledAligned(font: Font, text: String, scale: Float, align: TextAlign, x: Float, y: Float, color: RGBAColor) = drawScaledAligned(font, text, scale, align, x, y, color.toInt()) fun GuiGraphics.drawScaledAligned(font: Font, text: String, scale: Float, align: RenderGravity, x: Float, y: Float, color: RGBAColor) = drawScaledAligned(font, text, scale, align, x, y, color.toInt())
fun GuiGraphics.drawScaledAligned(font: Font, text: Component, scale: Float, align: TextAlign, x: Float, y: Float, color: RGBAColor) = drawScaledAligned(font, text, scale, align, x, y, color.toInt()) fun GuiGraphics.drawScaledAligned(font: Font, text: Component, scale: Float, align: RenderGravity, x: Float, y: Float, color: RGBAColor) = drawScaledAligned(font, text, scale, align, x, y, color.toInt())
fun GuiGraphics.drawScaledAligned(font: Font, text: FormattedCharSequence, scale: Float, align: TextAlign, x: Float, y: Float, color: RGBAColor) = drawScaledAligned(font, text, scale, align, x, y, color.toInt()) fun GuiGraphics.drawScaledAligned(font: Font, text: FormattedCharSequence, scale: Float, align: RenderGravity, x: Float, y: Float, color: RGBAColor) = drawScaledAligned(font, text, scale, align, x, y, color.toInt())

View File

@ -0,0 +1,64 @@
package ru.dbotthepony.mc.otm.client.render
import net.minecraft.client.gui.GuiGraphics
import net.minecraft.world.item.ItemStack
interface IGUIRenderable {
fun render(guiGraphics: GuiGraphics, x: Float, y: Float, gravity: RenderGravity = RenderGravity.TOP_LEFT)
/**
* Render at specified [x], [y] with fixed [width] x [height]
*/
fun render(guiGraphics: GuiGraphics, x: Float, y: Float, width: Float, height: Float)
fun composeBefore(other: IGUIRenderable): IGUIRenderable {
return object : IGUIRenderable {
override fun render(guiGraphics: GuiGraphics, x: Float, y: Float, gravity: RenderGravity) {
this@IGUIRenderable.render(guiGraphics, x, y, gravity)
other.render(guiGraphics, x, y, gravity)
}
override fun render(guiGraphics: GuiGraphics, x: Float, y: Float, width: Float, height: Float) {
this@IGUIRenderable.render(guiGraphics, x, y, width, height)
other.render(guiGraphics, x, y, width, height)
}
}
}
fun composeAfter(other: IGUIRenderable): IGUIRenderable {
return other.composeBefore(this)
}
companion object {
fun of(value: ItemStack, width: Float = 16f, height: Float = 16f): IGUIRenderable {
return ItemStackIcon(value, width, height)
}
fun of(value: IGUIRenderable): IGUIRenderable {
return value
}
}
}
data class ItemStackIcon(private val itemStack: ItemStack, val width: Float = 16f, val height: Float = 16f) : IGUIRenderable {
override fun render(guiGraphics: GuiGraphics, x: Float, y: Float, gravity: RenderGravity) {
return render(guiGraphics, gravity.x(x, width), gravity.y(y, height), width, height)
}
override fun render(guiGraphics: GuiGraphics, x: Float, y: Float, width: Float, height: Float) {
if (x % 1f == 0f && y % 1f == 0f && width == 16f && height == 16f) {
guiGraphics.renderFakeItem(itemStack, x.toInt(), y.toInt())
} else {
val pose = guiGraphics.pose()
pose.pushPose()
pose.translate(x % 1f, y % 1f, 0f)
if (width != 16f || height != 16f)
pose.scale(width / 16f, height / 16f, 1f)
guiGraphics.renderFakeItem(itemStack, x.toInt(), y.toInt())
pose.popPose()
}
}
}

View File

@ -0,0 +1,184 @@
package ru.dbotthepony.mc.otm.client.render
import ru.dbotthepony.mc.otm.core.FloatSupplier
import kotlin.math.roundToInt
private operator fun FloatSupplier.div(other: Float): Float {
return getAsFloat() / other
}
private operator fun Float.minus(other: FloatSupplier): Float {
return this - other.getAsFloat()
}
enum class RenderGravity {
TOP_LEFT {
override fun x(x: Float, width: FloatSupplier): Float {
return x
}
override fun y(y: Float, height: FloatSupplier): Float {
return y
}
override fun x(x: Float, width: Float): Float {
return x
}
override fun y(y: Float, height: Float): Float {
return y
}
},
TOP_CENTER {
override fun x(x: Float, width: FloatSupplier): Float {
return x - width / 2f
}
override fun y(y: Float, height: FloatSupplier): Float {
return y
}
override fun x(x: Float, width: Float): Float {
return x - width / 2f
}
override fun y(y: Float, height: Float): Float {
return y
}
},
TOP_RIGHT {
override fun x(x: Float, width: FloatSupplier): Float {
return x - width
}
override fun y(y: Float, height: FloatSupplier): Float {
return y
}
override fun x(x: Float, width: Float): Float {
return x - width
}
override fun y(y: Float, height: Float): Float {
return y
}
},
CENTER_LEFT {
override fun x(x: Float, width: FloatSupplier): Float {
return x
}
override fun y(y: Float, height: FloatSupplier): Float {
return y - height / 2f
}
override fun x(x: Float, width: Float): Float {
return x
}
override fun y(y: Float, height: Float): Float {
return y - height / 2f
}
},
CENTER_CENTER {
override fun x(x: Float, width: FloatSupplier): Float {
return x - width / 2f
}
override fun y(y: Float, height: FloatSupplier): Float {
return y - height / 2f
}
override fun x(x: Float, width: Float): Float {
return x - width / 2f
}
override fun y(y: Float, height: Float): Float {
return y - height / 2f
}
},
CENTER_RIGHT {
override fun x(x: Float, width: FloatSupplier): Float {
return x - width
}
override fun y(y: Float, height: FloatSupplier): Float {
return y - height / 2f
}
override fun x(x: Float, width: Float): Float {
return x - width
}
override fun y(y: Float, height: Float): Float {
return y - height / 2f
}
},
BOTTOM_LEFT {
override fun x(x: Float, width: FloatSupplier): Float {
return x
}
override fun y(y: Float, height: FloatSupplier): Float {
return y - height
}
override fun x(x: Float, width: Float): Float {
return x
}
override fun y(y: Float, height: Float): Float {
return y - height
}
},
BOTTOM_CENTER {
override fun x(x: Float, width: FloatSupplier): Float {
return x - width / 2f
}
override fun y(y: Float, height: FloatSupplier): Float {
return y - height
}
override fun x(x: Float, width: Float): Float {
return x - width / 2f
}
override fun y(y: Float, height: Float): Float {
return y - height
}
},
BOTTOM_RIGHT {
override fun x(x: Float, width: FloatSupplier): Float {
return x - width
}
override fun y(y: Float, height: FloatSupplier): Float {
return y - height
}
override fun x(x: Float, width: Float): Float {
return x - width
}
override fun y(y: Float, height: Float): Float {
return y - height
}
};
abstract fun x(x: Float, width: FloatSupplier): Float
abstract fun y(y: Float, height: FloatSupplier): Float
abstract fun x(x: Float, width: Float): Float
abstract fun y(y: Float, height: Float): Float
fun x(x: Float, width: Int): Float {
return x(x, width.toFloat()).roundToInt().toFloat()
}
fun y(y: Float, height: Int): Float {
return y(y, height.toFloat()).roundToInt().toFloat()
}
}

View File

@ -185,11 +185,11 @@ class BlackHoleRenderer(private val context: BlockEntityRendererProvider.Context
val sorse = DynamicBufferSource.WORLD val sorse = DynamicBufferSource.WORLD
font.drawAligned(poseStack, sorse, text1, TextAlign.TOP_LEFT, 0.8f, 0.8f - font.lineHeight.toFloat() / 2f, 0x0) font.drawAligned(poseStack, sorse, text1, RenderGravity.TOP_LEFT, 0.8f, 0.8f - font.lineHeight.toFloat() / 2f, 0x0)
font.drawAligned(poseStack, sorse, text2, TextAlign.TOP_LEFT, 0.8f, 0.8f + font.lineHeight.toFloat() / 2f, 0x0) font.drawAligned(poseStack, sorse, text2, RenderGravity.TOP_LEFT, 0.8f, 0.8f + font.lineHeight.toFloat() / 2f, 0x0)
poseStack.translate(0.0, 0.0, -1.0) poseStack.translate(0.0, 0.0, -1.0)
font.drawAligned(poseStack, sorse, text1, TextAlign.TOP_LEFT, 0f, -font.lineHeight.toFloat() / 2f, 0xFFFFFF) font.drawAligned(poseStack, sorse, text1, RenderGravity.TOP_LEFT, 0f, -font.lineHeight.toFloat() / 2f, 0xFFFFFF)
font.drawAligned(poseStack, sorse, text2, TextAlign.TOP_LEFT, 0f, font.lineHeight.toFloat() / 2f, 0xFFFFFF) font.drawAligned(poseStack, sorse, text2, RenderGravity.TOP_LEFT, 0f, font.lineHeight.toFloat() / 2f, 0xFFFFFF)
poseStack.popPose() poseStack.popPose()
} }

View File

@ -48,21 +48,21 @@ class EnergyCounterRenderer(private val context: BlockEntityRendererProvider.Con
var y = -16f var y = -16f
val finalX = font.drawAligned(poseStack, sorse, "00000000", TextAlign.CENTER_CENTER, -4f, y, RGBAColor.GRAY) val finalX = font.drawAligned(poseStack, sorse, "00000000", RenderGravity.CENTER_CENTER, -4f, y, RGBAColor.GRAY)
font.drawAligned(poseStack, sorse, "00000000", TextAlign.CENTER_CENTER, -4f, y + font.lineHeight, RGBAColor.GRAY) font.drawAligned(poseStack, sorse, "00000000", RenderGravity.CENTER_CENTER, -4f, y + font.lineHeight, RGBAColor.GRAY)
font.drawAligned(poseStack, sorse, "/t", TextAlign.CENTER_LEFT, finalX.toFloat(), y, RGBAColor.GRAY) font.drawAligned(poseStack, sorse, "/t", RenderGravity.CENTER_LEFT, finalX.toFloat(), y, RGBAColor.GRAY)
font.drawAligned(poseStack, sorse, "/s", TextAlign.CENTER_LEFT, finalX.toFloat(), y + font.lineHeight, RGBAColor.GRAY) font.drawAligned(poseStack, sorse, "/s", RenderGravity.CENTER_LEFT, finalX.toFloat(), y + font.lineHeight, RGBAColor.GRAY)
poseStack.pushPose() poseStack.pushPose()
poseStack.translate(-0.1, -0.1, -0.1) poseStack.translate(-0.1, -0.1, -0.1)
font.drawAligned(poseStack, sorse, tile.lastTick.toString(0), TextAlign.CENTER_RIGHT, finalX.toFloat(), y, RGBAColor.WHITE) font.drawAligned(poseStack, sorse, tile.lastTick.toString(0), RenderGravity.CENTER_RIGHT, finalX.toFloat(), y, RGBAColor.WHITE)
font.drawAligned(poseStack, sorse, tile.sumHistory(20).toString(0), TextAlign.CENTER_RIGHT, finalX.toFloat(), y + font.lineHeight, RGBAColor.WHITE) font.drawAligned(poseStack, sorse, tile.sumHistory(20).toString(0), RenderGravity.CENTER_RIGHT, finalX.toFloat(), y + font.lineHeight, RGBAColor.WHITE)
poseStack.popPose() poseStack.popPose()
y += font.lineHeight * 3 y += font.lineHeight * 3
font.drawAligned(poseStack, sorse, TOTAL, TextAlign.CENTER_CENTER, 0f, y, RGBAColor.WHITE) font.drawAligned(poseStack, sorse, TOTAL, RenderGravity.CENTER_CENTER, 0f, y, RGBAColor.WHITE)
font.drawAligned(poseStack, sorse, tile.passed.formatPower(), TextAlign.CENTER_CENTER, 0f, y + font.lineHeight, RGBAColor.WHITE) font.drawAligned(poseStack, sorse, tile.passed.formatPower(), RenderGravity.CENTER_CENTER, 0f, y + font.lineHeight, RGBAColor.WHITE)
poseStack.popPose() poseStack.popPose()
} }

View File

@ -12,7 +12,6 @@ import net.minecraft.core.Direction
import org.joml.Matrix4f import org.joml.Matrix4f
import ru.dbotthepony.mc.otm.core.TranslatableComponent import ru.dbotthepony.mc.otm.core.TranslatableComponent
import ru.dbotthepony.mc.otm.block.BlackHoleBlock import ru.dbotthepony.mc.otm.block.BlackHoleBlock
import ru.dbotthepony.mc.otm.block.RotatableMatteryBlock
import ru.dbotthepony.mc.otm.block.entity.tech.GravitationStabilizerBlockEntity import ru.dbotthepony.mc.otm.block.entity.tech.GravitationStabilizerBlockEntity
import ru.dbotthepony.mc.otm.block.entity.blackhole.BlackHoleBlockEntity import ru.dbotthepony.mc.otm.block.entity.blackhole.BlackHoleBlockEntity
import ru.dbotthepony.mc.otm.block.entity.WorkerState import ru.dbotthepony.mc.otm.block.entity.WorkerState
@ -157,12 +156,12 @@ class GravitationStabilizerRenderer(private val context: BlockEntityRendererProv
val sorse = DynamicBufferSource.WORLD val sorse = DynamicBufferSource.WORLD
val font = minecraft.font val font = minecraft.font
font.drawAligned(poseStack, sorse, TranslatableComponent("otm.3d2d.gravitation_stabilizer.mass", bhTile.mass.formatMatter(formatAsReadable = ShiftPressedCond)), TextAlign.TOP_CENTER, 1f, -font.lineHeight.toFloat() / 2f + 1f, 0) font.drawAligned(poseStack, sorse, TranslatableComponent("otm.3d2d.gravitation_stabilizer.mass", bhTile.mass.formatMatter(formatAsReadable = ShiftPressedCond)), RenderGravity.TOP_CENTER, 1f, -font.lineHeight.toFloat() / 2f + 1f, 0)
font.drawAligned(poseStack, sorse, TranslatableComponent("otm.3d2d.gravitation_stabilizer.strength", "%.2f".format(bhTile.gravitationStrength)), TextAlign.TOP_CENTER, 1f, font.lineHeight.toFloat() / 2f + 1f, 0) font.drawAligned(poseStack, sorse, TranslatableComponent("otm.3d2d.gravitation_stabilizer.strength", "%.2f".format(bhTile.gravitationStrength)), RenderGravity.TOP_CENTER, 1f, font.lineHeight.toFloat() / 2f + 1f, 0)
poseStack.translate(0.2f, 0f, -0.5f) poseStack.translate(0.2f, 0f, -0.5f)
font.drawAligned(poseStack, sorse, TranslatableComponent("otm.3d2d.gravitation_stabilizer.mass", bhTile.mass.formatMatter(formatAsReadable = ShiftPressedCond)), TextAlign.TOP_CENTER, 0f, -font.lineHeight.toFloat() / 2f, 0xFFFFFF) font.drawAligned(poseStack, sorse, TranslatableComponent("otm.3d2d.gravitation_stabilizer.mass", bhTile.mass.formatMatter(formatAsReadable = ShiftPressedCond)), RenderGravity.TOP_CENTER, 0f, -font.lineHeight.toFloat() / 2f, 0xFFFFFF)
font.drawAligned(poseStack, sorse, TranslatableComponent("otm.3d2d.gravitation_stabilizer.strength", "%.2f".format(bhTile.gravitationStrength)), TextAlign.TOP_CENTER, 0f, font.lineHeight.toFloat() / 2f, 0xFFFFFF) font.drawAligned(poseStack, sorse, TranslatableComponent("otm.3d2d.gravitation_stabilizer.strength", "%.2f".format(bhTile.gravitationStrength)), RenderGravity.TOP_CENTER, 0f, font.lineHeight.toFloat() / 2f, 0xFFFFFF)
poseStack.popPose() poseStack.popPose()
} }

View File

@ -7,7 +7,7 @@ import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider
import ru.dbotthepony.mc.otm.block.entity.decorative.HoloSignBlockEntity import ru.dbotthepony.mc.otm.block.entity.decorative.HoloSignBlockEntity
import ru.dbotthepony.mc.otm.client.font import ru.dbotthepony.mc.otm.client.font
import ru.dbotthepony.mc.otm.client.render.DynamicBufferSource import ru.dbotthepony.mc.otm.client.render.DynamicBufferSource
import ru.dbotthepony.mc.otm.client.render.TextAlign import ru.dbotthepony.mc.otm.client.render.RenderGravity
import ru.dbotthepony.mc.otm.client.render.drawAligned import ru.dbotthepony.mc.otm.client.render.drawAligned
import ru.dbotthepony.mc.otm.core.math.RGBAColor import ru.dbotthepony.mc.otm.core.math.RGBAColor
import ru.dbotthepony.mc.otm.core.math.rotateWithBlockFacing import ru.dbotthepony.mc.otm.core.math.rotateWithBlockFacing
@ -37,7 +37,7 @@ class HoloSignRenderer(private val context: BlockEntityRendererProvider.Context)
var y = -totalHeight / 2f var y = -totalHeight / 2f
for (line in lines) { for (line in lines) {
font.drawAligned(poseStack = poseStack, buffer = sorse, text = line, align = TextAlign.TOP_CENTER, x = 0f, y = y, color = RGBAColor.YELLOW.toInt()) font.drawAligned(poseStack = poseStack, buffer = sorse, text = line, align = RenderGravity.TOP_CENTER, x = 0f, y = y, color = RGBAColor.YELLOW.toInt())
y += font.lineHeight + 2f y += font.lineHeight + 2f
} }

View File

@ -5,7 +5,7 @@ import net.minecraft.client.renderer.MultiBufferSource
import net.minecraft.client.renderer.entity.EntityRenderer import net.minecraft.client.renderer.entity.EntityRenderer
import net.minecraft.client.renderer.entity.EntityRendererProvider import net.minecraft.client.renderer.entity.EntityRendererProvider
import net.minecraft.resources.ResourceLocation import net.minecraft.resources.ResourceLocation
import ru.dbotthepony.mc.otm.client.render.TextAlign import ru.dbotthepony.mc.otm.client.render.RenderGravity
import ru.dbotthepony.mc.otm.client.render.drawAligned import ru.dbotthepony.mc.otm.client.render.drawAligned
import ru.dbotthepony.mc.otm.client.render.rotateAroundPoint import ru.dbotthepony.mc.otm.client.render.rotateAroundPoint
import ru.dbotthepony.mc.otm.client.render.translation import ru.dbotthepony.mc.otm.client.render.translation
@ -30,7 +30,7 @@ class PlasmaProjectileRenderer(context: EntityRendererProvider.Context) : Entity
pose.pushPose() pose.pushPose()
pose.scale(0.03f, 0.03f, 0.03f) pose.scale(0.03f, 0.03f, 0.03f)
pose.rotateAroundPoint(pose.translation(), Angle.deg(roll = entity.xRot.toDouble(), yaw = entity.yRot.toDouble(), pitch = 180.0)) pose.rotateAroundPoint(pose.translation(), Angle.deg(roll = entity.xRot.toDouble(), yaw = entity.yRot.toDouble(), pitch = 180.0))
font.drawAligned(pose, "PLASMA", TextAlign.CENTER_CENTER, 0f, 0f, 0xFFFFFF) font.drawAligned(pose, "PLASMA", RenderGravity.CENTER_CENTER, 0f, 0f, 0xFFFFFF)
pose.popPose() pose.popPose()
} }
} }

View File

@ -1,23 +1,33 @@
package ru.dbotthepony.mc.otm.client.screen package ru.dbotthepony.mc.otm.client.screen
import com.mojang.blaze3d.vertex.PoseStack
import net.minecraft.client.gui.GuiGraphics import net.minecraft.client.gui.GuiGraphics
import net.minecraft.client.gui.screens.inventory.InventoryScreen import net.minecraft.client.gui.screens.inventory.InventoryScreen
import net.minecraft.world.item.ItemStack
import net.minecraft.world.item.Items
import ru.dbotthepony.mc.otm.client.mousePos import ru.dbotthepony.mc.otm.client.mousePos
import ru.dbotthepony.mc.otm.client.moveMousePosScaled import ru.dbotthepony.mc.otm.client.moveMousePosScaled
import ru.dbotthepony.mc.otm.client.render.ItemStackIcon
import ru.dbotthepony.mc.otm.client.render.Widgets18 import ru.dbotthepony.mc.otm.client.render.Widgets18
import ru.dbotthepony.mc.otm.core.TranslatableComponent import ru.dbotthepony.mc.otm.core.TranslatableComponent
import ru.dbotthepony.mc.otm.client.render.sprite import ru.dbotthepony.mc.otm.client.render.sprite
import ru.dbotthepony.mc.otm.client.screen.panels.* import ru.dbotthepony.mc.otm.client.screen.panels.*
import ru.dbotthepony.mc.otm.client.screen.panels.button.LargeRectangleButtonPanel import ru.dbotthepony.mc.otm.client.screen.panels.button.LargeRectangleButtonPanel
import ru.dbotthepony.mc.otm.client.screen.panels.slot.AbstractSlotPanel import ru.dbotthepony.mc.otm.client.screen.panels.slot.AbstractSlotPanel
import ru.dbotthepony.mc.otm.client.screen.panels.slot.BatterySlotPanel
import ru.dbotthepony.mc.otm.client.screen.panels.slot.UserFilteredSlotPanel import ru.dbotthepony.mc.otm.client.screen.panels.slot.UserFilteredSlotPanel
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.panels.util.BackgroundPanel
import ru.dbotthepony.mc.otm.client.screen.panels.util.DiscreteScrollBarPanel import ru.dbotthepony.mc.otm.client.screen.panels.util.DiscreteScrollBarPanel
import ru.dbotthepony.mc.otm.client.screen.widget.HorizontalPowerGaugePanel
import ru.dbotthepony.mc.otm.client.screen.widget.PowerGaugePanel
import ru.dbotthepony.mc.otm.client.screen.widget.ProgressGaugePanel
import ru.dbotthepony.mc.otm.client.screen.widget.TallHorizontalProfiledPowerGaugePanel
import ru.dbotthepony.mc.otm.client.screen.widget.WideProfiledPowerGaugePanel
import ru.dbotthepony.mc.otm.client.setMousePos import ru.dbotthepony.mc.otm.client.setMousePos
import ru.dbotthepony.mc.otm.client.shouldOpenVanillaInventory import ru.dbotthepony.mc.otm.client.shouldOpenVanillaInventory
import ru.dbotthepony.mc.otm.core.math.integerDivisionDown import ru.dbotthepony.mc.otm.core.math.integerDivisionDown
import ru.dbotthepony.mc.otm.menu.ExoPackInventoryMenu import ru.dbotthepony.mc.otm.menu.ExoPackInventoryMenu
import ru.dbotthepony.mc.otm.menu.widget.ProgressGaugeWidget
import ru.dbotthepony.mc.otm.network.ExoPackMenuOpen import ru.dbotthepony.mc.otm.network.ExoPackMenuOpen
import ru.dbotthepony.mc.otm.network.MatteryPlayerNetworkChannel import ru.dbotthepony.mc.otm.network.MatteryPlayerNetworkChannel
import yalter.mousetweaks.api.MouseTweaksDisableWheelTweak import yalter.mousetweaks.api.MouseTweaksDisableWheelTweak
@ -133,18 +143,74 @@ class ExoPackInventoryScreen(menu: ExoPackInventoryMenu) : MatteryScreen<ExoPack
val resultPanel = SlotPanel(this, craftingCanvas, menu.craftingResultSlot, x = craftingCanvas.width - 18f, y = topLine.height / 2f - 9f) val resultPanel = SlotPanel(this, craftingCanvas, menu.craftingResultSlot, x = craftingCanvas.width - 18f, y = topLine.height / 2f - 9f)
object : EditablePanel<ExoPackInventoryScreen>( SpritePanel(this, craftingCanvas, CRAFT_ARROW, x = craftingSlotsCanvas.width,
this@ExoPackInventoryScreen, width = craftingCanvas.width - resultPanel.width - craftingSlotsCanvas.width,
craftingCanvas, height = topLine.height, centerSprite = true)
x = craftingSlotsCanvas.width,
width = craftingCanvas.width - resultPanel.width - craftingSlotsCanvas.width, if (menu.capability.isExoPackSmeltingInstalled) {
height = topLine.height val craftingTab = frame.Tab()
) { val furnaceTab = frame.Tab()
override fun innerRender(graphics: GuiGraphics, mouseX: Float, mouseY: Float, partialTick: Float) {
CRAFT_ARROW.render(graphics, x = width / 2f - CRAFT_ARROW.width / 2f, y = height / 2f - CRAFT_ARROW.height / 2f) craftingTab.activeIcon = ItemStackIcon(ItemStack(Items.CRAFTING_TABLE))
craftingTab.inactiveIcon = craftingTab.activeIcon
furnaceTab.activeIcon = ItemStackIcon(ItemStack(Items.FURNACE))
furnaceTab.inactiveIcon = furnaceTab.activeIcon
craftingTab.onOpen = Runnable { craftingCanvas.visible = true }
craftingTab.onClose = Runnable { craftingCanvas.visible = false }
val furnaceCanvas = EditablePanel(this, topLine, width = 90f)
furnaceCanvas.dock = Dock.LEFT
furnaceCanvas.visible = false
furnaceTab.onOpen = Runnable { furnaceCanvas.visible = true; menu.furnaceMenuOpenState.accept(true) }
furnaceTab.onClose = Runnable { furnaceCanvas.visible = false; menu.furnaceMenuOpenState.accept(false) }
for (i in menu.capability.smelters.indices) {
val row = EditablePanel(this, furnaceCanvas, height = AbstractSlotPanel.SIZE)
row.dock = Dock.TOP
row.dockTop = 4f
SlotPanel(this, row, menu.furnaceInputs[i]).also {
it.dock = Dock.LEFT
it.dockLeft = 12f
it.dockResize = DockResizeMode.NONE
}
ProgressGaugePanel(this, row, menu.furnaceProgress[i]).also {
it.dock = Dock.LEFT
it.dockLeft = 9f
it.dockResize = DockResizeMode.NONE
}
SlotPanel(this, row, menu.furnaceOutputs[i]).also {
it.dock = Dock.LEFT
it.dockLeft = 10f
it.dockResize = DockResizeMode.NONE
}
} }
} }
val chargeWidth = HorizontalPowerGaugePanel.GAUGE_BACKGROUND_TALL.width + AbstractSlotPanel.SIZE + 4f + ProgressGaugePanel.GAUGE_BACKGROUND.width
val chargeStrip = BackgroundPanel.paddedCenter(this, frame, frame.width / 2f - chargeWidth / 2f, frame.height + 2f, chargeWidth, AbstractSlotPanel.SIZE)
chargeStrip.customDock { chargeStrip.setPos(frame.width / 2f - chargeWidth / 2f, frame.height + 2f) }
BatterySlotPanel(this, chargeStrip, menu.exoPackPowerSlot).also {
it.dock = Dock.LEFT
}
SpritePanel(this, chargeStrip, ProgressGaugePanel.GAUGE_BACKGROUND).also {
it.dock = Dock.LEFT
it.dockLeft = 2f
it.dockResize = DockResizeMode.NONE
}
TallHorizontalProfiledPowerGaugePanel(this, chargeStrip, menu.exoPackPower).also {
it.dock = Dock.LEFT
it.dockLeft = 2f
}
scrollPanel.dock = Dock.RIGHT scrollPanel.dock = Dock.RIGHT
scrollPanel.setDockMargin(right = 3f) scrollPanel.setDockMargin(right = 3f)

View File

@ -3,7 +3,6 @@ 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.platform.InputConstants
import com.mojang.blaze3d.systems.RenderSystem import com.mojang.blaze3d.systems.RenderSystem
import com.mojang.blaze3d.vertex.PoseStack
import it.unimi.dsi.fastutil.ints.IntAVLTreeSet 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
@ -550,6 +549,19 @@ open class EditablePanel<out S : Screen> @JvmOverloads constructor(
return x < 0 || y < 0 || x + width > parent.width || y + height > parent.height return x < 0 || y < 0 || x + width > parent.width || y + height > parent.height
} }
private var once = false
set(value) {
if (value && field != value) {
if (updateVisibility) {
updateVisible()
}
field = value
}
}
private var updateVisibility = false
fun calculateAbsoluteRectangle(): Rect2f { fun calculateAbsoluteRectangle(): Rect2f {
if (scissor) { if (scissor) {
return Rect2f(absoluteX, absoluteY, width, height) return Rect2f(absoluteX, absoluteY, width, height)
@ -703,7 +715,10 @@ open class EditablePanel<out S : Screen> @JvmOverloads constructor(
} }
if (child.isVisible() != isVisible()) { if (child.isVisible() != isVisible()) {
updateVisible() if (once)
updateVisible()
else
updateVisibility = true
} }
} }
@ -768,6 +783,8 @@ open class EditablePanel<out S : Screen> @JvmOverloads constructor(
} }
fun render(graphics: GuiGraphics, mouseX: Float, mouseY: Float, partialTick: Float) { fun render(graphics: GuiGraphics, mouseX: Float, mouseY: Float, partialTick: Float) {
once = true
if (!isVisible()) { if (!isVisible()) {
return return
} }
@ -1145,6 +1162,21 @@ open class EditablePanel<out S : Screen> @JvmOverloads constructor(
} }
updateBounds() updateBounds()
for (child in visibleChildrenInternal) {
child.parentLayoutPerformed()
}
}
private var repositioningCallback: Runnable? = null
fun customDock(callback: Runnable?) {
if (callback != null) dock = Dock.NONE
repositioningCallback = callback
}
open fun parentLayoutPerformed() {
repositioningCallback?.run()
} }
fun updateBounds() { fun updateBounds() {
@ -1656,6 +1688,7 @@ open class EditablePanel<out S : Screen> @JvmOverloads constructor(
protected open fun tickInner() {} protected open fun tickInner() {}
fun tick() { fun tick() {
once = true
tickCount++ tickCount++
tickInner() tickInner()
@ -1663,8 +1696,6 @@ open class EditablePanel<out S : Screen> @JvmOverloads constructor(
for (child in Array(visibleChildrenInternal.size) { visibleChildrenInternal[it] }) { for (child in Array(visibleChildrenInternal.size) { visibleChildrenInternal[it] }) {
child.tick() child.tick()
} }
} }
var isRemoved = false var isRemoved = false

View File

@ -1,7 +1,6 @@
package ru.dbotthepony.mc.otm.client.screen.panels package ru.dbotthepony.mc.otm.client.screen.panels
import com.mojang.blaze3d.systems.RenderSystem import com.mojang.blaze3d.systems.RenderSystem
import com.mojang.blaze3d.vertex.PoseStack
import it.unimi.dsi.fastutil.objects.Object2ObjectArrayMap import it.unimi.dsi.fastutil.objects.Object2ObjectArrayMap
import it.unimi.dsi.fastutil.objects.Object2ObjectFunction import it.unimi.dsi.fastutil.objects.Object2ObjectFunction
import net.minecraft.client.gui.GuiGraphics import net.minecraft.client.gui.GuiGraphics
@ -11,7 +10,7 @@ import net.minecraft.world.effect.MobEffect
import net.minecraft.world.effect.MobEffectInstance import net.minecraft.world.effect.MobEffectInstance
import net.minecraft.world.entity.LivingEntity import net.minecraft.world.entity.LivingEntity
import ru.dbotthepony.mc.otm.client.minecraft import ru.dbotthepony.mc.otm.client.minecraft
import ru.dbotthepony.mc.otm.client.render.TextAlign import ru.dbotthepony.mc.otm.client.render.RenderGravity
import ru.dbotthepony.mc.otm.client.render.determineTooltipPosition import ru.dbotthepony.mc.otm.client.render.determineTooltipPosition
import ru.dbotthepony.mc.otm.client.render.drawAligned import ru.dbotthepony.mc.otm.client.render.drawAligned
import ru.dbotthepony.mc.otm.client.render.drawScaledAligned import ru.dbotthepony.mc.otm.client.render.drawScaledAligned
@ -118,7 +117,7 @@ open class EffectListPanel<out S : Screen> @JvmOverloads constructor(
minecraft.mobEffectTextures.get(effect.effect).render(graphics, x = 3f, y = 3f, width = width - 6f, height = height - 6f) minecraft.mobEffectTextures.get(effect.effect).render(graphics, x = 3f, y = 3f, width = width - 6f, height = height - 6f)
RenderSystem.setShaderColor(1f, 1f, 1f, 1f) RenderSystem.setShaderColor(1f, 1f, 1f, 1f)
graphics.drawScaledAligned(font, formatTickDuration(effect.duration), 0.75f, TextAlign.CENTER_CENTER, width / 2f - 1f, height / 2f, RGBAColor.WHITE) graphics.drawScaledAligned(font, formatTickDuration(effect.duration), 0.75f, RenderGravity.CENTER_CENTER, width / 2f - 1f, height / 2f, RGBAColor.WHITE)
} }
override fun innerRenderTooltips(graphics: GuiGraphics, mouseX: Float, mouseY: Float, partialTick: Float): Boolean { override fun innerRenderTooltips(graphics: GuiGraphics, mouseX: Float, mouseY: Float, partialTick: Float): Boolean {
@ -146,8 +145,8 @@ open class EffectListPanel<out S : Screen> @JvmOverloads constructor(
name.append(" ${effect.amplifier + 1}") name.append(" ${effect.amplifier + 1}")
} }
graphics.drawAligned(font, name, TextAlign.TOP_LEFT, x + renderWidth + 12f, y + 7f, RGBAColor.WHITE) graphics.drawAligned(font, name, RenderGravity.TOP_LEFT, x + renderWidth + 12f, y + 7f, RGBAColor.WHITE)
graphics.drawAligned(font, formatTickDuration(effect.duration, true), TextAlign.TOP_LEFT, x + renderWidth + 12f, y + 7f + font.lineHeight + 2f, 8355711) graphics.drawAligned(font, formatTickDuration(effect.duration, true), RenderGravity.TOP_LEFT, x + renderWidth + 12f, y + 7f + font.lineHeight + 2f, 8355711)
} }
return isHovered return isHovered

View File

@ -2,7 +2,6 @@ package ru.dbotthepony.mc.otm.client.screen.panels
import com.mojang.blaze3d.platform.InputConstants 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 net.minecraft.client.gui.GuiGraphics import net.minecraft.client.gui.GuiGraphics
import net.minecraft.client.gui.narration.NarratableEntry import net.minecraft.client.gui.narration.NarratableEntry
import net.minecraft.client.gui.narration.NarratableEntry.NarrationPriority import net.minecraft.client.gui.narration.NarratableEntry.NarrationPriority
@ -13,7 +12,6 @@ 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.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,
@ -29,8 +27,8 @@ open class FramePanel<out S : Screen>(
open inner class Tab( open inner class Tab(
var onOpen: Runnable? = null, var onOpen: Runnable? = null,
var onClose: Runnable? = null, var onClose: Runnable? = null,
var activeIcon: AbstractMatterySprite? = null, var activeIcon: IGUIRenderable? = null,
var inactiveIcon: AbstractMatterySprite? = null, var inactiveIcon: IGUIRenderable? = null,
) : EditablePanel<S>(this@FramePanel.screen, this@FramePanel, 0f, 0f, 28f, 28f) { ) : EditablePanel<S>(this@FramePanel.screen, this@FramePanel, 0f, 0f, 28f, 28f) {
var isActive = tabs.isEmpty() var isActive = tabs.isEmpty()
var initial = false var initial = false
@ -54,7 +52,6 @@ open class FramePanel<out S : Screen>(
} }
override fun innerRender(graphics: GuiGraphics, mouseX: Float, mouseY: Float, partialTick: Float) { override fun innerRender(graphics: GuiGraphics, mouseX: Float, mouseY: Float, partialTick: Float) {
val stack = graphics.pose()
val width: Float val width: Float
val height: Float val height: Float
@ -88,10 +85,10 @@ open class FramePanel<out S : Screen>(
) )
val skinActive = activeIcon ?: return val skinActive = activeIcon ?: return
skinActive.render(graphics, TAB_WIDTH_ACTIVE / 2f - skinActive.width / 2f, TAB_HEIGHT_ACTIVE / 2f - skinActive.height / 2f) skinActive.render(graphics, TAB_WIDTH_ACTIVE / 2f, TAB_HEIGHT_ACTIVE / 2f, gravity = RenderGravity.CENTER_CENTER)
} else { } else {
val skinInactive = inactiveIcon ?: return val skinInactive = inactiveIcon ?: return
skinInactive.render(graphics, width / 2f - skinInactive.width / 2f, TAB_HEIGHT_ACTIVE / 2f - skinInactive.height / 2f) skinInactive.render(graphics, width / 2f, TAB_HEIGHT_ACTIVE / 2f, gravity = RenderGravity.CENTER_CENTER)
} }
} }
@ -259,7 +256,7 @@ open class FramePanel<out S : Screen>(
// title // title
val title = title ?: return val title = title ?: return
RenderSystem.depthFunc(GL30.GL_ALWAYS) RenderSystem.depthFunc(GL30.GL_ALWAYS)
graphics.drawAligned(font, title, TextAlign.TOP_LEFT, 8f, 5f, 4210752) graphics.drawAligned(font, title, RenderGravity.TOP_LEFT, 8f, 5f, 4210752)
RenderSystem.depthFunc(GL30.GL_ALWAYS) RenderSystem.depthFunc(GL30.GL_ALWAYS)
} }

View File

@ -3,7 +3,7 @@ package ru.dbotthepony.mc.otm.client.screen.panels
import net.minecraft.client.gui.GuiGraphics import net.minecraft.client.gui.GuiGraphics
import net.minecraft.client.gui.screens.Screen import net.minecraft.client.gui.screens.Screen
import net.minecraft.network.chat.Component import net.minecraft.network.chat.Component
import ru.dbotthepony.mc.otm.client.render.TextAlign import ru.dbotthepony.mc.otm.client.render.RenderGravity
import ru.dbotthepony.mc.otm.client.render.drawAligned import ru.dbotthepony.mc.otm.client.render.drawAligned
import ru.dbotthepony.mc.otm.core.TextComponent import ru.dbotthepony.mc.otm.core.TextComponent
import ru.dbotthepony.mc.otm.core.math.RGBAColor import ru.dbotthepony.mc.otm.core.math.RGBAColor
@ -29,35 +29,35 @@ open class Label<out S : Screen> @JvmOverloads constructor(
} }
var color = RGBAColor.SLATE_GRAY var color = RGBAColor.SLATE_GRAY
var align = TextAlign.TOP_LEFT var align = RenderGravity.TOP_LEFT
override fun innerRender(graphics: GuiGraphics, mouseX: Float, mouseY: Float, partialTick: Float) { override fun innerRender(graphics: GuiGraphics, mouseX: Float, mouseY: Float, partialTick: Float) {
clearDepth(graphics) clearDepth(graphics)
if (shadow) { if (shadow) {
when (align) { when (align) {
TextAlign.TOP_LEFT -> graphics.drawAligned(font, text, align, shadowX, shadowY, shadowColor.toInt()) RenderGravity.TOP_LEFT -> graphics.drawAligned(font, text, align, shadowX, shadowY, shadowColor.toInt())
TextAlign.TOP_CENTER -> graphics.drawAligned(font, text, align, shadowX + width / 2f, shadowY, shadowColor.toInt()) RenderGravity.TOP_CENTER -> graphics.drawAligned(font, text, align, shadowX + width / 2f, shadowY, shadowColor.toInt())
TextAlign.TOP_RIGHT -> graphics.drawAligned(font, text, align, shadowX + width, shadowY, shadowColor.toInt()) RenderGravity.TOP_RIGHT -> graphics.drawAligned(font, text, align, shadowX + width, shadowY, shadowColor.toInt())
TextAlign.CENTER_LEFT -> graphics.drawAligned(font, text, align, shadowX, height / 2f + shadowY, shadowColor.toInt()) RenderGravity.CENTER_LEFT -> graphics.drawAligned(font, text, align, shadowX, height / 2f + shadowY, shadowColor.toInt())
TextAlign.CENTER_CENTER -> graphics.drawAligned(font, text, align, shadowX + width / 2f, height / 2f + shadowY, shadowColor.toInt()) RenderGravity.CENTER_CENTER -> graphics.drawAligned(font, text, align, shadowX + width / 2f, height / 2f + shadowY, shadowColor.toInt())
TextAlign.CENTER_RIGHT -> graphics.drawAligned(font, text, align, shadowX + width, height / 2f + shadowY, shadowColor.toInt()) RenderGravity.CENTER_RIGHT -> graphics.drawAligned(font, text, align, shadowX + width, height / 2f + shadowY, shadowColor.toInt())
TextAlign.BOTTOM_LEFT -> graphics.drawAligned(font, text, align, shadowX, height + shadowY, shadowColor.toInt()) RenderGravity.BOTTOM_LEFT -> graphics.drawAligned(font, text, align, shadowX, height + shadowY, shadowColor.toInt())
TextAlign.BOTTOM_CENTER -> graphics.drawAligned(font, text, align, shadowX + width / 2f, height + shadowY, shadowColor.toInt()) RenderGravity.BOTTOM_CENTER -> graphics.drawAligned(font, text, align, shadowX + width / 2f, height + shadowY, shadowColor.toInt())
TextAlign.BOTTOM_RIGHT -> graphics.drawAligned(font, text, align, shadowX + width, height + shadowY, shadowColor.toInt()) RenderGravity.BOTTOM_RIGHT -> graphics.drawAligned(font, text, align, shadowX + width, height + shadowY, shadowColor.toInt())
} }
} }
when (align) { when (align) {
TextAlign.TOP_LEFT -> font.drawAligned(graphics.pose(), text, align, 0f, 0f, color.toInt()) RenderGravity.TOP_LEFT -> font.drawAligned(graphics.pose(), text, align, 0f, 0f, color.toInt())
TextAlign.TOP_CENTER -> font.drawAligned(graphics.pose(), text, align, width / 2f, 0f, color.toInt()) RenderGravity.TOP_CENTER -> font.drawAligned(graphics.pose(), text, align, width / 2f, 0f, color.toInt())
TextAlign.TOP_RIGHT -> font.drawAligned(graphics.pose(), text, align, width - (if (shadow) shadowX else 0f), 0f, color.toInt()) RenderGravity.TOP_RIGHT -> font.drawAligned(graphics.pose(), text, align, width - (if (shadow) shadowX else 0f), 0f, color.toInt())
TextAlign.CENTER_LEFT -> font.drawAligned(graphics.pose(), text, align, 0f, height / 2f, color.toInt()) RenderGravity.CENTER_LEFT -> font.drawAligned(graphics.pose(), text, align, 0f, height / 2f, color.toInt())
TextAlign.CENTER_CENTER -> font.drawAligned(graphics.pose(), text, align, width / 2f, height / 2f, color.toInt()) RenderGravity.CENTER_CENTER -> font.drawAligned(graphics.pose(), text, align, width / 2f, height / 2f, color.toInt())
TextAlign.CENTER_RIGHT -> font.drawAligned(graphics.pose(), text, align, width - (if (shadow) shadowX else 0f), height / 2f, color.toInt()) RenderGravity.CENTER_RIGHT -> font.drawAligned(graphics.pose(), text, align, width - (if (shadow) shadowX else 0f), height / 2f, color.toInt())
TextAlign.BOTTOM_LEFT -> font.drawAligned(graphics.pose(), text, align, 0f, height, color.toInt()) RenderGravity.BOTTOM_LEFT -> font.drawAligned(graphics.pose(), text, align, 0f, height, color.toInt())
TextAlign.BOTTOM_CENTER -> font.drawAligned(graphics.pose(), text, align, width / 2f, height, color.toInt()) RenderGravity.BOTTOM_CENTER -> font.drawAligned(graphics.pose(), text, align, width / 2f, height, color.toInt())
TextAlign.BOTTOM_RIGHT -> font.drawAligned(graphics.pose(), text, align, width - (if (shadow) shadowX else 0f), height, color.toInt()) RenderGravity.BOTTOM_RIGHT -> font.drawAligned(graphics.pose(), text, align, width - (if (shadow) shadowX else 0f), height, color.toInt())
} }
} }

View File

@ -13,9 +13,14 @@ class SpritePanel<out S : Screen>(
y: Float = 0f, y: Float = 0f,
width: Float = sprite.width, width: Float = sprite.width,
height: Float = sprite.height, height: Float = sprite.height,
val winding: UVWindingOrder = sprite.winding var winding: UVWindingOrder = sprite.winding,
var centerSprite: Boolean = false
) : EditablePanel<S>(screen, parent, x, y, width, height) { ) : EditablePanel<S>(screen, parent, x, y, width, height) {
override fun innerRender(graphics: GuiGraphics, mouseX: Float, mouseY: Float, partialTick: Float) { override fun innerRender(graphics: GuiGraphics, mouseX: Float, mouseY: Float, partialTick: Float) {
sprite.render(graphics, 0f, 0f, width, height, winding) if (centerSprite) {
sprite.render(graphics, width / 2f - sprite.width / 2f, height / 2f - sprite.height / 2f, sprite.width, sprite.height, winding)
} else {
sprite.render(graphics, 0f, 0f, width, height, winding)
}
} }
} }

View File

@ -1,11 +1,9 @@
package ru.dbotthepony.mc.otm.client.screen.panels.button package ru.dbotthepony.mc.otm.client.screen.panels.button
import com.mojang.blaze3d.vertex.PoseStack
import net.minecraft.client.gui.GuiGraphics import net.minecraft.client.gui.GuiGraphics
import net.minecraft.client.gui.screens.Screen import net.minecraft.client.gui.screens.Screen
import net.minecraft.network.chat.Component import net.minecraft.network.chat.Component
import ru.dbotthepony.mc.otm.client.playGuiClickSound import ru.dbotthepony.mc.otm.client.render.RenderGravity
import ru.dbotthepony.mc.otm.client.render.TextAlign
import ru.dbotthepony.mc.otm.client.render.Widgets18 import ru.dbotthepony.mc.otm.client.render.Widgets18
import ru.dbotthepony.mc.otm.client.render.drawAligned import ru.dbotthepony.mc.otm.client.render.drawAligned
import ru.dbotthepony.mc.otm.client.screen.panels.EditablePanel import ru.dbotthepony.mc.otm.client.screen.panels.EditablePanel
@ -55,7 +53,7 @@ open class ButtonPanel<out S : Screen>(
override fun innerRender(graphics: GuiGraphics, mouseX: Float, mouseY: Float, partialTick: Float) { override fun innerRender(graphics: GuiGraphics, mouseX: Float, mouseY: Float, partialTick: Float) {
renderStretchableBackground(graphics, mouseX, mouseY, partialTick) renderStretchableBackground(graphics, mouseX, mouseY, partialTick)
graphics.drawAligned(font, label, TextAlign.CENTER_CENTER, width / 2f, height / 2f, textColor.toInt()) graphics.drawAligned(font, label, RenderGravity.CENTER_CENTER, width / 2f, height / 2f, textColor.toInt())
} }
override fun sizeToContents() { override fun sizeToContents() {

View File

@ -3,7 +3,6 @@ package ru.dbotthepony.mc.otm.client.screen.panels.input
import com.mojang.blaze3d.platform.InputConstants import com.mojang.blaze3d.platform.InputConstants
import com.mojang.blaze3d.systems.RenderSystem import com.mojang.blaze3d.systems.RenderSystem
import com.mojang.blaze3d.vertex.DefaultVertexFormat import com.mojang.blaze3d.vertex.DefaultVertexFormat
import com.mojang.blaze3d.vertex.PoseStack
import com.mojang.blaze3d.vertex.VertexFormat import com.mojang.blaze3d.vertex.VertexFormat
import it.unimi.dsi.fastutil.chars.Char2IntFunction import it.unimi.dsi.fastutil.chars.Char2IntFunction
import it.unimi.dsi.fastutil.chars.Char2IntOpenHashMap import it.unimi.dsi.fastutil.chars.Char2IntOpenHashMap
@ -20,7 +19,7 @@ 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.playGuiClickSound import ru.dbotthepony.mc.otm.client.playGuiClickSound
import ru.dbotthepony.mc.otm.client.render.DynamicBufferSource import ru.dbotthepony.mc.otm.client.render.DynamicBufferSource
import ru.dbotthepony.mc.otm.client.render.TextAlign import ru.dbotthepony.mc.otm.client.render.RenderGravity
import ru.dbotthepony.mc.otm.client.render.drawAligned import ru.dbotthepony.mc.otm.client.render.drawAligned
import ru.dbotthepony.mc.otm.client.render.drawRect import ru.dbotthepony.mc.otm.client.render.drawRect
import ru.dbotthepony.mc.otm.client.render.tesselator import ru.dbotthepony.mc.otm.client.render.tesselator
@ -1119,7 +1118,7 @@ open class TextInputPanel<out S : Screen>(
graphics.drawAligned( graphics.drawAligned(
font = font, font = font,
text = placeholder, text = placeholder,
align = TextAlign.TOP_LEFT, align = RenderGravity.TOP_LEFT,
x = dockPadding.left, x = dockPadding.left,
y = y, y = y,
color = placeholderColor color = placeholderColor
@ -1133,7 +1132,7 @@ open class TextInputPanel<out S : Screen>(
graphics.drawAligned( graphics.drawAligned(
font = font, font = font,
text = line, text = line,
align = TextAlign.TOP_LEFT, align = RenderGravity.TOP_LEFT,
x = dockPadding.left, x = dockPadding.left,
y = y, y = y,
color = textColor color = textColor
@ -1187,7 +1186,7 @@ open class TextInputPanel<out S : Screen>(
graphics.drawAligned( graphics.drawAligned(
font = font, font = font,
text = "_", text = "_",
align = TextAlign.TOP_LEFT, align = RenderGravity.TOP_LEFT,
x = dockPadding.left + (if (activeLine == null) 0f else font.width(activeLine).toFloat()), x = dockPadding.left + (if (activeLine == null) 0f else font.width(activeLine).toFloat()),
y = topPadding + (cursorLine - scrollLines) * (font.lineHeight + rowSpacing), y = topPadding + (cursorLine - scrollLines) * (font.lineHeight + rowSpacing),
color = cursorColor color = cursorColor
@ -1196,7 +1195,7 @@ open class TextInputPanel<out S : Screen>(
graphics.drawAligned( graphics.drawAligned(
font = font, font = font,
text = "|", text = "|",
align = TextAlign.TOP_LEFT, align = RenderGravity.TOP_LEFT,
x = dockPadding.left + font.width(activeLine.substring(0, cursorRow)).toFloat() - 1f, x = dockPadding.left + font.width(activeLine.substring(0, cursorRow)).toFloat() - 1f,
y = topPadding + (cursorLine - scrollLines) * (font.lineHeight + rowSpacing), y = topPadding + (cursorLine - scrollLines) * (font.lineHeight + rowSpacing),
color = cursorColor color = cursorColor
@ -1210,7 +1209,7 @@ open class TextInputPanel<out S : Screen>(
graphics.drawAligned( graphics.drawAligned(
font = font, font = font,
text = cursorLine.toString(), text = cursorLine.toString(),
align = TextAlign.TOP_RIGHT, align = RenderGravity.TOP_RIGHT,
x = width, x = width,
y = topPadding, y = topPadding,
color = cursorColor color = cursorColor
@ -1219,7 +1218,7 @@ open class TextInputPanel<out S : Screen>(
graphics.drawAligned( graphics.drawAligned(
font = font, font = font,
text = cursorRow.toString(), text = cursorRow.toString(),
align = TextAlign.TOP_RIGHT, align = RenderGravity.TOP_RIGHT,
x = width - dockPadding.right, x = width - dockPadding.right,
y = topPadding + font.lineHeight + rowSpacing, y = topPadding + font.lineHeight + rowSpacing,
color = cursorColor color = cursorColor
@ -1228,7 +1227,7 @@ open class TextInputPanel<out S : Screen>(
graphics.drawAligned( graphics.drawAligned(
font = font, font = font,
text = lines.size.toString(), text = lines.size.toString(),
align = TextAlign.TOP_RIGHT, align = RenderGravity.TOP_RIGHT,
x = width - dockPadding.right, x = width - dockPadding.right,
y = topPadding + font.lineHeight * 2f + rowSpacing * 2f, y = topPadding + font.lineHeight * 2f + rowSpacing * 2f,
color = cursorColor color = cursorColor

View File

@ -21,7 +21,7 @@ abstract class AbstractSlotPanel<out S : MatteryScreen<*>> @JvmOverloads constru
y: Float = 0f, y: Float = 0f,
width: Float = SIZE, width: Float = SIZE,
height: Float = SIZE, height: Float = SIZE,
open val noItemIcon: MatterySprite? = null open val noItemIcon: IGUIRenderable? = null
) : EditablePanel<S>(screen, parent, x, y, width, height), IItemStackPanel { ) : EditablePanel<S>(screen, parent, x, y, width, height), IItemStackPanel {
protected open fun renderSlotBackground(graphics: GuiGraphics, mouseX: Float, mouseY: Float, partialTick: Float) { protected open fun renderSlotBackground(graphics: GuiGraphics, mouseX: Float, mouseY: Float, partialTick: Float) {
SLOT_BACKGROUND.render(graphics, width = width, height = height) SLOT_BACKGROUND.render(graphics, width = width, height = height)
@ -51,7 +51,7 @@ abstract class AbstractSlotPanel<out S : MatteryScreen<*>> @JvmOverloads constru
renderRegular(graphics, itemStack) renderRegular(graphics, itemStack)
if (itemStack.isEmpty) { if (itemStack.isEmpty) {
noItemIcon?.render(graphics, width = width, height = height) noItemIcon?.render(graphics, 0f, 0f, width, height)
} }
} }

View File

@ -11,6 +11,7 @@ import net.minecraft.world.inventory.AbstractContainerMenu
import net.minecraft.world.inventory.Slot import net.minecraft.world.inventory.Slot
import net.minecraft.world.item.ItemStack import net.minecraft.world.item.ItemStack
import ru.dbotthepony.mc.otm.client.minecraft import ru.dbotthepony.mc.otm.client.minecraft
import ru.dbotthepony.mc.otm.client.render.IGUIRenderable
import ru.dbotthepony.mc.otm.client.render.MatterySprite import ru.dbotthepony.mc.otm.client.render.MatterySprite
import ru.dbotthepony.mc.otm.client.render.Widgets18 import ru.dbotthepony.mc.otm.client.render.Widgets18
import ru.dbotthepony.mc.otm.client.render.drawRect import ru.dbotthepony.mc.otm.client.render.drawRect
@ -29,7 +30,7 @@ open class SlotPanel<out S : MatteryScreen<*>, out T : Slot> @JvmOverloads const
y: Float = 0f, y: Float = 0f,
width: Float = SIZE, width: Float = SIZE,
height: Float = SIZE, height: Float = SIZE,
noItemIcon: MatterySprite? = null noItemIcon: IGUIRenderable? = null
) : AbstractSlotPanel<S>(screen, parent, x, y, width, height, noItemIcon), ISlotPanel<T> { ) : AbstractSlotPanel<S>(screen, parent, x, y, width, height, noItemIcon), ISlotPanel<T> {
override fun mouseClickedInner(x: Double, y: Double, button: Int): Boolean { override fun mouseClickedInner(x: Double, y: Double, button: Int): Boolean {
screen.returnSlot = slot screen.returnSlot = slot
@ -107,7 +108,7 @@ open class SlotPanel<out S : MatteryScreen<*>, out T : Slot> @JvmOverloads const
RenderSystem.setShaderTexture(0, texture.atlasLocation()) RenderSystem.setShaderTexture(0, texture.atlasLocation())
graphics.blit(1, 1, 0, 16, 16, texture) graphics.blit(1, 1, 0, 16, 16, texture)
} else { } else {
noItemIcon?.render(graphics, width = width, height = height) noItemIcon?.render(graphics, 0f, 0f, width = width, height = height)
} }
} }

View File

@ -1,8 +1,6 @@
package ru.dbotthepony.mc.otm.client.screen.tech package ru.dbotthepony.mc.otm.client.screen.tech
import com.mojang.blaze3d.platform.InputConstants import com.mojang.blaze3d.platform.InputConstants
import com.mojang.blaze3d.systems.RenderSystem
import com.mojang.blaze3d.vertex.PoseStack
import it.unimi.dsi.fastutil.ints.Int2FloatAVLTreeMap import it.unimi.dsi.fastutil.ints.Int2FloatAVLTreeMap
import it.unimi.dsi.fastutil.ints.Int2ObjectFunction import it.unimi.dsi.fastutil.ints.Int2ObjectFunction
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap
@ -12,7 +10,6 @@ import net.minecraft.client.gui.GuiGraphics
import net.minecraft.network.chat.Component import net.minecraft.network.chat.Component
import net.minecraft.world.entity.player.Inventory import net.minecraft.world.entity.player.Inventory
import net.minecraft.world.item.ItemStack import net.minecraft.world.item.ItemStack
import org.lwjgl.opengl.GL11
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.AndroidResearchManager import ru.dbotthepony.mc.otm.android.AndroidResearchManager
@ -22,7 +19,7 @@ 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.minecraft import ru.dbotthepony.mc.otm.client.minecraft
import ru.dbotthepony.mc.otm.client.playGuiClickSound import ru.dbotthepony.mc.otm.client.playGuiClickSound
import ru.dbotthepony.mc.otm.client.render.TextAlign import ru.dbotthepony.mc.otm.client.render.RenderGravity
import ru.dbotthepony.mc.otm.client.render.Widgets18 import ru.dbotthepony.mc.otm.client.render.Widgets18
import ru.dbotthepony.mc.otm.client.render.drawColor import ru.dbotthepony.mc.otm.client.render.drawColor
import ru.dbotthepony.mc.otm.client.render.drawLine import ru.dbotthepony.mc.otm.client.render.drawLine
@ -35,7 +32,6 @@ import ru.dbotthepony.mc.otm.client.screen.panels.slot.AbstractSlotPanel
import ru.dbotthepony.mc.otm.client.screen.panels.slot.BatterySlotPanel import ru.dbotthepony.mc.otm.client.screen.panels.slot.BatterySlotPanel
import ru.dbotthepony.mc.otm.client.screen.panels.slot.EquipmentBatterySlotPanel import ru.dbotthepony.mc.otm.client.screen.panels.slot.EquipmentBatterySlotPanel
import ru.dbotthepony.mc.otm.client.screen.panels.util.DraggableCanvasPanel import ru.dbotthepony.mc.otm.client.screen.panels.util.DraggableCanvasPanel
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.core.math.RGBAColor import ru.dbotthepony.mc.otm.core.math.RGBAColor
import ru.dbotthepony.mc.otm.core.ifPresentK import ru.dbotthepony.mc.otm.core.ifPresentK
@ -663,7 +659,7 @@ class AndroidStationScreen constructor(p_97741_: AndroidStationMenu, p_97742_: I
init { init {
dock = Dock.BOTTOM dock = Dock.BOTTOM
dockTop = 2f dockTop = 2f
align = TextAlign.TOP_RIGHT align = RenderGravity.TOP_RIGHT
} }
override fun innerRender(graphics: GuiGraphics, mouseX: Float, mouseY: Float, partialTick: Float) { override fun innerRender(graphics: GuiGraphics, mouseX: Float, mouseY: Float, partialTick: Float) {

View File

@ -1,6 +1,5 @@
package ru.dbotthepony.mc.otm.client.screen.tech package ru.dbotthepony.mc.otm.client.screen.tech
import com.mojang.blaze3d.vertex.PoseStack
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 net.minecraft.network.chat.Component
@ -9,7 +8,7 @@ import net.minecraft.world.entity.player.Inventory
import ru.dbotthepony.mc.otm.OverdriveThatMatters import ru.dbotthepony.mc.otm.OverdriveThatMatters
import ru.dbotthepony.mc.otm.client.isShiftDown import ru.dbotthepony.mc.otm.client.isShiftDown
import ru.dbotthepony.mc.otm.client.render.MatteryAtlas import ru.dbotthepony.mc.otm.client.render.MatteryAtlas
import ru.dbotthepony.mc.otm.client.render.TextAlign import ru.dbotthepony.mc.otm.client.render.RenderGravity
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.Dock
import ru.dbotthepony.mc.otm.client.screen.panels.DockProperty import ru.dbotthepony.mc.otm.client.screen.panels.DockProperty
@ -74,7 +73,7 @@ class EssenceStorageScreen(menu: EssenceStorageMenu, inventory: Inventory, title
init { init {
dock = Dock.TOP dock = Dock.TOP
dockMargin = DockProperty(bottom = 3f) dockMargin = DockProperty(bottom = 3f)
align = TextAlign.TOP_CENTER align = RenderGravity.TOP_CENTER
} }
override fun tickInner() { override fun tickInner() {

View File

@ -14,7 +14,7 @@ import net.minecraft.world.item.ItemStack
import net.minecraft.world.item.crafting.Ingredient import net.minecraft.world.item.crafting.Ingredient
import ru.dbotthepony.mc.otm.OverdriveThatMatters import ru.dbotthepony.mc.otm.OverdriveThatMatters
import ru.dbotthepony.mc.otm.client.minecraft import ru.dbotthepony.mc.otm.client.minecraft
import ru.dbotthepony.mc.otm.client.render.TextAlign import ru.dbotthepony.mc.otm.client.render.RenderGravity
import ru.dbotthepony.mc.otm.client.render.drawAligned import ru.dbotthepony.mc.otm.client.render.drawAligned
import ru.dbotthepony.mc.otm.client.screen.panels.slot.AbstractSlotPanel import ru.dbotthepony.mc.otm.client.screen.panels.slot.AbstractSlotPanel
import ru.dbotthepony.mc.otm.client.screen.widget.ProgressGaugePanel import ru.dbotthepony.mc.otm.client.screen.widget.ProgressGaugePanel
@ -70,12 +70,12 @@ object PlatePressRecipeCategory : IRecipeCategory<PlatePressRecipe>, IDrawable {
mouseX: Double, mouseX: Double,
mouseY: Double mouseY: Double
) { ) {
graphics.drawAligned(minecraft.font, TranslatableComponent("otm.gui.recipe.ticks", recipe.workTime), TextAlign.TOP_CENTER, 40f, 30f, RGBAColor.BLACK) graphics.drawAligned(minecraft.font, TranslatableComponent("otm.gui.recipe.ticks", recipe.workTime), RenderGravity.TOP_CENTER, 40f, 30f, RGBAColor.BLACK)
val average = recipe.experience.toString() val average = recipe.experience.toString()
if (average != "0.0") { if (average != "0.0") {
graphics.drawAligned(minecraft.font, TranslatableComponent("gui.jei.category.smelting.experience", average), TextAlign.TOP_CENTER, 40f, 1f, RGBAColor.BLACK) graphics.drawAligned(minecraft.font, TranslatableComponent("gui.jei.category.smelting.experience", average), RenderGravity.TOP_CENTER, 40f, 1f, RGBAColor.BLACK)
} }
} }

View File

@ -0,0 +1,15 @@
package ru.dbotthepony.mc.otm.config
import ru.dbotthepony.mc.otm.core.math.Decimal
import ru.dbotthepony.mc.otm.core.math.defineDecimal
object ExopackConfig : AbstractConfig("exopack") {
val ENERGY_CAPACITY by builder
.comment("Internal battery capacity of Exopack")
.defineDecimal("ENERGY_CAPACITY", Decimal(400_000), Decimal.ZERO)
val FURNACE_POWER_CONSUMPTION by builder
.comment("Power consumed per tick by built in furnace")
.comment("Vanilla furnace consumes 10 MtU/t (1 tick = 10 MtU, 1 Coal = 16 000 MtU,", "this ratio is utilized by almost all mods)")
.defineDecimal("FURNACE_POWER_CONSUMPTION", Decimal(20), Decimal.ZERO)
}

View File

@ -7,15 +7,23 @@ import net.minecraft.world.InteractionHand
import net.minecraft.world.InteractionResultHolder import net.minecraft.world.InteractionResultHolder
import net.minecraft.world.entity.LivingEntity import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.player.Player import net.minecraft.world.entity.player.Player
import net.minecraft.world.item.* import net.minecraft.world.item.Item
import net.minecraft.world.item.ItemStack
import net.minecraft.world.item.Rarity
import net.minecraft.world.item.TooltipFlag
import net.minecraft.world.item.UseAnim
import net.minecraft.world.level.Level import net.minecraft.world.level.Level
import ru.dbotthepony.mc.otm.OverdriveThatMatters import ru.dbotthepony.mc.otm.capability.MatteryPlayerCapability
import ru.dbotthepony.mc.otm.core.TranslatableComponent
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.core.TranslatableComponent
import ru.dbotthepony.mc.otm.runIfClient import ru.dbotthepony.mc.otm.runIfClient
class ExoPackCraftingUpgradeItem : Item(Properties().stacksTo(1).rarity(Rarity.RARE)) { class ExopackUpgradeItem(
val type: MatteryPlayerCapability.UpgradeType,
val upgradeName: String,
val upgradedName: String,
) : Item(Properties().stacksTo(1).rarity(Rarity.RARE)) {
override fun getUseDuration(p_41454_: ItemStack): Int { override fun getUseDuration(p_41454_: ItemStack): Int {
return 30 return 30
} }
@ -36,13 +44,13 @@ class ExoPackCraftingUpgradeItem : Item(Properties().stacksTo(1).rarity(Rarity.R
} }
val alreadyHas = runIfClient(true) { val alreadyHas = runIfClient(true) {
minecraft.player?.matteryPlayer?.isExoPackCraftingUpgraded == true type.prop.get(minecraft.player?.matteryPlayer ?: return@runIfClient false)
} }
if (alreadyHas) { if (alreadyHas) {
tooltip.add(TranslatableComponent("otm.gui.exopack_upgrades.already_activated").withStyle(ChatFormatting.DARK_RED)) tooltip.add(TranslatableComponent("otm.gui.exopack_upgrades.already_activated").withStyle(ChatFormatting.DARK_RED))
} else { } else {
tooltip.add(TranslatableComponent("otm.gui.exopack_upgrades.crafting_upgrade").withStyle(ChatFormatting.DARK_GREEN)) tooltip.add(TranslatableComponent("otm.gui.exopack_upgrades.$upgradeName").withStyle(ChatFormatting.DARK_GREEN))
} }
} }
@ -59,7 +67,7 @@ class ExoPackCraftingUpgradeItem : Item(Properties().stacksTo(1).rarity(Rarity.R
if (player !is Player) return super.finishUsingItem(itemStack, level, player) if (player !is Player) return super.finishUsingItem(itemStack, level, player)
val mattery = player.matteryPlayer ?: return super.finishUsingItem(itemStack, level, player) val mattery = player.matteryPlayer ?: return super.finishUsingItem(itemStack, level, player)
if (!mattery.hasExoPack || mattery.isExoPackCraftingUpgraded) { if (!mattery.hasExoPack || type.prop.get(mattery)) {
return super.finishUsingItem(itemStack, level, player) return super.finishUsingItem(itemStack, level, player)
} }
@ -67,9 +75,8 @@ class ExoPackCraftingUpgradeItem : Item(Properties().stacksTo(1).rarity(Rarity.R
itemStack.shrink(1) itemStack.shrink(1)
if (player is ServerPlayer) { if (player is ServerPlayer) {
mattery.isExoPackCraftingUpgraded = true type.prop.set(mattery, true)
player.displayClientMessage(TranslatableComponent("otm.exopack_upgrades.$upgradedName").withStyle(ChatFormatting.DARK_GREEN), false)
player.displayClientMessage(TranslatableComponent("otm.exopack_upgrades.crafting_upgraded").withStyle(ChatFormatting.DARK_GREEN), false)
} }
return itemStack return itemStack

View File

@ -3,7 +3,6 @@ package ru.dbotthepony.mc.otm.item.weapon
import com.mojang.blaze3d.systems.RenderSystem import com.mojang.blaze3d.systems.RenderSystem
import net.minecraft.client.Minecraft import net.minecraft.client.Minecraft
import net.minecraft.client.model.HumanoidModel import net.minecraft.client.model.HumanoidModel
import net.minecraft.client.renderer.block.model.ItemTransforms
import net.minecraft.nbt.CompoundTag import net.minecraft.nbt.CompoundTag
import net.minecraft.network.FriendlyByteBuf import net.minecraft.network.FriendlyByteBuf
import net.minecraft.server.level.ServerPlayer import net.minecraft.server.level.ServerPlayer
@ -24,7 +23,7 @@ import net.minecraftforge.network.NetworkEvent
import ru.dbotthepony.mc.otm.* import ru.dbotthepony.mc.otm.*
import ru.dbotthepony.mc.otm.capability.matteryEnergy import ru.dbotthepony.mc.otm.capability.matteryEnergy
import ru.dbotthepony.mc.otm.client.font import ru.dbotthepony.mc.otm.client.font
import ru.dbotthepony.mc.otm.client.render.TextAlign import ru.dbotthepony.mc.otm.client.render.RenderGravity
import ru.dbotthepony.mc.otm.client.render.drawAligned import ru.dbotthepony.mc.otm.client.render.drawAligned
import ru.dbotthepony.mc.otm.client.render.drawRect import ru.dbotthepony.mc.otm.client.render.drawRect
import ru.dbotthepony.mc.otm.client.render.setDrawColor import ru.dbotthepony.mc.otm.client.render.setDrawColor
@ -468,7 +467,7 @@ abstract class AbstractWeaponItem<D : WeaponDataTable>(val tables: KClass<D>, pr
pose.translate(0.0, 0.0, -1.0) pose.translate(0.0, 0.0, -1.0)
pose.scale(0.7f, 0.7f, 0.7f) pose.scale(0.7f, 0.7f, 0.7f)
val text = it.batteryLevel.formatPower() val text = it.batteryLevel.formatPower()
font.drawAligned(pose, text, TextAlign.TOP_LEFT, 2f, 2f, RGBAColor.WHITE.toInt()) font.drawAligned(pose, text, RenderGravity.TOP_LEFT, 2f, 2f, RGBAColor.WHITE.toInt())
pose.popPose() pose.popPose()
} }

View File

@ -4,14 +4,19 @@ import com.google.common.collect.ImmutableList
import com.mojang.datafixers.util.Pair import com.mojang.datafixers.util.Pair
import net.minecraft.core.NonNullList import net.minecraft.core.NonNullList
import net.minecraft.resources.ResourceLocation import net.minecraft.resources.ResourceLocation
import net.minecraft.server.level.ServerLevel
import net.minecraft.server.level.ServerPlayer import net.minecraft.server.level.ServerPlayer
import net.minecraft.world.Container import net.minecraft.world.Container
import net.minecraft.world.entity.ExperienceOrb
import net.minecraft.world.entity.player.Player import net.minecraft.world.entity.player.Player
import net.minecraft.world.inventory.* import net.minecraft.world.inventory.*
import net.minecraft.world.item.ItemStack import net.minecraft.world.item.ItemStack
import ru.dbotthepony.mc.otm.capability.MatteryPlayerCapability import ru.dbotthepony.mc.otm.capability.MatteryPlayerCapability
import ru.dbotthepony.mc.otm.compat.curios.curiosSlots import ru.dbotthepony.mc.otm.compat.curios.curiosSlots
import ru.dbotthepony.mc.otm.container.iterator import ru.dbotthepony.mc.otm.container.iterator
import ru.dbotthepony.mc.otm.menu.input.InstantBooleanInput
import ru.dbotthepony.mc.otm.menu.widget.ProfiledLevelGaugeWidget
import ru.dbotthepony.mc.otm.menu.widget.ProgressGaugeWidget
import ru.dbotthepony.mc.otm.network.ExoSuitCarriedPacket import ru.dbotthepony.mc.otm.network.ExoSuitCarriedPacket
import ru.dbotthepony.mc.otm.network.ExoSuitMenuInitPacket import ru.dbotthepony.mc.otm.network.ExoSuitMenuInitPacket
import ru.dbotthepony.mc.otm.network.ExoSuitSlotPacket import ru.dbotthepony.mc.otm.network.ExoSuitSlotPacket
@ -102,6 +107,42 @@ class ExoPackInventoryMenu(val capability: MatteryPlayerCapability) : MatteryMen
} }
} }
private fun popFurnaceExp() {
if (capability.isExoPackSmeltingInstalled && capability.exoPackSmelterExperience >= 1f && !ply.level().isClientSide) {
val whole = capability.exoPackSmelterExperience.toInt()
capability.exoPackSmelterExperience -= whole
ExperienceOrb.award(ply.level() as ServerLevel, ply.position(), whole)
}
}
val furnaceInputs: List<MatterySlot> = capability.smelters.map {
object : MatterySlot(it.input, 0) {
override fun mayPlace(itemStack: ItemStack): Boolean {
return super.mayPlace(itemStack) && capability.isExoPackSmeltingInstalled
}
}
}
val furnaceOutputs: List<MachineOutputSlot> = capability.smelters.map {
object : MachineOutputSlot(it.output, 0, onTake = ::popFurnaceExp) {
override fun mayPickup(player: Player): Boolean {
return super.mayPickup(player) && capability.isExoPackSmeltingInstalled
}
}
}
val furnaceProgress = capability.smelters.map { ProgressGaugeWidget(mSynchronizer, it) }
val exoPackPowerSlot = BatterySlot(capability.exoPackEnergy.parent, 0)
val exoPackPower = ProfiledLevelGaugeWidget(mSynchronizer, capability.exoPackEnergy)
val furnaceMenuOpenState = InstantBooleanInput(this)
init {
addStorageSlot(furnaceInputs, condition = furnaceMenuOpenState)
addStorageSlot(furnaceOutputs, condition = furnaceMenuOpenState)
addSlot(exoPackPowerSlot)
}
private var isRemoved = false private var isRemoved = false
override fun slotsChanged(container: Container) { override fun slotsChanged(container: Container) {

View File

@ -48,6 +48,7 @@ import ru.dbotthepony.mc.otm.core.util.IStreamCodec
import ru.dbotthepony.mc.otm.core.util.ItemValueCodec import ru.dbotthepony.mc.otm.core.util.ItemValueCodec
import ru.dbotthepony.mc.otm.core.util.NullValueCodec import ru.dbotthepony.mc.otm.core.util.NullValueCodec
import ru.dbotthepony.mc.otm.core.util.VarIntValueCodec import ru.dbotthepony.mc.otm.core.util.VarIntValueCodec
import ru.dbotthepony.mc.otm.menu.input.InstantBooleanInput
import ru.dbotthepony.mc.otm.network.MatteryPacket import ru.dbotthepony.mc.otm.network.MatteryPacket
import ru.dbotthepony.mc.otm.network.MatteryPlayerNetworkChannel import ru.dbotthepony.mc.otm.network.MatteryPlayerNetworkChannel
import ru.dbotthepony.mc.otm.network.MenuFieldPacket import ru.dbotthepony.mc.otm.network.MenuFieldPacket
@ -457,9 +458,9 @@ abstract class MatteryMenu @JvmOverloads protected constructor(
return slot return slot
} }
protected fun addStorageSlot(slot: Iterable<Slot>, addMapping: Boolean = true) { protected fun addStorageSlot(slot: Iterable<Slot>, addMapping: Boolean = true, prepend: Boolean = false, condition: BooleanSupplier = BooleanSupplier { true }) {
for (value in slot) for (value in slot)
addStorageSlot(value, addMapping) addStorageSlot(value, addMapping, prepend, condition)
} }
/** /**
@ -762,8 +763,7 @@ abstract class MatteryMenu @JvmOverloads protected constructor(
val syncContainer = container ?: SimpleContainer(count) val syncContainer = container ?: SimpleContainer(count)
var isOpen = false val isOpen = InstantBooleanInput(this)
val input = PlayerInput(BooleanValueCodec, allowSpectators = true, handler = { isOpen = it })
return UpgradeSlots( return UpgradeSlots(
slots = immutableList(count) { slots = immutableList(count) {
@ -776,10 +776,10 @@ abstract class MatteryMenu @JvmOverloads protected constructor(
return super.mayPlace(itemStack) && itemStack.getCapability(MatteryCapability.UPGRADE).map { it.upgradeTypes.any { allowedTypes[it]!!.boolean } }.orElse(false) return super.mayPlace(itemStack) && itemStack.getCapability(MatteryCapability.UPGRADE).map { it.upgradeTypes.any { allowedTypes[it]!!.boolean } }.orElse(false)
} }
} }
}.also { for (i in it.indices.reversed()) addStorageSlot(it[i], prepend = true, condition = { isOpen }) }, }.also { for (i in it.indices.reversed()) addStorageSlot(it[i], prepend = true, condition = isOpen) },
allowedTypes = ConditionalEnumSet(allowedTypes), allowedTypes = ConditionalEnumSet(allowedTypes),
openState = GetterSetter.of({ isOpen }, { input.input(it); isOpen = it }), openState = isOpen,
currentStats = object : IMatteryUpgrade { currentStats = object : IMatteryUpgrade {
override val upgradeTypes: Set<UpgradeType> = setOf() override val upgradeTypes: Set<UpgradeType> = setOf()
override val speedBonus: Double by mSynchronizer.computedDouble(DoubleSupplier { container?.speedBonus ?: 0.0 }).property override val speedBonus: Double by mSynchronizer.computedDouble(DoubleSupplier { container?.speedBonus ?: 0.0 }).property

View File

@ -0,0 +1,25 @@
package ru.dbotthepony.mc.otm.menu.input
import ru.dbotthepony.mc.otm.core.GetterSetter
import ru.dbotthepony.mc.otm.menu.MatteryMenu
import java.util.function.BooleanSupplier
class InstantBooleanInput(menu: MatteryMenu) : GetterSetter<Boolean>, BooleanSupplier {
var value = false
private set
val input = menu.booleanInput(true) { value = it }
override fun get(): Boolean {
return value
}
override fun getAsBoolean(): Boolean {
return value
}
override fun accept(t: Boolean) {
value = t
input.input(t)
}
}

View File

@ -345,7 +345,7 @@ class FieldSynchronizer(private val callback: Runnable, private val alwaysCallCa
} }
} }
private val dirtyFields = ReferenceArraySet<AbstractField<*>>(fields.size) private val dirtyFields = ReferenceArraySet<AbstractField<*>>(4)
// use LinkedList because it is ensured memory is freed on LinkedList#clear // use LinkedList because it is ensured memory is freed on LinkedList#clear
private val mapBacklogs = Reference2ObjectOpenHashMap<Map<*, *>, LinkedList<Pair<Any?, (DataOutputStream) -> Unit>>>() private val mapBacklogs = Reference2ObjectOpenHashMap<Map<*, *>, LinkedList<Pair<Any?, (DataOutputStream) -> Unit>>>()

View File

@ -187,6 +187,7 @@ private fun addMainCreativeTabItems(consumer: CreativeModeTab.Output) {
accept(MItems.EXOPACK_PROBE) accept(MItems.EXOPACK_PROBE)
accept(MItems.ExopackUpgrades.INVENTORY_UPGRADE_CREATIVE) accept(MItems.ExopackUpgrades.INVENTORY_UPGRADE_CREATIVE)
accept(MItems.ExopackUpgrades.CRAFTING_UPGRADE) accept(MItems.ExopackUpgrades.CRAFTING_UPGRADE)
accept(MItems.ExopackUpgrades.SMELTING_UPGRADE)
accept(MItems.ExopackUpgrades.INVENTORY_UPGRADE_BIG) accept(MItems.ExopackUpgrades.INVENTORY_UPGRADE_BIG)
accept(MItems.ExopackUpgrades.INVENTORY_UPGRADE_HUGE) accept(MItems.ExopackUpgrades.INVENTORY_UPGRADE_HUGE)

View File

@ -14,13 +14,13 @@ 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.MatteryPlayerCapability
import ru.dbotthepony.mc.otm.capability.UpgradeType 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.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.ExoPackProbeItem import ru.dbotthepony.mc.otm.item.exopack.ExoPackProbeItem
import ru.dbotthepony.mc.otm.item.exopack.ExoPackSlotUpgradeItem import ru.dbotthepony.mc.otm.item.exopack.ExoPackSlotUpgradeItem
import ru.dbotthepony.mc.otm.item.matter.CreativePatternItem import ru.dbotthepony.mc.otm.item.matter.CreativePatternItem
@ -33,6 +33,7 @@ import ru.dbotthepony.mc.otm.item.tool.MatteryAxeItem
import ru.dbotthepony.mc.otm.item.armor.PortableGravitationStabilizerItem import ru.dbotthepony.mc.otm.item.armor.PortableGravitationStabilizerItem
import ru.dbotthepony.mc.otm.item.armor.SimpleTritaniumArmorItem import ru.dbotthepony.mc.otm.item.armor.SimpleTritaniumArmorItem
import ru.dbotthepony.mc.otm.item.armor.TritaniumArmorItem import ru.dbotthepony.mc.otm.item.armor.TritaniumArmorItem
import ru.dbotthepony.mc.otm.item.exopack.ExopackUpgradeItem
import ru.dbotthepony.mc.otm.item.exopack.ProceduralExoPackSlotUpgradeItem import ru.dbotthepony.mc.otm.item.exopack.ProceduralExoPackSlotUpgradeItem
import ru.dbotthepony.mc.otm.item.weapon.PlasmaRifleItem import ru.dbotthepony.mc.otm.item.weapon.PlasmaRifleItem
@ -500,7 +501,8 @@ object MItems {
object ExopackUpgrades { object ExopackUpgrades {
val INVENTORY_UPGRADE_CREATIVE: Item by registry.register("exosuit_inventory_upgrade_creative") { ExoPackSlotUpgradeItem(null, 27, Rarity.EPIC) } val INVENTORY_UPGRADE_CREATIVE: Item by registry.register("exosuit_inventory_upgrade_creative") { ExoPackSlotUpgradeItem(null, 27, Rarity.EPIC) }
val CRAFTING_UPGRADE: Item by registry.register("exosuit_crafting_upgrade", ::ExoPackCraftingUpgradeItem) val CRAFTING_UPGRADE: Item by registry.register("exosuit_crafting_upgrade") { ExopackUpgradeItem(MatteryPlayerCapability.UpgradeType.CRAFTING, "crafting_upgrade", "crafting_upgraded") }
val SMELTING_UPGRADE: Item by registry.register("exopack_smelting_upgrade") { ExopackUpgradeItem(MatteryPlayerCapability.UpgradeType.SMELTING, "smelting_upgrade", "smelting_installed") }
val INVENTORY_UPGRADES = SupplierList(8) { val INVENTORY_UPGRADES = SupplierList(8) {
registry.register("exosuit_inventory_upgrade_$it") { ExoPackSlotUpgradeItem(18, Rarity.COMMON) }::get registry.register("exosuit_inventory_upgrade_$it") { ExoPackSlotUpgradeItem(18, Rarity.COMMON) }::get