mirror of
https://github.com/zhenyan121/Cubed.git
synced 2026-08-08 17:57:02 +08:00
fix: stabilize block item registration and display
Store item names as owned strings in ItemManager, set block type property for block items, validate item kind before placement, and handle items without textures gracefully in inventory UI.
This commit is contained in:
@@ -40,6 +40,7 @@ private:
|
|||||||
static inline IDMap m_id_map;
|
static inline IDMap m_id_map;
|
||||||
static inline bool is_init = false;
|
static inline bool is_init = false;
|
||||||
static inline CrossPlaneMap m_cross_plane_map;
|
static inline CrossPlaneMap m_cross_plane_map;
|
||||||
static void set_up_cross_plane_map();
|
static void set_up_cross_plane_map(
|
||||||
|
const std::vector<std::pair<bool, BlockType>>& types);
|
||||||
};
|
};
|
||||||
} // namespace Cubed
|
} // namespace Cubed
|
||||||
@@ -25,7 +25,7 @@ private:
|
|||||||
using acc = ItemMap::accessor;
|
using acc = ItemMap::accessor;
|
||||||
using cacc = ItemMap::const_accessor;
|
using cacc = ItemMap::const_accessor;
|
||||||
|
|
||||||
using IDMap = tbb::concurrent_hash_map<std::string_view, ItemID>;
|
using IDMap = tbb::concurrent_hash_map<std::string, ItemID>;
|
||||||
using BlockToIDMap = tbb::concurrent_hash_map<BlockType, ItemID>;
|
using BlockToIDMap = tbb::concurrent_hash_map<BlockType, ItemID>;
|
||||||
void add(const std::filesystem::path& path);
|
void add(const std::filesystem::path& path);
|
||||||
|
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ private:
|
|||||||
|
|
||||||
void load_block_status(unsigned status_id);
|
void load_block_status(unsigned status_id);
|
||||||
void load_block_texture(unsigned block_id);
|
void load_block_texture(unsigned block_id);
|
||||||
void load_item_texture();
|
void init_item_texture();
|
||||||
void load_cross_plane_texture(unsigned id);
|
void load_cross_plane_texture(unsigned id);
|
||||||
const Texture* load_image_texture(const std::string& path);
|
const Texture* load_image_texture(const std::string& path);
|
||||||
void load_pbr_texture(unsigned id);
|
void load_pbr_texture(unsigned id);
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
#include "Cubed/tools/log.hpp"
|
#include "Cubed/tools/log.hpp"
|
||||||
#include "Cubed/tools/toml.utils.hpp"
|
#include "Cubed/tools/toml.utils.hpp"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
|
|
||||||
namespace fs = std::filesystem;
|
namespace fs = std::filesystem;
|
||||||
@@ -122,7 +123,7 @@ float BlockManager::roughness(BlockType id) {
|
|||||||
|
|
||||||
void BlockManager::init() {
|
void BlockManager::init() {
|
||||||
fs::path data_path{block_data_dir};
|
fs::path data_path{block_data_dir};
|
||||||
|
std::vector<std::pair<bool, BlockType>> types;
|
||||||
for (auto entry : fs::recursive_directory_iterator(data_path)) {
|
for (auto entry : fs::recursive_directory_iterator(data_path)) {
|
||||||
if (!entry.is_regular_file()) {
|
if (!entry.is_regular_file()) {
|
||||||
continue;
|
continue;
|
||||||
@@ -169,9 +170,12 @@ void BlockManager::init() {
|
|||||||
if (!m_datas.emplace(static_cast<BlockType>(*id), std::move(data))) {
|
if (!m_datas.emplace(static_cast<BlockType>(*id), std::move(data))) {
|
||||||
Logger::error("Block Type {} already exist!", *id);
|
Logger::error("Block Type {} already exist!", *id);
|
||||||
}
|
}
|
||||||
|
m_id_map.emplace(*name, static_cast<BlockType>(*id));
|
||||||
|
types.emplace_back(*is_cross_plane, static_cast<BlockType>(*id));
|
||||||
}
|
}
|
||||||
|
std::sort(types.begin(), types.end(),
|
||||||
set_up_cross_plane_map();
|
[](const auto& a, const auto& b) { return a.second < b.second; });
|
||||||
|
set_up_cross_plane_map(types);
|
||||||
is_init = true;
|
is_init = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -197,11 +201,12 @@ BlockType BlockManager::id_from_name(const std::string& name) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BlockManager::set_up_cross_plane_map() {
|
void BlockManager::set_up_cross_plane_map(
|
||||||
|
const std::vector<std::pair<bool, BlockType>>& types) {
|
||||||
unsigned cur_id = 0;
|
unsigned cur_id = 0;
|
||||||
for (const auto& [id, data] : m_datas) {
|
for (auto id : types) {
|
||||||
if (data.is_cross_plane) {
|
if (id.first) {
|
||||||
m_cross_plane_map.emplace(data.id, cur_id);
|
m_cross_plane_map.emplace(id.second, cur_id);
|
||||||
|
|
||||||
cur_id++;
|
cur_id++;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -79,6 +79,7 @@ void ItemManager::add(const std::filesystem::path& path) {
|
|||||||
if (a->second.kind == ItemKind::BLOCK) {
|
if (a->second.kind == ItemKind::BLOCK) {
|
||||||
BlockType b = BlockManager::id_from_name(a->second.name);
|
BlockType b = BlockManager::id_from_name(a->second.name);
|
||||||
m_block_to_id_map.emplace(b, a->first);
|
m_block_to_id_map.emplace(b, a->first);
|
||||||
|
a->second.property = b;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@@ -91,7 +92,7 @@ const ItemData& ItemManager::get_item_data(std::string_view key) const {
|
|||||||
{
|
{
|
||||||
IDMap::const_accessor cacc;
|
IDMap::const_accessor cacc;
|
||||||
|
|
||||||
if (m_id_map.find(cacc, key)) {
|
if (m_id_map.find(cacc, std::string(key))) {
|
||||||
id = cacc->second;
|
id = cacc->second;
|
||||||
} else {
|
} else {
|
||||||
Logger::error("Can't Find key {} in id map", key);
|
Logger::error("Can't Find key {} in id map", key);
|
||||||
|
|||||||
@@ -408,17 +408,19 @@ void LocalPlayer::place_block(float dt) {
|
|||||||
}
|
}
|
||||||
if (m_mouse_state.right) {
|
if (m_mouse_state.right) {
|
||||||
auto& data = ItemManager::get(m_hotbar[m_selected_hotbar].id);
|
auto& data = ItemManager::get(m_hotbar[m_selected_hotbar].id);
|
||||||
auto* t = std::get_if<BlockType>(&data.property);
|
if (data.kind == ItemKind::BLOCK) {
|
||||||
ASSERT(t);
|
auto* t = std::get_if<BlockType>(&data.property);
|
||||||
auto type = *t;
|
ASSERT(t);
|
||||||
if (type != 0) {
|
auto type = *t;
|
||||||
glm::ivec3 near_pos = m_look_block->pos + m_look_block->normal;
|
if (type != 0) {
|
||||||
if (!m_world.is_solid(near_pos)) {
|
glm::ivec3 near_pos = m_look_block->pos + m_look_block->normal;
|
||||||
Hitbox block_box = ClientWorld::get_block_aabb(near_pos);
|
if (!m_world.is_solid(near_pos)) {
|
||||||
auto player_box = HitboxManager::hitbox("cubed:player");
|
Hitbox block_box = ClientWorld::get_block_aabb(near_pos);
|
||||||
player_box.box.center += get_player_pos();
|
auto player_box = HitboxManager::hitbox("cubed:player");
|
||||||
if (!player_box.box.intersects(block_box)) {
|
player_box.box.center += get_player_pos();
|
||||||
m_world.report_block_change(near_pos, type);
|
if (!player_box.box.intersects(block_box)) {
|
||||||
|
m_world.report_block_change(near_pos, type);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -122,9 +122,13 @@ void TextureManager::load_block_texture(unsigned id) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextureManager::load_item_texture() {
|
void TextureManager::init_item_texture() {
|
||||||
for (ItemID i = 0; i < ItemManager::size(); ++i) {
|
for (ItemID i = 0; i < ItemManager::size(); ++i) {
|
||||||
auto& item = ItemManager::get(i);
|
auto& item = ItemManager::get(i);
|
||||||
|
if (item.path.empty()) {
|
||||||
|
m_item_textures.try_emplace(item.id, nullptr);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
auto data = Tools::load_image_data(item.path);
|
auto data = Tools::load_image_data(item.path);
|
||||||
std::unique_ptr<Texture> texture =
|
std::unique_ptr<Texture> texture =
|
||||||
std::make_unique<Texture>(TextureType::TEXTURE_2D);
|
std::make_unique<Texture>(TextureType::TEXTURE_2D);
|
||||||
@@ -279,6 +283,7 @@ void TextureManager::init_texture() {
|
|||||||
Logger::info("Map Init Success");
|
Logger::info("Map Init Success");
|
||||||
|
|
||||||
init_block();
|
init_block();
|
||||||
|
init_item_texture();
|
||||||
init_block_status();
|
init_block_status();
|
||||||
init_ui();
|
init_ui();
|
||||||
init_skin();
|
init_skin();
|
||||||
|
|||||||
@@ -1,12 +1,11 @@
|
|||||||
#include "Cubed/ui/inventory_ui.hpp"
|
#include "Cubed/ui/inventory_ui.hpp"
|
||||||
|
|
||||||
#include "Cubed/app.hpp"
|
#include "Cubed/app.hpp"
|
||||||
#include "Cubed/gameplay/block_manager.hpp"
|
#include "Cubed/gameplay/item_manager.hpp"
|
||||||
#include "Cubed/scene/scene_manager.hpp"
|
#include "Cubed/scene/scene_manager.hpp"
|
||||||
#include "Cubed/scene/world_scene.hpp"
|
#include "Cubed/scene/world_scene.hpp"
|
||||||
#include "Cubed/ui/column_layout.hpp"
|
#include "Cubed/ui/column_layout.hpp"
|
||||||
#include "Cubed/ui/image.hpp"
|
#include "Cubed/ui/image.hpp"
|
||||||
|
|
||||||
namespace Cubed {
|
namespace Cubed {
|
||||||
InventoryUI::InventoryUI(WorldScene& scene) : m_scene(scene) {}
|
InventoryUI::InventoryUI(WorldScene& scene) : m_scene(scene) {}
|
||||||
|
|
||||||
@@ -22,12 +21,15 @@ void InventoryUI::init() {
|
|||||||
column.set_anchor(Anchor::CENTER);
|
column.set_anchor(Anchor::CENTER);
|
||||||
column.set_child_anchor(ColumnLayoutAnchor::LEFT);
|
column.set_child_anchor(ColumnLayoutAnchor::LEFT);
|
||||||
auto& item_textures = texture_manager.get_item_textures();
|
auto& item_textures = texture_manager.get_item_textures();
|
||||||
auto sum = item_textures.size();
|
|
||||||
{
|
{
|
||||||
auto& row_layout = column.add_child<RowLayout>();
|
auto& row_layout = column.add_child<RowLayout>();
|
||||||
auto row = &row_layout;
|
auto row = &row_layout;
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
for (auto& [id, texture] : item_textures) {
|
for (auto& [id, texture] : item_textures) {
|
||||||
|
if (id == 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (i % 10 == 0) {
|
if (i % 10 == 0) {
|
||||||
auto& r = column.add_child<RowLayout>();
|
auto& r = column.add_child<RowLayout>();
|
||||||
row = &r;
|
row = &r;
|
||||||
@@ -40,8 +42,6 @@ void InventoryUI::init() {
|
|||||||
m_slots.emplace_back(&slot);
|
m_slots.emplace_back(&slot);
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
for (size_t i = 1; i < sum; ++i) {
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
auto& label = back->add_child<Label>();
|
auto& label = back->add_child<Label>();
|
||||||
@@ -97,10 +97,12 @@ void InventoryUI::update(float dt) {
|
|||||||
void InventoryUI::update_item_info() {
|
void InventoryUI::update_item_info() {
|
||||||
auto show_item_info = [this](ItemSlot* slot) {
|
auto show_item_info = [this](ItemSlot* slot) {
|
||||||
if (slot && !m_selected_image->has_texture()) {
|
if (slot && !m_selected_image->has_texture()) {
|
||||||
|
|
||||||
auto type = slot->id();
|
auto type = slot->id();
|
||||||
|
|
||||||
if (type != 0) {
|
if (type != 0) {
|
||||||
m_item_info->set_text(BlockManager::local_name(type))
|
auto& data = ItemManager::get(type);
|
||||||
.set_visible(true);
|
m_item_info->set_text(data.name).set_visible(true);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user