sm64/data/iwa_path/newbom.s
2022-12-04 22:27:02 -05:00

730 lines
19 KiB
ArmAsm

/********************************************************************************
-------------------------
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
/*################*/