Inventory (WIP part I)

This commit is contained in:
MihailRis
2024-01-21 15:23:46 +03:00
parent fe5cab0db0
commit 5142f3b4e7
13 changed files with 864 additions and 175 deletions
+304 -116
View File
@@ -1,146 +1,334 @@
#include "InventoryView.h"
#include <iostream>
#include <glm/glm.hpp>
#include "BlocksPreview.h"
#include "LevelFrontend.h"
#include "../window/Events.h"
#include "../window/input.h"
#include "../assets/Assets.h"
#include "../graphics/Atlas.h"
#include "../graphics/Shader.h"
#include "../graphics/Batch2D.h"
#include "../graphics/GfxContext.h"
#include "../graphics/Font.h"
#include "../content/Content.h"
#include "../items/ItemDef.h"
#include "../items/Inventory.h"
#include "../maths/voxmaths.h"
#include "../objects/Player.h"
#include "../voxels/Block.h"
#include "../frontend/gui/controls.h"
#include "../util/stringutil.h"
InventoryLayout::InventoryLayout(glm::vec2 size) : size(size) {}
void InventoryLayout::add(SlotLayout slot) {
slots.push_back(slot);
}
void InventoryLayout::setSize(glm::vec2 size) {
this->size = size;
}
void InventoryLayout::setOrigin(glm::vec2 origin) {
this->origin = origin;
}
glm::vec2 InventoryLayout::getSize() const {
return size;
}
glm::vec2 InventoryLayout::getOrigin() const {
return origin;
}
std::vector<SlotLayout>& InventoryLayout::getSlots() {
return slots;
}
SlotLayout::SlotLayout(
glm::vec2 position,
bool background,
bool itemSource,
itemsharefunc shareFunc,
slotcallback rightClick
)
: position(position),
background(background),
itemSource(itemSource),
shareFunc(shareFunc),
rightClick(rightClick) {}
InventoryPanel::InventoryPanel(
glm::vec2 position,
glm::vec2 size,
glm::vec4 color)
: position(position), size(size), color(color) {}
InventoryBuilder::InventoryBuilder()
: layout(std::make_unique<InventoryLayout>(glm::vec2()))
{}
void InventoryBuilder::addGrid(
int cols, int rows,
glm::vec2 coord,
int padding,
SlotLayout slotLayout)
{
const int slotSize = InventoryView::SLOT_SIZE;
const int interval = InventoryView::SLOT_INTERVAL;
uint width = cols * (slotSize + interval) - interval + padding*2;
uint height = rows * (slotSize + interval) - interval + padding*2;
auto lsize = layout->getSize();
if (coord.x + width > lsize.x) {
lsize.x = coord.x + width;
}
if (coord.y + height > lsize.y) {
lsize.y = coord.y + height;
}
layout->setSize(lsize);
for (int row = 0; row < rows; row++) {
for (int col = 0; col < cols; col++) {
glm::vec2 position (
col * (slotSize + interval) + padding,
row * (slotSize + interval) + padding
);
auto builtSlot = slotLayout;
builtSlot.position = position;
layout->add(builtSlot);
}
}
}
std::unique_ptr<InventoryLayout> InventoryBuilder::build() {
return std::unique_ptr<InventoryLayout>(layout.release());
}
SlotView::SlotView(
ItemStack& stack,
LevelFrontend* frontend,
InventoryInteraction* interaction,
const Content* content,
SlotLayout layout)
: UINode(glm::vec2(), glm::vec2(InventoryView::SLOT_SIZE)),
frontend(frontend),
interaction(interaction),
content(content),
stack(stack),
layout(layout) {
color(glm::vec4(0, 0, 0, 0.2f));
}
// performance disaster
void SlotView::draw(Batch2D* batch, Assets* assets) {
glm::vec2 coord = calcCoord();
int slotSize = InventoryView::SLOT_SIZE;
glm::vec4 tint(1.0f);
glm::vec4 color = color_;
if (hover_ || highlighted) {
tint *= 1.333f;
color = glm::vec4(1, 1, 1, 0.2f);
}
batch->color = color;
if (color.a > 0.0) {
batch->texture(nullptr);
if (highlighted) {
batch->rect(coord.x-4, coord.y-4, slotSize+8, slotSize+8);
} else {
batch->rect(coord.x, coord.y, slotSize, slotSize);
}
}
batch->color = glm::vec4(1.0f);
Shader* uiShader = assets->getShader("ui");
Viewport viewport(Window::width, Window::height);
GfxContext ctx(nullptr, viewport, batch);
auto preview = frontend->getBlocksPreview();
auto indices = content->getIndices();
ItemDef* item = indices->getItemDef(stack.getItemId());
switch (item->iconType) {
case item_icon_type::none:
break;
case item_icon_type::block:
batch->render();
{
GfxContext subctx = ctx.sub();
subctx.depthTest(true);
subctx.cullFace(true);
Block* cblock = content->requireBlock(item->icon);
preview->begin(&subctx.getViewport());
preview->draw(cblock, coord.x, coord.y, slotSize, tint);
}
uiShader->use();
batch->begin();
break;
case item_icon_type::sprite: {
size_t index = item->icon.find(':');
std::string name = item->icon.substr(index+1);
UVRegion region(0.0f, 0.0, 1.0f, 1.0f);
if (index == std::string::npos) {
batch->texture(assets->getTexture(name));
} else {
std::string atlasname = item->icon.substr(0, index);
Atlas* atlas = assets->getAtlas(atlasname);
if (atlas && atlas->has(name)) {
region = atlas->get(name);
batch->texture(atlas->getTexture());
}
}
batch->rect(
coord.x, coord.y, slotSize, slotSize,
0, 0, 0, region, false, true, tint);
break;
}
}
if (stack.getCount() > 1) {
auto font = assets->getFont("normal");
std::wstring text = std::to_wstring(stack.getCount());
int x = coord.x+slotSize-text.length()*8;
int y = coord.y+slotSize-16;
batch->color = glm::vec4(0, 0, 0, 1.0f);
font->draw(batch, text, x+1, y+1);
batch->color = glm::vec4(1.0f);
font->draw(batch, text, x, y);
}
}
void SlotView::setHighlighted(bool flag) {
highlighted = flag;
}
bool SlotView::isHighlighted() const {
return highlighted;
}
void SlotView::clicked(gui::GUI* gui, int button) {
ItemStack& grabbed = interaction->getGrabbedItem();
if (button == mousecode::BUTTON_1) {
if (Events::pressed(keycode::LEFT_SHIFT)) {
if (layout.shareFunc) {
layout.shareFunc(stack);
}
return;
}
if (!layout.itemSource && stack.accepts(grabbed)) {
stack.move(grabbed, content->getIndices());
} else {
if (layout.itemSource) {
if (grabbed.isEmpty()) {
grabbed.set(stack);
} else {
grabbed.clear();
}
} else {
std::swap(grabbed, stack);
}
}
} else if (button == mousecode::BUTTON_2) {
if (layout.rightClick) {
layout.rightClick(stack, grabbed);
return;
}
if (layout.itemSource)
return;
if (grabbed.isEmpty()) {
if (!stack.isEmpty()) {
grabbed.set(stack);
int halfremain = stack.getCount() / 2;
grabbed.setCount(stack.getCount() - halfremain);
stack.setCount(halfremain);
}
} else {
if (stack.isEmpty()) {
stack.set(grabbed);
stack.setCount(1);
} else {
stack.setCount(stack.getCount()+1);
}
grabbed.setCount(grabbed.getCount()-1);
}
}
}
InventoryView::InventoryView(
int columns,
const Content* content,
LevelFrontend* frontend,
std::vector<itemid_t> items)
: content(content),
InventoryInteraction* interaction,
std::shared_ptr<Inventory> inventory,
std::unique_ptr<InventoryLayout> layout)
: Container(glm::vec2(), glm::vec2()),
content(content),
indices(content->getIndices()),
items(items),
inventory(inventory),
layout(std::move(layout)),
frontend(frontend),
columns(columns) {
interaction(interaction) {
size(this->layout->getSize());
color(glm::vec4(0, 0, 0, 0.5f));
}
InventoryView::~InventoryView() {
}
InventoryView::~InventoryView() {}
void InventoryView::setPosition(int x, int y) {
position.x = x;
position.y = y;
}
void InventoryView::build() {
int index = 0;
for (auto& slot : layout->getSlots()) {
ItemStack& item = inventory->getSlot(index);
int InventoryView::getWidth() const {
return columns * iconSize + (columns-1) * interval + padding.x * 2;
}
int InventoryView::getHeight() const {
uint inv_rows = ceildiv(items.size(), columns);
return inv_rows * iconSize + (inv_rows-1) * interval + padding.y * 2;
}
void InventoryView::setSlotConsumer(slotconsumer consumer) {
this->consumer = consumer;
}
void InventoryView::setItems(std::vector<itemid_t> items) {
this->items = items;
}
void InventoryView::actAndDraw(const GfxContext* ctx) {
Assets* assets = frontend->getAssets();
Shader* uiShader = assets->getShader("ui");
auto viewport = ctx->getViewport();
uint inv_w = getWidth();
uint inv_h = getHeight();
int xs = position.x + padding.x;
int ys = position.y + padding.y;
glm::vec4 tint (1.0f);
int mx = Events::cursor.x;
int my = Events::cursor.y;
// background
auto batch = ctx->getBatch2D();
batch->texture(nullptr);
batch->color = glm::vec4(0.0f, 0.0f, 0.0f, 0.5f);
batch->rect(position.x, position.y, inv_w, inv_h);
batch->render();
// blocks & items
if (Events::scroll) {
scroll -= Events::scroll * (iconSize+interval);
auto view = std::make_shared<SlotView>(
item, frontend, interaction, content, slot
);
if (!slot.background) {
view->color(glm::vec4());
}
slots.push_back(view.get());
add(view, slot.position);
index++;
}
scroll = std::min(scroll, int(inv_h-viewport.getHeight()));
scroll = std::max(scroll, 0);
}
auto blocksPreview = frontend->getBlocksPreview();
// todo: optimize
{
Window::clearDepth();
GfxContext subctx = ctx->sub();
subctx.depthTest(true);
subctx.cullFace(true);
uint index = 0;
for (uint i = 0; i < items.size(); i++) {
ItemDef* item = indices->getItemDef(items[i]);
int x = xs + (iconSize+interval) * (index % columns);
int y = ys + (iconSize+interval) * (index / columns) - scroll;
if (y < -int(iconSize+interval) || y >= int(viewport.getHeight())) {
index++;
continue;
}
if (mx > x && mx < x + (int)iconSize && my > y && my < y + (int)iconSize) {
tint.r *= 1.2f;
tint.g *= 1.2f;
tint.b *= 1.2f;
if (Events::jclicked(mousecode::BUTTON_1)) {
if (consumer) {
consumer(items[i]);
}
}
} else {
tint = glm::vec4(1.0f);
}
switch (item->iconType) {
case item_icon_type::none:
break;
case item_icon_type::block: {
Block* cblock = content->requireBlock(item->icon);
blocksPreview->begin(&ctx->getViewport());
blocksPreview->draw(cblock, x, y, iconSize, tint);
break;
}
case item_icon_type::sprite: {
batch->begin();
uiShader->use();
size_t index = item->icon.find(':');
std::string name = item->icon.substr(index+1);
UVRegion region(0.0f, 0.0, 1.0f, 1.0f);
if (index == std::string::npos) {
batch->texture(assets->getTexture(name));
} else {
std::string atlasname = item->icon.substr(0, index);
Atlas* atlas = assets->getAtlas(atlasname);
if (atlas && atlas->has(name)) {
region = atlas->get(name);
batch->texture(atlas->getTexture());
}
}
batch->rect(x, y, 48, 48, 0, 0, 0, region, false, true, glm::vec4(1.0f));
batch->render();
break;
}
}
index++;
}
}
uiShader->use();
void InventoryView::setSelected(int index) {
for (int i = 0; i < int(slots.size()); i++) {
auto slot = slots[i];
slot->setHighlighted(i == index);
}
}
void InventoryView::setCoord(glm::vec2 coord) {
Container::setCoord(coord - layout->getOrigin());
}
void InventoryView::setInventory(std::shared_ptr<Inventory> inventory) {
this->inventory = inventory;
}
InventoryLayout* InventoryView::getLayout() const {
return layout.get();
}
// performance disaster x2
void InventoryView::draw(Batch2D* batch, Assets* assets) {
Container::draw(batch, assets);
Window::clearDepth();
}
void InventoryView::drawBackground(Batch2D* batch, Assets* assets) {
glm::vec2 coord = calcCoord();
batch->texture(nullptr);
batch->color = color_;
batch->rect(coord.x-1, coord.y-1, size_.x+2, size_.y+2);
}
+121 -17
View File
@@ -5,46 +5,150 @@
#include <functional>
#include <glm/glm.hpp>
#include "../frontend/gui/UINode.h"
#include "../frontend/gui/panels.h"
#include "../frontend/gui/controls.h"
#include "../items/ItemStack.h"
#include "../typedefs.h"
class Batch2D;
class Assets;
class GfxContext;
class Content;
class ContentIndices;
class LevelFrontend;
class Inventory;
typedef std::function<void(itemid_t)> slotconsumer;
typedef std::function<void(ItemStack&)> itemsharefunc;
typedef std::function<void(ItemStack&, ItemStack&)> slotcallback;
class InventoryView {
class InventoryInteraction;
struct SlotLayout {
glm::vec2 position;
bool background;
bool itemSource;
itemsharefunc shareFunc;
slotcallback rightClick;
SlotLayout(glm::vec2 position,
bool background,
bool itemSource,
itemsharefunc shareFunc,
slotcallback rightClick);
};
// temporary unused
struct InventoryPanel {
glm::vec2 position;
glm::vec2 size;
glm::vec4 color;
InventoryPanel(glm::vec2 position,
glm::vec2 size,
glm::vec4 color);
};
class InventoryLayout {
glm::vec2 size;
glm::vec2 origin;
std::vector<SlotLayout> slots;
public:
InventoryLayout(glm::vec2 size);
void add(SlotLayout slot);
void setSize(glm::vec2 size);
void setOrigin(glm::vec2 origin);
glm::vec2 getSize() const;
glm::vec2 getOrigin() const;
std::vector<SlotLayout>& getSlots();
};
class InventoryBuilder {
std::unique_ptr<InventoryLayout> layout;
public:
InventoryBuilder();
void addGrid(
int cols, int rows,
glm::vec2 coord,
int padding,
SlotLayout slotLayout);
std::unique_ptr<InventoryLayout> build();
};
class SlotView : public gui::UINode {
LevelFrontend* frontend;
InventoryInteraction* interaction;
const Content* const content;
ItemStack& stack;
bool highlighted = false;
SlotLayout layout;
public:
SlotView(ItemStack& stack,
LevelFrontend* frontend,
InventoryInteraction* interaction,
const Content* content,
SlotLayout layout);
virtual void draw(Batch2D* batch, Assets* assets) override;
void setHighlighted(bool flag);
bool isHighlighted() const;
virtual void clicked(gui::GUI*, int) override;
};
class InventoryView : public gui::Container {
const Content* content;
const ContentIndices* indices;
std::vector<itemid_t> items;
slotconsumer consumer = nullptr;
std::shared_ptr<Inventory> inventory;
std::unique_ptr<InventoryLayout> layout;
LevelFrontend* frontend;
InventoryInteraction* interaction;
std::vector<SlotView*> slots;
int scroll = 0;
int columns;
uint iconSize = 48;
uint interval = 4;
glm::ivec2 padding {interval, interval};
glm::ivec2 position {0, 0};
public:
InventoryView(
int columns,
const Content* content,
LevelFrontend* frontend,
std::vector<itemid_t> items);
InventoryInteraction* interaction,
std::shared_ptr<Inventory> inventory,
std::unique_ptr<InventoryLayout> layout);
virtual ~InventoryView();
virtual void actAndDraw(const GfxContext* ctx);
void build();
void setItems(std::vector<itemid_t> items);
virtual void draw(Batch2D* batch, Assets* assets) override;
virtual void drawBackground(Batch2D* batch, Assets* assets) override;
void setPosition(int x, int y);
int getWidth() const;
int getHeight() const;
void setSlotConsumer(slotconsumer consumer);
void setInventory(std::shared_ptr<Inventory> inventory);
virtual void setCoord(glm::vec2 coord) override;
InventoryLayout* getLayout() const;
void setSelected(int index);
static const int SLOT_INTERVAL = 4;
static const int SLOT_SIZE = 48;
};
class InventoryInteraction {
ItemStack grabbedItem;
public:
InventoryInteraction() = default;
ItemStack& getGrabbedItem() {
return grabbedItem;
}
};
#endif // FRONTEND_INVENTORY_VIEW_H_
+6 -2
View File
@@ -28,6 +28,8 @@
#include "../settings.h"
#include "../engine.h"
#include "../items/ItemDef.h"
#include "../items/ItemStack.h"
#include "../items/Inventory.h"
#include "LevelFrontend.h"
#include "graphics/Skybox.h"
@@ -169,8 +171,10 @@ void WorldRenderer::draw(const GfxContext& pctx, Camera* camera, bool hudVisible
shader->uniform3f("u_cameraPos", camera->position);
shader->uniform1i("u_cubemap", 1);
{
itemid_t id = level->player->getChosenItem();
ItemDef* item = indices->getItemDef(id);
auto player = level->player;
auto inventory = player->getInventory();
ItemStack& stack = inventory->getSlot(player->getChosenSlot());
ItemDef* item = indices->getItemDef(stack.getItemId());
assert(item != nullptr);
float multiplier = 0.5f;
shader->uniform3f("u_torchlightColor",
+1 -3
View File
@@ -10,8 +10,6 @@ using gui::Align;
using glm::vec2;
using glm::vec4;
#include <iostream>
UINode::UINode(vec2 coord, vec2 size) : coord(coord), size_(size) {
}
@@ -85,7 +83,7 @@ shared_ptr<UINode> UINode::getAt(vec2 pos, shared_ptr<UINode> self) {
}
bool UINode::isInteractive() const {
return interactive;
return interactive && visible();
}
void UINode::setInteractive(bool flag) {
+184 -23
View File
@@ -44,6 +44,7 @@
#include "../engine.h"
#include "../core_defs.h"
#include "../items/ItemDef.h"
#include "../items/Inventory.h"
using glm::vec2;
using glm::vec3;
@@ -163,26 +164,142 @@ void HudRenderer::createDebugPanel(Engine* engine) {
panel->refresh();
}
std::shared_ptr<InventoryView> HudRenderer::createContentAccess() {
auto level = frontend->getLevel();
auto content = level->content;
auto indices = content->getIndices();
auto player = level->player;
auto inventory = player->getInventory();
int itemsCount = indices->countItemDefs();
auto accessInventory = std::make_shared<Inventory>(itemsCount);
for (int id = 1; id < itemsCount; id++) {
accessInventory->getSlot(id-1).set(ItemStack(id, 1));
}
const int slotSize = InventoryView::SLOT_SIZE;
const int interval = InventoryView::SLOT_INTERVAL;
int padding = 8;
int columns = 8;
int rows = ceildiv(itemsCount-1, columns);
uint cawidth = columns * (slotSize + interval) - interval + padding;
uint caheight = rows * (slotSize + interval) - interval + padding*2;
auto layout = std::make_unique<InventoryLayout>(glm::vec2(cawidth, caheight));
for (int i = 0; i < itemsCount-1; i++) {
int row = i / columns;
int col = i % columns;
glm::vec2 position (
col * slotSize + (col-1) * interval + padding,
row * slotSize + (row-1) * interval + padding
);
layout->add(SlotLayout(position, false, true,
[=](ItemStack& item) {
auto copy = ItemStack(item);
inventory->move(copy, indices);
},
[=](ItemStack& item, ItemStack& grabbed) {
inventory->getSlot(player->getChosenSlot()).set(item);
}));
}
auto contentAccess = std::make_shared<InventoryView>(
content,
frontend,
interaction.get(),
accessInventory,
std::move(layout)
);
contentAccess->build();
return contentAccess;
}
std::shared_ptr<InventoryView> HudRenderer::createHotbar() {
auto level = frontend->getLevel();
auto player = level->player;
auto inventory = player->getInventory();
auto content = level->content;
const int slotSize = InventoryView::SLOT_SIZE;
const int interval = InventoryView::SLOT_INTERVAL;
int padding = 4;
uint width = 10 * (slotSize + interval) - interval + padding*2;
uint height = slotSize + padding * 2;
auto layout = std::make_unique<InventoryLayout>(glm::vec2(width, height));
for (int i = 0; i < 10; i++) {
glm::vec2 position (i * (slotSize + interval) + padding, padding);
layout->add(SlotLayout(position, false, false, nullptr, nullptr));
}
layout->setOrigin(glm::vec2(width / 2, 0));
auto view = std::make_shared<InventoryView>(
content,
frontend,
interaction.get(),
inventory,
std::move(layout)
);
view->build();
view->setInteractive(false);
return view;
}
std::shared_ptr<InventoryView> HudRenderer::createInventory() {
auto level = frontend->getLevel();
auto player = level->player;
auto inventory = player->getInventory();
auto content = level->content;
SlotLayout slotLayout(glm::vec2(), true, false, [=](ItemStack& stack) {
stack.clear();
}, nullptr);
int columns = 10;
int rows = ceildiv(inventory->size(), columns);
int padding = 4;
InventoryBuilder builder;
builder.addGrid(columns, rows, glm::vec2(), padding, slotLayout);
auto layout = builder.build();
auto view = std::make_shared<InventoryView>(
content,
frontend,
interaction.get(),
inventory,
std::move(layout)
);
view->build();
return view;
}
HudRenderer::HudRenderer(Engine* engine, LevelFrontend* frontend)
: assets(engine->getAssets()),
gui(engine->getGUI()),
frontend(frontend) {
auto level = frontend->getLevel();
frontend(frontend)
{
auto menu = gui->getMenu();
auto content = level->content;
auto indices = content->getIndices();
std::vector<itemid_t> items;
for (itemid_t id = 1; id < indices->countItemDefs(); id++) {
items.push_back(id);
}
contentAccess.reset(new InventoryView(8, content, frontend, items));
contentAccess->setSlotConsumer([=](blockid_t id) {
level->player->setChosenItem(id);
});
interaction = std::make_unique<InventoryInteraction>();
grabbedItemView = std::make_shared<SlotView>(
interaction->getGrabbedItem(),
frontend,
interaction.get(),
frontend->getLevel()->content,
SlotLayout(glm::vec2(), false, false, nullptr, nullptr)
);
grabbedItemView->color(glm::vec4());
grabbedItemView->setInteractive(false);
hotbarView.reset(new InventoryView(1, content, frontend, std::vector<itemid_t> {0}));
contentAccess = createContentAccess();
contentAccessPanel = std::make_shared<Panel>(
contentAccess->size(), vec4(0.0f), 0.0f
);
contentAccessPanel->color(glm::vec4());
contentAccessPanel->add(contentAccess);
contentAccessPanel->scrollable(true);
hotbarView = createHotbar();
inventoryView = createInventory();
uicamera = new Camera(vec3(), 1);
uicamera->perspective = false;
@@ -191,10 +308,18 @@ HudRenderer::HudRenderer(Engine* engine, LevelFrontend* frontend)
createDebugPanel(engine);
menu->reset();
gui->add(this->debugPanel);
gui->add(debugPanel);
gui->add(contentAccessPanel);
gui->add(hotbarView);
gui->add(inventoryView);
gui->add(grabbedItemView);
}
HudRenderer::~HudRenderer() {
gui->remove(grabbedItemView);
gui->remove(inventoryView);
gui->remove(hotbarView);
gui->remove(contentAccessPanel);
gui->remove(debugPanel);
delete uicamera;
}
@@ -206,7 +331,12 @@ void HudRenderer::drawDebug(int fps){
}
void HudRenderer::update(bool visible) {
auto level = frontend->getLevel();
auto player = level->player;
auto menu = gui->getMenu();
menu->visible(pause);
if (!visible && inventoryOpen) {
inventoryOpen = false;
}
@@ -232,13 +362,35 @@ void HudRenderer::update(bool visible) {
if ((pause || inventoryOpen) == Events::_cursor_locked) {
Events::toggleCursor();
}
glm::vec2 invSize = contentAccessPanel->size();
inventoryView->visible(inventoryOpen);
contentAccessPanel->visible(inventoryOpen);
contentAccessPanel->size(glm::vec2(invSize.x, Window::height));
for (int i = keycode::NUM_1; i <= keycode::NUM_9; i++) {
if (Events::jpressed(i)) {
player->setChosenSlot(i - keycode::NUM_1);
}
}
if (Events::jpressed(keycode::NUM_0)) {
player->setChosenSlot(9);
}
if (!inventoryOpen && Events::scroll) {
int slot = player->getChosenSlot();
slot = (slot + Events::scroll) % 10;
if (slot < 0) {
slot += 10;
}
player->setChosenSlot(slot);
}
}
void HudRenderer::drawOverlay(const GfxContext& ctx) {
if (pause) {
Shader* uishader = assets->getShader("ui");
uishader->use();
uishader->uniformMatrix("u_projview", uicamera->getProjection()*uicamera->getView());
uishader->uniformMatrix("u_projview", uicamera->getProjView());
const Viewport& viewport = ctx.getViewport();
const uint width = viewport.getWidth();
@@ -271,12 +423,11 @@ void HudRenderer::draw(const GfxContext& ctx){
Shader* uishader = assets->getShader("ui");
uishader->use();
uishader->uniformMatrix("u_projview", uicamera->getProjection()*uicamera->getView());
uishader->uniformMatrix("u_projview", uicamera->getProjView());
// Draw selected item preview
hotbarView->setPosition(width-60, height-60);
hotbarView->setItems({player->getChosenItem()});
hotbarView->actAndDraw(&ctx);
hotbarView->setCoord(glm::vec2(width/2, height-65));
hotbarView->setSelected(player->getChosenSlot());
// Crosshair
batch->begin();
@@ -289,10 +440,20 @@ void HudRenderer::draw(const GfxContext& ctx){
}
if (inventoryOpen) {
// draw content access panel (all available items)
contentAccess->setPosition(viewport.getWidth()-contentAccess->getWidth(), 0);
contentAccess->actAndDraw(&ctx);
auto caLayout = contentAccess->getLayout();
auto invLayout = inventoryView->getLayout();
float caWidth = caLayout->getSize().x;
glm::vec2 invSize = invLayout->getSize();
float width = viewport.getWidth();
inventoryView->setCoord(glm::vec2(
glm::min(width/2-invSize.x/2, width-caWidth-10-invSize.x),
height/2-invSize.y/2
));
contentAccessPanel->setCoord(glm::vec2(width-caWidth, 0));
}
grabbedItemView->setCoord(glm::vec2(Events::cursor));
batch->render();
}
+13 -2
View File
@@ -15,12 +15,15 @@ class Assets;
class Player;
class Level;
class Engine;
class SlotView;
class InventoryView;
class LevelFrontend;
class InventoryInteraction;
namespace gui {
class GUI;
class UINode;
class Panel;
}
class HudRenderer {
@@ -34,13 +37,21 @@ class HudRenderer {
bool inventoryOpen = false;
bool pause = false;
std::unique_ptr<InventoryView> contentAccess;
std::unique_ptr<InventoryView> hotbarView;
std::shared_ptr<gui::Panel> contentAccessPanel;
std::shared_ptr<InventoryView> contentAccess;
std::shared_ptr<InventoryView> hotbarView;
std::shared_ptr<InventoryView> inventoryView;
std::shared_ptr<gui::UINode> debugPanel;
std::unique_ptr<InventoryInteraction> interaction;
std::shared_ptr<SlotView> grabbedItemView;
gui::GUI* gui;
LevelFrontend* frontend;
void createDebugPanel(Engine* engine);
std::shared_ptr<InventoryView> createContentAccess();
std::shared_ptr<InventoryView> createHotbar();
std::shared_ptr<InventoryView> createInventory();
public:
HudRenderer(Engine* engine, LevelFrontend* frontend);
~HudRenderer();