Elin:解析/釣り

From Ylvapedia
Revision as of 13:29, 27 November 2024 by Sakumashiki (talk | contribs) (EN版の更新を反映)
Jump to navigation Jump to search

釣りに関する計算式などのページです。

魚 LV

自分の釣りレベルから釣れる魚LVを算出する公式:

fishLV = rnd(fishingLevel * 2) + 1
  • 釣りレベル: 現在の釣りスキルレベル。
  • rnd: 0から関数に渡された値までの間のランダムな数値。

調整済み魚LV

調整済み魚LVはアイテム作成時に計算されます。これは「rnd」関数に複数回呼び出しを行い、最後に「+2」というハードコードされた値を追加します。最終的な調整レベルは次のようになります。

adjustedLV = fishLV + 2 + rnd(rnd(rnd(rnd(Mathf.Min(fishLV * 2, 20)) + 1) + 1) + 1)
  • 調整プロセスには以下の処理が含まれます。
    • 基本となる fishLVrnd(fishingLevel * 2) + 1 と決定します。
    • 「rnd」関数に複数回呼び出しを適用します。
      • 「rnd」は「0」から「(最大値 - 1)」までの間のランダムな数値を生成します。
      • 各呼び出しは、直前の「rnd」の結果に依存し、徐々に可能な範囲を狭めていきます。
    • ハードコードされた「+2」を追加し、調整されたLVが常にオフセットを持つようにします。

釣りレベルが「10」の場合:

  • 「基本レベル」:
    • 「fishLV = rnd(10 * 2) + 1 = rnd(20) + 1」。
    • 結果例:「10」。
  • 調整:
    • 1つ目 rnd(20) → 結果 = 7.
    • 2つ目 rnd(7 + 1) → 結果 = 3.
    • 3つ目 rnd(3 + 1) → 結果 = 2.
    • 4つ目 rnd(2 + 1) → 結果 = 0.
  • 最終的な調整後LV:
    • adjustedLV = 10 + 2 + 0 = 12.

魚LV範囲表

釣りレベル 最低LV 最大LV
1 3 5
2 3 7
3 3 9
4 3 11
5 3 13
6 3 15
7 3 17
8 3 19
9 3 21
10 3 23
11 3 25
12 3 27
13 3 29
14 3 31
15 3 33
16 3 35
17 3 37
18 3 39
19 3 40

コード (EA 23.41)

int num3 = EClass.rnd(num * 2) + 1;
thing = ThingGen.Create("fish", -1, num3);

lv = lv + 2 + EClass.rnd(EClass.rnd(EClass.rnd(EClass.rnd(Mathf.Min(lv * 2, 20)) + 1) + 1) + 1);

魚の数

自分の釣りレベルから釣れる匹数を計算する式は次の通りです。

numberOfFish = rnd(fishingLevel / (fishLV + 10)) + 1
  • 釣りレベル:現在の釣りスキルレベル。
  • 魚レベルLV:魚のレベル。
  • rnd0から関数に渡された値までの間のランダムな数値。

釣りレベルが22で、魚のレベルが1と判定された場合、潜在的な魚の数は以下のように計算されます。

rnd(22 / (1 + 10)) + 1

もっと簡略化するとこうなります:

rnd(22 / 11) + 1

rnd(2)は、0から約1の間の乱数を生成します。1を足すと、少なくとも1匹の魚を捕まえることができます。魚の数は、ランダムな結果によって1匹か2匹のどちらかになります。

土地フィート

追加で1匹の魚を捕まえる最初のチャンスは「5%」から始まります。

土地フィートに以下を含む場合:

  • ビーチ (3604): 基本確率に 20% を追加します。
  • 海 (3605): 基本確率に 20% を追加します。
  • 釣り場 (3706): 基本確率に 25% を追加します。

海 (3605) または ビーチ (3604) はいずれか一方のみが存在し得る(両方は存在しない)ため、合計確率は以下のように計算されます。

chanceForOneMoreFish = 5
chanceForOneMoreFish += isBeach * 20 + isSea * 20 + isFishingSpot * 25

以下を参照してください。

  • isBeach: 土地フィートが「ビーチ(3604)」であることを示すフラグ(0または1)。
  • isSea: 土地フィートが「海(3605)」であることを示すフラグ(0または1)。
  • isFishingSpot: 土地が釣り場(3706)であるかどうかを示すフラグ(0または1)。

例えば:

  • 海 (3605)が存在し、さらに釣り場(3706)も存在する場合:
chanceForOneMoreFish = 5 + 1 * 20 + 1 * 25 = 50
  • 海 (3605) の代わりに ビーチ (3604) が存在する場合:
chanceForOneMoreFish = 5 + 1 * 20 + 1 * 25 = 50

魚の数を増やすチャンスの確認

chanceForOneMoreFishの値は、0から99(両端の値を含む)の間の数値を生成するrnd(100)関数によって生成された乱数と比較されます。

chanceForOneMoreFishが乱数以上の場合、魚の数は「1」増えます。

このチェックは以下のように実装されています。

if (chanceForOneMoreFish >= rnd(100))

例えば:

  • chanceForOneMoreFish = 50、かつ rnd(100) によって生成された乱数が 50 以下 の場合、魚が1匹追加で釣れます。

土地フィートの例

例 1: 釣り場 (3706) と海 (3605)

あなたの釣りレベルが「22」、魚のレベルが「1」だとします。魚の基本数は以下のように計算されます。

numberOfFish = rnd(22 / (1 + 10)) + 1 = rnd(2) + 1

これにより、ランダムな結果に応じて「1」または「2」の魚が得られます。

次に、陸での成果を評価します。

  • まず、chanceForOneMoreFish = 5(基本確率)とします。
  • 海(3605)20 を追加します。
  • 釣り場 (3706)25 を追加します。

新しい chanceForOneMoreFish は次のようになります。

chanceForOneMoreFish = 5 + 20 + 25 = 50

続いて、ランダムなチャンスが判定されます。

if (chanceForOneMoreFish >= rnd(100))

rnd(100)によって生成された乱数が「50以下」の場合、魚の数は「1」増えます。したがって、

  • 「numberOfFish = numberOfFish + 1」(乱数のチェックに合格した場合)。
  • 乱数が「50」を超える場合、魚の数は変化しません。
例2: 釣りスポット (3706) とビーチ (3604)

同じ釣りレベルと魚LVの場合、土地の成果は以下のようになります。

  • ビーチ (3604)20 を追加します。
  • 釣りスポット (3706)25 を追加します。

合計の「chanceForOneMoreFish」は次のままです。

chanceForOneMoreFish = 5 + 20 + 25 = 50

ランダムチェックは、追加の魚の確率が同じであることを除いて、上記と同じ動作をします。

魚の数表

魚LV 魚を2匹釣るための最低釣りレベル 魚を3匹釣るための最低釣りレベル
1 22 33
5 30 45
10 40 60
15 50 75
20 60 90
25 70 105
30 80 120
35 90 135
40 100 150

コード (EA 23.40)

num2 = EClass.rnd(num / (num3 + 10)) + 1;
int num4 = 5;
if (EClass.Branch != null)
{
    num4 += EClass.Branch.Evalue(3604) * 20 + EClass.Branch.Evalue(3605) * 20 + EClass.Branch.Evalue(3706) * 25;
}
if (num4 >= EClass.rnd(100))
{
    num2++;
}
if (thing != null)
{
    thing.SetNum(num2);
    thing.SetBlessedState(BlessedState.Normal);
}

釣り速度

釣りのプロセスには、2つの重要な変数が関わります。

  • 進行度: 釣りの全体の所要時間または完了率を表し、0から100までの範囲です。
  • ヒット: 魚との格闘中に試行された回数を追跡します。以下の条件が適用されます。
    • 増加: 以下のいずれかが発生するまで、試行ごとにヒットが増加します。

魚が釣れた場合(「hit」が「ランダム閾値」より大きい場合)。

特定のランダム条件により「hit」が「0」にリセットされる場合。

成功

魚を釣るための成功閾値を計算する式は以下の通りです。

successThreshold = Mathf.Clamp(10 - rnd(fishingLevel + 1) / 10, 5, 10)
  • fishingLevel: 現在の釣りスキルレベル。
  • rnd: 0 から関数に渡された値までの間の乱数。
  • Clamp: 値が 5(最も簡単)から 10(最も難しい)の範囲に収まるようにします。

実際の成功ロジックは以下の通りです。

if (hit > rnd(successThreshold)) {
hit = 100;
progress = MaxProgress;
}
  • hit: 現在の試行回数を追跡します。hitがsuccessThresholdのランダムロールを超えると魚が釣れたことになります。
  • progress: 成功すると自動的に完了します。

釣りレベルが「20」の場合、計算は以下のように進みます。

  1. rnd(20 + 1) は「0」から「20」までの間の乱数を生成します。
  2. この乱数を「10」で割った値を「10」から引きます。

結果は [5, 10] の範囲に制限され、successThreshold が決定されます。

例えば:

  • rnd(21) = 10 の場合、計算は次のようになります。
successThreshold = Mathf.Clamp(10 - (10 / 10), 5, 10) = 9

乱数rnd(9)の値によって閾値が決定されます。 hit > rnd(9) の場合、魚が釣れます。

成功閾値テーブル

釣りレベル 最小成功閾値 最大成功閾値
1 10 10
5 10 10
10 9 10
15 9 10
20 8 10
25 8 10
30 7 10
35 7 10
40 6 10
45 6 10
50 5 10
55 5 10
60 5 10

リセット

「ヒット」のリセットを決定する計算式は以下の通りです。

resetThreshold = Mathf.Clamp(10 - rnd(fishingLevel + 1) / 5, 2, 10)
  • fishingLevel: 現在の釣りスキルレベル。
  • rnd: 0 から関数に渡された値までの間の乱数。
  • Clamp: 値が 2(リセットが最も容易な閾値)から 10(リセットが最も困難な閾値)の範囲に収まるようにします。

rnd(resetThreshold)0' に等しく、かつ progress >= 10 の場合、hitカウンターは 0 にリセットされます。

釣りレベルが 30 の場合、計算は以下のように進みます。

  1. rnd(30 + 1) は、0から30までの間のランダムな数値を生成します。
  2. このランダムな数値を5で割った値から10を引きます。
  3. 結果は[2, 10]の範囲に制限され、resetThresholdが決定されます。

例えば:

  • rnd(31) = 10の場合、計算は次のようになります。
resetThreshold = Mathf.Clamp(10 - (10 / 5), 2, 10) = 8

2番目の乱数ロール、rnd(8)が実行されます。結果が「0」の場合、「ヒット」カウンターがリセットされます。

リセット閾値テーブル

釣りレベル Min resetThreshold Max resetThreshold
1 10 10
5 9 10
10 8 10
15 7 10
20 6 10
25 5 10
30 4 10
35 3 10
40 2 10
45 2 10
50 2 10

コード(EA 23.37)

public override void OnProgress()
{
if (this.owner.IsPC && (this.owner.Tool == null || !this.owner.Tool.HasElement(245, 1)))
{
this.Cancel();
return;
}
if (this.hit >= 0)
{
this.owner.renderer.PlayAnime(AnimeID.Fishing, default(Vector3), false);
this.owner.PlaySound(「fish_fight」, 1f, true);
this.Ripple();
int a = Mathf.Clamp(10 - EClass.rnd(this.owner.Evalue(245) + 1) / 10, 5, 10);
if (this.hit > EClass.rnd(a))
{
this.hit = 100;
this.progress = this.MaxProgress;
}
this.hit++;
return;
}
if (EClass.rnd(Mathf.Clamp(10 - EClass.rnd(this.owner.Evalue(245) + 1) / 5, 2, 10)) == 0 && this.progress >= 10)
{
this.hit = 0;
}
if (this.progress == 2 || (this.progress >= 8 && this.progress % 6 == 0 && EClass.rnd(3) == 0))
{
this.owner.renderer.PlayAnime(AnimeID.Shiver, default(Vector3), false);
this.Ripple();
}
}