summaryrefslogtreecommitdiffstats
path: root/crawl-ref
diff options
context:
space:
mode:
authorharanp <haranp@c06c8d41-db1a-0410-9941-cceddc491573>2008-06-16 06:11:50 +0000
committerharanp <haranp@c06c8d41-db1a-0410-9941-cceddc491573>2008-06-16 06:11:50 +0000
commitf13fb6fd227d1bf21cbef7542c487271a178a77c (patch)
treea8a1702f38fe1c6d77a8b2eb46711bfb89917074 /crawl-ref
parentaca7f0db12247aae824668b0aeea4f2dd47f8be4 (diff)
downloadcrawl-ref-f13fb6fd227d1bf21cbef7542c487271a178a77c.tar.gz
crawl-ref-f13fb6fd227d1bf21cbef7542c487271a178a77c.zip
Finally implemented stack_iterator(), a way to iterate over objects in
a stack without all that o = mitm[o].link stuff. Redid Ely's destroy weapons power to use it. git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@5875 c06c8d41-db1a-0410-9941-cceddc491573
Diffstat (limited to 'crawl-ref')
-rw-r--r--crawl-ref/source/religion.cc28
-rw-r--r--crawl-ref/source/stuff.cc49
-rw-r--r--crawl-ref/source/stuff.h21
3 files changed, 81 insertions, 17 deletions
diff --git a/crawl-ref/source/religion.cc b/crawl-ref/source/religion.cc
index 0bbdd9de6f..df5340db9d 100644
--- a/crawl-ref/source/religion.cc
+++ b/crawl-ref/source/religion.cc
@@ -3021,35 +3021,30 @@ bool ely_destroy_weapons()
god_acting gdact;
bool success = false;
- int i = igrd[you.x_pos][you.y_pos];
- while (i != NON_ITEM)
+ for ( stack_iterator si(you.pos()); si; ++si )
{
- const int next = mitm[i].link; // In case we can't get it later.
-
- if (mitm[i].base_type != OBJ_WEAPONS
- && mitm[i].base_type != OBJ_MISSILES
- || item_is_stationary(mitm[i])) // Held in a net?
+ item_def& item(*si);
+ if ( (item.base_type != OBJ_WEAPONS
+ && item.base_type != OBJ_MISSILES)
+ || item_is_stationary(item)) // Held in a net?
{
- i = next;
continue;
}
- if (!check_warning_inscriptions(mitm[i], OPER_DESTROY))
+ if (!check_warning_inscriptions(item, OPER_DESTROY))
{
mpr("Won't destroy {!D} inscribed item.");
- i = next;
continue;
}
- const int value = item_value( mitm[i], true );
+ const int value = item_value( item, true );
#ifdef DEBUG_DIAGNOSTICS
mprf(MSGCH_DIAGNOSTICS, "Destroyed weapon value: %d", value);
#endif
piety_gain_t pgain = PIETY_NONE;
- bool is_evil_weapon = is_evil_item(mitm[i]);
- if (is_evil_weapon
- || _destroyed_valuable_weapon(value, mitm[i].base_type))
+ const bool is_evil_weapon = is_evil_item(item);
+ if (is_evil_weapon || _destroyed_valuable_weapon(value, item.base_type))
{
pgain = PIETY_SOME;
gain_piety(1);
@@ -3057,7 +3052,7 @@ bool ely_destroy_weapons()
// Elyvilon doesn't care about item sacrifices at altars, so
// I'm stealing _Sacrifice_Messages.
- _print_sacrifice_message(GOD_ELYVILON, mitm[i], pgain);
+ _print_sacrifice_message(GOD_ELYVILON, item, pgain);
if (is_evil_weapon)
{
// Print this is addition to the above!
@@ -3065,9 +3060,8 @@ bool ely_destroy_weapons()
GOD_ELYVILON);
}
- destroy_item(i);
+ destroy_item( si.link() );
success = true;
- i = next;
}
if (!success)
diff --git a/crawl-ref/source/stuff.cc b/crawl-ref/source/stuff.cc
index d2e1fbb52e..ea171db473 100644
--- a/crawl-ref/source/stuff.cc
+++ b/crawl-ref/source/stuff.cc
@@ -77,6 +77,55 @@
#include "tutorial.h"
#include "view.h"
+stack_iterator::stack_iterator(const coord_def& pos)
+{
+ cur_link = igrd(pos);
+ if ( cur_link != NON_ITEM )
+ next_link = mitm[cur_link].link;
+ else
+ next_link = NON_ITEM;
+}
+
+stack_iterator::stack_iterator(int start_link)
+{
+ cur_link = start_link;
+ if ( cur_link != NON_ITEM )
+ next_link = mitm[cur_link].link;
+ else
+ next_link = NON_ITEM;
+}
+
+stack_iterator::operator bool() const
+{
+ return ( cur_link != NON_ITEM );
+}
+
+item_def& stack_iterator::operator*() const
+{
+ ASSERT( cur_link != NON_ITEM );
+ return mitm[cur_link];
+}
+
+int stack_iterator::link() const
+{
+ return cur_link;
+}
+
+const stack_iterator& stack_iterator::operator ++ ()
+{
+ cur_link = next_link;
+ if ( cur_link != NON_ITEM )
+ next_link = mitm[cur_link].link;
+ return *this;
+}
+
+stack_iterator stack_iterator::operator++(int dummy)
+{
+ const stack_iterator copy = *this;
+ ++(*this);
+ return copy;
+}
+
radius_iterator::radius_iterator( const coord_def& _center, int _radius,
bool _roguelike_metric, bool _require_los,
bool _exclude_center )
diff --git a/crawl-ref/source/stuff.h b/crawl-ref/source/stuff.h
index 66e492c7ca..3bb0221fca 100644
--- a/crawl-ref/source/stuff.h
+++ b/crawl-ref/source/stuff.h
@@ -48,6 +48,27 @@ int roll_dice( int num, int size );
int roll_dice( const struct dice_def &dice );
void scale_dice( dice_def &dice, int threshold = 24 );
+// stack_iterator guarantees validity so long as you don't manually
+// mess with item_def.link: i.e., you can kill the item you're
+// examining but you can't kill the item linked to it.
+class stack_iterator : public std::iterator<std::forward_iterator_tag,
+ item_def>
+{
+public:
+ stack_iterator( const coord_def& pos );
+ stack_iterator( int start_link );
+
+ operator bool() const;
+ item_def& operator *() const;
+ int link() const;
+
+ const stack_iterator& operator ++ ();
+ stack_iterator operator ++ (int);
+private:
+ int cur_link;
+ int next_link;
+};
+
class radius_iterator : public std::iterator<std::bidirectional_iterator_tag,
coord_def>
{