/*============================================================================
	アクションゲームメインルーチン Game.c
------------------------------------------------------------------------------
												Programmed by Keiichi.Tago.
 ============================================================================*/
#include "Game.h"

/* -------------------- Pad 情報から方向を求める */
int Key2Dir[] = { -1, 0, 2, 1, 4, -1, 3, 2, 6, 7, -1, 0, 5, 6, 4, -1 };

/* -------------------- Sin テーブル */
int SinTable[] = {
/*  0*/	   0,  4,  9, 14, 19, 24, 29, 33, 38, 42, 47, 51, 55, 59, 63, 67,
		  70, 74, 77, 80, 83, 85, 88, 90, 92, 94, 95, 97, 98, 98, 99, 99,
/* 32*/	 100, 99, 99, 98, 98, 97, 95, 94, 92, 90, 88, 85, 83, 80, 77, 74,
		  70, 67, 63, 59, 55, 51, 47, 42, 38, 33, 29, 24, 19, 14,  9,  4,
/* 64*/	   0, -4, -9,-14,-19,-24,-29,-33,-38,-42,-47,-51,-55,-59,-63,-67,
		 -70,-74,-77,-80,-83,-85,-88,-90,-92,-94,-95,-97,-98,-98,-99,-99,
/* 96*/	-100,-99,-99,-98,-98,-97,-95,-94,-92,-90,-88,-85,-83,-80,-77,-74,
		 -70,-67,-63,-59,-55,-51,-47,-42,-38,-33,-29,-24,-19,-14, -9, -4,
/*128*/    0,  4,  9, 14, 19, 24, 29, 33, 38, 42, 47, 51, 55, 59, 63, 67,
		  70, 74, 77, 80, 83, 85, 88, 90, 92, 94, 95, 97, 98, 98, 99, 99,
/*160*/	 100, 99, 99, 98, 98, 97, 95, 94, 92, 90, 88, 85, 83, 80, 77, 74,
		  70, 67, 63, 59, 55, 51, 47, 42, 38, 33, 29, 24, 19, 14,  9,  4,
/*192*/	   0, -4, -9,-14,-19,-24,-29,-33,-38,-42,-47,-51,-55,-59,-63,-67,
		 -70,-74,-77,-80,-83,-85,-88,-90,-92,-94,-95,-97,-98,-98,-99,-99,
/*224*/	-100,-99,-99,-98,-98,-97,-95,-94,-92,-90,-88,-85,-83,-80,-77,-74,
		 -70,-67,-63,-59,-55,-51,-47,-42,-38,-33,-29,-24,-19,-14, -9, -4
};

/* -------------------- 敵の縦の大きさ*/
int nEnemyYSize[] = {
	0,		/* 0 定義なし */
	2,		/* 1 スライム */
	2,		/* 2 ジャンプスライム */
	4,		/* 3 スケルトン */
	4,		/* 4 スケルトン(楯無し) */
	4,		/* 5 ウェアウルフ */
	2,		/* 6 コウモリ */
	4,		/* 3 ナイト */
	4,		/* 3 ハイパワーナイト */
};

/* -------------------- スタティック変数 */
PLAYERINFO PlayerInfo;
BOOL bEndFlag;
BOOL bGameEndFlag;
BOOL bButtonA;
BOOL bButtonB;
BOOL bAutoMove;
BOOL bIventInitFlag;
int nBottomLine;		/* 一番下 */
/* -------------------- イベント用スタティック変数 */
int nIventMsg;
int nIventCount;
char far *lpIvObjectAddress;	/* イベントオブジェクトのアドレス */
int nObjectNumber;				/* 現在選択中のオブジェクト番号 */
int nSc1Color;					/* SCREEN 1 の現在選択中のパレット番号 */
int nSc2Color;					/* SCREEN 2 の現在選択中のパレット番号 */
int nIvent;						/* 現在選択中のイベント番号 */
int nLeftIvent;					/* 左に消えたときのイベント */
int nRightIvent;				/* 右に消えたときのイベント */
int nMsgType;					/* メッセージの種類 */
int nMsgCount;					/* ゲーム中のメッセージ表示カウンタ */
int nStage;						/* 現在の STAGE */
int nStartFlag;					/* 0=リスタート、コンティニュー, 1=スタート */
int nCenter;					/* まん中 */
int nAtari1;					/* 下から上に抜ける */
int nAtari2;					/* 壁 */
int nLeft;						/* 左端 */
int nRight;						/* 右端 */
int nTop;						/* 上端 */
int nBottom;					/* 下端 */
/* -------------------- 雨 */
int nRainFlag;					/* 0=晴, 1=雨 */
int nRainDrawFlag;
int nRainY[24];
int nRainSpeed[24];
int nRainNextSpeed;
/* -------------------- アイテム */
int nItemType;
int nItemX;
int nItemY;
int nItemVy;
int nItemJump;
int nItemCount;
/* -------------------- ファイヤーボール */
int nFireStat;
int nFireX;
int nFireY;
int nFireDir;
int nFireCount;
/* -------------------- 敵 */
ENEMYINFO EnemyInfo[ 4 ];
int nEnemySwitchTable[6];		/* こんな敵が出る */
int nEnemyMax[2];				/* 画面上の敵の最大数 */
int nEnemyType[2];				/* 0=画面にいない, 1=出現中の敵番号 */
int nEnemyActionFlag;			/* 0 と 1 を繰り返す */
int nEnemyAppearCount;			/* 次の敵の出るタイミング */
int nEnemyMuteFlag;				/* 0=敵が出現する, 1=敵は出現しない */

/*============================================================
	ゲームメインルーチン
--------------------------------------------------------------
In  : なし
Out : なし
============================================================*/
void Game( void )
{
	/* 背景初期化 */
	wsBgInit( COLOR_MODE );
	/* スプライト初期化 */
	wsSpInit( COLOR_MODE );
	/* パレット設定 ( 16 色中 8 色を選択する) */
	wsPalInit( COLOR_MODE );

	/* スプライト初期化 */
	wsSpSetObjectFile( 0, "/rom0/GENERIC.CHR" );
	wsSpSetPalet( 0, 0, 7 );	/* 文字 */
	wsSpSetObjectFile( 1, "/rom0/PLAYER1.CHR" );
	wsSpSetPalet( 1, 0, 4 );	/* プレイヤーキャラ */
	wsSpSetObjectFile( 2, "/rom0/ENEMY1.CHR" );

	/* 変数初期化 */
	nBottomLine = 17600;

	/* イベント初期化 */
	SetIventFile( "/rom0/IVENT.IVT" );

	/* プレイヤー初期設定 */
	PlayerInfo.nLeft = 3;
	PlayerInfo.nLifeMax = 5;

	/* ゲーム変数初期化 */
	nStage = 1;
	nIvent = 0;
	nStartFlag = 1;
	nItemCount = 0;

	/* とりあえず設定 */
	nCenter = 108 * 100;

	/* ==================== ゲームループ */
	while( 1 ) {
		int i;
		/* 変数初期化 */
		bEndFlag = FALSE;
		bGameEndFlag = FALSE;
		bButtonA = FALSE;
		bButtonB = FALSE;
		bAutoMove = FALSE;
		bIventInitFlag = FALSE;
		nMsgCount = 0;
		memset( &EnemyInfo, 0, sizeof( EnemyInfo ) );
		nEnemyAppearCount = 0;
		nItemType = 0;
		nFireStat = 0;
		nEnemyMuteFlag = 0;
		/* プレイヤー初期設定 */
		PlayerInfo.nType = 0;
		PlayerInfo.nJumpMax = 320;
		PlayerInfo.nJumpMax2 = 5;
		PlayerInfo.nJumpCount = 0;
		PlayerInfo.nLife = PlayerInfo.nLifeMax;
		PlayerInfo.nZombieCount = 0;
		/* Life 表示 */
		wsSpSetChr( 0, 0, 384, 5 );
		wsSpSetObject( 0, 0, 0, 384, 0, 8, 0 );
		/* Left 表示 */
		wsSpSetChr( 0, 5, 389, 2 );
		wsSpSetLetter( 391, 'ｘ', 15, 7 );
		wsSpSetObject( 0, 1, 10, 389, 0, 88, 0 );
		wsSpPutChar( 12, 391, 104, 0, 7 );
		wsSpPutChar( 13, 392, 112, 0, 7 );
		DrawStatus();
		/* Ivent 設定 */
		nIventMsg = 0;
		nMsgType = 0;
		nMsgCount = 0;
		if ( nStartFlag == 1 ) {
			if ( nStage == 1 ) {
				nIvent = 0;
				nMsgType = 1;
				nMsgCount = 200;
			} else if ( nStage == 2 ) {
				nIvent = 8;
				nMsgType = 2;
				nMsgCount = 200;
			}
		}
		nStartFlag = 0;
		SetIvent( nIvent );
		DrawMsg( nMsgType );
		/* 画面を明るくする */
		wsPalSetLuminosity( 15 );
		/* メインループ */
		while( bEndFlag == FALSE ) {
			nEnemyAppearCount--;
			if ( nEnemyAppearCount < 0 ) {
				AppearEnemy();
			}
			MoveObject();
			DrawObject();
			if ( nRainFlag == 1 ) {
				DrawRain();
			}
			if ( nMsgCount > 0 ) {
				nMsgCount--;
				if ( nMsgCount <= 0 ) {
					nMsgType = 0;
					DrawMsg( 0 );
				}
			}
			wsPalMove();
			sys_wait( 1 );
			if ( nIventMsg != 0 ) {
				switch( nIventMsg ) {
					case IV_MSG_RIGHT:
						if ( nRightIvent != -1 ) {
							if ( bIventInitFlag == TRUE ) {
								wsPalSetLuminosity( 0 );
								nIventCount = 50;
								bIventInitFlag = FALSE;
							}
							nIventCount--;
							if ( nIventCount < 0 ) {
								ExecIventMsg( nIventMsg );
								wsPalSetLuminosity( 15 );
							}
						} else {
							nIventMsg = 0;
						}
						break;
					case IV_MSG_LEFT:
						if ( nLeftIvent != -1 ) {
							if ( bIventInitFlag == TRUE ) {
								wsPalSetLuminosity( 0 );
								nIventCount = 50;
								bIventInitFlag = FALSE;
							}
							nIventCount--;
							if ( nIventCount < 0 ) {
								ExecIventMsg( nIventMsg );
								wsPalSetLuminosity( 15 );
							}
						} else {
							nIventMsg = 0;
						}
						break;
					case IV_MSG_WALK_RIGHT:
						PlayerInfo.nVx = 100;
						PlayerInfo.nDir = 1;
						PlayerInfo.nAttack = 0;
						PlayerInfo.nMove = 1;
						nIventCount--;
						if ( nIventCount < 0 ) {
							nIventMsg = 0;
						}
						break;
					case IV_MSG_WALK_LEFT:
						PlayerInfo.nVx = -100;
						PlayerInfo.nDir = 0;
						PlayerInfo.nAttack = 0;
						PlayerInfo.nMove = 1;
						nIventCount--;
						if ( nIventCount < 0 ) {
							nIventMsg = 0;
						}
						break;
					case IV_MSG_DAMAGE:
					case IV_MSG_DIE:
						PlayerInfo.nAttack = 0;
						nIventCount--;
						if ( nIventCount < 0 ) {
							if ( nIventMsg == IV_MSG_DIE ) {
								/* 死んだ */
								wsSndPlaySe( 5 );
								bEndFlag = TRUE;
							}
							PlayerInfo.nDir = PlayerInfo.nDirBackup;
							nIventMsg = 0;
						}
						break;
					case IV_MSG_STAGECLEAR:
						ExecIventMsg( nIventMsg );
						break;
				}
			}
		}
		if ( bGameEndFlag == TRUE ) {
			break;
		}
		PlayerInfo.nLeft--;
		if ( PlayerInfo.nLeft < 0 ) {
			int nGameover;
			nGameover = Gameover();
			if ( nGameover == 1 ) {
				break;
			}
			/* プレイヤー初期設定 */
			PlayerInfo.nLeft = 3;
			nStartFlag = 1;
		}
		wsPalSetLuminosity( 0 );
		for( i=0; i<40; i++ ) {
			wsPalMove();
			sys_wait( 1 );
		}
	}
	wsBgInit( COLOR_MODE );
	wsSpInit( COLOR_MODE );
	SystemInf.nPhase = PHASE_TITLE;
}

/*============================================================
	ファイヤーボール
--------------------------------------------------------------
In  : nX = 横座標
    : nY = 縦座標
    : nDir = 方向 (0=左, 1=右)
Out : なし
============================================================*/
void SetFire( int nX, int nY, int nDir )
{
	if ( nMsgCount <= 0 ) {
		nFireStat = 1;
		nFireX = nX;
		nFireY = nY;
		nFireDir = nDir;
		wsSpSetObject( 0, 5 + nDir, 14, 397, 0, nFireX / 100, nFireY / 100 );
	}
}

/*============================================================
	アイテムを置く
--------------------------------------------------------------
In  : nType = アイテムの種類
    : nX = 横座標
    : nY = 縦座標
Out : なし
============================================================*/
void SetItem( int nType, int nX, int nY )
{
	if ( nMsgCount <= 0 ) {
		nItemType = nType;
		nItemX = nX;
		nItemY = nY;
		nItemVy = 0;
		nItemJump = 1;
		wsSpSetObject( 0, 1 + nItemType, 36, 419, 0, nItemX / 100, nItemY / 100 );
	}
}

/*============================================================
	敵を配置する
--------------------------------------------------------------
In  : なし
Out : なし
============================================================*/
void AppearEnemy( void )
{
	int nX, nY;
	int i, j;
	if ( nEnemyMuteFlag == 0 ) {
		if ( nEnemyType[ 0 ] > 100 ) {
			if ( EnemyInfo[ 0 ].nType == 0 ) {
				if ( nEnemyType[ 0 ] == 101 ) {
					/* STAGE 1 ボス出現 */
					SetEnemy( 101, 22300, 6400, 0 );
				} else if ( nEnemyType[ 0 ] == 102 ) {
					/* STAGE 2 ボス出現 */
					SetEnemy( 102, 15000, -6400, 0 );
				}
			}
		} else {
			int nSelectEnemy;
			int nEnemyLoopStart;
			int nEnemyLoopEnd;
			if ( nEnemyType[ 0 ] == 8 ) {
				/* ハイパワーナイトは 1 体しか出ない */
				nEnemyMuteFlag = 1;
			}
			/* ザコ出現 */
			nEnemyAppearCount = rand() % 150;
			nX = ( rand() & 1 ) * 25600 - 3200;
			nSelectEnemy = rand() & 1;
			if ( PlayerInfo.nX < 6400 ) {
				nX = 22300;
			} else if ( PlayerInfo.nX > 16000 ) {
				nX = -3100;
			}
			if ( nEnemyType[ 0 ] != 0 ) {
				if ( ( nEnemyType[ 1 ] == 0 ) || ( nSelectEnemy == 0 ) ) {
					nEnemyLoopStart = 0;
					nEnemyLoopEnd = nEnemyMax[ 0 ];
				} else {
					nEnemyLoopStart = 2;
					nEnemyLoopEnd = nEnemyLoopStart + nEnemyMax[ 1 ];
				}
				for( i=nEnemyLoopStart; i<nEnemyLoopEnd; i++ ) {
					if ( EnemyInfo[ i ].nType == 0 ) {
						int nAtariX;
						int nAtariY;
						if ( nEnemyType[ i >> 1 ] == 6 ) {
							/* コウモリは空にいるため例外 */
							nY = 1600;
							for( j=0; j<4; j++ ) {
								if ( ( EnemyInfo[ i ].nType == 6 ) && ( j != i ) ) {
									int nTemp;
									nTemp = EnemyInfo[ j ].nX - nX;
									if ( nTemp < 0 ) nTemp = -nTemp;
									if ( nTemp < 3200 ) nY = -1;
								}
							}
						} else {
							nAtariX = ( wsBgGetScrollPositionX() + nX / 100 ) / 8;
							nAtariY = wsBgGetScrollPositionY() / 8;
							nY = -1;
							for( j=0; j<18; j++ ) {
								if ( ( wsBgGetChrNumber( nAtariX, nAtariY + nEnemyYSize[ nEnemyType[ i >> 1 ] ] + j - 1 ) & 0x1FF ) >= nAtari1 ) {
									nY = ( j - 1 ) * 800;
									break;
								}
							}
						}
						if ( nY != -1 ) {
							SetEnemy( nEnemyType[ i >> 1 ], nX, nY, i );
						}
						break;
					}
				}
			}
		}
	}
}

/*============================================================
	敵を置く
--------------------------------------------------------------
In  : nType = 敵の種類
    : nX = 横座標
    : nY = 縦座標
    : nIndex = 索引番号 (0〜3)
Out : なし
============================================================*/
void SetEnemy( int nType, int nX, int nY, int nIndex )
{
	int i;
	if ( nType == 0 ) {
		EnemyInfo[ nIndex ].nType = 0;
		for( i=0; i<18; i++ ) {
			sprite_set_location( ENEMY_SPNUMBER + nIndex * 18 + i, 224, 144 );
		}
	} else {
		memset( &EnemyInfo[ nIndex ], 0, sizeof( ENEMYINFO ) );
		EnemyInfo[ nIndex ].nType = nType;
		EnemyInfo[ nIndex ].nX = nX;
		EnemyInfo[ nIndex ].nY = nY;
		EnemyInfo[ nIndex ].nYSize = nEnemyYSize[ nType ];
		EnemyInfo[ nIndex ].nActionFlag = 1;
		switch( nType ) {
			case 1:
				/* スライム */
				EnemyInfo[ nIndex ].nLife = 2;
				EnemyInfo[ nIndex ].nXSize = 3;
				EnemyInfo[ nIndex ].nAtariX1 = 0;
				EnemyInfo[ nIndex ].nAtariY1 = 0;
				EnemyInfo[ nIndex ].nAtariX2 = 2300;
				EnemyInfo[ nIndex ].nAtariY2 = 1500;
				MoveSlime( nIndex );
				break;
			case 2:
				/* ジャンプスライム */
				EnemyInfo[ nIndex ].nLife = 2;
				EnemyInfo[ nIndex ].nXSize = 3;
				EnemyInfo[ nIndex ].nAtariX1 = 0;
				EnemyInfo[ nIndex ].nAtariY1 = 0;
				EnemyInfo[ nIndex ].nAtariX2 = 2300;
				EnemyInfo[ nIndex ].nAtariY2 = 1500;
				MoveJumpSlime( nIndex );
				break;
			case 3:
				/* スケルトン */
				EnemyInfo[ nIndex ].nLife = 3;
				EnemyInfo[ nIndex ].nXSize = 3;
				EnemyInfo[ nIndex ].nAtariX1 = 0;
				EnemyInfo[ nIndex ].nAtariY1 = 0;
				EnemyInfo[ nIndex ].nAtariX2 = 2300;
				EnemyInfo[ nIndex ].nAtariY2 = 3100;
				EnemyInfo[ nIndex ].nRand = rand() & 1023;
				Skeleton( nIndex );
				break;
			case 4:
				/* スケルトン(楯無し) */
				EnemyInfo[ nIndex ].nLife = 3;
				EnemyInfo[ nIndex ].nXSize = 3;
				EnemyInfo[ nIndex ].nAtariX1 = 0;
				EnemyInfo[ nIndex ].nAtariY1 = 0;
				EnemyInfo[ nIndex ].nAtariX2 = 2300;
				EnemyInfo[ nIndex ].nAtariY2 = 3100;
				EnemyInfo[ nIndex ].nRand = rand() & 1023;
				Skeleton2( nIndex );
				break;
			case 5:
				/* ウェアウルフ */
				EnemyInfo[ nIndex ].nLife = 2;
				EnemyInfo[ nIndex ].nXSize = 3;
				EnemyInfo[ nIndex ].nAtariX1 = 0;
				EnemyInfo[ nIndex ].nAtariY1 = 0;
				EnemyInfo[ nIndex ].nAtariX2 = 2300;
				EnemyInfo[ nIndex ].nAtariY2 = 3100;
				if ( EnemyInfo[ nIndex ].nX > PlayerInfo.nX ) {
					EnemyInfo[ nIndex ].nDir = 0;
				} else {
					EnemyInfo[ nIndex ].nDir = 1;
				}
				Wolf( nIndex );
				break;
			case 6:
				/* コウモリ */
				EnemyInfo[ nIndex ].nLife = 1;
				EnemyInfo[ nIndex ].nXSize = 3;
				EnemyInfo[ nIndex ].nAtariX1 = 0;
				EnemyInfo[ nIndex ].nAtariY1 = 0;
				EnemyInfo[ nIndex ].nAtariX2 = 2300;
				EnemyInfo[ nIndex ].nAtariY2 = 1500;
				Bat( nIndex );
				break;
			case 7:
				/* ナイト */
				EnemyInfo[ nIndex ].nLife = 4;
				EnemyInfo[ nIndex ].nXSize = 3;
				EnemyInfo[ nIndex ].nAtariX1 = 0;
				EnemyInfo[ nIndex ].nAtariY1 = 0;
				EnemyInfo[ nIndex ].nAtariX2 = 2300;
				EnemyInfo[ nIndex ].nAtariY2 = 3100;
				EnemyInfo[ nIndex ].nRand = rand() & 1023;
				Knight( nIndex );
				break;
			case 8:
				/* ハイパワーナイト */
				EnemyInfo[ nIndex ].nLife = 15;
				EnemyInfo[ nIndex ].nXSize = 3;
				EnemyInfo[ nIndex ].nAtariX1 = 0;
				EnemyInfo[ nIndex ].nAtariY1 = 0;
				EnemyInfo[ nIndex ].nAtariX2 = 2300;
				EnemyInfo[ nIndex ].nAtariY2 = 3100;
				EnemyInfo[ nIndex ].nRand = rand() & 1023;
				Knight( nIndex );
				break;
			case 101:
				/* STAGE 1 ドラゴン */
				EnemyInfo[ nIndex ].nLife = 20;
				EnemyInfo[ nIndex ].nXSize = 8;
				EnemyInfo[ nIndex ].nAtariX1 = 0;
				EnemyInfo[ nIndex ].nAtariY1 = 0;
				EnemyInfo[ nIndex ].nAtariX2 = 6300;
				EnemyInfo[ nIndex ].nAtariY2 = 6300;
				EnemyInfo[ nIndex ].nRand = rand() & 1023;
				for ( i=1; i<4; i++ ) {
					EnemyInfo[ i ].nType = 101;
				}
				EnemyInfo[ nIndex ].nActionCount = 16;
				Dragon1( nIndex );
				break;
			case 102:
				/* STAGE 2 ドラゴン */
				EnemyInfo[ nIndex ].nLife = 30;
				EnemyInfo[ nIndex ].nXSize = 8;
				EnemyInfo[ nIndex ].nAtariX1 = 0;
				EnemyInfo[ nIndex ].nAtariY1 = 0;
				EnemyInfo[ nIndex ].nAtariX2 = 6300;
				EnemyInfo[ nIndex ].nAtariY2 = 6300;
				EnemyInfo[ nIndex ].nRand = rand() & 1023;
				for ( i=1; i<4; i++ ) {
					EnemyInfo[ i ].nType = 102;
				}
				EnemyInfo[ nIndex ].nActionCount = 16;
				Dragon2( nIndex );
				break;
		}
	}
}

/*============================================================
	敵がダメージを受けた
--------------------------------------------------------------
In  : nIndex = 索引番号 (0〜3)
Out : なし
============================================================*/
void DamageEnemy( int nIndex )
{
	if ( EnemyInfo[ nIndex ].nStat < 100 ) {
		EnemyInfo[ nIndex ].nLife--;
		EnemyInfo[ nIndex ].nVy -= 150;
		EnemyInfo[ nIndex ].nJump = 1;
		EnemyInfo[ nIndex ].nDamageDir = 1 - PlayerInfo.nDir;
		EnemyInfo[ nIndex ].nStat = 100;		/* 敵がふっ飛ぶ */
		EnemyInfo[ nIndex ].nActionCount = 20;
		EnemyInfo[ nIndex ].nAnimeCount = 0;
		if ( EnemyInfo[ nIndex ].nLife <= 0 ) {
			EnemyInfo[ nIndex ].nStat = 101;	/* 敵が死んだ */
		}
	}
	/* ダメージを食らった */
	wsSndPlaySe( 3 );
}

/*============================================================
	メッセージ表示
--------------------------------------------------------------
In  : nMsgType = メッセージの種類 (0=メッセージを消す)
Out : なし
============================================================*/
void DrawMsg( int nMsgType )
{
	int i;
	for( i=0; i<24; i++ ) {
		sprite_set_location( 14 + i, 224, 144 );
	}
	switch( nMsgType ) {
		case 1:
			wsSpPutString( 14, 398, 80, 56, 7, 15, 7, "ＳＴＡＧＥ　１" );
			wsSpPutString( 21, 405, 68, 72, 7, 15, 7, "Ｔｈｅ　Ｆｏｒｅｓｔ" );
			break;
		case 2:
			wsSpPutString( 14, 398, 80, 60, 7, 15, 7, "ＳＴＡＧＥ　２" );
			wsSpPutString( 21, 405, 68, 72, 7, 15, 7, "Ｔｈｅ　Ｃａｓｔｌｅ" );
			break;
	}
}

/*============================================================
	ゲームオーバー
--------------------------------------------------------------
In  : なし
Out : 0 = コンティニュー, 1 = タイトルに戻る
============================================================*/
int Gameover( void )
{
	int nRetCode;
	int nKey;
	BOOL bUp = FALSE;
	BOOL bDown = FALSE;
	BOOL bA = FALSE;
	int nMenu = 0;
	int i;
	DrawMsg( 0 );
	wsPalSetLuminosity( 5 );
	for( i=0; i<75; i++ ) {
		wsPalMove();
		sys_wait( 1 );
	}
	wsSpSetPalet( 0, 0, 7 );	/* 文字 */
	wsPalSetLuminosityDirectOne( 15, 15 );
	/* GAME OVER 表示 */
	wsSpPutString( 14, 398, 76, 60, 7, 15, 7, "ＧＡＭＥ" );
	wsSpPutString( 18, 402, 116, 60, 7, 15, 7, "ＯＶＥＲ" );
	wsSpPutString( 22, 406, 84, 76, 7, 15, 7, "ＣＯＮＴＩＮＵＥ" );
	wsSpPutString( 30, 414, 84, 92, 7, 15, 7, "ＴＩＴＬＥ" );
	wsSpSetLetter( 419, '★', 15, 7 );
	while( 1 ) {
		/* キー判定 */
		nKey = key_press_check();
		/* 上を押したときの判定 */
		if ( nKey & KEY_UP1 ) {
			bUp = TRUE;
		} else if ( bUp == TRUE ) {
			nMenu--;
			if ( nMenu < 0 ) {
				nMenu = GAMEOVER_MENU_MAX - 1;
			}
			bUp = FALSE;
			wsSndPlaySe( 0 );
		}
		/* 下を押したときの判定 */
		if ( nKey & KEY_DOWN1 ) {
			bDown = TRUE;
		} else if ( bDown == TRUE ) {
			nMenu++;
			if ( nMenu >= GAMEOVER_MENU_MAX ) {
				nMenu = 0;
			}
			bDown = FALSE;
			wsSndPlaySe( 0 );
		}
		/* A ボタンを押したときの判定 */
		if ( nKey & KEY_A ) {
			bA = TRUE;
		} else if ( bA == TRUE ) {
			wsSndPlaySe( 6 );
			break;
		}
		wsSpPutChar( 35, 419, 76, 76 + nMenu * 16, 7 );
		sys_wait( 1 );
	}
	DrawMsg( 0 );
	nRetCode = nMenu;
	return( nRetCode );
}

/*============================================================
	一時停止
--------------------------------------------------------------
In  : なし
Out : 0 = ゲームに戻る, 1 = タイトルに戻る
============================================================*/
int Pause( void )
{
	int nRetCode;
	int nKey;
	BOOL bUp = FALSE;
	BOOL bDown = FALSE;
	BOOL bA = FALSE;
	int nMenu = 0;
	int i;
	DrawMsg( 0 );
	wsPalSetLuminosity( 5 );
	for( i=0; i<75; i++ ) {
		wsPalMove();
		sys_wait( 1 );
	}
	wsSpSetPalet( 0, 0, 7 );	/* 文字 */
	wsPalSetLuminosityDirectOne( 15, 15 );
	/* PAUSE 表示 */
	wsSpPutString( 14, 398, 92, 60, 7, 15, 7, "ＰＡＵＳＥ" );
	wsSpPutString( 19, 403, 76, 76, 7, 15, 7, "ＲＥＴＵＲＮ　ＧＡＭＥ" );
	wsSpPutString( 30, 414, 76, 92, 7, 15, 7, "ＴＩＴＬＥ" );
	wsSpSetLetter( 419, '★', 15, 7 );
	while( 1 ) {
		/* キー判定 */
		nKey = key_press_check();
		/* 上を押したときの判定 */
		if ( nKey & KEY_UP1 ) {
			bUp = TRUE;
		} else if ( bUp == TRUE ) {
			nMenu--;
			if ( nMenu < 0 ) {
				nMenu = PAUSE_MENU_MAX - 1;
			}
			bUp = FALSE;
			wsSndPlaySe( 0 );
		}
		/* 下を押したときの判定 */
		if ( nKey & KEY_DOWN1 ) {
			bDown = TRUE;
		} else if ( bDown == TRUE ) {
			nMenu++;
			if ( nMenu >= PAUSE_MENU_MAX ) {
				nMenu = 0;
			}
			bDown = FALSE;
			wsSndPlaySe( 0 );
		}
		/* A ボタンを押したときの判定 */
		if ( ( nKey & KEY_START ) || ( nKey & KEY_A ) ) {
			bA = TRUE;
		} else if ( bA == TRUE ) {
			wsSndPlaySe( 6 );
			break;
		}
		wsSpPutChar( 35, 419, 68, 76 + nMenu * 16, 7 );
		sys_wait( 1 );
	}
	DrawMsg( 0 );
	if ( nRainFlag == 1 ) {
		InitRain();
	}
	if ( nFireStat != 0 ) {
		int nTemp;
		nTemp = 5 + ( nFireStat - 1 ) * 2 + nFireDir;
		wsSpSetObject( 0, nTemp, 14, 397, 0, nFireX / 100, nFireY / 100 );
	}
	wsPalSetLuminosity( 15 );
	nRetCode = nMenu;
	return( nRetCode );
}

/*============================================================
	ステージクリア
--------------------------------------------------------------
In  : なし
Out : なし
============================================================*/
void StageClear( void )
{
	int nKey;
	BOOL bA = FALSE;
	int i;
	DrawMsg( 0 );
	wsPalSetLuminosity( 7 );
	for( i=0; i<75; i++ ) {
		wsPalMove();
		sys_wait( 1 );
	}
	wsSpSetPalet( 0, 0, 7 );	/* 文字 */
	wsPalSetLuminosityDirectOne( 15, 15 );
	/* STAGE CLEAR 表示 */
	wsSpPutString( 14, 398, 64, 60, 7, 15, 7, "ＳＴＡＧＥ　ＣＬＥＡＲ！" );
	for( i=0; i<120; i++ ) {
		/* キー判定 */
		nKey = key_press_check();
		/* A ボタンを押したときの判定 */
		if ( nKey & KEY_A ) {
			bA = TRUE;
		} else if ( bA == TRUE ) {
			break;
		}
		sys_wait( 1 );
	}
	DrawMsg( 0 );
	wsPalSetLuminosity( 15 );
}

/*============================================================
	ゲームクリア
--------------------------------------------------------------
In  : なし
Out : なし
============================================================*/
void GameClear( void )
{
	int nKey;
	BOOL bA = FALSE;
	int i;
	DrawMsg( 0 );
	wsPalSetLuminosity( 7 );
	for( i=0; i<75; i++ ) {
		wsPalMove();
		sys_wait( 1 );
	}
	wsSpSetPalet( 0, 0, 7 );	/* 文字 */
	wsPalSetLuminosityDirectOne( 15, 15 );
	/* GAME CLEAR 表示 */
	for( i=0; i<1200; i++ ) {
		if ( i == 0 ) {
			wsSpPutString( 14, 398, 52, 60, 7, 15, 7, "ＣＯＮＧＲＡＴＵＬＡＴＩＯＮ！" );
			wsSpPutString( 29, 413, 96, 76, 7, 15, 7, "　　　　" );
		} else if ( i == 200 ) {
			wsSpPutString( 14, 398, 92, 60, 7, 15, 7, "ＳＴＡＦＦ　　　　　　　　　　" );
		} else if ( i == 400 ) {
			wsSpPutString( 14, 398, 84, 60, 7, 15, 7, "ＰＲＯＧＲＡＭ　　　　　　　　" );
			wsSpPutString( 29, 413, 96, 76, 7, 15, 7, "多胡圭一" );
		} else if ( i == 600 ) {
			wsSpPutString( 14, 398, 84, 60, 7, 15, 7, "ＧＲＡＰＨＩＣ　　　　　　　　" );
			wsSpPutString( 29, 413, 96, 76, 7, 15, 7, "宅波和志" );
		} else if ( i == 800 ) {
			wsSpPutString( 14, 398, 52, 60, 7, 15, 7, "ＳＰＥＣＩＡＬ　ＴＨＡＮＫＳ！" );
			wsSpPutString( 29, 413, 96, 76, 7, 15, 7, "堀井大介" );
		} else if ( i == 1000 ) {
			wsSpPutString( 14, 398, 80, 68, 7, 15, 7, "ａｎｄ　Ｙｏｕ！　　　　　　　" );
			wsSpPutString( 29, 413, 96, 76, 7, 15, 7, "　　　　" );
		}
		/* キー判定 */
		nKey = key_press_check();
		/* A ボタンを押したときの判定 */
		if ( ( ( nKey & KEY_START ) || ( nKey & KEY_A ) ) && ( i > 200 ) ) {
			bA = TRUE;
		} else if ( bA == TRUE ) {
			break;
		}
		sys_wait( 1 );
	}
	wsPalSetLuminosity( 0 );
	for( i=0; i<75; i++ ) {
		wsPalMove();
		sys_wait( 1 );
	}
	DrawMsg( 0 );
	wsPalSetLuminosity( 15 );
}

/*============================================================
	ダメージを受けた
--------------------------------------------------------------
In  : ふっ飛ぶ方向 ( 0=左, 1=右 )
Out : なし
============================================================*/
void Damage( int nDir )
{
	if ( nIventMsg == 0 ) {
		if ( SystemInf.nInvincibility == 0 ) {
			PlayerInfo.nLife--;
		}
		PlayerInfo.nVy = -( PlayerInfo.nJumpMax >> 1 );
		PlayerInfo.nZombieCount = 120;
		PlayerInfo.nJump = 1;
		PlayerInfo.nDirBackup = PlayerInfo.nDir;
		PlayerInfo.nDamageDir = nDir;
		if ( PlayerInfo.nLife > 0 ) {
			nIventMsg = IV_MSG_DAMAGE;
			nIventCount = 20;
		} else {
			nIventMsg = IV_MSG_DIE;
			nIventCount = 20;
		}
		DrawStatus();
	}
	/* ダメージを食らった */
	wsSndPlaySe( 3 );
}

/*============================================================
	ステータス表示
--------------------------------------------------------------
In  : なし
Out : なし
============================================================*/
void DrawStatus( void )
{
	int i;
	/* Life 表示 */
	for ( i=0; i<PlayerInfo.nLifeMax; i++ ) {
		if ( i<PlayerInfo.nLife ) {
			wsSpPutChar( 2 + i, 386, 24 + i * 8, 0, 7 );
		} else {
			wsSpPutChar( 2 + i, 387, 24 + i * 8, 0, 7 );
		}
	}
	wsSpPutChar( 9, 388, 24 + PlayerInfo.nLifeMax * 8, 0, 7 );
	/* Left 再表示 */
	wsSpSetLetter( 392, '０' + PlayerInfo.nLeft, 15, 7 );
}

/*============================================================
	雨初期化
--------------------------------------------------------------
In  : なし
Out : なし
============================================================*/
void InitRain( void )
{
	int i;
	/* 雨初期化 */
	wsBgSetPalet( nObjectNumber, 0, 14 );	/* かなり卑怯な設定方法 BgPalet14 = SpPalet6 */
	nRainNextSpeed = 2;
	for( i=0; i<12; i++ ) {
		sprite_set_char( 14 + i, 13 | ( 6 << 9 ) | 0x2000 );
		sprite_set_location( 14 + i, 224, 144 );
		nRainY[ i ] = ( i % 6 ) * 18 + 144;
		nRainSpeed[ i ] = nRainNextSpeed << 1;
		nRainNextSpeed++;
		if ( nRainNextSpeed > 4 ) {
			nRainNextSpeed = 2;
		}
	}
}

/*============================================================
	雨表示
--------------------------------------------------------------
In  : なし
Out : なし
============================================================*/
void DrawRain( void )
{
	int nRainDrawStart;
	int nRainDrawEnd;
	int i;
	nRainDrawFlag++;
	nRainDrawFlag &= 1;
	nRainDrawStart = 6 * nRainDrawFlag;
	nRainDrawEnd = nRainDrawStart + 6;
	for ( i=nRainDrawStart; i<nRainDrawEnd; i++ ) {
		sprite_set_location( 14 + i, i * 20 - ( nRainY[ i ] >> 1 ), nRainY[ i ] );
		nRainY[ i ] += nRainSpeed[ i ];
		if ( nRainY[ i ] > 255 ) {
			nRainY[ i ] = - 8;
			nRainSpeed[ i ] = nRainNextSpeed << 1;
			nRainNextSpeed++;
			if ( nRainNextSpeed > 4 ) {
				nRainNextSpeed = 2;
			}
		}
	}
}

/*============================================================
	キャラクタの行動
--------------------------------------------------------------
In  : なし
Out : なし
============================================================*/
void MoveObject( void )
{
	int nKey;
	int nScrollX;
	int nScrollY;
	int nChrX;
	int nChrY;
	int nAtariX;
	int nAtariY;
	int nAtariLen;
	int nAtariTemp;
	WORD wMapChr;
	int i;
	/* ==================== プレイヤー移動 */
	nKey = key_press_check();
	/* START ボタンで終了する */
	if ( ( nKey & KEY_START ) && ( nIventMsg == 0 ) ) {
		if ( Pause() == 1 ) {
			bEndFlag = TRUE;
			bGameEndFlag = TRUE;
		}
	}
	if ( nIventMsg >= IV_MSG_DAMAGE ) {
		if ( PlayerInfo.nMove == 2 ) {
			PlayerInfo.nMove = 0;
		}
		if ( PlayerInfo.nDamageDir == 1 ) {
			nKey |= KEY_RIGHT1;
			nKey &= ~KEY_LEFT1;
		} else {
			nKey |= KEY_LEFT1;
			nKey &= ~KEY_RIGHT1;
		}
	}
	nScrollX = wsBgGetScrollPositionX();
	nScrollY = wsBgGetScrollPositionY();
	if ( ( nIventMsg == 0 ) || ( nIventMsg >= IV_MSG_DAMAGE ) ) {
		PlayerInfo.nVx = 0;
		/* 止まっている？ */
		if ( !( nKey & KEY_LEFT1 ) && !( nKey & KEY_RIGHT1 ) && ( PlayerInfo.nMove == 1 ) ) {
			PlayerInfo.nMove = 0;
			PlayerInfo.nAnimeCount = 0;
		}
		/* しゃがんでいる？ */
		if ( !( nKey & KEY_DOWN1 ) && ( PlayerInfo.nMove == 2 ) ) {
			if ( PlayerInfo.nAttack == 0 ) {
				PlayerInfo.nMove = 0;
			}
		}
		/* 左右方向に移動する */
		if ( PlayerInfo.nMove < 2 ) {
			if ( !( ( PlayerInfo.nAttack == 1 ) && ( PlayerInfo.nJump == 0 ) ) ) {
				if ( nKey & KEY_LEFT1 ) {
					PlayerInfo.nMove = 1;
					if ( ( nScrollX <= nLeft * 8 ) ||
						 ( PlayerInfo.nX > nCenter ) ) {
						/* スクロールストップ */
						if ( PlayerInfo.nX > 0 * 100 ) {
							PlayerInfo.nVx = -100;
						} else {
							if ( nIventMsg == 0 ) {
								/* 左端に到着 */
								PlayerInfo.nX = 0 * 100;
								PlayerInfo.nVx = -100;
								nIventMsg = IV_MSG_LEFT;
								bIventInitFlag = TRUE;
							}
						}
					} else {
						/* スクロールして左に進む */
						wsBgScroll( -1, 0 );
						/* 敵の移動 */
						for( i=0; i<4; i++ ) {
							EnemyInfo[ i ].nX += 100;
						}
						/* アイテムの移動 */
						if ( nItemType != 0 ) {
							nItemX += 100;
						}
						/* 炎の移動 */
						if ( nFireStat != 0 ) {
							nFireX += 100;
						}
					}
					PlayerInfo.nDir = 0;
				}
				if ( nKey & KEY_RIGHT1 ) {
					PlayerInfo.nMove = 1;
					if ( ( nScrollX > ( nRight - 27 ) * 8 ) ||
						 ( PlayerInfo.nX < nCenter ) ) {
						/* スクロールストップ */
						if ( PlayerInfo.nX < 200 * 100 ) {
							PlayerInfo.nVx = 100;
						} else {
							/* 右端に到着 */
							if ( nIventMsg == 0 ) {
								PlayerInfo.nX = 200 * 100;
								PlayerInfo.nVx = 100;
								nIventMsg = IV_MSG_RIGHT;
								bIventInitFlag = TRUE;
							}
						}
					} else {
						/* スクロールして左に進む */
						wsBgScroll( 1, 0 );
						/* 敵の移動 */
						for( i=0; i<4; i++ ) {
							EnemyInfo[ i ].nX -= 100;
						}
						/* アイテムの移動 */
						if ( nItemType != 0 ) {
							nItemX -= 100;
						}
						/* 炎の移動 */
						if ( nFireStat != 0 ) {
							nFireX -= 100;
						}
					}
					PlayerInfo.nDir = 1;
				}
			}
		}
		/* しゃがむ */
		if ( ( nKey & KEY_DOWN1 ) && ( PlayerInfo.nJump == 0 )  && ( PlayerInfo.nAttack == 0 ) ) {
			PlayerInfo.nMove = 2;
		}
		/* ジャンプ */
		if ( nKey & KEY_A ) {
			if ( ( PlayerInfo.nMove < 2 ) && ( bButtonA == FALSE ) && ( PlayerInfo.nJump == 0 ) ) {
				PlayerInfo.nVy -= PlayerInfo.nJumpMax;
				PlayerInfo.nJump = 1;
			}
			bButtonA = TRUE;
		} else {
			bButtonA = FALSE;
		}
		/* 攻撃 */
		if ( nKey & KEY_B ) {
			if ( ( PlayerInfo.nAttack == 0 ) && ( bButtonB == FALSE ) ) {
				PlayerInfo.nAttack = 1;
				PlayerInfo.nAnimeCount = 0;
			}
			bButtonB = TRUE;
		} else {
			bButtonB = FALSE;
		}
		/* ボタンを押し続けると高くジャンプする */
		if ( ( nKey & KEY_A ) && ( bButtonA == TRUE ) && ( PlayerInfo.nJump == 1 ) ) {
			PlayerInfo.nJumpCount2++;
			if ( PlayerInfo.nJumpCount2 > 2 ) {
				if ( PlayerInfo.nJumpCount < PlayerInfo.nJumpMax2 ) {
					PlayerInfo.nVy -= 30;
					PlayerInfo.nJumpCount++;
				}
				PlayerInfo.nJumpCount2 = 0;
			}
		}
	}
	/* キャラクタ移動 */
	PlayerInfo.nX += PlayerInfo.nVx;
	PlayerInfo.nY += PlayerInfo.nVy;
	if ( PlayerInfo.nX < -24 * 100 ) {
		PlayerInfo.nX = -24 * 100;
	}
	if ( PlayerInfo.nX > 223 * 100 ) {
		PlayerInfo.nX = 224 * 100;
	}
	/* ジャンプ中は自由落下 */
	if ( PlayerInfo.nJump == 1 ) {
		PlayerInfo.nVy += 20;
	}
	/* 下に落ちすぎないための処理(下に落ちた) */
/* 現在落ちる場面は存在しない
	if ( PlayerInfo.nY >= nBottomLine ) {
		PlayerInfo.nY = nBottomLine;
		PlayerInfo.nVx = 0;
		PlayerInfo.nVy = 0;
		PlayerInfo.nMove = 0;
		PlayerInfo.nJump = 0;
		PlayerInfo.nAttack = 0;
		PlayerInfo.nJumpCount = 0;
		PlayerInfo.nJumpCount2 = 0;
*/
		/* 1 機減る */
/*
	}
*/
	/* -------------------- 敵との当たり判定 */
	if ( PlayerInfo.nAttack == 1 ) {
		if ( ( PlayerInfo.nAnimeCount >= 8 ) && ( PlayerInfo.nAnimeCount < 13 ) ) {
			/* 攻撃の当たり判定 */
			Attack();
		}
	}
	/* -------------------- 背景との当たり判定 */
	/* 当たり判定用変数設定 */
	nChrX = nScrollX + PlayerInfo.nX / 100;
	nChrY = nScrollY + PlayerInfo.nY / 100;
	nAtariX = nChrX / 8;
	nAtariY = nChrY / 8;
	if ( PlayerInfo.nDir == 0 ) {
		if ( ( nChrX % 8 ) != 0 ) {
			nAtariX++;
		}
	}
	if ( PlayerInfo.nVy < 0 ) {
		if ( ( nChrY % 8 ) != 0 ) {
			nAtariY++;
		}
	}
	/* 左右の当たり判定 */
	nAtariLen = 2;
	if ( ( ( PlayerInfo.nY / 100 ) % 3 ) == 0 ) {
		nAtariLen = 1;
	}
	if ( PlayerInfo.nDir == 0 ) {
		/* 左側 */
		for( i=0; i<nAtariLen; i++ ) {
			wMapChr = wsBgGetChrNumber( nAtariX - 1, nAtariY + 3 - i ) & 0x1FF;
			if ( wMapChr >= nAtari1 ) {
				PlayerInfo.nVx = 0;
				PlayerInfo.nX = ( nAtariX * 8 - nScrollX ) * 100;
			}
		}
	} else {
		/* 右側 */
		for( i=0; i<nAtariLen; i++ ) {
			wMapChr = wsBgGetChrNumber( nAtariX + 3, nAtariY + 3 - i ) & 0x1FF;
			if ( wMapChr >= nAtari1 ) {
				PlayerInfo.nVx = 0;
				PlayerInfo.nX = ( nAtariX * 8 - nScrollX ) * 100;
			}
		}
	}
	/* 足元の当たり判定 */
	nAtariLen = 2;
	if ( ( ( PlayerInfo.nX / 100 ) % 8 ) == 0 ) {
		nAtariLen = 1;
	}
	nAtariTemp = 0;
	for( i=0; i<nAtariLen; i++ ) {
		if ( PlayerInfo.nDir == 0 ) {
			wMapChr = wsBgGetChrNumber( nAtariX + 1 - i, nAtariY + 4 ) & 0x1FF;
		} else {
			wMapChr = wsBgGetChrNumber( nAtariX + 1 + i, nAtariY + 4 ) & 0x1FF;
		}
		if ( wMapChr >= nAtari1 ) {
			nAtariTemp = 1;
/*			if ( ( PlayerInfo.nVy > 0 ) && ( ( nChrY - PlayerInfo.nVy + 32 ) < ( ( nAtariY + 4 ) * 16 ) ) ) {*/
			if ( PlayerInfo.nVy > 0 ) {
				PlayerInfo.nJump = 0;
				PlayerInfo.nAttack = 0;
				PlayerInfo.nVy = 0;
				PlayerInfo.nY = ( nAtariY * 8 - nScrollY ) * 100;
				PlayerInfo.nJumpCount = 0;
				PlayerInfo.nJumpCount2 = 0;
				break;
			}
		}
	}
	if ( nAtariTemp == 0 ) PlayerInfo.nJump = 1;
	/* 頭上の当たり判定 */
/* (未完成)
	nAtariTemp = 0;
	wMapChr = wsBgGetChrNumber( nAtariX + 1, nAtariY ) & 0xFF;
	if ( ( wMapChr >= nAtari1 ) && ( PlayerInfo.nVy < 0 ) ) {
		PlayerInfo.nVy = 0;
		PlayerInfo.nY = ( nAtariY + 1 ) * 8 * 100;
	}
*/
	/* 敵移動 */
	if ( nIventMsg == 0 ) {
		MoveEnemy();
	}
	/* アイテム移動 */
	if ( nItemType != 0 ) {
		MoveItem();
	}
	/* ファイヤーボール移動 */
	if ( nFireStat != 0 ) {
		MoveFire();
	}
}

/*============================================================
	プレイヤーの攻撃
--------------------------------------------------------------
In  : なし
Out : なし
============================================================*/
void Attack( void )
{
	int nAttackX1;
	int nAttackX2;
	int nAttackY1;
	int nAttackY2;
	int i;
	if ( PlayerInfo.nDir == 0 ) {
		/* 左向きの場合 */
		nAttackX1 = PlayerInfo.nX - 1500;
		nAttackX2 = PlayerInfo.nX;
	} else {
		/* 右向きの場合 */
		nAttackX1 = PlayerInfo.nX + 2300;
		nAttackX2 = PlayerInfo.nX + 3900;
	}
	if ( PlayerInfo.nMove == 2 ) {
		/* しゃがんでいる場合 */
		nAttackY1 = PlayerInfo.nY + 1600;
		nAttackY2 = PlayerInfo.nY + 3100;
	} else {
		/* 立っている場合 */
		nAttackY1 = PlayerInfo.nY;
		nAttackY2 = PlayerInfo.nY + 1500;
	}
	for( i=0; i<4; i++ ) {
		if ( EnemyInfo[ i ].nType != 0 ) {
			switch( EnemyInfo[ i ].nType ) {
				case 1:	/* スライムに当たった？ */
				case 2:	/* ジャンプスライムに当たった？ */
				case 4:	/* スケルトン(楯無し)に当たった？ */
				case 5:	/* ウェアウルフに当たった？ */
				case 6:	/* コウモリに当たった？ */
					if ( ( nAttackX1 <= ( EnemyInfo[ i ].nX + EnemyInfo[ i ].nAtariX2 ) ) &&
					     ( nAttackX2 >= ( EnemyInfo[ i ].nX + EnemyInfo[ i ].nAtariX1 ) ) ) {
						if ( ( nAttackY1 <= ( EnemyInfo[ i ].nY + EnemyInfo[ i ].nAtariY2 ) ) &&
						     ( nAttackY2 >= ( EnemyInfo[ i ].nY + EnemyInfo[ i ].nAtariY1 ) ) ) {
							/* ダメージを与える */
							DamageEnemy( i );
						}
					}
					break;
				case 3:
					/* スケルトンに当たった？ */
					if ( PlayerInfo.nDir == EnemyInfo[ i ].nDir ) {
						/* 同じ方向を向いている */
						/* 後ろからの攻撃は無防備 */
						if ( ( nAttackX1 <= ( EnemyInfo[ i ].nX + EnemyInfo[ i ].nAtariX2 ) ) &&
						     ( nAttackX2 >= ( EnemyInfo[ i ].nX + EnemyInfo[ i ].nAtariX1 ) ) ) {
							if ( ( nAttackY1 <= ( EnemyInfo[ i ].nY + EnemyInfo[ i ].nAtariY2 ) ) &&
							     ( nAttackY2 >= ( EnemyInfo[ i ].nY + EnemyInfo[ i ].nAtariY1 ) ) ) {
								/* スケルトンにダメージを与える */
								DamageEnemy( i );
							}
						}
					} else {
						/* 向かい合っている */
						int nAtariTune;
						if ( EnemyInfo[ i ].nStat == 0 ) {
							nAtariTune = 1600;
						} else {
							if ( EnemyInfo[ i ].nDrawCount != 2 ) {
								nAtariTune = 1600;
							} else {
								nAtariTune = 0;
							}
						}
						/* 歩いている場合は上段防御、振りかぶりも上段防御、振り切ったら無防備 */
						if ( ( nAttackX1 <= ( EnemyInfo[ i ].nX + EnemyInfo[ i ].nAtariX2 ) ) &&
						     ( nAttackX2 >= ( EnemyInfo[ i ].nX + EnemyInfo[ i ].nAtariX1 ) ) ) {
							if ( ( nAttackY1 <= ( EnemyInfo[ i ].nY + EnemyInfo[ i ].nAtariY2 ) ) &&
							     ( nAttackY2 >= ( EnemyInfo[ i ].nY + EnemyInfo[ i ].nAtariY1 + nAtariTune ) ) ) {
								/* スケルトンにダメージを与える */
								DamageEnemy( i );
							}
						} else {
							/* 防御した */
							wsSndPlaySe( 2 );
						}
					}
					break;
				case 7:
				case 8:
					/* ナイト、ハイパワーナイトに当たった？ */
					if ( PlayerInfo.nDir == EnemyInfo[ i ].nDir ) {
						/* 同じ方向を向いている */
						/* 後ろからの攻撃は無防備 */
						if ( ( nAttackX1 <= ( EnemyInfo[ i ].nX + EnemyInfo[ i ].nAtariX2 ) ) &&
						     ( nAttackX2 >= ( EnemyInfo[ i ].nX + EnemyInfo[ i ].nAtariX1 ) ) ) {
							if ( ( nAttackY1 <= ( EnemyInfo[ i ].nY + EnemyInfo[ i ].nAtariY2 ) ) &&
							     ( nAttackY2 >= ( EnemyInfo[ i ].nY + EnemyInfo[ i ].nAtariY1 ) ) ) {
								/* ダメージを与える */
								DamageEnemy( i );
							}
						}
					} else {
						/* 向かい合っている */
						int nAtariTune1;
						int nAtariTune2;
						nAtariTune2 = 0;
						if ( EnemyInfo[ i ].nStat == 0 ) {
							nAtariTune1 = 1600;
						} else if ( EnemyInfo[ i ].nStat == 4 ) {
							nAtariTune1 = 0;
							nAtariTune2 = 1600;
						} else {
							if ( EnemyInfo[ i ].nDrawCount != 2 ) {
								nAtariTune1 = 1600;
							} else {
								nAtariTune1 = 0;
							}
						}
						/* 歩いている場合は上段防御、振りかぶりも上段防御、振り切ったら無防備、下段防御もあり */
						if ( ( nAttackX1 <= ( EnemyInfo[ i ].nX + EnemyInfo[ i ].nAtariX2 ) ) &&
						     ( nAttackX2 >= ( EnemyInfo[ i ].nX + EnemyInfo[ i ].nAtariX1 ) ) ) {
							if ( ( nAttackY1 <= ( EnemyInfo[ i ].nY + EnemyInfo[ i ].nAtariY2 - nAtariTune2 ) ) &&
							     ( nAttackY2 >= ( EnemyInfo[ i ].nY + EnemyInfo[ i ].nAtariY1 + nAtariTune1 ) ) ) {
								/* ダメージを与える */
								DamageEnemy( i );
							}
						} else {
							/* 防御した */
							wsSndPlaySe( 2 );
						}
					}
					break;
				case 101:
				case 102:
					/* ドラゴンに当たった？ */
					if ( ( nAttackX1 <= ( EnemyInfo[ i ].nX + EnemyInfo[ i ].nAtariX2 ) ) &&
					     ( nAttackX2 >= ( EnemyInfo[ i ].nX + EnemyInfo[ i ].nAtariX1 ) ) ) {
						if ( ( nAttackY1 <= ( EnemyInfo[ i ].nY + EnemyInfo[ i ].nAtariY2 ) ) &&
						     ( nAttackY2 >= ( EnemyInfo[ i ].nY + EnemyInfo[ i ].nAtariY1 ) ) ) {
							/* ドラゴンにダメージを与える */
							/* ドラゴンの本体は 0 である */
							DamageEnemy( 0 );
						}
					}
					break;
			}
		}
	}
}

/*============================================================
	敵移動
--------------------------------------------------------------
In  : なし
Out : なし
============================================================*/
void MoveEnemy( void )
{
	int nEnemyLoopStart;
	int nEnemyLoopEnd;
	int i;
	/* ==================== 敵の移動 */
	/* 2 キャラずつ交互に移動 */
	nEnemyActionFlag++;
	nEnemyActionFlag &= 1;
	nEnemyLoopStart = nEnemyActionFlag << 1;
	nEnemyLoopEnd = nEnemyLoopStart + 2;
	for( i=nEnemyLoopStart; i<nEnemyLoopEnd; i++ ) {
		if ( EnemyInfo[ i ].nType == 0 ) {
			/* 敵が存在しない */
			continue;
		}
		/* ジャンプ中は自由落下 */
		if ( EnemyInfo[ i ].nJump == 1 ) {
			EnemyInfo[ i ].nVy += 20;
		}
		if ( EnemyInfo[ i ].nStat >= 100 ) {
			/* ふっ飛ぶ */
			if ( EnemyInfo[ i ].nActionCount == 20 ) {
				if ( EnemyInfo[ i ].nDamageDir == 0 ) {
					EnemyInfo[ i ].nVx = 200;
				} else {
					EnemyInfo[ i ].nVx = -200;
				}
			}
			EnemyInfo[ i ].nActionCount--;
			if ( EnemyInfo[ i ].nActionCount <= 0 ) {
				EnemyInfo[ i ].nActionCount = 0;
				if ( EnemyInfo[ i ].nStat == 101 ) {
					/* ボスならステージクリア */
					if ( EnemyInfo[ i ].nType > 100 ) {
						nIventMsg = IV_MSG_STAGECLEAR;
					} else {
						int nItem;
						/* 死んだ */
						wsSndPlaySe( 5 );
						/* 敵を消す */
						SetEnemy( 0, 0, 0, i );
						EnemyInfo[ i ].nType = 0;
						/* アイテムを落とす */
						nItem = 0;
						nItemCount++;
						if ( ( nItemCount % 10 ) == 9 ) {
							/* 体力回復 */
							nItem = 1;
						}
						if ( ( nItemCount % 50 ) == 49 ) {
							/* 体力最大増加 */
							nItem = 3;
						}
						if ( ( nItemCount % 80 ) == 79 ) {
							/* 1 UP */
							nItem = 2;
							nItemCount = 0;
						}
						/* アイテムを置く */
						if ( nItem != 0 ) {
							SetItem( nItem, EnemyInfo[ i ].nX + 4, EnemyInfo[ i ].nY );
						}
					}
				} else {
					EnemyInfo[ i ].nStat = 0;
					EnemyInfo[ i ].nVx = 0;
					EnemyInfo[ i ].nAnimeCount = 0;
					EnemyInfo[ i ].nActionCount = 0;
				}
			}
		}
		/* 通常行動 */
		switch( EnemyInfo[ i ].nType ) {
			case 1:
				/* スライム */
				MoveSlime( i );
				break;
			case 2:
				/* ジャンプスライム */
				MoveJumpSlime( i );
				break;
			case 3:
				/* スケルトン */
				Skeleton( i );
				break;
			case 4:
				/* スケルトン(楯無し) */
				Skeleton2( i );
				break;
			case 5:
				/* ウェアウルフ */
				Wolf( i );
				break;
			case 6:
				/* コウモリ */
				Bat( i );
				break;
			case 7:
				/* ナイト */
				Knight( i );
				break;
			case 8:
				/* ハイパワーナイト */
				Knight( i );
				break;
			case 101:
				/* STAGE 1 ドラゴン */
				Dragon1( i );
				break;
			case 102:
				/* STAGE 2 ドラゴン */
				Dragon2( i );
				break;
		}
		/* 敵キャラが 40 ドット以上画面外に出たら消去する */
		if ( ( EnemyInfo[ i ].nX < ( -3200 - 4000 ) ) || ( EnemyInfo[ i ].nX > ( 22400 + 4000 ) ) ) {
			if ( EnemyInfo[ i ].nType < 100 ) {
				SetEnemy( 0, 0, 0, i );
				EnemyInfo[ i ].nType = 0;
			}
		}
	}
}

/*============================================================
	ファイヤーボール移動
--------------------------------------------------------------
In  : なし
Out : なし
============================================================*/
void MoveFire( void )
{
	int nDif;
	int i;
	if ( nFireStat == 1 ) {
		int nScrollY;
		int nAtariX;
		int nAtariY;
		wsSpMoveObject( 0, 5 + nFireDir, 14, nFireX / 100, nFireY / 100 );
		nScrollY = wsBgGetScrollPositionY();
		nAtariX = ( wsBgGetScrollPositionX() + nFireX / 100 + 8 ) / 8;
		nAtariY = ( nScrollY + nFireY / 100 ) / 8;
		nFireX += ( -130 + ( 260 * nFireDir ) );
		nFireY += 100;
		if ( ( wsBgGetChrNumber( nAtariX, nAtariY + 3 ) & 0x1FF ) >= nAtari1 ) {
			nFireStat = 2;
			nFireCount = 40;
			wsSpSetObject( 0, 7, 14, 397, 0, nFireX / 100, nFireY / 100 );
		}
	} else if ( nFireStat == 2 ) {
		int nTemp;
		nTemp = ( nFireCount >> 1 ) & 1;
		wsSpMoveObject( 0, 7, 14, nFireX / 100, nFireY / 100 );
		nFireCount--;
		if ( nFireCount < 0 ) {
			nFireStat = 0;
			for( i=0; i<12; i++ ) {
				sprite_set_location( 14 + i, 224, 144 );
			}
		}
	}
	/* 画面外に出た時の処理 */
	if ( ( nFireX < -3200 ) || ( nFireX > 22400 ) ) {
		nFireStat = 0;
		for( i=0; i<12; i++ ) {
			sprite_set_location( 14 + i, 224, 144 );
		}
	}
	/* ファイヤーボールに触れた */
	nDif = nFireX - PlayerInfo.nX;
	if ( ( nDif > -2400 ) && ( nDif < 1600 ) ) {
		nDif = nFireY - PlayerInfo.nY;
		if ( ( nDif > -800 ) && ( nDif < 2400 ) ) {
			/* ダメージを受けた */
			if ( PlayerInfo.nZombieCount == 0 ) {
				Damage( 0 );
			}
		}
	}
}

/*============================================================
	アイテム移動
--------------------------------------------------------------
In  : なし
Out : なし
============================================================*/
void MoveItem( void )
{
	int nDif;
	int i;
	wsSpMoveObject( 0, 1 + nItemType, 36, nItemX / 100, nItemY / 100 );
	if ( nItemJump == 1 ) {
		int nScrollY;
		int nAtariX;
		int nAtariY;
		nScrollY = wsBgGetScrollPositionY();
		nAtariX = ( wsBgGetScrollPositionX() + nItemX / 100 + 8 ) / 8;
		nAtariY = ( nScrollY + nItemY / 100 ) / 8;
		nItemY += nItemVy;
		nItemVy += 20;
		if ( ( wsBgGetChrNumber( nAtariX, nAtariY + 1 ) & 0x1FF ) >= nAtari1 ) {
			nItemJump = 0;
			nItemVy = 0;
			nItemY = ( ( nAtariY * 8 ) - nScrollY ) * 100;
		}
	}
	/* 画面外に出た時の処理 */
	if ( ( nItemX < -1600 ) || ( nItemX > 22400 ) ) {
		nItemType = 0;
		for( i=0; i<2; i++ ) {
			sprite_set_location( 36 + i, 224, 144 );
		}
	}
	/* アイテムを GET! した */
	nDif = nItemX - PlayerInfo.nX;
	if ( ( nDif >= -400 ) && ( nDif <= 1200 ) ) {
		nDif = nItemY - PlayerInfo.nY;
		if ( ( nDif >= 0 ) && ( nDif <= 2400 ) ) {
			/* アイテムの効果 */
			switch( nItemType ) {
				case 1:
					/* Life 回復 */
					if ( PlayerInfo.nLife < PlayerInfo.nLifeMax ) {
						PlayerInfo.nLife++;
					}
					break;
				case 2:
					/* 1UP */
					if ( PlayerInfo.nLeft < 9 ) {
						PlayerInfo.nLeft++;
					}
					break;
				case 3:
					/* LifeMax 増加 */
					if ( PlayerInfo.nLifeMax < 7 ) {
						PlayerInfo.nLifeMax++;
					}
					break;
			}
			/* アイテムを消す */
			nItemType = 0;
			for( i=0; i<2; i++ ) {
				sprite_set_location( 36 + i, 224, 144 );
			}
			/* ステータス再描画 */
			DrawStatus();
			/* アイテムを取ったときの効果音 */
			wsSndPlaySe( 1 );
		}
	}
}

/*============================================================
	敵の BG 画面との当たり判定
--------------------------------------------------------------
In  : nIndex = 索引番号 (0〜3)
    : nYLen = 敵の縦の大きさ
Out : なし
============================================================*/
void EnemyBgAtari( int nIndex, int nYLen )
{
	int nScrollX;
	int nScrollY;
	int nChrX;
	int nChrY;
	int nAtariX;
	int nAtariY;
	int nAtariLen;
	int nAtariTemp;
	WORD wMapChr;
	int i;
	/* 当たり判定用変数設定 */
	nScrollX = wsBgGetScrollPositionX();
	nScrollY = wsBgGetScrollPositionY();
	nChrX = nScrollX + EnemyInfo[ nIndex ].nX / 100;
	nChrY = nScrollY + EnemyInfo[ nIndex ].nY / 100;
	nAtariX = nChrX / 8;
	nAtariY = nChrY / 8;
	if ( EnemyInfo[ nIndex ].nVx < 0 ) {
		if ( ( nChrX % 8 ) != 0 ) {
			nAtariX++;
		}
	}
	if ( EnemyInfo[ nIndex ].nVy < 0 ) {
		if ( ( nChrY % 8 ) != 0 ) {
			nAtariY++;
		}
	}
	/* 左右の当たり判定 */
	nAtariLen = 2;
	if ( ( ( EnemyInfo[ nIndex ].nY / 100 ) % 3 ) == 0 ) {
		nAtariLen = 1;
	}
	if ( EnemyInfo[ nIndex ].nVx < 0 ) {
		/* 左側 */
		for( i=0; i<nAtariLen; i++ ) {
			wMapChr = wsBgGetChrNumber( nAtariX - 1, nAtariY + nYLen - i - 1 ) & 0x1FF;
			if ( wMapChr >= nAtari1 ) {
				EnemyInfo[ nIndex ].nVx = 0;
				EnemyInfo[ nIndex ].nX = ( nAtariX * 8 - nScrollX ) * 100;
			}
		}
	} else {
		/* 右側 */
		for( i=0; i<nAtariLen; i++ ) {
			wMapChr = wsBgGetChrNumber( nAtariX + 3, nAtariY + nYLen - i - 1 ) & 0x1FF;
			if ( wMapChr >= nAtari1 ) {
				EnemyInfo[ nIndex ].nVx = 0;
				EnemyInfo[ nIndex ].nX = ( nAtariX * 8 - nScrollX ) * 100;
			}
		}
	}
	/* 足元の当たり判定 */
	nAtariLen = 2;
	if ( ( ( EnemyInfo[ nIndex ].nX / 100 ) % 8 ) == 0 ) {
		nAtariLen = 1;
	}
	nAtariTemp = 0;
	for( i=0; i<nAtariLen; i++ ) {
		if ( EnemyInfo[ nIndex ].nVx < 0 ) {
			wMapChr = wsBgGetChrNumber( nAtariX + 1 - i, nAtariY + nYLen ) & 0x1FF;
		} else {
			wMapChr = wsBgGetChrNumber( nAtariX + 1 + i, nAtariY + nYLen ) & 0x1FF;
		}
		if ( wMapChr >= nAtari1 ) {
			nAtariTemp = 1;
			if ( EnemyInfo[ nIndex ].nVy > 0 ) {
				EnemyInfo[ nIndex ].nJump = 0;
				EnemyInfo[ nIndex ].nVy = 0;
				EnemyInfo[ nIndex ].nY = ( nAtariY * 8 - nScrollY ) * 100;
				break;
			}
		}
	}
	if ( nAtariTemp == 0 ) {
		EnemyInfo[ nIndex ].nJump = 1;
	}
}

/*============================================================
	スライムの行動
--------------------------------------------------------------
In  : nIndex = 索引番号 (0〜3)
Out : なし
============================================================*/
void MoveSlime( int nIndex )
{
	int nRand;
	int nTemp;
	/* アニメーションカウンタ */
	EnemyInfo[ nIndex ].nAnimeCount--;
	if ( EnemyInfo[ nIndex ].nStat == 0 ) {
		if ( EnemyInfo[ nIndex ].nAnimeCount < 0 ) {
			EnemyInfo[ nIndex ].nAnimeCount = 16;
			EnemyInfo[ nIndex ].nDrawNumber++;
			EnemyInfo[ nIndex ].nDrawNumber &= 1;
			EnemyInfo[ nIndex ].nActionFlag = 1;
			nRand = rand();
			if ( nRand < 12288 ) {
				EnemyInfo[ nIndex ].nStat = ( nRand / 8192 ) + 1;
				EnemyInfo[ nIndex ].nActionCount = 8 + rand() / 4096;
				EnemyInfo[ nIndex ].nAnimeCount = 0;
				if ( EnemyInfo[ nIndex ].nX > PlayerInfo.nX ) {
					EnemyInfo[ nIndex ].nDir = 0;
				} else {
					EnemyInfo[ nIndex ].nDir = 1;
				}
			}
		}
	} else if ( EnemyInfo[ nIndex ].nStat <= 2 ) {
		/* 向かってくる */
		EnemyInfo[ nIndex ].nVx = 0;
		if ( EnemyInfo[ nIndex ].nAnimeCount < 0 ) {
			EnemyInfo[ nIndex ].nAnimeCount = 2;
			EnemyInfo[ nIndex ].nDrawNumber++;
			EnemyInfo[ nIndex ].nDrawNumber &= 1;
			EnemyInfo[ nIndex ].nVx = EnemyInfo[ nIndex ].nDir << 1;
			EnemyInfo[ nIndex ].nVx--;
			EnemyInfo[ nIndex ].nVx *= ( 120 * EnemyInfo[ nIndex ].nStat );
			EnemyInfo[ nIndex ].nActionFlag = 1;
			EnemyInfo[ nIndex ].nActionCount--;
			if ( EnemyInfo[ nIndex ].nActionCount < 0 ) {
				EnemyInfo[ nIndex ].nAnimeCount = 0;
				EnemyInfo[ nIndex ].nVx = 0;
				EnemyInfo[ nIndex ].nStat = 0;
			}
		}
	}
	/* キャラクタ移動 */
	EnemyInfo[ nIndex ].nX += EnemyInfo[ nIndex ].nVx;
	EnemyInfo[ nIndex ].nY += EnemyInfo[ nIndex ].nVy;
	/* BG との当たり判定 */
	EnemyBgAtari( nIndex, 2 );
	/* プレイヤーとの当たり判定 */
	nTemp = EnemyInfo[ nIndex ].nX - PlayerInfo.nX;
	if ( nTemp < 0 ) {
		nTemp = -nTemp;
	}
	if ( nTemp < 1600 ) {
		nTemp = EnemyInfo[ nIndex ].nY - ( PlayerInfo.nY + 1600 );
		if ( nTemp < 0 ) nTemp = -nTemp;
		if ( nTemp < 1200 ) {
			/* プレイヤーにダメージ */
			if ( PlayerInfo.nZombieCount == 0 ) {
				Damage( EnemyInfo[ nIndex ].nDir );
			}
		}
	}
}

/*============================================================
	ジャンプスライムの行動
--------------------------------------------------------------
In  : nIndex = 索引番号 (0〜3)
Out : なし
============================================================*/
void MoveJumpSlime( int nIndex )
{
	int nRand;
	int nTemp;
	/* アニメーションカウンタ */
	EnemyInfo[ nIndex ].nAnimeCount--;
	if ( EnemyInfo[ nIndex ].nStat == 0 ) {
		/* 止まっている */
		if ( EnemyInfo[ nIndex ].nAnimeCount < 0 ) {
			EnemyInfo[ nIndex ].nAnimeCount = 16;
			EnemyInfo[ nIndex ].nDrawNumber++;
			EnemyInfo[ nIndex ].nDrawNumber &= 1;
			EnemyInfo[ nIndex ].nDrawNumber += 2;
			EnemyInfo[ nIndex ].nActionFlag = 1;
			nRand = rand();
			if ( ( nRand < 12288 ) && ( EnemyInfo[ nIndex ].nVy == 0 ) ) {
				EnemyInfo[ nIndex ].nStat = ( nRand / 8192 ) + 1;
				EnemyInfo[ nIndex ].nActionCount = 8 + rand() / 4096;
				EnemyInfo[ nIndex ].nVy -= ( 100 * EnemyInfo[ nIndex ].nStat );
				EnemyInfo[ nIndex ].nAnimeCount = 0;
				if ( EnemyInfo[ nIndex ].nX > PlayerInfo.nX ) {
					EnemyInfo[ nIndex ].nDir = 0;
				} else {
					EnemyInfo[ nIndex ].nDir = 1;
				}
			}
		}
	} else if ( EnemyInfo[ nIndex ].nStat <= 2 ) {
		/* ジャンプして向かってくる */
		EnemyInfo[ nIndex ].nVx = 0;
		if ( EnemyInfo[ nIndex ].nAnimeCount < 0 ) {
			EnemyInfo[ nIndex ].nAnimeCount = 2;
			EnemyInfo[ nIndex ].nDrawNumber++;
			EnemyInfo[ nIndex ].nDrawNumber &= 1;
			EnemyInfo[ nIndex ].nDrawNumber += 2;
			EnemyInfo[ nIndex ].nVx = EnemyInfo[ nIndex ].nDir << 1;
			EnemyInfo[ nIndex ].nVx--;
			EnemyInfo[ nIndex ].nVx *= ( 100 * EnemyInfo[ nIndex ].nStat );
			EnemyInfo[ nIndex ].nActionFlag = 1;
			EnemyInfo[ nIndex ].nActionCount--;
			if ( EnemyInfo[ nIndex ].nActionCount < 0 ) {
				EnemyInfo[ nIndex ].nVx = 0;
				EnemyInfo[ nIndex ].nStat = 0;
				EnemyInfo[ nIndex ].nAnimeCount = 0;
			}
		}
	}
	/* キャラクタ移動 */
	EnemyInfo[ nIndex ].nX += EnemyInfo[ nIndex ].nVx;
	EnemyInfo[ nIndex ].nY += EnemyInfo[ nIndex ].nVy;
	/* BG との当たり判定 */
	EnemyBgAtari( nIndex, 2 );
	/* プレイヤーとの当たり判定 */
	nTemp = EnemyInfo[ nIndex ].nX - PlayerInfo.nX;
	if ( nTemp < 0 ) {
		nTemp = -nTemp;
	}
	if ( nTemp < 1600 ) {
		nTemp = EnemyInfo[ nIndex ].nY - ( PlayerInfo.nY + 1600 );
		if ( nTemp < 0 ) nTemp = -nTemp;
		if ( nTemp < 1200 ) {
			/* プレイヤーにダメージ */
			if ( PlayerInfo.nZombieCount == 0 ) {
				Damage( EnemyInfo[ nIndex ].nDir );
			}
		}
	}
}

/*============================================================
	スケルトンの行動
--------------------------------------------------------------
In  : nIndex = 索引番号 (0〜3)
Out : なし
============================================================*/
void Skeleton( int nIndex )
{
	int nTemp;
	/* アニメーションカウンタ */
	EnemyInfo[ nIndex ].nAnimeCount--;
	switch( EnemyInfo[ nIndex ].nStat ) {
		case 0:
			/* 向かってくる */
			if ( EnemyInfo[ nIndex ].nX > PlayerInfo.nX ) {
				EnemyInfo[ nIndex ].nDir = 0;
			} else {
				EnemyInfo[ nIndex ].nDir = 1;
			}
			if ( EnemyInfo[ nIndex ].nAnimeCount < 0 ) {
				EnemyInfo[ nIndex ].nAnimeCount = 4;
				EnemyInfo[ nIndex ].nDrawCount++;
				EnemyInfo[ nIndex ].nDrawCount &= 1;
				EnemyInfo[ nIndex ].nDrawNumber = 4 + EnemyInfo[ nIndex ].nDrawCount;
				EnemyInfo[ nIndex ].nDrawNumber += ( EnemyInfo[ nIndex ].nDir << 1 );
				EnemyInfo[ nIndex ].nActionFlag = 1;
				EnemyInfo[ nIndex ].nVx = EnemyInfo[ nIndex ].nDir << 1;
				EnemyInfo[ nIndex ].nVx--;
				EnemyInfo[ nIndex ].nVx *= 60;
			}
			nTemp = EnemyInfo[ nIndex ].nX - PlayerInfo.nX;
			if ( nTemp < 0 ) nTemp = -nTemp;
			if ( nTemp < ( 2200 + EnemyInfo[ nIndex ].nRand ) ) {
				if ( rand() > 12000 ) {
					EnemyInfo[ nIndex ].nStat = 2;
				} else {
					EnemyInfo[ nIndex ].nStat = 1;
				}
				EnemyInfo[ nIndex ].nDrawCount = 0;
				EnemyInfo[ nIndex ].nVx = 0;
				EnemyInfo[ nIndex ].nAnimeCount = 0;
				EnemyInfo[ nIndex ].nRand = rand() & 1023;
			}
			break;
		case 1:
			/* 後ずさり */
			if ( EnemyInfo[ nIndex ].nX > PlayerInfo.nX ) {
				EnemyInfo[ nIndex ].nDir = 0;
			} else {
				EnemyInfo[ nIndex ].nDir = 1;
			}
			if ( EnemyInfo[ nIndex ].nAnimeCount < 0 ) {
				EnemyInfo[ nIndex ].nAnimeCount = 8;
				EnemyInfo[ nIndex ].nDrawCount++;
				EnemyInfo[ nIndex ].nDrawCount &= 1;
				EnemyInfo[ nIndex ].nDrawNumber = 4 + EnemyInfo[ nIndex ].nDrawCount;
				EnemyInfo[ nIndex ].nDrawNumber += ( EnemyInfo[ nIndex ].nDir << 1 );
				EnemyInfo[ nIndex ].nActionFlag = 1;
				EnemyInfo[ nIndex ].nVx = EnemyInfo[ nIndex ].nDir << 1;
				EnemyInfo[ nIndex ].nVx--;
				EnemyInfo[ nIndex ].nVx *= -50;
			}
			nTemp = EnemyInfo[ nIndex ].nX - PlayerInfo.nX;
			if ( nTemp < 0 ) nTemp = -nTemp;
			if ( nTemp > ( 4400 + EnemyInfo[ nIndex ].nRand ) ) {
				if ( rand() > 22000 ) {
					EnemyInfo[ nIndex ].nStat = 2;
				} else {
					EnemyInfo[ nIndex ].nStat = 0;
				}
				EnemyInfo[ nIndex ].nDrawCount = 0;
				EnemyInfo[ nIndex ].nVx = 0;
				EnemyInfo[ nIndex ].nAnimeCount = 0;
				EnemyInfo[ nIndex ].nRand = rand() & 1023;
			}
			break;
		case 2:
			/* 剣を振る */
			if ( EnemyInfo[ nIndex ].nAnimeCount < 0 ) {
				EnemyInfo[ nIndex ].nAnimeCount = 12;
				if ( EnemyInfo[ nIndex ].nDrawCount > 2 ) {
					EnemyInfo[ nIndex ].nStat = 0;
					EnemyInfo[ nIndex ].nAnimeCount = 0;
					EnemyInfo[ nIndex ].nRand = rand() & 1023;
				} else {
					EnemyInfo[ nIndex ].nDrawNumber = 8;
					EnemyInfo[ nIndex ].nDrawNumber += ( EnemyInfo[ nIndex ].nDir << 1 );
					EnemyInfo[ nIndex ].nDrawNumber += ( EnemyInfo[ nIndex ].nDrawCount & 1 );
					EnemyInfo[ nIndex ].nActionFlag = 1;
				}
				if ( EnemyInfo[ nIndex ].nDrawCount == 1 ) {
					/* 剣を振った */
					wsSndPlaySe( 4 );
					/* スケルトンの攻撃 */
					AttackToPlayer( nIndex, 0 );
				}
				EnemyInfo[ nIndex ].nDrawCount++;
			}
			break;
	}
	/* キャラクタ移動 */
	EnemyInfo[ nIndex ].nX += EnemyInfo[ nIndex ].nVx;
	EnemyInfo[ nIndex ].nY += EnemyInfo[ nIndex ].nVy;
	/* BG との当たり判定 */
	EnemyBgAtari( nIndex, 4 );
	/* プレイヤーとの当たり判定 */
	nTemp = EnemyInfo[ nIndex ].nX - PlayerInfo.nX;
	if ( nTemp < 0 ) {
		nTemp = -nTemp;
	}
	if ( nTemp < 1600 ) {
		nTemp = EnemyInfo[ nIndex ].nY - ( PlayerInfo.nY );
		if ( nTemp < 0 ) nTemp = -nTemp;
		if ( nTemp < 1600 ) {
			/* プレイヤーにダメージ */
			if ( PlayerInfo.nZombieCount == 0 ) {
				Damage( EnemyInfo[ nIndex ].nDir );
			}
		}
	}
}

/*============================================================
	スケルトン(楯無し)の行動
--------------------------------------------------------------
In  : nIndex = 索引番号 (0〜3)
Out : なし
============================================================*/
void Skeleton2( int nIndex )
{
	int nTemp;
	/* アニメーションカウンタ */
	EnemyInfo[ nIndex ].nAnimeCount--;
	switch( EnemyInfo[ nIndex ].nStat ) {
		case 0:
			/* 向かってくる */
			if ( EnemyInfo[ nIndex ].nX > PlayerInfo.nX ) {
				EnemyInfo[ nIndex ].nDir = 0;
			} else {
				EnemyInfo[ nIndex ].nDir = 1;
			}
			if ( EnemyInfo[ nIndex ].nAnimeCount < 0 ) {
				EnemyInfo[ nIndex ].nAnimeCount = 4;
				EnemyInfo[ nIndex ].nDrawCount++;
				EnemyInfo[ nIndex ].nDrawCount &= 1;
				EnemyInfo[ nIndex ].nDrawNumber = 12 + EnemyInfo[ nIndex ].nDrawCount;
				EnemyInfo[ nIndex ].nDrawNumber += ( EnemyInfo[ nIndex ].nDir << 1 );
				EnemyInfo[ nIndex ].nActionFlag = 1;
				EnemyInfo[ nIndex ].nVx = EnemyInfo[ nIndex ].nDir << 1;
				EnemyInfo[ nIndex ].nVx--;
				EnemyInfo[ nIndex ].nVx *= 60;
			}
			nTemp = EnemyInfo[ nIndex ].nX - PlayerInfo.nX;
			if ( nTemp < 0 ) nTemp = -nTemp;
			if ( nTemp < ( 2200 + EnemyInfo[ nIndex ].nRand ) ) {
				if ( rand() > 12000 ) {
					EnemyInfo[ nIndex ].nStat = 2;
				} else {
					EnemyInfo[ nIndex ].nStat = 1;
				}
				EnemyInfo[ nIndex ].nDrawCount = 0;
				EnemyInfo[ nIndex ].nVx = 0;
				EnemyInfo[ nIndex ].nAnimeCount = 0;
				EnemyInfo[ nIndex ].nRand = rand() & 1023;
			}
			break;
		case 1:
			/* 後ずさり */
			if ( EnemyInfo[ nIndex ].nX > PlayerInfo.nX ) {
				EnemyInfo[ nIndex ].nDir = 0;
			} else {
				EnemyInfo[ nIndex ].nDir = 1;
			}
			if ( EnemyInfo[ nIndex ].nAnimeCount < 0 ) {
				EnemyInfo[ nIndex ].nAnimeCount = 8;
				EnemyInfo[ nIndex ].nDrawCount++;
				EnemyInfo[ nIndex ].nDrawCount &= 1;
				EnemyInfo[ nIndex ].nDrawNumber = 12 + EnemyInfo[ nIndex ].nDrawCount;
				EnemyInfo[ nIndex ].nDrawNumber += ( EnemyInfo[ nIndex ].nDir << 1 );
				EnemyInfo[ nIndex ].nActionFlag = 1;
				EnemyInfo[ nIndex ].nVx = EnemyInfo[ nIndex ].nDir << 1;
				EnemyInfo[ nIndex ].nVx--;
				EnemyInfo[ nIndex ].nVx *= -50;
			}
			nTemp = EnemyInfo[ nIndex ].nX - PlayerInfo.nX;
			if ( nTemp < 0 ) nTemp = -nTemp;
			if ( nTemp > ( 4400 + EnemyInfo[ nIndex ].nRand ) ) {
				if ( rand() > 22000 ) {
					EnemyInfo[ nIndex ].nStat = 2;
				} else {
					EnemyInfo[ nIndex ].nStat = 0;
				}
				EnemyInfo[ nIndex ].nDrawCount = 0;
				EnemyInfo[ nIndex ].nVx = 0;
				EnemyInfo[ nIndex ].nAnimeCount = 0;
				EnemyInfo[ nIndex ].nRand = rand() & 1023;
			}
			break;
		case 2:
			/* 剣を振る */
			if ( EnemyInfo[ nIndex ].nAnimeCount < 0 ) {
				EnemyInfo[ nIndex ].nAnimeCount = 12;
				if ( EnemyInfo[ nIndex ].nDrawCount > 2 ) {
					EnemyInfo[ nIndex ].nStat = 0;
					EnemyInfo[ nIndex ].nAnimeCount = 0;
					EnemyInfo[ nIndex ].nRand = rand() & 1023;
				} else {
					EnemyInfo[ nIndex ].nDrawNumber = 16;
					EnemyInfo[ nIndex ].nDrawNumber += ( EnemyInfo[ nIndex ].nDir << 1 );
					EnemyInfo[ nIndex ].nDrawNumber += ( EnemyInfo[ nIndex ].nDrawCount & 1 );
					EnemyInfo[ nIndex ].nActionFlag = 1;
				}
				if ( EnemyInfo[ nIndex ].nDrawCount == 1 ) {
					/* 剣を振った */
					wsSndPlaySe( 4 );
					/* スケルトンの攻撃 */
					AttackToPlayer( nIndex, 0 );
				}
				EnemyInfo[ nIndex ].nDrawCount++;
			}
			break;
	}
	/* キャラクタ移動 */
	EnemyInfo[ nIndex ].nX += EnemyInfo[ nIndex ].nVx;
	EnemyInfo[ nIndex ].nY += EnemyInfo[ nIndex ].nVy;
	/* BG との当たり判定 */
	EnemyBgAtari( nIndex, 4 );
	/* プレイヤーとの当たり判定 */
	nTemp = EnemyInfo[ nIndex ].nX - PlayerInfo.nX;
	if ( nTemp < 0 ) {
		nTemp = -nTemp;
	}
	if ( nTemp < 1600 ) {
		nTemp = EnemyInfo[ nIndex ].nY - ( PlayerInfo.nY );
		if ( nTemp < 0 ) nTemp = -nTemp;
		if ( nTemp < 1600 ) {
			/* プレイヤーにダメージ */
			if ( PlayerInfo.nZombieCount == 0 ) {
				Damage( EnemyInfo[ nIndex ].nDir );
			}
		}
	}
}

/*============================================================
	ウェアウルフの行動
--------------------------------------------------------------
In  : nIndex = 索引番号 (0〜3)
Out : なし
============================================================*/
void Wolf( int nIndex )
{
	int nTemp;
	/* アニメーションカウンタ */
	EnemyInfo[ nIndex ].nAnimeCount--;
	if ( EnemyInfo[ nIndex ].nStat == 0 ) {
		/* 向かってくる */
		if ( EnemyInfo[ nIndex ].nAnimeCount < 0 ) {
			EnemyInfo[ nIndex ].nAnimeCount = 3;
			EnemyInfo[ nIndex ].nDrawCount++;
			EnemyInfo[ nIndex ].nDrawCount &= 3;
			nTemp = EnemyInfo[ nIndex ].nDrawCount;
			if ( nTemp == 3 ) nTemp = 1;
			EnemyInfo[ nIndex ].nDrawNumber = 20 + nTemp;
			EnemyInfo[ nIndex ].nDrawNumber += ( EnemyInfo[ nIndex ].nDir * 3 );
			EnemyInfo[ nIndex ].nActionFlag = 1;
			EnemyInfo[ nIndex ].nVx = EnemyInfo[ nIndex ].nDir << 1;
			EnemyInfo[ nIndex ].nVx--;
			EnemyInfo[ nIndex ].nVx *= 100;
		}
	}
	/* キャラクタ移動 */
	EnemyInfo[ nIndex ].nX += EnemyInfo[ nIndex ].nVx;
	EnemyInfo[ nIndex ].nY += EnemyInfo[ nIndex ].nVy;
	/* BG との当たり判定 */
	EnemyBgAtari( nIndex, 4 );
	/* プレイヤーとの当たり判定 */
	nTemp = EnemyInfo[ nIndex ].nX - PlayerInfo.nX;
	if ( nTemp < 0 ) {
		nTemp = -nTemp;
	}
	if ( nTemp < 1600 ) {
		nTemp = EnemyInfo[ nIndex ].nY - ( PlayerInfo.nY );
		if ( nTemp < 0 ) nTemp = -nTemp;
		if ( nTemp < 1600 ) {
			/* プレイヤーにダメージ */
			if ( PlayerInfo.nZombieCount == 0 ) {
				Damage( EnemyInfo[ nIndex ].nDir );
			}
		}
	}
}

/*============================================================
	コウモリの行動
--------------------------------------------------------------
In  : nIndex = 索引番号 (0〜3)
Out : なし
============================================================*/
void Bat( int nIndex )
{
	int nRand;
	int nTemp;
	/* アニメーションカウンタ */
	EnemyInfo[ nIndex ].nAnimeCount--;
	if ( EnemyInfo[ nIndex ].nStat == 0 ) {
		/* ぶらさがっている */
		EnemyInfo[ nIndex ].nJump = 0;
		if ( EnemyInfo[ nIndex ].nAnimeCount < 0 ) {
			EnemyInfo[ nIndex ].nAnimeCount = 16;
			EnemyInfo[ nIndex ].nDrawNumber = 28;
			EnemyInfo[ nIndex ].nActionFlag = 1;
			EnemyInfo[ nIndex ].nRand = ( rand() % 100 ) + 150;
			nRand = rand();
			if ( nRand < 5000 ) {
				EnemyInfo[ nIndex ].nStat = 1;
				EnemyInfo[ nIndex ].nActionCount = 64;
				EnemyInfo[ nIndex ].nAnimeCount = 0;
				if ( EnemyInfo[ nIndex ].nX > PlayerInfo.nX ) {
					EnemyInfo[ nIndex ].nDir = 0;
				} else {
					EnemyInfo[ nIndex ].nDir = 1;
				}
			}
		}
	} else if ( EnemyInfo[ nIndex ].nStat == 1 ) {
		/* 向かってくる */
		EnemyInfo[ nIndex ].nJump = 0;
		EnemyInfo[ nIndex ].nVx = 0;
		if ( EnemyInfo[ nIndex ].nAnimeCount < 0 ) {
			EnemyInfo[ nIndex ].nAnimeCount = 2;
			EnemyInfo[ nIndex ].nDrawNumber++;
			EnemyInfo[ nIndex ].nDrawNumber &= 1;
			EnemyInfo[ nIndex ].nDrawNumber += 26;
			EnemyInfo[ nIndex ].nVx = EnemyInfo[ nIndex ].nDir << 1;
			EnemyInfo[ nIndex ].nVx--;
			EnemyInfo[ nIndex ].nVx *= EnemyInfo[ nIndex ].nRand;
			EnemyInfo[ nIndex ].nY = 1600 + SinTable[ EnemyInfo[ nIndex ].nActionCount ] * 88;
			EnemyInfo[ nIndex ].nActionFlag = 1;
			EnemyInfo[ nIndex ].nActionCount--;
			if ( EnemyInfo[ nIndex ].nActionCount < 0 ) {
				EnemyInfo[ nIndex ].nAnimeCount = 0;
				EnemyInfo[ nIndex ].nVx = 0;
				EnemyInfo[ nIndex ].nStat = 0;
			}
		}
	} else {
		/* ダメージを受けたら落ちる */
		EnemyInfo[ nIndex ].nDrawNumber = 26;
		EnemyInfo[ nIndex ].nJump = 1;
		/* BG との当たり判定 */
		EnemyBgAtari( nIndex, 2 );
	}
	/* キャラクタ移動 */
	EnemyInfo[ nIndex ].nX += EnemyInfo[ nIndex ].nVx;
	EnemyInfo[ nIndex ].nY += EnemyInfo[ nIndex ].nVy;
	/* プレイヤーとの当たり判定 */
	nTemp = EnemyInfo[ nIndex ].nX - PlayerInfo.nX;
	if ( nTemp < 0 ) {
		nTemp = -nTemp;
	}
	if ( nTemp < 1600 ) {
		nTemp = EnemyInfo[ nIndex ].nY - ( PlayerInfo.nY + 1600 );
		if ( nTemp < 0 ) nTemp = -nTemp;
		if ( nTemp < 1200 ) {
			/* プレイヤーにダメージ */
			if ( PlayerInfo.nZombieCount == 0 ) {
				Damage( EnemyInfo[ nIndex ].nDir );
			}
		}
	}
}

/*============================================================
	ナイトの行動
--------------------------------------------------------------
In  : nIndex = 索引番号 (0〜3)
Out : なし
============================================================*/
void Knight( int nIndex )
{
	int nTemp;
	/* アニメーションカウンタ */
	EnemyInfo[ nIndex ].nAnimeCount--;
	switch( EnemyInfo[ nIndex ].nStat ) {
		case 0:
			/* 向かってくる */
			if ( EnemyInfo[ nIndex ].nX > PlayerInfo.nX ) {
				EnemyInfo[ nIndex ].nDir = 0;
			} else {
				EnemyInfo[ nIndex ].nDir = 1;
			}
			if ( ( PlayerInfo.nAttack == 1 ) && ( PlayerInfo.nMove == 2 ) ) {
				/* 下段防御 */
				if ( rand() < 25000 ) {
					EnemyInfo[ nIndex ].nStat = 4;
					EnemyInfo[ nIndex ].nAnimeCount = 5 + rand() % 30;
					EnemyInfo[ nIndex ].nDrawNumber = 29 + EnemyInfo[ nIndex ].nDir;
					EnemyInfo[ nIndex ].nActionFlag = 1;
					EnemyInfo[ nIndex ].nVx = 0;
				}
			}
			if ( EnemyInfo[ nIndex ].nAnimeCount < 0 ) {
				EnemyInfo[ nIndex ].nAnimeCount = 4;
				EnemyInfo[ nIndex ].nDrawCount++;
				EnemyInfo[ nIndex ].nDrawCount &= 3;
				nTemp = EnemyInfo[ nIndex ].nDrawCount;
				if ( nTemp == 3 ) nTemp = 1;
				EnemyInfo[ nIndex ].nDrawNumber = 31 + nTemp;
				EnemyInfo[ nIndex ].nDrawNumber += ( EnemyInfo[ nIndex ].nDir * 3 );
				EnemyInfo[ nIndex ].nActionFlag = 1;
				EnemyInfo[ nIndex ].nVx = EnemyInfo[ nIndex ].nDir << 1;
				EnemyInfo[ nIndex ].nVx--;
				EnemyInfo[ nIndex ].nVx *= 60;
			}
			nTemp = EnemyInfo[ nIndex ].nX - PlayerInfo.nX;
			if ( nTemp < 0 ) nTemp = -nTemp;
			if ( nTemp < ( 2200 + EnemyInfo[ nIndex ].nRand ) ) {
				if ( rand() > 12000 ) {
					if ( rand() > 16384 ) {
						EnemyInfo[ nIndex ].nStat = 2;
					} else {
						EnemyInfo[ nIndex ].nStat = 3;
					}
				} else {
					EnemyInfo[ nIndex ].nStat = 1;
				}
				EnemyInfo[ nIndex ].nDrawCount = 0;
				EnemyInfo[ nIndex ].nVx = 0;
				EnemyInfo[ nIndex ].nAnimeCount = 0;
				EnemyInfo[ nIndex ].nRand = rand() & 1023;
			}
			break;
		case 1:
			/* 後ずさり */
			if ( EnemyInfo[ nIndex ].nX > PlayerInfo.nX ) {
				EnemyInfo[ nIndex ].nDir = 0;
			} else {
				EnemyInfo[ nIndex ].nDir = 1;
			}
			if ( EnemyInfo[ nIndex ].nAnimeCount < 0 ) {
				EnemyInfo[ nIndex ].nAnimeCount = 8;
				EnemyInfo[ nIndex ].nDrawCount++;
				EnemyInfo[ nIndex ].nDrawCount &= 3;
				nTemp = EnemyInfo[ nIndex ].nDrawCount;
				if ( nTemp == 3 ) nTemp = 1;
				EnemyInfo[ nIndex ].nDrawNumber = 31 + nTemp;
				EnemyInfo[ nIndex ].nDrawNumber += ( EnemyInfo[ nIndex ].nDir * 3 );
				EnemyInfo[ nIndex ].nActionFlag = 1;
				EnemyInfo[ nIndex ].nVx = EnemyInfo[ nIndex ].nDir << 1;
				EnemyInfo[ nIndex ].nVx--;
				EnemyInfo[ nIndex ].nVx *= -50;
			}
			nTemp = EnemyInfo[ nIndex ].nX - PlayerInfo.nX;
			if ( nTemp < 0 ) nTemp = -nTemp;
			if ( nTemp > ( 4400 + EnemyInfo[ nIndex ].nRand ) ) {
				if ( rand() > 22000 ) {
					if ( rand() > 16384 ) {
						EnemyInfo[ nIndex ].nStat = 2;
					} else {
						EnemyInfo[ nIndex ].nStat = 3;
					}
				} else {
					EnemyInfo[ nIndex ].nStat = 0;
				}
				EnemyInfo[ nIndex ].nDrawCount = 0;
				EnemyInfo[ nIndex ].nVx = 0;
				EnemyInfo[ nIndex ].nAnimeCount = 0;
				EnemyInfo[ nIndex ].nRand = rand() & 1023;
			}
			break;
		case 2:
		case 3:
			KnightAttack( nIndex );
			break;
		case 4:
			/* 下段防御 */
			if ( EnemyInfo[ nIndex ].nAnimeCount < 0 ) {
				EnemyInfo[ nIndex ].nStat = 0;
				EnemyInfo[ nIndex ].nAnimeCount = 0;
				EnemyInfo[ nIndex ].nRand = rand() & 1023;
			}
			break;
	}
	/* キャラクタ移動 */
	EnemyInfo[ nIndex ].nX += EnemyInfo[ nIndex ].nVx;
	EnemyInfo[ nIndex ].nY += EnemyInfo[ nIndex ].nVy;
	/* BG との当たり判定 */
	EnemyBgAtari( nIndex, 4 );
	/* プレイヤーとの当たり判定 */
	nTemp = EnemyInfo[ nIndex ].nX - PlayerInfo.nX;
	if ( nTemp < 0 ) {
		nTemp = -nTemp;
	}
	if ( nTemp < 1600 ) {
		nTemp = EnemyInfo[ nIndex ].nY - PlayerInfo.nY;
		if ( nTemp < 0 ) nTemp = -nTemp;
		if ( nTemp < 1600 ) {
			/* プレイヤーにダメージ */
			if ( PlayerInfo.nZombieCount == 0 ) {
				Damage( EnemyInfo[ nIndex ].nDir );
			}
		}
	}
}

/*============================================================
	ナイトの攻撃
--------------------------------------------------------------
In  : nIndex = 索引番号 (0〜3)
Out : なし
============================================================*/
void KnightAttack( int nIndex )
{
	/* 剣を振る */
	if ( EnemyInfo[ nIndex ].nAnimeCount < 0 ) {
		EnemyInfo[ nIndex ].nAnimeCount = 15;
		if ( EnemyInfo[ nIndex ].nDrawCount > 2 ) {
			EnemyInfo[ nIndex ].nStat = 0;
			EnemyInfo[ nIndex ].nAnimeCount = 0;
			EnemyInfo[ nIndex ].nRand = rand() & 1023;
		} else {
			if ( EnemyInfo[ nIndex ].nStat == 2 ) {
				EnemyInfo[ nIndex ].nDrawNumber = 37;
			} else {
				EnemyInfo[ nIndex ].nDrawNumber = 41;
			}
			EnemyInfo[ nIndex ].nDrawNumber += ( EnemyInfo[ nIndex ].nDir << 1 );
			EnemyInfo[ nIndex ].nDrawNumber += ( EnemyInfo[ nIndex ].nDrawCount & 1 );
			EnemyInfo[ nIndex ].nActionFlag = 1;
		}
		if ( EnemyInfo[ nIndex ].nDrawCount == 1 ) {
			/* 剣を振った */
			wsSndPlaySe( 4 );
			/* ナイトの攻撃 */
			AttackToPlayer( nIndex, EnemyInfo[ nIndex ].nStat - 2 );
		}
		EnemyInfo[ nIndex ].nDrawCount++;
	}
}

/*============================================================
	レッドドラゴンの行動
--------------------------------------------------------------
In  : nIndex = 索引番号 (0〜3)
Out : なし
============================================================*/
void Dragon1( int nIndex )
{
	if ( nIndex == 0 ) {
		int nTemp;
		int i;
		/* アニメーションカウンタ */
		EnemyInfo[ nIndex ].nAnimeCount--;
		if ( EnemyInfo[ nIndex ].nStat == 0 ) {
			/* 止まっている */
			if ( EnemyInfo[ nIndex ].nAnimeCount < 0 ) {
				int nTemp;
				EnemyInfo[ nIndex ].nAnimeCount = 8;
				if ( EnemyInfo[ nIndex ].nX > PlayerInfo.nX ) {
					EnemyInfo[ nIndex ].nDir = 0;
				} else {
					EnemyInfo[ nIndex ].nDir = 1;
				}
				EnemyInfo[ nIndex ].nDrawCount++;
				EnemyInfo[ nIndex ].nDrawCount &= 3;
				nTemp = EnemyInfo[ nIndex ].nDrawCount;
				if ( nTemp > 0 ) nTemp += 2;
				if ( nTemp == 5 ) nTemp = 3;
				EnemyInfo[ nIndex ].nDrawNumber = 64 + nTemp * 4;
				EnemyInfo[ nIndex ].nDrawNumber += ( 20 * EnemyInfo[ nIndex ].nDir );
				EnemyInfo[ 0 ].nActionFlag = 1;
				EnemyInfo[ nIndex ].nActionCount--;
				if ( EnemyInfo[ nIndex ].nActionCount < 0 ) {
					int nRand;
					nRand = rand() % 3;
					EnemyInfo[ nIndex ].nAnimeCount = 0;
					EnemyInfo[ nIndex ].nDrawCount = 0;
					switch( nRand ) {
						case 0:
							EnemyInfo[ nIndex ].nActionCount = rand() % 4;
							EnemyInfo[ nIndex ].nStat = 0;
							break;
						case 1:
							EnemyInfo[ nIndex ].nActionCount = 63;
							EnemyInfo[ nIndex ].nXBak = EnemyInfo[ nIndex ].nX;
							EnemyInfo[ nIndex ].nYBak = EnemyInfo[ nIndex ].nY;
							EnemyInfo[ nIndex ].nStat = 1;
							break;
						case 2:
							if ( nFireStat == 0 ) {
								EnemyInfo[ nIndex ].nActionCount = 2;
								EnemyInfo[ nIndex ].nStat = 2;
							} else {
								EnemyInfo[ nIndex ].nActionCount = rand() % 4;
								EnemyInfo[ nIndex ].nStat = 0;
							}
							break;
					}
				}
			}
		} else if ( EnemyInfo[ nIndex ].nStat == 1 ) {
			/* 空を飛ぶ */
			if ( EnemyInfo[ nIndex ].nAnimeCount < 0 ) {
				int nTemp;
				EnemyInfo[ nIndex ].nAnimeCount = 3;
				EnemyInfo[ nIndex ].nDrawCount++;
				if ( EnemyInfo[ nIndex ].nDrawCount > 3 ) {
					EnemyInfo[ nIndex ].nDrawCount = 0;
				}
				nTemp = EnemyInfo[ nIndex ].nDrawCount;
				if ( nTemp > 0 ) nTemp += 2;
				if ( nTemp == 5 ) nTemp = 3;
				EnemyInfo[ nIndex ].nDrawNumber = 64 + nTemp * 4;
				EnemyInfo[ nIndex ].nDrawNumber += ( 20 * EnemyInfo[ nIndex ].nDir );
				EnemyInfo[ nIndex ].nActionFlag = 1;
			}
			EnemyInfo[ nIndex ].nX += ( -100 + 200 * EnemyInfo[ nIndex ].nDir );
			EnemyInfo[ nIndex ].nY = EnemyInfo[ nIndex ].nYBak - SinTable[ EnemyInfo[ nIndex ].nActionCount ] * 50;
			EnemyInfo[ nIndex ].nActionCount--;
			if ( EnemyInfo[ nIndex ].nActionCount < 0 ) {
					EnemyInfo[ nIndex ].nActionCount = rand() % 4;
				EnemyInfo[ nIndex ].nStat = 0;
			}
		} else if ( EnemyInfo[ nIndex ].nStat == 2 ) {
			/* 火を吐く */
			DragonFire( nIndex );
		}
		/* キャラクタ移動 */
		EnemyInfo[ nIndex ].nX += EnemyInfo[ nIndex ].nVx;
		EnemyInfo[ nIndex ].nY += EnemyInfo[ nIndex ].nVy;
		/* BG との当たり判定 */
		EnemyBgAtari( nIndex, 8 );
		/* プレイヤーとの当たり判定 */
		nTemp = EnemyInfo[ nIndex ].nX - PlayerInfo.nX;
		if ( ( nTemp < 2400 ) && ( nTemp > -4800 ) ) {
			nTemp = EnemyInfo[ nIndex ].nY - PlayerInfo.nY;
			if ( ( nTemp < 3200 ) && ( nTemp > -4800 ) ) {
				/* プレイヤーにダメージ */
				if ( PlayerInfo.nZombieCount == 0 ) {
					Damage( EnemyInfo[ nIndex ].nDir );
				}
			}
		}
		/* 4 分割された各パーツの制御 */
		for ( i=1; i<4; i++ ) {
			EnemyInfo[ i ].nX = EnemyInfo[ 0 ].nX + 3200 * ( i & 1 );
			EnemyInfo[ i ].nY = EnemyInfo[ 0 ].nY + 3200 * ( ( i >> 1 ) & 1 );
			EnemyInfo[ i ].nDrawNumber = EnemyInfo[ 0 ].nDrawNumber + i;
			EnemyInfo[ i ].nActionFlag = EnemyInfo[ 0 ].nActionFlag;
		}
	}
}

/*============================================================
	グリーンドラゴンの行動
--------------------------------------------------------------
In  : nIndex = 索引番号 (0〜3)
Out : なし
============================================================*/
void Dragon2( int nIndex )
{
	if ( nIndex == 0 ) {
		int nTemp;
		int i;
		/* アニメーションカウンタ */
		EnemyInfo[ nIndex ].nAnimeCount--;
		if ( EnemyInfo[ nIndex ].nStat == 0 ) {
			/* 止まっている */
			if ( EnemyInfo[ nIndex ].nAnimeCount < 0 ) {
				int nTemp;
				EnemyInfo[ nIndex ].nAnimeCount = 3;
				if ( EnemyInfo[ nIndex ].nX > PlayerInfo.nX ) {
					EnemyInfo[ nIndex ].nDir = 0;
				} else {
					EnemyInfo[ nIndex ].nDir = 1;
				}
				EnemyInfo[ nIndex ].nDrawCount++;
				EnemyInfo[ nIndex ].nDrawCount &= 3;
				nTemp = EnemyInfo[ nIndex ].nDrawCount;
				if ( nTemp > 0 ) nTemp += 2;
				if ( nTemp == 5 ) nTemp = 3;
				EnemyInfo[ nIndex ].nDrawNumber = 64 + nTemp * 4;
				EnemyInfo[ nIndex ].nDrawNumber += ( 20 * EnemyInfo[ nIndex ].nDir );
				EnemyInfo[ 0 ].nActionFlag = 1;
				EnemyInfo[ nIndex ].nActionCount--;
				if ( EnemyInfo[ nIndex ].nActionCount < 0 ) {
					int nRand;
					nRand = rand() % 3;
					EnemyInfo[ nIndex ].nAnimeCount = 0;
					EnemyInfo[ nIndex ].nDrawCount = 0;
					switch( nRand ) {
						case 0:
							EnemyInfo[ nIndex ].nActionCount = rand() % 4;
							EnemyInfo[ nIndex ].nStat = 0;
							break;
						case 1:
							EnemyInfo[ nIndex ].nActionCount = 63;
							EnemyInfo[ nIndex ].nXBak = EnemyInfo[ nIndex ].nX;
							EnemyInfo[ nIndex ].nYBak = EnemyInfo[ nIndex ].nY;
							EnemyInfo[ nIndex ].nStat = 1;
							break;
						case 2:
							if ( nFireStat == 0 ) {
								EnemyInfo[ nIndex ].nActionCount = 2;
								EnemyInfo[ nIndex ].nStat = 2;
							} else {
								EnemyInfo[ nIndex ].nActionCount = rand() % 4;
								EnemyInfo[ nIndex ].nStat = 0;
							}
							break;
					}
				}
			}
		} else if ( EnemyInfo[ nIndex ].nStat == 1 ) {
			/* 空を飛ぶ */
			if ( EnemyInfo[ nIndex ].nAnimeCount < 0 ) {
				int nTemp;
				EnemyInfo[ nIndex ].nAnimeCount = 3;
				EnemyInfo[ nIndex ].nDrawCount++;
				if ( EnemyInfo[ nIndex ].nDrawCount > 3 ) {
					EnemyInfo[ nIndex ].nDrawCount = 0;
				}
				nTemp = EnemyInfo[ nIndex ].nDrawCount;
				if ( nTemp > 0 ) nTemp += 2;
				if ( nTemp == 5 ) nTemp = 3;
				EnemyInfo[ nIndex ].nDrawNumber = 64 + nTemp * 4;
				EnemyInfo[ nIndex ].nDrawNumber += ( 20 * EnemyInfo[ nIndex ].nDir );
				EnemyInfo[ nIndex ].nActionFlag = 1;
			}
			EnemyInfo[ nIndex ].nX += ( -300 + 600 * EnemyInfo[ nIndex ].nDir );
			EnemyInfo[ nIndex ].nY = EnemyInfo[ nIndex ].nYBak - SinTable[ EnemyInfo[ nIndex ].nActionCount ] * 70;
			EnemyInfo[ nIndex ].nActionCount--;
			if ( EnemyInfo[ nIndex ].nActionCount < 0 ) {
					EnemyInfo[ nIndex ].nActionCount = rand() % 4;
				EnemyInfo[ nIndex ].nStat = 0;
			}
			if ( EnemyInfo[ nIndex ].nActionCount < 8 ) {
				if ( rand() < 4000 ) {
					if ( nFireStat == 0 ) {
							if ( EnemyInfo[ nIndex ].nX > PlayerInfo.nX ) {
								EnemyInfo[ nIndex ].nDir = 0;
							} else {
								EnemyInfo[ nIndex ].nDir = 1;
							}
						EnemyInfo[ nIndex ].nActionCount = 2;
						EnemyInfo[ nIndex ].nStat = 2;
						EnemyInfo[ nIndex ].nJump = 0;
					}
				}
			}
		} else if ( EnemyInfo[ nIndex ].nStat == 2 ) {
			/* 火を吐く */
			DragonFire( nIndex );
		}
		/* キャラクタ移動 */
		EnemyInfo[ nIndex ].nX += EnemyInfo[ nIndex ].nVx;
		EnemyInfo[ nIndex ].nY += EnemyInfo[ nIndex ].nVy;
		/* BG との当たり判定 */
		EnemyBgAtari( nIndex, 8 );
		/* プレイヤーとの当たり判定 */
		nTemp = EnemyInfo[ nIndex ].nX - PlayerInfo.nX;
		if ( ( nTemp < 2400 ) && ( nTemp > -4800 ) ) {
			nTemp = EnemyInfo[ nIndex ].nY - PlayerInfo.nY;
			if ( ( nTemp < 3200 ) && ( nTemp > -4800 ) ) {
				/* プレイヤーにダメージ */
				if ( PlayerInfo.nZombieCount == 0 ) {
					Damage( EnemyInfo[ nIndex ].nDir );
				}
			}
		}
		/* 4 分割された各パーツの制御 */
		for ( i=1; i<4; i++ ) {
			EnemyInfo[ i ].nX = EnemyInfo[ 0 ].nX + 3200 * ( i & 1 );
			EnemyInfo[ i ].nY = EnemyInfo[ 0 ].nY + 3200 * ( ( i >> 1 ) & 1 );
			EnemyInfo[ i ].nDrawNumber = EnemyInfo[ 0 ].nDrawNumber + i;
			EnemyInfo[ i ].nActionFlag = EnemyInfo[ 0 ].nActionFlag;
		}
	}
}

/*============================================================
	ドラゴンの攻撃
--------------------------------------------------------------
In  : nIndex = 索引番号 (0〜3)
Out : なし
============================================================*/
void DragonFire( int nIndex )
{
	static int nAnimeTbl[] = { 1, 2, 0 };
	int nTemp;
	if ( EnemyInfo[ nIndex ].nAnimeCount < 0 ) {
		EnemyInfo[ nIndex ].nAnimeCount = 12;
		nTemp = EnemyInfo[ nIndex ].nDrawCount;
		nTemp = nAnimeTbl[ nTemp ];
		if ( nTemp == 2 ) {
			/* 炎発射 */
			if ( EnemyInfo[ nIndex ].nDir == 0 ) {
				SetFire( EnemyInfo[ nIndex ].nX - 900, EnemyInfo[ nIndex ].nY + 1000, EnemyInfo[ nIndex ].nDir );
			} else {
				SetFire( EnemyInfo[ nIndex ].nX + 4000, EnemyInfo[ nIndex ].nY + 1000, EnemyInfo[ nIndex ].nDir );
			}
		}
		EnemyInfo[ nIndex ].nDrawNumber = 64 + nTemp * 4;
		EnemyInfo[ nIndex ].nDrawNumber += ( 20 * EnemyInfo[ nIndex ].nDir );
		EnemyInfo[ nIndex ].nActionFlag = 1;
		EnemyInfo[ nIndex ].nDrawCount++;
		EnemyInfo[ nIndex ].nActionCount--;
		if ( EnemyInfo[ nIndex ].nActionCount < 0 ) {
			EnemyInfo[ nIndex ].nActionCount = rand() % 4;
			EnemyInfo[ nIndex ].nStat = 0;
		}
	}
}

/*============================================================
	敵が剣で攻撃する
--------------------------------------------------------------
In  : nIndex = 索引番号 (0〜3)
    : nUpDown = (0=上段攻撃, 1=下段攻撃)
Out : なし
============================================================*/
void AttackToPlayer( int nIndex, int nUpDown )
{
	int nAttackX1;
	int nAttackX2;
	int nAttackY1;
	int nAttackY2;
	int nPlayerStat;
	if ( EnemyInfo[ nIndex ].nDir == 0 ) {
		nAttackX1 = EnemyInfo[ nIndex ].nX - 1600;
	} else {
		nAttackX1 = EnemyInfo[ nIndex ].nX + 3200;
	}
	nAttackY1 = EnemyInfo[ nIndex ].nY + nUpDown * 1600;
	nAttackX2 = nAttackX1 + 1500;
	nAttackY2 = nAttackY1 + 1500;
	nPlayerStat = 0;
	/* プレイヤーに攻撃 */
	if ( ( nAttackX1 <= ( PlayerInfo.nX + 2300 ) ) &&
	     ( nAttackX2 >= ( PlayerInfo.nX ) ) ) {
		if ( ( nAttackY1 <= ( PlayerInfo.nY + 3100 ) ) &&
		     ( nAttackY2 >= ( PlayerInfo.nY ) ) ) {
			if ( EnemyInfo[ nIndex ].nDir == PlayerInfo.nDir ) {
				/* 後ろからの攻撃の場合プレイヤーにダメージ */
				if ( PlayerInfo.nZombieCount == 0 ) {
					Damage( EnemyInfo[ nIndex ].nDir );
				}
			} else {
				/* 前からの攻撃の場合 */
				if ( PlayerInfo.nAttack == 1 ) {
					if ( ( PlayerInfo.nAnimeCount > 9 ) && ( PlayerInfo.nAnimeCount < 20 ) ) {
						/* 自分が剣を振りきっている場合は無条件でダメージを食らう */
						if ( PlayerInfo.nZombieCount == 0 ) {
							Damage( EnemyInfo[ nIndex ].nDir );
						}
					} else {
						/* プレイヤーが攻撃中でも楯が有効な場合は防御する */
						if ( PlayerInfo.nMove == 2 ) {
							/* しゃがんでいる */
							nPlayerStat = 2;
						} else {
							/* 立っている */
							nPlayerStat = 1;
						}
					}
				} else {
					if ( PlayerInfo.nJump != 0 ) {
						if ( PlayerInfo.nVy < 0 ) {
							/* シャンプ上昇中、しゃがんでいる */
							nPlayerStat = 2;
						} else {
							/* ジャンプ下降中、立っている */
							nPlayerStat = 1;
						}
					} else {
						if ( PlayerInfo.nMove == 2 ) {
							/* しゃがんでいる */
							nPlayerStat = 2;
						} else {
							/* 立っている */
							nPlayerStat = 1;
						}
					}
				}
				if ( nPlayerStat != 0 ) {
					/* 自分の状態によっては防御する */
					if ( nPlayerStat == 1 ) {
						/* 立っている */
						if ( nAttackY1 > ( PlayerInfo.nY + 1500 ) ) {
							/* 相手が下段を攻撃した */
							if ( PlayerInfo.nZombieCount == 0 ) {
								Damage( EnemyInfo[ nIndex ].nDir );
							}
						} else {
							/* 防御した */
							wsSndPlaySe( 2 );
						}
					} else {
						/* しゃがんでいる */
						if ( nAttackY1 < ( PlayerInfo.nY + 1600 ) ) {
							/* 相手が上段を攻撃した */
							if ( PlayerInfo.nZombieCount == 0 ) {
								Damage( EnemyInfo[ nIndex ].nDir );
							}
						} else {
							/* 防御した */
							wsSndPlaySe( 2 );
						}
					}
				}
			}
		}
	}
}

/*============================================================
	キャラクタを描画する
--------------------------------------------------------------
In  : PlayerInfo = プレイヤー情報の格納アドレス
Out : なし
============================================================*/
void DrawObject( void )
{
	int nSp;
	long x, y;
	int i, j;
	/* ==================== プレイヤーキャラクタ描画 */
	if ( PlayerInfo.nZombieCount > 0 ) {
		PlayerInfo.nZombieCount--;
	}
	x = PlayerInfo.nX / 100;
	y = PlayerInfo.nY / 100;
	if ( ( ( PlayerInfo.nZombieCount >> 1 ) & 1 ) ) {
		wsSpSetObject( 1, 18, PLAYER_SPNUMBER, PLAYER_SPDEFINE, 0, x, y );
	} else {
		if ( nIventMsg >= IV_MSG_DAMAGE ) {
			if ( PlayerInfo.nDir == 1 ) {
				/* 左向き */
				wsSpSetObject( 1, 3, PLAYER_SPNUMBER, PLAYER_SPDEFINE, 0, x, y );
			} else {
				/* 右向き */
				wsSpSetObject( 1, 6, PLAYER_SPNUMBER, PLAYER_SPDEFINE, 0, x, y );
			}
		} else {
			if ( PlayerInfo.nAttack == 1 ) {
				/* 攻撃中 */
				nSp = PlayerInfo.nAnimeCount;
				if ( nSp == 8 ) {
					/* 剣を振った */
					wsSndPlaySe( 4 );
				};
				if ( nSp < 7 ) {
					nSp = 0;
				} else if ( nSp < 14 ) {
					nSp = 1;
				} else {
					nSp = 0;
				}
				if ( PlayerInfo.nMove == 2 ) {
					/* しゃがんでいる */
					nSp += 4;
				}
				if ( PlayerInfo.nDir == 0 ) {
					wsSpSetObject( 1, 10 + nSp, PLAYER_SPNUMBER, PLAYER_SPDEFINE, 0, x, y );
				} else {
					wsSpSetObject( 1, 12 + nSp, PLAYER_SPNUMBER, PLAYER_SPDEFINE, 0, x, y );
				}
				PlayerInfo.nAnimeCount++;
				if ( PlayerInfo.nAnimeCount > 28 ) {
					PlayerInfo.nAnimeCount = 0;
					PlayerInfo.nAttack = 0;
				}
			} else {
				if ( PlayerInfo.nJump == 1 ) {
					/* ジャンプ中 */
					if ( PlayerInfo.nDir == 0 ) {
					if ( PlayerInfo.nVy < 0 ) {
							wsSpSetObject( 1, 8, PLAYER_SPNUMBER, PLAYER_SPDEFINE, 0, x, y );
						} else {
							wsSpSetObject( 1, 3, PLAYER_SPNUMBER, PLAYER_SPDEFINE, 0, x, y );
						}
					} else {
						if ( PlayerInfo.nVy < 0 ) {
							wsSpSetObject( 1, 9, PLAYER_SPNUMBER, PLAYER_SPDEFINE, 0, x, y );
						} else {
							wsSpSetObject( 1, 6, PLAYER_SPNUMBER, PLAYER_SPDEFINE, 0, x, y );
						}
					}
				} else {
					switch( PlayerInfo.nMove ) {
						case 0:
							/* 移動していない */
							if ( PlayerInfo.nJump == 0 ) {
								/* 立っている */
								if ( PlayerInfo.nDir == 0 ) {
									wsSpSetObject( 1, 0, PLAYER_SPNUMBER, PLAYER_SPDEFINE, 0, x, y );
								} else {
									wsSpSetObject( 1, 1, PLAYER_SPNUMBER, PLAYER_SPDEFINE, 0, x, y );
								}
								PlayerInfo.nAnimeCount = 0;
							}
							break;
						case 1:
							/* 移動中 */
							if ( PlayerInfo.nJump == 0 ) {
								/* 歩く */
								nSp = PlayerInfo.nAnimeCount / 15;
								if ( nSp > 2 ) nSp = 1;
								if ( PlayerInfo.nDir == 0 ) {
									wsSpSetObject( 1, 2 + nSp, PLAYER_SPNUMBER, PLAYER_SPDEFINE, 0, x, y );
								} else {
									wsSpSetObject( 1, 5 + nSp, PLAYER_SPNUMBER, PLAYER_SPDEFINE, 0, x, y );
								}
								PlayerInfo.nAnimeCount++;
								if ( PlayerInfo.nAnimeCount > 59 ) {
									PlayerInfo.nAnimeCount = 0;
								}
							}
							break;
						case 2:
							/* しゃがむ */
							if ( PlayerInfo.nJump == 0 ) {
								/* しゃがむ */
								if ( PlayerInfo.nDir == 0 ) {
									wsSpSetObject( 1, 8, PLAYER_SPNUMBER, PLAYER_SPDEFINE, 0, x, y );
								} else {
									wsSpSetObject( 1, 9, PLAYER_SPNUMBER, PLAYER_SPDEFINE, 0, x, y );
								}
							}
							break;
					}
				}
			}
		}
	}
	/* 敵キャラクタ描画 */
	if ( EnemyInfo[ 0 ].nType >= 100 ) {
		if ( EnemyInfo[ 0 ].nActionFlag == 1 ) {
			for( i=1; i<4; i++ ) {
				EnemyInfo[ i ].nActionFlag = 1;
			}
		}
	}
	for( i=0; i<4; i++ ) {
		int nTemp;
		int nPalet;
		x = EnemyInfo[ i ].nX / 100;
		y = EnemyInfo[ i ].nY / 100;
		if ( EnemyInfo[ i ].nType == 0 ) {
			/* 敵が存在しない */
			continue;
		}
		nTemp = 18 * i;
		if ( EnemyInfo[ i ].nActionFlag == 1 ) {
			nPalet = 5 + ( i >> 1 );
			if ( ( x > -32 ) && ( x < 224 ) ) {
				/* 敵表示 */
				wsSpSetObject( 2, EnemyInfo[ i ].nDrawNumber, ENEMY_SPNUMBER + nTemp, ENEMY_SPDEFINE + nTemp, nPalet, x, y );
				EnemyInfo[ i ].nActionFlag = 0;
			}
		} else {
			if ( ( x > -32 ) && ( x < 224 ) ) {
				/* 敵移動 */
				nPalet = 5 + ( i >> 1 );
				wsSpMoveObject( 2, EnemyInfo[ i ].nDrawNumber, ENEMY_SPNUMBER + nTemp, x, y );
			} else {
				/* 敵消去 */
				for ( j=0; j<18; j++ ) {
					sprite_set_location( ENEMY_SPNUMBER + i * 18 + j, 224, 144 );
				}
			}
		}
	}
}

/*============================================================
	イベントオブジェクトファイルの設定
--------------------------------------------------------------
In  : lpPath = イベントオブジェクトのファイルネーム
Out : なし
============================================================*/
void SetIventFile( char far *lpPath )
{
	lpIvObjectAddress = mmap( lpPath );
}

/*============================================================
	イベント初期化
--------------------------------------------------------------
In  : nInitNumber = 初期化するイベント番号
Out : なし
============================================================*/
void InitIvent( int nInitNumber )
{
	WORD far *lpInitIndex;
	WORD far *lpInitIvent;
	char far *lpPath;
	lpInitIndex = (WORD far *)( lpIvObjectAddress + 6 );
	lpInitIvent = (WORD far *)( (DWORD)lpIvObjectAddress + (DWORD)lpInitIndex[ nInitNumber ] );
	lpPath = (char far *)( lpInitIvent ) + 34;
	wsBgInit( COLOR_MODE );
	nObjectNumber = lpInitIvent[ 0 ];
	nSc1Color = lpInitIvent[ 8 ];
	nSc2Color = lpInitIvent[ 10 ];
	nAtari1 = lpInitIvent[ 11 ];
	nAtari2 = lpInitIvent[ 12 ];
	nLeft = lpInitIvent[ 13 ];
	nRight = lpInitIvent[ 14 ];
	nTop = lpInitIvent[ 15 ];
	nBottom = lpInitIvent[ 16 ];
	wsBgSetObjectFile( nObjectNumber, lpPath );
	wsBgSetChr( nObjectNumber, lpInitIvent[ 1 ], lpInitIvent[ 2 ], lpInitIvent[ 3 ] );
	if ( lpInitIvent[ 4 ] != -1 ) {
		wsBgSetChr( nObjectNumber, lpInitIvent[ 4 ], lpInitIvent[ 5 ], lpInitIvent[ 6 ] );
	}
	wsBgSetPalet( nObjectNumber, lpInitIvent[ 7 ], nSc1Color );
	wsBgSetPalet( nObjectNumber, lpInitIvent[ 9 ], nSc2Color );
	wsPalSetLuminosityDirect( 0 );
}

/*============================================================
	イベント発生
--------------------------------------------------------------
In  : nIventNumber = 発生するイベント番号
Out : なし
============================================================*/
void SetIvent( int nIventNumber )
{
	WORD far *lpIvIndex;
	WORD far *lpIvent;
	int nMapNumber;
	int i;
	lpIvIndex = (WORD far *)( lpIvObjectAddress + 6 + 128 * 2 );
	lpIvent = (WORD far *)( (DWORD)lpIvObjectAddress + (DWORD)lpIvIndex[ nIventNumber ] );
	/* イベント初期化が済んでいる場合は初期化しなくてよい */
	InitIvent( lpIvent[ 0 ] );
	/* SCREEN2 設定 */
	wsBgInitScroll( SCREEN2, nObjectNumber, lpIvent[ 1 ], lpIvent[ 2 ], lpIvent[ 3 ], nSc2Color );
	/* SCREEN1 設定*/
	nMapNumber = lpIvent[ 10 ];
	/* 雨を消す */
	nRainFlag = 0;
	for( i=0; i<24; i++ ) {
		sprite_set_location( 14 + i, 224, 144 );
	}
	/* 敵を消す */
	for( i=0; i<4; i++ ) {
		SetEnemy( 0, 0, 0, i );
	}
	/* アイテムを消す */
	nItemType = 0;
	/* 炎を消す */
	nFireStat = 0;
	/* 敵が出現する */
	nEnemyMuteFlag = 0;
	if ( nMapNumber == -2 ) {
		/* 特殊処理(時間がない。本来ならば IVENT ファイルに組み込むべき物である。) */
		/* 城の雲のラスター表示 */
		wsBgSetVram( SCREEN1, nObjectNumber, 6, 0, 0, 0, nSc1Color, SETVRAM_RL_REVERSE );
		wsBgSetVram( SCREEN1, nObjectNumber, 7, 0, 14, 0, nSc1Color, SETVRAM_NORMAL );
		wsBgSetEffect( SCREEN1, lpIvent[ 16 ], lpIvent[ 17 ], lpIvent[ 18 ], lpIvent[ 19 ] );
		wsBgSetBgSpeed( lpIvent[ 12 ] );
		wsBgSetBgAutoScroll( lpIvent[ 13 ], lpIvent[ 14 ], lpIvent[ 15 ] );
		if ( ( nIventNumber == 20 ) || ( nIventNumber == 21 ) ) {
			/* 城壁の特殊処理(雨が降る。本来ならば IVENT ファイルに組み込むべき物である。) */
			nRainFlag = 1;
			InitRain();
		}
	} else if ( nMapNumber != -1 ) {
		wsBgSetVram( SCREEN1, nObjectNumber, nMapNumber, lpIvent[ 11 ], 0, 0, nSc1Color, SETVRAM_NORMAL );
		wsBgSetEffect( SCREEN1, lpIvent[ 16 ], lpIvent[ 17 ], lpIvent[ 18 ], lpIvent[ 19 ] );
		wsBgSetBgSpeed( lpIvent[ 12 ] );
		wsBgSetBgAutoScroll( lpIvent[ 13 ], lpIvent[ 14 ], lpIvent[ 15 ] );
	}
	/* その他変数初期化 */
	PlayerInfo.nX = lpIvent[ 4 ];
	PlayerInfo.nY = lpIvent[ 5 ];
	nIventMsg = 0;
	if ( lpIvent[ 6 ] == IV_WALK_RIGHT ) {
		nIventMsg = IV_MSG_WALK_RIGHT;
	} else if ( lpIvent[ 6 ] == IV_WALK_LEFT ) {
		nIventMsg = IV_MSG_WALK_LEFT;
	}
	nIventCount = lpIvent[ 7 ];
	nIvent = nIventNumber;
	nLeftIvent = lpIvent[ 8 ];
	nRightIvent = lpIvent[ 9 ];
	/* とりあえず初期化 */
	for ( i=0; i<4; i++ ) {
		memset( &EnemyInfo[ i ], 0, sizeof( ENEMYINFO ) );
	}
	/* 敵初期化 */
	nEnemyMax[ 0 ] = lpIvent[ 20 ];
	nEnemyMax[ 1 ] = lpIvent[ 24 ];
	nEnemyType[ 0 ] = lpIvent[ 21 + rand() % 3 ];
	nEnemyType[ 1 ] = lpIvent[ 25 + rand() % 3 ];
	if ( nEnemyType[ 0 ] == 101 ) {
		/* STAGE 1 ドラゴン */
		wsSpSetPalet( 2, 8, 5 );
		wsSpSetPalet( 2, 8, 6 );
	} else if ( nEnemyType[ 0 ] == 102 ) {
		/* STAGE 2 ドラゴン */
		wsSpSetPalet( 2, 9, 5 );
		wsSpSetPalet( 2, 9, 6 );
	} else {
		wsSpSetPalet( 2, nEnemyType[ 0 ] - 1, 5 );
		if ( nRainFlag != 1 ) {
			/* 雨が降っている時は敵 2 は出現しない */
			wsSpSetPalet( 2, nEnemyType[ 1 ] - 1, 6 );
		}
	}
	if ( rand() < 8192 ) {
		nEnemyMax[ 1 ] = 0;
		nEnemyType[ 1 ] = 0;
	}
	wsPalSetLuminosityDirect( 0 );
}

/*============================================================
	イベントの推移
--------------------------------------------------------------
In  : nMessage = 発生したイベントの種類
Out : イベントメッセージ
============================================================*/
void ExecIventMsg( int nMessage )
{
	WORD far *lpIvIndex;
	WORD far *lpIvent;
	lpIvIndex = (WORD far *)( lpIvObjectAddress + 6 + 128 * 2 );
	lpIvent = (WORD far *)( (DWORD)lpIvObjectAddress + (DWORD)lpIvIndex[ nIvent ] );
	switch( nMessage ) {
		case IV_MSG_LEFT:
			/* 左に消えた */
			if ( lpIvent[ 8 ] != -1 ) {
				SetIvent( lpIvent[ 8 ] );
			}
			break;
		case IV_MSG_RIGHT:
			/* 右に消えた */
			if ( lpIvent[ 9 ] != -1 ) {
				SetIvent( lpIvent[ 9 ] );
			}
			break;
		case IV_MSG_STAGECLEAR:
			/* ステージクリア */
			StageClear();
			nStage++;
			if ( nStage == 1 ) {
				nIvent = 0;
				nMsgType = 1;
				nMsgCount = 200;
			} else if ( nStage == 2 ) {
				nIvent = 8;
				nMsgType = 2;
				nMsgCount = 200;
			} else if ( nStage == 3 ) {
				/* ゲームクリア (エンディング後 STAGE 1 に戻る ) */
				GameClear();
				nStage = 1;
				nIvent = 0;
				nMsgType = 1;
				nMsgCount = 200;
			}
			SetIvent( nIvent );
			break;
	}
}

/* デバッグ用
{
	static char str[100];
	wsBgInit( COLOR_MODE_GRAYSCALE );
	display_control( DCM_SCR2 );
	lcd_set_sleep( 1 );
	text_screen_init();
	text_set_screen( 1 );
	sprintf( str, "Val = %d, %d, %d", a, b, c );
	text_put_string( 0, 0, str );
	key_wait();
	display_control( DCM_SCR1 | DCM_SCR2 | DCM_SPR );
	wwc_set_color_mode( COLOR_MODE_16COLOR );
}
*/
