/********************************************************************************
					-------------------------
				 	 Ultra 64 MARIO Brothers
					-------------------------

					File		: pathping.s
					Description	: enemy ping
					Date		: 1995.9.11
					Author		: H.yajima

 ********************************************************************************/

#define	PING_STAR_X		 3167
#define	PING_STAR_Y		 -4300
#define	PING_STAR_Z		 5108

#define	ANM_ping_walk			0
#define	ANM_ping_slip			1
#define	ANM_ping_slip_end		2
#define	ANM_ping_wait			3

#define	PING_ANIM_WALK			0
#define	PING_ANIM_SLIP			1
#define	PING_ANIM_SLIP_END		2
#define	PING_ANIM_WAIT			3 


/*################*/
#ifdef ASSEMBLER
/*################*/

/********************************************************************************
	==========
	 oya ping
	==========
 ********************************************************************************/

e_pingboss:
e_ping_oya:
	p_initialize(enemyA)
	p_setbit(flag,stf_moveON | stf_YangleSAME | stf_playerdistON | stf_playerangleON )
	/* p_setshapeinfo(ping_info) */
	p_set_pointer(skelanime,ping_anime)
	p_set_skelanime_number(ANM_ping_wait)
	p_setmovedata(30,-400,-50,0,0,0,0,0)
	p_save_nowpos
	p_setobjname(FRIEND)
	p_sethitbox(200,300)
	p_hitON
	p_while
		p_program(s_ping_oya)
	/*	p_program(stMainMoveBG)	*/
	p_loop

/********************************************************************************
	ping kodomo (0)
 ********************************************************************************/

e_ping_kodomo_badoya:
	p_initialize(enemyA)
	p_end

e_ping_kodomo_return:
	p_initialize(enemyA)
	p_end

e_ping:
e_ping_kodomo:
	p_initialize(enemyA)
	p_setbit(flag,stf_moveON | stf_YangleSAME | stf_playerdistON | stf_playerangleON | stf_catchON )
	p_BGcheckYset
	p_set_pointer(skelanime,ping_anime)
	p_set_skelanime_number(0)
	p_setmovedata(30,-400,-50,0,0,200,0,0)
	p_setd(objname,OBJNAME_TAKE)
	p_setd(enemyinfo,ENEMYINFO_FRIEND_ENEMY)
	p_hitON
	p_sethitbox(40,40)
	p_save_nowpos
	p_while
		p_program(s_ping_kodomo)
	p_loop



/*################*/
#else
/*################*/


/********************************************************************************
		----------------
		 ping parameter
		----------------
 ********************************************************************************/

#define	MESSAGE_KODOMO_SAGASE	57
#define	MESSAGE_KODOMO_ARIGATO	58
#define	MESSAGE_KODOMO_CHIGAU	59

/* ==================== used work 0 =================*/
#define	ping_mode_backup	(execstp->s[stw_work3].d)
#define	ping_randomspeed	(execstp->s[stw_work4].f)
#define	ping_randomdist		(execstp->s[stw_work5].f)
#define	ping_randomtime		(execstp->s[stw_work6].d)
#define	ping_randomangle	(execstp->s[stw_work7].d)

#define	ping_timer			(execstp->s[stw_work9].d)

/********************************************************************************
	Ping Sound Program
 ********************************************************************************/


extern int s_anime_sound(short f1, short f2, unsigned long sound)
{
    float	speed;
    
    if ( ( speed = (float)(execstp->map.skelanim.vspeed) / 0x10000 ) == 0 ) speed = 1;
    
    if ( s_check_animenumber_speed(f1, speed) ||
		 s_check_animenumber_speed(f2, speed) ) {
		 objsound(sound);
		 return(1);
    }
    return(0);
}

extern void sound_pingwalk(int flag)
{

	unsigned long sound;

	if ( execstp->s[stw_skelanimeNo].d == PING_ANIM_WALK ){

		if ( flag == 0 )	sound = NA_SE3_PENGUINWALK;
		else				sound = NA_SE3_PENGUINOYA;
		s_anime_sound( 1, 11,sound );

	}

}
/********************************************************************************
		------------------
		 ping oya program
		------------------
 ********************************************************************************/

/*------------------------------------------------------------------------------*/
/*		oya end																	*/
/*------------------------------------------------------------------------------*/
static void ping_oya_end(void)
{

	float			dist;
	float			returndist;
	StrategyRecord *stp = s_search_nearobject(e_ping_kodomo,&dist);

	if ( s_search_catch_enemy(e_ping_kodomo_return,1000) ){

		if ( obj_process == 0 ){
			s_set_skelanimeNo(PING_ANIM_WALK);
			obj_speedF = 10;
			if ( ( s_calc_playerscope() > 800 ) )	obj_process = 1;
		 	s_chase_angleY(obj_targetangle,0x400);
		} else {
			obj_speedF = 0;
			s_set_skelanimeNo(PING_ANIM_WAIT);
			if ( ( s_calc_playerscope() < 700 ) )	obj_process = 0;
		}				


	} else {
		obj_speedF = 0;
		s_set_skelanimeNo(PING_ANIM_WAIT);
	}


	if ( stp != NULL && dist < 300 && stp->s[stw_actionmode].d != 0){
		obj_mode			= mode_ping_oya_kodomo_find;
		stp->s[stw_imm].d 	= 1;
		execstp->childobj	= stp;
	}


}

/*------------------------------------------------------------------------------*/
/*		oya kodomo find															*/
/*------------------------------------------------------------------------------*/
static void ping_oya_kodomo_find(void)
{
	int	code_oya;
	int	code_kodomo;
	int	message;


	switch(obj_process){
		case 0:
			s_set_skelanimeNo(PING_ANIM_WAIT);

			if ( s_rideon_player() == 0 ){

				code_oya 	= ((           execstp->s[stw_actorcode].d ) >> 16 ) & 0xff;
				code_kodomo = (( execstp->childobj->s[stw_actorcode].d ) >> 16 ) & 0xff;
				if ( code_oya == code_kodomo ) message = MESSAGE_KODOMO_ARIGATO;
				else						   message = MESSAGE_KODOMO_CHIGAU;	

				if ( s_call_talkdemo(DLOG_LOOKUP,ENEMYDEMO_LOOKPLAYER,CAM_DEMO_TALK,message) ){
					if ( message == MESSAGE_KODOMO_ARIGATO ) obj_process = 1;
					else									 obj_process = 2;
					Mbitset(execstp->childobj->s[stw_enemyinfo].d,ENEMYINFO_CATCH_OFF_REQUEST);
				}

			} else {
				s_set_skelanimeNo(PING_ANIM_WALK);
			}
			break;
		case 1:

			if ( execstp->childobj->s[stw_actionmode].d == 0 ){
				Mbitclr(execstp->childobj->s[obj_enemyinfo].d,ENEMYINFO_CATCH_OFF_REQUEST);
				s_rename_pathname(execstp->childobj,e_ping_kodomo_return);
				sv2_enemyset_star(PING_STAR_X,PING_STAR_Y,PING_STAR_Z,200);
				obj_mode = mode_ping_oya_end;
			}
			break;		

		case 2:

			if ( execstp->childobj->s[stw_actionmode].d == 0 ){
				Mbitclr(execstp->childobj->s[obj_enemyinfo].d,ENEMYINFO_CATCH_OFF_REQUEST);
				s_rename_pathname(execstp->childobj,e_ping_kodomo_badoya);
				obj_mode = mode_ping_oya_end;
			}

			break;
	}


}

/*------------------------------------------------------------------------------*/
/*		oya wait																*/
/*------------------------------------------------------------------------------*/
static void ping_oya_wait(void)
{
	int		near_kodomo_flag = 0;
	float	dist;
	StrategyRecord *stp = s_search_nearobject(e_ping_kodomo,&dist);
	s_set_scale(4.0);
	s_set_skelanimeNo(PING_ANIM_WAIT);

	if ( dist < 500 )	near_kodomo_flag = 1;

	if ( stp != NULL && dist < 300 && stp->s[stw_actionmode].d != 0){

		obj_mode			= mode_ping_oya_kodomo_find;
		stp->s[stw_imm].d 	= 1;
		execstp->childobj 	= stp;
		
	} else {

		switch(obj_process){
			case 0:
				if ( s_hitcheck_message(300,100) && (near_kodomo_flag == 0) )	obj_process++;
				break;
			case 1:
				
				if ( s_call_talkdemo(DLOG_LOOKUP,ENEMYDEMO_LOOKPLAYER,CAM_DEMO_TALK,MESSAGE_KODOMO_SAGASE) ){
					obj_process++;
				}
				break;
			case 2:
				if ( obj_playerdist > 450 )	obj_process = 0;
				break;
		}

	}

	if ( s_check_animenumber(1) )	objsound(NA_SE3_PENGUINVOICE);

}

/*------------------------------------------------------------------------------*/
/*		oya main program														*/
/*------------------------------------------------------------------------------*/
static void *ping_oya_modejmp[] = {
	
	 ping_oya_wait,
	 ping_oya_kodomo_find,
	 ping_oya_end
	
};

extern void s_ping_oya(void)
{

	execstp->status |= OBJECT_NOWATER;
	s_enemybgcheck();
 	s_modejmp(ping_oya_modejmp);
	s_enemymove(-78);
	sound_pingwalk(1);
	obj_mail = 0;

}

/********************************************************************************
		---------------------
		 ping kodomo program
		---------------------
 ********************************************************************************/

static void ping_slip_check(void)
{
	if ( s_check_playercatch() ){
		ping_mode_backup = obj_mode;
		obj_mode 		 = mode_ping_kodomo_slip;
	}
}

/*------------------------------------------------------------------------------*/
/*			runaway																*/
/*------------------------------------------------------------------------------*/
static void ping_kodomo_runaway(void)
{

	int	rflag = 0;

	if ( obj_timer == 0 ){ if ( s_distance_nearobj(e_ping_oya) < 1000 ) rflag = 1; }

	s_set_skelanimeNo(PING_ANIM_WALK);	
	obj_speedF = 3+ping_randomspeed;
 	s_chase_angleY(obj_targetangle+0x8000,0x600+ping_randomangle);
	if ( obj_playerdist > 500+ping_randomdist )		obj_mode = mode_ping_kodomo_wait;
	ping_slip_check();
	if ( rflag )									obj_mode = mode_ping_kodomo_oya_loop;
}

/*------------------------------------------------------------------------------*/
/*			search																*/
/*------------------------------------------------------------------------------*/
static void ping_kodomo_search(void)
{

	s_set_skelanimeNo(PING_ANIM_WALK);	
	obj_speedF = 3+ping_randomspeed;
 	s_chase_angleY(obj_targetangle,0x600+ping_randomangle);
	if ( obj_playerdist < 300+ping_randomdist )	obj_mode = mode_ping_kodomo_wait; 
	if ( obj_playerdist > 1100 				  )	obj_mode = mode_ping_kodomo_wait; 
	ping_slip_check();

}

/*------------------------------------------------------------------------------*/
/*			slip																*/
/*------------------------------------------------------------------------------*/
static void ping_kodomo_slip(void)
{
	if ( obj_timer > 5 ){ 
		if ( obj_timer == 6 )	objsound(NA_SE3_PENGUINJUMP);
		s_set_skelanimeNo(PING_ANIM_SLIP);

		if ( obj_timer > 20+5 ){
			if ( s_check_playercatch() == 0)	obj_mode = mode_ping_kodomo_slip_end;
		}			
	}
}

/*------------------------------------------------------------------------------*/
/*			slip_end															*/
/*------------------------------------------------------------------------------*/
static void ping_kodomo_slip_end(void)
{
	if ( obj_timer > 20 ){ 
		obj_speedF = 0;
		s_set_skelanimeNo(PING_ANIM_SLIP_END);
		if ( obj_timer > 20+20 ){
			obj_mode = ping_mode_backup;
		}
	}
}

/*------------------------------------------------------------------------------*/
/*			wait																*/
/*------------------------------------------------------------------------------*/

static void ping_kodomo_wait(void)
{

	int	rflag = 0;

	s_set_skelanimeNo(PING_ANIM_WAIT);

	if ( obj_timer == 0 ){
		ping_randomangle	= Randomf()*0x400;
		ping_randomdist		= Randomf()*100;
		ping_randomspeed	= Randomf();
		obj_speedF = 0;
		if ( s_distance_nearobj(e_ping_oya) < 1000 ) rflag = 1;
	}

	if ( obj_playerdist < 1000 && obj_playerdist > 600+ping_randomdist ) obj_mode = mode_ping_kodomo_search;
	else if ( obj_playerdist < 300+ping_randomdist ) 					 obj_mode = mode_ping_kodomo_runaway;
	if ( rflag )														 obj_mode = mode_ping_kodomo_oya_loop;

	if ( s_enemy_areaout() )	s_copy_initpos();

}


/*------------------------------------------------------------------------------*/
/*		oya loop																*/
/*------------------------------------------------------------------------------*/
static void ping_kodomo_oya_loop(void)
{

	float 	dist;
	short	angle;

	StrategyRecord *stp = s_find_obj(e_ping_oya);

	if ( stp != NULL ){
		if ( obj_playerdist < 1000 )	obj_speedF = 2;
		else					   		obj_speedF = 0;
		dist  = s_distance_obj2obj(execstp,stp);
		angle = s_calc_targetangle(execstp,stp);
		if ( dist > 200 )	s_chase_angleY(angle		,0x400);
		else				s_chase_angleY(angle+0x8000 ,0x400);
		s_set_skelanimeNo(PING_ANIM_WALK);
	}

	ping_slip_check();

}

/*------------------------------------------------------------------------------*/
/*		oya loop																*/
/*------------------------------------------------------------------------------*/

static void *ping_kodomo_modejmp[] = {
	
	 ping_kodomo_wait,
	 ping_kodomo_search,
	 ping_kodomo_runaway,
	 ping_kodomo_slip,
	 ping_kodomo_slip_end,
	 ping_kodomo_oya_loop
	
};

static void s_ping_kodomo_main(void)
{

	if ( obj_imm != 0 ){
		obj_mode = mode_ping_kodomo_oya_loop;
		obj_imm = 0;
	}

	s_enemybgcheck();
	s_modejmp(ping_kodomo_modejmp);
	s_enemymove(-78);

	sound_pingwalk(0);

}

extern void s_ping_kodomo(void)
{
	switch(execstp->s[stw_actionmode].d){
		case	CHILEDMODE_NO_CATCH:	
			s_ping_kodomo_main();
			break;
		case	CHILEDMODE_CATCH:
			s_mode_catch(PING_ANIM_WALK,mode_ping_kodomo_wait);	
			if ( s_check_pathname(e_ping_kodomo_badoya))	s_rename_pathname(execstp,e_ping_kodomo);
			s_copy_worldXYZ(execstp,player1stp);
			if ( ( frameCounter % 30)  == 0 ){
				AudStartSound(player1stp,NA_SE3_PENGUINVOICE_S);
			}
			break;
		case	CHILEDMODE_THROW:		s_mode_throw(0,0,mode_ping_kodomo_wait);		 	break;
		case	CHILEDMODE_DROP:		s_mode_drop();							  			break;
	}
}


/*==============================================================================*/
/*==============================================================================*/
/*==============================================================================*/
/*==============================================================================*/
/*==============================================================================*/

/********************************************************************************/
/*																				*/
/*		Eye Animation	(hms-proc)												*/
/*																				*/
/********************************************************************************/

extern unsigned CtrlPingEye(int code, MapNode *node, void *data)
{
	if (code == MAP_CBACK_EXEC) {

	    StrategyRecord	*stp	= (StrategyRecord *)hmsActiveShape;
		MapSelect 		*select = (MapSelect *)node;
		int		timer;

		select->selsw = 0;

		timer = frameCounter % 50;
		if 		( timer < 43 )	select->selsw = 0;	
		else if ( timer < 45 )	select->selsw = 1;
		else if ( timer < 47 )	select->selsw = 2;
		else					select->selsw = 1;

		if ( stp->pathname == (Path *)SegmentToVirtual(e_ping_oya) ){


			if ( stp->s[stw_speedF].f > 5 )	select->selsw = 3;
		}

	}
	return(0);
}


/*################*/
#endif
/*################*/
/*===============================================================================
		end end end end end end end end 
===============================================================================*/



