This commit is contained in:
SoulliesOfficial
2026-03-18 13:42:23 -04:00
parent 7580c4d87c
commit 56cee0cf01
38 changed files with 1156 additions and 3392 deletions

View File

@@ -0,0 +1,41 @@
using System;
using System.Collections.Generic;
using Ichni.RhythmGame.Beatmap;
using UnityEngine;
namespace Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse.Beatmap
{
[System.Serializable]
public class DTMFramesFloor_BM : EnvironmentObject_BM
{
public float patternSizeX = 100.0f;
public float patternSizeY = 100.0f;
public float gridDensity = 1.0f;
public float timeAngle = 0.1f;
public float stepA = 0.25f;
public float stepB = 0.24f;
public bool enableOuterBorder = true;
public float outerBorderColorR = 1f;
public float outerBorderColorG = 1f;
public float outerBorderColorB = 1f;
public float outerBorderColorA = 1f;
public float outerBorderWidth = 0.02f;
public DTMFramesFloor_BM()
{
}
public override void ExecuteBM()
{
Color outerColor = new Color(outerBorderColorR, outerBorderColorG, outerBorderColorB, outerBorderColorA);
matchedElement = DTMFramesFloor.GenerateElement(elementName, elementGuid, tags, false,
themeBundleName, objectName, GetElement(attachedElementGuid), isStatic,
patternSizeX, patternSizeY, gridDensity,
timeAngle, stepA, stepB,
enableOuterBorder, outerColor, outerBorderWidth);
}
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: d6073730876ef064e86673c02d0c6e36

View File

@@ -0,0 +1,43 @@
using System;
using System.Collections.Generic;
using Ichni.RhythmGame.Beatmap;
namespace Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse.Beatmap
{
[System.Serializable]
public class DTMGlobalFog_BM : EnvironmentObject_BM
{
public FlexibleFloat_BM fogColorStartR = new FlexibleFloat_BM();
public FlexibleFloat_BM fogColorStartG = new FlexibleFloat_BM();
public FlexibleFloat_BM fogColorStartB = new FlexibleFloat_BM();
public FlexibleFloat_BM fogColorStartA = new FlexibleFloat_BM();
public FlexibleFloat_BM fogColorEndR = new FlexibleFloat_BM();
public FlexibleFloat_BM fogColorEndG = new FlexibleFloat_BM();
public FlexibleFloat_BM fogColorEndB = new FlexibleFloat_BM();
public FlexibleFloat_BM fogColorEndA = new FlexibleFloat_BM();
public FlexibleFloat_BM fogColorDuo = new FlexibleFloat_BM();
public FlexibleFloat_BM skyboxFogIntensity = new FlexibleFloat_BM();
public FlexibleFloat_BM skyboxFogHeight = new FlexibleFloat_BM();
public FlexibleFloat_BM skyboxFogFalloff = new FlexibleFloat_BM();
public FlexibleFloat_BM skyboxFogOffset = new FlexibleFloat_BM();
public DTMGlobalFog_BM()
{
}
public override void ExecuteBM()
{
matchedElement = DTMGlobalFog.GenerateElement(elementName, elementGuid, tags, false,
themeBundleName, objectName, GetElement(attachedElementGuid), isStatic,
fogColorStartR?.ConvertToGameType(), fogColorStartG?.ConvertToGameType(), fogColorStartB?.ConvertToGameType(), fogColorStartA?.ConvertToGameType(),
fogColorEndR?.ConvertToGameType(), fogColorEndG?.ConvertToGameType(), fogColorEndB?.ConvertToGameType(), fogColorEndA?.ConvertToGameType(),
fogColorDuo?.ConvertToGameType(),
skyboxFogIntensity?.ConvertToGameType(), skyboxFogHeight?.ConvertToGameType(),
skyboxFogFalloff?.ConvertToGameType(), skyboxFogOffset?.ConvertToGameType());
}
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 68f4e10e5b6171549a44658b6b917a2a

View File

@@ -7,7 +7,7 @@ using UnityEngine;
namespace Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse
{
public class DTM_Ripple : MonoBehaviour, IPoolable
public class DTMRipple : MonoBehaviour, IPoolable
{
#region [] Exposed Fields & References
public ParticleSystem mainRipple;

View File

@@ -0,0 +1,105 @@
using System;
using System.Collections.Generic;
using Ichni.RhythmGame.Beatmap;
using UnityEngine;
namespace Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse
{
public class DTMFramesFloor : EnvironmentObject
{
#region [] Exposed Fields
public float patternSizeX;
public float patternSizeY;
public float gridDensity;
public float timeAngle;
public float stepA;
public float stepB;
public bool enableOuterBorder;
public Color outerBorderColor;
public float outerBorderWidth;
public Renderer meshRenderer;
#endregion
#region [] Lifecycle & Factory
public static DTMFramesFloor GenerateElement(string elementName, Guid id, List<string> tags,
bool isFirstGenerated, string themeBundleName, string objectName, GameElement parentElement,
bool isStatic,
float patternSizeX, float patternSizeY, float gridDensity,
float timeAngle, float stepA, float stepB,
bool enableOuterBorder,
Color outerBorderColor,
float outerBorderWidth)
{
DTMFramesFloor framesFloor = EnvironmentObject.GenerateElement(elementName, id, tags,
isFirstGenerated, themeBundleName, objectName, parentElement, isStatic).GetComponent<DTMFramesFloor>();
framesFloor.patternSizeX = patternSizeX;
framesFloor.patternSizeY = patternSizeY;
framesFloor.gridDensity = gridDensity;
framesFloor.timeAngle = timeAngle;
framesFloor.stepA = stepA;
framesFloor.stepB = stepB;
framesFloor.enableOuterBorder = enableOuterBorder;
framesFloor.outerBorderColor = outerBorderColor;
framesFloor.outerBorderWidth = outerBorderWidth;
return framesFloor;
}
public override void FirstSetUpObject(bool isFirstGenerated)
{
if (meshRenderer == null)
meshRenderer = GetComponentInChildren<Renderer>();
meshRenderer.InitializeShader(); // 实例化材质 / Instantiate material
UpdateMaterialProperties();
}
#endregion
#region [] Core Effect Logic
public void UpdateMaterialProperties()
{
if (meshRenderer != null && meshRenderer.material != null)
{
Material mat = meshRenderer.material;
mat.SetVector("_PatternSize", new Vector4(patternSizeX, patternSizeY, 0, 0));
mat.SetFloat("_GridDensity", gridDensity);
mat.SetFloat("_TimeAngle", timeAngle);
mat.SetFloat("_StepA", stepA);
mat.SetFloat("_StepB", stepB);
float borderOn = enableOuterBorder ? 1f : 0f;
mat.SetFloat("_EnableOuterBorder", borderOn);
if (enableOuterBorder)
{
mat.EnableKeyword("_OUTER_BORDER_ON");
}
else
{
mat.DisableKeyword("_OUTER_BORDER_ON");
}
mat.SetColor("_OuterBorderColor", outerBorderColor);
mat.SetFloat("_OuterBorderWidth", outerBorderWidth);
// Base Color and Alpha Sync (Unity Color -> HDR)
mat.SetColor("_Color0", colorSubmodule.currentBaseColor);
}
}
public override void Refresh()
{
base.Refresh();
// Sync environment color changes
if (meshRenderer != null)
{
meshRenderer.material.SetColor("_Color0", colorSubmodule.currentBaseColor);
}
}
#endregion
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 677671f1d5140b2489dc52c18792b8f5

View File

@@ -0,0 +1,115 @@
using System;
using System.Collections.Generic;
using Ichni.RhythmGame.Beatmap;
using UnityEngine;
using AtmosphericHeightFog;
using FogMode = AtmosphericHeightFog.FogMode;
namespace Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse
{
public class DTMGlobalFog : EnvironmentObject
{
#region [] Exposed Fields
public HeightFogGlobal heightFogGlobal;
public FlexibleFloat fogColorStartR, fogColorStartG, fogColorStartB, fogColorStartA;
public FlexibleFloat fogColorEndR, fogColorEndG, fogColorEndB, fogColorEndA;
public FlexibleFloat fogColorDuo;
public FlexibleFloat skyboxFogIntensity;
public FlexibleFloat skyboxFogHeight;
public FlexibleFloat skyboxFogFalloff;
public FlexibleFloat skyboxFogOffset;
#endregion
#region [] Lifecycle & Factory
public static DTMGlobalFog GenerateElement(string elementName, Guid id, List<string> tags,
bool isFirstGenerated, string themeBundleName, string objectName, GameElement parentElement,
bool isStatic,
FlexibleFloat fogColorStartR, FlexibleFloat fogColorStartG, FlexibleFloat fogColorStartB, FlexibleFloat fogColorStartA,
FlexibleFloat fogColorEndR, FlexibleFloat fogColorEndG, FlexibleFloat fogColorEndB, FlexibleFloat fogColorEndA,
FlexibleFloat fogColorDuo,
FlexibleFloat skyboxFogIntensity, FlexibleFloat skyboxFogHeight,
FlexibleFloat skyboxFogFalloff, FlexibleFloat skyboxFogOffset)
{
DTMGlobalFog globalFog = EnvironmentObject.GenerateElement(elementName, id, tags,
isFirstGenerated, themeBundleName, objectName, parentElement, isStatic).GetComponent<DTMGlobalFog>();
globalFog.fogColorStartR = fogColorStartR;
globalFog.fogColorStartG = fogColorStartG;
globalFog.fogColorStartB = fogColorStartB;
globalFog.fogColorStartA = fogColorStartA;
globalFog.fogColorEndR = fogColorEndR;
globalFog.fogColorEndG = fogColorEndG;
globalFog.fogColorEndB = fogColorEndB;
globalFog.fogColorEndA = fogColorEndA;
globalFog.fogColorDuo = fogColorDuo;
globalFog.skyboxFogIntensity = skyboxFogIntensity;
globalFog.skyboxFogHeight = skyboxFogHeight;
globalFog.skyboxFogFalloff = skyboxFogFalloff;
globalFog.skyboxFogOffset = skyboxFogOffset;
return globalFog;
}
public override void FirstSetUpObject(bool isFirstGenerated)
{
if (heightFogGlobal == null)
{
heightFogGlobal = GetComponentInChildren<HeightFogGlobal>();
}
// Ensure fog mode is set to script settings so it accepts our overrides
if (heightFogGlobal != null)
{
heightFogGlobal.fogMode = FogMode.UseScriptSettings;
}
}
#endregion
#region [] Event Animation Logic
private void Update()
{
if (heightFogGlobal == null) return;
float songTime = CoreServices.TimeProvider.SongTime;
fogColorStartR?.UpdateFlexibleFloat(songTime);
fogColorStartG?.UpdateFlexibleFloat(songTime);
fogColorStartB?.UpdateFlexibleFloat(songTime);
fogColorStartA?.UpdateFlexibleFloat(songTime);
fogColorEndR?.UpdateFlexibleFloat(songTime);
fogColorEndG?.UpdateFlexibleFloat(songTime);
fogColorEndB?.UpdateFlexibleFloat(songTime);
fogColorEndA?.UpdateFlexibleFloat(songTime);
fogColorDuo?.UpdateFlexibleFloat(songTime);
skyboxFogIntensity?.UpdateFlexibleFloat(songTime);
skyboxFogHeight?.UpdateFlexibleFloat(songTime);
skyboxFogFalloff?.UpdateFlexibleFloat(songTime);
skyboxFogOffset?.UpdateFlexibleFloat(songTime);
if (fogColorStartR != null && fogColorStartG != null && fogColorStartB != null && fogColorStartA != null)
{
heightFogGlobal.fogColorStart = new Color(fogColorStartR.value, fogColorStartG.value, fogColorStartB.value, fogColorStartA.value);
}
if (fogColorEndR != null && fogColorEndG != null && fogColorEndB != null && fogColorEndA != null)
{
heightFogGlobal.fogColorEnd = new Color(fogColorEndR.value, fogColorEndG.value, fogColorEndB.value, fogColorEndA.value);
}
if (fogColorDuo != null) heightFogGlobal.fogColorDuo = fogColorDuo.value;
if (skyboxFogIntensity != null) heightFogGlobal.skyboxFogIntensity = skyboxFogIntensity.value;
if (skyboxFogHeight != null) heightFogGlobal.skyboxFogHeight = skyboxFogHeight.value;
if (skyboxFogFalloff != null) heightFogGlobal.skyboxFogFalloff = skyboxFogFalloff.value;
if (skyboxFogOffset != null) heightFogGlobal.skyboxFogOffset = skyboxFogOffset.value;
}
#endregion
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: e8bab02f6d349f6418ccfe0674b93013

View File

@@ -0,0 +1,9 @@
using UnityEngine;
namespace Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse
{
public class DTMStarrySkybox : GameElement
{
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 638fbd0e919667f47a93485dd230c71f

View File

@@ -6,7 +6,7 @@ namespace Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse
public class DTMRippleEffect : EffectBase
{
#region [] Effect Fields & States
private DTM_Ripple ripple;
private DTMRipple ripple;
public float rippleTime;
public Vector3 positionOffset;
public Vector3 eulerAnglesOffset;
@@ -33,7 +33,7 @@ namespace Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse
public override void Adjust()
{
GameObject prefab = GameManager.Instance.customPrefabs["departure_to_multiverse"].GetPrefab("DTM_Ripple");
ripple = LeanPool.Spawn(prefab, attachedGameElement.transform).GetComponent<DTM_Ripple>();
ripple = LeanPool.Spawn(prefab, attachedGameElement.transform).GetComponent<DTMRipple>();
ripple.transform.localPosition = positionOffset;
ripple.transform.localEulerAngles = eulerAnglesOffset;
ripple.transform.localScale = scale;

View File

@@ -1,107 +0,0 @@
import os
import re
game_dir = r"d:\Projects\ichni Official\Assets\ThemeBundles\DepartureToMultiverse\Scripts\Game"
datacore_dir = r"d:\Projects\ichni Official\Assets\ThemeBundles\DepartureToMultiverse\Scripts\DataCore"
def extract_beatmap_namespace(filepath):
try:
with open(filepath, 'r', encoding='utf-8') as f:
content = f.read()
except Exception as e:
print("Error reading", filepath, e)
return
# Find the start of namespace Beatmap
match = re.search(r'^\s*namespace\s+Beatmap\s*\{', content, re.MULTILINE)
if not match:
print("No Beatmap namespace in", filepath)
return
start_idx = match.start()
# We need to find the matching closing brace
brace_depth = 0
end_idx = -1
for i in range(start_idx, len(content)):
if content[i] == '{':
brace_depth += 1
elif content[i] == '}':
brace_depth -= 1
if brace_depth == 0:
end_idx = i + 1
break
if end_idx == -1:
print("Mismatched braces in", filepath)
return
bm_namespace_content = content[start_idx:end_idx]
# Find the name of the _BM class to name the new file
class_match = re.search(r'public\s+(?:partial\s+)?class\s+(\w+_BM)', bm_namespace_content)
if not class_match:
print("No _BM class found in namespace Beatmap for", filepath)
return
bm_class_name = class_match.group(1)
# Make the original file clean
new_game_content = content[:start_idx] + content[end_idx:]
new_game_content = new_game_content.rstrip()
# close the namespace of the original file if needed, actually it's usually inside the original namespace!
# Let's check if "namespace Beatmap" is inside another namespace.
# Yes, typically "namespace Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse" wraps everything.
# The new_game_content currently might have a trailing `}` because the outer namespace is closed at the end.
# E.g.
# namespace Outer {
# class OuterClass { }
# namespace Beatmap { ... }
# }
# If we remove "namespace Beatmap { ... }", we still need the trailing "}".
new_game_content = re.sub(r'[\r\n\s]*namespace\s+Beatmap[\s\S]*\}\s*\}\s*$', '\n}', content) # A quick hacky way but relies on structure.
# Better way: just remove the exact substring, then it leaves the outer closing brace intact.
# wait, if namespace Beatmap { ... } is inside namespace Outer { ... }
# start_idx to end_idx is exactly "namespace Beatmap { ... }"
# So content[:start_idx] + content[end_idx:] will leave the outer } perfectly.
new_content = content[:start_idx] + content[end_idx:]
# Clean up excess newlines
new_content = re.sub(r'\n\s*\n\s*\n', '\n\n', new_content)
# Ensure it ends with a newline
new_content = new_content.strip() + '\n'
with open(filepath, 'w', encoding='utf-8') as f:
f.write(new_content)
# Now create the DataCore file
rel_path = os.path.relpath(filepath, game_dir)
datacore_file_dir = os.path.dirname(os.path.join(datacore_dir, rel_path))
os.makedirs(datacore_file_dir, exist_ok=True)
datacore_filepath = os.path.join(datacore_file_dir, bm_class_name + ".cs")
# We need usings. Extract original usings
usings = "".join(re.findall(r'^(?:using\s+[\w\.]+;\s*)+', content, re.MULTILINE))
# Format the new DataCore file
datacore_content = usings + "\n"
# Wrap in outer namespace
datacore_content += "namespace Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse.Beatmap\n{\n"
# Extract the classes inside "namespace Beatmap"
inner_classes = re.search(r'namespace\s+Beatmap\s*\{([\s\S]*)\}', bm_namespace_content).group(1)
datacore_content += inner_classes + "}\n"
with open(datacore_filepath, 'w', encoding='utf-8') as f:
f.write(datacore_content)
print(f"Split {os.path.basename(filepath)} -> {bm_class_name}.cs")
for root, dirs, files in os.walk(game_dir):
for file in files:
if file.endswith('.cs'):
filepath = os.path.join(root, file)
extract_beatmap_namespace(filepath)

View File

@@ -1,7 +0,0 @@
fileFormatVersion: 2
guid: 93391ba5485d4154293a4540acd4e942
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant: