1.1 - legendary support, support range display for effects, add config to show +ability lvl separately

This commit is contained in:
radimous 2024-09-24 08:04:23 +02:00
parent 3033e586fe
commit 26ef291de4
9 changed files with 196 additions and 35 deletions

View file

@ -184,6 +184,9 @@ dependencies {
implementation fg.deobf("curse.maven:quark-243121:3840125")
implementation fg.deobf("curse.maven:architects-palette-433862:4498424")
implementation fg.deobf("curse.maven:geckolib-388172:4181370")
implementation fg.deobf("curse.maven:cofh-core-69162:4801048") // wold plushie effects
implementation fg.deobf("curse.maven:alexs-mobs-426558:3853078") // wold plushie effects
implementation fg.deobf("curse.maven:citadel-331936:3783096") // alex mobs dep
//faster loading
implementation fg.deobf("curse.maven:lazydfu-433518:3209972")

View file

@ -38,7 +38,7 @@ mod_name=VHat Can I Roll?
# The license of the mod. Review your options at https://choosealicense.com/. All Rights Reserved is the default.
mod_license=GNU LGPL 3.0
# The mod version. See https://semver.org/
mod_version=1.0
mod_version=1.1
# The group ID for the mod. It is only important when publishing as an artifact to a Maven repository.
# This should match the base package used for the mod sources.
# See https://maven.apache.org/guides/mini/guide-naming-conventions.html

View file

@ -6,12 +6,28 @@ public class Config {
public static final ForgeConfigSpec SPEC;
public static final ForgeConfigSpec.BooleanValue VAULT_SCREEN_BUTTON;
public static final ForgeConfigSpec.BooleanValue ALLOW_DUPE;
public static final ForgeConfigSpec.IntValue BUTTON_X;
public static final ForgeConfigSpec.IntValue BUTTON_Y;
public static final ForgeConfigSpec.BooleanValue COMBINE_LVL_TO_ABILITIES;
static {
ForgeConfigSpec.Builder builder = new ForgeConfigSpec.Builder();
COMBINE_LVL_TO_ABILITIES = builder
.comment("combine +lvl to abilities into one row")
.define("combineLvlToAbilities", true);
builder.push("BUTTON");
VAULT_SCREEN_BUTTON = builder
.comment("open VHat can I roll? from vault screen")
.define("vaultScreenButton", true);
BUTTON_X = builder
.comment("x position of the button")
.defineInRange("buttonPositionX", 5, Integer.MIN_VALUE, Integer.MAX_VALUE);
BUTTON_Y = builder
.comment("y position of the button")
.defineInRange("buttonPositionY", 109, Integer.MIN_VALUE, Integer.MAX_VALUE);
builder.pop();
builder.push("DEBUG");
ALLOW_DUPE = builder

View file

@ -31,10 +31,11 @@ import java.util.List;
public class GearModifierScreen extends AbstractElementScreen {
//TODO: code cleanup - variable naming, magic numbers, some logic reordering etc
//TODO: legendary modifiers
private ModifierListContainer modifierList;
private final TextInputElement<?> lvlInput;
private boolean legendary;
private LabelElement<?> legendaryLabel;
private int currIndex = 0;
private final List<TabElement<?>> tabs = new ArrayList<>();
@ -68,6 +69,7 @@ public class GearModifierScreen extends AbstractElementScreen {
this.lvlInput = this.addElement(createLvlInput());
createLvlButtons();
createLegendaryButton();
// inner black window
this.modifierList = new ModifierListContainer(
@ -97,12 +99,16 @@ public class GearModifierScreen extends AbstractElementScreen {
this.lvlInput.setInput(String.valueOf(this.getCurrLvl() - 1));
}
private void updateModifierList() {
private void updateModifierList(boolean keepScroll) {
var oldScroll = this.modifierList.getScroll();
this.removeElement(this.modifierList);
this.modifierList = new ModifierListContainer(
Spatials.positionXY(7, 50).size(this.getGuiSpatial().width() - 14, this.getGuiSpatial().height() - 57),
this)
.layout(this.translateWorldSpatial());
if (keepScroll) {
this.modifierList.setScroll(oldScroll);
}
this.addElement(this.modifierList);
ScreenLayout.requestLayout();
@ -149,7 +155,7 @@ public class GearModifierScreen extends AbstractElementScreen {
this.addElement(tab);
}
this.currIndex = tabIndex;
updateModifierList();
updateModifierList(false);
}
private TextInputElement<?> createLvlInput() {
@ -163,7 +169,7 @@ public class GearModifierScreen extends AbstractElementScreen {
editBox.setMaxLength(3);
editBox.setValue(String.valueOf(VaultBarOverlay.vaultLevel));
});
inputElement.onTextChanged(s -> updateModifierList());
inputElement.onTextChanged(s -> updateModifierList(true));
return inputElement;
}
@ -206,6 +212,31 @@ public class GearModifierScreen extends AbstractElementScreen {
this.addElement(btnPlus);
}
private void toggleLegend() {
this.legendary = !this.legendary;
updateLegendaryLabel();
updateModifierList(true);
}
private void updateLegendaryLabel() {
if (this.legendaryLabel != null) {
this.removeElement(this.legendaryLabel);
}
var formatting = this.legendary ? ChatFormatting.GOLD : ChatFormatting.WHITE;
this.legendaryLabel = new LabelElement<>(Spatials.positionXY(this.getGuiSpatial().width() - 5 - 13, 38),
new TextComponent("").withStyle(formatting), LabelTextStyle.defaultStyle())
.layout(this.translateWorldSpatial());
this.addElement(legendaryLabel);
}
private void createLegendaryButton() {
updateLegendaryLabel();
NineSliceButtonElement<?> btnLegend =
new NineSliceButtonElement<>(Spatials.positionXY(this.getGuiSpatial().width() - 8 - 13, 35).size(14, 14),
ScreenTextures.BUTTON_EMPTY_TEXTURES, this::toggleLegend).layout(this.translateWorldSpatial());
this.addElement(btnLegend);
}
private void createTabs() {
for (int i = 0; i < VHatCanIRoll.getVaultGearItems().size(); i++) {
addTab(i);
@ -226,6 +257,10 @@ public class GearModifierScreen extends AbstractElementScreen {
this.translateWorldSpatial()));
}
public boolean isLegendary() {
return legendary;
}
@Override
public boolean keyPressed(int keyCode, int scanCode, int modifiers) {
// left/right to increase/decrease lvl
@ -250,6 +285,10 @@ public class GearModifierScreen extends AbstractElementScreen {
if (keyCode == InputConstants.KEY_TAB && hasShiftDown()) {
switchTab((currIndex - 1 + VHatCanIRoll.getVaultGearItems().size()) % VHatCanIRoll.getVaultGearItems().size());
}
// alt to toggle legendary
if (keyCode == InputConstants.KEY_LALT || keyCode == InputConstants.KEY_RALT) {
toggleLegend();
}
return super.keyPressed(keyCode, scanCode, modifiers);
}
}

View file

@ -1,11 +1,16 @@
package com.radimous.vhatcaniroll;
import com.radimous.vhatcaniroll.mixin.EffectConfigAccessor;
import com.radimous.vhatcaniroll.mixin.VaultGearTierConfigAccessor;
import iskallia.vault.config.gear.VaultGearTierConfig;
import iskallia.vault.gear.attribute.VaultGearAttribute;
import iskallia.vault.gear.attribute.VaultGearAttributeRegistry;
import iskallia.vault.gear.attribute.ability.AbilityLevelAttribute;
import iskallia.vault.gear.attribute.ability.special.base.SpecialAbilityModification;
import iskallia.vault.gear.attribute.config.BooleanFlagGenerator;
import iskallia.vault.gear.attribute.config.ConfigurableAttributeGenerator;
import iskallia.vault.gear.attribute.custom.EffectGearAttribute;
import iskallia.vault.init.ModConfigs;
import iskallia.vault.util.TextComponentUtils;
import net.minecraft.ChatFormatting;
import net.minecraft.network.chat.Component;
@ -27,19 +32,19 @@ public class Helper {
new ChatFormatting[]{ChatFormatting.RED, ChatFormatting.GREEN, ChatFormatting.BLUE, ChatFormatting.YELLOW,
ChatFormatting.LIGHT_PURPLE, ChatFormatting.AQUA, ChatFormatting.WHITE};
public static List<Component> getModifierList(int lvl, VaultGearTierConfig cfg) {
public static List<Component> getModifierList(int lvl, VaultGearTierConfig cfg, boolean legendary) {
Map<VaultGearTierConfig.ModifierAffixTagGroup, VaultGearTierConfig.AttributeGroup> modifierGroup =
((VaultGearTierConfigAccessor) cfg).getModifierGroup();
ArrayList<Component> modList = new ArrayList<>();
for (VaultGearTierConfig.ModifierAffixTagGroup affixTagGroup : modifierGroup.keySet()) {
processAffixTagGroup(lvl, affixTagGroup, modifierGroup, modList);
processAffixTagGroup(lvl, affixTagGroup, modifierGroup, modList, legendary);
}
return modList;
}
private static void processAffixTagGroup(int lvl, VaultGearTierConfig.ModifierAffixTagGroup affixTagGroup,
Map<VaultGearTierConfig.ModifierAffixTagGroup, VaultGearTierConfig.AttributeGroup> modifierGroup,
ArrayList<Component> modList) {
ArrayList<Component> modList, boolean legendary) {
if (affixTagGroup.equals(VaultGearTierConfig.ModifierAffixTagGroup.ABILITY_ENHANCEMENT)) {
return;
}
@ -48,11 +53,17 @@ public class Helper {
}
modList.add(new TextComponent(affixTagGroup.toString().replace("_", " ")).withStyle(ChatFormatting.BOLD));
Map<String, Integer> groupCounts = countGroups(lvl, affixTagGroup, modifierGroup);
Map<String, Integer> groupCounts = countGroups(lvl, affixTagGroup, modifierGroup, legendary);
List<String> grList = new ArrayList<>();
for (VaultGearTierConfig.ModifierTierGroup modifierTierGroup : modifierGroup.get(affixTagGroup)) {
ArrayList<VaultGearTierConfig.ModifierTier<?>> mTierList = getModifierTiers(lvl, modifierTierGroup);
ArrayList<VaultGearTierConfig.ModifierTier<?>> mTierList;
if (legendary) {
mTierList = getLegendaryModifierTiers(lvl, modifierTierGroup);
} else {
mTierList = getModifierTiers(lvl, modifierTierGroup);
}
if (mTierList.isEmpty()) {
continue;
}
@ -80,10 +91,16 @@ public class Helper {
}
private static Map<String, Integer> countGroups(int lvl, VaultGearTierConfig.ModifierAffixTagGroup affixTagGroup,
Map<VaultGearTierConfig.ModifierAffixTagGroup, VaultGearTierConfig.AttributeGroup> modifierGroup) {
Map<VaultGearTierConfig.ModifierAffixTagGroup, VaultGearTierConfig.AttributeGroup> modifierGroup,
boolean legendary) {
Map<String, Integer> groupCounts = new HashMap<>();
for (VaultGearTierConfig.ModifierTierGroup modifierTierGroup : modifierGroup.get(affixTagGroup)) {
ArrayList<VaultGearTierConfig.ModifierTier<?>> mTierList = getModifierTiers(lvl, modifierTierGroup);
ArrayList<VaultGearTierConfig.ModifierTier<?>> mTierList;
if (legendary) {
mTierList = getLegendaryModifierTiers(lvl, modifierTierGroup);
} else {
mTierList = getModifierTiers(lvl, modifierTierGroup);
}
if (mTierList.isEmpty()) {
continue;
}
@ -93,6 +110,26 @@ public class Helper {
return groupCounts;
}
private static ArrayList<VaultGearTierConfig.ModifierTier<?>> getLegendaryModifierTiers(int lvl,
VaultGearTierConfig.ModifierTierGroup modifierTierGroup) {
var res = new ArrayList<VaultGearTierConfig.ModifierTier<?>>();
var highest = modifierTierGroup.getHighestForLevel(lvl);
if (highest == null) {
return res; // empty
}
int index = Math.min(highest.getModifierTier() + 2, modifierTierGroup.size() - 1);
var legendTier = modifierTierGroup.get(index);
if (legendTier == null || legendTier.getWeight() == 0){
return res; // empty
}
if (legendTier.getModifierConfiguration() instanceof BooleanFlagGenerator.BooleanFlag bf &&
!bf.get()) {
return res; // empty
}
res.add(legendTier);
return res; // only one
}
@NotNull private static ArrayList<VaultGearTierConfig.ModifierTier<?>> getModifierTiers(int lvl,
VaultGearTierConfig.ModifierTierGroup modifierTierGroup) {
return modifierTierGroup.getModifiersForLevel(lvl).stream()
@ -115,39 +152,82 @@ public class Helper {
}
C minConfig = (C) val.get(0).getModifierConfiguration();
C maxConfig = (C) val.get(val.size() - 1).getModifierConfiguration();
MutableComponent res = null;
if (val.size() > 1) {
res = atrGenerator.getConfigRangeDisplay(atr.getReader(), minConfig, maxConfig);
}
MutableComponent res;
ResourceLocation atrRegName = atr.getRegistryName();
if (atrRegName == null) {
return new TextComponent("ERR - NULL REGISTRY NAME");
}
String atrName = atrRegName.toString();
var minConfigDisplay = atrGenerator.getConfigDisplay(atr.getReader(), minConfig);
if (res == null && minConfigDisplay != null) {
var minConfigDisplay = atrGenerator.getConfigDisplay(atr.getReader(), minConfig);
var maxConfigDisplay = atrGenerator.getConfigDisplay(atr.getReader(), maxConfig);
if (val.size() > 1) {
// range
res = atrGenerator.getConfigRangeDisplay(atr.getReader(), minConfig, maxConfig);
if (res != null && minConfig instanceof AbilityLevelAttribute.Config minConfigAbility) {
return abilityLvlComponent(res, atr, minConfigAbility);
}
if (res != null && atrName.equals("the_vault:wendarr_affinity")) {
return res.append(" God Affinity").withStyle(atr.getReader().getColoredTextStyle());
}
if (atrName.equals("the_vault:effect_avoidance") && minConfigDisplay != null) {
// res -> "30% - 50%"
// single -> "30% Poison Avoidance"
// minRange -> "30%"
var single = minConfigDisplay.withStyle(atr.getReader().getColoredTextStyle());
var minRange = atrGenerator.getConfigRangeDisplay(atr.getReader(), minConfig, minConfig);
if (minRange != null && res != null) {
res.append(single.getString().replace(minRange.getString(), ""));
// res -> "30% - 50% Poison Avoidance"
}
}
if (minConfig instanceof EffectGearAttribute.Config minEffectConfig
&& maxConfig instanceof EffectGearAttribute.Config
&& maxConfigDisplay != null) {
var effectStr = ((EffectConfigAccessor)minEffectConfig).getAmplifier() + "-" +
maxConfigDisplay.getString();
return new TextComponent(effectStr).withStyle(atr.getReader().getColoredTextStyle());
}
if (res != null) {
return atr.getReader().formatConfigDisplay(LogicalSide.CLIENT, res);
}
}
if (minConfigDisplay != null) {
res = minConfigDisplay.withStyle(atr.getReader().getColoredTextStyle());
if (atrName.equals("the_vault:added_ability_level")) {
return res.append(" added ability levels").withStyle(atr.getReader().getColoredTextStyle());
if (minConfig instanceof AbilityLevelAttribute.Config minConfigAbility) {
return abilityLvlComponent(res, atr, minConfigAbility);
}
if (atrName.equals("the_vault:wendarr_affinity")) {
return TextComponentUtils.replace(TextComponentUtils.createSourceStack(LogicalSide.CLIENT), res,
"Wendarr Affinity", new TextComponent("God Affinity"))
.withStyle(atr.getReader().getColoredTextStyle());
}
if (minConfig instanceof EffectGearAttribute.Config ) {
return minConfigDisplay;
}
return res;
}
if (res != null && atrName.equals("the_vault:added_ability_level")) {
return new TextComponent("ERR - NULL DISPLAY " + atrName);
}
private static Component abilityLvlComponent(MutableComponent res, VaultGearAttribute<?> atr,
AbilityLevelAttribute.Config minConfig) {
if (Config.COMBINE_LVL_TO_ABILITIES.get()) {
return res.append(" added ability levels").withStyle(atr.getReader().getColoredTextStyle());
} else {
var abComp = new TextComponent("+").withStyle(atr.getReader().getColoredTextStyle());
var optSkill = ModConfigs.ABILITIES.getAbilityById(minConfig.getAbilityKey());
if (optSkill.isEmpty()) {
return res.append(" added ability levels").withStyle(atr.getReader().getColoredTextStyle());
}
var abName = optSkill.get().getName();
abComp.append(res);
abComp.append(" to level of ");
abComp.append(new TextComponent(abName).withStyle(SpecialAbilityModification.getAbilityStyle()));
return abComp;
}
if (res != null && atrName.equals("the_vault:wendarr_affinity")) {
return res.append(" God Affinity").withStyle(atr.getReader().getColoredTextStyle());
}
if (atrName.equals("the_vault:effect_avoidance") && minConfigDisplay != null) {
var single = minConfigDisplay.withStyle(atr.getReader().getColoredTextStyle());
res.append(single.getString().replace(minConfigDisplay.getString(), ""));
}
return atr.getReader().formatConfigDisplay(LogicalSide.CLIENT, res);
}
}

View file

@ -19,15 +19,17 @@ public class ModifierListContainer extends VerticalScrollClipContainer<ModifierL
super(spatial, Padding.ZERO, ScreenTextures.INSET_BLACK_BACKGROUND);
int i = 20;
int k = 9;
boolean legendary = parent.isLegendary();
Optional<VaultGearTierConfig> optCfg = VaultGearTierConfig.getConfig(parent.getCurrGear());
LabelElement<?> itemName = new LabelElement<>(
Spatials.positionXY(k, 5).width(this.innerWidth() - k).height(15), new TextComponent(
parent.getCurrGear().getItem().toString().toUpperCase() + " - LVL " + parent.getCurrLvl()).withStyle(ChatFormatting.UNDERLINE), LabelTextStyle.defaultStyle()
parent.getCurrGear().getItem().toString().toUpperCase() + " - LVL " + parent.getCurrLvl())
.withStyle(ChatFormatting.UNDERLINE).withStyle(legendary ? ChatFormatting.GOLD : ChatFormatting.WHITE), LabelTextStyle.defaultStyle()
);
this.addElement(itemName);
if (optCfg.isPresent()) {
VaultGearTierConfig cfg = optCfg.get();
for (var modifier : Helper.getModifierList(parent.getCurrLvl(), cfg)) {
for (var modifier : Helper.getModifierList(parent.getCurrLvl(), cfg, legendary)) {
LabelElement<?> labelelement = new LabelElement<>(
Spatials.positionXY(k, i).width(this.innerWidth() - k).height(15), modifier, LabelTextStyle.defaultStyle()
);
@ -41,6 +43,12 @@ public class ModifierListContainer extends VerticalScrollClipContainer<ModifierL
);
this.addElement(labelelement);
}
}
public float getScroll() {
return this.verticalScrollBarElement.getValue();
}
public void setScroll(float scroll) {
this.verticalScrollBarElement.setValue(scroll);
}
}

View file

@ -0,0 +1,14 @@
package com.radimous.vhatcaniroll.mixin;
import iskallia.vault.gear.attribute.custom.EffectGearAttribute;
import net.minecraft.resources.ResourceLocation;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
@Mixin(value = EffectGearAttribute.Config.class, remap = false)
public interface EffectConfigAccessor {
@Accessor
int getAmplifier();
@Accessor
ResourceLocation getEffectKey();
}

View file

@ -48,7 +48,7 @@ public class StatisticsElementContainerScreenMixin extends AbstractSkillTabEleme
Minecraft.getInstance().getSoundManager().play(SimpleSoundInstance.forUI(SoundEvents.UI_BUTTON_CLICK, 1.0F));
Minecraft.getInstance().setScreen(new GearModifierScreen());
}).layout(
(screen, gui, parent, world) -> world.width(21).height(21).translateX(gui.right() + 5).translateY(this.getTabContentSpatial().bottom() + 109)
(screen, gui, parent, world) -> world.width(21).height(21).translateX(gui.right() + Config.BUTTON_X.get()).translateY(this.getTabContentSpatial().bottom() + Config.BUTTON_Y.get())
)
.tooltip((tooltipRenderer, poseStack, mouseX, mouseY, tooltipFlag) -> {
tooltipRenderer.renderTooltip(poseStack, List.of(new TextComponent("Gear modifiers")), mouseX, mouseY, ItemStack.EMPTY, TooltipDirection.RIGHT);
@ -59,7 +59,7 @@ public class StatisticsElementContainerScreenMixin extends AbstractSkillTabEleme
this.addElement(
new FakeItemSlotElement<>(Spatials.positionXY(-3, 3), () -> new ItemStack(ModItems.CHESTPLATE), () -> false, ScreenTextures.EMPTY, ScreenTextures.EMPTY
).layout(
(screen, gui, parent, world) -> world.width(21).height(21).translateX(gui.right() + 5).translateY(this.getTabContentSpatial().bottom() + 109)
(screen, gui, parent, world) -> world.width(21).height(21).translateX(gui.right() + Config.BUTTON_X.get()).translateY(this.getTabContentSpatial().bottom() + Config.BUTTON_Y.get())
)
.tooltip((tooltipRenderer, poseStack, mouseX, mouseY, tooltipFlag) -> {
tooltipRenderer.renderTooltip(poseStack, List.of(new TextComponent("Gear modifiers")), mouseX, mouseY, ItemStack.EMPTY, TooltipDirection.RIGHT);

View file

@ -5,10 +5,11 @@
"compatibilityLevel": "JAVA_8",
"refmap": "vhatcaniroll.refmap.json",
"mixins": [
"EffectConfigAccessor"
],
"client": [
"VaultGearTierConfigAccessor",
"StatisticsElementContainerScreenMixin"
"StatisticsElementContainerScreenMixin",
"VaultGearTierConfigAccessor"
],
"injectors": {
"defaultRequire": 1