From c7198b4f655bbc356f779ae6ce077d52111c54d3 Mon Sep 17 00:00:00 2001 From: radimous Date: Sat, 18 Jan 2025 11:30:20 +0100 Subject: [PATCH] crafted modifiers and transmogs --- .../com/radimous/vhatcaniroll/Config.java | 4 + .../ui/CraftedModifiersListContainer.java | 248 ++++++++++++++++++ .../vhatcaniroll/ui/GearModifierScreen.java | 118 +++++++-- .../vhatcaniroll/ui/InnerGearScreen.java | 12 + .../ui/ModifierListContainer.java | 7 +- .../ui/TransmogListContainer.java | 88 +++++++ .../assets/vhatcaniroll/lang/en_us.json | 4 +- 7 files changed, 461 insertions(+), 20 deletions(-) create mode 100644 src/main/java/com/radimous/vhatcaniroll/ui/CraftedModifiersListContainer.java create mode 100644 src/main/java/com/radimous/vhatcaniroll/ui/InnerGearScreen.java create mode 100644 src/main/java/com/radimous/vhatcaniroll/ui/TransmogListContainer.java diff --git a/src/main/java/com/radimous/vhatcaniroll/Config.java b/src/main/java/com/radimous/vhatcaniroll/Config.java index 009814d..47e7a34 100644 --- a/src/main/java/com/radimous/vhatcaniroll/Config.java +++ b/src/main/java/com/radimous/vhatcaniroll/Config.java @@ -15,6 +15,7 @@ public class Config { public static final ForgeConfigSpec.BooleanValue SHOW_WEIGHT; public static final ForgeConfigSpec.BooleanValue SHOW_CHANCE; public static final ForgeConfigSpec.BooleanValue QOL_HUNTERS_CONFLICT_RESOLUTION; + public static final ForgeConfigSpec.BooleanValue SHOW_UNOBTAINABLE_CRAFTED; // string instead of enum, because forge would remove enum values that are not present in the enum // (this could cause problems if mods are extending the enum - like wold's) public static final ForgeConfigSpec.ConfigValue> AFFIX_TAG_GROUP_CHANCE_BLACKLIST; @@ -62,6 +63,9 @@ public class Config { .comment("vhcir won't show chance/weight for affixes in these groups") .define("affixTagGroupBlacklist", List.of(VaultGearTierConfig.ModifierAffixTagGroup.CRAFTED_PREFIX.name(), VaultGearTierConfig.ModifierAffixTagGroup.CRAFTED_SUFFIX.name())); + SHOW_UNOBTAINABLE_CRAFTED = builder + .comment("show unobtainable crafted modifiers (above current lvl)") + .define("showUnobtainableCrafted", false); SPEC = builder.build(); } } diff --git a/src/main/java/com/radimous/vhatcaniroll/ui/CraftedModifiersListContainer.java b/src/main/java/com/radimous/vhatcaniroll/ui/CraftedModifiersListContainer.java new file mode 100644 index 0000000..0c9cf60 --- /dev/null +++ b/src/main/java/com/radimous/vhatcaniroll/ui/CraftedModifiersListContainer.java @@ -0,0 +1,248 @@ +package com.radimous.vhatcaniroll.ui; + +import com.mojang.blaze3d.systems.RenderSystem; +import com.mojang.blaze3d.vertex.PoseStack; +import com.radimous.vhatcaniroll.Config; +import com.radimous.vhatcaniroll.logic.ModifierCategory; +import iskallia.vault.client.atlas.TextureAtlasRegion; +import iskallia.vault.client.gui.framework.ScreenTextures; +import iskallia.vault.client.gui.framework.element.ButtonElement; +import iskallia.vault.client.gui.framework.element.DynamicLabelElement; +import iskallia.vault.client.gui.framework.element.FakeItemSlotElement; +import iskallia.vault.client.gui.framework.element.LabelElement; +import iskallia.vault.client.gui.framework.element.NineSliceButtonElement; +import iskallia.vault.client.gui.framework.element.VerticalScrollClipContainer; +import iskallia.vault.client.gui.framework.render.spi.IElementRenderer; +import iskallia.vault.client.gui.framework.screen.layout.ScreenLayout; +import iskallia.vault.client.gui.framework.spatial.Spatials; +import iskallia.vault.client.gui.framework.spatial.spi.IPosition; +import iskallia.vault.client.gui.framework.spatial.spi.ISpatial; +import iskallia.vault.client.gui.framework.text.LabelTextStyle; +import iskallia.vault.config.gear.VaultGearWorkbenchConfig; +import iskallia.vault.gear.VaultGearState; +import iskallia.vault.gear.data.VaultGearData; +import iskallia.vault.init.ModGearAttributes; +import net.minecraft.ChatFormatting; +import net.minecraft.client.Minecraft; +import net.minecraft.network.chat.MutableComponent; +import net.minecraft.network.chat.Style; +import net.minecraft.network.chat.TextColor; +import net.minecraft.network.chat.TextComponent; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; +import org.jetbrains.annotations.NotNull; + +import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.Supplier; + +import static iskallia.vault.client.gui.framework.ScreenTextures.BUTTON_EMPTY; +import static iskallia.vault.client.gui.framework.ScreenTextures.BUTTON_EMPTY_16_48_TEXTURES; +import static iskallia.vault.client.gui.framework.ScreenTextures.BUTTON_EMPTY_DISABLED; + + +public class CraftedModifiersListContainer extends VerticalScrollClipContainer + implements InnerGearScreen { + + public CraftedModifiersListContainer(ISpatial spatial, int lvl, ModifierCategory modifierCategory, + ItemStack gearPiece) { + super(spatial); + int labelX = 9; + int labelY = 0; + + var player = Minecraft.getInstance().player; + if (player == null) { + return; + } + + var stackCopy = gearPiece.copy(); + VaultGearData gearData = VaultGearData.read(stackCopy); + gearData.setItemLevel(lvl); + gearData.setState(VaultGearState.IDENTIFIED); + gearData.createOrReplaceAttributeValue(ModGearAttributes.PREFIXES, 1); + gearData.createOrReplaceAttributeValue(ModGearAttributes.SUFFIXES, 1); + gearData.write(stackCopy); + + + + var crMods = VaultGearWorkbenchConfig.getConfig(gearPiece.getItem()) + .map(VaultGearWorkbenchConfig::getAllCraftableModifiers).orElse(null); + if (crMods == null) { + cookieDialog(); + return; + } + + for (VaultGearWorkbenchConfig.CraftableModifierConfig mod : crMods) { + boolean disabled = false; + + // is unlocked? + MutableComponent fullCmp = new TextComponent(""); + var mm = mod.createModifier().orElse(null); + if (mm == null) { + continue; + } + var oCfgDisplay = mm.getConfigDisplay(gearPiece); + oCfgDisplay.ifPresent(fullCmp::append); + MutableComponent restriction = new TextComponent(""); + int minLevel = mod.getMinLevel(); + if (mod.getUnlockCategory() == VaultGearWorkbenchConfig.UnlockCategory.LEVEL && lvl < minLevel) { + if (!Config.SHOW_UNOBTAINABLE_CRAFTED.get()){ + continue; + } + restriction.append(new TextComponent(" LVL " + minLevel + "+").withStyle(ChatFormatting.DARK_RED)); + disabled = true; + } + if (mod.getUnlockCategory() == VaultGearWorkbenchConfig.UnlockCategory.VAULT_DISCOVERY && !mod.hasPrerequisites(player)) { + if (minLevel > lvl) { + if (!Config.SHOW_UNOBTAINABLE_CRAFTED.get()){ + continue; + } + restriction.append(new TextComponent(" ARCHIVE").withStyle(ChatFormatting.DARK_RED)); + } else { + restriction.append(new TextComponent(" ARCHIVE").withStyle(Style.EMPTY.withColor(TextColor.parseColor("#ff6f00")))); + } + disabled = true; + } + LabelElement labelelement = new LabelElement<>( + Spatials.positionXY(8, labelY + 5).width(this.innerHeight() - labelX), fullCmp, + LabelTextStyle.defaultStyle().shadow() // WHY DOESN'T SHADOW WORK? + ); + NineSliceButtonElement btn = new NineSliceButtonElement<>(Spatials.positionXY(0, labelY ).width(innerWidth()).height(18), + new NineSliceButtonElement.NineSliceButtonTextures(BUTTON_EMPTY, BUTTON_EMPTY, BUTTON_EMPTY, BUTTON_EMPTY_DISABLED), () -> {}); + + + //align right + LabelElement restrictionLabel = new LabelElement<>( + Spatials.positionXY(btn.right() - 70, labelY + 5).width(this.innerHeight() - labelX).height(14), restriction, + LabelTextStyle.defaultStyle().border4() + ); + btn.setDisabled(disabled); + this.addElement(btn); + this.addElement(labelelement); + this.addElement(restrictionLabel); + labelY += 18; + + } + + + } + + public float getScroll() { + return 0; + } + + public void setScroll(float scroll) { + } + + @Override + public InnerGearScreen create(ISpatial spatial, int lvl, ModifierCategory modifierCategory, ItemStack gearPiece) { + return new CraftedModifiersListContainer(spatial, lvl, modifierCategory, gearPiece); + } + + + + + // :) + private void cookieDialog(){ + var noModifiers = new LabelElement<>(Spatials.positionXY(innerWidth()/2 - 60, 20).width(18).height(18), new TextComponent("No crafted modifiers found."), LabelTextStyle.defaultStyle().border4().center()); + var wantCookie = new LabelElement<>(Spatials.positionXY(innerWidth()/2 - 50, 80).width(18).height(18), new TextComponent("Would you like a cookie?"), LabelTextStyle.defaultStyle().border4().center()); + var yesBtn = new ButtonElement<>(Spatials.positionXY(innerWidth()/2 - 20, 100).width(100).height(20), BUTTON_EMPTY_16_48_TEXTURES, () -> {}); + var noBtn = new ButtonElement<>(Spatials.positionXY(innerWidth()/2 - 20, 120).width(100).height(20), BUTTON_EMPTY_16_48_TEXTURES, () -> { /* sad cookie monster noises */}); + var yesLabel = new LabelElement<>(Spatials.positionXY(innerWidth()/2 - 6, 105).width(18).height(18), new TextComponent("Yes"), LabelTextStyle.defaultStyle().border4().center()); + var noLabel = new LabelElement<>(Spatials.positionXY(innerWidth()/2 - 3, 125).width(18).height(18), new TextComponent("No"), LabelTextStyle.defaultStyle().border4().center()); + var sadCookie = new LabelElement<>(Spatials.positionXY(innerWidth()/2 - 65, 145).width(18).height(18), new TextComponent("*Sad cookie monster noises*").withStyle(ChatFormatting.GRAY), LabelTextStyle.defaultStyle().center()); + yesBtn.setOnClick(() -> { + this.removeElement(noModifiers); + this.removeElement(wantCookie); + this.removeElement(yesBtn); + this.removeElement(noBtn); + this.removeElement(yesLabel); + this.removeElement(noLabel); + this.removeElement(sadCookie); + ScreenLayout.requestLayout(); + cookie(); + }); + + noBtn.setOnClick(() -> { + this.addElement(sadCookie); + noBtn.setDisabled(true); + ScreenLayout.requestLayout(); + }); + this.addElement(noModifiers); + this.addElement(wantCookie); + this.addElement(yesLabel); + this.addElement(noLabel); + this.addElement(noBtn); + this.addElement(yesBtn); + + + } + private void cookie(){ + AtomicInteger counter = new AtomicInteger(0); + var slot = new ScaledFakeItemSlotElement<>(Spatials.positionXY(innerWidth()/2, innerHeight()/2), () -> new ItemStack(Items.COOKIE), () -> false, ScreenTextures.EMPTY, ScreenTextures.EMPTY,8*16,8*16, 8f); + slot.whenClicked(counter::getAndIncrement); + this.addElement(slot); + this.addElement(new CookieLabelElement(Spatials.positionXY(innerWidth()/2, innerHeight()/2 - 70).width(18).height(18), counter::get, LabelTextStyle.defaultStyle().border4().center())); + } + + private class CookieLabelElement extends DynamicLabelElement{ + public CookieLabelElement(IPosition position, + Supplier valueSupplier, LabelTextStyle.Builder labelTextStyle) { + super(position, valueSupplier, labelTextStyle); + } + + @Override protected void onValueChanged(Integer count) { + this.set(new TextComponent(count.toString())); + } + + @Override public void render(IElementRenderer renderer, @NotNull PoseStack poseStack, int mouseX, int mouseY, + float partialTick) { + if (this.valueSupplier.get() == 0) { + return; + } + var ll = RenderSystem.getModelViewStack(); + ll.pushPose(); + float scale = 2f; + ll.scale(scale, scale, scale); + ll.translate(-getWorldSpatial().x() * (1 - 1/scale), -getWorldSpatial().y() * (1 - 1/scale), 0); + RenderSystem.applyModelViewMatrix(); + + super.render(renderer, poseStack, mouseX, mouseY, partialTick); + ll.popPose(); + + } + } + + private static class ScaledFakeItemSlotElement > extends FakeItemSlotElement { + private float scale; + private long lastClicked = 0; + public ScaledFakeItemSlotElement(ISpatial spatial, Supplier itemStack, Supplier disabled, TextureAtlasRegion slotTexture, TextureAtlasRegion disabledSlotTexture, int width, int height, float scale) { + super(Spatials.positionX((int) (spatial.x() - (scale * 9))).positionY((int) (spatial.y() - (scale * 9))), itemStack, disabled, slotTexture, disabledSlotTexture, width, height); + this.scale = scale; + } + + @Override public void render(IElementRenderer renderer, @NotNull PoseStack poseStack, int mouseX, int mouseY, float partialTick) { + float originalScale = scale; + long msDiff = System.currentTimeMillis() - lastClicked; + if (msDiff < 150) { + scale *= 1 + msDiff * 0.001f; + } else if (msDiff < 300) { + scale *= 1 + (300 - msDiff) * 0.001f; + } + var viewStack = RenderSystem.getModelViewStack(); + viewStack.pushPose(); + viewStack.translate(- (scale - originalScale) * originalScale, - (scale - originalScale) * originalScale, 0); + viewStack.scale(scale, scale, 1); + viewStack.translate(-getWorldSpatial().x() * (1 - 1/scale), -getWorldSpatial().y() * (1 - 1/scale), 0); + RenderSystem.applyModelViewMatrix(); + super.render(renderer, poseStack, mouseX, mouseY, partialTick); + viewStack.popPose(); + scale = originalScale; + } + + @Override public boolean mouseClicked(double mouseX, double mouseY, int buttonIndex) { + if (this.isEnabled() && this.containsMouse(mouseX, mouseY) && buttonIndex == 0) + lastClicked = System.currentTimeMillis(); + return super.mouseClicked(mouseX, mouseY, buttonIndex); + } + } +} \ No newline at end of file diff --git a/src/main/java/com/radimous/vhatcaniroll/ui/GearModifierScreen.java b/src/main/java/com/radimous/vhatcaniroll/ui/GearModifierScreen.java index ea78d02..a0fc9b1 100644 --- a/src/main/java/com/radimous/vhatcaniroll/ui/GearModifierScreen.java +++ b/src/main/java/com/radimous/vhatcaniroll/ui/GearModifierScreen.java @@ -17,6 +17,8 @@ import iskallia.vault.client.gui.framework.element.NineSliceButtonElement; import iskallia.vault.client.gui.framework.element.NineSliceElement; import iskallia.vault.client.gui.framework.element.TabElement; import iskallia.vault.client.gui.framework.element.TextureAtlasElement; +import iskallia.vault.client.gui.framework.element.VerticalScrollClipContainer; +import iskallia.vault.client.gui.framework.element.spi.ILayoutElement; import iskallia.vault.client.gui.framework.element.spi.ILayoutStrategy; import iskallia.vault.client.gui.framework.render.ScreenTooltipRenderer; import iskallia.vault.client.gui.framework.render.TooltipDirection; @@ -39,19 +41,19 @@ import java.util.List; public class GearModifierScreen extends AbstractElementScreen { //TODO: remove magic numbers - - private ModifierListContainer modifierList; + private InnerGearScreen innerScreen; private final ScrollableLvlInputElement lvlInput; private ModifierCategory modifierCategory = ModifierCategory.NORMAL; private LabelElement modifierCategoryLabel; + private NineSliceButtonElement modifierCategoryButton; private HelpContainer helpContainer; + private LabelElement windowName; private int currIndex = 0; private final List> tabs = new ArrayList<>(); public GearModifierScreen() { - super(new TranslatableComponent("vhatcaniroll.screen.title"), ScreenRenderers.getBuffered(), ScreenTooltipRenderer::create); - + super(new TextComponent("VHat can I roll?"), ScreenRenderers.getBuffered(), ScreenTooltipRenderer::create); // make screen size 95% of the window height and width that looks good this.setGuiSize(Spatials.size(340, 300).height((int) ( (Minecraft.getInstance().getWindow().getHeight() / Minecraft.getInstance().getWindow().getGuiScale()) * @@ -66,10 +68,10 @@ public class GearModifierScreen extends AbstractElementScreen { // window title LabelElement windowName = new LabelElement<>( Spatials.positionXY(7, 38).size(this.getGuiSpatial().width() / 2 - 7, 20), - this.title.copy().withStyle(ChatFormatting.BLACK), + new TranslatableComponent("vhatcaniroll.screen.title.random").withStyle(ChatFormatting.BLACK), LabelTextStyle.defaultStyle() ).layout(this.translateWorldSpatial()); - + this.windowName = windowName; this.addElement(background); this.addElement(windowName); @@ -84,13 +86,17 @@ public class GearModifierScreen extends AbstractElementScreen { // inner black window ISpatial modListSpatial = Spatials.positionXY(7, 50).size(this.getGuiSpatial().width() - 14, this.getGuiSpatial().height() - 57); - this.modifierList = new ModifierListContainer(modListSpatial, lvlInput.getValue(), modifierCategory, getCurrGear()).layout(this.translateWorldSpatial()); - this.addElement(this.modifierList); + this.innerScreen = new ModifierListContainer(modListSpatial, lvlInput.getValue(), modifierCategory, getCurrGear()).layout(this.translateWorldSpatial()); + this.addElement(this.innerScreen); // help container will overlay the modifier list this.helpContainer = new HelpContainer(Spatials.positionXY(0, 0).size(0, 0)); createHelpButton(helpContainer); this.addElement(helpContainer); + + createModifierButton(); + createTransmogButton(); + createCraftedModsButton(); } // helper methods @@ -104,21 +110,57 @@ public class GearModifierScreen extends AbstractElementScreen { * @param keepScroll whether to keep the current scroll position */ private void updateModifierList(boolean keepScroll) { - var oldScroll = this.modifierList.getScroll(); - - this.removeElement(this.modifierList); + var oldScroll = this.innerScreen.getScroll(); + this.removeElement(this.innerScreen); ISpatial modListSpatial = Spatials.positionXY(7, 50).size(this.getGuiSpatial().width() - 14, this.getGuiSpatial().height() - 57); - this.modifierList = new ModifierListContainer(modListSpatial, lvlInput.getValue(), modifierCategory, getCurrGear()).layout(this.translateWorldSpatial()); - - if (keepScroll) { - this.modifierList.setScroll(oldScroll); + this.innerScreen = this.innerScreen.create(modListSpatial, lvlInput.getValue(), modifierCategory, getCurrGear()); + if (this.innerScreen instanceof ILayoutElement layoutElement) { + layoutElement.layout(this.translateWorldSpatial()); } - this.addElement(this.modifierList); + if (keepScroll) { + this.innerScreen.setScroll(oldScroll); + } + + this.addElement(this.innerScreen); ScreenLayout.requestLayout(); } + private void switchToTransmog(){ + this.removeElement(this.innerScreen); + this.modifierCategory = ModifierCategory.NORMAL; + updateModifierCategoryButtonLabel(); + ISpatial modListSpatial = Spatials.positionXY(7, 50).size(this.getGuiSpatial().width() - 14, this.getGuiSpatial().height() - 57); + this.innerScreen = new TransmogListContainer(modListSpatial, getCurrGear()).layout(this.translateWorldSpatial()); + this.modifierCategoryButton.setDisabled(true); + this.windowName.set(new TranslatableComponent("vhatcaniroll.screen.title.transmogs").withStyle(ChatFormatting.BLACK)); + this.addElement(this.innerScreen); + ScreenLayout.requestLayout(); + } + + private void switchToModifiers(){ + this.removeElement(this.innerScreen); + ISpatial modListSpatial = Spatials.positionXY(7, 50).size(this.getGuiSpatial().width() - 14, this.getGuiSpatial().height() - 57); + this.innerScreen = new ModifierListContainer(modListSpatial, lvlInput.getValue(), modifierCategory, getCurrGear()).layout(this.translateWorldSpatial()); + this.modifierCategoryButton.setDisabled(false); + this.windowName.set(new TranslatableComponent("vhatcaniroll.screen.title.random").withStyle(ChatFormatting.BLACK)); + this.addElement(this.innerScreen); + ScreenLayout.requestLayout(); + } + + private void switchToCrafted(){ + this.removeElement(this.innerScreen); + this.modifierCategory = ModifierCategory.NORMAL; + updateModifierCategoryButtonLabel(); + ISpatial modListSpatial = Spatials.positionXY(7, 50).size(this.getGuiSpatial().width() - 14, this.getGuiSpatial().height() - 57); + this.innerScreen = new CraftedModifiersListContainer(modListSpatial, lvlInput.getValue(), modifierCategory, getCurrGear()).layout(this.translateWorldSpatial()); + this.modifierCategoryButton.setDisabled(true); + this.windowName.set(new TranslatableComponent("vhatcaniroll.screen.title.crafted").withStyle(ChatFormatting.BLACK)); + this.addElement(this.innerScreen); + ScreenLayout.requestLayout(); + } + // pulled from QuestOverviewElementScreen private ILayoutStrategy translateWorldSpatial() { return (screen, gui, parent, world) -> world.translateXY(this.getGuiSpatial()); @@ -236,12 +278,14 @@ public class GearModifierScreen extends AbstractElementScreen { } private void nextModifierCategory() { + if (!(this.innerScreen instanceof ModifierListContainer)) return; this.modifierCategory = modifierCategory.next(); updateModifierCategoryButtonLabel(); updateModifierList(true); } private void previousModifierCategory() { + if (!(this.innerScreen instanceof ModifierListContainer)) return; this.modifierCategory = modifierCategory.previous(); updateModifierCategoryButtonLabel(); updateModifierList(true); @@ -269,6 +313,7 @@ public class GearModifierScreen extends AbstractElementScreen { } }).layout(this.translateWorldSpatial()); this.addElement(btnLegend); + this.modifierCategoryButton = btnLegend; } private void createConfigButton(){ @@ -294,6 +339,39 @@ public class GearModifierScreen extends AbstractElementScreen { ); } + private void createModifierButton() { + this.addElement(new ButtonElement<>(Spatials.positionXY(-3, 3), ScreenTextures.BUTTON_QUEST_TEXTURES, () -> { + if (!(this.innerScreen instanceof ModifierListContainer)) + switchToModifiers(); + })).layout((screen, gui, parent, world) -> { + world.width(21).height(21).translateX(gui.left() - 18).translateY(this.getGuiSpatial().bottom() - 120); + }).tooltip( + Tooltips.single(TooltipDirection.LEFT, () -> new TextComponent("Random Modifiers")) + ); + } + + private void createTransmogButton() { + this.addElement(new ButtonElement<>(Spatials.positionXY(-3, 3), ScreenTextures.BUTTON_QUEST_TEXTURES, () -> { + if (!(this.innerScreen instanceof TransmogListContainer)) + switchToTransmog(); + })).layout((screen, gui, parent, world) -> { + world.width(21).height(21).translateX(gui.left() - 18).translateY(this.getGuiSpatial().bottom() - 72); + }).tooltip( + Tooltips.single(TooltipDirection.LEFT, () -> new TextComponent("Transmogs")) + ); + } + + private void createCraftedModsButton() { + this.addElement(new ButtonElement<>(Spatials.positionXY(-3, 3), ScreenTextures.BUTTON_QUEST_TEXTURES, () -> { + if (!(this.innerScreen instanceof CraftedModifiersListContainer)) + switchToCrafted(); + })).layout((screen, gui, parent, world) -> { + world.width(21).height(21).translateX(gui.left() - 18).translateY(this.getGuiSpatial().bottom() - 96); + }).tooltip( + Tooltips.single(TooltipDirection.LEFT, () -> new TextComponent("Crafted Modifiers")) + ); + } + @Override public boolean keyPressed(int keyCode, int scanCode, int modifiers) { // left/right to increase/decrease lvl @@ -305,10 +383,14 @@ public class GearModifierScreen extends AbstractElementScreen { } // up/down to scroll up/down if (keyCode == InputConstants.KEY_K || keyCode == InputConstants.KEY_UP) { - this.modifierList.onMouseScrolled(0, 0, 1); + if (this.innerScreen instanceof VerticalScrollClipContainer vsc){ + vsc.onMouseScrolled(0,0,1); + } } if (keyCode == InputConstants.KEY_J || keyCode == InputConstants.KEY_DOWN) { - this.modifierList.onMouseScrolled(0, 0, -1); + if (this.innerScreen instanceof VerticalScrollClipContainer vsc){ + vsc.onMouseScrolled(0,0,-1); + } } // tab to next gear item if (keyCode == InputConstants.KEY_TAB && !hasShiftDown()) { diff --git a/src/main/java/com/radimous/vhatcaniroll/ui/InnerGearScreen.java b/src/main/java/com/radimous/vhatcaniroll/ui/InnerGearScreen.java new file mode 100644 index 0000000..9d08628 --- /dev/null +++ b/src/main/java/com/radimous/vhatcaniroll/ui/InnerGearScreen.java @@ -0,0 +1,12 @@ +package com.radimous.vhatcaniroll.ui; + +import com.radimous.vhatcaniroll.logic.ModifierCategory; +import iskallia.vault.client.gui.framework.element.spi.IElement; +import iskallia.vault.client.gui.framework.spatial.spi.ISpatial; +import net.minecraft.world.item.ItemStack; + +public interface InnerGearScreen extends IElement { + float getScroll(); + void setScroll(float scroll); + InnerGearScreen create(ISpatial spatial, int lvl, ModifierCategory modifierCategory, ItemStack gearPiece); +} diff --git a/src/main/java/com/radimous/vhatcaniroll/ui/ModifierListContainer.java b/src/main/java/com/radimous/vhatcaniroll/ui/ModifierListContainer.java index 21e512a..fc02989 100644 --- a/src/main/java/com/radimous/vhatcaniroll/ui/ModifierListContainer.java +++ b/src/main/java/com/radimous/vhatcaniroll/ui/ModifierListContainer.java @@ -17,7 +17,7 @@ import java.util.Optional; import com.radimous.vhatcaniroll.logic.Modifiers; -public class ModifierListContainer extends VerticalScrollClipContainer { +public class ModifierListContainer extends VerticalScrollClipContainer implements InnerGearScreen { public ModifierListContainer(ISpatial spatial, int lvl, ModifierCategory modifierCategory, ItemStack gearPiece) { super(spatial, Padding.ZERO, ScreenTextures.INSET_BLACK_BACKGROUND); @@ -69,4 +69,9 @@ public class ModifierListContainer extends VerticalScrollClipContainer implements InnerGearScreen { + + public TransmogListContainer(ISpatial spatial, ItemStack gearPiece) { + super(spatial, Padding.ZERO, ScreenTextures.INSET_BLACK_BACKGROUND); + int labelX = 9; + int labelY = 0; + + var player = Minecraft.getInstance().player; + if (player == null) { + return; + } + var discoveredModelIds = ClientDiscoveredEntriesData.Models.getDiscoveredModels(); + var discoveredModelObserverIds = ClientDiscoveredEntriesData.Models.getObserverModels(); + var model =new DiscoveredModelSelectElement.DiscoveredModelSelectorModel( + ObservableSupplier.of(() -> gearPiece, SideOnlyFixer::stackEqualExact), discoveredModelObserverIds, x -> {}); + var mEntries = model.getEntries(); + for (var x : mEntries) { + ItemStack displayStack = new ItemStack(gearPiece.getItem()); + VaultGearData gearData = VaultGearData.read(displayStack); + gearData.setState(VaultGearState.IDENTIFIED); + gearData.createOrReplaceAttributeValue(ModGearAttributes.GEAR_MODEL, x.getModelId()); + gearData.write(displayStack); + this.addElement(new FakeItemSlotElement<>(Spatials.positionXY(labelX, labelY).width(16).height(16), () -> displayStack, () -> false, ScreenTextures.EMPTY, ScreenTextures.EMPTY)); + var oMod = ModDynamicModels.REGISTRIES.getModel(gearPiece.getItem(), x.getModelId()); + if (oMod.isPresent()) { + var mod = oMod.get(); + VaultGearRarity rollRarity = ModConfigs.GEAR_MODEL_ROLL_RARITIES.getRarityOf(gearPiece, mod.getId()); + this.addElement(new LabelElement<>( + Spatials.positionXY(labelX + 20, labelY + 6).width(this.innerWidth() - labelX).height(15), + new TextComponent(mod.getDisplayName()).withStyle(Style.EMPTY.withColor(rollRarity.getColor().getValue())), LabelTextStyle.defaultStyle())); + + NineSliceButtonElement btn = new NineSliceButtonElement<>(Spatials.positionXY(0, labelY ).width(innerWidth()).height(18), + new NineSliceButtonElement.NineSliceButtonTextures(BUTTON_EMPTY, BUTTON_EMPTY, BUTTON_EMPTY, BUTTON_EMPTY_DISABLED), () -> {}); + var canTransmog = TransmogTableBlock.canTransmogModel(player, discoveredModelIds, x.getModelId()); + btn.setDisabled(!canTransmog); + this.addElement(btn); + + + } + + labelY += 18; + } + + } + public float getScroll() { + return this.verticalScrollBarElement.getValue(); + } + + public void setScroll(float scroll) { + this.verticalScrollBarElement.setValue(scroll); + } + + @Override + public InnerGearScreen create(ISpatial spatial, int lvl, ModifierCategory modifierCategory, ItemStack gearPiece) { + return new TransmogListContainer(spatial, gearPiece); + } +} \ No newline at end of file diff --git a/src/main/resources/assets/vhatcaniroll/lang/en_us.json b/src/main/resources/assets/vhatcaniroll/lang/en_us.json index b382d27..c243b93 100644 --- a/src/main/resources/assets/vhatcaniroll/lang/en_us.json +++ b/src/main/resources/assets/vhatcaniroll/lang/en_us.json @@ -1,5 +1,7 @@ { - "vhatcaniroll.screen.title": "Gear Modifiers", + "vhatcaniroll.screen.title.random": "Random Modifiers", + "vhatcaniroll.screen.title.crafted": "Crafted Modifiers", + "vhatcaniroll.screen.title.transmogs": "Transmogs", "vhatcaniroll.openmodscreen": "Open VHat can I roll? screen", "key.categories.vhatcaniroll": "VHat can I roll?" }