mirror of https://github.com/hykilpikonna/AquaDX
[+] Slide related visual feature (#81)
New Features: 1. Invert the Slide hierarchy 2. Slide Track shrinking animation Changes: 1. Improve the visual effect of Break-Slide judge blink 2. `DisableTrackStartTabs` now also hide user's best achievementpull/84/head
parent
11beb6676e
commit
85dd8029af
|
@ -13,12 +13,11 @@ public class BreakSlideJudgeBlink
|
|||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(SlideJudge), "UpdateBreakEffectAdd")]
|
||||
private static void FixBreakSlideJudgeBlink(
|
||||
SpriteRenderer ___SpriteRenderAdd, SpriteRenderer ___SpriteRender,
|
||||
SlideJudge.SlideJudgeType ____judgeType, SlideJudge.SlideAngle ____angle
|
||||
SpriteRenderer ___SpriteRenderAdd, int ____addEffectCount
|
||||
)
|
||||
{
|
||||
if (!___SpriteRenderAdd.gameObject.activeSelf) return;
|
||||
float num = ___SpriteRenderAdd.color.r;
|
||||
float num = (____addEffectCount & 0b10) >> 1;
|
||||
___SpriteRenderAdd.color = new Color(num, num, num, 1f);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -84,4 +84,24 @@ public class Config
|
|||
推荐与自定义皮肤一起使用 (否则视觉效果可能并不好)
|
||||
""")]
|
||||
public bool BreakSlideJudgeBlink { get; set; }
|
||||
|
||||
[ConfigComment(
|
||||
en: """
|
||||
Make the Slide Track disappear with an inward-shrinking animation, similar to AstroDX
|
||||
""",
|
||||
zh: """
|
||||
使 Slide Track 消失时有类似 AstroDX 一样的向内缩入的动画
|
||||
""")]
|
||||
public bool SlideArrowAnimation { get; set; }
|
||||
|
||||
[ConfigComment(
|
||||
en: """
|
||||
Invert the Slide hierarchy, so that the new Slide appears on top like Maimai classic
|
||||
Enable to support color changing effects achieved by overlaying multiple stars
|
||||
""",
|
||||
zh: """
|
||||
反转 Slide 层级, 使新出现的 Slide 像旧框一样显示在上层
|
||||
启用以支持通过叠加多个星星达成的变色效果
|
||||
""")]
|
||||
public bool SlideLayerReverse { get; set; }
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
using HarmonyLib;
|
||||
using Monitor;
|
||||
using TMPro;
|
||||
using UI;
|
||||
using UnityEngine;
|
||||
|
||||
|
@ -13,7 +14,8 @@ public class DisableTrackStartTabs
|
|||
[HarmonyPatch(typeof(TrackStartMonitor), "SetTrackStart")]
|
||||
private static void DisableTabs(
|
||||
SpriteCounter ____trackNumber, SpriteCounter ____bossTrackNumber, SpriteCounter ____utageTrackNumber,
|
||||
MultipleImage ____musicTabImage, GameObject[] ____musicTabObj, GameObject ____derakkumaRoot
|
||||
MultipleImage ____musicTabImage, GameObject[] ____musicTabObj, GameObject ____derakkumaRoot,
|
||||
TimelineRoot ____musicDetail
|
||||
)
|
||||
{
|
||||
____trackNumber.transform.parent.gameObject.SetActive(false);
|
||||
|
@ -24,5 +26,15 @@ public class DisableTrackStartTabs
|
|||
____musicTabObj[1].gameObject.SetActive(false);
|
||||
____musicTabObj[2].gameObject.SetActive(false);
|
||||
____derakkumaRoot.SetActive(false);
|
||||
var traverse = Traverse.Create(____musicDetail);
|
||||
traverse.Field<MultipleImage>("_achivement_Base").Value.ChangeSprite(1);
|
||||
traverse.Field<MultipleImage>("_clearRank_Base").Value.ChangeSprite(1);
|
||||
traverse.Field<TextMeshProUGUI>("_achivement_Text").Value.gameObject.SetActive(false);
|
||||
traverse.Field<TextMeshProUGUI>("_achivement_decimal_Text").Value.gameObject.SetActive(false);
|
||||
traverse.Field<TextMeshProUGUI>("_achivement_percent_Text").Value.gameObject.SetActive(false);
|
||||
traverse.Field<MultipleImage>("_clearRank_Image").Value.gameObject.SetActive(false);
|
||||
traverse.Field<GameObject>("_deluxScore_Obj").Value.SetActive(false);
|
||||
traverse.Field<MultipleImage>("_comboRank_Image").Value.ChangeSprite(0);
|
||||
traverse.Field<MultipleImage>("_syncRank_Image").Value.ChangeSprite(0);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,115 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using HarmonyLib;
|
||||
using Manager;
|
||||
using Monitor;
|
||||
using Monitor.Game;
|
||||
using Process;
|
||||
using UnityEngine;
|
||||
|
||||
namespace AquaMai.Visual;
|
||||
|
||||
public class SlideArrowAnimation
|
||||
{
|
||||
private static List<SpriteRenderer> _animatingSpriteRenderers = [];
|
||||
|
||||
[HarmonyTranspiler]
|
||||
[HarmonyPatch(typeof(SlideRoot), "NoteCheck")]
|
||||
private static IEnumerable<CodeInstruction> GetUnVisibleColorHook(IEnumerable<CodeInstruction> instructions)
|
||||
{
|
||||
var methodGetUnVisibleColor = AccessTools.Method(typeof(SlideRoot), "GetUnVisibleColor");
|
||||
|
||||
var oldInstList = new List<CodeInstruction>(instructions);
|
||||
var newInstList = new List<CodeInstruction>();
|
||||
|
||||
for (var i = 0; i < oldInstList.Count; i++)
|
||||
{
|
||||
var inst = oldInstList[i];
|
||||
if (inst.Calls(methodGetUnVisibleColor))
|
||||
{
|
||||
// 现在栈上应该有: SpriteRenderer, SlideRoot(this)
|
||||
// 这一条 IL 会消耗 this, 调用 GetUnVisibleColor(), 推一个 Color 到栈上
|
||||
// 然后接下来的一条 IL 是调用 SpriteRenderer.color 的 setter 把 SpriteRenderer 和 Color 一起消耗掉
|
||||
// 我们现在直接用一个 static method 消耗掉 SpriteRenderer 和 this
|
||||
// 所以要忽略当前 IL, 再忽略下一条 IL, 然后构造一个 Call
|
||||
|
||||
// ReSharper disable once ConvertClosureToMethodGroup
|
||||
var redirect = CodeInstruction.Call((SpriteRenderer r, SlideRoot s) => OnSlideArrowDisable(r, s));
|
||||
newInstList.Add(redirect);
|
||||
i++; // 跳过下一条 IL
|
||||
}
|
||||
else
|
||||
{
|
||||
newInstList.Add(inst);
|
||||
}
|
||||
}
|
||||
return newInstList;
|
||||
}
|
||||
|
||||
public static void OnSlideArrowDisable(SpriteRenderer renderer, SlideRoot slideRoot)
|
||||
{
|
||||
_animatingSpriteRenderers.Add(renderer);
|
||||
}
|
||||
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(SlideRoot), "SetArrowObject")]
|
||||
private static void RemoveArrowAnimation(GameObject arrowobj)
|
||||
{
|
||||
var spriteRenderer = arrowobj.GetComponent<SpriteRenderer>();
|
||||
spriteRenderer.transform.localScale = Vector3.one;
|
||||
if (_animatingSpriteRenderers.Contains(spriteRenderer))
|
||||
{
|
||||
_animatingSpriteRenderers.Remove(spriteRenderer);
|
||||
}
|
||||
}
|
||||
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(SlideRoot), "SetBreakArrowObject")]
|
||||
private static void RemoveBreakArrowAnimation(GameObject breakArrowobj)
|
||||
{
|
||||
var breakSlideObj = breakArrowobj.GetComponent<BreakSlide>();
|
||||
breakSlideObj.SpriteRender.transform.localScale = Vector3.one;
|
||||
if (_animatingSpriteRenderers.Contains(breakSlideObj.SpriteRender))
|
||||
{
|
||||
_animatingSpriteRenderers.Remove(breakSlideObj.SpriteRender);
|
||||
}
|
||||
}
|
||||
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(GameCtrl), "UpdateNotes")]
|
||||
private static void OnGameCtrlUpdateNotesLast()
|
||||
{
|
||||
for (var num = _animatingSpriteRenderers.Count - 1; num >= 0; num--)
|
||||
{
|
||||
var spriteRenderer = _animatingSpriteRenderers[num];
|
||||
if (spriteRenderer == null)
|
||||
{
|
||||
_animatingSpriteRenderers.RemoveAt(num);
|
||||
}
|
||||
else
|
||||
{
|
||||
var localScale = spriteRenderer.transform.localScale;
|
||||
var scale = localScale.y - NotesManager.GetAddMSec() / 150f;
|
||||
if (scale <= 0)
|
||||
{
|
||||
spriteRenderer.transform.localScale = new Vector3(1f, 0f, 1f);
|
||||
spriteRenderer.color = new Color(1f, 1f, 1f, 0f);
|
||||
_animatingSpriteRenderers.RemoveAt(num);
|
||||
}
|
||||
else
|
||||
{
|
||||
localScale.y = scale;
|
||||
spriteRenderer.color = new Color(1f, 1f, 1f, Mathf.Sqrt(scale));
|
||||
spriteRenderer.transform.localScale = localScale;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(GameProcess), "SetRelease")]
|
||||
private static void OnBeforeGameProcessSetRelease()
|
||||
{
|
||||
_animatingSpriteRenderers.Clear();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
using System.Collections.Generic;
|
||||
using HarmonyLib;
|
||||
using Monitor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace AquaMai.Visual;
|
||||
|
||||
public class SlideLayerReverse
|
||||
{
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(SlideRoot), "Initialize")]
|
||||
private static void CalcArrowLayer(
|
||||
bool ___BreakFlag, List<SpriteRenderer> ____spriteRenders, List<BreakSlide> ____breakSpriteRenders,
|
||||
int ___SlideIndex, int ____baseArrowSortingOrder
|
||||
)
|
||||
{
|
||||
// 原本的 sortingOrder 是 -(SlideIndex + _baseArrowSortingOrder + index)
|
||||
// 令 orderBase = SlideIndex + _baseArrowSortingOrder
|
||||
// 分配给这条 slide 的 sortingOrder 范围是 -(orderBase + count - 1) ~ -(orderBase)
|
||||
// 现在要保留 slide 内部箭头顺序, 但使得 slide 间次序反转
|
||||
// 范围会变成 orderBase ~ orderBase + count - 1
|
||||
// 其中原本是 -(orderBase) 的箭头应该调整为 orderBase + count - 1
|
||||
|
||||
var orderBase = ___SlideIndex + ____baseArrowSortingOrder; // SlideIndex + _baseArrowSortingOrder
|
||||
if (!___BreakFlag)
|
||||
{
|
||||
var lastIdx = ____spriteRenders.Count - 1;
|
||||
for (var index = 0; index < ____spriteRenders.Count; index++)
|
||||
{
|
||||
var renderer = ____spriteRenders[index];
|
||||
renderer.sortingOrder = -32700 + orderBase + lastIdx - index;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var lastIdx = ____breakSpriteRenders.Count - 1;
|
||||
for (var index = 0; index < ____breakSpriteRenders.Count; index++)
|
||||
{
|
||||
var breakSlide = ____breakSpriteRenders[index];
|
||||
breakSlide.SetSortingOrder(-32700 + orderBase + lastIdx - index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(SlideFan), "Initialize")]
|
||||
private static void CalcFanArrowLayer(
|
||||
SpriteRenderer[] ____spriteLines, SpriteRenderer[] ____effectSprites,
|
||||
int ___SlideIndex, int ____baseArrowSortingOrder
|
||||
)
|
||||
{
|
||||
var orderBase = ___SlideIndex + ____baseArrowSortingOrder; // SlideIndex + _baseArrowSortingOrder
|
||||
var lastIdx = ____spriteLines.Length - 1;
|
||||
for (var index = 0; index < ____spriteLines.Length; index++)
|
||||
{
|
||||
var renderer = ____spriteLines[index];
|
||||
renderer.sortingOrder = -32700 + orderBase + lastIdx - index;
|
||||
}
|
||||
lastIdx = ____effectSprites.Length - 1;
|
||||
for (var index = 0; index < ____effectSprites.Length; index++)
|
||||
{
|
||||
var renderer = ____effectSprites[index];
|
||||
renderer.sortingOrder = 1000 + orderBase + lastIdx - index;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue