function Game_Talk() {
    this.initialize.apply(this, arguments);
}

Game_Talk.prototype.initialize = function() {
    this._talk = '';
    this._talked = {};
    this._roulette = [];
    this._testMode = false;
};

Game_Talk.prototype.prepareTalk = function(test) {
    this._talk = null;
    this._roulette = [];
    this._testMode = test || false;
};

Game_Talk.prototype.talk = function() {
    return this._talk;
};

Game_Talk.prototype.setTalk = function(person, talk, once) {
    if(!this._talked[person]) this._talked[person] = [];
    if(!this._talk && !this.isTalked(person,talk)){
        if(!this.isTest()){
            this._talked[person].push(talk);
            this._talk = talk;
        }
        return true;
    }else if(!once){
        this._roulette.push(talk);
    }
    return false;
};

Game_Talk.prototype.isTest = function() {
    return this._testMode;
};

Game_Talk.prototype.isTalked = function(person,talk) {
    return this._talked[person] && this._talked[person].includes(talk);
};

Game_Talk.prototype.removeTalked = function(person,talk) {
    this._talked[person] = this._talked[person].filter(function(talked) {
        return talked !== talk;
    });
};

Game_Talk.prototype.talkRoulette = function() {
    this._talk = this._roulette[Math.floor(Math.random() * this._roulette.length)]
};

Game_Talk.prototype.talkData = function() {
    return {
        partner:[
        {id:'初回', condition:this.chapter() == 1, once:false},
        {id:'キス未遂', condition:this.chapter() >= 2 && this.time() < 1, once:true},
        {id:'平常', condition:this.chapter() === 2, once:false},
        {id:'予感', condition:this.chapter() === 3 && $gameParty.hasAnyItem(), once:false},
        {id:'扉', condition:this.chapter() === 4 && $gameParty.hasAnyItem(), once:false},
        //長い棒未入手で5分以上経ったとき
        {id:'裏とか', condition:this.chapter() >= 2 && this.playtime('min', '探索開始') >= 5 && !$gameSwitches.value(22), once:false},
        //百合ポイントアップから1分以上進展がないとき
        {id:'脚立', condition:this.chapter() >= 2 && this.playtime('min', '百合') >= 1 && !$gameSwitches.value(25), once:false},
        //脚立入手から3分以上
        {id:'時計', condition:this.chapter() >= 2 && this.playtime('min', '脚立') >= 3 && !$gameSwitches.value(33), once:false},
        {id:'時計2', condition:this.chapter() >= 2 && this.playtime('min', '時計') >= 1 && !$gameSwitches.value(40), once:false},
        //{id:'長い棒', condition:this.chapter() >= 2 && this.playtime('min', '長い棒') >= 3 && (!$gameSwitches.value(23) || !$gameSwitches.value(24)), once:false},
        {id:'何度か', condition:this.chapter() >= 2 && this.playtime('min', '探索開始') >= 1, once:false},
        {id:'アイテム', condition:this.chapter() >= 2 && $gameParty.hasAnyItem(), once:false},
        ],
    }
};

Game_Talk.prototype.talkCheck = function(speaker, test) {
    this.prepareTalk(test);
    const data = this.talkData()[speaker];
    let result = '';

    data.forEach(function(talk) {
        if(talk.condition){
            if(this.setTalk(speaker, talk.id, talk.once)){
                result = true;
                return;
            }
        }
    },this);

    if(this.isTest()) return result;
    
    // 初話題がすべて終わっている場合は既存の内容からランダム
    if(!this._talk) this.talkRoulette();
};

Game_Talk.prototype.chapter = function() {
    return $gameVariables.value(5);
};

Game_Talk.prototype.yuriPt = function() {
    return $gameVariables.value(7);
};

Game_Talk.prototype.time = function() {
    return $gameVariables.value(21);
};

Game_Talk.prototype.talkTimes = function() {
    return $gameVariables.value(22);
};

Game_Talk.prototype.playtime = function(type, id) {
    const base = $gameSystem.timeStamp(id);
    const time = $gameSystem.playtime() - base;
    if(!base) return false;
    switch(type){
        case 'hour': return Math.floor(time / 60 / 60);
        case 'min': return Math.floor(time / 60) % 60;
        case 'sec': return time % 60;
    }
};

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

const _Game_Event_update      = Game_Event.prototype.update;
 Game_Event.prototype.update = function() {
   _Game_Event_update.apply(this, arguments);
   this.updateTalk();
   this.updateNear();
 };

Game_Event.prototype.updateTalk = function() {
    if(!this.needTalkWait && this.needTalk()){
        $gameTemp.requestBalloon(this, 8);
        this.needTalkWait = 180;
    }
    if(this.needTalkWait > 0){
        this.needTalkWait--;
    }
};

Game_Event.prototype.needTalk = function() {// add.
    if(!this.isTalkEvent()) return false;
    if($gameMap.isEventRunning()) return false;
    const name = this.event().meta.talk;
    return $gameTalk.talkCheck(name, true)
};

Game_Event.prototype.isTalkEvent = function() {
    return this.event() && this.event().meta.talk && this.isVisible();
};

Game_CharacterBase.prototype.distance = function(target, x, y) {
    var x = target ? target.x : x;
    var y = target ? target.y : y;
    const sx = this.deltaXFrom(x);
    const sy = this.deltaYFrom(y);
    const ax = Math.abs(sx);
    const ay = Math.abs(sy);
    return Math.sqrt(ax**2 + ay**2);
};

Game_Event.prototype.updateNear = function() {
    if(this.isPartner()){
        this.checkNearPartner();
    }
};

Game_Event.prototype.checkNearPartner = function() {
    const partner = $gamePlayer;
    if(this.distance(partner) < 3){
        if(!$gameMap.isEventRunning()) this._nearCount++;
    }else{
        this._nearCount = 0;
    }
    if(this._nearCount > 30 * 60){//30秒
        this._nearCount = 0;
        $gameTemp.reserveCommonEvent(25);
    }
};