OSDN Git Service

DTXManiaソリューション、DTXManiaプロジェクト、DTXCreatorプロジェクト、FDKプロジェクトについて英語化。
[dtxmania/dtxmania.git] / DTXMania / コード / ステージ / 07.演奏 / CAct演奏ゲージ共通.cs
diff --git a/DTXMania/コード/ステージ/07.演奏/CAct演奏ゲージ共通.cs b/DTXMania/コード/ステージ/07.演奏/CAct演奏ゲージ共通.cs
new file mode 100644 (file)
index 0000000..439ea56
--- /dev/null
@@ -0,0 +1,405 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Runtime.InteropServices;
+using System.Drawing;
+using System.Diagnostics;
+using SharpDX;
+using FDK;
+
+using Color = System.Drawing.Color;
+using Rectangle = System.Drawing.Rectangle;
+
+namespace DTXMania
+{
+       /// <summary>
+       /// CAct演奏Drumsゲージ と CAct演奏Gutiarゲージ のbaseクラス。ダメージ計算やDanger/Failed判断もこのクラスで行う。
+       /// </summary>
+       internal class CAct演奏ゲージ共通 : CActivity
+       {
+               const double GAUGE_MAX = 1.0;
+               const double GAUGE_INITIAL = 2.0 / 3;
+               const double GAUGE_MIN = -0.1;
+               const double GAUGE_ZERO = 0.0;
+               const double GAUGE_DANGER = 0.3;
+
+               private float[,] fDamageGaugeDelta = {
+                       // #23625 2011.1.10 ickw_284: tuned damage/recover factors
+                       // drums,   guitar,  bass
+                       {  0.004f,  0.006f,  0.006f  },
+                       {  0.002f,  0.003f,  0.003f  },
+                       {  0.000f,  0.000f,  0.000f  },
+                       { -0.020f, -0.030f, -0.030f  },
+                       { -0.050f, -0.050f, -0.050f  }
+               };
+               private float[] fDamageLevelFactor = {
+                       0.5f, 1.0f, 1.5f
+               };
+
+               private double db現在のゲージ値;
+               private CCounter ct本体移動;
+               private CCounter ct本体振動;
+               private CTexture txゲージ;
+               private CTextureAf txゲージ白;
+               private ST白い星[] st白い星 = new ST白い星[24];
+
+               private CActDigit actDigit;
+
+               /// <summary>
+               /// Riskyモードか否か
+               /// </summary>
+               public bool bRisky { get; private set; }
+
+               /// <summary>
+               /// Risky初期値
+               /// </summary>
+               public int nRiskyTimesInitial { get; private set; }
+
+               /// <summary>
+               /// 残Miss回数
+               /// </summary>
+               public int nRiskyTimes { get; private set; }
+
+               /// <summary>
+               /// 閉店状態になったかどうか
+               /// </summary>
+               /// <returns></returns>
+               public bool IsFailed
+               {
+                       get
+                       {
+                               if (bRisky)
+                               {
+                                       return (nRiskyTimes <= 0);
+                               }
+                               return this.db現在のゲージ値 <= GAUGE_MIN;
+                       }
+               }
+
+               /// <summary>
+               /// DANGERかどうか
+               /// </summary>
+               /// <returns></returns>
+               public bool IsDanger
+               {
+                       get
+                       {
+                               if (bRisky)
+                               {
+                                       switch (nRiskyTimesInitial)
+                                       {
+                                               case 1:
+                                                       return false;
+                                               case 2:
+                                               case 3:
+                                                       return (nRiskyTimes <= 1);
+                                               default:
+                                                       return (nRiskyTimes <= 2);
+                                       }
+                               }
+                               return (this.db現在のゲージ値 <= GAUGE_DANGER);
+                       }
+               }
+
+               public CAct演奏ゲージ共通()
+               {
+                       base.list子Activities.Add(actDigit = new CActDigit(Color.Red, Color.Black, 24));
+               }
+
+               public override void On非活性化()
+               {
+                       if (base.b活性化してる)
+                       {
+                               this.ct本体振動 = null;
+                               this.ct本体移動 = null;
+                               for (int i = 0; i < 24; i++)
+                               {
+                                       this.st白い星[i].ct進行 = null;
+                               }
+                               base.On非活性化();
+                       }
+               }
+
+               public override void OnUnmanagedリソースの作成()
+               {
+                       if (b活性化してる)
+                       {
+                               this.txゲージ = TextureFactory.tテクスチャの生成(CSkin.Path(@"Graphics\ScreenPlayDrums gauge.png"));
+                               this.txゲージ白 = TextureFactory.tテクスチャの生成Af(CSkin.Path(@"Graphics\ScreenPlayDrums_gauge_white.png "));
+                               base.OnUnmanagedリソースの作成();
+                       }
+               }
+
+               public override void OnManagedリソースの解放()
+               {
+                       if (b活性化してる)
+                       {
+                               TextureFactory.tテクスチャの解放(ref this.txゲージ);
+                               TextureFactory.tテクスチャの解放(ref this.txゲージ白);
+                               base.OnUnmanagedリソースの解放();
+                       }
+               }
+
+               public override int On進行描画()
+               {
+                       if (b活性化してる && CDTXMania.Instance.ConfigIni.eDark == EDark.Off)
+                       {
+                               #region [ 初めての進行描画 ]
+                               if (base.b初めての進行描画)
+                               {
+                                       for (int k = 0; k < 24; k++)
+                                       {
+                                               this.st白い星[k].x = 6 + CDTXMania.Instance.Random.Next(12);
+                                               this.st白い星[k].fScale = 0.2f + (CDTXMania.Instance.Random.Next(2) * 0.05f);
+                                               this.st白い星[k].ct進行 = new CCounter(0, CDTXMania.Instance.Coordinates.GaugeMax, 8 + CDTXMania.Instance.Random.Next(4), CDTXMania.Instance.Timer);
+                                               this.st白い星[k].ct進行.n現在の値 = CDTXMania.Instance.Random.Next(CDTXMania.Instance.Coordinates.GaugeMax);
+                                       }
+                                       this.ct本体移動 = new CCounter(0, 0x1a, 20, CDTXMania.Instance.Timer);
+                                       this.ct本体振動 = new CCounter(0, 360, 4, CDTXMania.Instance.Timer);
+                                       base.b初めての進行描画 = false;
+                               }
+                               #endregion
+                               this.ct本体移動.t進行Loop();
+                               this.ct本体振動.t進行Loop();
+
+
+                               #region [ 緑orオレンジのゲージ表示 ]
+                               double dbゲージ最大値 = CDTXMania.Instance.Coordinates.GaugeMax;
+                               int n表示するゲージの高さ = (this.db現在のゲージ値 == 1.0) ?
+                                       ((int)(dbゲージ最大値 * this.db現在のゲージ値)) :
+                                       ((int)((dbゲージ最大値 * this.db現在のゲージ値) + (2.0 * Math.Sin(Math.PI * 2 * (((double)this.ct本体振動.n現在の値) / 360.0)))));
+
+                               if (n表示するゲージの高さ <= 0)
+                               {
+                                       return 0;
+                               }
+                               if (this.txゲージ != null)
+                               {
+                                       this.txゲージ.vc拡大縮小倍率 = new Vector3(1f, 1f, 1f);
+                                       this.txゲージ.n透明度 = 0xff;
+                                       this.txゲージ.b加算合成 = false;
+                               }
+                               int nCtゲージ内部上昇スクロール現在値 = (int)(this.ct本体移動.n現在の値 * Scale.Y);
+                               int n表示ゲージ最大値 = CDTXMania.Instance.Coordinates.Gauge.Y;
+                               int ybar = (n表示ゲージ最大値 - n表示するゲージの高さ) - nCtゲージ内部上昇スクロール現在値;
+                               int height = n表示するゲージの高さ + nCtゲージ内部上昇スクロール現在値;
+                               while (height > 0)
+                               {
+                                       Rectangle rect = (this.db現在のゲージ値 == 1.0) ?
+                                               CDTXMania.Instance.Coordinates.ImgGaugeOrange :
+                                               CDTXMania.Instance.Coordinates.ImgGaugeNormal;
+                                       #region [ clipping ]
+                                       if (ybar < (n表示ゲージ最大値 - n表示するゲージの高さ))
+                                       {
+                                               int d = (n表示ゲージ最大値 - n表示するゲージの高さ) - ybar;
+                                               rect.Y += d;
+                                               rect.Height -= d;
+                                               ybar += d;
+                                       }
+                                       if ((ybar + rect.Height) > n表示ゲージ最大値)
+                                       {
+                                               int num7 = (ybar + rect.Height) - n表示ゲージ最大値;
+                                               rect.Height -= num7;
+                                       }
+                                       if (rect.Top >= rect.Bottom)
+                                       {
+                                               break;
+                                       }
+                                       #endregion
+                                       if (this.txゲージ != null)
+                                       {
+                                               this.txゲージ.t2D描画(
+                                                       CDTXMania.Instance.Device,
+                                                       CDTXMania.Instance.Coordinates.Gauge.X,
+                                                       ybar,
+                                                       rect
+                                               );
+                                       }
+                                       height -= rect.Height;
+                                       ybar += rect.Height;
+                               }
+                               #endregion
+                               #region [ 光彩 ]
+                               if (this.txゲージ白 != null)
+                               {
+                                       this.txゲージ白.vc拡大縮小倍率 = new Vector3(1f, 1f, 1f);
+                                       this.txゲージ白.n透明度 = 180;
+                                       this.txゲージ白.b加算合成 = true;
+                               }
+                               {
+                                       Rectangle rect = CDTXMania.Instance.Coordinates.ImgGaugeLight;
+                                       int ylight = (n表示ゲージ最大値 - n表示するゲージの高さ);
+                                       if (ylight < n表示ゲージ最大値)
+                                       {
+                                               if ((ylight + rect.Height) > n表示ゲージ最大値)
+                                               {
+                                                       int d = (ylight + rect.Height) - n表示ゲージ最大値;
+                                                       rect.Height -= d;
+                                               }
+                                               if ((rect.Top < rect.Bottom) && (this.txゲージ白 != null))
+                                               {
+                                                       this.txゲージ白.t2D描画(
+                                                               CDTXMania.Instance.Device,
+                                                               CDTXMania.Instance.Coordinates.Gauge.X,
+                                                               ylight,
+                                                               rect
+                                                       );
+                                               }
+                                       }
+                               }
+                               #endregion
+                               #region [ ゲージ頂上の光源 ]
+                               if (this.txゲージ != null)
+                               {
+                                       this.txゲージ.n透明度 = 0xff;
+                                       this.txゲージ.b加算合成 = false;
+                               }
+                               {
+                                       Rectangle rect = CDTXMania.Instance.Coordinates.ImgGaugeTopLight;
+                                       int yゲージ頂上 = n表示ゲージ最大値 - n表示するゲージの高さ;
+                                       if (yゲージ頂上 < n表示ゲージ最大値)
+                                       {
+                                               #region [ clipping ]
+                                               if ((yゲージ頂上 + rect.Height) > n表示ゲージ最大値)
+                                               {
+                                                       int d = (yゲージ頂上 + rect.Height) - n表示ゲージ最大値;
+                                                       rect.Height -= d;
+                                               }
+                                               #endregion
+                                               if ((rect.Top < rect.Bottom) && (this.txゲージ != null))
+                                               {
+                                                       this.txゲージ.t2D描画(
+                                                               CDTXMania.Instance.Device,
+                                                               CDTXMania.Instance.Coordinates.Gauge.X,
+                                                               yゲージ頂上,
+                                                               rect
+                                                       );
+                                               }
+                                       }
+                               }
+                               #endregion
+                               #region [ 泡 ]
+                               if (this.txゲージ != null)
+                               {
+                                       this.txゲージ.b加算合成 = true;
+                               }
+                               for (int j = 0; j < 24; j++)
+                               {
+                                       this.st白い星[j].ct進行.t進行Loop();
+                                       int x = CDTXMania.Instance.Coordinates.Gauge.X + this.st白い星[j].x;
+                                       int y泡 = (n表示ゲージ最大値 - n表示するゲージの高さ) + CDTXMania.Instance.Coordinates.GaugeMax - this.st白い星[j].ct進行.n現在の値;
+                                       if (y泡 + CDTXMania.Instance.Coordinates.ImgGaugeStar.H / 2 < n表示ゲージ最大値)
+                                       {
+                                               int n透明度 = (this.st白い星[j].ct進行.n現在の値 < 176) ? 0 : ((int)(255.0 * (((double)(this.st白い星[j].ct進行.n現在の値 - 176)) / 176.0)));
+                                               if ((n透明度 != 0) && (y泡 < CDTXMania.Instance.Coordinates.Gauge.Y))
+                                               {
+                                                       Rectangle rect = CDTXMania.Instance.Coordinates.ImgGaugeStar;
+                                                       if (this.txゲージ != null)
+                                                       {
+                                                               this.txゲージ.vc拡大縮小倍率 = new Vector3(this.st白い星[j].fScale, this.st白い星[j].fScale, 1f);
+                                                               this.txゲージ.n透明度 = n透明度;
+                                                               this.txゲージ.t2D描画(
+                                                                       CDTXMania.Instance.Device,
+                                                                       x,
+                                                                       y泡,
+                                                                       rect
+                                                               );
+                                                       }
+                                               }
+                                       }
+                               }
+                               #endregion
+
+                               #region [ Risky残りMiss回数表示 ]
+                               if (this.bRisky)    // #23599 2011.7.30 yyagi Risky残りMiss回数表示
+                               {
+                                       int w = actDigit.Measure(nRiskyTimes);
+                                       actDigit.Draw(nRiskyTimes,
+                                               CDTXMania.Instance.Coordinates.Gauge.X + (CDTXMania.Instance.Coordinates.ImgGaugeNormal.W / 2 - w / 2),
+                                               CDTXMania.Instance.Coordinates.Gauge.Y - actDigit.MaximumHeight);
+                               }
+                               #endregion
+                       }
+                       return 0;
+               }
+
+
+               /// <summary>
+               /// ゲージの初期化
+               /// </summary>
+               /// <param name="nRiskyTimes_Initial_">Riskyの初期値(0でRisky未使用)</param>
+               public void Init(int nRiskyTimes_InitialVal)
+               {
+                       nRiskyTimesInitial = nRiskyTimes_InitialVal;
+                       nRiskyTimes = nRiskyTimes_InitialVal;
+                       bRisky = (this.nRiskyTimes > 0);
+
+                       if (!bRisky)
+                       {
+                               this.db現在のゲージ値 = GAUGE_INITIAL;
+                       }
+                       else
+                       {
+                               this.db現在のゲージ値 = GAUGE_MAX;
+                       }
+               }
+
+               public void Damage(EPart part, EJudge e今回の判定)
+               {
+                       double fDamage;
+
+                       // DAMAGELEVELTUNING
+                       // before applying #23625 modifications
+                       switch (e今回の判定)
+                       {
+                               case EJudge.Perfect:
+                               case EJudge.Great:
+                               case EJudge.Good:
+                                       fDamage = bRisky ? 0 : fDamageGaugeDelta[(int)e今回の判定, (int)part];
+                                       break;
+                               case EJudge.Poor:
+                               case EJudge.Miss:
+                                       if (bRisky)
+                                       {
+                                               // Risky=1のときは1Miss即閉店なのでダメージ計算しない
+                                               fDamage = (nRiskyTimes == 1) ? 0 : -GAUGE_MAX / (nRiskyTimesInitial - 1);
+
+                                               if (nRiskyTimes >= 0)
+                                               {
+                                                       // 念のため-1未満には減らないようにしておく
+                                                       nRiskyTimes--;
+                                               }
+                                       }
+                                       else
+                                       {
+                                               fDamage = fDamageGaugeDelta[(int)e今回の判定, (int)part];
+                                       }
+                                       if (e今回の判定 == EJudge.Miss && !bRisky)
+                                       {
+                                               fDamage *= fDamageLevelFactor[(int)CDTXMania.Instance.ConfigIni.eDamageLevel.Value];
+                                       }
+                                       break;
+
+                               default:
+                                       fDamage = 0.0f;
+                                       break;
+                       }
+
+                       this.db現在のゲージ値 += fDamage;
+
+                       if (this.db現在のゲージ値 > GAUGE_MAX)
+                       {
+                               // RISKY時は決してゲージが増加しないので、上限チェックはしなくて良い
+                               this.db現在のゲージ値 = GAUGE_MAX;
+                       }
+               }
+
+               [StructLayout(LayoutKind.Sequential)]
+               private struct ST白い星
+               {
+                       public int x;
+                       public float fScale;
+                       public CCounter ct進行;
+               }
+       }
+}