From adb21570e7da7ff280113e938ee7a26089614e63 Mon Sep 17 00:00:00 2001 From: Robert Vollmert Date: Wed, 11 Nov 2009 16:38:12 +0100 Subject: Convert another 45 monster loops to monster_iterator. A total of 53 have been converted; 39 left, of which some should stay. Now at a net loss of lines of code for monster_iterator. Occurrences of MAX_MONSTERS down to 65 from 116 in *.cc. --- crawl-ref/source/abyss.cc | 28 ++-- crawl-ref/source/acr.cc | 6 +- crawl-ref/source/attitude-change.cc | 269 +++++++++++++++++------------------- crawl-ref/source/beam.cc | 21 +-- crawl-ref/source/decks.cc | 34 +++-- crawl-ref/source/effects.cc | 75 +++++----- crawl-ref/source/ghost.cc | 12 +- crawl-ref/source/godabil.cc | 12 +- crawl-ref/source/misc.cc | 12 +- crawl-ref/source/mon-abil.cc | 65 ++++----- crawl-ref/source/mon-act.cc | 17 ++- crawl-ref/source/monstuff.cc | 164 ++++++++++------------ crawl-ref/source/spells3.cc | 9 +- crawl-ref/source/view.cc | 76 +++++----- crawl-ref/source/wiz-mon.cc | 22 ++- crawl-ref/source/xom.cc | 82 ++++------- 16 files changed, 388 insertions(+), 516 deletions(-) diff --git a/crawl-ref/source/abyss.cc b/crawl-ref/source/abyss.cc index cf3f74267d..e5d64fff31 100644 --- a/crawl-ref/source/abyss.cc +++ b/crawl-ref/source/abyss.cc @@ -18,6 +18,7 @@ #include "mapmark.h" #include "message.h" #include "misc.h" +#include "mon-iter.h" #include "mon-util.h" #include "monplace.h" #include "mtransit.h" @@ -442,16 +443,11 @@ void area_shift(void) _xom_check_nearness_setup(); - for (unsigned int i = 0; i < MAX_MONSTERS; i++) + // Remove non-nearby monsters. + for (monster_iterator mi; mi; ++mi) { - monsters &m = menv[i]; - - if (!m.alive()) - continue; - - // Remove non-nearby monsters. - if (grid_distance(m.pos(), you.pos()) > 10) - _abyss_lose_monster(m); + if (grid_distance(mi->pos(), you.pos()) > 10) + _abyss_lose_monster(**mi); } for (rectangle_iterator ri(5); ri; ++ri) @@ -546,12 +542,9 @@ void area_shift(void) void save_abyss_uniques() { - for (int i = 0; i < MAX_MONSTERS; ++i) - { - monsters &m = menv[i]; - if (m.alive() && m.needs_transit()) - m.set_transit( level_id(LEVEL_ABYSS) ); - } + for (monster_iterator mi; mi; ++mi) + if (mi->needs_transit()) + mi->set_transit(level_id(LEVEL_ABYSS)); } void abyss_teleport( bool new_area ) @@ -602,9 +595,8 @@ void abyss_teleport( bool new_area ) tile_init_flavour(); #endif - for (int i = 0; i < MAX_MONSTERS; ++i) - if (menv[i].alive()) - _abyss_lose_monster(menv[i]); + for (monster_iterator mi; mi; ++mi) + _abyss_lose_monster(**mi); // Orbs and fixed artefacts are marked as "lost in the abyss". for (int i = 0; i < MAX_ITEMS; ++i) diff --git a/crawl-ref/source/acr.cc b/crawl-ref/source/acr.cc index ff1a1ccd3b..70901ec1cb 100644 --- a/crawl-ref/source/acr.cc +++ b/crawl-ref/source/acr.cc @@ -89,6 +89,7 @@ #include "misc.h" #include "mon-act.h" #include "mon-cast.h" +#include "mon-iter.h" #include "monplace.h" #include "monstuff.h" #include "mon-util.h" @@ -4025,9 +4026,8 @@ static void _move_player(coord_def move) mprf(MSGCH_DIAGNOSTICS, "Number of items present: %d", j); j = 0; - for (int i = 0; i < MAX_MONSTERS; ++i) - if (menv[i].type != -1) - ++j; + for (monster_iterator mi; mi; ++mi) + ++j; mprf(MSGCH_DIAGNOSTICS, "Number of monsters present: %d", j); mprf(MSGCH_DIAGNOSTICS, "Number of clouds present: %d", env.cloud_no); diff --git a/crawl-ref/source/attitude-change.cc b/crawl-ref/source/attitude-change.cc index 509525fb65..518d77cb9a 100644 --- a/crawl-ref/source/attitude-change.cc +++ b/crawl-ref/source/attitude-change.cc @@ -16,6 +16,7 @@ #include "goditem.h" #include "message.h" #include "mon-behv.h" +#include "mon-iter.h" #include "mon-util.h" #include "monster.h" #include "monstuff.h" @@ -145,44 +146,42 @@ static bool _holy_beings_on_level_attitude_change() { bool success = false; - for (int i = 0; i < MAX_MONSTERS; ++i) + for (monster_iterator mi; mi; ++mi) { - monsters *monster = &menv[i]; - if (monster->alive() - && monster->is_holy()) - { + if (!mi->is_holy()) + continue; + #ifdef DEBUG_DIAGNOSTICS - mprf(MSGCH_DIAGNOSTICS, "Holy attitude changing: %s on level %d, branch %d", - monster->name(DESC_PLAIN).c_str(), - static_cast(you.your_level), - static_cast(you.where_are_you)); + mprf(MSGCH_DIAGNOSTICS, "Holy attitude changing: %s on level %d, branch %d", + mi->name(DESC_PLAIN).c_str(), + static_cast(you.your_level), + static_cast(you.where_are_you)); #endif - // If you worship a good god, you get another chance to make - // neutral and hostile holy beings good neutral. - if (is_good_god(you.religion) && !monster->wont_attack()) - { - if (testbits(monster->flags, MF_ATT_CHANGE_ATTEMPT)) - { - monster->flags &= ~MF_ATT_CHANGE_ATTEMPT; - - success = true; - } - } - // If you don't worship a good god, you make all friendly - // and good neutral holy beings that worship a good god - // hostile. - else if (!is_good_god(you.religion) && monster->wont_attack() - && is_good_god(monster->god)) + // If you worship a good god, you get another chance to make + // neutral and hostile holy beings good neutral. + if (is_good_god(you.religion) && !mi->wont_attack()) + { + if (testbits(mi->flags, MF_ATT_CHANGE_ATTEMPT)) { - monster->attitude = ATT_HOSTILE; - monster->del_ench(ENCH_CHARM, true); - behaviour_event(monster, ME_ALERT, MHITYOU); - // For now CREATED_FRIENDLY/WAS_NEUTRAL stays. + mi->flags &= ~MF_ATT_CHANGE_ATTEMPT; success = true; } } + // If you don't worship a good god, you make all friendly + // and good neutral holy beings that worship a good god + // hostile. + else if (!is_good_god(you.religion) && mi->wont_attack() + && is_good_god(mi->god)) + { + mi->attitude = ATT_HOSTILE; + mi->del_ench(ENCH_CHARM, true); + behaviour_event(*mi, ME_ALERT, MHITYOU); + // For now CREATED_FRIENDLY/WAS_NEUTRAL stays. + + success = true; + } } return (success); @@ -197,32 +196,29 @@ static bool _unholy_and_evil_beings_on_level_attitude_change() { bool success = false; - for (int i = 0; i < MAX_MONSTERS; ++i) + for (monster_iterator mi; mi; ++mi) { - monsters *monster = &menv[i]; - if (monster->alive() - && (monster->is_unholy() - || monster->is_evil())) - { + if (!mi->is_unholy() && !mi->is_evil()) + continue; + #ifdef DEBUG_DIAGNOSTICS - mprf(MSGCH_DIAGNOSTICS, "Unholy/evil attitude changing: %s " - "on level %d, branch %d", - monster->name(DESC_PLAIN, true).c_str(), - static_cast(you.your_level), - static_cast(you.where_are_you)); + mprf(MSGCH_DIAGNOSTICS, "Unholy/evil attitude changing: %s " + "on level %d, branch %d", + mi->name(DESC_PLAIN, true).c_str(), + static_cast(you.your_level), + static_cast(you.where_are_you)); #endif - // If you worship a good god, you make all friendly and good - // neutral unholy and evil beings hostile. - if (is_good_god(you.religion) && monster->wont_attack()) - { - monster->attitude = ATT_HOSTILE; - monster->del_ench(ENCH_CHARM, true); - behaviour_event(monster, ME_ALERT, MHITYOU); - // For now CREATED_FRIENDLY/WAS_NEUTRAL stays. + // If you worship a good god, you make all friendly and good + // neutral unholy and evil beings hostile. + if (is_good_god(you.religion) && mi->wont_attack()) + { + mi->attitude = ATT_HOSTILE; + mi->del_ench(ENCH_CHARM, true); + behaviour_event(*mi, ME_ALERT, MHITYOU); + // For now CREATED_FRIENDLY/WAS_NEUTRAL stays. - success = true; - } + success = true; } } @@ -238,33 +234,30 @@ static bool _chaotic_beings_on_level_attitude_change() { bool success = false; - for (int i = 0; i < MAX_MONSTERS; ++i) + for (monster_iterator mi; mi; ++mi) { - monsters *monster = &menv[i]; - if (monster->alive() - && monster->is_chaotic()) - { + if (!mi->is_chaotic()) + continue; + #ifdef DEBUG_DIAGNOSTICS - mprf(MSGCH_DIAGNOSTICS, "Chaotic attitude changing: %s on level %d, branch %d", - monster->name(DESC_PLAIN).c_str(), - static_cast(you.your_level), - static_cast(you.where_are_you)); + mprf(MSGCH_DIAGNOSTICS, "Chaotic attitude changing: %s on level %d, branch %d", + mi->name(DESC_PLAIN).c_str(), + static_cast(you.your_level), + static_cast(you.where_are_you)); #endif - // If you worship Zin, you make all friendly and good neutral - // chaotic beings hostile. - if (you.religion == GOD_ZIN && monster->wont_attack()) - { - monster->attitude = ATT_HOSTILE; - monster->del_ench(ENCH_CHARM, true); - behaviour_event(monster, ME_ALERT, MHITYOU); - // For now CREATED_FRIENDLY/WAS_NEUTRAL stays. + // If you worship Zin, you make all friendly and good neutral + // chaotic beings hostile. + if (you.religion == GOD_ZIN && mi->wont_attack()) + { + mi->attitude = ATT_HOSTILE; + mi->del_ench(ENCH_CHARM, true); + behaviour_event(*mi, ME_ALERT, MHITYOU); + // For now CREATED_FRIENDLY/WAS_NEUTRAL stays. - success = true; - } + success = true; } } - return (success); } @@ -277,30 +270,28 @@ static bool _spellcasters_on_level_attitude_change() { bool success = false; - for (int i = 0; i < MAX_MONSTERS; ++i) + for (monster_iterator mi; mi; ++mi) { - monsters *monster = &menv[i]; - if (monster->alive() - && monster->is_actual_spellcaster()) - { + if (!mi->is_actual_spellcaster()) + continue; + #ifdef DEBUG_DIAGNOSTICS - mprf(MSGCH_DIAGNOSTICS, "Spellcaster attitude changing: %s on level %d, branch %d", - monster->name(DESC_PLAIN).c_str(), - static_cast(you.your_level), - static_cast(you.where_are_you)); + mprf(MSGCH_DIAGNOSTICS, "Spellcaster attitude changing: %s on level %d, branch %d", + mi->name(DESC_PLAIN).c_str(), + static_cast(you.your_level), + static_cast(you.where_are_you)); #endif - // If you worship Trog, you make all friendly and good neutral - // magic users hostile. - if (you.religion == GOD_TROG && monster->wont_attack()) - { - monster->attitude = ATT_HOSTILE; - monster->del_ench(ENCH_CHARM, true); - behaviour_event(monster, ME_ALERT, MHITYOU); - // For now CREATED_FRIENDLY/WAS_NEUTRAL stays. + // If you worship Trog, you make all friendly and good neutral + // magic users hostile. + if (you.religion == GOD_TROG && mi->wont_attack()) + { + mi->attitude = ATT_HOSTILE; + mi->del_ench(ENCH_CHARM, true); + behaviour_event(*mi, ME_ALERT, MHITYOU); + // For now CREATED_FRIENDLY/WAS_NEUTRAL stays. - success = true; - } + success = true; } } @@ -322,18 +313,17 @@ static bool _make_god_gifts_on_level_disappear(bool seen = false) : GOD_NO_GOD; int count = 0; - for (int i = 0; i < MAX_MONSTERS; ++i) + for (monster_iterator mi; mi; ++mi) { - monsters *monster = &menv[i]; - if (is_follower(monster) - && monster->has_ench(ENCH_ABJ) - && mons_is_god_gift(monster, god)) + if (is_follower(*mi) + && mi->has_ench(ENCH_ABJ) + && mons_is_god_gift(*mi, god)) { - if (!seen || simple_monster_message(monster, " abandons you!")) + if (!seen || simple_monster_message(*mi, " abandons you!")) count++; // The monster disappears. - monster_die(monster, KILL_DISMISSED, NON_MONSTER); + monster_die(*mi, KILL_DISMISSED, NON_MONSTER); } } @@ -366,18 +356,17 @@ static bool _make_holy_god_gifts_on_level_good_neutral(bool seen = false) : GOD_NO_GOD; int count = 0; - for (int i = 0; i < MAX_MONSTERS; ++i) + for (monster_iterator mi; mi; ++mi) { - monsters *monster = &menv[i]; - if (is_follower(monster) - && !monster->has_ench(ENCH_CHARM) - && monster->is_holy() - && mons_is_god_gift(monster, god)) + if (is_follower(*mi) + && !mi->has_ench(ENCH_CHARM) + && mi->is_holy() + && mons_is_god_gift(*mi, god)) { // monster changes attitude - monster->attitude = ATT_GOOD_NEUTRAL; + mi->attitude = ATT_GOOD_NEUTRAL; - if (!seen || simple_monster_message(monster, " becomes indifferent.")) + if (!seen || simple_monster_message(*mi, " becomes indifferent.")) count++; } } @@ -412,18 +401,17 @@ static bool _make_god_gifts_on_level_hostile(bool seen = false) : GOD_NO_GOD; int count = 0; - for (int i = 0; i < MAX_MONSTERS; ++i) + for (monster_iterator mi; mi; ++mi) { - monsters *monster = &menv[i]; - if (is_follower(monster) - && mons_is_god_gift(monster, god)) + if (is_follower(*mi) + && mons_is_god_gift(*mi, god)) { // monster changes attitude and behaviour - monster->attitude = ATT_HOSTILE; - monster->del_ench(ENCH_CHARM, true); - behaviour_event(monster, ME_ALERT, MHITYOU); + mi->attitude = ATT_HOSTILE; + mi->del_ench(ENCH_CHARM, true); + behaviour_event(*mi, ME_ALERT, MHITYOU); - if (!seen || simple_monster_message(monster, " turns against you!")) + if (!seen || simple_monster_message(*mi, " turns against you!")) count++; } } @@ -457,33 +445,32 @@ static bool _yred_slaves_on_level_abandon_you() { bool success = false; - for (int i = 0; i < MAX_MONSTERS; ++i) + for (monster_iterator mi; mi; ++mi) { - monsters *monster = &menv[i]; - if (_is_yred_enslaved_body_and_soul(monster)) + if (_is_yred_enslaved_body_and_soul(*mi)) { #ifdef DEBUG_DIAGNOSTICS mprf(MSGCH_DIAGNOSTICS, "Undead soul abandoning: %s on level %d, branch %d", - monster->name(DESC_PLAIN).c_str(), + mi->name(DESC_PLAIN).c_str(), static_cast(you.your_level), static_cast(you.where_are_you)); #endif - yred_make_enslaved_soul(monster, true, true, true); + yred_make_enslaved_soul(*mi, true, true, true); success = true; } - else if (is_yred_undead_slave(monster)) + else if (is_yred_undead_slave(*mi)) { #ifdef DEBUG_DIAGNOSTICS mprf(MSGCH_DIAGNOSTICS, "Undead abandoning: %s on level %d, branch %d", - monster->name(DESC_PLAIN).c_str(), + mi->name(DESC_PLAIN).c_str(), static_cast(you.your_level), static_cast(you.where_are_you)); #endif - monster->attitude = ATT_HOSTILE; - behaviour_event(monster, ME_ALERT, MHITYOU); + mi->attitude = ATT_HOSTILE; + behaviour_event(*mi, ME_ALERT, MHITYOU); // For now CREATED_FRIENDLY stays. success = true; @@ -499,20 +486,19 @@ static bool _beogh_followers_on_level_abandon_you() // Note that orc high priests' summons are gifts of Beogh, so we // can't use is_orcish_follower() here. - for (int i = 0; i < MAX_MONSTERS; ++i) + for (monster_iterator mi; mi; ++mi) { - monsters *monster = &menv[i]; - if (mons_is_god_gift(monster, GOD_BEOGH)) + if (mons_is_god_gift(*mi, GOD_BEOGH)) { #ifdef DEBUG_DIAGNOSTICS mprf(MSGCH_DIAGNOSTICS, "Orc abandoning: %s on level %d, branch %d", - monster->name(DESC_PLAIN).c_str(), + mi->name(DESC_PLAIN).c_str(), static_cast(you.your_level), static_cast(you.where_are_you)); #endif - monster->attitude = ATT_HOSTILE; - behaviour_event(monster, ME_ALERT, MHITYOU); + mi->attitude = ATT_HOSTILE; + behaviour_event(*mi, ME_ALERT, MHITYOU); // For now CREATED_FRIENDLY stays. success = true; @@ -526,20 +512,19 @@ static bool _jiyva_slimes_on_level_abandon_you() { bool success = false; - for (int i = 0; i < MAX_MONSTERS; ++i) + for (monster_iterator mi; mi; ++mi) { - monsters *monster = &menv[i]; - if (is_fellow_slime(monster)) + if (is_fellow_slime(*mi)) { #ifdef DEBUG_DIAGNOSTICS mprf(MSGCH_DIAGNOSTICS, "Slime abandoning: %s on level %d, branch %d", - monster->name(DESC_PLAIN).c_str(), + mi->name(DESC_PLAIN).c_str(), static_cast(you.your_level), static_cast(you.where_are_you)); #endif - monster->attitude = ATT_HOSTILE; - behaviour_event(monster, ME_ALERT, MHITYOU); + mi->attitude = ATT_HOSTILE; + behaviour_event(*mi, ME_ALERT, MHITYOU); // For now WAS_NEUTRAL stays. success = true; @@ -625,27 +610,25 @@ bool yred_slaves_abandon_you() static bool _fedhas_plants_on_level_hostile() { - for (int i = 0; i < MAX_MONSTERS; ++i) + for (monster_iterator mi; mi; ++mi) { - monsters *monster = &menv[i]; - if (monster->alive() - && mons_is_plant(monster)) + if (mons_is_plant(*mi)) { #ifdef DEBUG_DIAGNOSTICS mprf(MSGCH_DIAGNOSTICS, "Plant hostility: %s on level %d, branch %d", - monster->name(DESC_PLAIN).c_str(), + mi->name(DESC_PLAIN).c_str(), static_cast(you.your_level), static_cast(you.where_are_you)); #endif // You can potentially turn an oklob or whatever neutral // again by going back to Fedhas. - if (testbits(monster->flags, MF_ATT_CHANGE_ATTEMPT)) - monster->flags &= ~MF_ATT_CHANGE_ATTEMPT; + if (testbits(mi->flags, MF_ATT_CHANGE_ATTEMPT)) + mi->flags &= ~MF_ATT_CHANGE_ATTEMPT; - monster->attitude = ATT_HOSTILE; - monster->del_ench(ENCH_CHARM, true); - behaviour_event(monster, ME_ALERT, MHITYOU); + mi->attitude = ATT_HOSTILE; + mi->del_ench(ENCH_CHARM, true); + behaviour_event(*mi, ME_ALERT, MHITYOU); // For now WAS_NEUTRAL stays. } } diff --git a/crawl-ref/source/beam.cc b/crawl-ref/source/beam.cc index 8a10cc4531..8203461539 100644 --- a/crawl-ref/source/beam.cc +++ b/crawl-ref/source/beam.cc @@ -45,6 +45,7 @@ #include "message.h" #include "misc.h" #include "mon-behv.h" +#include "mon-iter.h" #include "monplace.h" #include "monstuff.h" #include "mon-util.h" @@ -2610,26 +2611,18 @@ bool mass_enchantment( enchant_type wh_enchant, int pow, int origin, const kill_category kc = (origin == MHITYOU ? KC_YOU : KC_OTHER); - for (int i = 0; i < MAX_MONSTERS; ++i) + for (monster_iterator mi(&you.get_los()); mi; ++mi) { - monsters* const monster = &menv[i]; - - if (!monster->alive()) - continue; - - if (!mons_near(monster)) - continue; - - if (monster->has_ench(wh_enchant)) + if (mi->has_ench(wh_enchant)) continue; if (m_attempted) ++*m_attempted; - if (_monster_resists_mass_enchantment(monster, wh_enchant, pow)) + if (_monster_resists_mass_enchantment(*mi, wh_enchant, pow)) continue; - if (monster->add_ench(mon_enchant(wh_enchant, 0, kc))) + if (mi->add_ench(mon_enchant(wh_enchant, 0, kc))) { if (m_succumbed) ++*m_succumbed; @@ -2644,11 +2637,11 @@ bool mass_enchantment( enchant_type wh_enchant, int pow, int origin, default: msg = NULL; break; } if (msg) - msg_generated = simple_monster_message(monster, msg); + msg_generated = simple_monster_message(*mi, msg); // Extra check for fear (monster needs to reevaluate behaviour). if (wh_enchant == ENCH_FEAR) - behaviour_event(monster, ME_SCARE, origin); + behaviour_event(*mi, ME_SCARE, origin); } } diff --git a/crawl-ref/source/decks.cc b/crawl-ref/source/decks.cc index e82ba90e70..cdd4626e99 100644 --- a/crawl-ref/source/decks.cc +++ b/crawl-ref/source/decks.cc @@ -31,6 +31,7 @@ #include "maps.h" #include "message.h" #include "misc.h" +#include "mon-iter.h" #include "monplace.h" #include "monstuff.h" #include "mutation.h" @@ -2513,16 +2514,13 @@ static void _crusade_card(int power, deck_rarity_type rarity) if (power_level >= 1) { // A chance to convert opponents. - for (int i = 0; i < MAX_MONSTERS; ++i) + for (monster_iterator mi(&you.get_los()); mi; ++mi) { - monsters* const monster = &menv[i]; - if (!monster->alive() - || !mons_near(monster) - || monster->friendly() - || monster->holiness() != MH_NATURAL - || mons_is_unique(monster->type) - || mons_immune_magic(monster) - || player_will_anger_monster(monster)) + if (mi->friendly() + || mi->holiness() != MH_NATURAL + || mons_is_unique(mi->type) + || mons_immune_magic(*mi) + || player_will_anger_monster(*mi)) { continue; } @@ -2531,35 +2529,35 @@ static void _crusade_card(int power, deck_rarity_type rarity) // (though not immunity) check. Specifically, // you can convert Killer Klowns this way. // Might be too good. - if (monster->hit_dice * 35 < random2(power)) + if (mi->hit_dice * 35 < random2(power)) { - simple_monster_message(monster, " is converted."); + simple_monster_message(*mi, " is converted."); if (one_chance_in(5 - power_level)) { - monster->attitude = ATT_FRIENDLY; + mi->attitude = ATT_FRIENDLY; // If you worship a god that lets you recruit // permanent followers, or a god allied with one, // count this as a recruitment. if (is_good_god(you.religion) || you.religion == GOD_BEOGH - && mons_species(monster->type) == MONS_ORC - && !monster->is_summoned() - && !monster->is_shapeshifter()) + && mons_species(mi->type) == MONS_ORC + && !mi->is_summoned() + && !mi->is_shapeshifter()) { // Prevent assertion if the monster was // previously worshipping a different god, // rather than already worshipping your god or // being an atheist. - monster->god = GOD_NO_GOD; + mi->god = GOD_NO_GOD; - mons_make_god_gift(monster, is_good_god(you.religion) ? + mons_make_god_gift(*mi, is_good_god(you.religion) ? GOD_SHINING_ONE : GOD_BEOGH); } } else - monster->add_ench(ENCH_CHARM); + mi->add_ench(ENCH_CHARM); } } } diff --git a/crawl-ref/source/effects.cc b/crawl-ref/source/effects.cc index 195aaa9792..a9eb9ceee6 100644 --- a/crawl-ref/source/effects.cc +++ b/crawl-ref/source/effects.cc @@ -43,6 +43,7 @@ #include "misc.h" #include "mon-behv.h" #include "mon-cast.h" +#include "mon-iter.h" #include "monplace.h" #include "monstuff.h" #include "mon-util.h" @@ -2449,44 +2450,35 @@ bool recharge_wand(int item_slot) return (false); } +// Berserking monsters cannot be ordered around. +static bool _follows_orders(monsters* mon) +{ + return (mon->friendly() && mon->type != MONS_GIANT_SPORE + && !mon->berserk()); +} + // Sets foe target of friendly monsters. // If allow_patrol is true, patrolling monsters get MHITNOT instead. static void _set_friendly_foes(bool allow_patrol = false) { - for (int i = 0; i < MAX_MONSTERS; ++i) + for (monster_iterator mi(&you.get_los()); mi; ++mi) { - monsters *mon(&menv[i]); - if (!mon->alive() || !mons_near(mon) || !mon->friendly() - || mon->type == MONS_GIANT_SPORE) - { + if (!_follows_orders(*mi)) continue; - } - - // Berserking monsters cannot be ordered around. - if (mon->berserk()) - continue; - - mon->foe = (allow_patrol && mon->is_patrolling() ? MHITNOT + mi->foe = (allow_patrol && mi->is_patrolling() ? MHITNOT : you.pet_target); } } static void _set_allies_patrol_point(bool clear = false) { - for (int i = 0; i < MAX_MONSTERS; ++i) + for (monster_iterator mi(&you.get_los()); mi; ++mi) { - monsters *mon(&menv[i]); - if (!mon->alive() || !mons_near(mon) || !mon->friendly()) + if (!_follows_orders(*mi)) continue; - - // Berserking monsters cannot be ordered around. - if (mon->berserk() || mon->type == MONS_GIANT_SPORE) - continue; - - mon->patrol_point = (clear ? coord_def(0, 0) : mon->pos()); - + mi->patrol_point = (clear ? coord_def(0, 0) : mi->pos()); if (!clear) - mon->behaviour = BEH_WANDER; + mi->behaviour = BEH_WANDER; } } @@ -4166,57 +4158,52 @@ void update_level(double elapsedTime) dungeon_events.fire_event( dgn_event(DET_TURN_ELAPSED, coord_def(0, 0), turns * 10)); - for (int m = 0; m < MAX_MONSTERS; m++) + for (monster_iterator mi; mi; ++mi) { - monsters *mon = &menv[m]; - - if (!mon->alive()) - continue; - #if DEBUG_DIAGNOSTICS mons_total++; #endif // Pacified monsters often leave the level now. - if (mon->pacified() && turns > random2(40) + 21) + if (mi->pacified() && turns > random2(40) + 21) { - make_mons_leave_level(mon); + make_mons_leave_level(*mi); continue; } // Following monsters don't get movement. - if (mon->flags & MF_JUST_SUMMONED) + if (mi->flags & MF_JUST_SUMMONED) continue; // XXX: Allow some spellcasting (like Healing and Teleport)? - bwr - // const bool healthy = (mon->hit_points * 2 > mon->max_hit_points); + // const bool healthy = (mi->hit_points * 2 > mi->max_hit_points); // This is the monster healing code, moved here from tag.cc: - if (mons_can_regenerate(mon)) + if (mons_can_regenerate(*mi)) { - if (monster_descriptor(mon->type, MDSC_REGENERATES) - || mon->type == MONS_PLAYER_GHOST) + if (monster_descriptor(mi->type, MDSC_REGENERATES) + || mi->type == MONS_PLAYER_GHOST) { - mon->heal(turns); + mi->heal(turns); } else { // Set a lower ceiling of 0.1 on the regen rate. const int regen_rate = - std::max(mons_natural_regen_rate(mon) * 2, 5); + std::max(mons_natural_regen_rate(*mi) * 2, 5); - mon->heal(div_rand_round(turns * regen_rate, 50)); + mi->heal(div_rand_round(turns * regen_rate, 50)); } } // Handle nets specially to remove the trapping property of the net. - if (mon->caught()) - mon->del_ench(ENCH_HELD, true); + if (mi->caught()) + mi->del_ench(ENCH_HELD, true); - _catchup_monster_moves(mon, turns); + _catchup_monster_moves(*mi, turns); - if (turns >= 10 && mon->alive()) - mon->timeout_enchantments(turns / 10); + if (turns >= 10 && mi->alive()) + mi->timeout_enchantments(turns / 10); } #if DEBUG_DIAGNOSTICS diff --git a/crawl-ref/source/ghost.cc b/crawl-ref/source/ghost.cc index 901a4b92d4..1886b65f8b 100644 --- a/crawl-ref/source/ghost.cc +++ b/crawl-ref/source/ghost.cc @@ -16,6 +16,7 @@ #include "externs.h" #include "itemname.h" #include "itemprop.h" +#include "mon-iter.h" #include "ng-input.h" #include "random.h" #include "skills2.h" @@ -846,16 +847,13 @@ void ghost_demon::announce_ghost(const ghost_demon &g) void ghost_demon::find_extra_ghosts( std::vector &gs, int n ) { - for (int i = 0; n > 0 && i < MAX_MONSTERS; ++i) + for (monster_iterator mi; mi; ++mi) { - if (!menv[i].alive()) - continue; - - if (menv[i].type == MONS_PLAYER_GHOST && menv[i].ghost.get()) + if (mi->type == MONS_PLAYER_GHOST && mi->ghost.get()) { // Bingo! - announce_ghost(*menv[i].ghost); - gs.push_back(*menv[i].ghost); + announce_ghost(*(mi->ghost)); + gs.push_back(*(mi->ghost)); --n; } } diff --git a/crawl-ref/source/godabil.cc b/crawl-ref/source/godabil.cc index a7f4c77484..a017265ad9 100644 --- a/crawl-ref/source/godabil.cc +++ b/crawl-ref/source/godabil.cc @@ -23,6 +23,7 @@ #include "misc.h" #include "mon-act.h" #include "mon-behv.h" +#include "mon-iter.h" #include "monplace.h" #include "monstuff.h" #include "mon-util.h" @@ -203,22 +204,21 @@ static bool _yred_enslaved_souls_on_level_disappear() { bool success = false; - for (int i = 0; i < MAX_MONSTERS; ++i) + for (monster_iterator mi; mi; ++mi) { - monsters *monster = &menv[i]; - if (_is_yred_enslaved_soul(monster)) + if (_is_yred_enslaved_soul(*mi)) { #ifdef DEBUG_DIAGNOSTICS mprf(MSGCH_DIAGNOSTICS, "Undead soul disappearing: %s on level %d, branch %d", - monster->name(DESC_PLAIN).c_str(), + mi->name(DESC_PLAIN).c_str(), static_cast(you.your_level), static_cast(you.where_are_you)); #endif - simple_monster_message(monster, " is freed."); + simple_monster_message(*mi, " is freed."); // The monster disappears. - monster_die(monster, KILL_DISMISSED, NON_MONSTER); + monster_die(*mi, KILL_DISMISSED, NON_MONSTER); success = true; } diff --git a/crawl-ref/source/misc.cc b/crawl-ref/source/misc.cc index 0c4d997d89..d1744552bb 100644 --- a/crawl-ref/source/misc.cc +++ b/crawl-ref/source/misc.cc @@ -56,6 +56,7 @@ #include "mapmark.h" #include "message.h" #include "monplace.h" +#include "mon-iter.h" #include "mon-util.h" #include "monstuff.h" #include "ouch.h" @@ -2968,14 +2969,11 @@ static void monster_threat_values(double *general, double *highest, double sum = 0; int highest_xp = -1; - monsters *monster = NULL; - for (int it = 0; it < MAX_MONSTERS; it++) + for (monster_iterator mi(&you.get_los()); mi; ++mi) { - monster = &menv[it]; - - if (monster->alive() && mons_near(monster) && !monster->friendly()) + if (!mi->friendly()) { - const int xp = exper_value(monster); + const int xp = exper_value(*mi); const double log_xp = log((double)xp); sum += log_xp; if (xp > highest_xp) @@ -2983,7 +2981,7 @@ static void monster_threat_values(double *general, double *highest, highest_xp = xp; *highest = log_xp; } - if (!you.can_see(monster)) + if (!you.can_see(*mi)) *invis = true; } } diff --git a/crawl-ref/source/mon-abil.cc b/crawl-ref/source/mon-abil.cc index 7067112d6e..bfc77357b8 100644 --- a/crawl-ref/source/mon-abil.cc +++ b/crawl-ref/source/mon-abil.cc @@ -24,6 +24,7 @@ #include "mon-act.h" #include "mon-behv.h" #include "mon-cast.h" +#include "mon-iter.h" #include "monplace.h" #include "monspeak.h" #include "monstuff.h" @@ -591,44 +592,41 @@ static bool _orc_battle_cry(monsters *chief) const int boss_index = monster_index(chief); const int level = chief->hit_dice > 12? 2 : 1; std::vector seen_affected; - for (int i = 0; i < MAX_MONSTERS; ++i) + for (monster_iterator mi(chief); mi; ++mi) { - monsters *mon = &menv[i]; - if (mon != chief - && mon->alive() - && mons_species(mon->type) == MONS_ORC - && mons_aligned(boss_index, i) - && mon->hit_dice < chief->hit_dice - && !mon->berserk() - && !mon->has_ench(ENCH_MIGHT) - && !mon->cannot_move() - && !mon->confused() - && chief->can_see(mon)) + if (*mi != chief + && mons_species(mi->type) == MONS_ORC + && mons_aligned(boss_index, mi->mindex()) + && mi->hit_dice < chief->hit_dice + && !mi->berserk() + && !mi->has_ench(ENCH_MIGHT) + && !mi->cannot_move() + && !mi->confused()) { - mon_enchant ench = mon->get_ench(ENCH_BATTLE_FRENZY); + mon_enchant ench = mi->get_ench(ENCH_BATTLE_FRENZY); if (ench.ench == ENCH_NONE || ench.degree < level) { const int dur = - random_range(12, 20) * speed_to_duration(mon->speed); + random_range(12, 20) * speed_to_duration(mi->speed); if (ench.ench != ENCH_NONE) { ench.degree = level; ench.duration = std::max(ench.duration, dur); - mon->update_ench(ench); + mi->update_ench(ench); } else { - mon->add_ench(mon_enchant(ENCH_BATTLE_FRENZY, level, + mi->add_ench(mon_enchant(ENCH_BATTLE_FRENZY, level, KC_OTHER, dur)); } affected++; - if (you.can_see(mon)) - seen_affected.push_back(mon); + if (you.can_see(*mi)) + seen_affected.push_back(*mi); - if (mon->asleep()) - behaviour_event(mon, ME_DISTURB, MHITNOT, chief->pos()); + if (mi->asleep()) + behaviour_event(*mi, ME_DISTURB, MHITNOT, chief->pos()); } } } @@ -729,23 +727,20 @@ static bool _moth_incite_monsters(const monsters *mon) return false; int goaded = 0; - for (int i = 0; i < MAX_MONSTERS; ++i) + circle_def c(mon->pos(), 3, C_SQUARE); + for (monster_iterator mi(&c); mi; ++mi) { - monsters *targ = &menv[i]; - if (targ == mon || !targ->alive() || !targ->needs_berserk()) + if (*mi == mon || !mi->needs_berserk()) continue; - if (mon->pos().distance_from(targ->pos()) > 3) - continue; - - if (is_sanctuary(targ->pos())) + if (is_sanctuary(mi->pos())) continue; // Cannot goad other moths of wrath! - if (targ->type == MONS_MOTH_OF_WRATH) + if (mi->type == MONS_MOTH_OF_WRATH) continue; - if (_make_monster_angry(mon, targ) && !one_chance_in(3 * ++goaded)) + if (_make_monster_angry(mon, *mi) && !one_chance_in(3 * ++goaded)) return (true); } @@ -779,6 +774,7 @@ bool mon_special_ability(monsters *monster, bolt & beem) spell_type spell = SPELL_NO_SPELL; + circle_def c; switch (mclass) { case MONS_UGLY_THING: @@ -832,16 +828,9 @@ bool mon_special_ability(monsters *monster, bolt & beem) break; } - for (int i = 0; i < MAX_MONSTERS; i++) + c = circle_def(monster->pos(), 4, C_CIRCLE); + for (monster_iterator targ(&c); targ; ++targ) { - monsters *targ = &menv[i]; - - if (targ->type == MONS_NO_MONSTER) - continue; - - if (distance(monster->pos(), targ->pos()) >= 5) - continue; - if (mons_atts_aligned(monster->attitude, targ->attitude)) continue; diff --git a/crawl-ref/source/mon-act.cc b/crawl-ref/source/mon-act.cc index e0b9dfbe94..0f17f8c53b 100644 --- a/crawl-ref/source/mon-act.cc +++ b/crawl-ref/source/mon-act.cc @@ -31,6 +31,7 @@ #include "mon-abil.h" #include "mon-behv.h" #include "mon-cast.h" +#include "mon-iter.h" #include "monplace.h" #include "monstuff.h" #include "mutation.h" @@ -2077,20 +2078,18 @@ void handle_monsters() // them to move again. memset(immobile_monster, 0, sizeof immobile_monster); - for (int i = 0; i < MAX_MONSTERS; ++i) + for (monster_iterator mi; mi; ++mi) { - monsters *monster = &menv[i]; - - if (!monster->alive() || immobile_monster[i]) + if (immobile_monster[mi->mindex()]) continue; - const coord_def oldpos = monster->pos(); + const coord_def oldpos = mi->pos(); - monster->update_los(); - _handle_monster_move(monster); + mi->update_los(); + _handle_monster_move(*mi); - if (!invalid_monster(monster) && monster->pos() != oldpos) - immobile_monster[i] = true; + if (!invalid_monster(*mi) && mi->pos() != oldpos) + immobile_monster[mi->mindex()] = true; // If the player got banished, discard pending monster actions. if (you.banished) diff --git a/crawl-ref/source/monstuff.cc b/crawl-ref/source/monstuff.cc index 6c849a2ba6..3e37144226 100644 --- a/crawl-ref/source/monstuff.cc +++ b/crawl-ref/source/monstuff.cc @@ -34,6 +34,7 @@ #include "message.h" #include "misc.h" #include "mon-behv.h" +#include "mon-iter.h" #include "monplace.h" #include "monspeak.h" #include "notes.h" @@ -1269,18 +1270,17 @@ void pikel_band_neutralise () // with MF_BAND_MEMBER are Pikel's band members. bool message_made = false; - for (int i = 0; i < MAX_MONSTERS; ++i) + for (monster_iterator mi; mi; ++mi) { - monsters *monster = &menv[i]; - if (monster->alive() && monster->type == MONS_HUMAN - && testbits(monster->flags, MF_BAND_MEMBER)) + if (mi->type == MONS_HUMAN + && testbits(mi->flags, MF_BAND_MEMBER)) { - if (monster->observable() && !message_made) + if (mi->observable() && !message_made) { mpr("Pikel's slaves thank you for their freedom."); message_made = true; } - mons_pacify(monster); + mons_pacify(*mi); } } } @@ -1296,60 +1296,59 @@ static void _hogs_to_humans() // porkalator spell, they should be handled specially... int any = 0, human = 0; - for (int i = 0; i < MAX_MONSTERS; ++i) + for (monster_iterator mi; mi; ++mi) { - monsters *monster = &menv[i]; - if (monster->alive() && monster->type == MONS_HOG) - { - const bool could_see = you.can_see(monster); + if (!mi->type == MONS_HOG) + continue; - // XXX: This resets the size of slime creatures, the number - // of heads a hydra has, and the number of spikes a manticore - // has. Plus it also changes the colour of a draconian which - // has a sub-type. And it re-rolls the spellbook the monster - // has. - if (monster->number == 0) - monster->type = MONS_HUMAN; - else - monster->type = (monster_type) (monster->number - 1); + const bool could_see = you.can_see(*mi); - monster->number = 0; - define_monster(*monster); + // XXX: This resets the size of slime creatures, the number + // of heads a hydra has, and the number of spikes a manticore + // has. Plus it also changes the colour of a draconian which + // has a sub-type. And it re-rolls the spellbook the monster + // has. + if (mi->number == 0) + mi->type = MONS_HUMAN; + else + mi->type = (monster_type) (mi->number - 1); - const bool can_see = you.can_see(monster); + mi->number = 0; + define_monster(**mi); - // A monster changing factions while in the arena messes up - // arena book-keeping. - if (!crawl_state.arena) + const bool can_see = you.can_see(*mi); + + // A monster changing factions while in the arena messes up + // arena book-keeping. + if (!crawl_state.arena) + { + // * A monster's attitude shouldn't downgrade from friendly + // or good-neutral because you helped it. It'd suck to + // lose a permanent ally that way. + // + // * A monster has to be smart enough to realize that you + // helped it. + if (mi->attitude == ATT_HOSTILE + && mons_intel(*mi) >= I_NORMAL) { - // * A monster's attitude shouldn't downgrade from friendly - // or good-neutral because you helped it. It'd suck to - // lose a permanent ally that way. - // - // * A monster has to be smart enough to realize that you - // helped it. - if (monster->attitude == ATT_HOSTILE - && mons_intel(monster) >= I_NORMAL) - { - monster->attitude = ATT_GOOD_NEUTRAL; - monster->flags |= MF_WAS_NEUTRAL; - } + mi->attitude = ATT_GOOD_NEUTRAL; + mi->flags |= MF_WAS_NEUTRAL; } + } - behaviour_event(monster, ME_EVAL); + behaviour_event(*mi, ME_EVAL); - if (could_see && can_see) - { - any++; - if (monster->type == MONS_HUMAN) - human++; - } - else if (could_see && !can_see) - mpr("The hog vanishes!"); - else if (!could_see && can_see) - mprf("%s appears from out of thin air!", - monster->name(DESC_CAP_A).c_str()); + if (could_see && can_see) + { + any++; + if (mi->type == MONS_HUMAN) + human++; } + else if (could_see && !can_see) + mpr("The hog vanishes!"); + else if (!could_see && can_see) + mprf("%s appears from out of thin air!", + mi->name(DESC_CAP_A).c_str()); } if (any == 1) @@ -1393,14 +1392,13 @@ void mons_relocated(monsters *monster) if (invalid_monster_index(headnum)) return; - for (int i = 0; i < MAX_MONSTERS; ++i) + for (monster_iterator mi; mi; ++mi) { - monsters *tentacle = &menv[i]; - if (tentacle->type == MONS_KRAKEN_TENTACLE - && (int)tentacle->number == headnum - && _tentacle_too_far(monster, tentacle)) + if (mi->type == MONS_KRAKEN_TENTACLE + && (int)mi->number == headnum + && _tentacle_too_far(monster, *mi)) { - monster_die(tentacle, KILL_RESET, -1, true, false); + monster_die(*mi, KILL_RESET, -1, true, false); } } } @@ -1423,15 +1421,14 @@ static int _destroy_tentacles(monsters *head) if (invalid_monster_index(headnum)) return 0; - for (int i = 0; i < MAX_MONSTERS; ++i) + for (monster_iterator mi; mi; ++mi) { - monsters *monster = &menv[i]; - if (monster->type == MONS_KRAKEN_TENTACLE - && (int)monster->number == headnum) + if (mi->type == MONS_KRAKEN_TENTACLE + && (int)mi->number == headnum) { - if (mons_near(monster)) + if (mons_near(*mi)) tent++; - monster->hurt(monster, INSTANT_DEATH); + mi->hurt(*mi, INSTANT_DEATH); } } return tent; @@ -2199,9 +2196,9 @@ void monster_cleanup(monsters *monster) unsigned int monster_killed = monster_index(monster); monster->reset(); - for (int dmi = 0; dmi < MAX_MONSTERS; dmi++) - if (menv[dmi].foe == monster_killed) - menv[dmi].foe = MHITNOT; + for (monster_iterator mi; mi; ++mi) + if (mi->foe == monster_killed) + mi->foe = MHITNOT; if (you.pet_target == monster_killed) you.pet_target = MHITNOT; @@ -2210,24 +2207,14 @@ void monster_cleanup(monsters *monster) // If you're invis and throw/zap whatever, alerts menv to your position. void alert_nearby_monsters(void) { - monsters *monster = 0; // NULL {dlb} - - for (int it = 0; it < MAX_MONSTERS; it++) - { - monster = &menv[it]; - - // Judging from the above comment, this function isn't - // intended to wake up monsters, so we're only going to - // alert monsters that aren't sleeping. For cases where an - // event should wake up monsters and alert them, I'd suggest - // calling noisy() before calling this function. -- bwr - if (monster->alive() - && mons_near(monster) - && !monster->asleep()) - { - behaviour_event(monster, ME_ALERT, MHITYOU); - } - } + // Judging from the above comment, this function isn't + // intended to wake up monsters, so we're only going to + // alert monsters that aren't sleeping. For cases where an + // event should wake up monsters and alert them, I'd suggest + // calling noisy() before calling this function. -- bwr + for (monster_iterator mi(&you.get_los()); mi; ++mi) + if (!mi->asleep()) + behaviour_event(*mi, ME_ALERT, MHITYOU); } static bool _valid_morph(monsters *monster, monster_type new_mclass) @@ -3620,15 +3607,14 @@ int dismiss_monsters(std::string pattern) { // Dismiss by regex text_pattern tpat(pattern); int ndismissed = 0; - for (int mon = 0; mon < MAX_MONSTERS; mon++) + for (monster_iterator mi; mi; ++mi) { - monsters *monster = &menv[mon]; - if (monster->alive() && - (tpat.empty() || tpat.matches(monster->name(DESC_PLAIN, true)))) + if (mi->alive() && + (tpat.empty() || tpat.matches(mi->name(DESC_PLAIN, true)))) { if (!keep_item) - _vanish_orig_eq(monster); - monster_die(monster, KILL_DISMISSED, NON_MONSTER, false, true); + _vanish_orig_eq(*mi); + monster_die(*mi, KILL_DISMISSED, NON_MONSTER, false, true); ++ndismissed; } } diff --git a/crawl-ref/source/spells3.cc b/crawl-ref/source/spells3.cc index 97b2cb04d0..edca2202c5 100644 --- a/crawl-ref/source/spells3.cc +++ b/crawl-ref/source/spells3.cc @@ -35,6 +35,7 @@ #include "message.h" #include "misc.h" #include "mon-behv.h" +#include "mon-iter.h" #include "monplace.h" #include "monstuff.h" #include "mon-util.h" @@ -1767,12 +1768,8 @@ bool remove_sanctuary(bool did_attack) // Now that the sanctuary is gone, monsters aren't afraid of it // anymore. - for (int i = 0; i < MAX_MONSTERS; ++i) - { - monsters *mon = &menv[i]; - if (mon->alive()) - mons_stop_fleeing_from_sanctuary(mon); - } + for (monster_iterator mi; mi; ++mi) + mons_stop_fleeing_from_sanctuary(*mi); if (is_resting()) stop_running(); diff --git a/crawl-ref/source/view.cc b/crawl-ref/source/view.cc index c0a55da171..3ee1f5e6bb 100644 --- a/crawl-ref/source/view.cc +++ b/crawl-ref/source/view.cc @@ -48,6 +48,7 @@ #include "message.h" #include "misc.h" #include "mon-behv.h" +#include "mon-iter.h" #include "monplace.h" #include "monstuff.h" #include "mon-util.h" @@ -122,34 +123,31 @@ void flush_comes_into_view() void monster_grid_updates() { - for (int s = 0; s < MAX_MONSTERS; ++s) + for (monster_iterator mi(&you.get_los()); mi; ++mi) { - monsters *monster = &menv[s]; - - if (monster->alive() && mons_near(monster)) + if ((mi->asleep() || mons_is_wandering(*mi)) + && check_awaken(*mi)) { - if ((monster->asleep() || mons_is_wandering(monster)) - && check_awaken(monster)) - { - behaviour_event(monster, ME_ALERT, MHITYOU, you.pos(), false); - handle_monster_shouts(monster); - } + behaviour_event(*mi, ME_ALERT, MHITYOU, you.pos(), false); + handle_monster_shouts(*mi); + } - if (!monster->visible_to(&you)) - continue; + if (!mi->visible_to(&you)) + continue; - good_god_follower_attitude_change(monster); - beogh_follower_convert(monster); - slime_convert(monster); - fedhas_neutralise(monster); - } + good_god_follower_attitude_change(*mi); + beogh_follower_convert(*mi); + slime_convert(*mi); + fedhas_neutralise(*mi); } } -static void _check_monster_pos(const monsters* monster, int s) +static void _check_monster_pos(const monsters* monster) { + int s = monster->mindex(); ASSERT(mgrd(monster->pos()) == s); + // [rob] The following in case asserts aren't enabled. // [enne] - It's possible that mgrd and monster->x/y are out of // sync because they are updated separately. If we can see this // monster, then make sure that the mgrd is set correctly. @@ -169,20 +167,15 @@ static void _check_monster_pos(const monsters* monster, int s) void monster_grid() { - for (int s = 0; s < MAX_MONSTERS; ++s) + for (monster_iterator mi(&you.get_los()); mi; ++mi) { - monsters *monster = &menv[s]; - - if (monster->alive() && mons_near(monster)) - { - _check_monster_pos(monster, s); - env.show.update_monster(monster); + _check_monster_pos(*mi); + env.show.update_monster(*mi); #ifdef USE_TILE - if (monster->visible_to(&you)) - tile_place_monster(monster->pos().x, monster->pos().y, s, true); + if (mi->visible_to(&you)) + tile_place_monster(mi->pos().x, mi->pos().y, s, true); #endif - } } } @@ -190,39 +183,34 @@ void update_monsters_in_view() { unsigned int num_hostile = 0; - for (int s = 0; s < MAX_MONSTERS; s++) + for (monster_iterator mi; mi; ++mi) { - monsters *monster = &menv[s]; - - if (!monster->alive()) - continue; - - if (mons_near(monster)) + if (mons_near(*mi)) { - if (monster->attitude == ATT_HOSTILE) + if (mi->attitude == ATT_HOSTILE) num_hostile++; - if (mons_is_unknown_mimic(monster)) + if (mons_is_unknown_mimic(*mi)) { // For unknown mimics, don't mark as seen, // but do mark it as in view for later messaging. // FIXME: is this correct? - monster->flags |= MF_WAS_IN_VIEW; + mi->flags |= MF_WAS_IN_VIEW; } - else if (monster->visible_to(&you)) + else if (mi->visible_to(&you)) { - handle_seen_interrupt(monster); - seen_monster(monster); + handle_seen_interrupt(*mi); + seen_monster(*mi); } else - monster->flags &= ~MF_WAS_IN_VIEW; + mi->flags &= ~MF_WAS_IN_VIEW; } else - monster->flags &= ~MF_WAS_IN_VIEW; + mi->flags &= ~MF_WAS_IN_VIEW; // If the monster hasn't been seen by the time that the player // gets control back then seen_context is out of date. - monster->seen_context.clear(); + mi->seen_context.clear(); } // Xom thinks it's hilarious the way the player picks up an ever diff --git a/crawl-ref/source/wiz-mon.cc b/crawl-ref/source/wiz-mon.cc index eaccf8346e..7817b29e2d 100644 --- a/crawl-ref/source/wiz-mon.cc +++ b/crawl-ref/source/wiz-mon.cc @@ -23,6 +23,7 @@ #include "monplace.h" #include "monspeak.h" #include "monstuff.h" +#include "mon-iter.h" #include "mon-util.h" #include "output.h" #include "religion.h" @@ -253,13 +254,9 @@ void debug_list_monsters() std::string prev_name = ""; int count = 0; - for (int i = 0; i < MAX_MONSTERS; ++i) + for (monster_iterator mi; mi; ++mi) { - const monsters *m = &menv[mon_nums[i]]; - if (!m->alive()) - continue; - - std::string name = m->name(DESC_PLAIN, true); + std::string name = mi->name(DESC_PLAIN, true); if (prev_name != name && count > 0) { @@ -276,15 +273,15 @@ void debug_list_monsters() count++; prev_name = name; - int exp = exper_value(m); + int exp = exper_value(*mi); total_exp += exp; - if ((m->flags & (MF_WAS_NEUTRAL | MF_CREATED_FRIENDLY)) - || m->has_ench(ENCH_ABJ)) + if ((mi->flags & (MF_WAS_NEUTRAL | MF_CREATED_FRIENDLY)) + || mi->has_ench(ENCH_ABJ)) { continue; } - if (m->flags & MF_GOT_HALF_XP) + if (mi->flags & MF_GOT_HALF_XP) exp /= 2; total_adj_exp += exp; @@ -338,9 +335,8 @@ void wizard_spawn_control() { // 50 spots are reserved for non-wandering monsters. int max_spawn = MAX_MONSTERS - 50; - for (int i = 0; i < MAX_MONSTERS; ++i) - if (menv[i].alive()) - max_spawn--; + for (monster_iterator mi; mi; ++mi) + if (mi->alive()) if (max_spawn <= 0) { diff --git a/crawl-ref/source/xom.cc b/crawl-ref/source/xom.cc index 91d006d747..34f8392ee6 100644 --- a/crawl-ref/source/xom.cc +++ b/crawl-ref/source/xom.cc @@ -26,6 +26,7 @@ #include "message.h" #include "misc.h" #include "mon-behv.h" +#include "mon-iter.h" #include "mon-util.h" #include "monplace.h" #include "monstuff.h" @@ -1197,14 +1198,10 @@ static int _xom_do_potion(bool debug = false) static int _xom_confuse_monsters(int sever, bool debug = false) { bool rc = false; - monsters *monster; - for (unsigned i = 0; i < MAX_MONSTERS; ++i) + for (monster_iterator mi(&you.get_los()); mi; ++mi) { - monster = &menv[i]; - - if (monster->type == MONS_NO_MONSTER || !mons_near(monster) - || monster->wont_attack() - || !mons_class_is_confusable(monster->type) + if (mi->wont_attack() + || !mons_class_is_confusable(mi->type) || one_chance_in(20)) { continue; @@ -1213,14 +1210,14 @@ static int _xom_confuse_monsters(int sever, bool debug = false) if (debug) return (XOM_GOOD_CONFUSION); - if (monster->add_ench(mon_enchant(ENCH_CONFUSION, 0, + if (mi->add_ench(mon_enchant(ENCH_CONFUSION, 0, KC_FRIENDLY, random2(sever)))) { // Only give this message once. if (!rc) god_speaks(GOD_XOM, _get_xom_speech("confusion").c_str()); - simple_monster_message(monster, " looks rather confused."); + simple_monster_message(*mi, " looks rather confused."); rc = true; } } @@ -1541,24 +1538,16 @@ static int _xom_swap_weapons(bool debug = false) } std::vector mons_wpn; - for (unsigned i = 0; i < MAX_MONSTERS; ++i) + for (monster_iterator mi(&you); mi; ++mi) { - monsters* m = &menv[i]; - - if (!m->alive()) - continue; - - if (!you.see_cell(m->pos())) - continue; - - if (!wpn || m->wont_attack() || m->is_summoned() - || mons_itemuse(m) < MONUSE_STARTING_EQUIPMENT - || (m->flags & MF_HARD_RESET)) + if (!wpn || mi->wont_attack() || mi->is_summoned() + || mons_itemuse(*mi) < MONUSE_STARTING_EQUIPMENT + || (mi->flags & MF_HARD_RESET)) { continue; } - const int mweap = m->inv[MSLOT_WEAPON]; + const int mweap = mi->inv[MSLOT_WEAPON]; if (mweap == NON_ITEM) continue; @@ -1567,11 +1556,11 @@ static int _xom_swap_weapons(bool debug = false) // Let's be nice about this. if (weapon.base_type == OBJ_WEAPONS && !(weapon.flags & ISFLAG_SUMMONED) - && you.can_wield(weapon, true) && m->can_wield(*wpn, true) + && you.can_wield(weapon, true) && mi->can_wield(*wpn, true) && !get_weapon_brand(weapon) != SPWPN_DISTORTION && (!is_artefact(weapon) || _art_is_safe(weapon))) { - mons_wpn.push_back(m); + mons_wpn.push_back(*mi); } } if (mons_wpn.empty()) @@ -1677,18 +1666,9 @@ static int _xom_rearrange_pieces(int sever, bool debug = false) return (XOM_DID_NOTHING); std::vector mons; - for (unsigned i = 0; i < MAX_MONSTERS; ++i) - { - monsters* m = &menv[i]; - - if (!m->alive()) - continue; + for (monster_iterator mi(&you); mi; ++mi) + mons.push_back(*mi); - if (!you.see_cell(m->pos())) - continue; - - mons.push_back(m); - } if (mons.empty()) return (XOM_DID_NOTHING); @@ -1741,24 +1721,16 @@ static int _xom_rearrange_pieces(int sever, bool debug = false) static int _xom_animate_monster_weapon(int sever, bool debug = false) { std::vector mons_wpn; - for (unsigned i = 0; i < MAX_MONSTERS; ++i) + for (monster_iterator mi(&you); mi; ++mi) { - monsters* m = &menv[i]; - - if (!m->alive()) - continue; - - if (!you.see_cell(m->pos())) - continue; - - if (m->wont_attack() || m->is_summoned() - || mons_itemuse(m) < MONUSE_STARTING_EQUIPMENT - || (m->flags & MF_HARD_RESET)) + if (mi->wont_attack() || mi->is_summoned() + || mons_itemuse(*mi) < MONUSE_STARTING_EQUIPMENT + || (mi->flags & MF_HARD_RESET)) { continue; } - const int mweap = m->inv[MSLOT_WEAPON]; + const int mweap = mi->inv[MSLOT_WEAPON]; if (mweap == NON_ITEM) continue; @@ -1771,7 +1743,7 @@ static int _xom_animate_monster_weapon(int sever, bool debug = false) && !is_special_unrandom_artefact(weapon) && !get_weapon_brand(weapon) != SPWPN_DISTORTION) { - mons_wpn.push_back(m); + mons_wpn.push_back(*mi); } } if (mons_wpn.empty()) @@ -2846,22 +2818,18 @@ static int _xom_player_confusion_effect(int sever, bool debug = false) bool mons_too = false; if (coinflip()) { - for (unsigned i = 0; i < MAX_MONSTERS; ++i) + for (monster_iterator mi(&you.get_los()); mi; ++mi) { - monsters* const monster = &menv[i]; - - if (!monster->alive() - || !mons_near(monster) - || !mons_class_is_confusable(monster->type) + if (!mons_class_is_confusable(mi->type) || one_chance_in(20)) { continue; } - if (monster->add_ench(mon_enchant(ENCH_CONFUSION, 0, + if (mi->add_ench(mon_enchant(ENCH_CONFUSION, 0, KC_FRIENDLY, random2(sever)))) { - simple_monster_message(monster, + simple_monster_message(*mi, " looks rather confused."); } mons_too = true; -- cgit v1.2.3-54-g00ecf