ReC98/th04/main/boss/b4m.cpp

58 lines
1.9 KiB
C++
Raw Normal View History

/// Stage 4 Boss - Marisa
/// ---------------------
#include "platform.h"
#include "pc98.h"
#include "th01/math/subpixel.hpp"
#include "th04/math/motion.hpp"
#include "th04/main/playfld.hpp"
#include "th04/main/phase.hpp"
#include "th04/main/boss/boss.hpp"
/// State
/// -----
#define flystep_pointreflected_frame boss_statebyte[13]
/// -----
// On [flystep_pointreflected_frame] 0, this function sets up [boss] movement
// towards the point reflection of Marisa's position across a fixed position
// near the top of the sealed moon in the background. The velocity is
// calculated to reach this exact point at [duration - 12], with Marisa braking
// on the last 12 frames by halving that velocity each frame. Every call to
// this function, including the one on frame 0, then applies this velocity to
// [boss].
// [duration] values <12 will move Marisa into the opposite direction instead.
// Returns `true` if the function was called for [duration] frames.
//
// ZUN bug: Not defined for [duration] values of 12 or 13, which will crash the
// game with a division by zero ("Divide Error"). The two patterns that pass a
// variable [duration] to this function also only happen to call this function
// every 4 frames rather than every frame, introducing additional jerkiness.
bool pascal near marisa_flystep_pointreflected(int duration)
{
enum {
POINT_X = TO_SP(PLAYFIELD_W / 2),
POINT_Y = TO_SP((PLAYFIELD_H * 7) / 23),
BRAKE_DURATION = 12,
};
if(flystep_pointreflected_frame == 0) {
boss.pos.velocity.x.v = (
(POINT_X - boss.pos.cur.x) / ((duration / 2) - (BRAKE_DURATION / 2))
);
boss.pos.velocity.y.v = (
(POINT_Y - boss.pos.cur.y) / ((duration / 2) - (BRAKE_DURATION / 2))
);
}
flystep_pointreflected_frame++;
if(flystep_pointreflected_frame >= (duration - BRAKE_DURATION)) {
boss.pos.velocity.x.v /= 2;
boss.pos.velocity.y.v /= 2;
}
if(flystep_pointreflected_frame >= duration) {
return true;
}
boss.pos.update_seg3();
return false;
}