このページはイニシエダンジョン解析についてのメモの置き場です。
----
*実行ツリー予想 [#w58d4fc5]
Main.as frame3()
↓
Main.as firstSet() //ここでaccessSetで["first",this.myID + "<>" + this.playData.save_data.ID + "<>" + this.playData.save_data.passCode];が渡されて....
↓
Main.as accessCheck() //ここでaccessにfirstが渡される
↓
AccessClass.as access() //URLRequestEventがCOMPLETEで下へ
↓
AccessClass.as loaderCompleteFunc() //ここの引数のEventにエラーがなければ下へ
↓
Main.as accessEnd() //↑から渡されるparam1はURLLoaderのデータ(鯖から送られてくるデータ)のmodeを参照//ここの引数でparam1がfirstだと↓に行く
↓
Main.as TitleShow()
↓

requestでfirstとか返せれば復元できる?

メモ
・this.Main.urlを任意のurlで書き換えてinishie.cgiを用意すれば動かせるかも
localで動かすとflash SecurityError: Error #2028: Local-with-filesystem SWF fileになる

↑
原因は、ファイルアクセスのセキュリティエラーなので、
Security.loadPolicyFile("http://inishie-dungeon.com/crossdomain.xml");を
Security.loadPolicyFile("C:ローカルパス");と書き換えて、
そのxmlファイルの中身を
|<cross-domain-policy>
| <allow-access-from domain="*" />
|</cross-domain-policy>
にすればいけます。

|>「requestでfirstとか返せれば復元できる?」
「inishie.cgi」というファイルにアクセスして"first"などを返してもらうのが本来の処理ですが、
自分の場合は、inishie.cgiで返した文字列をflash側が正しく読み込んでくれなかったので、
event.COMPLETEを発生させる為だけの適当な文字列を返すだけのcgiファイルを作り、
"first"などの文字列を返す処理は、ソースコード内に書くことによって回避しました。

ダンジョン1Fに行くまでの手順は、確か、
"first"→"charamake"→"gamestart"→"mapload"です。

~
*メモ [#b1f51c6f]
ザイーガガチャはショップのアイテムセットとオプションセットの処理で代用した物って本来の挙動に近いんだろうか?
代用した物で許容できるなら、AccessClassのnewloaderCompleteFunc内にあるザイーガイベントの処理部分をこんな感じにしてしまえば
それっぽくはなるはず……自分の環境で試してみましたが、他に試してくれる人が居てくれると幸いです。
問題無さそうならスクリプトを差し替えても構いません。
           else if(this.loader.data.eventtype.substr(0,6) == "zaeega")
            {
               i = 0;
               var ilen:* = 0;
               this.loader.data.mode = "zaeega";
               this.loader.data.zcnt = this.Main.myPlayScreen.town_data.zaeega_cnt;
               if(this.Main.myPlayScreen.town_data.zaeega_cnt == 0)
               {
                  var itemlist:* = this.Main.myItemData.getDropItems(this.Main.myPlayScreen,this.Main.myPlayScreen.max_floor,this.Main.myPlayScreen.itemRand.nextInt(100));
                  if(this.Main.mso.data.quest.split("/")[8].split(",")[0] == 1)
                  {
                     itemlist.push(800);
                  }
                  else if(this.Main.mso.data.quest.split("/")[8].split(",")[0] == 2)
                  {
                     itemlist.push(800);
                     itemlist.push(820);
                  }
                  ilen = itemlist.length;
                  this.Main.myPlayScreen.town_data.zaeega_item_list = [];
                  var ooql:* = this.Main.myPlayScreen.old_quest_lv[0];
                  this.Main.myPlayScreen.old_quest_lv[0] = 7;
                  while(i < 10)
                  {
                     var itemno:* = itemlist[this.Main.myPlayScreen.itemRand.nextInt(ilen)];
                     var ditemdata:* = this.Main.myItemData.getItemData(itemno);
                     var itemop:* = this.Main.myPlayScreen.myItemOption.optionSet(itemno,this.Main.myPlayScreen.itemRand.nextInt(2) + 4,this.Main.myPlayScreen.itemRand);
                     this.Main.myPlayScreen.town_data.zaeega_item_list.push(ditemdata + itemop);
                     i++;
                  }
                  this.Main.myPlayScreen.old_quest_lv[0] = ooql;
               }
               this.loader.data.item = this.Main.myPlayScreen.town_data.zaeega_item_list[this.loader.data.zcnt];
               this.loader.data.zcnt++;
            }
ItemOptionクラスoptionSetメソッド内にthis.myparent.old_quest_lv[0]で出てくるオプションのクオリティを変える処理がある…パっと見一番いいオプションのクオリティはクリア後でも4%になってるっぽい?
一時的にここを最大の7(クリア後)に変えてオプションを定義した後戻す処理を組み込んでみました
ItemIDが存在しないと召喚(多分デコイとかも)によって色々消えるのでItemIDの生成処理を探して追加(これでドロップアイテムのItemDataが"ItemNo,ItemId,Option"の本来の形式になったはず)
まちの鍛冶屋・魔法屋の販売アイテムリストを流用しているので、クエストをクリアしていてもリングやアミュレットが出てこない設定だったことが判明。クエスト状況を参照し、別途リングやアミュレットをアイテムリストに追加する処理を入れました。


~
*メモ [#w4be49ff]
タウンポータルに関するセーブデータの場所の情報提供感謝します。
階段処理でタウンポータル関連の記述がない気もしますが、初期地点0,0にキャラ配置される(上り階段も配置されるから多分大丈夫)と信じてあまり修正しない方向で、
%% タウンポータルで帰還した際にquest[36]="0,0"にされてたのでその部分を消し、ポータルを消すかどうかのフラグを設定して階段処理の際に階段を上った場合はフラグを折り、後でフラグを確認してquest[36]="0,0"を入れるかどうかを決定するように修正%%
%%タウンポータルの行き先がundefinedになってたのはinishieFirst.xmlのfloornameに第4引数が無かった為、param1.Main.floorName.name2をセットすることができなかったのが原因%%
取り消し線の部分はとりあえずの対処が完了したので一旦取り消し

~
*メモ [#j0aba2fb]
セーブデータの全体的な構造について
自由に書き換えたく調べてみました
まだ数回しか試せておらず、間違っているかもしれませんので書き換える際はバックアップを忘れずにしてください

一番最初に来る構造については
|RIGHT:BGCOLOR(#171717):|||c
|オフセット|サイズ|内容|例や説明|h
|0x0|4|不明|2byte目に0xBFが必ず来る?|
|0x4|0x2|Size|ファイル全体のサイズ-0x6byteの値が入る|
|0x6|0x4|TCSO|TCSOの文字が来る|
|0xA|0x7|不明|2byte目に0x4が入っているがそれ以外は分からない|
|0x11|0x1|SaveLen|セーブデータ名の長さが入る|
|0x12|SaveLen|文字列|セーブデータ名が入る|
|0x12+SaveLen|0x4|不明|4byte目に0x3が入っている|

各種データの構造については
|RIGHT:BGCOLOR(#171717):|||c
|オフセット|サイズ|内容|例や説明|h
|0x0|1|n*2 + 1|データの文字列の長さを示す値が入る。itemの場合、4文字なので4*2+1=9|
|0x1|n|文字列|データの文字列が入る|
|0x1+n|1|不明|基本的に0x6が来る、しかしdropRandIndexは0x4が来る?データの型を示しているかもしれない|
|0x2+n|m|DataSize*2+x|データのサイズを示す値が入る、mはDataSizeの大きさにより1、もしくは2が入る&br;xはDataSizeの値により変わる。0x1~0x3Fであれば0x1、それ以上は0x8001に加えDataSizeが0x40byte毎に+0x80される&br;0x40~0x7Fであれば0x8081. 0x80~0xBFであれば0x8101という感じ|
|0x2+n+m|DataSize|データ情報|itemであればアイテムの内容が、charaであればキャラクターの情報が来る|
|0x2+n+m+DataSize|0x1|0x0|終端を示すNullかなと思われる|
といった構造のようです
ですので、先頭0x4byte目と0x5byte目の数値を増やし、かつ各種データ構造の0x2+nに来る値を変えれば初期化されず弄ることができました
↑おそらく、バイナリエディタを使用してのセーブデータ編集についてかと思われますが、
セーブデータファイル(.sol形式)を編集するための専用のソフトウェアを使用された方がよいかと思われます。
各種データ構造について考える必要が無く、格納されてるデータの形式に気を付けるだけなので文字数とかに悩まされることがなくなります。
いちいちffdecを起動するのが億劫な場合、ffdecの格納フォルダ(winのデフォルトではProgram Files (x86)\FFDec)にsoleditor.batというファイルがありますので
それを起動させると.sol形式編集用のソフトであるSol cookie editerを起動できます
soleditor.batのショートカットを適当な場所に配置するといいかもです

~
*メモ(BGM関係) [#n15fd8bb]
BGM再生用のスクリプト

#fold(開く){{
このコードを入れると&color(red){bgmファイルをおいてるフォルダ};に指定したBGMファイルがなくてもエラーを出さずにプレイすることができる。
Soundsの601行の''public function bgmLoad(param1:int) : void''から625行のコードを以下に置き換える

#      private var bgmurl:String = "&color(red){bgmファイルをおいてるフォルダ};";
#      private var bgmno:int = 0;

#      public function bgmLoad(param1:int) : void
#      {
#         var url:URLRequest = null;
#         var bgm_no:int = param1;
#         try
#         {
#            if(this.bgm[bgm_no] == null)
#            {
#               this.bgmno = bgm_no;
#               url = new URLRequest(this.bgmurl + this.bgm_name[bgm_no] + ".mp3");
#               this.bgm[bgm_no] = new Sound(url);
#               this.bgm[bgm_no].addEventListener(IOErrorEvent.IO_ERROR, bgm_io_error);
#            }
#         }
#         catch(err:Error)
#         {
#            Main.errorCall(err);
#         }
#      }

#      public function bgm_io_error(e:Event) : void
#      {
#         this.bgm[this.bgmno] = new BGM0();
#      }
}}
~
旧版のBGMと差し替えたりする目的で需要があるかもしれないので一応メモとして

#fold(対応表){{
|RIGHT:BGCOLOR(#171717):|RIGHT:|||c
|bgm_name[n]|id(audiostock_n)|使用箇所|その他|h
|[1]|57979|タイトル(メインテーマ)||
|[2] |81450|まち||
|[3] |84219|ちかしつ|(B1~5)|
|[4] |20554|ちかろう|(B6~10)|
|[5] |67323|カタコンベ|(B11~15)|
|[6] |60494|ちかめいきゅう|(B16~20)|
|[7] |2931|げすいどう|(B21~25)|
|[8] |11387|ちかていえん|(B27~30)|
|[9] |11384|ようがんちたい|(B31~35)|
|[10] |69772|しんでん|(B36~40)|
|[11]|78262|くものす|(B41~50)|
|[12] |67350|ちていこ|(B51~60)|
|[13] |66247|もうじゃのかいろう|(B61~70)|
|[14] |67349|まぞくのとりで|(B71~80)|
|[15] |22167|ぼうきゃくのぬま|(B81~90)|
|[16] |70987|ふういんのきゅうでん|(B91~100)|
|[17] |57973|めがみのたいない|(B101~110)|
|[18] |67325|レスキュー||
|[19] |57977|ボス戦(B10,B20,B25)|+やねうら(1~4)|
|[20] |15667|ボス戦(B15)|+おうのま|
|[21]|93509|ボス戦(B30,B50,B70)|+ふんすいのちか|
|[22] |20487|ボス戦(B35,B60,B80)|+いわく付きの宝箱|
|[23] |11494|ボス戦(B40)||
|[24] |9576|ボス戦(B90)||
|[25] |23480|ボス戦(B99)|+やねうら(5)|
|[26] |67351_intro|ボス戦(B100)||
|[27] |67351_loop|ボス戦(B100)||
|[28] |57733|ボス戦(B110)||
|[29] |81397|エンディング(B40)||
|[30] |91815|エンディング(B110)||
|[31]|86607|ひみつのにわ|(B26)|
}}

~
*emergeについて [#sead4daa]
現状最も取り組むべき部分だと思うのですが、記述様式の解説不足、取り組みやすい管理方法、現状についての説明など、多くの問題がある様に感じます。

取っ付きづらいと思ったので、自分が分かる範囲で現段階の状況をなるべく噛み砕きつつ整理します。
#fold{{
具体的な例を1つ、げすいどうのラージポイズンスライムはクローンではB21から出現しますが、原作ではB23からの出現だったことが原作wikiのダンジョンのページから見て取れます。

この場合現状クローンでは、B21から24Fの範囲でラージポイズンスライムを含むA,B,C,の3パターンから敵の配置が抽選される仕組みですが、そもそもげすいどうはそれすらも未完成でまだ1パターンしかありません。
新たに「B21からB22」と「B23からB24」ではそれぞれ別のパターンから抽選する様にスクリプトを編集する必要があるうえ、当然それぞれA,B,C,の3パターンを用意しなければいけません。

これはinishieFirstからラージポイズンスライムのIDが[201]であることを確認して、inishieMapA5のなかみを見てemerge_no = "A"の中にある0,201,,,0,500の部分がラージポイズンスライムの出現に関わる部分だとわかるので、この部分を消せば即席で出ないパターンを作ること自体はできます。
※(数値の意味は[[emerge>マップ#dbabc483]]にある通りで、頭のemerge_idは使われてないので0になっていて次がエネミーのID、,,の間は省略されている)

ただしこれでは、ラージポイズンスライムが出る/出ないをバリエーションとしても、残りの2パターンがまだ無いので原作を想像しながら用意する必要があります。

ここで肝となるのがemergeのそれぞれの引数になります、[[解説されている事が全て>マップ#h0f01cfc]]なのですが、これが直感的にイメージするのが非常に難しい。

例えばマーマンを1000として基準とした時、ラージスライムを500にすれば出現率は半分、他のエネミーを333にすればそのエネミーは3分の1の確率で’出現’します。(おそらく)
それだけならまだましなのですが、イニシエダンジョンでは’群れ’として配置することができるので、

「ラージスライムが出現確率によって1体ずつ計5匹出現した」、と「ラージスライム5匹の群れが1つ出現して、1匹ずつばらばらな場所に配置された」だと全く同じ様に5匹のスライムに見えますが、まるで意味が変わってきます。


さらには、group_typeでマーマンの様なエネミーを1つのかたまりの群れで出現させる事もできますし、別のエネミーを’おとも’や’取り巻き’と言った感じで出現させることもできますので

どんなパターンで出現してるかを想像しながらエネミー全体のバランスを考えてそれを当てはめていくのは、非常に骨が折れる作業になります。

※調整次第で例えば「溶岩地帯のドラゴンって見る機会は少ないけど、出てくるときはやたらいっぱいいるな...」みたいな風に調整することができます。(おそらくは多くても2匹くらいが適切なのでまれに単体で出現させるべき)


現在では先人の方々がほぼ埋めてくださっているので、ある程度妥協しつつ意見を出し合って修正していく段階になります。

色々書きましたが直近では、下水道のemergeの原作データが見つかった訳ですので、クローン仕様に逆コンバートしてそれにラージポイズンスライムあり、なしのバージョンを作れば
ある程度満足度のあるものが作れるかと思います。(できるとは言ってないので他力本願)
}}

~
*メモ(全般) [#t2008c72]

ザイーガガチャとキャラ死亡周りの改良修正と死亡ログと全体的なバグ修正のテストです。
スクリプトを読みやすくするために大規模に改変しています。
適用されたオリジナルの[[スクリプト]]の履歴は[[2025-03-02>https://wikiwiki.jp/id-a/::cmd/backup?page=スクリプト&age=54]]です。
[[スクリプト]]に追加する予定なので、動作確認とコメントをお願いいたします。

メモ(全般)のスクリプトは[[Memo/スクリプト]]にあります。

#fold(変更点を開く){{
***初期 [#c9f3af42]
-墓のログを本格実装しました。墓のログはmilkywayの内部で作成されます。
--ログを保存する変数はないため、this.Main.mso.data.loglistを追加してセーブデータに保存するようにしました。
--ゲーム内の墓のログの画像を見つけることはできなかったため完全再現はできていないかもしれません。
--リプレイログの再現方法は分からないのでリプレイボタンやレスキューログなどはありません。
-milkywayを中心としたキャラ死亡周りの多くのバグを修正しました。
--同時に複数キャラが死んだ場合はキャラの生死判定が滅茶苦茶になるバグが起きる可能性は大きく減少しました、残りはセーブを保存するタイミングの前後で起きている可能性があります。
--ザイーガガチャスクリプトは問題ないため追加、charamakeでキャラデータの情報の一部が欠けていたのを修正。chararesetとcharareviveで墓のログを削除。chararesetでHPが最大HPまで満たしていないのを修正。
--newpassとloginlogとlogoutとnewpassはエラーにならないようにしました。loginlogに必要な情報を追加しました。

***編集その1 [#q7cd953f]
-charamakeの初期HPを9999にしました。
-イニシエサイトのプレイログをそのままひらがな読みにした文章をログに採用しました。
-操作キャラが倒されたときの町の座標をpartybreakと同じにしました。

***編集その2 [#w1a16d2b]
-this.Main.mso.data.loglistは配列区切りで使用されている"<>"がGraveWindow.loadEndで使用されていることが判明したため、loglistの名前をgravelogに変更して配列区切りを"[]"に変更してloglistは削除します。loglistの削除コードは[[うごかす方法]]に公開するときに撤去しますが、仮に残っていても動作に問題ありません。
--関数を汎用的にするためにdeadMessageの名前はlogTextに変更しました。
--gravelogは将来的にプレイログを再現するために他のデータも保存するようになります。もし使用されたセーブデータが100KBを超えるとユーザーに許可を求められるようなので許可をお願いします。
--保存するログデータはプレイ当時のほぼ完全なプレイヤーデータになります。ほぼの理由は、倉庫アイテムデータであるitemは倉庫以外のログ以外ではセーブ容量の節約のために保存しないで代わりに現在進行のセーブを利用します。
-一部の変数の型を指定しました、理由はデバッグが楽になるのと型推論しなくなることで処理が高速化されるからです。
-スクリプトが長すぎて編集できないのでページを分けました。

***編集その3 [#z1b5a662]
-編集その2でやったことですが、同時に複数キャラが死んだ場合はキャラの生死判定が滅茶苦茶になるバグは修正されました。
-無理のない範囲でスクリプトの行数を減らしました。
-更に一部の変数の型を指定しました。

***編集その4 [#oefd57eb]
-れんしゅうモードとチャレンジモードで日誌をつけるとセーブデータが壊れる恐れがあるため安全策を組みました。
--これまでは例外により処理が停止していましたが、"savelog"から"diary"に処理を変更することで安全にプレイを続行できるようになりました。
--こちらでは手が付けられないため、解決されるまでこのままにしておきます。
-イニシエダンジョンのURLに""を代入してゲーム内で参照しないようにしました。
--イニシエダンジョンのドメインが販売中のため、新しいドメインの所有者にURLを悪用される恐れがあるためです。
-墓のログの特殊フロアの表示方法を更新しました。

***編集その5 [#jedc0e2c]
-パッチの開始位置を''private function newFirstLCFunc(param1:Event) : *''からに変更しました。
-サーバー時刻を現在のシステム時刻で設定しました。大きな問題があった場合は戻します。
-ひみつのコードを送信するときに現在のシステム時刻を設定しました。
--ついでにデバッグメッセージらしき文章を削除しました。オリジナルのメッセージは分からないので"?"を残しておきます。
-プレイヤーに倒された場合は、墓のログに名前を表示しなかったのを修正しました。
-操作キャラが死んだときに所持金を失っていないのを修正しました。
-操作キャラが倒されたときに移動される町の座標を公式と同じにしました。
--パーティをかいさん時の座標については、公式の情報を知らないのでそのままにしておきます。
-死亡しないフロアは、ver1.0313の「死亡しないフロアで倒れた際は「きぜつ」状態になるようにした。」に従って、HP1ではなくきぜつ状態にしました。
-undeadFloorはthis.Main.myPlayScreen.live_flagを代入するようにしました。
--死亡しないフロアは、レスキューモード、れんしゅうステージ、おうのま、てんしのへや、きょうかいのやねうら、ひみつのにわです。
--以前の値を残してありますが、それらは通常アクセスされることはありません。
-きぜつ状態になった場合は墓のログを作成するようにしました。
-墓のログに西暦は表示しないようにしました。
-ログ作成の関数内部でエラーが発生した場合はゲームをフリーズしないようにしました。
--エラーが発生した場合はログにエラーの原因を表示します。
-紫墓のログに失ったアイテム名を表示するようになりました。

***編集その6 [#g3abbaad]
-きぜつ状態にになったときに「の メモ」を表示するようになりました。
--死んだときにHPを-1にしたのをやめただけです。
-codesendの大部分を作り直しました。
--エラーなど複数の問題を修正しました。
--「コードが まちがっています」を表示するようになりました。
--編集その5で動作しなくなった、ギフトのないコード(主に[[mod]]用)を直しました。

***編集その7 [#a08fb58c]
-gameclearを行った後、STARTでゲームが始まらないのを修正しました。
-chararesetで持ち物を削除して、ジョブの初期アイテムを装備するようしました。
--ゾンビの状態のままリセットするとセーブ内に持ち物が残る恐れがあるためです。
-charadelでフリーズしていたのを修正しました。
--原因はtemp変数にvarで型指定した事が原因のようで、他の場所でvarを呼ばずに使われている部分において影響を与えてました。
--クローン版の初期の設計で関数内にtemp変数をvar宣言しなかった理由が分からないけど、今後は基本的にvarなし変数は残さないようにします。
-多くの変数名を変更しました。
--命名規則は推定的にthis.Main.mso.data.charaはcharaData、partyはpartyData、questはquestData、itemはitemDataとします。
-いくつか誤った型指定と多くのバグを直しました。
--色々と解ってきたのでそろそろ安定すると思います…

***編集その8 [#a249f4fe]
-マップの墓と実際の死亡判定が一致しなかったのを修正しました。
-マップに墓がある場合その結果が優先されるため、実際の影響はないと思います。
-編集その7でpartyPos[4]とpartyPos[5]の値が変化したことが原因でした。

***編集その9 [#i4cae557]
-メモ(全般)の動作に必要な[[スクリプト]]のバージョンを[[2025-03-02>https://wikiwiki.jp/id-a/::cmd/backup?page=スクリプト&age=54]]に更新しました。

***編集その10 [#ieaa3f23]
-パッチの開始位置を''private function newFirstLCFunc(param1:Event) : *''から''private function setCode(code:String, xml:XML) : Array''の関数の終わりまでにしました。
-今回からプレリリーステストになります。
--スクリプト内のコメントは撤去しました。
--ページ編集の原文は手元のファイルから上書きしてるため、上書き編集の結果は戻されます。
-エリアとマップの移動処理の行数を減らしました。
--行数を減らす理由は、wikiのページ編集の上限が1500行に制限されているためです。
--この時に動作が不安定になったのを探して何度も修正したため、まだ問題があるかもしれません。
-にっしをつけるで、プレイヤーキャラのプレイ回数をカウントする問題を修正しました。
--本家は、プレイヤーキャラのプレイ回数は、ダンジョン内のかいだんをおりるを使用した場合のみカウントします。
-ザイーガのぶつを買った時のセーブで所持金を減らさない問題を修正しました。
--これは本家の仕様の通りです。これで無料ガチャはもうできません!
-ギフトをうけとるで、そうこの空きスロットがない場合はギフトのうけとりに失敗するようにしました。
--失敗した場合、ギフトは失われません。(間違っていたら意見をお願いします)
-codesendの処理を更に改善しました。
--メモ(全般)で追加したUI関連のメッセージはすべて仮です。情報提供をおねがいします。
}}

~

*コメント [#comments]
#pcomment(,reply,5,)