feat: add pig spawn egg item

Add pig spawn egg asset and texture, parse spawn egg item kind and creature property, and spawn the configured entity when used on an empty block. Also fix item texture loading to use actual image dimensions and update selected item UI sizing.
This commit is contained in:
2026-08-04 18:00:08 +08:00
parent 1514338144
commit abf1f4db7d
7 changed files with 38 additions and 10 deletions

View File

@@ -0,0 +1,8 @@
{
"id": 10,
"name": "pig_spawn_egg",
"description": "",
"texture": "texture/item/spawn_egg/pig_spawn_egg.png",
"type": "spawn_egg",
"creature": "cubed:pig"
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 174 B

View File

@@ -29,7 +29,7 @@ inline constexpr ItemKind get_item_kind(std::string_view kind) {
if (kind == "block") {
return ItemKind::BLOCK;
}
if (kind == "SPAWN_EGG") {
if (kind == "spawn_egg") {
return ItemKind::SPAWN_EGG;
}
return ItemKind::NONE;

View File

@@ -69,7 +69,13 @@ void ItemManager::add(const std::filesystem::path& path) {
std::string type = doc["type"].GetString();
data.kind = get_item_kind(type);
}
if (data.kind == ItemKind::SPAWN_EGG) {
if (doc.HasMember("creature")) {
data.property = doc["creature"].GetString();
} else {
data.property = "cubed:pig";
}
}
acc a;
if (m_map.emplace(a, data.id, std::move(data))) {
if (!m_id_map.emplace(a->second.name, a->first)) {

View File

@@ -424,6 +424,14 @@ void LocalPlayer::place_block(float dt) {
}
}
}
if (data.kind == ItemKind::SPAWN_EGG) {
auto* name = std::get_if<std::string>(&data.property);
ASSERT(name);
glm::ivec3 near_pos = m_look_block->pos + m_look_block->normal;
if (!m_world.is_solid(near_pos)) {
m_world.entity_manager().create(*name, near_pos);
}
}
}
}

View File

@@ -11,7 +11,6 @@ namespace {
constexpr int BLOCK_SIZE = 16;
constexpr int BLOCK_NORMAL_SIZE = 128;
constexpr int CROSS_PLANE_SIZE = 16;
constexpr int BLOCK_ITEM_SIZE = 512;
constexpr int BLOCK_STATUS_SIZE = 16;
constexpr int SKIN_SIZE = 64;
@@ -133,8 +132,8 @@ void TextureManager::init_item_texture() {
std::unique_ptr<Texture> texture =
std::make_unique<Texture>(TextureType::TEXTURE_2D);
texture->tex_image_2d(TextureFormat::RGBA8, TextureFormat::RGBA,
GL_UNSIGNED_BYTE, data.data, BLOCK_ITEM_SIZE,
BLOCK_ITEM_SIZE);
GL_UNSIGNED_BYTE, data.data, data.width,
data.height);
texture->set_nearest();

View File

@@ -6,6 +6,11 @@
#include "Cubed/scene/world_scene.hpp"
#include "Cubed/ui/column_layout.hpp"
#include "Cubed/ui/image.hpp"
namespace {
constexpr int SELECTED_ITEM_SIZE = 128;
}
namespace Cubed {
InventoryUI::InventoryUI(WorldScene& scene) : m_scene(scene) {}
@@ -80,8 +85,10 @@ void InventoryUI::init() {
}
{
auto& image = back->add_child<Image>();
image.set_texture(nullptr, true);
image.set_scale(0.25f);
image.set_width(SELECTED_ITEM_SIZE);
image.set_height(SELECTED_ITEM_SIZE);
image.set_anchor(Anchor::FOLLOW_MOUSE).set_offset({0, 0});
image.set_visible(false);
m_selected_image = &image;
@@ -137,7 +144,7 @@ bool InventoryUI::handle_mouse_button_event(const MouseButtonEvent& e) {
if (m_selected_id != 0) {
auto it = item_textures.find(m_selected_id);
ASSERT(it != item_textures.end());
m_selected_image->set_texture(it->second.get(), true);
m_selected_image->set_texture(it->second.get(), false);
m_selected_image->set_visible(true);
return true;
}
@@ -150,7 +157,7 @@ bool InventoryUI::handle_mouse_button_event(const MouseButtonEvent& e) {
if (m_selected_id != 0) {
auto it = item_textures.find(m_selected_id);
ASSERT(it != item_textures.end());
m_selected_image->set_texture(it->second.get(), true);
m_selected_image->set_texture(it->second.get(), false);
m_hotbar[pos]->set_item(0, nullptr);
auto& player = m_scene.client_world().get_player();
player.set_hotbar(pos, {0, 0});
@@ -161,7 +168,7 @@ bool InventoryUI::handle_mouse_button_event(const MouseButtonEvent& e) {
}
}
if (m_selected_image->has_texture()) {
m_selected_image->set_texture(nullptr, true);
m_selected_image->set_texture(nullptr, false);
m_selected_image->set_visible(false);
auto [slot, pos] = get_hovered_hotbar_slot();
if (slot) {