Add free button hotkey

This commit is contained in:
Stepland 2022-11-21 23:55:25 +01:00
parent f0f15b4e64
commit 0e8b092d5d
5 changed files with 65 additions and 3 deletions

View File

@ -79,6 +79,11 @@ namespace better {
const auto [start_beat, end_beat] = note.get_time_bounds();
/*
Old comment dating back to a time when "collision_zone" was set to a
fixed value of 1000ms :
---
Two notes collide if they are within ~one second of each other :
Approach and burst animations of original jubeat markers last 16 frames
at (supposedly) 30 fps, which means a note needs (a bit more than) half
@ -110,6 +115,23 @@ namespace better {
return found_collision;
};
bool Notes::would_collide(const better::Note& potential_new_note, const better::Timing& timing, const sf::Time& collision_zone) const {
const auto [start_beat, end_beat] = potential_new_note.get_time_bounds();
const auto collision_start = timing.beats_at(timing.time_at(start_beat) - collision_zone);
const auto collision_end = timing.beats_at(timing.time_at(end_beat) + collision_zone);
bool found_collision = false;
in(
{collision_start, collision_end},
[&](const Notes::const_iterator& it){
if (it->second.get_position() == potential_new_note.get_position()) {
found_collision = true;
}
}
);
return found_collision;
}
Notes Notes::between(const Interval<Fraction>& bounds) {
Notes res;
in(bounds.start, bounds.end, [&](const Notes::const_iterator& it){

View File

@ -35,11 +35,19 @@ namespace better {
void erase(const Note& note);
/*
Returns true if the given note (assumed to already be in the container)
Returns true if the given note (assumed to ALREADY BE in the container)
is colliding with ANOTHER note. This means notes exactly equal to the
one passed as an argument are NOT taken into account.
*/
bool is_colliding(const better::Note& note, const better::Timing& timing, const sf::Time& collision_zone) const;
bool is_colliding(const better::Note& existing_note, const better::Timing& timing, const sf::Time& collision_zone) const;
/*
Returns true if INSERTING the note passed as argument would result
in a collision. The note is assumed not to be part of the container yet
so existing notes in the container that are exactly equal to the one
passed as argument WILL be taken into account
*/
bool would_collide(const better::Note& potential_new_note, const better::Timing& timing, const sf::Time& collision_zone) const;
Notes between(const Interval<Fraction>& bounds);
std::size_t count_between(const Interval<Fraction>& bounds);

View File

@ -516,13 +516,27 @@ void EditorState::display_playfield(Marker& marker, Judgement markerEndingState)
}
if (chart_state) {
// Check for collisions then display them
// Check for real (+ potential if requested) collisions
// then display them
std::array<bool, 16> collisions = {};
for (const auto& [_, note] : chart_state->visible_notes) {
if (chart_state->chart.notes->is_colliding(note, *applicable_timing, config.editor.collision_zone)) {
collisions[note.get_position().index()] = true;
}
}
if (show_free_buttons) {
for (unsigned int i = 0; i < 16; i++) {
unsigned int x = i % 4;
unsigned int y = i / 4;
if (chart_state->chart.notes->would_collide(
better::TapNote{current_exact_beats(), {x, y}},
*applicable_timing,
config.editor.collision_zone
)) {
collisions[i] = true;
}
}
}
for (int i = 0; i < 16; ++i) {
if (collisions.at(i)) {
int x = i % 4;

View File

@ -165,6 +165,10 @@ public:
bool show_timing_menu = false;
void display_timing_menu();
// Toggled by the F hotkey, highlights in red on the playfield the buttons
// where adding a note would result in a collision
bool show_free_buttons = false;
enum class SaveOutcome {
UserSaved,
UserDeclindedSaving,

View File

@ -362,6 +362,10 @@ int main() {
}
}
break;
case sf::Keyboard::F:
if (editor_state) {
editor_state->show_free_buttons = true;
}
case sf::Keyboard::O:
if (event.key.control) {
feis::save_ask_open(editor_state, assets_folder, settings_folder, config);
@ -409,6 +413,16 @@ int main() {
break;
}
break;
case sf::Event::KeyReleased:
switch (event.key.code) {
case sf::Keyboard::F:
if (editor_state) {
editor_state->show_free_buttons = false;
}
default:
break;
}
break;
default:
break;
}