Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions builtin/settingtypes.txt
Original file line number Diff line number Diff line change
Expand Up @@ -508,6 +508,9 @@ directional_colored_fog (Colored fog) bool true
# set to the nearest valid value.
ambient_occlusion_gamma (Ambient occlusion gamma) float 2.2 0.25 4.0

# Enables animation of inventory items.
inventory_items_animations (Inventory items animations) bool false

[**Menus]

# Use a cloud animation for the main menu background.
Expand Down
3 changes: 3 additions & 0 deletions minetest.conf.example
Original file line number Diff line number Diff line change
Expand Up @@ -588,6 +588,9 @@
# type: float min: 0.25 max: 4
# ambient_occlusion_gamma = 2.2

# Enable animation of inventory items.
# inventory_items_animations = false

### Menus

# Use a cloud animation for the main menu background.
Expand Down
1 change: 1 addition & 0 deletions src/defaultsettings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ void set_default_settings(Settings *settings)
settings->setDefault("console_alpha", "200");
settings->setDefault("selectionbox_color", "(0,0,0)");
settings->setDefault("enable_node_highlighting", "false");
settings->setDefault("inventory_items_animations", "false");
settings->setDefault("crosshair_color", "(255,255,255)");
settings->setDefault("crosshair_alpha", "255");
settings->setDefault("hud_scaling", "1.0");
Expand Down
83 changes: 47 additions & 36 deletions src/guiFormSpecMenu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -572,7 +572,7 @@ void GUIFormSpecMenu::parseItemImage(parserData* data,std::string element)

if(!data->explicit_size)
warningstream<<"invalid use of item_image without a size[] element"<<std::endl;
m_itemimages.push_back(ImageDrawSpec(name, pos, geom));
m_itemimages.push_back(ImageDrawSpec("", name, pos, geom));
return;
}
errorstream<< "Invalid ItemImage element(" << parts.size() << "): '" << element << "'" << std::endl;
Expand Down Expand Up @@ -1483,7 +1483,6 @@ void GUIFormSpecMenu::parseItemImageButton(parserData* data,std::string element)
IItemDefManager *idef = m_gamedef->idef();
ItemStack item;
item.deSerialize(item_name, idef);
video::ITexture *texture = idef->getInventoryTexture(item.getDefinition(idef).name, m_gamedef);

m_tooltips[name] =
TooltipSpec(item.getDefinition(idef).description,
Expand All @@ -1505,13 +1504,17 @@ void GUIFormSpecMenu::parseItemImageButton(parserData* data,std::string element)
}

e->setUseAlphaChannel(true);
e->setImage(guiScalingImageButton(Environment->getVideoDriver(), texture, geom.X, geom.Y));
e->setPressedImage(guiScalingImageButton(Environment->getVideoDriver(), texture, geom.X, geom.Y));
e->setImage(guiScalingImageButton(Environment->getVideoDriver(), NULL, geom.X, geom.Y));
e->setPressedImage(guiScalingImageButton(Environment->getVideoDriver(), NULL, geom.X, geom.Y));
e->setScaleImage(true);
spec.ftype = f_Button;
rect+=data->basepos-padding;
spec.rect=rect;
m_fields.push_back(spec);
pos = padding + AbsoluteRect.UpperLeftCorner;
pos.X += stof(v_pos[0]) * (float) spacing.X;
pos.Y += stof(v_pos[1]) * (float) spacing.Y;
m_itemimages.push_back(ImageDrawSpec("", item_name, pos, geom));
return;
}
errorstream<< "Invalid ItemImagebutton element(" << parts.size() << "): '" << element << "'" << std::endl;
Expand Down Expand Up @@ -2151,7 +2154,8 @@ GUIFormSpecMenu::ItemSpec GUIFormSpecMenu::getItemAtPos(v2s32 p) const
return ItemSpec(InventoryLocation(), "", -1);
}

void GUIFormSpecMenu::drawList(const ListDrawSpec &s, int phase)
void GUIFormSpecMenu::drawList(const ListDrawSpec &s, int phase,
bool &item_hovered)
{
video::IVideoDriver* driver = Environment->getVideoDriver();

Expand Down Expand Up @@ -2193,12 +2197,13 @@ void GUIFormSpecMenu::drawList(const ListDrawSpec &s, int phase)
&& m_selected_item->i == item_i;
bool hovering = rect.isPointInside(m_pointer);

if(phase == 0)
{
if(hovering)
if (phase == 0) {
if (hovering) {
item_hovered = true;
driver->draw2DRectangle(m_slotbg_h, rect, &AbsoluteClippingRect);
else
} else {
driver->draw2DRectangle(m_slotbg_n, rect, &AbsoluteClippingRect);
}
}

//Draw inv slot borders
Expand Down Expand Up @@ -2232,7 +2237,8 @@ void GUIFormSpecMenu::drawList(const ListDrawSpec &s, int phase)
if(!item.empty())
{
drawItemStack(driver, m_font, item,
rect, &AbsoluteClippingRect, m_gamedef);
rect, &AbsoluteClippingRect, m_gamedef,
selected, hovering, false);
}

// Draw tooltip
Expand Down Expand Up @@ -2273,11 +2279,15 @@ void GUIFormSpecMenu::drawList(const ListDrawSpec &s, int phase)

void GUIFormSpecMenu::drawSelectedItem()
{
if(!m_selected_item)
return;

video::IVideoDriver* driver = Environment->getVideoDriver();

if (!m_selected_item) {
drawItemStack(driver, m_font, ItemStack(),
core::rect<s32>(v2s32(0, 0), v2s32(0, 0)),
NULL, m_gamedef, false, false, true);
return;
}

Inventory *inv = m_invmgr->getInventory(m_selected_item->inventoryloc);
sanity_check(inv);
InventoryList *list = inv->getList(m_selected_item->listname);
Expand All @@ -2287,7 +2297,7 @@ void GUIFormSpecMenu::drawSelectedItem()

core::rect<s32> imgrect(0,0,imgsize.X,imgsize.Y);
core::rect<s32> rect = imgrect + (m_pointer - imgrect.getCenter());
drawItemStack(driver, m_font, stack, rect, NULL, m_gamedef);
drawItemStack(driver, m_font, stack, rect, NULL, m_gamedef, false, false, true);
}

void GUIFormSpecMenu::drawMenu()
Expand Down Expand Up @@ -2369,6 +2379,12 @@ void GUIFormSpecMenu::drawMenu()

driver->draw2DRectangle(todraw, rect, 0);
}

/*
Call base class
*/
gui::IGUIElement::draw();

/*
Draw images
*/
Expand Down Expand Up @@ -2413,37 +2429,32 @@ void GUIFormSpecMenu::drawMenu()
const ImageDrawSpec &spec = m_itemimages[i];
IItemDefManager *idef = m_gamedef->idef();
ItemStack item;
item.deSerialize(spec.name, idef);
video::ITexture *texture = idef->getInventoryTexture(item.getDefinition(idef).name, m_gamedef);
// Image size on screen
item.deSerialize(spec.item_name, idef);
core::rect<s32> imgrect(0, 0, spec.geom.X, spec.geom.Y);
// Image rectangle on screen
// Viewport rectangle on screen
core::rect<s32> rect = imgrect + spec.pos;
const video::SColor color(255,255,255,255);
const video::SColor colors[] = {color,color,color,color};
draw2DImageFilterScaled(driver, texture, rect,
core::rect<s32>(core::position2d<s32>(0,0),
core::dimension2di(texture->getOriginalSize())),
NULL/*&AbsoluteClippingRect*/, colors, true);
drawItemStack(driver, m_font, item, rect, &AbsoluteClippingRect,
m_gamedef, false, false, false);
}

/*
Draw items
Phase 0: Item slot rectangles
Phase 1: Item images; prepare tooltip
*/
int start_phase=0;
for(int phase=start_phase; phase<=1; phase++)
for(u32 i=0; i<m_inventorylists.size(); i++)
{
drawList(m_inventorylists[i], phase);
}

/*
Call base class
*/
gui::IGUIElement::draw();

bool item_hovered = false;
int start_phase = 0;
for (int phase = start_phase; phase <= 1; phase++) {
for (u32 i = 0; i < m_inventorylists.size(); i++) {
drawList(m_inventorylists[i], phase, item_hovered);
}
}
if (!item_hovered) {
drawItemStack(driver, m_font, ItemStack(),
core::rect<s32>(v2s32(0, 0), v2s32(0, 0)),
NULL, m_gamedef, false, true, false);
}

/* TODO find way to show tooltips on touchscreen */
#ifndef HAVE_TOUCHSCREENGUI
m_pointer = m_device->getCursorControl()->getPosition();
Expand Down
20 changes: 17 additions & 3 deletions src/guiFormSpecMenu.h
Original file line number Diff line number Diff line change
Expand Up @@ -143,21 +143,32 @@ class GUIFormSpecMenu : public GUIModalMenu
{
}
ImageDrawSpec(const std::string &a_name,
v2s32 a_pos, v2s32 a_geom):
const std::string &a_item_name,
const v2s32 &a_pos, const v2s32 &a_geom):
name(a_name),
item_name (a_item_name),
pos(a_pos),
geom(a_geom)
{
scale = true;
}
ImageDrawSpec(const std::string &a_name,
v2s32 a_pos):
const v2s32 &a_pos, const v2s32 &a_geom):
name(a_name),
pos(a_pos),
geom(a_geom)
{
scale = true;
}
ImageDrawSpec(const std::string &a_name,
const v2s32 &a_pos):
name(a_name),
pos(a_pos)
{
scale = false;
}
std::string name;
std::string item_name;
v2s32 pos;
v2s32 geom;
bool scale;
Expand Down Expand Up @@ -282,7 +293,7 @@ class GUIFormSpecMenu : public GUIModalMenu
void regenerateGui(v2u32 screensize);

ItemSpec getItemAtPos(v2s32 p) const;
void drawList(const ListDrawSpec &s, int phase);
void drawList(const ListDrawSpec &s, int phase, bool &item_hovered);
void drawSelectedItem();
void drawMenu();
void updateSelectedItem();
Expand Down Expand Up @@ -334,6 +345,8 @@ class GUIFormSpecMenu : public GUIModalMenu
std::vector<std::pair<FieldSpec,gui::IGUIScrollBar*> > m_scrollbars;

ItemSpec *m_selected_item;
f32 m_timer1;
f32 m_timer2;
u32 m_selected_amount;
bool m_selected_dragging;

Expand Down Expand Up @@ -373,6 +386,7 @@ class GUIFormSpecMenu : public GUIModalMenu
TextDest *m_text_dst;
unsigned int m_formspec_version;
std::string m_focused_element;
bool m_selection_active;

typedef struct {
bool explicit_size;
Expand Down
99 changes: 84 additions & 15 deletions src/hud.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,9 @@ Hud::Hud(video::IVideoDriver *driver, scene::ISceneManager* smgr,
use_hotbar_selected_image = false;
}

void Hud::drawItem(const ItemStack &item, const core::rect<s32>& rect, bool selected) {

void Hud::drawItem(const ItemStack &item, const core::rect<s32>& rect,
bool selected)
{
if (selected) {
/* draw hihlighting around selected item */
if (use_hotbar_selected_image) {
Expand Down Expand Up @@ -154,7 +155,8 @@ void Hud::drawItem(const ItemStack &item, const core::rect<s32>& rect, bool sele
video::SColor bgcolor2(128, 0, 0, 0);
if (!use_hotbar_image)
driver->draw2DRectangle(bgcolor2, rect, NULL);
drawItemStack(driver, g_fontengine->getFont(), item, rect, NULL, gamedef);
drawItemStack(driver, g_fontengine->getFont(), item, rect, NULL,
gamedef, selected, false, false);
}

//NOTE: selectitem = 0 -> no selected; selectitem 1-based
Expand Down Expand Up @@ -489,23 +491,90 @@ void drawItemStack(video::IVideoDriver *driver,
const ItemStack &item,
const core::rect<s32> &rect,
const core::rect<s32> *clip,
IGameDef *gamedef)
IGameDef *gamedef,
bool selected,
bool hovered,
bool dragged)
{
if(item.empty())
static s32 hovered_time;
static s32 selected_time;
static s32 dragged_time;
static scene::IMesh *hovered_mesh;
static scene::IMesh *selected_mesh;
static scene::IMesh *dragged_mesh;
bool enable_animations =
g_settings->getBool("inventory_items_animations");

if (item.empty()) {
if (selected) {
selected_mesh = NULL;
} else if (hovered) {
hovered_mesh = NULL;
} else if (dragged) {
dragged_mesh = NULL;
}
return;
}

const ItemDefinition &def = item.getDefinition(gamedef->idef());
video::ITexture *texture = gamedef->idef()->getInventoryTexture(def.name, gamedef);
scene::IMesh* mesh = gamedef->idef()->getWieldMesh(def.name, gamedef);

if (mesh) {
driver->clearZBuffer();
s32 delta = 0;
if (selected) {
if (mesh != selected_mesh) {
selected_mesh = mesh;
selected_time = getTimeMs();
} else {
delta = porting::getDeltaMs(selected_time, getTimeMs()) % 100000;
}
} else if (hovered) {
if (mesh != hovered_mesh) {
hovered_mesh = mesh;
hovered_time = getTimeMs();
} else {
delta = porting::getDeltaMs(hovered_time, getTimeMs()) % 100000;
}
} else if (dragged) {
if (mesh != dragged_mesh) {
dragged_mesh = mesh;
dragged_time = getTimeMs();
} else {
delta = porting::getDeltaMs(dragged_time, getTimeMs()) % 100000;
}
}
core::rect<s32> oldViewPort = driver->getViewPort();
core::matrix4 oldProjMat = driver->getTransform(video::ETS_PROJECTION);
core::matrix4 oldViewMat = driver->getTransform(video::ETS_VIEW);
core::matrix4 ProjMatrix;
ProjMatrix.buildProjectionMatrixOrthoLH(2, 2, -1, 100);
driver->setTransform(video::ETS_PROJECTION, ProjMatrix);
driver->setTransform(video::ETS_VIEW, ProjMatrix);
core::matrix4 matrix;
matrix.makeIdentity();

if (enable_animations) {
float timer_f = (float)delta / 5000.0;
matrix.setRotationDegrees(core::vector3df(0, 360 * timer_f, 0));
}

// Draw the inventory texture
if(texture != NULL)
{
const video::SColor color(255,255,255,255);
const video::SColor colors[] = {color,color,color,color};
draw2DImageFilterScaled(driver, texture, rect,
core::rect<s32>(core::position2d<s32>(0,0),
core::dimension2di(texture->getOriginalSize())),
clip, colors, true);
driver->setTransform(video::ETS_WORLD, matrix);
driver->setViewPort(rect);

u32 mc = mesh->getMeshBufferCount();
for (u32 j = 0; j < mc; ++j) {
scene::IMeshBuffer *buf = mesh->getMeshBuffer(j);
video::SMaterial &material = buf->getMaterial();
material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
material.Lighting = false;
driver->setMaterial(material);
driver->drawMeshBuffer(buf);
}

driver->setTransform(video::ETS_VIEW, oldViewMat);
driver->setTransform(video::ETS_PROJECTION, oldProjMat);
driver->setViewPort(oldViewPort);
}

if(def.type == ITEM_TOOL && item.wear != 0)
Expand Down
Loading