//=============================================================================
// GeneralTrigger.js
// ----------------------------------------------------------------------------
// Copyright (c) 2015 Triacontane
// This software is released under the MIT License.
// http://opensource.org/licenses/mit-license.php
// ----------------------------------------------------------------------------
// Version
// 1.1.0 2016/07/06 レベルアップ時、レベルダウン時のトリガーを追加
// 1.0.2 2016/06/22 最強装備を選択した場合にエラーが発生する問題を修正
// 1.0.1 2016/06/17 ロードが失敗するバグを修正
// 1.0.0 2016/06/14 初版
// ----------------------------------------------------------------------------
// [Blog]   : http://triacontane.blogspot.jp/
// [Twitter]: https://twitter.com/triacontane/
// [GitHub] : https://github.com/triacontane/
//=============================================================================

/*:
 * @plugindesc トリガープラグイン
 * @author トリアコンタン
 *
 * @param ニューゲーム
 * @desc ニューゲーム時にONになるスイッチ番号
 * @default 0
 * @type switch
 *
 * @param コンティニュー
 * @desc コンティニュー時にONになるスイッチ番号
 * @default 0
 * @type switch
 *
 * @param オプション画面
 * @desc オプション画面を出た時にONになるスイッチ番号。ただしタイトル画面の場合は無効です。
 * @default 0
 * @type switch
 *
 * @param メニュー画面
 * @desc メニュー画面を出た時にONになるスイッチ番号
 * @default 0
 * @type switch
 *
 * @param セーブ画面
 * @desc セーブ画面を出た時にONになるスイッチ番号
 * @default 0
 * @type switch
 *
 * @param 戦闘画面
 * @desc 戦闘画面を出た時にONになるスイッチ番号
 * @default 0
 * @type switch
 *
 * @param ショップ画面
 * @desc ショップ画面を出た時にONになるスイッチ番号
 * @default 0
 * @type switch
 *
 * @param 別マップ移動
 * @desc 別マップ移動時にONになるスイッチ番号
 * @default 0
 * @type switch
 *
 * @param アイテム増減
 * @desc アイテム増減時にONになるスイッチ番号
 * @default 0
 * @type switch
 *
 * @param 武器増減
 * @desc 武器増減時にONになるスイッチ番号
 * @default 0
 * @type switch
 *
 * @param 防具増減
 * @desc 防具増減時にONになるスイッチ番号
 * @default 0
 * @type switch
 *
 * @param アイテムID
 * @desc アイテム、武器、防具入手時に格納されるアイテムIDを格納する変数番号
 * @default 0
 * @type variable
 *
 * @param アイテム個数
 * @desc アイテム、武器、防具入手時に格納されるアイテム増減数を格納する変数番号
 * @default 0
 * @type variable
 *
 * @param メンバー加入
 * @desc メンバー加入時にONになるスイッチ番号
 * @default 0
 * @type switch
 *
 * @param メンバー離脱
 * @desc メンバー離脱時にONになるスイッチ番号
 * @default 0
 * @type switch
 *
 * @param レベルアップ
 * @desc レベルアップ時にONになるスイッチ番号
 * @default 0
 * @type switch
 *
 * @param レベルダウン
 * @desc レベルダウン時にONになるスイッチ番号
 * @default 0
 * @type switch
 *
 * @param アクターID
 * @desc 加入・離脱、レベルアップ、レベルダウンしたアクターIDを格納する変数番号
 * @default 0
 * @type variable
 * 
 * @param マップ画面でのみ有効
 * @desc アイテムの増減やレベルアップについて、マップ画面でのみスイッチをONにします。(ON/OFF)
 * @default OFF
 *
 * @help ゲーム中、様々な局面でスイッチをONにします。
 * 主に並列処理、自動実行のコモンイベントと組み合わせて使用します。
 * 以下のタイミングでスイッチをONにできます。
 *
 * ・ニューゲーム
 * ・コンティニュー
 * ・メニュー画面を閉じたとき
 * ・オプション画面を閉じたとき
 * ・セーブ画面を閉じたとき
 * ・ショップ画面を閉じたとき
 * ・別マップに移動したとき
 * ・アイテムを入手したとき
 * ・メンバーが加入、離脱したとき
 * ・レベルが増減したとき
 * 
 * また、トリガーの種類によっては、スイッチがONになると同時に変数に
 * 所定の値が代入されます。
 * 
 * 例えば、アイテム入手のトリガーがONになったときに指定された変数に
 * アイテムIDが格納されます。
 * 専用の入手インフォメーション等が作成できます。
 *
 * このプラグインにはプラグインコマンドはありません。
 *
 * 利用規約：
 *  作者に無断で改変、再配布が可能で、利用形態（商用、18禁利用等）
 *  についても制限はありません。
 *  このプラグインはもうあなたのものです。
 */

(function() {
    'use strict';
    var pluginName = 'GeneralTrigger';

    var getParamOther = function(paramNames) {
        if (!Array.isArray(paramNames)) paramNames = [paramNames];
        for (var i = 0; i < paramNames.length; i++) {
            var name = PluginManager.parameters(pluginName)[paramNames[i]];
            if (name) return name;
        }
        return null;
    };

    var getParamNumber = function(paramNames, min, max) {
        var value = getParamOther(paramNames);
        if (arguments.length < 2) min = -Infinity;
        if (arguments.length < 3) max = Infinity;
        return (parseInt(value, 10) || 0).clamp(min, max);
    };

    var getParamBoolean = function(paramNames) {
        var value = getParamOther(paramNames);
        return (value || '').toUpperCase() === 'ON';
    };

    //=============================================================================
    // パラメータの取得と整形
    //=============================================================================
    var paramNewGame      = getParamNumber(['NewGame', 'ニューゲーム']);
    var paramContinue     = getParamNumber(['Continue', 'コンティニュー']);
    var paramOptions      = getParamNumber(['Options', 'オプション画面']);
    var paramSave         = getParamNumber(['Save', 'セーブ画面']);
    var paramMenu         = getParamNumber(['Menu', 'メニュー画面']);
    var paramBattle       = getParamNumber(['Battle', '戦闘画面']);
    var paramShop         = getParamNumber(['Shop', 'ショップ画面']);
    var paramMoveMap      = getParamNumber(['MoveMap', '別マップ移動']);
    var paramGainItem     = getParamNumber(['GainItem', 'アイテム増減']);
    var paramGainWeapon   = getParamNumber(['GainWeapon', '武器増減']);
    var paramGainArmor    = getParamNumber(['GainArmor', '防具増減']);
    var paramItemId       = getParamNumber(['ItemId', 'アイテムID']);
    var paramItemAmount   = getParamNumber(['ItemAmount', 'アイテム個数']);
    var paramAddMember    = getParamNumber(['AddMember', 'メンバー加入']);
    var paramRemoveMember = getParamNumber(['RemoveMember', 'メンバー離脱']);
    var paramLevelUp      = getParamNumber(['LevelUp', 'レベルアップ']);
    var paramLevelDown    = getParamNumber(['LevelDown', 'レベルダウン']);
    var paramActorId      = getParamNumber(['ActorId', 'アクターID']);
    var paramValidOnlyMap = getParamBoolean(['ValidOnlyMap', 'マップ画面でのみ有効']);

    //=============================================================================
    // SceneManager
    //  トリガースイッチを設定処理を追加定義します。
    //=============================================================================
    var _SceneManager_pop = SceneManager.pop;
    SceneManager.pop      = function() {
        if (this._stack.length > 0) {
            this._scene.setPopTrigger();
        }
        _SceneManager_pop.apply(this, arguments);
    };

    SceneManager.setTriggerSwitch = function(switchNumber) {
        if ($gameSwitches && switchNumber > 0) {
            $gameSwitches._data[switchNumber] = true;
        }
    };

    SceneManager.setTriggerVariable = function(variableNumber, value) {
        if ($gameVariables && variableNumber > 0) {
            $gameVariables._data[variableNumber] = value;
        }
    };

    SceneManager.isTriggerValid = function() {
        return !paramValidOnlyMap || this._scene instanceof Scene_Map;
    };

    //=============================================================================
    // DataManager
    //  ニューゲーム、コンティニューのトリガースイッチを設定します。
    //=============================================================================
    var _DataManager_setupNewGame = DataManager.setupNewGame;
    DataManager.setupNewGame      = function() {
        _DataManager_setupNewGame.apply(this, arguments);
        SceneManager.setTriggerSwitch(paramNewGame);
    };

    var _DataManager_loadGame = DataManager.loadGame;
    DataManager.loadGame      = function(saveFileId) {
        var result = _DataManager_loadGame.apply(this, arguments);
        SceneManager.setTriggerSwitch(paramContinue);
        return result;
    };

    //=============================================================================
    // Game_Player
    //  場所移動時にトリガースイッチを設定します。
    //=============================================================================
    var _Game_Player_reserveTransfer      = Game_Player.prototype.reserveTransfer;
    Game_Player.prototype.reserveTransfer = function(mapId, x, y, d, fadeType) {
        _Game_Player_reserveTransfer.apply(this, arguments);
        SceneManager.setTriggerSwitch(paramMoveMap);
    };

    var _Game_Party_addActor      = Game_Party.prototype.addActor;
    Game_Party.prototype.addActor = function(actorId) {
        var length = this._actors.length;
        _Game_Party_addActor.apply(this, arguments);
        if (length !== this._actors.length && SceneManager.isTriggerValid()) {
            SceneManager.setTriggerSwitch(paramAddMember);
            SceneManager.setTriggerVariable(paramActorId, actorId);
        }
    };

    var _Game_Party_removeActor      = Game_Party.prototype.removeActor;
    Game_Party.prototype.removeActor = function(actorId) {
        var length = this._actors.length;
        _Game_Party_removeActor.apply(this, arguments);
        if (length !== this._actors.length && SceneManager.isTriggerValid()) {
            SceneManager.setTriggerSwitch(paramRemoveMember);
            SceneManager.setTriggerVariable(paramActorId, actorId);
        }
    };

    var _Game_Party_gainItem      = Game_Party.prototype.gainItem;
    Game_Party.prototype.gainItem = function(item, amount, includeEquip) {
        _Game_Party_gainItem.apply(this, arguments);
        if (!item || !SceneManager.isTriggerValid()) return;
        switch (this.itemContainer(item)) {
            case this._items:
                SceneManager.setTriggerSwitch(paramGainItem);
                break;
            case this._weapons:
                SceneManager.setTriggerSwitch(paramGainWeapon);
                break;
            case this._armors:
                SceneManager.setTriggerSwitch(paramGainArmor);
                break;
        }
        SceneManager.setTriggerVariable(paramItemId, item.id);
        SceneManager.setTriggerVariable(paramItemAmount, amount);
    };

    var _Game_Actor_levelUp = Game_Actor.prototype.levelUp;
    Game_Actor.prototype.levelUp = function() {
        _Game_Actor_levelUp.apply(this, arguments);
        if (SceneManager.isTriggerValid()) {
            SceneManager.setTriggerSwitch(paramLevelUp);
            SceneManager.setTriggerVariable(paramActorId, this.actorId());
        }
    };

    var _Game_Actor_levelDown = Game_Actor.prototype.levelDown;
    Game_Actor.prototype.levelDown = function() {
        _Game_Actor_levelDown.apply(this, arguments);
        if (SceneManager.isTriggerValid()) {
            SceneManager.setTriggerSwitch(paramLevelDown);
            SceneManager.setTriggerVariable(paramActorId, this.actorId());
        }
    };

    //=============================================================================
    // Scene_Base
    //  各クラス用のトリガースイッチを設定します。
    //=============================================================================
    Scene_Base.prototype.setPopTrigger = function() {
    };

    Scene_Options.prototype.setPopTrigger = function() {
        SceneManager.setTriggerSwitch(paramOptions);
    };

    Scene_Menu.prototype.setPopTrigger = function() {
        SceneManager.setTriggerSwitch(paramMenu);
    };

    Scene_Save.prototype.setPopTrigger = function() {
        SceneManager.setTriggerSwitch(paramSave);
    };

    Scene_Shop.prototype.setPopTrigger = function() {
        SceneManager.setTriggerSwitch(paramShop);
    };

    Scene_Battle.prototype.setPopTrigger = function() {
        SceneManager.setTriggerSwitch(paramBattle);
    };
})();

