diff --git a/src/better_notes.cpp b/src/better_notes.cpp index 930c829..c6a4fa8 100644 --- a/src/better_notes.cpp +++ b/src/better_notes.cpp @@ -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& bounds) { Notes res; in(bounds.start, bounds.end, [&](const Notes::const_iterator& it){ diff --git a/src/better_notes.hpp b/src/better_notes.hpp index cb3ebc0..b60e095 100644 --- a/src/better_notes.hpp +++ b/src/better_notes.hpp @@ -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& bounds); std::size_t count_between(const Interval& bounds); diff --git a/src/editor_state.cpp b/src/editor_state.cpp index e39b517..c650f10 100644 --- a/src/editor_state.cpp +++ b/src/editor_state.cpp @@ -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 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; diff --git a/src/editor_state.hpp b/src/editor_state.hpp index fad4399..15a5cda 100644 --- a/src/editor_state.hpp +++ b/src/editor_state.hpp @@ -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, diff --git a/src/main.cpp b/src/main.cpp index 4e958e2..c615962 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -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; }