Elona改造講座 第19回(鍛冶の改造例)

Elona改造講座、第19回です。
今回は鍛冶の改造の一例として
 ①武器の作成に使える素材を増やす
 ②ハンマーの呪縛状態で品質を制限する
 ③ハンマーの獲得経験値の調整
という改造を施してみましょう。


①武器の作成に使える素材を増やす

まずは武器の作成に使える素材を増やしてみます。
デフォルトでは武器の作成に使える素材は
 ・鉱石系(小分類が77001の「狭義の鉱石系」とでも言うべきもの)
 ・ドラゴン類の皮
 ・バニラロック
の3種類です。
ここに新たに
 ・結晶系3種(魔力・太陽・大地)
 ・金塊
 ・偽金塊
を追加してみましょう。結晶系はSESTでも追加されてるやつですね。
変更箇所は全部で3箇所になります。まずは鍛冶のメイン処理*label_smith_2831から。ここを

	else {
		if ( step == 1 ) {
			reftype = refitem(inv(3, ci), 5, ci)
			if ( inv(4, ci) >= 4 & inv(4, ci) <= 5 & reftype >= 10000 & reftype <= 50000 ) {
				txtnew
				txt_select -1, lang("エンチャントを継承するアーティファクトを選ぶ必要がある。このアーティファクトは合成後、永久に失われる。", "Choose a artifact. Once you extract a enchant, the subject will be lost forever."), "", "", "", "", "", "", "", ""
				snd 100
				invctrl(1) = 2
			}
		}
		else {
			if ( step == 2 ) {
				reftype = refitem(inv(3, ci), 5, ci)
				// 鉱石系(77001) 皮(ID:337) バニラロック(ID:716)
				if ( reftypeminor == 77001 | inv(3, ci) == 337 | inv(3, ci) == 716 ) {
					cdata(144, cc) = 1
				}
				else {
					if ( inv(4, ci) >= 4 & inv(4, ci) <= 5 & reftype >= 10000 & reftype <= 50000 ) {
						if ( ibit(13, ci) ) {
							snd 27
							txt_select -1, lang("それはあなたの大事なものだ。<調べる>メニューから解除できる。", "It's set as no-drop. You can reset it from the <examine> menu."), "", "", "", "", "", "", "", ""
							continue
						}
						cdata(144, cc) = 3
					}
				}
			}
		}
	}
	craftref(step * 2) = ci, inv(3, ci)
	step++

このように変更します。

	else {
		if ( step == 1 ) {
			reftype = refitem(inv(3, ci), 5, ci)
			if ( inv(4, ci) >= 4 & inv(4, ci) <= 5 & reftype >= 10000 & reftype <= 50000 ) {
				txtnew
				txt_select -1, lang("エンチャントを継承するアーティファクトを選ぶ必要がある。このアーティファクトは合成後、永久に失われる。", "Choose a artifact. Once you extract a enchant, the subject will be lost forever."), "", "", "", "", "", "", "", ""
				snd 100
				invctrl(1) = 2
			}
		}
		else {
			if ( step == 2 ) {
				reftype = refitem(inv(3, ci), 5, ci)
				// 鉱石系(77001) 皮(ID:337) バニラロック(ID:716)
				// 結晶系(ID:35,36,37) 金塊(ID:38) 偽金塊(ID:208)
				if ( reftypeminor == 77001 | inv(3, ci) == 337 | inv(3, ci) == 716 ) {
					cdata(144, cc) = 1
				}
				else : if ( (35 <= inv(3, ci) & inv(3, ci) <= 38) | (inv(3, ci) == 208) ) {
					cdata(144, cc) = 1
				}
				else {
					if ( inv(4, ci) >= 4 & inv(4, ci) <= 5 & reftype >= 10000 & reftype <= 50000 ) {
						if ( ibit(13, ci) ) {
							snd 27
							txt_select -1, lang("それはあなたの大事なものだ。<調べる>メニューから解除できる。", "It's set as no-drop. You can reset it from the <examine> menu."), "", "", "", "", "", "", "", ""
							continue
						}
						cdata(144, cc) = 3
					}
				}
			}
		}
	}
	craftref(step * 2) = ci, inv(3, ci)
	step++

次にオートターン処理*label_smith_2832。ここを

	if ( reftypeminor == 77001 ) {
		if ( inv(3, ci) == 42 ) {
			fltmaterial = 13 // ダイヤ製
		}
		else : if ( inv(3, ci) == 41 ) {
			fltmaterial = 23 // エメラルド製
		}
		else : if ( inv(3, ci) == 40 ) {
			fltmaterial = 21 // ミカ製
		}
		else : if ( inv(3, ci) == 39 ) {
			fltmaterial = 15 // ルビナス製
		}
		refvalue = refitem(inv(3, ci), 20, ci)
		fixlv = calcfixlv(limit(quality / (refvalue * powf(11, 2) / limitmin(inv(25, cw) * 2 / 25, 1)), 1, 4))
	}

このように変更します。

	if ( (reftypeminor == 77001) | (35 <= inv(3, ci) & inv(3, ci) <= 38) | (inv(3, ci) == 208) ) {
		if ( inv(3, ci) == 42 ) {
			fltmaterial = 13 // ダイヤ製
		}
		else : if ( inv(3, ci) == 41 ) {
			fltmaterial = 23 // エメラルド製
		}
		else : if ( inv(3, ci) == 40 ) {
			fltmaterial = 21 // ミカ製
		}
		else : if ( inv(3, ci) == 39 ) {
			fltmaterial = 15 // ルビナス製
		}
		else : if ( 35 <= inv(3, ci) & inv(3, ci) <= 37 ) {
			fltmaterial =  5 // 結晶系の場合、硝子製
		}
		else : if ( inv(3, ci) == 38 ) {
			fltmaterial = 32 // 金塊の場合、ゴールデン製
		}
		else : if ( inv(3, ci) == 208 ) {
			fltmaterial = 16 // 偽金塊の場合、???
		}
		refvalue = refitem(inv(3, ci), 20, ci)
		fixlv = calcfixlv(limit(quality / (refvalue * powf(11, 2) / limitmin(inv(25, cw) * 2 / 25, 1)), 1, 4))
	}

仕上げです。関数smithcheck。ここを

if ( _switch_val@m18 == 1 | _switch_sw@m18 ) {
	_switch_sw@m18 = 0
	reftypeminor@m18 = refitem(inv(3, prm_1473), 9, prm_1473)
	if ( reftypeminor@m18 == 77001 ) {
		// 鉱石系(77001)
		notsmith@m18 = 0
	}
	else : if ( inv(3, prm_1473) == 716 ) {
		// バニラロック(ID:716)
		notsmith@m18 = 0
	}
	else : if ( inv(3, prm_1473) == 337 ) {
		// 皮(ID:337) ドラゴン類に限る
		s@m18 = refchara(inv(23, prm_1473), 8, 1)
		if ( instr(s@m18, 0, "/dragon/") != (-1) ) {
			notsmith@m18 = 0
		}
	}
	goto *label_smith_3055
	_switch_sw@m18++
}

このように変更します。

if ( _switch_val@m18 == 1 | _switch_sw@m18 ) {
	_switch_sw@m18 = 0
	reftypeminor@m18 = refitem(inv(3, prm_1473), 9, prm_1473)
	if ( reftypeminor@m18 == 77001 ) {
		// 鉱石系(77001)
		notsmith@m18 = 0
	}
	else : if ( (35 <= inv(3, prm_1473) & inv(3, prm_1473) <= 38) | (inv(3, prm_1473) == 208) ) {
		// 結晶系(ID:35,36,37) 金塊(ID:38) 偽金塊(ID:208)
		notsmith@m18 = 0
	}
	else : if ( inv(3, prm_1473) == 716 ) {
		// バニラロック(ID:716)
		notsmith@m18 = 0
	}
	else : if ( inv(3, prm_1473) == 337 ) {
		// 皮(ID:337) ドラゴン類に限る
		s@m18 = refchara(inv(23, prm_1473), 8, 1)
		if ( instr(s@m18, 0, "/dragon/") != (-1) ) {
			notsmith@m18 = 0
		}
	}
	goto *label_smith_3055
	_switch_sw@m18++
}

武器作成の素材選択時、追加したアイテムが表示されることを確認してください。

素材選択画面に追加したアイテムが表示されるようになりました!

実際に鍛冶も行ってみましょう。
結晶系で硝子製に、金塊でゴールデン製になれば成功です。

この例では金塊を素材に使ったのでゴールデン製になりました

さて、それではここで一つ練習問題を。
偽金塊は何製になるでしょうか?
itemmat.csvを見て素材IDを調べたり、実際に自分で試してみるのも面白いと思うぞ(ニヤリ)

②ハンマーの呪縛状態で品質を制限する

お次はハンマーが呪われている場合・堕落している場合に品質に制限をかけてみましょう。SEやSESTでも似た機能がありますね(あちらは堕落時は良質固定のようなので若干仕様が違うようですが)
 
変更箇所はオートターン処理*label_smith_2832だけでOKです。ここを

	// 神器品質は奇跡品質に
	if ( fixlv > 4 ) {
		fixlv = 4
	}
	nostack = 1
	mode = 8
	itemcreate -1, 0, cdata(1, 0), cdata(2, 0), 0
	mode = 0
	inv(8, ci) = 3
	fixmaterial = fltmaterial
	fltmaterial = 0

このように変更します。

	// 神器品質は奇跡品質に
	if ( fixlv > 4 ) {
		fixlv = 4
	}
	// 呪いハンマーの場合、奇跡品質以上は高品質に
	if ( inv(17, cw) == (-1) ) {
		debugmsg "呪いハンマー(奇跡品質以上は高品質に)"
		if ( fixlv > 3 ) {
			fixlv = 3
		}
	}
	// 堕落ハンマーの場合、高品質以上は良質に
	if ( inv(17, cw) == (-2) ) {
		debugmsg "堕落ハンマー(高品質以上は良質に)"
		if ( fixlv > 2 ) {
			fixlv = 2
		}
	}
	debugmsg "fixlv = " + fixlv
	nostack = 1
	mode = 8
	itemcreate -1, 0, cdata(1, 0), cdata(2, 0), 0
	mode = 0
	inv(8, ci) = 3
	fixmaterial = fltmaterial
	fltmaterial = 0

inv(17, cw)はハンマーの祝福/呪縛状態です。
-1なら呪い、-2なら堕落を表します。
(+1なら祝福ですが今回は関係ありません)
呪縛状態に応じて完成品の品質(変数fixlv)に制限をかけているわけですね。
 
注意点として、inv(17, ci)にしないよう気を付けてください(1敗)これだとハンマーではなく鍛冶で完成したアイテムそのものの祝福/呪縛状態で判断してしまいます。 
debugmsgはデバッグ用ウインドウ(コンフィグで表示ON/OFF切り替え可)にメッセージを表示する機能です。通常プレイでは非推奨の機能ですが、デバッグ時の確認には非常に有用なので是非とも活用しましょう。

堕落ハンマーだと粗悪or良質しかできなくなります
(銘選択が出なくなるのである意味有益?)

堕落ハンマーの作り方はちょっと面倒ですが、「何も持っていない仲間にハンマーを渡す→呪縛の巻物を渡す→ハンマーが呪われたのを確認→更に呪縛の巻物を渡す」でできるかと思います。

③ハンマーの獲得経験値の改造

最後にハンマーの獲得経験値に手を加えてみましょう。
武具の作成に成功した時のハンマー経験値は変数expsmithです。これを計算する処理が以下の部分になります。
(実際の経験値獲得処理はこの変数expsmithを関数modexpsmithに渡すことで行います)

	// 鍛冶ハンマーExp計算
	expsmith = rnd(limit(quality - powf(inv(25, cw), 3), 1, 2147483647)) + limitmax(inv(27, cw), quality / 1000)

これを見て分かるように、ハンマーの経験値は2つの項から成り立っていることが分かります。便宜上、第1項を「Lv3乗項」、第2項を「生産数項」と呼称します。

まずは「Lv3乗項」から行きます。この項は素材価値qualityとハンマーLvの3乗を比較し、素材価値の方が高ければ多量の経験値(ただし乱数の機嫌次第)が得られるという仕組みです。

rnd(limit(quality - powf(inv(25, cw), 3), 1, 2147483647))

ダイヤ原石(価値4200)だとLv16まではすぐ上がったのにLv17からなかなか上がらなくなったというのはここに起因しているわけですね。
(Lv16なら16^3=4096<4200で範囲内ですが、Lv17なら17^3=4913>4200でオーバーしてしまう為)
 
ここは3乗の部分を弄ると経験値が激変してしまいます。
例えばここを「ハンマーLvの2乗」にすると、Lv64までは急激なレベルアップを続けることでしょう。
(Lv64だと64^2=4096<4200でダイヤ原石の価値未満ですが、Lv65だと65^2=4225>4200でオーバーしてしまいます)
逆に3乗以外の部分は弄ってもあまり大きな差はありません。
例えば素材価値を10倍(ダイヤ原石なら42000)で計算しても、急激なレベルアップはLv34までしか続きません。
(Lv34だと34^3=39304<42000ですが、Lv35だと35^3=42875>42000)
 
調整が難しい為この項には手を付けず、OF対策をするだけに留めておきましょう。Elonaの整数型は「符号付32bit整数」であり、この場合扱える最も大きな数は2^31-1=2147483647となります。
3乗してこれを超えないのはLv1290までとなります。
(1290^3=2146689000はギリOKですが、1291^3=2151685171はOFしてしまいます)
Lv1291以上の場合は1290の3乗で計算するようにしたものがこちらです。

// 鍛冶ハンマーExp計算(Lv1291以上でのOF対策)
if ( inv(25, cw) <= 1290 ) {
	hammer_level_cubed = powf( inv(25, cw) , 3 )
}
else {
	hammer_level_cubed = 2146689000
}
expsmith = rnd(limit(quality - hammer_level_cubed, 1, 2147483647)) + limitmax(inv(27, cw), quality / 1000)

続いて「生産数項」を見ていきましょう。
inv(27, cw)は生産数で、鍛冶を行う度に+1され、レベルアップ時に0に戻ります。この項は生産数に応じたポイントの経験値を得られる処理ですが、素材価値/1000が上限となっています。したがって例えばダイヤ原石(価値4200)の場合、回数ごとの得られる経験値は1, 2, 3, 4, 4, 4, …となります。

limitmax(inv(27, cw), quality / 1000)

これはこれで特に問題ありませんが、エゴ鉱石の無い環境だとこの項で得られる経験値など無いも同然です。そこで例として素材価値/100に緩和してみましょう。この場合ミカでも最大7ポイント、ダイヤ原石なら最大42ポイントの経験値が得られます。

// 鍛冶ハンマーExp計算(Lv1291以上でのOF対策,生産数項の上限緩和)
if ( inv(25, cw) <= 1290 ) {
	hammer_level_cubed = powf( inv(25, cw) , 3 )
}
else {
	hammer_level_cubed = 2146689000
}
expsmith = rnd(limit(quality - hammer_level_cubed, 1, 2147483647)) + limitmax(inv(27, cw), quality / 100)

※注意点
上記の計算では折れた刃の価値(10)は面倒なので無視して考えています。
どうせダイヤ原石から見れば0.3%にも満たない程度の価値ですし……

余談

MMA系列だと樽エージングで記憶石や魔力石が作れますが、あれって内部的には特定のパラメータを持った大地の結晶や魔力の結晶なんですよね。私は樽エージングには手を付けてないので分からないのですが、あれらを素材に使っても大丈夫なんでしょうか? 想像では通常より価値が高いだけの単なる大地の結晶や魔力の結晶として扱われるものと考えていますが……
(通常品の価値は450~470ですが、記憶石や魔力石は価値1000みたい)

この記事が気に入ったらサポートをしてみませんか?