User:びゃっこ/すたぶ/解析状態異常: Difference between revisions

一般的な状態異常付与を書く
(エーテル病処理を消す(エーテル病のページはあるのでそこに移したいが追跡対象の解析ページが増えるのは主にモチベ的にきつい))
(一般的な状態異常付与を書く)
Line 16: Line 16:
また、「朦朧->混濁」や「切り傷->出血->大出血」<ref>これらは名称・挙動こそ異なるものの、内部上では同一の状態異常として扱われている。</ref>のように一部の状態異常には深度がありますが、これは残りターン数によって段階が決定されています。
また、「朦朧->混濁」や「切り傷->出血->大出血」<ref>これらは名称・挙動こそ異なるものの、内部上では同一の状態異常として扱われている。</ref>のように一部の状態異常には深度がありますが、これは残りターン数によって段階が決定されています。


例えば朦朧は蓄積可能な状態異常なので、連続して付与することでターン数が伸び、一定の残りターン数になると深度が混濁になる、ということが起こっています。
例えば朦朧は蓄積可能な状態異常なので、連続して付与することでターン数が伸び、一定の残りターン数になると深度が混濁になる、ということが起こっています。<ref>病気などターン経過によって残りターン数が減少しないものもありますが、それらは「ターン経過による減少処理」を無効化して実現しています。</ref>


=== 状態異常の強制付与 ===
=== 状態異常の強制付与 ===
Line 36: Line 36:


== 一般的な状態異常付与 ==
== 一般的な状態異常付与 ==
魔法による付与やポーションの効果による付与、その他特殊処理による付与は状態異常の強度を直接指定することで付与しています。
魔法による付与やポーション・巻物・魔法杖の効果による付与、その他特殊処理による付与は状態異常の強度を直接指定することで付与しています。


魔法による付与は魔法パワーを状態異常の強度に、ポーション・巻物・魔法杖の効果による付与はそのパワーが状態異常の強度として扱われていることが殆どです。


=== 一時的耐性による軽減・無効化 ===
<syntaxhighlight lang="c#">
if (c.GainResistFactor > 0 && CanGainConResist)
{
if (c.GainResistFactor >= 400)
{
c.power /= 2;
}
ResistCon(c);
if (c.power <= 0)
{
return null;
}
}
...
public void ResistCon(Condition con)
{
if (con.power > 0 && resistCon != null)
{
int a = ClassExtension.TryGetValue<int, int>((IDictionary<int, int>)resistCon, con.id, 0);
if (1000 < EClass.rnd(a))
{
con.power = 0;
}
else if (500 < EClass.rnd(a))
{
con.power /= 5;
}
else if (200 < EClass.rnd(a))
{
con.power /= 3;
}
else if (100 < EClass.rnd(a))
{
con.power /= 2;
}
}
}
</syntaxhighlight>付与される状態異常に一時的耐性を持っている場合、一時的耐性の値に応じた確率で状態異常強度を軽減もしくは付与の無効化をします。
以下4つの処理を、状態異常の付与が無効になるか状態異常強度を減少するかするまで順番に行います。どの条件も満たさない場合は軽減や無効化は行われません。
1: 0 ~ (一時的耐性 - 1)の範囲のランダムな値が1000より大きいなら、状態異常の付与を無効
2: 0 ~ (一時的耐性 - 1)の範囲のランダムな値が500より大きいなら、状態異常強度を'''「0.2倍」'''に軽減
3: 0 ~ (一時的耐性 - 1)の範囲のランダムな値が300より大きいなら、状態異常強度を'''「0.333倍」'''に軽減
4: 0 ~ (一時的耐性 - 1)の範囲のランダムな値が100より大きいなら、状態異常強度を'''「0.5倍」'''に軽減
また、'''一時的耐性が400以上'''の場合、上記の'''軽減・無効化と重複して'''状態異常強度を'''「0.5」'''倍にします。
=== 主能力による軽減 ===
<syntaxhighlight lang="c#">
if (defenseAttribute != null)
{
c.power = 100 * c.power / Mathf.Max(100 + defenseAttribute.Value, 1);
}
</syntaxhighlight>付与される状態異常に対応する主能力がある場合、付与するキャラクターの主能力に応じて状態異常強度は軽減されます。
軽減率は以下の式で算出されます。
状態異常強度 = 状態異常強度 / (1 + 対応主能力 × 0.01)
=== 属性耐性による軽減・無効化 ===
<syntaxhighlight lang="c#">
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;
}
}
}
</syntaxhighlight>付与される状態異常に対応する属性耐性が5以上ある場合、状態異常強度は軽減されます。(弱点の場合は何も行われません。)
軽減率は以下の式で算出されます。
状態異常強度 = 状態異常強度 / CLAMP(属性耐性 / 5, 1, 4) ^ 2 + 1
表に直すと軽減率は以下のようになります。<ref>免疫でも状態異常強度が残るため、古代種フィートやメタルフィートなどで免疫属性のダメージを受けた場合はその属性の状態異常も付与される。
免疫≠状態な事に注意。</ref>
{| class="wikitable"
|+
!1 (耐性)
!2 (強い耐性)
!3 (素晴らしい耐性)
!4 (免疫)
|-
|×0.5
|×0.2
|×0.1
|×0.06
|}
さらに、この軽減によって状態異常強度が40以下になった場合、付与は無効化されます。
また、'''状態異常が炎上で、付与するキャラクターの火炎属性耐性が15以上'''だった場合、状態異常強度に関わらず付与は無効化されます。
'''状態異常が出血で、付与するキャラクターの出血属性耐性が15以上'''だった場合、状態異常強度に関わらず付与は無効化されます。
=== ターン数算出・付与 ===
<syntaxhighlight lang="c#">
int num2 = c.EvaluateTurn(c.power);
if (num2 == 0)
{
return null;
}
c.value = num2;
conditions.Add(c);
...
public virtual int EvaluateTurn(int p)
{
return Mathf.Max(1, base.source.duration.Calc(p, 0, P2));
}
</syntaxhighlight>これまでの処理で無効化されておらず、状態異常強度が1未満になっていないなら付与する状態異常のターン数を算出します。(計算式については状態異常表を参照)
算出した結果1ターン未満になった場合、最低でも1ターンが保障されます。
その後、算出したターン数分の状態異常を付与します。
=== 一時的耐性の獲得 ===
<syntaxhighlight lang="c#">
if (CanGainConResist)
{
AddResistCon(c);
}
...
public void AddResistCon(Condition con)
{
if (con.power > 0 && con.GainResistFactor > 0)
{
int key = con.id;
if (resistCon == null)
{
resistCon = new Dictionary<int, int>();
}
if (resistCon.ContainsKey(key))
{
resistCon[key] += con.power * con.GainResistFactor / 100;
}
else
{
resistCon[key] = con.power * con.GainResistFactor / 100;
}
}
}
</syntaxhighlight>状態異常が付与されると、『』か《》付きのキャラクターは'''付与された際の強度に応じて'''一時的耐性が蓄積されます。
蓄積する一時耐性の値は以下の式で算出されます。(計算式については状態異常表を参照)
獲得一時耐性値 = 状態異常強度 × (一時耐性係数 / 100)


==攻撃による状態異常付与==
==攻撃による状態異常付与==
Line 359: Line 511:


付与される混乱の強度は'''「1 ~ 3の範囲内のランダムな値」'''で、耐性や無効化を無視します。
付与される混乱の強度は'''「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;
        }
付与する状態異常が炎上ではなく<ref>この条件の必要性が不明</ref>、付与する状態異常が出血であり、出血耐性評価が素晴らしい以上の時、出血付与は失敗します。
付与する状態異常が炎上の時は、炎上耐性が素晴らしい以上なら、付与が失敗します。
古代種持ちの火炎攻撃でも、炎上耐性が素晴らしい以上なら炎上はしません。
            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にします。
{| class="wikitable"
|+対応関係
|-
!状態異常!!対応する属性耐性!!特筆事項
|-
|毒||毒||
|-
|恐怖||幻惑||
|-
|混乱||幻惑||
|-
|睡眠||神経||
|-
|麻痺||神経||
|-
|盲目||闇||
|-
|朦朧||音||
|-
|結露||冷気||
|}
        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;
    }
==まとめ==
状態異常が付与される流れは、
*攻撃ならば、1ダメージ以上与える。もしくはキズアミを信仰しているのが必要。(chance関数の条件)
**免疫である属性でも古代種フィート持ちの攻撃でダメージをもらう場合は付与されうる。
**衝撃の混乱と麻痺はこの条件がなくても付与される。
*属性強度依存<ref>未確認</ref>の確率を潜り抜けるのが必要。(多くの状態異常はchance関数を判定に含む)
*炎上と出血は耐性評価15以上には通らない
**例え古代種やforceのついた攻撃でも不能。
*ボスなどが獲得する抵抗でpowerを減らす処理が起きる。
*forceがない状態異常は以下の軽減処理を受ける。forceを持つのは電撃の麻痺、衝撃の混乱と麻痺のみ
**1. 無効エンチャントや種族としての無効を持っている場合、無効化される。
**2. 主能力で一部の状態異常は減衰される。
**3. 属性耐性(評価)で対応する状態異常は減衰される。評価1段階ごとに大幅に通りにくくなる。
<references />
<references />
250

edits