379 lines
11 KiB
ArmAsm
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
|
|
/*################*/
|
|
|
|
|