mirror of
https://github.com/zhenyan121/Cubed.git
synced 2026-08-09 02:07:04 +08:00
feature: hud (#37)
* build: replace FetchContent with direct includes for glm * build(deps): replace SOIL2 with stb for image and vorbis decoding * build: replace FetchContent with direct includes for toml++ * refactor(texture): bump block texture size to 512 and disable items tab * feat: add hotbar system with ItemStack and RowLayout * fix(ui): restrict Ctrl key handling to typing mode * feat(ui): add widget border support and highlight selected hotbar slot * fix(ui): update borders on scale change and correct Image width - Added update_border() calls in set_scale() for Button, ChatBox, Image, Label, and TextField. - Fixed Image::width() to multiply by width instead of height. - Added early return in Widget::update_border() if border is not supported. * feat(ui): add border visual feedback on slider drag * feat(ui): add ItemSlot widget and refactor hotbar to use it * feat(world_scene): add inventory UI and pause type enum * feat(ui): add item slot tooltip and make window size static * fix(ui label): account for background offset in width/height * refactor(ui): centralize item info label in inventory and add update * feat(ui): add hotbar interaction in inventory UI * fix(inventory-ui): correct row creation logic for first item The loop starting at index 0 created a new row on the first iteration (i % 10 == 0). Shift the loop to start at 1 and adjust modulus condition to create rows correctly every 10 items. * feat(block): add name_key for localized block names Add `name_key` field to all block TOML definitions, enabling per-block localization. Update `BlockData` struct and `BlockManager` with `local_name()` method that returns a localized string via the translation system. Add corresponding entries to `en_US.json` and `zh_CN.json`. Modify inventory UI to use the localized name when displaying block info, and fix a bug where emptying a hotbar slot did not clear the item locally. * fix(ui): change inventory item slot color from white to gray * fix(ui): add missing include for std::array
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
#include "Cubed/gameplay/block.hpp"
|
||||
|
||||
#include "Cubed/localization.hpp"
|
||||
#include "Cubed/tools/cubed_assert.hpp"
|
||||
#include "Cubed/tools/log.hpp"
|
||||
#include "Cubed/tools/toml.utils.hpp"
|
||||
@@ -38,7 +39,13 @@ const std::string& BlockManager::name_form_id(BlockType id) {
|
||||
}
|
||||
return m_datas[id].name;
|
||||
}
|
||||
|
||||
std::string BlockManager::local_name(BlockType id) {
|
||||
if (id >= sums()) {
|
||||
Logger::error("Id {}, is Over The Max Id", id, sums() - 1);
|
||||
return tr(m_datas[0].name_key);
|
||||
}
|
||||
return tr(m_datas[id].name_key);
|
||||
}
|
||||
bool BlockManager::is_gas(BlockType id) {
|
||||
if (id >= sums()) {
|
||||
Logger::error("Id {}, is Over The Max Id", id, sums() - 1);
|
||||
@@ -146,7 +153,8 @@ void BlockManager::init() {
|
||||
auto is_blend = safe_get_value(block, "is_blend", false);
|
||||
auto is_transitional = safe_get_value(block, "is_transitional", false);
|
||||
auto roughness = safe_get_value(block, "roughness", 1.0);
|
||||
m_datas.emplace_back(*id, *name, *is_liquid, *is_passable,
|
||||
auto name_key = safe_get_value(block, "name_key", "Unknow_key");
|
||||
m_datas.emplace_back(*name, *name_key, *id, *is_liquid, *is_passable,
|
||||
*is_cross_plane, *is_transparent, *is_gas,
|
||||
*is_discard, *is_blend, *is_transitional,
|
||||
static_cast<float>(*roughness));
|
||||
|
||||
@@ -126,8 +126,6 @@ void ClientPlayer::reload_config() {
|
||||
}
|
||||
void ClientPlayer::set_player_pos(const glm::vec3& pos) { m_player_pos = pos; }
|
||||
|
||||
void ClientPlayer::set_place_block(unsigned id) { m_place_block = id; }
|
||||
|
||||
void ClientPlayer::update(float delta_time) {
|
||||
m_gait = compute_gait();
|
||||
update_move(delta_time);
|
||||
@@ -193,6 +191,7 @@ bool ClientPlayer::update_player_move_state(Key key, KeyAction action) {
|
||||
}
|
||||
} else if (key == Key::LEFT_CTRL) {
|
||||
if (action == KeyAction::PRESS) {
|
||||
|
||||
m_sprinting = true;
|
||||
}
|
||||
/*
|
||||
@@ -207,6 +206,26 @@ bool ClientPlayer::update_player_move_state(Key key, KeyAction action) {
|
||||
change_mode(CREATIVE);
|
||||
}
|
||||
}
|
||||
} else if (key == Key::NUMPAD_1 || key == Key::DIGIT_1) {
|
||||
m_selected_hotbar = 0;
|
||||
} else if (key == Key::NUMPAD_2 || key == Key::DIGIT_2) {
|
||||
m_selected_hotbar = 1;
|
||||
} else if (key == Key::NUMPAD_3 || key == Key::DIGIT_3) {
|
||||
m_selected_hotbar = 2;
|
||||
} else if (key == Key::NUMPAD_4 || key == Key::DIGIT_4) {
|
||||
m_selected_hotbar = 3;
|
||||
} else if (key == Key::NUMPAD_5 || key == Key::DIGIT_5) {
|
||||
m_selected_hotbar = 4;
|
||||
} else if (key == Key::NUMPAD_6 || key == Key::DIGIT_6) {
|
||||
m_selected_hotbar = 5;
|
||||
} else if (key == Key::NUMPAD_7 || key == Key::DIGIT_7) {
|
||||
m_selected_hotbar = 6;
|
||||
} else if (key == Key::NUMPAD_8 || key == Key::DIGIT_8) {
|
||||
m_selected_hotbar = 7;
|
||||
} else if (key == Key::NUMPAD_9 || key == Key::DIGIT_9) {
|
||||
m_selected_hotbar = 8;
|
||||
} else if (key == Key::NUMPAD_0 || key == Key::DIGIT_0) {
|
||||
m_selected_hotbar = 9;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
@@ -287,16 +306,30 @@ void ClientPlayer::place_block(float dt) {
|
||||
}
|
||||
}
|
||||
if (m_mouse_state.right) {
|
||||
glm::ivec3 near_pos = m_look_block->pos + m_look_block->normal;
|
||||
if (!m_world.is_solid(near_pos)) {
|
||||
AABB block_box = ClientWorld::get_block_aabb(near_pos);
|
||||
AABB player_box = get_aabb(get_player_pos());
|
||||
if (!player_box.intersects(block_box)) {
|
||||
m_world.report_block_change(near_pos, m_place_block);
|
||||
auto type = m_hotbar[m_selected_hotbar].type;
|
||||
if (type != 0) {
|
||||
glm::ivec3 near_pos = m_look_block->pos + m_look_block->normal;
|
||||
if (!m_world.is_solid(near_pos)) {
|
||||
AABB block_box = ClientWorld::get_block_aabb(near_pos);
|
||||
AABB player_box = get_aabb(get_player_pos());
|
||||
if (!player_box.intersects(block_box)) {
|
||||
m_world.report_block_change(near_pos, type);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int ClientPlayer::selected_hotbar() const { return m_selected_hotbar; }
|
||||
void ClientPlayer::set_hotbar(int pos, const ItemStack& item) {
|
||||
ASSERT(pos >= 0 && static_cast<size_t>(pos) < HOTBAR_SUM);
|
||||
m_hotbar[pos] = item;
|
||||
}
|
||||
std::span<const ItemStack, ClientPlayer::HOTBAR_SUM>
|
||||
ClientPlayer::get_hotbar() const {
|
||||
return m_hotbar;
|
||||
}
|
||||
|
||||
void ClientPlayer::update_move(float delta_time) {
|
||||
// if frame rate less than 1 frame per second, don't update
|
||||
if (delta_time > 1.0f) {
|
||||
@@ -537,14 +570,14 @@ bool ClientPlayer::update_scroll(float yoffset) {
|
||||
}
|
||||
if (m_game_mode == CREATIVE) {
|
||||
if (yoffset < 0) {
|
||||
m_place_block += 1;
|
||||
if (m_place_block >= BlockManager::sums()) {
|
||||
m_place_block = 1;
|
||||
m_selected_hotbar += 1;
|
||||
if (m_selected_hotbar >= 10) {
|
||||
m_selected_hotbar = 0;
|
||||
}
|
||||
} else {
|
||||
m_place_block -= 1;
|
||||
if (m_place_block <= 0) {
|
||||
m_place_block = BlockManager::sums() - 1;
|
||||
m_selected_hotbar -= 1;
|
||||
if (m_selected_hotbar < 0) {
|
||||
m_selected_hotbar = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -615,7 +648,9 @@ float& ClientPlayer::acceleration() { return m_acceleration; }
|
||||
float& ClientPlayer::deceleration() { return m_deceleration; }
|
||||
float& ClientPlayer::g() { return m_g; }
|
||||
float& ClientPlayer::fly_y_speed() { return m_fly_y_speed; }
|
||||
unsigned ClientPlayer::get_current_block() const { return m_place_block; };
|
||||
const ItemStack& ClientPlayer::get_current_itemstack() const {
|
||||
return m_hotbar[m_selected_hotbar];
|
||||
};
|
||||
void ClientPlayer::set_gait(Gait gait) { m_gait = gait; }
|
||||
GameMode& ClientPlayer::game_mode() { return m_game_mode; }
|
||||
ClientWorld& ClientPlayer::get_world() { return m_world; }
|
||||
@@ -662,6 +697,10 @@ void ClientPlayer::init(std::string_view name) {
|
||||
audio.play_3d(sound, m_player_pos);
|
||||
Logger::debug("Player block {} walk sound", name);
|
||||
});
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
m_hotbar[i].type = i;
|
||||
}
|
||||
}
|
||||
|
||||
bool ClientPlayer::is_underwater() const { return m_underwater; }
|
||||
|
||||
Reference in New Issue
Block a user