505 lines
12 KiB
OpenEdge ABL
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
|
|
===============================================================================*/
|
|
|
|
|
|
|