SoundManager.playSe = function(name) {
    const se = {name: name, volume: 90, pitch: 100, pan: 0};
    AudioManager.playSe(se);
};

var $gameTalk           = null;
DataManager.createGameObjects = function() {
    $gameTemp          = new Game_Temp();
    $gameSystem        = new Game_System();
    $gameScreen        = new Game_Screen();
    $gameTimer         = new Game_Timer();
    $gameMessage       = new Game_Message();
    $gameSwitches      = new Game_Switches();
    $gameVariables     = new Game_Variables();
    $gameSelfSwitches  = new Game_SelfSwitches();
    $gameActors        = new Game_Actors();
    $gameParty         = new Game_Party();
    //$gameTroop         = new Game_Troop();
    $gameMap           = new Game_Map();
    $gamePlayer        = new Game_Player();
    $gameTalk          = new Game_Talk();//@追加
};

DataManager.makeSaveContents = function() {
    // A save data does not contain $gameTemp, $gameMessage, and $gameTroop.
    const contents = {};
    contents.system = $gameSystem;
    contents.screen = $gameScreen;
    contents.timer = $gameTimer;
    contents.switches = $gameSwitches;
    contents.variables = $gameVariables;
    contents.selfSwitches = $gameSelfSwitches;
    contents.actors = $gameActors;
    contents.party = $gameParty;
    contents.map = $gameMap;
    contents.player = $gamePlayer;
    contents.talk = $gameTalk;//@追加
    return contents;
};

DataManager.extractSaveContents = function(contents) {
    $gameSystem = contents.system;
    $gameScreen = contents.screen;
    $gameTimer = contents.timer;
    $gameSwitches = contents.switches;
    $gameVariables = contents.variables;
    $gameSelfSwitches = contents.selfSwitches;
    $gameActors = contents.actors;
    $gameParty = contents.party;
    $gameMap = contents.map;
    $gamePlayer = contents.player;
    $gameTalk = contents.talk;//@追加
};

Scene_Boot.prototype.loadSystemImages = function() {
    ColorManager.loadWindowskin();
    ImageManager.loadSystem("IconSet");
    ImageManager.loadSystem("TMWindowCaption");
    ImageManager.loadSystem("TMWindowCaptionVR");
};

Input.keyMapper = {
    //キーマップ
		9: 'tab',       // tab
		13: 'ok',       // enter
		16: 'shift',    // shift
		17: 'control',  // control
		18: 'control',  // alt
		27: 'escape',   // escape
		32: 'ok',       // space
		33: 'pageup',   // pageup
		34: 'pagedown', // pagedown
		37: 'left',     // left arrow
		38: 'up',       // up arrow
		39: 'right',    // right arrow
		40: 'down',     // down arrow
		45: 'escape',   // insert
		81: 'pageup',   // Q
		87: 'pagedown', // W
		88: 'escape',   // X
		90: 'ok',       // Z
		96: 'escape',   // numpad 0
		98: 'down',     // numpad 2
		100: 'left',    // numpad 4
		102: 'right',   // numpad 6
		104: 'up',      // numpad 8
		120: 'debug',    // F9
    //WASDに対応
		65: 'left',     // left arrow
		87: 'up',       // up arrow
		68: 'right',    // right arrow
		83: 'down'     // down arrow
	};

//-----------------------------------------------------------------------------
// Game_System
//-----------------------------------------------------------------------------

//playtimeを修正
const _Game_System_initialize = Game_System.prototype.initialize;
Game_System.prototype.initialize = function() {
    _Game_System_initialize.call(this);
    this._playTime = 0;
    this._timeStamp = {};
};

Game_System.prototype.countPlayTime = function() {
    this._playTime++;
};

Game_System.prototype.playtime = function() {
    return Math.floor(this._playTime / 60);
};

Game_System.prototype.recordTimeStamp = function(id) {
    this._timeStamp[id] = this.playtime();
};

Game_System.prototype.timeStamp = function(id) {
    return this._timeStamp[id] ? this._timeStamp[id] : 0;
};

const _Scene_Base_update = Scene_Base.prototype.update;
Scene_Base.prototype.update = function() {
    _Scene_Base_update.call(this);
    this.updateTime();
};

Scene_Base.prototype.updateTime = function() {
    $gameSystem.countPlayTime();
};

//-----------------------------------------------------------------------------
// Game_Screen
//-----------------------------------------------------------------------------

Game_Screen.prototype.initialize = function() {
    this.clear();
    this._tone = [-255, -255, -255, 0];//@add
};

//-----------------------------------------------------------------------------
// Game_Event
//-----------------------------------------------------------------------------

Game_Event.prototype.isVisible = function() {
    return !this._erased && !this.isTransparent() && this.characterName();
};

//イベント中は動かないようにする
Game_Event.prototype.updateSelfMovement = function() {
    if (
        !this._locked &&
        this.isNearTheScreen() &&
        this.checkStop(this.stopCountThreshold()) &&
        !$gameMap.isEventRunning()
    ) {
        switch (this._moveType) {
            case 1:
                this.moveTypeRandom();
                break;
            case 2:
                this.moveTypeTowardPlayer();
                break;
            case 3:
                this.moveTypeCustom();
                break;
        }
    }
};

//-----------------------------------------------------------------------------
// Game_Interpreter
//-----------------------------------------------------------------------------

//ピクチャー移動のウェイトモードを足す
/*
Game_Interpreter.prototype.updateWaitMode = function() {
    let character = null;
    let waiting = false;
    switch (this._waitMode) {
        case "message":
            waiting = $gameMessage.isBusy();
            break;
        case "transfer":
            waiting = $gamePlayer.isTransferring();
            break;
        case "scroll":
            waiting = $gameMap.isScrolling();
            break;
        case "route":
            character = this.character(this._characterId);
            waiting = character && character.isMoveRouteForcing();
            break;
        case "animation":
            character = this.character(this._characterId);
            waiting = character && character.isAnimationPlaying();
            break;
        case "balloon":
            character = this.character(this._characterId);
            waiting = character && character.isBalloonPlaying();
            break;
        case "gather":
            waiting = $gamePlayer.areFollowersGathering();
            break;
        case "action":
            waiting = BattleManager.isActionForced();
            break;
        case "video":
            waiting = Video.isPlaying();
            break;
        case "image":
            waiting = !ImageManager.isReady();
            break;
    }
    if (!waiting) {
        this._waitMode = "";
    }
    return waiting;
};*/

//-----------------------------------------------------------------------------
// 相手とぶつかりあうと位置交換
//-----------------------------------------------------------------------------

Game_Player.prototype.checkEventTriggerTouch = function(x, y) {
    if (this.canStartLocalEvents()) {
        this.startMapEvent(x, y, [1], true);// 「イベントからの接触」をプレイヤーからの接触で起こらないように
    }

    $gameMap.events().forEach(function(event) {
        if(event.isObstacle() && event.posNt(x,y) && !$gameMap.isEventRunning()){
            event.turnTowardPlayer();
            event.countObstacle();
            if(this.isDashing()) event.countObstacle();
        }else{
            event.resetObstacle();
        }
        if(event.obstacle() > 20) {
            this.swapPotision(event);
        }
    }, this);
};

Game_Player.prototype.swapPotision = function(event) {
    const direction = this.direction();
    const x1 = this.x;
    const y1 = this.y;
    const x2 = $gameMap.roundXWithDirection(x1, direction);
    const y2 = $gameMap.roundYWithDirection(y1, direction);
    if(event.posNt(x2,y2) && this.isMapPassable(x1 ,y1, direction) && !this.isCollidedWithOut(x2, y2, event)){
        event.setDirection(this.reverseDir(direction));
        event.jumpStraight();
        event.resetObstacle();
        this.jumpStraight();
    }
};

Game_CharacterBase.prototype.isCollidedWithOut = function(x, y, target) {
    var events = $gameMap.eventsXyNt(x, y);
    return events.some(function(event) {
        return event.isNormalPriority() && event !== target;
    });
};

Game_Event.prototype.countObstacle = function() {
    if(this._obstacle === undefined) this.resetObstacle();
    this._obstacle++;
};

Game_Event.prototype.resetObstacle = function() {
    this._obstacle = 0;
};

Game_Event.prototype.obstacle = function() {
    return this._obstacle;
};

Game_Event.prototype.isPartner = function() {
    return this.event().meta.partner;
};

Game_Event.prototype.isObstacle = function() {
    return this.event().meta.obstacle;
};

Game_CharacterBase.prototype.jumpStraight = function(a) {
    var x = 0;
    var y = 0;
    const d = this.direction();
    var a = a || 1;
    if(d == 8){
        y = -1 * a;
    }else if(d == 6){
        x = 1 * a;
    }else if(d == 4){
        x = -1 * a;
    }else if(d == 2){
        y = 1 * a;
    }
    this.jump(x,y);
};


//向きとか画像とかパターンとかまとめて指定
Game_Character.prototype.setIDP = function(characterName, characterIndex, direction, pattern) {
    this._characterName = characterName;
    this._characterIndex = characterIndex;
    this._direction = direction;
    this._pattern = pattern;
};

//特定リージョンを通行不能に
Game_Event.prototype.isCollidedWithCharacters = function(x, y) {
    return (
        Game_Character.prototype.isCollidedWithCharacters.call(this, x, y) ||
        this.isCollidedWithPlayerCharacters(x, y) ||
        this.isCollidedRegion(x, y)
    );
};

Game_Event.prototype.isCollidedRegion = function(x, y) {
    return $gameMap.regionId(x, y) === 10;
};


//-----------------------------------------------------------------------------
// Window_Message
//-----------------------------------------------------------------------------

Window_Message.prototype.newPage = function(textState) {
    this.contents.clear();
    this.resetFontSettings();
    this.clearFlags();
    this.updateSpeakerName();
    this.loadMessageFace();
    textState.x = this.centeredX(0, textState.startX);
    textState.y = 0;
    textState.startX = this.centeredX(1, textState.startX);
    textState.height = this.calcTextHeight(textState);
};

Window_Message.prototype.centeredX = function(line, base) {
    if($gameMessage.background() === 2){
        var text = this._textState.text.split(/\r\n|\r|\n/)[line];
        if(text){
            text = text.replace(/\C\[\d\]/g,"");
            text = text.replace(//g,"");
            return (Graphics.boxWidth - this.textWidth(text)) / 2;
        }
    }
    return base;
};

Scene_Message.prototype.messageWindowRect = function() {
    const ww = Graphics.boxWidth;
    const wh = this.calcWindowHeight(3, false) + 8;
    const wx = (Graphics.boxWidth - ww) / 2;
    const wy = 0;
    return new Rectangle(wx, wy, ww, wh);
};

//-----------------------------------------------------------------------------
// Sprite_ButtonEx
//-----------------------------------------------------------------------------

function Sprite_ButtonEx() {
    this.initialize(...arguments);
}

Sprite_ButtonEx.prototype = Object.create(Sprite_Button.prototype);
Sprite_ButtonEx.prototype.constructor = Sprite_ButtonEx;

Sprite_ButtonEx.prototype.initialize = function(bitmap, x, y) {
    Sprite_Button.prototype.initialize.call(this);
    this.bitmap = bitmap;
    this.x = x;
    this.y = y;
    this.updateFrame();
    //this.updateOpacity();
};
Sprite_ButtonEx.prototype.setupFrames = function() {
    const data = this.buttonData();
    if(data){
        const x = data.x * this.blockWidth();
        const width = data.w * this.blockWidth();
        const height = this.blockHeight();
        this.loadButtonImage();
        this.setColdFrame(x, 0, width, height);
        this.setHotFrame(x, height, width, height);
    }
};

Sprite_ButtonEx.prototype.checkBitmap = function() {

};

Sprite_ButtonEx.prototype.update = function() {
    Sprite_Clickable.prototype.update.call(this);
    this.checkBitmap();
    this.updateFrame();
    //this.updateOpacity();
    this.processTouch();
};

Sprite_ButtonEx.prototype.updateOpacity = function() {
    this.opacity = this._pressed ? 255 : 192;
};