Elona改造講座 第17回(鍛冶ハンマーの移植:中編)

Elona改造講座第17回。鍛冶ハンマーの移植、中編です。
今回は前回移植したサブルーチンや関数をstart.hspから呼び出していきましょう。今回でAF合成を除き鍛冶ハンマーの一通りの機能は使えるようになるはずです。


①インベントリ操作モード名の追加

MMAhのソースを"その方向には、操作できる対象はない。"で検索してください。すぐ下の行にinvtitleという文字列配列の初期化処理が見つかるかと思います。

invtitle = "", "調べる", "置く", "拾う", "", "食べる", "装備する", "読む", "飲む", "振る", "渡す", "購入する", "売却する", "鑑定する", "使う", "開く", "料理する", "調合", "混ぜる対象", "捧げる", "交換する", "提示する", "取る", "対象の", "入れる", "もらう", "投げる", "盗む", "交換する", "予約する"

デフォルトでは29要素目の"予約する"までしかありませんが、新たに30要素目として"鍛える"を追加しましょう。次のようになればOKです。

// CS追加 鍛冶 インベントリタイトルに鍛冶用のタイトル("鍛える")を追加
invtitle = "", "調べる", "置く", "拾う", "", "食べる", "装備する", "読む", "飲む", "振る", "渡す", "購入する", "売却する", "鑑定する", "使う", "開く", "料理する", "調合", "混ぜる対象", "捧げる", "交換する", "提示する", "取る", "対象の", "入れる", "もらう", "投げる", "盗む", "交換する", "予約する", "鍛える"

30行ほど下に英語モード用のinvtitleもあるので、ここも30要素目として"Forge"を追加しましょう(ooのバージョンによっては英語モードにのみ30要素目が存在しないようです)。

// CS追加 鍛冶 インベントリタイトルに鍛冶用のタイトル("Forge")を追加
invtitle = "", "Examine", "Drop", "Pick Up", "", "Eat", "Wear", "Read", "Drink", "Zap", "Give", "Buy", "Sell", "Identify", "Use", "Open", "Cook", "Mix", "Mix Target", "Offer", "Trade", "Present", "Take", "Target", "Put", "Take", "Throw", "Pickpocket", "Trade", "Reserve", "Forge"

画像のようになれば成功です。英語モード用の方も変更してますが、画像だと右側に見切れてますね。

invtitleの30要素目に「鍛える」を追加しました

②インベントリ操作モードの変更

*label_0934を変更します。
カスタムアイテムを食べられるようにしたり、体液を飲むようにしたりする時にも変更した箇所ですね。
countequip = 0にする条件に「invctrl != 30」を追加します。これは「インベントリ操作モードが鍛冶モードでないこと」という意味になります。

		cnt2 = cnt
		// CS追加 鍛冶ハンマー対応 invctrl != 30を条件に追加
//		if ( invctrl != 1 & invctrl != 5 & invctrl != 13 & invctrl != 14 & invctrl != 18 & invctrl != 20 & invctrl != 23 & invctrl != 25 & invctrl != 27 ) {
		if ( invctrl != 1 & invctrl != 5 & invctrl != 13 & invctrl != 14 & invctrl != 18 & invctrl != 20 & invctrl != 23 & invctrl != 25 & invctrl != 27 & invctrl != 30 ) {
			countequip = 0
		}
		else {
			countequip = 1
		}
invctrl != 30を追加しました。
横に長い行なのでウインドウ幅で折り返して表示しています。

続いてinvctrl == 27の場合の下に、invctrl == 30の場合(鍛冶モードの場合)を追加しましょう。関数smithcheckを呼び出して、このアイテムが鍛冶モードで一覧に表示されるか否かを決定しています。

		if ( invctrl == 27 ) {
			if ( cnt2 == 0 ) {
				if ( inv(21, cnt) != 1 ) {
					continue
				}
			}
		}
		// CS追加 鍛冶ハンマー対応 invctrl == 30の場合、smithcheck()を実行
		if ( invctrl == 30 ) {
			if ( smithcheck(cnt, invctrl(1)) ) {
				continue
			}
		}
		// CS追加 ここまで

画像のようになれば成功です。

前回追加した関数smithcheckはここで呼び出します

*label_0937の末尾にもinvctrl == 30の場合の処理を追加します。これはitem_separateという名前から推測する限り、スタックされたアイテムを分割する処理のようです。

// CS追加 鍛冶ハンマー対応
if ( invctrl == 30 ) {
	item_separate ci
	invsubroutine = 0
	return 1
}
// CS追加 ここまで
return -1

画像のようになれば成功です(label_0937の末尾の為、実際にはlabel_0938のすぐ上を探した方が早いでしょう)。

アイテムを分割しているようです

③ハンマー使用時、鍛冶メインを呼び出す

いよいよ今回の肝となる部分です。「_switch_val == 2000」で検索すると鍛冶ハンマー使用時の処理が出てくるので、ここでlabel_smith_2831を呼び出し、その戻り値statが真ならオートターンの設定を行います。
(cdata(140, cc)はオートターン種別で、20012は鍛冶のオートターンを表します。これは次の項で使用します)
何らかの理由でPC以外が使用した場合には「何もおきない…」ようにする安全措置も入っているようですね。

		// カメラを使用
		if ( _switch_val == 1001 ) {
			outputmapimage inv(17, ci)
			snd 44
			txt_select -1, lang("周囲の風景をカメラに収めた。", "You captured the surrounding landscape with a camera."), "", "", "", "", "", "", "", ""
			break
		}
		// 鍛冶ハンマーを使用
//		if ( _switch_val == 2000 ) {
//			txt_select -1, lang("それはomake_MMA/TrashThrowでは使用できない。", "You can't use it on the omake_MMA/TrashThrow."), "", "", "", "", "", "", "", ""
//			break
//		}
		// CS追加(v1.1) 鍛冶ハンマー使用時の効果を移植
		if ( _switch_val == 2000 ) {
			if ( cc != 0 ) {
				txt_select -1, lang("何もおきない… ", "Nothing happens..."), "", "", "", "", "", "", "", ""
				break
			}
			cw = ci
			snd 100
			gosub *label_smith_2831
			if ( stat ) {
				extend = 0
				cdata(140, cc) = 20012
				cdata(141, cc) = 25 + rnd(11)
				cdata(142, cc) = cw
			}
			else {
				obvious = 0
			}
			break
		}
		// CS追加 ここまで

画像のようになれば成功です。
(MMA/TTでは使用できないことを示すメッセージも念の為にコメントアウトして残しています)

前回移植した鍛冶のメインを呼び出します

④鍛冶オートターン処理

オートターンの制御を行うサブルーチンはlabel_1182です。ここにオートターン種別が20012の場合、鍛冶のオートターン処理label_smith_2832を呼び出す処理を追加しましょう。

	if ( cdata(140, cc) == 6 | cdata(140, cc) == 10006 ) {
		at 40
		gosub *label_1000
	}
	if ( cdata(140, cc) == 3 ) {
		gosub *label_1007
		gosub *label_1052
		return stat
	}
	// CS追加(v1.1) 鍛冶 鍛冶のオートターン処理を実行
	if ( cdata(140, cc) == 20012 ) {
		at 20
		gosub *label_smith_2832
	}
	// CS追加 ここまで
	if ( cdata(141, cc) > 0 ) {
		return 1
	}
	rowactend cc

画像のようになれば成功です。

前回移植した鍛冶のオートターン処理を呼び出します

また、鍛冶はオートターン中にダメージを受けると行動を中断する仕様になっています。"は歌唱を中断した。"で検索して、すぐ下に鍛冶(ID:20012)を中断する処理を追加しましょう。これが無いと行動を中断された時に配列actlistnの20012要素目にアクセスしようとしてエラー落ちしてしまいます(体験談)

if ( cc != 0 | rtval == 0 ) {
	if ( synccheck(cc, -1) ) {
		// CS追加(v1.1) 鍛冶 オートターン中断処理に鍛冶(ID:20012)を追加
		if ( cdata(140, cc) == 10006 ) {
			txt_select -1, lang(name(cc) + "は歌唱を中断した。", name(cc) + " stop" + _s(cc) + " singing."), "", "", "", "", "", "", "", ""
		}
		else : if ( cdata(140, cc) == 20012) {
			txt_select -1, lang(name(cc) + "は鍛冶を中断した。", name(cc) + " stop" + _s(cc) + " smithing."), "", "", "", "", "", "", "", ""
		}
		else {
			txt_select -1, lang(name(cc) + "は" + actlistn(cdata(140, cc)) + "を中断した。", name(cc) + " stop" + _s(cc) + " " + actlistn(cdata(140, cc)) + "."), "", "", "", "", "", "", "", ""
		}
	}
	if ( cdata(140, cc) == 5 | cdata(140, cc) == 7 | cdata(140, cc) == 8 | cdata(140, cc) == 9 ) {
		if ( cdata(144, cc) != 0 ) {
			calc_wither_spot cc
		}
	}
	rowactend cc
}

画像のようになれば成功です。

これが無いとactlistnの配列範囲外にアクセスしてしまいます

⑤動作確認用の処理

この項は必須ではありませんが、てっとり早く動作確認する為、願いに"鍛冶素材"を追加しましょう。折れた刃と各種鉱石100個ずつを生成するだけのものです(デバッグ用の願いなのでウィザードモード限定にしています)。

// CS追加(v1.1) 鍛冶 必要素材(折れた刃(ID:50)と各種鉱石(ID:39~42)100個ずつ)を願いの対象に追加(ウィザードモード限定)
if ( gdata(828) ) {
	if ( inputlog == "鍛冶素材" | inputlog == "forge material" ) {
		flt
		itemcreate -1, 50, cdata(1, 0), cdata(2, 0), 100
		flt
		itemcreate -1, 39, cdata(1, 0), cdata(2, 0), 100
		flt
		itemcreate -1, 40, cdata(1, 0), cdata(2, 0), 100
		flt
		itemcreate -1, 41, cdata(1, 0), cdata(2, 0), 100
		flt
		itemcreate -1, 42, cdata(1, 0), cdata(2, 0), 100
		txtgod godcheck(), 2415
		return
	}
}
鍛冶素材を願えるようにしました
折れた刃って意外と集めにくいんですよね……

⑥動作確認

ハンマーを買うなり願うなりして入手したら、いよいよお待ちかねの鍛冶タイムです!
折れた刃を選択すると武器種選択→鉱石選択と進み、決定すると武器の作成を開始します。
(鉱石に対応した素材になります。鉱石の代わりにドラゴン類の皮やバニラロックも選択可)

武器種の選択。この後素材となる鉱石を選択します
大剣+エメラルド鉱石でこうなりました

皮を選択すると防具が生産されます。
(通常は鱗製ですがNPCの種別によっては異なる素材になります。どれが何になるかは作ってみてのお楽しみ。気になる人は前回のソースコードを実際に見てみましょう)

防具種の選択。素材はNPCの種別に依存します
通常は鱗製になります

また、酸でマイナスの強化値が付いた武具を選択すると修理もできます。
(+にするのはLv21から)
 
ハンマーに経験値が入りレベルアップすれば成功です。
また、Lv11まで上げると表示名が「丈夫なハンマー」に変化します。

ハンマーLv11で「丈夫なハンマー」に進化しました!

⑦次回予告

次回は鍛冶ハンマーLv21以上で解禁されるAF合成について取り扱います。
予習したい方はハンマーをLv21まで上げたうえで、「アーティファクト合成許可証」を願ってAF合成を実行してみてください。恐らく上手く行かないはずです。
 
余裕があれば「なぜ上手く行かないのか?」「どうすれば対処できるか?」も考えてみましょう。原因と対策は次回解説しますのでご安心を。ハンマーをLv21まで上げるのは大変という人の為の対策も用意してありますのでご安心ください。

⑧補足:ドラゴン類について

ドラゴン類の皮で竜鱗素材の武具が製造できると聞いてこう思った方もいるかと思います。
「MMA系列に類なんて概念あったか?」と。
これは実際に試してもらった方が早いのですが、ドラゴン類の皮を素材にするとしっかり竜鱗製になります。類はooで追加された概念ですがこれ自体はfilterがベースになっており、filterの/dragon/は本家Elonaの時点から存在したからこうなるみたいですね(/dragon/は終末での出現対象・竜族特攻の対象の判定で使用されているそうです)

鉱石の代わりに冥界ドラゴンの皮を使用するとしっかり竜鱗製になりました
(とは言えMMA系の竜鱗は大して強くないのですが……)

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