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

From Ylvapedia
< User:びゃっこ‎ | すたぶ
Revision as of 08:07, 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.01, 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;
}

攻撃者が制圧状態場合、ダメージが、「0.667」倍になります。

敵Lv補正

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

レベル50を超えるPC勢力以外のキャラクターが受けるあらゆるダメージは軽減されます。

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

ダメージ = ダメージ × (1 - Min(0.025 × √(攻撃対象Lv - 50), 0.8))

この軽減は攻撃対象がLv1074の時最大となり、ダメージ倍率は「0.2」倍となります。以下は敵Lvごとのダメージ倍率の簡易表です。

レベル毎のダメージ軽減
敵のLv 軽減率(倍)
51 ×0.98
100 ×0.83
150 ×0.75
200 ×0.70
250 ×0.65
300 ×0.61
350 ×0.57
400 ×0.54
450 ×0.50
500 ×0.47
550 ×0.45
600 ×0.42
650 ×0.39
700 ×0.37
750 ×0.34
800 ×0.32
850 ×0.30
900 ×0.28
950 ×0.25
1000 ×0.23
1050 ×0.21
1074 ×0.20
1100 ×0.20

狂戦士補正

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

狂戦士化状態の攻撃者による、状態異常や瘴気など[5]以外のあらゆるダメージを「1.5」倍にします。

摂理補正

if (EClass.game.principal.enableDamageReduction && IsPCFaction)
{
	int num3 = ((origin != null) ? origin.LV : EClass._zone.DangerLv);
	if (num3 > 50)
	{
		dmg = dmg * (100 - (int)Mathf.Min(95f, Mathf.Sqrt(num3 - 50))) / 100;
	}
}

「高レベル帯での敵の与えるダメージを減衰する」摂理が有効のとき、PC勢力がLv51以上のキャラクターから受けるあらゆるダメージを軽減します。

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

ダメージ = ダメージ × (1 - MIN(0.01 × √(攻撃者Lv - 50), 0.95))


また危険度51階以上のフロアでは、状態異常や瘴気など[5]によるダメージをフロアの危険度に応じてダメージを軽減します。

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

ダメージ = ダメージ × (1 - MIN(0.01 × √(フロア危険度 - 50), 0.95))

物理軽減(PDR)補正

bool flag = originalTarget != null;
...
dmg = dmg * Mathf.Max(0, 100 - Mathf.Min(Evalue((e == Element.Void || e.id == 926) ? 55 : 56), 100) / ((!flag) ? 1 : 2)) / 100;

あらゆる無属性ダメージを、物理軽減(種族特性や「それは物理軽減をXX%上昇させる」エンチャントによるもの)を用いて軽減します。

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

ダメージ = ダメージ × MAX((1 - MIN(物理軽減強度 × 0.01, 1) × (1、肉の壁フィートによるダメージのみ0.5)), 0)

物理軽減が100以上の場合、無属性ダメージは0ダメージになります。(肉の壁フィートによるダメージを除く。)

肉の壁フィートによるダメージの場合は物理軽減の効果が半減し、物理軽減「100」の「0.5」倍が上限となります。

属性軽減(EDR)補正

bool flag = originalTarget != null;
...
dmg = dmg * Mathf.Max(0, 100 - Mathf.Min(Evalue((e == Element.Void || e.id == 926) ? 55 : 56), 100) / ((!flag) ? 1 : 2)) / 100;

あらゆる属性ダメージを、属性軽減(種族特性や「それは属性軽減をXX%上昇させる」エンチャントによるもの)を用いて軽減します。

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

ダメージ = ダメージ × MAX((1 - MIN(属性軽減強度 × 0.01, 1) × (1、肉の壁フィートによるダメージのみ0.5)), 0)

属性軽減が100以上の場合、属性ダメージは0ダメージになります。(肉の壁フィートによるダメージを除く。)

肉の壁フィートによるダメージの場合は属性軽減の効果が半減し、属性軽減「100」の「0.5」倍が上限となります。

発見済み弱点補正

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

攻撃対象の弱点を発見している場合、PCによる攻撃のみ、状態異常や瘴気など[5]以外のあらゆるダメージが増加します。

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

ダメージ = ダメージ × (1 + MIN(対応する発見済み弱点数 × 0.01, 0.1))

発見済み弱点数x10「1.1」倍が上限です。

盾軽減補正

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

攻撃対象のスタイルが盾持ち且つ盾スキルが5以上の場合、無属性ダメージが「0.9」倍になります。

ダメージ耐性補正

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

ダメージ耐性の値に応じてあらゆるダメージを軽減します。

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

ダメージ = ダメージ / CLAMP((1 + ダメージ耐性強度 × 0.01), 0.25, 10))

主要属性が魔法属性のキャラクターのみダメージ耐性「-10」をもち、それ以外では使われていません。(事実上、主要属性が魔法属性のキャラクターに「1.11」倍)

大地の加護補正

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

オパートス信仰による大地の加護を持つ場合、被ダメージを「0.9」倍します。

狐守補正

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


プレイヤーが狐守フィートを持っている場合[6]、攻撃対象がPCパーティー内にいた場合のあらゆるダメージをバフ数に応じて軽減し、攻撃対象がPCパーティー外にいた場合のあらゆるダメージ[7]がデバフ数に応じて増加します。

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

ダメージ = ダメージ × MIN(1 + 攻撃対象デバフ数 × 0.05, 1.2)

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

ダメージ = ダメージ / MIN(1 + 攻撃対象バフ数 × 0.05, 1.2)

バフ・デバフ数が「5」個以上の時効果が最大となり、与ダメージは「1.2」倍、被ダメージは「0.83」倍となります。

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

           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. 5.0 5.1 5.2 暴力禁止エンチャント有効下でダメージを与えられるもの、つまり攻撃者の認識ができないもの。
  6. PC以外が持っていても効果がない。
  7. 状態異常や瘴気、PCパーティーと全く関係のないダメージも増加する。