summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source
diff options
context:
space:
mode:
Diffstat (limited to 'crawl-ref/source')
-rw-r--r--crawl-ref/source/makefile.obj1
-rw-r--r--crawl-ref/source/mon-iter.cc87
-rw-r--r--crawl-ref/source/mon-iter.h49
3 files changed, 137 insertions, 0 deletions
diff --git a/crawl-ref/source/makefile.obj b/crawl-ref/source/makefile.obj
index c85450cd5f..ccbfb75aeb 100644
--- a/crawl-ref/source/makefile.obj
+++ b/crawl-ref/source/makefile.obj
@@ -103,6 +103,7 @@ mon-behv.o \
mon-cast.o \
mon-gear.o \
mon-info.o \
+mon-iter.o \
mon-pick.o \
mon-util.o \
monplace.o \
diff --git a/crawl-ref/source/mon-iter.cc b/crawl-ref/source/mon-iter.cc
new file mode 100644
index 0000000000..1158a9028d
--- /dev/null
+++ b/crawl-ref/source/mon-iter.cc
@@ -0,0 +1,87 @@
+#include "AppHdr.h"
+
+#include "mon-iter.h"
+
+#include "actor.h"
+#include "coord-circle.h"
+#include "env.h"
+#include "monster.h"
+
+monster_iterator::monster_iterator()
+ : restr(R_NONE), curr_mid(0)
+{
+ advance(true);
+}
+
+monster_iterator::monster_iterator(const circle_def* circle_)
+ : restr(R_CIRC), curr_mid(0), circle(circle_)
+{
+ advance(true);
+}
+
+monster_iterator::monster_iterator(const los_def* los_)
+ : restr(R_LOS), curr_mid(0), los(los_)
+{
+ advance(true);
+}
+
+monster_iterator::monster_iterator(const actor* act_)
+ : restr(R_ACT), curr_mid(0), act(act_)
+{
+ advance(true);
+}
+
+monster_iterator::operator bool() const
+{
+ return (curr_mid < MAX_MONSTERS);
+}
+
+monsters* monster_iterator::operator*() const
+{
+ return (&env.mons[curr_mid]);
+}
+
+monsters* monster_iterator::operator->() const
+{
+ return (&env.mons[curr_mid]);
+}
+
+monster_iterator& monster_iterator::operator++()
+{
+ advance();
+ return (*this);
+}
+
+monster_iterator monster_iterator::operator++(int)
+{
+ monster_iterator copy = *this;
+ ++(*this);
+ return (copy);
+}
+
+bool monster_iterator::valid(int mid) const
+{
+ monsters* mon = &env.mons[mid];
+ if (!mon->alive())
+ return (false);
+ switch (restr)
+ {
+ case R_CIRC:
+ return (circle->contains(mon->pos()));
+ case R_LOS:
+ return (los->see_cell(mon->pos()));
+ case R_ACT:
+ return (act->can_see(mon));
+ default:
+ return (true);
+ }
+}
+
+void monster_iterator::advance(bool may_stay)
+{
+ if (!may_stay)
+ ++curr_mid;
+ while (curr_mid < MAX_MONSTERS && !valid(curr_mid))
+ ++curr_mid;
+}
+
diff --git a/crawl-ref/source/mon-iter.h b/crawl-ref/source/mon-iter.h
new file mode 100644
index 0000000000..7f31831c64
--- /dev/null
+++ b/crawl-ref/source/mon-iter.h
@@ -0,0 +1,49 @@
+/*
+ * Provide a way to iterator over all monsters,
+ * subject to a few common restrictions.
+ *
+ * TODO:
+ * - Iterate over actors?
+ */
+
+#ifndef MON_ITER_H
+#define MON_ITER_H
+
+enum restr_type
+{
+ R_NONE,
+ R_CIRC,
+ R_LOS,
+ R_ACT
+};
+
+class circle_def;
+class los_def;
+class actor;
+
+class monster_iterator
+{
+public:
+ monster_iterator();
+ monster_iterator(const circle_def* circle_);
+ monster_iterator(const los_def* los_);
+ monster_iterator(const actor* act_);
+
+ operator bool() const;
+ monsters* operator*() const;
+ monsters* operator->() const;
+ monster_iterator& operator++();
+ monster_iterator operator++(int);
+
+protected:
+ restr_type restr;
+ int curr_mid;
+ const circle_def* circle;
+ const los_def* los;
+ const actor* act;
+
+ bool valid(int mid) const;
+ void advance(bool may_stay=false);
+};
+
+#endif