feat: 场景

This commit is contained in:
m0_75251201
2025-11-04 17:05:34 +08:00
parent 0206a83f56
commit 5d69efbc3f
84 changed files with 1406 additions and 21 deletions

View File

@@ -1,9 +1,129 @@
using System.Collections.Generic;
using System.IO;
using UnityEngine; // 假设在Unity环境中使用Debug.LogError
namespace HitFeedback
{
public class Config
{
public KeyCode hotKey = KeyCode.F8;
public Dictionary<string, float> probability = new Dictionary<string, float>();
public void LoadConfig(string filename)
{
if (!File.Exists(filename))
{
Debug.LogError($"Config file not found: {filename}");
return; // 如果文件不存在,就没必要继续了
}
// 清空旧的概率数据,确保每次加载都是从新开始
probability.Clear();
try
{
using (var sr = new StreamReader(filename))
{
string line;
var lineNumber = 0; // 用于错误报告
while ((line = sr.ReadLine()) != null)
{
lineNumber++;
line = line.Trim(); // 移除行首尾的空白字符
// 忽略空行和注释行
if (string.IsNullOrEmpty(line) || line.StartsWith(";") || line.StartsWith("#"))
{
continue;
}
// 查找等号
var separatorIndex = line.IndexOf('=');
if (separatorIndex == -1)
{
Debug.LogWarning($"Skipping malformed line in config file '{filename}' at line {lineNumber}: No '=' found. Line: '{line}'");
continue;
}
var key = line.Substring(0, separatorIndex).Trim();
var valueStr = line.Substring(separatorIndex + 1).Trim();
// 解析 hotKey
if (key.Equals("hotKey", System.StringComparison.OrdinalIgnoreCase))
{
try
{
hotKey = (KeyCode)System.Enum.Parse(typeof(KeyCode), valueStr, true);
}
catch (System.ArgumentException)
{
Debug.LogError($"Invalid KeyCode '{valueStr}' in config file '{filename}' at line {lineNumber}. Using default F8.");
hotKey = KeyCode.F8; // 设置为默认值或保持不变
}
}
// 解析 probability 字典项
else
{
if (float.TryParse(valueStr, out var probValue))
{
probability[key] = probValue;
}
else
{
Debug.LogWarning($"Invalid float value '{valueStr}' for key '{key}' in config file '{filename}' at line {lineNumber}. Skipping entry.");
}
}
}
}
}
catch (System.Exception ex)
{
Debug.LogError($"Error reading config file '{filename}': {ex.Message}");
}
}
/// <summary>
/// 将当前配置存储到指定INI文件。
/// </summary>
/// <param name="filename">要保存的INI文件的路径。</param>
public void SaveConfig(string filename)
{
try
{
// 确保目录存在
var directory = Path.GetDirectoryName(filename);
if (!string.IsNullOrEmpty(directory) && !Directory.Exists(directory))
{
Directory.CreateDirectory(directory);
}
using (var sw = new StreamWriter(filename))
{
sw.WriteLine("; HitFeedback Configuration File");
sw.WriteLine("; Generated by HitFeedback.Config class");
sw.WriteLine(); // 空行
sw.WriteLine("[General]");
sw.WriteLine($"hotKey = {hotKey.ToString()}");
sw.WriteLine();
if (probability.Count > 0)
{
sw.WriteLine("[Probabilities]");
foreach (var kvp in probability)
{
// 使用 InvariantCulture 确保浮点数的格式在不同区域设置下都一致
sw.WriteLine($"{kvp.Key} = {kvp.Value.ToString(System.Globalization.CultureInfo.InvariantCulture)}");
}
}
else
{
sw.WriteLine("; No probabilities currently configured.");
}
sw.WriteLine();
}
Debug.Log($"Config saved to: {filename}");
}
catch (System.Exception ex)
{
Debug.LogError($"Error saving config file '{filename}': {ex.Message}");
}
}
}
}
}

View File

@@ -14,13 +14,17 @@ namespace HitFeedback
public class ModBehaviour:Duckov.Modding.ModBehaviour
{
public const string AudioFolderName = "audio";
public const string ConfigFileName = "config.ini";
public string audioFolderPath;
public string configFilePath;
public List<string> audioFilePath = new List<string>();
public Dictionary<string,float> audioFilePath = new Dictionary<string,float>();
public Health health;
public Config config=new Config();
public float totalWeight;
private void Update()
{
@@ -34,12 +38,46 @@ namespace HitFeedback
{
LevelManager.OnLevelInitialized += OnSceneLoaded;
audioFolderPath=Path.Combine(info.path,AudioFolderName);
configFilePath=Path.Combine(info.path, ConfigFileName);
FindWavFiles();
config.LoadConfig(configFilePath);
ApplyConfig();
foreach (var f in audioFilePath)
{
totalWeight+=f.Value;
}
}
protected override void OnBeforeDeactivate()
{
LevelManager.OnLevelInitialized -= OnSceneLoaded;
SaveConfig();
}
private void OnDestroy()
{
SaveConfig();
}
private void ApplyConfig()
{
foreach (var f in config.probability)
{
if (audioFilePath.ContainsKey(f.Key))
{
audioFilePath[f.Key] = f.Value;
}
}
}
private void SaveConfig()
{
config.probability.Clear();
foreach (var f in audioFilePath)
{
config.probability.Add(f.Key, f.Value);
}
config.SaveConfig(configFilePath);
}
private void FindWavFiles()
{
@@ -55,7 +93,7 @@ namespace HitFeedback
{
foreach (string filePath in files)
{
audioFilePath.Add(filePath);
audioFilePath.Add(Path.GetFileName(filePath), 1);
}
}
}
@@ -101,16 +139,21 @@ namespace HitFeedback
{
if (audioFilePath.Count > 0)
{
var randomIndex = Random.Range(0, audioFilePath.Count);
var filePath = audioFilePath[randomIndex];
AudioManager.PostCustomSFX(filePath);
var randomIndex = Random.Range(0, totalWeight);
foreach (var f in audioFilePath)
{
randomIndex -= f.Value;
if (randomIndex <= 0)
{
AudioManager.PostCustomSFX(Path.Combine(audioFolderPath, f.Key));
return;
}
}
}
else
{
Debug.LogWarning("Mod Feedback: No audio clips loaded to play.");
}
}
}
}

View File

@@ -0,0 +1,4 @@
// <autogenerated />
using System;
using System.Reflection;
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]

View File

@@ -0,0 +1,22 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Reflection;
[assembly: System.Reflection.AssemblyCompanyAttribute("HitFeedback")]
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+0206a83f56b5a794fe2f173b4a047cc4f0d4cd90")]
[assembly: System.Reflection.AssemblyProductAttribute("HitFeedback")]
[assembly: System.Reflection.AssemblyTitleAttribute("HitFeedback")]
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]
// 由 MSBuild WriteCodeFragment 类生成。

View File

@@ -0,0 +1 @@
0e8871f70d957c8690d2d7e899b7c26cc6fec6a1db85ba1988bdbe458697eb11

View File

@@ -0,0 +1,8 @@
is_global = true
build_property.RootNamespace = HitFeedback
build_property.ProjectDir = D:\vs_project\DuckovMods\HitFeedback\
build_property.EnableComHosting =
build_property.EnableGeneratedComInterfaceComImportInterop =
build_property.CsWinRTUseWindowsUIXamlProjections = false
build_property.EffectiveAnalysisLevelStyle =
build_property.EnableCodeStyleSeverity =

Binary file not shown.

View File

@@ -13,7 +13,7 @@ using System.Reflection;
[assembly: System.Reflection.AssemblyCompanyAttribute("HitFeedback")]
[assembly: System.Reflection.AssemblyConfigurationAttribute("Release")]
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+2b7943339c8fff4147e07028e81b3fff19ff0d80")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+0206a83f56b5a794fe2f173b4a047cc4f0d4cd90")]
[assembly: System.Reflection.AssemblyProductAttribute("HitFeedback")]
[assembly: System.Reflection.AssemblyTitleAttribute("HitFeedback")]
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]

View File

@@ -1 +1 @@
1ef47fdca68bb8ba079c984a562e35f7d221eeaabc5c5290fb8b33cc52111227
044e9b3ac36cbf242c64f55f40a9077d40727cb97e540d335e1e29dbc7dccff1