Cosmetic armor support in exosuit gui
This commit is contained in:
parent
0511802a8c
commit
fafa42b9b7
@ -181,8 +181,10 @@ dependencies {
|
||||
val the_one_probe_version: String by project
|
||||
val mekanism_version: String by project
|
||||
val curios_version: String by project
|
||||
val cosmetic_armor_reworked_version: String by project
|
||||
|
||||
implementation(fg.deobf("top.theillusivec4.curios:curios-forge:${mc_version}-${curios_version}"))
|
||||
implementation(fg.deobf("lain.mods.cos:CosmeticArmorReworked:${mc_version}-${cosmetic_armor_reworked_version}"))
|
||||
|
||||
compileOnly(fg.deobf("mezz.jei:jei-${mc_version}-common-api:${jei_version}"))
|
||||
compileOnly(fg.deobf("mezz.jei:jei-${mc_version}-forge-api:${jei_version}"))
|
||||
|
@ -18,6 +18,7 @@ jupiter_version=5.8.2
|
||||
the_one_probe_version=6.2.1
|
||||
mekanism_version=10.3.2.homebaked
|
||||
curios_version=5.1.1.0
|
||||
cosmetic_armor_reworked_version=v1
|
||||
|
||||
kotlin_for_forge_version=3.1.0
|
||||
kotlin_version=1.6.10
|
||||
|
@ -12,6 +12,7 @@ import ru.dbotthepony.mc.otm.client.render.Widgets18
|
||||
import ru.dbotthepony.mc.otm.client.screen.ExoSuitInventoryScreen
|
||||
import ru.dbotthepony.mc.otm.client.screen.panels.LargeRectangleButtonPanel
|
||||
import ru.dbotthepony.mc.otm.client.screen.panels.Panel2Widget
|
||||
import ru.dbotthepony.mc.otm.compat.cos.isCosmeticArmorScreen
|
||||
import ru.dbotthepony.mc.otm.core.TranslatableComponent
|
||||
import ru.dbotthepony.mc.otm.registry.AndroidFeatures
|
||||
|
||||
@ -52,7 +53,7 @@ fun onPostScreenInit(event: ScreenEvent.Init.Post) {
|
||||
val player = minecraft.player?.matteryPlayer ?: return
|
||||
|
||||
val eventScreen = event.screen
|
||||
val screen = if (eventScreen is AbstractContainerScreen<*> && eventScreen.menu is InventoryMenu) eventScreen else return
|
||||
val screen = if (eventScreen is AbstractContainerScreen<*> && (eventScreen.menu is InventoryMenu || eventScreen.isCosmeticArmorScreen)) eventScreen else return
|
||||
|
||||
if (player.hasExoSuit) {
|
||||
val widget = Panel2Widget(LargeRectangleButtonPanel(screen, null,
|
||||
|
@ -12,12 +12,14 @@ import ru.dbotthepony.mc.otm.client.render.element
|
||||
import ru.dbotthepony.mc.otm.client.screen.panels.*
|
||||
import ru.dbotthepony.mc.otm.client.setMousePos
|
||||
import ru.dbotthepony.mc.otm.client.shouldOpenVanillaInventory
|
||||
import ru.dbotthepony.mc.otm.compat.cos.CosmeticToggleButton
|
||||
import ru.dbotthepony.mc.otm.compat.curios.curiosSlots
|
||||
import ru.dbotthepony.mc.otm.core.maxScrollDivision
|
||||
import ru.dbotthepony.mc.otm.menu.ExoSuitInventoryMenu
|
||||
import ru.dbotthepony.mc.otm.network.ExoSuitMenuOpen
|
||||
import ru.dbotthepony.mc.otm.network.MatteryPlayerNetworkChannel
|
||||
import yalter.mousetweaks.api.MouseTweaksDisableWheelTweak
|
||||
import kotlin.math.cos
|
||||
|
||||
@MouseTweaksDisableWheelTweak
|
||||
class ExoSuitInventoryScreen(menu: ExoSuitInventoryMenu) : MatteryScreen<ExoSuitInventoryMenu>(menu, TranslatableComponent("otm.gui.exosuit")) {
|
||||
@ -103,8 +105,22 @@ class ExoSuitInventoryScreen(menu: ExoSuitInventoryMenu) : MatteryScreen<ExoSuit
|
||||
armorSlotsStrip.dock = Dock.LEFT
|
||||
|
||||
for (slot in menu.armorSlots) {
|
||||
val panel = SlotPanel(this, armorSlotsStrip, slot)
|
||||
panel.dock = Dock.TOP
|
||||
val cosmeticSlot = menu.cosmeticArmorSlots[slot.type]
|
||||
|
||||
if (cosmeticSlot == null) {
|
||||
SlotPanel(this, armorSlotsStrip, slot).also {
|
||||
it.dock = Dock.TOP
|
||||
}
|
||||
} else {
|
||||
FoldableSlotPanel(this, armorSlotsStrip,
|
||||
SlotPanel(this, null, slot).also {
|
||||
CosmeticToggleButton(this, it, slot.type)
|
||||
},
|
||||
listOf(SlotPanel(this, null, cosmeticSlot))
|
||||
).also {
|
||||
it.dock = Dock.TOP
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val playerRectangle = EntityRendererPanel(this, topLine, minecraft!!.player!!)
|
||||
|
@ -13,7 +13,7 @@ open class EditBoxPanel<out S : Screen>(
|
||||
width: Float = 0f,
|
||||
height: Float = 20f,
|
||||
val defaultText: Component = TextComponent("")
|
||||
) : MinecraftWidgetPanel<S, EditBox>(screen, parent, x, y, width, height) {
|
||||
) : Widget2Panel<S, EditBox>(screen, parent, x, y, width, height) {
|
||||
override fun makeNew(): EditBox {
|
||||
return object : EditBox(font, 0, 0, width.toInt(), height.toInt().coerceAtMost(20), defaultText) {
|
||||
override fun isHoveredOrFocused(): Boolean {
|
||||
|
@ -41,7 +41,7 @@ enum class DockResizeMode(val changeWidth: Boolean, val changeHeight: Boolean) {
|
||||
ALL(true, true), NONE(false, false), WIDTH(true, false), HEIGHT(false, true)
|
||||
}
|
||||
|
||||
interface ISlotPanel<S : Slot> {
|
||||
interface ISlotPanel<out S : Slot> {
|
||||
val slot: S
|
||||
}
|
||||
|
||||
@ -464,13 +464,10 @@ open class EditablePanel<out S : Screen> @JvmOverloads constructor(
|
||||
return
|
||||
}
|
||||
|
||||
val old = field
|
||||
field = value
|
||||
|
||||
if (value) {
|
||||
onHovered()
|
||||
} else {
|
||||
onUnHovered()
|
||||
}
|
||||
onHoverUpdate(old, value)
|
||||
}
|
||||
|
||||
fun unsetHovered() {
|
||||
@ -481,6 +478,14 @@ open class EditablePanel<out S : Screen> @JvmOverloads constructor(
|
||||
}
|
||||
}
|
||||
|
||||
protected open fun onHoverUpdate(oldHover: Boolean, newHover: Boolean) {
|
||||
if (newHover) {
|
||||
onHovered()
|
||||
} else {
|
||||
onUnHovered()
|
||||
}
|
||||
}
|
||||
|
||||
protected open fun onHovered() {}
|
||||
protected open fun onUnHovered() {}
|
||||
|
||||
@ -1468,6 +1473,7 @@ open class EditablePanel<out S : Screen> @JvmOverloads constructor(
|
||||
var isRemoved = false
|
||||
private set
|
||||
|
||||
protected open fun beforeRemoved() {}
|
||||
protected open fun onRemoved() {}
|
||||
|
||||
fun remove() {
|
||||
@ -1476,6 +1482,7 @@ open class EditablePanel<out S : Screen> @JvmOverloads constructor(
|
||||
}
|
||||
|
||||
killFocus()
|
||||
beforeRemoved()
|
||||
|
||||
if (screen is MatteryScreen<*>) {
|
||||
screen.removePanel(this as EditablePanel<MatteryScreen<*>>)
|
||||
|
@ -0,0 +1,103 @@
|
||||
package ru.dbotthepony.mc.otm.client.screen.panels
|
||||
|
||||
import net.minecraft.world.inventory.Slot
|
||||
import ru.dbotthepony.mc.otm.client.screen.MatteryScreen
|
||||
|
||||
open class FoldableSlotPanel<out S : MatteryScreen<*>, out T : Slot> @JvmOverloads constructor(
|
||||
screen: S,
|
||||
parent: EditablePanel<*>?,
|
||||
val mainSlot: SlotPanel<S, T>,
|
||||
val extraSlots: Collection<EditablePanel<S>>,
|
||||
x: Float = 0f,
|
||||
y: Float = 0f,
|
||||
width: Float = AbstractSlotPanel.SIZE,
|
||||
height: Float = AbstractSlotPanel.SIZE,
|
||||
) : EditablePanel<S>(screen, parent, x, y, width, height), ISlotPanel<T> {
|
||||
init {
|
||||
mainSlot.parent = this
|
||||
mainSlot.dock = Dock.FILL
|
||||
}
|
||||
|
||||
open inner class HoverPanel : BackgroundPanel<S>(
|
||||
screen,
|
||||
null,
|
||||
this@FoldableSlotPanel.absoluteX,
|
||||
this@FoldableSlotPanel.absoluteY,
|
||||
width = extraSlots.stream().mapToDouble { (it.width + it.dockMargin.right + it.dockMargin.left).toDouble() }.sum().toFloat() + mainSlot.width + mainSlot.dockMargin.left + mainSlot.dockMargin.right,
|
||||
height = extraSlots.stream().mapToDouble { (it.height + it.dockMargin.top + it.dockMargin.bottom).toDouble() }.max().orElse(0.0).toFloat().coerceAtLeast(mainSlot.height + mainSlot.dockMargin.top + mainSlot.dockMargin.bottom),
|
||||
) {
|
||||
init {
|
||||
x -= dockPadding.left
|
||||
y -= dockPadding.top
|
||||
|
||||
width += dockPadding.left + dockPadding.right
|
||||
height += dockPadding.top + dockPadding.bottom
|
||||
|
||||
mainSlot.parent = this
|
||||
mainSlot.dock = Dock.LEFT
|
||||
|
||||
for (slot in extraSlots) {
|
||||
slot.parent = this
|
||||
slot.dock = Dock.LEFT
|
||||
}
|
||||
|
||||
screen.addPanel(this)
|
||||
}
|
||||
|
||||
override fun beforeRemoved() {
|
||||
mainSlot.parent = this@FoldableSlotPanel
|
||||
mainSlot.dock = Dock.FILL
|
||||
|
||||
for (slot in extraSlots) {
|
||||
slot.parent = null
|
||||
}
|
||||
|
||||
this@FoldableSlotPanel.hoverPanel = null
|
||||
}
|
||||
|
||||
override fun onUnHovered() {
|
||||
remove()
|
||||
}
|
||||
|
||||
override fun tick() {
|
||||
super.tick()
|
||||
|
||||
x = this@FoldableSlotPanel.absoluteX - dockPadding.left
|
||||
y = this@FoldableSlotPanel.absoluteY - dockPadding.top
|
||||
}
|
||||
}
|
||||
|
||||
override val slot: T
|
||||
get() = mainSlot.slot
|
||||
|
||||
var hoveringSince: Long? = null
|
||||
protected set
|
||||
var hoverPanel: HoverPanel? = null
|
||||
protected set
|
||||
|
||||
override fun onHovered() {
|
||||
hoveringSince = System.nanoTime()
|
||||
}
|
||||
|
||||
override fun onUnHovered() {
|
||||
hoveringSince = null
|
||||
}
|
||||
|
||||
override fun beforeRemoved() {
|
||||
hoverPanel?.remove()
|
||||
}
|
||||
|
||||
override fun tick() {
|
||||
super.tick()
|
||||
|
||||
val hoveringSince = hoveringSince
|
||||
|
||||
if (hoveringSince != null && System.nanoTime() - hoveringSince >= MAX_HOVER_TIME && hoverPanel == null && extraSlots.isNotEmpty()) {
|
||||
hoverPanel = HoverPanel()
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val MAX_HOVER_TIME = 1_000_000_000
|
||||
}
|
||||
}
|
@ -19,7 +19,7 @@ import ru.dbotthepony.mc.otm.client.render.setDrawColor
|
||||
import ru.dbotthepony.mc.otm.client.screen.MatteryScreen
|
||||
import javax.annotation.Nonnull
|
||||
|
||||
open class SlotPanel<out S : MatteryScreen<*>, T : Slot> @JvmOverloads constructor(
|
||||
open class SlotPanel<out S : MatteryScreen<*>, out T : Slot> @JvmOverloads constructor(
|
||||
screen: S,
|
||||
parent: EditablePanel<*>?,
|
||||
final override val slot: T,
|
||||
|
@ -4,11 +4,9 @@ import com.mojang.blaze3d.systems.RenderSystem
|
||||
import com.mojang.blaze3d.vertex.PoseStack
|
||||
import net.minecraft.client.gui.components.AbstractWidget
|
||||
import net.minecraft.client.gui.screens.Screen
|
||||
import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen
|
||||
import org.lwjgl.opengl.GL11
|
||||
import ru.dbotthepony.mc.otm.client.screen.MatteryScreen
|
||||
|
||||
abstract class MinecraftWidgetPanel<out S : Screen, T : AbstractWidget>(
|
||||
abstract class Widget2Panel<out S : Screen, T : AbstractWidget>(
|
||||
screen: S,
|
||||
parent: EditablePanel<*>?,
|
||||
x: Float,
|
||||
@ -114,4 +112,4 @@ abstract class MinecraftWidgetPanel<out S : Screen, T : AbstractWidget>(
|
||||
val (x1, y1) = screenToLocal(x, y)
|
||||
return getOrCreateWidget().mouseReleased(x1.toDouble(), y1.toDouble(), button)
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,142 @@
|
||||
package ru.dbotthepony.mc.otm.compat.cos
|
||||
|
||||
import com.mojang.blaze3d.platform.InputConstants
|
||||
import com.mojang.blaze3d.vertex.PoseStack
|
||||
import lain.mods.cos.impl.ModObjects
|
||||
import lain.mods.cos.impl.client.gui.GuiCosArmorInventory
|
||||
import lain.mods.cos.impl.client.gui.GuiCosArmorToggleButton
|
||||
import lain.mods.cos.impl.network.packet.PacketSetSkinArmor
|
||||
import net.minecraft.client.gui.screens.Screen
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.server.level.ServerPlayer
|
||||
import net.minecraft.world.Container
|
||||
import net.minecraft.world.entity.EquipmentSlot
|
||||
import net.minecraft.world.entity.player.Player
|
||||
import net.minecraft.world.inventory.InventoryMenu
|
||||
import net.minecraft.world.inventory.Slot
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import net.minecraftforge.fml.ModList
|
||||
import ru.dbotthepony.mc.otm.client.minecraft
|
||||
import ru.dbotthepony.mc.otm.client.render.SkinElement
|
||||
import ru.dbotthepony.mc.otm.client.render.element
|
||||
import ru.dbotthepony.mc.otm.client.screen.panels.AbstractSlotPanel
|
||||
import ru.dbotthepony.mc.otm.client.screen.panels.EditablePanel
|
||||
import ru.dbotthepony.mc.otm.client.screen.panels.RectangleButtonPanel
|
||||
import ru.dbotthepony.mc.otm.menu.MatterySlot
|
||||
|
||||
val isCosmeticArmorLoaded by lazy {
|
||||
ModList.get().isLoaded("cosmeticarmorreworked")
|
||||
}
|
||||
|
||||
val Player.cosmeticArmorSlots: Map<EquipmentSlot, Slot>? get() {
|
||||
if (!isCosmeticArmorLoaded) {
|
||||
return null
|
||||
}
|
||||
|
||||
return cosmeticArmorSlotsImpl
|
||||
}
|
||||
|
||||
private class CosmeticSlot(container: Container, private val slot: EquipmentSlot, private val player: Player) : MatterySlot(container, when (slot) {
|
||||
EquipmentSlot.FEET -> 0
|
||||
EquipmentSlot.LEGS -> 1
|
||||
EquipmentSlot.CHEST -> 2
|
||||
EquipmentSlot.HEAD -> 3
|
||||
else -> throw IllegalArgumentException()
|
||||
}) {
|
||||
override fun mayPlace(itemStack: ItemStack): Boolean {
|
||||
return super.mayPlace(itemStack) && itemStack.canEquip(slot, player)
|
||||
}
|
||||
|
||||
override fun getMaxStackSize(): Int {
|
||||
return 1
|
||||
}
|
||||
|
||||
override fun getNoItemIcon(): com.mojang.datafixers.util.Pair<ResourceLocation, ResourceLocation>? {
|
||||
return when (slot) {
|
||||
EquipmentSlot.FEET -> com.mojang.datafixers.util.Pair.of(InventoryMenu.BLOCK_ATLAS, InventoryMenu.EMPTY_ARMOR_SLOT_BOOTS)
|
||||
EquipmentSlot.LEGS -> com.mojang.datafixers.util.Pair.of(InventoryMenu.BLOCK_ATLAS, InventoryMenu.EMPTY_ARMOR_SLOT_LEGGINGS)
|
||||
EquipmentSlot.CHEST -> com.mojang.datafixers.util.Pair.of(InventoryMenu.BLOCK_ATLAS, InventoryMenu.EMPTY_ARMOR_SLOT_CHESTPLATE)
|
||||
EquipmentSlot.HEAD -> com.mojang.datafixers.util.Pair.of(InventoryMenu.BLOCK_ATLAS, InventoryMenu.EMPTY_ARMOR_SLOT_HELMET)
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private val Player.cosmeticArmorSlotsImpl: Map<EquipmentSlot, Slot>? get() {
|
||||
val manager = ModObjects.invMan ?: return null
|
||||
|
||||
val container = if (this !is ServerPlayer) {
|
||||
manager.getCosArmorInventoryClient(uuid)
|
||||
} else {
|
||||
manager.getCosArmorInventory(uuid)
|
||||
}
|
||||
|
||||
return mapOf(
|
||||
EquipmentSlot.HEAD to CosmeticSlot(container, EquipmentSlot.HEAD, this),
|
||||
EquipmentSlot.CHEST to CosmeticSlot(container, EquipmentSlot.CHEST, this),
|
||||
EquipmentSlot.LEGS to CosmeticSlot(container, EquipmentSlot.LEGS, this),
|
||||
EquipmentSlot.FEET to CosmeticSlot(container, EquipmentSlot.FEET, this),
|
||||
)
|
||||
}
|
||||
|
||||
val Screen.isCosmeticArmorScreen: Boolean get() {
|
||||
if (!isCosmeticArmorLoaded) {
|
||||
return false
|
||||
}
|
||||
|
||||
return isCosmeticArmorScreenImpl
|
||||
}
|
||||
|
||||
private val Screen.isCosmeticArmorScreenImpl: Boolean get() {
|
||||
return this is GuiCosArmorInventory
|
||||
}
|
||||
|
||||
class CosmeticToggleButton<out S : Screen>(
|
||||
screen: S,
|
||||
parent: EditablePanel<S>? = null,
|
||||
index: EquipmentSlot,
|
||||
x: Float = 0f,
|
||||
y: Float = 0f,
|
||||
width: Float = 5f,
|
||||
height: Float = 5f
|
||||
) : RectangleButtonPanel<S>(screen, parent, x, y, width, height) {
|
||||
override val PRESSED: SkinElement
|
||||
get() = BUTTON_ACTIVE
|
||||
override val HOVERED: SkinElement
|
||||
get() = BUTTON_ACTIVE
|
||||
override val IDLE: SkinElement
|
||||
get() = BUTTON_INACTIVE
|
||||
override val DISABLED: SkinElement
|
||||
get() = BUTTON_INACTIVE
|
||||
|
||||
private val index = when (index) {
|
||||
EquipmentSlot.FEET -> 0
|
||||
EquipmentSlot.LEGS -> 1
|
||||
EquipmentSlot.CHEST -> 2
|
||||
EquipmentSlot.HEAD -> 3
|
||||
else -> throw IllegalArgumentException()
|
||||
}
|
||||
|
||||
override fun onClick(clickButton: Int) {
|
||||
if (clickButton == InputConstants.MOUSE_BUTTON_LEFT) {
|
||||
val inv = ModObjects.invMan.getCosArmorInventoryClient(minecraft.player?.uuid ?: throw ConcurrentModificationException())
|
||||
inv.setSkinArmor(index, !inv.isSkinArmor(index))
|
||||
ModObjects.network.sendToServer(PacketSetSkinArmor(index, inv.isSkinArmor(index)))
|
||||
}
|
||||
}
|
||||
|
||||
override fun innerRender(stack: PoseStack, mouseX: Float, mouseY: Float, partialTick: Float) {
|
||||
val inv = ModObjects.invMan.getCosArmorInventoryClient(minecraft.player?.uuid ?: throw ConcurrentModificationException())
|
||||
|
||||
if (inv.isSkinArmor(index)) {
|
||||
BUTTON_ACTIVE.render(stack, x, y, width, height)
|
||||
} else {
|
||||
BUTTON_INACTIVE.render(stack, x, y, width, height)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
val BUTTON_INACTIVE = GuiCosArmorInventory.TEXTURE.element(0f, 176f, 5f, 5f)
|
||||
val BUTTON_ACTIVE = GuiCosArmorInventory.TEXTURE.element(5f, 176f, 5f, 5f)
|
||||
}
|
||||
}
|
@ -10,6 +10,7 @@ import net.minecraft.world.entity.player.Player
|
||||
import net.minecraft.world.inventory.*
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import ru.dbotthepony.mc.otm.capability.MatteryPlayerCapability
|
||||
import ru.dbotthepony.mc.otm.compat.cos.cosmeticArmorSlots
|
||||
import ru.dbotthepony.mc.otm.compat.curios.curiosSlots
|
||||
import ru.dbotthepony.mc.otm.container.iterator
|
||||
import ru.dbotthepony.mc.otm.network.ExoSuitCarriedPacket
|
||||
@ -85,6 +86,8 @@ class ExoSuitInventoryMenu(val capability: MatteryPlayerCapability) : MatteryMen
|
||||
}
|
||||
}
|
||||
|
||||
val cosmeticArmorSlots: Map<net.minecraft.world.entity.EquipmentSlot, Slot> = ply.cosmeticArmorSlots?.also { it.values.forEach(this::addSlot) } ?: mapOf()
|
||||
|
||||
override fun slotsChanged(container: Container) {
|
||||
super.slotsChanged(container)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user