User:びゃっこ/すたぶ/解析状態異常
主に属性強度(eleP、状態異常の通りやすさのあれ)と 状態異常にかかる際の軽減についての処理なんかを記載する予定。
DamageHPの一部とCondition.csとかを中心に見ていく。
攻撃による状態異常付与
あらゆる攻撃は、そのダメージ量とは別に「属性強度」という値を持ちます。[1]
これは状態異常の発生率と付与される状態異常の強度に関わり、物理攻撃や魔法攻撃で属性ダメージを受ける際には属性強度に基づいて状態異常の付与が決定されます。
属性強度の実際の値と計算式については、各ページを参照してください。
攻撃による状態異常付与の一般的な条件
if (dmg > 0 || (origin != null && origin.HasElement(1345)))
{
ApplyElementEffect(e, eleP, origin);
}
攻撃による状態異常付与は、まず1ダメージ以上を与える必要があります。
キズアミを信仰しているキャラクターはこの条件を無視することができます。
火炎属性
case 910:
if (Chance(30 + eleP / 5, 100))
{
MarkHostile().AddCondition<ConBurning>(eleP);
}
break;
火炎属性の攻撃で炎上が付与されます。
付与確率は「30 + 属性強度 / 5」%で、最低30%、最大100%です。
付与される炎上の強度は「属性強度」と等しいです。
冷気属性
case 911:
if (Chara.isWet)
{
if (Chance(30 + eleP / 10, 100))
{
Chara.AddCondition<ConFreeze>(eleP);
}
}
else if (Chance(50 + eleP / 10, 100))
{
Chara.AddCondition<ConWet>(eleP);
}
break;
冷気属性の攻撃で濡れ・凍結が付与されます。
濡れでないなら濡れの判定のみ、濡れているなら凍結の判定のみ行われます。
濡れの付与確率は「50 + 属性強度 / 10」%で、最低50%、最大100%です。
付与される濡れの強度は「属性強度」と等しいです。
凍結の付与確率は「30 + 属性強度 / 10」%で、最低30%、最大100%です。
付与される凍結の強度は「属性強度」と等しいです。
電撃属性
case 912:
if (Chance(75 + eleP / 20, 100) && EClass.rnd(3) == 0)
{
Chara.AddCondition<ConParalyze>(1, force: true);
}
break;
電撃属性の攻撃で麻痺が付与されます。
付与確率は「(75 + 属性強度 / 20) * 0.333」%で、最低約「25」%、最大「33.3」%です。
付与される麻痺は「1」ターンで、これは耐性や無効化を無視します。
暗黒属性
case 913:
if (Chance(30 + eleP / 5, 100))
{
Chara.AddCondition<ConBlind>(eleP);
}
break;
暗黒属性の攻撃で盲目が付与されます。
付与確率は「30 + 属性強度 / 5」%で、最低約30%、最大100%です。
付与される盲目の強度は「属性強度」と等しいです。
幻惑属性
case 914:
flag = false;
if (EClass.rnd(3) != 0)
{
if (Chance(30 + eleP / 5, 100))
{
Chara.AddCondition<ConConfuse>(eleP);
}
}
else if (Chance(30 + eleP / 5, 100))
{
Chara.AddCondition<ConSleep>(eleP);
}
break;
...
if (Chara.conSleep != null && flag)
{
Chara.conSleep.Kill();
}
幻惑属性の攻撃で混乱か睡眠が付与されます。
確率2/3で混乱の判定のみ、残りの1/3の確率で睡眠の判定のみが起こります。
混乱・麻痺ともに付与確率は「30 + 属性強度 / 5」%で、最低30%、最大100%です。
付与される状態異常の強度は「属性強度」と等しいです。
また、この属性の攻撃では睡眠が解除されません。
毒属性
case 915:
if (Chance(30 + eleP / 5, 100))
{
MarkHostile().AddCondition<ConPoison>(eleP);
}
break;
毒属性の攻撃で毒が付与されます。
付与確率は「30 + 属性強度 / 5」%で、最低約30%、最大100%です。
付与される毒の強度は「属性強度」と等しいです。
轟音属性
case 917:
if (Chance(50 + eleP / 10, 100))
{
Chara.AddCondition<ConDim>(eleP);
}
break;
轟音属性の攻撃で朦朧が付与されます。
混乱・麻痺ともに付与確率は「50 + 属性強度 / 10」%で、最低50%、最大100%です。
付与される状態異常の強度は「属性強度」と等しいです。
神経属性
case 918:
flag = false;
if (Chance(30 + eleP / 5, 100))
{
Chara.AddCondition<ConParalyze>(eleP);
}
break;
...
if (Chara.conSleep != null && flag)
{
Chara.conSleep.Kill();
}
神経属性の攻撃で麻痺が付与されます。 付与確率は「30 + 属性強度 / 5」%で、最低30%、最大100%です。
付与される麻痺の強度は「属性強度」と等しいです。
また、この属性の攻撃では睡眠が解除されません。
混沌属性
case 920:
flag = false;
if (Chance(5 + eleP / 25, 40))
{
Chara.AddCondition<ConBlind>(eleP / 2);
}
if (Chance(5 + eleP / 25, 40))
{
Chara.AddCondition<ConParalyze>(eleP / 2);
}
if (Chance(5 + eleP / 25, 40))
{
Chara.AddCondition<ConConfuse>(eleP / 2);
}
if (Chance(5 + eleP / 25, 40))
{
MarkHostile().AddCondition<ConPoison>(eleP / 2);
}
if (Chance(5 + eleP / 25, 40))
{
Chara.AddCondition<ConSleep>(eleP / 2);
}
if (Chance(5 + eleP / 25, 40))
{
Chara.AddCondition<ConDim>(eleP / 2);
}
if (Chance(30 + eleP / 10, 100))
{
Chara.SAN.Mod(EClass.rnd(2));
}
break;
...
if (Chara.conSleep != null && flag)
{
Chara.conSleep.Kill();
}
混沌属性の攻撃で盲目・麻痺・混乱・毒・睡眠・朦朧が付与され、狂気度が上昇します。
それぞれの状態異常が同時に付与されることがあります。また、この属性の攻撃では睡眠が解除されません。
盲目の付与確率は「5 + 属性強度 / 25」%で、最低5%、最大「40」%です。
付与される盲目の強度は「属性強度 / 2」です。
麻痺の付与確率は「5 + 属性強度 / 25」%で、最低5%、最大「40」%です。
付与される麻痺の強度は「属性強度 / 2」です。
混乱の付与確率は「5 + 属性強度 / 25」%で、最低5%、最大「40」%です。
付与される混乱の強度は「属性強度 / 2」です。
毒の付与確率は「5 + 属性強度 / 25」%で、最低5%、最大「40」%です。
付与される毒の強度は「属性強度 / 2」です。
睡眠の付与確率は「5 + 属性強度 / 25」%で、最低5%、最大「40」%です。
付与される睡眠の強度は「属性強度 / 2」です。
朦朧の付与確率は「5 + 属性強度 / 25」%で、最低5%、最大「40」%です。
付与される朦朧の強度は「属性強度 / 2」です。
狂気度の上昇確率は「(30 + 属性強度 / 10) / 2」%で、最低15%、最大「50」%です。
上昇する狂気度は「1」です。
エーテル属性
case 922:
Chara.ModCorruption(EClass.rnd(eleP / 50 + 10));
break;
エーテル属性の攻撃でエーテル病が進行します。
進行確率は100%です。
進行度は「0 ~ (10 + 属性強度 / 50)の範囲内のランダムな値」です。[2]
酸属性
case 923:
if (Chance(50 + eleP / 10, 100) && EClass.rnd(4) == 0)
{
ActEffect.Proc(EffectId.Acid, Chara);
}
break;
酸属性の攻撃で装備品の劣化判定が発生します。 付与確率は「(50 + 属性強度 / 10) / 4」%で、最低12.5%、最大「25」%です。
出血属性
case 924:
if (Chance(50 + eleP / 10, 100))
{
MarkHostile().AddCondition<ConBleed>(eleP);
}
break;
出血属性の攻撃で出血が付与されます。
付与確率は「50 + 属性強度 / 10」%で、最低50%、最大100%です。
付与される出血の強度は「属性強度」と等しいです。
衝撃属性
case 925:
if (EClass.rnd(3) == 0)
{
if (Chance(30 + eleP / 5, 100))
{
Chara.AddCondition<ConDim>(eleP);
}
}
else if (EClass.rnd(2) == 0)
{
if (EClass.rnd(3) == 0)
{
Chara.AddCondition<ConParalyze>(1, force: true);
}
}
else if (EClass.rnd(2) == 0)
{
Chara.AddCondition<ConConfuse>(1 + EClass.rnd(3), force: true);
}
break;
幻惑属性の攻撃で朦朧、麻痺、混乱のどれか1つが付与されます。
判定は、1/3で朦朧、1/9で麻痺、1/6で混乱。残る7/18は判定発生なしです。
朦朧の付与確率は「30 + 属性強度 / 5」%で、最低30%、最大100%です。
付与される朦朧の強度は「属性強度」と等しいです。
麻痺の付与確率は100%です。
付与される麻痺は「1」ターンで、耐性や無効化を無視します。
混乱の付与確率は100%です。
付与される混乱の強度は「1 ~ 3の範囲内のランダムな値」で、耐性や無効化を無視します。
Condition.cs
条件
public Condition AddCondition<T>(int p = 100, bool force = false) where T : Condition
{
return AddCondition(typeof(T).Name, p, force);
}
public Condition AddCondition(string id, int p = 100, bool force = false)
{
return AddCondition(Condition.Create(id, p), force);
}
public Condition AddCondition(Condition c, bool force = false)
{
c.owner = this;
if (!(c is ConBurning))
{
if (c is ConBleed && ResistLv(964) >= 3)
{
return null;
}
}
else if (ResistLv(950) >= 3)
{
return null;
}
付与する状態異常が炎上ではなく[3]、付与する状態異常が出血であり、出血耐性評価が素晴らしい以上の時、出血付与は失敗します。
付与する状態異常が炎上の時は、炎上耐性が素晴らしい以上なら、付与が失敗します。
古代種持ちの火炎攻撃でも、炎上耐性が素晴らしい以上なら炎上はしません。
if (c.GainResistFactor > 0 && CanGainConResist)
{
if (c.GainResistFactor >= 400)
{
c.power /= 2;
}
ResistCon(c);
if (c.power <= 0)
{
return null;
}
}
if (!force)
{
if (c.source.negate.Length != 0)
{
string[] negate = c.source.negate;
foreach (string text in negate)
{
if (HasElement(text))
{
return null;
}
}
}
Element defenseAttribute = c.GetDefenseAttribute(this);
if (defenseAttribute != null)
{
c.power = 100 * c.power / (100 + defenseAttribute.Value);
}
if (c.source.resistance.Length != 0)
{
int num = ResistLv(EClass.sources.elements.alias[c.source.resistance[0]].id);
if (num > 0)
{
c.power /= num * num + 1;
if (c.power <= 40)
{
return null;
}
}
}
c.power = c.EvaluatePower(c.power);
if (c.power <= 0)
{
return null;
}
}
状態異常への抵抗を判断する処理です。
forceがあるものはこれらの軽減処理を無視します。forceを持つのは電撃の麻痺、衝撃の混乱と麻痺です。
衝撃の混乱と麻痺に至っては、chance関数なく判定されるため、衝撃耐性でダメージを0にしても付与が成功すると考えられます。
上記の特例を除き、無効エンチャントや種族特性などで状態異常は無効化されます。
次に、状態異常ごとの対応主能力で減衰がかかります。powerの値が 100 / (100 + 対応主能力)倍になります。
かける状態異常に対応した属性耐性を持っているなら、属性評価2乗 + 1 でpowerを割ります。割った後に、powerの値が40以下なら、0にします。
| 状態異常 | 対応する属性耐性 | 特筆事項 |
|---|---|---|
| 毒 | 毒 | |
| 恐怖 | 幻惑 | |
| 混乱 | 幻惑 | |
| 睡眠 | 神経 | |
| 麻痺 | 神経 | |
| 盲目 | 闇 | |
| 朦朧 | 音 | |
| 結露 | 冷気 |
for (int j = 0; j < conditions.Count; j++)
{
if (conditions[j].id != c.id)
{
continue;
}
if (c.Type == ConditionType.Stance || c.IsToggle)
{
conditions[j].Kill();
return null;
}
if (conditions[j].CanStack(c))
{
if (conditions[j].WillOverride)
{
conditions[j].Kill(silent: true);
continue;
}
if (CanGainConResist)
{
AddResistCon(c);
}
conditions[j].OnStacked(c.power);
conditions[j].OnStartOrStack();
conditions[j].PlayEffect();
}
if (!conditions[j].AllowMultipleInstance)
{
return null;
}
}
foreach (Condition condition in conditions)
{
if (condition.TryNullify(c))
{
return null;
}
}
int num2 = c.EvaluateTurn(c.power);
if (num2 == 0)
{
return null;
}
c.value = num2;
conditions.Add(c);
if (CanGainConResist)
{
AddResistCon(c);
}
c.SetOwner(this);
c.Start();
SetDirtySpeed();
if (c.ShouldRefresh)
{
Refresh();
}
if (IsPC && c.ConsumeTurn && !EClass.pc.isRestrained)
{
EClass.player.EndTurn();
}
if (c.SyncRide && (ride != null || parasite != null))
{
if (ride != null)
{
ride.AddCondition(Condition.Create(c.source.alias, c.power));
}
if (parasite != null)
{
parasite.AddCondition(Condition.Create(c.source.alias, c.power));
}
}
return c;
}
Chara.cs
エーテル病進行度
public void ModCorruption(int a)
{
if (a > 0)
{
if (ResistLv(962) > 0 && EClass.rnd(ResistLv(962) + 1) != 0)
{
return;
}
int num = Evalue(412);
if (num != 0)
{
float num2 = (float)a * 100f / (float)Mathf.Max(100 + num * 2, 10);
a = (int)num2 + ((EClass.rndf(1f) > num2 % 1f) ? 1 : 0);
}
}
エーテル病が進行する攻撃に被弾したときに呼び出される処理です。
エーテル耐性があるならば、
- 蓄積が発生する確率が1/(エーテル耐性評価値+1)にまで下がります。
- 次にエーテル鈍化による減衰を計算します。
- 蓄積量aが、100/(100 + 鈍化*2)倍になります。 ただし、(100 + 鈍化*2)には下限10があります。
- 最後に計算後の蓄積量aを整数にするための処理をします。
if (a == 0)
{
return;
}
int num3 = (corruption + a) / 100 - corruption / 100;
for (int i = 0; i < Mathf.Abs(num3); i++)
{
if (!MutateRandom((num3 > 0) ? 1 : (-1), 100, ether: true))
{
break;
}
}
corruption += a;
int num4 = 0;
aが0なら計算を終えます。
foreach (Element value in elements.dict.Values)
{
if (value.source.category == "ether")
{
num4 += value.Value;
}
}
if (num4 > 0 && IsPC)
{
Tutorial.Reserve("ether");
}
corruption = num4 * 100 + corruption % 100;
}
まとめ
状態異常が付与される流れは、
- 攻撃ならば、1ダメージ以上与える。もしくはキズアミを信仰しているのが必要。(chance関数の条件)
- 免疫である属性でも古代種フィート持ちの攻撃でダメージをもらう場合は付与されうる。
- 衝撃の混乱と麻痺はこの条件がなくても付与される。
- 属性強度依存[4]の確率を潜り抜けるのが必要。(多くの状態異常はchance関数を判定に含む)
- 炎上と出血は耐性評価15以上には通らない
- 例え古代種やforceのついた攻撃でも不能。
- ボスなどが獲得する抵抗でpowerを減らす処理が起きる。
- forceがない状態異常は以下の軽減処理を受ける。forceを持つのは電撃の麻痺、衝撃の混乱と麻痺のみ
- 1. 無効エンチャントや種族としての無効を持っている場合、無効化される。
- 2. 主能力で一部の状態異常は減衰される。
- 3. 属性耐性(評価)で対応する状態異常は減衰される。評価1段階ごとに大幅に通りにくくなる。