Elona改造講座 第12回(MMAhにSESTイツパロトルを移植)
Elona改造講座、第12回です。
今回はSESTイツパロトルをMMAhに移植してみます。
事前準備としてuser\graphicフォルダにSESTのイツパロトルの画像(char_453.bmp)をコピーしてください。
また、elmのセシリアの画像(chara_486.bmp)がある場合は削除しておいてください(元々セシリアの画像を入れてない人は削除の必要はありません)。
①画像サイズの定義
「chipc(3, 447)」で検索して、その下の行に以下を追加してください。これはイツパロトルの画像(画像ID:453)が縦2マスの大型キャラであることを定義するものです。
chipc(3, 453) = inf_tiles * 2, inf_tiles + 16
下の画像のようになれば成功です。画像ではSESTの願いの神(画像ID:454)やPlusのヤカテクト&イツパロトル(画像ID:495~496)の画像サイズの定義も追加しています。後々必要になるかもしれないので念の為にこれらも追加しておきましょう。
②キャラ定義の追加
イツパロトル(ID:367)のキャラ定義を追加します。セシリア(ID:354)や頑嬢(ID:363)と同じ要領で、ソースコード中にキャラ定義を追加します。
キャラ定義はSESTから持ってきましょう。早速SESTを逆コンパイルして、ソースコード内を「"《元素のイツパロトル》"」で検索。すぐに見つかってめでたしめでたし……と言いたいところですがここで1つ問題が。
どうやらSESTでは逆コンパイルの都合か変数名が復元されないようで、
全て var_XXXX という名前に置き換えられてしまっています。
if ( var_85 == 367 ) {
if ( var_83 == 16 ) {
if ( var_86 == 3 ) {
return 6
}
if ( var_86 == 5 ) {
return 0
}
if ( var_86 == 6 ) {
return 100
}
if ( var_86 == 2 ) {
if ( var_77 ) {
return "《元素のイツパロトル》"
}
else {
return "<Itzpalt>"
}
}
if ( var_86 == 10 ) {
return var_3112(357)
}
if ( var_86 == 8 ) {
return "" + "/god/"
}
return 0
}
if ( var_83 == 2 ) {
var_87 = "god"
var_83 = 2
gosub *label_1405
var_2553 = 453
return
}
if ( var_83 == 3 ) {
var_82(27, var_243) = 367
if ( var_328 != 0 ) {
var_82(38, var_243) = var_328
}
else {
var_82(38, var_243) = 400
}
if ( var_1384 != 0 ) {
var_82(38, var_243) = var_1384 * (100 + var_82(38, var_243) * 2) / 100
}
var_82(13, var_243) = -1
var_82(202, var_243) = 1
var_82(207, var_243) = 60
var_82(208, var_243) = 2
var_82(209, var_243) = 10
var_1930 = 0
var_82(215, var_243) = -1, 419, 420, 421
var_82(220, var_243) = 904
var_82(212, var_243) = 14
if ( var_77 ) {
var_88(0, var_243) = "《元素のイツパロトル》"
}
else {
var_88(0, var_243) = "<Itzpalt>"
}
var_82(9, var_243) = 0
var_82(69, var_243) = 0
ocbitmod 13, var_243, 1
var_87 = "god"
var_83 = 3
gosub *label_1405
var_87 = "wizard"
var_83 = 3
gosub *label_1406
var_82(8, var_243) = 0
var_82(7, var_243) = 453
var_329 = 6
var_1747 = 1
return
}
if ( var_83 == 4 ) {
if ( var_1751 == 0 ) {
var_819 = 676
}
var_1745 = 1
return
}
return 0
}
ooと見比べつつ気合で解読していきましょう。キャラ定義を何度もじっくり見てきた人なら元の変数が類推できるはずです。上記の例だとvar_82がcdata、var_243がrcなどは比較的分かりやすいでしょうか? 調べた限りで分かった主要な対応関係を書いておきます(SEST 2020/12/20版の場合の例)。
数値・文字列・関数名などは復元されるようなので、それらも手掛かりにしましょう。頑張って変数名を類推した結果がこちらになります。何やら見慣れたコードになりましたね。
※言語設定による分岐はlang関数を使う形に書き換えています。
if ( dbid == 367 ) {
if ( dbmode == 16 ) {
if ( dbspec == 3 ) {
return 6
}
if ( dbspec == 5 ) {
return 0
}
if ( dbspec == 6 ) {
return 100
}
if ( dbspec == 2 ) {
return "" + lang("《元素のイツパロトル》", "<Itzpalt>")
}
if ( dbspec == 10 ) {
return cobjlvorg(357)
}
if ( dbspec == 8 ) {
return "" + "/god/"
}
return 0
}
if ( dbmode == 2 ) {
dbidn = "god"
dbmode = 2
gosub *label_1405
cpicref = 453
return
}
if ( dbmode == 3 ) {
cdata(27, rc) = 367
if ( initlv != 0 ) {
cdata(38, rc) = initlv
}
else {
cdata(38, rc) = 400
}
if ( voidlv != 0 ) {
cdata(38, rc) = voidlv * (100 + cdata(38, rc) * 2) / 100
}
cdata(13, rc) = -1
cdata(202, rc) = 1
cdata(207, rc) = 60
cdata(208, rc) = 2
cdata(209, rc) = 10
creaturepack = 0
cdata(215, rc) = -1, 419, 420, 421 // 3属性ボルト
cdata(220, rc) = 904 // エンチャント封印
cdata(212, rc) = 14
cdatan(0, rc) = lang("《元素のイツパロトル》", "<Itzpalt>")
cdata(9, rc) = 0
cdata(69, rc) = 0
ocbitmod 13, rc, 1
dbidn = "god"
dbmode = 3
gosub *label_1405
dbidn = "wizard"
dbmode = 3
gosub *label_1406
cdata(8, rc) = 0
cdata(7, rc) = 453
fixlv = 6
cspecialeq = 1
return
}
if ( dbmode == 4 ) {
if ( nospartifact == 0 ) {
eqweapon1 = 676 // エレメンタルスタッフ
}
eqtwohand = 1
return
}
return 0
}
更にここからMMAhに存在しない技能や処理をコメントアウトします。ジャンプ先ラベルの指定もMMAh用に書き換えます(ジャンプ先ラベルはお使いのヴァリアントのバージョンに合わせてください)
if ( dbid == 367 ) {
if ( dbmode == 16 ) {
if ( dbspec == 3 ) {
return 6
}
if ( dbspec == 5 ) {
return 0
}
if ( dbspec == 6 ) {
return 100
}
if ( dbspec == 2 ) {
return "" + lang("《元素のイツパロトル》", "<Itzpalt>")
}
//if ( dbspec == 10 ) {
// return cobjlvorg(357)
//}
if ( dbspec == 8 ) {
return "" + "/god/"
}
return 0
}
if ( dbmode == 2 ) {
dbidn = "god"
dbmode = 2
gosub *label_1116
cpicref = 453
return
}
if ( dbmode == 3 ) {
cdata(27, rc) = 367
if ( initlv != 0 ) {
cdata(38, rc) = initlv
}
else {
cdata(38, rc) = limitmax(400, cfg_mmah_maxlevel)
}
if ( voidlv != 0 ) {
cdata(38, rc) = limit(voidlv * (50 + cdata(38, rc)) / 50, 1, cfg_mmah_maxlevel)
}
cdata(13, rc) = -1
cdata(202, rc) = 1
cdata(207, rc) = 60
cdata(208, rc) = 2
cdata(209, rc) = 10
creaturepack = 0
cdata(215, rc) = -1, 419, 420, 421 // 3属性ボルト
//cdata(220, rc) = 904 // エンチャント封印
cdata(212, rc) = 14
cdatan(0, rc) = lang("《元素のイツパロトル》", "<Itzpalt>")
cdata(9, rc) = 0
cdata(69, rc) = 0
ocbitmod 13, rc, 1
dbidn = "god"
dbmode = 3
gosub *label_1116
dbidn = "wizard"
dbmode = 3
gosub *label_1117
cdata(8, rc) = 0
cdata(7, rc) = 453
fixlv = 6
cspecialeq = 1
return
}
if ( dbmode == 4 ) {
if ( nospartifact == 0 ) {
eqweapon1 = 676 // エレメンタルスタッフ
}
eqtwohand = 1
return
}
return 0
}
完成です。これを凄腕の黒天使(ID:365)の下に追加しましょう。画像のようになれば成功です。
③降臨処理の追加
願いでSESTイツパロトルを降臨できるようにします。セシリアやすくつ捕獲玉の時と同じ要領で、願いの対象を追加します。
セシリアの降臨処理の下に、次の処理を追加してください(セシリアの降臨を追加してない人の場合はブラックプチの下に追加)。
// 独自拡張 SEST追加キャラの降臨(イツパロトル)
if ( inputlog == "イツパロトル" | inputlog == "itzpalt" ) {
txt_select -1, lang("「汝の召喚に応えよう、定命の者よ」", cnvtalk("Very well. I will go down to you, mortal.")), "", "", "", "", "", "", "", ""
flt
characreate -1, 367, cdata(1, 0), cdata(2, 0)
throwsstpevent "AdventGod", rc, inputlog, 0
adventothergod "itzpalt"
return
}
MMAhにはPlusイツパロトル(ID:484)の降臨処理が用意されている(ただしPlus拡張なので通常のゲーム中では実行されない)ので、それを参考にしてみるのも良いでしょう。画像のようになれば成功です。
④動作確認
F5キーの願いで"イツパロトル"を願ってみましょう。イツパロトルが降臨すれば成功です。Lv400の種族神の魔法使いになっているはずです。
⑤セシリアとの競合
(この章はセシリアを使用する人にだけ関係する話です)
最初に削除したセシリアの画像(chara_486.bmp)を元に戻してみましょう。この状態でイツパロトルを降臨させてみてください。どうなりましたか? 恐らくイツパロトルの下半身がセシリアになった状態で出現すると思います。
これはキャラデータの破損やバグの類ではなく、メモリ上にロードされた画像データがイツパロトルの下半分とセシリアで重複した領域を指している為に発生する現象です。イツパロトルの画像IDは453、セシリアの画像IDは486で、Elonaのキャラ画像(character.bmp)は横33キャラ分の為、ちょうど真下に来るわけですね。しかも上側に来るイツパロトルは大型キャラ。なんと運の悪い……
elmとSESTの両方との互換性を保ちつつ、両方のキャラを正常に表示する方法は……分かりません!(ここでの「互換性」とはこちらで生成したセシリアをelmに連れ込んだり、イツパロトルをSESTに連れ込んだりした場合。あるいはその逆にelmやSESTからこちらに連れてきた場合にグラフィックが正常のまま、という意味です)
互換性を捨てて良いのならセシリアかイツパロトルのどちらかの画像を別の画像IDを指すようにすれば対処できます。例えばSESTイツパロトルの画像(本来は453)を、Plusイツパロトル(496)のものに差し替える等です。その場合の変更箇所は2箇所になります。
dbmode == 2のここと、
if ( dbmode == 2 ) {
dbidn = "god"
dbmode = 2
gosub *label_1116
cpicref = 496 // 453 // 画像をPlus版に差し替え
return
}
dbmode == 3のここですね。
dbidn = "wizard"
dbmode = 3
gosub *label_1117
cdata(8, rc) = 0
cdata(7, rc) = 496 // 453 // 画像をPlus版に差し替え
fixlv = 6
cspecialeq = 1
降臨させてみましょう。ちゃんとchara_496.bmpの画像が表示されたでしょうか?
もし上半分しか表示されないという人は①の画像サイズの定義のところに以下を追記したかどうかを確認してください。
chipc(3, 496) = inf_tiles * 2, inf_tiles + 16
⑥終わりに
SESTの変数名が自動復元できなくてまず出端をくじかれ、割とすんなり解読できたと思ったら今度は画像が重複して……とやってることは簡単な割にトラブルの多い回でした。
次回は今回と同じ要領でSESTジュアも追加してみましょう。あとせっかくイツパロトルを追加したので撃破時に称号を獲得できるようにもしてみます。