💿🐜 Antkeeper source code https://antkeeper.com
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

168 lines
5.4 KiB

  1. /*
  2. * Copyright (C) 2023 Christopher J. Howard
  3. *
  4. * This file is part of Antkeeper source code.
  5. *
  6. * Antkeeper source code is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * Antkeeper source code is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. #include "game/states/collection-menu-state.hpp"
  20. #include "game/states/main-menu-state.hpp"
  21. #include "game/controls.hpp"
  22. #include <engine/scene/text.hpp>
  23. #include <engine/debug/log.hpp>
  24. #include "game/menu.hpp"
  25. #include "game/strings.hpp"
  26. #include <engine/utility/hash/fnv1a.hpp>
  27. #include <engine/resources/resource-manager.hpp>
  28. #include <engine/animation/screen-transition.hpp>
  29. #include <engine/animation/ease.hpp>
  30. using namespace hash::literals;
  31. collection_menu_state::collection_menu_state(::game& ctx):
  32. game_state(ctx)
  33. {
  34. debug::log_trace("Entering collection menu state...");
  35. // Construct box material
  36. box_material = std::make_shared<render::material>();
  37. box_material->set_blend_mode(render::material_blend_mode::translucent);
  38. box_material->set_shader_template(ctx.resource_manager->load<gl::shader_template>("ui-element-untextured.glsl"));
  39. box_material->set_variable("tint", std::make_shared<render::matvar_fvec4>(1, math::fvec4{0.5f, 0.5f, 0.5f, 1}));
  40. // Construct box billboard
  41. box_billboard.set_material(box_material);
  42. // Construct selection material
  43. selection_material = std::make_shared<render::material>();
  44. selection_material->set_blend_mode(render::material_blend_mode::translucent);
  45. selection_material->set_shader_template(ctx.resource_manager->load<gl::shader_template>("ui-element-untextured.glsl"));
  46. box_material->set_variable("tint", std::make_shared<render::matvar_fvec4>(1, math::fvec4{1, 1, 1, 1}));
  47. // Construct selection billboard
  48. selection_billboard.set_material(selection_material);
  49. // Add box and selection billboard to UI scene
  50. ctx.ui_scene->add_object(box_billboard);
  51. ctx.ui_scene->add_object(selection_billboard);
  52. row_count = 64;
  53. column_count = 6;
  54. selected_row = 0;
  55. selected_column = 0;
  56. resize_box();
  57. mouse_moved_subscription = ctx.input_manager->get_event_dispatcher().subscribe<input::mouse_moved_event>
  58. (
  59. [&](const auto& event)
  60. {
  61. }
  62. );
  63. mouse_button_pressed_subscription = ctx.input_manager->get_event_dispatcher().subscribe<input::mouse_button_pressed_event>
  64. (
  65. [&](const auto& event)
  66. {
  67. const auto& viewport_size = ctx.window->get_viewport_size();
  68. const math::fvec2 mouse_position =
  69. {
  70. static_cast<float>(event.position.x()),
  71. static_cast<float>(viewport_size.y() - event.position.y() + 1)
  72. };
  73. if (box_bounds.contains(mouse_position))
  74. {
  75. int column = static_cast<int>((mouse_position.x() - box_bounds.min.x()) / selection_size);
  76. int row = static_cast<int>((box_bounds.max.y() - mouse_position.y()) / selection_size);
  77. if (column != selected_column || row != selected_row)
  78. {
  79. selected_column = column;
  80. selected_row = row;
  81. selection_billboard.set_translation
  82. (
  83. {
  84. (box_bounds.min.x() + selection_size * 0.5f) + selection_size * selected_column,
  85. (box_bounds.max.y() - selection_size * 0.5f) - selection_size * selected_row ,
  86. 0.0f
  87. }
  88. );
  89. debug::log_debug("selected colony: ({}, {})", selected_column, selected_row);
  90. }
  91. }
  92. }
  93. );
  94. window_resized_subscription = ctx.window->get_resized_channel().subscribe
  95. (
  96. [&](const auto& event)
  97. {
  98. this->resize_box();
  99. }
  100. );
  101. // Queue enable menu controls
  102. //ctx.function_queue.push(std::bind(::enable_menu_controls, std::ref(ctx)));
  103. // Fade in from black
  104. ctx.fade_transition->transition(config::title_fade_in_duration, true, ease<float>::out_cubic);
  105. debug::log_trace("Entered collection menu state");
  106. }
  107. collection_menu_state::~collection_menu_state()
  108. {
  109. debug::log_trace("Exiting collection menu state...");
  110. // Destruct menu
  111. //::disable_menu_controls(ctx);
  112. debug::log_trace("Exited collection menu state");
  113. }
  114. void collection_menu_state::resize_box()
  115. {
  116. const float padding = 64.0f;
  117. const auto viewport_size = math::fvec2(ctx.window->get_viewport_size());
  118. box_bounds.min.x() = viewport_size.x() * 0.5f + padding;
  119. box_bounds.max.x() = viewport_size.x() - padding;
  120. selection_size = (box_bounds.max.x() - box_bounds.min.x()) / static_cast<float>(column_count);
  121. box_bounds.max.y() = viewport_size.y() - padding;
  122. box_bounds.min.y() = std::max<float>(padding, box_bounds.max.y() - selection_size * row_count);
  123. const math::fvec2 box_size = box_bounds.size();
  124. const math::fvec2 box_center = box_bounds.center();
  125. // Resize box
  126. box_billboard.set_scale({box_size.x() * 0.5f, box_size.y() * 0.5f, 1.0f});
  127. box_billboard.set_translation({box_center.x(), box_center.y(), -1.0f});
  128. // Resize selection
  129. selection_billboard.set_scale({selection_size * 0.5f, selection_size * 0.5f, 1.0f});
  130. selection_billboard.set_translation
  131. (
  132. {
  133. (box_bounds.min.x() + selection_size * 0.5f) + selection_size * selected_column,
  134. (box_bounds.max.y() - selection_size * 0.5f) - selection_size * selected_row,
  135. 0.0f
  136. }
  137. );
  138. }