Elona改造講座 第21回(自動拾いの書式とコンフィグ機能の追加)

Elona改造講座、第21回です。
2023年5月27日に始まったこの講座もかれこれ丸1年。
今回はシステム面の改造として次の2点を行います。
どちらもゲームには直接関係が無い機能ではあります。
 ・自動拾いの書式指定追加
 ・コンフィグ機能の実装


①自動拾いの書式指定の追加

omakeで追加された自動拾い(autopick)機能。単に指定したアイテムを拾うのみならず、アイテム名の前後に特定の記号を付けることで拾う時に行う動作を指定することもできます。例として以下のようなものがあります。
  "!" 拾わずに破壊
  "~" 何もしない
  "?" 拾う時に確認(これのみ末尾)
 
ここにSESTで追加された以下2つの書式指定を追加します。
  "%" 拾った時に自動保存
  "=" 拾った時に大事なものに指定
 
自動拾いの処理は*label_1207で定義されています。
まずラベル先頭から約10行下。ここを

p = 0
p(1) = 0
noteget buff, cnt
// 自動拾い コメント行はスキップ
if ( instr(buff, 0, "#") != (-1) ) {
	continue
}
s = buff
// 自動拾い "!"と"~"を除去
if ( instr(s, 0, "!") != (-1) | instr(s, 0, "~") != (-1) ) {
	getstr s, s, 1
}
if ( instr(s, 0, "?") != (-1) ) {
	getstr s, s, 0, 63
}

このように書き換えます。
書式指定に使う文字を除去する処理に"%"と"="を追加しただけですね。

p = 0
p(1) = 0
noteget buff, cnt
// 自動拾い コメント行はスキップ
if ( instr(buff, 0, "#") != (-1) ) {
	continue
}
s = buff
// 自動拾い "!""~"を除去
// CS追加(v1.2) "%""="も除去
if ( instr(s, 0, "!") != (-1) | instr(s, 0, "~") != (-1) | instr(s, 0, "%") != (-1) | instr(s, 0, "=") != (-1) ) {
	getstr s, s, 1
}
if ( instr(s, 0, "?") != (-1) ) {
	getstr s, s, 0, 63
}

以下、簡単な解説。
関数instrは文字列に特定の文字が存在するかを示す関数です。例えばinstr(s, 0, "%")だと「文字列sの0番目以降に"%"があるか」を調べます(無ければ-1が返ります)
関数getstrは文字列の指定した文字以降を抜き出す関数になります。
例えばgetstr s, s, 1だと「文字列sの1番目以降をsに代入」となり、もう少し分かりやすく言うと「文字列sの先頭の文字を除去」という意味になります。
これらはどちらもHSPの標準の関数なので、詳しくはHSPの仕様書を参照してください。

②自動拾い時の動作の定義

これらの書式指定に対して具体的にどのような動作をするかは*label_1207の末尾で定義されています。ここを

if ( instr(buff, 0, "~") != (-1) ) {
	break
}
if ( instr(buff, 0, "?") != (-1) ) {
	txt_select -1, lang(itemname(cnt2) + "を拾う?", "Pick up " + itemname(cnt2) + "?"), "", "", "", "", "", "", "", ""
	rtval = questionyesno()
	if ( rtval != 0 ) {
		gosub *label_0470
		break
	}
}
in = inv(0, cnt2)
ci = cnt2
gosub *label_1209
break

このように変更します。
autosave = 1 * (gdata(20) != 35)は自動保存を行う際に必要な処理です。
ibitmod 13, cnt2, 1はアイテムcnt2に「大事なもの」フラグを付与する処理です。

if ( instr(buff, 0, "~") != (-1) ) {
	break
}
if ( instr(buff, 0, "?") != (-1) ) {
	txt_select -1, lang(itemname(cnt2) + "を拾う?", "Pick up " + itemname(cnt2) + "?"), "", "", "", "", "", "", "", ""
	rtval = questionyesno()
	if ( rtval != 0 ) {
		gosub *label_0470
		break
	}
}
// CS追加(v1.2) 拾った時に自動保存  ※SESTから移植
if ( instr(buff, 0, "%") != (-1) ) {
	autosave = 1 * (gdata(20) != 35)
}
// CS追加(v1.2) 拾った時に大事なもの指定  ※SESTから移植
if ( instr(buff, 0, "=") != (-1) ) {
	txt_select -1, lang(itemname(cnt2) + "を大事なものに指定した。", "You set " + itemname(cnt2) + " as no-drop."), "", "", "", "", "", "", "", ""
	ibitmod 13, cnt2, 1
}
// CS追加 ここまで
in = inv(0, cnt2)
ci = cnt2
gosub *label_1209
break

③自動拾いの動作確認

セーブフォルダ内のautopick.txtを編集して、書式指定が機能するかどうか確認しましょう。autopick.txtを編集して保存したら、Shift+BackSpaceで再読み込みを忘れないでください。また、自動保存の確認時はウィザードモードとオートセーブ無効化機能を解除するのを忘れないでください。拾った時に自動保存や大事なもの指定が機能したら成功です。

自動拾い時に大事なもの指定できました!
既に手持ちに大事なもの指定済の音楽チケットがある場合、自動スタックされます。

④コンフィグ機能の追加

続いてコンフィグ機能の追加です。コンフィグに使う変数はあらかじめ初期化処理の部分で定義しておきましょう。この例ではcfg_cs_FastFishing, cfg_cs_CallCecilia, cfg_cs_DisableSisterMutationの3つの変数をコンフィグで変更可能にします。

cfg_mmah_maxlevel = 10000
cfg_mmah_mybrother = 0
cfg_mmah_fontantialiasing = 0
cfg_mmah_high_priest_reflection = 1
cfg_mmah_mapchip_of_nefialist = 0
cfg_mmah_mouseoperation = 0
cfg_mmah_dont_show_nodrop_item = 0
cfg_youngersistervoice = 0
cfg_cg_off = 0
cfg_shortcut = 0
cfg_sub_shortcut = 0
cfg_camera = 0
cfg_usecharaffhp = 0
cfg_dump = 0
cfg_guest = 0
cfg_talkconvert = 0
// CS追加 コンフィグ用変数
cfg_cs_FastFishing = 1 // 釣りスキップフラグ
cfg_cs_CallCecilia = 1 // セシリア出現フラグ
cfg_cs_DisableSisterMutation = 1 // 妹化防止フラグ
// CS追加 ここまで

まずは*label_1162を編集します。
ここには設定ファイル(omake_config.txt)の内容を読み込む処理が羅列されているので、追加したい項目の値を変数に読み出します。

	if ( instr(s, 0, "MMAH_mouseoperation.") != (-1) ) {
		setconfig
		cfg_mmah_mouseoperation = limit(int(rtvaln), 0, 1)
		continue
	}
	if ( instr(s, 0, "MMAH_dont_show_nodrop_item.") != (-1) ) {
		setconfig
		cfg_mmah_dont_show_nodrop_item = limit(int(rtvaln), 0, 1)
		continue
	}
	// CS追加(v1.2) CS用コンフィグ
	if ( instr(s, 0, "CS_fastfishing.") != (-1) ) {
		setconfig
		cfg_cs_FastFishing = limit(int(rtvaln), 0, 1)
		continue
	}
	if ( instr(s, 0, "CS_callcecilia.") != (-1) ) {
		setconfig
		cfg_cs_CallCecilia = limit(int(rtvaln), 0, 1)
		continue
	}
	if ( instr(s, 0, "CS_disablesistermutation.") != (-1) ) {
		setconfig
		cfg_cs_DisableSisterMutation = limit(int(rtvaln), 0, 1)
		continue
	}
	// CS追加 ここまで

続いて*label_1168。
コンフィグメニューに新しい項目「拡張設定(CS)」を追加します。
ここで文字列配列sの末尾に空の文字列""がありますが、これは終端を検知する為に使用しているようなので削除しないでください。項目を増やした為、メニューの縦幅dyも430に広げておきます。

	if ( submenu == 0 ) {
		// CS追加(v1.2) CS用コンフィグをメニューに追加 メニュー窓の縦幅も広げる
		if ( jp ) {
			q = "オプション"
			s = "ゲームの設定", "画面と音の設定", "ネット機能の設定", "詳細な設定", "ゲームパッド", "メッセージとログ", "言語(Language)", "拡張設定1", "拡張設定2", "拡張設定1(MMA)", "拡張設定2(MMA)", "拡張設定(SSTP)", "拡張設定1(" + mmahsver + ")", "拡張設定2(" + mmahsver + ")", "拡張設定3(" + mmahsver + ")", "拡張設定(CS)", ""
		}
		if ( en ) {
			q = "Option"
			s = "Game Setting", "Screen & Sound", "Network Setting", "Detailed Setting", "Game Pad", "Message & Log", "Language", "EX Setting 1", "EX Setting 2", "EX Setting 1(MMA)", "EX Setting 2(MMA)", "EX Setting(SSTP)", "EX Setting 1(" + mmahsver + ")", "EX Setting 2(" + mmahsver + ")", "EX Setting 3(" + mmahsver + ")", "EX Setting(CS)", ""
		}
		dx = 370
//		dy = 410
		dy = 430
	}

同じく*label_1168の、今度は末尾。
デフォルトではサブメニューはNo.15「拡張設定3(MMAH)」までありますが、ここにNo.16として「拡張設定(CS)」のサブメニュー項目名を追加します。今回追加する3項目の名前は"釣りアニメ省略"、"セシリア降臨"、"妹肉による妹化の防止"とします。

// CS追加(v1.2) CS用コンフィグ サブメニュー
if ( submenu == 16 ) {
	if ( jp ) {
		q = "拡張設定(CS)"
		s = "釣りアニメ省略", "セシリア降臨", "妹肉による妹化の防止", ""
	}
	if ( en ) {
		q = "Ex Setting(CS)"
		s = "Skip fishing effect", "Advent Cecilia", "Disable sister mutation", ""
	}
	dx = 440
	dy = 450
}
// CS追加 ここまで

次は関数draw_config_menuの変更です。
この関数では各サブメニューの各項目の選択肢を定義しています。今回追加する3項目は全て「する/しない」の2択です。また、「する」を1、「しない」を0にしたいので「しない」の方から先に記述しています。

// CS追加(v1.2) CS用コンフィグ サブメニューの選択肢表示
if ( submenu == 16 ) {
	if ( cnt == 0 ) {
		s = lang("省略しない", "Disable"), lang("省略する", "Enable")
		mes s(cfg_cs_FastFishing)
	}
	if ( cnt == 1 ) {
		s = lang("降臨しない", "Disable"), lang("降臨する", "Enable")
		mes s(cfg_cs_CallCecilia)
	}
	if ( cnt == 2 ) {
		s = lang("防止しない", "Mutate"), lang("防止する", "DisableMutate")
		mes s(cfg_cs_DisableSisterMutation)
	}
}
// CS追加 ここまで

仕上げは関数change_config_menuの変更です。
コンフィグ画面での設定変更時、変数に反映する処理です。

// CS追加(v1.2) CS用コンフィグ
if ( submenu == 16 ) {
	snd 20
	if ( cs == 0 ) {
		cfg_cs_FastFishing = limit(1 - cfg_cs_FastFishing, 0, 1)
		valn = "CS_fastfishing.", str(cfg_cs_FastFishing)
		gosub *label_1159
	}
	if ( cs == 1 ) {
		cfg_cs_CallCecilia = limit(1 - cfg_cs_CallCecilia, 0, 1)
		valn = "CS_callcecilia.", str(cfg_cs_CallCecilia)
		gosub *label_1159
	}
	if ( cs == 2 ) {
		cfg_cs_DisableSisterMutation = limit(1 - cfg_cs_DisableSisterMutation, 0, 1)
		valn = "CS_disablesistermutation.", str(cfg_cs_DisableSisterMutation)
		gosub *label_1159
	}
}
// CS追加 ここまで
return

⑤コンフィグの動作確認

メニューに新しい項目が増えており、実際に切り替えることができたら成功です。omake_config.txtにも変更内容が反映されることを確認しておいてください。

コンフィグに新しい項目「拡張設定(CS)」が追加されました!
「拡張設定(CS)」のサブメニューです。
今はまだ3項目しかありません。
コンフィグを変更するとomake_config.txtにも反映されます。

念の為、変更した内容が実際にゲーム中に反映されることも確認しておいてください。

⑥終わりに

今回はゲーム本編には関係の無いシステム面の改造でお送りしました。
コンフィグ機能を追加すると何だか本格的にヴァリアントらしくなった気がしますね(別にヴァリアント開発講座とかではないのですが……)。

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