-
-
Notifications
You must be signed in to change notification settings - Fork 189
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature: Armor Stack Decay Timer #2538
base: beta
Are you sure you want to change the base?
Changes from all commits
5279029
ed1baf4
245e8f6
5413084
ee6ad2c
507670c
cdae1a9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
package at.hannibal2.skyhanni.config.features.combat; | ||
|
||
import at.hannibal2.skyhanni.config.FeatureToggle; | ||
import at.hannibal2.skyhanni.config.core.config.Position; | ||
import com.google.gson.annotations.Expose; | ||
import io.github.notenoughupdates.moulconfig.annotations.ConfigEditorBoolean; | ||
import io.github.notenoughupdates.moulconfig.annotations.ConfigLink; | ||
import io.github.notenoughupdates.moulconfig.annotations.ConfigOption; | ||
|
||
public class ArmorStackDisplayConfig { | ||
@Expose | ||
@ConfigOption(name = "Enable", desc = "Enable the armor stack display feature.") | ||
@ConfigEditorBoolean | ||
@FeatureToggle | ||
public boolean enabled = true; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. please make this default diabled |
||
|
||
@Expose | ||
@ConfigOption(name = "Single Line Display", desc = "Show the overlay in a single line.") | ||
@ConfigEditorBoolean | ||
@FeatureToggle | ||
public boolean showInSingleLine = true; | ||
|
||
@Expose | ||
@ConfigOption(name = "Show Armor Stack", desc = "Display the current number of stacks for armors, such as Crimson, Terror, Aurora, etc.") | ||
@ConfigEditorBoolean | ||
@FeatureToggle | ||
public boolean armorStackDisplay = true; | ||
|
||
@Expose | ||
@ConfigOption(name = "Show Armor Stack Type", desc = "Display the type of armor stack, such as 'Dominus', 'Hydra Strike', etc.") | ||
@ConfigEditorBoolean | ||
@FeatureToggle | ||
public boolean armorStackType = false; | ||
|
||
@Expose | ||
@ConfigOption(name = "Show Stack Decay Timer", desc = "Display a timer that shows when the armor stack will decay.") | ||
@ConfigEditorBoolean | ||
@FeatureToggle | ||
public boolean armorStackDecayTimer = true; | ||
|
||
@Expose | ||
@ConfigOption(name = "Max Stack Only", desc = "Display the decay timer only for the 10th stack.") | ||
@ConfigEditorBoolean | ||
@FeatureToggle | ||
public boolean maxStackOnly = false; | ||
|
||
@Expose | ||
@ConfigLink(owner = ArmorStackDisplayConfig.class, field = "enabled") | ||
public Position position = new Position(50, -210, 1.4f); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -26,10 +26,9 @@ public class CombatConfig { | |
public QuiverConfig quiverConfig = new QuiverConfig(); | ||
|
||
@Expose | ||
@ConfigOption(name = "Armor Stack Display", desc = "") | ||
@ConfigOption(name = "Armor Stack", desc = "") | ||
@Accordion | ||
// TODO rename to armor stack display | ||
public StackDisplayConfig stackDisplayConfig = new StackDisplayConfig(); | ||
public ArmorStackDisplayConfig armorStackDisplayConfig = new ArmorStackDisplayConfig(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. please remove the suffix "Config" from the variable name (not the class name) |
||
|
||
@Expose | ||
@ConfigOption(name = "Summonings", desc = "") | ||
|
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,40 +3,162 @@ package at.hannibal2.skyhanni.features.combat | |
import at.hannibal2.skyhanni.SkyHanniMod | ||
import at.hannibal2.skyhanni.events.ActionBarUpdateEvent | ||
import at.hannibal2.skyhanni.events.GuiRenderEvent | ||
import at.hannibal2.skyhanni.events.LorenzTickEvent | ||
import at.hannibal2.skyhanni.events.LorenzWorldChangeEvent | ||
import at.hannibal2.skyhanni.events.PlaySoundEvent | ||
import at.hannibal2.skyhanni.skyhannimodule.SkyHanniModule | ||
import at.hannibal2.skyhanni.utils.InventoryUtils | ||
import at.hannibal2.skyhanni.utils.ItemUtils.getLore | ||
import at.hannibal2.skyhanni.utils.LorenzUtils | ||
import at.hannibal2.skyhanni.utils.RegexUtils.findMatcher | ||
import at.hannibal2.skyhanni.utils.RenderUtils.renderString | ||
import at.hannibal2.skyhanni.utils.RenderUtils.renderStrings | ||
import at.hannibal2.skyhanni.utils.SimpleTimeMark | ||
import at.hannibal2.skyhanni.utils.TimeUtils.format | ||
import at.hannibal2.skyhanni.utils.repopatterns.RepoPattern | ||
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent | ||
import kotlin.time.Duration.Companion.milliseconds | ||
|
||
@SkyHanniModule | ||
object ArmorStackDisplay { | ||
private val config get() = SkyHanniMod.feature.combat.stackDisplayConfig | ||
private var display = "" | ||
private val config get() = SkyHanniMod.feature.combat.armorStackDisplayConfig | ||
private var stackCount = 0 | ||
private var stackSymbol = "" | ||
private var stackType = "" | ||
private var armorPieceCount = 0 | ||
private var display = listOf<String>() | ||
private var stackDecayTimeCurrent = SimpleTimeMark.farPast() | ||
|
||
/** | ||
* REGEX-TEST: §66,171/4,422❤ §6§l10ᝐ§r §a1,295§a❈ Defense §b525/1,355✎ §3400ʬ | ||
* REGEX-TEST: §66,171/4,422❤ §65ᝐ §b-150 Mana (§6Wither Impact§b) §b1,016/1,355✎ §3400ʬ | ||
*/ | ||
private val armorStackPattern by RepoPattern.pattern( | ||
private val stackPattern by RepoPattern.pattern( | ||
"combat.armorstack.actionbar", | ||
" (?:§6|§6§l)(?<stack>\\d+[ᝐ⁑|҉Ѫ⚶])" | ||
" (?:§6|§6§l)(?<stack>\\d+)(?<symbol>[ᝐ⁑|҉Ѫ⚶])", | ||
) | ||
|
||
/** | ||
* REGEX-TEST: §7Health: §a+205, §7Defense: §a+55, §7Intelligence: §a+125, §7Combat Wisdom: §a+0.75, §8[§8⚔§8] §8[§8⚔§8], , §bArachno Resistance II, §7Grants §a+3❈ Defense §7against §aspiders§7., §bVeteran I, §7Grants §3+0.75☯ Combat Wisdom§7., , §6Tiered Bonus: Arcane Vision (2/4), §7Gives you the ability to see the runic, §7affinity of enemies., §7, §7Using the proper §bRune §7when casting spells, §7from §bRunic Items §7grants 1 stack of §6Arcane, §6Vision Ѫ§7., §7, §7Each §6Arcane Vision Ѫ §7stack grants you §c+2%, §c§7damage on your §bRunic Spells§7., §7, §7At §c10 §7stacks, the spells also explode on hit., §7, §7Lose 1 stack after §c4s §7of not gaining a stack., , §7§8This item can be reforged!, §6§lLEGENDARY LEGGINGS | ||
*/ | ||
private val armorStackTierBonus by RepoPattern.pattern( | ||
"combat.armorstack.armor", | ||
"§6Tiered Bonus: (?<type>.*) \\((?<amount>\\d)\\/4\\)" | ||
) | ||
|
||
@SubscribeEvent | ||
fun onActionBar(event: ActionBarUpdateEvent) { | ||
if (!isEnabled()) return | ||
val stacks = armorStackPattern.findMatcher(event.actionBar) { | ||
"§6§l" + group("stack") | ||
} ?: "" | ||
display = stacks | ||
|
||
stackPattern.findMatcher(event.actionBar) { | ||
updateStack(group("stack").toInt(), group("symbol")) | ||
} ?: resetStack() | ||
|
||
if (config.armorStackDisplay) event.changeActionBar(event.actionBar.replace(Regex("$stackPattern"), "").trim()) | ||
} | ||
|
||
@SubscribeEvent | ||
fun onPlaySound(event: PlaySoundEvent) { | ||
if (!isEnabled() && !config.armorStackDecayTimer) return | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i think the AND here is wrong, a OR makes more sense to me |
||
if (event.soundName in listOf("tile.piston.out", "tile.piston.in") && | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. please move the list into a member of the class so that we dont need to recreate it each time There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. additionally, a set is probably better than a list here? |
||
event.pitch == 1.0f && event.volume == 3.0f) { | ||
resetDecayTime() | ||
} | ||
} | ||
|
||
@SubscribeEvent | ||
fun onWorldChange(event: LorenzWorldChangeEvent) { | ||
if (!isEnabled()) return | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the check here can go |
||
resetStack() | ||
} | ||
|
||
@SubscribeEvent | ||
fun onRenderOverlay(event: GuiRenderEvent.GuiOverlayRenderEvent) { | ||
if (isEnabled()) { | ||
config.position.renderStrings(display, posLabel = "Armor Stack Display") | ||
} | ||
} | ||
|
||
@SubscribeEvent | ||
fun onTick(event: LorenzTickEvent) { | ||
if (!isEnabled()) return | ||
config.position.renderString(display, posLabel = "Armor Stack Display") | ||
display = drawDisplay() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. please add a check so that this only happens every second tick (10 times a second, not 20 times a second). Can be done via |
||
} | ||
|
||
private fun drawDisplay(): List<String> { | ||
if (stackCount == 0 || armorPieceCount < 3) return emptyList() | ||
val displaySingleLine = config.showInSingleLine | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the config variables here can all be removed/inlined (not the isMaxStack one) |
||
val showStack = config.armorStackDisplay | ||
val showTimer = config.armorStackDecayTimer | ||
val maxStackOnly = config.maxStackOnly | ||
val isMaxStack = stackCount == 10 | ||
|
||
val decayTimeString = if (showTimer) { | ||
val remainingTime = stackDecayTimeCurrent.timeUntil().coerceAtLeast(0.milliseconds) | ||
remainingTime.format(showMilliSeconds = true, showSmallerUnits = true) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Im not enitrely sure, but i think |
||
} else "" | ||
|
||
val colorCode = when { | ||
isMaxStack && maxStackOnly -> "§b" | ||
isMaxStack -> "§9" | ||
else -> "§b" | ||
} | ||
|
||
if (displaySingleLine) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. you can move the two returns below to this if block directly |
||
return listOf(buildString { | ||
if (showStack) { | ||
append("§6") | ||
if (config.armorStackType) append("$stackType: ") | ||
append("§l$stackCount$stackSymbol ") | ||
} | ||
|
||
if (showTimer && (!maxStackOnly || isMaxStack)) { | ||
append("$colorCode($decayTimeString)") | ||
|
||
} | ||
}) | ||
} else { | ||
return buildList { | ||
if (showStack) { | ||
add(buildString { | ||
append("§6") | ||
if (config.armorStackType) append("$stackType: ") | ||
append("§l$stackCount$stackSymbol ") | ||
}) | ||
} | ||
|
||
if (showTimer && (!maxStackOnly || isMaxStack)) { | ||
add("$colorCode$decayTimeString") | ||
} | ||
} | ||
} | ||
} | ||
|
||
private fun resetDecayTime() { | ||
armorPieceCount = InventoryUtils.getArmor().firstNotNullOfOrNull { armor -> | ||
val lore = armor?.getLore().toString() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I dont like the |
||
armorStackTierBonus.findMatcher(lore) { stackType = group("type"); group("amount") } | ||
?.toInt() | ||
} ?: 0 | ||
|
||
|
||
val stackDecayTime = when (armorPieceCount) { | ||
2 -> 4000 | ||
3 -> 7000 | ||
4 -> 10000 | ||
else -> 0 | ||
}.milliseconds | ||
stackDecayTimeCurrent = SimpleTimeMark.now() + stackDecayTime | ||
} | ||
|
||
private fun resetStack() { | ||
stackCount = 0 | ||
stackSymbol = "" | ||
} | ||
|
||
private fun updateStack(newStackCount: Int, newStackSymbol: String) { | ||
if (stackCount != newStackCount && config.armorStackDecayTimer) resetDecayTime() | ||
stackCount = newStackCount | ||
stackSymbol = newStackSymbol | ||
} | ||
|
||
fun isEnabled() = LorenzUtils.inSkyBlock && config.enabled | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please explain a bit more what this feature does. (include crimson armor names maybe, or their ability names)