New overlay system

This commit is contained in:
Charlotte Som 2022-02-04 19:08:48 +00:00
parent 9f3ba37a23
commit e6ae1efcbc
5 changed files with 128 additions and 79 deletions

View file

@ -1,16 +1,2 @@
package codes.som.hibiscus.features
import codes.som.hibiscus.api.feature.Feature
import codes.som.hibiscus.features.combat.Criticals
import codes.som.hibiscus.features.movement.Flight
import codes.som.hibiscus.features.movement.Speed
import codes.som.hibiscus.features.overlay.FeatureListOverlay
import codes.som.hibiscus.features.player.NoFallDamage
val ALL_FEATURES: Array<() -> Feature> = arrayOf(
::NoFallDamage,
::Flight,
::FeatureListOverlay,
::Speed,
::Criticals,
)

View file

@ -1,6 +1,28 @@
package codes.som.hibiscus.features
import codes.som.hibiscus.api.feature.Feature
import codes.som.hibiscus.features.combat.Criticals
import codes.som.hibiscus.features.movement.Flight
import codes.som.hibiscus.features.movement.Speed
import codes.som.hibiscus.features.overlay.Overlay
import codes.som.hibiscus.features.player.NoFallDamage
val ALL_FEATURES: Array<() -> Feature> = arrayOf(
::NoFallDamage,
::Flight,
::Overlay,
::Speed,
::Criticals,
)
class FeaturesRegistry {
private val features = ALL_FEATURES.map { it() }.sortedBy { it.name }
fun getAllFeatures() = features.asSequence()
inline fun <reified T : Feature> getFeature() =
getFeature(T::class.java)
@Suppress("UNCHECKED_CAST")
fun <T : Feature> getFeature(type: Class<T>) =
features.first { it.javaClass == type } as T
}

View file

@ -1,48 +0,0 @@
package codes.som.hibiscus.features.overlay
import codes.som.hibiscus.HibiscusMod
import codes.som.hibiscus.api.feature.Feature
import codes.som.hibiscus.api.feature.FeatureCategory
import codes.som.hibiscus.events.PostRenderAllEvent
import imgui.ImGui
import imgui.flag.ImGuiCol
import imgui.flag.ImGuiStyleVar
import imgui.flag.ImGuiWindowFlags
class FeatureListOverlay : Feature("Feature List", FeatureCategory.OVERLAY) {
init {
on { _: PostRenderAllEvent ->
val viewport = ImGui.getMainViewport()
ImGui.setNextWindowPos(viewport.posX, viewport.posY)
val enabledFeatures =
HibiscusMod.features.getAllFeatures()
.filter { it.category != FeatureCategory.OVERLAY }
.filter { it.enabled }.toList()
if (enabledFeatures.isEmpty())
return@on
ImGui.pushStyleColor(ImGuiCol.WindowBg, 10, 10, 10, 170)
ImGui.pushStyleVar(ImGuiStyleVar.WindowPadding, 8f, 8f)
ImGui.pushStyleVar(ImGuiStyleVar.WindowMinSize, 0f, 0f)
if (ImGui.begin(
"Feature List",
ImGuiWindowFlags.NoDecoration + ImGuiWindowFlags.NoInputs +
ImGuiWindowFlags.NoMove + ImGuiWindowFlags.AlwaysAutoResize
)
) {
ImGui.pushStyleColor(ImGuiCol.Text, 244, 161, 255, 255)
for (feature in enabledFeatures)
ImGui.text(feature.name)
ImGui.popStyleColor()
}
ImGui.end()
ImGui.popStyleVar(2)
ImGui.popStyleColor()
}
enabled = true
}
}

View file

@ -0,0 +1,69 @@
package codes.som.hibiscus.features.overlay
import codes.som.hibiscus.HibiscusMod
import codes.som.hibiscus.api.feature.Feature
import codes.som.hibiscus.api.feature.FeatureCategory
import codes.som.hibiscus.events.PostRenderAllEvent
import imgui.ImGui
import imgui.flag.ImGuiCol
import imgui.flag.ImGuiStyleVar
import imgui.flag.ImGuiWindowFlags
class Overlay : Feature("Overlay", FeatureCategory.OVERLAY) {
init {
val enabledFeatures by values.bool("Enabled Features", true)
on { _: PostRenderAllEvent ->
val viewport = ImGui.getMainViewport()
ImGui.setNextWindowPos(viewport.posX, viewport.posY)
ImGui.setNextWindowSize(viewport.sizeX, viewport.sizeY)
ImGui.pushStyleColor(ImGuiCol.WindowBg, 0, 0, 0, 0)
ImGui.begin(
"Overlay##Overlay",
ImGuiWindowFlags.NoMove + ImGuiWindowFlags.NoInputs + ImGuiWindowFlags.NoDecoration
)
if (enabledFeatures)
drawEnabledFeatures()
ImGui.end()
ImGui.popStyleColor()
}
enabled = true
}
private fun drawEnabledFeatures() {
val enabledFeatures =
HibiscusMod.features.getAllFeatures()
.filter { it.category != FeatureCategory.OVERLAY }
.filter { it.enabled }.toList()
if (enabledFeatures.isEmpty())
return
val padX = 8f
val padY = 8f
val pos = ImGui.getCursorScreenPos()
ImGui.setCursorScreenPos(pos.x + padX, pos.y + padY)
ImGui.beginGroup()
ImGui.pushStyleColor(ImGuiCol.Text, 244, 161, 255, 255)
for (feature in enabledFeatures)
ImGui.text(feature.name)
ImGui.popStyleColor()
ImGui.endGroup()
val min = ImGui.getItemRectMin()
val max = ImGui.getItemRectMax()
ImGui.getBackgroundDrawList().addRectFilled(
min.x - padX, min.y - padY, max.x + padX,
max.y + padY,
0xAA0A0A0AL.toInt(),
0F
)
}
}

View file

@ -3,6 +3,7 @@ package codes.som.hibiscus.gui
import codes.som.hibiscus.HibiscusMod
import codes.som.hibiscus.api.feature.Feature
import codes.som.hibiscus.api.feature.FeatureCategory
import codes.som.hibiscus.features.overlay.Overlay
import imgui.ImGui
import imgui.flag.ImGuiCol
import imgui.flag.ImGuiCond.Once
@ -12,25 +13,21 @@ import imgui.type.ImBoolean
object ModuleControlsUI {
private val moduleValueWindows = mutableMapOf<Feature, ImBoolean>()
private fun categoryPanel(category: FeatureCategory, initialX: Float, initialY: Float) {
ImGui.setNextWindowPos(initialX, initialY, Once)
ImGui.setNextWindowCollapsed(true, Once)
ImGui.setNextWindowSize(300f, 0f, Once)
private fun drawCategoryPanel(category: FeatureCategory, ) {
ImGui.begin(category.humanName, AlwaysVerticalScrollbar)
for (feature in HibiscusMod.features.getAllFeatures().filter { it.category == category }) {
featureControls(feature)
drawFeatureControls(feature)
}
ImGui.end()
}
private fun featureControls(feature: Feature) {
private fun drawFeatureControls(feature: Feature) {
if (feature.values.exist()) {
ImGui.columns(2, "Features Columns", false)
ImGui.setColumnWidth(0, ImGui.getWindowContentRegionMaxX() - ImGui.getWindowContentRegionMinX() - 24)
ImGui.setColumnWidth(0, ImGui.getWindowContentRegionMaxX() - ImGui.getWindowContentRegionMinX() - 30)
}
if (feature.enabled) {
@ -66,15 +63,38 @@ object ModuleControlsUI {
}
}
}
private fun drawOverlaySettings() {
val overlayFeature = HibiscusMod.features.getFeature<Overlay>()
if (ImGui.begin("${overlayFeature.name}##Feature Controls"))
for (value in overlayFeature.values)
value.drawUIControl()
ImGui.end()
}
fun render(delta: Float) {
for ((index, category) in FeatureCategory.values().withIndex()) {
categoryPanel(
category,
ImGui.getMainViewport().posX + 10f,
ImGui.getMainViewport().posY + 10f + index * 30f
)
var yOffset = 0f
fun pushInitialPanelConfig() {
val initialX = ImGui.getMainViewport().posX + 10f
val initialY = ImGui.getMainViewport().posY + 10f + yOffset
ImGui.setNextWindowPos(initialX, initialY, Once)
ImGui.setNextWindowCollapsed(true, Once)
ImGui.setNextWindowSize(300f, 0f, Once)
}
for (category in FeatureCategory.values()) {
if (category == FeatureCategory.OVERLAY)
continue
pushInitialPanelConfig()
drawCategoryPanel(category)
yOffset += 30f
}
pushInitialPanelConfig()
drawOverlaySettings()
}
}