/********************************************************************************
					-------------------------
				 	 Ultra 64 MARIO Brothers
					-------------------------
					    Strategy

				Feburary 31 1996       programed by Iwamoto Daiki
 ********************************************************************************/

/*################*/
#ifdef ASSEMBLER
/*################*/

/********************************************************************************
						Path Data
 ********************************************************************************/

e_ring:
	p_initialize(option)
	p_shapeOFF
	p_while
		p_program(s_ring_main)
	p_loop



e_ring_parts:
	p_initialize(item)
	p_setbit(flag,stf_moveON)
	p_set_pointer(skelanime,ring_anime)
	p_sethitbox2(75,20,20)
	p_setobjname(RECOVER)
	p_setd(ap,2)
	p_hitON
	p_program(s_ring_init)

	p_while
		p_hitON
		p_program(s_ring_event)
	p_loop

e_manta_ring:
	p_initialize(item)
	p_setbit(flag,stf_moveON)
	p_set_pointer(skelanime,ring_anime)
	p_sethitbox2(75,20,20)
	p_setobjname(RECOVER)
	p_setd(ap,2)
	p_hitON
	p_program(s_manta_ring_init)

	p_while
		p_hitON
		p_program(s_manta_ring_main)
	p_loop


e_ring_dummy:
	p_initialize(option)

	p_while
	p_loop


/*################*/
#else
/*################*/


/***************************************************************************************************
		C Program
 ****************************************************************************************************/
#define RING_R	120

#define ring_scalex		(execstp->s[stw_work0].d)
#define ring_scaley		(execstp->s[stw_work1].d)
#define ring_scalez		(execstp->s[stw_work2].d)
#define ring_vectorX	(execstp->s[stw_work3].f)
#define ring_vectorY	(execstp->s[stw_work4].f)
#define ring_vectorZ	(execstp->s[stw_work5].f)
#define be_inter		(execstp->s[stw_work6].f)
#define ringNo			(execstp->s[stw_work7].d)
#define ring_scale		(execstp->s[stw_work8].f)


#define ring_count		(ring_dstp->s[stw_work0].d)
#define be_ringNo		(ring_dstp->s[stw_work1].d)


/***************************************************************************************************
						Ring Inter  (Housen vector)
***************************************************************************************************/
static float ring_inter(void)
{
	float plX = (obj_worldX - player_posX);
	float plY = (obj_worldY - (player_posY+80));
	float plZ = (obj_worldZ - player_posZ);
	float inter;
	
	inter = plX*ring_vectorX + plY*ring_vectorY + plZ*ring_vectorZ;

	return(inter);
}
/***************************************************************************************************
						Ring Init
***************************************************************************************************/
static void ring_main_init(void)
{
	stSetSkelAnimeNumber(0);

	ring_scalex = (int)(Randomf()*0x1000)+0x1000;
	ring_scaley = (int)(Randomf()*0x1000)+0x1000;
	ring_scalez = (int)(Randomf()*0x1000)+0x1000;

	ring_vectorX = cos(obj_animeangleX)*sin(obj_animeangleZ)*-1;
	ring_vectorY = cos(obj_animeangleX)*cos(obj_animeangleZ);
	ring_vectorZ = sin(obj_animeangleX);

	be_inter = ring_inter();


}
/***************************************************************************************************
						Ring Init
***************************************************************************************************/
extern void s_ring_init(void)
{
	ring_main_init();

	execstp->s[stw_alpha].d = 70;
	stSetSkelAnimeNumber(0);
	
	execstp->s[stw_animeangleX].d = 0x8000;

}
/***************************************************************************************************
						Ring & Player Check
***************************************************************************************************/
static void RingPlayerCheck(float scale,StrategyRecord* ring_dstp)
{
	float inter = ring_inter();

	
	if (ObjApproach(execstp,player_posX,player_posY+80,player_posZ,(RING_R)*(scale+0.2))==0) { 
		be_inter = inter;
		return; 
	}

	if ( inter*be_inter < 0) {
		StrategyRecord* stratp = execstp->motherobj;
		if (stratp != NULL) {
			if (ringNo == be_ringNo+1 || (stratp->s[stw_work8].d)==0 ) {
				(stratp->s[stw_work8].d) += 1;
				if ( (stratp->s[stw_work8].d) < 6) { 
					AppNumber( (char) (stratp->s[stw_work8].d),0,-40,0 );
					Na_SecretPointSe((u8)(stratp->s[stw_work8].d));
				}

				be_ringNo = ringNo;
			}
			else {
				(stratp->s[stw_work8].d) = 0;
			}
	
		}
		obj_mode = 1;
	}

	be_inter = inter;


}
/***************************************************************************************************
						Ring Scaling
***************************************************************************************************/
static void RingScaling(float scale)
{


	execstp->map.scale[0] = sin(ring_scalex)*0.1 + scale;
	execstp->map.scale[1] = sin(ring_scaley)*0.5 + scale;
	execstp->map.scale[2] = sin(ring_scalez)*0.1 + scale;

	ring_scalex += (int)0x1700;
	ring_scaley += (int)0x1700;
	ring_scalez += (int)0x1700;




}
/***************************************************************************************************
						Ring Remove
***************************************************************************************************/
static void RingRemove(void)
{

	float scale = ((float)obj_timer)*0.2+ring_scale;
	

	if (obj_timer > 20) {
		execstp->status = 0;
	}

	(execstp->s[stw_alpha].d) -= 10;
	if (execstp->s[stw_alpha].d < 0) execstp->s[stw_alpha].d = 0;

	RingScaling(scale);

}



/***************************************************************************************************
						Ring Event
***************************************************************************************************/
extern void RingEvent(void)
{

	float scale = ((float)obj_timer/225.) * 3.0 + 0.5;
	StrategyRecord* stratp = execstp->motherobj;
	StrategyRecord* ring_dstp =  stratp->motherobj;

	
	if (obj_timer > 225 ) {
		(execstp->s[stw_alpha].d) -= 2;
		if (execstp->s[stw_alpha].d < 3) execstp->status = 0;		
	}

	RingPlayerCheck(scale,ring_dstp);
	RingScaling(scale);

	execstp->s[stw_worldY].f += 10;
	execstp->s[stw_animeangleY].d += 0x100;


	PlayerApproachOnOff(execstp,5000);

	if (stratp->s[stw_work8].d == 4 && ringNo == be_ringNo+1) {
		execstp->s[stw_alpha].d = 50+sin(obj_timer*0x1000)*200;
	}

	ring_scale = scale;
	
}
/***************************************************************************************************
						Manta Ring Main
***************************************************************************************************/
extern void s_ring_event(void)
{

	switch (obj_mode) {

		case 0: RingEvent();
				break;

		case 1: RingRemove();
				break;
	}
	
}






/*================================ Ring Parent =======================================================*/
#define ring_star_flag 	(execstp->s[stw_work8].d)

#define RING_STARX	 3400
#define RING_STARY	-3200
#define RING_STARZ	 -500
/***************************************************************************************************
						Ring init
***************************************************************************************************/
extern void s_ring_oya_init(void)
{
	StrategyRecord* ring_dstp = s_makeobj_nowpos(execstp,S_NULL,e_ring_dummy);

	execstp->motherobj = ring_dstp;
}
/***************************************************************************************************
						Ring Main
***************************************************************************************************/
extern void oya_ring_make(void)
{
	StrategyRecord* ring_dstp =  execstp->motherobj;
	
	if (obj_timer == 300) obj_timer = 0;
	if (obj_timer == 0 || obj_timer == 50 || obj_timer == 150 || obj_timer == 200 || obj_timer == 250 ) {	
		StrategyRecord* stp = s_makeobj_nowpos(execstp,S_ring,e_ring_parts);
		stp->s[stw_work7].d = ring_count;
		ring_count++;

		if (ring_count > 10000) ring_count = 0;
	}



}
/***************************************************************************************************
						Ring Main
***************************************************************************************************/
extern void s_ring_main(void)
{

	switch (obj_mode) {
		case 0: oya_ring_make();
				if (ring_star_flag == 5) {
					s_kemuri();
					s_enemyset_star(RING_STARX,RING_STARY,RING_STARZ);
					obj_mode = 1;
				}
				break;

		case 1: break;
	}
}



/*================================================================================================
							Manta Ring

==================================================================================================*/

/***************************************************************************************************
						Ring Init
***************************************************************************************************/
extern void s_manta_ring_init(void)
{
	ring_main_init();

	execstp->s[stw_alpha].d = 150;

}
/***************************************************************************************************
						Manta Ring Event
***************************************************************************************************/
static void manta_RingEvent(void)
{

	float scale = ((float)obj_timer/(50))*1.3+0.1;
	StrategyRecord* stratp = execstp->motherobj;
	StrategyRecord* ring_dstp =  stratp->motherobj;

	if (scale >1.3) {
		scale = 1.3;
	}


	if (obj_timer > 150 ) {
		(execstp->s[stw_alpha].d) -= 2;
		if (execstp->s[stw_alpha].d < 3) execstp->status = 0;		
	}

	RingPlayerCheck(scale,ring_dstp);


	RingScaling(scale);
	PlayerApproachOnOff(execstp,5000);


	if (stratp->s[stw_work8].d == 4 && ringNo == be_ringNo+1) {
		execstp->s[stw_alpha].d = 50+sin(obj_timer*0x1000)*200;
	}

	ring_scale = scale;
}
/***************************************************************************************************
						Manta Ring Main
***************************************************************************************************/
extern void s_manta_ring_main(void)
{

	switch (obj_mode) {

		case 0: manta_RingEvent();
				break;

		case 1: RingRemove();
				break;
	}


	
}



/*################*/
#endif
/*################*/


