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

534 lines
14 KiB
ArmAsm

/********************************************************************************
-------------------------
Ultra 64 MARIO Brothers
-------------------------
Strategy
Feburary 31 1996 programed by Iwamoto Daiki
********************************************************************************/
/*################*/
#ifdef ASSEMBLER
/*################*/
/********************************************************************************
Otos Path Data
********************************************************************************/
e_otos:
p_initialize(enemyA)
p_setbit(flag,stf_moveON| stf_YangleSAME )
p_set_pointer(skelanime,otos_anime)
p_BGcheckYset
p_save_nowpos
p_program(s_otos_init)
p_while
p_hitON
p_program(s_otos_event)
p_loop
/********************************************************************************/
/* Oya Otos path Program */
/********************************************************************************/
e_big_otos:
p_initialize(enemyA)
p_setbit(flag,stf_moveON| stf_YangleSAME )
p_set_pointer(skelanime,otos_anime)
p_BGcheckYset
p_save_nowpos
p_program(s_oya_otos_init)
p_while
p_hitON
p_program(s_otos_event)
p_loop
/********************************************************************************/
/* Oya Otos No2 path Program */
/********************************************************************************/
e_big_otos2:
p_initialize(enemyA)
p_setbit(flag,stf_moveON| stf_YangleSAME )
p_set_pointer(skelanime,otos_anime)
p_save_nowpos
p_program(s_oya_otos_init)
p_program(s_oya_otos2_init)
p_while
p_program(s_oya_otos2_main)
p_loop
/********************************************************************************
Ice Otos Path Data
********************************************************************************/
e_ice_otos:
p_initialize(enemyA)
p_setbit(flag,stf_moveON| stf_YangleSAME )
p_set_pointer(skelanime,ice_otos_anime)
p_BGcheckYset
p_save_nowpos
p_setd(work0,0x10)
p_program(s_otos_init)
p_while
p_hitON
p_program(s_otos_event)
p_loop
/********************************************************************************/
/* Oya Ice Otos path Program */
/********************************************************************************/
e_big_ice_otos:
p_initialize(enemyA)
p_setbit(flag,stf_moveON| stf_YangleSAME )
p_set_pointer(skelanime,ice_otos_anime)
p_BGcheckYset
p_save_nowpos
p_setd(work0,0x10)
p_program(s_oya_otos_init)
p_while
p_hitON
p_program(s_otos_event)
p_loop
/*################*/
#else
/*################*/
/***************************************************************************************************
C Program
****************************************************************************************************/
#define otos_attFlag (execstp->s[stw_work0].d)
#define otos_be_worldX (execstp->s[stw_work1].f)
#define otos_be_worldY (execstp->s[stw_work2].f)
#define otos_be_worldZ (execstp->s[stw_work3].f)
#define otos_appearFlag (execstp->s[stw_work4].d)
#define NORMALOTOS 0
#define OYAOTOS 1
/*--- otos_attFlag ----*/
#define OTOS_KOBUN 1
#define ICEOTOS 16
#define OTOS_STARX 0
#define OTOS_STARY 950
#define OTOS_STARZ -6800
#define OTOS2_STARX 3700
#define OTOS2_STARY 600
#define OTOS2_STARZ -5500
#define ICE_STARX 130
#define ICE_STARY 1600
#define ICE_STARZ -4335
static HitCheckRecord otos_hit = {
OBJNAME_MOTOS,
0,1,0,0, /* flag,hp,ap,coin */
63+10,113+10, /* player attack hitarea */
63 ,113 , /* player damege hitarea */
};
static HitCheckRecord oya_otos_hit = {
OBJNAME_MOTOS,
0,1,0,0, /* flag,hp,ap,coin */
105+10,225+10, /* player attack hitarea */
105 ,225 , /* player damage hitarea */
};
/***************************************************************************************************
Otos Initialize
***************************************************************************************************/
extern void s_otos_init(void)
{
stSetSkelAnimeNumber(0);
obj_attX = execstp->s[stw_worldX].f;
obj_attZ = execstp->s[stw_worldZ].f;
obj_programselect = 0;
execstp->s[stw_gravity].f = 4.;
// execstp->s[stw_friction].f = 0.91+((float)effect_p1/100);
execstp->s[stw_friction].f = 0.91;
execstp->s[stw_specificG].f = 1.3;
s_set_hitparam(execstp,&otos_hit); /* Set HitCheck Param */
}
/***************************************************************************************************
Oya Otos Initialize
***************************************************************************************************/
extern void s_oya_otos_init(void)
{
stSetSkelAnimeNumber(0);
obj_attX = execstp->s[stw_worldX].f;
obj_attY = execstp->s[stw_worldY].f;
obj_attZ = execstp->s[stw_worldZ].f;
obj_programselect = 1;
execstp->s[stw_gravity].f = 5.;
execstp->s[stw_friction].f = 0.93;
execstp->s[stw_specificG].f = 1.3;
s_set_hitparam(execstp,&oya_otos_hit); /* Set HitCheck Param */
}
/***************************************************************************************************
Otos Player Hit Event
***************************************************************************************************/
static void OtosPlayerHitEvent(void)
{
if ((obj_mode==OBJ_MELT) || (obj_mode==OBJ_AIRDEAD)) return;
if ( obj_mail & EMAIL_PLAYERHIT ){
if (obj_programselect == 0) objsound(NA_SE3_MOTOS_HIT_S);
else objsound(NA_SE3_MOTOS_HIT_B);
Mbitclr(execstp->s[stw_mail].d,EMAIL_PLAYERHIT);
obj_mode = 2;
execstp->s[stw_flag].d &= (stf_YangleSAME^0xffffffff);
stSetSkelAnimeNumber(3);
execstp->s[stw_work5].d = execstp->s[stw_angleY].d;
}
}
/***************************************************************************************************
Otos Search Event
***************************************************************************************************/
extern void OtosPlayerSearchEvent(void)
{
float posiX = obj_attX;
float posiY = obj_worldY;
float posiZ = obj_attZ;
if (obj_timer < 10) {
execstp->s[stw_speedF].f = 3.;
s_chase_obj_angle(execstp,player1stp,stw_angleY,0x1000);
}
else {
if (obj_programselect == NORMALOTOS) {
execstp->s[stw_speedF].f = 20.;
if (obj_timer > 30) obj_timer = 0;
}
else {
execstp->s[stw_speedF].f = 30.;
if (obj_timer > 35) obj_timer = 0;
}
}
if (PlayerApproach(posiX,posiY,posiZ,1000) == 0) {
obj_mode = 0;
stSetSkelAnimeNumber(0);
}
}
/***************************************************************************************************
Otos Refrect Event
***************************************************************************************************/
extern void OtosReflectEvent(void)
{
if (execstp->s[stw_speedF].f < 10. && (int)(execstp->s[stw_speedY].f) == 0) {
execstp->s[stw_speedF].f = 1.;
(execstp->s[stw_work4].d)++;
execstp->s[stw_flag].d |= stf_YangleSAME;
execstp->s[stw_angleY].d = execstp->s[stw_animeangleY].d;
s_chase_obj_angle(execstp,player1stp,stw_angleY,0x500);
}
else execstp->map.skelanim.frame = 0;
if (execstp->s[stw_work4].d == 18) {
obj_mode = 1;
execstp->s[stw_work4].d = 0;
stSetSkelAnimeNumber(1);
}
}
/***************************************************************************************************
Otos Go Home
***************************************************************************************************/
extern void OtosU_Turn(void)
{
if (obj_timer == 0) {
execstp->s[stw_flag].d &= (stf_YangleSAME^0xffffffff);
execstp->s[stw_angleY].d += 0x8000;
}
execstp->s[stw_speedF].f = 5.;
if (obj_timer == 15) {
execstp->s[stw_angleY].d = execstp->s[stw_animeangleY].d;
execstp->s[stw_flag].d |= stf_YangleSAME;
obj_mode = 0;
}
}
/***************************************************************************************************
Otos Bg Check
***************************************************************************************************/
static void OtosBgCheck(short bg_flag)
{
if ((bg_flag & 0x08)==0 && obj_mode != 2) {
execstp->s[stw_worldX].f = otos_be_worldX;
// execstp->s[stw_worldY].f = otos_be_worldY;
execstp->s[stw_worldZ].f = otos_be_worldZ;
obj_mode = 3;
}
}
/***************************************************************************************************
Otos Move
***************************************************************************************************/
static void OtosSound(void)
{
short anim_frame = execstp->map.skelanim.frame;
switch (obj_mode) {
case 0 : if (anim_frame == 0 || anim_frame == 12) {
if (obj_programselect == 0) objsound(NA_SE3_MOTOSWALK);
else objsound(NA_SE3_BIGMOTOSWALK);
}
break;
case 1 :
case 3 : if (anim_frame == 0 || anim_frame == 5) {
if (obj_programselect == 0) objsound(NA_SE3_MOTOSWALK);
else objsound(NA_SE3_BIGMOTOSWALK);
}
break;
}
}
/***************************************************************************************************
Otos Move
***************************************************************************************************/
static void OtosMove(void)
{
short bg_flag = 0;
bg_flag = ObjMoveEvent();
OtosBgCheck(bg_flag);
OtosSound();
ObjDangerCheck(bg_flag,moveobj_bgcp);
if (otos_attFlag & ICEOTOS) {
if (obj_worldY < 1030) obj_mode = OBJ_MELT;
}
}
/***************************************************************************************************
Otos Spit Coin
***************************************************************************************************/
static void OtosSpitCoin(void)
{
StrategyRecord *stratp;
stratp = s_makeobj_nowpos(execstp,S_coin,e_move_coin);
objsound(NA_SE2_COINFLY);
stratp->s[stw_speedF].f = 10;
stratp->s[stw_speedY].f = 100;
stratp->s[stw_worldY].f = obj_worldY + 310;
stratp->s[stw_angleY].d = execstp->s[stw_work5].d + 0x8000 + (Randomf()*0x400);
}
/***************************************************************************************************
Otos Melt
***************************************************************************************************/
static void OtosMelt(void)
{
if (ObjMeltEvent()==1) {
if (obj_programselect == 0 ) {
if (otos_attFlag == OTOS_KOBUN) (motherp->s[stw_work4].d)++;
OtosSpitCoin();
}
else {
s_kemuri();
if (otos_attFlag == ICEOTOS) { s_enemyset_star( ICE_STARX, ICE_STARY, ICE_STARZ); }
else {
s_enemyset_star(OTOS_STARX,OTOS_STARY,OTOS_STARZ);
s_makeobj_absolute(execstp,0,S_NULL,e_mapobj_motos_07, 0, 154,-5631,0,0,0);
}
}
}
}
/***************************************************************************************************
Otos Event
***************************************************************************************************/
extern void s_otos_event(void)
{
otos_be_worldX = execstp->s[stw_worldX].f;
otos_be_worldY = execstp->s[stw_worldY].f;
otos_be_worldZ = execstp->s[stw_worldZ].f;
OtosPlayerHitEvent();
switch (obj_mode) {
case 0: execstp->s[stw_speedF].f = 5.;
if ( ShapePatrol(execstp,obj_attX,obj_worldY,obj_attZ,800) == 1) {
obj_mode = 1;
stSetSkelAnimeNumber(1);
}
OtosMove();
break;
case 1: OtosPlayerSearchEvent();
OtosMove();
break;
case 2: OtosReflectEvent();
OtosMove();
break;
case 3: OtosU_Turn();
OtosMove();
break;
case OBJ_MELT : OtosMelt();
break;
case OBJ_AIRDEAD : execstp->status = 0;
break;
}
PlayerApproachOnOff(execstp,3000);
//rmonpf(("dd %d\n",obj_mode));
}
/*=================================================================================================
BIG OTOS No2
=================================================================================================*/
/***************************************************************************************************
Make Treasure Box
***************************************************************************************************/
static void MakeOtos2(int posx, int posy, int posz, short angy)
{
StrategyRecord* stp = s_makeobj_absolute(execstp,0,S_otos,e_otos,posx,posy,posz,0,angy,0);
stp->s[stw_work0].d = OTOS_KOBUN;
stp->s[stw_programselect].d = 0;
}
/***************************************************************************************************
BIG Otos No2 Init
***************************************************************************************************/
extern void s_oya_otos2_init(void)
{
MakeOtos2(4454,307,-5426, 0);
MakeOtos2(3840,307,-6041, 0);
MakeOtos2(3226,307,-5426, 0);
MapHideShape(&execstp->map);
s_hitOFF();
obj_mode = 4;
}
/***************************************************************************************************
Otos Melt
***************************************************************************************************/
static void OyaOtos2Melt(void)
{
if (ObjMeltEvent()==1) {
s_kemuri();
s_enemyset_star(OTOS2_STARX,OTOS2_STARY,OTOS2_STARZ);
}
}
/***************************************************************************************************
BIG Otos No2 Init
***************************************************************************************************/
extern void s_oya_otos2_main(void)
{
short bg_flag;
otos_be_worldX = execstp->s[stw_worldX].f;
otos_be_worldY = execstp->s[stw_worldY].f;
otos_be_worldZ = execstp->s[stw_worldZ].f;
OtosPlayerHitEvent();
switch (obj_mode) {
case 0: execstp->s[stw_speedF].f = 5.;
if ( ShapePatrol(execstp,obj_attX,obj_worldY,obj_attZ,1000) == 1) {
obj_mode = 1;
stSetSkelAnimeNumber(1);
}
OtosMove();
break;
case 1: OtosPlayerSearchEvent();
OtosMove();
break;
case 2: OtosReflectEvent();
OtosMove();
break;
case 3: OtosU_Turn();
OtosMove();
break;
case 4: if (otos_appearFlag == 3) {
Na_NazoClearBgm();
if (obj_timer > FRAME*3) obj_mode = 5;
}
break;
case 5: bg_flag = ObjMoveEvent();
if ((bg_flag & OM_GROUND)==0x09) obj_mode = 0;
if (bg_flag == 0x01) {
objsound(NA_SE3_MOTOS_APPEAR_B);
Viewshaking(VS_SMALL,obj_worldX,obj_worldY,obj_worldZ);
s_kemuri();
}
MapDispShape(&execstp->map);
s_hitON();
break;
case OBJ_MELT : OyaOtos2Melt();
break;
case OBJ_AIRDEAD : execstp->status = 0;
break;
}
}
/*################*/
#endif
/*################*/