//=============================================================================
// 第7版 - 初版
// 第8版 - 情報取得-全般-スイッチの項目に 三麻判定を追加
// 第9版 - 起動条件に一局終了時を追加、及び一局終了時の情報取得コマンドを追加
// 第9版2刷 - 情報取得コマンドの値を修訂
// 第10版 - 二人麻雀か を取得する項目を追加
// 第11版 - 二人麻雀の時に 自摸和了の場合でもロン和了のイベントが実行される不具合修訂
// 
//=============================================================================

/*:
 * @target MZ
 * @plugindesc 麻雀 (麻雀イベント)
 * @author 
 * @base AP1S_MajiangCore
 * @orderAfter AP1S_MajiangCore
 * @orderAfter AP1S_MajiangManagers
 * 
 * @help
 * 
 * 麻雀 (麻雀イベント)
 * 
 * このプラグインのプラグインコマンドは 「次の対局にイベントを登録」を除き
 * 麻雀対局中以外では使用できません 
 * 通常のイベントでは使用しないでください
 * 
 * 詳細な使用方法は 同梱の麻雀イベント説明書をご覧ください
 * 
 * 
 * 
 * @command setEvents
 * @text 次の対局にイベントを登録
 * @desc 次に開始される対局に対し麻雀イベントを設定します
 * 
 * @arg events
 * @text 登録するイベント
 * @desc 
 * @type struct<events>[]
 * @default []
 * 
 * 
 * 
 * 
 * @command getinfo_battler_switch
 * @text 情報取得-対局者-スイッチ
 * @desc 指定の対局者の情報を取得します
 * 
 * @arg battler
 * @text 指定の対局者
 * @desc 
 * @type select
 * @option 現在ツモ番の対局者[全] @value current
 * @option 副露、ロンした対局者[副,栄] @value target
 * @option プレイヤー[全] @value position_0
 * @option プレイヤーの下家[全] @value position_1
 * @option プレイヤーの対面[全] @value position_2
 * @option プレイヤーの上家[全] @value position_3
 * @option 東家[全] @value menfeng_1
 * @option 南家[全] @value menfeng_2
 * @option 西家[全] @value menfeng_3
 * @option 北家[全] @value menfeng_4
 * @default current
 * 
 * @arg info
 * @text 取得する情報
 * @desc 
 * @type select
 * @option 存在する @value exist
 * @option 親 @value method_isDealer
 * @option プレイヤー @value method_isPlayer
 * @option 聴牌している @value method_isTingpai
 * @option 立直している @value method_isLizhi
 * @option 門前 @value method_isMenqian
 * @option 起家 @value method_isQijia
 * @option 焼き鳥 @value method_yakitori
 * @option トップ目 @value top
 * @option ラス目 @value las
 * @option 立直をしていて一発圏内 @value yifa
 * @option 副露等のない一巡 @value method_yishun
 * @option 流し満貫の可能性がある @value method_isNagashiMangan
 * @default exist
 * 
 * @arg valueId
 * @text 出力スイッチ
 * @desc 取得した情報を次のスイッチに出力します
 * @type switch
 * @default 0 
 * 
 * 
 * 
 * 
 * @command getinfo_battler_variable
 * @text 情報取得-対局者-変数
 * @desc 指定の対局者の情報を取得します
 * 
 * @arg battler
 * @text 指定の対局者
 * @desc 
 * @type select
 * @option 現在ツモ番の対局者[全] @value current
 * @option 副露、ロンした対局者[副,栄] @value target
 * @option プレイヤー[全] @value position_0
 * @option プレイヤーの下家[全] @value position_1
 * @option プレイヤーの対面[全] @value position_2
 * @option プレイヤーの上家[全] @value position_3
 * @option 東家[全] @value menfeng_1
 * @option 南家[全] @value menfeng_2
 * @option 西家[全] @value menfeng_3
 * @option 北家[全] @value menfeng_4
 * @default current
 * 
 * @arg info
 * @text 取得する情報
 * @desc 
 * @type select
 * @option アクターID @value method_actorId
 * @option 座席ID @value method_position
 * @option 点数 @value method_point
 * @option 自風の風ID @value method_feng
 * @option 現在の順位 @value ranking
 * @option 向聴数 @value xiangting
 * @option 向聴数(四面子一雀頭) @value xiangtingNormal
 * @option 向聴数(七対子) @value xiangtingQiduizi
 * @option 向聴数(国士無双) @value xiangtingGuoshi
 * @option 晒した面子の数 @value mianziLength
 * @option 槓子の数 @value method_gangCount
 * @default method_actorId
 * 
 * @arg valueId
 * @text 出力変数
 * @desc 取得した数値を次の変数に出力します 
 * @type variable
 * @default 0 
 * 
 * 
 * 
 * 
 * 
 * 
 * 
 * 
 * 
 * @command getinfo_duiju_switch
 * @text 情報取得-全般-スイッチ
 * @desc 使用可能な起動条件 : [全]  対局の全般的な情報を取得します
 * 
 * @arg info
 * @text 取得する情報
 * @desc 
 * @type select
 * @option 現在オーラス @value allLast
 * @option 東南戦 @value match_0
 * @option 半荘戦 @value match_1
 * @option 一荘戦 @value match_2
 * @option 一局戦 @value match_3
 * @option 四人麻雀 @value quartet
 * @option 三麻 @value samma
 * @option 二人麻雀 @value duo
 * @default allLast
 * 
 * @arg valueId
 * @text 出力スイッチ
 * @desc 取得した情報を次のスイッチに出力します
 * @type switch 
 * @default 0 
 * 
 * 
 * 
 * 
 * @command getinfo_duiju_variable
 * @text 情報取得-全般-変数
 * @desc 使用可能な起動条件 : [全]  対局の全般的な情報を取得します
 * 
 * @arg info
 * @text 取得する情報
 * @desc 
 * @type select
 * @option 牌の残り枚数 @value shengyu
 * @option 現在の場風の風ID @value quanfeng
 * @option 現在の局 @value ju
 * @option 現在の本場 @value tsumibo
 * @option 現在の供託立直棒数 @value lizhibo
 * @option 現在までにカンが行われた数 @value gangCount
 * @option 現在の立直者数 @value lizhi
 * @default shengyu
 * 
 * @arg valueId
 * @text 出力変数
 * @desc 取得した数値を次の変数に出力します 
 * @type variable
 * @default 0 
 * 
 * 
 * 
 * 
 * 
 * @command getinfo_condition_switch
 * @text 情報取得-起動条件-スイッチ
 * @desc 使用可能な起動条件 : [全]  呼び出された起動条件を取得します
 * 
 * @arg info
 * @text 取得する情報
 * @desc 
 * @type select
 * @option 配牌完了後[配] @value kind_peipai
 * @option 自摸後[摸] @value kind_zimo
 * @option 打牌後[打] @value kind_dapai
 * @option 立直後[立] @value kind_lizhi
 * @option 暗、加カン後[槓] @value kind_gang
 * @option 自摸和了後[和] @value kind_zimoHele
 * @option 副露後[副] @value kind_fulu
 * @option ロン和了後[栄] @value kind_rong
 * @option 流局した後[流] @value kind_liuju
 * @default kind_peipai
 * 
 * @arg valueId
 * @text 出力スイッチ
 * @desc 取得した情報を次のスイッチに出力します
 * @type switch
 * @default 0 
 * 
 * 
 * 
 * 
 * @command getinfo_dapai_switch
 * @text 情報取得-最後の打牌-スイッチ
 * @desc 使用可能な起動条件 : [摸,打,立,槓,和,副,栄,流]  最後に打牌された牌の情報を取得します
 * 
 * @arg info
 * @text 取得する情報
 * @desc 
 * @type select
 * @option 存在する @value exist
 * @option 対象牌がドラ @value dora
 * @option 対象牌が赤ドラ @value method_isAkadora
 * @default dora
 * 
 * @arg valueId
 * @text 出力スイッチ
 * @desc 取得した情報を次のスイッチに出力します
 * @type switch
 * @default 0 
 * 
 * 
 * 
 * 
 * @command getinfo_dapai_variable
 * @text 情報取得-最後の打牌-変数
 * @desc 使用可能な起動条件 : [摸,打,立,槓,和,副,栄,流]  最後に打牌された牌の情報を取得します
 * 
 * @arg info
 * @text 取得する情報
 * @desc 
 * @type select
 * @option 対象牌の牌コード(赤ドラ区分あり) @value method_exportCode
 * @option 対象牌の牌コード(赤ドラ区分なし) @value method_code
 * @default method_exportCode
 * 
 * @arg valueId
 * @text 出力変数
 * @desc 取得した数値を次の変数に出力します 
 * @type variable
 * @default 0 
 * 
 * 
 * 
 * 
 * 
 * 
 * @command getinfo_lizhi_switch
 * @text 情報取得-立直-スイッチ
 * @desc 使用可能な起動条件 : [立]  立直の情報を取得します
 * 
 * @arg info
 * @text 取得する情報
 * @desc 
 * @type select
 * @option ダブル立直 @value double
 * @default double
 * 
 * @arg valueId
 * @text 出力スイッチ
 * @desc 取得した情報を次のスイッチに出力します
 * @type switch
 * @default 0 
 * 
 * 
 * 
 * @command getinfo_fulu_switch
 * @text 情報取得-副露-スイッチ
 * @desc 使用可能な起動条件 : [副]  副露の情報を取得します
 * 
 * @arg info
 * @text 取得する情報
 * @desc 
 * @type select
 * @option 対象の副露がチー @value kind_chi
 * @option 対象の副露がポン @value kind_peng
 * @option 対象の副露が大明槓 @value kind_daminggang
 * @default chi
 * 
 * @arg valueId
 * @text 出力スイッチ
 * @desc 取得した情報を次のスイッチに出力します
 * @type switch
 * @default 0 
 * 
 * 
 * 
 * @command getinfo_gang_switch
 * @text 情報取得-カン-スイッチ
 * @desc 使用可能な起動条件 : [槓]  暗槓、加槓の情報を取得します
 * 
 * @arg info
 * @text 取得する情報
 * @desc 
 * @type select
 * @option 対象のカンが暗槓 @value kind_angang
 * @option 対象のカンが加槓 @value kind_jiagang
 * @default angang
 * 
 * @arg valueId
 * @text 出力スイッチ
 * @desc 取得した情報を次のスイッチに出力します
 * @type switch
 * @default 0 
 * 
 * 
 * 
 * 
 * @command getinfo_hele_switch
 * @text 情報取得-和了-スイッチ
 * @desc 使用可能な起動条件 : [和,栄]  和了の情報を取得します
 * 
 * @arg info
 * @text 取得する情報
 * @desc 
 * @type select
 * @option 和了点数が満貫未満 @value mangan_0
 * @option 和了点数が満貫 @value mangan_1
 * @option 和了点数が跳満 @value mangan_2
 * @option 和了点数が倍満 @value mangan_3
 * @option 和了点数が三倍満 @value mangan_4
 * @option 和了点数が役満 @value mangan_5
 * @option 和了役に立直が含まれる @value heleYaku_lizhi
 * @option 和了役にダブル立直が含まれる @value heleYaku_doubleLizhi
 * @option 和了役に一発が含まれる @value heleYaku_yifa
 * @option 和了役に門前清自摸和が含まれる @value heleYaku_zimo
 * @option 和了役に断么九が含まれる @value heleYaku_duanyaojiu
 * @option 和了役に平和が含まれる @value heleYaku_pinghe
 * @option 和了役に一盃口が含まれる @value heleYaku_yibeikou
 * @option 和了役に二盃口が含まれる @value heleYaku_liangbeikou
 * @option 和了役に嶺上開花が含まれる @value heleYaku_lingshangKaihua
 * @option 和了役に海底撈月が含まれる @value heleYaku_haidiLaoyue
 * @option 和了役に河底撈魚が含まれる @value heleYaku_hediLaoyu
 * @option 和了役に場風牌が含まれる @value heleYaku_quanfeng
 * @option 和了役に自風牌が含まれる @value heleYaku_menfeng
 * @option 和了役に連風牌が含まれる @value heleYaku_lianfeng
 * @option 和了役に白が含まれる @value heleYaku_baiban
 * @option 和了役に發が含まれる @value heleYaku_lufa
 * @option 和了役に中が含まれる @value heleYaku_hongzhong
 * @option 和了役に北が含まれる @value heleYaku_bei
 * @option 和了役に槍槓が含まれる @value heleYaku_qianggang
 * @option 和了役に七対子が含まれる @value heleYaku_qiduizi
 * @option 和了役に対々和が含まれる @value heleYaku_duiduihe
 * @option 和了役に一気通貫が含まれる @value heleYaku_yiqiTongguan
 * @option 和了役に三色同順が含まれる @value heleYaku_sanseTongshun
 * @option 和了役に三色同刻が含まれる @value heleYaku_sanseTongke
 * @option 和了役に混全帯么九が含まれる @value heleYaku_hunquandai
 * @option 和了役に純全帯么九が含まれる @value heleYaku_chunquandai
 * @option 和了役に混老頭が含まれる @value heleYaku_hunlaotou
 * @option 和了役に清老頭が含まれる @value heleYaku_qinglaotou
 * @option 和了役に混一色が含まれる @value heleYaku_hunyise
 * @option 和了役に清一色が含まれる @value heleYaku_qingyise
 * @option 和了役に三暗刻が含まれる @value heleYaku_sananke
 * @option 和了役に四暗刻が含まれる @value heleYaku_sianke
 * @option 和了役に四暗刻単騎が含まれる @value heleYaku_siankeDanqi
 * @option 和了役に三槓子が含まれる @value heleYaku_sangangzi
 * @option 和了役に四槓子が含まれる @value heleYaku_sigangzi
 * @option 和了役に小三元が含まれる @value heleYaku_xiaosanyuan
 * @option 和了役に大三元が含まれる @value heleYaku_dasanyuan
 * @option 和了役に国士無双が含まれる @value heleYaku_guoshiwushuang
 * @option 和了役に純正国士無双が含まれる @value heleYaku_chunzhengGuoshi
 * @option 和了役に小四喜和が含まれる @value heleYaku_xiaosixi
 * @option 和了役に大四喜和が含まれる @value heleYaku_dasixi
 * @option 和了役に字一色が含まれる @value heleYaku_ziyise
 * @option 和了役に緑一色が含まれる @value heleYaku_luyise
 * @option 和了役に大車輪が含まれる @value heleYaku_dachelun
 * @option 和了役に九蓮宝燈が含まれる @value heleYaku_jiulianBaodeng
 * @option 和了役に純正九蓮宝燈が含まれる @value heleYaku_chunzhengJiulian
 * @option 和了役に天和が含まれる @value heleYaku_tianhe
 * @option 和了役に地和が含まれる @value heleYaku_dihe
 * @option 和了役に人和が含まれる @value heleYaku_renhe
 * @option 和了役に八連荘が含まれる @value heleYaku_balianzhuang
 * @option 和了役に三連刻が含まれる @value heleYaku_sanlianke
 * @option 和了役に四連刻が含まれる @value heleYaku_silianke
 * @option 和了役に一色三順が含まれる @value heleYaku_yiseSanshun
 * @option 和了役に一色四順が含まれる @value heleYaku_yiseSishun
 * @option 和了役に三風刻が含まれる @value heleYaku_sanfengke
 * @option 和了役に客風三刻が含まれる @value heleYaku_kefengSanke
 * @option 和了役に五門斉が含まれる @value heleYaku_wumenqi
 * @option 和了役に清海湖が含まれる @value heleYaku_qinghaihu
 * @option 和了役に十二落抬が含まれる @value heleYaku_shierLuotai
 * @option 和了役に紅孔雀が含まれる @value heleYaku_hongkongque
 * @option 和了役に大七星が含まれる @value heleYaku_daqixing
 * @option 和了役に黒一色が含まれる @value heleYaku_heiyise
 * @default mangan_0
 * 
 * @arg valueId
 * @text 出力スイッチ
 * @desc 取得した情報を次のスイッチに出力します
 * @type switch
 * @default 0 
 * 
 * 
 * 
 * 
 * @command getinfo_hele_variable
 * @text 情報取得-和了-変数
 * @desc 使用可能な起動条件 : [和,栄]  和了の情報を取得します
 * 
 * @arg info
 * @text 取得する情報
 * @desc 
 * @type select
 * @option 和了の点数 @value point
 * @option 和了の翻数 @value fan
 * @option 和了の符数 @value fu
 * @default point
 * 
 * @arg valueId
 * @text 出力変数
 * @desc 取得した情報を次の変数に出力します
 * @type variable
 * @default 0 
 * 
 * 
 * 
 * 
 * 
 * @command getinfo_liuju_switch
 * @text 情報取得-流局-スイッチ
 * @desc 使用可能な起動条件 : [流]  流局の情報を取得します
 * 
 * @arg info
 * @text 取得する情報
 * @desc 
 * @type select
 * @option 流局の種類が荒牌平局 @value kind_huangpaiPingju
 * @option 流局の種類が四家立直 @value kind_sijiaLizhi
 * @option 流局の種類が三家和流局 @value kind_sanjiaHe
 * @option 流局の種類が四開槓 @value kind_sikaigang
 * @option 流局の種類が四風連打 @value kind_sifengLianda
 * @option 流局の種類が九種九牌 @value kind_jiuzhongJiupai
 * @default kind_huangpaiPingju
 * 
 * @arg valueId
 * @text 出力スイッチ
 * @desc 取得した情報を次のスイッチに出力します
 * @type switch
 * @default 0 
 * 
 * 
 * 
 * 
 * @command getinfo_last_switch
 * @text 情報取得-一局終了-スイッチ
 * @desc 使用可能な起動条件 : [終]  一局終了時の情報を取得します
 * 
 * @arg info
 * @text 取得する情報
 * @desc 
 * @type select
 * @option これで終局 @value checkGameEnd
 * @option 親が和了または流局時聴牌 @value lianzhuang
 * @default checkGameEnd
 * 
 * @arg valueId
 * @text 出力スイッチ
 * @desc 取得した情報を次のスイッチに出力します
 * @type switch
 * @default 0 
 * 
 * 
 * 
 * 
 * @command getinfo_script
 * @text 情報取得-スクリプト
 * @desc スクリプトにより情報の取得を行います
 * 
 * @arg script
 * @text スクリプト
 * @desc 
 * @type multiline_string
 * @default
 * 
 * 
 * @command command_closeAllWindows
 * @text コマンド-ウィンドウを全て閉じる
 * @desc 使用可能な起動条件 : [全]  麻雀関連のウィンドウを全て閉じます
 * 
 * @command command_closeStatusWindow
 * @text コマンド-ステータスウィンドウを閉じる
 * @desc 使用可能な起動条件 : [全]  中央に評されるステータスウィンドウを閉じます
 * 
 * @command command_openAllWindows
 * @text コマンド-ウィンドウを全て開く
 * @desc 使用可能な起動条件 : [全]  閉じられている麻雀関連のウィンドウを全て開きます
 * 
 * 
 * @command command_forceTerminate
 * @text コマンド-対局を強制終了する
 * @desc 使用可能な起動条件 : [全]
 * 
 * 
 * 
 * 
 * 
 * 
 * 
 * 
 * 
 * 
 * 
 * 
 */
 
 
/*~struct~events:
 * 
 * @param condition
 * @text 起動条件
 * @desc このイベントが起動する条件を指定します
 * @type select
 * @option 配牌完了後[配] @value peipai
 * @option 自摸後[摸] @value zimo
 * @option 打牌後[打] @value dapai
 * @option 立直後[立] @value lizhi
 * @option 暗、加カン後[槓] @value gang
 * @option 自摸和了後[和] @value zimoHele
 * @option 副露後[副] @value fulu
 * @option ロン和了後[栄] @value rong
 * @option 流局した後[流] @value liuju
 * @option 一局が終了した後[終] @value last
 * @default peipai
 * 
 * @param commonId
 * @text 実行するコモンイベント
 * @desc 起動条件を満たしたとき 次のイベントを実行します
 * @type common_event
 * @default 0
 */

 


( function()
{
	'use strict';
	
	const P_name = decodeURIComponent(document.currentScript.src).match(/([^\/]+)\.js$/)[1]; //プラグイン名
	
	
	
	
	//----------------
	
	const _MajiangManager_start = MajiangManager.start;
	MajiangManager.start = function()
	{
		this._interpreter = new Game_Interpreter();
		this.clearEventData();
		this.setEventData();
		
		_MajiangManager_start.apply(this,arguments);
	};
	
	const _MajiangManager_setTerminate = MajiangManager.setTerminate;
	MajiangManager.setTerminate = function()
	{
		_MajiangManager_setTerminate.apply(this,arguments);
		this.clearEventData();
		this._interpreter = null;
		PC_CheckCondition.terminate();
	};
	
	
	
	MajiangManager.clearEventData = function()
	{
		this._eventData = [];
		this._eventRunning = false;
		this._events = [];
	};
	
	
	MajiangManager.setEventData = function()
	{
		this._eventData = $dataMajiangSystem.temp?.events || [];
	};
	
	
	
	
	MajiangManager.startEvent = function(common,args)
	{
		if(common)
		{
			this._eventRunning = true;
			PC_CheckCondition.set(args);
			
			this._interpreter.setup(common.list);
			this._interpreter.update();
		}
	};
	
	
	
	MajiangManager.findCommonId = function(condition)
	{
		const events = this._eventData.filter(e => e.condition === condition);
		return events.map(e => e.commonId);
	};
	
	MajiangManager.eventRunning = function()
	{
		return (this._interpreter.isRunning());
	}
	MajiangManager.updateEvent = function()
	{
		if(this._eventRunning)
		{
			if(this.eventRunning())
			{
				this._interpreter.update();
			}
			else
			{
				this.terminateEvent();
			}
		}
	};
	
	MajiangManager.terminateEvent = function()
	{
		this._eventRunning = false;
		this.requestOpenAllWindows();
	};
	
	
	
	
	MajiangManager.pushEvent = function(condition ,current,target,action,dapai)
	{
		const commons = this.findCommonId(condition);
		
		const args = {};
		args.condition = condition;
		args.current = current;
		args.target = target;
		
		args.action = action;
		args.dapai = dapai;
		
		for(const commonId of commons)
		{
			const common = $dataCommonEvents[commonId];
			if(common)
			{
				this.push("startEvent",common,args);
			}
		}
	};
	
	const _MajiangManager_peipaiCompleted = MajiangManager.peipaiCompleted;
	MajiangManager.peipaiCompleted = function()
	{
		_MajiangManager_peipaiCompleted.apply(this,arguments);
		this.pushEvent("peipai",this.currentBattler());
		
	};
	
	const _MajiangManager_zimoEvent = MajiangManager.zimoEvent;
	MajiangManager.zimoEvent = function()
	{
		_MajiangManager_zimoEvent.apply(this,arguments);
		const current = this.currentBattler();
		this.pushEvent("zimo",current,null,null,this._dapai);
	};
	
	const _MajiangManager_applyDapai = MajiangManager.applyDapai;
	MajiangManager.applyDapai = function()
	{
		_MajiangManager_applyDapai.apply(this,arguments);
		const current = this.currentBattler();
		this.pushEvent("dapai",current,null,null,this._dapai);
		
	};
	
	
	
	
	
	
	
	const _MajiangManager_setActionLines = MajiangManager.setActionLines;
	MajiangManager.setActionLines = function(battler,action)
	{
		const current = this.currentBattler();
		
		let target = null;
		let key = "";
		switch(action.kind)
		{
			case "chi" : 
			case "peng" : 
			case "daminggang" : 
				target = battler; 
				key = "fulu"; 
			break;
			/*
			case "rong" : 
				target = battler;
				key = "rong";
			break;
			case "zimo" : 
				key = "zimoHele";
			break;
			*/
			case "jiuzhongJiupai" :
				key = "jiuzhongJiupai";
			break;
			case "angang" : 
			case "jiagang":
				key = "gang";
			break;
		}
		
		_MajiangManager_setActionLines.apply(this,arguments);
		if(key)
		{
			this.pushEvent(key,current,target,action,this._dapai);
		}
	};
	
	const _MajiangManager_startEndYiju = MajiangManager.startEndYiju;
	MajiangManager.startEndYiju = function()
	{
		const helejia = this.helejia();
		if(helejia.length > 0)
		{
			const current = this.currentBattler();
			
			if(this._isRong)
			{
				for(const target of helejia)
				{
					this.pushEvent("rong",current,target,null,this._dapai);
				}
			}
			else
			{
				this.pushEvent("zimoHele",current,null,null,this._dapai);
			}
		}
		_MajiangManager_startEndYiju.apply(this,arguments);
	};
	
	
	
	const _MajiangManager_setLizhiLines = MajiangManager.setLizhiLines;
	MajiangManager.setLizhiLines = function(battler,isDouble)
	{
		const action = {"isDouble" : isDouble};
		
		_MajiangManager_setLizhiLines.apply(this,arguments);
		this.pushEvent("lizhi",battler,null,action,this._dapai);
	};
	
	
	
	
	
	const _MajiangManager_setLiujuMessage = MajiangManager.setLiujuMessage;
	MajiangManager.setLiujuMessage = function()
	{
		const current = this.currentBattler();
		_MajiangManager_setLiujuMessage.apply(this,arguments);
		this.pushEvent("liuju",current,null,this._liuju,this._dapai);
	};
	
	MajiangManager.setEndGameEvent = function()
	{
		const current = this.currentBattler();
		this.pushEvent("last",current,null,null,this._dapai);
		
	};
	
	
	
	class CheckCondition
	{
		set(args)
		{
			this.clear();
			this._data = args;
		}
		
		terminate()
		{
			this.clear();
		}
		
		query(type,info,kind,valueId ,args)
		{
			const methodName = [type + "_" + info];
			if(!this[methodName])
			{
				throw new Error("Method not found: " + methodName);
			}
			let value = false;
			if(!this.checkCallStatus(type,this._data.condition))
			{
				value = ((kind === "switch") ? false : -1);
			}
			else
			{
				value = this[methodName](...args);
			}
			
			if(kind === "switch")
			{
				$gameSwitches.setValue(valueId,value);
			}
			else
			{
				$gameVariables.setValue(valueId,value);
			}
		}
		checkCallStatus(type,condition)
		{
			if(    (type === "battler" && !this.battler())
				|| (type === "dapai" && !this.dapai())
				|| (type === "hele" && !this.helejia())
			)
			{
				return false;
			}
			if(["liuju","fulu","gang","lizhi"].includes(type) && type !== condition)
			{
				return false;
			}
			return true;
		}
		
		clear()
		{
			this._data = {};
		}
		
		setBattlerType(type)
		{
			this._battlerType = type;
		}
		
		battler()
		{
			const b = $gameMajiangBattlers;
			const data = this._battlerType.split("_");
			const value = Number(data[1]);
			switch(data[0])
			{
				case "position" : return b.battler(value);
				case "menfeng" : return b.allBattlers().find(b => b.menfeng() === value);
				default : return this._data[this._battlerType];
			}
		}
		current()
		{
			return this._data.current;
		}
		
		target()
		{
			return this._data.target;
		}
		script(text)
		{
			eval(text);
		}
		
		helejia()
		{
			switch(this._data.condition)
			{
				case "zimoHele" : 
					return this._data.current;
				case "rong" : 
					return this._data.target;
			}
		}
		dapai()
		{
			return this._data.dapai;
		}
		
		battler_exist()
		{
			return !!(this.battler());
		}
		
		
		battler_top()
		{
			return (MajiangManager.topBattler() === this.battler());
		}
		battler_las()
		{
			return (MajiangManager.lastBattler() === this.battler());
		}
		battler_yifa()
		{
			return (this.battler().isLizhi() && this.battler().yifa());
		}
		
		
		
		battler_method(methodName)
		{
			return this.battler()[methodName]();
		}
		
		battler_ranking()
		{
			const ranking = MajiangManager.currentRanking();
			const battler = this.battler();
			return ranking.findIndex(b => b === battler) + 1;
		}
		
		battler_xiangting()
		{
			const tehai = this.battler().tehai().map(p => p.code());
			return $gameMajiangPaishan.countXiangting(tehai);
		}
		battler_xiangtingNormal()
		{
			const tehai = this.battler().tehai().map(p => p.code());
			return $gameMajiangPaishan.countXiangting(tehai,["normal"]);
		}
		battler_xiangtingQiduizi()
		{
			const tehai = this.battler().tehai().map(p => p.code());
			return $gameMajiangPaishan.countXiangting(tehai,["qiduizi"]);
		}
		battler_xiangtingGuoshi()
		{
			const tehai = this.battler().tehai().map(p => p.code());
			return $gameMajiangPaishan.countXiangting(tehai,["guoshiwushuang"]);
		}
		
		battler_heLength()
		{
			return this.battler().he().length;
		}
		battler_mianziLength()
		{
			return this.battler().fulu().length;
		}
		battler_gangCount()
		{
			return this.battler().gangCount();
		}
		
		duiju_allLast()
		{
			return MajiangManager.currentAllLast();
		}
		
		duiju_match(match)
		{
			return ($gameMajiangSystem.gamerule.match == Number(match));
		}
		duiju_quartet()
		{
			return MajiangManager.quartet();
		}
		duiju_samma()
		{
			return MajiangManager.samma();
		}
		duiju_duo()
		{
			return MajiangManager.duo();
		}
		
		duiju_shengyu()
		{
			return $gameMajiangPaishan.shengyu();
		}
		
		duiju_quanfeng()
		{
			return MajiangManager.currentQuanfeng();
		}
		
		duiju_ju()
		{
			return MajiangManager.currentJu();
		}
		
		duiju_tsumibo()
		{
			return MajiangManager.tsumibo();
		}
		
		duiju_lizhibo()
		{
			return MajiangManager.lizhibo();
		}
		
		duiju_gangCount()
		{
			return MajiangManager.gangCount();
		}
		
		duiju_lizhi()
		{
			const all = $gameMajiangBattlers.allBattlers();
			return all.filter(b => b.isLizhi()).length;
		}
		
		condition_kind(kind)
		{
			return (kind === this._data.condition);
		}
		dapai_exist()
		{
			return !!(this.dapai());
		}
		
		dapai_dora()
		{
			return (this.dapai().dora() > 0);
		}
		
		dapai_method(methodName)
		{
			return this.dapai()[methodName]();
		}
		
		
		
		
		lizhi_doubleLizhi()
		{
			return !!this._data.action.isDouble;
		}
		
		fulu_kind(kind)
		{
			return (this._data.action.kind === kind);
		}
		
		gang_kind(kind)
		{
			return (this._data.action.kind === kind);
		}
		
		hele_mangan(value)
		{
			return (this.helejia().manganRank() === Number(value));
		}
		hele_heleYaku(yaku)
		{
			const result = this.helejia().heleResult();
			return (result.yaku.yakuResult.find(y => y.name === yaku));
		}
		hele_point()
		{
			return (this.helejia().heleResult().point.gainPoint);
		}
		hele_fan()
		{
			const result = this.helejia().heleResult();
			if(result.point.yakuman)
			{
				return -result.point.yakuman;
			}
			return (result.point.fan);
		}
		hele_fu()
		{
			return (this.helejia().heleResult().point.fu);
		}
		
		liuju_kind(kind)
		{
			return (this._data.action === kind);
		}
		
		last_checkGameEnd()
		{
			return MajiangManager.checkGameEnd();
		}
		last_lianzhuang()
		{
			return MajiangManager.isLianzhuang();
		}
	}
	
	const PC_CheckCondition = new CheckCondition();
	
	const PF_setCommand = function(commandName,args)
	{
		const name = commandName.split("_");
		const type = name[1];
		const kind = name[2];
		const data = (args.info || "").split("_");
		const info = data[0];
		const valueId = Number(args.valueId);
		const methodArgs = data.slice(1);
		
		if(args.battler)
		{
			PC_CheckCondition.setBattlerType(args.battler);
		}
		
		PC_CheckCondition.query(type,info,kind,valueId,methodArgs);
	};
	
	
	(() =>
	{
		const commandName = [
			"getinfo_battler_switch",
			"getinfo_battler_variable",
			"getinfo_duiju_switch",
			"getinfo_duiju_variable",
			"getinfo_condition_switch",
			"getinfo_dapai_switch",
			"getinfo_dapai_variable",
			"getinfo_lizhi_switch",
			"getinfo_fulu_switch",
			"getinfo_gang_switch",
			"getinfo_hele_switch",
			"getinfo_hele_variable",
			"getinfo_liuju_switch",
			"getinfo_last_switch",
		];
		
		for(const name of commandName)
		{
			PluginManager.registerCommand(P_name,name,args =>  
			{
				PF_setCommand(name,args)
			});
		}
	})();
	
	PluginManager.registerCommand(P_name,"getinfo_script",args =>  
	{
		PC_CheckCondition.script(args.script);
	});
	
	PluginManager.registerCommand(P_name,"setEvents",args =>  
	{
		$dataMajiangSystem.temp.events = JSON.parse(args.events || "[]").map(d =>
		{
			
			const ret = JSON.parse(d)
			ret.commonId = Number(ret.commonId);
			return ret;
		});
		
	});
	
	
	
	PluginManager.registerCommand(P_name,"command_forceTerminate",args =>  
	{
		MajiangManager.requestTerminate();
	});
	
	
	PluginManager.registerCommand(P_name,"command_closeAllWindows",args =>  
	{
		MajiangManager.requestCloseAllWindows();
	});
	
	PluginManager.registerCommand(P_name,"command_closeStatusWindow",args =>  
	{
		MajiangManager.requestCloseStatusWindow();
	});
	
	PluginManager.registerCommand(P_name,"command_openAllWindows",args =>  
	{
		MajiangManager.requestOpenAllWindows();
	});
	
})();













