#include "EnemyManager.h"
#include "StaticData.h"
#include <cstdlib>

namespace MotionTest {
using namespace HPL;
using namespace E3D;
using namespace General;
using namespace MotionTestConsts;
using namespace BasicStaticDataConsts;

EnemyManager::EnemyManager() {
}
EnemyManager::~EnemyManager() {
}

///////////////////
// オーバーライド
BOOL EnemyManager::is_Skip( E3DObject* obj ) {
	return obj->get_Valid() == FALSE ? TRUE: FALSE;

}
int EnemyManager::checkInView( E3DObject* obj ) {
	int status;
	// チェックイン
	if( E3DChkInView( staticData->get_SwapChainID(), obj->m_nSigID, &status ) ){
		_ASSERT( 0 );
		return 1;
	}
	return 0;
}
/** ターゲットの方向を向く
  *
  */
void EnemyManager::rotate_AgainstTarget( E3DObject* obj, int nTargetSigID ) {
	if( staticData->is_SkipPlayer(obj) ) {
		// プレイヤーの諸事情により敵はプレイヤーの方向を向かない


		if( obj->m_Game.m_Counter->step() & CounterStateType::ALL_LOOP_END ) {
			// 一定周期がきた

			// 方向をランダムにする
			D3DXVECTOR3 vRndDir = D3DXVECTOR3(MathTool::nextRandom<float>(-1,1), 0, MathTool::nextRandom<float>(-1,1));

			// 正規化
			D3DXVec3Normalize( &vRndDir, &vRndDir);

			// 方向を向く
			staticData->face( vRndDir, 1, obj->m_nSigID, obj->m_Move.m_nQuoatanion );

			// カウンタリセット
			obj->m_Game.m_Counter->reset();
		}
	} else {
		// プレイヤーの方向を向く
		int ret = 0;

		// プレイヤーの位置取得
		D3DXVECTOR3 vPlayerPosition;
		ret = E3DGetPos( nTargetSigID, &vPlayerPosition );

		D3DXVECTOR3 vPosition;
		ret = E3DGetPos( obj->m_nSigID, &vPosition );
		// プレイヤーへの方向取得
		D3DXVECTOR3 vDiff = vPlayerPosition - vPosition;

		
		// Y軸は変えない（ジャンプ中とかあるので変更しないこと）

		// 移動量を設定（向いている方向にする）
		obj->m_Move.m_vVelocity.x = vDiff.x;
		obj->m_Move.m_vVelocity.z = vDiff.z;

		D3DXVECTOR3 vDirection = -obj->m_Move.m_vVelocity;
		vDirection.y = 0;
		staticData->face( vDirection,
			1, obj->m_nSigID, obj->m_Move.m_nQuoatanion );
	}
}


int EnemyManager::checkHitToGround( E3DObject* obj ) {
	int ret = 0;

	ret = staticData->checkObjectOnGround( obj, FALSE);
	if( ret ) {
		_ASSERT(0);
		return ret;
	}
	return 0;
}
/*
int EnemyManager::checkHitToBillBoard( E3DObject* obj ) {

	// 当ったショットのSigIDリスト
	int nShotID[MotionTestConsts::SHOT_MAX];

	// 当ったショットの数
	int nConfNum;

	// 当ったかどうかの結果
	int confptr = 0;

	int ret = 0;

	// 全ビルボードとの当り判定をチェック
	ret = E3DChkConfBillboard( obj->m_nSigID,
		1.f, &confptr, nShotID, MotionTestConsts::SHOT_MAX, &nConfNum );

	if( confptr != 0 ) {
		// 何かに当った

		for(int i = 0; i < nConfNum; i ++ ) {
			// 弾を消す

			ret = E3DSetValidFlag( -1, nShotID[i] , FALSE);

			// 逆引きでビルボード情報を取得
			E3DBillBoard* billBoard = staticData->m_ShotBillBoardManager.m_mapSigIDToBillBoardMap[ nShotID[i] ];
			billBoard->set_Alive( FALSE );

			// 敵の体力を減らす
			float fNextHP = obj->m_Game.m_fHP - MotionTestConsts::SHOT_POWER;
			if( fNextHP <= 0) {
				fNextHP = 0;
				// 死亡
				obj->set_Valid( FALSE );
				E3DSetValidFlag( obj->m_nSigID, -1, FALSE );
			}
			obj->m_Game.m_fHP = fNextHP;
		}



		if( static_cast<int>(staticData->m_lstEnemyLifeBarList.size() ) < MotionTestConsts::ENEMY_LIFE_BAR_STACK_NUM_MAX ) {
			// 敵の体力表示リストにキュー有り。

			// 
			BOOL bFound = FALSE;

			for(std::list<EnemyLifeBar*>::iterator it = staticData->m_lstEnemyLifeBarList.begin();
				it != staticData->m_lstEnemyLifeBarList.end();
				it ++ )
			{
				EnemyLifeBar* lifeBar = *it;
				if( lifeBar->m_nSigID == obj->m_nSigID ) {
					// 既に登録済み
					// →情報更新
					lifeBar->m_fHP = obj->m_Game.m_fHP;
					lifeBar->m_Counter.reset();
					bFound = TRUE;
					break;
				}
			}
			if( bFound == FALSE ) {
				// 新規追加
				EnemyLifeBar* lifeBar = new EnemyLifeBar();
				lifeBar->m_fHP = obj->m_Game.m_fHP;
				lifeBar->m_fHPMax = obj->m_Game.m_fHPMax;
				lifeBar->m_strName = std::string( "Cyclops");
				lifeBar->m_Counter.set_FrameCounterMax( MotionTestConsts::ENEMY_LIFE_BAR_REMAIN_COUNT );
				lifeBar->m_Counter.set_LoopNumMax( 1 );
				lifeBar->m_nSigID = obj->m_nSigID;
				lifeBar->m_Counter.reset();
				staticData->m_lstEnemyLifeBarList.push_back(lifeBar );
			}

		}
	}
	return 0;
}*/
int EnemyManager::checkHitToPlayer( E3DObject* obj ) {

	int ret = 0;

	/////////
	// スキップチェック
	if( staticData->is_SkipPlayer( obj ) ) {
		return 0;
	} else if( obj->m_Game.m_nHoldTargetSigID == staticData->get_Player()->m_nSigID ) {
		// 捕まえている
		// 当りチェックはしない
		return 0;
	} else if( (staticData->get_Player()->m_Game.m_nType == PlayerType::EVIGEN && (
		staticData->get_Player()->m_nEventNumber == Motion::Evigen::DAMAGE_A ||
		staticData->get_Player()->m_nEventNumber == Motion::Evigen::DAMAGE_B ||
		staticData->get_Player()->m_nEventNumber == Motion::Evigen::DAMAGE_CRASH_UP ) ) ||
		(staticData->get_Player()->m_Game.m_nType == PlayerType::TANYA && FALSE ) )
	{
		// ダメージ中は食らわない
		return 0;
	}

	//
	/////////

	// 現在のフレーム番号を取得
	int motid;
	int frameno;
	ret = E3DGetMotionFrameNo( obj->m_nSigID, &motid, &frameno );
	// 食いちぎりなどで、一度だけ悲鳴を出す
	BOOL bOnceDeathVoice = FALSE;

	// 食いちぎりで、既に上半身が無い
	BOOL bIsJohanshin = FALSE;

	int confptr = 0;		

	int inviewptr;

	ret = E3DChkConflictOBB( staticData->get_Player()->m_nSigID, -1,
		obj->m_nSigID, -1, &confptr , &inviewptr);
	if( ret ) {
		_ASSERT( 0 );
		return 1;
	}
	if( confptr ) {
		// 通常ダメージ（吹っ飛び）
		BOOL bNormalDamage = FALSE;

		// 服のみ破く
		BOOL bTearHuku = FALSE;

		// モーションを変える
		int rnd = MathTool::nextRandom<int>(0,3 );

		int nNextEventNo = -1;
		if( staticData->get_Player()->m_Game.m_nType == PlayerType::EVIGEN ) {
			nNextEventNo = Motion::Evigen::DAMAGE_A;
			if( rnd == 0 ) {
				nNextEventNo = Motion::Evigen::DAMAGE_B;
			} else if( rnd == 1 ) {
				nNextEventNo = Motion::Evigen::DAMAGE_CRASH_UP;
			}
		}

		float fDamage = (obj->m_Game.m_fDamage + 
			MathTool::nextRandom<float>( -obj->m_Game.m_fDamageError,
			obj->m_Game.m_fDamage ) );

		if( //
			obj->m_Game.m_nType == EnemyType::WORM_BIG &&
			obj->m_nEventNumber == Motion::Worm::ATTACK_A ) 
		{
			// 噛み付き

			// 即死
			fDamage = staticData->get_Player()->m_Game.m_fHPMax;

			if( staticData->get_Player()->m_Game.m_nType == PlayerType::EVIGEN ) {
				// 死にモーション
				nNextEventNo = Motion::Evigen::DEATH ;
				if( staticData->m_aryOptionList[TitleSceneConsts::CheckType::KUBI] ) {
					// 上半身を消す
					char MATS[][100] = {
						"atama",
						"kami",
						"karada",
						"huku",
						"apron",
						"katyu",
						"shitagi",
						"danmen",	//首の断面も消す
					};
					for(int i = 0; i < 8; i ++ ) {
						int mat = 0;
						ret = E3DGetMaterialNoByName( staticData->get_Player()->m_nSigID, MATS[i], &mat );
						if( ret ) {
							_ASSERT( 0 );
							return 1;
						}
						ret = E3DSetMaterialAlpha( staticData->get_Player()->m_nSigID, mat, 0.f );
						if( ret ) {
							_ASSERT( 0 );
							return 1;
						}
					}
					// 胴体の断面を表示
					int mat = 0;
					ret = E3DGetMaterialNoByName( staticData->get_Player()->m_nSigID, "danmen_body", &mat );
					if( ret ) {
						_ASSERT( 0 );
						return 1;
					}
					ret = E3DSetMaterialAlpha( staticData->get_Player()->m_nSigID, mat, 1.f );
					if( ret ) {
						_ASSERT( 0 );
						return 1;
					}
					// 一度だけ声を出す
					bOnceDeathVoice = TRUE;
					bIsJohanshin = TRUE;
				}
			}

		} else if( staticData->get_Player()->m_Game.m_nType == PlayerType::EVIGEN &&
			obj->m_Game.m_nType == EnemyType::WORM_BIG &&
			obj->m_nEventNumber == Motion::Worm::ATTACK_B )
		{
			// 丸呑みへ。
			obj->m_Game.m_nHoldTargetSigID = staticData->get_Player()->m_nSigID;
			staticData->get_Player()->m_Game.m_nHolderSigID = obj->m_nSigID;

			// 即死
			fDamage = staticData->get_Player()->m_Game.m_fHPMax;

			// TODO 丸呑み状態
			if( staticData->get_Player()->m_Game.m_nType == PlayerType::EVIGEN ) {
				nNextEventNo = Motion::Evigen::SWALLOW ;
			}

			obj->m_nEventNumber = Motion::Worm::SWALLOW;

		} else if( 
			obj->m_Game.m_nType == EnemyType::ZOMBIE &&
			obj->m_nOldEventNumber == obj->m_nEventNumber &&
			((obj->m_nEventNumber == Motion::Zombie::ATTACK_A && frameno > 35) ||
			(obj->m_nEventNumber == Motion::Zombie::ATTACK_B && frameno > 48))
			)
		{
			// 単純攻撃
			bNormalDamage = TRUE;

			// 服を破く
			bTearHuku = TRUE;
			
		} else if(
			obj->m_Game.m_nType == EnemyType::ZOMBIE_B &&
			obj->m_nOldEventNumber == obj->m_nEventNumber &&
			obj->m_nEventNumber == Motion::Zombie_B::ATTACK_A )//&& frameno > 25 )
		{
			// 単純攻撃
			bNormalDamage = TRUE;

			// 服を破く
			bTearHuku = TRUE;
		} else if( obj->m_Game.m_nType == EnemyType::ZOMBIE_B &&
			obj->m_nOldEventNumber == obj->m_nEventNumber &&
			obj->m_nEventNumber == Motion::Zombie_B::JUMP_ATTACK )
		{
			// くびちょんぱ
			// 頭をもがす
			staticData->remove_Head();

			if( staticData->get_Player()->m_Game.m_nType == PlayerType::EVIGEN ) {
				// 通常死
				nNextEventNo = Motion::Evigen::DEATH ;
			}

			// 声出す
			bOnceDeathVoice = TRUE;

			// HP=0
			fDamage = staticData->get_Player()->m_Game.m_fHPMax;

		} else if( obj->m_Game.m_nType == EnemyType::ZOMBIE &&
			obj->m_nOldEventNumber == obj->m_nEventNumber &&
			(obj->m_nEventNumber == Motion::Zombie::ATTACK_C && frameno > 38))
		{
			// 捕まった
			if( staticData->get_Player()->m_Game.m_nType == PlayerType::EVIGEN ) {
				nNextEventNo = Motion::Evigen::DAMAGE_A;
			}
			obj->m_Game.m_nHoldTargetSigID = staticData->get_Player()->m_nSigID;
			staticData->get_Player()->m_Game.m_nHolderSigID = obj->m_nSigID;
			obj->m_nEventNumber = Motion::Zombie::HOLD;

		} else if( obj->m_Game.m_nType == EnemyType::ZOMBIE ) {
			// これ以外の状態でのゾンビには当り判定が無い
			bNormalDamage = FALSE;
		} else {
			bNormalDamage = TRUE;
		}
		if( bNormalDamage ) {
			// プレイヤーを吹っ飛ばす

			staticData->blow_Out( obj, staticData->get_Player() , 1);



		}

		// 服を剥ぎ取る
		if( staticData->get_Player()->m_Game.m_nType == PlayerType::EVIGEN &&
			bTearHuku && staticData->m_nClothBreak == 0 )
		{
			staticData->m_nClothBreak = 1;
			staticData->set_Texture( staticData->get_Player()->m_nSigID, "huku", Material::CLOTH_NORMAL + staticData->m_nClothBreak, FALSE );
			staticData->set_Texture( staticData->get_Player()->m_nSigID, "huku_under", Material::CLOTH_NORMAL + staticData->m_nClothBreak, FALSE );
		}

		////////////
		// プレイヤーの位置＋プレイヤーの方向×一定距離から血を出す
		// 目の高さ
		D3DXVECTOR3 vEyeHeight( 0, PLAYER_EYE_HEIGHT_FROM_CENTER , 0 );
		D3DXVECTOR3 vBloodPosition = staticData->get_Player()->m_Move.m_vPosition;

		// 目の高さにする
		vBloodPosition += vEyeHeight;

		// プレイヤーの方向
		D3DXVECTOR3 vDirection;
		E3DGetCharaDir( staticData->get_Player()->m_nSigID, 0,0, &vDirection );
		vDirection *= -1;
		vDirection.y = 0;
		// normalize
		D3DXVec3Normalize( &vDirection, &vDirection );

		D3DXVECTOR3 vBloodDistance = vDirection;
		//scale
		D3DXVec3Scale( &vBloodDistance, &vBloodDistance, SHOT_FROM_DISTANCE );

		vBloodPosition += vBloodDistance;

		// 血を一定数出す
		for(int i = 0; i < PLAYER_DAMAGE_BLOOD_NUM; i ++ ) {
			staticData->create_Blood( vBloodPosition, vDirection );
		}

		float fOldHP = staticData->get_Player()->m_Game.m_fHP;

		// ダメージ
		staticData->get_Player()->m_Game.m_fHP -= fDamage;

		if( staticData->get_Player()->m_Game.m_fHP <= 0 ) {
			// 死亡した

			staticData->get_Player()->m_Game.m_fHP = 0;
			// ゲームオーバー

			// ある確率で頭がもげる
			if( staticData->m_aryOptionList[TitleSceneConsts::CheckType::KUBI] && bIsJohanshin == FALSE) {
				if( MathTool::nextRandom<float>(0, 100 ) < 10.f ) {
					// 頭をもがす
					staticData->remove_Head();
				}
			}

			if( bOnceDeathVoice && fOldHP > 0 ) {
				// ちょうど今死んだところ。一度だけ声を出す
				ret = E3DPlaySound( staticData->m_arySoundList[ Sound::VOICE_CRASH ], 0, 0, 0 );
			}
		}

		staticData->get_Player()->m_nUnderEventNumber = -1;
		staticData->get_Player()->m_nEventNumber = nNextEventNo;

		// テクスチャ切り替え
		float fAlpha = 0;
		if( staticData->get_Player()->m_Game.m_nType == PlayerType::EVIGEN ) {
			int nMaterial = Material::DAMAGE;
			if( MathTool::nextRandom<int>(0,2) == 1 ) {
				nMaterial = Material::DAMAGE_CRASH;
			}
			ret = staticData->set_Texture( staticData->get_Player()->m_nSigID, "atama", nMaterial, TRUE );

			int nTex = staticData->m_nUnderColor == 0 ? Material::KARADA_DAMAGE : Material::KARADA_DAMAGE_BLACK;
			ret = staticData->set_Texture( staticData->get_Player()->m_nSigID, "karada", nTex, FALSE );
			ret = staticData->set_Texture( staticData->get_Player()->m_nSigID, "karada_under", nTex, FALSE );

			//マテリアル設定
			int mat;
			E3DGetMaterialNoByName( staticData->get_Player()->m_nSigID, "atama", &mat );
			E3DGetMaterialAlpha( staticData->get_Player()->m_nSigID, mat, &fAlpha );

		}

		// 視点をプレイヤーを正面から見る位置に変える
		if( staticData->m_nCameraTargetSigID == staticData->get_Player()->m_nSigID ) {
			staticData->set_CameraInFrontOfObject( //staticData->m_nCameraTargetSigID,
				staticData->get_Player()->m_nSigID,
				0 );
		}


		
		if( bOnceDeathVoice == FALSE && fAlpha > 0.5f ){
			if( staticData->get_Player()->m_Game.m_nType == PlayerType::EVIGEN ) {
				// SE
				int nVoiceID = MathTool::nextRandom<int>(0,2 ) + Sound::VOICE_HIT_1;
				if( nNextEventNo == Motion::Evigen::DAMAGE_CRASH_UP ||
					nNextEventNo == Motion::Evigen::SWALLOW)
				{
					// 吹っ飛び
					nVoiceID = Sound::VOICE_CRASH;
				}
				ret = E3DPlaySound( staticData->m_arySoundList[ nVoiceID ], 0, 0, 0 );
			}

		}

	} else {
		// 触れていない

	}


	// 敵同士でぶつからないようにする
	//ret = checkHitToEnemy( obj );

	return 0;
}
int EnemyManager::render( E3DObject* obj ) {

	// sig id取得
	int hsid = obj->m_nSigID;

	// 通常描画
	if( E3DRender( staticData->get_SwapChainID(), hsid, 0, 1, 0, 0 ) ){
		_ASSERT( 0 );
		return 1;
	}

	// αブレンド描画
	if( E3DRender( staticData->get_SwapChainID(), hsid, 1, 1, 0, 0 ) ){
		_ASSERT( 0 );
		return 1;
	}
	int ret = E3DSetBeforePos( obj->m_nSigID) ;
	return 0;
}

int EnemyManager::createObjects( int nType, int nNum ) {
	int ret = 0;

	char lpszSigFilePath[MAX_PATH];

	if( nType == EnemyType::CYCLOPS ) {
		strcpy_s( lpszSigFilePath, MAX_PATH, "Media\\Cyclops\\Cyclops.sig");
	} else if( nType == EnemyType::WORM_BIG ||
		nType == EnemyType::WORM_SMALL) {
		strcpy_s( lpszSigFilePath, MAX_PATH, "Media\\worm\\worm.sig");
	} else if( nType == EnemyType::ZOMBIE ) {
		strcpy_s( lpszSigFilePath, MAX_PATH, "Media\\zombie\\zombie.sig");
	} else if( nType == EnemyType::MOSUKO ) {
		strcpy_s( lpszSigFilePath, MAX_PATH, "Media\\js2\\js_1.sig");
	} else if( nType == EnemyType::MOSUKO_LONG ) {
		strcpy_s( lpszSigFilePath, MAX_PATH, "Media\\js2\\js_2.sig");
	} else if( nType == EnemyType::ZOMBIE_B ) {
		strcpy_s( lpszSigFilePath, MAX_PATH, "Media\\zombie_B\\zombie_B.sig");
	} else if( nType == EnemyType::TROL ) {
		strcpy_s( lpszSigFilePath, MAX_PATH, "Media\\trol\\トロルくん.sig");
	} else {
		_ASSERT( 0 );
		return 1;
	}

	// 有効にする
	this->m_mapEnableMap[nType] = TRUE;
	this->m_mapValidObjectListMap[nType] = std::list<E3DObject*>();

	float fZoom = this->get_Zoom(nType);

	// コピー元となるマスタSIGID
	int nMasterSigID = 0;

	/////////////////
	// Sigファイル読み込み
	ret = E3DSigLoad( lpszSigFilePath, 0, fZoom, &nMasterSigID );
	if( ret ) {
		_ASSERT( 0 );
		return ret;
	}
	// 追加処理
	E3DObject* master = this->add_Object( nType, nMasterSigID );


	// テクスチャ作成
	int nBumpMapTexID = 0;
	int matno = 0;

	if( nType == EnemyType::ZOMBIE_B) {
		int nPool = 0;				//0:ビデオメモリ
		int nTransparent = 0;	//0:不透過
		ret = E3DCreateTexture("Media\\zombie_B\\zombie_B_bump.png", nPool,
			nTransparent, &nBumpMapTexID);
		if( ret ) {
			_ASSERT(0);
		}

		// 
		ret = E3DGetMaterialNoByName( master->m_nSigID, "zombie", &matno );
		if( ret || matno < 0 ) {
			_ASSERT(0);
		}

		// バンプマッピングとして利用
		ret = E3DSetBumpMapToMaterial( master->m_nSigID,
			matno, nBumpMapTexID );
		if( ret ) {
			_ASSERT(0);
		}
	}

	// クローンマネージャに登録
	ret = this->m_CloneManager.add_MasterBuffer( nType, nMasterSigID);

	// 予約一個消化
	nNum --;

	if( nNum >= 1 ) {
		// まだ作成すべきものがある
		// Sigを複製

		// テクスチャパス
		char lpszTextureDirPath[MAX_PATH];
		if( nType == EnemyType::CYCLOPS ) {
			strcpy_s( lpszTextureDirPath, MAX_PATH, "Media\\Cyclops\\");
		} else if( nType == EnemyType::WORM_BIG ||
			nType == EnemyType::WORM_SMALL) {
			strcpy_s( lpszTextureDirPath, MAX_PATH, "Media\\worm\\");
		} else if( nType == EnemyType::ZOMBIE ) {
			strcpy_s( lpszTextureDirPath, MAX_PATH, "Media\\zombie\\");
		} else if( nType == EnemyType::MOSUKO ) {
			strcpy_s( lpszTextureDirPath, MAX_PATH, "Media\\js2\\");
		} else if( nType == EnemyType::MOSUKO_LONG ) {
			strcpy_s( lpszTextureDirPath, MAX_PATH, "Media\\js2\\");
		} else if( nType == EnemyType::ZOMBIE_B ) {
			strcpy_s( lpszTextureDirPath, MAX_PATH, "Media\\zombie_B\\");
		} else if( nType == EnemyType::TROL ) {
			strcpy_s( lpszTextureDirPath, MAX_PATH, "Media\\trol\\");
		} else {
			_ASSERT( 0 );
			return 1;
		}

		for(int i = 0; i < nNum; i ++ ) {
			E3DSigBufferData* bfSigBufferData = this->m_CloneManager.get_MasterBuffer(nType);
			// コピー
			int nSigID = 0;
			ret = E3DSigLoadFromBuf( lpszTextureDirPath,
				bfSigBufferData->m_lpczBuffer,
				bfSigBufferData->m_nBufferSize,
				0, 1.f, &nSigID );
				
			// 登録作業
			E3DObject* obj = this->add_Object( nType, nSigID );


			if( nType == EnemyType::ZOMBIE_B) {
				// バンプマッピングとして利用
				ret = E3DSetBumpMapToMaterial( obj->m_nSigID,
					matno, nBumpMapTexID );
				if( ret ) {
					_ASSERT(0);
				}
			}
		}

	}
	return 0;
}

E3DObject* EnemyManager::add_Object(int nType, int nSigID ) {
	int ret = 0;

	// オブジェクト生成
	E3DObject* obj = new E3DObject();

	// sig id 登録
	obj->m_nSigID = nSigID;

	//! オブジェクトタイプ
	obj->m_Game.m_nObjectType = ObjectType::ENEMY;

	// 種類
	obj->m_Game.m_nType = nType;

	// 逆引きに登録
	this->m_mapSigIDToObjectMap[ nSigID ] = obj;

	// リストに追加
	this->m_mapObjectListMap[nType].push_back( obj );

	float fZoom = this->get_Zoom(nType);

	char lpszMOAFilePath[MAX_PATH];
	if( nType == EnemyType::CYCLOPS ) {
		strcpy_s( lpszMOAFilePath, MAX_PATH, "Media\\Cyclops\\Cyclops.moa");
	} else if( nType == EnemyType::WORM_BIG ||
		nType == EnemyType::WORM_SMALL ) {
		strcpy_s( lpszMOAFilePath, MAX_PATH, "Media\\worm\\worm\\worm.moa");
	} else if( nType == EnemyType::ZOMBIE ) {
		strcpy_s( lpszMOAFilePath, MAX_PATH, "Media\\zombie\\zombie\\zombie.moa");
	} else if( nType == EnemyType::MOSUKO ||
		nType == EnemyType::MOSUKO_LONG)
	{
		strcpy_s( lpszMOAFilePath, MAX_PATH, "Media\\js2\\js\\js.moa");
	} else if( nType == EnemyType::ZOMBIE_B ) {
		strcpy_s( lpszMOAFilePath, MAX_PATH, "Media\\zombie_B\\zombie_B\\zombie_B.moa");
	} else if( nType == EnemyType::TROL ) {
		strcpy_s( lpszMOAFilePath, MAX_PATH, "Media\\trol\\motion\\motion.moa");
	} else {
		_ASSERT( 0 );
		return NULL;

	}

	// MOAファイル読み込み
	ret = staticData->loadMOAFile( lpszMOAFilePath, obj, fZoom );

	// クォータニオン
	ret = E3DCreateQ( &obj->m_Move.m_nQuoatanion );

	/////
	// 状態
	int nBase = 200;
	int nRnd = 100;
	obj->m_Game.m_Counter = new HPLCounter( nBase + MathTool::nextRandom<int>(-nRnd, nRnd), -1);

	// 死んでから消えるまでの時間
	obj->m_Game.m_DeathCounter = new HPLCounter( 100, 1 );
	return obj;
}

/** 待機しているオブジェクトを呼び出します。
  * @retval NULL	既に全て埋まっていて存在しない場合
  */
E3DObject* EnemyManager::search( int nType ) {

	if( this->m_mapEnableMap[nType] == FALSE ) {
		// 存在しない敵を作ろうとした
		return NULL;//_ASSERT(0);
	}
	int ret = 0;
	for(std::list<E3DObject*>::iterator it = this->m_mapObjectListMap[nType].begin();
		it != this->m_mapObjectListMap[nType].end(); it ++ )
	{
		E3DObject* obj = *it;
		if( obj->get_Valid() == FALSE ) {

			obj->set_Valid( TRUE );

			// 有効オブジェクトリストに追加
			this->m_mapValidObjectListMap[nType].push_back(obj);

			obj->m_Game.m_fHP = obj->m_Game.m_fHPMax;
			obj->m_Game.m_fDamage = ENEMY_DAMAGE;
			obj->m_Game.m_fDamageError = ENEMY_DAMAGE / 2.f;
			if( obj->m_Game.m_nType == EnemyType::WORM_BIG ) {
				obj->m_Game.m_Counter->set_FrameCounterMax( 200 );
			}

			// モデル有効化
			ret = E3DSetValidFlag( obj->m_nSigID, -1, TRUE);
			if( ret ) {
				_ASSERT(0);
			}

			obj->m_Game.m_DeathCounter->reset();

			//////////////////////
			// test 場所配置
			float MAX_DISTANCE = 50000;
			float ERR = 5000;

			float DEG = MathTool::nextRandom<float>(0, 360 );
			float fDistance = MAX_DISTANCE + MathTool::nextRandom<float>(-ERR,ERR);

			E3DSetPosOnGround( obj->m_nSigID, 
				staticData->get_GroundSigID(),
				MAP_HEIGHT, MAP_MIN, 
				fDistance * cos(D3DXToRadian( DEG )),
				fDistance * sin(D3DXToRadian( DEG )));

			// 速度
			obj->m_Move.m_fSpeed = MotionTestConsts::PLAYER_WALK_SPEED * MotionTestConsts::ENEMY_WALK_RATE;

			if( obj->m_Game.m_nType == EnemyType::WORM_BIG ) {
				// ビッグ
				int mat = 0;
				ret = E3DGetMaterialNoByName( obj->m_nSigID, "worm", &mat );
				ret = E3DSetMaterialAlpha( obj->m_nSigID, mat, 1.f);
			}
			obj->m_nEventNumber = 0;

			// モス子
			if( obj->m_Game.m_nType == EnemyType::MOSUKO ||
				obj->m_Game.m_nType == EnemyType::MOSUKO_LONG )
			{
				obj->m_Game.m_nWeaponType = MathTool::nextRandom<int>(0, MosukoWeaponType::NUM_MAX );

				// kami (blue/gold)
				int nKamiMaterial = Material::MOSUKO_HAIR + MathTool::nextRandom<int>(0,2);
				staticData->set_Texture( obj->m_nSigID, "kami", nKamiMaterial , FALSE);

				// karada
				int nKaradaMaterial = Material::MOSUKO_KARADA_3; //着衣
				float fRnd = MathTool::nextRandom<float>(0,100.f);
				if( fRnd < 2 ) {
					nKaradaMaterial = Material::MOSUKO_KARADA_1;	// 完全な裸
				} else if( fRnd < 5 ) {
					nKaradaMaterial = Material::MOSUKO_KARADA_2;	// パンツのみ
				} else if( fRnd < 10 ) {
					nKaradaMaterial = Material::MOSUKO_KARADA_4;	// 「スク水」を一発変換するATOKはできておるのう
				}

				staticData->set_Texture( obj->m_nSigID, "karada", nKaradaMaterial, FALSE );
				staticData->set_Texture( obj->m_nSigID, "koshim", nKaradaMaterial, FALSE );

				// gun
				int partno = 0;
				char lpszPartNameList[][100] = {
					"gun-tekubi[L]_X+",
					"ken-ken",
					"boushi-boushi",
					"ranndoseru-mune",
					"sukato",
				};
				BOOL bValidList[] = {
					obj->m_Game.m_nWeaponType == MosukoWeaponType::GUN || obj->m_Game.m_nWeaponType == MosukoWeaponType::BOTH,
					obj->m_Game.m_nWeaponType == MosukoWeaponType::KATANA || obj->m_Game.m_nWeaponType == MosukoWeaponType::BOTH,
					MathTool::nextRandom<float>(0.f, 100.f) <= 20,
					MathTool::nextRandom<float>(0.f, 100.f) <= 20,
					MathTool::nextRandom<float>(0.f, 100.f) <= 80 && nKaradaMaterial == Material::MOSUKO_KARADA_3,
				};
				int num = sizeof( bValidList) / sizeof(BOOL );
				for(int i = 0; i < num; i ++ ) {
					ret = E3DGetPartNoByName( obj->m_nSigID, lpszPartNameList[i], &partno );
					if( ret ) {
						_ASSERT(0);
					}
					ret = E3DSetValidFlag( obj->m_nSigID, partno, bValidList[i] );
					if( ret ) {
						_ASSERT(0);
					}
				}

			}
			return obj;
		}
	}
	return NULL;
}
int EnemyManager::checkHitToEnemy( E3DObject* obj ) {
	int ret = 0;

	//std::list<E3DObject*> lstDone;

	for(std::map<int, std::list<E3DObject*> >::iterator mit = this->m_mapObjectListMap.begin();
		mit != this->m_mapObjectListMap.end();
		mit ++ ) 
	{
		if( this->m_mapEnableMap[ mit->first ] == FALSE ) {
			// 処理しないオブジェクト
			continue;
		}

		if( mit->first != EnemyType::MOSUKO &&
			mit->first != EnemyType::MOSUKO_LONG )
		{
			continue;
		}

		if( obj->m_Game.m_nType == mit->first ) {
			// 同じ敵同士は当り判定を持たない
			continue;
		}

		//for(std::list<E3DObject*>::iterator it = mit->second.begin();
		//	it != mit->second.end(); it ++ )
		for(std::list<E3DObject*>::iterator it = this->m_mapValidObjectListMap[mit->first].begin();
			it != this->m_mapValidObjectListMap[mit->first].end(); it ++ )
		{
			E3DObject* other = *it;

			if( other == obj ) {
				continue;
			}

			if( other->get_Valid() == FALSE ) {
				continue;
			}

			/*BOOL bContinue = FALSE;
			for(std::list<E3DObject*>::iterator done = lstDone.begin();
				done != lstDone.end(); done ++ )
			{
				E3DObject* doneObj = *done;
				if( doneObj == obj || doneObj == other) {
					bContinue = TRUE;
					break;
				}
			}
			if( bContinue == TRUE ) {
				continue;
			}*/

			
			//int confptr;
			/*
			int inviewptr;
			ret = E3DChkConflictAABB( obj->m_nSigID,// -1,
				other->m_nSigID, //-1,
				&confptr , &inviewptr);
			if( ret ) {
				_ASSERT( 0 );
				return 1;
			}*/
			D3DXVECTOR3 vPos1;
			E3DGetPos( obj->m_nSigID, &vPos1 );
			D3DXVECTOR3 vPos2;
			E3DGetPos( other->m_nSigID, &vPos2 );
			D3DXVECTOR3 vDiff = vPos1 - vPos2;

			// これ以上近づいたら反発する
			const float ENEMY_DISTANCE = 1500.f;

			// 実際の距離
			float fDistance = D3DXVec3Length( &vDiff);


			if( fDistance < ENEMY_DISTANCE ) {
/*				lstDone.push_back( obj );
				lstDone.push_back( other );*/



/*				D3DXVec3Normalize( &vDiff, &vDiff );
				vDiff *= ENEMY_DISTANCE;
				vDiff.y = 0;
				vPos1 = vPos2 + vDiff;
				obj->m_Move.m_vPosition = vPos1;
				E3DSetPos( obj->m_nSigID, vPos1 );*/

				// 状態によって攻撃が互いに当ったり当らなかったり
				//staticData->blow_Out( obj, other , 1.f);

			}
		}
	}
	return 0;
}

float EnemyManager::get_Zoom( int nType ) {
	
	float fZoom = 1.f;
	if( nType == EnemyType::CYCLOPS ) {
		fZoom = 1.f;
	} else if( nType == EnemyType::WORM_BIG ) {
		fZoom = 1.0f;
	} else if( nType == EnemyType::WORM_SMALL ) {
		fZoom = 0.1f;
	} else if( nType == EnemyType::ZOMBIE ) {
		fZoom = 0.4f;
	} else if( nType == EnemyType::MOSUKO ||
		nType == EnemyType::MOSUKO_LONG )
	{
		fZoom = 1.f;
	} else if( nType == EnemyType::ZOMBIE_B ) {
		fZoom = 0.4f;
	} else if( nType == EnemyType::TROL ) {
		fZoom = 0.5f;
	}
	return fZoom;
}
}
