sm64/data/p/pathballoon.p

505 lines
12 KiB
OpenEdge ABL

/********************************************************************************
-------------------------
Ultra 64 MARIO Brothers
-------------------------
File : pathballoon.s
Description : balloon enemy
Date : 1995.10.13
Author : H.yajima
********************************************************************************/
/*################*/
#ifdef ASSEMBLER
/*################*/
e_balloon:
p_initialize(enemyA)
p_setbit(flag,stf_moveON | stf_YangleSAME | stf_FspeedON | stf_playerdistON )
p_save_nowpos
p_makeshape(S_ballooneye ,e_balloon_eye )
p_changeshape(imm,S_balloonbody)
p_softspritemodeON
p_program(s_areastage_init)
p_while
p_program(s_balloon)
p_loop
/*-------------------------- balloon eye program -------*/
e_balloon_eye:
p_initialize(option)
p_setbit( flag,stf_moveON )
p_program(s_areastage_init)
p_while
p_program(s_balloon_eye)
p_loop
/*-------------------------- balloon fire program -------*/
e_balloon_fire:
p_initialize(item)
p_softspritemodeON
p_setbit( flag,stf_moveON | stf_FspeedON )
p_hitON
p_sethitbox(50,50)
p_setd(ap,1)
p_setd(objname,OBJNAME_DAMAGE)
p_setmovedata(30,0,0,0,0,0,0,0)
p_program(s_areastage_init)
p_while
p_program(s_balloon_fire)
p_loop
/*------------------------------------------------------*/
e_balloon_gomi:
p_initialize(effect)
p_softspritemodeON
p_setbit( flag,stf_moveON )
p_do(10)
p_program(s_balloon_gomi)
p_next
p_killshape
/*################*/
#else
/*################*/
/********************************************************************************
---------------------
balloon gomi program
---------------------
********************************************************************************/
extern void s_balloon_gomi(void)
{
if ( obj_timer == 0 ){
obj_speedY = Randomf()*20+20;
obj_speedF = Randomf()*20+20;
obj_angleY = Randomd();
}
s_optionmove_F(); /* option move */
}
/********************************************************************************
---------------------
balloon fire program
---------------------
********************************************************************************/
/*======================================*/
/* fire (1) */
/*======================================*/
static void balloonfire_1(void)
{
s_set_scale(3.0);
obj_speedF = 20;
s_enemybgcheck();
if ( (obj_mail & EMAIL_PLAYERHIT) != 0 ){
obj_mode = mode_balloonfire_2;
} else {
if ( (obj_timer > 100) || (obj_movestatus & MOVESTAT_WALL) || ( execstp->status & OBJECT_AREAOUT ) ){
s_remove_obj(execstp);
s_kemuri();
}
}
}
/*======================================*/
/* fire (2) */
/*======================================*/
static void balloonfire_2(void)
{
int i;
s_remove_obj(execstp);
for(i=0;i<10;i++){
s_makeobj_nowpos(execstp,S_syabon,e_balloon_gomi);
}
}
/*======================================*/
/* fire main */
/*======================================*/
static void *balloonfire_modejmp[] = {
balloonfire_1,
balloonfire_2
};
extern void s_balloon_fire(void)
{
s_modejmp(balloonfire_modejmp);
}
/********************************************************************************
makefire
********************************************************************************/
static void balloon_makefire(void)
{
StrategyRecord *firep;
float scale = execstp->map.scale[1];
firep = s_makeobj_nowpos(execstp,S_syabon,e_balloon_fire);
firep->s[stw_worldY].f += 50 * scale;
firep->s[stw_worldX].f += sin(execstp->s[stw_angleY].d) * 90 * scale;
firep->s[stw_worldZ].f += cos(execstp->s[stw_angleY].d) * 90 * scale;
objsound(NA_SE3_RABBITJUMP);
}
/********************************************************************************
---------------------
balloon eye program
---------------------
********************************************************************************/
extern void s_balloon_eye(void)
{
s_copy_worldXYZ_angleXYZ(execstp,execstp->motherobj);
if ( ( execstp->status & OBJECT_AREAOUT ) == 0 ){
s_copy_scale(execstp,execstp->motherobj);
s_set_skeleton(execstp,0,0,(100)*(execstp->map.scale[1]) );
s_create_matrix(execstp,stw_skeletonX,stw_angleX);
s_rotate_vertex(execstp,stw_worldX,stw_skeletonX);
obj_animeangleX = obj_angleX;
execstp->s[stw_animepositionY].f = (execstp->map.scale[1])*(100);
}
if ( execstp->motherobj->s[stw_work7].d != 1 ){ /* wink flag */
execstp->s[stw_animecounter].d = -1;
} else {
execstp->s[stw_animecounter].d++;
if ( execstp->s[stw_animecounter].d == 15 ) execstp->motherobj->s[stw_work7].d = 0; /* wink reset */
}
if ( execstp->motherobj->status == 0) s_remove_obj(execstp);
}
/********************************************************************************
---------------------
balloon main program
---------------------
********************************************************************************/
/********************************************************************************
player eye
********************************************************************************/
#define balloon_eyetimer (execstp->s[stw_work0].d)
#define balloon_eyecount (execstp->s[stw_work1].d)
#define balloon_eyedata (execstp->s[stw_work2].d)
#define balloon_flag (execstp->s[stw_work3].d)
#define balloon_subtimer (execstp->s[stw_work4].d)
#define balloon_random (execstp->s[stw_work5].d)
#define balloon_scale (execstp->s[stw_work6].f)
#define balloon_wink (execstp->s[stw_work7].d)
#define BL_XMOVE_COUNT 32
#define BL_SCALE_COUNT 8
#define BL_WAIT_COUNT (16*4)
#define BL_REVENGE_COUNT 16
#define BL_ROLLTIME 64
#define BL_XMOVETIME (BL_ROLLTIME+BL_XMOVE_COUNT)
#define BL_SCALE (BL_XMOVETIME+BL_SCALE_COUNT)
#define BL_DOWNWAIT (BL_SCALE+BL_WAIT_COUNT)
#define BL_REVENGE (BL_DOWNWAIT+BL_REVENGE_COUNT)
static void balloon_eyedamage(void)
{
short ang1;
short add;
float timevar,timevar2;
StrategyRecord *stp;
int i;
float scale;
float mainscale;
if ( obj_programselect ) mainscale = 2;
else mainscale = 1;
if ( balloon_flag < 0 ) add = 0x1000;
else add = -0x1000;
timevar2 = (float)(obj_timer+1)/(float)(BL_XMOVETIME);
if ( obj_timer < BL_ROLLTIME ){
ang1 = obj_angleY;
obj_angleY += add * cos(0x4000 * timevar2 );
if ( ang1 < 0 && obj_angleY >= 0 ) objsound(NA_SE3_EYEROLL);
obj_angleX = -0x4000 * (1.0 - cos(0x4000 * timevar2 ));
s_effect_updown(4);
} else if ( obj_timer < BL_XMOVETIME ){
if ( obj_timer == BL_ROLLTIME ) objsound(NA_SE3_ENEMYDOWN);
timevar = (float)(obj_timer-BL_ROLLTIME+1)/(float)(BL_XMOVE_COUNT);
obj_angleY += add * cos(0x4000 * timevar2 );
obj_angleX = -0x4000 * (1.0 - cos(0x4000 * timevar2 ));
s_effect_updown((int)(4*(1-timevar)) );
scale = 0.6+0.4*cos(0x4000 * timevar);
s_set_scale(scale*mainscale);
} else if ( obj_timer < BL_SCALE ){
} else if ( obj_timer < BL_DOWNWAIT ){
if ( obj_timer == BL_SCALE ){
s_hitOFF();
s_kemuri();
balloon_scale = (0.6*mainscale);
if ( obj_programselect ){
obj_worldY+= 100;
s_enemyset_star(1370, 2000, -320);
s_remove_obj(execstp);
} else {
s_make_bluecoin();
}
}
balloon_scale -= (0.2*mainscale);
if ( balloon_scale < 0 ) balloon_scale = 0;
s_set_scale(balloon_scale);
} else {
s_remove_obj(execstp);
}
/*--------------------------------------------------
if ( obj_playerdist > 2000 ){
obj_mode = mode_balloon_roll;
obj_angleY = 0;
obj_angleX = 0;
s_set_scale(1.0);
}
--------------------------------------------------*/
}
/********************************************************************************
player eye
********************************************************************************/
#define BL_MEMAWASHI_TIME 120
#define BL_MEMAWASHI_ANGLE 65536*1
#define BL_ATTACKTIME 50
static void balloon_playereye(void)
{
short Yold = obj_angleY;
short angleadd;
if ( obj_timer == 0 ){
if ( obj_programselect ) balloon_eyetimer = 200;
else balloon_eyetimer = 120;
balloon_eyedata = 0;
balloon_flag = 0;
balloon_subtimer = 0;
}
s_chase_obj_angle(execstp,player1stp,stw_angleY,0x800);
s_chase_obj_angle(execstp,player1stp,stw_angleX,0x400);
/*------- angle addition ----------*/
angleadd = Yold-(short)obj_angleY;
if ( angleadd == 0 ){
balloon_eyedata = 0;
balloon_flag = 0;
} else if ( angleadd > 0 ){
if ( balloon_flag > 0 ) balloon_eyedata += angleadd;
else balloon_eyedata = 0;
balloon_flag = 1;
} else {
if ( balloon_flag < 0 ) balloon_eyedata -= angleadd;
else balloon_eyedata = 0;
balloon_flag = -1;
}
if ( balloon_eyedata == 0 ) balloon_eyetimer = BL_MEMAWASHI_TIME;
if ( balloon_eyedata > BL_MEMAWASHI_ANGLE ){
obj_mode = mode_balloon_eyedamage;
}
balloon_eyetimer--;
if ( balloon_eyetimer == 0 ){
balloon_eyetimer = BL_MEMAWASHI_TIME;
balloon_eyedata = 0;
}
/*---------------------------------*/
/*===== balloon fireshot ======*/
if ( balloon_eyedata < 5000 ){
if ( balloon_subtimer == balloon_random ) balloon_wink = 1;
if ( balloon_subtimer == balloon_random+20 ){
balloon_makefire();
balloon_subtimer = 0;
balloon_random = Randomf()*BL_ATTACKTIME + BL_ATTACKTIME;
}
balloon_subtimer++;
} else {
balloon_subtimer = 0;
balloon_random = Randomf()*BL_ATTACKTIME + BL_ATTACKTIME;
}
/*---------------------------------*/
if ( obj_playerdist > 800 ) obj_mode = mode_balloon_roll;
}
/********************************************************************************
roll
********************************************************************************/
#define BL_SHOTTIME_START 30
#define BL_SHOTTIME_FIRE 60
#define BL_SHOTTIME_RESET 0
static void balloon_roll(void)
{
short targetangle = s_calc_targetangle(execstp,player1stp);
short dangle1 = s_calc_dangle(obj_angleY,targetangle);
short dangle2 = s_calc_dangle(obj_angleY ,player1stp->s[stw_animeangleY].d);
if ( obj_timer == 0 ){
s_hitON();
obj_angleX = 0;
balloon_subtimer = BL_SHOTTIME_START;
balloon_random = Randomf()*20;
if (balloon_random & 1) obj_anglespeedY = -0x100;
else obj_anglespeedY = 0x100;
}
if ( dangle1 < 0x400 && dangle2 > 0x4000 ){
if ( obj_playerdist < 700 ) obj_mode = mode_balloon_playereye;
else balloon_subtimer++;
} else {
obj_angleY += obj_anglespeedY;
balloon_subtimer = BL_SHOTTIME_START;
}
/*===== balloon fireshot ======*/
if ( balloon_subtimer == ( BL_SHOTTIME_FIRE+balloon_random) ) balloon_wink = 1;
if ( balloon_subtimer > (20+BL_SHOTTIME_FIRE+balloon_random) ){
balloon_subtimer = BL_SHOTTIME_RESET;
balloon_random = Randomf()*80;
balloon_makefire();
}
}
/********************************************************************************
init
********************************************************************************/
static void balloon_init(void)
{
s_set_angle(execstp,0,0,0);
s_set_scale(obj_programselect+1);
if ( obj_timer == 0 ) s_copy_initpos();
if ( obj_playerdist < 1500 ) obj_mode = mode_balloon_roll;
}
/********************************************************************************
balloon main program
********************************************************************************/
static void *balloon_modejmp[] = {
balloon_init,
balloon_roll,
balloon_playereye,
balloon_eyedamage
};
#define BL_DAMAGE_R 100
#define BL_DAMAGE_H 150
static HitCheckRecord balloon_hit = {
OBJNAME_DAMAGE,
0,2,2,5, /* flag,ap,hp,coin */
80,150, /* damage check */
0, 0,
};
extern void s_balloon(void)
{
s_set_hitparam(execstp,&balloon_hit);
s_modejmp(balloon_modejmp);
if ( obj_mode != mode_balloon_eyedamage ){
if ( obj_playerdist > 3000 ||
execstp->status & OBJECT_AREAOUT ) obj_mode = mode_balloon_init;
}
obj_mail = 0;
}
/*################*/
#endif
/*################*/
/*===============================================================================
end end end end end end end end
===============================================================================*/