summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source/mon-pick.cc
diff options
context:
space:
mode:
authorPete Hurst <pete@streamuniverse.tv>2013-06-22 22:59:02 +0100
committerPete Hurst <pete@streamuniverse.tv>2013-06-23 02:43:28 +0100
commitea6f5a6ac38f62d16bedf5699726425b00860c1b (patch)
tree78f4eba59cbb159de7604d149aa5a35ca8d813d8 /crawl-ref/source/mon-pick.cc
parent0e5d46227251053be2ac5fb92cba2427c9c42b20 (diff)
downloadcrawl-ref-ea6f5a6ac38f62d16bedf5699726425b00860c1b.tar.gz
crawl-ref-ea6f5a6ac38f62d16bedf5699726425b00860c1b.zip
Refactor random-pick eliminating two globals from mon-place.cc
This provides support for using custom subclasses of monster_picker in the main mon-pick routines. It could perhaps be cleaned up further by refactoring a few places where it's used, but this avoids having to change any old code, whilst support a couple of new scenarios.
Diffstat (limited to 'crawl-ref/source/mon-pick.cc')
-rw-r--r--crawl-ref/source/mon-pick.cc50
1 files changed, 42 insertions, 8 deletions
diff --git a/crawl-ref/source/mon-pick.cc b/crawl-ref/source/mon-pick.cc
index b91678a22d..21c3549b25 100644
--- a/crawl-ref/source/mon-pick.cc
+++ b/crawl-ref/source/mon-pick.cc
@@ -9,8 +9,11 @@
#include "externs.h"
#include "branch.h"
+#include "coord.h"
+#include "env.h"
#include "errors.h"
#include "libutil.h"
+#include "mon-place.h"
#include "mon-util.h"
#include "place.h"
@@ -101,27 +104,57 @@ monster_type pick_monster(level_id place, mon_pick_vetoer veto)
return pick_monster_from(population[place.branch].pop, place.depth, veto);
}
+monster_type pick_monster(level_id place, monster_picker &picker)
+{
+ ASSERT(place.is_valid());
+ return picker.pick(population[place.branch].pop, place.depth, MONS_0);
+}
+
monster_type pick_monster_from(const pop_entry *fpop, int depth,
mon_pick_vetoer veto)
{
// XXX: If creating/destroying instances has performance issues, cache a
- // static instance and pass in the veto each time instead
- monster_picker picker(veto);
- return picker.pick(fpop, depth, MONS_0);
+ // static instance
+ monster_picker picker = monster_picker();
+ return picker.pick_with_veto(fpop, depth, MONS_0, veto);
+}
+
+monster_type monster_picker::pick_with_veto(const pop_entry *weights,
+ int level, monster_type none,
+ mon_pick_vetoer vetoer)
+{
+ _veto = vetoer;
+ return pick(weights, level, none);
}
// Veto specialisation for the monster_picker class; this simply calls the
// stored veto function. Can subclass further for more complex veto behaviour.
-bool monster_picker::veto(monster_type item)
+bool monster_picker::veto(monster_type mon)
+{
+ return _veto && _veto(mon);
+}
+
+bool positioned_monster_picker::veto(monster_type mon)
+{
+ // Actually pick a monster that is happy where we want to put it.
+ // Fish zombies on land are helpless and uncool.
+ if (!in_bounds(pos) || !monster_habitable_grid(mon, grd(pos)))
+ return true;
+ return monster_picker::veto(mon);
+}
+
+monster_type pick_monster_all_branches(int absdepth0, mon_pick_vetoer veto)
{
- return _veto(item);
+ monster_picker picker = monster_picker();
+ return pick_monster_all_branches(absdepth0, picker, veto);
}
// Used for picking zombies when there's nothing native.
// TODO: cache potential zombifiables for the given level/size, with a
// second pass to select ones that have a skeleton/etc and can be placed in
// a given spot.
-monster_type pick_monster_all_branches(int absdepth0, mon_pick_vetoer veto)
+monster_type pick_monster_all_branches(int absdepth0, monster_picker &picker,
+ mon_pick_vetoer veto)
{
monster_type valid[NUM_MONSTERS];
int rarities[NUM_MONSTERS];
@@ -139,10 +172,11 @@ monster_type pick_monster_all_branches(int absdepth0, mon_pick_vetoer veto)
if (depth < pop->minr || depth > pop->maxr)
continue;
- if (veto && (*veto)(pop->value))
+ if (veto && (*veto)(pop->value)
+ || !veto && picker.veto(pop->value))
continue;
- int rar = monster_picker::_rarity_at(pop, depth);
+ int rar = picker.rarity_at(pop, depth);
ASSERT(rar > 0);
monster_type mons = pop->value;