sm64/data/p/pathpirania.p
2022-12-04 22:27:02 -05:00

351 lines
8.6 KiB
OpenEdge ABL

/********************************************************************************
-------------------------
Ultra 64 MARIO Brothers
-------------------------
File : pathpirania.s
Description :
Date : 1995.
Author : H.yajima
********************************************************************************/
#define FISH_APPEAR_DIST 1500
#define FISH_REMOVE_DIST 2000
/*################*/
#ifdef ASSEMBLER
/*################*/
/********************************************************************************/
/* sakana PATH */
/********************************************************************************/
e_fishmother_many:
p_initialize(option)
p_setd(programselect,0)
p_jmp(e_sakanacommon)
e_fishmother_little:
p_initialize(option)
p_setd(programselect,1)
p_jmp(e_sakanacommon)
e_sakanamother:
p_initialize(option)
e_sakanacommon:
p_shapeDISABLE
p_setbit(flag,stf_moveON | stf_YangleSAME | stf_playerdistON )
p_while
p_program(s_sakanamother_program)
p_loop
e_sakanachild:
p_initialize(option)
p_setbit(flag,stf_moveON | stf_YangleSAME | stf_playerdistON | stf_playerangleON )
p_save_nowpos
p_while
p_program(s_sakana)
p_loop
/*################*/
#else
/*################*/
/********************************************************************************
mode
*********************************************************************************/
#define sakana_water (execstp->s[stw_work0].f)
#define sakana_playerY (execstp->s[stw_work1].f)
#define sakana_random (execstp->s[stw_work2].f)
#define sakana_randomangle (execstp->s[stw_work3].d)
#define sakana_randomdist (execstp->s[stw_work4].f)
#define sakana_randomspeed (execstp->s[stw_work5].f)
#define sakana_limitY (execstp->s[stw_work6].f)
#define runaway_random (execstp->s[stw_work7].f)
/*--------------------
sakana program 0 .... (20) fish
1 .... (5) fish
2 .... (20) pirania
--------------------*/
/********************************************************************************
---------------------
sakana mother program
---------------------
*********************************************************************************/
/********************************************************************************/
static void sakanamother_init(void)
{
int i,count;
short shape;
float appear_dist;
AnimePtr *animeptr;
StrategyRecord *p;
extern AnimePtr pirania_anime[];
extern AnimePtr RCP_fishAnime[];
/*===== fish program select =====*/
switch(obj_programselect){
case 0: shape = S_fish; count = 20; appear_dist = 1500; animeptr = RCP_fishAnime; break;
case 1: shape = S_fish; count = 5; appear_dist = 1500; animeptr = RCP_fishAnime; break;
case 2: shape = S_pirania; count = 20; appear_dist = 1500; animeptr = pirania_anime; break;
case 3: shape = S_pirania; count = 5; appear_dist = 1500; animeptr = pirania_anime; break;
}
/*===== fish make =====*/
if ( obj_playerdist < appear_dist || activeStageNo == 20 ){
for(i=0;i<count;i++){
p = s_makeobj_nowpos(execstp,shape,e_sakanachild);
p->s[stw_programselect].d = execstp->s[stw_programselect].d;
s_set_skeletonobj(p,animeptr,0);
s_random_XYZ_offset(p,700.0f);
}
obj_mode = mode_sakanamother_main;
}
}
/********************************************************************************/
static void sakanamother_main(void)
{
if ( activeStageNo != 20 ){
if ( ( player1stp->s[stw_worldY].f - obj_worldY ) > FISH_REMOVE_DIST ){
obj_mode = mode_sakanamother_remove;
}
}
}
/********************************************************************************/
static void sakanamother_remove(void)
{
obj_mode = mode_sakanamother_init;
}
/********************************************************************************/
static void *sakanamother_modejmp[] = {
sakanamother_init,
sakanamother_main,
sakanamother_remove
};
extern void s_sakanamother_program(void)
{
s_modejmp(sakanamother_modejmp);
}
/********************************************************************************
####
#### sakana search program
####
*********************************************************************************/
static void sakanamove_worldY(int data)
{
float motherY = execstp->motherobj->s[stw_worldY].f;
if ( activeStageNo == 20 ){
if ( s_abs_f(obj_worldY - sakana_playerY) > 500 ) data = 10;
obj_worldY = s_chase_position(obj_worldY,sakana_playerY,data);
} else {
if ( ((motherY-100-sakana_limitY) < obj_worldY ) && ( obj_worldY < (motherY+1000+sakana_limitY))) {
obj_worldY = s_chase_position(obj_worldY,sakana_playerY,data);
}
}
}
/********************************************************************************
####
#### sakana search program
####
*********************************************************************************/
static void s_sakana_search(void)
{
float dy = obj_worldY - ( player1stp->s[stw_worldY].f );
if ( obj_timer < 10 ) s_set_skelanime_speed(0,2.0);
else s_set_skelanime_speed(0,1.0);
if ( obj_timer == 0 ){
obj_speedF = 3+Randomf()*2;
if ( activeStageNo == 20 ) sakana_random = Randomf()* 700 ;
else sakana_random = Randomf()* 100 ;
sakana_randomdist = 200 + Randomf()*500;
}
sakana_playerY = player1stp->s[stw_worldY].f+sakana_random;
s_chase_angleY(obj_targetangle,0x400);
if ( obj_worldY < sakana_water-50 ){
if ( dy < 0 ) dy = 0-dy;
if ( dy < 500 ) sakanamove_worldY(2);
else sakanamove_worldY(4);
} else {
obj_worldY = sakana_water-50;
if ( dy > 300 ) obj_worldY--;
}
if ( obj_playerdist < 150 + sakana_randomdist ) obj_mode = mode_s_sakana_runaway;
}
/********************************************************************************
sakana runaway program
*********************************************************************************/
static void s_sakana_runaway(void)
{
float dy = obj_worldY - ( player1stp->s[stw_worldY].f );
int sound;
sakana_playerY = player1stp->s[stw_worldY].f+sakana_random;
if ( obj_timer == 0 ){
runaway_random = Randomf()*300;
sakana_randomangle = Randomf()*0x400+0x400;
sakana_randomspeed = Randomf()*4+8+5;
if ( obj_playerdist < 600 ) sound = 1;
else sound = 1/(obj_playerdist / 600.0);
sound = sound * 127;
objsound(NA_SE2_FISH);
}
if ( obj_timer < 20 ) s_set_skelanime_speed(0,4.0);
else s_set_skelanime_speed(0,1.0);
if ( obj_speedF < sakana_randomspeed ) obj_speedF += 0.5;
sakana_playerY = player1stp->s[stw_worldY].f+sakana_random;
s_chase_angleY(obj_targetangle+0x8000,sakana_randomangle);
if ( obj_worldY < sakana_water-50 ){
if ( dy < 0 ) dy = 0-dy;
if ( dy < 500 ) sakanamove_worldY(2);
else sakanamove_worldY(4);
} else {
obj_worldY = sakana_water-50;
if ( dy > 300 ) obj_worldY--;
}
if ( obj_playerdist > 500+runaway_random ) obj_mode = mode_s_sakana_search;
}
/********************************************************************************
sakana intialize
*********************************************************************************/
static void s_sakana_init(void)
{
s_set_skelanime_speed(0,1.0);
execstp->map.skelanim.frame = Randomf()*28;
sakana_limitY = Randomf()*300;
s_set_scale(0.8+Randomf()*0.4);
obj_mode = mode_s_sakana_search;
}
/********************************************************************************
========================
sakana main program
========================
*********************************************************************************/
static void *sakana_modejmp[] = {
s_sakana_init,
s_sakana_search,
s_sakana_runaway
};
extern void s_sakana(void)
{
float dx,dy,dz;
s_set_scale(1.0);
sakana_water = mcWaterCheck(obj_worldX,obj_worldZ);
if ( activeStageNo == 20 ){
sakana_water = 0;
#if 0
dx = ((snSceneInfo->camera->position[0] + player_worldX )/ 2.0f)-obj_worldX;
dy = ((snSceneInfo->camera->position[1] + player_worldY )/ 2.0f)-obj_worldY;
dz = ((snSceneInfo->camera->position[2] + player_worldZ )/ 2.0f)-obj_worldZ;
obj_playerdist = sqrtf(dx*dx+dy*dy+dz*dz);
#endif
}
execstp->s[stw_wall_offsetR].f = 30;
s_wallcheck();
if ( activeStageNo != YAJIMA_LAND ){
if ( sakana_water < -10000 ){ s_remove_obj(execstp); return; }
} else {
sakana_water = 1000;
}
s_modejmp(sakana_modejmp);
s_optionmove_F();
if ( execstp->motherobj->s[stw_mode].d == mode_sakanamother_remove ) s_remove_obj(execstp);
}
/*################*/
#endif
/*################*/
/*===============================================================================
end end end end end end end end
===============================================================================*/