diff --git a/OpenTaiko/src/Common/CConfigIni.cs b/OpenTaiko/src/Common/CConfigIni.cs index f8c6a329..a663bde2 100644 --- a/OpenTaiko/src/Common/CConfigIni.cs +++ b/OpenTaiko/src/Common/CConfigIni.cs @@ -1747,7 +1747,7 @@ namespace TJAPlayer3 //---------------------------------------- #endif this.strDTXManiaのバージョン = "Unknown"; - this.str曲データ検索パス = @"." + Path.DirectorySeparatorChar; + this.str曲データ検索パス = @"." + Path.DirectorySeparatorChar + "Songs" + Path.DirectorySeparatorChar; this.b全画面モード = false; this.b垂直帰線待ちを行う = true; this.n初期ウィンドウ開始位置X = 100; // #30675 2013.02.04 ikanick add diff --git a/OpenTaiko/src/Common/C定数.cs b/OpenTaiko/src/Common/C定数.cs index cdc649f9..acbced39 100644 --- a/OpenTaiko/src/Common/C定数.cs +++ b/OpenTaiko/src/Common/C定数.cs @@ -646,6 +646,7 @@ namespace TJAPlayer3 } + [Serializable] [StructLayout( LayoutKind.Sequential )] public struct STAUTOPLAY // Eレーンとindexを一致させること { diff --git a/OpenTaiko/src/Common/TJAPlayer3.cs b/OpenTaiko/src/Common/TJAPlayer3.cs index 7b6b2f55..83432803 100644 --- a/OpenTaiko/src/Common/TJAPlayer3.cs +++ b/OpenTaiko/src/Common/TJAPlayer3.cs @@ -3090,6 +3090,7 @@ for (int i = 0; i < 3; i++) { Trace.TraceInformation( "■ アプリケーションの終了" ); #region [ 曲検索の終了処理 ] //--------------------- + if ( actEnumSongs != null ) { Trace.TraceInformation( "曲検索actの終了処理を行います。" ); @@ -3172,6 +3173,15 @@ for (int i = 0; i < 3; i++) { Trace.Indent(); try { +#pragma warning disable SYSLIB0011 + if (EnumSongs.IsSongListEnumCompletelyDone) + { + BinaryFormatter songlistdb_ = new BinaryFormatter(); + using Stream songlistdb = File.OpenWrite($"{TJAPlayer3.strEXEのあるフォルダ}songlist.db"); + songlistdb_.Serialize(songlistdb, Songs管理.listSongsDB); + } +#pragma warning restore SYSLIB0011 + Songs管理 = null; Trace.TraceInformation( "曲リストの終了処理を完了しました。" ); } diff --git a/OpenTaiko/src/Songs/CDTX.cs b/OpenTaiko/src/Songs/CDTX.cs index d7c64b5f..49d76441 100644 --- a/OpenTaiko/src/Songs/CDTX.cs +++ b/OpenTaiko/src/Songs/CDTX.cs @@ -175,6 +175,7 @@ namespace TJAPlayer3 public bool bHit; public bool b可視 = true; public bool bHideBarLine = true; + public bool bProcessed = false; public bool bShow; public bool bShowRoll; public bool bBranch = false; @@ -655,9 +656,12 @@ namespace TJAPlayer3 #endregion } + [Serializable] public class DanSongs { + [NonSerialized] public CTexture TitleTex; + [NonSerialized] public CTexture SubTitleTex; public string Title; public string SubTitle; @@ -670,6 +674,8 @@ namespace TJAPlayer3 public static int Number = 0; public bool bTitleShow; public Dan_C[] Dan_C = new Dan_C[CExamInfo.cMaxExam]; + + [NonSerialized] public CWAV Wave; public DanSongs() @@ -1212,7 +1218,7 @@ namespace TJAPlayer3 public List listLyric; //歌詞を格納していくリスト。スペル忘れた(ぉい public List listLyric2; - public Dictionary kusudaMAP = new Dictionary(); + //public Dictionary kusudaMAP = new Dictionary(); public bool usingLyricsFile; //If lyric file is used (VTT/LRC), ignore #LYRIC tags & do not parse other lyric file tags @@ -1600,6 +1606,7 @@ namespace TJAPlayer3 // Replace non-shared kusudamas by balloons #region [Sync check] + /* for (int i = 0; i < TJAPlayer3.ConfigIni.nPlayerCount; i++) { CDTX dtx = dtxarr[i]; @@ -1620,10 +1627,12 @@ namespace TJAPlayer3 } } } + */ #endregion // Stack balloon values to all remining (= existing) kusudamas to player 1 #region [Accumulation] + /* CDTX dtx1 = dtxarr[0]; if (dtx1 == null) return; foreach (KeyValuePair kvp in dtx1.kusudaMAP) @@ -1653,6 +1662,7 @@ namespace TJAPlayer3 } } + */ #endregion } @@ -2427,6 +2437,8 @@ namespace TJAPlayer3 case 0x15: case 0x16: case 0x17: + case 0x19: + case 0x1D: case 0x20: case 0x21: { @@ -6469,6 +6481,7 @@ namespace TJAPlayer3 int? nReturnChip = null; //--して取得しないとだめよ~ダメダメ💛 + //:damedane: for (int i = listChips.Count - 1; i >= 0; i--) { if (b分岐前の連打開始) @@ -6705,13 +6718,11 @@ namespace TJAPlayer3 { if (IsEndedBranching) { - if (!this.kusudaMAP.ContainsKey(chip.n発声時刻ms)) - kusudaMAP[chip.n発声時刻ms] = chip; } else { // Balloon in branches - chip.nチャンネル番号 = 0x17; + chip.nチャンネル番号 = 0x19; } } diff --git a/OpenTaiko/src/Songs/CScoreIni.cs b/OpenTaiko/src/Songs/CScoreIni.cs index 29a6bc92..5e9144fb 100644 --- a/OpenTaiko/src/Songs/CScoreIni.cs +++ b/OpenTaiko/src/Songs/CScoreIni.cs @@ -12,12 +12,15 @@ using TJAPlayer3; namespace TJAPlayer3 { + [Serializable] public class CScoreIni { // プロパティ // [File] セクション public STファイル stファイル; + + [Serializable] [StructLayout( LayoutKind.Sequential )] public struct STファイル { @@ -42,6 +45,8 @@ namespace TJAPlayer3 // 演奏記録セクション(9種類) public STセクション stセクション; + + [Serializable] [StructLayout( LayoutKind.Sequential )] public struct STセクション { @@ -161,6 +166,8 @@ namespace TJAPlayer3 E = 6, UNKNOWN = 99 } + + [Serializable] public class C演奏記録 { public STAUTOPLAY bAutoPlay; diff --git a/OpenTaiko/src/Songs/CSongUniqueID.cs b/OpenTaiko/src/Songs/CSongUniqueID.cs index c0ab3378..08d3d0dd 100644 --- a/OpenTaiko/src/Songs/CSongUniqueID.cs +++ b/OpenTaiko/src/Songs/CSongUniqueID.cs @@ -42,6 +42,7 @@ namespace TJAPlayer3 #endregion + [Serializable] public class Data { public string id = ""; diff --git a/OpenTaiko/src/Songs/CSong管理.cs b/OpenTaiko/src/Songs/CSong管理.cs index 4b9bf940..7928a5d0 100644 --- a/OpenTaiko/src/Songs/CSong管理.cs +++ b/OpenTaiko/src/Songs/CSong管理.cs @@ -9,6 +9,7 @@ using System.Threading; using TJAPlayer3.C曲リストノードComparers; using FDK; using System.Drawing; +using System.Security.Cryptography; namespace TJAPlayer3 { @@ -47,8 +48,7 @@ namespace TJAPlayer3 get; set; } - /*[NonSerialized] - public List listSongsDB;*/ // songs.dbから構築されるlist + public Dictionary listSongsDB; // songs.dbから構築されるlist public List list曲ルート; // 起動時にフォルダ検索して構築されるlist public List list曲ルート_Dan = new List(); // 起動時にフォルダ検索して構築されるlist public List list曲ルート_Tower = new List(); // 起動時にフォルダ検索して構築されるlist @@ -83,7 +83,7 @@ namespace TJAPlayer3 public CSongs管理() { - //this.listSongsDB = new List(); + this.listSongsDB = new (); this.list曲ルート = new List(); this.n検索された曲ノード数 = 0; this.n検索されたスコア数 = 0; @@ -151,7 +151,6 @@ namespace TJAPlayer3 t曲を検索してリストを作成する(path, true, downloadBox.list子リスト, downloadBox); this.t曲リストへ後処理を適用する(downloadBox.list子リスト, $"/{downloadBox.strタイトル}/"); - tSongsDBになかった曲をファイルから読み込んで反映する(downloadBox.list子リスト); downloadBox.list子リスト.Insert(0, CSongDict.tGenerateBackButton(downloadBox, $"/{downloadBox.strタイトル}/")); } } @@ -204,7 +203,6 @@ namespace TJAPlayer3 #region[ 新処理 ] - CDTX dtx = new CDTX( fileinfo.FullName, false, 1.0, 0, 1 ); C曲リストノード c曲リストノード = new C曲リストノード(); c曲リストノード.eノード種別 = C曲リストノード.Eノード種別.SCORE; @@ -212,6 +210,7 @@ namespace TJAPlayer3 bool b = false; for( int n = 0; n < (int)Difficulty.Total; n++ ) { + CDTX dtx = new CDTX( fileinfo.FullName, false, 1.0, 0, 1 ); if( dtx.b譜面が存在する[ n ] ) { c曲リストノード.nスコア数++; @@ -284,6 +283,9 @@ namespace TJAPlayer3 c曲リストノード.arスコア[ n ].ScoreIni情報.ファイルサイズ = infoScoreIni.Length; c曲リストノード.arスコア[ n ].ScoreIni情報.最終更新日時 = infoScoreIni.LastWriteTime; } + + LoadChartInfo(c曲リストノード, dtx, n); + if( b == false ) { this.n検索されたスコア数++; @@ -293,7 +295,6 @@ namespace TJAPlayer3 } } } - dtx = null; } #endregion } @@ -332,202 +333,241 @@ namespace TJAPlayer3 //} #region[ 新処理 ] - CDTX dtx = new CDTX( str基点フォルダ + fileinfo.Name, false, 1.0, 0, 0 ); - C曲リストノード c曲リストノード = new C曲リストノード(); - c曲リストノード.eノード種別 = C曲リストノード.Eノード種別.SCORE; - bool b = false; - for( int n = 0; n < (int)Difficulty.Total; n++ ) - { - if( dtx.b譜面が存在する[ n ] ) - { - c曲リストノード.nスコア数++; - c曲リストノード.r親ノード = node親; - c曲リストノード.strBreadcrumbs = ( c曲リストノード.r親ノード == null ) ? - str基点フォルダ + fileinfo.Name : c曲リストノード.r親ノード.strBreadcrumbs + " > " + str基点フォルダ + fileinfo.Name; + string filePath = str基点フォルダ + fileinfo.Name; - c曲リストノード.strタイトル = dtx.TITLE; - c曲リストノード.strサブタイトル = dtx.SUBTITLE; - c曲リストノード.strMaker = dtx.MAKER; - c曲リストノード.nSide = dtx.SIDE; - c曲リストノード.bExplicit = dtx.EXPLICIT; + using SHA1 hashProvider = SHA1.Create(); + var fs = File.OpenRead(filePath); + byte[] rawhash = hashProvider.ComputeHash(fs); + string hash = ""; + for (int i = 0; i < rawhash.Length; i++) { + hash += string.Format("{0:X2}", rawhash[i]); + } - if (dtx.List_DanSongs != null) - c曲リストノード.DanSongs = dtx.List_DanSongs; + fs.Dispose(); - if (dtx.Dan_C != null) - c曲リストノード.Dan_C = dtx.Dan_C; + if (listSongsDB.TryGetValue(filePath + hash, out C曲リストノード value)) + { + this.n検索されたスコア数++; + listノードリスト.Add( value ); + CSongDict.tAddSongNode(value.uniqueId, value); + value.r親ノード = node親; + this.n検索された曲ノード数++; + } + else + { + CDTX dtx = new CDTX(filePath , false, 1.0, 0, 0 ); + C曲リストノード c曲リストノード = new C曲リストノード(); + c曲リストノード.eノード種別 = C曲リストノード.Eノード種別.SCORE; - if (!string.IsNullOrEmpty(dtx.GENRE)) + bool b = false; + for( int n = 0; n < (int)Difficulty.Total; n++ ) + { + if( dtx.b譜面が存在する[ n ] ) { - if(c曲リストノード.r親ノード != null) + c曲リストノード.nスコア数++; + c曲リストノード.r親ノード = node親; + c曲リストノード.strBreadcrumbs = ( c曲リストノード.r親ノード == null ) ? + str基点フォルダ + fileinfo.Name : c曲リストノード.r親ノード.strBreadcrumbs + " > " + str基点フォルダ + fileinfo.Name; + + c曲リストノード.strタイトル = dtx.TITLE; + c曲リストノード.strサブタイトル = dtx.SUBTITLE; + c曲リストノード.strMaker = dtx.MAKER; + c曲リストノード.nSide = dtx.SIDE; + c曲リストノード.bExplicit = dtx.EXPLICIT; + + if (dtx.TITLE == "例2") + { + + } + + c曲リストノード.DanSongs = new (); + if (dtx.List_DanSongs != null) + { + for(int i = 0; i < dtx.List_DanSongs.Count; i++) + { + c曲リストノード.DanSongs.Add(dtx.List_DanSongs[i]); + } + } + + if (dtx.Dan_C != null) + c曲リストノード.Dan_C = dtx.Dan_C; + + if (!string.IsNullOrEmpty(dtx.GENRE)) + { + if(c曲リストノード.r親ノード != null) + { + c曲リストノード.strジャンル = c曲リストノード.r親ノード.strジャンル; + c曲リストノード.str本当のジャンル = dtx.GENRE; + } + else + { + c曲リストノード.strジャンル = dtx.GENRE; + c曲リストノード.str本当のジャンル = dtx.GENRE; + } + } + else { c曲リストノード.strジャンル = c曲リストノード.r親ノード.strジャンル; - c曲リストノード.str本当のジャンル = dtx.GENRE; + c曲リストノード.str本当のジャンル = c曲リストノード.r親ノード.strジャンル; } - else - { - c曲リストノード.strジャンル = dtx.GENRE; - c曲リストノード.str本当のジャンル = dtx.GENRE; - } - } - else - { - c曲リストノード.strジャンル = c曲リストノード.r親ノード.strジャンル; - c曲リストノード.str本当のジャンル = c曲リストノード.r親ノード.strジャンル; - } - if (c曲リストノード.strSelectBGPath == null || !File.Exists(str基点フォルダ + dtx.SELECTBG)) - { - c曲リストノード.strSelectBGPath = c曲リストノード.r親ノード.strSelectBGPath; - } - else - { - c曲リストノード.strSelectBGPath = str基点フォルダ + dtx.SELECTBG; - } - if (!File.Exists(c曲リストノード.strSelectBGPath)) c曲リストノード.strSelectBGPath = null; + if (c曲リストノード.strSelectBGPath == null || !File.Exists(str基点フォルダ + dtx.SELECTBG)) + { + c曲リストノード.strSelectBGPath = c曲リストノード.r親ノード.strSelectBGPath; + } + else + { + c曲リストノード.strSelectBGPath = str基点フォルダ + dtx.SELECTBG; + } + if (!File.Exists(c曲リストノード.strSelectBGPath)) c曲リストノード.strSelectBGPath = null; - if (c曲リストノード.r親ノード != null) - { - c曲リストノード.strScenePreset = c曲リストノード.r親ノード.strScenePreset; - if (c曲リストノード.r親ノード.IsChangedForeColor) - { - c曲リストノード.ForeColor = c曲リストノード.r親ノード.ForeColor; - c曲リストノード.IsChangedForeColor = true; - } - if (c曲リストノード.r親ノード.IsChangedBackColor) - { - c曲リストノード.BackColor = c曲リストノード.r親ノード.BackColor; - c曲リストノード.IsChangedBackColor = true; - } - if (c曲リストノード.r親ノード.isChangedBoxColor) - { - c曲リストノード.BoxColor = c曲リストノード.r親ノード.BoxColor; - c曲リストノード.isChangedBoxColor = true; - } - if (c曲リストノード.r親ノード.isChangedBgColor) + if (c曲リストノード.r親ノード != null) { - c曲リストノード.BgColor = c曲リストノード.r親ノード.BgColor; - c曲リストノード.isChangedBgColor = true; - } - if (c曲リストノード.r親ノード.isChangedBgType) - { - c曲リストノード.BgType = c曲リストノード.r親ノード.BgType; - c曲リストノード.isChangedBgType = true; - } - if (c曲リストノード.r親ノード.isChangedBoxType) - { - c曲リストノード.BoxType = c曲リストノード.r親ノード.BoxType; - c曲リストノード.isChangedBoxType = true; - } - if (c曲リストノード.r親ノード.isChangedBoxChara) - { - c曲リストノード.BoxChara = c曲リストノード.r親ノード.BoxChara; - c曲リストノード.isChangedBoxChara = true; - } - + c曲リストノード.strScenePreset = c曲リストノード.r親ノード.strScenePreset; + if (c曲リストノード.r親ノード.IsChangedForeColor) + { + c曲リストノード.ForeColor = c曲リストノード.r親ノード.ForeColor; + c曲リストノード.IsChangedForeColor = true; + } + if (c曲リストノード.r親ノード.IsChangedBackColor) + { + c曲リストノード.BackColor = c曲リストノード.r親ノード.BackColor; + c曲リストノード.IsChangedBackColor = true; + } + if (c曲リストノード.r親ノード.isChangedBoxColor) + { + c曲リストノード.BoxColor = c曲リストノード.r親ノード.BoxColor; + c曲リストノード.isChangedBoxColor = true; + } + if (c曲リストノード.r親ノード.isChangedBgColor) + { + c曲リストノード.BgColor = c曲リストノード.r親ノード.BgColor; + c曲リストノード.isChangedBgColor = true; + } + if (c曲リストノード.r親ノード.isChangedBgType) + { + c曲リストノード.BgType = c曲リストノード.r親ノード.BgType; + c曲リストノード.isChangedBgType = true; + } + if (c曲リストノード.r親ノード.isChangedBoxType) + { + c曲リストノード.BoxType = c曲リストノード.r親ノード.BoxType; + c曲リストノード.isChangedBoxType = true; + } + if (c曲リストノード.r親ノード.isChangedBoxChara) + { + c曲リストノード.BoxChara = c曲リストノード.r親ノード.BoxChara; + c曲リストノード.isChangedBoxChara = true; + } - } + + } - switch (CStrジャンルtoNum.ForAC15(c曲リストノード.strジャンル)) - { - case 0: - c曲リストノード.ForeColor = TJAPlayer3.Skin.SongSelect_ForeColor_JPOP; - c曲リストノード.BackColor = TJAPlayer3.Skin.SongSelect_BackColor_JPOP; - break; - case 1: - c曲リストノード.ForeColor = TJAPlayer3.Skin.SongSelect_ForeColor_Anime; - c曲リストノード.BackColor = TJAPlayer3.Skin.SongSelect_BackColor_Anime; - break; - case 2: - c曲リストノード.ForeColor = TJAPlayer3.Skin.SongSelect_ForeColor_VOCALOID; - c曲リストノード.BackColor = TJAPlayer3.Skin.SongSelect_BackColor_VOCALOID; - break; - case 3: - c曲リストノード.ForeColor = TJAPlayer3.Skin.SongSelect_ForeColor_Children; - c曲リストノード.BackColor = TJAPlayer3.Skin.SongSelect_BackColor_Children; - break; - case 4: - c曲リストノード.ForeColor = TJAPlayer3.Skin.SongSelect_ForeColor_Variety; - c曲リストノード.BackColor = TJAPlayer3.Skin.SongSelect_BackColor_Variety; - break; - case 5: - c曲リストノード.ForeColor = TJAPlayer3.Skin.SongSelect_ForeColor_Classic; - c曲リストノード.BackColor = TJAPlayer3.Skin.SongSelect_BackColor_Classic; - break; - case 6: - c曲リストノード.ForeColor = TJAPlayer3.Skin.SongSelect_ForeColor_GameMusic; - c曲リストノード.BackColor = TJAPlayer3.Skin.SongSelect_BackColor_GameMusic; - break; - case 7: - c曲リストノード.ForeColor = TJAPlayer3.Skin.SongSelect_ForeColor_Namco; - c曲リストノード.BackColor = TJAPlayer3.Skin.SongSelect_BackColor_Namco; - break; - default: - break; - } + switch (CStrジャンルtoNum.ForAC15(c曲リストノード.strジャンル)) + { + case 0: + c曲リストノード.ForeColor = TJAPlayer3.Skin.SongSelect_ForeColor_JPOP; + c曲リストノード.BackColor = TJAPlayer3.Skin.SongSelect_BackColor_JPOP; + break; + case 1: + c曲リストノード.ForeColor = TJAPlayer3.Skin.SongSelect_ForeColor_Anime; + c曲リストノード.BackColor = TJAPlayer3.Skin.SongSelect_BackColor_Anime; + break; + case 2: + c曲リストノード.ForeColor = TJAPlayer3.Skin.SongSelect_ForeColor_VOCALOID; + c曲リストノード.BackColor = TJAPlayer3.Skin.SongSelect_BackColor_VOCALOID; + break; + case 3: + c曲リストノード.ForeColor = TJAPlayer3.Skin.SongSelect_ForeColor_Children; + c曲リストノード.BackColor = TJAPlayer3.Skin.SongSelect_BackColor_Children; + break; + case 4: + c曲リストノード.ForeColor = TJAPlayer3.Skin.SongSelect_ForeColor_Variety; + c曲リストノード.BackColor = TJAPlayer3.Skin.SongSelect_BackColor_Variety; + break; + case 5: + c曲リストノード.ForeColor = TJAPlayer3.Skin.SongSelect_ForeColor_Classic; + c曲リストノード.BackColor = TJAPlayer3.Skin.SongSelect_BackColor_Classic; + break; + case 6: + c曲リストノード.ForeColor = TJAPlayer3.Skin.SongSelect_ForeColor_GameMusic; + c曲リストノード.BackColor = TJAPlayer3.Skin.SongSelect_BackColor_GameMusic; + break; + case 7: + c曲リストノード.ForeColor = TJAPlayer3.Skin.SongSelect_ForeColor_Namco; + c曲リストノード.BackColor = TJAPlayer3.Skin.SongSelect_BackColor_Namco; + break; + default: + break; + } - c曲リストノード.nLevel = dtx.LEVELtaiko; - c曲リストノード.nLevelIcon = dtx.LEVELtaikoIcon; - c曲リストノード.uniqueId = dtx.uniqueID; + c曲リストノード.nLevel = dtx.LEVELtaiko; + c曲リストノード.nLevelIcon = dtx.LEVELtaikoIcon; + c曲リストノード.uniqueId = dtx.uniqueID; - CSongDict.tAddSongNode(c曲リストノード.uniqueId, c曲リストノード); + CSongDict.tAddSongNode(c曲リストノード.uniqueId, c曲リストノード); - c曲リストノード.arスコア[ n ] = new Cスコア(); - c曲リストノード.arスコア[ n ].ファイル情報.ファイルの絶対パス = str基点フォルダ + fileinfo.Name; - c曲リストノード.arスコア[ n ].ファイル情報.フォルダの絶対パス = str基点フォルダ; - c曲リストノード.arスコア[ n ].ファイル情報.ファイルサイズ = fileinfo.Length; - c曲リストノード.arスコア[ n ].ファイル情報.最終更新日時 = fileinfo.LastWriteTime; + c曲リストノード.arスコア[ n ] = new Cスコア(); + c曲リストノード.arスコア[ n ].ファイル情報.ファイルの絶対パス = str基点フォルダ + fileinfo.Name; + c曲リストノード.arスコア[ n ].ファイル情報.フォルダの絶対パス = str基点フォルダ; + c曲リストノード.arスコア[ n ].ファイル情報.ファイルサイズ = fileinfo.Length; + c曲リストノード.arスコア[ n ].ファイル情報.最終更新日時 = fileinfo.LastWriteTime; - if (c曲リストノード.r親ノード != null && String.IsNullOrEmpty(c曲リストノード.arスコア[n].譜面情報.Preimage)) - { - c曲リストノード.arスコア[n].譜面情報.Preimage = c曲リストノード.r親ノード.arスコア[0].譜面情報.Preimage; - } + if (c曲リストノード.r親ノード != null && String.IsNullOrEmpty(c曲リストノード.arスコア[n].譜面情報.Preimage)) + { + c曲リストノード.arスコア[n].譜面情報.Preimage = c曲リストノード.r親ノード.arスコア[0].譜面情報.Preimage; + } - string strFileNameScoreIni = c曲リストノード.arスコア[ n ].ファイル情報.ファイルの絶対パス + ".score.ini"; - if( File.Exists( strFileNameScoreIni ) ) - { - FileInfo infoScoreIni = new FileInfo( strFileNameScoreIni ); - c曲リストノード.arスコア[ n ].ScoreIni情報.ファイルサイズ = infoScoreIni.Length; - c曲リストノード.arスコア[ n ].ScoreIni情報.最終更新日時 = infoScoreIni.LastWriteTime; - } - if( b == false ) - { - this.n検索されたスコア数++; - listノードリスト.Add( c曲リストノード ); - this.n検索された曲ノード数++; - b = true; - } + string strFileNameScoreIni = c曲リストノード.arスコア[ n ].ファイル情報.ファイルの絶対パス + ".score.ini"; + if( File.Exists( strFileNameScoreIni ) ) + { + FileInfo infoScoreIni = new FileInfo( strFileNameScoreIni ); + c曲リストノード.arスコア[ n ].ScoreIni情報.ファイルサイズ = infoScoreIni.Length; + c曲リストノード.arスコア[ n ].ScoreIni情報.最終更新日時 = infoScoreIni.LastWriteTime; + } - if( TJAPlayer3.ConfigIni.bLog曲検索ログ出力 ) - { - // Trace.Indent(); - // try - // { - // StringBuilder sb = new StringBuilder( 0x100 ); - // sb.Append( string.Format( "nID#{0:D3}", c曲リストノード.nID ) ); - // if( c曲リストノード.r親ノード != null ) - // { - // sb.Append( string.Format( "(in#{0:D3}):", c曲リストノード.r親ノード.nID ) ); - // } - // else - // { - // sb.Append( "(onRoot):" ); - // } - // sb.Append( " SONG, File=" + c曲リストノード.arスコア[ 0 ].ファイル情報.ファイルの絶対パス ); - // sb.Append( ", Size=" + c曲リストノード.arスコア[ 0 ].ファイル情報.ファイルサイズ ); - // sb.Append( ", LastUpdate=" + c曲リストノード.arスコア[ 0 ].ファイル情報.最終更新日時 ); - // Trace.TraceInformation( sb.ToString() ); - // } - // finally - // { - // Trace.Unindent(); - // } - } - } - } + LoadChartInfo(c曲リストノード, dtx, n); + + if( b == false ) + { + this.n検索されたスコア数++; + listノードリスト.Add( c曲リストノード ); + if (!listSongsDB.ContainsKey(filePath + hash)) listSongsDB.Add(filePath + hash, c曲リストノード ); + this.n検索された曲ノード数++; + b = true; + } + + if( TJAPlayer3.ConfigIni.bLog曲検索ログ出力 ) + { + // Trace.Indent(); + // try + // { + // StringBuilder sb = new StringBuilder( 0x100 ); + // sb.Append( string.Format( "nID#{0:D3}", c曲リストノード.nID ) ); + // if( c曲リストノード.r親ノード != null ) + // { + // sb.Append( string.Format( "(in#{0:D3}):", c曲リストノード.r親ノード.nID ) ); + // } + // else + // { + // sb.Append( "(onRoot):" ); + // } + // sb.Append( " SONG, File=" + c曲リストノード.arスコア[ 0 ].ファイル情報.ファイルの絶対パス ); + // sb.Append( ", Size=" + c曲リストノード.arスコア[ 0 ].ファイル情報.ファイルサイズ ); + // sb.Append( ", LastUpdate=" + c曲リストノード.arスコア[ 0 ].ファイル情報.最終更新日時 ); + // Trace.TraceInformation( sb.ToString() ); + // } + // finally + // { + // Trace.Unindent(); + // } + } + } + } + } #endregion } } @@ -731,29 +771,9 @@ namespace TJAPlayer3 } //----------------- #endregion - - #region [ SongsDBになかった曲をファイルから読み込んで反映する ] - //----------------- - public void tSongsDBになかった曲をファイルから読み込んで反映する() - { - this.nファイルから反映できたスコア数 = 0; - this.tSongsDBになかった曲をファイルから読み込んで反映する( this.list曲ルート ); - } - private void tSongsDBになかった曲をファイルから読み込んで反映する( List ノードリスト ) - { - foreach( C曲リストノード c曲リストノード in ノードリスト ) - { - SlowOrSuspendSearchTask(); // #27060 中断要求があったら、解除要求が来るまで待機, #PREMOVIE再生中は検索負荷を落とす - if( c曲リストノード.eノード種別 == C曲リストノード.Eノード種別.BOX ) - { - this.tSongsDBになかった曲をファイルから読み込んで反映する( c曲リストノード.list子リスト ); - } - else if( ( c曲リストノード.eノード種別 == C曲リストノード.Eノード種別.SCORE ) - || ( c曲リストノード.eノード種別 == C曲リストノード.Eノード種別.SCORE_MIDI ) ) - { - for( int i = 0; i < (int)Difficulty.Total; i++ ) - { + private void LoadChartInfo(C曲リストノード c曲リストノード, CDTX cdtx, int i) + { if( ( c曲リストノード.arスコア[ i ] != null ) && !c曲リストノード.arスコア[ i ].bSongDBにキャッシュがあった ) { #region [ DTX ファイルのヘッダだけ読み込み、Cスコア.譜面情報 を設定する ] @@ -763,10 +783,6 @@ namespace TJAPlayer3 { try { - CDTX cdtx = new CDTX( c曲リストノード.arスコア[ i ].ファイル情報.ファイルの絶対パス, true, 0, 0, 0 ); - if( File.Exists( c曲リストノード.arスコア[ i ].ファイル情報.フォルダの絶対パス + "set.def" ) ) - cdtx = new CDTX( c曲リストノード.arスコア[ i ].ファイル情報.ファイルの絶対パス, true, 0, 0, 1 ); - c曲リストノード.arスコア[ i ].譜面情報.タイトル = cdtx.TITLE; @@ -866,12 +882,7 @@ namespace TJAPlayer3 //----------------- try { - var scoreIniPath = c曲リストノード.arスコア[i].ファイル情報.ファイルの絶対パス;// + ".score.ini"; - - if( File.Exists( scoreIniPath ) ) - { - this.tScoreIniを読み込んで譜面情報を設定する(scoreIniPath, c曲リストノード.arスコア[i]); - } + this.tScoreIniを読み込んで譜面情報を設定する(c曲リストノード.arスコア[i].ファイル情報.ファイルの絶対パス, c曲リストノード.arスコア[i]); // Legacy save files from DTX mania /* else @@ -893,12 +904,7 @@ namespace TJAPlayer3 //----------------- #endregion } - } - } - } } - //----------------- - #endregion #region [ 曲リストへ後処理を適用する ] //----------------- @@ -953,14 +959,18 @@ namespace TJAPlayer3 this.t曲リストへ後処理を適用する(this.list曲ルート); - foreach (C曲リストノード c曲リストノード in list曲ルート) + for (int p = 0; p < list曲ルート.Count; p++) { + var c曲リストノード = list曲ルート[p]; if (c曲リストノード.eノード種別 == C曲リストノード.Eノード種別.BOX) { if (c曲リストノード.strジャンル == "段位道場") { if (TJAPlayer3.ConfigIni.bDanTowerHide) + { list曲ルート.Remove(c曲リストノード); + p--; + } // Add to dojo list曲ルート_Dan = c曲リストノード.list子リスト; @@ -978,7 +988,10 @@ namespace TJAPlayer3 else if (c曲リストノード.strジャンル == "太鼓タワー") { if (TJAPlayer3.ConfigIni.bDanTowerHide) + { list曲ルート.Remove(c曲リストノード); + p--; + } list曲ルート_Tower = c曲リストノード.list子リスト; } @@ -1461,6 +1474,38 @@ Debug.WriteLine( dBPM + ":" + c曲リストノード.strタイトル ); { //var ini = new CScoreIni( strScoreIniファイルパス ); + /* + CScoreIni getScoreIni(string filePath) + { + if (!File.Exists(filePath)) + { + var result = new CScoreIni(filePath); + return result; + } + + using SHA1 hashProvider = SHA1.Create(); + var fs = File.OpenRead(filePath); + byte[] rawhash = hashProvider.ComputeHash(fs); + string hash = ""; + for (int i = 0; i < rawhash.Length; i++) { + hash += string.Format("{0:X2}", rawhash[i]); + } + + fs.Dispose(); + + if (listScoreDB.TryGetValue(hash, out CScoreIni value)) + { + return value; + } + else + { + var result = new CScoreIni(filePath); + listScoreDB.Add(hash, result); + return result; + } + } + */ + CScoreIni[] csi = { //new CScoreIni(fp[mainFile]), diff --git a/OpenTaiko/src/Songs/Cスコア.cs b/OpenTaiko/src/Songs/Cスコア.cs index 9572c7cd..1a0d8917 100644 --- a/OpenTaiko/src/Songs/Cスコア.cs +++ b/OpenTaiko/src/Songs/Cスコア.cs @@ -47,18 +47,18 @@ namespace TJAPlayer3 } } - public ST譜面情報 譜面情報; - - // Smaller version of ST譜面情報 to keep the main info for each player (High scores, clear status, score ranks + public ST譜面情報 譜面情報; + + // Smaller version of ST譜面情報 to keep the main info for each player (High scores, clear status, score ranks public STGamePlayInformations[] GPInfo = new STGamePlayInformations[5]; [Serializable] [StructLayout(LayoutKind.Sequential)] - public struct STGamePlayInformations - { + public struct STGamePlayInformations + { public int[] nHighScore; - public int[] nClear; //0:未クリア 1:クリア 2:フルコンボ 3:ドンダフルコンボ - public int[] nScoreRank; //0:未取得 1:白粋 2:銅粋 3:銀粋 4:金雅 5:桃雅 6:紫雅 7:虹極 + public int[] nClear; //0:未クリア 1:クリア 2:フルコンボ 3:ドンダフルコンボ + public int[] nScoreRank; //0:未取得 1:白粋 2:銅粋 3:銀粋 4:金雅 5:桃雅 6:紫雅 7:虹極 } [Serializable] @@ -96,10 +96,10 @@ namespace TJAPlayer3 public string strサブタイトル; public int[] nレベル; public int[] nクリア; //0:未クリア 1:クリア 2:フルコンボ 3:ドンダフルコンボ - public int[] nスコアランク; //0:未取得 1:白粋 2:銅粋 3:銀粋 4:金雅 5:桃雅 6:紫雅 7:虹極 - public CDTX.ELevelIcon[] nLevelIcon; - - // Tower lifes + public int[] nスコアランク; //0:未取得 1:白粋 2:銅粋 3:銀粋 4:金雅 5:桃雅 6:紫雅 7:虹極 + public CDTX.ELevelIcon[] nLevelIcon; + + // Tower lifes public int nLife; public int nTotalFloor; public int nTowerType; @@ -337,22 +337,22 @@ namespace TJAPlayer3 this.譜面情報.ハイスコア = 0; this.譜面情報.nハイスコア = new int[(int)Difficulty.Total]; this.譜面情報.strサブタイトル = ""; - this.譜面情報.nレベル = new int[(int)Difficulty.Total] { -1, -1, -1, -1, -1, -1, -1}; - this.譜面情報.nLevelIcon = new CDTX.ELevelIcon[(int)Difficulty.Total] { CDTX.ELevelIcon.eNone, CDTX.ELevelIcon.eNone, CDTX.ELevelIcon.eNone, CDTX.ELevelIcon.eNone, CDTX.ELevelIcon.eNone, CDTX.ELevelIcon.eNone, CDTX.ELevelIcon.eNone }; + this.譜面情報.nレベル = new int[(int)Difficulty.Total] { -1, -1, -1, -1, -1, -1, -1}; + this.譜面情報.nLevelIcon = new CDTX.ELevelIcon[(int)Difficulty.Total] { CDTX.ELevelIcon.eNone, CDTX.ELevelIcon.eNone, CDTX.ELevelIcon.eNone, CDTX.ELevelIcon.eNone, CDTX.ELevelIcon.eNone, CDTX.ELevelIcon.eNone, CDTX.ELevelIcon.eNone }; this.譜面情報.nクリア = new int[5]; this.譜面情報.nスコアランク = new int[5]; - for (int i = 0; i < 5; i++) - { - this.GPInfo[i].nHighScore = new int[(int)Difficulty.Total]; - this.GPInfo[i].nClear = new int[5]; - this.GPInfo[i].nScoreRank = new int[5]; - } - - this.譜面情報.nExamResult = new List { }; - //for (int i = 0; i < TJAPlayer3.stage選曲.r確定された曲.DanSongs.Count; i++) - //{ - // 譜面情報.nExamResult.Add(new int[CExamInfo.cMaxExam]); + for (int i = 0; i < 5; i++) + { + this.GPInfo[i].nHighScore = new int[(int)Difficulty.Total]; + this.GPInfo[i].nClear = new int[5]; + this.GPInfo[i].nScoreRank = new int[5]; + } + + this.譜面情報.nExamResult = new List { }; + //for (int i = 0; i < TJAPlayer3.stage選曲.r確定された曲.DanSongs.Count; i++) + //{ + // 譜面情報.nExamResult.Add(new int[CExamInfo.cMaxExam]); //} this.譜面情報.nLife = 5; diff --git a/OpenTaiko/src/Songs/C曲リストノード.cs b/OpenTaiko/src/Songs/C曲リストノード.cs index 7100748a..cfa58dd9 100644 --- a/OpenTaiko/src/Songs/C曲リストノード.cs +++ b/OpenTaiko/src/Songs/C曲リストノード.cs @@ -83,9 +83,9 @@ namespace TJAPlayer3 // Tower Lives public int nLife = 5; public int nTotalFloor = 140; - public int nTowerType = 0; - - // Unique id + public int nTowerType = 0; + + // Unique id public CSongUniqueID uniqueId; public int nDanTick = 0; @@ -94,10 +94,10 @@ namespace TJAPlayer3 public string[] strBoxText = new string[3]; public Eジャンル eジャンル = Eジャンル.None; - public string strSelectBGPath; - - // In-game visuals - + public string strSelectBGPath; + + // In-game visuals + public string strScenePreset = null; // コンストラクタ @@ -108,30 +108,30 @@ namespace TJAPlayer3 } public C曲リストノード Clone() - { + { return (C曲リストノード)MemberwiseClone(); } - public override bool Equals(object other) - { - if (other.GetType() == typeof(C曲リストノード)) - { - C曲リストノード obj = (C曲リストノード)other; - return this.nID == obj.nID; - } - return this.GetHashCode() == other.GetHashCode(); - } - - public override int GetHashCode() - { - return base.GetHashCode(); - } - - - // その他 - + public override bool Equals(object other) + { + if (other.GetType() == typeof(C曲リストノード)) + { + C曲リストノード obj = (C曲リストノード)other; + return this.nID == obj.nID; + } + return this.GetHashCode() == other.GetHashCode(); + } + + public override int GetHashCode() + { + return base.GetHashCode(); + } + + + // その他 + #region [ private ] - //----------------- + //----------------- private static int id; //----------------- #endregion diff --git a/OpenTaiko/src/Songs/Dan-C.cs b/OpenTaiko/src/Songs/Dan-C.cs index 0bd18313..f5a9d689 100644 --- a/OpenTaiko/src/Songs/Dan-C.cs +++ b/OpenTaiko/src/Songs/Dan-C.cs @@ -8,6 +8,7 @@ namespace TJAPlayer3 /// /// 段位認定を管理するクラス。 /// + [Serializable] public class Dan_C { public Dan_C() @@ -62,7 +63,7 @@ namespace TJAPlayer3 case Exam.Type.Combo: case Exam.Type.Accuracy: case Exam.Type.JudgeADLIB: - case Exam.Type.JudgeMine: + case Exam.Type.JudgeMine: SetCleared(); break; default: @@ -177,7 +178,7 @@ namespace TJAPlayer3 IsCleared[0] = true; if (GetAmount() >= GetValue(true)) IsCleared[1] = true; - else + else IsCleared[1] = false; } else @@ -225,7 +226,7 @@ namespace TJAPlayer3 case Exam.Type.Gauge: case Exam.Type.JudgePerfect: case Exam.Type.JudgeGood: - case Exam.Type.JudgeBad: + case Exam.Type.JudgeBad: case Exam.Type.JudgeADLIB: case Exam.Type.JudgeMine: case Exam.Type.Score: @@ -246,7 +247,7 @@ namespace TJAPlayer3 case Exam.Type.Gauge: case Exam.Type.JudgePerfect: case Exam.Type.JudgeGood: - case Exam.Type.JudgeBad: + case Exam.Type.JudgeBad: case Exam.Type.JudgeADLIB: case Exam.Type.JudgeMine: case Exam.Type.Score: diff --git a/OpenTaiko/src/Stages/02.Title/CActEnumSongs.cs b/OpenTaiko/src/Stages/02.Title/CActEnumSongs.cs index 17523acf..0e215b34 100644 --- a/OpenTaiko/src/Stages/02.Title/CActEnumSongs.cs +++ b/OpenTaiko/src/Stages/02.Title/CActEnumSongs.cs @@ -59,6 +59,7 @@ namespace TJAPlayer3 { if ( this.IsDeActivated ) return; + base.DeActivate(); this.ctNowEnumeratingSongs = null; } diff --git a/OpenTaiko/src/Stages/02.Title/CEnumSongs.cs b/OpenTaiko/src/Stages/02.Title/CEnumSongs.cs index 33531e43..b753afe1 100644 --- a/OpenTaiko/src/Stages/02.Title/CEnumSongs.cs +++ b/OpenTaiko/src/Stages/02.Title/CEnumSongs.cs @@ -289,47 +289,6 @@ namespace TJAPlayer3 Trace.TraceInformation( "コンパクトモードなので残りの起動処理は省略します。" ); return; } - - #region [ 00) songlist.dbの読み込みによる曲リストの構築 ] - //----------------------------- - TJAPlayer3.stage起動.eフェーズID = CStage.Eフェーズ.起動00_songlistから曲リストを作成する; - - Trace.TraceInformation( "1) songlist.dbを読み込みます。" ); - Trace.Indent(); - - try - { - if ( !TJAPlayer3.ConfigIni.bConfigIniがないかDTXManiaのバージョンが異なる ) - { - CSongs管理 s = new CSongs管理(); - s = Deserialize( strPathSongList ); // 直接this.Songs管理にdeserialize()結果を代入するのは避ける。nullにされてしまうことがあるため。 - if ( s != null ) - { - this.Songs管理 = s; - } - - int scores = this.Songs管理.n検索されたスコア数; - Trace.TraceInformation( "songlist.db の読み込みを完了しました。[{0}スコア]", scores ); - lock ( TJAPlayer3.stage起動.list進行文字列 ) - { - TJAPlayer3.stage起動.list進行文字列.Add( "SONG LIST...OK" ); - } - } - else - { - Trace.TraceInformation( "初回の起動であるかまたはDTXManiaのバージョンが上がったため、songlist.db の読み込みをスキップします。" ); - lock ( TJAPlayer3.stage起動.list進行文字列 ) - { - TJAPlayer3.stage起動.list進行文字列.Add( "SONG LIST...SKIPPED" ); - } - } - } - finally - { - Trace.Unindent(); - } - - #endregion } finally { @@ -359,6 +318,7 @@ namespace TJAPlayer3 try { + Deserialize(); #region [ 2) 曲データの検索 ] //----------------------------- @@ -426,6 +386,7 @@ namespace TJAPlayer3 //----------------------------- // base.eフェーズID = CStage.Eフェーズ.起動4_スコアキャッシュになかった曲をファイルから読み込んで反映する; + /* int num2 = this.Songs管理.n検索されたスコア数 - this.Songs管理.nスコアキャッシュから反映できたスコア数; Trace.TraceInformation( "{0}, {1}", this.Songs管理.n検索されたスコア数, this.Songs管理.nスコアキャッシュから反映できたスコア数 ); @@ -450,6 +411,7 @@ namespace TJAPlayer3 // { // this.list進行文字列.Add( string.Format( "{0} ... {1}/{2}", "Loading score properties from files", CDTXMania.Songs管理_裏読.nファイルから反映できたスコア数, CDTXMania.Songs管理_裏読.n検索されたスコア数 - cs.nスコアキャッシュから反映できたスコア数 ) ); // } + */ //----------------------------- #endregion #region [ 5) 曲リストへの後処理の適用 ] @@ -485,7 +447,7 @@ namespace TJAPlayer3 Trace.TraceInformation( "enum7) 曲データの情報を songlist.db へ出力します。" ); Trace.Indent(); - SerializeSongList( this.Songs管理, strPathSongList ); + SerializeSongList(); Trace.TraceInformation("songlist.db への出力を完了しました。"); Trace.Unindent(); //----------------------------- @@ -507,42 +469,15 @@ namespace TJAPlayer3 } - +#pragma warning disable SYSLIB0011 /// /// 曲リストのserialize /// - private static void SerializeSongList( CSongs管理 cs, string strPathSongList ) + private void SerializeSongList() { - bool bSucceededSerialize = true; - try - { - using(StreamWriter stream = new StreamWriter(strPathSongList)) - { - string temp = JsonSerializer.Serialize(cs); - stream.Write(temp); - } - } - catch ( Exception e ) - { - bSucceededSerialize = false; - Trace.TraceError( e.ToString() ); - Trace.TraceError( "例外が発生しましたが処理を継続します。 (9ad477a4-d922-412c-b87d-e3a49a608e92)" ); - } - finally - { - if ( !bSucceededSerialize ) - { - try - { - File.Delete( strPathSongList ); // serializeに失敗したら、songs2.dbファイルを消しておく - } - catch ( Exception e ) - { - Trace.TraceError( e.ToString() ); - Trace.TraceError( "例外が発生しましたが処理を継続します。 (62860c67-b44f-46f4-b4fc-999c6fe18cce)" ); - } - } - } + BinaryFormatter songlistdb_ = new BinaryFormatter(); + using Stream songlistdb = File.OpenWrite($"{TJAPlayer3.strEXEのあるフォルダ}songlist.db"); + songlistdb_.Serialize(songlistdb, Songs管理.listSongsDB); } /// @@ -550,42 +485,25 @@ namespace TJAPlayer3 /// /// /// - private CSongs管理 Deserialize( string strPathSongList ) + public void Deserialize() { - try - { - #region [ SongListDB(songlist.db)を読み込む ] - - if (!File.Exists(strPathSongList)) - { - return null; - } - - // byte[] buf = File.ReadAllBytes( SongListDBファイル名 ); // 一旦メモリにまとめ読みしてからdeserializeした方が高速かと思ったら全く変わらなかったので削除 - // using ( MemoryStream input = new MemoryStream(buf, false) ) - using ( StreamReader input = new StreamReader(strPathSongList) ) + try { - try + if (File.Exists($"{TJAPlayer3.strEXEのあるフォルダ}songlist.db")) { - return JsonSerializer.Deserialize(input.ReadToEnd()); - } - catch ( Exception e ) - { - // songs管理 = null; - - Trace.TraceError( e.ToString() ); - Trace.TraceError( "例外が発生しましたが処理を継続します。 (a4289e34-7140-4b67-b821-3b5370a725e1)" ); + BinaryFormatter songlistdb_ = new BinaryFormatter(); + using Stream songlistdb = File.OpenRead($"{TJAPlayer3.strEXEのあるフォルダ}songlist.db"); + this.Songs管理.listSongsDB = (Dictionary)songlistdb_.Deserialize(songlistdb); } } - #endregion - } - catch (Exception e) - { - Trace.TraceError( "songlist.db の読み込みに失敗しました。" ); - Trace.TraceError( e.ToString() ); - Trace.TraceError( "例外が発生しましたが処理を継続します。 (5a907ed2-f849-4bc4-acd0-d2a6aa3c9c87)" ); - } - return null; + catch(Exception exception) + { + this.Songs管理.listSongsDB = new(); + } + finally + { + } } + #pragma warning restore SYSLIB0011 } } diff --git a/OpenTaiko/src/Stages/05.SongSelect/CActSelect曲リスト.cs b/OpenTaiko/src/Stages/05.SongSelect/CActSelect曲リスト.cs index d43cba34..f613bc82 100644 --- a/OpenTaiko/src/Stages/05.SongSelect/CActSelect曲リスト.cs +++ b/OpenTaiko/src/Stages/05.SongSelect/CActSelect曲リスト.cs @@ -2956,7 +2956,7 @@ namespace TJAPlayer3 { if (i >= 2) continue; - displayTowerStatus(x + TJAPlayer3.Skin.SongSelect_DanStatus_Offset_X[i], y + TJAPlayer3.Skin.SongSelect_DanStatus_Offset_Y[i], Math.Min(クリア[i][0], 7) - 1, 0.3f); + displayTowerStatus(x + TJAPlayer3.Skin.SongSelect_TowerStatus_Offset_X[i], y + TJAPlayer3.Skin.SongSelect_TowerStatus_Offset_Y[i], Math.Min(クリア[i][0], 7) - 1, 0.3f); } } else @@ -2967,7 +2967,7 @@ namespace TJAPlayer3 { if (i >= 2) continue; - displayRegularCrowns(x + TJAPlayer3.Skin.SongSelect_DanStatus_Offset_X[i], y + TJAPlayer3.Skin.SongSelect_DanStatus_Offset_Y[i], クリア[i], スコアランク[i], 0.8f); + displayRegularCrowns(x + TJAPlayer3.Skin.SongSelect_RegularCrowns_Offset_X[i], y + TJAPlayer3.Skin.SongSelect_RegularCrowns_Offset_Y[i], クリア[i], スコアランク[i], 0.8f); } } diff --git a/OpenTaiko/src/Stages/07.Game/CStage演奏画面共通.cs b/OpenTaiko/src/Stages/07.Game/CStage演奏画面共通.cs index 57bcd992..f51d7b95 100644 --- a/OpenTaiko/src/Stages/07.Game/CStage演奏画面共通.cs +++ b/OpenTaiko/src/Stages/07.Game/CStage演奏画面共通.cs @@ -100,6 +100,7 @@ namespace TJAPlayer3 public override void Activate() { listChip = new List[ 5 ]; + List[] balloonChips = new List[5]; for( int i = 0; i < TJAPlayer3.ConfigIni.nPlayerCount; i++ ) { nNoteCount[i] = 0; @@ -126,6 +127,20 @@ namespace TJAPlayer3 break; } + if (TJAPlayer3.ConfigIni.nPlayerCount >= 2) + { + balloonChips[i] = new(); + for(int j = 0; j < listChip[i].Count; j++) + { + var chip = listChip[i][j]; + + if (NotesManager.IsGenericBalloon(chip)) + { + balloonChips[i].Add(chip); + } + } + } + int n整数値管理 = 0; if (r指定時刻に一番近い未ヒットChipを過去方向優先で検索する(0, i) != null) //2020.07.08 Mr-Ojii 未ヒットチップがないときの例外の発生回避 <-(KabanFriends)コード借りましたごめんなさい(´・ω・`) { @@ -168,6 +183,58 @@ namespace TJAPlayer3 break; } + if (TJAPlayer3.ConfigIni.nPlayerCount >= 2) + { + for(int j = 0; j < balloonChips[i].Count; j++) + { + var chip = balloonChips[i][j]; + if (NotesManager.IsKusudama(chip)) + { + for(int p = 0; p < TJAPlayer3.ConfigIni.nPlayerCount; p++) + { + if (p == i) continue; + var chip2 = balloonChips[p].Find(x => Math.Abs(x.db発声時刻ms - chip.db発声時刻ms) < 100); + + if (chip2 == null) + { + var chip3 = listChip[p].Find(x => Math.Abs(x.db発声時刻ms - chip.db発声時刻ms) < 100); + if (!NotesManager.IsKusudama(chip3)) + { + chip.nチャンネル番号 = 0x17; + } + } + else if (!NotesManager.IsKusudama(chip2)) + { + chip.nチャンネル番号 = 0x17; + } + } + } + } + /* + for(int p = 0; p < TJAPlayer3.ConfigIni.nPlayerCount; p++) + { + for(int j = 0; j < balloonChips[p].Count; j++) + { + var chip = balloonChips[i].Find(x => Math.Abs(x.db発声時刻ms - balloonChips[p][j].db発声時刻ms) < 100); + if (chip == null) + { + var chip2 = listChip[i].Find(x => Math.Abs(x.db発声時刻ms - balloonChips[p][j].db発声時刻ms) < 100); + if (NotesManager.IsKusudama(chip2)) + { + chip.nチャンネル番号 = NotesManager.GetNoteValueFromChar("7"); + } + } + else if (NotesManager.IsKusudama(chip) && !NotesManager.IsKusudama(balloonChips[p][j])) + { + chip.nチャンネル番号 = balloonChips[p][j].nチャンネル番号; + } + } + } + */ + } + + + int _totalNotes = 0; int _totalBalloons = 0; double _totalRolls = 0; @@ -202,7 +269,7 @@ namespace TJAPlayer3 _totalBalloons += Math.Min(_chip.nBalloon, _expectedHits); } - if (NotesManager.IsRoll(_chip)) + if (NotesManager.IsRoll(_chip) || NotesManager.IsFuzeRoll(_chip)) _totalRolls += (_chip.nノーツ終了時刻ms - _chip.n発声時刻ms) / 1000.0; } @@ -363,6 +430,8 @@ namespace TJAPlayer3 this.bUseBranch = new bool[]{ false, false, false, false, false }; this.n現在のコース = new CDTX.ECourse[5]; this.n次回のコース = new CDTX.ECourse[5]; + nCurrentKusudamaRollCount = 0; + nCurrentKusudamaCount = 0; for (int i = 0; i < 5; i++) { @@ -933,6 +1002,8 @@ namespace TJAPlayer3 public double nBranch条件数値A; public double nBranch条件数値B; private readonly int[] NowProcessingChip = new int[] { 0, 0, 0, 0, 0 }; + protected int nCurrentKusudamaRollCount; + protected int nCurrentKusudamaCount; private float _AIBattleState; private Queue[] _AIBattleStateBatch; @@ -1161,7 +1232,7 @@ namespace TJAPlayer3 pChip.nLag = (int) ( nTime - pChip.n発声時刻ms ); // #23580 2011.1.3 yyagi: add "nInputAdjustTime" to add input timing adjust feature int nDeltaTime = Math.Abs( pChip.nLag ); //Debug.WriteLine("nAbsTime=" + (nTime - pChip.n発声時刻ms) + ", nDeltaTime=" + (nTime + nInputAdjustTime - pChip.n発声時刻ms)); - if(NotesManager.IsRoll(pChip)) + if(NotesManager.IsRoll(pChip) || NotesManager.IsFuzeRoll(pChip)) { if ((SoundManager.PlayTimer.NowTimeMs * (((double)TJAPlayer3.ConfigIni.n演奏速度) / 20.0)) > pChip.n発声時刻ms && (SoundManager.PlayTimer.NowTimeMs * (((double)TJAPlayer3.ConfigIni.n演奏速度) / 20.0)) < pChip.nノーツ終了時刻ms) { @@ -1236,7 +1307,7 @@ namespace TJAPlayer3 //while ( nIndex_NearestChip_Future < count ) // 未来方向への検索 for ( ; nIndex_NearestChip_Future < count; nIndex_NearestChip_Future++) { - if ( ( ( 0x11 <= nChannel ) && ( nChannel <= 0x17 ) ) ) + if ( ( ( 0x11 <= nChannel ) && ( nChannel <= 0x17 ) ) || nChannel == 0x19 ) { CDTX.CChip chip = playerListChip[ nIndex_NearestChip_Future ]; @@ -1261,7 +1332,7 @@ namespace TJAPlayer3 //while ( nIndex_NearestChip_Past >= 0 ) // 過去方向への検索 for ( ; nIndex_NearestChip_Past >= 0; nIndex_NearestChip_Past-- ) { - if ( (( 0x15 <= nChannel ) && ( nChannel <= 0x17 ) || (nChannel == 0x20 || nChannel == 0x21)) ) + if ( ((( 0x15 <= nChannel ) && ( nChannel <= 0x17 ) || nChannel == 0x19) || (nChannel == 0x20 || nChannel == 0x21)) ) { CDTX.CChip chip = playerListChip[ nIndex_NearestChip_Past ]; @@ -1532,60 +1603,77 @@ namespace TJAPlayer3 bool IsKusudama = NotesManager.IsKusudama(pChip); bool IsFuze = NotesManager.IsFuzeRoll(pChip); - ref int rollCount = ref pChip.nRollCount; + int rollCount = pChip.nRollCount; int balloon = pChip.nBalloon; + if (IsKusudama) { - var ts = pChip.db発声時刻ms; - var km = TJAPlayer3.DTX.kusudaMAP; - - if (km.ContainsKey(ts)) - { - rollCount = ref km[ts].nRollCount; - balloon = km[ts].nBalloon; - } + nCurrentKusudamaRollCount++; + rollCount = nCurrentKusudamaRollCount; + balloon = nCurrentKusudamaCount; } if ((int)nowTime >= pChip.n発声時刻ms && (int)nowTime <= pChip.nノーツ終了時刻ms) { - if (rollCount == 0 && this.bPAUSE == false) + + if (IsKusudama) { - if (IsKusudama) + if (nCurrentKusudamaCount > 0) { - this.n風船残り[0] = balloon; + for(int i = 0; i < TJAPlayer3.ConfigIni.nPlayerCount; i++) + { + this.b連打中[i] = true; + actChara.ChangeAnime(i, CAct演奏Drumsキャラクター.Anime.Balloon_Breaking, true); + + + if (this.actBalloon.ct風船アニメ[i].IsUnEnded) + { + this.actBalloon.ct風船アニメ[i] = new CCounter(0, 9, 14, TJAPlayer3.Timer); + this.actBalloon.ct風船アニメ[i].CurrentValue = 1; + } + else + { + this.actBalloon.ct風船アニメ[i] = new CCounter(0, 9, 14, TJAPlayer3.Timer); + } + } + } + } + else + { + this.b連打中[player] = true; + actChara.ChangeAnime(player, CAct演奏Drumsキャラクター.Anime.Balloon_Breaking, true); + + + if (this.actBalloon.ct風船アニメ[player].IsUnEnded) + { + this.actBalloon.ct風船アニメ[player] = new CCounter(0, 9, 14, TJAPlayer3.Timer); + this.actBalloon.ct風船アニメ[player].CurrentValue = 1; } else { - this.n風船残り[player] = balloon; + this.actBalloon.ct風船アニメ[player] = new CCounter(0, 9, 14, TJAPlayer3.Timer); } } - - this.b連打中[player] = true; - actChara.ChangeAnime(player, CAct演奏Drumsキャラクター.Anime.Balloon_Breaking, true); - - - if (this.actBalloon.ct風船アニメ[player].IsUnEnded) - { - this.actBalloon.ct風船アニメ[player] = new CCounter(0, 9, 14, TJAPlayer3.Timer); - this.actBalloon.ct風船アニメ[player].CurrentValue = 1; - } - else - { - this.actBalloon.ct風船アニメ[player] = new CCounter(0, 9, 14, TJAPlayer3.Timer); - } this.eRollState = E連打State.balloon; - rollCount++; + if (IsKusudama) { - this.n風船残り[0]--; + //pChip.nRollCount = nCurrentKusudamaRollCount; + for(int i = 0; i < TJAPlayer3.ConfigIni.nPlayerCount; i++) + { + pChip.nRollCount = nCurrentKusudamaRollCount; + this.n風船残り[i] = balloon - rollCount; + } } else { - this.n風船残り[player]--; + pChip.nRollCount++; + rollCount = pChip.nRollCount; + this.n風船残り[player] = balloon - rollCount; } if (TJAPlayer3.stage選曲.n確定された曲の難易度[0] == (int)Difficulty.Dan) @@ -1625,29 +1713,35 @@ namespace TJAPlayer3 this.soundRed[pChip.nPlayerSide]?.PlayStart(); - if (balloon == rollCount) + if (this.n風船残り[player] <= 0) { if (IsKusudama) { - TJAPlayer3.Skin.soundBalloon.t再生する(); - var ts = pChip.db発声時刻ms; - for (int j = 0; j < TJAPlayer3.ConfigIni.nPlayerCount; j++) + //パァーン + /* + for(int i = 0; i < TJAPlayer3.ConfigIni.nPlayerCount; i++) { - var _dtx = new CDTX[5] { TJAPlayer3.DTX, TJAPlayer3.DTX_2P, TJAPlayer3.DTX_3P, TJAPlayer3.DTX_4P, TJAPlayer3.DTX_5P }; - var km = _dtx[j].kusudaMAP; - if (km.ContainsKey(ts)) + TJAPlayer3.Skin.soundBalloon.t再生する(); + pChip.bHit = true; + pChip.IsHitted = true; + chip現在処理中の連打チップ[i].bHit = true; + pChip.b可視 = false; + nCurrentKusudamaCount = 0; { - var tChip = km[ts]; - tChip.bHit = true; - tChip.IsHitted = true; - chip現在処理中の連打チップ[j].bHit = true; - tChip.b可視 = false; - { - actChara.ChangeAnime(j, CAct演奏Drumsキャラクター.Anime.Balloon_Broke, true); - if (actChara.CharaAction_Balloon_Delay[j] != null) actChara.CharaAction_Balloon_Delay[j] = new CCounter(0, TJAPlayer3.Skin.Characters_Balloon_Delay[actChara.iCurrentCharacter[j]] - 1, 1, TJAPlayer3.Timer); - } + actChara.ChangeAnime(i, CAct演奏Drumsキャラクター.Anime.Balloon_Broke, true); + if (actChara.CharaAction_Balloon_Delay[i] != null) actChara.CharaAction_Balloon_Delay[i] = new CCounter(0, TJAPlayer3.Skin.Characters_Balloon_Delay[actChara.iCurrentCharacter[i]] - 1, 1, TJAPlayer3.Timer); } - + }*/ + + TJAPlayer3.Skin.soundBalloon.t再生する(); + pChip.bHit = true; + pChip.IsHitted = true; + chip現在処理中の連打チップ[player].bHit = true; + pChip.b可視 = false; + nCurrentKusudamaCount = 0; + { + actChara.ChangeAnime(player, CAct演奏Drumsキャラクター.Anime.Balloon_Broke, true); + if (actChara.CharaAction_Balloon_Delay[player] != null) actChara.CharaAction_Balloon_Delay[player] = new CCounter(0, TJAPlayer3.Skin.Characters_Balloon_Delay[actChara.iCurrentCharacter[player]] - 1, 1, TJAPlayer3.Timer); } } else @@ -1674,10 +1768,24 @@ namespace TJAPlayer3 } else { - if (chip現在処理中の連打チップ[player] != null) - chip現在処理中の連打チップ[player].bHit = true; - this.b連打中[player] = false; - this.actChara.b風船連打中[player] = false; + if (IsKusudama) + { + for(int i = 0; i < TJAPlayer3.ConfigIni.nPlayerCount; i++) + { + if (chip現在処理中の連打チップ[i] != null) + chip現在処理中の連打チップ[i].bHit = true; + this.b連打中[i] = false; + this.actChara.b風船連打中[i] = false; + nCurrentKusudamaCount = 0; + } + } + else + { + if (chip現在処理中の連打チップ[player] != null) + chip現在処理中の連打チップ[player].bHit = true; + this.b連打中[player] = false; + this.actChara.b風船連打中[player] = false; + } return false; } return true; @@ -1792,17 +1900,33 @@ namespace TJAPlayer3 { #region [ Balloon ] - this.b連打中[nPlayer] = true; - this.actChara.b風船連打中[nPlayer] = true; + bool IsKusudama = NotesManager.IsKusudama(pChip); + + if (IsKusudama) + { + if (nCurrentKusudamaCount > 0) + { + for(int i = 0; i < TJAPlayer3.ConfigIni.nPlayerCount; i++) + { + this.b連打中[i] = true; + this.actChara.b風船連打中[i] = true; + } + } + } + else + { + this.b連打中[nPlayer] = true; + this.actChara.b風船連打中[nPlayer] = true; + } if (bAutoPlay || rollEffectHit) { - bool IsKusudama = NotesManager.IsKusudama(pChip); int rollCount = pChip.nRollCount; int balloon = pChip.nBalloon; if (IsKusudama) { + /* var ts = pChip.db発声時刻ms; var km = TJAPlayer3.DTX.kusudaMAP; @@ -1811,6 +1935,10 @@ namespace TJAPlayer3 rollCount = km[ts].nRollCount; balloon = km[ts].nBalloon; } + */ + rollCount = nCurrentKusudamaRollCount; + balloon = nCurrentKusudamaCount; + } if (balloon != 0 && this.bPAUSE == false) @@ -1836,7 +1964,10 @@ namespace TJAPlayer3 } if (!bAutoPlay && !rollEffectHit) { - this.tBalloonProcess(pChip, (SoundManager.PlayTimer.NowTime * (((double)TJAPlayer3.ConfigIni.n演奏速度) / 20.0)), nPlayer); + if (!IsKusudama || nCurrentKusudamaCount > 0) + { + this.tBalloonProcess(pChip, (SoundManager.PlayTimer.NowTime * (((double)TJAPlayer3.ConfigIni.n演奏速度) / 20.0)), nPlayer); + } } break; #endregion @@ -1845,7 +1976,19 @@ namespace TJAPlayer3 { if (pChip.nノーツ終了時刻ms <= (SoundManager.PlayTimer.NowTime * (((double)TJAPlayer3.ConfigIni.n演奏速度) / 20.0))) { - this.b連打中[nPlayer] = false; + if (NotesManager.IsKusudama(pChip)) + { + for(int i = 0; i < TJAPlayer3.ConfigIni.nPlayerCount; i++) + { + chip現在処理中の連打チップ[i].bHit = true; + this.b連打中[i] = false; + } + } + else + { + this.b連打中[nPlayer] = false; + } + // this.actChara.b風船連打中[nPlayer] = false; @@ -3596,6 +3739,15 @@ namespace TJAPlayer3 this.chip現在処理中の連打チップ[ nPlayer ] = pChip; } } + if ( !pChip.bProcessed && ( pChip.nバーからの距離dot.Drums < 0 ) ) + { + if (NotesManager.IsKusudama(pChip)) + { + nCurrentKusudamaRollCount = 0; + nCurrentKusudamaCount += pChip.nBalloon; + pChip.bProcessed = true; + } + } if (pChip.n描画優先度 <= 0) this.t進行描画_チップ_Taiko連打(configIni, ref dTX, ref pChip, nPlayer); } @@ -3611,6 +3763,8 @@ namespace TJAPlayer3 pChip.bHit = true; if( chip現在処理中の連打チップ[ nPlayer ] != null ) { + nCurrentKusudamaRollCount = 0; + nCurrentKusudamaCount = 0; chip現在処理中の連打チップ[ nPlayer ].bHit = true; if (chip現在処理中の連打チップ[nPlayer].nBalloon > chip現在処理中の連打チップ[nPlayer].nRollCount && chip現在処理中の連打チップ[nPlayer].nRollCount > 0) @@ -5214,6 +5368,8 @@ namespace TJAPlayer3 NowProcessingChip[i] = 0; } } + nCurrentKusudamaCount = 0; + nCurrentKusudamaRollCount = 0; this.ReSetScore(TJAPlayer3.DTX.nScoreInit[0, TJAPlayer3.stage選曲.n確定された曲の難易度[0]], TJAPlayer3.DTX.nScoreDiff[TJAPlayer3.stage選曲.n確定された曲の難易度[0]]); this.nHand = new int[]{ 0, 0, 0, 0, 0 }; @@ -5256,6 +5412,7 @@ namespace TJAPlayer3 dTX.listChip[i].bHit = false; dTX.listChip[i].bShow = true; + dTX.listChip[i].bProcessed = false; dTX.listChip[i].b可視 = true; dTX.listChip[i].IsHitted = false; dTX.listChip[i].IsMissed = false; diff --git a/OpenTaiko/src/Stages/07.Game/Taiko/CAct演奏Drums風船.cs b/OpenTaiko/src/Stages/07.Game/Taiko/CAct演奏Drums風船.cs index a85d2570..0040c475 100644 --- a/OpenTaiko/src/Stages/07.Game/Taiko/CAct演奏Drums風船.cs +++ b/OpenTaiko/src/Stages/07.Game/Taiko/CAct演奏Drums風船.cs @@ -205,8 +205,19 @@ namespace TJAPlayer3 } if (n連打数 == 0 && TJAPlayer3.stage演奏ドラム画面.actChara.b風船連打中[player]) { - TJAPlayer3.stage演奏ドラム画面.actChara.b風船連打中[player] = false; - TJAPlayer3.stage演奏ドラム画面.b連打中[player] = false; + if (btype == EBalloonType.KUSUDAMA) + { + for(int i = 0; i < TJAPlayer3.ConfigIni.nPlayerCount; i++) + { + TJAPlayer3.stage演奏ドラム画面.actChara.b風船連打中[i] = false; + TJAPlayer3.stage演奏ドラム画面.b連打中[i] = false; + } + } + else + { + TJAPlayer3.stage演奏ドラム画面.actChara.b風船連打中[player] = false; + TJAPlayer3.stage演奏ドラム画面.b連打中[player] = false; + } } diff --git a/OpenTaiko/src/Stages/07.Game/Taiko/CStage演奏ドラム画面.cs b/OpenTaiko/src/Stages/07.Game/Taiko/CStage演奏ドラム画面.cs index 8e34cb45..a442fa72 100644 --- a/OpenTaiko/src/Stages/07.Game/Taiko/CStage演奏ドラム画面.cs +++ b/OpenTaiko/src/Stages/07.Game/Taiko/CStage演奏ドラム画面.cs @@ -2583,13 +2583,10 @@ namespace TJAPlayer3 if (chkChip.n発声時刻ms <= (int)nowTime && chkChip.nノーツ終了時刻ms + 500 >= (int)nowTime) { - if (i == 0 && chkChip.nRollCount == 0 && NotesManager.IsKusudama(chkChip)) - { - this.n風船残り[0] = chkChip.nBalloon; - } + var balloon = NotesManager.IsKusudama(chkChip) ? nCurrentKusudamaCount : chkChip.nBalloon; if (!NotesManager.IsFuzeRoll(chkChip)) chkChip.bShow = false; this.actBalloon.On進行描画( - chkChip.nBalloon, + balloon, this.n風船残り[i], i, NotesManager.IsFuzeRoll(chkChip) diff --git a/OpenTaiko/src/Stages/07.Game/Taiko/NotesManager.cs b/OpenTaiko/src/Stages/07.Game/Taiko/NotesManager.cs index d724d7ca..17f34ec8 100644 --- a/OpenTaiko/src/Stages/07.Game/Taiko/NotesManager.cs +++ b/OpenTaiko/src/Stages/07.Game/Taiko/NotesManager.cs @@ -26,7 +26,7 @@ namespace TJAPlayer3 ["6"] = 6, // Big roll start | Konga pink roll ["7"] = 7, // Balloon ["8"] = 8, // Roll/Balloon end - ["9"] = 7, // Kusudama + ["9"] = 9, // Kusudama ["A"] = 10, // Joint Big Don (2P) ["B"] = 11, // Joint Big Ka (2P) ["C"] = 12, // Mine