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



	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 )



	＜引数＞	動的ハザードへのポインタ、ターゲットへのポインタ、ハザードタイプ

	＜返り値＞	なし	

	＜説明＞	動的ハザードにターゲットがセットしてある場合、

			    攻撃ターゲットを登録して、ターゲット処理フェイズで

				コールバックを呼ばせる

	＜注意＞	攻撃処理プログラム内で、

				動的ハザードに攻撃直線が当たったときに、そのハザードと

				攻撃ターゲットを引数にしてコールしてください。

