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))
物理軽減と属性軽減によるダメージ減少
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行目から状態異常に関する記述がみられます。
詳細は、こちらでご覧ください。
- ↑ この100は冒頭で出てきたmodであり、バランス調整用に変数になっているものの、ただの定数値だと考えられます。。
- ↑ 反魔法エンチャントは生成時に呪われた装備が負の値を取りえるため、0.1倍を下限としてダメージが減少することがあります。
- ↑ 3.0 3.1 値を一定範囲内に制限する関数です。 関数内の1つめの引数の値は、「2つめの引数の値」~「3つめの引数の値」の範囲内になるよう補正されます。
- ↑ 反魔法エンチャントは生成時に呪われた装備が負の値を取りえるため、ダメージが増加することがあります。この場合の上限はありません。
- ↑ 5.0 5.1 暴力禁止エンチャント有効下でダメージを与えられるもの、つまり攻撃者の認識ができないもの
- ↑ 未確認