User:びゃっこ/すたぶ/解析だめけいさん

< User:びゃっこ‎ | すたぶ
Revision as of 05:32, 13 September 2025 by びゃっこ (talk | contribs) (曖昧なとことか不要な情報とかをてなおし)

PV

ApplyProtection(int dmg, int mod = 100)
   {
       int armorSkill = GetArmorSkill();
       Element orCreateElement = elements.GetOrCreateElement(armorSkill);
       int num = PV + orCreateElement.Value + DEX / 10;
       int num2 = 1;
       int sides = 1;
       int bonus = 0;
       if (num > 0)
       {
           int num3 = num / 4;
           num2 = num3 / 10 + 1;
           sides = num3 / num2 + 1;
           bonus = 0;
           dmg = dmg * 100 / (100 + num);
       }
       int num4 = Dice.Roll(num2, sides, bonus, this);
       dmg -= num4 * mod / 100;
       if (dmg < 0)
       {
           dmg = 0;
       }
       return dmg;
   }

軽装備か重装備かを取得します。

PV + 軽or重装備のスキル + 器用/10として変数numを定めて、

その値が正である場合、4で割った値を変数num3に保管し、num2=num3/10 +1とし、

更にそこから sides = num3/num2 + 1を定義し、bonus=0とします。

そののち、ダメージを100/(100+num)倍にします。

さらに、Dice.cs中のRoll関数を用いて、運は被ダメージ者のもの、ダイス数はnum2、面数はsides、ボーナスは0でダイスロールをします。

ダメージからnum4 * 100[1] / 100 を引き算します。

最後に、ダメージが負になっていたら0に変更します。

処理順

ダメージ計算

反魔法無属性補正

if (ele == 0 || ele == 926)
{
	e = Element.Void;
	if (origin != null)
	{
		dmg = dmg * Mathf.Max(100 + origin.Evalue(93) / 2, 10) / 100;
	}
}

反魔法エンチャントの値に応じて、無属性の攻撃のダメージを増減させます。

ダメージ倍率は以下の通りです。[2]

ダメージ = ダメージ × MAX(1 + 反魔法エンチャント強度 × 0.005, 0.1)

属性耐性

if (!e.source.aliasRef.IsEmpty() && attackSource != AttackSource.ManaBackfire)
{
	int num2 = ((origin != null) ? origin.Evalue(1238) : 0);
	if (attackSource == AttackSource.MagicSword)
	{
		num2 += 2;
	}
	dmg = Element.GetResistDamage(dmg, Evalue(e.source.aliasRef), num2);
...
public static int GetResistDamage(int dmg, int v, int power = 0)
{
	int num = GetResistLv(v);
	if (power > 0 && num > 0)
	{
		num = Mathf.Max(num - power, 0);
	}
	if (num >= 4)
	{
		return 0;
	}
	return num switch
	{
		3 => dmg / 4, 
		2 => dmg / 3, 
		1 => dmg / 2, 
		0 => dmg, 
		-1 => dmg * 3 / 2, 
		-2 => dmg * 2, 
		_ => dmg * 2, 
	};
}
...
public static int GetResistLv(int v)
{
	int num = v / 5;
	if (num < -2)
	{
		num = -2;
	}
	if (num > 4)
	{
		num = 4;
	}
	return num;
}

無属性以外で、マナの反動によるダメージでないものは属性耐性によるダメージ増減が行われます。

まず、攻撃対象の属性耐性評価を算出します。

属性耐性評価 = CLAMP[3](該当する属性耐性 / 5, -2, 4)
※ゲーム内では耐性25以上は「免疫+」と評価されますが、現状特に意味はありません。

次に、攻撃者の属性貫通力を算出します。

属性貫通力 = 古代種フィートLv + (0、剣魔法のみ2)

属性耐性評価と属性貫通力が共に1以上であれば、最終的な属性耐性評価を減らします。ただし、これによって属性耐性評価が0未満になることはありません。

属性耐性評価 = MAX(属性耐性評価 - 属性貫通力, 0)

最終的な属性耐性評価の値に応じて、ダメージを増減させます。ダメージ倍率は以下の通りです。

-2 (致命的な弱点) -1 (弱点) 0 (なし) 1 (耐性) 2 (強い耐性) 3 (素晴らしい耐性) 4 (免疫)
×2 ×1.5 ×1 ×0.5 ×0.333 ×0.25 ×0

魔法耐性補正

if (!e.source.aliasRef.IsEmpty() && attackSource != AttackSource.ManaBackfire)
{
...
	dmg = dmg * 100 / (100 + Mathf.Clamp(Evalue(961) * 5, -50, 200));
...

無属性以外で、マナの反動によるダメージでないものは属性耐性と重複して魔法属性耐性によるダメージ増減が行われます。

ダメージ倍率は以下の通りです。

ダメージ = ダメージ / (1 + CLAMP[3](魔法属性耐性 × 0.05, -0.5, 2))

最低でダメージ「2倍」(魔法属性耐性-10)、最大でダメージ「0.333倍」(魔法属性耐性40)となります。

反魔法属性補正

if (!e.source.aliasRef.IsEmpty() && attackSource != AttackSource.ManaBackfire)
{
...
	dmg = dmg * Mathf.Max(100 - Evalue(93), 10) / 100;
...

無属性以外で、マナの反動によるダメージでないものは属性耐性と重複して反魔法エンチャントによるダメージ減少が行われます。

ダメージ倍率は以下の通りです。[4]

ダメージ = ダメージ × MAX(1 - , 0.1)

ダメージ減少の上限は「0.1」倍で、上限となるエンチャント強度は「90」です。

濡れ補正

switch (e.id)
{
    case 910:
	{
		Chara chara2 = Chara;
		if (chara2 != null && chara2.isWet)
		{
			dmg /= 3;
		}
		break;
	}
	case 912:
	{
		Chara chara = Chara;
		if (chara != null && chara.isWet)
		{
			dmg = dmg * 150 / 100;
		}
		break;
	}
}

攻撃対象が濡れ状態の場合、火炎属性はダメージが「0.333」倍、電撃属性はダメージ「1.5」倍になります。

制圧による与ダメージ減少

if (origin != null && origin.isChara && origin.Chara.HasCondition<ConSupress>())
       {
           dmg = dmg * 2 / 3;
       }

制圧状態のキャラの与ダメージが減る処理です。

ダメージが、2/3倍になります。

※ここからはしばらく、AttackTypeがFinishでないときの計算です。

敵のレベルに応じたダメージ軽減

レベル50を超えた敵が受けるダメージ軽減量は以下の通りです:

まず、レベル50以下の敵の軽減率は0%、レベル1074以上の敵は軽減率80%となります。

if (!this.IsPCFaction && this.LV > 50)
{
    dmg = dmg * (100 - (int)Mathf.Min(80f, Mathf.Sqrt((float)(this.LV - 50)) * 2.5f)) / 100;
}


プレイヤーのファクションに属さないキャラで、レベルがLv50より高い場合:

与えるダメージに、* (100 - [ 2.5 * √(敵のレベル - 50) か 80 かのうち小さいほう ][5]) / 100が掛けられます。

つまり、Lv1074以上の敵に対してはダメージが80%減少し、Lv51~Lv1073の敵に対しては[sqrt(敵Lv-50) * 2.5]%減少します。

レベル毎のダメージ軽減
敵のLv 軽減率(%)
51 2
100 17
150 25
200 30
250 35
300 39
350 43
400 46
450 50
500 53
550 55
600 58
650 61
700 63
750 66
800 68
850 70
900 72
950 75
1000 77
1050 79
1074 80
1100 80

物理軽減と属性軽減によるダメージ減少

dmg = dmg * Mathf.Max(0, 100 - Evalue((e == Element.Void || e.id == 926) ? 55 : 56)) / 100;

属性が無いなら物理軽減、あるなら属性軽減を用いて、ダメージを(100-その値)/100内にします。

100-その値の下限は0となっており、ダメージがマイナスになるのを防いでいます。

これらの軽減は基本的には種族特性ですが、信仰AFの一部にはこれらを上昇させるものが存在します。

弱点の知識による与ダメージ減少

if (origin != null && origin.IsPC && EClass.player.codex.Has(id))
           {
               dmg = dmg * (100 + Mathf.Min(10, EClass.player.codex.GetOrCreate(id).weakspot)) / 100;
           }

危ない本かカード収集によるそのモンスターへの与ダメージ増加を示しています。

(100+収集数[6])%増加します。

ただし、上限は110%です。

盾による軽減

           if (isChara && Chara.body.GetAttackStyle() == AttackStyle.Shield && elements.ValueWithoutLink(123) >= 5 && (e == Element.Void || e.id == 926))
           {
               dmg = dmg * 90 / 100;
           }

スタイルが盾持ちのキャラには物理ダメージが0.9倍になります。

ダメージ耐性

if (Evalue(971) > 0)
           {
               dmg = dmg * 100 / Mathf.Clamp(100 + Evalue(971), 25, 1000);
           }

ダメージ耐性を持つなら、被ダメージが100/(100+その値)倍になります。

ただし、(100+その値)は下限25、上限1000に押し込められます。

ダメージ耐性は詳細は不明ですが、内部的には物理という属性への耐性であり、物理属性は通常の属性軽減の式では計算が除外されていることから、

ここで計算している可能性があります。魔法属性のファンネルが無属性に弱点であり、この計算式に関連する可能性があります。

大地の加護

           if (HasElement(1305))
           {
               dmg = dmg * 90 / 100;
           }

オパートス信仰による大地の加護を持つなら被ダメージが0.9倍。

狐守

           if (EClass.pc.HasElement(1207) && isChara)
           {
               int num = 0;
               int num2 = 0;
               foreach (Condition condition2 in Chara.conditions)
               {
                   if (condition2.Type == ConditionType.Buff)
                   {
                       num++;
                   }
                   else if (condition2.Type == ConditionType.Debuff)
                   {
                       num2++;
                   }
               }
               if (IsPCParty)
               {
                   dmg = dmg * 100 / Mathf.Min(100 + num * 5, 120);
               }
               else
               {
                   dmg = dmg * Mathf.Min(100 + num2 * 5, 120) / 100;
               }
           }

プレイヤーが狐守フィートを持っていると、 まず、バフの数をnum、デバフの数をnum2として、 プレイヤーのパーティ内のキャラなら、被ダメージが100/(100+num*5)倍になります。ただし、(100+num*5)は上限120を持ちます。 そうでないとき、被ダメージが(100+num*5)/100倍になります。ただし、(100+num*5)は上限120を持ちます。

フィートの説明文に反して、だれがつけたバフ・デバフであろうと、狐守持ちのプレイヤーがいれば発動する効果のようです。

味方ミニオンへの配慮がないために、味方ミニオンが敵からデバフをもらうと、被ダメージが増加すると考えられます。

オートコンバット時の被ダメージ減少

           if (IsPCParty && EClass.pc.ai is GoalAutoCombat)
           {
               dmg = dmg * 100 / Mathf.Clamp(105 + EClass.pc.Evalue(135) / 10, 10, 110);
           }

プレイヤーのパーティ内のキャラなら、オートコンバット中はダメージが100/(105+戦略スキル/10)倍になります。

ただし、(105+戦略スキル/10)は下限10、上限110に押し込められます。

つまり、戦略スキル50で軽減が上限に達します。

メタルフィートによるダメージ軽減

           if (HasElement(1218) && attackSource != AttackSource.ManaBackfire && (hp > 0 || Evalue(1421) <= 0))
           {
               dmg = dmg * (1000 - Evalue(1218)) / 1000;
               if (dmg <= 0 && EClass.rnd(4) == 0)
               {
                   dmg++;
               }
           }

メタルによるダメージ軽減です。(マナの反動によるダメージや、マナの体の恩恵でHP0に踏みとどまっているときに受けるダメージには適用されません。)

まず、ダメージが(1000-メタルのフィートLv.)/1000倍になります。メタルのフィートLv.は基本的に999なので、

ダメージは1000分の一になります。

そして、ダメージが0以下かつ、0-3が均等に出る乱数で0が出たとき、

ダメージが1増えます。

これはメタルにほとんどダメージを与えられない時でも、ときどきダメージが入る現象を起こしています。

致命傷防御によるダメージ軽減

           if (dmg >= MaxHP / 10 && Evalue(68) > 0)
           {
               int num3 = MaxHP / 10;
               int num4 = dmg - num3;
               num4 = num4 * 100 / (200 + Evalue(68) * 10);
               dmg = num3 + num4;
           }

致命傷防御を持っているとき、被ダメージが最大HPの10%を超えるようであれば、ダメージは、num3 + num4になります。

num3は最大HPの10%で、

num4は元のダメージが最大HPの10%を超えた量に、100/(200 + 致命傷防御の値*10)をかけたものです。

現状、致命傷防御は黄金の騎士で100、防衛者で50です。

※ここからはAttackTypeがFinishでも発生します。

暴力禁止による与ダメージ消滅

       if (origin != null && origin.IsPC && EClass.pc.Evalue(654) > 0)
       {
           dmg = 0;
       }

子狐丸の、暴力禁止エンチャントの効果です。

ダメージがプレイヤーに由来するなら0にします。

フェイルセーフ的符号確認

 if (dmg < 0)
       {
           dmg = 0;
       }

もしダメージがマイナスなら、0にします。

攻撃の手痛さ

int num5 = Mathf.Clamp(dmg * 6 / MaxHP, 0, 4) + ((dmg > 0) ? 1 : 0);

しばらく後に使われるnum5を計算します。

num5は攻撃の手痛さを示すと考えられます。

まず、ダメージの6倍を最大HPで割ったものを上限4、下限0に押し込めます。

次に、ダメージが正の数なら、それに1を足し、そうでないなら0を足したものがnum5です。

マナの体の仕様

こちらのページで説明されています

ダメージを受ける

 else
       {
           hp -= dmg;
       }

マナの体を持たない場合はただダメージを受けます。

被ダメージ時の処理

出血アニメーション

if (isSynced && dmg != 0)
       {
           float ratio = (float)dmg / (float)MaxHP;
           Card c = ((parent is Chara) ? (parent as Chara) : this);
           ActEffect.TryDelay(delegate
           {
               c.PlayEffect("blood").SetParticleColor(EClass.Colors.matColors[material.alias].main).Emit(20 + (int)(30f * ratio));
               if (EClass.core.config.test.showNumbers || isThing)
               {
                   Popper popper = EClass.scene.popper.Pop(renderer.PositionCenter(), "DamageNum");
                   Color c2 = (c.IsPC ? EClass.Colors.textColors.damagePC : (c.IsPCFaction ? EClass.Colors.textColors.damagePCParty : EClass.Colors.textColors.damage));
                   if (e != Element.Void)
                   {
                       c2 = EClass.Colors.elementColors.TryGetValue(e.source.alias);
                       float num14 = (c2.r + c2.g + c2.b) / 3f;
                       num14 = ((num14 > 0.5f) ? 0f : (0.6f - num14));
                       c2 = new Color(c2.r + num14, c2.g + num14, c2.b + num14, 1f);
                   }
                   popper.SetText(dmg.ToString() ?? "", c2);
               }
           });
       }

被ダメージのエフェクト、例えば普通の生物なら血、機械なら金属クズなどを発生させる処理と、

ダメージを表示するオプションがONになっている際のダメージ表記を行っています。

死を回避する

       void EvadeDeath()
       {
           hp = 0;
           if (Evalue(1421) > 0 && isChara && Chara.mana.value < 0)
           {
               Chara.mana.value = 0;
           }
       }

HPを0にし(HPがマイナスにならないとキャラクターは死亡しない)、マナの体を持っているキャラならば、MPを0にします。

スタミナ消費による

               else
               {
                   if (attackSource != AttackSource.Finish && IsPCParty && Chara.host == null)
                   {
                       if (EClass.pc.ai is GoalAutoCombat && !EClass.player.invlunerable && (EClass.pc.ai as GoalAutoCombat).listHealthy.Contains(Chara))
                       {
                           EClass.core.actionsNextFrame.Add(delegate
                           {
                               Msg.Say(IsPC ? "abort_damage" : "abort_damgeAlly");
                           });
                           EClass.player.invlunerable = true;
                           EClass.player.TryAbortAutoCombat();
                           EClass.pc.stamina.Mod(-EClass.pc.stamina.max / 5);
                       }
                       if (EClass.player.invlunerable)
                       {
                           EvadeDeath();
                           goto IL_0a8f;
                       }
                   }

受けた攻撃がFinishでなく、かつPCに騎乗も寄生もしていないペットのとき、スタミナを消費して耐えます。


運命の誓約による即死回避

                   if (IsPC && Evalue(1220) > 0 && Chara.stamina.value >= Chara.stamina.max / 2)
                   {
                       Chara.stamina.Mod(-Chara.stamina.max / 2);
                       Chara.AddCondition<ConInvulnerable>();
                       EvadeDeath();
                   }
               }

もし、運命の誓約モードかつ、スタミナが最大値の半分以上残っているなら、

スタミナを最大値の半分減らし、死を回避します。

状態異常付与

飛んで、4213行目から状態異常に関する記述がみられます。

詳細は、こちらでご覧ください。

  1. この100は冒頭で出てきたmodであり、バランス調整用に変数になっているものの、ただの定数値だと考えられます。。
  2. 反魔法エンチャントは生成時に呪われた装備が負の値を取りえるため、0.1倍を下限としてダメージが減少することがあります。
  3. 3.0 3.1 値を一定範囲内に制限する関数です。 関数内の1つめの引数の値は、「2つめの引数の値」~「3つめの引数の値」の範囲内になるよう補正されます。
  4. 反魔法エンチャントは生成時に呪われた装備が負の値を取りえるため、ダメージが増加することがあります。この場合の上限はありません。
  5. 正確には小さい方を四捨五入したもの
  6. 未確認