diff options
Diffstat (limited to 'src/main/kotlin/features/misc/CustomCapes.kt')
| -rw-r--r-- | src/main/kotlin/features/misc/CustomCapes.kt | 172 |
1 files changed, 172 insertions, 0 deletions
diff --git a/src/main/kotlin/features/misc/CustomCapes.kt b/src/main/kotlin/features/misc/CustomCapes.kt new file mode 100644 index 0000000..fe54e6b --- /dev/null +++ b/src/main/kotlin/features/misc/CustomCapes.kt @@ -0,0 +1,172 @@ +package moe.nea.firmament.features.misc + +import util.render.CustomRenderPipelines +import kotlin.time.Duration +import kotlin.time.Duration.Companion.seconds +import net.minecraft.client.player.AbstractClientPlayer +import net.minecraft.client.renderer.RenderType +import com.mojang.blaze3d.vertex.VertexConsumer +import net.minecraft.client.renderer.MultiBufferSource +import net.minecraft.client.renderer.entity.state.AvatarRenderState +import com.mojang.blaze3d.vertex.PoseStack +import net.minecraft.world.entity.player.PlayerSkin +import net.minecraft.core.ClientAsset +import net.minecraft.resources.ResourceLocation +import moe.nea.firmament.Firmament +import moe.nea.firmament.util.MC +import moe.nea.firmament.util.TimeMark +import moe.nea.firmament.util.data.Config +import moe.nea.firmament.util.data.ManagedConfig +import moe.nea.firmament.util.mc.CustomRenderPassHelper + +object CustomCapes { + val identifier: String + get() = "developer-capes" + + @Config + object TConfig : ManagedConfig(identifier, Category.DEV) { + val showCapes by toggle("show-cape") { true } + } + + interface CustomCapeRenderer { + fun replaceRender( + renderLayer: RenderType, + vertexConsumerProvider: MultiBufferSource, + matrixStack: PoseStack, + model: (VertexConsumer) -> Unit + ) + } + + data class TexturedCapeRenderer( + val location: ResourceLocation + ) : CustomCapeRenderer { + override fun replaceRender( + renderLayer: RenderType, + vertexConsumerProvider: MultiBufferSource, + matrixStack: PoseStack, + model: (VertexConsumer) -> Unit + ) { + model(vertexConsumerProvider.getBuffer(RenderType.entitySolid(location))) + } + } + + data class ParallaxedHighlightCapeRenderer( + val template: ResourceLocation, + val background: ResourceLocation, + val overlay: ResourceLocation, + val animationSpeed: Duration, + ) : CustomCapeRenderer { + override fun replaceRender( + renderLayer: RenderType, + vertexConsumerProvider: MultiBufferSource, + matrixStack: PoseStack, + model: (VertexConsumer) -> Unit + ) { + val animationValue = (startTime.passedTime() / animationSpeed).mod(1F) + CustomRenderPassHelper( + { "Firmament Cape Renderer" }, + renderLayer.mode(), + renderLayer.format(), + MC.instance.mainRenderTarget, + true, + ).use { renderPass -> + renderPass.setPipeline(CustomRenderPipelines.PARALLAX_CAPE_SHADER) + renderPass.setAllDefaultUniforms() + renderPass.setUniform("Animation", 4) { + it.putFloat(animationValue.toFloat()) + } + renderPass.bindSampler("Sampler0", template) + renderPass.bindSampler("Sampler1", background) + renderPass.bindSampler("Sampler3", overlay) + renderPass.uploadVertices(2048, model) + renderPass.draw() + } + } + } + + interface CapeStorage { + companion object { + @JvmStatic + fun cast(playerEntityRenderState: AvatarRenderState) = + playerEntityRenderState as CapeStorage + + } + + var cape_firmament: CustomCape? + } + + data class CustomCape( + val id: String, + val label: String, + val render: CustomCapeRenderer, + ) + + enum class AllCapes(val label: String, val render: CustomCapeRenderer) { + FIRMAMENT_ANIMATED( + "Animated Firmament", ParallaxedHighlightCapeRenderer( + Firmament.identifier("textures/cape/parallax_template.png"), + Firmament.identifier("textures/cape/parallax_background.png"), + Firmament.identifier("textures/cape/firmament_star.png"), + 110.seconds + ) + ), + UNPLEASANT_GRADIENT( + "unpleasant_gradient", + TexturedCapeRenderer(Firmament.identifier("textures/cape/unpleasant_gradient.png")) + ), + FURFSKY_STATIC( + "FurfSky", + TexturedCapeRenderer(Firmament.identifier("textures/cape/fsr_static.png")) + ), + + FIRMAMENT_STATIC( + "Firmament", + TexturedCapeRenderer(Firmament.identifier("textures/cape/firm_static.png")) + ), + HYPIXEL_PLUS( + "Hypixel+", + TexturedCapeRenderer(Firmament.identifier("textures/cape/h_plus.png")) + ), + ; + + val cape = CustomCape(name, label, render) + } + + val byId = AllCapes.entries.associateBy { it.cape.id } + val byUuid = + listOf( + listOf( + Devs.nea to AllCapes.UNPLEASANT_GRADIENT, + Devs.kath to AllCapes.FIRMAMENT_STATIC, + Devs.jani to AllCapes.FIRMAMENT_ANIMATED, + Devs.nat to AllCapes.FIRMAMENT_ANIMATED, + Devs.HPlus.ic22487 to AllCapes.HYPIXEL_PLUS, + ), + Devs.FurfSky.all.map { it to AllCapes.FURFSKY_STATIC }, + ).flatten().flatMap { (dev, cape) -> dev.uuids.map { it to cape.cape } }.toMap() + + @JvmStatic + fun addCapeData( + player: AbstractClientPlayer, + playerEntityRenderState: AvatarRenderState + ) { + if (true) return // TODO: see capefeaturerenderer mixin + val cape = if (TConfig.showCapes) byUuid[player.uuid] else null + val capeStorage = CapeStorage.cast(playerEntityRenderState) + if (cape == null) { + capeStorage.cape_firmament = null + } else { + capeStorage.cape_firmament = cape + playerEntityRenderState.skin = PlayerSkin( + playerEntityRenderState.skin.body, + ClientAsset.ResourceTexture(Firmament.identifier("placeholder/fake_cape"), Firmament.identifier("placeholder/fake_cape")), + playerEntityRenderState.skin.elytra, + playerEntityRenderState.skin.model, + playerEntityRenderState.skin.secure, + ) + playerEntityRenderState.showCape = true + } + } + + val startTime = TimeMark.now() +} |
