参考資料

久しぶりに世紀末非想天則やったら三毛猫さんが1ラウンド目からテレッテ可能にしてほしいとかなんとかうるさくなり、なぜかhokuto.iniの内容に言及されたので星取り判定をそのままここに。これ以外のことはしてません。もう自分でも忘れてたんだけど…。
VC2010へのプロジェクトの変換は成功。警告出てた気がするけど。ビルドはd3dx9.hのインクルードに失敗。残当
行番号が出てないのでC/C++エディタオプションでオンに。ついでに#includeのオートコンプリートの項目を見つける。Eclipse/Javaの自動importを思い浮かべたが、調べたら#includeの次のファイル名入力に支援がかかるだけだった。残当

if (a) {|

Enter

if (a) {
    |

Enter

if (a) {

    |

}

if (a) {

}|

if (a) {
    |
}

うおっ
買うだけ買ってインストールするだけして放っておいたVC2010の感想をいまさら書いてどうするの…。

void BattleHook::checkGetStar(const ThData &cur1, const ThData &cur2)
{
  DWORD cond1 = cur1.type | (cur1.limit >= 100 ? HitCondition::LimitOver : 0x0);
  DWORD cond2 = cur2.type | (cur2.limit >= 100 ? HitCondition::LimitOver : 0x0);

  // 何かが当たった
  if (cur1.combo > m_prevData1.combo) {
    for (int i = 0; i < STAR_COND_MAX; i++) {
      if (!m_gotStar1[i] && (cond1 & m_starCond[i]) == m_starCond[i]) {
        decreaseStar(1, 1);
        m_gotStar1[i] = true;
      }
    }
  }
  // ヒット数が増えていないのに他が動いた = 新しいコンボの1Hit目
  else if (cur1.combo < m_prevData1.combo || cur1.damage != m_prevData1.damage
    || cur1.limit != m_prevData1.limit) {
    for (int i = 0; i < STAR_COND_MAX; i++) {
      if ((cond1 & m_starCond[i]) == m_starCond[i]) {
        decreaseStar(1, 1);
        m_gotStar1[i] = true;
      } else {
        m_gotStar1[i] = false;
      }
    }
  }

  // 上のコピペ
  // 何かが当たった
  if (cur2.combo > m_prevData2.combo) {
    for (int i = 0; i < STAR_COND_MAX; i++) {
      if (!m_gotStar2[i] && (cond2 & m_starCond[i]) == m_starCond[i]) {
        decreaseStar(0, 1);
        m_gotStar2[i] = true;
      }
    }
  }
  // ヒット数が増えていないのに他が動いた = 新しいコンボの1Hit目
  else if (cur2.combo < m_prevData2.combo || cur2.damage != m_prevData2.damage
    || cur2.limit != m_prevData2.limit) {
    for (int i = 0; i < STAR_COND_MAX; i++) {
      if ((cond2 & m_starCond[i]) == m_starCond[i]) {
        decreaseStar(0, 1);
        m_gotStar2[i] = true;
      } else {
        m_gotStar2[i] = false;
      }
    }
  }

  /*
  if (m_prevData1.type != cur1.type) {
    if ((cur1.type & HitType::CounterHit) ||
      ((cur1.type & HitType::RiftAttack) && (cur1.type & HitType::SmashAttack)) ||
      (cur1.type & HitType::BorderResist)) 
    {
      if (m_star2 > 0) {
        --m_star2;
      }
    }
  }
  if (m_prevData2.type != cur2.type) {
    if ((cur2.type & HitType::CounterHit) ||
      ((cur2.type & HitType::RiftAttack) && (cur2.type & HitType::SmashAttack)) ||
      (cur2.type & HitType::BorderResist)) 
    {
      if (m_star1 > 0) {
        --m_star1;
      }
    }
  }
  */
}

最初の方は、Counter HitだのChain Spellだののあそこに表示されるものの論理和に、LimitOverを勝手に追加してます。
コンボヒット数が増えたら確実に判定タイミングです。STAR_COND_MAXは7です。北斗七星だからね。m_starCond[k]はiniで設定されるk番目の条件(論理和)です。m_gotStarはその条件で既に星が取られているかどうかです。decreaseStar(p, n)はプレイヤーpからn個星を取る関数です。0個未満にはならないのと、1個以上→0個の変化が起きたときにカットインの表示とサウンド再生が必要になりましてね…。
次は新しくコンボが1Hitから始まった時の検出ですが、合計ダメージとリミットの変化を見ているだけです。なのでダメージとリミットが全く同じ技を続けて1Hitずつカウンターヒットさせると検出できません。が、根性補正でダメージが微妙に変わるのでほとんど問題になることはないだろうということで妥協しています。天候凪で全回復とかなら十分あり得そうではあるけれども。
コメントは旧星取り処理です。論理和が変化するたびに判定していますね。これだと同時に2つ以上の条件を満たした場合、1個しか取れません。また、ひとたびどれかの条件が満たされると、論理和が変化するたびに星が1つずつ取れていくというバグがありました。
例:CounterHit(1つめ)→CH+SmashAttack(2つめ)→CH+SA+RiftAttack(3つめ)→…
「--a;」という他とは違うコードスタイルに、id:nagoya313くんのコードをベースにしている名残が見えますね。


hokuto.ini抜粋

[GetStar]
SetName=RealHokuto

; RiftAttack    = 1
; SmashAttack   = 2
; BorderResist  = 4
; ChainArts     = 8
; ChainSpell    = 16
; CounterHit    = 32
; Limit >= 100% = 64

[Normal]
Condition1=3
Condition2=4
Condition3=32
Condition4=64
Condition5=0
Condition6=0
Condition7=0

[RealHokuto]
Condition1=4
Condition2=32
Condition3=64
Condition4=9
Condition5=16
Condition6=3
Condition7=0

[OldVersion]
Condition1=3
Condition2=4
Condition3=8
Condition4=16
Condition5=32
Condition6=64
Condition7=0

猫 さんの発言 (0:51)
ん?ではhitが1以上になったら判定〜 じゃ上手くいかないの?
unyounyo yappy さんの発言 (0:52)
1ヒットを2回やると 1Hit→1Hit と何も変わらなくてですね
最後に決めたコンボのヒット数が入ってるんで、コンボが切れてもずっとそのままなんすよ
猫 さんの発言 (0:53)
切れたら0にしてくれれば良かったのになぁ。
unyounyo yappy さんの発言 (0:53)
キャラのステートを見てニュートラルモーションで切れたことを判別すればいいんですねわかります
猫 さんの発言 (0:53)
まあ、表記する情報だからね。初期化しないな確かに。
蓄積のっちゃうーw
ん? 乗ると星が取られない?
unyounyo yappy さんの発言 (0:53)
さあどうなんだろうね
unyounyo yappy さんの発言 (0:54)
普通に受身で空中判定とか思うと考えもしなかったけど
猫 さんの発言 (0:54)
1hitカウンター! >星が取られる
立った>0に
またカウンター!>星二個目
unyounyo yappy さんの発言 (0:55)
うーん、そうか、蓄積乗ると星とられなくなるのか
猫 さんの発言 (0:55)
1hitのカウンター!>星取られる
しゃがんで暴れた>1のまんま
暴れ潰れてカウンター!>hitは1のままなんで星取れない
いかん、暴れが強くなる
unyounyo yappy さんの発言 (0:55)
わろた


D
蓄積バグってバスケとかに比べて知らない人に説明するの難しいよね…。むしろどんな変数があって、どんな条件で動いてて、っていうことが分からない以上、完璧に説明することは不可能なんじゃないかと思う。
あるゲージ補正値がコンボが終わった後も防御側がニュートラルポーズを取るまでリセットされず、起き上がりに攻撃を重ねてガードさせたりすると、攻撃側のブースト・オーラゲージがものすごい勢いで上昇し、防御側への気絶・ガークラゲージへのダメージがすごいことになるバグ(ゲージ超回収・すぐピヨる・すぐ割れる)。この動画を見てからは、蓄積起き攻め後、相手が空中からふんわり来る場合は隙を見てレバーをニュートラルにして明示的に蓄積を切ってます。まあ念のためってやつだけど、フリー状態のうちにレバーニュートラルが一瞬でもあれば絶対に切れるはずだから…。それと早めのガーキャン。


補足:インクリメント・デクリメント演算子の前置・後置
前置++/--はその値を1増やす・減らすしてからその変化後の値を返す、後置は変化前の値を返す、というのは既知として、普通に1増減させたい場合、C++しちゃってる人は大抵前置を使います(使いますが遣いますになる人は人形の遣いすぎです)。…本当にそうかはそんなにいろんな人のコードを読んだわけではないから分からないけど。むしろどちらでもいいところでの前置から私が何を感じるか、か。Cまでならどちらでもいいときは本当にどちらでもいいのですが、C++だとユーザー定義型に++/--演算子オーバーロードができるので、事情が違ってくるのです。
Wikipeadiaからよくある演算子オーバーロードのコード。

// 前置インクリメントのオーバーロード
T& T::operator++ {
  *this += 1;
  return *this;
}
// 後置インクリメントのオーバーロード
T T::operator++(int) {
  T old = *this;
  *this += 1;
  return old; 
}

前置後置の区別は引数に何の意味も無いintを持つかどうかでする、ということはどうでもよく、T old = *this;(T old(*this);と等価)でコピーコンストラクタを呼んでいるところがポイントです。前置の場合、自分を1増やして自分を1増やした値を返すのですから自分を(参照で)返せばいいのですが、後置の場合、自分を1増やした後、増やす前の値を返さなければいけないので、コピーが必要になるということです。今、返り値は必要なく、オブジェクトaを1増やしたいだけなので、++a;と書くということです。
私はC/Javaを始め、後置で慣れ過ぎているのでどうにも気持ちが悪く、ループカウンタint i;などはC++でも後置で書いています。まあ、さすがに、組み込み型でなくclass/structには前置を使いますけどね。むしろインクリメント・デクリメント演算子オーバーロードされているクラス自体が少ないというかなんというか。

std::vector v;
for (auto it = v.begin(); it != v.end(); ++it) { }

autoって使い方これでよかったよね???