見出し画像

Elona改造講座 第15回(MMAhに汐路のセリア全機能を実装)

Elona改造講座、第15回です。
最終回の今回はSESTの追加神「汐路のセリア」の全機能をMMAhで使えるようにしてみましょう。妹みたいな色のwikiの信仰のページを見てみるとこんな記述があります。

カスタムゴッドを利用して実装されているので、該当ファイルを移せば他のヴァリアントでも信仰できる。
ただし一部の専用効果が正しく機能しない場合があるため注意。

特殊効果付きカスタムゴッドの説明

この記述にある通り「汐路のセリア」もカスタムゴッドの一種なので、SESTの「Serria」フォルダをuserフォルダの中に持ってくるだけで基本的な機能は使えます。ここで言う基本的な機能とは
 ・捧げ物
 ・能力ボーナス
 ・ご褒美
 ・謎の貝等の大半の台詞
のことです。
逆に一部の専用効果とは上記以外の効果のことになります。これらはソース中で信仰中の神の名前(汐路のセリアの場合は"serria")を直接参照して実装されています。財のイナリを例にすると「天候が雨になりやすくなる」がこの専用効果に該当します。
("inari"で検索してみるとよく分かるかと思います)
 
下準備として「Serria」フォルダをuserフォルダにコピーしておきましょう。それとElonaの内部データに関する知識として
 gdata(80)は荷車に現在積載中の重量
 gdata(82)は荷車の限界重量
 godcheck()は信仰中の神の名前(英短縮名)を取得する関数
の3点を頭に入れておきましょう。

Serriaフォルダをuserフォルダにコピーしました

①荷車限界3倍効果の移植

まずはセリアの目玉効果とも言うべき荷車限界3倍の効果を移植します。
SESTのソースを"serria"で検索してみましょう。
全部で5箇所ヒットするはずなので、1つずつ解析していきまう
 
まずは1箇所目の"serria"。
これは荷車重量超過時に実際に速度を低下させる処理ですね。oo系列では荷車重量により段階的に速度が低下する形式に変更されているので計算式がちょっと複雑になっています。ですが「信仰中の神がセリアの場合にvar_90(82)を3倍して計算している」ので、荷車重量に関する処理との目星は付くでしょう。

荷車重量による速度低下処理(SEST側)

MMAhの荷車重量による速度低下処理は本家Elonaのままなので、SESTのような分岐はありません。単純にgdata(80)とgdata(82)を比較するだけです。追加すべき箇所はソース中を「gdata(82)」で検索すると見つかるはずです。
(バージョンによるとは思いますが、恐らく一番最初にヒットするはず。関数ride_beginの少し上です)
 
ここを

if ( mdata(6) == 1 | mdata(6) == 4 ) {
	if ( gdata(80) > gdata(82) ) {
		cdata(39, 0) -= 25 + 25 * (gdata(80) / (gdata(82) + 1))
	}
}

このように書き換えます。

// 荷車重量による速度低下 セリア信仰時は荷車限界3倍
if ( mdata(6) == 1 | mdata(6) == 4 ) {
	if ( godcheck() == "serria" ) {
		if ( gdata(80) > gdata(82) * 3 ) {
			cdata(39, 0) -= 25 + 25 * (gdata(80) / (gdata(82) * 3 + 1))
		}
	}
	else {
		if ( gdata(80) > gdata(82) ) {
			cdata(39, 0) -= 25 + 25 * (gdata(80) / (gdata(82) + 1))
		}
	}
}

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

荷車重量による速度低下処理をMMAhに移植しました

2箇所目の"serria"。
ここは荷車重量超過のメッセージを表示する箇所ですね。oo系列の仕様変更でメッセージが3段階になっていますが、セリア信仰中のみgdata(82)を3倍して計算するのは同じです。

荷車重量超過メッセージ(SEST側)

ここもMMAhへの移植時は場合分けが不要になる為、ずっとシンプルなコードになります。追加するべき箇所は「荷車の重量超過でかなり鈍足になっている」で検索すればすぐに見つかるでしょう。
ここを

if ( gdata(80) > gdata(82) ) {
	if ( adata(0, gdata(20)) == 1 | adata(0, gdata(20)) == 4 ) {
		msgtemp += lang("荷車の重量超過でかなり鈍足になっている! ", "The weight of your cargo burdens your traveling speed.")
	}
}

このように書き換えます。

// 荷車の重量超過 セリア信仰時は荷車限界3倍
if ( godcheck() == "serria" ) {
	if ( gdata(80) > gdata(82) * 3 ) {
		if ( adata(0, gdata(20)) == 1 | adata(0, gdata(20)) == 4 ) {
			msgtemp += lang("荷車の重量超過でかなり鈍足になっている! ", "The weight of your cargo burdens your traveling speed.")
		}
	}
}
else {
	if ( gdata(80) > gdata(82) ) {
		if ( adata(0, gdata(20)) == 1 | adata(0, gdata(20)) == 4 ) {
			msgtemp += lang("荷車の重量超過でかなり鈍足になっている! ", "The weight of your cargo burdens your traveling speed.")
		}
	}
}

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

荷車重量超過メッセージをMMAhに移植しました

3箇所目の"serria"。
関数modpietyの中ですが、ここはMMAhでは方式が異なる為、個別の神の名前を記述する必要はありません。従って変更は不要(のはず……)です。

神の名前を1柱ずつチェックしています(SEST側)

参考までにMMAhのmodpietyを掲載しておきます。

MMAhでは関数の使用が異なっているようです

4箇所目の"serria"。
表示している文字列から察するにここはキャラシート画面の表示処理でしょう。ここは単純にセリア信仰時に3倍して表示するだけです。

キャラシート表示時の荷車重量3倍(SEST側)

MMAhに移植する時も同様、セリア信仰時に3倍して表示するだけです。
追加するべき箇所は " Turns" や " Days" などで検索するとすぐに見つかることでしょう。
この1行を

s = "" + cnvweight(gdata(80)), cnvweight(gdata(82)), cnvweight(cdata(64, cc)) + " " + cnveqweight(cc), cnvrank(gdata(1)) + lang("階相当", " Level")

このように書き換えます。

// 荷車重量と荷車限界の表示 セリア信仰時は荷車限界3倍
if ( godcheck() == "serria" ) {
	s = "" + cnvweight(gdata(80)), cnvweight(gdata(82) * 3), cnvweight(cdata(64, cc)) + " " + cnveqweight(cc), cnvrank(gdata(1)) + lang("階相当", " Level")
}
else {
	s = "" + cnvweight(gdata(80)), cnvweight(gdata(82)), cnvweight(cdata(64, cc)) + " " + cnveqweight(cc), cnvrank(gdata(1)) + lang("階相当", " Level")
}

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

キャラシート表示時の荷車重量3倍処理をMMAhに移植しました

最後の5箇所目の"serria"。
ここは恐らくセリア信仰時に盗賊団を回避する為の処理でしょう。盗賊団との遭遇時、セリア信仰時は7/8の確率で無効化するようです。

盗賊団を回避する処理(SEST側)

移植する箇所を探すのもやや難しいです。"の心はすこし癒された。"で検索して3個目にヒットした箇所の40~50行ほど下を探すと見つかるかと思います。
この部分を

if ( rnd(220 + difficulty(0) * 10 - limit(gdata(80) * 150 / (gdata(82) + 1), 0, 210 + difficulty(0) * 10)) == 0 ) {
	encounter = 4
}

このように書き換えます。

// セリア信仰時は7/8の確率で盗賊団との遭遇を回避
if ( rnd(220 + difficulty(0) * 10 - limit(gdata(80) * 150 / (gdata(82) + 1), 0, 210 + difficulty(0) * 10)) == 0 ) {
	encounter = 4
	if ( godcheck() == "serria" ) {
		if ( rnd(8) ) {
			encounter = 0
		}
	}
}

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

盗賊団を回避する処理をMMAhに移植しました

SESTを"serria"で検索してヒットした場所はこれで全てです。……が、MMA系列には他にもまだ変更すべき点があります。帰還時の重量制限です。omakeやMMA系列では「荷車限界の2倍まで」という制限があるので、ここにもセリアの3倍効果を追加しましょう(oo系列では帰還時に交易品が消滅する仕様の為、帰還時の荷車重量にこのような制限はありません)。
 
変更箇所は2箇所。まずはここを

if ( chatval == 502 ) {
	if ( dbg_noweight == 0 & cdata(45, 0) >= 4 | gdata(80) > gdata(82) * 2 ) {
		buff = lang("荷物が重過ぎる" + _yo(), "Sorry, overweight.")
		continue
	}

このように変更しましょう。

if ( chatval == 502 ) {
	// 帰還時の荷車重量制限 セリア信仰時は荷車限界3倍
	if ( godcheck() == "serria" ) {
		cargo_serria_multiply = 3
	}
	else {
		cargo_serria_multiply = 1
	}
	if ( dbg_noweight == 0 & cdata(45, 0) >= 4 | gdata(80) > gdata(82) * 2 * cargo_serria_multiply ) {
		buff = lang("荷物が重過ぎる" + _yo(), "Sorry, overweight.")
		continue
	}

次にここを

if ( dbg_noweight == 0 & (cdata(45, 0) >= 4 | gdata(80) > gdata(82) * 2 ) ) {
	txt_select -1, lang("どこからか声が聞こえた。「悪いが重量オーバーだ」", "Someone shouts, \"Sorry, overweight.\""), "", "", "", "", "", "", "", ""
	flagaa_1(140) = 0
	gosub *label_1183
	if ( stat == 2 ) {
		return 2
	}
	if ( stat == 0 ) {
		return 0
	}
	gosub *label_1182
	return stat
}

このように変更しましょう。

// 帰還時の荷車重量制限 セリア信仰時は荷車限界3倍
if ( godcheck() == "serria" ) {
	cargo_serria_multiply = 3
}
else {
	cargo_serria_multiply = 1
}
if ( dbg_noweight == 0 & (cdata(45, 0) >= 4 | gdata(80) > gdata(82) * 2 * cargo_serria_multiply) ) {
	txt_select -1, lang("どこからか声が聞こえた。「悪いが重量オーバーだ」", "Someone shouts, \"Sorry, overweight.\""), "", "", "", "", "", "", "", ""
	flagaa_1(140) = 0
	gosub *label_1183
	if ( stat == 2 ) {
		return 2
	}
	if ( stat == 0 ) {
		return 0
	}
	gosub *label_1182
	return stat
}

例として「悪いが重量オーバーだ」の方の変更後の例を掲載しておきます。この画像のようになれば成功です。

帰還時の荷車重量制限も3倍にしました
(oo系列では帰還時に交易品が消滅する為、この処理はMMA系列でのみ必要になります)

②動作確認(荷車限界)

それでは荷車限界重量を3倍にする効果の動作確認を行いましょう。まずは無信仰状態になっておきましょう(改宗時の天罰による速度低下が確認の邪魔になる為)。次に「祭壇 汐路のセリア」を願ってセリアの祭壇を生成すれば準備はOKです。
 
このキャラクターは無信仰状態だと荷車限界は230sです。そこに490.5sもの交易品を積み込んでいる為、当然ながら重量超過により速度が大幅に低下してしまいます。

荷車限界230sに対して490.5sも詰んでいます
(重量超過で大幅に速度低下……)

次にこの状態でセリアを信仰してみましょう。信仰の効果で荷車限界が690sになる為、今度は490.5sでもへっちゃらなはずです。

セリア信仰により荷車限界が3倍の690sになりました
(重量範囲内なので速度低下なし!)

流石にこの状態でも690sを超えると超過してしまいますが……

流石に690sを超えるのは無理です

③宝玉の効果の移植

続いてセリアの宝玉「導きの宝玉」を使用時の効果を移植しましょう。SESTのソースを「大丈夫、僕が必ず旅路を導くから」で検索すると該当の処理が見つかります。エフェクトID:3003を新規追加してそこに処理を記述しているようです。効果自体はルルウィ像に近いものになっています。var_90(17)が天候の表す変数gdata(17)に相当すると予想されます。

セリアの宝玉の効果(SEST側)

移植する箇所について。
SEST方式(エフェクトID:3003を新規追加)でも構わないのですが、せっかくMMA系列なのだからフラメアの宝玉と同じ方式にしてみましょう。
"Plamja's gem stone"で検索すると宝玉(カスタムアイテム含む)の効果を定義している箇所が見つかるはずです。ここにセリアの宝玉の名称"storn of guidance"を条件にして、セリアの宝玉の効果を記述します。
(宝玉の名称はカスタムアイテムのファイル名を参照)
 
ここを

if ( inv(3, ci) == 743 ) {
	if ( equalsitem(ci, "Plamja's gem stone") ) {
		removeallfire
	}
}

こんな感じに変更しました。コメントも適宜追加してみました。

// カスタムアイテムの宝玉
if ( inv(3, ci) == 743 ) {
	// フラメアの宝玉
	if ( equalsitem(ci, "Plamja's gem stone") ) {
		removeallfire
	}
	// セリアの宝玉
	if ( equalsitem(ci, "storn of guidance") ) {
		// 晴れorエーテルの場合はクールタイムを0にする それ以外なら天候を晴れにする
		if ( gdata(17) == 1 ) {
			txt_select -1, lang("セリア「……残念だけど、この風は僕の手では止められないんだ」", "A calm voice echoes, " + cnvtalk("Unfortunately, I can't stop the ethereal wind.")), "", "", "", "", "", "", "", ""
			inv(9, ci) = 0 // クールタイムを0にする
		}
		else : if ( gdata(17) == 0 ) {
			txt_select -1, lang("セリア「……今はまだ僕の出番じゃないみたいだね」", "A calm voice echoes, " + cnvtalk("well, It's not the turn yet.")), "", "", "", "", "", "", "", ""
			inv(9, ci) = 0 // クールタイムを0にする
		}
		else {
			preweather = gdata(17)
			txt_select -1, lang("セリア「大丈夫、僕が必ず旅路を導くから」", "A calm voice echoes, " + cnvtalk("Leave it to me.")), "", "", "", "", "", "", "", ""
			txt_select -1, lang("天候が変わった。", "The weather changes."), "", "", "", "", "", "", "", ""
			gdata(17) = 0 // 天候を晴れにする
			envonly = 1
			gosub *label_0082
			if ( preweather != gdata(17) ) {
				throwsstpevent "WeatherChanged", 0, _weather(preweather), 0
			}
		}
	}
}
// カスタムアイテムの宝玉 ここまで

元からあったフラメアの宝玉の処理(removeallfireを呼び出す処理)の下にセリアの宝玉の処理を新規追加しています。晴れorエーテル風の時には効果が無い為、クールタイムをゼロクリアしてくれているみたいですね。なお「envonly = 1」とその後の「gosub *label_0082」も忘れないでください。
これが無いと晴れたにもかかわらず雨音がしたままになってしまいます(経験談)。

MMAhにセリアの宝玉の効果を移植しました

④動作確認(宝玉の効果)

セリアの宝玉の動作確認をしてみましょう。天候が雨・雷雨・雪のいずれかの場合、即座に晴れになるはずです。雨音が消えたことも確認しておいてください。

雨・雷雨・雪の時に使うと晴れになります

晴れorエーテル風の時は使用できず、専用のメッセージが表示されるだけです。この場合にはクールタイムにも入りません。

晴れorエーテル風の時は使用できません

⑤使徒「ペリカン」の特殊効果の移植

最後にセリアの使徒「ペリカン」の特殊効果を移植します。基本的には本家Elonaの妖精さんと同系統の効果(生成するのが種か交易品かの違い)ですが、発生確率が1/5だったり、荷車が操作できない場所では給料箱に送られたりなど違いも多いです。SESTではこのようになっています。

SESTでのペリカンの特殊効果です
(妖精さんの特殊効果のすぐ下に書かれていますね)

MMAhに移植する場合はこんな感じでいかがでしょうか? 本来は荷車操作不可のマップの場合に給料箱に送る処理もあるのですが、これは省略しています。というのも給料箱の中身はshop4.s2というセーブファイル(gzip圧縮)に格納されている為、gzip解凍→アイテム生成→gzip圧縮という手順を踏む必要が出てきます。セーブデータの直接編集は本講座の範囲(と私の現在の技量)を超えている為、ここでは荷車操作不可のマップであっても必ずペリカンの足元に生成するようにしています。
(荷車操作不可のマップでも拾うことだけはできますのでご安心ください)

// CNPC(343)の食事後の処理
if ( cdata(27, cc) == 343 ) {
	// ペリカンの場合、交易品を生成  ※SEST追加キャラ
	if ( userdatan(1, cdata(157, cc)) == "pelican" | userdatan(1, cdata(157, cc)) == "ペリカン" ) {
		if ( (nutrition >= 2000) & (rnd(5) == 0) ) {
			cibk = ci
			flt
			flttypemajor = 92000 // 交易品
			// 交易品の生成 荷車操作の可・不可によらず必ず足元に生成
			itemcreate -1, 0, cdata(1, cc), cdata(2, cc), rnd(3) + 1
			txtef 9
			txt_select cc, lang("「クェー」" + name(cc) + "は" + itemname(ci, 1) + "をどこからともなく持ってきた。", "「Quuuu」" + name(cc) + " brought the " + itemname(ci, 1) + "."), "", "", "", "", "", "", "", ""
			ci = cibk
		}
	}
	// ペリカン ここまで
}
// CNPCの食事後の処理 ここまで

追加場所は妖精さんの食後処理のすぐ下で良いでしょう。妖精さんの食後処理は「げふぅ」で検索するとすぐに見つかります。画像のようになれば成功です。

MMAhにペリカンの特殊能力を移植しました

⑥動作確認(ペリカンの食後効果)

信仰を深めてペリカンを仲間にしましょう。適当に時間を潰して腹を空かせたら食料を渡してあげてください。確率で交易品を生成してくるはずです(生成確率は1/5なので気長にリロードを繰り返しましょう)。

ペリカンが食後に交易品を生成してくれました!

⑦終わりに

今回は最終回ということで変更点が沢山ありましたね。
お疲れ様でした!
 
今回は特定の名前を持つCNPCに食後の特殊能力を追加しましたが、これと同じ要領で白金ガチョウの能力も移植できそうですね。生成するアイテムはプラチナ硬貨(ID:55)で固定ですし、荷車操作可否のチェックも不要なのでずっと簡単そうです。
 
本当なら盗賊団の出現率低下も確認したいところですが、元がランダムイベントなうえにセリア効果の発動も確率依存なので確認が困難です。どうしても確認したい人はこんな感じにメッセージを表示してみましょう。
txt_selectの代わりにdebugmsgを使ってもOKです。その場合はオプションから「デバッグ情報の表示」をONにしておきましょう。

if ( rnd(220 + difficulty(0) * 10 - limit(gdata(80) * 150 / (gdata(82) + 1), 0, 210 + difficulty(0) * 10)) == 0 ) {
	encounter = 4
	if ( godcheck() == "serria" ) {
		if ( rnd(8) ) {
			encounter = 0
			txt_select -1, lang("※セリア打消成功 ", " "), "", "", "", "", "", "", "", ""
		}
		else {
			txt_select -1, lang("※セリア打消失敗 ", " "), "", "", "", "", "", "", "", ""
		}
	}
}

⑧余談:荷車操作の可否の判定

検証中に気付いたことですが、荷車操作の可否の判別はcargocheck関数で行っているようです。

#deffunc cargocheck
	if ( refitem(inv(3, ci), 10, ci) == 0 ) {
		return 1
	}
	if ( mdata(6) != 1 & mdata(6) != 5 & mdata(6) != 3 & mdata(6) != 4 & mdata(6) != 6 & mdata(6) != 2 ) {
		msgdup++
		txt_select -1, lang("荷車の荷物は街か野外でしか操作できない。", "You can only use cargo items on the surface."), "", "", "", "", "", "", "", ""
		snd 27
		return 0
	}
	return 1

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