diff --git a/projects/Core/messages/message_controller.cpp b/projects/Core/messages/message_controller.cpp index 6c72c72fc3..7bc346cdaf 100644 --- a/projects/Core/messages/message_controller.cpp +++ b/projects/Core/messages/message_controller.cpp @@ -61,7 +61,7 @@ namespace core::messages { } // namespace void MessageController::update_time(const MessageData& data, const float delta_time) { - if (data.handle->state == message_handle_t::MessageState::Visible) { + if (data.handle->state == message_handle_t::QueuedMessageState::Visible) { data.handle->active_time += delta_time; } @@ -74,7 +74,7 @@ namespace core::messages { } if (*data.handle->time_left <= 0.f) { - data.handle->state = message_handle_t::MessageState::Finished; + data.handle->state = message_handle_t::QueuedMessageState::Finished; data.handle->time_left = std::optional(); } } @@ -95,7 +95,7 @@ namespace core::messages { if (!m_current->info.prioritized && !m_priority_data.empty()) { // Switch out normal message for prioritized, pausing it. m_current->message->hide(true); - m_current->handle->state = message_handle_t::MessageState::InterruptedByPriorityMessage; + m_current->handle->state = message_handle_t::QueuedMessageState::InterruptedByPriorityMessage; m_normal_data.insert(m_normal_data.begin(), *m_current); m_current = m_priority_data.front(); m_priority_data.erase(m_priority_data.begin()); @@ -103,16 +103,16 @@ namespace core::messages { update_time(*m_current, delta_time); switch (m_current->handle->state) { - case message_handle_t::MessageState::InterruptedByPriorityMessage: - m_current->handle->state = message_handle_t::MessageState::Visible; + case message_handle_t::QueuedMessageState::InterruptedByPriorityMessage: + m_current->handle->state = message_handle_t::QueuedMessageState::Visible; m_current->message->show(m_current->info.instant_fade, m_current->info.play_sound); break; - case message_handle_t::MessageState::Queued: + case message_handle_t::QueuedMessageState::Queued: m_current->handle->time_left = m_current->info.duration; - m_current->handle->state = message_handle_t::MessageState::Visible; + m_current->handle->state = message_handle_t::QueuedMessageState::Visible; m_current->message->show(m_current->info.instant_fade, m_current->info.play_sound); break; - case message_handle_t::MessageState::Finished: + case message_handle_t::QueuedMessageState::Finished: // Clear m_current, so it gets set next time update is run. m_current->message->hide(m_current->info.instant_fade); m_current = std::optional(); @@ -161,7 +161,7 @@ namespace core::messages { sync = queue.add(std::move(message), std::move(info)); } else { sync = std::make_shared(); - sync->state = message_handle_t::MessageState::Visible; + sync->state = message_handle_t::QueuedMessageState::Visible; sync->time_left = info.duration; sync->message = message; message->show(info.instant_fade, info.play_sound); @@ -246,7 +246,7 @@ namespace core::messages { for (auto it = m_unqueued_messages.begin(); it != m_unqueued_messages.end();) { update_time(*it, delta_time); - if (it->handle->state == message_handle_t::MessageState::Finished) { + if (it->handle->state == message_handle_t::QueuedMessageState::Finished) { it = m_unqueued_messages.erase(it); } else { ++it; diff --git a/projects/Core/messages/message_display.cpp b/projects/Core/messages/message_display.cpp index 5240e4e38a..4c9ca3dd2f 100644 --- a/projects/Core/messages/message_display.cpp +++ b/projects/Core/messages/message_display.cpp @@ -66,7 +66,7 @@ namespace core::messages { const auto max_in_queue = m_max_in_queue.get(); if (max_in_queue.has_value() && m_messages.size() > max_in_queue.value() && !m_active_messages.empty()) { m_active_messages.front().message->hide(); - m_active_messages.front().handle->state = message_handle_t::MessageState::Finished; + m_active_messages.front().handle->state = message_handle_t::QueuedMessageState::Finished; } int total_lines = 0; @@ -81,7 +81,7 @@ namespace core::messages { if (max_line_count.has_value() && total_lines_temp >= max_line_count.value()) { for (auto jit = it; jit != m_active_messages.end(); ++jit) { jit->info.duration = std::max(jit->handle->active_time, 1.0f); - jit->handle->state = message_handle_t::MessageState::Finished; + jit->handle->state = message_handle_t::QueuedMessageState::Finished; jit->handle->time_left = jit->info.duration; jit->handle->active_time = 0; jit->message->hide(jit->info.instant_fade); @@ -152,7 +152,7 @@ namespace core::messages { bool MessageDisplay::handle_active_message(MessageData& data, int& total_lines, app::Vector3& cursor_position, float fade_out, float delta_time) { update_time(data, delta_time); - if (data.handle->state != message_handle_t::MessageState::Finished) { + if (data.handle->state != message_handle_t::QueuedMessageState::Finished) { update_message_position(data, total_lines, cursor_position, delta_time); data.message->fade_out().set(fade_out); return true; @@ -170,7 +170,7 @@ namespace core::messages { } void MessageDisplay::update_time(MessageData& data, float delta_time) { - if (data.handle->state == message_handle_t::MessageState::Visible) { + if (data.handle->state == message_handle_t::QueuedMessageState::Visible) { data.handle->active_time += delta_time; } @@ -183,7 +183,7 @@ namespace core::messages { } if (*data.handle->time_left <= 0.f) { - data.handle->state = message_handle_t::MessageState::Finished; + data.handle->state = message_handle_t::QueuedMessageState::Finished; data.handle->time_left = std::optional(); } } @@ -203,7 +203,7 @@ namespace core::messages { cursor_position.y -= data.info.padding.x * cursor_y_direction; // Animate message box movement if the message is visible - if (data.handle->state == MessageHandle::MessageState::Visible) { + if (data.handle->state == QueuedMessageHandle::QueuedMessageState::Visible) { // When this message is queued, stall it on the pickup position data.message->position().set( modloader::math::lerp( @@ -261,7 +261,7 @@ namespace core::messages { data.message->show(false, data.info.play_sound); } - data.handle->state = message_handle_t::MessageState::Visible; + data.handle->state = message_handle_t::QueuedMessageState::Visible; } int MessageDisplay::get_expand_direction_y_multiplier() const { diff --git a/projects/Core/messages/message_handle.h b/projects/Core/messages/message_handle.h index 8be5570836..0aa61a2c4c 100644 --- a/projects/Core/messages/message_handle.h +++ b/projects/Core/messages/message_handle.h @@ -6,20 +6,20 @@ #include namespace core::messages { - struct MessageHandle { - enum class MessageState { + struct QueuedMessageHandle { + enum class QueuedMessageState { Queued, InterruptedByPriorityMessage, Visible, Finished }; - MessageState state = MessageState::Queued; + QueuedMessageState state = QueuedMessageState::Queued; std::optional time_left; float active_time = 0; std::weak_ptr message; }; } // namespace core::messages -using message_handle_t = core::messages::MessageHandle; +using message_handle_t = core::messages::QueuedMessageHandle; using message_handle_ptr_t = std::shared_ptr; diff --git a/projects/Randomizer/features/wheel_initialization.cpp b/projects/Randomizer/features/wheel_initialization.cpp index 1c4732f348..e95d6f4b6c 100644 --- a/projects/Randomizer/features/wheel_initialization.cpp +++ b/projects/Randomizer/features/wheel_initialization.cpp @@ -20,7 +20,7 @@ namespace randomizer::features::wheel { set_wheel_item_description(wheel, position, desc); set_wheel_item_texture(wheel, position, texture); set_wheel_item_color(wheel, position, 255, 255, 255, 255); - set_wheel_item_callback(wheel, position, WheelBind::Ability1, callback); + set_wheel_item_callback(wheel, position, WheelBind::All, callback); } void on_dev_changed() { @@ -190,8 +190,16 @@ namespace randomizer::features::wheel { }); initialize_item(9001, 9, "Force Exit", "Forcibly exit the game.", "file:assets/icons/wheel/force_exit.blue.png", [](auto, auto, auto) { modloader::shutdown(); }); - initialize_item(9001, 10, "Clear messages", "Clears the message queue.", "file:assets/icons/wheel/clear_messages.blue.png", - [](auto, auto, auto) { core::message_controller().clear_central(); }); + initialize_item(9001, 10, "Clear messages", "[Ability1] Clear all\n[Ability2] Clear queue\n[Ability3] Clear free", "file:assets/icons/wheel/clear_messages.blue.png", + [](auto, auto, auto bind) { + if (bind == WheelBind::Ability1 || bind == WheelBind::Ability2) { + core::message_controller().clear_central(); + } + + if (bind == WheelBind::Ability1 || bind == WheelBind::Ability3) { + seed::destroy_free_message_boxes(); + } + }); initialize_item(9001, 11, "Next", "Go to next page of actions", "file:assets/icons/wheel/menu.blue.png", [](auto, auto, auto) { set_active_wheel(9000); }); on_dev_changed(); diff --git a/projects/Randomizer/online/multiplayer.cpp b/projects/Randomizer/online/multiplayer.cpp index 8a57761b91..07991736de 100644 --- a/projects/Randomizer/online/multiplayer.cpp +++ b/projects/Randomizer/online/multiplayer.cpp @@ -374,7 +374,7 @@ namespace randomizer::online { std::shared_ptr box = nullptr; if (message->has_id()) { auto it = m_message_boxes.find(message->id()); - if (it != m_message_boxes.end() && it->second->state != message_handle_t::MessageState::Finished) { + if (it != m_message_boxes.end() && it->second->state != message_handle_t::QueuedMessageState::Finished) { box = it->second->message.lock(); it->second->time_left = message->time(); } diff --git a/projects/Randomizer/seed/instructions.cpp b/projects/Randomizer/seed/instructions.cpp index e0f6af4c8d..032437393d 100644 --- a/projects/Randomizer/seed/instructions.cpp +++ b/projects/Randomizer/seed/instructions.cpp @@ -22,21 +22,21 @@ namespace randomizer::seed { core::api::uber_states::UberState value; }; - struct SeedMessage { - core::messages::MessageHandle::MessageState last_state = core::messages::MessageHandle::MessageState::Queued; + struct QueuedMessageBox { + core::messages::QueuedMessageHandle::QueuedMessageState last_state = core::messages::QueuedMessageHandle::QueuedMessageState::Queued; message_handle_ptr_t handle; std::optional visible_callback; std::optional hidden_callback; }; - struct SeedControlledMessage { + struct FreeMessageBox { std::shared_ptr message; std::optional timeout; }; std::unordered_map> warp_icons; - std::unordered_map central_message_boxes; - std::unordered_map message_boxes; + std::unordered_map queued_message_boxes; + std::unordered_map free_message_boxes; std::unordered_set message_boxes_with_timeouts; std::vector timers; bool prevent_grant = false; @@ -47,23 +47,23 @@ namespace randomizer::seed { auto on_update = core::api::game::event_bus().register_handler(GameEvent::Update, EventTiming::After, [](auto, auto) { if (!core::api::game::in_game()) { - central_message_boxes.clear(); + queued_message_boxes.clear(); message_boxes_with_timeouts.clear(); - message_boxes.clear(); + free_message_boxes.clear(); timers.clear(); return; } - for (auto& message: central_message_boxes | std::views::values) { + for (auto& message: queued_message_boxes | std::views::values) { if (message.last_state == message.handle->state) { continue; } - if (message.handle->state == core::messages::MessageHandle::MessageState::Visible && message.visible_callback.has_value()) { + if (message.handle->state == core::messages::QueuedMessageHandle::QueuedMessageState::Visible && message.visible_callback.has_value()) { game_seed().execute_command(message.visible_callback.value()); } - if (message.last_state == core::messages::MessageHandle::MessageState::Visible && message.hidden_callback.has_value()) { + if (message.last_state == core::messages::QueuedMessageHandle::QueuedMessageState::Visible && message.hidden_callback.has_value()) { game_seed().execute_command(message.hidden_callback.value()); } @@ -72,7 +72,7 @@ namespace randomizer::seed { std::unordered_set to_destroy; for (const auto id: message_boxes_with_timeouts) { - auto& box = message_boxes.at(id); + auto& box = free_message_boxes.at(id); if (box.timeout.has_value()) { box.timeout.value() -= core::api::game::delta_time(); if (box.timeout.value() < 0) { @@ -83,7 +83,7 @@ namespace randomizer::seed { for (const auto id: to_destroy) { message_boxes_with_timeouts.erase(id); - message_boxes.erase(id); + free_message_boxes.erase(id); } for (const auto& timer: timers) { @@ -542,8 +542,8 @@ namespace randomizer::seed { ); if (id.has_value()) { - central_message_boxes[id.value()] = {.handle = handle}; - message_boxes.erase(id.value()); + queued_message_boxes[id.value()] = {.handle = handle}; + free_message_boxes.erase(id.value()); message_boxes_with_timeouts.erase(id.value()); } } @@ -568,8 +568,8 @@ namespace randomizer::seed { std::size_t id; std::size_t command; void execute(Seed& seed, SeedMemory& memory) const override { - const auto it = central_message_boxes.find(id); - if (it == central_message_boxes.end()) { + const auto it = queued_message_boxes.find(id); + if (it == queued_message_boxes.end()) { on_visible ? it->second.visible_callback : it->second.hidden_callback = command; } } @@ -586,9 +586,9 @@ namespace randomizer::seed { std::size_t id; void execute(Seed& seed, SeedMemory& memory) const override { message_boxes_with_timeouts.erase(id); - message_boxes[id].message = std::make_shared(); - message_boxes[id].message->text_processor(general_text_processor()); - central_message_boxes.erase(id); + free_message_boxes[id].message = std::make_shared(); + free_message_boxes[id].message->text_processor(general_text_processor()); + queued_message_boxes.erase(id); } [[nodiscard]] std::string to_string(const Seed& seed, const SeedMemory& memory) const override { return std::format("FreeMessageCreate {}", id); } @@ -600,8 +600,8 @@ namespace randomizer::seed { std::size_t id; void execute(Seed& seed, SeedMemory& memory) const override { - if (message_boxes.contains(id)) { - message_boxes[id].message->show(false, memory.booleans.get(0)); + if (free_message_boxes.contains(id)) { + free_message_boxes[id].message->show(false, memory.booleans.get(0)); } } @@ -614,8 +614,8 @@ namespace randomizer::seed { std::size_t id; void execute(Seed& seed, SeedMemory& memory) const override { - if (message_boxes.contains(id)) { - message_boxes[id].message->hide(false); + if (free_message_boxes.contains(id)) { + free_message_boxes[id].message->hide(false); } } @@ -628,8 +628,8 @@ namespace randomizer::seed { std::size_t id; void execute(Seed& seed, SeedMemory& memory) const override { - if (message_boxes.contains(id)) { - message_boxes[id].message->position().set(memory.floats.get(0), memory.floats.get(1), 0.f); + if (free_message_boxes.contains(id)) { + free_message_boxes[id].message->position().set(memory.floats.get(0), memory.floats.get(1), 0.f); } } @@ -646,8 +646,8 @@ namespace randomizer::seed { std::size_t id; app::AlignmentMode__Enum alignment; void execute(Seed& seed, SeedMemory& memory) const override { - if (message_boxes.contains(id)) { - message_boxes[id].message->alignment().set(alignment); + if (free_message_boxes.contains(id)) { + free_message_boxes[id].message->alignment().set(alignment); } } @@ -664,8 +664,8 @@ namespace randomizer::seed { std::size_t id; core::api::screen_position::ScreenPosition screen_position; void execute(Seed& seed, SeedMemory& memory) const override { - if (message_boxes.contains(id)) { - message_boxes[id].message->screen_position().set(screen_position); + if (free_message_boxes.contains(id)) { + free_message_boxes[id].message->screen_position().set(screen_position); } } @@ -683,8 +683,8 @@ namespace randomizer::seed { app::VerticalAnchorMode__Enum anchor; void execute(Seed& seed, SeedMemory& memory) const override { - if (message_boxes.contains(id)) { - message_boxes[id].message->vertical_anchor().set(anchor); + if (free_message_boxes.contains(id)) { + free_message_boxes[id].message->vertical_anchor().set(anchor); } } @@ -702,8 +702,8 @@ namespace randomizer::seed { app::HorizontalAnchorMode__Enum anchor; void execute(Seed& seed, SeedMemory& memory) const override { - if (message_boxes.contains(id)) { - message_boxes[id].message->horizontal_anchor().set(anchor); + if (free_message_boxes.contains(id)) { + free_message_boxes[id].message->horizontal_anchor().set(anchor); } } @@ -718,10 +718,10 @@ namespace randomizer::seed { std::size_t id; void execute(Seed& seed, SeedMemory& memory) const override { - message_boxes.erase(id); + free_message_boxes.erase(id); message_boxes_with_timeouts.erase(id); - if (central_message_boxes.contains(id)) { - central_message_boxes.at(id).handle->time_left = 0; + if (queued_message_boxes.contains(id)) { + queued_message_boxes.at(id).handle->time_left = 0; } } @@ -734,13 +734,13 @@ namespace randomizer::seed { std::size_t id; void execute(Seed& seed, SeedMemory& memory) const override { - const auto it = central_message_boxes.find(id); - if (it != central_message_boxes.end() && !it->second.handle->message.expired()) { + const auto it = queued_message_boxes.find(id); + if (it != queued_message_boxes.end() && !it->second.handle->message.expired()) { it->second.handle->message.lock()->text().process_and_set(memory.strings.get(0)); } - const auto qit = message_boxes.find(id); - if (qit != message_boxes.end()) { + const auto qit = free_message_boxes.find(id); + if (qit != free_message_boxes.end()) { qit->second.message->text().process_and_set(memory.strings.get(0)); } } @@ -756,13 +756,13 @@ namespace randomizer::seed { std::size_t id; void execute(Seed& seed, SeedMemory& memory) const override { - const auto it = central_message_boxes.find(id); - if (it != central_message_boxes.end() && !it->second.handle->message.expired()) { + const auto it = queued_message_boxes.find(id); + if (it != queued_message_boxes.end() && !it->second.handle->message.expired()) { it->second.handle->time_left = memory.floats.get(0); } - const auto qit = message_boxes.find(id); - if (qit != message_boxes.end()) { + const auto qit = free_message_boxes.find(id); + if (qit != free_message_boxes.end()) { qit->second.timeout = memory.floats.get(0); message_boxes_with_timeouts.emplace(qit->first); } @@ -779,13 +779,13 @@ namespace randomizer::seed { std::size_t id; void execute(Seed& seed, SeedMemory& memory) const override { - const auto it = central_message_boxes.find(id); - if (it != central_message_boxes.end() && !it->second.handle->message.expired()) { + const auto it = queued_message_boxes.find(id); + if (it != queued_message_boxes.end() && !it->second.handle->message.expired()) { it->second.handle->message.lock()->show_box().set(memory.booleans.get(0)); } - const auto qit = message_boxes.find(id); - if (qit != message_boxes.end()) { + const auto qit = free_message_boxes.find(id); + if (qit != free_message_boxes.end()) { qit->second.message->show_box().set(memory.booleans.get(0)); } } @@ -1519,7 +1519,8 @@ namespace randomizer::seed { void destroy_volatile_seed_data() { timers.clear(); - central_message_boxes.clear(); + queued_message_boxes.clear(); + free_message_boxes.clear(); for (const auto& icon: warp_icons | std::views::values) { remove_icon(icon); @@ -1527,4 +1528,8 @@ namespace randomizer::seed { warp_icons.clear(); } + + void destroy_free_message_boxes() { + free_message_boxes.clear(); + } } // namespace randomizer::seed diff --git a/projects/Randomizer/seed/instructions.h b/projects/Randomizer/seed/instructions.h index 7200fca792..278a665858 100644 --- a/projects/Randomizer/seed/instructions.h +++ b/projects/Randomizer/seed/instructions.h @@ -91,4 +91,6 @@ namespace randomizer::seed { std::unique_ptr create_instruction(const nlohmann::json& j); void destroy_volatile_seed_data(); + + void destroy_free_message_boxes(); }