351 lines
8.6 KiB
OpenEdge ABL
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
|
|
===============================================================================*/
|
|
|
|
|
|
|