Attached Files |
Silent.cs [^] (710,915 bytes) 2014-04-21 14:02
Screenshot.bmp [^] (2,376,342 bytes) 2014-04-21 14:05
0001-Fix-inventory-panel-in-tiles-mode.patch [^] (12,840 bytes) 2014-04-28 06:23 [Show Content] [Hide Content]From f9ae2f189373529e871baadb1bf01f0d78d56039 Mon Sep 17 00:00:00 2001
From: Peter Wicks Stringfield <peterwicksstringfield@gmail.com>
Date: Sun, 27 Apr 2014 23:14:23 -0500
Subject: [PATCH] Fix inventory panel in tiles mode.
1. Do not allow the inventory panel to become stuck on the second (or
third, or fourth, ...) page when the player steps off a large pile of
items.
2. Do not hide items under the previous/next page buttons.
---
crawl-ref/source/tilereg-grid.h | 4 +-
crawl-ref/source/tilereg-inv.cc | 233 ++++++++++++++++++++++++++++++---------
crawl-ref/source/tilereg-inv.h | 4 +
3 files changed, 184 insertions(+), 57 deletions(-)
diff --git a/crawl-ref/source/tilereg-grid.h b/crawl-ref/source/tilereg-grid.h
index c253833..03f497a 100644
--- a/crawl-ref/source/tilereg-grid.h
+++ b/crawl-ref/source/tilereg-grid.h
@@ -37,7 +37,7 @@ public:
virtual void on_resize();
virtual void update() = 0;
- void place_cursor(const coord_def &cursor);
+ virtual void place_cursor(const coord_def &cursor);
virtual const string name() const = 0;
virtual bool update_tab_tip_text(string &tip, bool active) = 0;
@@ -49,7 +49,7 @@ protected:
// Place the cursor and set idx with the index into m_items of the click.
// If click was invalid, return false.
- bool place_cursor(MouseEvent &event, unsigned int &idx);
+ virtual bool place_cursor(MouseEvent &event, unsigned int &idx);
unsigned int cursor_index() const;
void add_quad_char(char c, int x, int y, int ox, int oy,
bool outline = false);
diff --git a/crawl-ref/source/tilereg-inv.cc b/crawl-ref/source/tilereg-inv.cc
index e889918..b31a690 100644
--- a/crawl-ref/source/tilereg-inv.cc
+++ b/crawl-ref/source/tilereg-inv.cc
@@ -44,15 +44,22 @@ void InventoryRegion::pack_buffers()
if (i >= m_items.size())
break;
- InventoryTile &item = m_items[i++];
+ InventoryTile &item = m_items[i];
- if ((y==my-1 && x==mx-1 && item.tile) || (y==0 && x==0 && m_grid_page>0))
+ // Previous and next page buttons.
+ if ((y==my-1 && x==mx-1 && item.tile)
+ || (y==0 && x==0 && m_grid_page>0))
{
// draw a background for paging tiles
m_buf.add_dngn_tile(TILE_ITEM_SLOT, x, y);
continue;
}
+ // Previous/next page buttons have no representative in m_items, so
+ // don't advance i when we deal with them, or else we will skip an
+ // actual item.
+ ++i;
+
if (item.flag & TILEI_FLAG_FLOOR)
{
if (i >= (unsigned int) mx * my * (m_grid_page+1) && item.tile)
@@ -75,21 +82,17 @@ void InventoryRegion::pack_buffers()
if (i >= m_items.size())
break;
- InventoryTile &item = m_items[i++];
+ InventoryTile &item = m_items[i];
- if (y==my-1 && x==mx-1 && item.tile)
- {
- // continuation to next page icon
- m_buf.add_main_tile(TILE_UNSEEN_ITEM, x, y);
- continue;
- }
- else if (y==0 && x==0 && m_grid_page>0)
+ if ((y==my-1 && x==mx-1 && item.tile)
+ || (y==0 && x==0 && m_grid_page>0))
{
- // previous page icon
m_buf.add_main_tile(TILE_UNSEEN_ITEM, x, y);
continue;
}
+ ++i;
+
if (item.flag & TILEI_FLAG_EQUIP)
{
if (item.flag & TILEI_FLAG_CURSE)
@@ -127,6 +130,69 @@ void InventoryRegion::pack_buffers()
}
}
+// Compensate for previous page button, the cursor is being drawn on the wrong
+// item.
+void InventoryRegion::place_cursor(const coord_def &cursor)
+{
+ if (m_cursor != NO_CURSOR && cursor_index() < m_items.size())
+ {
+ // Only one of these places is marked at any one time of course. But
+ // maybe m_grid_page can change between calls to this function?
+ m_items[cursor_index()].flag &= ~TILEI_FLAG_CURSOR;
+ m_items[cursor_index() - 1].flag &= ~TILEI_FLAG_CURSOR;
+ m_dirty = true;
+ }
+
+ if (m_cursor != cursor)
+ m_last_clicked_item = -1;
+
+ m_cursor = cursor;
+
+ if (m_cursor == NO_CURSOR
+ || (cursor_index() >= m_items.size() && m_grid_page == 0)
+ || (cursor_index() >= m_items.size() + 1 && m_grid_page > 0))
+ return;
+
+ // Add cursor to new location
+ const unsigned int location = cursor_index() - (m_grid_page > 0 ? 1 : 0);
+ m_items[location].flag |= TILEI_FLAG_CURSOR;
+ m_dirty = true;
+}
+
+// Compensate for previous page button, the result of cursor_index is allowed
+// to be one higher than it normally would be.
+bool InventoryRegion::place_cursor(MouseEvent &event, unsigned int &item_idx)
+{
+ int cx, cy;
+ if (!mouse_pos(event.px, event.py, cx, cy))
+ {
+ place_cursor(NO_CURSOR);
+ return false;
+ }
+
+ const coord_def cursor(cx, cy);
+ place_cursor(cursor);
+
+ if (mouse_control::current_mode() != MOUSE_MODE_COMMAND
+ && !tiles.get_map_display())
+ {
+ return false;
+ }
+
+ if (event.event != MouseEvent::PRESS)
+ return false;
+
+ item_idx = cursor_index();
+ if ((item_idx >= m_items.size()
+ && m_grid_page == 0)
+ || (item_idx >= m_items.size() + 1
+ && m_grid_page > 0)
+ || m_items[item_idx].empty())
+ return false;
+
+ return true;
+}
+
int InventoryRegion::handle_mouse(MouseEvent &event)
{
unsigned int item_idx;
@@ -134,19 +200,35 @@ int InventoryRegion::handle_mouse(MouseEvent &event)
return 0;
// handle paging
- if (m_cursor.x==(mx-1) && m_cursor.y==(my-1) && event.button==MouseEvent::LEFT)
+ if (_is_next_button(item_idx))
{
- // next page
- m_grid_page++;
- update();
- return CK_NO_KEY;
+ if (event.button==MouseEvent::LEFT)
+ {
+ // next page
+ m_grid_page++;
+ update();
+ return CK_NO_KEY;
+ }
+ else
+ return 0;
}
- else if (m_cursor.x==0 && m_cursor.y==0 && m_grid_page>0 && event.button==MouseEvent::LEFT)
+ else if (_is_prev_button(item_idx))
{
- // prev page
- m_grid_page--;
- update();
- return CK_NO_KEY;
+ if (event.button==MouseEvent::LEFT)
+ {
+ // prev page
+ m_grid_page--;
+ update();
+ return CK_NO_KEY;
+ }
+ else
+ return 0;
+ }
+
+ // Compensate for previous page button.
+ if (m_grid_page > 0)
+ {
+ --item_idx;
}
int idx = m_items[item_idx].idx;
@@ -294,8 +376,6 @@ bool InventoryRegion::update_tip_text(string& tip)
return false;
unsigned int item_idx = cursor_index();
- if (item_idx >= m_items.size() || m_items[item_idx].empty())
- return false;
// page next/prev
if (_is_next_button(item_idx))
@@ -309,6 +389,13 @@ bool InventoryRegion::update_tip_text(string& tip)
return true;
}
+ // Compensate for previous page button.
+ if (m_grid_page > 0)
+ --item_idx;
+
+ if (item_idx >= m_items.size() || m_items[item_idx].empty())
+ return false;
+
int idx = m_items[item_idx].idx;
// TODO enne - consider subclassing this class, rather than depending
@@ -589,27 +676,9 @@ bool InventoryRegion::update_alt_text(string &alt)
return false;
unsigned int item_idx = cursor_index();
- if (item_idx >= m_items.size() || m_items[item_idx].empty())
- return false;
-
- if (m_last_clicked_item >= 0
- && item_idx == (unsigned int) m_last_clicked_item)
- {
- return false;
- }
-
- int idx = m_items[item_idx].idx;
- const item_def *item;
-
- if (m_items[item_idx].flag & TILEI_FLAG_FLOOR)
- item = &mitm[idx];
- else
- item = &you.inv[idx];
-
- if (!item->defined())
- return false;
describe_info inf;
+
if (_is_next_button(item_idx))
{
// alt text for next page button
@@ -621,7 +690,33 @@ bool InventoryRegion::update_alt_text(string &alt)
inf.title = "Previous page";
}
else
+ {
+ // Compensate for previous page button.
+ if (m_grid_page > 0)
+ --item_idx;
+
+ if (item_idx >= m_items.size() || m_items[item_idx].empty())
+ return false;
+
+ if (m_last_clicked_item >= 0
+ && item_idx == (unsigned int) m_last_clicked_item)
+ {
+ return false;
+ }
+
+ int idx = m_items[item_idx].idx;
+ const item_def *item;
+
+ if (m_items[item_idx].flag & TILEI_FLAG_FLOOR)
+ item = &mitm[idx];
+ else
+ item = &you.inv[idx];
+
+ if (!item->defined())
+ return false;
+
get_item_desc(*item, inf);
+ }
alt_desc_proc proc(crawl_view.msgsz.x, crawl_view.msgsz.y);
process_description<alt_desc_proc>(proc, inf);
@@ -636,22 +731,30 @@ void InventoryRegion::draw_tag()
if (m_cursor == NO_CURSOR)
return;
int curs_index = cursor_index();
- if (curs_index >= (int)m_items.size())
- return;
- int idx = m_items[curs_index].idx;
- if (idx == -1)
- return;
-
- bool floor = m_items[curs_index].flag & TILEI_FLAG_FLOOR;
if (_is_next_button(curs_index))
draw_desc("Next page");
else if (_is_prev_button(curs_index))
draw_desc("Previous page");
- else if (floor && mitm[idx].defined())
- draw_desc(mitm[idx].name(DESC_PLAIN).c_str());
- else if (!floor && you.inv[idx].defined())
- draw_desc(you.inv[idx].name(DESC_INVENTORY_EQUIP).c_str());
+ else
+ {
+ // Compensate for previous page button.
+ if (m_grid_page > 0)
+ --curs_index;
+
+ if (curs_index >= (int)m_items.size())
+ return;
+ int idx = m_items[curs_index].idx;
+ if (idx == -1)
+ return;
+
+ bool floor = m_items[curs_index].flag & TILEI_FLAG_FLOOR;
+
+ if (floor && mitm[idx].defined())
+ draw_desc(mitm[idx].name(DESC_PLAIN).c_str());
+ else if (!floor && you.inv[idx].defined())
+ draw_desc(you.inv[idx].name(DESC_INVENTORY_EQUIP).c_str());
+ }
}
void InventoryRegion::activate()
@@ -705,7 +808,8 @@ static void _fill_item_info(InventoryTile &desc, const item_info &item)
desc.flag |= TILEI_FLAG_FLOOR;
}
-void InventoryRegion::update()
+// Part of update(), broken off because we might need to do it twice.
+void InventoryRegion::_update_add_items()
{
m_items.clear();
m_dirty = true;
@@ -855,7 +959,26 @@ void InventoryRegion::update()
m_items.push_back(desc);
}
} while (s);
+}
+
+void InventoryRegion::update()
+{
+ _update_add_items();
+
+ // If there are not enough items to put anything on the page we are on,
+ // then go back to the first page. This can happen if the player steps off
+ // a large item stack onto an empty tile. Make sure to account for the
+ // previous and next page buttons. (m_items.size() already counts the blank
+ // squares between inventory items and ground items.)
+ const signed int spaces_used = mx*my*m_grid_page - 2*m_grid_page;
+ ASSERT(spaces_used >= 0);
+ if (m_items.size() < static_cast<unsigned int>(spaces_used))
+ {
+ m_grid_page = 0;
+ _update_add_items();
+ }
+ // Fill the rest of the panel with blank tiles.
while ((int)m_items.size() < mx * my) // * (m_grid_page+1)) // let's not do this for p2 either
{
InventoryTile desc;
@@ -873,6 +996,6 @@ bool InventoryRegion::_is_prev_button(int idx)
bool InventoryRegion::_is_next_button(int idx)
{
// idx is an index in m_items as returned by cursor_index()
- return idx == mx*my*(m_grid_page+1)-1;
+ return idx == mx*my*(m_grid_page+1)-1-2*m_grid_page;
}
#endif
diff --git a/crawl-ref/source/tilereg-inv.h b/crawl-ref/source/tilereg-inv.h
index e3853db..ea03a99 100644
--- a/crawl-ref/source/tilereg-inv.h
+++ b/crawl-ref/source/tilereg-inv.h
@@ -17,12 +17,16 @@ public:
virtual const string name() const { return "Inventory"; }
+ virtual void place_cursor(const coord_def &cursor);
+
protected:
+ virtual bool place_cursor(MouseEvent &event, unsigned int &item_idx);
virtual void pack_buffers();
virtual void draw_tag();
virtual void activate();
private:
+ void _update_add_items();
bool _is_next_button(int idx);
bool _is_prev_button(int idx);
};
--
1.7.9.5
|