/********************************************************************************
					-------------------------
				 	 Ultra 64 MARIO Brothers
					-------------------------
					   New Bom hei Strategy

				Junuary 31 1996       programed by Iwamoto Daiki
 ********************************************************************************/

/*################*/
#ifdef ASSEMBLER
/*################*/

/********************************************************************************
		e new bom hei
 ********************************************************************************/

e_newbom:
	p_initialize(plfire)
	p_setbit(flag,stf_moveON| stf_YangleSAME | stf_catchON | stf_playerangleON| stf_playerdistON| stf_NOramsave)
	p_set_pointer(skelanime,RCP_new_BomAnime)
	p_BGcheckYset
	p_set_skelanime_number(0)
	p_hitON
	p_save_nowpos
	p_program(s_newbom_init)

	p_while
		p_program(s_newbom_main)
	p_loop

e_bom_pusu:
	p_initialize(option)
	p_setbit(flag,stf_moveON )
	p_softspritemodeON
	p_animereset
	p_program(s_bom_pusu_init)

	p_wait(1)
	p_while
		p_program(s_samplesmoke_main)
		p_animeinc
	p_loop


/*--------------------------------------------------------------------------------*/
e_messbom:
	p_initialize(enemyA)
	p_setbit(flag,stf_moveON| stf_YangleSAME | stf_catchON |stf_playerdistON | stf_playerangleON)
	p_set_pointer(skelanime,RCP_new_BomAnime)
	p_setobjname(FRIEND)
	p_BGcheckYset
	p_sethitbox(100,60)
	p_set_skelanime_number(0)
	p_setd(work2,0)
	p_save_nowpos
	p_program(s_messbom_init)

	p_while
		p_hitON
		p_program(s_mess_bom_main)
	p_loop


e_futa_bom:
	p_initialize(enemyA)
	p_setbit(flag,stf_moveON| stf_YangleSAME | stf_catchON |stf_playerdistON | stf_playerangleON | stf_NOramsave)
	p_set_pointer(skelanime,RCP_new_BomAnime)
	p_setobjname(FRIEND)
	p_BGcheckYset
	p_sethitbox(100,60)
	p_set_skelanime_number(0)
	p_setd(work2,1)
	p_save_nowpos
	p_program(s_messbom_init)

	p_while
		p_hitON
		p_program(s_mess_bom_main)
	p_loop

/*---------------- Bom Futa ------------------------------------------------*/

e_bom_cannon:
	p_initialize(moveBG)
	p_setbit(flag,stf_moveON| stf_NOramsave)
	p_setshapeinfo(bom_futa_check_info)
	p_save_nowpos
	p_program(s_bom_cannon_make)

	p_while
		p_program(s_bom_cannon_main)
		p_program(stMainMoveBG)
	p_loop

/*################*/
#else
/*################*/


/***************************************************************************************************
		C Program
 ****************************************************************************************************/
#define BOMBTIME		 150
#define newbom_eyetimer  (execstp->s[stw_work0].d)
#define bombard_switch	 (execstp->s[stw_work1].d)
#define bombard_timer	 (execstp->s[stw_work2].d)

#define bom_be_worldX	 (execstp->s[stw_work5].f)
#define bom_be_worldY	 (execstp->s[stw_work6].f)
#define bom_be_worldZ	 (execstp->s[stw_work7].f)

static HitCheckRecord newbom_hit = {
	OBJNAME_TAKE,
	  0,0,0,0,			/* flag,hp,ap,coin 		 */
	 65,113,			/* player attack hitarea */
	 0 ,0  ,			/* player damege hitarea */
};

/***************************************************************************************************
						Bom Initialize
***************************************************************************************************/
extern void s_newbom_init(void)
{
	execstp->s[stw_gravity].f   = 2.5;
	execstp->s[stw_friction].f  = 0.8;
	execstp->s[stw_specificG].f = 1.3;
	
	execstp->s[stw_enemyinfo].d = ENEMYINFO_BOMB;

}
/***************************************************************************************************
						NewBom Bomber Event
***************************************************************************************************/
static void NewBomCoinCheck(void)
{
	if (((execstp->s[stw_actorcode].d >> 8) & 0x01)==0) {
		iwa_MakeCoin(execstp,1);

		execstp->s[stw_actorcode].d = 0x01<<8;
		st_ramsave(execstp,1);
	}

}
/***************************************************************************************************
						NewBom Bomber Event
***************************************************************************************************/
static void NewBomBomber(void)
{

	if (obj_timer < 5) {
		s_set_scale((float)obj_timer/5.0 + 1.0);
	}
	else {
		StrategyRecord *stp = s_makeobj_nowpos(execstp,S_bombfire,e_bombfire);
		stp->s[stw_animepositionY].f += 100;

		NewBomCoinCheck();
		Obj_reset(S_blackbom,e_newbom,3000);
		execstp->status = 0;		/* s_removeobj */	/* object remove */
	}
}
/***************************************************************************************************
						Bom Hit Check
***************************************************************************************************/
static void BomHitCheck(void)
{

	s_set_hitparam(execstp,&newbom_hit);		/* Set HitCheck Param */
	
	if ( obj_mail & EMAIL_PLAYERHIT ){
		if ( obj_mail & EMAIL_PLAYER_KICK  ) {
				obj_angleY = player_angleY;
				obj_speedF = 25;
				obj_speedY = 30;
				obj_mode = 1;
		}
		if ( obj_mail & EMAIL_BOMB  ) {
			obj_mode = 3;
		}

		Mbitclr(obj_mail,EMAIL_PLAYERHITALL);
	}

	if (s_fire_hitcheck(execstp)==1) {
		obj_mode = 3;
	}

}
/***************************************************************************************************
						NewBom Move Event
***************************************************************************************************/
static void NewBomMove(void)
{
	Plane *plane;
	short anim_frame = execstp->map.skelanim.frame;
	short bg_flag;

	execstp->s[stw_speedF].f = 5.;
	bg_flag = ObjMoveEvent();	
	
	if (ShapePatrol(execstp,obj_attX,obj_attY,obj_attZ,400)==1 && ShapeSameAngle(obj_angleY,obj_targetangle,0x2000)==1) {
		bombard_switch = 1;
		obj_mode = 2;
	}

	ObjDangerCheck(bg_flag,moveobj_bgcp);

}
/***************************************************************************************************
						NewBom Anger Event
***************************************************************************************************/
static void NewBomAnger(void)
{
	Plane *plane;
	short anim_frame = execstp->map.skelanim.frame += 1;
	short bg_flag;

	execstp->s[stw_speedF].f = 20.;
	bg_flag = ObjMoveEvent();	
	
	if (anim_frame==5 || anim_frame==16) objsound(NA_SE3_BOMBHEI_WALK);  	

	s_chase_obj_angle(execstp,player1stp,stw_angleY,0x800);

	ObjDangerCheck(bg_flag,moveobj_bgcp);
}
/***************************************************************************************************
						NewBom Throw Event
***************************************************************************************************/
static void NewBomThought(void)
{
	short bg_flag = 0;
		
	bg_flag = ObjMoveEvent();

	if ((bg_flag & 0x01) == 1) {
		obj_mode = 3;
	}


}
/***************************************************************************************************
						NewBom Consider Event
***************************************************************************************************/
static void MoveNewBomConsiderEvent(void)
{

	switch (obj_mode) {
		case 0:	NewBomMove();			break;
		case 1:	NewBomThought(); 		break;
		case 2: NewBomAnger();			break;
		case 3: NewBomBomber();			break;

		case OBJ_MELT : if (ObjMeltEvent()==1) {
							Obj_reset(S_blackbom,e_newbom,3000);
						}  
						break;
		case OBJ_AIRDEAD : execstp->status = 0; 
						   Obj_reset(S_blackbom,e_newbom,3000);
						   break;
	}	

//	PlayerApproachOnOff(execstp,3000);
	
	BomHitCheck();
	
	if (bombard_timer > BOMBTIME) { obj_mode = 3; }

}

/***************************************************************************************************
						NewBom Consider Event
***************************************************************************************************/
static void StopNewBomConsiderEvent(void)
{

	switch (obj_mode) {
		case 1:	NewBomThought(); 		break;
		case 3: NewBomBomber();			break;

		case OBJ_MELT : if (ObjMeltEvent()==1) {
							Obj_reset(S_blackbom,e_newbom,3000);
						}  
						break;
		case OBJ_AIRDEAD : execstp->status = 0;  
						   Obj_reset(S_blackbom,e_newbom,3000);
						   break;
	}	

//	PlayerApproachOnOff(execstp,3000);
	
	BomHitCheck();

	if (bombard_timer > BOMBTIME) { obj_mode = 3; }
	
}

/***************************************************************************************************
						NewBom Consider Event
***************************************************************************************************/
static void NewBomConsiderEvent(void)
{
	if (obj_programselect == 0) MoveNewBomConsiderEvent();
	else						StopNewBomConsiderEvent();


}





/***************************************************************************************************
						NewBom Catch
***************************************************************************************************/
static void NewBomCatch(void)
{

	MapHideShape(&execstp->map);
	stSetSkelAnimeNumber(1);
	s_posoffset_mother(player1stp,0,60,100);

	bombard_switch = 1;    /* bomber_switch ON */

	if(bombard_timer > BOMBTIME) {
		player1stp->s[stw_mail].d |= PLAYERMAIL_BOMB_BURN;
		obj_mode = 3;
	}

}

/***************************************************************************************************
						NewBom Drop
***************************************************************************************************/
static void NewBomDrop(void)
{

	s_mode_drop();

	MapDispShape(&execstp->map);
	stSetSkelAnimeNumber(0);

	execstp->s[stw_actionmode].d = CHILEDMODE_NO_CATCH;
	obj_mode = 0;


}
/***************************************************************************************************
						NewBom Throw
***************************************************************************************************/
static void NewBomThrow(void)
{

	s_throw_object();	
	MapDispShape(&execstp->map);
	execstp->s[stw_actionmode].d = CHILEDMODE_NO_CATCH;
	execstp->s[stw_flag].d &= (stf_YangleSAME^0xffffffff); 
	
	execstp->s[stw_speedF].f = 25.;
	execstp->s[stw_speedY].f = 20.;
	obj_mode = 1;

}

/***************************************************************************************************
						new bom Main
***************************************************************************************************/
static void ObjEyeEvent(long* eye_timer)
{

	if (*eye_timer == 0) {
		if ((short)(Randomf()*100) == 0) {
			obj_animecounter = 1;
			*eye_timer = 1;
		}
	}
	else {
		(*eye_timer)++;
		if (*eye_timer >  5) obj_animecounter = 0;
		if (*eye_timer > 10) obj_animecounter = 1;
		if (*eye_timer > 15) {obj_animecounter = 0; *eye_timer = 0;}
	}

}
/***************************************************************************************************
						new bom Main
***************************************************************************************************/
extern void s_newbom_main(void)
{

	char fl;

if (PlayerApproach(obj_worldX,obj_worldY,obj_worldZ,4000)) {

	switch(execstp->s[stw_actionmode].d) {
		case CHILEDMODE_NO_CATCH:	NewBomConsiderEvent();	break;
		case CHILEDMODE_CATCH:		NewBomCatch();			break;
		case CHILEDMODE_THROW:		NewBomThrow();			break;
		case CHILEDMODE_DROP:		NewBomDrop();			break;
	}

	ObjEyeEvent(&newbom_eyetimer);

	if (bombard_switch == 1) {
		if (bombard_timer > 120) fl = 0x01;
		else			   		 fl = 0x07; 	
		if ((bombard_timer & fl) == 0 )s_makeobj_nowpos(execstp,S_dust,e_bom_pusu);
		objsound_level(NA_LSE3_BOMBHEI_STEAM);
		bombard_timer++;  
	}

}
}

/*=================================================================================================*/

/***************************************************************************************************
						Bom Pusu Init
***************************************************************************************************/
extern void s_bom_pusu_init(void)
{
	
	obj_worldX += (int) (Randomf()*80)-40;
	obj_worldY += (int) (Randomf()*80)+60;
	obj_worldZ += (int) (Randomf()*80)-40;

	s_set_scale(1.2);		

}




















/*=================================================================================================*/
/*=================================================================================================*/
/*=================================================================================================*/
/*=================================================================================================*/
/*=================================================================================================*/

/*=================================================================================================
			Message Bom
===================================================================================================*/
#define NORMAL_MESS		0
#define FUTA_MESS		1


#define messbom_messNo   (execstp->s[stw_programselect].d)
#define messbom_trig     (execstp->s[stw_work1].d)
#define messbom_attFlag  (execstp->s[stw_work2].d)
#define futabom_Flag  	 (execstp->s[stw_work3].d)
/* work0 is used for eyetimer */

/***************************************************************************************************
					Mess	Bom Initialize
***************************************************************************************************/
extern void s_messbom_init(void)
{
	execstp->s[stw_gravity].f   = 2.5;
	execstp->s[stw_friction].f  = 0.8;
	execstp->s[stw_specificG].f = 1.3;
	
	execstp->s[stw_enemyinfo].d = ENEMYINFO_MESSAGE;

}
/***************************************************************************************************
						Message Bom Move Event
***************************************************************************************************/
static void MessBomMove(void)
{
	Plane *plane;
	short anim_frame = execstp->map.skelanim.frame;
	short bg_flag = 0;

	bom_be_worldX = obj_worldX;
	bom_be_worldY = obj_worldY;
	bom_be_worldZ = obj_worldZ;
	
	bg_flag = ObjMoveEvent();	

	if (anim_frame==5 || anim_frame==16) objsound(NA_SE3_BOMBHEI_WALK);  	

	if (obj_playerdist < 1000) {
	 	obj_angleY = s_chase_angle(execstp->s[stw_angleY].d,obj_targetangle,0x140);
	}

	if (execstp->s[stw_mail].d == EMAIL_PLAYERHIT) obj_mode = 2;

}
/***************************************************************************************************
						Futa Bom Event  (Futa Bomb Message Event)
***************************************************************************************************/
static void FutaBomEvent(short msg1,short msg2)
{

	StrategyRecord* stp;
	short mess_demo,futa_demo;

	switch (futabom_Flag) {

		case 0: mess_demo = cameraDemoStratMsgNum(CAM_DEMO_TALK,execstp,msg1);
//				rmonpf(("Msg_demo %d\n",mess_demo));

				if (mess_demo != 0) {
					BuSetCannonFlag();					// Canon Flag On
					if ((stp = s_find_obj(e_bom_cannon)) != NULL) {
						futabom_Flag = 1;
					}
					else futabom_Flag = 3;
				}
				break;

		case 1:	stp = s_find_obj(e_bom_cannon);
				futa_demo = cameraDemoStrat(CAM_DEMO_CANNONDOOR,stp);

//				rmonpf(("Cam_demo %d\n",futa_demo));
				if (futa_demo == -1) {
					futabom_Flag = 2;
				}
 				break;

		case 2: mess_demo = cameraDemoStratMsgNum(CAM_DEMO_TALK,execstp,msg2);
//				rmonpf(("Mess_demo %d\n",mess_demo));
				if (mess_demo != 0) {
					futabom_Flag = 3;
				}
				break;

		case 3:	CtrlPlayerDialog(DLOG_DONE);
				Mbitclr( execstp->status,OBJECT_DEMOMOVEENTRY );
				messbom_trig = 2;
				execstp->s[stw_mail].d = 0;
				obj_mode = 0;
				futabom_Flag = 2;
				break;
	}

}
/***************************************************************************************************
						Message Bom Attribute Check
***************************************************************************************************/
static void MessBomCall(void)
{

	if (CtrlPlayerDialog(DLOG_LOOKFRONT)==DLOG_RESULT_READY) {

	Mbitset( execstp->status,OBJECT_DEMOMOVEENTRY );				//kaijo only me



		switch (messbom_attFlag) {
			case NORMAL_MESS:	if (cameraDemoStratMsgNum(CAM_DEMO_TALK,execstp,messbom_messNo) != 0) {
									CtrlPlayerDialog(DLOG_DONE);
									Mbitclr( execstp->status,OBJECT_DEMOMOVEENTRY );
									messbom_trig = 2;
									execstp->s[stw_mail].d = 0;
									obj_mode = 0;
								}
								break;


			case FUTA_MESS:		if(activeCourseNo == 1)  {
									FutaBomEvent(4,105);

								}
								else	{
									FutaBomEvent(47,106);  
								}
				 				break;
		}

	}

}
/***************************************************************************************************
						Message Bom Message
***************************************************************************************************/
static void MessBomMessage(void)
{

	short anim_frame = execstp->map.skelanim.frame;

//	obj_speedF = 0;
//	ObjMoveEvent();

	if (anim_frame==5 || anim_frame==16) objsound(NA_SE3_BOMBHEI_WALK);  	

	obj_angleY = s_chase_angle(obj_angleY,obj_targetangle,0x1000);

	if ((short) obj_angleY == (short) obj_targetangle) {
		obj_mode = 3;
	}

	objsound(NA_SE1_KANBAN_READ);

}
/***************************************************************************************************
						Message Bom Consider Event
***************************************************************************************************/
static void MessBomConsiderEvent(void)
{

	switch (obj_mode) {
		case 0:	MessBomMove();			break;
		case 2: MessBomMessage();		break;
		case 3:	MessBomCall();			break;

	}	

	PlayerApproachOnOff(execstp,3000);
	


}
/***************************************************************************************************
						Message Bom Main
***************************************************************************************************/
extern void s_mess_bom_main(void)
{

	MessBomConsiderEvent();


	ObjEyeEvent(&newbom_eyetimer);

	obj_mail = 0;

}


/*-------------------------------------------------------------------------------------------------
						Bom Futa Event
---------------------------------------------------------------------------------------------------*/
#define FUTA_UP	30
#define FUTA_SLIDE	50

/***************************************************************************************************
							 Main
***************************************************************************************************/
extern void s_bom_cannon_make(void)
{

	if (BuGetCannonFlag() == 1) {
		StrategyRecord* stratp = s_makeobj_nowpos(execstp,S_cannon_base,e_cannon_base);
		stratp->s[stw_programselect].d = obj_programselect;
		stratp->s[stw_worldX].f = obj_attX;
		stratp->s[stw_worldY].f = obj_attY;
		stratp->s[stw_worldZ].f = obj_attZ;

		obj_mode = 3;
		execstp->status = 0;
	}

}
/***************************************************************************************************
						Bom Futa Open
***************************************************************************************************/
static void bomFuta_Open(void)
{
	if ( obj_timer == 0 )	objsound(NA_SE2_TAIHOUCAP_OPEN);

	if (obj_timer < FUTA_UP) {
		obj_speedY = -15./FUTA_UP;
		obj_worldY += obj_speedY;
		obj_speedX = 0;
	}

	else {
		if (obj_timer == (FUTA_SLIDE+FUTA_UP)) { 
			s_bom_cannon_make();
			return;
		}

		obj_speedX = (200./FUTA_SLIDE);
		obj_speedY = 0;
		obj_worldX += obj_speedX;

	}



}
/***************************************************************************************************
							 Main
***************************************************************************************************/
extern void s_bom_cannon_main(void)
{

	
	switch (obj_mode) {
		case 0:	obj_speedX = 0;
				obj_speedY = 0;
				obj_shapeLOD = 4000;
				if (BuGetCannonFlag() == 1) {
					obj_mode = 1;
				}
				break;
		case 1: if (obj_timer == FRAME*2)  { obj_mode = 2; }
				obj_shapeLOD = 20000;
				break;

		case 2:	bomFuta_Open(); break;


	}

}

/*################*/
#endif
/*################*/


