/*
 ******************************************************************************
 *              
 *      デモ制御の為のヘッダーファイル
 * 	$Id: m_demo.h,v 1.1 2003/06/06 00:15:12 tong Exp $
 ******************************************************************************
 */
#ifndef __M_DEMO_H__
#define __M_DEMO_H__
#include "m_field_make.h"
#include "m_name_table.h"
#include "m_scene.h"

#ifdef _LANGUAGE_C_PLUS_PLUS
extern "C" {
#endif

/*
 ******************************************************************************
 *	典型的な関数の型
 ******************************************************************************
 */
typedef void (*M_DEMO_PROC1)(GAME *);

/*
 ******************************************************************************
 *	デモの種類
 ******************************************************************************
 */    
#define M_DEMO_TYPE_NONE           ( 0)  /* デモなし */
#define M_DEMO_TYPE_SCROLL         ( 1)  /* ゼルダスクロール */
#define M_DEMO_TYPE_SCENEOUT       ( 2)  /* シーンをでる */
#define M_DEMO_TYPE_DOOR           ( 3)  /* ドア */
#define M_DEMO_TYPE_ITEM           ( 4)  /* アイテム使う */
#define M_DEMO_TYPE_SCROLL2        ( 5)  /* ゼルダスクロール（ちょっと優先） */
#define M_DEMO_TYPE_DOOR2          ( 6)  /* ドア（ちょっと優先） */
#define M_DEMO_TYPE_TALK           ( 7)  /* 会話 */
#define M_DEMO_TYPE_SPEAK          ( 8)  /* 強制会話 */
#define M_DEMO_TYPE_REPORT         ( 9)  /* 強制メッセージ出力 */
#define M_DEMO_TYPE_OUTDOOR        (10)  /* ドアからでてくる */
#define M_DEMO_TYPE_SCENEIN        (11)  /* シーンにはいる */
#define M_DEMO_TYPE_EVENTMSG       (12)  /* イベント告知 */
#define M_DEMO_TYPE_COOL           (13)  /* 大掛かりなデモ */
#define M_DEMO_TYPE_MAX            (14)

#if defined(__M_DEMO_C__)
#if DEBUG
const char  *demo_type_str[M_DEMO_TYPE_MAX] =
    { "NONE",
      "SCROLL",
      "SCENEOUT",
      "DOOR",
      "ITEM",
      "DOOR2",
      "TALK",
      "SPEAK",
      "MESSAGE",
      "OUTDOOR",
      "SCENEIN",
      "EVENTMSG",
      "COOL" };
#endif
#endif


/*
 ******************************************************************************
 *	状態
 ******************************************************************************
 */
#define M_DEMO_STATUS_WAIT         (0)
#define M_DEMO_STATUS_READY        (1)
#define M_DEMO_STATUS_RUN          (2)
#define M_DEMO_STATUS_STOP         (9)

/*
 ******************************************************************************
 *	 レジスターを使ったデモ初期値
 ******************************************************************************
 */
#define M_DEMO_STANDARD_TALK_DISTANCE_DEFAULT		(55.0F)	/* 会話可能距離の標準値 */
#define M_DEMO_STANDARD_TALK_HEIGHT_DEFAULT		(60.0F)	/* 会話可能距離の標準値 */
#define M_DEMO_STANDARD_TALK_ANGLE_DEFAULT		(12530)	/* 会話可能角度の標準値 */
	    
#define M_DEMO_STANDARD_TALK_DISTANCE()	\
		(M_DEMO_STANDARD_TALK_DISTANCE_DEFAULT + (float)DEMOREG(0))
#define M_DEMO_STANDARD_TALK_HEIGHT()	\
		(M_DEMO_STANDARD_TALK_HEIGHT_DEFAULT + (float)DEMOREG(1))
#define M_DEMO_STANDARD_TALK_ANGLE()	\
		(M_DEMO_STANDARD_TALK_ANGLE_DEFAULT + (int)DEMOREG(2))
	    
/*
 ******************************************************************************
 *	デモ指令用マクロ
 ******************************************************************************
 */
/* 幾つのキャラクターが命令を持つか */	    
#define M_DEMO_ORDER_PLAYER      (0)
#define M_DEMO_ORDER_MSG         (1)
#define M_DEMO_ORDER_CAMERA      (2)
#define M_DEMO_ORDER_DEMO        (3)
#define M_DEMO_ORDER_NPC0        (4)
#define M_DEMO_ORDER_NPC1        (5)
#define M_DEMO_ORDER_NPC2        (6)
#define M_DEMO_ORDER_EFFECT      (7)
#define M_DEMO_ORDER_KANKYO      (8)
#define M_DEMO_ORDER_QUEST       (9)
#define M_DEMO_TOTAL_ORDER_KIND  (10)

/*
 ******************************************************************************
 *	向きデータ
 ******************************************************************************
 */
#define M_DEMO_DIRECT_N    (0)		/* 北   */
#define M_DEMO_DIRECT_NE   (1)		/* 北東 */
#define M_DEMO_DIRECT_E    (2)		/* 東   */
#define M_DEMO_DIRECT_SE   (3)		/* 南東 */
#define M_DEMO_DIRECT_S    (4)		/* 南   */
#define M_DEMO_DIRECT_SW   (5)		/* 南西 */
#define M_DEMO_DIRECT_W    (6)		/* 西   */
#define M_DEMO_DIRECT_NW   (7)		/* 北西 */

#if defined(__M_DEMO_C__)
#define SQRT2  (1.414213562f)

static float  direct_vector[8][2] = {
    { -1.f,  0.f }, /* 北 */  { -SQRT2,  SQRT2 }, /* 北東 */
    {  0.f,  1.f }, /* 東 */  {  SQRT2,  SQRT2 }, /* 南東 */
    {  1.f,  0.f }, /* 南 */  {  SQRT2, -SQRT2 }, /* 南西 */
    {  0.f, -1.f }, /* 西 */  { -SQRT2, -SQRT2 }, /* 北西 */
    /*   Z       X     */
};
#define DEMO_DIRECT_X  (1)
#define DEMO_DIRECT_Z  (0)
	
static short  direct_back_angle[8] = {
    (short)0x0000, (short)0xe000, (short)0xc000, (short)0xa000,
    (short)0x8000, (short)0x6000, (short)0x4000, (short)0x2000,
};
#endif  /* __M_DEMO_C__ */
	    
#define M_DEMO_DOOR_MARGIN  (20.f)
	    
/* キャラクター毎に幾つの変数を持つか */
#define M_DEMO_TOTAL_ORDER_VAL	(10)
	
typedef struct {
    unshort	data[M_DEMO_TOTAL_ORDER_VAL];
} M_DEMO_ORDER;

/* 旧データ::現在使っておりません */
typedef struct {
    ACTOR	*actor;		/* 会話要求アクター */
    int		msg;		/* メッセージ番号 */
    int		turn;		/* 会話中に振返るか？ */
    int		use_camera;	/* 会話用カメラ使うか？ */
    int		use_zoom_sound;	/* ズーム音使うか？ */
    int		display_name;	/* 名前表示をするか？ */
    int		change_player;	/* プレーヤーのモードを変更するか？ */
    int		return_demo_wait;	/* 会話終了の際にプレーヤーのモードを棒立ち(デモ用)にするか？ */
    rgba_t	window_color;	/* ウインドウ本体の色 */
} M_DEMO_TALK;
    
/*
 ******************************************************************************
 *	各デモ用個別データ
 ******************************************************************************
 */    

typedef struct {
    ACTOR	*actor;
    int         type;
    void        (*proc)(ACTOR *);
    float       v;
} M_DEMO_CLIENT;

/* 会話要求アクター登録最大値（とりあえずこの数で） */
#define M_DEMO_REQUEST_MAX  		(mFM_BK_MV_AC_NUM*2)

/* 会話デモ用データ */
typedef struct _talk_demo_data_struct_ {
    int		msg;		/* メッセージ番号 */
    int		turn;		/* 会話中に振返るか？ */
    int		use_zoom_sound;	/* ズーム音使うか？ */
    int		display_name;	/* 名前表示をするか？ */
    int		change_player;	/* プレーヤーのモードを変更するか？ */
    int		return_demo_wait;	/* 会話終了の際にプレーヤーのモードを棒立ち(デモ用)にするか？ */
    rgba_t	window_color;	/* ウインドウ本体の色 */
    struct {                    /* デモ関係者がうごかないように */
	char    lsn, spk;       /* 体重をコントロールするため？ */
    }  org_weight;
} M_DEMO_TALK_DATA;

/* ドアデモ用データ */
typedef struct _door_demo_data_struct_ {
    int		type;		/* ドアのタイプ */
    struct {			/* 家情報   */
	float   size;		/*   大きさ */
	int	direct;		/*   向き   */
    } house;
} M_DEMO_DOOR_DATA;

/* イベント告知デモ用データ */
typedef struct _eventmsg_demo_data_struct_ {
    int		msg;		/* メッセージ番号 */
    rgba_t	window_color;	/* ウインドウ本体の色 */
    int         count0;         /* メッセージを出すまでのウエイト  */
    int         count1;		/* シーン切り替えるまでのウエイト */
    Door_data   dd;             /* 飛び先データ */
    char        dummy[4];       /* memcpyするのでDoor_dataのバウンダリ対策 */
} M_DEMO_EMSG_DATA;

/* 大掛かりなデモ用データ */
typedef struct _cool_demo_data_struct_ {
    u32           label;         /* 何者がデモを制御しているか？ */
    M_DEMO_PROC1  ct_func;       /* 初期化関数 */
    M_DEMO_PROC1  dt_func;       /* 後始末関数 */
    M_DEMO_PROC1  move_func;     /* メイン関数 */
} M_DEMO_COOL_DATA;

/*
 ******************************************************************************
 *	デモ構造体宣言
 ******************************************************************************
 */    
typedef struct {
    ACTOR 	*speaker_actor_p;		/* 話しかけ側のアクター(主にプレイヤー) */
    ACTOR 	*listen_actor_p;		/* 聞き手のアクター(主にＮＰＣ) */
    int 	speaker_able;			/* 話しかけ側のアクターが準備出来た(主にプレイヤー) */
    int 	listen_able;			/* 聞き手のアクターが準備出来た(主にＮＰＣ) */
    
    M_DEMO_ORDER	order[M_DEMO_TOTAL_ORDER_KIND];		/* デモ指令変数 */
    signed char	change_player_destiny;				/* プレイヤーの状態を変更命令 */

    /*
    ** 
    **    新型
    **
    */
    int  status;                                /* 状態                 */
    M_DEMO_CLIENT  client;                      /* 走ってるデモのタイプ */
    M_DEMO_CLIENT  request[M_DEMO_REQUEST_MAX]; /* デモの要求をストック */
    int  nreq;                                  /* ストックした数       */
    int  hp_req;                                /* 一番高い優先順位     */
    int  camera_type;                           /* カメラのタイプ       */
    int  camera_keep;                           /* 終了後カメラを戻すか */
    
    union _each_own_data_ {                     /* ＊各タイプ別データ＊ */
	M_DEMO_TALK_DATA  talk;                 /*   会話デモ用         */
	M_DEMO_DOOR_DATA  door;                 /*   ドアデモ用         */
	M_DEMO_EMSG_DATA  emsg;                 /*   イベント告知用     */
	M_DEMO_COOL_DATA  cool;                 /*   大掛かりなデモ用   */
    } d;
    
} M_DEMO_DATA;


/*
 ******************************************************************************
 *	デモ制御の初期化
 ******************************************************************************
 */
extern void  mDemo_Init(GAME *game_p);

/*
 ******************************************************************************
 *	デモ制御のおおもと
 ******************************************************************************
 */
extern void  mDemo_Main(GAME *game_p);
extern void  mDemo_stock_clear(void);
    
/*
 ***********************************************************************
 *	デモ中か？チェック
 ***********************************************************************
 */
extern int  mDemo_CheckDemo(void);
extern int  mDemo_CheckDemo4Event(void);

/*
 ***********************************************************************
 *	どのデモが走ってるか？チェック
 ***********************************************************************
 */
extern int  mDemo_CheckDemoType(void);



/*
 ******************************************************************************
 *	プレイヤーとの会話中のアクターポインターをゲット
 ******************************************************************************
 */
extern ACTOR *mDemo_Get_talk_actor(void);

/*
 ****************************************************************
 *	 デモ用カメラの使用
 ****************************************************************
 */
extern int mDemo_Get_camera(void);
extern void mDemo_Set_camera(unchar value);

/*
 ******************************************************************************
 *	デモ指令変数のセット
 ******************************************************************************
 */
extern void mDemo_Set_OrderValue(int kind,		/* どのキャラクターの命令か("M_DEMO_TOTAL_ORDER_KIND"参照) */
				 int num,		/* 何番目の変数を見るか("M_DEMO_TOTAL_ORDER_VAL"参照) */
				 unshort value);
/*
 ******************************************************************************
 *	デモ指令変数のゲット
 ******************************************************************************
 */
extern unshort mDemo_Get_OrderValue(int kind,		/* どのキャラクターの命令か("M_DEMO_TOTAL_ORDER_KIND"参照) */
				    int num);		/* 何番目の変数を見るか("M_DEMO_TOTAL_ORDER_VAL"参照) */

/*
 ****************************************************************
 *	メッセージの番号を無理やり変える
 *		（ウインドウが現れる前に呼ばないと意味がないかも）
 ****************************************************************
 */
extern void mDemo_Set_msg_num(int msg_num);

/*
 ****************************************************************
 *	プレイヤーの状態を変更命令セット
 ****************************************************************
 */
extern void mDemo_Set_change_player_destiny(signed char value);

/*
 ***********************************************************************
 *	会話可能になったことを知らせる
 ***********************************************************************
 */
/* 話しかけ側(主にプレイヤー) */
extern void mDemo_Set_SpeakerAble(void);
/* 聞き手側(主にＮＰＣ) */
extern void mDemo_Set_ListenAble(void);

/* 話しかけ側(主にプレイヤー) */
extern void mDemo_Unset_SpeakerAble(void);
/* 聞き手側(主にＮＰＣ) */
extern void mDemo_Unset_ListenAble(void);

/*
 ***********************************************************************
 *	会話可能になったかを調べる
 ***********************************************************************
 */
/* 話しかけ側(主にプレイヤー) */
extern int mDemo_Check_SpeakerAble(void);
/* 聞き手側(主にＮＰＣ) */
extern int mDemo_Check_ListenAble(void);

/*
 ***********************************************************************
 *	会話可能になる角度かを調べる
 ***********************************************************************
 */
extern int mDemo_Check_DiffAngle_forTalk(short diff);

/*
 ****************************************************************
 *	会話中のアクターポインターを得る
 *		（有効でないならFALSEを返しNULLを入れる）
 ****************************************************************
 */
extern int mDemo_Get_Talk_Actors(ACTOR **speaker_actor_pp,		/* 話しかけ側のアクター(主にプレイヤー) */
				 ACTOR **listen_actor_pp);		/* 聞き手のアクター(主にＮＰＣ) */

/*
 ****************************************************************
 *	 "会話の際に会話用カメラを使用しているか"
 ****************************************************************
 */
#define mDemo_Get_talk_camera()      mDemo_Get_camera()
#define mDemo_Set_talk_camera(value) mDemo_Set_camera(value)

/*
 ****************************************************************
 *	 "会話開始時にズーム音使うか"
 ****************************************************************
 */
extern int mDemo_Get_use_zoom_sound(void);
extern void mDemo_Set_use_zoom_sound(unchar value);

/*
 ****************************************************************
 *	 "会話の際に名前を表示するか"
 ****************************************************************
 */
extern int mDemo_Get_talk_display_name(void);
extern void mDemo_Set_talk_display_name(signed char value);

/*
 ****************************************************************
 *	 "会話の際にプレーヤーのモードを変更するか"
 ****************************************************************
 */
extern int mDemo_Get_talk_change_player(void);
extern void mDemo_Set_talk_change_player(unchar value);

/*
 ****************************************************************
 *	 "会話終了の際にプレーヤーのモードを棒立ち(デモ用)にするか"
 ****************************************************************
 */
extern int mDemo_Get_talk_return_demo_wait(void);
extern void mDemo_Set_talk_return_demo_wait(unchar value);

/*
 ****************************************************************
 *	 "会話の際にプレーヤーのモードを変更するか"
 ****************************************************************
 */
extern int mDemo_Get_talk_turn(void);
extern void mDemo_Set_talk_turn(unchar value);

/*
 ****************************************************************
 *	 "メッセージウインドウの色"
 ****************************************************************
 */
extern rgba_t *mDemo_Get_talk_window_color_p(void);
extern void mDemo_Set_talk_window_color(rgba_t *color_p);


/*
 ****************************************************************
 *	ドアデモ時の家の情報を設定
 ****************************************************************
 */
extern int mDemo_Set_house_info(float  size,	/* 家の一辺の大きさ */
				int  direct);   /* 家の向き M_DEMO_DIRECT_x */






/*
** 
**    新型
**
*/
#define mDemo_check_title_demo()  (ZCommonGet(start_demo.type) != M_DEMO_TYPE_NONE)

/*
***************************************************************
**      デモのリクエスト
***************************************************************
*/
typedef void	(*mDemo_REQUEST_PR)(ACTOR *);

extern int  mDemo_Request(int type, ACTOR *actor, mDemo_REQUEST_PR proc);

/*
***************************************************************
**      リクエストが通ったか？チェック
***************************************************************
*/

extern int  mDemo_Check(int type, ACTOR *actor);

#if 0	/* 2000 12/11 komatu */
/*
***************************************************************
**      デモのリクエストが幾つされたか
***************************************************************
*/
extern int mDemo_RequestTotal(void);
#endif

/*
***************************************************************
**      デモ開始
***************************************************************
*/
extern int  mDemo_Start(ACTOR *actor);

extern int  mDemo_Check_and_Go(int type, ACTOR *actor);

/*
***************************************************************
**      デモ終了
***************************************************************
*/
extern int  mDemo_End(ACTOR *actor);

/*
***************************************************************
**      デモ終了してもカメラ戻さない
***************************************************************
*/
extern void  mDemo_KeepCamera(int on_off);

#ifdef _LANGUAGE_C_PLUS_PLUS
} /* extern "C" */
#endif

#endif /* __M_DEMO_H__ */
