/********************************************************************************
					-------------------------
				 	 Ultra 64 MARIO Brothers
					-------------------------

					File		: pathcarryboy.s
					Description	: 
					Date		: 1995.
					Author		: H.yajima

 ********************************************************************************/

#define	 ANM_carryboy_carry				0
#define	 ANM_carryboy_carry_wait		1
#define	 ANM_carryboy_help				2
#define	 ANM_carryboy_pitch             3
#define	 ANM_carryboy_quick_move		4
#define	 ANM_carryboy_wait				5

/*################*/
#ifdef ASSEMBLER
/*################*/

e_carryboy:
	p_initialize(enemyA)
	p_setbit(flag,stf_moveON | stf_YangleSAME | stf_playerdistON | stf_catchON )
	p_set_pointer(skelanime,carryboy_anime)
	p_set_skelanime_number(5)
	p_setd(objname,OBJNAME_TAKE)
	p_sethitbox(150,100)
	p_setmovedata(30,-400,-50,1000,1000,200,0,0)
	p_makeobj_child(S_NULL,e_carryboy_hand)
	p_setd(havecoin,5)
	p_hitON
	p_save_nowpos
	p_while
		p_program(s_carryboy)
	p_loop

e_carryboy_hand:
	p_initialize(enemyA)
	p_setbit(flag,stf_moveON | stf_YangleSAME )
	p_softspritemodeON
	p_setf(skeletonY,-60)
	p_setf(skeletonZ,150)
	p_while
		p_program(s_carryboy_hand)
	p_loop

/*################*/
#else
/*################*/
/********************************************************************************
		C Program (carryboy)
 ********************************************************************************/

#define		carryboy_flag	(execstp->s[stw_work1].d)
#define		carryboy_timer	(execstp->s[stw_work2].d)
#define		carryboy_keycheck	(execstp->s[stw_work3].d)

/********************************************************************************
		C Program (katsugi)
 ********************************************************************************/

extern void s_motoshand_main(float f,float v,long mail)
{
	switch (execstp->motherobj->s[stw_imm].d ){
	 	case	0:
			break;
		case	1:
			s_copy_mapwork(player1stp,execstp);
			break;
		case	2:
			player1stp->s[stw_mail].d |= ( PLAYERMAIL_CARRYMODE_OFF + mail );
			playerWorks[0].velocity = f; 
			playerWorks[0].speed[1] = v; 
			execstp->motherobj->s[stw_imm].d = 0;
			break;
		case	3:
			player1stp->s[stw_mail].d |= ( PLAYERMAIL_CARRYMODE_OFF + PLAYERMAIL_CARRYTHROW_SMALL );
			playerWorks[0].velocity = 10; 
			playerWorks[0].speed[1] = 10; 
			execstp->motherobj->s[stw_imm].d = 0;
			break;
	}
	obj_angleY = execstp->motherobj->s[stw_angleY].d;
	if ( execstp->motherobj->status == 0 )	s_remove_obj(execstp);
}


extern void s_carryboy_hand(void)
{
	s_motoshand_main( 40 , 40 , PLAYERMAIL_CARRYTHROW_SMALL );
}


#define		SOBJ_INITPOS	0
#define		SOBJ_RETURN 	1
#define		SOBJ_SEARCH		2
#define		SOBJ_MOVE		3
#define		SOBJ_WALL		4

extern int s_searchobj_angle(int code,float scope,float player,short frame)
{

	int	flag = 0;


	if ( carryboy_flag != SOBJ_WALL ){

		if ( s_calc_playerscope() > scope ){	
			if (s_calc_enemyscope()	< 200 ){
				flag = SOBJ_INITPOS;
			} else {
				flag = SOBJ_RETURN;
				obj_targetangle = s_calc_returnangle();
			}
		} else if ( obj_playerdist > player ){
			if ( ( frameCounter % frame ) == 0 ){
				obj_targetangle = s_calc_targetangle(execstp,player1stp);
			}	
		  	flag = SOBJ_SEARCH;
		} else {
		 	flag = SOBJ_MOVE;
		}

		if ( code ){
			if ( s_check_gakewall( &obj_targetangle )){;
				flag = SOBJ_WALL;
				carryboy_flag = SOBJ_WALL;
			}
		}

	} else {
	 	flag = SOBJ_WALL;
	}


	return(flag);

}


/********************************************************************************
		carryboy search
 ********************************************************************************/

typedef struct {
	short	anglespeed;
	float	speedF;
	float	accel;
} SOBJ_Record;

static SOBJ_Record	carryboy_movedata[] = {

	{  0x200,  0, 1 },		/* initpos 	*/
	{  0x200, 10, 1 },		/* return	*/
	{  0x200, 20, 1 },		/* search 	*/
	{  0x200, 20, 1 },		/* move		*/
	{  0x800, 10, 1 },		/* wall		*/

};

extern int s_step_speed(float *speed,float limit, float accel)
{

	int flag = 0;

	if ( *speed > limit ){
		*speed -= accel;
		if ( *speed < limit )	*speed = limit;
	} else if ( *speed < limit ){
		*speed += accel;
		if ( *speed > limit )	*speed = limit;
	} else {
	 	flag = 1;
	}

	return(flag);

}


#define	CARRYBOY_SEARCH		0
#define	CARRYBOY_DASH		1
#define	CARRYBOY_WAIT		2
#define	CARRYBOY_RETURN     3
#define	CARRYBOY_WALL		4


static void carryboy_search(void)
{

	int 	flag;
	int		look;
	float	speed;
	float	accel;
	short	anime;
	int		old_process;

	if ( obj_timer == 0 ) carryboy_timer = 0;
	obj_targetangle = s_calc_targetangle(execstp,player1stp);

	switch( old_process = obj_process ){

	 	case CARRYBOY_SEARCH:
			obj_speedF = 0;
			if ( s_calc_playerscope() < 2000 ){
				s_chase_angleY(obj_targetangle,0x400  );
				if ( carryboy_timer > 40 || s_calc_dangle(obj_angleY,obj_targetangle) < 0x1000 ) obj_process = CARRYBOY_DASH;
			} else {
				obj_process = CARRYBOY_RETURN;
			}
			break;

		case CARRYBOY_DASH:
			s_step_speed(&obj_speedF,30,4 );
			if ( s_calc_dangle(obj_angleY,obj_targetangle) > 0x4000 )	obj_process = CARRYBOY_WAIT;
			if ( s_calc_playerscope() > 2000 ) obj_process = CARRYBOY_RETURN;
			break;

		case CARRYBOY_WAIT:
			s_step_speed(&obj_speedF,0,4 );
 			if ( carryboy_timer > 48  )	obj_process = CARRYBOY_SEARCH;
			break;

		case CARRYBOY_RETURN:
			if ( s_calc_enemyscope() < 500 ){
			  	obj_speedF = 0;
			} else {
				s_step_speed(&obj_speedF,10,4 );
				obj_targetangle = s_calc_returnangle();
				s_chase_angleY(obj_targetangle,0x800 );
			}				
			if ( s_calc_playerscope() < 2000-100 ) obj_process = CARRYBOY_SEARCH;
			break;
	}

	if ( old_process != obj_process ) carryboy_timer = 0;
	else							  carryboy_timer++;


	s_set_skelanimeNo(ANM_carryboy_quick_move);		/* skeleton animation */
	if( obj_speedF > 1 ) objsound_level(NA_LSE3_KATSUGINAGE_MOVE);

	dbErrPrint("fg %d",flag);
	dbErrPrint("sp %d",obj_speedF);

}

/********************************************************************************
		carryboy pitch !!!
 ********************************************************************************/

static void carryboy_pitch(void)
{

	if ( obj_process == 0 ){
		if ( s_setanime_endcheck( ANM_carryboy_carry )) obj_process++;
		carryboy_timer = Randomf()*30+10;
		carryboy_keycheck = 0;
		obj_speedF = 0;

	} else if ( obj_process == 1 ){

		carryboy_keycheck += key_gacha();
		dbErrPrint("%d",carryboy_keycheck);			 	 
		if ( carryboy_keycheck > 10 ){
			obj_imm = 3;
			obj_mode = mode_carryboy_stopwait;
			Mbitclr(execstp->s[stw_mail].d,EMAIL_CARRYMODE_ON);
		} else {
			s_set_skelanimeNo(ANM_carryboy_carry_wait);

			obj_angleY += 0x800;
			if ( carryboy_timer-- < 0 ){
				if ( s_next_bgcheck(50,150) || carryboy_timer < -16 ) obj_process++;
			}

		}

	} else {
		s_set_skelanimeNo(ANM_carryboy_pitch);
		if ( s_check_animenumber(18) ){
			objsound(NA_SE3_THROW_B);
			execstp->s[stw_imm].d = 2;			
			obj_mode = mode_carryboy_stopwait;
			Mbitclr(execstp->s[stw_mail].d,EMAIL_CARRYMODE_ON);
		}
	}		

}

static void carryboy_stopwait(void)
{
	obj_speedF = 0;
	obj_speedY = 0;
	s_set_skelanimeNo(ANM_carryboy_quick_move );
	if ( obj_timer > 100 ) obj_mode = mode_carryboy_search;

}


/********************************************************************************
		carryboy fly !!
 ********************************************************************************/
static void carryboy_fly(void)
{
	extern unsigned long e_bombfire[];

	if ( obj_movestatus & ( MOVESTAT_BGBOUND | MOVESTAT_WATER | MOVESTAT_WALL ) ){
	 	s_remove_obj(execstp);
		s_makecoin(execstp,5,20);
		s_kemuri_sound( NA_SE3_KATSUGINAGE_DOWN );
	}

}

/********************************************************************************
		carryboy main program
 ********************************************************************************/
static void *carryboy_modejmp[] = {
	
	 carryboy_search,
	 carryboy_pitch,
	 carryboy_fly,
	 carryboy_stopwait
	
};

extern void carryboy_main(void)
{
	s_enemybgcheck();						/*  monky bgcheck 	*/
	s_modejmp(carryboy_modejmp);
	s_enemymove(-30);

	if ( execstp->s[stw_mail].d & EMAIL_CARRYMODE_ON ){
		obj_mode = mode_carryboy_pitch;
		execstp->s[stw_imm].d = 1;
		objsound(NA_SE3_CATCH_B);
	}

}

/********************************************************************************
		======================
		 carryboy total main
		======================
 ********************************************************************************/

extern void s_carryboy(void)
{

	float			f,y;
	StrategyRecord	*stp;

	f = 20;
	y = 50;

	s_set_scale(2.0);
	Mbitset(execstp->s[stw_enemyinfo].d,ENEMYINFO_CARRY);

	switch(execstp->s[stw_actionmode].d){
		case	CHILEDMODE_NO_CATCH:	carryboy_main();		  				break;
		case	CHILEDMODE_CATCH:		s_mode_catch( ANM_carryboy_help ,0 );	break;
		case	CHILEDMODE_THROW:
		case	CHILEDMODE_DROP:	
						s_mode_throw(f,y,mode_carryboy_fly );
						break;
	}

	obj_mail = 0;
	dbErrPrint("md %d",execstp->s[stw_mode].d);

}


/*################*/
#endif
/*################*/
/*===============================================================================
		end end end end end end end end 
===============================================================================*/



