JavaScript
RPGツクールMV

ツクールMVでセーブデータの表示を改造する+セーブ日時を表示する

セーブ画面のレイアウトを改造するプラグインを作ろうとしたのですが、既にいいプラグインがあったんですよね。

【プラグイン】セーブウインドウ改造プラグイン
最終的にはゲームの仕様などが複雑に絡むため、プラグイン一つで何でも解決!とは行かないことがわかり、作成中のプラグインは没になりました。
しかし、何も発表しないのは悔しいので、どうやったらメニュー画面を改造できるかだけまとめます。

表示の仕組みは?

セーブデータを参照する画面はWindow_SaveFileで管理されます。
Scene_LoadScene_Saveは、Window_SaveFileへのsetHandler()で渡す関数が違うだけです。
共通のScene_Fileをベースとして持ち、どちらも機能はほぼ同じです。

saveinfoって何よ?

saveinfoとはDataManager.makeSavefileInfo()で作られる、サムネイル用の情報をまとめた構造体です。
セーブデータを書き込む直前に作成されて、よくわからないタイミングで埋め込まれます。
(ソースコード内を検索すればすぐに見つかるのですが、OOP的に細かい原理は意識しないようにする)

rpg_manager.js
DataManager.makeSavefileInfo = function() {
    var info = {};
    info.globalId   = this._globalId;
    info.title      = $dataSystem.gameTitle;
    info.characters = $gameParty.charactersForSavefile();
    info.faces      = $gameParty.facesForSavefile();
    info.playtime   = $gameSystem.playtimeText();
    info.timestamp  = Date.now();
    return info;
};

デフォルトでは上記の要素のみです。
よく話題に上がるのが「セーブした場所の名前を記録してほしい」ですね。
案外簡単に実装できます。

rpg_manager.js
function addMapName(info){
    info.mapname = $gameMap.displayName();
}

const DataManager_makeSavefileInfo= DataManager.makeSavefileInfo;
DataManager.makeSavefileInfo =function(){
    const info = DataManager_makeSavefileInfo.call(this);
    addMapName(info);
    return info;
};

表示するときはWindow_SavefileList.prototype.drawContents()を改造すればOKです。

rpg_manager.js
Window_SavefileList.prototype.drawContents = function(info, rect, valid) {
    var bottom = rect.y + rect.height;
    if (rect.width >= 420) {
        this.drawGameTitle(info, rect.x + 192, rect.y, rect.width - 192);
        if (valid) {
            this.drawPartyCharacters(info, rect.x + 220, bottom - 4);
        }
    }
    var lineHeight = this.lineHeight();
    var y2 = bottom - lineHeight;
    if (y2 >= lineHeight) {
        this.drawPlaytime(info, rect.x, y2, rect.width);
    }
};

第一引数にinfoというデータがありますが、これが前述のsaveinfoです。
ブレークポイントで中身を確認しながら表示を機能を作りましょう。

セーブ日時を表示する

セーブした日付はセーブデータに最初から格納されています。
saveInfoにtimestampというメンバがあって、これをnew Date(saveInfo.timestamp)で変換すれば必要なデータがすぐに手に入ります。
毎回変換するのが遅いと気になるのであれば、データ作成時に文字列へ変換するのがいいだろうと思います。
文字列に変換するのは以下のような関数で行えます。
すごく楽。

//日付表示設定を細かく改造したい場合、このパラメータを改造する。
//詳細はJavaScript Dateで検索すること
//また、このパラメータをオプションに設定すること
const dateOptions =  {
//        weekday: "long", // 曜日
    year: "numeric",
    month: "short",
    day: "numeric",
    hour: "2-digit",
    minute: "2-digit"
};

/**
 * @return {String}
 * @param {Date} date 
 */
function dateFormat(date){
    //For languages ​​other than Japanese, change "ja-JP"
    return date.toLocaleDateString("ja-JP",dateOptions);
}

あとはdrawContents()で適当にdrawText()すればOKです。

以上。
ずいぶん雑な解説でしたが、saveinfoをdrawContents()で表示するのだけわかれば後は何でもできます。