/********************************************************************************
					-------------------------
				 	 Ultra 64 MARIO Brothers
					-------------------------

					File		: pathballoon.s 
					Description	: balloon enemy
					Date		: 1995.10.13
					Author		: H.yajima

 ********************************************************************************/


/*################*/
#ifdef ASSEMBLER
/*################*/

e_balloon:
	p_initialize(enemyA)
	p_setbit(flag,stf_moveON | stf_YangleSAME | stf_FspeedON | stf_playerdistON )
	p_save_nowpos
	p_makeshape(S_ballooneye ,e_balloon_eye  )
	p_changeshape(imm,S_balloonbody)
	p_softspritemodeON
	p_program(s_areastage_init)
	p_while
		p_program(s_balloon)
	p_loop

/*-------------------------- balloon eye program -------*/

e_balloon_eye:
	p_initialize(option)
	p_setbit( flag,stf_moveON )
	p_program(s_areastage_init)
	p_while
		p_program(s_balloon_eye)
	p_loop



/*-------------------------- balloon fire program -------*/

e_balloon_fire:
	p_initialize(item)
	p_softspritemodeON
	p_setbit( flag,stf_moveON | stf_FspeedON )
	p_hitON
	p_sethitbox(50,50)
	p_setd(ap,1)
	p_setd(objname,OBJNAME_DAMAGE)
	p_setmovedata(30,0,0,0,0,0,0,0)
	p_program(s_areastage_init)
	p_while
		p_program(s_balloon_fire)
	p_loop

/*------------------------------------------------------*/

e_balloon_gomi:
	p_initialize(effect)
	p_softspritemodeON
	p_setbit( flag,stf_moveON )
	p_do(10)
		p_program(s_balloon_gomi)
	p_next
	p_killshape

/*################*/
#else
/*################*/

/********************************************************************************
			---------------------
			balloon gomi program
			---------------------
 ********************************************************************************/

extern void s_balloon_gomi(void)
{

	if ( obj_timer == 0 ){
		obj_speedY = Randomf()*20+20;
		obj_speedF = Randomf()*20+20;
		obj_angleY = Randomd();
	}
	s_optionmove_F();	/* option move */

}

/********************************************************************************
			---------------------
			balloon fire program
			---------------------
 ********************************************************************************/

/*======================================*/
/*		fire (1)						*/
/*======================================*/
static void balloonfire_1(void)
{
	s_set_scale(3.0);
	obj_speedF = 20;
	s_enemybgcheck();

	if ( (obj_mail & EMAIL_PLAYERHIT) != 0 ){
		obj_mode = mode_balloonfire_2;
	} else {
		if ( (obj_timer > 100) || (obj_movestatus & MOVESTAT_WALL) || ( execstp->status & OBJECT_AREAOUT ) ){ 
			s_remove_obj(execstp);
			s_kemuri();
		}
	}


}

/*======================================*/
/*		fire (2)						*/
/*======================================*/
static void balloonfire_2(void)
{
	
	int  i;

	s_remove_obj(execstp);

	for(i=0;i<10;i++){
		s_makeobj_nowpos(execstp,S_syabon,e_balloon_gomi);
	}

}

/*======================================*/
/*		fire main						*/
/*======================================*/

static void *balloonfire_modejmp[] = {
	
	 balloonfire_1,
	 balloonfire_2
	
};

extern void s_balloon_fire(void)
{
	s_modejmp(balloonfire_modejmp);
}

/********************************************************************************
			makefire
 ********************************************************************************/
static void balloon_makefire(void)
{

	StrategyRecord *firep;
	float	scale = execstp->map.scale[1];

	firep = s_makeobj_nowpos(execstp,S_syabon,e_balloon_fire);
	firep->s[stw_worldY].f += 50 * scale;
	firep->s[stw_worldX].f += sin(execstp->s[stw_angleY].d) * 90 * scale;
	firep->s[stw_worldZ].f += cos(execstp->s[stw_angleY].d) * 90 * scale;
	
	objsound(NA_SE3_RABBITJUMP);

}


/********************************************************************************
			---------------------
			 balloon eye program
			---------------------
 ********************************************************************************/

extern void s_balloon_eye(void)
{

	s_copy_worldXYZ_angleXYZ(execstp,execstp->motherobj);

	if ( ( execstp->status & OBJECT_AREAOUT ) == 0	){ 
		s_copy_scale(execstp,execstp->motherobj);
		s_set_skeleton(execstp,0,0,(100)*(execstp->map.scale[1]) );
		s_create_matrix(execstp,stw_skeletonX,stw_angleX);
		s_rotate_vertex(execstp,stw_worldX,stw_skeletonX);
		obj_animeangleX = obj_angleX;
		execstp->s[stw_animepositionY].f = (execstp->map.scale[1])*(100);
	}

	if	( execstp->motherobj->s[stw_work7].d != 1 ){											/* wink flag */
		execstp->s[stw_animecounter].d  = -1;
	} else {
		execstp->s[stw_animecounter].d++;
		if ( execstp->s[stw_animecounter].d  == 15 )	execstp->motherobj->s[stw_work7].d = 0;	/* wink reset */
	}

	if ( execstp->motherobj->status == 0)	s_remove_obj(execstp);




}

/********************************************************************************
			---------------------
			balloon main program
			---------------------
 ********************************************************************************/

/********************************************************************************
			player eye
 ********************************************************************************/

#define		balloon_eyetimer	(execstp->s[stw_work0].d)
#define		balloon_eyecount	(execstp->s[stw_work1].d)
#define		balloon_eyedata	(execstp->s[stw_work2].d)
#define		balloon_flag	(execstp->s[stw_work3].d)
#define		balloon_subtimer	(execstp->s[stw_work4].d)
#define		balloon_random	(execstp->s[stw_work5].d)
#define		balloon_scale	(execstp->s[stw_work6].f)
#define		balloon_wink	(execstp->s[stw_work7].d)



#define	BL_XMOVE_COUNT		32
#define	BL_SCALE_COUNT		8
#define	BL_WAIT_COUNT		(16*4)
#define	BL_REVENGE_COUNT	16


#define	BL_ROLLTIME			64
#define	BL_XMOVETIME		(BL_ROLLTIME+BL_XMOVE_COUNT)
#define	BL_SCALE			(BL_XMOVETIME+BL_SCALE_COUNT)
#define	BL_DOWNWAIT			(BL_SCALE+BL_WAIT_COUNT)
#define	BL_REVENGE			(BL_DOWNWAIT+BL_REVENGE_COUNT)

static void balloon_eyedamage(void)
{

	short			ang1;
	short 			add;
	float			timevar,timevar2;
	StrategyRecord 	*stp;
	int				i;
	float			scale;
	float			mainscale;

	if ( obj_programselect ) mainscale = 2;
	else					 mainscale = 1;

	if ( balloon_flag < 0 )	add =  0x1000;
	else					add = -0x1000;

	timevar2 = (float)(obj_timer+1)/(float)(BL_XMOVETIME);

	if        ( obj_timer < BL_ROLLTIME ){

		ang1 = obj_angleY;
		obj_angleY +=    add * cos(0x4000 * timevar2 );
		if ( ang1 < 0 && obj_angleY >= 0 ) objsound(NA_SE3_EYEROLL);


		obj_angleX = -0x4000 * (1.0 - cos(0x4000 * timevar2 ));
		s_effect_updown(4);

		

	} else if ( obj_timer < BL_XMOVETIME ){

		if ( obj_timer == BL_ROLLTIME ) 	objsound(NA_SE3_ENEMYDOWN);

		timevar = (float)(obj_timer-BL_ROLLTIME+1)/(float)(BL_XMOVE_COUNT);
		obj_angleY +=    add * cos(0x4000 * timevar2 );
		obj_angleX = -0x4000 * (1.0 - cos(0x4000 * timevar2 ));
		s_effect_updown((int)(4*(1-timevar)) );
		
		scale = 0.6+0.4*cos(0x4000 * timevar);

		s_set_scale(scale*mainscale);


	} else if ( obj_timer < BL_SCALE ){

	} else if ( obj_timer < BL_DOWNWAIT ){
		if ( obj_timer == BL_SCALE ){
			s_hitOFF();
			s_kemuri();
			balloon_scale = (0.6*mainscale);
			if ( obj_programselect ){
				obj_worldY+= 100;
				s_enemyset_star(1370, 2000, -320);
				s_remove_obj(execstp);
			} else {
				s_make_bluecoin();
			}
		}

		balloon_scale -= (0.2*mainscale);
		if ( balloon_scale < 0 )	balloon_scale = 0;
		s_set_scale(balloon_scale);


	} else {
		s_remove_obj(execstp);
	}

/*--------------------------------------------------
	 	if ( obj_playerdist > 2000 ){
			obj_mode = mode_balloon_roll;
			obj_angleY = 0;
			obj_angleX = 0;
			s_set_scale(1.0);
		} 
--------------------------------------------------*/

}



/********************************************************************************
			player eye
 ********************************************************************************/

#define	BL_MEMAWASHI_TIME	120
#define BL_MEMAWASHI_ANGLE	65536*1

#define	BL_ATTACKTIME		50

static void balloon_playereye(void)
{

	short Yold = obj_angleY;
	short angleadd;

	if ( obj_timer == 0 ){
		if ( obj_programselect )	balloon_eyetimer = 200;
		else						balloon_eyetimer = 120;

		balloon_eyedata 	 = 0;
		balloon_flag  		 = 0;
		balloon_subtimer	 = 0;
	}


	s_chase_obj_angle(execstp,player1stp,stw_angleY,0x800);
	s_chase_obj_angle(execstp,player1stp,stw_angleX,0x400);

	/*------- angle addition ----------*/

	angleadd = Yold-(short)obj_angleY;
	if ( angleadd == 0 ){
		balloon_eyedata	= 0;
		balloon_flag	= 0;
	} else if ( angleadd > 0 ){
		if ( balloon_flag > 0 )		balloon_eyedata += angleadd;
		else 						balloon_eyedata = 0;
		balloon_flag = 1;
	} else {
		if ( balloon_flag < 0 )		balloon_eyedata -= angleadd;
		else 						balloon_eyedata = 0;
		balloon_flag = -1;
	}

	if ( balloon_eyedata == 0 ) balloon_eyetimer = BL_MEMAWASHI_TIME;
	if ( balloon_eyedata > BL_MEMAWASHI_ANGLE ){
		obj_mode = mode_balloon_eyedamage;
	}

	balloon_eyetimer--;
	if ( balloon_eyetimer == 0 ){
		balloon_eyetimer = BL_MEMAWASHI_TIME;
		balloon_eyedata	 = 0;
	}

	/*---------------------------------*/


	/*===== balloon fireshot ======*/

	if ( balloon_eyedata < 5000 ){
		if ( balloon_subtimer == balloon_random    )	balloon_wink = 1;
		if ( balloon_subtimer == balloon_random+20 ){
			balloon_makefire();
		 	balloon_subtimer = 0;
			balloon_random   = Randomf()*BL_ATTACKTIME + BL_ATTACKTIME;
		}
	 	balloon_subtimer++;
	} else {
	 	balloon_subtimer = 0;
		balloon_random   = Randomf()*BL_ATTACKTIME + BL_ATTACKTIME;
	}

	/*---------------------------------*/

	if ( obj_playerdist >  800 )		obj_mode = mode_balloon_roll;

}


/********************************************************************************
			 roll
 ********************************************************************************/


#define	BL_SHOTTIME_START	30
#define	BL_SHOTTIME_FIRE	60
#define	BL_SHOTTIME_RESET	0


static void balloon_roll(void)
{

	short targetangle	= s_calc_targetangle(execstp,player1stp);

	short dangle1		= s_calc_dangle(obj_angleY,targetangle);
	short dangle2 		= s_calc_dangle(obj_angleY	,player1stp->s[stw_animeangleY].d);

	if ( obj_timer == 0 ){
		s_hitON();
		obj_angleX 	= 0;
		balloon_subtimer 	= BL_SHOTTIME_START;
		balloon_random   	= Randomf()*20;
		if (balloon_random & 1)	obj_anglespeedY = -0x100;
		else					obj_anglespeedY = 0x100;
	}

	if ( dangle1 < 0x400 && dangle2 > 0x4000 ){
			if ( obj_playerdist <  700 )		obj_mode = mode_balloon_playereye;
			else								balloon_subtimer++;
	} else {
	 	obj_angleY += obj_anglespeedY;
		balloon_subtimer = BL_SHOTTIME_START;
	}

	/*===== balloon fireshot ======*/

	if ( balloon_subtimer == (   BL_SHOTTIME_FIRE+balloon_random) )	balloon_wink = 1;
	if ( balloon_subtimer  > (20+BL_SHOTTIME_FIRE+balloon_random) ){
		balloon_subtimer = BL_SHOTTIME_RESET;
		balloon_random   	= Randomf()*80;
		balloon_makefire();
	}

}

/********************************************************************************
			init
 ********************************************************************************/
static void balloon_init(void)
{
	s_set_angle(execstp,0,0,0);
	s_set_scale(obj_programselect+1);
	if ( obj_timer == 0 )	s_copy_initpos();	
	if ( obj_playerdist <  1500 ) obj_mode = mode_balloon_roll;

}


/********************************************************************************
			balloon main program
 ********************************************************************************/

static void *balloon_modejmp[] = {
	
	 balloon_init,
	 balloon_roll,
	 balloon_playereye,
	 balloon_eyedamage
	
};

#define	BL_DAMAGE_R		100
#define	BL_DAMAGE_H		150

static HitCheckRecord balloon_hit = {
	OBJNAME_DAMAGE,
	0,2,2,5,	/* flag,ap,hp,coin 		 */
	 80,150,	/* damage check	*/
	  0,  0,
};

extern void s_balloon(void)
{

	
	s_set_hitparam(execstp,&balloon_hit);
	s_modejmp(balloon_modejmp);

	if ( obj_mode != mode_balloon_eyedamage ){
		if ( obj_playerdist > 3000 ||
			execstp->status   & OBJECT_AREAOUT 	) obj_mode = mode_balloon_init;
	}

	obj_mail = 0;
}

/*################*/
#endif
/*################*/
/*===============================================================================
		end end end end end end end end 
===============================================================================*/



