/* _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

	FILE	: Field.cpp

+ ------ Explanation of file --------------------------------------------------------------------------

+ _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ */

#include "Common.h"

#include "systemManager.h"
#include "CardData.h"
#include "textureManager.h"
#include "Mouse.h"
#include "Scene.h"
#include "Phase.h"
#include "Dialog.h"
#include "FieldMenu.h"
#include "animeCalc.h"
#include "Skill.h"

#include "Field.h"

// 移動セット(追加)
#define ADDMOVE		((int)m_moveList.size())
// 移動セット(同時)
#define SAMEMOVE	(!m_moveList.empty() ? m_moveList.back().id : 0)

// 移動：末尾に追加
#define MOVEBACK	-1

// 座標データ
VEC3	gCardPos[ZONE_MAX][PLY_NUM] ={
	VEC3(2.8f, 0.0f, -1.0f),	// デッキ
	VEC3(-2.8f, 0.0f,  1.0f),
	VEC3(2.8f, 0.0f, -2.0f),	// 捨札
	VEC3(-2.8f, 0.0f,  2.0f),
	VEC3(2.94f,0.0f, -0.2f),	// 除外
	VEC3(-2.94f,0.0f,  0.2f),
	VEC3(0.0f, 2.1f, -3.9f),	// 手札
	VEC3(0.0f, 1.0f,  2.0f),
	VEC3(-1.5f, 0.0f, -0.7f),	// プログレス
	VEC3(1.5f, 0.0f,  0.7f),
	VEC3(-1.4f, 0.0f, -1.8f),	// エナジー
	VEC3(1.4f, 0.0f,  1.8f),
	VEC3(-2.6f, 0.0f, -0.7f),	// ダメージ
	VEC3(2.6f, 0.0f,  0.7f),
	VEC3(1.5f, 0.0f, -1.8f),	// アクション
	VEC3(-1.2f, 0.0f,  1.8f),
	VEC3(0.0f, 2.8f, -3.2f),	// 処理場
	VEC3(0.0f, 2.8f, -3.2f),
};

// 角度データ(表の状態)
VEC3	gCardDeg[ZONE_MAX][PLY_NUM] ={
	VEC3(  0.0f,   0.0f,   0.0f),	// デッキ
	VEC3(  0.0f, 180.0f,   0.0f),
	VEC3(  0.0f,   0.0f,   0.0f),	// 捨札
	VEC3(  0.0f, 180.0f,   0.0f),
	VEC3(  0.0f,  90.0f,   0.0f),	// 除外
	VEC3(  0.0f, 270.0f,   0.0f),
	VEC3(-35.0f,   0.0f,   0.0f),	// 手札
	VEC3(-110.0f,  0.0f,   0.0f),
	VEC3(  0.0f,   0.0f,   0.0f),	// プログレス
	VEC3(  0.0f, 180.0f,   0.0f),
	VEC3(  0.0f,   0.0f,   0.0f),	// エナジー
	VEC3(  0.0f, 180.0f,   0.0f),
	VEC3(  0.0f, -90.0f,   0.0f),	// ダメージ
	VEC3(  0.0f,  90.0f,   0.0f),
	VEC3(  0.0f,   0.0f,   0.0f),	// アクション
	VEC3(  0.0f, 180.0f,   0.0f),
	VEC3(-30.0f,   0.0f,   0.0f),	// 処理場
	VEC3(-30.0f,   0.0f,   0.0f),
};

//! vectorソート用
bool operator<(const CARDMOVE& left, const CARDMOVE& right)
{
	return left.id < right.id;
}
bool operator>(const CARDMOVE& left, const CARDMOVE& right)
{
	return left.id > right.id;
}

//! コンストラクタ
Field::Field()
{
}

//! デストラクタ
Field::~Field()
{
	release();
}

//! 解放
void Field::release(void)
{
	for(int ply = 0; ply < PLY_NUM; ply++){
		for(int i = 0; i < DECK_MAX; i++){
			SAFE_DELETE(m_pCard[ply][i]);
		}
		for(int i = 0; i < PROGRESS_MAX; i++){
			SAFE_DELETE(m_pPrgDmy[ply][i]);
		}
	}
}

//! 初期化
void Field::init(Phase* pPhase, Dialog* pDialog, FieldMenu* pMenu, CardData* pCardData)
{
	m_pTexMan = SystemManager::getInstance()->getTexMan();
	m_pMouse = SystemManager::getInstance()->getMouse();
	m_pCamera = SystemManager::getInstance()->getCamera();
	m_pPhase = pPhase;
	m_pDialog = pDialog;
	m_pMenu = pMenu;
	pCardData;

	ZeroMemory(m_pDeck,		sizeof(m_pDeck));
	ZeroMemory(m_pDisCard,	sizeof(m_pDisCard));
	ZeroMemory(m_pExcude,	sizeof(m_pExcude));
	ZeroMemory(m_pHand,		sizeof(m_pHand));
	ZeroMemory(m_pProgress,	sizeof(m_pProgress));
	ZeroMemory(m_pEnergy,	sizeof(m_pEnergy));
	ZeroMemory(m_pDamage,	sizeof(m_pDamage));
	ZeroMemory(m_pAction,	sizeof(m_pAction));
	ZeroMemory(m_pTemp,		sizeof(m_pTemp));
	ZeroMemory(m_pPrgDmy,	sizeof(m_pPrgDmy));

	for(int ply = 0; ply < PLY_NUM; ply++){
		for(int i = 0; i < DECK_MAX; i++){
			// カード生成
			m_pCard[ply][i] = new Card();
			Card* pCard = getCard(ply, i);
			pCard->init(pCardData);
			pCard->setData(pCardData->getDeck(ply, i)->serNo);
			if(ply == PLY_1P){
				pCard->m_sleeveTexID = m_pTexMan->loadTexture(TEXLOAD_SLEEVE1R);
			}else{
				pCard->m_sleeveTexID = m_pTexMan->loadTexture(TEXLOAD_SLEEVE2R);
			}
			pCard->m_brightTexID = m_pTexMan->loadTexture(TEXLOAD_CARDBRIGHT);

			// デッキに登録
			setDeck(ply, i, getCard(ply, i), false);
			getDeck(ply, i)->setPos(getFieldPos(ply, ZONE_DECK, i));
			getDeck(ply, i)->setDegree(getFieldDegree(ply, ZONE_DECK, i, true, false));
		}
		// ダミー生成
		for(int i = 0; i < PROGRESS_MAX; i++){
			m_pPrgDmy[ply][i] = new Card();
			Card* pCard = getPrgDmy(ply, i);
			pCard->init(pCardData);
			pCard->m_ply = ply;
			pCard->m_zone = ZONE_PROGRESS;
			pCard->m_num = i;
			pCard->m_select = SELECT_LOCK;
			pCard->m_isTransDraw = true;
			pCard->m_ci = CARD_INFO("", -1, -1, 0, 0, 0, 0, FRAME_NON, false, TYPE_PG, "", -1);
			pCard->setPos(getFieldPos(ply, ZONE_PROGRESS, i));
			pCard->setDegree(getFieldDegree(ply, ZONE_PROGRESS, i, true, true));
			pCard->m_brightTexID = m_pTexMan->loadTexture(TEXLOAD_CARDBRIGHT);
		}
	}
}

//! 更新
void Field::update(void)
{
	for(int ply = 0; ply < PLY_NUM; ply++){
		for(int i = 0; i < DECK_MAX; i++){
			getCard(ply, i)->update();
		}
		for(int i = 0; i < PROGRESS_MAX; i++){
			getPrgDmy(ply, i)->update();
		}
	}

	updateMove();
	updateSelect();
}

//! 描画
void Field::draw(void)
{
	for(int ply = 0; ply < PLY_NUM; ply++){
		for(int i = 0; i < DECK_MAX; i++){
			if(getCard(ply, i)){
				getCard(ply, i)->draw();
			}
		}
		for(int i = 0; i < PROGRESS_MAX; i++){
			if(!getProgress(ply, i) && getPrgDmy(ply, i)->m_select != SELECT_LOCK){
				getPrgDmy(ply, i)->draw();
			}
		}
	}
}

//! 移動更新
void Field::updateMove(void)
{
	// カード更新
	bool isAnime = false;
	for(int ply = 0; ply < PLY_NUM; ply++){
		for(int i = 0; i < DECK_MAX; i++){
			if(getCard(ply, i)->getAnimeCalc()->isRun()){
				isAnime = true;
			}
		}
		for(int i = 0; i < PROGRESS_MAX; i++){
			if(getPrgDmy(ply, i)->getAnimeCalc()->isRun()){
				isAnime = true;
			}
		}
	}

	// 全カード停止
	if(!isAnime && !m_moveList.empty()){
		sort(m_moveList.begin(), m_moveList.end());

		// 動かしている最中
		if(m_moveList.begin()->isAnime){
			// 対象ID全てのアニメチェック
			bool isRun = false;
			for(iteCardMove ite = m_moveList.begin(); ite != m_moveList.end(); ite++){
				if(m_moveList.begin()->id != ite->id){
					break;
				}
				if(ite->pCard->getAnimeCalc()->isRun()){
					isRun = true;
					break;
				}
			}
			// アニメ終了
			if(!isRun){
				int nowID = m_moveList.begin()->id;
				for(iteCardMove ite = m_moveList.begin(); ite != m_moveList.end();){
					if(nowID != ite->id){
						break;
					}
					ite = m_moveList.erase(ite);
				}
			}
		}else{
			// moveListから1度に動かすカードを取得
			int s=m_moveList.size();
			for(iteCardMove ite = m_moveList.begin(); ite != m_moveList.end(); ite++){
				// IDが変わったので終了
				if(m_moveList.begin()->id != ite->id){
					break;
				}

				// アニメを作成し開始する(1枚追加で+1)
				VEC3 pos = getFieldPos(ite->ply, ite->zone, ite->num, ite->size);
				VEC3 deg = getFieldDegree(ite->ply, ite->zone, ite->num, ite->isAwake, ite->isFront);
				animeCalcClass* pAnime = ite->pCard->getAnimeCalc();
				pAnime->clear();
				pAnime->set(0, 0.0f, ite->pCard->m_pos, ite->pCard->m_degree, ite->pCard->m_scale);
				pAnime->set(1, ite->time, pos, deg, ite->pCard->m_scale);
				pAnime->start();
				ite->isAnime = true;

				// この後に削除ずらしがないのであればデータをfillする
				bool isNext = false;
				for(iteCardMove ite2 = (ite + 1); ite2 != m_moveList.end(); ite2++){
					if(ite->bzone == ite2->bzone){
						isNext = true;
						break;
					}
				}
				// ずらし無し
				if(!isNext){
					fillZone(ite->bply, ite->bzone);
				}
			}
		}
	}
}

//! 選択更新
void Field::updateSelect(void)
{
	Card* pCard;
	if(m_pDialog->isExist() && m_pDialog->getID() == DLG_CARDLIST){
		// フォーカス解除
		for(int ply = 0; ply < PLY_NUM; ply++){
			for(int i = 0; i < DECK_MAX; i++){
				pCard = getCard(ply, i);
				pCard->m_focus = false;
			}
		}

		// カードリストからカード取得
		m_pMenu->updateData(m_pDialog->m_cardList.getFocus());
	}else{
		VecpCard vCard;
		for(int ply = 0; ply < PLY_NUM; ply++){
			for(int i = 0; i < DECK_MAX; i++){
				pCard = getCard(ply, i);
				pCard->m_focus = false;

				// 移動中は処理しない
				if(pCard->getAnimeCalc()->isRun()){
					continue;
				}
				// マウスヒットチェック
				if(m_pMouse->isHitPlane(pCard->m_vPos, &pCard->m_world)){
					vCard.push_back(pCard);
				}
			}

			for(int i = 0; i < PROGRESS_MAX; i++){
				pCard = getPrgDmy(ply, i);
				pCard->m_focus = false;

				if(!getProgress(ply, i)){
					// マウスヒットチェック
					if(m_pMouse->isHitPlane(pCard->m_vPos, &pCard->m_world)){
						vCard.push_back(pCard);
					}
				}else{
					pCard->m_select = SELECT_LOCK;
				}
			}
		}

		// 一番近いもののみを判定
		float	len;
		VEC3	pos;
		VEC3	camPos = m_pCamera->m_eye;
		float	min = 9999999.9f;
		pCard = NULL;
		for(ItepCard ite = vCard.begin(); ite != vCard.end(); ite++){
			pos = (*ite)->m_pos - camPos;
			len = sqrt(pos.y * pos.y + pos.z * pos.z);
			if(len < min){
				min = len;
				pCard = *ite;
			}
		}

		// 更新
		if(pCard && !isMoveRun()){
			if(!m_pDialog->isExist() || !m_pDialog->isFocus()){
				pCard->m_focus = true;
				if(m_pMouse->getInputL() & MOUSE_PUSH){
					switch(pCard->m_select){
						case SELECT_NON:
							// 1枚の場合は入れ替えにする
							if(m_pPhase->m_selectNum == 1){
								if(getSelect()){
									getSelect()->m_select = SELECT_NON;
								}
								pCard->m_select = SELECT_ON;
							}else if(m_pPhase->m_selectNum > getSelectNum()){
								pCard->m_select = SELECT_ON;
							}
							break;
						case SELECT_ON:
							pCard->m_select = SELECT_NON;
							if(m_pDialog->isOverWrite()){
								m_pDialog->close();
							}
							break;
						case SELECT_LOCK:
							break;
					}
					// ダイアログオープン
					if(pCard->m_select == SELECT_ON){
						m_pDialog->openDlg(pCard);
					}
				}
			}
		}
		// メニュー更新
		m_pMenu->updateData(getFocus());
	}
}

//! 選択カード取得
Card* Field::getSelect(int num)
{
	// 選択カードを削除する処理の場合はnum=0
	// 選択カードを保持する処理の場合はnum=++

#define SEL(p)		{Card* pCard = (p);\
					if((pCard) && (pCard)->m_select == SELECT_ON){vCard.push_back(pCard);}}

	VecpCard vCard;

	// getCardすればいいのだが各フィールドごとの
	// 順番で取得しないと汚くなる
	for(int ply = 0; ply < PLY_NUM; ply++){
		// デッキ
		for(int i = 0; i < DECK_MAX; i++){
			SEL(getDeck(ply, i));
		}
		// 捨札
		for(int i = 0; i < DISCARD_MAX; i++){
			SEL(getDisCard(ply, i));
		}
		// 除外
		for(int i = 0; i < EXCUDE_MAX; i++){
			SEL(getExcude(ply, i));
		}
		// 手札
		for(int i = 0; i < HAND_MAX; i++){
			SEL(getHand(ply, i));
		}
		// プログレス
		for(int i = 0; i < PROGRESS_MAX; i++){
			SEL(getProgress(ply, i));
		}
		// エナジー
		for(int i = 0; i < ENERGY_MAX; i++){
			SEL(getEnergy(ply, i));
		}
		// ダメージ
		for(int i = 0; i < DAMAGE_MAX; i++){
			SEL(getDamage(ply, i));
		}
		// 処理場
		for(int i = 0; i < TEMP_MAX; i++){
			SEL(getTemp(ply, i));
		}
		// アクション
		SEL(getAction(ply));
		// プログレスダミー
		for(int i = 0; i < PROGRESS_MAX; i++){
			if(!getProgress(ply, i)){
				SEL(getPrgDmy(ply, i));
			}
		}
	}

	return(vCard.size() > (uint)num ? vCard[num] : NULL);
#undef SEL
}
//! フォーカスカード取得
Card* Field::getFocus(void)
{
	Card* pCard = NULL;
	for(int ply = 0; ply < PLY_NUM; ply++){
		for(int i = 0; i < DECK_MAX; i++){
			if(getCard(ply, i) && getCard(ply, i)->m_focus){
				pCard = getCard(ply, i);
				break;
			}
		}
	}

	return(pCard);
}

//! カード詰め
void Field::fillZone(int ply, int zone)
{
	switch(zone){
		case ZONE_DECK:		fillDeck	(ply);		break;
		case ZONE_DISCARD:	fillDisCard	(ply);		break;
		case ZONE_EXCUDE:	fillExcude	(ply);		break;
		case ZONE_HAND:		fillHand	(ply);		break;
		case ZONE_PROGRESS:	break;
		case ZONE_ENERGY:	fillEnergy	(ply);		break;
		case ZONE_DAMAGE:	fillDamage	(ply);		break;
		case ZONE_ACTION:	break;
		case ZONE_TEMP:		fillTemp	(ply);		break;
	}
}
void Field::fillDeck(int ply)
{
	int last = -1;

	// 最終位置の算出
	for(int i = DECK_MAX - 1; i >= 0; i--){
		if(getDeck(ply, i)){
			last = i;
			break;
		}
	}
	// 詰める
	for(int i = 0; i <= last; i++){
		if(!getDeck(ply, i)){
			for(int j = i + 1; j <= last; j++){
				// 参照先のみ変更
				m_pDeck[ply][j - 1] = getDeck(ply, j);
			}
			deleteDeck(ply, last);
			last--;
			i--;	// 空白が連続している可能性がある
		}
	}

	// データ変更
	int deckNum = getDeckNum(ply);
	for(int i = 0; i < deckNum; i++){
		setDeck(ply, i, getDeck(ply, i), getDeck(ply, i)->m_reverse == CARD_FRONT);
	}
}
void Field::fillDisCard(int ply)
{
	int last = -1;

	// 最終位置の算出
	for(int i = DISCARD_MAX - 1; i >= 0; i--){
		if(getDisCard(ply, i)){
			last = i;
			break;
		}
	}
	// 詰める
	for(int i = 0; i <= last; i++){
		if(!getDisCard(ply, i)){
			for(int j = i + 1; j <= last; j++){
				// 参照先のみ変更
				m_pDisCard[ply][j - 1] = getDisCard(ply, j);
			}
			deleteDisCard(ply, last);
			last--;
			i--;	// 空白が連続している可能性がある
		}
	}

	// データ変更
	int disNum = getDisCardNum(ply);
	for(int i = 0; i < disNum; i++){
		setDisCard(ply, i, getDisCard(ply, i), getDisCard(ply, i)->m_reverse == CARD_FRONT);
	}
}
void Field::fillExcude(int ply)
{
	int last = -1;

	// 最終位置の算出
	for(int i = EXCUDE_MAX - 1; i >= 0; i--){
		if(getExcude(ply, i)){
			last = i;
			break;
		}
	}
	// 詰める
	for(int i = 0; i <= last; i++){
		if(!getExcude(ply, i)){
			for(int j = i + 1; j <= last; j++){
				// 参照先のみ変更
				m_pExcude[ply][j - 1] = getExcude(ply, j);
			}
			deleteExcude(ply, last);
			last--;
			i--;	// 空白が連続している可能性がある
		}
	}

	// データ変更
	int excudeNum = getExcudeNum(ply);
	for(int i = 0; i < excudeNum; i++){
		setExcude(ply, i, getExcude(ply, i), getExcude(ply, i)->m_reverse == CARD_FRONT);
	}
}
void Field::fillHand(int ply)
{
	int last = -1;

	// 最終位置の算出
	for(int i = HAND_MAX - 1; i >= 0; i--){
		if(getHand(ply, i)){
			last = i;
			break;
		}
	}
	// 詰める
	for(int i = 0; i <= last; i++){
		if(!getHand(ply, i)){
			for(int j = i + 1; j <= last; j++){
				// 参照先のみ変更
				m_pHand[ply][j - 1] = getHand(ply, j);
			}
			deleteHand(ply, last);
			last--;
			i--;	// 空白が連続している可能性がある
		}
	}

	// データ変更
	int handNum = getHandNum(ply);
	for(int i = 0; i < handNum; i++){
		setHand(ply, i, getHand(ply, i), getHand(ply, i)->m_reverse == CARD_FRONT);
	}
}
void Field::fillEnergy(int ply)
{
	int last = -1;

	// 最終位置の算出
	for(int i = ENERGY_MAX - 1; i >= 0; i--){
		if(getEnergy(ply, i)){
			last = i;
			break;
		}
	}
	// 詰める
	for(int i = 0; i <= last; i++){
		if(!getEnergy(ply, i)){
			for(int j = i + 1; j <= last; j++){
				// 参照先のみ変更
				m_pEnergy[ply][j - 1] = getEnergy(ply, j);
			}
			deleteEnergy(ply, last);
			last--;
			i--;	// 空白が連続している可能性がある
		}
	}

	// データ変更
	int energyNum = getEnergyNum(ply);
	for(int i = 0; i < energyNum; i++){
		setEnergy(ply, i, getEnergy(ply, i), getEnergy(ply, i)->m_reverse == CARD_FRONT, getEnergy(ply, i)->m_awake == CARD_AWAKE);
	}
}
void Field::fillDamage(int ply)
{
	int last = -1;

	// 最終位置の算出
	for(int i = DAMAGE_MAX - 1; i >= 0; i--){
		if(getDamage(ply, i)){
			last = i;
			break;
		}
	}
	// 詰める
	for(int i = 0; i <= last; i++){
		if(!getDamage(ply, i)){
			for(int j = i + 1; j <= last; j++){
				// 参照先のみ変更
				m_pDamage[ply][j - 1] = getDamage(ply, j);
			}
			deleteDamage(ply, last);
			last--;
			i--;	// 空白が連続している可能性がある
		}
	}

	// データ変更
	int damageNum = getDamageNum(ply);
	for(int i = 0; i < damageNum; i++){
		setDamage(ply, i, getDamage(ply, i), getDamage(ply, i)->m_reverse == CARD_FRONT);
	}
}
void Field::fillTemp(int ply)
{
	int last = -1;

	// 最終位置の算出
	for(int i = TEMP_MAX - 1; i >= 0; i--){
		if(getTemp(ply, i)){
			last = i;
			break;
		}
	}
	// 詰める
	for(int i = 0; i <= last; i++){
		if(!getTemp(ply, i)){
			for(int j = i + 1; j <= last; j++){
				// 参照先のみ変更
				m_pTemp[ply][j - 1] = getTemp(ply, j);
			}
			deleteTemp(ply, last);
			last--;
			i--;	// 空白が連続している可能性がある
		}
	}

	// データ変更
	int tempNum = getTempNum(ply);
	for(int i = 0; i < tempNum; i++){
		setTemp(ply, i, getTemp(ply, i), getTemp(ply, i)->m_reverse == CARD_FRONT);
	}
}

//! デッキ下を空ける
void Field::liftDeck(int ply)
{
	fillDeck(ply);
	for(int i = getDeckNum(ply) - 1; i > 0; i--){
		setDeck(ply, i + 1, getDeck(ply, i), getDeck(ply, i)->m_reverse == CARD_FRONT);
	}
	deleteDeck(ply, 0);
}

//! カードカウント
int Field::getZoneMax(int zone)
{
	int iRet = 0;

	switch(zone){
		case ZONE_DECK:		iRet = DECK_MAX;	break;
		case ZONE_DISCARD:	iRet = DISCARD_MAX;	break;
		case ZONE_EXCUDE:	iRet = EXCUDE_MAX;	break;
		case ZONE_HAND:		iRet = HAND_MAX;	break;
		case ZONE_PROGRESS:	iRet = PROGRESS_MAX;break;
		case ZONE_ENERGY:	iRet = ENERGY_MAX;	break;
		case ZONE_DAMAGE:	iRet = DAMAGE_MAX;	break;
		case ZONE_ACTION:	iRet = 1;			break;
		case ZONE_TEMP:		iRet = TEMP_MAX;	break;
	}

	return(iRet);
}
int Field::getZoneNum(int ply, int zone, bool isMove)
{
	int iRet = 0;

	switch(zone){
		case ZONE_DECK:		iRet = getDeckNum		(ply);		break;
		case ZONE_DISCARD:	iRet = getDisCardNum	(ply);		break;
		case ZONE_EXCUDE:	iRet = getExcudeNum		(ply);		break;
		case ZONE_HAND:		iRet = getHandNum		(ply);		break;
		case ZONE_PROGRESS:	iRet = getProgressNum	(ply);		break;
		case ZONE_ENERGY:	iRet = getEnergyNum		(ply);		break;
		case ZONE_DAMAGE:	iRet = getDamageNum		(ply);		break;
		case ZONE_ACTION:	iRet = (getAction(ply) ? 1 : 0);	break;
		case ZONE_TEMP:		iRet = getTempNum		(ply);		break;
	}

	// 移動元を含める
	if(isMove){
		// 移動元データはmoveListの中
		for(iteCardMove ite = m_moveList.begin(); ite != m_moveList.end(); ite++){
			if(ite->bply == ply && ite->bzone == zone){
				iRet++;
			}
		}
	}

	return(iRet);
}
int Field::getDeckNum(int ply)
{
	int iRet = 0;

	for(int i = 0; i < DECK_MAX; i++){
		if(getDeck(ply, i)){
			iRet++;
		}
	}

	return(iRet);
}
int Field::getDisCardNum(int ply)
{
	int iRet = 0;

	for(int i = 0; i < DISCARD_MAX; i++){
		if(getDisCard(ply, i)){
			iRet++;
		}
	}

	return(iRet);
}
int Field::getExcudeNum(int ply)
{
	int iRet = 0;

	for(int i = 0; i < EXCUDE_MAX; i++){
		if(getExcude(ply, i)){
			iRet++;
		}
	}

	return(iRet);
}
int Field::getHandNum(int ply)
{
	int iRet = 0;

	for(int i = 0; i < HAND_MAX; i++){
		if(getHand(ply, i)){
			iRet++;
		}
	}

	return(iRet);
}
int Field::getProgressNum(int ply)
{
	int iRet = 0;

	for(int i = 0; i < PROGRESS_MAX; i++){
		if(getProgress(ply, i)){
			iRet++;
		}
	}

	return(iRet);
}
int Field::getEnergyNum(int ply)
{
	int iRet = 0;

	for(int i = 0; i < ENERGY_MAX; i++){
		if(getEnergy(ply, i)){
			iRet++;
		}
	}

	return(iRet);
}
int Field::getDamageNum(int ply)
{
	int iRet = 0;

	for(int i = 0; i < DAMAGE_MAX; i++){
		if(getDamage(ply, i)){
			iRet++;
		}
	}

	return(iRet);
}
int Field::getTempNum(int ply)
{
	int iRet = 0;

	for(int i = 0; i < TEMP_MAX; i++){
		if(getTemp(ply, i)){
			iRet++;
		}
	}

	return(iRet);
}

//! 有効数カウント
int Field::getAwakeEnergyNum(int ply)
{
	int iRet = 0;

	for(int i = 0; i < ENERGY_MAX; i++){
		if(getEnergy(ply, i) && getEnergy(ply, i)->m_awake == CARD_AWAKE){
			iRet++;
		}
	}

	return(iRet);
}
int Field::getFallEnergyNum(int ply)
{
	int iRet = 0;

	for(int i = 0; i < ENERGY_MAX; i++){
		if(getEnergy(ply, i) && getEnergy(ply, i)->m_awake == CARD_FALL){
			iRet++;
		}
	}

	return(iRet);
}

//! カード取得
Card* Field::getZone(int ply, int zone, int num, bool isMove)
{
	Card* pCard = NULL;

	switch(zone){
		case ZONE_DECK:		pCard = getDeck		(ply, num);	break;
		case ZONE_DISCARD:	pCard = getDisCard	(ply, num);	break;
		case ZONE_EXCUDE:	pCard = getExcude	(ply, num);	break;
		case ZONE_HAND:		pCard = getHand		(ply, num);	break;
		case ZONE_PROGRESS:	pCard = getProgress	(ply, num);	break;
		case ZONE_ENERGY:	pCard = getEnergy	(ply, num);	break;
		case ZONE_DAMAGE:	pCard = getDamage	(ply, num);	break;
		case ZONE_ACTION:	pCard = getAction	(ply);		break;
		case ZONE_TEMP:		pCard = getTemp		(ply, num);	break;
	}

	// 移動元の取得
	if(isMove){
		// 移動元はmoveListの中
		for(iteCardMove ite = m_moveList.begin(); ite != m_moveList.end(); ite++){
			if(ite->bply == ply && ite->bzone == zone && ite->bnum == num){
				// 対象があれば移動先から取得
				pCard = getZone(ite->ply, ite->zone, ite->num);
			}
		}
	}

	return(pCard);
}

//! カードセット
void Field::setZone(int ply, int zone, int num, Card* pCard, bool isAwake, bool isFront)
{
	switch(zone){
		case ZONE_DECK:		setDeck		(ply, num, pCard, isFront);			break;
		case ZONE_DISCARD:	setDisCard	(ply, num, pCard, isFront);			break;
		case ZONE_EXCUDE:	setExcude	(ply, num, pCard, isFront);			break;
		case ZONE_HAND:		setHand		(ply, num, pCard, isFront);			break;
		case ZONE_PROGRESS:	setProgress	(ply, num, pCard, isFront, isAwake);break;
		case ZONE_ENERGY:	setEnergy	(ply, num, pCard, isFront, isAwake);break;
		case ZONE_DAMAGE:	setDamage	(ply, num, pCard, isFront);			break;
		case ZONE_ACTION:	setAction	(ply,	   pCard, isFront, isAwake);break;
		case ZONE_TEMP:		setTemp		(ply, num, pCard, isFront);			break;
	}
}
void Field::setDeck(int ply, int num, Card* pCard, bool isFront)
{
	m_pDeck[ply][num] = pCard;
	pCard->m_num = num;
	pCard->m_ply = ply;
	pCard->m_zone = ZONE_DECK;
	pCard->m_reverse = (isFront ? CARD_FRONT : CARD_BACK);
	pCard->setAwake();
}
void Field::setDisCard(int ply, int num, Card* pCard, bool isFront)
{
	m_pDisCard[ply][num] = pCard;
	pCard->m_num = num;
	pCard->m_ply = ply;
	pCard->m_zone = ZONE_DISCARD;
	pCard->m_reverse = (isFront ? CARD_FRONT : CARD_BACK);
	pCard->setAwake();
}
void Field::setExcude(int ply, int num, Card* pCard, bool isFront)
{
	m_pExcude[ply][num] = pCard;
	pCard->m_num = num;
	pCard->m_ply = ply;
	pCard->m_zone = ZONE_EXCUDE;
	pCard->m_reverse = (isFront ? CARD_FRONT : CARD_BACK);
	pCard->setAwake();
}
void Field::setHand(int ply, int num, Card* pCard, bool isFront)
{
	m_pHand[ply][num] = pCard;
	pCard->m_num = num;
	pCard->m_ply = ply;
	pCard->m_zone = ZONE_HAND;
	pCard->m_reverse = (isFront ? CARD_FRONT : CARD_BACK);
	pCard->setAwake();
}
void Field::setProgress(int ply, int num, Card* pCard, bool isFront, bool isAwake)
{
	m_pProgress[ply][num] = pCard;
	pCard->m_num = num;
	pCard->m_ply = ply;
	pCard->m_zone = ZONE_PROGRESS;
	pCard->m_reverse = (isFront ? CARD_FRONT : CARD_BACK);
	isAwake ? pCard->setAwake() : pCard->setFall();
}
void Field::setEnergy(int ply, int num, Card* pCard, bool isFront, bool isAwake)
{
	m_pEnergy[ply][num] = pCard;
	pCard->m_num = num;
	pCard->m_ply = ply;
	pCard->m_zone = ZONE_ENERGY;
	pCard->m_reverse = (isFront ? CARD_FRONT : CARD_BACK);
	isAwake ? pCard->setAwake() : pCard->setFall();
}
void Field::setDamage(int ply, int num, Card* pCard, bool isFront)
{
	m_pDamage[ply][num] = pCard;
	pCard->m_num = num;
	pCard->m_ply = ply;
	pCard->m_zone = ZONE_DAMAGE;
	pCard->m_reverse = (isFront ? CARD_FRONT : CARD_BACK);
	pCard->setAwake();
}
void Field::setAction(int ply, Card* pCard, bool isFront, bool isAwake)
{
	m_pAction[ply] = pCard;
	pCard->m_num = 0;
	pCard->m_ply = ply;
	pCard->m_zone = ZONE_ACTION;
	pCard->m_reverse = (isFront ? CARD_FRONT : CARD_BACK);
	pCard->setAwake();
	isAwake ? pCard->setAwake() : pCard->setFall();
}
void Field::setTemp(int ply, int num, Card* pCard, bool isFront)
{
	m_pTemp[ply][num] = pCard;
	pCard->m_num = num;
	pCard->m_ply = ply;
	pCard->m_zone = ZONE_TEMP;
	pCard->m_reverse = (isFront ? CARD_FRONT : CARD_BACK);
	pCard->setAwake();
}

//! カード削除
void Field::deleteZone(Card* pCard)
{
	switch(pCard->m_zone){
		case ZONE_DECK:		deleteDeck		(pCard->m_ply, pCard->m_num);	break;
		case ZONE_DISCARD:	deleteDisCard	(pCard->m_ply, pCard->m_num);	break;
		case ZONE_EXCUDE:	deleteExcude	(pCard->m_ply, pCard->m_num);	break;
		case ZONE_HAND:		deleteHand		(pCard->m_ply, pCard->m_num);	break;
		case ZONE_PROGRESS:	deleteProgress	(pCard->m_ply, pCard->m_num);	break;
		case ZONE_ENERGY:	deleteEnergy	(pCard->m_ply, pCard->m_num);	break;
		case ZONE_DAMAGE:	deleteDamage	(pCard->m_ply, pCard->m_num);	break;
		case ZONE_ACTION:	deleteAction	(pCard->m_ply);					break;
		case ZONE_TEMP:		deleteTemp		(pCard->m_ply, pCard->m_num);	break;
	}
}
void Field::deleteDeck(int ply, int num)
{
	m_pDeck[ply][num]->m_select = SELECT_NON;
	m_pDeck[ply][num] = NULL;
}
void Field::deleteDisCard(int ply, int num)
{
	m_pDisCard[ply][num]->m_select = SELECT_NON;
	m_pDisCard[ply][num] = NULL;
}
void Field::deleteExcude(int ply, int num)
{
	m_pExcude[ply][num]->m_select = SELECT_NON;
	m_pExcude[ply][num] = NULL;
}
void Field::deleteHand(int ply, int num)
{
	m_pHand[ply][num]->m_select = SELECT_NON;
	m_pHand[ply][num] = NULL;
}
void Field::deleteProgress(int ply, int num)
{
	m_pProgress[ply][num]->m_select = SELECT_NON;
	m_pProgress[ply][num] = NULL;
}
void Field::deleteEnergy(int ply, int num)
{
	m_pEnergy[ply][num]->m_select = SELECT_NON;
	m_pEnergy[ply][num] = NULL;
}
void Field::deleteDamage(int ply, int num)
{
	m_pDamage[ply][num]->m_select = SELECT_NON;
	m_pDamage[ply][num] = NULL;
}
void Field::deleteAction(int ply)
{
	m_pAction[ply]->m_select = SELECT_NON;
	m_pAction[ply] = NULL;
}
void Field::deleteTemp(int ply, int num)
{
	m_pTemp[ply][num]->m_select = SELECT_NON;
	m_pTemp[ply][num] = NULL;
}

//! 移動セット
void Field::setMove(Card* pCard, int id, int ply, int zone, int num, bool isAwake, int isFront, bool isShift, float time)
{
	int bply = pCard->m_ply;
	int bzone = pCard->m_zone;
	int bnum = pCard->m_num;

	// 末尾
	if(num == MOVEBACK){
		num = getZoneNum(ply, zone);
	}

	// 表裏自動
	bool rev = (isFront == CARD_FRONT ? true : false);
	if(isFront == -1){
		bool r[ZONE_MAX] = {false, true, true, ply == PLY_MY, true, false, true, true, true};
		rev = r[zone];
	}

	if(pCard->m_ply != ply || pCard->m_zone != zone || pCard->m_num != num){
		// 移動元削除
		deleteZone(pCard);
	}
	// 移動先追加
	setZone(ply, zone, num, pCard, isAwake, rev);

	int size = getZoneNum(ply, zone);
	// アニメ開始はupdateから
	m_moveList.push_back(CARDMOVE(id, pCard, ply, zone, num, size, isAwake, rev, bply, bzone, bnum, time));

	if(isShift){
		// その場アニメの場合はずらす必要はない
		if(zone != bzone){
			// ずらしアニメ：追加
			if(OR(zone, ZONE_HAND, ZONE_ENERGY, ZONE_DAMAGE, ZONE_TEMP)){
				Card*	pCard;
				int		cnt = 0;
				int		i = 0;
				while(1){
					pCard = getZone(ply, zone, i);
					if(pCard){
						m_moveList.push_back(CARDMOVE(id, pCard, ply, zone, cnt, size, pCard->m_awake == CARD_AWAKE, pCard->m_reverse == CARD_FRONT, ply, zone, pCard->m_num, time));
						cnt++;
					}
					i++;
					if(cnt >= size) break;
				}
			}
			// ずらしアニメ：削除
			if(OR(bzone, ZONE_HAND, ZONE_ENERGY, ZONE_DAMAGE, ZONE_TEMP)){
				size = getZoneNum(bply, bzone);
				Card*	pCard;
				int		cnt = 0;
				int		i = 0;
				while(1){
					pCard = getZone(bply, bzone, i);
					if(pCard){
						m_moveList.push_back(CARDMOVE(id, pCard, bply, bzone, cnt, size, pCard->m_awake == CARD_AWAKE, pCard->m_reverse == CARD_FRONT, bply, bzone, pCard->m_num, time));
						cnt++;
					}
					i++;
					if(cnt >= size) break;
				}
			}
		}
	}
}
//! アニメセット
void Field::setAnime(Card* pCard, int isAwake, int isFront)
{
	bool awake = isAwake == CARD_AWAKE ? true : false;
	if(isAwake == -1){
		awake = pCard->m_awake == CARD_AWAKE ? true : false;
	}
	// アニメの変更のみでデータは移動しない
	setMove(pCard, ADDMOVE, pCard->m_ply, pCard->m_zone, pCard->m_num, awake, isFront, false, CARD_ANIME_SPEED * 0.75f);
}

//! アニメ待機
void Field::wait(float time)
{
	// ダミーを使用して移動無しアニメを追加する
	m_moveList.push_back(CARDMOVE(ADDMOVE, getPrgDmy(PLY_MY, 0), PLY_MY, ZONE_PROGRESS, 0, -1, true, true, PLY_MY, ZONE_PROGRESS, 0, time));
}

//! 座標取得
VEC3 Field::getFieldPos(int ply, int zone, int num, int max)
{
#if defined(_LOCAL_)
	if(m_pPhase->m_isChange){
		ply = !ply;
	}
#endif

	// 基準座標
	VEC3 ret = gCardPos[zone][ply];

#if defined(_LOCAL_)
	if(m_pPhase->m_isChange){
		ply = !ply;
	}
#endif

	// 基準座標から移動
	switch(zone){
		case ZONE_DECK:
			ret.y += (0.4f / DECK_MAX) * num;
			break;
		case ZONE_DISCARD:
			ret.y += (0.4f / DISCARD_MAX) * num;
			break;
		case ZONE_EXCUDE:
			ret.y += (0.4f / EXCUDE_MAX) * num;
			break;
		case ZONE_HAND:{
			float w, x;
			if(max <= 4){
				// 中心から重ねず表示
				w = VER_CARD_W;
				x = -((max / 2.0f * w) - (w / 2.0f));
			}else{
				// 幅を固定して重ねて表示
				x = -1.2f;
				w = (-x * 2.0f) / (max - 1);
			}
			ret.x = (x + (num * w)) * (ply == PLY_MY ? 1.0f : -1.0f);
			ret.z += num * 0.0001f * (ply == PLY_MY ? 1.0f : -1.0f);
			break;
		}
		case ZONE_PROGRESS:
			ret.x += num * 1.0f * (ply == PLY_MY ? 1.0f : -1.0f);
			break;
		case ZONE_ENERGY:
			ret.x += num * 0.25f * (ply == PLY_MY ? 1.0f : -1.0f);
			ret.y += num * 0.001f;
			break;
		case ZONE_DAMAGE:
			ret.y += num * 0.001f;
			ret.z += num * 0.2f * (ply == PLY_MY ? -1.0f : 1.0f);
			break;
		case ZONE_ACTION:
			break;
		case ZONE_TEMP:{
			float w, x;
			if(max <= 4){
				// 重ねず表示
				w = VER_CARD_W;
				x = -((max / 2.0f * w) - (w / 2.0f));
			}else{
				// 幅を固定して重ねて表示
				x = -1.0f;
				w = (-x * 2.0f) / (max - 1);
			}
			ret.x = (x + (num * w)) * (ply == PLY_MY ? 1.0f : -1.0f);
			ret.z += num * -0.0001f;
			break;
		}
	}

	return(ret);
}
//! 角度取得
VEC3 Field::getFieldDegree(int ply, int zone, int num, bool isAwake, bool isFront)
{
#if defined(_LOCAL_)
	if(m_pPhase->m_isChange){
		ply = !ply;
	}
#endif

	// 基準角度
	VEC3 ret = gCardDeg[zone][ply];

	if(!isAwake){
		switch(zone){
			case ZONE_HAND:
			case ZONE_PROGRESS:
			case ZONE_ENERGY:
			case ZONE_ACTION:
				// x→y→zで掛けているため工夫
				ret.y += (isFront ? 90.0f : -90.0f);
				break;
		}
	}

	if(!isFront){
		switch(zone){
			case ZONE_DAMAGE:
				ret.y += (ply == PLY_MY ? -180.0f : 180.0f);
			case ZONE_DECK:
			case ZONE_DISCARD:
			case ZONE_EXCUDE:
			case ZONE_PROGRESS:
			case ZONE_ENERGY:
			case ZONE_ACTION:
				ret.z += (ply == PLY_MY ? -180.0f : 180.0f);
				break;
			case ZONE_HAND:
			case ZONE_TEMP:
				ret.y += (ply == PLY_MY ? -180.0f : 180.0f);
				break;
		}
	}

	return(ret);
}

// Process ----------------------------------------------------------------------------------------

//! カードをドロー
bool Field::drawCard(int ply)
{
	bool bRet = false;
	if(getDeckNum(ply) > 0){
		searchDeck(ply, getDeckNum(ply) - 1);
		bRet = true;
	}

	return(bRet);
}

//! デッキからセット
bool Field::addEnergy(int ply, bool isAwake)
{
	bool bRet = false;
	if(getDeckNum(ply) > 0){
		if(getEnergyNum(ply) < DAMAGE_MAX){
			setMove(getDeck(ply, getDeckNum(ply) - 1), ADDMOVE, ply, ZONE_ENERGY, MOVEBACK, isAwake);
		}
		bRet = true;
	}

	return(bRet);
}
bool Field::addDamage(int ply)
{
	bool bRet = false;
	if(getDeckNum(ply) > 0){
		if(getDamageNum(ply) < DAMAGE_MAX){
			setMove(getDeck(ply, getDeckNum(ply) - 1), ADDMOVE, ply, ZONE_DAMAGE, MOVEBACK);
		}
		bRet = true;
	}

	return(bRet);
}
bool Field::addTemp(int ply)
{
	bool bRet = false;
	if(getDeckNum(ply) > 0){
		setMove(getDeck(ply, getDeckNum(ply) - 1), ADDMOVE, ply, ZONE_TEMP, MOVEBACK);
		bRet = true;
	}

	return(bRet);
}

//! シフト
void Field::shiftProgress(int ply, int hand, int prg)
{
	if(getProgress(ply, prg)){
		dumpProgress(ply, prg);
	}
	setMove(getHand(ply, hand), ADDMOVE, ply, ZONE_PROGRESS, prg);
}
void Field::shiftAction(int ply, int hand)
{
	if(getAction(ply)){
		dumpAction(ply);
	}
	setMove(getHand(ply, hand), ADDMOVE, ply, ZONE_ACTION, 0);
}

//! 攻撃宣言
Card* Field::attackProgress(int ply, int prg)
{
	fallProgress(ply, prg);

	return(getProgress(PLY_OPPO, PROGRESS_MAX - 1 - prg));
}

//! ガードしてパワーをアップ
void Field::guardProgress(int ply, int hand, int prg)
{
	getProgress(ply, prg)->m_addPower.push_back(TURN_VALUE(getHand(ply, hand)->m_ci.guard, TURN_NOW_BATTLE));
}

//! 攻撃通過判定
bool Field::isSuccessAttack(int ply, int prg)
{
	bool	bRet;
	Card*	mp = getProgress(ply, prg);
	Card*	op = getProgress(!ply, PROGRESS_MAX - 1 - prg);
	if(op){
		bRet = mp->getSumPower() >= op->getSumPower();
	}else{
		bRet = true;
	}

	return(bRet);
}

//! ダメージを与える
void Field::giveDamage(int ply, int num)
{
	// 注意
	// checkDrawを抜けた同フレームでgiveDamageを行うとリメイクより先に
	// ダメージ判定が入ってしまうので、次フレームで行うように

	wait();

	// ダメージ用カードはtempに移動してある
	for(int i = 0; i < num; i++){
		if(getDamageNum(ply) < DAMAGE_MAX){
			if(getTemp(ply, getTempNum(ply) - 1)->m_ci.frame == FRAME_NON){
printf("ダメージ１点入りました\n");
				setMove(getTemp(ply, getTempNum(ply) - 1), ADDMOVE, ply, ZONE_DAMAGE, MOVEBACK);
			}else{
printf("リジェクトしました(%s)\n", getTemp(ply, getTempNum(ply) - 1)->m_ci.name);
				dumpTemp(ply, getTempNum(ply) - 1);
			}
		}
	}
}

//! ダメージリバース
void Field::damageReverse(int ply, int num)
{
	setAnime(getDamage(ply, num), CARD_AWAKE, CARD_BACK);
}

//! リメイク
void Field::remakeDeck(int ply, int dis)
{
printf("%sを除外しました\n", getDisCard(ply, dis)->m_ci.name);

	setMove(getDisCard(ply, dis), ADDMOVE, ply, ZONE_EXCUDE, MOVEBACK);

	fillDisCard(ply);

	if(getDisCardNum(ply) > 0){
		setMove(getDisCard(ply, getDisCardNum(ply) - 1), ADDMOVE, ply, ZONE_DECK, 0);
		int cnt = 1;
		for(int i = getDisCardNum(ply) - 1; i >= 0; i--){
			setMove(getDisCard(ply, i), SAMEMOVE, ply, ZONE_DECK, cnt);
			cnt++;
		}
	}
	shuffleDeck(ply);

printf("リメイク終了\n");
}

//! デッキシャッフル
void Field::shuffleDeck(int ply)
{
	int		deckNum = getDeckNum(ply);
	int		r1, r2;

	fillDeck(ply);

	// デッキが1枚以下ならシャッフルする必要がない
	if(deckNum > 1){
		// 参照先のみランダム
		for(int j = 0; j < 10000; j++){
			r1 = rand() % deckNum;
			r2 = rand() % deckNum;
			REPLACE(Card*, m_pDeck[ply][r1], m_pDeck[ply][r2]);
		}

		// データが前のままなので更新
		for(int i = 0; i < deckNum; i++){
			setDeck(ply, i, getDeck(ply, i), getDeck(ply, i)->m_reverse == CARD_FRONT);
			getDeck(ply, i)->setPos(getFieldPos(ply, ZONE_DECK, i));
			getDeck(ply, i)->setDegree(getFieldDegree(ply, ZONE_DECK, i, true, getDeck(ply, i)->m_reverse == CARD_FRONT));
		}

		// シャッフルアニメ
		Card*			pCard;
		animeCalcClass*	pAnime;
		VEC3			moveB, moveF;
		for(int i = 0; i < 20; i++){
			r1 = rand() % (deckNum - deckNum / 5);	// 見栄えが悪いので上部は動かさない
			pCard = getDeck(ply, r1);
			moveB = moveF = pCard->m_pos;
			moveB.z -= 0.2f;
			moveF.z += 0.2f;
			pAnime = pCard->getAnimeCalc();
			pAnime->clear();
			pAnime->set(0, 0.03f, pCard->m_pos, pCard->m_degree, pCard->m_scale);
			pAnime->set(1, 0.03f, moveB, pCard->m_degree, pCard->m_scale);
			pAnime->set(2, 0.03f, moveF, pCard->m_degree, pCard->m_scale);
			pAnime->set(3, 0.03f, pCard->m_pos, pCard->m_degree, pCard->m_scale);
			pAnime->setDelay(i * pAnime->getSumTime() * 0.5f);	// 1/2被りで開始
			pAnime->start();
		}
	}
}

//! 手札シャッフル
void Field::shuffleHand(int ply)
{
	int		handNum = getHandNum(ply);
	int		r1, r2;

	fillHand(ply);

	// 手札が1枚以下ならシャッフルする必要がない
	if(handNum > 1){
		// 参照先のみランダム
		for(int j = 0; j < 1000; j++){
			r1 = rand() % handNum;
			r2 = rand() % handNum;
			REPLACE(Card*, m_pHand[ply][r1], m_pHand[ply][r2]);
		}

		// データが前のままなので更新
		for(int i = 0; i < handNum; i++){
			setHand(ply, i, getHand(ply, i), getHand(ply, i)->m_reverse == CARD_FRONT);
			getHand(ply, i)->setPos(getFieldPos(ply, ZONE_HAND, i));
			getHand(ply, i)->setDegree(getFieldDegree(ply, ZONE_HAND, i, true, getHand(ply, i)->m_reverse == CARD_FRONT));
		}
	}
}

//! デッキからLv0プログレスをセット
void Field::setZeroProgress(int ply)
{
	int deckNum = getDeckNum(ply);
	int cnt = 0;

	fillDeck(ply);
	for(int i = 0; i < deckNum; i++){
		if(getDeck(ply, i)->m_ci.level == 0 && getDeck(ply, i)->m_ci.type == TYPE_PG){
			setMove(getDeck(ply, i), ADDMOVE, ply, ZONE_PROGRESS, cnt, true, CARD_BACK);
			cnt++;
			if(cnt >= PROGRESS_MAX){
				break;
			}
		}
	}
}

//! 手札のLv0プログレスをプレイ
void Field::playZeroProgress(int ply, int num)
{
	setMove(getHand(ply, num), ADDMOVE, ply, ZONE_PROGRESS, getProgressNum(ply), true, CARD_BACK);
}

//! シフト計算
int Field::getShiftCost(Card* pMaterial, Card* pShift)
{
	int iRet = -1;

	if(!pMaterial){
		// 場にカードがない
		iRet = pShift->getSumLevel();
	}else if(pMaterial->getSumLevel() >= pShift->getSumLevel()){
		// 同レベルシフトorレベルダウンシフト
		iRet = 1;
	}else{
		// 通常コスト
		iRet = pShift->getSumLevel() - pMaterial->getSumLevel();
	}

	return(iRet);
}

//! エナジー使用
void Field::useEnergy(int ply, int num)
{
	int		cnt = 0;
	// 後ろから使用
	for(int i = getEnergyNum(ply) - 1; i >= 0; i--){
		if(getEnergy(ply, i)->m_awake == CARD_AWAKE){
			fallEnergy(ply, i);
			cnt++;
			if(cnt >= num){
				break;
			}
		}
	}
}

//! プログレスをプレイ
void Field::playHand(int ply, int hand, int prg, bool isAwake)
{
	setMove(getHand(ply, hand), ADDMOVE, ply, ZONE_PROGRESS, prg, isAwake);
}

//! プログレスを登場
void Field::entryDeck(int ply, int deck, int prg, bool isAwake)
{
	if(getProgress(ply, prg)){
		dumpProgress(ply, prg);
	}
	setMove(getDeck(ply, deck), ADDMOVE, ply, ZONE_PROGRESS, prg, isAwake);
}
void Field::entryDisCard(int ply, int dis, int prg, bool isAwake)
{
	if(getProgress(ply, prg)){
		dumpProgress(ply, prg);
	}
	setMove(getDisCard(ply, dis), ADDMOVE, ply, ZONE_PROGRESS, prg, isAwake);
}

//! 捨札に送る
bool Field::dumpDeck(int ply, int num)
{
	bool ret = false;
	if(num >= 0 && getDeckNum(ply) > 0){
		setMove(getDeck(ply, num), ADDMOVE, ply, ZONE_DISCARD, MOVEBACK);
		ret = true;
	}

	return(ret);
}
void Field::dumpHand(int ply, int num)
{
	setMove(getHand(ply, num), ADDMOVE, ply, ZONE_DISCARD, MOVEBACK);
}
void Field::dumpProgress(int ply, int num)
{
	setMove(getProgress(ply, num), ADDMOVE, ply, ZONE_DISCARD, MOVEBACK);
}
void Field::dumpDamage(int ply, int num)
{
	setMove(getDamage(ply, num), ADDMOVE, ply, ZONE_DISCARD, MOVEBACK);
}
void Field::dumpAction(int ply)
{
	setMove(getAction(ply), ADDMOVE, ply, ZONE_DISCARD, MOVEBACK);
}
void Field::dumpTemp(int ply, int num)
{
	setMove(getTemp(ply, num), ADDMOVE, ply, ZONE_DISCARD, MOVEBACK);
}

//! デッキに戻す
void Field::backProgress(int ply, int prg, int deck)
{
	setMove(getProgress(ply, prg), ADDMOVE, ply, ZONE_DECK, deck);
}

//! 手札に戻す
void Field::bounceProgress(int ply, int num)
{
	setMove(getProgress(ply, num), ADDMOVE, ply, ZONE_HAND, MOVEBACK);
}

//! 手札に加える
void Field::searchDeck(int ply, int num)
{
	setMove(getDeck(ply, num), ADDMOVE, ply, ZONE_HAND, MOVEBACK);
}
void Field::searchDisCard(int ply, int num)
{
	setMove(getDisCard(ply, num), ADDMOVE, ply, ZONE_HAND, MOVEBACK);
}
void Field::searchTemp(int ply, int num)
{
	setMove(getTemp(ply, num), ADDMOVE, ply, ZONE_HAND, MOVEBACK);
}

//! アウェイク・フオール
void Field::awakeProgress(int ply, int num)
{
	setAnime(getProgress(ply, num), CARD_AWAKE);
}
void Field::fallProgress(int ply, int num)
{
	setAnime(getProgress(ply, num), CARD_FALL);
}
void Field::awakeEnergy(int ply, int num)
{
	setAnime(getEnergy(ply, num), CARD_AWAKE);
}
void Field::fallEnergy(int ply, int num)
{
	setAnime(getEnergy(ply, num), CARD_FALL);
}
void Field::awakeAction(int ply)
{
	setAnime(getAction(ply), CARD_AWAKE);
}
void Field::fallAction(int ply)
{
	setAnime(getAction(ply), CARD_FALL);
}

//! 裏返す
void Field::reverseDeck(int ply, int num, bool isFront)
{
	setAnime(getDeck(ply, num), -1, isFront ? CARD_FRONT : CARD_BACK);
}
void Field::reverseProgress(int ply, int num, bool isFront)
{
	setAnime(getProgress(ply, num), -1, isFront ? CARD_FRONT : CARD_BACK);
}
void Field::reverseDamage(int ply, int num, bool isFront)
{
	setAnime(getDamage(ply, num), -1, isFront ? CARD_FRONT : CARD_BACK);
}

//! 入れ替える
void Field::replaceCard(Card* pCard1, Card* pCard2, bool isFront1, bool isAwake1, bool isFront2, bool isAwake2)
{
	int ply1 = pCard1->m_ply;
	int zone1 = pCard1->m_zone;
	int num1 = pCard1->m_num;
	int ply2 = pCard2->m_ply;
	int zone2 = pCard2->m_zone;
	int num2 = pCard2->m_num;
	setMove(pCard1, ADDMOVE, ply2, zone2, num2, isAwake1, isFront1 ? CARD_FRONT : CARD_BACK, false);
	setMove(pCard2, SAMEMOVE, ply1, zone1, num1, isAwake2, isFront2 ? CARD_FRONT : CARD_BACK, false);
}

//! 処理場移動
void Field::toTemp(int ply, int zone, int num)
{
	setMove(getZone(ply, zone, num), ADDMOVE, ply, ZONE_TEMP, getTempNum(ply));
}
void Field::fromTemp(int ply, int zone, int num, int temp)
{
	if(temp == -1){
		temp = getTempNum(ply) - 1;
	}
	setMove(getTemp(ply, temp), ADDMOVE, ply, zone, num);
}

//! 全選択
void Field::selLockAll(int lock)
{
	for(int ply = 0; ply < PLY_NUM; ply++){
		selLockPly(ply, lock);
	}
}
//! 選択プレイヤーロック
void Field::selLockPly(int ply, int lock)
{
	for(int i = 0; i < ZONE_MAX; i++){
		selLockZone(ply, i, lock);
	}
}
//! 選択ゾーンロック
void Field::selLockZone(int ply, int zone, int lock)
{
	int max = getZoneMax(zone);
	for(int i = 0; i < max; i++){
		selLockOnce(ply, zone, i, lock);
	}
}
//! 単体ロック
void Field::selLockOnce(int ply, int zone, int num, int lock)
{
	Card* pCard = getZone(ply, zone, num);
	if(pCard){
		pCard->m_select = lock;
	}
}
//! 選択ゾーン以外ロック
void Field::selLockZoneExcept(int ply, int zone)
{
	selLockAll(SELECT_LOCK);
	selLockZone(ply, zone, SELECT_NON);
}
//! 条件付き選択ゾーンロック
int Field::selLockValue(int ply, int zone, int data, int value, char* ope, int lock)
{
	int ret = 0;
	Card* pCard = NULL;
	int d, num;

	// カードデータ分け
	num = getZoneMax(zone);
	for(int i = 0; i < num; i++){
		pCard = getZone(ply, zone, i);
		if(pCard){
			_getValueData(pCard, &d, data);

			// 比較
			if(	(strcmp(ope, "==") == 0 && d == value) ||
				(strcmp(ope, "!=") == 0 && d != value) ||
				(strcmp(ope, ">" ) == 0 && d >  value) ||
				(strcmp(ope, ">=") == 0 && d >= value) ||
				(strcmp(ope, "<" ) == 0 && d <  value) ||
				(strcmp(ope, "<=") == 0 && d <= value))
			{
				selLockOnce(ply, zone, i, lock);
				ret++;
			}
		}
	}

	return(ret);
}
//! 条件カード以外ロック
int Field::selLockValueExcept(int ply, int zone, int data, int value, char* ope)
{
	selLockAll(SELECT_LOCK);
	return(selLockValue(ply, zone, data, value, ope, SELECT_NON));
}
//! ダミーロック
void Field::selLockPrgDmy(int ply, int lock, int num)
{
	if(num == -1){
		for(int i = 0; i < PROGRESS_MAX; i++){
			if(!getProgress(ply, i)){
				getPrgDmy(ply, i)->m_select = lock;
			}else{
				getPrgDmy(ply, i)->m_select = SELECT_LOCK;
			}
		}
	}else{
		if(!getProgress(ply, num)){
			getPrgDmy(ply, num)->m_select = lock;
		}else{
			getPrgDmy(ply, num)->m_select = SELECT_LOCK;
		}
	}

	for(int i = 0; i < PROGRESS_MAX; i++){
		// 相手側も使用することはないので自動でロック
		getPrgDmy(!ply, i)->m_select = SELECT_LOCK;
	}
}


//! 選択数の取得
int Field::getSelectNum(void)
{
	int		iRet = 0;
	Card*	pCard;

	for(int ply = 0; ply < PLY_NUM; ply++){
		for(int i = 0; i < DECK_MAX; i++){
			pCard = getCard(ply, i);
			if(pCard && pCard->m_select == SELECT_ON){
				iRet++;
			}
		}
		for(int i = 0; i < PROGRESS_MAX; i++){
			if(!getProgress(ply, i)){
				if(getPrgDmy(ply, i)->m_select == SELECT_ON){
					iRet++;
				}
			}
		}
	}

	return(iRet);
}
//! カードデータ数の取得
int Field::getValueNum(int ply, int zone, int data, int value, char* ope)
{
	int iRet = 0;
	Card* pCard = NULL;
	int d, num;

	// カードデータ分け
	num = getZoneMax(zone);
	for(int i = 0; i < num; i++){
		pCard = getZone(ply, zone, i);
		if(pCard){
			_getValueData(pCard, &d, data);

			// 比較
			if(	(strcmp(ope, "==") == 0 && d == value) ||
				(strcmp(ope, "!=") == 0 && d != value) ||
				(strcmp(ope, ">" ) == 0 && d >  value) ||
				(strcmp(ope, ">=") == 0 && d >= value) ||
				(strcmp(ope, "<" ) == 0 && d <  value) ||
				(strcmp(ope, "<=") == 0 && d <= value))
			{
				iRet++;
			}
		}
	}

	return(iRet);
}
//! カードデータのポインタ取得
void Field::getValueCard(int ply, int zone, int data, int value, VecpCard* vCard, char* ope)
{
	int iRet = 0;
	Card* pCard = NULL;
	int d, num;

	// カードデータ分け
	num = getZoneMax(zone);
	for(int i = 0; i < num; i++){
		pCard = getZone(ply, zone, i);
		if(pCard){
			_getValueData(pCard, &d, data);

			// 比較
			if(	(strcmp(ope, "==") == 0 && d == value) ||
				(strcmp(ope, "!=") == 0 && d != value) ||
				(strcmp(ope, ">" ) == 0 && d >  value) ||
				(strcmp(ope, ">=") == 0 && d >= value) ||
				(strcmp(ope, "<" ) == 0 && d <  value) ||
				(strcmp(ope, "<=") == 0 && d <= value))
			{
				vCard->push_back(pCard);
			}
		}
	}
}
// getValue簡略化
void Field::_getValueData(Card* pCard, int* d, int data)
{
	// とりあえず数値のみ対応
	switch(data){
//			case CI_NAME:		*d = pCard->m_ci.name;			break;
//			case CI_LINKREQ:	*d = pCard->m_ci.linkReq;		break;
//			case CI_SKILLTYPE:	*d = pCard->m_ci.skillType;		break;
//			case CI_RACE:		*d = pCard->m_ci.race;			break;
			case CI_CARDNO:		*d = pCard->m_ci.cardNo;		break;
			case CI_COLOR:		*d = pCard->m_ci.color;			break;
			case CI_POWER:		*d = pCard->getSumPower();		break;
			case CI_GUARD:		*d = pCard->m_ci.guard;			break;
			case CI_LEVEL:		*d = pCard->getSumLevel();		break;
			case CI_STRIKE:		*d = pCard->getSumStrike();		break;
			case CI_LINK:		*d = pCard->getSumLink();		break;
			case CI_FRAME:		*d = pCard->m_ci.frame;			break;
			case CI_BOOST:		*d = pCard->m_ci.boost;			break;
			case CI_TYPE:		*d = pCard->m_ci.type;			break;
			case CI_SERNO:		*d = pCard->m_ci.serNo;			break;
			case CD_REVERSE:	*d = pCard->m_reverse;			break;
			case CD_SELECT:		*d = pCard->m_select;			break;
			case CD_AWAKE:		*d = pCard->m_awake;			break;
		}
}

