/*:
 * @plugindesc 
 * @target MV
 * @help 
 */
let StuckRecovery_CkInterval = 60; 
(function() {
    const STUCK_TIME     = 120;  
    const EVENT_NAME     = "停止対策"; 
    const FADE_TYPE      = 2;    
    let _stuckTimer = 0;
    let _lastPos = { x: -1, y: -1 };
    const _Game_Player_update = Game_Player.prototype.update;
    Game_Player.prototype.update = function(sceneActive) {
        _Game_Player_update.call(this, sceneActive);
        if (this._canCheckStuck()) {
            this._checkStuckPosition();
        } else {
            _stuckTimer = 0;
        }
    };
    Game_Player.prototype._canCheckStuck = function() {
        return !$gameMap.isEventRunning() &&
            !$gameMessage.isBusy() &&
            !this.isMoveRouteForcing() &&
            !this.isTransferring();
    };
    Game_Player.prototype._isOnImpassableTile = function() {
        const dirs = [2, 4, 6, 8];
        return dirs.every(d => !this.canPass(this.x, this.y, d));
    };
    Game_Player.prototype._checkStuckPosition = function() {
        if (!StuckRecovery_CkFlg) return;
        StuckRecovery_CkFlg = false;
        if (MenuFlgSwich) return;
        if (this.x === _lastPos.x && this.y === _lastPos.y && this._isOnImpassableTile()) {
            _stuckTimer += StuckRecovery_CkInterval;
        } else {
            _stuckTimer = 0;
        }
        _lastPos.x = this.x;
        _lastPos.y = this.y;
        if (_stuckTimer >= STUCK_TIME) {
            _stuckTimer = 0;
            const ev = $gameMap.events().find(e => e.event().name === EVENT_NAME);
            if (!ev) {
                console.log(`停止対策イベントが存在しないため、救済処理は実行されません。`);
                return;
            }
            console.warn("⚠ スタック検知：停止対策イベントに転送します");
            $gamePlayer.reserveTransfer($gameMap.mapId(), ev.x, ev.y, 2, FADE_TYPE);
        }
    };
})();
let StuckRecovery_CkFlg = false;
let StuckRecovery_NUpdateSc = Game_Interpreter.prototype.NUpdateSc;
Game_Interpreter.prototype.NUpdateSc = function () {
    StuckRecovery_NUpdateSc.call(this);
    StuckRecovery_CkInterval--;
    if (StuckRecovery_CkInterval <= 0) {
        StuckRecovery_CkInterval = 60;
        StuckRecovery_CkFlg = true;
    }
}
