diff options
author | Pete Hurst <pete@streamuniverse.tv> | 2013-06-22 22:59:02 +0100 |
---|---|---|
committer | Pete Hurst <pete@streamuniverse.tv> | 2013-06-23 02:43:28 +0100 |
commit | ea6f5a6ac38f62d16bedf5699726425b00860c1b (patch) | |
tree | 78f4eba59cbb159de7604d149aa5a35ca8d813d8 /crawl-ref/source/mon-pick.cc | |
parent | 0e5d46227251053be2ac5fb92cba2427c9c42b20 (diff) | |
download | crawl-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.cc | 50 |
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; |