Elin:解析/物理戦闘: Difference between revisions
(盾の発動エンチャについて記載。) |
(ノックバックを追加。衝撃波無効を追加。) |
||
| Line 531: | Line 531: | ||
ただし、'''闇子・闇の老師が元々持つヴォーパル'''は、攻撃対象が闇子・闇の老師の透明化を見破っている場合0になります。<ref>闇子・闇の老師の特別仕様。タグやフィートによる判別ではなく、idによる判別。</ref><ref>武器に付与されているヴォーパルは0にならない。</ref> | ただし、'''闇子・闇の老師が元々持つヴォーパル'''は、攻撃対象が闇子・闇の老師の透明化を見破っている場合0になります。<ref>闇子・闇の老師の特別仕様。タグやフィートによる判別ではなく、idによる判別。</ref><ref>武器に付与されているヴォーパルは0にならない。</ref> | ||
== | ==武器攻撃エンチャント== | ||
{| class="wikitable" | {| class="wikitable" | ||
|+武器専用エンチャントの名前 | |+武器専用エンチャントの名前 | ||
|- | |- | ||
! | !名称 | ||
!近接 | !近接 | ||
!遠隔 | !遠隔 | ||
!投擲!!簡易説明 | !投擲!!簡易説明 | ||
|- | |- | ||
|突貫 | |突貫 | ||
|○ | |○ | ||
| Line 547: | Line 546: | ||
|当たった相手を突き抜けて後方にも当たる。 | |当たった相手を突き抜けて後方にも当たる。 | ||
|- | |- | ||
|拡散 | |拡散 | ||
|○ | |○ | ||
| Line 554: | Line 552: | ||
|減衰のある範囲攻撃 | |減衰のある範囲攻撃 | ||
|- | |- | ||
|旋風 | |旋風 | ||
|○ | |○ | ||
| Line 561: | Line 558: | ||
|攻撃が最初の相手から伝播する | |攻撃が最初の相手から伝播する | ||
|- | |- | ||
|連撃 | |連撃 | ||
|○ | |○ | ||
| Line 568: | Line 564: | ||
|複数回攻撃する | |複数回攻撃する | ||
|- | |- | ||
|追尾 | |追尾 | ||
|○ | |○ | ||
| Line 575: | Line 570: | ||
|回避された際に追撃する | |回避された際に追撃する | ||
|- | |- | ||
|逆襲 | |逆襲 | ||
|○ | |○ | ||
| Line 582: | Line 576: | ||
|回避された際に確率で確定命中クリティカル攻撃をする | |回避された際に確率で確定命中クリティカル攻撃をする | ||
|- | |- | ||
|牽制 | |牽制 | ||
|○ | |○ | ||
| Line 589: | Line 582: | ||
|制圧の状態異常を付与する | |制圧の状態異常を付与する | ||
|- | |- | ||
|衝撃波 | |衝撃波 | ||
|○ | |○ | ||
| Line 596: | Line 588: | ||
|最初の攻撃対象の周りにも当たる衝撃波を発する | |最初の攻撃対象の周りにも当たる衝撃波を発する | ||
|- | |- | ||
| | |ノックバック | ||
|○ | |||
|○ | |||
|○ | |||
|攻撃対象を1マス押しのける | |||
|- | |||
|護符節約 | |護符節約 | ||
|○ | |○ | ||
| Line 603: | Line 600: | ||
|霊符と唄の使用回数を増やす | |霊符と唄の使用回数を増やす | ||
|- | |- | ||
|慈悲の重み | |慈悲の重み | ||
|○ | |○ | ||
| Line 610: | Line 606: | ||
|このエンチャントが付与された武器によって対象が死亡するとき、死を回避 | |このエンチャントが付与された武器によって対象が死亡するとき、死を回避 | ||
|- | |- | ||
|事故防止 | |事故防止 | ||
|○ | |○ | ||
| Line 837: | Line 832: | ||
foreach (Card item4 in p.ListCards()) | foreach (Card item4 in p.ListCards()) | ||
{ | { | ||
if (item4.trait.CanBeAttacked || (item4.isChara && item4.Chara.IsHostile(Act.CC))) | 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); | int rawDamage = AttackProcess.Current.GetRawDamage(0.1f + 0.05f * Mathf.Sqrt(splash), crit: false, maxRoll: false); | ||
| Line 847: | Line 842: | ||
} | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
攻撃対象の半径1マス以内の衝撃波無効エンチャントを持たない敵すべてを攻撃します。 | |||
エンチャント強度は衝撃波のダメージ倍率に影響し、倍率は「0.1 + 0.05 × √(衝撃波エンチャント強度)」倍です。 | エンチャント強度は衝撃波のダメージ倍率に影響し、倍率は「0.1 + 0.05 × √(衝撃波エンチャント強度)」倍です。 | ||
| Line 879: | Line 874: | ||
エンチャント強度は発動確率に影響し、どちらの効果の確率も「10 + 5 × √(エンチャント強度)」%で、最大「'''90'''」%です。 | エンチャント強度は発動確率に影響し、どちらの効果の確率も「10 + 5 × √(エンチャント強度)」%で、最大「'''90'''」%です。 | ||
=== ノックバック === | |||
<syntaxhighlight lang="c#"> | |||
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); | |||
} | |||
</syntaxhighlight>攻撃対象が吊られた状態や重力状態でない場合、攻撃命中時に攻撃者と攻撃対象を結ぶ直線上にあるマスへ攻撃対象を1マス移動させます。 | |||
エンチャント強度は発動率に影響し、発動率は'''「15 + エンチャント強度 × 2」'''%で、最大'''「100」'''%です。 | |||
===== 海嘯のノックバック ===== | |||
<syntaxhighlight> | |||
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(); | |||
} | |||
} | |||
</syntaxhighlight>'''攻撃者が固有のノックバック強度を持ち'''<ref>該当する海嘯以外でもコンソールでノックバックエンチャを付与すると再現可能。ただし、現状は海嘯にしかなく、海嘯専用の仕様が多いため固有このページでは「海嘯のノックバック」と呼びます。</ref>、攻撃対象が吊られた状態や重力状態でない場合、近接攻撃時に命中の成否を問わず攻撃者と攻撃対象を結ぶ直線上にあるマスへ攻撃対象を1マス移動させます。 | |||
エンチャント強度は発動率に影響し、発動率は'''「15 + エンチャント強度 × 2」'''%で、最大'''「100」'''%です。 | |||
攻撃者が海嘯で、これによって攻撃対象が移動した場合、攻撃対象に強度20の麻痺と強度100の呼吸困難を耐性や無効化エンチャントを無視して強制的に付与します。 | |||
攻撃者が海嘯で、これによって攻撃対象が移動しなかった場合、攻撃対象に強度200の呼吸困難を耐性や無効化エンチャントを無視して強制的に付与します。 | |||
さらに攻撃対象が衝撃波無効エンチャントを持っていない場合、攻撃力と等倍の衝撃波のダメージを与えます。 | |||
ただし、衝撃波のダメージは貫通率0%かつ無属性固定で、対象の物理防御力で軽減されます。 | |||
その後、攻撃者は死亡します。 | |||
=== 慈悲の重み === | === 慈悲の重み === | ||
Revision as of 19:46, 17 September 2025
このページには正規のプレイによって得られた情報ではなく、Elinのデータ解析・デバッグモード・内部ファイル閲覧などによって得た情報が掲載されています。 ゲームの重大なネタバレや、プレイの楽しみを損なう情報が含まれている可能性があります。 閲覧は自己責任でお願いするとともに、通常ページに解析ページへのリンクを貼ることはお控えください。 また、このページの情報をWikiの他のページに記載する際は計算コードなどをそのまま掲示するのではなく、コードが読めない人にもわかりやすいように内容を要約して書いていただけると幸いです。 |
近接攻撃処理順
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 連射数
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 + 武器の基礎ダイス数」です。
最終的なダメージ修正は「基礎ダメージ修正 + 武器のダメージ修正」です。
最終的な命中力は「基礎命中力 + 武器の命中修正」です。
最終的な貫通率は「基礎貫通率 + 武器の貫通率」です。
投擲
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;
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;
}
}
if (ammo != null && !(ammo.trait is TraitAmmoTalisman))
{
dNumAmmo = ((ammo.source.offense.Length != 0) ? ammo.source.offense[0] : 0);
dDimAmmo = ammo.c_diceDim;
dBonusAmmo = ammo.DMG + ammo.encLV;
if (dNumAmmo < 1)
{
dNumAmmo = 1;
}
if (dDimAmmo < 1)
{
dDimAmmo = 1;
}
toHitFix += ammo.HIT;
}
else
{
dNumAmmo = 0;
dDimAmmo = 0;
}
if (dNum < 1)
{
dNum = 1;
}
if (dDim < 1)
{
dDim = 1;
}
if (penetration > 100)
{
penetration = 100;
}
プレイヤーは、戦術スキルを使用して近接武器を振るうか、または射撃スキルを使用して遠距離武器を撃ちます。
武器がワンド、または理力武器のエンチャントが付いている場合、戦術スキルまたは射撃スキルの代わりに詠唱スキルを、武器スキル(長剣、短剣、斧など)の代わりに魔道具スキルを使用します。
ダメージのダイス数及びダイス面は武器に表記されているものを使用します。
基礎ダメージ修正は「攻撃中の武器のダメージ修正 + 防具のダメージ修正合計 + キャラ固有のダメージ修正[1]」です。
ダメージ倍率は「0.6 + (武器スキルに対応する主能力 + 武器スキル / 2 + (近接武器は戦術、遠距離武器は射撃、ワンドまたは理力武器の場合魔道具)) / 50.0)」です。
プレイヤーが武器の知識フィートを持っている場合、ダメージ倍率に『0.05 * (武器の知識フィートのランク)』だけ加算されます。(事実上、+0.05または+0.10)
貫通率は武器に表記されているものを使用します。[2]
使用する武器が遠隔武器で、射手座のフィートを持つ場合、貫通率に25%を加算します。
使用する武器が近接武器で、天秤座のフィートを持つ場合、貫通率に25%を加算します。[4]
基礎命中力は「(器用、ワンドなら意志) / 4 + 武器スキルに対応する主能力 / 3 + 武器スキル 」を、スタート50、ステップ25、レート75%のCURVE関数で計算した後、50を足したものです。
命中力は「基礎命中力 + 攻撃中の武器の命中修正 + 防具の命中修正合計 + (ワンドのみ:50、それ以外は0)」です。
さらに、弾薬を消費して攻撃した場合:
ダメージ修正に「弾薬のダメージダイスを振った結果 + 弾薬のダメージ修正」を加算します。
命中力に「弾薬の命中修正」を加算します。
遠隔武器の距離修正
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)))
{
num5++;
}
}
}
bool flag = false;
for (int k = 0; k < num5; k++)
{
if (k > 0)
{
Act.CC.Say("attack_chaser");
}
flag = AttackProcess.Current.Perform(count, hasHit, dmgMulti * mtp, maxRoll, subAttack);
if (!flag && frustration > 0 && 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」%です。
攻撃者が海嘯で、これによって攻撃対象が移動した場合、攻撃対象に強度20の麻痺と強度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つ以上装備している場合、事故防止エンチャントの付与されていない武器での攻撃ができなくなります。(事故防止エンチャントの付与された武器を複数もつ場合、その分だけ攻撃します。)
事故防止エンチャントが付与された武器の霊符が発動しなくなります。
武器攻撃命中時の属性追加ダメージエンチャントと発動エンチャントは発動しなくなります。(回避時の発動エンチャントは発動します。)
シールドバッシュができなくなります。
(信仰中の神による効果の)首狩り、マナ吸収、スタミナ吸収ができなくなります。
効果は常に発動し、エンチャント強度による発動率などへの影響はありません。
命中判定
命中力の算出
基礎の命中力は以下の表の式で算出されます。
| 武器の種類 | 計算式 |
|---|---|
| 投擲 | 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
命中力・回避力への補正
命中力・回避力に影響を与える以下の要素は、複合して作用しながら次の表の上から順で適用されます。[8]
| 条件 | 効果 |
|---|---|
| 攻撃者の慧眼のエンチャント | 命中力 = 命中力 * (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でクランプ[9]])) |
| 攻撃者が盲目 | 命中力 = 命中力 * (0.333、遠距離/投擲の場合は0.1) |
| 対象が盲目 | 回避力 = 回避力 * 0.5 |
| 対象が混乱もしくは朦朧 | 回避力 = 回避力 * 0.5 |
| 対象が高所にいる | 回避力 = 回避力 * 1.2 |
二刀流の補足説明:
ここでいう、「手の番号」は利き手・もう片方の手と、カオスシェイプなどが持つ2本目以降の手を表します。
1-100の間でクランプされるのは(2000 / (20 + [攻撃者の二刀流スキル])だけです。つまり、二刀流のペナルティを無効化するには、二刀流スキルが1980必要です。
命中成否判定
命中成否判定では攻撃が命中するか、外れるか、クリティカルになるかするまで、上から順に判定します。
ただし、攻撃者が海嘯だった場合、外れた場合も命中として扱います。[10]
逆襲エンチャントの効果による攻撃の場合、確定クリティカル。
射手座・ペガサス座・天秤座のいずれかのフィートを持つ攻撃者がセブンセンシズ状態のとき、攻撃は命中[11]
対象が朦朧状態の場合、25%の確率でクリティカル
対象が死亡・仮死・睡眠いずれかの状態の場合、確定でクリティカル
[対象の見切りスキル] * 10 > 命中力の場合、見切り成否判定を行う。 見切り力 = 回避力 * 100 / 命中力 とし、以下3つの式を上から順に処理する。[12] 見切り力 > 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%で対象の回避を無視して命中する)[11]
random 0 - 19 が 0 のとき、攻撃は外れる (5%で攻撃者の命中を無視して外れる)
命中力 < 1 のとき、攻撃は外れる
回避力 < 1 のとき、攻撃は命中[11]
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 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;
}
斬撃無双・カウンター・パリィから発生した近接攻撃はそれぞれ追加の攻撃倍率を持ち、それを攻撃力に乗算します。
攻撃力は以下のようになります。
物理攻撃力 = 物理攻撃力 × 追加の攻撃倍率
斬撃無双の攻撃倍率は「0.2」倍、カウンターの攻撃倍率は「1」[13]倍、パリィの攻撃倍率は「1.5」倍です。
物理攻撃力の上限
int num = Dice.Roll(dNum, dDim, dBonus, CC);
...
num = Mathf.Clamp(num, 0, 9999999);
num = (int)(dMulti * (float)num * dmgMulti);
return Mathf.Clamp(num, 0, 9999999);
上記までの物理攻撃力の算出の際、「9999999」を超えた場合は「9999999」に補正されます。
後述する連射数修正と種族特攻エンチャントは、この上限の適用後に計算されます。
連射数修正
遠隔武器の連射数によるダメージ減衰は、物理攻撃力の上限の補正後に計算されます。
(倍率は「遠隔武器の連射数修正」の節を参照してください。)
種族特攻エンチャント
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 int 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;
}
攻撃対象の防御力は「防御固定値」と「防御割合」の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」%で固定です。
ダメージ計算
これまで求めてきた攻撃力、貫通率、防御力、属性変換率を使用してダメージ計算を行います。
int num7 = num;
int num8 = num * num6 / 100;
num -= num8;
int 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);
}
}
}
事故防止エンチャントが付与されておらず、「属性変換か唄魔法が有効でないワンド以外」[14]の属性追加ダメージエンチャントの付与された武器か弾の攻撃が命中した場合、付与された属性追加ダメージエンチャントそれぞれについて追加の属性攻撃を行います。
それぞれの属性追加ダメージの最大値は以下の式で算出されます。
属性追加最大ダメージ = 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[15](√(攻撃者の盾スキル) - 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
武器の元々の発動エンチャント強度を参照するため、両手持ちによるエンチャント強度上昇は発動率に影響しません。[16]
また、「牽引」を発動する場合のみ、発動率は「100」%になります。
発動エンチャントで発動するアビリティや魔法のパワーは以下の式で算出されます。[17]
発動したアビリティのパワー = CURVE((100 + 10 × 発動エンチャント強度) × (1 + 0.01 × 対応武器スキル), 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」%になります。
発動エンチャントで発動するアビリティや魔法のパワーは以下の式で算出されます。[17]
発動したアビリティのパワー = CURVE((100 + 10 × 発動エンチャント強度) × (1 + 0.01 × 盾スキル), 400, 100, 75)
- ↑ 1.0 1.1 1.2 1.3 エーテル病の殺戮への飢えが該当する。
- ↑ 2.0 2.1 2.2 固有の貫通率を持っているキャラクターであればその値も加算される。
- ↑ 投擲武器でないときは0
- ↑ 4.0 4.1 これにより貫通率が100%を超える場合、貫通率は100%に補正される。
- ↑ 闇子・闇の老師の特別仕様。タグやフィートによる判別ではなく、idによる判別。
- ↑ 武器に付与されているヴォーパルは0にならない。
- ↑ 該当する海嘯以外でもコンソールでノックバックエンチャを付与すると再現可能。ただし、現状は海嘯にしかなく、海嘯専用の仕様が多いため固有このページでは「海嘯のノックバック」と呼びます。
- ↑ プログラムでは、X=X+1のように、同じ文字が一つの式に複数回登場して右辺にあるものが調整前の数字、左辺にあるものが調整後の数字になる記法があります。
- ↑ クランプとは値に上限と下限を適用するという意味です。この場合、確率なので0から100%に設定されています
- ↑ 海嘯のみの特別仕様。タグやフィートではなく、海嘯のidで判定される。クリティカルだった場合はクリティカル扱いになる。
- ↑ 11.0 11.1 11.2 この場合、クリティカルにはならない。
- ↑ 見切り力が301以上であれば、見切りによる回避判定は3回行われる
- ↑ 変動するような仕組みは用意されているものの、bonusが初期値以外の値を取らないため現状は1倍で固定。
- ↑ 属性変換や唄魔法が有効なワンドは追加ダメージが発生する
- ↑ 値を一定範囲内に制限する関数です。 関数内の1つめの引数の値は、「2つめの引数の値」~「3つめの引数の値」の範囲内になるよう補正されます。
- ↑ 編者註: EA23.200時点でバグとして報告済みですが、発動エンチャに関わるバグが修正されたPatch1でも修正されていません。 おそらく、大地の槌などが強くなりすぎないようにという意図の下このような処理になっていると思われます。
- ↑ 17.0 17.1 アビリティのパワーは変動しますが、アビリティのダメージ算出の際に使用される関連能力は発動者の能力を参照せず、「パワー / 10」として計算されます。