sm64coopdx/src/game/behaviors/water_splashes_and_waves.inc.c
MysterD b2bdf8859c Cleanup ; recursive descent fixes ; fixed behavior override comparisons
Moved dynos parsing for bhvs and models to a common file
Fixed recursive descent to correctly parse the entire expression
Adjusted bhv generation to use recursive descent
Switched all known behavior comparisons to the overridden versions
Fixed issue with Chain Chomp in star road
2022-06-02 19:07:43 -07:00

149 lines
5.3 KiB
C

// water_splashes_and_waves.c.inc
// Water droplets from Mario jumping in a pool of water.
struct WaterDropletParams sWaterSplashDropletParams = {
/* Flags */ WATER_DROPLET_FLAG_RAND_ANGLE,
/* Model */ MODEL_WHITE_PARTICLE_SMALL,
/* Behavior */ bhvWaterDroplet,
/* Unused (flag-specific) */ 0, 0,
/* Random fvel offset, scale */ 5.0f, 3.0f,
/* Random yvel offset, scale */ 30.0f, 20.0f,
/* Random size offset, scale */ 0.5f, 1.0f
};
// Water droplets from Mario jumping in shallow water.
struct WaterDropletParams gShallowWaterSplashDropletParams = {
/* Flags */ WATER_DROPLET_FLAG_RAND_ANGLE | WATER_DROPLET_FLAG_SET_Y_TO_WATER_LEVEL,
/* Model */ MODEL_WHITE_PARTICLE_SMALL,
/* Behavior */ bhvWaterDroplet,
/* Unused (flag-specific) */ 0, 0,
/* Random fvel offset, scale */ 2.0f, 3.0f,
/* Random yvel offset, scale */ 20.0f, 20.0f,
/* Random size offset, scale */ 0.5f, 1.0f
};
// The fish particle easter egg from Mario jumping in shallow water.
struct WaterDropletParams sWaterDropletFishParams = {
/* Flags */ WATER_DROPLET_FLAG_RAND_ANGLE | WATER_DROPLET_FLAG_SET_Y_TO_WATER_LEVEL,
/* Model */ MODEL_FISH,
/* Behavior */ bhvWaterDroplet,
/* Unused (flag-specific) */ 0, 0,
/* Random fvel offset, scale */ 2.0f, 3.0f,
/* Random yvel offset, scale */ 20.0f, 20.0f,
/* Random size offset, scale */ 1.0f, 0.0f
};
// Water droplets from Mario running in shallow water.
struct WaterDropletParams gShallowWaterWaveDropletParams = {
/* Flags */ WATER_DROPLET_FLAG_RAND_ANGLE_INCR_PLUS_8000 | WATER_DROPLET_FLAG_RAND_ANGLE | WATER_DROPLET_FLAG_SET_Y_TO_WATER_LEVEL,
/* Model */ MODEL_WHITE_PARTICLE_SMALL,
/* Behavior */ bhvWaterDroplet,
/* Move angle range */ 0x6000,
/* Unused (flag-specific) */ 0,
/* Random fvel offset, scale */ 2.0f, 8.0f,
/* Random yvel offset, scale */ 10.0f, 10.0f,
/* Random size offset, scale */ 0.5f, 1.0f
};
void bhv_water_splash_spawn_droplets(void) {
s32 i;
if (o->oTimer == 0)
o->oPosY = find_water_level(o->oPosX, o->oPosZ);
if (o->oPosY > FLOOR_LOWER_LIMIT_MISC) // Make sure it is not at the default water level
for (i = 0; i < 3; i++)
spawn_water_droplet(o, &sWaterSplashDropletParams);
}
void bhv_water_droplet_loop(void) {
UNUSED u32 unusedVar;
f32 waterLevel = find_water_level(o->oPosX, o->oPosZ);
if (o->oTimer == 0) {
if (cur_obj_has_model(MODEL_FISH))
o->header.gfx.node.flags &= ~GRAPH_RENDER_BILLBOARD;
else
o->header.gfx.node.flags |= GRAPH_RENDER_BILLBOARD;
o->oFaceAngleYaw = random_u16();
}
// Apply gravity
o->oVelY -= 4.0f;
o->oPosY += o->oVelY;
// Check if fallen back into the water
if (o->oVelY < 0.0f) {
if (waterLevel > o->oPosY) {
// Create the smaller splash
struct Object* small = try_to_spawn_object(0, 1.0f, o, MODEL_SMALL_WATER_SPLASH, bhvWaterDropletSplash);
if (small != NULL) {
// immediately update render position
small->parentObj = NULL;
small->header.gfx.pos[0] = o->oPosX;
small->header.gfx.pos[1] = o->oPosY;
small->header.gfx.pos[2] = o->oPosZ;
}
obj_mark_for_deletion(o);
} else if (o->oTimer > 20)
obj_mark_for_deletion(o);
}
if (waterLevel < FLOOR_LOWER_LIMIT_MISC)
obj_mark_for_deletion(o);
}
void bhv_idle_water_wave_loop(void) {
if (o->parentObj == NULL || o->parentObj->behavior != smlua_override_behavior(bhvMario)) {
obj_mark_for_deletion(o);
return;
}
obj_copy_pos(o, o->parentObj);
u8 index = o->parentObj->oBehParams - 1;
o->oPosY = gMarioStates[index].waterLevel + 5;
if (!(o->parentObj->oMarioParticleFlags & ACTIVE_PARTICLE_IDLE_WATER_WAVE)) {
o->parentObj->oActiveParticleFlags &= (u16)~ACTIVE_PARTICLE_IDLE_WATER_WAVE;
o->activeFlags = ACTIVE_FLAG_DEACTIVATED;
}
}
void bhv_water_droplet_splash_init(void) {
cur_obj_scale(random_float() + 1.5);
}
void bhv_bubble_splash_init(void) {
f32 waterLevel = find_water_level(o->oPosX, o->oPosZ);
obj_scale_xyz(o, 0.5f, 1.0f, 0.5f);
o->oPosY = waterLevel + 5.0f;
}
void bhv_shallow_water_splash_init(void) {
struct Object *fishObj;
// Have a 1 in 256 chance to spawn the fish particle easter egg.
if ((random_u16() & 0xFF) <= 0) // Strange
{
fishObj = spawn_water_droplet(o, &sWaterDropletFishParams);
if (fishObj != NULL) {
obj_init_animation_with_sound(fishObj, blue_fish_seg3_anims_0301C2B0, 0);
}
}
}
void bhv_wave_trail_shrink(void) {
f32 waterLevel = find_water_level(o->oPosX, o->oPosZ);
// Destroy every other water wave to space them out (this is a terrible way of doing it)
if (o->oTimer == 0)
if (gGlobalTimer & 1)
obj_mark_for_deletion(o);
o->oPosY = waterLevel + 5.0f;
if (o->oTimer == 0)
o->oWaveTrailSize = o->header.gfx.scale[0];
if (o->oAnimState > 3) {
o->oWaveTrailSize = o->oWaveTrailSize - 0.1; // Shrink the wave
if (o->oWaveTrailSize < 0.0f)
o->oWaveTrailSize = 0.0f;
o->header.gfx.scale[0] = o->oWaveTrailSize;
o->header.gfx.scale[2] = o->oWaveTrailSize;
}
}