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

379 lines
11 KiB
ArmAsm

/********************************************************************************
-------------------------
Ultra 64 MARIO Brothers
-------------------------
Bird Strategy
Feburary 14 1996 programed by Iwamoto Daiki
********************************************************************************/
/*################*/
#ifdef ASSEMBLER
/*################*/
/********************************************************************************
Bird Path Data
********************************************************************************/
/********************************************************************************/
/* bird path program */
/********************************************************************************/
e_bird:
p_initialize(player_friend)
p_setbit(flag,stf_moveON| stf_YangleSAME)
p_set_pointer(skelanime,RCP_birdAnime)
p_setd(objname,OBJNAME_BIRD)
p_sethitbox(300/4,300/4)
p_program(s_bird_init)
bird_main:
p_while
p_program(s_bird_main)
p_loop
/*################*/
#else
/*################*/
/***************************************************************************************************
C Program
****************************************************************************************************/
#define bird_stateFlag (execstp->s[stw_work0].d)
/* --- work7 is used -----*/
#define TORISPEED 20
/***************************************************************************************************
Bird Move Event Initial
***************************************************************************************************/
extern void s_bird_init(void)
{
stSetSkelAnimeNumber(0);
obj_attX = execstp->s[stw_worldX].f + 800;
obj_attY = execstp->s[stw_worldY].f - 150;
obj_attZ = execstp->s[stw_worldZ].f + 300;
MapHideShape(&execstp->map);
s_hitOFF();
}
/***************************************************************************************************
Bird BG Check
***************************************************************************************************/
static float CheckCenser(Plane **plane,float dist)
{
float censerx = dist*sin(execstp->s[stw_angleY].d) + execstp->s[stw_worldX].f;
float censery = execstp->s[stw_worldY].f;
float censerz = dist*cos(execstp->s[stw_angleY].d) + execstp->s[stw_worldZ].f;
float checky = GroundCheck(censerx,10000,censerz,plane);
return(checky);
}
/***************************************************************************************************
Bird BG Check
***************************************************************************************************/
static void BirdBGcheck(void)
{
Plane *plane;
float checky;
checky = CheckCenser(&plane,1500./4);
if ((checky + 300/4) > execstp->s[stw_worldY].f) {
execstp->s[stw_angleX].d -= degree(20);
}
checky = CheckCenser(&plane,800./4);
if ((checky + 500/4) > execstp->s[stw_worldY].f) {
execstp->s[stw_angleX].d -= degree(40);
}
checky = CheckCenser(&plane,0.);
if ((checky + 500/4) > execstp->s[stw_worldY].f) {
execstp->s[stw_worldY].f = (checky + 500/4);
}
if (execstp->s[stw_angleX].d < degree(-120) ) execstp->s[stw_angleX].d = degree(-120);
}
/***************************************************************************************************
Bird World Move
***************************************************************************************************/
static void BirdWorldMove(short flag ,int speed)
{
Plane *plane;
short direct = execstp->s[stw_angleY].d;
short directy = execstp->s[stw_angleX].d;
short anim_frame = execstp->map.skelanim.frame;
float be_posx = execstp->s[stw_worldX].f;
float be_posz = execstp->s[stw_worldZ].f;
float speedF;
execstp->s[stw_speedY].f = speed*sin(directy);
speedF = speed*cos(directy);
execstp->s[stw_speedX].f = speedF*sin(direct);
execstp->s[stw_speedZ].f = speedF*cos(direct);
execstp->s[stw_worldX].f += execstp->s[stw_speedX].f;
if (flag == 0) execstp->s[stw_worldY].f -= (execstp->s[stw_speedY].f + cos((short)(anim_frame*3276.8))*50/4);
else execstp->s[stw_worldY].f -= (execstp->s[stw_speedY].f + cos((short)(anim_frame*6553.6))*50/4);
execstp->s[stw_worldZ].f += execstp->s[stw_speedZ].f;
GroundCheck(execstp->s[stw_worldX].f,execstp->s[stw_worldY].f,execstp->s[stw_worldZ].f,&plane);
if (plane == NULL) {
execstp->s[stw_worldX].f = be_posx;
execstp->s[stw_worldZ].f = be_posz;
}
if (anim_frame == 0) objsound(NA_SE3_OWL); //SOUND
}
/*--------------------Bird Delivery Event----------------------------------------------------------*/
/***************************************************************************************************
Bird Control
***************************************************************************************************/
static void BirdControl(void)
{
short stickx = contOr->stickx;
short sticky = contOr->sticky;
short anglex = execstp->s[stw_angleX].d;
if (stickx < 10 && stickx > -10) stickx = 0;
if (sticky < 10 && sticky > -10) sticky = 0;
execstp->s[stw_angleY].d -= stickx*5;
}
/***************************************************************************************************
Bird Delivery Move
***************************************************************************************************/
static void BirdDeliveryMove(int speed,float be_posx,float be_posz)
{
short direct = execstp->s[stw_angleY].d;
short directy = execstp->s[stw_angleX].d;
short anim_frame = execstp->map.skelanim.frame;
float speedF;
execstp->s[stw_speedY].f = speed*sin(directy);
speedF = speed*cos(directy);
execstp->s[stw_speedX].f = speedF*sin(direct);
execstp->s[stw_speedZ].f = speedF*cos(direct);
execstp->s[stw_worldX].f += execstp->s[stw_speedX].f;
execstp->s[stw_worldY].f -= (execstp->s[stw_speedY].f + cos((short)(anim_frame*6553.6))*50/4);
execstp->s[stw_worldZ].f += execstp->s[stw_speedZ].f;
if (anim_frame == 0) objsound(NA_SE3_OWL);
}
/***************************************************************************************************
Bird Delivery BGCheck
***************************************************************************************************/
static void DeliveryBgCheck(float be_posx,float be_posy,float be_posz)
{
Plane *plane;
BGWallCheckRecord wall_check;
float checky;
/*---- Wall Check ----*/
wall_check.wx = execstp->s[stw_worldX].f;
wall_check.wy = execstp->s[stw_worldY].f;
wall_check.wz = execstp->s[stw_worldZ].f;
wall_check.offsetY = 10;
wall_check.r = 50;
if (mcBGWallCheck(&wall_check) != 0) {
execstp->s[stw_worldX].f = wall_check.wx;
execstp->s[stw_worldY].f = wall_check.wy;
execstp->s[stw_worldZ].f = wall_check.wz;
player1stp->s[stw_mail].d |= PLAYERMAIL_BIRDMODE_OFF;
}
checky = GroundCheck(execstp->s[stw_worldX].f,execstp->s[stw_worldY].f,execstp->s[stw_worldZ].f,&plane);
if (plane == NULL) {
execstp->s[stw_worldX].f = be_posx;
execstp->s[stw_worldZ].f = be_posz;
return;
}
if (I_abs(obj_worldX) > 8000) obj_worldX = be_posx;
if (I_abs(obj_worldZ) > 8000) obj_worldZ = be_posz;
if ((checky + 500/4) > execstp->s[stw_worldY].f) {
execstp->s[stw_worldY].f = (checky + 500/4);
}
}
/***************************************************************************************************
Bird Delivery Up
***************************************************************************************************/
static void BirdDelivery_UP(float be_posx,float be_posz)
{
float dx = 0 - obj_worldX;
float dz = 0 - obj_worldZ;
short targetAngleY = atan(dz,dx);
obj_angleY = s_chase_angle(obj_angleY,targetAngleY,0x500);
obj_angleX = degree(290);
if (obj_timer > 28) {
objsound_level(NA_LSE2_BLOWUP_WIND);
execstp->map.skelanim.frame = 1;
}
if (obj_worldY > 6500) {
obj_mode = 1;
}
BirdDeliveryMove(TORISPEED*3,be_posx,be_posz);
}
/***************************************************************************************************
Bird Delivery Event
***************************************************************************************************/
static void BirdDelivery(void)
{
float be_posx = execstp->s[stw_worldX].f;
float be_posy = execstp->s[stw_worldY].f;
float be_posz = execstp->s[stw_worldZ].f;
switch (obj_mode) {
case 0: BirdDelivery_UP(be_posx,be_posz);
break;
case 1: BirdControl();
obj_angleX = degree(10);
if (obj_worldY < 2700) {
s_begin_enemydemo(STRATMAIN_DEMOMODE+STRATMAIN_PLAYERSTOP); //Strategy Stop
if (cameraDemoStratMsgNum(CAM_DEMO_TALK,execstp,45) != 0) {
s_end_enemydemo(STRATMAIN_DEMOMODE+STRATMAIN_PLAYERSTOP);
obj_mode = 2;
}
}
BirdDeliveryMove(20,be_posx,be_posz);
break;
case 2: BirdControl();
obj_angleX = degree(0);
BirdDeliveryMove(20,be_posx,be_posz);
if (obj_timer > FRAME*2) { player1stp->s[stw_mail].d |= PLAYERMAIL_BIRDMODE_OFF; }
break;
}
DeliveryBgCheck(be_posx,be_posy,be_posz);
}
/*-------------------------------------------------------------------------------------------------*/
/***************************************************************************************************
Bird Go Home
***************************************************************************************************/
static void DecideDirection(void)
{
float dx = obj_attX - obj_worldX;
float dy = obj_attY - obj_worldY;
float dz = obj_attZ - obj_worldZ;
short targetAngleY = atan(dz,dx);
short targetAngleX = atan(sqrtf(dx*dx + dz*dz),-dy);
execstp->s[stw_angleY].d = s_chase_angle(execstp->s[stw_angleY].d,targetAngleY,(0x500/4));
execstp->s[stw_angleX].d = s_chase_angle(execstp->s[stw_angleX].d,targetAngleX,(0x500/4));
}
/***************************************************************************************************
Bird Move Event
***************************************************************************************************/
extern void BirdMove(void)
{
if (execstp->s[stw_mail].d == 1) {
BirdDelivery();
stSetSkelAnimeNumber(1);
}
else {
stSetSkelAnimeNumber(0);
DecideDirection();
BirdBGcheck();
BirdWorldMove(0,TORISPEED/2);
obj_mode = 0;
obj_timer = 0;
}
PlayerApproachOnOff(execstp,2000);
}
/***************************************************************************************************
Bird Move Event
***************************************************************************************************/
extern void s_bird_main(void)
{
switch(bird_stateFlag) {
case 0: if (PlayerApproach(obj_worldX,obj_worldY,obj_worldZ,50)) {
MapDispShape(&execstp->map);
bird_stateFlag = 1;
}
break;
case 1: BirdMove();
if (CtrlPlayerDialog(DLOG_LOOKUP)==DLOG_RESULT_READY) {
if (cameraDemoStratMsgNum(CAM_DEMO_TALK,execstp,44) != 0) {
CtrlPlayerDialog(DLOG_DONE);
s_hitON();
bird_stateFlag = 2;
}
}
break;
case 2: BirdMove();
break;
}
}
/*################*/
#endif
/*################*/