//////////////////////////////////////////////////////////////////////
//--------------------------------------------------------------------
//	Patche 統合プレイヤースクリプトフレームワーク v0.3.0
//--------------------------------------------------------------------
//	プレイヤースクリプト稼働用エンジン
//////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////
//	スクリプト部
//////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////
//	設定定義部
//////////////////////////////////////////////////////////////////////
let FLAN_CDNS	= "__FLAN_FRAMEWORK";
let FLAN_CD_PLAYER_POWER		= "PLAYER_POWER";
let FLAN_CD_PLAYER_POWER_ENABLE	= "PLAYER_POWER_ENABLE";

//統合プレイヤーフレームワーク用名前空間
let MZC_CDNS_PLAYER = "MZC_CDNS_PLAYER";

//プレイヤーを表すインデックス
let MZC_CD_PLAYERINDEX = "MZC_CD_PLAYERINDEX";

//低速時の魔法陣とドットをステージ側で描画するか
let MZC_CD_PLAYERSLOWEFFECT_ONSTAGE = "MZC_CD_PLAYERSLOWEFFECT_ONSTAGE";

//通常ステージかExステージ（非フルパワー時もアイテム回収）か
let MZC_CD_PLAYER_ISEXMODE = "MZC_CD_PLAYER_ISEXMODE";

//Patche本体が呼び出されたかどうか
let MZC_CD_PLAYER_ISPATCHE = "MZC_CD_PLAYER_ISPATCHE";

//ボムを使用した瞬間か否か
let MZC_CD_PLAYER_ISBOMBED_FRAME = "MZC_CD_PLAYER_ISBOMBED_FRAME";

//アイテム収集ライン
let MZC_CD_PLAYER_ITEM_COLLECT_LINE = "MZC_CD_PLAYER_ITEM_COLLECT_LINE";

//////////////////////////////////////////////////////////////////////
//	メンバ変数(各プレイヤースクリプトからは読み取り専用)
//////////////////////////////////////////////////////////////////////

//プレイヤーを表すインデックス
let m_nPlayerIndex = myIndex;

//Patche本体からの起動か否か
let m_bIsPatche = true;

//現在のフレーム（Pathe初期化時が0）
let m_nCount = 0;

//プレイヤーインデックスを変更してからの経過フレーム（変更時が0）
let m_nPlayerCount = -1;

//ミス中の経過フレーム（ミスした瞬間が0、通常時は-1）
let m_nMissedCount = -1;

//ボムを発動してからの経過フレーム（ボムを撃った瞬間が0、通常時は-1）
let m_nBombCount = -1;

//低速移動か
let m_bIsSlowMove = false;

//現在のパワー
let m_nPower = 0;

//フルパワーモードに達した瞬間か否か
let m_bIsFullPowerFrame = false;

//ショットが押されているか
let m_bIsShooting = false;

//ユーザーが押されているか
let m_bIsUserPushing = false;

//右に移動中か
let m_bIsMoveRight = false;

//左に移動中か
let m_bIsMoveLeft = false;

//まっすぐ移動中か
let m_bIsMoveStraight = true;

//最後に低速キーを押した/放したフレーム
let m_nSlowKeyTime = -1;

//最後に低速キーを押して/放してからの経過フレーム
let m_nSlowKeyPassedTime = -1;

//最後にショットキーを押した/放したフレーム
let m_nShotKeyTime = -1;

//最後にショットキーを押して/放してからの経過フレーム
let m_nShotKeyPassedTime = -1;

//最後にユーザーキーを押した/放したフレーム
let m_nUserKeyTime = -1;

//最後にユーザーキーを押して/放してからの経過フレーム
let m_nUserKeyPassedTime = -1;

//////////////////////////////////////////////////////////////////////
//	プレイヤー固有パラメータ
//////////////////////////////////////////////////////////////////////

//Pアイテム対応にするか
let m_bPlayerPowerEnable = false;

//高速時の移動速度
let m_nPlayerSpeedFast = 0;

//低速時の移動速度
let m_nPlayerSpeedSlow = 0;

//アイテム収集ライン
let m_nPlayerItemCollectLine = 0;

//当たり判定の半径
let m_nPlayerIntersectionRadius = 0;

//グレイズ半径
let m_nPlayerGrazeRadius = 0;

//食らいボム有効フレーム
let m_nPlayerRebirthFrame = 0;

//食らいボム有効フレーム減少量(初期値：3)
let m_nPlayerRebirthFrameReduction = 3;

//初期ボム数
let m_nPlayerInitialBombCount = 0;

//フレームに表示する残機画像ファイルへのパス
let m_sPlayerLifeImage = "";

//フレームに表示する残機画像の範囲（左、上、右、下）
let m_nPlayerLifeImageRect = [ 0, 0, 0, 0 ];

//自弾を定義してあるファイルへのパス
let m_sPlayerShotData = "";

//低速時の魔法陣の描画の有無
let m_bPlayerDrawBorder = false;

//低速時のドットの描画の有無
let m_bPlayerDrawDot = false;

//パワーアップ音を鳴らす段階
let m_nPlayerPowerupSound = [];

//ショット音を鳴らすか否か
let m_bPlayerShotSound = true;

//ロードする画像のリスト
let m_sPlayerImageData = [];

//ロードする効果音のリスト
let m_sPlayerSoundData = [];

let m_bPlayerSupportZapping = false;

//////////////////////////////////////////////////////////////////////
//	内部使用グローバル変数・共通データ
//////////////////////////////////////////////////////////////////////

//低速時エフェクトをステージ側で描写する
let m_bIsDrawSlowEffectOnStage = false;

//前回パワーアップ音を鳴らしたフレーム
let m_nPowerupedFrame = -65535;

//EXモードか
let m_bIsExMode = false;

//各キーを一度は押したか
let m_bIsPushSlow = false;
let m_bIsPushShot = false;
let m_bIsPushUser = false;

//プレイヤードットタスクオブジェクト
let m_objPlayerDotObj = Obj_Create( OBJ_EFFECT );

//プレイヤードットタスク継続フラグ
let m_bIsContinueDotTask = false;

//ザッピング可能か否か
let m_bZappingEnable = false;

//ザッピング直前のボム数
let m_nOldBombCount = -1;

//////////////////////////////////////////////////////////////////////
//	メイン動作部
//////////////////////////////////////////////////////////////////////

@Initialize {
	if ( IsCommonDataAreaExists( MZC_CDNS_PLAYER ) == false ) {
		CreateCommonDataArea( MZC_CDNS_PLAYER );
	}
	if ( IsCommonDataAreaExists( FLAN_CDNS ) == false ) {
		CreateCommonDataArea( FLAN_CDNS );
	}
	SetCommonDataEx( MZC_CDNS_PLAYER, MZC_CD_PLAYER_ISPATCHE, bPatche );
	m_bIsPatche = bPatche;
	m_nCount = 0;
	m_nMissedCount = -1;
	m_nBombCount = -1;
	SetAutoEffect( false );
	SetPlayerInvincibility( 0 );
	SetInitialBombCount( 0 );
	InitializeBaseTask();
}

//初回起動時にのみ呼び出される初期化タスク
task InitializeBaseTask() {
	let playerDefaultX = GetCenterX();
	let playerDefaultY = 400;
	//明示的に各CommonDataが定義されるまでは全ての処理を延期する
	while ( m_nPlayerIndex < 0 ) {
		let pindex = GetCommonDataDefaultEx( MZC_CDNS_PLAYER, MZC_CD_PLAYERINDEX, -1 );
		if ( 0 <= pindex && pindex < playerNum ) {
			m_nPlayerIndex = pindex;
		}
		SetX( playerDefaultX );
		SetY( playerDefaultY );
		yield;
	}
	SetX( playerDefaultX );
	SetY( playerDefaultY );

	SetAutoEffect( true );
	m_bIsSlowMove = false;
	m_nPower = GetCommonDataDefaultEx( FLAN_CDNS, FLAN_CD_PLAYER_POWER, 0 );
	m_bIsDrawSlowEffectOnStage = GetCommonDataDefaultEx( MZC_CDNS_PLAYER,
														 MZC_CD_PLAYERSLOWEFFECT_ONSTAGE,
														 false );
	m_bIsFullPowerFrame = false;
	m_bIsShooting = false;
	m_bIsUserPushing = false;
	m_bIsMoveRight = false;
	m_bIsMoveLeft = false;
	m_bIsMoveStraight = true;
	m_bIsExMode = GetCommonDataDefaultEx( MZC_CDNS_PLAYER, MZC_CD_PLAYER_ISEXMODE, false );
	m_bIsPushSlow = false;
	m_bIsPushShot = false;
	m_bIsPushUser = false;

	//共通リソース読み込み
	LoadSE( m_sSePlayerShotSound );
	LoadSE( m_sSePlayerPowerupSound );
	LoadGraphic( m_sImgPlayerBorder );
	LoadGraphic( m_sImgPlayerDot );

	if ( m_bIsPatche == true ) {
		changePlayerIndexTask();
	}
	else {
		watchInitCommonDataTask();
	}
	InitializePlayerTask();
}

//プレイヤーインデックス設定時に呼び出される初期化タスク
task InitializePlayerTask() {
	m_bPlayerPowerEnable = playerPowerEnable[ m_nPlayerIndex ];
	m_nPlayerSpeedFast = playerSpeedFast[ m_nPlayerIndex ];
	m_nPlayerSpeedSlow = playerSpeedSlow[ m_nPlayerIndex ];
	m_nPlayerItemCollectLine = playerItemCollectLines[ m_nPlayerIndex ];
	m_nPlayerIntersectionRadius = playerIntersectionRadius[ m_nPlayerIndex ];
	m_nPlayerGrazeRadius = playerGrazeRadius[ m_nPlayerIndex ];
	m_nPlayerRebirthFrame = playerRebirthFrame[ m_nPlayerIndex ];
	m_nPlayerRebirthFrameReduction = playerRebirthFrameReduction[ m_nPlayerIndex ];
	m_nPlayerInitialBombCount = playerInitialBombCount[ m_nPlayerIndex ];
	m_sPlayerLifeImage = playerLifeImages[ m_nPlayerIndex ];
	m_nPlayerLifeImageRect = playerLifeImageRects[ m_nPlayerIndex ];
	m_sPlayerShotData = playerShotData[ m_nPlayerIndex ];
	m_bPlayerDrawBorder = playerDrawBorder[ m_nPlayerIndex ];
	m_bPlayerDrawDot = playerDrawDot[ m_nPlayerIndex ];
	m_nPlayerPowerupSound = playerPowerupSound[ m_nPlayerIndex ];
	m_bPlayerShotSound = playerShotSound[ m_nPlayerIndex ];
	m_sPlayerImageData = playerImageData[ m_nPlayerIndex ];
	m_sPlayerSoundData = playerSoundData[ m_nPlayerIndex ];
	m_bPlayerSupportZapping = playerSupportZapping[ m_nPlayerIndex ];

	//ステージがパワーアップサポート外ならフルパワー固定する
	if ( GetCommonDataDefaultEx( FLAN_CDNS, FLAN_CD_PLAYER_POWER_ENABLE, false ) == false ) {
		m_bPlayerPowerEnable = false;
		m_nPower = 128;
		SetCommonDataEx( FLAN_CDNS, FLAN_CD_PLAYER_POWER, 128 );
	}

	//単体稼働の場合
	if ( bPatche == false ) {
		m_bIsExMode = false;
		m_bIsDrawSlowEffectOnStage = false;
	}
	
	ascent ( let i in 0..length( m_sPlayerImageData ) ) {
		LoadGraphic( m_sPlayerImageData[ i ] );
	}
	ascent ( let i in 0..length( m_sPlayerSoundData ) ) {
		LoadSE( m_sPlayerSoundData[ i ] );
	}

	//自弾ロード
	LoadPlayerShotData( m_sPlayerShotData );
	
	if ( length( m_sPlayerLifeImage ) > 0 ) {
		//残機数の画像
		SetPlayerLifeImage( m_sPlayerLifeImage,
							m_nPlayerLifeImageRect[ 0 ],
							m_nPlayerLifeImageRect[ 1 ],
							m_nPlayerLifeImageRect[ 2 ],
							m_nPlayerLifeImageRect[ 3 ] );
	}

	//移動速度を設定
	SetSpeed( m_nPlayerSpeedFast, m_nPlayerSpeedSlow );


	//アイテム回収ラインを設定
	SetItemCollectLine( [ m_nPlayerItemCollectLine, -1 ][ m_bPlayerPowerEnable == true
														  && m_bIsExMode == false
														  && m_nPower < 128 ] );
	SetCommonDataEx( MZC_CDNS_PLAYER, MZC_CD_PLAYER_ITEM_COLLECT_LINE,
					 [ m_nPlayerItemCollectLine, -1 ][ m_bPlayerPowerEnable == true
													   && m_bIsExMode == false
													   && m_nPower < 128 ] );
	
	//グレイズ半径を設定
	SetGrazeCircle( m_nPlayerGrazeRadius );

	//ボム初期値を設定
	SetInitialBombCount( m_nPlayerInitialBombCount );
	if ( m_nOldBombCount >= 0 ) {
		AddBomb( -m_nPlayerInitialBombCount );
		AddBomb( m_nOldBombCount );
	}

	//食らいボム有効フレームを設定
	SetRebirthFrame( m_nPlayerRebirthFrame );

	//食らいボム有効フレーム減少量(初期値：3)を設定
	SetRebirthFrameReduction( [ 3, m_nPlayerRebirthFrameReduction ][ m_nPlayerRebirthFrameReduction >= 0 ] );

	//低速時のドットタスク開始
	if ( m_bPlayerDrawDot == true && m_bIsDrawSlowEffectOnStage == false ) {
		m_bIsContinueDotTask = true;
		m_objPlayerDotObj = makePlayerDot( m_sImgPlayerDot );
	}

	//本体呼び出しであり、プレイヤースクリプトがザッピングに対応している場合のみザッピング可能
	if ( m_bPlayerSupportZapping == true && m_bIsPatche == true ) {
		m_bZappingEnable = true;
	}
	else {
		m_bZappingEnable = false;
	}

	//ボムフラグ初期化
	SetCommonDataEx( MZC_CDNS_PLAYER, MZC_CD_PLAYER_ISBOMBED_FRAME, false );
	
	//プレイヤーカウント初期化
	m_nPlayerCount = 0;
			
	//各スクリプト固有処理
	onInitialize();
	
	MainTask();
}

@MainLoop {
	if ( m_nPlayerIndex < 0 ) {
		let pindex = GetCommonDataDefaultEx( MZC_CDNS_PLAYER, MZC_CD_PLAYERINDEX, -1 );
		if ( 0 <= pindex && pindex < playerNum ) {
			m_nPlayerIndex = pindex;
		}
		m_nPlayerIndex = pindex;
	}

	//汎用カウンタ更新
	m_nCount++;
	m_nPlayerCount++;

	if ( m_nPlayerIndex >= 0 ) {
		//ミス時カウンタ更新
		if ( OnMissed() == false ) {
			m_nMissedCount = -1;
		}

		//ボムカウンタ更新
		if ( OnBomb() == true ) {
			m_nBombCount++;
			if ( m_nBombCount == 0 ) {
				//ボムフラグ更新
				SetCommonDataEx( MZC_CDNS_PLAYER, MZC_CD_PLAYER_ISBOMBED_FRAME, true );
			}
			else {
				//ボムフラグ更新
				SetCommonDataEx( MZC_CDNS_PLAYER, MZC_CD_PLAYER_ISBOMBED_FRAME, false );
			}
		}
		else {
			m_nBombCount = -1;
			//ボムフラグ更新
			SetCommonDataEx( MZC_CDNS_PLAYER, MZC_CD_PLAYER_ISBOMBED_FRAME, false );
		}

		//パワー更新
		if ( m_bPlayerPowerEnable == true ) {
			m_bIsFullPowerFrame = false;
			let oldPower = m_nPower;
			let power = GetCommonDataDefaultEx( FLAN_CDNS, FLAN_CD_PLAYER_POWER, 0 );
			if ( 0 <= power && power < 128 ) {
				m_nPower = power;
			}
			else if ( power < 0 ) {
				m_nPower = 0;
			}
			else {
				m_nPower = 128;
			}
			if ( oldPower < 128 && m_nPower == 128 ) {
				m_bIsFullPowerFrame = true;
				if ( m_bIsExMode == false ) {
					SetItemCollectLine( m_nPlayerItemCollectLine );
					SetCommonDataEx( MZC_CDNS_PLAYER, MZC_CD_PLAYER_ITEM_COLLECT_LINE,
									 m_nPlayerItemCollectLine );
				}
				DeleteEnemyShotToItem( SHOT );
			}
			ascent( let i in 0..length( m_nPlayerPowerupSound ) ) {
				if ( oldPower < m_nPlayerPowerupSound[ i ]
					 && m_nPower >= m_nPlayerPowerupSound[ i ] ) {
					if ( m_nPowerupedFrame + 30 < m_nCount ) {
						m_nPowerupedFrame = m_nCount;
						PlaySE( m_sSePlayerPowerupSound );
					}
					break;
				}
			}
		}

		//低速移動フラグ更新
		if ( GetKeyState( VK_SLOWMOVE ) == KEY_PUSH
			 || GetKeyState( VK_SLOWMOVE ) == KEY_HOLD ) {
			m_bIsSlowMove = true;
			if ( m_bIsPushSlow == false ) {
				m_bIsPushSlow = true;
			}
		}
		else {
			m_bIsSlowMove = false;
		}

		//ショットが押されているか
		if ( GetKeyState( VK_SHOT ) == KEY_PUSH
			 || GetKeyState( VK_SHOT ) == KEY_HOLD ) {
			m_bIsShooting = true;
			if ( m_bIsPushShot == false ) {
				m_bIsPushShot = true;
			}
		}
		else {
			m_bIsShooting = false;
		}

		//ユーザーが押されているか
		if ( GetKeyState( VK_USER ) == KEY_PUSH
			 || GetKeyState( VK_USER ) == KEY_HOLD ) {
			m_bIsUserPushing = true;
			if ( m_bIsPushUser == false ) {
				m_bIsPushUser = true;
			}
		}
		else {
			m_bIsUserPushing = false;
		}

		//どの方向に移動中か
		if ( GetKeyState( VK_LEFT ) == KEY_PUSH
			 || GetKeyState( VK_LEFT ) == KEY_HOLD ) {
			m_bIsMoveRight = false;
			m_bIsMoveLeft = true;
			m_bIsMoveStraight = false;
		}
		else if ( GetKeyState( VK_RIGHT ) == KEY_PUSH
				  || GetKeyState( VK_RIGHT ) == KEY_HOLD ) {
			m_bIsMoveRight = true;
			m_bIsMoveLeft = false;
			m_bIsMoveStraight = false;
		}
		else {
			m_bIsMoveRight = false;
			m_bIsMoveLeft = false;
			m_bIsMoveStraight = true;
		}

		//低速キー時間チェック更新
		if ( GetKeyState( VK_SLOWMOVE ) == KEY_PUSH
			 || GetKeyState( VK_SLOWMOVE ) == KEY_PULL ) {
			m_nSlowKeyTime = m_nCount;
		}
		if ( m_bIsPushSlow == true ) {
			m_nSlowKeyPassedTime = m_nCount - m_nSlowKeyTime;
		}

		//ショットキー時間チェック更新
		if ( GetKeyState( VK_SHOT ) == KEY_PUSH
			 || GetKeyState( VK_SHOT ) == KEY_PULL ) {
			m_nShotKeyTime = m_nCount;
		}
		if ( m_bIsPushShot == true ) {
			m_nShotKeyPassedTime = m_nCount - m_nShotKeyTime;
		}

		//ユーザーキー時間チェック更新
		if ( GetKeyState( VK_USER ) == KEY_PUSH
			 || GetKeyState( VK_USER ) == KEY_PULL ) {
			m_nUserKeyTime = m_nCount;
		}
		if ( m_bIsPushUser == true ) {
			m_nUserKeyPassedTime = m_nCount - m_nUserKeyTime;
		}

		//当たり判定設定
		SetIntersectionCircle( GetPlayerX(), GetPlayerY(), m_nPlayerIntersectionRadius );

		//ショット音
		if ( m_bIsShooting == true
			 && m_bPlayerShotSound == true
			 && OnEvent() == false
			 && m_nCount % 5 == 0 ) {
			PlaySE( m_sSePlayerShotSound );
		}

		//各スクリプト固有処理
		onMainLoop();
		yield;
	}
}

@Missed {
	//※　カウンタ更新系はこちらでも同様に更新する
	//MainLoopを呼び出さないのは、各プレイヤースクリプト中での
	//MainLoop中の固有処理を考慮してのこと

	//汎用カウンタ更新
	m_nCount++;
	m_nPlayerCount++;

	if ( m_nPlayerIndex >= 0 ) {

		//ミス時カウンタ更新
		m_nMissedCount++;

		//パワー更新
		if ( m_bPlayerPowerEnable == true ) {
			if ( m_nMissedCount == 0 ) {
				m_nPower -= 16;
				if ( m_nPower < 0 ) {
					m_nPower = 0;
				}
				SetCommonDataEx( FLAN_CDNS, FLAN_CD_PLAYER_POWER, m_nPower );
				if ( m_bIsExMode == false ) {
					SetItemCollectLine( -1 );
					SetCommonDataEx( MZC_CDNS_PLAYER, MZC_CD_PLAYER_ITEM_COLLECT_LINE,
									 -1 );
				}
			}
			m_bIsFullPowerFrame = false;
			let oldPower = m_nPower;
			let power = GetCommonDataDefaultEx( FLAN_CDNS, FLAN_CD_PLAYER_POWER, 0 );
			if ( 0 <= power && power < 128 ) {
				m_nPower = power;
			}
			else if ( power < 0 ) {
				m_nPower = 0;
			}
			else {
				m_nPower = 128;
			}
			if ( oldPower < 128 && m_nPower == 128 ) {
				m_bIsFullPowerFrame = true;
				if ( m_bIsExMode == false ) {
					SetItemCollectLine( m_nPlayerItemCollectLine );
					SetCommonDataEx( MZC_CDNS_PLAYER, MZC_CD_PLAYER_ITEM_COLLECT_LINE,
									 m_nPlayerItemCollectLine );
				}
				DeleteEnemyShotToItem( SHOT );
			}
		}

		//低速移動フラグ更新
		if ( GetKeyState( VK_SLOWMOVE ) == KEY_PUSH
			 || GetKeyState( VK_SLOWMOVE ) == KEY_HOLD ) {
			m_bIsSlowMove = true;
			if ( m_bIsPushSlow == false ) {
				m_bIsPushSlow = true;
			}
		}
		else {
			m_bIsSlowMove = false;
		}

		//ショットが押されているか
		if ( GetKeyState( VK_SHOT ) == KEY_PUSH
			 || GetKeyState( VK_SHOT ) == KEY_HOLD ) {
			m_bIsShooting = true;
			if ( m_bIsPushShot == false ) {
				m_bIsPushShot = true;
			}
		}
		else {
			m_bIsShooting = false;
		}

		//ユーザーが押されているか
		if ( GetKeyState( VK_USER ) == KEY_PUSH
			 || GetKeyState( VK_USER ) == KEY_HOLD ) {
			m_bIsUserPushing = true;
			if ( m_bIsPushUser == false ) {
				m_bIsPushUser = true;
			}
		}
		else {
			m_bIsUserPushing = false;
		}

		//どの方向に移動中か
		if ( GetKeyState( VK_LEFT ) == KEY_PUSH
			 || GetKeyState( VK_LEFT ) == KEY_HOLD ) {
			m_bIsMoveRight = false;
			m_bIsMoveLeft = true;
			m_bIsMoveStraight = false;
		}
		else if ( GetKeyState( VK_RIGHT ) == KEY_PUSH
				  || GetKeyState( VK_RIGHT ) == KEY_HOLD ) {
			m_bIsMoveRight = true;
			m_bIsMoveLeft = false;
			m_bIsMoveStraight = false;
		}
		else {
			m_bIsMoveRight = false;
			m_bIsMoveLeft = false;
			m_bIsMoveStraight = true;
		}

		//低速キー時間チェック更新
		if ( GetKeyState( VK_SLOWMOVE ) == KEY_PUSH
			 || GetKeyState( VK_SLOWMOVE ) == KEY_PULL ) {
			m_nSlowKeyTime = m_nCount;
		}
		if ( m_bIsPushSlow == true ) {
			m_nSlowKeyPassedTime = m_nCount - m_nSlowKeyTime;
		}

		//ショットキー時間チェック更新
		if ( GetKeyState( VK_SHOT ) == KEY_PUSH
			 || GetKeyState( VK_SHOT ) == KEY_PULL ) {
			m_nShotKeyTime = m_nCount;
		}
		if ( m_bIsPushShot == true ) {
			m_nShotKeyPassedTime = m_nCount - m_nShotKeyTime;
		}

		//ユーザーキー時間チェック更新
		if ( GetKeyState( VK_USER ) == KEY_PUSH
			 || GetKeyState( VK_USER ) == KEY_PULL ) {
			m_nUserKeyTime = m_nCount;
		}
		if ( m_bIsPushUser == true ) {
			m_nUserKeyPassedTime = m_nCount - m_nUserKeyTime;
		}


		//各スクリプト固有処理
		onMissedLoop();
	}
}

@SpellCard {
	if ( m_nPlayerIndex >= 0 ) {
		//各スクリプト固有処理
		onSpellCard();
	}
}

@DrawLoop {
	if ( m_nPlayerIndex >= 0 ) {
		if ( m_bPlayerDrawBorder == true ) {
			DrawPlayerBorder( m_sImgPlayerBorder, m_nCount );
		}
		if ( m_bPlayerDrawDot == true && m_bIsDrawSlowEffectOnStage == false ) {
			drawPlayerDot( m_objPlayerDotObj, m_nCount );
		}

		//各スクリプト固有処理
		onDrawLoop();
	}
}

@Finalize {
	if ( m_nPlayerIndex >= 0 ) {
		//各スクリプト固有処理
		onFinalize();

		ClearCommonDataEx( MZC_CDNS_PLAYER );
		if ( m_bPlayerDrawBorder == true && m_bIsDrawSlowEffectOnStage == false ) {
			DeleteGraphic( m_sImgPlayerBorder );
		}
		if ( m_bPlayerDrawDot == true && m_bIsDrawSlowEffectOnStage == false ) {
			DeleteGraphic( m_sImgPlayerDot );
		}
		DeleteSE( m_sSePlayerPowerupSound );
		DeleteSE( m_sSePlayerShotSound );

		ascent ( let i in 0..length( m_sPlayerImageData ) ) {
			DeleteGraphic( m_sPlayerImageData[ i ] );
		}
		ascent ( let i in 0..length( m_sPlayerSoundData ) ) {
			DeleteSE( m_sPlayerSoundData[ i ] );
		}
	}
}

task FinalizePlayerTask() {
	//各スクリプト固有処理
	onFinalize();
	if ( Obj_BeDeleted( m_objPlayerDotObj ) == false ) {
		Obj_Delete( m_objPlayerDotObj );
	}
	ascent ( let i in 0..length( m_sPlayerImageData ) ) {
		DeleteGraphic( m_sPlayerImageData[ i ] );
	}
	ascent ( let i in 0..length( m_sPlayerSoundData ) ) {
		DeleteSE( m_sPlayerSoundData[ i ] );
	}
	m_bIsContinueDotTask = false;
}

//////////////////////////////////////////////////////////////////////
//	メソッド定義部
//////////////////////////////////////////////////////////////////////

//	(本体起動専用)プレイヤーインデックスの変更を監視するタスク
task changePlayerIndexTask() {
	loop {
		if ( m_bZappingEnable == true && m_nPlayerIndex >= 0 ) {
			let pindex = GetCommonDataDefaultEx( MZC_CDNS_PLAYER,
												 MZC_CD_PLAYERINDEX,
												 m_nPlayerIndex );
			if ( m_nPlayerIndex != pindex && OnBomb() == false ) {
				//現在のボム数を格納
				m_nOldBombCount = GetPlayerBomb();
				FinalizePlayerTask();
				//インデックス変更処理
				m_nPlayerIndex = pindex;
				InitializePlayerTask();
			}
		}
		yield;
	}
}

//	(個別起動専用)初期化用共通データの格納を監視するタスク
task watchInitCommonDataTask() {
	loop {
		//ステージがパワーアップサポート外ならフルパワー固定する
		if ( GetCommonDataDefaultEx( FLAN_CDNS, FLAN_CD_PLAYER_POWER_ENABLE, false ) == false ) {
			m_bPlayerPowerEnable = false;
			m_nPower = 128;
			SetCommonDataEx( FLAN_CDNS, FLAN_CD_PLAYER_POWER, 128 );
		}
		else {
			m_bPlayerPowerEnable = true;
			m_nPower = 0;
			SetCommonDataEx( FLAN_CDNS, FLAN_CD_PLAYER_POWER, 0 );
			if ( m_bIsExMode == false ) {
				//アイテム回収ラインを設定
				SetItemCollectLine( -1 );
				SetCommonDataEx( MZC_CDNS_PLAYER, MZC_CD_PLAYER_ITEM_COLLECT_LINE,
								 -1 );
			}
			return;
		}
		yield;
	}
}

//	プレイヤーボーダー描画
function DrawPlayerBorder( let file, let count ) {
	let limit = 30;
	let slow = 0;
	let maxAlphaBase = 192;//80;
	let maxAlpha = maxAlphaBase;
	let minAlpha = 0;
	let alpha = 0;

	//低速が一回も押されていない
	if ( m_nSlowKeyPassedTime < 0 ) {
		return;
	}

	if ( limit < m_nSlowKeyPassedTime ) {
		slow = limit;
	}
	else {
		slow = m_nSlowKeyPassedTime;
	}
	let state = GetPlayerMoveState();
	if ( ( count > limit && slow <= limit && state == MOVE_NORMAL )
		 || state == MOVE_SLOW ) {
		if ( state == MOVE_NORMAL ) {
			minAlpha = maxAlphaBase;
			maxAlpha = 0;
		}
		else {
			minAlpha = 0;
			maxAlpha = maxAlphaBase;
			limit /= 2;
		}
		if ( slow >= limit ) {
			alpha = maxAlpha;
		}
		else if ( slow <= 0 ) {
			alpha = minAlpha;
		}
		else {
			alpha = minAlpha + ( maxAlpha - minAlpha ) * slow / limit;
		}
		SetAlpha( alpha );
		SetGraphicAngle( 0, 0, count * 2 );
		//SetGraphicRect( 1, 1, 64, 64 );
		SetGraphicRect( 0, 0, 63, 63 );
		SetColor( 255, 255, 255 );
		SetTexture( file );
		DrawGraphic( GetPlayerX(), GetPlayerY() );
		SetAlpha( 255 );
		SetGraphicAngle( 0, 0, 0 );
	}
}

//	プレイヤードットオブジェクト生成
function makePlayerDot( let file ) {
	let wid = 15;
	let obj = Obj_Create( OBJ_EFFECT );
	Obj_SetAutoDelete( obj, false );
	ObjEffect_SetTexture( obj, file );
	ObjEffect_SetPrimitiveType( obj, PRIMITIVE_TRIANGLESTRIP );
	ObjEffect_CreateVertex( obj, 4 );
	ascent ( let i in 0..4 ) {
		let x = truncate( i / 2 );
		let y = i % 2;
		ObjEffect_SetVertexColor( obj, i, 0, 255, 255, 255 );
		ObjEffect_SetVertexXY( obj, i,
							   wid / 2 * [ -1, 1 ][ x ],
							   wid / 2 * [ -1, 1 ][ y ] );
		ObjEffect_SetVertexUV( obj, i,
							   [ 0, wid ][ x ], [ 0, wid ][ y ] );
	}
	
	ObjEffect_SetRenderState( obj, ALPHA );
	ObjEffect_SetLayer( obj, 3 );
	return obj;
}

//	プレイヤードット描写
function drawPlayerDot( let obj, let count ) {
	if ( m_bIsContinueDotTask == true ) {
		let limit = 30;
		let slow = 0;
		let maxAlpha = 255;
		let minAlpha = 0;
		let alpha = 0;

		//低速が一回も押されていない
		if ( m_nSlowKeyPassedTime < 0 ) {
		}
		else {
			if ( limit < m_nSlowKeyPassedTime ) {
				slow = limit;
			}
			else {
				slow = m_nSlowKeyPassedTime;
			}
			let state = GetPlayerMoveState();
			if ( ( ( m_nCount > limit && slow <= limit && m_bIsSlowMove == false )
				   || m_bIsSlowMove == true )
				 && OnMissed() == false ) {
				if ( m_bIsSlowMove == false ) {
					minAlpha = 255;
					maxAlpha = 0;
				}
				else {
					minAlpha = 0;
					maxAlpha = 255;
					limit /= 2;
				}
				if ( slow >= limit ) {
					alpha = maxAlpha;
				}
				else if ( slow <= 0 ) {
					alpha = minAlpha;
				}
				else {
					alpha = minAlpha + ( maxAlpha - minAlpha ) * slow / limit;
				}
			}
			else {
				alpha = 0;
			}
			ObjEffect_SetAngle( obj, 0, 0, count * 2 );
			Obj_SetPosition( obj, GetPlayerX(), GetPlayerY() );
			ascent ( let i in 0..4 ) {
				ObjEffect_SetVertexColor( obj, i, alpha, 255, 255, 255 );
			}
		}
	}
}


//////////////////////////////////////////////////////////////////////
//	共通部品インクルード部
//////////////////////////////////////////////////////////////////////

#include_function ".\common\utils.dnh"
#include_function ".\common\function_value.dnh"
#include_function ".\setting\parameter.dnh"

