/*-------------------------------------------------------------

	target.txt
	ターゲットシステムオーバービューおよび
	game/target.c内関数のリファレンス

	2000/03/28 M.Sonoyama
	$Id: target.txt,v 1.1.1.3 2002/11/19 11:41:44 Yoshizawa1 Exp $
	
	Metal Gear Solid2 Project for PlayStation2

--------------------------------------------------------------*/	

■ターゲットシステム概要
	ターゲットシステムは、キャラクタ同士の攻撃判定を
	制御するシステムです。
	具体的には、攻撃ターゲットと防御ターゲットの接触判定を行い、
	接触していた場合に、接触情報をそれぞれのTARGET構造体にセットして、
	あらかじめ設定されていたコールバック関数をコールするという動作をします。

■ターゲット構造体
	game/g_struct.h内に定義

■ターゲット処理クラス
	ターゲットは、その処理クラスが一致するもの同士でないと
	接触しないようになっています。
	処理クラスは以下の通りです。

	TARGET_POWER	： ダメージ系攻撃クラス
	TARGET_CAPTURE	： つかみ系攻撃クラス
	TARGET_SEEK		： 視線系攻撃クラス（ダメージがない）
	TARGET_TOUCH	： 接触系攻撃クラス

	（以下、未実装）
	TARGET_PUSH	： 押し押され系攻撃クラス
	TARGET_STICK	： くっつき系攻撃クラス

■ターゲット属性クラス
	ターゲットは様々な属性を持たせることができます。
	攻撃、防御するキャラに応じて、正しくクラスを設定する
	必要があります。
	属性クラスは以下の通りです。

	以下の２つは必ずどちらかを設定。
	TARGET_OFFENSE	： 攻撃側ターゲット
	TARGET_DEFENSE	： 防御側ターゲット

	以下は攻撃側専用
	TARGET_ONLINE		： 直線ターゲット。箱ではなく直線的に
						   攻撃する。弾など。
	TARGET_GET_NORMAL	： 直線ターゲット専用。
						   当たったターゲットの面の法線を求める。
	TARGET_DIE		： 一発死に攻撃。プレイヤーがレーションを装備
						   していても使えない。踏み潰しなど。
	TARGET_ONLINE_MIN	： 直線ターゲット専用。複数のターゲットに当たった場合、
						   一番近いもののみに当たったことにする。
	TARGET_CHECK_ONE	： 箱ターゲット（デフォルト）専用。
						   どれか一つに当たったらチェックを終了する。
	TARGET_CHILD_SKIP	： 子ターゲットチェックを行わない。	
						   TARGET_CHILDクラス設定時のみの仕様。
	TARGET_DIRECT_ATTACK： 後述のGM_TargetSetDirectAttack内で立てられる。
	TARGET_NAME_IS_SE	： taget->nameには、ヒットしたときに鳴らして欲しいＳＥ番号が
						   入っている。（自動でなるわけではない。）

	以下は防御側専用
	TARGET_DOWN			： このターゲットはダウン状態にある。
	TARGET_DEAD			： このターゲットは死に状態にある。
	TARGET_LOCKON		： このターゲットはロックオンされる。
	TARGET_CHILD_ALWAYS	： 攻撃側のクラスに関わらず、子ターゲットまで
						   チェックさせる。
	TARGET_SKIP			： チェックしない。
	TARGET_CALL_CALLBACK_THROUGH_HIT ：	THROUGH属性の攻撃がヒットしたときでも、
										防御側のコールバックをコールする。

	以下、攻撃・防御兼用
	TARGET_THROUGH		： このターゲットに当たっても攻撃側は
						   当たったと思わない。具体的には、
		  				   攻撃側に設定されたコールバックは呼ばれない。
						   防御側に設定されたコールバックのみ呼ばれる。

	TARGET_HAS_NAME		： 名前ありターゲット、防御側と攻撃側がこのクラスで
						   かつ、同じ名前を持つときには接触判定しない。
	TARGET_HIT_SAMENAME	： TARGET_HAS_NAMEを持つ攻撃、防御ターゲットが接触したとき、
						   その両方にこのフラグが立っていると、その名前が異なるときは
						   接触判定を無効とする。
	TARGET_ROTATE		： 箱ターゲット専用。
						   回転を考慮するターゲット。
						   位置の更新には、GM_MoveTarget2()を使用すること

■ターゲットサイド
	サイドは、そのターゲットの属する陣営（？）を表します。
	サイドの「同じ」ターゲット同士でないと当たりません。
	サイドは以下の通りです。

	PLAYER_SIDE	： プレイヤー陣営
	ENEMY_SIDE	： 敵陣営
	BOTH_SIDE	： 陣営なし。上記どちらの攻撃も当たり、
				   どちらにも攻撃する。

■ターゲットの使用方法
	ターゲットはパラメータ設定をした後、
	ターゲットシステムに登録する、という使い方をします。
	攻撃側と防御側にわけて、使用例をあげておきます。

	◆攻撃側
	  攻撃ターゲットの基本的な使用方法は以下の通りです。
	  （個々の関数については後述。）
	  １）箱ターゲット

	     ○初期設定
		FVECTOR			size, offset, pos, force ;
		TARGET			target ;
		POWER_TARGET	power ;
		int				map, side ;
		long64			weapon ;
		int				vital, damage, faint ;

		size = （箱のサイズ）	
		offset = （target->centerからのオフセット）
		map = （現在いるマップ）
		side = （サイド）
		GM_SetTarget( &target, TARGET_OFFENSE, map, side,
				      &size, &offset ) ;
		//武器設定、この攻撃はどの武器なのか？
		//game/g_define.hに定義あり。
		weapon = （武器）
		GM_SetTargetWeaponType( &target, weapon ) ;

		vital = （その攻撃の耐久力） 
		damage = （その攻撃が与えるダメージ値）
		faint = （その攻撃が与える気絶値）
		force = （その攻撃が与える力積）
		GM_SetPowerTarget( &target, &power, POWER_ONCE, 
						   vital, faint, damage, &force ) ;
		//POWER_ONCEについては後述。
		
		//コールバック登録。引数を一つだけ、( void * )型で登録できる。
		//workを登録しておくのが普通。
		GM_SetTargetCallBack( &target, AttackCallbackFunction, 
						      ( void * )param ) ;

	     ○毎フレームの処理
		pos = （ターゲット位置）
		GM_MoveTarget( &target, &pos ) ;
		//pos + offsetの位置を中心にしたsizeの箱で
		//攻撃する。

		//ターゲット登録。
		//攻撃ターゲットは毎フレーム登録し直す。
		GM_PutTarget( &target ) ;

	   ２）直線ターゲット
	       少しだけ違います。
	       ○初期設定の違い
			GM_SetTarget( &target, TARGET_OFFENSE | TARGET_ONLINE, ・・・) ;
		
           ○毎フレームの処理の違い
			FVECTOR	from, to ;

			GM_MoveOnlineTarget( &target, &from, &to ) ;
	        GM_PutTarget( &target ) ;

	◆防御側
	  防御側は、箱ターゲットのみです。			
	       ○初期設定
			size = （箱のサイズ）	
			offset = （target->centerからのオフセット）
			map = （現在いるマップ）
			side = （サイド）
			GM_SetTarget( &target, TARGET_DEFENSE, map, side,
	 				      &size, &offset ) ;

			vital = （そのキャラの耐久力） 
			GM_SetPowerTarget( &target, &power, POWER_DECREASE, 
							   vital, 0, 0, &DG_ZeroVector ) ;
			//POWER_DECREASEについては後述。
		
			//コールバック登録。引数を一つだけ、( void * )型で登録できる。
			GM_SetTargetCallBack( &target, DefenseCallbackFunction, 
							      ( void * )param ) ;		

			GM_PutTarget( &target ) ;
			//防御側は最初に一回登録すればよい。

	      ○毎フレームの処理
			pos = （ターゲット位置）
			GM_MoveTarget( &target, &pos ) ;
			//TARGET_ROTATEの場合はGM_MoveTarget2()を使用すること！！

■コールバックについて
	攻撃ターゲットが防御ターゲットに当たった時、
	それぞれに設定されたコールバック関数が呼ばれます。
	このコールバック関数は、
		CallbackFunc( TARGET *, TARGET *, void * ) ;
	という形式である必要があります。
	第１引数には攻撃ターゲットのポインタ、
	第２引数には防御ターゲットのポインタ、	
	第３引数にはそれぞれが設定した引数がはいります。

■子ターゲットについて
	防御ターゲットは子ターゲットを持つことができます。
	子ターゲットが設定されている場合、攻撃側にTARGET_CHILD属性が
	ついていれば、１段階目チェックで親ターゲットに当たっていた場合、
	続いて子ターゲットとのチェックを行います。

	子ターゲットに当たった場合には、その子ターゲットに接触情報が入り、
	その子ターゲットに設定されたコールバックが呼ばれます。
	子ターゲットに当たっていない場合には、当たったとみなされません。

	子ターゲットは優先レベルをもち、優先レベルの高い子ターゲットから
	チェックが行われます。当たった場合には、そこでチェックを終了します。
	つまり、それより優先レベルの低い子ターゲットはチェックされません。
	
	子ターゲットを持つターゲットの構造は以下のようになります。
	また、孫ターゲットを持つことは出来ません。

	parent ---------------------------+--- level[ 0 ]_children +-- child1
	(TARGET_DEFENSE | TARGET_CHILD)	  |                        |
	                                  |                        +-- child2
	                                  |                        |...
									  |
									  +--- level[ 1 ]_children +-- child3
	                                  |                        |
	                                  |                        +-- child4
	                                  |                        |...
									  |
									  +--- level[ 2 ]_children +-- child5
									  |		           |
									  ...                      ...

■接触情報
	ターゲットが当たった場合、構造体には次の情報が入ります。

	・攻撃側
		target->damaged に防御側の攻撃クラスが入る。

	・防御側
		target->damaged に攻撃側の攻撃クラスが入る。
		target->weapon_type に攻撃側の武器が入る。

■各攻撃系の説明
	◆ダメージ系攻撃クラス(TARGET_POWER)
		GM_SetPowerTargetの第３引数に、攻撃タイプを
		設定します。攻撃タイプは以下の通りです。

		POWER_ONCE 		： 一撃のみで壊れる。（弾など）
		POWER_DECREASE	： 耐久力減衰で壊れる。
						   通常キャラの防御ターゲットはこのタイプ
		POWER_CONST		： 壊れない。	
		POWER_EXPLODE	： 爆発型。力積を放射状に計算する。

■関数リファレンス

--------------------------------------------------------------------------------

	void	GM_SetTarget( TARGET *targ, int class, int map, int side,
					      FVECTOR *size, FVECTOR *offset ) ;

	＜引数＞	ターゲットへのポインタ、クラス、マップ、サイド
			サイズ、オフセット
	＜返り値＞	なし
	＜説明＞	ターゲットの初期設定を行います。
	＜注意＞	classには、TARGET_OFFENSEとTARGET_DEFENSEのいづれかを
			必ず設定。
			また、各属性クラスとTARGET_SEEKもここで必要に応じて設定。

--------------------------------------------------------------------------------

	void	GM_SetTargetWeaponType( TARGET *targ, long64 weapon_type ) ;

	＜引数＞	ターゲットへのポインタ、武器タイプ
	＜返り値＞	なし
	＜説明＞	攻撃ターゲット専用。武器タイプを設定。
	＜注意＞	武器タイプはgame/g_define.hに定義。
			武器番号と間違えないように注意。

--------------------------------------------------------------------------------

	void	GM_SetTargetCallBack( TARGET *targ, TARGET_CALLBACK func, void *param ) ;

	＜引数＞	ターゲットへのポインタ、コールバック関数、引数
	＜返り値＞	なし
	＜説明＞	ターゲットが当たった際のコールバックを設定する。
	＜注意＞	上記、■コールバックについて、を参照。
				CallBackのＢが大文字なのは許してください。

--------------------------------------------------------------------------------

	void	GM_PutTarget( TARGET *targ ) ;

	＜引数＞	ターゲットへのポインタ
	＜返り値＞	なし
	＜説明＞	ターゲットをターゲットシステムに登録する。
	＜注意＞	攻撃ターゲットは毎フレーム登録が必要。
				防御ターゲットは一回で良い。
	
--------------------------------------------------------------------------------

	void	GM_FreeTarget( TARGET *targ ) ;

	＜引数＞	ターゲットへのポインタ
	＜返り値＞	なし
	＜説明＞	ターゲットをシステム登録から削除
	＜注意＞	防御ターゲットのみ必要な処理。

--------------------------------------------------------------------------------

	void	GM_MoveTargetMap( TARGET *targ, FVECTOR *pos, int map ) ;

	＜引数＞	ターゲットへのポインタ、位置、マップ
	＜返り値＞	なし
	＜説明＞	箱型ターゲットを配置する。
	＜注意＞

--------------------------------------------------------------------------------

	void	GM_MoveTarget2Map( TARGET *targ, FMATRIX *pos, int map ) ;

	＜引数＞	ターゲットへのポインタ、位置回転マトリクス、マップ
	＜返り値＞	なし
	＜説明＞	回転あり箱型ターゲットを配置する。
	＜注意＞

--------------------------------------------------------------------------------

	void	GM_MoveTarget3Map( TARGET *targ, FMATRIX *pos, int map ) ;

	＜引数＞	ターゲットへのポインタ、位置回転マトリクス、マップ
	＜返り値＞	なし
	＜説明＞	回転なし箱型ターゲットを配置する。
	＜注意＞	マトリクスの回転情報は無視される。

--------------------------------------------------------------------------------

	void	GM_MoveOnlineTargetMap( TARGET *targ, FVECTOR *from, FVECTOR *to,
					int map ) ;

	＜引数＞	ターゲットへのポインタ、開始位置、終了位置、マップ
	＜返り値＞	なし
	＜説明＞	直線型ターゲットを配置する。
	＜注意＞	直線攻撃ターゲットのみ。

--------------------------------------------------------------------------------

	void	GM_TargetConnectChild( TARGET *targ, TARGET *children,
				       int n, int level ) ;

	＜引数＞	ターゲットへのポインタ、子ターゲット（配列）へのポインタ、
				子ターゲット数、優先レベル
	＜返り値＞	なし
	＜説明＞	子ターゲットを指定優先レベルで接続する。
	＜注意＞	classに TARGET_CHILD属性が自動的に付加される。

--------------------------------------------------------------------------------

	void	GM_TargetDisconnectChild( TARGET *targ, TARGET *children ) ;

	＜引数＞	ターゲットへのポインタ、子ターゲット（配列）へのポインタ、
	＜返り値＞	ターゲットへのポインタ、子ターゲットへのポインタ
	＜説明＞	子ターゲットの接続を切る。
	＜注意＞

--------------------------------------------------------------------------------

	void	GM_SetTargetName( TARGET *targ, int name ) ;

	＜引数＞	ターゲットへのポインタ、名前
	＜返り値＞	なし
	＜説明＞	ターゲットに名前をつける。
	＜注意＞	classに、TARGET_HAS_NAME属性が自動的に付加される。
				効果については、上記■ターゲット属性クラス、を参照

--------------------------------------------------------------------------------

	void	GM_SetTargetSize( TARGET *targ, FVECTOR *size ) ;

	＜引数＞	ターゲットへのポインタ、サイズ
	＜返り値＞	なし
	＜説明＞	ターゲットのサイズを変更する。
	＜注意＞	回転あり箱型ターゲットのサイズを変更するときは
			この関数で行う必要がある。

--------------------------------------------------------------------------------

	void	GM_SetPowerTarget( TARGET *targ, POWER_TARGET *power, int type,
							   short vital, short faint, short damage, FVECTOR *force ) ;

	＜引数＞	ターゲットへのポインタ、POWER_TARGETへのポインタ、
				攻撃タイプ、耐久力、気絶値、ダメージ値、力積
	＜返り値＞	なし
	＜説明＞	POWER_TARGETを初期化して接続する。
	＜注意＞	classに、TARGET_POWER属性が自動的に付加される。

--------------------------------------------------------------------------------

	void	GM_SetCaptureTarget( TARGET *targ, CAPTURE_TARGET *capture,
				 			     CONTROL *ctrl, OBJECT *body ) ;

	＜引数＞	ターゲットへのポインタ、CAPTURE_TARGETへのポインタ、
				CONTROLへのポインタ、OBJECTへのポインタ
	＜返り値＞	なし
	＜説明＞	CAPTURE_TARGETを初期化して接続する。
	＜注意＞	classに、TARGET_CAPTURE属性が自動的に付加される。

--------------------------------------------------------------------------------

	void	GM_DamageTarget( TARGET *off, TARGET *def ) ;

	＜引数＞	攻撃ターゲットへのポインタ、防御ターゲットへのポインタ
	＜返り値＞	なし
	＜説明＞	攻撃側の気絶値、ダメージ値、力積を、防御側に反映させる。
	＜注意＞	

--------------------------------------------------------------------------------

	void	GM_CaptureTarget( TARGET *off, TARGET *def ) ;

	＜引数＞	攻撃ターゲットへのポインタ、防御ターゲットへのポインタ
	＜返り値＞	なし
	＜説明＞	攻撃側CAPTURE_TARGETに防御側パラメータを、
				防御側CAPTURE_TARGETに攻撃側パラメータを接続する。
	＜注意＞

--------------------------------------------------------------------------------

	void	GM_ClearTargetDamage( TARGET *def ) ;

	＜引数＞	防御ターゲットへのポインタ
	＜返り値＞	なし
	＜説明＞	ダメージ系攻撃の接触情報をクリアする。
	＜注意＞	

--------------------------------------------------------------------------------

	void	GM_TargetSetSkip( TARGET *def ) ;

	＜引数＞	防御ターゲットへのポインタ
	＜返り値＞	なし
	＜説明＞	ターゲットの当たり判定を一時的に行わないようにする
	＜注意＞

--------------------------------------------------------------------------------

	void	GM_TargetResetSkip( TARGET *def ) ;

	＜引数＞	防御ターゲットへのポインタ
	＜返り値＞	なし
	＜説明＞	上の解除
	＜注意＞

--------------------------------------------------------------------------------

	void	GM_TargetGetCenter( FVECTOR *center, TARGET *target )

	＜引数＞	格納FVECTORポインタ、ターゲットへのポインタ
	＜返り値＞	なし
	＜説明＞	ターゲットの中心座標をcenterに格納する。
	＜注意＞

--------------------------------------------------------------------------------

	void	GM_TargetHitCancel( TARGET *off, TARGET *def )

	＜引数＞	攻撃ターゲットへのポインタ、防御ターゲットへのポインタ
	＜返り値＞	なし
	＜説明＞	攻撃を当たらなかったことにする。
	＜注意＞	使用する際は、防御側のコールバック関数内でコールすること。

--------------------------------------------------------------------------------

	int		GM_TargetCheckCenter2Center( TARGET *off, TARGET *def,
										 int chk_flag, int segflag, int flrflag )

	＜引数＞	攻撃ターゲットへのポインタ、防御ターゲットへのポインタ
				オンラインチェック用パラメータ
	＜返り値＞	なし	
	＜説明＞	ターゲット中心間にハザードがあれば１を返す。
	＜注意＞	

--------------------------------------------------------------------------------

	void	GM_TargetSetDirectAttack( TARGET *off, TARGET *def )

	＜引数＞	攻撃ターゲットへのポインタ、防御ターゲットへのポインタ
	＜返り値＞	なし	
	＜説明＞	直接指定で特定のターゲットに攻撃を当てる。
	＜注意＞	

--------------------------------------------------------------------------------

	void	GM_SetTargettoDynamicHazard( void *seg, TARGET *target, int type )

	＜引数＞	動的ハザードへのポインタ、ターゲットへのポインタ、ハザードタイプ
	＜返り値＞	なし	
	＜説明＞	GM_TargetHitDynamicHazardとセットで使用される。
				動的ハザードにターゲットをセットする。
	＜注意＞	
	
--------------------------------------------------------------------------------

	void	GM_TargetHitDynamicHazard( void *ptr, TARGET *off, int type )

	＜引数＞	動的ハザードへのポインタ、ターゲットへのポインタ、ハザードタイプ
	＜返り値＞	なし	
	＜説明＞	動的ハザードにターゲットがセットしてある場合、
			    攻撃ターゲットを登録して、ターゲット処理フェイズで
				コールバックを呼ばせる
	＜注意＞	攻撃処理プログラム内で、
				動的ハザードに攻撃直線が当たったときに、そのハザードと
				攻撃ターゲットを引数にしてコールしてください。
