From e4483eca01b48b943cd0461e24a74ae1a3139ed4 Mon Sep 17 00:00:00 2001 From: Nicolas James Date: Wed, 12 Feb 2025 21:57:46 +1100 Subject: Update to most recent version (old initial commit) --- src/client/window/inventory_window.cc | 196 ++++++++++++++++++++++++++++++++++ 1 file changed, 196 insertions(+) create mode 100644 src/client/window/inventory_window.cc (limited to 'src/client/window/inventory_window.cc') diff --git a/src/client/window/inventory_window.cc b/src/client/window/inventory_window.cc new file mode 100644 index 0000000..5023f1d --- /dev/null +++ b/src/client/window/inventory_window.cc @@ -0,0 +1,196 @@ +#include "client/window/inventory_window.hh" + +namespace client { +namespace window { + +using iw = class inventory_window; + +bool iw::maybe_handle_mousebuttondown(const SDL_Event& event) noexcept { + + if (event.button.button != SDL_BUTTON_LEFT) { + return false; + } + if (!this->is_inside(client::input::state.mouse_pos)) { + return false; + } + + const auto index = + this->maybe_get_inventory_index(client::input::state.mouse_pos); + if (!index.has_value()) { + return false; + } + + const auto& inventory = client::get_localplayer().inventory; + if (inventory.contents[*index] != nullptr) { + this->grabbed.emplace(*index); + } + return true; +} + +static proto::packet make_swap_packet(const std::uint32_t& a, + const std::uint32_t& b) noexcept { + proto::packet ret; + const auto packet = ret.mutable_item_swap_packet(); + packet->set_index_a(a); + packet->set_index_b(b); + return ret; +} + +bool iw::maybe_handle_mousebuttonup(const SDL_Event& event) noexcept { + + if (event.button.button != SDL_BUTTON_LEFT) { + return false; + } + if (!this->grabbed.has_value()) { + return false; + } + + if (const auto index = + this->maybe_get_inventory_index(input::state.mouse_pos); + index.has_value() && index != *grabbed) { + + auto& inventory = client::get_localplayer().inventory; + std::swap(inventory.contents[*grabbed], inventory.contents[*index]); + + // replicate on server + state::connection->rsend_packet( + make_swap_packet(static_cast(*grabbed), + static_cast(*index))); + } + + this->grabbed.reset(); + return true; +} + +std::optional +iw::maybe_get_inventory_index(const glm::vec2& pos) const noexcept { + + const float item_size = this->get_item_size(); + for (int x = 0; x < shared::player::INVENTORY_COLS; ++x) { + for (int y = 0; y < shared::player::INVENTORY_ROWS; ++y) { + const glm::vec2 off{this->pos + + glm::vec2{OUTLINE_WIDTH, OUTLINE_WIDTH} + + glm::vec2{x, y} * item_size}; + if (!basic_window::is_inside(pos, off, + glm::vec2{item_size, item_size})) { + continue; + } + return x + y * shared::player::INVENTORY_COLS; + } + } + return std::nullopt; +} + +bool iw::maybe_handle_event(const SDL_Event& event) noexcept { + switch (event.type) { + case SDL_MOUSEBUTTONDOWN: + return this->maybe_handle_mousebuttondown(event); + case SDL_MOUSEBUTTONUP: + return this->maybe_handle_mousebuttonup(event); + } + + return basic_window::maybe_handle_event(event); +} + +void iw::draw() noexcept { + basic_window::draw(); + + const float item_size = this->get_item_size(); + + const auto& localplayer = client::get_localplayer(); + client::render::draw_rectangle( + {.pos = {.offset = {this->pos.x + static_cast( + localplayer.get_active_item()) * + item_size, + this->pos.y}}, + .size = {.offset = {item_size, item_size}}, + .colour = {this->secondary_clr, 1.0f}}); + for (int i = 1; i < shared::player::INVENTORY_COLS; ++i) { + const float off = item_size * static_cast(i); + client::render::draw_rectangle( + {.pos = {.offset = {this->pos.x + off, + this->pos.y + OUTLINE_WIDTH}}, + .size = {.offset = {OUTLINE_WIDTH, + item_size * shared::player::INVENTORY_ROWS - + OUTLINE_WIDTH}}, + .colour = {this->tertiary_clr, 1.0f}}); + + if (i <= shared::player::INVENTORY_ROWS) { + client::render::draw_rectangle( + {.pos = {.offset = {pos.x + OUTLINE_WIDTH, pos.y + off}}, + .size = {.offset = {this->size.x - 2.0f * OUTLINE_WIDTH, + OUTLINE_WIDTH}}, + .colour = {this->tertiary_clr, 1.0f}}); + } + } + + const auto& inventory = localplayer.inventory; + if (const auto index = + this->maybe_get_inventory_index(client::input::state.mouse_pos); + index.has_value()) { + const glm::vec2 off{glm::vec2{*index % shared::player::INVENTORY_COLS, + *index / shared::player::INVENTORY_COLS} * + item_size}; + client::render::draw_rectangle( + {.pos = {.offset = this->pos + off + + glm::vec2{OUTLINE_WIDTH, OUTLINE_WIDTH}}, + .size = {.offset = glm::vec2{item_size, item_size} - + glm::vec2{OUTLINE_WIDTH, OUTLINE_WIDTH}}, + .colour = {this->secondary_clr, 1.0f}}); + } + + for (int x = 0; x < shared::player::INVENTORY_COLS; ++x) { + for (int y = 0; y < shared::player::INVENTORY_ROWS; ++y) { + const auto index = static_cast( + x + y * shared::player::INVENTORY_COLS); + const auto& item = inventory.contents[index]; + if (item == nullptr) { + continue; + } + if (this->grabbed.has_value() && *this->grabbed == index) { + continue; + } + + const glm::vec2 off{glm::vec2{x, y} * item_size}; + const auto item_ptr = dynamic_cast(&*item); + if (item_ptr == nullptr) { + continue; + } + item_ptr->draw(this->pos + off, glm::vec2{item_size, item_size}); + + client::render::draw_text( + std::to_string(item->quantity), + {.pos = {.offset = + this->pos + off + + glm::vec2{item_size * 0.75f, item_size * 0.2f}}, + .offset_height = item_size * 0.40f, + .colour = {this->font_colour, 1.0f}, + .has_backing = false, + .is_centered = true, + .is_vcentered = true}); + } + } + + if (this->grabbed.has_value()) { + const auto item_ptr = + dynamic_cast(&*inventory.contents[*grabbed]); + if (item_ptr != nullptr) { + item_ptr->draw(client::input::state.mouse_pos - + glm::vec2{item_size, item_size} * 0.5f, + glm::vec2{item_size, item_size}); + client::render::draw_text( + std::to_string(item_ptr->quantity), + {.pos = {.offset = + client::input::state.mouse_pos + + glm::vec2{item_size * 0.25f, item_size * -0.3f}}, + .offset_height = item_size * 0.40f, + .colour = {this->font_colour, 1.0f}, + .has_backing = false, + .is_centered = true, + .is_vcentered = true}); + } + } +} + +} // namespace window +} // namespace client -- cgit v1.2.3