Elin:解析/物理戦闘: Difference between revisions

From Ylvapedia
(エネルギー反射の追加の攻撃倍率が抜けていたので追加。エネルギー反射の特殊処理を一部だけ記述。(詳細を全て書ききるのは諦めました))
(攻撃力の上限は100000000になった。大回転の攻撃倍率を追加。)
Line 1,381: Line 1,381:
     AttackProcess.Current.Perform(j, hasHit, chara.IsPCFactionOrMinion ? 0.5f : 2.5f);
     AttackProcess.Current.Perform(j, hasHit, chara.IsPCFactionOrMinion ? 0.5f : 2.5f);


</syntaxhighlight>突進・斬撃無双・カウンター・パリィ・レーザー反射から発生した攻撃はそれぞれ追加の攻撃倍率を持ち、それを攻撃力に乗算します。
</syntaxhighlight>突進・斬撃無双・大回転・カウンター・パリィ・レーザー反射から発生した攻撃はそれぞれ追加の攻撃倍率を持ち、それを攻撃力に乗算します。


攻撃力は以下のようになります。
攻撃力は以下のようになります。
  物理攻撃力 = 物理攻撃力 × 追加の攻撃倍率
  物理攻撃力 = 物理攻撃力 × 追加の攻撃倍率
斬撃無双の攻撃倍率は'''「0.2」'''倍、カウンターの攻撃倍率は'''「1」'''<ref>変動するような仕組みは用意されているものの、bonusが初期値以外の値を取らないため現状は1倍で固定。</ref>倍、パリィの攻撃倍率は'''「1.5」'''倍、PC勢力へのレーザー反射は'''「0.5」'''倍、PC勢力以外へのレーザー反射は'''「2.5」'''倍です。
斬撃無双の攻撃倍率は'''「0.2」'''倍、大回転の攻撃倍率は'''「1.2」'''倍、カウンターの攻撃倍率は'''「1」'''<ref>変動するような仕組みは用意されているものの、bonusが初期値以外の値を取らないため現状は1倍で固定。</ref>倍、パリィの攻撃倍率は'''「1.5」'''倍、PC勢力へのレーザー反射は'''「0.5」'''倍、PC勢力以外へのレーザー反射は'''「2.5」'''倍です。


突進の攻撃倍率は以下の式で算出されます。
突進の攻撃倍率は以下の式で算出されます。
Line 1,395: Line 1,395:
...
...
num = (long)(dMulti * (float)num * dmgMulti);
num = (long)(dMulti * (float)num * dmgMulti);
return (long)Mathf.Clamp(num, 0f, 9999999);
return (long)Mathf.Clamp(num, 0f, 100000000f);
</syntaxhighlight>上記までの物理攻撃力の算出の際、「9999999」を超えた場合は'''「9999999」'''に補正されます。
</syntaxhighlight>上記までの物理攻撃力の算出の際、「100000000」を超えた場合は'''「100000000」'''に補正されます。


後述する連射数修正と種族特攻エンチャントは、この上限の適用後に計算されます。
後述する連射数修正と種族特攻エンチャントは、この上限の適用後に計算されます。

Revision as of 07:58, 19 October 2025

バージョン EA23.212: この記事は、Elin最新の安定版リリースに、少なくとも20のマイナーバージョンが遅れています。ページの更新をお願いします。

近接攻撃処理順

FOR 0 TO 攻撃可能武器数
    IF パリィ判定に1度でも成功している
        EXIT FOR
    ↓
    FOR 0 TO 突貫・拡散・旋風エンチャ攻撃回数
        IF パリィ判定に1度でも成功している
            EXIT FOR
        ↓
        FOR 0 TO 連撃エンチャ攻撃回数
            パリィ判定
            ↓
            IF パリィ判定に成功
                EXIT FOR
            ↓
            FOR 0 TO 追尾エンチャ回数
                命中判定
                ↓
                IF 命中判定に成功 OR 逆襲エンチャ発動
                    攻撃能力の算出
                    ↓
                    補正前ダメージ算出
                    ↓
                    属性追加ダメージエンチャ処理
                    ↓
                    シールドバッシュ
                    ↓
                    盾の発動エンチャ処理
                    ↓
                    武器の発動エンチャ処理
                    ↓
                    武器のノックバック処理
                    ↓
                    霊符発動処理
                    ↓
                    EXIT FOR
                ↓
                発動エンチャント
            ↓
            牽制エンチャ処理
            ↓
            衝撃波エンチャ処理
            ↓
            海嘯のノックバック処理
            ↓
        ↓
    ↓
↓
IF パリィ判定に1度でも成功している
    パリィ反撃処理
↓
ELSE IF 攻撃を1度でも回避している
    カウンター処理
↓
終了

遠隔攻撃処理順

突貫・拡散エンチャント処理
↓
FOR 0 TO 連射数
    ↓
    エネルギー反射判定
    ↓
    IF エネルギー反射に成功
        エネルギー反射処理
    ↓
    IF エネルギーでない OR エネルギー反射に失敗
        FOR 0 TO 追尾エンチャ回数
            命中判定
            ↓
            IF 命中判定に成功
                攻撃能力の算出
                ↓
                補正前ダメージ算出
                ↓
                属性追加ダメージエンチャ処理
                ↓
                発動エンチャ処理
                ↓
                武器のノックバック処理
                ↓
                EXIT FOR
            ↓
        ↓
        発動エンチャント
    ↓
↓
終了

投擲攻撃処理順

命中判定
↓
IF 命中判定に成功
    攻撃能力の算出
    ↓
    補正前ダメージ算出
    ↓
    属性追加ダメージエンチャ処理
    ↓
    武器のノックバック処理↓
↓
発動エンチャ処理
↓
終了

攻撃能力の算出

格闘

else if (IsMartial || IsMartialWeapon)
{
	weaponSkill = CC.elements.GetOrCreateElement(100);
	bool flag2 = weapon != null && weapon.Evalue(482) > 0;
	if (flag2)
	{
		weaponSkill = CC.elements.GetOrCreateElement(305);
	}
	attackType = ((!CC.race.meleeStyle.IsEmpty()) ? CC.race.meleeStyle.ToEnum<AttackType>() : ((EClass.rnd(2) == 0) ? AttackType.Kick : AttackType.Punch));
	dBonus = CC.DMG + CC.encLV + (int)Mathf.Sqrt(Mathf.Max(0, weaponSkill.GetParent(CC).Value / 5 + weaponSkill.Value / 4));
	dNum = 2 + Mathf.Min(weaponSkill.Value / 10, 4);
	dDim = 5 + (int)Mathf.Sqrt(Mathf.Max(0, weaponSkill.Value / 3));
	dMulti = 0.6f + (float)(weaponSkill.GetParent(CC).Value / 2 + weaponSkill.Value / 2 + CC.Evalue(flag2 ? 304 : 132) / 2) / 50f;
	dMulti += 0.05f * (float)CC.Evalue(1400);
	toHitBase = EClass.curve(CC.DEX / 3 + weaponSkill.GetParent(CC).Value / 3 + weaponSkill.Value, 50, 25) + 50;
	toHitFix = CC.HIT;
	if (attackStyle == AttackStyle.Shield)
	{
		toHitBase = toHitBase * 75 / 100;
	}
	penetration = Mathf.Clamp(weaponSkill.Value / 10 + 5, 5, 20) + CC.Evalue(92);
	if (CC.HasElement(1246))
	{
		penetration += 25;
	}
	if (IsMartialWeapon)
	{
		dBonus += weapon.DMG;
		dNum += weapon.source.offense[0];
		dDim = Mathf.Max(dDim / 2 + weapon.c_diceDim, 1);
		toHitFix += weapon.HIT;
		penetration += weapon.Penetration;
		if (!weapon.source.attackType.IsEmpty())
		{
			attackType = weapon.source.attackType.ToEnum<AttackType>();
		}
	}
}

キャラクターは格闘スキルを使用して格闘攻撃を繰り出します。通常はパンチないしキックですが、武器の近接戦闘スタイルやキャラクターの特性に基づいて攻撃エフェクトは変わります。

武器に理力武器のエンチャントが付いている場合、格闘スキルの代わりに魔道具スキルを、戦術スキルの代わりに詠唱スキルを使用します。


素手及び通常の格闘武器の場合:

ダメージの基礎ダイス数は「2 + 格闘 / 10」で、最大で6です。

ダメージの基礎ダイス面は「5 + √(格闘 / 3)」です。

基礎ダメージ修正は「√(筋力 / 5 + 格闘 / 4) + 防具のダメージ修正合計 + キャラ固有のダメージ修正[1]」です。

ダメージ倍率は「0.6 + ((筋力 / 2 + 格闘 / 2 + 戦術 / 2) / 50.0)」です

貫通率は「格闘 / 10 + 5」で、最低5%、最高で20%です。[2]

ペガサス座のフィートを持つ場合、基礎貫通率に25%を加算します。

基礎命中力は「(器用 / 3 + 筋力 / 3 + 格闘)」を、スタート50、ステップ25、レート75%のCURVE関数で計算した後、50を足したものです。


理力武器のエンチャントが付いた格闘武器の場合:

ダメージの基礎ダイス数は「2 + 魔道具 / 10」で、最大で6です。

ダメージの基礎ダイス面は「5 + √(魔道具 / 3)」です。

基礎ダメージ修正は「√(魔力 / 5 + 魔道具 / 4) + 防具のダメージ修正合計 + キャラ固有のダメージ修正[1]」です。

ダメージ倍率は「0.6 + ((魔力 / 2 + 魔道具 / 2 + 詠唱 / 2) / 50.0)」です

基礎貫通率は「魔道具 / 10 + 5」で、最低5%、最高で20%です。[2]

ペガサス座のフィートを持つ場合、基礎貫通率に25%を加算します。

基礎命中力は「器用 / 3 + 魔力 / 3 + 魔道具」を、スタート50、ステップ25、レート75%のCURVE関数で計算した後、50を足したものです。


プレイヤーが武器の知識フィートを持っている場合、ダメージ倍率に『0.05×(武器の知識フィートのランク)』だけ加算されます。(事実上、+0.05または+0.10)

プレイヤーが盾を装備している場合、基礎命中力は0.75倍に修正されます。

上記の後、基礎命中力に防具の命中修正が加算されます。


さらに、格闘武器を装備している場合は以下の修正を受けます。

最終的なダイス数は「基礎ダイス数 + 武器の基礎ダイス数」です。

最終的なダイス面は「基礎ダイス面 / 2 + 武器の基礎ダイス数」です。

最終的なダメージ修正は「基礎ダメージ修正 + 武器のダメージ修正」です。

両手持ちをしている場合、ダメージ倍率を「1.5」倍にし、さらに「0.1 × √(両手持ちスキル)」だけ加算します。

最終的な命中力は「基礎命中力 + 武器の命中修正」です。

最終的な貫通率は「基礎貫通率 + 武器の貫通率」です。

投擲

if (isThrow)
{
	bool flag = weapon.HasTag(CTAG.throwWeapon) || weapon.HasTag(CTAG.throwWeaponEnemy);
	int num2 = (int)Mathf.Clamp(Mathf.Sqrt(weapon.SelfWeight + weapon.ChildrenWeight) * 3f + 25f + (float)(flag ? 75 : 0), 10f, 400f + Mathf.Sqrt(CC.STR) * 50f);
	int num3 = Mathf.Clamp(weapon.material.hardness, flag ? 40 : 20, 200);
	weaponSkill = CC.elements.GetOrCreateElement(108);
	attackType = AttackType.Blunt;
	dBonus = CC.DMG + (CC.IsPCParty ? 3 : 7);
	dNum = 2;
	dDim = (((!CC.IsPCParty) ? CC.LV : 0) + CC.STR + CC.Evalue(108)) * num2 * num3 / 10000 / 2;
	dMulti = 1f;
	toHitBase = EClass.curve(CC.DEX / 4 + CC.STR / 2 + weaponSkill.Value, 50, 25) + (CC.IsPCFaction ? 75 : 250);
	toHitFix = CC.HIT + weapon.HIT;
	penetration = 25;
}

プレイヤーの投げたアイテムは投擲武器であってもそうでなくても投擲スキルを参照します。

攻撃エフェクトは常に鈍器です。

重量値は 25 + 投擲武器限定75[3] + 3 * √ [アイテムの重量] ですが、下限10、上限400 + 50 * √(筋力)があります。

ここでいうアイテムの重量はゲーム中の〇.〇sに1000をかけたものです。

武器の材質値は素材の硬度です。上限は200で、これはダークマターの硬度と等しく、下限は投擲武器を投げている場合40、それ以外では20として設定されています。


ダイスの数は常に「2」です。

ダイスの面は「((プレイヤーパーティー外のキャラのみLv) + 筋力 + 投擲 ) * 重量値 * 武器の材質値 / 10000 / 2」です。

ダメージボーナスは「(プレイヤーパーティー内のキャラの場合:3、それ以外の場合:7) + 武器のダメージ修正 + 防具のダメージ修正合計 + キャラ固有のダメージ修正[1]」です。

ダメージ倍率は常に「1」です。

貫通力は常に25%です。

基礎命中力は「器用 / 4 + 筋力 / 2 + 投擲」を、スタート50、ステップ25、レート75%のCURVE関数で計算した後、プレイヤーキャラクターの場合:75、それ以外の場合:250 を足したもので、

最終的な命中力は「基礎命中力 + 武器の命中修正 + 防具の命中修正合計」です。

近接&遠隔武器

else
{
    if (IsRanged)
    {
        weaponSkill = CC.elements.GetOrCreateElement(toolRange.WeaponSkill);
    }
    else
    {
        weaponSkill = CC.elements.GetOrCreateElement(weapon.category.skill);
    }
    if (!weapon.source.attackType.IsEmpty())
    {
        attackType = weapon.source.attackType.ToEnum<AttackType>();
    }
    bool flag3 = IsCane || weapon.Evalue(482) > 0;
    if (flag3)
    {
        weaponSkill = CC.elements.GetOrCreateElement(305);
    }
    dBonus = CC.DMG + CC.encLV + weapon.DMG;
    dNum = weapon.source.offense[0];
    dDim = weapon.c_diceDim;
    dMulti = 0.6f + (float)(weaponSkill.GetParent(CC).Value + weaponSkill.Value / 2 + CC.Evalue(flag3 ? 304 : (IsRanged ? 133 : 132))) / 50f;
    dMulti += 0.05f * (float)CC.Evalue(IsRanged ? 1404 : 1400);
    toHitBase = EClass.curve((IsCane ? CC.WIL : CC.DEX) / 4 + weaponSkill.GetParent(CC).Value / 3 + weaponSkill.Value, 50, 25) + 50;
    if (CC.HasElement(1208) && weaponSkill.id == 101)
    {
        toHitBase = toHitBase * 115 / 100;
    }
    toHitFix = CC.HIT + weapon.HIT;
    penetration = weapon.Penetration + CC.Evalue(92);
    if (IsRanged)
    {
        if (CC.HasElement(1244))
        {
            penetration += 25;
        }
    }
    else if (CC.HasElement(1247))
    {
        penetration += 25;
    }
    if (IsCane)
    {
        toHitBase += 50;
    }
}

プレイヤーは、戦術スキルを使用して近接武器を振るうか、または射撃スキルを使用して遠距離武器を撃ちます。

武器がワンド、または理力武器のエンチャントが付いている場合、戦術スキルまたは射撃スキルの代わりに詠唱スキルを、武器スキル(長剣、短剣、斧など)の代わりに魔道具スキルを使用します。


ダメージのダイス数及びダイス面は武器に表記されているものを使用します。

基礎ダメージ修正は「攻撃中の武器のダメージ修正 + 防具のダメージ修正合計 + キャラ固有のダメージ修正[1]」です。

ダメージ倍率は「0.6 + (武器スキルに対応する主能力 + 武器スキル / 2 + (近接武器は戦術、遠距離武器は射撃、ワンドまたは理力武器の場合魔道具)) / 50.0)」です

両手持ちをしている場合、ダメージ倍率を「1.5」倍にし、さらに「0.1 × √(両手持ちスキル)」だけ加算します。

プレイヤーが武器の知識フィートを持っている場合、ダメージ倍率に『0.05 * (武器の知識フィートのランク)』だけ加算されます。(事実上、+0.05または+0.10)


貫通率は武器に表記されているものを使用します。[2]

使用する武器が遠隔武器で、射手座のフィートを持つ場合、貫通率に25%を加算します。

使用する武器が近接武器で、天秤座のフィートを持つ場合、貫通率に25%を加算します。[4]

基礎命中力は「(器用、ワンドなら意志) / 4 + 武器スキルに対応する主能力 / 3 + 武器スキル 」を、スタート50、ステップ25、レート75%のCURVE関数で計算した後、50を足したものです。

命中力は「基礎命中力 + 攻撃中の武器の命中修正 + 防具の命中修正合計 + (ワンドのみ:50、それ以外は0)」です。

さらに、長剣スキルに関連する武器で古き狐の血統フィートを持つキャラクターの場合、命中力を「1.15」倍にします。



さらに、弾薬を消費して攻撃した場合:

ダメージ修正に「弾薬のダメージダイスを振った結果 + 弾薬のダメージ修正」を加算します。

命中力に「弾薬の命中修正」を加算します。

遠隔武器の距離修正

distMod = 100;

if (!isThrow)
{
	if (!IsRanged)
	{
		attackStyle = CC.body.GetAttackStyle();
	}
	else if (TP != null)
	{
		int num = CC.pos.Distance(TP);
		distMod = Mathf.Max(115 - 10 * Mathf.Abs(num - toolRange.BestDist) * 100 / (100 + weapon.Evalue(605) * 10), 80);
	}
}

dMulti = dMulti * (float)distMod / 100f;
toHit = toHitBase + toHitFix;
toHit = toHit * distMod / 100;

遠隔武器には、適正の攻撃距離があり、それによって命中力とダメージ倍率が増減します。

Evalue(605)はmod_precisionであり、遠隔武器の改造道具の精密射撃レベルにあたります。

適正攻撃距離から離れているほど、ペナルティも増えます。

精密射撃の改造道具のない場合、0(適正攻撃距離)の時は命中力、ダメージ共に115%になります、±1は105%、±2は95%、±3は85%、それ以降は80%になります。


精密射撃modの強度と適正距離差による命中力とダメージの倍率(%)は以下の表のようになっています。

精密射撃mod強度 適正距離差0 適正距離差1 適正距離差2 適正距離差3 適正距離差4
0 115 105 95 85 80
10 115 110 105 100 95
20 115 112 109 105 102
30 115 113 110 108 105
40 115 113 111 109 107
50 115 114 112 110 109
60 115 114 113 111 110
70 115 114 113 112 110
80 115 114 113 112 111
90 115 114 113 112 111
99 115 115 114 113 112

遠隔武器の連射数修正

GameSetting.EffectData effectData = EClass.setting.effect.guns.TryGetValue(weapon.id) ?? EClass.setting.effect.guns[flag2 ? "cane" : (flag ? "gun" : "bow")];
bool hasHit = false;
int numFire = effectData.num;
int numFireWithoutDamageLoss = numFire;
...
if (num > 0)
{
	numFire += Mathf.Min(num / 10 + ((num % 10 > EClass.rnd(10)) ? 1 : 0), 10);
	numFireWithoutDamageLoss += num / 100 + ((num % 100 > EClass.rnd(100)) ? 1 : 0);
}
...
if (IsRanged && count >= numFireWithoutDamageLoss)
{
	num = num * 100 / (100 + (count - numFireWithoutDamageLoss + 1) * 30);
}

速射modや連続射撃により遠隔武器に追加の射撃が発生している場合、追加の射撃には回数に応じたダメージ減衰が発生します。

ここでの「numFireWithoutDamageLoss」とは減衰が発生しない発射数で、「count」は現在何発目の射撃かの変数です。「count」は0スタートで、1発目の射撃では0が代入されています。

追加の射撃のダメージ倍率は以下の式で算出されます。

減衰なし発射数 = 遠隔武器の元々の発射数 + 速射mod強度 / 100
ダメージ倍率 = 1 / 1 + 0.3 × (現在の発射回数 - 減衰なし発射数)
※速射mod強度の除算で小数以下が発生する場合、その確率で減衰なし発射数に+1
※ここでの「現在の発射回数」とはコード上での「count + 1」です

例えば元々の発射数が3のアサルトライフルを強度30の速射modによって発射数を6にした場合、

ダメージ倍率は1発目: 100%、2発目: 100%、3発目: 100%、4発目: 76%、5発目:62%、6発目: 52% となります。


元々の発射数が3のアサルトライフルを強度500の速射modによって発射数を13にした場合、

ダメージ倍率は1発目: 100%、2発目: 100%、3発目: 100%、4発目: 100%、5発目: 100%、6発目: 100%、7発目: 100%、8発目: 100%、9発目: 76%、10発目: 62%、11発目: 52% 、12発目: 45% 、13発目: 40% となります。

ヴォーパル

int num2 = CC.Evalue(91);
string id = CC.id;
if ((id == "stalker" || id == "stalker_shadow") && TC.isChara && TC.Chara.CanSee(CC))
{
	num2 = 0;
}
...
num2 += weapon.Evalue(91, ignoreGlobalElement: true);
...
if (hit && num2 > EClass.rnd(100))
{
	CC.Say("vopal");
	penetration = 100;
}

ヴォーパルのエンチャントがついた攻撃は、ヴォーパルのエンチャント強度の確率で攻撃の貫通率を100%にします。

(例えばヴォーパルが30の場合、30%の確率で貫通率を100%にします。 貫通率+30%ではありません。)

ただし、闇子・闇の老師が元々持つヴォーパルは、攻撃対象が闇子・闇の老師の透明化を見破っている場合0になります。[5][6]

武器攻撃エンチャント

武器専用エンチャントの名前
名称 近接 遠隔 投擲 簡易説明
突貫 × 当たった相手を突き抜けて後方にも当たる。
拡散 × 減衰のある範囲攻撃
旋風 × × 攻撃が最初の相手から伝播する
連撃 × × 複数回攻撃する
追尾 × 回避された際に追撃する
逆襲 × × 回避された際に確率で確定命中クリティカル攻撃をする
牽制 × × 制圧の状態異常を付与する
衝撃波 × × 最初の攻撃対象の周りにも当たる衝撃波を発する
ノックバック 攻撃対象を1マス押しのける
護符節約 霊符と唄の使用回数を増やす
慈悲の重み このエンチャントが付与された武器によって対象が死亡するとき、死を回避
事故防止 追加攻撃を抑止

突貫

int num2 = GetWeaponEnc(606, addSelfEnc: false);
...
List<Point> list2 = EClass._map.ListPointsInLine(Act.CC.pos, Act.TC.pos, num2 / 10 + ((num2 % 10 > EClass.rnd(10)) ? 1 : 0) + 1);
...
if (num2 > 0)
{
	foreach (Point item in list2)
	{
		if (!item.Equals(orgPos))
		{
			Chara firstChara = item.FirstChara;
			if (firstChara != null && firstChara.IsHostile(Act.CC))
			{
				AttackWithFlurry(firstChara, item, 1f, subAttack: false);
			}
		}
	}
}

攻撃者の半径「突貫エンチャント強度 / 10 + 1」マス以内かつ、攻撃者と攻撃対象を結ぶ直線上に存在する敵を攻撃します。拡散・旋風エンチャントと共存できず、拡散・旋風の処理は省略されます。

半径に小数点以下が存在する場合、小数点以下の数値の確率で半径に+1します。

1マス内に複数のキャラクターが存在する場合、一番上のキャラクターのみ攻撃されます。

拡散

ActMelee.cs

int scatter = GetWeaponEnc(607, addSelfEnc: false);

else if (scatter > 0)
{
	Act.TP.ForeachNeighbor(delegate(Point p)
	{
		if (!p.Equals(orgPos))
		{
			Chara firstChara2 = p.FirstChara;
			if (firstChara2 != null && firstChara2.IsHostile(Act.CC))
			{
				AttackWithFlurry(firstChara2, p, Mathf.Min(0.5f + 0.05f * Mathf.Sqrt(scatter), 1f + 0.01f * Mathf.Sqrt(scatter)), subAttack: true);
			}
		}
	});
}

ActRanged.cs

int scatter = GetWeaponEnc(607);
...
else if (scatter > 0)
{
	Act.TP.ForeachNeighbor(delegate(Point _p)
	{
		points.Add(_p.Copy());
	});
}
...
if (scatter > 0)
{
	dmgMulti = Mathf.Clamp(1.2f - 0.2f * (float)Act.CC.Dist(Act.TP) - (Act.TP.Equals(orgTP) ? 0f : 0.4f), 0.2f, 1f);
}

攻撃対象の半径1マス以内に存在する敵を攻撃します。突貫・旋風エンチャントと共存できず、旋風の処理は省略されます。

拡散の効果による攻撃はダメージ減衰補正がかかり、

近接攻撃の倍率は「0.5 + 0.05 × √(拡散エンチャント強度)」か「1 + 0.01 × √(拡散エンチャント強度)」のどちらか小さい方です。

遠隔攻撃の倍率は「1.2 - 0.2 × (攻撃者と拡散の攻撃対象との距離) - (0.4、攻撃対象と同じマスにいる敵は0)」で、最小0.2倍です。

旋風

int num3 = GetWeaponEnc(622, addSelfEnc: true);
...
else if (num3 > 0)
{
	List<Point> list = new List<Point>();
	Act.TP.ForeachNeighbor(delegate(Point p)
	{
		list.Add(p.Copy());
	});
	list.Shuffle();
	int num4 = 0;
	for (int i = 0; i < 9 && num3 > EClass.rnd(10 + (int)Mathf.Pow(3f, i + 2)); i++)
	{
		num4++;
	}
	foreach (Point item2 in list)
	{
		foreach (Card item3 in item2.ListCards().Copy())
		{
			if (num4 <= 0 || !Act.CC.IsAliveInCurrentZone)
			{
				break;
			}
			if (item3.trait.CanBeAttacked || (item3.isChara && item3.Chara.IsHostile(Act.CC)))
			{
				AttackWithFlurry(item3, item2, 1f, subAttack: true);
				num4--;
			}
		}
	}
}

攻撃対象のいるマス除く半径1マス以内のランダムな敵1体を攻撃します。攻撃回数はエンチャント強度に依存します。同じ敵を2回攻撃することはありません。

旋風の攻撃回数は "旋風エンチャント強度 > 0~「10 + 3 ^ (旋風攻撃回数 + 2)」までのランダムな値" の判定を満たし続ける限り、最大9回まで増加します。

連撃

flurry = GetWeaponEnc(621, addSelfEnc: true);
...
void AttackWithFlurry(Card _tc, Point _tp, float mtp, bool subAttack)
{
	int num6 = 1;
	if (flurry > 0)
	{
		for (int l = 0; l < 10 && flurry > EClass.rnd(25 + (int)Mathf.Pow(5f, l + 2)); l++)
		{
			num6++;
		}
	}
	for (int m = 0; m < num6; m++)
	{
		if (!Act.CC.IsAliveInCurrentZone)
		{
			break;
		}
		if (!_tc.IsAliveInCurrentZone)
		{
			break;
		}
		if (m > 0)
		{
			Act.CC.Say("attack_flurry");
		}
		Attack(_tc, _tp, mtp, subAttack);
	}
}

追加の攻撃を行います。攻撃回数はエンチャント強度に依存します。

連撃の攻撃回数は "連撃エンチャント強度 > 0~「25 + 5 ^ (連撃攻撃回数 + 2)」までのランダムな値" の判定を満たし続ける限り、最大10回まで増加します。

追尾・逆襲

splash = GetWeaponEnc(608, addSelfEnc: true);
chaser = GetWeaponEnc(620, addSelfEnc: true);
...
if (chaser > 0)
{
	for (int j = 0; j < 10; j++)
	{
		if (chaser > EClass.rnd(4 + (int)Mathf.Pow(4f, j + 2)))
		{
			num8++;
		}
	}
}
bool flag = false;
for (int k = 0; k < num8; k++)
{
	if (!Act.CC.IsAliveInCurrentZone)
	{
		break;
	}
	if (!Act.TC.IsAliveInCurrentZone)
	{
		break;
	}
	if (k > 0)
	{
		Act.CC.Say("attack_chaser");
	}
	flag = AttackProcess.Current.Perform(count, hasHit, dmgMulti * mtp * BaseDmgMTP, maxRoll, subAttack);
	if (!flag && frustration > 0 && !Act.TC.HasElement(439) && 10f + 2f * Mathf.Sqrt(frustration) > (float)EClass.rnd(100))
	{
		AttackProcess.Current.critFury = true;
		flag = AttackProcess.Current.Perform(count, hasHit, dmgMulti * mtp, maxRoll, subAttack);
		AttackProcess.Current.critFury = false;
	}
	if (flag || !Act.CC.IsAliveInCurrentZone || !Act.TC.IsAliveInCurrentZone)
	{
		break;
	}
}

追尾エンチャントは、攻撃が回避された場合、攻撃が命中するまで追尾の回数分再度攻撃を行います。

逆襲エンチャントは、影抜きエンチャントを持たない攻撃対象に攻撃が回避された場合、確率で必中のクリティカルになる攻撃を行います。

追尾と逆襲は共存し、追尾による攻撃1回毎にも逆襲の判定が行われます。逆襲が発動した場合、追尾による再攻撃は終了します。

追尾の回数は "追尾エンチャント強度 > 0~「4 + 4 ^ (追尾回数 + 2)」までのランダムな値" の判定を満たし続ける限り、最大10回まで増加します。

逆襲エンチャントの効果の発動率は「10 + 2 × √(逆襲エンチャント強度)」%です。

牽制

feint = GetWeaponEnc(623, addSelfEnc: true);
...
if (feint > 0 && 10f + 4f * Mathf.Sqrt(feint) > (float)EClass.rnd(100))
{
	Act.TC.Chara.AddCondition<ConSupress>(100 + 5 * (int)Mathf.Sqrt(feint));
}

「10 + 4 × √(牽制エンチャント強度)」%の確率で、状態異常強度「100 + 5 × √(牽制エンチャント強度)」の妨害の状態異常を攻撃対象へ付与します。

衝撃波

splash = GetWeaponEnc(608, addSelfEnc: true);
...
if (splash > 0)
{
	Act.TP.ForeachNeighbor(delegate(Point p)
	{
		if (p.Equals(Act.TP) || p.Equals(Act.CC.pos))
		{
			return;
		}
		if (!p.IsBlocked)
		{
			p.PlayEffect("smoke_shockwave");
			p.Copy().Animate(AnimeID.QuakeMini, animeBlock: true);
		}
		foreach (Card item4 in p.ListCards())
		{
			if ((item4.trait.CanBeAttacked || (item4.isChara && item4.Chara.IsHostile(Act.CC))) && !item4.HasElement(430))
			{
				int rawDamage = AttackProcess.Current.GetRawDamage(0.1f + 0.05f * Mathf.Sqrt(splash), crit: false, maxRoll: false);
				rawDamage = item4.ApplyProtection(rawDamage);
				item4.DamageHP(rawDamage, 0, 100, AttackSource.Shockwave, Act.CC);
			}
		}
	});
}

攻撃対象の半径1マス以内の衝撃波無効エンチャントを持たない敵すべてを攻撃します。

エンチャント強度は衝撃波のダメージ倍率に影響し、倍率は「0.1 + 0.05 × √(衝撃波エンチャント強度)」倍です。

ただし、衝撃波のダメージは貫通率0%かつ無属性固定で、対象の物理防御力で軽減されます。

護符節約

mod_talisman = GetWeaponEnc(609, addSelfEnc: true);
...
if (mod_talisman > 0 && Mathf.Min(10f + Mathf.Sqrt(mod_talisman) * 5f, 90f) > (float)EClass.rnd(100))
{
	flag2 = false;
}
...
if (flag2)
{
	w.c_ammo--;
int weaponEnc = GetWeaponEnc(CC, weapon, 609, addSelfEnc: true);
...
if (conWeapon != null && (weaponEnc <= 0 || !(Mathf.Min(10f + Mathf.Sqrt(weaponEnc) * 5f, 90f) > (float)EClass.rnd(100))))
{
	conWeapon.Mod(-1);
}

近接武器の霊符発動時、霊符の残り回数を確率で消費しなくなります。(霊符は弾丸として装填されるため、弾丸装填数を減らさない処理をします。)

また、唄魔法が有効な攻撃の場合の唄魔法の残り回数を確率で消費しなくなります。

エンチャント強度は発動確率に影響し、どちらの効果の確率も「10 + 5 × √(エンチャント強度)」%で、最大「90」%です。

ノックバック

num3 += weapon.Evalue(603, ignoreGlobalElement: true);
...
if (TC.isChara && !TC.HasCondition<ConGravity>() && num3 > 0 && num3 * 2 + 15 > EClass.rnd(100) && !TC.isRestrained && TC.Chara.TryMoveFrom(CC.pos) == Card.MoveResult.Success)
{
	TC.pos.PlayEffect("vanish");
	TC.PlaySound("push", 1.5f);
}

攻撃対象が吊られた状態や重力状態でない場合、攻撃命中時に攻撃者と攻撃対象を結ぶ直線上にあるマスへ攻撃対象を1マス移動させます。

エンチャント強度は発動率に影響し、発動率は「15 + エンチャント強度 × 2」%で、最大「100」%です。

海嘯のノックバック
if (Act.TC.isChara && !Act.TC.HasCondition<ConGravity>() && Act.TC.ExistsOnMap && knockback > 0 && knockback * 2 + 15 > EClass.rnd(100) && !Act.TC.isRestrained)
{
	Card.MoveResult num9 = Act.TC.Chara.TryMoveFrom(Act.CC.pos);
	bool flag3 = Act.CC.id == "tsunami";
	if (num9 == Card.MoveResult.Success)
	{
		Act.TC.renderer.SetFirst(first: true);
		Act.TC.PlaySound("wave_hit_small");
		if (flag3)
		{
			Act.TC.Chara.AddCondition<ConParalyze>(20, force: true);
			Act.TC.Chara.AddCondition<ConSuffocation>(100, force: true);
		}
	}
	else if (flag3)
	{
		Act.TC.PlaySound("wave_hit");
		Act.TC.pos.PlayEffect("wave_hit");
		Act.TC.Chara.AddCondition<ConSuffocation>(200, force: true);
		if (!Act.TC.HasElement(430))
		{
			int rawDamage = AttackProcess.Current.GetRawDamage(1f, crit: false, maxRoll: false);
			rawDamage = Act.TC.ApplyProtection(rawDamage);
			Act.TC.DamageHP(rawDamage, 0, 100, AttackSource.Shockwave, Act.CC);
		}
		Act.CC.Die();
	}
}

攻撃者が固有のノックバック強度を持ち[7]、攻撃対象が吊られた状態や重力状態でない場合、近接攻撃時に命中の成否を問わず攻撃者と攻撃対象を結ぶ直線上にあるマスへ攻撃対象を1マス移動させます。

エンチャント強度は発動率に影響し、発動率は「15 + エンチャント強度 × 2」%で、最大「100」%です。

攻撃者が海嘯で、これによって攻撃対象が移動した場合、攻撃対象に1ターンの麻痺と強度100の呼吸困難を耐性や無効化エンチャントを無視して強制的に付与します。


攻撃者が海嘯で、これによって攻撃対象が移動しなかった場合、攻撃対象に強度200の呼吸困難を耐性や無効化エンチャントを無視して強制的に付与します。

さらに攻撃対象が衝撃波無効エンチャントを持っていない場合、攻撃力と等倍の衝撃波のダメージを与えます。

ただし、衝撃波のダメージは貫通率0%かつ無属性固定で、対象の物理防御力で軽減されます。

その後、攻撃者は死亡します。

慈悲の重み

else if (Chara.host != null || (weapon != null && weapon.HasElement(485)))
{
	EvadeDeath();
	flag = true;
}

エンチャントが付与された武器での攻撃によって攻撃対象が死亡する時、死を回避して強度200の気絶を付与します。(寄生状態のキャラが死亡する処理と同じです。)

効果は常に発動し、エンチャント強度による発動率や気絶強度への影響はありません。

事故防止

bool safety = Act.CC.HasElement(486) && Act.CC.IsPCFactionOrMinion;
...
if (w != null)
{
	if (safety)
	{
		if (!w.HasElement(486))
		{
			return;
		}
...
if (w != null && w.c_ammo > 0 && !Act.CC.HasCondition<ConReload>() && !safety)
{
	bool flag2 = true;
	TraitAmmo traitAmmo = ((w.ammoData == null) ? null : (w.ammoData.trait as TraitAmmo));
	if (traitAmmo != null && traitAmmo is TraitAmmoTalisman traitAmmoTalisman)
	{
bool flag2 = CC.HasElement(486) && CC.IsPCFactionOrMinion;
...
if (list2.Count > 0 && !flag2)
{
	...
		if (item.IsActive(weapon) && item.source.categorySub == "eleAttack")
		{
        ...
			if (num10 > EClass.rnd(100))
			{
				TC.DamageHP(dmg, item.id, isThrow ? (100 + item.Value * 5) : (30 + item.Value), AttackSource.WeaponEnchant, CC);
			}
		}
	}
	Proc(list2);
}
...
if (!IsRanged && !flag2 && attackStyle == AttackStyle.Shield)
{
if ((weapon == null || !weapon.HasElement(486)) && origin.Evalue(428) > 0 && !IsPCFactionOrMinion && EClass.rnd(dmg) >= EClass.rnd(MaxHP / 10) + MaxHP / 100 + 1)
{
	origin.Chara.TryNeckHunt(Chara, origin.Evalue(428) * 20, harvest: true);
}
...
void ProcAbsorb()
{
	if (origin != null && origin.isChara && isChara && (weapon == null || !weapon.HasElement(486)))
	{
		int valueOrDefault = (origin.Evalue(662) + weapon?.Evalue(662, ignoreGlobalElement: true)).GetValueOrDefault();
		int valueOrDefault2 = (origin.Evalue(661) + weapon?.Evalue(661, ignoreGlobalElement: true)).GetValueOrDefault();

事故防止エンチャントが付与された武器を1つ以上装備している場合、事故防止エンチャントの付与されていない武器での攻撃ができなくなります。(事故防止エンチャントの付与された武器を複数もつ場合、その分だけ攻撃します。)

事故防止エンチャントが付与された武器の霊符が発動しなくなります。

武器攻撃命中時の属性追加ダメージエンチャントと発動エンチャントは発動しなくなります。(回避時の発動エンチャントは発動します。)

シールドバッシュができなくなります。

(信仰中の神による効果の)首狩り、マナ吸収、スタミナ吸収ができなくなります。

効果は常に発動し、エンチャント強度による発動率などへの影響はありません。

盾エンチャント

カウンター

if (orgTC.isChara && orgTC.ExistsOnMap && orgTC != cC && !orgTC.IsRestrainedResident && ACT.Melee.CanPerform(orgTC.Chara, cC))
{
...
	else if (AllowCounter && hasMissed && !cC.HasElement(439) && orgTC.HasElement(380))
	{
		orgTC.Say((orgTC.isChara && orgTC.Chara.IsHostile()) ? "counter_enemy" : "counter");
		new ActMeleeCounter().Perform(orgTC.Chara, cC);
	}
}

影抜きエンチャントを持たない攻撃者の攻撃を攻撃対象が1度でも回避に成功した場合、攻撃者による攻撃が全て終了した後で攻撃対象は近接物理攻撃行動を行います。[8]ただし、攻撃者が攻撃対象の攻撃可能範囲内に居る必要があります。

(攻撃者が追尾・逆襲エンチャントを持っていた場合、全ての追尾・逆襲の効果を回避する必要があります。)

これによる近接物理攻撃でカウンター・パリィは発生しません。

盾の暴君

シールドバッシュの攻撃力・貫通率、盾の発動エンチャントの発動率が増加します。

詳細は「シールドバッシュ」の節「盾の発動エンチャント」の節を参照してください。

突撃者

float num2 = 1f + 0.1f * (float)num;
num2 = num2 * (float)(100 + EClass.curve(Act.CC.Evalue(382), 50, 25, 65)) / 100f;
Attack(num2);
if (Act.TC.isChara && Act.TC.ExistsOnMap && Act.CC.HasElement(382))
{
	if (!Act.TC.IsPowerful || EClass.rnd(4) == 0)
	{
		Act.TC.Chara.AddCondition<ConParalyze>(2, force: true);
	}
	if (!Act.TC.IsPowerful || EClass.rnd(3) == 0)
	{
		Act.TC.Chara.AddCondition<ConDim>(5, force: true);
	}
	if (!Act.TC.IsPowerful || EClass.rnd(2) == 0)
	{
		Act.TC.Chara.AddCondition<ConConfuse>(8, force: true);
	}
}

突進による物理攻撃力をエンチャント強度に応じて増加させます。

倍率は「1 + CURVE(突撃者エンチャント強度, 50, 25, 65) × 0.01」倍です。

また、突進後に、

1ターンの麻痺を攻撃対象に耐性や無効化エンチャントを無視して強制的に付与します。攻撃対象が『』や《》つきの場合、これは「25」%の確率で発生します。

強度5の朦朧を攻撃対象に耐性や無効化エンチャントを無視して強制的に付与します。攻撃対象が『』や《》つきの場合、これは「33」%の確率で発生します。

強度8の混乱を攻撃対象に耐性や無効化エンチャントを無視して強制的に付与します。攻撃対象が『』や《》つきの場合、これは「50」%の確率で発生します。

パリィ

影抜きエンチャントを持たない攻撃者からのパリィ判定に成功した場合、攻撃を無効化して反撃します。

詳細は「パリィ」の節を参照してください。

エネルギー反射

if (weapon.trait is TraitToolRangeGunEnergy && Act.TC != null && Act.TC.isChara && Act.TC.HasElement(383))
{
	if (weapon.id == "gun_laser")
	{
		num5 = 50;
	}
	num5 += Mathf.Max(25 * Act.TC.PER / Mathf.Max(1, Act.CC.PER), 50);
	if (Act.CC.IsPowerful)
	{
		num5 /= 2;
	}
}
if (num5 > EClass.rnd(100))
{
	Card tC = Act.TC;
	Chara cC = Act.CC;
	Point point = Act.TP.Copy();
	List<Chara> list = Act.TC.pos.ListCharasInRadius(Act.TC.Chara, Act.TC.GetSightRadius(), (Chara c) => c.IsHostile(Act.TC.Chara));
	Chara chara = ((list.Count > 0) ? list.RandomItem() : Act.CC?.Chara);
	Act.TC.Say((Act.TC.isChara && Act.TC.Chara.IsHostile()) ? "attack_reflect_enemy" : "attack_reflect");
	Act.TC.PlaySound("attack_gun_laser_parry");
	AttackProcess.Current.PlayRangedAnime(numFire, 0.1f);
	AttackProcess.Current.CC = Act.TC?.Chara;
	AttackProcess.Current.TC = chara;
	AttackProcess.Current.TP.Set(chara.pos);
	AttackProcess.Current.posRangedAnime = chara.pos;
	AttackProcess.Current.Perform(j, hasHit, chara.IsPCFactionOrMinion ? 0.5f : 2.5f);
	Act.TC = tC;
	Act.CC = cC;
	Act.TP.Set(point);
}

攻撃対象がエネルギー反射エンチャントを持ち、エネルギー銃の遠隔武器[9]による攻撃の場合、

確率で攻撃対象の視界内に存在する攻撃対象にとっての敵を一時的に攻撃対象として移し替えます。

また、PC勢力に反射される場合は攻撃力を「0.5」倍に、それ以外に反射される場合は攻撃力を「2.5」倍にします。

反射確率は以下の式で算出されます。

エネルギー反射確率(%) = MAX(25 × (攻撃対象の感覚 / MAX(攻撃者の感覚, 1)), 50) + (0、レーザーガンによる攻撃の場合50) 

攻撃対象の感覚が攻撃者の感覚の2倍以上の時、反射確率は最大の「50」%となります。

レーザーガンによる攻撃であれば、反射確率にさらに50%が加算されるため、「100」%になります。

攻撃者が『』や《》付きのキャラクターの場合、反射確率は半分になります。


レーザー反射による攻撃は非常に特殊な処理が行われる事に注意してください。

攻撃者の攻撃能力・攻撃者の装備している武器・命中力・回避力を流用した上で攻撃者と攻撃対象を変更する」処理のため、

・反射するキャラクターの回避力が低い程反射した攻撃が当たりやすい
・反射するキャラクターが海嘯なら反射が必中
・反射するキャラクターの唄魔法が有効なら唄魔法を適用し、残り回数も消費する
・発動エンチャント・属性追加ダメージは反射元の武器を参照するが、反射するキャラクターのファクションエンチャントに属性追加ダメージがある場合はそれを反射に追加する

などの現象が発生します。詳細は文章での解説が非常に困難なため割愛します。

パリィ

if (AllowParry && !Act.TC.IsDisabled && !Act.TC.IsRestrainedResident)
{
	int num5 = Act.TC.Evalue(437);
	if (num5 > 0 && !Act.CC.HasElement(439))
	{
		int num6 = EClass.curve(5 + num5 / 3, 10, 3, 70);
		int num7 = Act.TC.Evalue(123);
		if (Act.TC.isChara)
		{
			foreach (BodySlot slot2 in Act.TC.Chara.body.slots)
			{
				if (slot2.thing != null && slot2.thing.HasElement(437) && Act.TC.Evalue(slot2.thing.category.skill) > num7)
				{
					num7 = Act.TC.Evalue(slot2.thing.category.skill);
				}
			}
		}
		num6 = num6 * 100 / (int)Mathf.Clamp((float)AttackProcess.Current.weaponSkill.Value / (float)num7 * 100f, 50f, 150f);
		if (EClass.rnd(100) < num6)
		{
			Act.TC.Say((Act.TC.isChara && Act.TC.Chara.IsHostile()) ? "parry_enemy" : "parry");
			Act.TC.PlaySound("parry");
			parried = true;
			return;
		}
	}
}

攻撃者が影抜きエンチャントを持たない場合、攻撃1回ごとに命中判定に入る前にパリィ判定を行います。

パリィ判定

パリィ判定は以下のように行われます。

1.パリィエンチャント強度から「パリィ基礎成功率」を求める。
パリィ基礎成功率(%) = CURVE(5 + 攻撃対象のパリィエンチャント強度合計 / 3, 10, 3, 70)
2.攻撃対象の盾スキルとパリィエンチャントが付与されている全ての装備の関連スキルをそれぞれ比較し、最も高い値を攻撃対象の「パリィスキル」とする。
3.攻撃者の武器スキルとパリィスキルから、「パリィ成功率補正」を求める。
パリィ成功率補正 = CLAMP[10](攻撃者の武器スキル / パリィスキル, 0.5, 1.5)
4.パリィ基礎成功率とパリィ成功率補正から「パリィ成功率」を求める。
パリィ成功率(%) = パリィ基礎成功率 / パリィ成功率補正
5.パリィ成功率ぶんの確率でパリィ判定は成功する。

パリィ判定に成功した場合、それ以降に発生するあらゆる攻撃者からの攻撃や処理を全て中断します。 その後、攻撃対象は近接物理攻撃行動を行います。[8]

これによる近接物理攻撃でカウンター・パリィは発生しません。

命中判定

命中力の算出

基礎の命中力は以下の表の式で算出されます。

武器の種類 計算式
投擲 CURVE([攻撃者の器用] / 4 + [攻撃者の筋力] / 2 + [攻撃者の武器スキル], 50, 25, 75) + 75(PCのファクション以外の場合250)
格闘 (盾なし) CURVE([攻撃者の器用] / 3 + [攻撃者の武器の主能力] / 3 + [攻撃者の武器スキル], 50, 25, 75) + 50
格闘 (盾あり) CURVE([攻撃者の器用] / 3 + [攻撃者の武器の主能力] / 3 + [攻撃者の武器スキル], 50, 25, 75) + 50 の結果に0.75をかけたもの
ワンド CURVE([攻撃者の意志] / 4 + [攻撃者の武器の主能力] / 3 + [攻撃者の武器スキル], 50, 25, 75) + 100
その他すべての武器 CURVE([攻撃者の器用or意志] / 4 + [攻撃者の武器の主能力] / 3 + [攻撃者の武器スキル], 50, 25, 75) + 50

上記の式で算出した値に装備と武器による命中修正が足し算され、その後遠距離武器には距離による修正が適用されたものが「命中力」となります。

回避力の算出

「回避力」は以下の式で算出されます。

回避力 = CURVE ([攻撃対象の感覚] / 3 + [攻撃対象の回避スキル], 50, 10, 75) + [攻撃対象のDV] + 25

命中力・回避力への補正

命中力・回避力に影響を与える以下の要素は、複合して作用しながら次の表の上から順で適用されます。[11]

命中修正
条件 効果
攻撃者の慧眼のエンチャント 命中力 = 命中力 * (1 + 慧眼エンチャント強度 * 0.01)
攻撃者が災い状態 命中力 = 命中力 * 0.75
攻撃者が高所にいる 命中力 = 命中力 * 1.2
攻撃者が乗馬している 命中力 = 命中力 * 100 / (100 + 500 / (5 or 10 + [攻撃者の乗馬スキル] の高い方))
攻撃者がペットを寄生させている 命中力 = 命中力 * 100 / (100 + 1000 / (5 or 10 + [攻撃者の共存スキル] の高い方))
騎乗されているペットによる攻撃 命中力 = 命中力 * 100 / (100 + 1000 / (5 or 10 + [攻撃者の筋力] の高い方))
寄生しているペットによる攻撃 命中力 = 命中力 * 100 / (100 + 1000 / (5 または 10 + [攻撃者の器用] の高い方))
攻撃者が両手持ち 命中力 = 命中力 + 25 + sqrt([攻撃者の両手持ちスキル] * 2) 
攻撃者が二刀流 命中力 = 命中力 * 100 / ((115 + 手の番号 * (15、攻撃者の二刀流スキルが25以上の場合12、攻撃者の二刀流スキルが25以上の場合10)) + (手の番号 * (2000 / (20 + [攻撃者の二刀流スキル])[0-100でクランプ[12]]))
攻撃者が盲目 命中力 = 命中力 * (0.333、遠距離/投擲の場合は0.1)
対象が盲目 回避力 = 回避力 * 0.5
対象が混乱もしくは朦朧 回避力 = 回避力 * 0.5
対象が高所にいる 回避力 = 回避力 * 1.2

二刀流の補足説明:

ここでいう、「手の番号」は利き手・もう片方の手と、カオスシェイプなどが持つ2本目以降の手を表します。

1-100の間でクランプされるのは(2000 / (20 + [攻撃者の二刀流スキル])だけです。つまり、二刀流のペナルティを無効化するには、二刀流スキルが1980必要です。

命中成否判定

命中成否判定では攻撃が命中するか、外れるか、クリティカルになるかするまで、上から順に判定します。

ただし、攻撃者が海嘯だった場合、外れた場合も命中として扱います。[13]

逆襲エンチャントの効果による攻撃の場合、確定クリティカル。
射手座・ペガサス座・天秤座のいずれかのフィートを持つ攻撃者がセブンセンシズ状態のとき、攻撃は命中[14]
対象が朦朧状態の場合、25%の確率でクリティカル
対象が死亡・仮死・睡眠いずれかの状態の場合、確定でクリティカル
[対象の見切りスキル] * 10 > 命中力の場合、見切り成否判定を行う。

見切り力 = 回避力 * 100 / 命中力 とし、以下3つの式を上から順に処理する。[15]
見切り力 > 300 かつ、 random 0 - ([対象の見切りスキル] + 250) > 100 のとき、攻撃は外れる
見切り力 > 200 かつ、 random 0 - ([対象の見切りスキル] + 250) > 150 のとき、攻撃は外れる
見切り力 > 150 かつ、 random 0 - ([対象の見切りスキル] + 250) > 200 のとき、攻撃は外れる
[対象の完全回避] > random 0 - 99 のとき、攻撃は外れる (random X-Yは等確率でXからYまでの乱数を生成する関数。0から99までの値が等確率で選ばれる。完全回避分の確率で回避する。)
random 0 - 19 が 0 のとき、攻撃は命中 (5%で対象の回避を無視して命中する)[14]
random 0 - 19 が 0 のとき、攻撃は外れる (5%で攻撃者の命中を無視して外れる)
命中力 < 1 のとき、攻撃は外れる
回避力 < 1 のとき、攻撃は命中[14]
random 0 - 命中力 < random 0 - (回避力 * 125 (遠距離攻撃なら150) / 100) のとき、攻撃は外れる
random 0 - 5000 < [攻撃者の感覚] + 50 のとき、攻撃はクリティカル
[攻撃者のクリティカルエンチャント合計] + sqrt([攻撃者の心眼スキル]) > random 0 - 200のとき、攻撃はクリティカル
攻撃者が[死の真髄]フィートを所持している場合、以下の判定を行う
   HP減少率 = 100 - [攻撃者の現在HP] * 100 / [攻撃者の最大HP]
   HP減少率 >= 50 かつ、 (HP減少率 ^ 4 / 3) > random 0 - 100000000 のとき、攻撃はクリティカル (HPが5割以上減っている状態で、減少率に応じて最小2%~最大33%の確率でクリティカル)
攻撃は命中

補正前ダメージ算出

物理攻撃力

攻撃者の物理攻撃力は攻撃のダイス数・ダイス面数・ダメージ修正を使ってダイスロールをした後、戦禍の炎状態によるダメージ修正を追加し、

その後攻撃倍率と距離修正をかけたものです。

(「攻撃能力の算出」の節を参照してください。)

クリティカルだった場合、ダイスロールの結果は最大値になり、格闘攻撃のみ攻撃力が1.25倍になります。

※Elonaと違い、武器の重量によるダメージ倍率は存在しません。

最大ロール化

public class ActRush : ActMelee
{
...
	public override bool ShouldRollMax => true;
...
}
...
public class ActMeleeCounter : ActMelee
{
...
	public override bool ShouldRollMax => true;
...
}
public class ActMeleeParry : ActMelee
{
...
	public override bool ShouldRollMax => true;
...
}
if (crit || maxRoll)
{
	num = Dice.RollMax(dNum, dDim, dBonus);
	if (ammo != null && !flag)
	{
		num += Dice.RollMax(dNumAmmo, dDimAmmo, dBonusAmmo);
	}
	if (crit && (IsMartial || IsMartialWeapon))
	{
		dMulti *= 1.25f;
	}
}

突進・カウンター・パリィから発生した近接攻撃は常にダイスロールの結果を最大にし、格闘攻撃の攻撃力を1.25倍にします。事実上の確定クリティカルとなります。

クリティカルとの違いは「クリティカルの演出がない」、「心眼に経験値が入らない」ことのみです。

行動による攻撃倍率

public class ActRush : ActMelee
{
...
    int num = Act.CC.Dist(Act.TP);
...
	float num2 = 1f + 0.1f * (float)num;
	num2 = num2 * (float)(100 + EClass.curve(Act.CC.Evalue(382), 50, 25, 65)) / 100f;
	Attack(num2);
...
}
public class ActMeleeBladeStorm : ActMelee
{
	public override float BaseDmgMTP => 0.2f;
}
...
public class ActMeleeCounter : ActMelee
{
...
	public float bonus;
	public override float BaseDmgMTP => 1f + bonus;
}
...
public class ActMeleeParry : ActMelee
{
	public override float BaseDmgMTP => 1.5f;
}
...
if (weapon.trait is TraitToolRangeGunEnergy && Act.TC != null && Act.TC.isChara && Act.TC.HasElement(383))
{
    AttackProcess.Current.Perform(j, hasHit, chara.IsPCFactionOrMinion ? 0.5f : 2.5f);

突進・斬撃無双・大回転・カウンター・パリィ・レーザー反射から発生した攻撃はそれぞれ追加の攻撃倍率を持ち、それを攻撃力に乗算します。

攻撃力は以下のようになります。

物理攻撃力 = 物理攻撃力 × 追加の攻撃倍率

斬撃無双の攻撃倍率は「0.2」倍、大回転の攻撃倍率は「1.2」倍、カウンターの攻撃倍率は「1」[16]倍、パリィの攻撃倍率は「1.5」倍、PC勢力へのレーザー反射は「0.5」倍、PC勢力以外へのレーザー反射は「2.5」倍です。

突進の攻撃倍率は以下の式で算出されます。

突進攻撃倍率 = (1 + 攻撃対象との距離 × 0.1) × (1 + CURVE(突撃者エンチャント強度, 50, 25, 65) × 0.01)

物理攻撃力の上限

long num = Dice.Roll(dNum, dDim, dBonus, CC);
...
num = (long)(dMulti * (float)num * dmgMulti);
return (long)Mathf.Clamp(num, 0f, 100000000f);

上記までの物理攻撃力の算出の際、「100000000」を超えた場合は「100000000」に補正されます。

後述する連射数修正と種族特攻エンチャントは、この上限の適用後に計算されます。

連射数修正

遠隔武器の連射数によるダメージ減衰は、物理攻撃力の上限の補正後に計算されます。

(倍率は「遠隔武器の連射数修正」の節を参照してください。)

種族特攻エンチャント

void AddBane(bool valid, int idEle, int mod)
{
	if (valid)
	{
		bane += (CC.Evalue(idEle) + ((weapon != null) ? weapon.Evalue(idEle, ignoreGlobalElement: true) : 0)) * mod / 100;
	}
}

特攻のエンチャントがついた武器で特攻が有効な種族を攻撃した場合、以下の式の通り物理攻撃力にボーナスを得ます。

物理攻撃力 = 物理攻撃力 × (1 + 0.03 × (有効な種族特攻エンチャント強度の合計) + 0.015 × (全特攻エンチャント強度))

防御力

public virtual long ApplyProtection(long 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 = 0L;
	}
	return dmg;
}

攻撃対象の防御力は「防御固定値」と「防御割合」の2つに分かれています。

防御固定値は、ダイス数が「(PV + 軽装or重装スキル + 器用 / 10) / 40 + 1」、ダイス面が「(PV + 軽装or重装スキル + 器用 / 10) / (ダイス数 × 4) + 1」でダイスロールをしたものです。

防御割合は以下の式で算出されます。

防御割合 = 1 / (1 + 0.01 × (PV + 軽装or重装スキル + 器用 / 10))

属性強度・属性変換率

if (weapon != null)
{
	foreach (Element value2 in weapon.elements.dict.Values)
	{
		if (value2.source.categorySub == "eleConvert")
		{
			num4 = EClass.sources.elements.alias[value2.source.aliasRef].id;
			num5 = 50 + value2.Value * 2;
			num6 = Mathf.Min(value2.Value, 100);
			break;
		}
	}
}
if (num4 == 0)
{
	if (CC.HasCondition<ConWeapon>())
	{
		conWeapon = CC.GetCondition<ConWeapon>();
		num4 = conWeapon.sourceElement.id;
		num5 = conWeapon.power / 2;
		num6 = (int)Mathf.Min(40f + MathF.Sqrt(conWeapon.power), 80f);
	}
	if (conWeapon == null && weapon == null && (CC.MainElement != Element.Void || CC.HasElement(1565)))
	{
		num4 = (CC.HasElement(1565) ? 915 : CC.MainElement.id);
		num5 = CC.Power / 3 + EClass.rnd(CC.Power / 2);
		if (CC.MainElement != Element.Void)
		{
			num5 += CC.MainElement.Value;
		}
		showEffect = false;
		num6 = 50;
	}
	if (conWeapon == null && weapon != null && weapon.trait is TraitToolRangeCane)
	{
		IEnumerable<Element> enumerable = weapon.elements.dict.Values.Where((Element e) => e.source.categorySub == "eleAttack");
		if (enumerable.Count() > 0)
		{
			num4 = enumerable.RandomItem().id;
			num5 = num4 switch
			{
				920 => 30, 
				914 => 50, 
				918 => 50, 
				_ => 100, 
			};
		}
		num6 = 50;
	}
}

属性変換エンチャントがついた武器か、唄魔法が有効な攻撃か、ワンドでの攻撃か、属性格闘をもつかエーテル病のエーテルの滴る手にかかったキャラクターの素手による攻撃の場合、物理攻撃は「属性強度」と「属性変換率」をもちます。

条件を複数満たす場合、属性変換エンチャント>唄魔法>属性格闘>ワンド の順で優先されます。

属性強度

属性強度とは、状態異常を付与する際に使用される強度です。値が大きい程状態異常にしやすく、状態異常の強度が上がります。

属性変換エンチャントのついた武器の属性強度は「50 + 属性変換エンチャント強度 × 2」です。

唄魔法が有効な攻撃の属性強度は「唄魔法のパワー / 2」です。

属性格闘の属性強度はキャラクターのLvと構成素材に依存(キャラクター毎に素材が異なり複雑過ぎるため計算式は省略)します。

ワンドの属性強度は混沌属性は「30」、幻惑と神経属性は「50」、それ以外は「100」で固定です。

属性変換率

属性変換率とは、攻撃対象の防御力を無視する割合です。

属性変換エンチャントのついた武器の属性変換率は「属性変換エンチャント強度」%で、最大100%です。

唄魔法が有効な攻撃の属性変換率は「40 + √(唄魔法のパワー)」%で、最小40%、最大80%です。

属性格闘の属性変換率は「50」%で固定です。

ワンドの属性変換率は「50」%で固定です。

ダメージ計算

これまで求めてきた攻撃力、貫通率、防御力、属性変換率を使用してダメージ計算を行います。

long num7 = num;
long num8 = num * num6 / 100;
num -= num8;
long num9 = num * penetration / 100;
num -= num9;
num = TC.ApplyProtection(num) + num9 + num8;
TC.DamageHP(num, num4, num5, (!IsRanged && !isThrow) ? AttackSource.Melee : AttackSource.Range, CC, showEffect, weapon);

まず、属性変換によるダメージと貫通によるダメージ、防御力による軽減を計算します。

属性変換ダメージ = 物理攻撃力 × 属性変換率
貫通ダメージ = (物理攻撃力 - 属性変換ダメージ) × 貫通率
非貫通ダメージ = (物理攻撃力 - 属性変換ダメージ - 貫通ダメージ) × 防御割合 - 防御固定値 ※(負の値になった場合0に補正)

以上から、物理攻撃によるダメージは以下の通りです。

軽減後ダメージ = 属性変換ダメージ + 貫通ダメージ + 非貫通ダメージ

この後、DamageHP関数の中で属性耐性などの各種補正によって最終的なダメージは増減します

属性追加ダメージエンチャント

foreach (Element item in list)
{
	if (!TC.IsAliveInCurrentZone)
	{
		break;
	}
	if (item.IsActive(weapon) && item.source.categorySub == "eleAttack")
	{
		int num10 = 25;
		int num11 = EClass.rnd(num * (100 + item.Value * 10) / 500 + 5);
		num11 = num11 * (100 + GetTwoHandEncBonus(CC)) / 100;
		if (conWeapon == null && weapon != null && weapon.trait is TraitToolRangeCane)
		{
			num10 = 0;
		}
		if (num10 > EClass.rnd(100))
		{
			TC.DamageHP(num11, item.id, isThrow ? (100 + item.Value * 5) : (30 + item.Value), AttackSource.WeaponEnchant, CC);
		}
	}
}

事故防止エンチャントが付与されておらず、「属性変換か唄魔法が有効でないワンド以外」[17]の属性追加ダメージエンチャントの付与された武器か弾の攻撃が命中した場合、付与された属性追加ダメージエンチャントそれぞれについて追加の属性攻撃を行います。

それぞれの属性追加ダメージの最大値は以下の式で算出されます。

属性追加最大ダメージ = 5 + 軽減後ダメージ × (0.2 + エンチャント強度 × 0.02)

0~属性追加最大ダメージまでの範囲の内のランダムな値が属性ダメージとなります。


追加の属性攻撃の発動率はそれぞれ「25」%で固定です。

属性攻撃の属性強度は投擲武器のみ「100 + エンチャント強度 × 5」、それ以外は「30 + エンチャント強度」です。

シールドバッシュ

if (!IsRanged && !flag2 && attackStyle == AttackStyle.Shield)
{
	int num12 = CC.Evalue(123);
	int num13 = CC.Evalue(381);
	if (CC.elements.ValueWithoutLink(123) >= 10 && Mathf.Clamp(Mathf.Sqrt(num12) - 2f, 8f, 15f) + Mathf.Min(Mathf.Sqrt(num13), 25f) > (float)EClass.rnd(100))
	{
		num = num7 * (Mathf.Min(50 + num12 + num13, 200) + (int)Mathf.Min(Mathf.Sqrt(num13), 100f)) / 100;
		penetration = (int)Mathf.Sqrt(num13) + ((num13 != 0) ? 20 : 0);
		if (penetration > 100)
		{
			penetration = 100;
		}
		num9 = num * penetration / 100;
		num -= num9;
		num = TC.ApplyProtection(num) + num9;
		Debug.Log("Bash:" + num + "/" + num7);
		CC.PlaySound("shield_bash");
		CC.Say("shield_bash", CC, TC);
		TC.DamageHP(num, AttackSource.None, CC);
		if (TC.IsAliveInCurrentZone && TC.isChara)
		{
			if (EClass.rnd(2) == 0)
			{
				TC.Chara.AddCondition<ConDim>(50 + (int)Mathf.Sqrt(num12) * 10);
			}
			TC.Chara.AddCondition<ConParalyze>(EClass.rnd(2), force: true);
		}
		ProcShieldEncs(CC, TC, 500 + num13);
	}
}

武器に事故防止エンチャントが付与されておらず、盾スキルが10以上の盾を持つキャラクターの近接攻撃が命中した場合、確率でシールドバッシュが行われます。

シールドバッシュの発生確率は以下の式で算出されます。

シールドバッシュ発生率(%) = CLAMP[10](√(攻撃者の盾スキル) - 2, 8, 15) + MIN(√(盾の暴君エンチャント強度), 25)

発動率の最小は「8」%です。

盾スキルが「100」以上になると発動率が上昇しはじめ、最大で「15」%まで効果があります。

盾の暴君エンチャントは発動率に加算され、最大で「+25」%まで効果があります。

シールドバッシュの攻撃力は以下の式で算出されます。

シールドバッシュ攻撃力 = 物理攻撃力 × (MIN((0.5 + 攻撃者の盾スキル × 0.01), 2) + MIN(√(盾の暴君エンチャント強度) × 0.01, 1))

シールドバッシュは貫通率も持ちます。貫通力は以下の式で算出されます。[4]

シールドバッシュ貫通率(%) = √(盾の暴君エンチャント強度) + (0、盾の暴君エンチャントがある場合20)

上で求めたシールドバッシュ攻撃力・貫通力に攻撃対象の物理防御力を適用して、シールドバッシュダメージを計算します。

貫通ダメージ = シールドバッシュ攻撃力 × 貫通率
非貫通ダメージ = (シールドバッシュ攻撃力 - 貫通ダメージ) × 防御割合 - 防御固定値 ※(負の値になった場合0に補正)

シールドバッシュダメージ = 貫通ダメージ + 非貫通ダメージ

シールドバッシュは唄魔法や属性変換エンチャントなどに関わらず無属性ダメージとなります。

50%の確率で、1ターンの麻痺を攻撃対象に耐性や無効化エンチャントを無視して強制的に付与します。

50%の確率で、状態異常強度が「50 + 10 × √(攻撃者の盾スキル)」の朦朧を攻撃対象に付与します。

武器の発動エンチャント

ProcAbility(list, CC, TC, weaponSkill.Value + GetTwoHandEncBonus(CC), subAttack);
...
public static void ProcAbility(Element e, Chara CC, Card TC, int bonus, bool subAttack = false, int mtpChance = 100)
{
	if (!(e is Ability))
	{
		return;
	}
	int num = (10 + e.Value / 5) * mtpChance / 100;
	int power = EClass.curve((100 + e.Value * 10) * (100 + bonus) / 100, 400, 100);
	if (e.id == 6602)
	{
		num = 100;
	}
	if (num <= EClass.rnd(100))
	{
		return;
	}
	...
	if (card.IsAliveInCurrentZone)
	{
		Card tC = Act.TC;
		ActEffect.ProcAt(e.source.proc[0].ToEnum<EffectId>(), power, BlessedState.Normal, CC, card, card.pos, isNeg: false, new ActRef
		{
			n1 = text,
			aliasEle = e.source.aliasRef,
			noFriendlyFire = true
		});
		Act.TC = tC;
	}
}

武器に事故防止エンチャントが付与されておらず、アビリティ発動のエンチャント(「それは○○を発動する」)が付与されている場合、攻撃の命中の成否に関わらずあらゆる物理攻撃において確率でアビリティが発動します。

発動エンチャントの発動確率は以下の式で算出されます。

発動エンチャ発動率(%) = 10 + 武器の元々の発動エンチャント強度 / 5

武器の元々の発動エンチャント強度を参照するため、両手持ちによるエンチャント強度上昇は発動率に影響しません。[18]

また、「牽引」を発動する場合のみ、発動率は「100」%になります。


発動エンチャントで発動するアビリティや魔法のパワーは以下の式で算出されます。[19]

発動したアビリティのパワー = CURVE((100 + 10 × 武器の元々の発動エンチャント強度) × (1 + 0.01 × 対応武器スキル × (1、両手持ちLv15以上の両手持ち時1.25、両手持ちLv15以上の両手持ち時1.5)), 400, 100, 75)

盾の発動エンチャント

if (!IsRanged && !flag2 && attackStyle == AttackStyle.Shield)
{
	int num12 = CC.Evalue(123);
	int num13 = CC.Evalue(381);
...
        ProcShieldEncs(CC, TC, 500 + num13);
...
public static void ProcShieldEncs(Chara CC, Card TC, int mtpChance = 100)
{
	foreach (BodySlot slot in CC.body.slots)
	{
		if (slot.elementId == 35 && slot.thing != null && (slot.thing.category.IsChildOf("shield") || slot.thing.category.IsChildOf("martial")))
		{
			ProcAbility(slot.thing.elements.dict.Values.ToList(), CC, TC, CC.Evalue((slot.thing.category.skill == 0) ? 123 : slot.thing.category.skill), subAttack: false, mtpChance);
		}
	}
}

シールドバッシュが発生し、盾にアビリティ発動のエンチャント(「それは○○を発動する」)が付与されている場合、確率でアビリティが発動します。

発動エンチャントの発動確率は以下の式で算出されます。

発動エンチャ発動率(%) = (10 + 発動エンチャント強度 / 5) × (5 + 盾の暴君エンチャント強度 × 0.01)

「牽引」を発動する場合のみ、発動率は「100」%になります。


発動エンチャントで発動するアビリティや魔法のパワーは以下の式で算出されます。[19]

発動したアビリティのパワー = CURVE((100 + 10 × 発動エンチャント強度) × (1 + 0.01 × 盾スキル), 400, 100, 75)


  1. 1.0 1.1 1.2 1.3 エーテル病の殺戮への飢えが該当する。
  2. 2.0 2.1 2.2 固有の貫通率を持っているキャラクターであればその値も加算される。
  3. 投擲武器でないときは0
  4. 4.0 4.1 これにより貫通率が100%を超える場合、貫通率は100%に補正される。
  5. 闇子・闇の老師の特別仕様。タグやフィートによる判別ではなく、idによる判別。
  6. 武器に付与されているヴォーパルは0にならない。
  7. 該当する海嘯以外でもコンソールでノックバックエンチャを付与すると再現可能。ただし、現状は海嘯にしかなく、海嘯専用の仕様が多いためこのページでは「海嘯のノックバック」と呼びます。
  8. 8.0 8.1 行動そのものを行うため、複数の武器を装備している場合はその分攻撃し、連撃や旋風などあらゆる(カウンター・パリィ以外の)エンチャントが適用されます。
  9. レーザーガン、レールガンが該当。
  10. 10.0 10.1 値を一定範囲内に制限する関数です。 関数内の1つめの引数の値は、「2つめの引数の値」~「3つめの引数の値」の範囲内になるよう補正されます。
  11. プログラムでは、X=X+1のように、同じ文字が一つの式に複数回登場して右辺にあるものが調整前の数字、左辺にあるものが調整後の数字になる記法があります。
  12. クランプとは値に上限と下限を適用するという意味です。この場合、確率なので0から100%に設定されています
  13. 海嘯のみの特別仕様。タグやフィートではなく、海嘯のidで判定される。クリティカルだった場合はクリティカル扱いになる。
  14. 14.0 14.1 14.2 この場合、クリティカルにはならない。
  15. 見切り力が301以上であれば、見切りによる回避判定は3回行われる
  16. 変動するような仕組みは用意されているものの、bonusが初期値以外の値を取らないため現状は1倍で固定。
  17. 属性変換や唄魔法が有効なワンドは追加ダメージが発生する
  18. 編者註: EA23.200時点でバグとして報告済みですが、発動エンチャに関わるバグが修正されたPatch1でも修正されていません。 おそらく、大地の槌などが強くなりすぎないようにという意図の下このような処理になっていると思われます。
  19. 19.0 19.1 アビリティのパワーは変動しますが、アビリティのダメージ算出の際に使用される関連能力は発動者の能力を参照せず、「パワー / 10」として計算されます。