#include "GCommonWork.h"


#include "GPlayerManager.h"

#include "GPMEvigenAttack.h"
#include "GPMPeseruAttack.h"
#include "GPMTrellamaAttack.h"
#include "GPMTanyaAttack.h"
#include "GPMUndelsenAttack.h"
#include "GPMDurandanaAttack.h"
#include "GPMGardaAttack.h"
#include "GPMKappaAttack.h"

#include "GDefaultAttack.h"

#ifdef _DXLIB
#include "GStaticDataDX.h"
#else
#include "GStaticData.h"
#endif

#include "GEnum.h"

using namespace std;
using namespace GEnum;

GCommonWork::GCommonWork() {
	this->m_nGameSceneType = GameSceneType::G_TITLE;
	this->m_nWinnerForceID = -1;


}
GCommonWork::~GCommonWork() {
}

void GCommonWork::setup() {
	// アタック制御
	getStaticData()->m_AttackManager.put( GEnum::PlayerType::EVIGEN, new GPMEvigenAttack() );
	getStaticData()->m_AttackManager.put( GEnum::PlayerType::PESERU, new GPMPeseruAttack() );
	getStaticData()->m_AttackManager.put( GEnum::PlayerType::TRELLAMA, new GPMTrellamaAttack() );
	getStaticData()->m_AttackManager.put( GEnum::PlayerType::TANYA, new GPMTanyaAttack() );
	getStaticData()->m_AttackManager.put( GEnum::PlayerType::UNDELSEN, new GPMUndelsenAttack() );
	getStaticData()->m_AttackManager.put( GEnum::PlayerType::DURANDANA, new GPMDurandanaAttack() );
	getStaticData()->m_AttackManager.put( GEnum::PlayerType::GARDA, new GPMGardaAttack() );

	// 待ち
	getStaticData()->m_AttackManager.put( GEnum::PlayerType::SAKURI, new GDefaultAttack() );
	getStaticData()->m_AttackManager.put( GEnum::PlayerType::TANYA_YOUJO, new GDefaultAttack() );
	getStaticData()->m_AttackManager.put( GEnum::PlayerType::FOBOKO_P, new GDefaultAttack() );
	getStaticData()->m_AttackManager.put( GEnum::PlayerType::RAMDA, new GDefaultAttack() );
	getStaticData()->m_AttackManager.put( GEnum::PlayerType::KAPPA, new GPMKappaAttack() );
	getStaticData()->m_AttackManager.put( GEnum::PlayerType::DELTA, new GDefaultAttack() );
	getStaticData()->m_AttackManager.put( GEnum::PlayerType::NOTOKO, new GDefaultAttack() );
	getStaticData()->m_AttackManager.put( GEnum::PlayerType::ELLIN, new GDefaultAttack() );

	HPLSprite* lpSprite = getStaticData()->getSprite(GEnum::SpriteType::COMMON);
#ifdef _DXLIB
	int nIndex = lpSprite->getSequence( Common::TILE, FaceDirection::LEFT )->getImageInformation(0)->imageTag;
	int nHandle = getStaticData()->m_Basic.m_Graphics.m_ImageManager.get( nIndex );
	getStaticData()->getBlockManager()->setupBlock("data/maps/Block000.txt",
		lpSprite->clone(), nHandle );
#else
	getStaticData()->getBlockManager()->setupBlock("data/maps/Block000.txt",
		lpSprite->clone());
#endif

	// TODO Mixer

	getStaticData()->m_ObjectManager.setup();

	// scroller調整
	getStaticData()->m_ScrollManager.getScroller(0)->screenRect.set(0,0,this->m_Setting.windowWidth, this->m_Setting.windowHeight );

}


void GCommonWork::setupMap(int mapIndex){
	///////////


	// マップ読み込み
	HPLMapManager* mapManager = getStaticData()->getMapManager();
	std::string mapFilePathBase = mapManager->getMapFilePath(mapIndex);
	
	// 本体 csv
	std::string mapCSV = mapFilePathBase + std::string(".csv");
	
	// シナリオ
	// EventPack読み込み
/*	setEventPackManager(new HPLEventPackManager("data/event/EventPack.txt"));

	// イベントボックス情報が無い場合のデフォルトデータ
	std::string eventBoxFilePath("data/maps/NULL_EventBox.txt");

	// イベントボックス情報
	std::string checkEventBoxFileExists = mapFilePathBase + std::string(".txt");
	if(HPLFile::isExists(checkEventBoxFileExists.c_str()) == true){
		eventBoxFilePath = checkEventBoxFileExists;

	}

	// イメージ初期化
	this->getEventImage()->deactivate();

	eventPack = NULL;
	HPLEventBoxManager* boxManager = getEventBoxManager();
	if(boxManager != NULL){
		delete boxManager;
		boxManager = NULL;
	}
	setEventBoxManager(new HPLEventBoxManager(eventBoxFilePath.c_str()));
*/

	// オブジェクトをクリア
	getStaticData()->m_ObjectManager.clear();

	// ブロックをリセット
	AbstractBlockManager* blockManager = getStaticData()->getBlockManager();

	/////////
	// マップロード
	blockManager->loadMatrix(mapCSV.c_str());

	// タイルサイズ
	int tileSize = getStaticData()->getSetting()->tileSize;

	////////////////////
	// set scroller
	{
		HPLRect virRect(0,0,
			(float)(blockManager->getBlockMatrix()->getColumnSize() * tileSize),
			(float)(blockManager->getBlockMatrix()->getRowSize() * tileSize));

		HPLScroller* scroller = getStaticData()->getScrollManager()->getScroller(0);
		scroller->setVirtualRect(virRect);
	}

	this->m_Game.setGameOver(false);
	this->m_Game.setMenu(false);
	this->m_Game.setScenario(false);
	this->m_Game.setTheWorld(false);

	/////
	// オブジェクト配置
	// 配置用データファイルパス
	std::string objectPlaceDataFilePath = mapFilePathBase + std::string("-object.csv");

	// 配置用データ
	AbstractBlockManager placerBlockManager;

	placerBlockManager.loadMatrix(objectPlaceDataFilePath.c_str());

	// 配置
	this->m_ObjectPlacer.loadAndPlace(placerBlockManager.getBlockMatrix(),
		this->m_Setting.tileSize,
		getStaticData()->getMapData(),
		mapIndex);

	for( int i = 0; i < GEnum::PLAYER_MAX_NUM; i ++ ) {
		// プレイヤー
		GPlayer* player = &getStaticData()->m_ObjectManager.m_aryPlayerList[i];

		// ダメージ量初期化
		player->setStoredDamage( 0 );
		player->m_bIsNaked = false;

		/////
		// プレイヤー状態異常解除

		// プレイヤー生き返り
		player->setAlive(true);

		// プレイヤー拘束解除
		player->setHeld(false);

		// プレイヤーHP。イベントで死んでいる場合1に戻す
		if(player->getHP() <= 0){
			player->setHP(1);
		}

		// リスポーンカウンタ停止
		player->m_RespawnWaitCounter.end();

		// 空中にセット
		player->getTrigger()->setTrigger( TriggerType::ON_THE_GROUND, false );

		// 状態を元に戻す
		// 空中ならFLYDOWN,地上ならSTAND
		player->rollBackState();

	}
	// 最初のイベントはスキップ
//	this->setSkipFirst( true );

	/////
	// チェンジリング
//	this->m_Game.setChangingMap(false);

}


/**
	二つの「範囲」が共有部分を持つか判定
*/
bool GCommonWork::isShare(float aMin, float aMax, float bMin, float bMax){
	HPLRect a(aMin, 0, aMax-aMin, 1);
	HPLRect b(bMin, 0, bMax-bMin, 1);

	return a.isShare(b);
}
void GCommonWork::changeState(HPLShootingObject* obj, int newState){
	int ot = obj->getObjectType();
	if(ot == ObjectType::PLAYER){
		((GPlayer*)obj)->changeState(newState);
	}else if(ot == ObjectType::ENEMY){
//		((GEnemy*)obj)->changeState(newState);
	}else if(ot == ObjectType::NEUTRAL){
//		((GNeutral*)obj)->changeState(newState);
	}else if(ot == ObjectType::SHOT){
		((GShot*)obj)->changeState(newState);
	}
}

int GCommonWork::getEvigenSequenceID(HPLShootingObject* obj){
	int st = obj->getState()->getState();

	int id = GEnum::Motion::STAND;

	if(st == StateType::WALK){
		id = GEnum::Motion::WALK;
	}else if(st == StateType::FLYDOWN){
		id = GEnum::Motion::FLYDOWN;
	}else if(st == StateType::CROUCH){
		id = GEnum::Motion::CROUCH;
	}else if(st == StateType::FLYUP){
		id = GEnum::Motion::FLYUP;
	}else if(st == StateType::ATTACK ||
		st == StateType::ATTACK_PUNCH ||
		st == StateType::ATTACK_PINEAPPLE)
	{
		id = GEnum::Motion::ATTACK;

		// ジャンプ攻撃(ATTACKのみ対象)
		if( st == StateType::ATTACK &&
			obj->getTrigger()->getTrigger( TriggerType::ON_THE_GROUND ) == false )
		{
			id = GEnum::Motion::JATTACK;
		}
	} else if( st == StateType::ATTACK_2 ) {
		id = GEnum::Motion::ATTACK_2;
	}else if(st == StateType::DAMAGE){
		id = this->getDamageSequenceID(obj);

		
	}else if(st == StateType::DAMAGE_FLYDOWN){
		id = GEnum::Motion::DAMAGE_FLYDOWN;
	}else if(st == StateType::DAMAGE_FLYDOWN_REVERSE){
		id = GEnum::Motion::DAMAGE_FLYDOWN_REVERSE;
	}else if(st == StateType::DAMAGE_ELEC){
		id = GEnum::Motion::DAMAGE_ELEC;
	}else if(st == StateType::DEAD ||
		st == StateType::LYING)
	{
		id = GEnum::Motion::DEAD;
	}else if(st == StateType::DEAD_FLYDOWN){
		id = GEnum::Motion::DEAD_FLYDOWN;
	}else if(st == StateType::DEAD_FLYUP){
		id = GEnum::Motion::DEAD_FLYUP;
	}else if(st == StateType::HOLD_DOWN){
		id = GEnum::Motion::DAMAGE_HOLD_DOWN;

	}else if(st == StateType::ATTACK_GUN){
		id = GEnum::Motion::ATTACK_GUN;
	}else if(st == StateType::HOLD){
		id = GEnum::Motion::DAMAGE_HOLD;

	}else if(st == StateType::BIND_DAMAGE_ELEC){
		id = GEnum::Motion::BIND_DAMAGE_ELEC;
	}else if(st == StateType::BIND){
		id = GEnum::Motion::BIND;

	}else if(st == StateType::EATENING){
		id = GEnum::Motion::EATENING;
	}else if(st == StateType::DISAPPEAR){
		id = GEnum::Motion::EATEN;
	}else if(st == StateType::BIND_DAMAGE){
		id = GEnum::Motion::BIND_DAMAGE;
	}else if(st == StateType::BROKEN){
		id = GEnum::Motion::BROKEN;
	} else if( st == StateType::CAKE && this->m_vecPlayerSequenceNumbers[obj->getType()] >= Motion::TAUNT ) {
		// TAUNTかつ、そのシーケンスを持つもの
		id = GEnum::Motion::TAUNT;
	}

	return id;
}

int GCommonWork::getDamageSequenceID(HPLShootingObject* player){
	int st = player->getState()->getState();

	int id = GEnum::Motion::DAMAGE;
	return id;
}


void GCommonWork::setDamageFlyingState(HPLShootingObject* obj){
	int nNextState = HPLActionMoveTool::setDamageFlyingState( obj );

	if(nNextState >= 0){
		if(obj->getObjectType() == ObjectType::PLAYER){
			((GPlayer*)obj)->changeState(nNextState);
		}/*else{
			((TTEnemy*)obj)->changeState(nextState);
		}*/

	}

}

/** プレイヤーなのか敵なのか判別して取得
  */
HPLSequence* GCommonWork::getSequenceFromObject( HPLShootingObject* lpObject ) {
	if( lpObject->getObjectType() == ObjectType::PLAYER) {
		return ((GPlayer*)lpObject)->getSequence();
	} else if( lpObject->getObjectType() == ObjectType::ENEMY ) {
		//return ((GEnemy*)lpObject)->getSequence();
	} else if( lpObject->getObjectType() == ObjectType::EFFECT ) {
		return ((GEffect*)lpObject)->getSequence();
	} else if( lpObject->getObjectType() == ObjectType::SHOT ) {
		return ((GShot*)lpObject)->getSequence();
	
	} else {
		HPLError::error( "invalid object type[%d]", lpObject->getObjectType() );
		return NULL;
	}
	return NULL;
}


void GCommonWork::rollBack( HPLShootingObject* lpObject ) {
	if( lpObject->getObjectType() == ObjectType::PLAYER) {
		((GPlayer*)lpObject)->rollBackState();
	} else {
		this->changeState( lpObject, StateType::STAND );
	}
}


/**
  * 二つのオブジェクトの当り判定を行う
  * 通常版
  * @param[in]	lpoObject1
  * @param[in]	lpoObject2
  * @retval	true	接触時
  */
bool GCommonWork::isHit( HPLShootingObject* lpoObject1, HPLShootingObject* lpoObject2 ) {
	//return lpoObject1->getHitArea().isShare( lpoObject2->getHitArea() );
	return HPLActionMoveTool::isHit( lpoObject1, lpoObject2 );
}

void GCommonWork::blowAway( HPLShootingObject* lpoBlower,
						   HPLShootingObject* lpoTarget , float fSpeed)
{
	HPLActionMoveTool::blowAway( lpoBlower, lpoTarget, fSpeed );
}

static const int MAX_SIZE = 256;
void GCommonWork::drawNumbers( int nLeft, int nTop, int nNum ) {
	char buf[MAX_SIZE];
	// 文字列にする
	sprintf( buf, "%d", nNum );

	HPLSequence* lpSequence = getStaticData()->getSequence( SpriteType::COMMON, Common::NUMBERS );

	HPLImageInformation* lpInfo = lpSequence->getImageInformation(0);

	for( int i = 0; i < static_cast<int>( strlen( buf ) ); i ++ ) {
		// 表示位置調整
		int nX = static_cast<int>( nLeft + i * lpInfo->srcRect.getWidth() );

		// 数字に合わせて切り取り位置調整
		int nNumIndex = buf[i] - '0';
		lpInfo->srcRect.setX( nNumIndex * lpInfo->srcRect.getWidth() );

		float rotate = 0;
		int alpha = 255;

		float rate = 1;
		float zoomx = rate;
		float zoomy = rate;

#ifdef _DXLIB
		DrawRectGraph( nX, nTop, lpInfo->srcRect.getX(), lpInfo->srcRect.getY(),
			lpInfo->srcRect.getWidth(), lpInfo->srcRect.getHeight(),
			getStaticData()->m_Basic.m_Graphics.m_ImageManager.get( lpInfo->imageTag ),
			TRUE, FALSE );
#else
		HPLSDLImageTool::blitRotozoomSpriteLeftTop(
			static_cast<float>( nX ),
			static_cast<float>( nTop ), rotate, lpSequence, getStaticData()->getImageManager(),
			getStaticData()->getGraphics()->getScreen(), alpha,
			rate, rate);
#endif
	}
}

void GCommonWork::hitToPlayer( HPLShootingObject* lpDamageSource, GPlayer* lpTargetPlayer, float fSpeed, float fDamage ) {

	fSpeed += lpTargetPlayer->getStoredDamage() / 10.f;

	this->blowAway( lpDamageSource, lpTargetPlayer, fSpeed );

	// ダメージが溜まる
	lpTargetPlayer->addDamage( fDamage );
	
	// ダメージ状態になる
	lpTargetPlayer->changeState( StateType::DAMAGE );
}

/** プレイヤーの種類をランダムにする
  * @param[in]	bIsExceptController		操作しているプレイヤーについては除外
  */
void GCommonWork::randomPlayers( bool bIsExceptController ) {

	int nExceptionPlayerIndex = getStaticData()->m_ObjectManager.m_nPlayingIndex;
	int nExceptedPlayerType = getStaticData()->m_ObjectManager.m_aryPlayerList[nExceptionPlayerIndex].getType();

	if( bIsExceptController == false ) {
		nExceptionPlayerIndex = -1;
		nExceptedPlayerType = -1;
	}
	
	vector<int> vecTypes = GEnum::randomPlayers( nExceptionPlayerIndex, nExceptedPlayerType  );
	for( int i = 0; i < PLAYER_MAX_NUM; i ++ ) {
		GPlayer* lpPlayer = &getStaticData()->m_ObjectManager.m_aryPlayerList[i];
		lpPlayer->changeType( vecTypes[i] );
	}
/*
	bool bAlreadySetList[ PlayerType::MAX_NUM ];
	for( int i = 0; i < PlayerType::MAX_NUM; i ++ ) {
		bAlreadySetList[i] = false;
	}

	// 全部埋まった
	bool bIsFilled = false;

	for( int i = 0; i < GEnum::PLAYER_MAX_NUM; i ++ ) {

		GPlayer* lpPlayer = &getStaticData()->m_ObjectManager.m_aryPlayerList[i];
		int nType = lpPlayer->getType();
		if( bIsExceptController && 
			i == getStaticData()->m_ObjectManager.m_nPlayingIndex ) 
		{
			// do nothing
		} else {
			// ランダム
			nType = HPLMath::nextInt(0,PlayerType::MAX_NUM );
			if( bIsFilled ) {
				// 全部予約済み
				// ランダムにするしかない
				// do nothing
			} else {
				
				int nCounter = 1;
				while( bAlreadySetList[nType] && nCounter < PlayerType::MAX_NUM) {
					// 既に選択されている
					
					// 他のを探す
					nType = HPLMath::nextInt(0,PlayerType::MAX_NUM );
					nCounter ++;
				}
				if( nCounter >= PlayerType::MAX_NUM ) {
					// 全て埋まっていた

					// ランダムにする。以降は全部ランダム
					bIsFilled = true;
				}
					
			}
			lpPlayer->changeType( nType );
		}
		bAlreadySetList[ nType ] = true;
	}
*/
}
GEffect* GCommonWork::createEffect(int nType, const HPLVector& vFrom, const HPLVector& vTo,
	int nCreateEnemyType, int nForceID )
{
	HPLVector vecEffectCenter = vFrom;
	vecEffectCenter.add( vTo );
	vecEffectCenter.multiple( 0.5f );
		
	GEffect* lpEffect = getStaticData()->m_ObjectManager.m_EffectManager.create(
		nType, vecEffectCenter, nCreateEnemyType, nForceID );
	return lpEffect;
}

HPLSequencePair* GCommonWork::getWeaponSequencePair(GPlayer& lpPlayer) {
	int t = lpPlayer.getType();
	int st = lpPlayer.getState()->getState();

	if( t == PlayerType::EVIGEN ) {
		if( st == StateType::ATTACK ){
			// Z:近接：火炎放射
			return lpPlayer.m_lpEvigenWeaponSprite->getPair( Sequence::EvigenWeapon::FRAME_THROWER );
		} else if( st == StateType::ATTACK_GUN ) {
			return lpPlayer.m_lpEvigenWeaponSprite->getPair( Sequence::EvigenWeapon::MINIGUN_NORMAL );
		} else if( st == StateType::ATTACK_2 ) {
			// 見アイル
			return lpPlayer.m_lpEvigenWeaponSprite->getPair( Sequence::EvigenWeapon::MISSILE_LAUNCHER );
		}
	} else if( t == PlayerType::DURANDANA ) {
		return lpPlayer.m_lpDurandalSprite->getPair( lpPlayer.getSequenceID() );
	}
	return NULL;
}

void GCommonWork::drawPlayerWeapon( GPlayer& player, int nLeft, int nTop )
/*	int nPlayerType, HPLState state,
	HPLSprite* m_lpEvigenWeaponSprite,
	HPLSprite* m_lpDurandalSprite,
	int nFaceDirection,
	int left, int top,
	int nSequenceID

	)*/
{
	// zoom
	HPLScroller* lpScroller = getStaticData()->getScrollManager()->getScroller(0);
	float fZoom = lpScroller->m_fZoomRate;
	float fCenterX = player.getCenter().getX() + lpScroller->getVirtualRect().getX();
	float fCenterY = player.getCenter().getY() + lpScroller->getVirtualRect().getY();
	fCenterX *= fZoom;
	fCenterY *= fZoom;

	// プレイヤーの武器シーケンス取得
	HPLSequencePair* lpPair = this->getWeaponSequencePair( player );

	int nPlayerType = player.getType();
	int nFaceDirection = player.getFaceDirection();

	if( lpPair != NULL ) {
		if( nPlayerType == GEnum::PlayerType::EVIGEN ) {
			// シーケンス取得
			HPLSequence* lpWeaponSequence = 
#ifdef _DXLIB
				lpPair->left;
#else
				nFaceDirection == FaceDirection::LEFT ?
				lpPair->left:
				lpPair->right;
#endif

			float rotateAngle = 0;
			int alpha = 255;

#ifdef _DXLIB
			getStaticData()->m_Basic.m_Graphics.draw(
				fCenterX, fCenterY, lpPair->left,
				player.getFaceDirection(), rotateAngle, fZoom );
#else
			HPLSDLImageTool::blitRotozoomSpriteLeftTop(
				static_cast<float>( nLeft ),
				static_cast<float>( nTop ), rotateAngle, lpWeaponSequence, getStaticData()->getImageManager(),
				getStaticData()->getGraphics()->getScreen(), alpha);
#endif
			if(this->m_Game.isTheWorld() == false){
				if(lpWeaponSequence->step().isFinishAnimation ) {
					lpWeaponSequence->resetCounter();
				}
			}
		} else if( nPlayerType == PlayerType::DURANDANA ) {
			// 腕表示
			HPLSequence* lpDurandalSequence = 
#ifdef _DXLIB
				lpPair->left;
#else
				nFaceDirection == FaceDirection::RIGHT ?
				lpPair->right :
				lpPair->left;
#endif

			float rotateAngle = 0;
			int alpha = 255;

#ifdef _DXLIB
			getStaticData()->m_Basic.m_Graphics.draw(
				fCenterX, fCenterY, lpPair->left,
				player.getFaceDirection(), rotateAngle, fZoom );
#else
			HPLSDLImageTool::blitRotozoomSpriteLeftTop(
				static_cast<float>( nLeft ),
				static_cast<float>( nTop ), rotateAngle, lpDurandalSequence, getStaticData()->getImageManager(),
				getStaticData()->getGraphics()->getScreen(), alpha);
#endif

			if(this->m_Game.isTheWorld() == false){
				if(lpDurandalSequence->step().isFinishAnimation ) {
					lpDurandalSequence->resetCounter();
				}
			}
		}
	}
}


//! AI/プレイヤー操作の種類
namespace AIType {
	enum {
		PC,
		NPC_AI,
		NPC_TITLE,		//! 左に行くだけ。時々攻撃。時々ジャンプ
		NO_AI,			//! なすがまま。アニメーション有り。自然落下有り
	};
}
static GPlayerManager playerManager;	//! 操作管理用
void GCommonWork::defaultPlayerProcess( GPlayer* lpPlayer, bool bIsEnemy ) {

	int nAIType = AIType::NPC_AI;

	if( lpPlayer->isAlive() == false ) {
		// 死んでる
		// ・量産キャラ：即消えるので何もしない
		// ・PC/NPC		：動かない＆表示しない状態なので何もしない
		return;
	}
	// 現在のゲームシーンタイプ判別
	if( this->m_nGameSceneType == GameSceneType::G_TITLE ) {
		// タイトルシーン
		// どのタイプもタイトル画面AIとなる
		// 量産キャラはタイトルでは発生しない
		nAIType = AIType::NPC_TITLE;

	} else {	// this->m_nGameSceneType

		if( getStaticData()->m_lpReadyGoSequence->getState().isFinishAnimation == false ) {
			// ゲームスタート時のウエイト中

			// 何もしない
			nAIType = AIType::NO_AI;
		} else {
			// 自軍である
			bool bIsAlly = lpPlayer->m_nForceID == getStaticData()->m_ObjectManager.m_nPlayingIndex;

			if( bIsEnemy ) {
				// 量産キャラ

				if( this->isTestStage() && bIsAlly == false) {
					// テストステージ
					//  and
					// 敵軍

					// なすがまま
					nAIType = AIType::NO_AI;
				} else {
					// AI動作
					nAIType = AIType::NPC_AI;
				}
			} else {

				bool bIsDefaultAIType = false;		// デフォルトのAI設定か？

				// プレイヤーキャラクタ(PC/NPC)
				if( this->m_nGameSceneType == GameSceneType::G_GAME ) {
					// ゲームシーン
					
					bIsDefaultAIType = true;

				} else if( this->m_nGameSceneType == GameSceneType::G_RESULT ) {
					// 結果シーン

					if( lpPlayer->m_nForceID == this->m_nWinnerForceID ) {
						// Winner

						bIsDefaultAIType = true;

					} else {
						// Loser
						// なすがまま
						nAIType = AIType::NO_AI;
					}
				} else {
					HPLError::assertIt(false, "対応していない新ステート[%d]", this->m_nGameSceneType);
				} 

				if( bIsDefaultAIType ) {
					// デフォルト設定
					if( this->m_Game.m_bIsAutoPlay == false && bIsAlly )
					{
						// オートプレイ中ではない
						// 自軍

						// プレイヤー操作
						nAIType = AIType::PC;
					} else {
						// 操作対象以外

						if( this->isTestStage() ) {
							// テストステージ

							// なすがまま
							nAIType = AIType::NO_AI;
						} else {
							// NPC
							nAIType = AIType::NPC_AI;
						}
					}
				}
			} // bIsEnemy
		}
	} // this->m_nGameSceneType

	if( nAIType == AIType::PC ) {
		// プレイヤー操作キャラである
#ifdef _DXLIB

		// キー操作での移動決定
		lpPlayer->updateKeyState( true,
			getStaticData()->getInputManager(),
			KeyMap::MAX_KEY);

#else
		HPLSDLInputManager* inputManager = getStaticData()->getInputManager();

		///////
		// キー入力をプレイヤーに反映
		lpPlayer->updateKeyState(true, inputManager, GEnum::KeyMap::MAX_KEY);
#endif

	} else {
		// NPC/NO_AI
		// 操作できない対象
#ifdef _DXLIB
		lpPlayer->updateKeyState( false, NULL, KeyMap::MAX_KEY );
#else
		lpPlayer->updateKeyState( false, NULL, KeyMap::MAX_KEY );
#endif
		if( nAIType == AIType::NPC_AI ) {

			// NPCのAI動作
			playerManager.moveAI( lpPlayer );

		} else if( nAIType == AIType::NPC_TITLE ) {

			// AI
			lpPlayer->updateKeyState( false, NULL, KeyMap::MAX_KEY );

			// キーリセット
			lpPlayer->resetKeyState( KeyMap::MAX_KEY );

			//playerManager.moveAI( player );

			// 左へ進む
			lpPlayer->setKeyState( KeyMap::LEFT , true );

			if( HPLMath::nextDouble(0,100 ) < 1.0 ) {
				// たまに攻撃する
				lpPlayer->setKeyState( KeyMap::A + HPLMath::nextInt(0,3 ), true );
			} 
			if( HPLMath::nextDouble(0,100) < 5.f ) {
				// たまにジャンプ
				lpPlayer->setKeyState( KeyMap::UP, true );
			}
		} else if( nAIType == AIType::NO_AI ) {
			// キー解放
			lpPlayer->resetKeyState( KeyMap::MAX_KEY);
		}

	}
	////
	// aiboもアップデートだけする
	//aibo->updateKeyState(false, inputManager, GEnum::KeyMap::MAX_KEY);

	/////
	// aiboのAI行動
	// 相棒表示時のみ
	/*if(player->isWithAibo()){
		playerManager.aiboMove(player, aibo);
	}*/


	////////////////////////////////////////////////////////////////////////////
	// collision check
	// fall and hit to collision
	HPLVector velocityAngle = lpPlayer->getVelocityAngle();
	HPLVector center = lpPlayer->getCenter();
	playerManager.collisionCheck(
		lpPlayer,
		&center, &velocityAngle);
	//center.add(velocityAngle);
	//player->setCenter(center);
	//player->setVelocityAngle(velocityAngle);
	
	/*if(player->isWithAibo()){
		velocityAngle = aibo->getVelocityAngle();
		center = aibo->getCenter();
		playerManager.collisionCheck(
			getStaticData()->m_ObjectManager.m_Player->aibo,
			&center, &velocityAngle);
		//center.add(velocityAngle);
		//aibo->setCenter(center);
		//aibo->setVelocityAngle(velocityAngle);
	}*/

	////////////////////////////////////////////////////////////////////////////
	// input moving
	
	velocityAngle = lpPlayer->getVelocityAngle();
	playerManager.move(
		lpPlayer, &velocityAngle);
	lpPlayer->setVelocityAngle(velocityAngle);


	/*if(player->isWithAibo()){
		velocityAngle = aibo->getVelocityAngle();
		playerManager.move(
			aibo, &velocityAngle);
		aibo->setVelocityAngle(velocityAngle);
	}*/

	////////////////////////////////////////////////////////////////////////////
	// attack
	velocityAngle = lpPlayer->getVelocityAngle();
	center = lpPlayer->getCenter();
	playerManager.attack(
		lpPlayer, &center, &velocityAngle);
	//center.add(velocityAngle);
	//player->setCenter(center);

	lpPlayer->setVelocityAngle(velocityAngle);

	// 攻撃ヒット確認
	playerManager.checkHitToPlayer( lpPlayer );
	/*if(player->isWithAibo()){
		velocityAngle = aibo->getVelocityAngle();
		center = aibo->getCenter();
		playerManager.attack(
			aibo, &center, &velocityAngle);
		//center.add(velocityAngle);
		aibo->setCenter(center);
		aibo->setVelocityAngle(velocityAngle);
	}*/
}

/** 敵がサンドバックのステージ
  */
bool GCommonWork::isTestStage() {
	
	return getStaticData()->getMapManager()->getSelectedMap() == MapType::MAP003;

}

/** 使いまわしのゲームシーンを初期化
  */
void GCommonWork::changeGameSceneType( int nGameSceneType ) {
	// 同じゲームシーンを使いまわしているため、手動で初期化が必要
	getStaticData()->m_SceneManager.getScene()->quit();
	this->setGameSceneType( nGameSceneType );
	getStaticData()->m_SceneManager.setScene( SceneType::GAME );
	getStaticData()->m_SceneManager.getScene()->init();
}

bool GCommonWork::isEnemyCreatable() {
	// タイトル画面では生成できない
	return getStaticData()->m_CommonWork.getGameSceneType() != GameSceneType::G_TITLE;
}

