/********************************************************************************
					-------------------------
				 	 Ultra 64 MARIO Brothers
					-------------------------
					   S_oneup_kinoko Item Strategy

					March 31 1996       programed by Iwamoto Daiki
 ********************************************************************************/

/*################*/
#ifdef ASSEMBLER
/*################*/

/*==============================================================================
						Path Data
 ===============================================================================*/

e_1up_kinoko:
	p_initialize(item)
	p_setbit(flag,stf_moveON| stf_playerangleON)
	p_softspritemodeON
	p_sethitbox2(30,30,0)
	p_setf(animepositionY,30)
	p_program(s_1up_kinoko_init)

	p_while
		p_program(s_1up_kinoko_main)
	p_loop

e_1up_kinoko_escape:
	p_initialize(item)
	p_setbit(flag,stf_moveON| stf_playerangleON)
	p_softspritemodeON
	p_sethitbox2(30,30,0)
	p_setf(animepositionY,30)
	p_program(s_1up_kinoko_init)

	p_while
		p_program(s_1up_kinoko_escape_main)
	p_loop

e_1up_kinoko_slider:
	p_initialize(item)
	p_setbit(flag,stf_moveON)
	p_softspritemodeON
	p_sethitbox2(30,30,0)
	p_setf(animepositionY,30)
	p_program(s_1up_kinoko_init)

	p_while
		p_hitON
		p_program(s_1up_kinoko_slider_main)
	p_loop

e_1up_kinoko_stop:
	p_initialize(item)
	p_setbit(flag,stf_moveON)
	p_softspritemodeON
	p_sethitbox2(30,30,0)
	p_setf(animepositionY,30)
	p_program(s_1up_kuppa_init)

	p_while
		p_hitON
		p_program(s_1up_kinoko_stop_main)
	p_loop


e_1up_kinoko_set:
	p_initialize(item)
	p_setbit(flag,stf_moveON| stf_playerangleON)
	p_softspritemodeON
	p_sethitbox2(30,30,0)
	p_setf(animepositionY,30)
	p_program(s_1up_kinoko_init)

	p_while
		p_hitON
		p_program(s_set_1up_kinoko_main)
	p_loop


/*--------------------------------------------------------------------*/
e_1up_kinoko_secret:
	p_initialize(item)
	p_setbit(flag,stf_moveON| stf_playerangleON)
	p_softspritemodeON
	p_sethitbox2(30,30,0)
	p_setf(animepositionY,30)
	p_program(s_1up_kinoko_init)

	p_while
		p_hitON
		p_program(s_1up_kinoko_secret_main)
	p_loop


e_dummy_kinoko:
	p_initialize(item)
	p_setbit(flag,stf_moveON)
	p_sethitbox(100,100)
	p_hitON

	p_while
		p_program(s_dummy_kinoko)
	p_loop

/*--------------------------------------------------------------------*/
e_1up_secret_chase:
	p_initialize(item)
	p_setbit(flag,stf_moveON| stf_playerangleON)
	p_softspritemodeON
	p_sethitbox2(30,30,0)
	p_setf(animepositionY,30)
	p_program(s_1up_kinoko_init)

	p_while
		p_hitON
		p_program(s_1up_secret_chase_main)
	p_loop

e_dummy_kinoko_chase:
	p_initialize(item)
	p_setbit(flag,stf_moveON)
	p_sethitbox(100,100)
	p_hitON

	p_while
		p_program(s_dummy_kinoko_chase)
	p_loop

/*--------------------------------------------------------------------*/

e_1up_secret_tate:
	p_initialize(item)
	p_setbit(flag,stf_moveON)

	p_while
		p_program(s_1up_secret_tate_main)
	p_loop

/*--------------------------------------------------------------------*/



#if 0

e_item_test:
	p_initialize(item)
	p_setbit(flag,stf_moveON)

	p_while
		p_program(s_item_test)
	p_loop
#endif

/*################*/
#else
/*################*/


/*==================================================================================================
		C Program
 ===================================================================================================*/

/*==================================================================================================
		1 Up Kinoko
 ===================================================================================================*/
#define iup_kinoko_SPEED		30

/***************************************************************************************************
						Player Hit
***************************************************************************************************/
static void OneUp_kinoko_Hit(void)
{
	char i;

	if ( s_hitcheck(execstp,player1stp) == 1  ){
			Na_FixSeFlagEntry(NA_SE2_ONEUP);
			(marioWorks->nlifes)++;
			execstp->status = 0;
			SendMotorEvent(5,80);		/* MOTOR 1997.5.30 */

	}


}
/***************************************************************************************************
						    init
***************************************************************************************************/
extern void s_1up_kinoko_init(void)
{

	obj_angleX = -0x4000;

	execstp->s[stw_gravity].f   = 3.0;
	execstp->s[stw_friction].f  = 1.0;
	execstp->s[stw_specificG].f = 1.0;

}
/***************************************************************************************************
						    1up Kuppa init
***************************************************************************************************/
extern void s_1up_kuppa_init(void)
{

	s_1up_kinoko_init();

	if (obj_programselect == 1) {
		if ((BuGetItemFlag() & BU_ITEM_KILLKOOPA1) == 0) {
			execstp->status = 0;
		}
	}
	else if (obj_programselect == 2) {
		if ((BuGetItemFlag() & BU_ITEM_KILLKOOPA2) == 0) {
			execstp->status = 0;
		}
	}

}
/***************************************************************************************************
					1up_kinoko Apeear
***************************************************************************************************/
static void OneUp_kinoko_Appear(void)
{

	if (obj_timer < 5 ) {
		obj_speedY = 40;

	}
	else {
		obj_anglespeedX = -0x1000;
		obj_angleX += obj_anglespeedX;

		obj_speedY = iup_kinoko_SPEED*(cos(obj_angleX))+2;
		obj_speedF = iup_kinoko_SPEED*(-sin(obj_angleX));
	}

}

/***************************************************************************************************
					1up_kinoko Get
***************************************************************************************************/
static void OneUp_kinoko_Get(void)
{
	float dx = player_posX - obj_worldX;
	float dy = (player_posY+120) - obj_worldY;
	float dz = player_posZ - obj_worldZ;
	short targetAngleX = atan(sqrtf(dx*dx + dz*dz),dy);
	
	s_chase_obj_angle(execstp,player1stp,stw_angleY,0x1000);
 	obj_angleX = s_chase_angle(execstp->s[stw_angleX].d,targetAngleX,0x1000);

	obj_speedY = iup_kinoko_SPEED*(sin(obj_angleX));
	obj_speedF = iup_kinoko_SPEED*(cos(obj_angleX));


	OneUp_kinoko_Hit();
	
}

/***************************************************************************************************
					1up_kinoko Escape
***************************************************************************************************/
static void OneUp_kinoko_Escape(short move_flag)
{

	obj_speedF = 8;

	obj_angleY = obj_targetangle + 0x8000;

	
	OneUp_kinoko_Hit();

	if (move_flag & OM_WALL) { obj_mode = 2; }


	if (PlayerApproach(obj_worldX,obj_worldY,obj_worldZ,3000)==0) {
		obj_mode = 2;

	}	
}


/*==================================================================================================
		1 Up Kinoko 
 ===================================================================================================*/
/***************************************************************************************************
						    Main
***************************************************************************************************/
extern void s_1up_kinoko_main(void)
{
	ObjMoveEvent();

	switch (obj_mode) {
		case 0 : if (obj_timer > 17) { s_makeobj_nowpos(execstp,S_NULL,e_twinkle_special); } 
				 if (obj_timer == 0) Na_FixSeFlagEntry(NA_SE2_ONEUP_APPEAR);
				 OneUp_kinoko_Appear();
				 if (obj_timer == (32+5)) {
					s_hitON();
					obj_mode = 1;
					obj_speedF = 2;
				}
				break;

		case 1: if (obj_timer > FRAME*10) {
					obj_mode = 2;
				}	
				OneUp_kinoko_Hit();
				break;

		case 2: iwa_TimerRemove(execstp,30);
				OneUp_kinoko_Hit();
				break;
	}


	PlayerApproachOnOff(execstp,3000);


}







/*==================================================================================================
		1 Up Kinoko Escape
 ===================================================================================================*/
/***************************************************************************************************
						    Main
***************************************************************************************************/
extern void s_1up_kinoko_escape_main(void)
{
	short move_flag = ObjMoveEvent();

	switch (obj_mode) {
		case 0 : if (obj_timer > 17) { s_makeobj_nowpos(execstp,S_NULL,e_twinkle_special); } 
				 if (obj_timer == 0) Na_FixSeFlagEntry(NA_SE2_ONEUP_APPEAR);
				 OneUp_kinoko_Appear();
				 if (obj_timer == (32+5)) {
					s_hitON();
					obj_mode = 1;
					obj_speedF = 8;
				}
				break;

		case 1: s_makeobj_nowpos(execstp,S_NULL,e_twinkle_special);
				OneUp_kinoko_Escape(move_flag);
				break;

		case 2: iwa_TimerRemove(execstp,30);
				OneUp_kinoko_Hit();
				break;
	}


	PlayerApproachOnOff(execstp,3000);


}


/*==================================================================================================
		1 Up Kinoko Slider
 ===================================================================================================*/

/***************************************************************************************************
						    Slider
***************************************************************************************************/
static void OneUp_kinoko_Slider(void)
{
	short move_flag = ObjMoveEvent();

	if (move_flag & OM_TOUCH) {
			 execstp->s[stw_speedF].f += 25;
			 execstp->s[stw_speedY].f = 0;
		}
		else { execstp->s[stw_speedF].f *= 0.98; }

	if (execstp->s[stw_speedF].f > 40.0) { execstp->s[stw_speedF].f = 40.0; }

	if (PlayerApproach(obj_worldX,obj_worldY,obj_worldZ,5000)==0) {
		obj_mode = 2;

	}	


}
/***************************************************************************************************
						    Main
***************************************************************************************************/
extern void s_1up_kinoko_slider_main(void)
{

	switch (obj_mode) {
		case 0 : PlayerApproachOnOff(execstp,3000);
				 if (PlayerApproach(obj_worldX,obj_worldY,obj_worldZ,1000)) {
					obj_mode = 1;

				 }	
 				 break;

		case 1 : OneUp_kinoko_Slider();
				 break;

		case 2: iwa_TimerRemove(execstp,30);
				OneUp_kinoko_Hit();
				break;
	}

	OneUp_kinoko_Hit();
	

	s_makeobj_nowpos(execstp,S_NULL,e_twinkle_special);


}

/*==================================================================================================
		1 Up Kinoko Stop
 ===================================================================================================*/
/***************************************************************************************************
						    Main
***************************************************************************************************/
extern void s_1up_kinoko_stop_main(void)
{


	OneUp_kinoko_Hit();
	PlayerApproachOnOff(execstp,3000);

}

/*==================================================================================================
		Set 1 Up Kinoko 
 ===================================================================================================*/
/***************************************************************************************************
						    Main
***************************************************************************************************/
extern void s_set_1up_kinoko_main(void)
{


	short move_flag;

	switch (obj_mode) {
		case 0 : if (PlayerApproach(obj_worldX,obj_worldY,obj_worldZ,1000)) {
					obj_speedY = 40;
					obj_mode = 1;
				}
				break;

		case 1: move_flag = ObjMoveEvent();
				/*OneUp_kinoko_Get(); */
				OneUp_kinoko_Escape(move_flag);
				s_makeobj_nowpos(execstp,S_NULL,e_twinkle_special);
				break;

		case 2: move_flag = ObjMoveEvent();
				OneUp_kinoko_Hit();
				iwa_TimerRemove(execstp,30);
				break;
	}


	PlayerApproachOnOff(execstp,3000);
}

/*==================================================================================================
		 1 Up Kinoko secret
 ===================================================================================================*/
#define kinoko_dummyFlag	(execstp->s[stw_work0].d)

/***************************************************************************************************
						    Main
***************************************************************************************************/
extern void s_1up_kinoko_secret_main(void)
{


	short move_flag;

	switch (obj_mode) {
		case 0 : MapHideShape(&execstp->map);
				 if (kinoko_dummyFlag == obj_programselect) {
					obj_speedY = 40;
					obj_mode = 3;
					MapDispShape(&execstp->map);
					Na_FixSeFlagEntry(NA_SE2_ONEUP_APPEAR);
				}
				break;

		case 1: move_flag = ObjMoveEvent();
				OneUp_kinoko_Escape(move_flag);
				s_makeobj_nowpos(execstp,S_NULL,e_twinkle_special);
				break;

		case 2: move_flag = ObjMoveEvent();
				OneUp_kinoko_Hit();
				iwa_TimerRemove(execstp,30);
				break;

		case 3 : move_flag = ObjMoveEvent();
				 if (obj_timer > 17) { s_makeobj_nowpos(execstp,S_NULL,e_twinkle_special); } 
				 OneUp_kinoko_Appear();
				 if (obj_timer == (32+5)) {
					s_hitON();
					obj_mode = 1;
					obj_speedF = 8;
				}
				break;
	}


}


/***************************************************************************************************
						Dummy Get 1up Kinoko
***************************************************************************************************/
extern void s_dummy_kinoko() {

	if (  s_hitcheck(execstp,player1stp) == 1 ){
		StrategyRecord* stratp = s_find_obj(e_1up_kinoko_secret);
		if (stratp != NULL) {
			(stratp->s[stw_work0].d) += 1;
		}

		execstp->status = 0;
		
	}

}



/*==================================================================================================
		 1 Up Kinoko secret 2
 ===================================================================================================*/
/***************************************************************************************************
						    Main
***************************************************************************************************/
extern void s_1up_secret_chase_main(void)
{


	short move_flag;

	switch (obj_mode) {
		case 0 : MapHideShape(&execstp->map);
				 if (kinoko_dummyFlag == obj_programselect) {
					obj_speedY = 40;
					obj_mode = 3;
					MapDispShape(&execstp->map);
					Na_FixSeFlagEntry(NA_SE2_ONEUP_APPEAR);
				}
				break;

		case 1: OneUp_kinoko_Get();
				move_flag = ObjMoveEvent();
				break;

		case 3 : move_flag = ObjMoveEvent();
				 if (obj_timer > 17) { s_makeobj_nowpos(execstp,S_NULL,e_twinkle_special); } 
				 OneUp_kinoko_Appear();
				 if (obj_timer == (32+5)) {
					s_hitON();
					obj_mode = 1;
					obj_speedF = 10;
				}
				break;
	}
}

/***************************************************************************************************
						Dummy Get 1up Kinoko 2
***************************************************************************************************/
extern void s_dummy_kinoko_chase() {

	if (  s_hitcheck(execstp,player1stp) == 1 ){
		StrategyRecord* stratp = s_find_obj(e_1up_secret_chase);
		if (stratp != NULL) {
			(stratp->s[stw_work0].d) += 1;
		}

		execstp->status = 0;
		
	}

}




/*==================================================================================================
		 1 Up Kinoko secret Tate
 ===================================================================================================*/
/***************************************************************************************************
					 1up Kinoko Secret (Tate)
***************************************************************************************************/
extern void s_1up_secret_tate_main() {

	char i;

	if (PlayerApproach(obj_worldX,obj_worldY,obj_worldZ,700)) {

		s_makeobj_chain(2, 0, 50, 0,execstp,S_oneup_kinoko,e_1up_secret_chase);
		for (i=0; i<2; i++) s_makeobj_chain(0, 0, -200*i, 0,execstp,S_NULL,e_dummy_kinoko_chase);

		execstp->status = 0;

	}


}




#if 0
/***************************************************************************************************
						    Test
***************************************************************************************************/
extern void s_item_test(void)
{
	StrategyRecord *stratp;

	if (contOr->trigger & CONT_L) {

		stratp = s_makeobj_nowpos(execstp,	S_itemhat_hat ,e_itemhat_blow);
		stratp->s[stw_worldX].f = player_posX;
		stratp->s[stw_worldY].f = player_posY+160;
		stratp->s[stw_worldZ].f = player_posZ;

		stratp->s[stw_angleY].d = player_angleY;

		stratp->s[stw_speedY].f = 10;
		stratp->s[stw_speedF].f = 20;
	}

}

#endif


/*################*/
#endif
/*################*/


