sm64/data/iwa_path/ironball.s
2022-12-04 22:27:02 -05:00

522 lines
13 KiB
ArmAsm

/********************************************************************************
-------------------------
Ultra 64 MARIO Brothers
-------------------------
Iron Ball Strategy
Feburary 19 1996 programed by Iwamoto Daiki
********************************************************************************/
/*################*/
#ifdef ASSEMBLER
/*################*/
/********************************************************************************/
/* Slider IronBall path Program */
/********************************************************************************/
e_ironball:
p_initialize(enemyA)
p_setbit(flag,stf_moveON)
p_softspritemodeON
p_setf(animepositionY,130)
p_program(s_ironball_init)
p_while
p_program(s_ironball)
p_loop
e_ironball_normal:
p_initialize(enemyA)
p_setbit(flag,stf_moveON)
p_softspritemodeON
p_setf(animepositionY,130)
p_program(s_ironball_normal_init)
p_while
p_program(s_ironball_normal_main)
p_loop
e_rail_ironball:
p_initialize(enemyA)
p_setbit(flag,stf_moveON)
p_softspritemodeON
p_setf(animepositionY,130)
p_program(s_rail_ironball_init)
p_while
p_program(s_rail_ironball)
p_loop
e_gush_ironball:
p_initialize(enemyA)
p_setbit(flag,stf_moveON)
p_setd(work2,0x3f)
p_program(s_gush_ironball_init)
p_while
p_program(s_gush_ironball)
p_loop
e_gush_ironball_few:
p_initialize(enemyA)
p_setbit(flag,stf_moveON)
p_setd(work2,0x7f)
p_program(s_gush_ironball_init)
p_while
p_program(s_gush_ironball)
p_loop
e_gush_ironball2:
p_initialize(enemyA)
p_setbit(flag,stf_moveON)
p_while
p_program(s_gush_ironball2)
p_loop
/*################*/
#else
/*################*/
/***************************************************************************************************
C Program
****************************************************************************************************/
#define target_angY (execstp->s[stw_work0].d)
#define iron_maxspeed (execstp->s[stw_work1].f)
/*-----------------------
programselect
0 stage9 No1
1 stage36 No1
2 stage9 No2
3 stage13 No1
4 stage13 No2
-------------------------*/
static HitCheckRecord ironball_hit = {
OBJNAME_DAMAGE,
0,2,0,0, /* flag,ap,hp,coin */
100, 150, /* player damage hitarea */
0, 0, /* player attack hitarea */
};
extern short ironball_stage9_raildata[];
extern short ironball_stage36_raildata[];
extern short ironball_stage9_2_raildata[];
extern short ironball_stage13_a_raildata[]={
0, -4786, 101, -2166,
1, -5000, 81, -2753,
2, -5040, 33, -3846,
3, -4966, 38, -4966,
4, -4013, -259, -4893,
5, -2573, -1019, -4780,
6, -1053, -1399, -4806,
7, 760, -1637, -4833,
8, 2866, -2047, -4886,
9, 3386, -6546, -4833,
-1,
};
extern short ironball_stage13_b_raildata[]={
0, -1476, 29, -680,
1, -1492, 14, -1072,
2, -1500, 3, -1331,
3, -1374, -17, -1527,
4, -1178, -83, -1496,
5, -292, -424, -1425,
6, 250, -491, -1433,
7, 862, -613, -1449,
8, 1058, -1960, -1449,
-1,
};
/*==================================================================================================*/
/*==================================================================================================*/
/***************************************************************************************************
Move Ironball Init
***************************************************************************************************/
extern void s_rail_ironball_init(void)
{
execstp->s[stw_gravity].f = 5.5;
execstp->s[stw_friction].f = 1.0;
execstp->s[stw_specificG].f = 2.0;
}
/***************************************************************************************************
Iron Ball Attack
***************************************************************************************************/
static void iron_PlayerTouch(void)
{
s_set_hitparam(execstp,&ironball_hit); /* Set HitCheck Param */
if ( obj_mail & EMAIL_PLAYERHIT ){
Mbitclr(obj_mail,EMAIL_PLAYERHITALL);
}
}
/***************************************************************************************************
Iron Ball Attack
***************************************************************************************************/
static void iron_ReadRailData(void)
{
switch (obj_programselect) {
case 0: road_root(execstp) = (short*) (SegmentToVirtual(ironball_stage9_raildata));
break;
case 1: road_root(execstp) = (short*) (SegmentToVirtual(ironball_stage36_raildata));
break;
case 2: road_root(execstp) = (short*) (SegmentToVirtual(ironball_stage9_2_raildata));
break;
case 3: road_root(execstp) = (short*) (ironball_stage13_a_raildata);
break;
case 4: road_root(execstp) = (short*) (ironball_stage13_b_raildata);
break;
}
}
/***************************************************************************************************
Raill Iron Ball Event
***************************************************************************************************/
extern void Ironball_Move(void)
{
short move_flag;
int lift_flag;
iron_ReadRailData();
move_flag = ObjMoveEvent();
lift_flag = s_road_move(lift_flag);
target_angY = road_angleY(execstp);
obj_angleY = s_chase_angle(obj_angleY,target_angY,0x400);
if (execstp->s[stw_speedF].f > 70.0) execstp->s[stw_speedF].f = 70.0;
iron_PlayerTouch();
if (lift_flag == -1) {
if (PlayerApproach(obj_worldX,obj_worldY,obj_worldZ,7000)) {
s_kemuri();
s_burneffect(0,0,92);
}
execstp->status = 0;
}
if ((move_flag & OM_TOUCH) && obj_speedY > 5) { objsound(NA_SE2_M_BALL_BOUND); }
}
/***************************************************************************************************
Raill Iron Ball Event
***************************************************************************************************/
static void iron_ProgramInit(void)
{
int lift_flag;
iron_ReadRailData();
lift_flag = s_road_move(lift_flag);
obj_angleY = road_angleY(execstp);
switch(obj_programselect) {
case 0: obj_speedF = 20;
break;
case 1: obj_speedF = 10;
break;
case 2: obj_speedF = 20;
break;
case 3: obj_speedF = 25;
break;
case 4: obj_speedF = 10;
s_set_scale(0.3);
obj_animepositionY = 130*0.3;
break;
}
}
/***************************************************************************************************
Rail Iron Ball Event
***************************************************************************************************/
extern void s_rail_ironball(void)
{
switch (obj_mode) {
case 0: obj_mode = 1;
iron_ProgramInit();
break;
case 1: Ironball_Move();
break;
}
if (obj_programselect != 4) {
Viewshaking(VS_GOROGORO,obj_worldX,obj_worldY,obj_worldZ);
}
// objsound_level(NA_LSE2_ROCKROLL);
PlayerApproachOnOff(execstp,4000);
}
/*-------------------------------------------------------------------------------------------------*/
#define gush_iron_length (execstp->s[stw_work0].f)
#define gush_iron_random (execstp->s[stw_work1].f)
#define gush_iron_freq (execstp->s[stw_work2].d)
/***************************************************************************************************
Rail Iron Ball Program Select
***************************************************************************************************/
extern void s_gush_ironball_init(void)
{
switch (obj_programselect) {
case 0: gush_iron_length = 7000.;
gush_iron_random = 2.0;
break;
case 1: gush_iron_length = 8000.;
gush_iron_random = 1.0;
break;
case 2: gush_iron_length = 6000.;
gush_iron_random = 2.0;
break;
}
}
/***************************************************************************************************
Rail Iron Ball Event
***************************************************************************************************/
extern void s_gush_ironball(void)
{
StrategyRecord *stratp;
if (obj_timer == 256) obj_timer = 0;
if (PlayerApproach(obj_worldX,obj_worldY,obj_worldZ,1000) || (obj_worldY < player_posY) ) {
return;
}
if ((obj_timer & gush_iron_freq)== 0) {
if (PlayerApproach(obj_worldX,obj_worldY,obj_worldZ,(int)gush_iron_length)) {
if ((int)(Randomf()*gush_iron_random) == 0) {
stratp = s_makeobj_nowpos(execstp,S_ironball,e_rail_ironball);
stratp->s[stw_programselect].d = obj_programselect;
}
}
}
}
/***************************************************************************************************
Rail Iron Ball Event 2
***************************************************************************************************/
extern void s_gush_ironball2(void)
{
StrategyRecord *stratp;
if (obj_timer == 256) obj_timer = 0;
if (PlayerApproach(obj_worldX,obj_worldY,obj_worldZ,800) || (obj_worldY < player_posY) ) {
return;
}
if ((obj_timer & 0x3f)== 0) {
if (PlayerApproach(obj_worldX,obj_worldY,obj_worldZ,(int)12000)) {
if ((int)(Randomf()*1.5) == 0) {
stratp = s_makeobj_nowpos(execstp,S_ironball,e_rail_ironball);
stratp->s[stw_programselect].d = obj_programselect;
}
}
}
}
/*==================================================================================================
====================================================================================================
====================================================================================================
====================================================================================================
====================================================================================================
====================================================================================================
====================================================================================================
====================================================================================================
====================================================================================================*/
/*====================================================================================================
Furiko Ironball
====================================================================================================*/
/***************************************************************************************************
Move Ironball Init
***************************************************************************************************/
extern void s_ironball_init(void)
{
execstp->s[stw_gravity].f = 12.;
execstp->s[stw_friction].f = 1.0;
execstp->s[stw_specificG].f = 2.0;
}
/***************************************************************************************************
Iron Ball Event
***************************************************************************************************/
extern void s_ironball(void)
{
Plane *plane;
short move_flag;
move_flag = ObjMoveEvent();
// rmonpf(("speedf %f\n",obj_speedF));
// rmonpf(("a %f\n",plane->a));
// rmonpf(("c %f\n",plane->c));
GroundCheck(obj_worldX,obj_worldY,obj_worldZ,&plane);
if (plane->a==0 && plane->c==0) obj_speedF = 28;
iron_PlayerTouch();
Viewshaking(VS_GOROGORO,obj_worldX,obj_worldY,obj_worldZ);
objsound_level(NA_LSE2_ROCKROLL);
PlayerApproachOnOff(execstp,3000);
}
/*==================================================================================================
Ironball Normal
====================================================================================================*/
/***************************************************************************************************
Normal Ironball Init
***************************************************************************************************/
extern void s_ironball_normal_init(void)
{
execstp->s[stw_gravity].f = 5.5;
execstp->s[stw_friction].f = 1.0;
execstp->s[stw_specificG].f = 2.0;
obj_attX = obj_worldX;
obj_attY = obj_worldY;
obj_attZ = obj_worldZ;
obj_speedF = 0;
obj_angleY = 0;
}
/***************************************************************************************************
Normal Iron Ball Move
***************************************************************************************************/
static void normal_ball_Move(void)
{
short move_flag;
move_flag = ObjMoveEvent();
iron_PlayerTouch();
if (obj_speedF > 10) {
Viewshaking(VS_GOROGORO,obj_worldX,obj_worldY,obj_worldZ);
objsound_level(NA_LSE2_ROCKROLL);
}
if ((move_flag & OM_TOUCH) && (move_flag & OM_GROUND)==0) { objsound(NA_SE2_M_BALL_BOUND); }
if (PlayerApproach(obj_worldX,obj_worldY,obj_worldZ,6000)==0) {
MapHideShape(&execstp->map);
s_hitOFF();
obj_worldX = obj_attX;
obj_worldY = obj_attY;
obj_worldZ = obj_attZ;
s_ironball_normal_init();
obj_mode = 2;
}
}
/***************************************************************************************************
Iron Ball Event
***************************************************************************************************/
extern void s_ironball_normal_main(void)
{
execstp->s[stw_gravity].f = 5.5;
switch (obj_mode) {
case 0: if (PlayerApproach(obj_worldX,obj_worldY,obj_worldZ,3000)) {
obj_mode = 1;
MapDispShape(&execstp->map);
s_hitON();
}
break;
case 1: normal_ball_Move();
break;
case 2: if (PlayerApproach(obj_worldX,obj_worldY,obj_worldZ,5000)) {
obj_mode = 0;
}
break;
}
}
/*################*/
#endif
/*################*/