require("th105_ai_lib_20090203WaitEx.txt")			--waitEx, waitTachi

--SetInput		version20090203		（変更点は末尾に記載）

--機能：引数commandで与えられた文字列を元にコマンド入力する
--		
--		コマンド入力中は引数exceptionで与えられた関数にelapsedFrameを与えて呼び出し、戻り値>0の場合はコマンド入力を中断する
--
--使用例1：SetInput("236C")
--使用例2：SetInput("A(7)A(51)4B(15)6C5(15)236C", checkEnemyGround)
--
--使用カスタマイズ関数：waitEx(), waitTachi()
--使用定数：キー：ACT_UP〜ACT_BC
function SetInput( command , exception )

	local counter = 1	--現在何番目の文字を処理しているか
	local oldInput = ""	--文字列比較を行うため、nil以外の初期値を設定する
	local waitProc		--waitフレーム数指定文字列作成中か。作成中ならtrue
	local excCode = 0	--引数で与えられた関数exceptionの戻り値を格納する。0より大きい場合コマンド入力を中断する
	local elapsedFrame = 0		--SetInputを呼び出した直後からの経過フレーム数（yieldした回数）
	
	--引数で与えられたコマンド1文字ずつについて入力処理を行う
	for input in string.gmatch( command, ".") do

	local front_=front;
	local back_=back;
		if not(is_dir_front)then
			front_=back;
			back_=front;
		end
	local front=front_;
	local back=back_;
		
		--A〜Eの後にyieldとkey_offとyieldをはさむ。("6C"は同時押しできる。"AxA"はxの前にA離す)
		if oldInput >= "A" and oldInput <= "E" then
			--直前がA〜Eの場合
			--現在の値が"H"なら、key_offせずホールド(押しっぱ)とする。
			if input == "H" then
				--なにもしない
			else
				--上記以外の場合
				--現在の値に関わらず、その前にyieldする
				--1フレより2フレのほうが、キー抜け(コマンド失敗)の確率が低い
				excCode = waitEx(2-1, exception, elapsedFrame)
				elapsedFrame = elapsedFrame + 2-1	--waitEx第一引数のぶんだけカウントアップ
				if excCode > 0 then
					return excCode	--戻り値>0の場合、コマンド入力を中断
						--waitTachi()は呼び出さない（コマンド中断後にいろいろな動作をさせられるようにするため）
				end
				--現在の値に関わらず、その前に直前A〜Eをkey_offする。
				key_off( ACT_A )
				key_off( ACT_B )
				key_off( ACT_C )
				key_off( ACT_D )
				key_off( ACT_AB )	--E
				key_off( ACT_BC )	--F
				--現在の値に関わらず、その前にyieldする
				--1フレより2フレのほうが、キー抜け(コマンド失敗)の確率が低い
				excCode = waitEx(2-1, exception, elapsedFrame)
				elapsedFrame = elapsedFrame + 2-1	--waitEx第一引数のぶんだけカウントアップ
				if excCode > 0 then
					return excCode	--戻り値>0の場合、コマンド入力を中断
				end
			end
		elseif oldInput >= "a" and oldInput <= "e" then
			--直前がa〜eの場合
			--現在の値に関わらず、その前にyieldする
			excCode = waitEx(1, exception, elapsedFrame)
			elapsedFrame = elapsedFrame + 1	--waitEx第一引数のぶんだけカウントアップ
			if excCode > 0 then
				return excCode	--戻り値>0の場合、コマンド入力を中断
			end
		end
		
		if waitProc then
			--waitフレーム数指定用文字列作成中の場合
			
			if input >= "0" and input <= "9" then
				--"0"〜"9"を元にwaitフレーム数指定用文字列を作成する
				waitString = waitString .. input
			elseif input == ")" then
				--括弧で囲まれた文字を数値としてwaitする
				excCode = waitEx(tonumber(waitString), exception, elapsedFrame)
				elapsedFrame = elapsedFrame + tonumber(waitString)	--waitEx第一引数のぶんだけカウントアップ
				if excCode > 0 then
					return excCode	--戻り値>0の場合、コマンド入力を中断
				end
				waitProc = false
			end
		else
			--上記以外の場合
			--(通常の場合)
		
			--1〜9の前にkey_offとyieldをはさむ。("236C"ができる。)
			if input >= "1" and input <= "9" then
				--現在1〜9の場合
				--1〜9の前にyieldする(ただし1文字目はyieldしない)
				if counter > 1 then
					--1フレより2フレのほうが、キー抜け(コマンド失敗)の確率が低い
					excCode = waitEx(2-1, exception, elapsedFrame)
					elapsedFrame = elapsedFrame + 2-1	--waitEx第一引数のぶんだけカウントアップ
					if excCode > 0 then
						return excCode	--戻り値>0の場合、コマンド入力を中断
					end
				end
				--1〜9の前に全方向key_offする
				--全方向キーoff
				key_off( ACT_UP )
				key_off( ACT_DOWN )
				key_off( ACT_LEFT )
				key_off( ACT_RIGHT )
				key_off( ACT_DOWNLEFT )
				key_off( ACT_DOWNRIGHT )
				key_off( ACT_UPLEFT )
				key_off( ACT_UPRIGHT )
			end
		
			--"1"〜"9", "A〜E"などの文字を元にキー入力を行う
			if input == "1" then
				key_on( ACT_DOWN )
				key_on( back )
			elseif input == "2" then
				key_on( ACT_DOWN )
			elseif input == "3" then
				key_on( ACT_DOWN )
				key_on( front )
			elseif input == "4" then
				key_on( back )
			elseif input == "5" then
				--レバーニュートラル(別途"1"〜"9"共通処理にて処理済)
			elseif input == "6" then
				key_on( front )
			elseif input == "7" then
				key_on( ACT_UP )
				key_on( back )
			elseif input == "8" then
				key_on( ACT_UP )
			elseif input == "9" then
				key_on( ACT_UP )
				key_on( front )
			--ボタン押し
			elseif input == "A" then
				key_on( ACT_A )
			elseif input == "B" then
				key_on( ACT_B )
			elseif input == "C" then
				key_on( ACT_C )
			elseif input == "D" then
				key_on( ACT_D )
			elseif input == "E" then
				key_on( ACT_AB )
			elseif input == "F" then
				key_on( ACT_BC )
			elseif input == "H" then
				--ホールド(別途処理済)
			--ホールド(押しっぱ)解除
			elseif input == "a" then
				key_off( ACT_A )
			elseif input == "b" then
				key_off( ACT_B )
			elseif input == "c" then
				key_off( ACT_C )
			elseif input == "d" then
				key_off( ACT_D )
			elseif input == "e" then
				key_off( ACT_AB )
			elseif input == "f" then
				key_off( ACT_BC )
			--yield
			elseif input == "(" then
				waitProc = true
				waitString = ""	--初期化
			elseif input == "_" then
				excCode = waitEx(1, exception, elapsedFrame)
				elapsedFrame = elapsedFrame + 1	--waitEx第一引数のぶんだけカウントアップ
				if excCode > 0 then
					return excCode	--戻り値>0の場合、コマンド入力を中断
				end
			elseif input == "v" then
				excCode = waitEx(5, exception, elapsedFrame)
				elapsedFrame = elapsedFrame + 5	--waitEx第一引数のぶんだけカウントアップ
				if excCode > 0 then
					return excCode	--戻り値>0の場合、コマンド入力を中断
				end
			elseif input == "x" then
				excCode = waitEx(10, exception, elapsedFrame)
				elapsedFrame = elapsedFrame + 10	--waitEx第一引数のぶんだけカウントアップ
				if excCode > 0 then
					return excCode	--戻り値>0の場合、コマンド入力を中断
				end
			end
		end
		
		--1文字前の入力コマンドの値を保存する
		oldInput = input
		--何番目の文字を処理しているかの変数をカウントアップする
		counter = counter + 1
	end
	
	--文字列loop後
	--最後のキー入力を成立させるためyieldする
	--1フレより2フレのほうが、キー抜け（コマンド失敗）の確率が低い
	excCode = waitEx(2, exception, elapsedFrame)
	elapsedFrame = elapsedFrame + 2	--waitEx第一引数のぶんだけカウントアップ
	if excCode > 0 then
		return excCode	--戻り値>0の場合、コマンド入力を中断
	end
	--方向キーもボタンも離す
	--問題：ホールド(押しっぱ)終了ができない。対策：押しっぱ部分はSetInputを使わず、押しっぱ直前までの入力にし、押しっぱは別途記述する
	key_reset()
	--yieldする。問題：最後Cだと最速ではない(1フレ余分)。最速欲しいなら別途関数作って対処
	excCode = waitEx(1, exception, elapsedFrame)
	elapsedFrame = elapsedFrame + 1	--waitEx第一引数のぶんだけカウントアップ
	if excCode > 0 then
		return excCode	--戻り値>0の場合、コマンド入力を中断
	end
	
	--立ち状態になるまで待つ（技実行中は関数を終了しない）（理由：そのほうが使う機会が多そうだしソースすっきりしそうなので）
	--問題：技の途中で関数を終了したいとき困る。対策：需要多いなら引数オプションで拡張
--	waitTachi()
	
	return excCode
end


--カスタマイズ
--		version20090203からの変更点
--			・最後のwaitTachi()が邪魔だったのでオミット。
--			・入力間の待ちを2フレから1フレに短縮。
--			・相手が後ろに居る場合でも意図したコマンドが出るようにfrontとbackを調整。
--
--version20090203
--		version20090113からの変更点
--			・関数waitEx()　の呼出に第3引数 elapsedFrame 追加
--			  用途：関数exceptionにSetInput内部情報（SetInput呼び出し直後からの経過フレーム数）を与える
--			・戻り値変更：コマンド完了時にexcCode（実質0）を戻り値にセットするようにした
--			  以前はnilを戻り値にしており、呼び出し元で数値比較をするとPANIC
--			・bug修正："A(20)"が"A(2)"に解釈されるbugを修正（"1"〜"9"対象を"0"〜"9"対象に修正）
--version20090113
--		version20090105からの変更点
--			・" "を廃止。かわりに"_"とする。(スレで連続した複数の半角スペースは1文字に変換されるため)
--			・"o"を廃止。かわりに"H"とする。
--			・"x"と同じ意味として、"(10)"という表記も使えるようにした。例：短さ優先で丁度10フレなら"x"を。わかりやすさ優先なら"(10)"を使う
--			・引数exceptionで与えられた関数を呼び出し、戻り値>0であればそれを戻り値にセットして関数終了。
--			  用途例：相手が地上にいなければコンボ中断、など
