diff options
Diffstat (limited to 'crawl-ref/source')
-rw-r--r-- | crawl-ref/source/debug.cc | 2 | ||||
-rw-r--r-- | crawl-ref/source/makeitem.cc | 2 | ||||
-rw-r--r-- | crawl-ref/source/mon-data.h | 14 | ||||
-rw-r--r-- | crawl-ref/source/mon-util.cc | 141 | ||||
-rw-r--r-- | crawl-ref/source/monstuff.cc | 33 | ||||
-rw-r--r-- | crawl-ref/source/religion.cc | 7 | ||||
-rw-r--r-- | crawl-ref/source/view.cc | 8 | ||||
-rw-r--r-- | crawl-ref/source/view.h | 2 |
8 files changed, 147 insertions, 62 deletions
diff --git a/crawl-ref/source/debug.cc b/crawl-ref/source/debug.cc index f70889b35e..6b65e9bce1 100644 --- a/crawl-ref/source/debug.cc +++ b/crawl-ref/source/debug.cc @@ -3654,7 +3654,7 @@ void wizard_give_monster_item(monsters *mon) return; } - // Shouldn't be be using MONUSE_MAGIC_ITEMS? + // Shouldn't we be using MONUSE_MAGIC_ITEMS? if (item_use == MONUSE_STARTING_EQUIPMENT && !mons_is_unique( mon->type )) { diff --git a/crawl-ref/source/makeitem.cc b/crawl-ref/source/makeitem.cc index 3093e091e3..096eac8612 100644 --- a/crawl-ref/source/makeitem.cc +++ b/crawl-ref/source/makeitem.cc @@ -3960,7 +3960,7 @@ void give_armour(monsters *mon, int level) if ( one_chance_in( mon->type == MONS_NAGA ? 800 : mon->type == MONS_NAGA_WARRIOR ? 300 : mon->type == MONS_NAGA_MAGE ? 200 - : 100)) + : 100 )) { mitm[bp].base_type = OBJ_ARMOUR; mitm[bp].sub_type = ARM_NAGA_BARDING; diff --git a/crawl-ref/source/mon-data.h b/crawl-ref/source/mon-data.h index a4d9b9183e..1693e06566 100644 --- a/crawl-ref/source/mon-data.h +++ b/crawl-ref/source/mon-data.h @@ -58,7 +58,7 @@ exp_mod: see give_adjusted_experience() in monstuff.cc - the experience given for killing this monster is calculated something like this: - experience = hp_max * HD * HD * exp_mod / 10 + experience = hp_max * HD * HD * exp_mod / 10 I think. Actually it is @@ -119,6 +119,12 @@ MONUSE_WEAPONS_ARMOUR, MONUSE_MAGIC_ITEMS + From MONUSE_STARTING_EQUIPMENT on, monsters are capable of handling items. + Contrary to what one might expect MONUSE_WEAPONS_ARMOUR also means a + monster is capable of using wands and will also pick them up, something + that those with MONUSE_STARTING_EQUIPMENT won't do. + MONUSE_MAGIC_ITEMS is currently never used anywhere. + size: SIZE_TINY, // rat/bat SIZE_LITTLE, // spriggan @@ -168,7 +174,7 @@ 700, 10, MONS_GIANT_ANT, MONS_GIANT_ANT, MH_NATURAL, -3, { {AT_BITE, AF_POISON, 8}, AT_NO_ATK, AT_NO_ATK, AT_NO_ATK }, { 3, 3, 5, 0 }, - 4, 10, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_SILENT, I_INSECT, + 4, 10, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_SILENT, I_INSECT, HT_LAND, 12, DEFAULT_ENERGY, MONUSE_NOTHING, SIZE_LITTLE, }, @@ -191,7 +197,7 @@ 150, 4, MONS_GIANT_BAT, MONS_GIANT_BAT, MH_NATURAL, -1, { {AT_HIT, AF_PLAIN, 1}, AT_NO_ATK, AT_NO_ATK, AT_NO_ATK }, { 1, 2, 3, 0 }, - 1, 14, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_SILENT, I_ANIMAL, + 1, 14, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_SILENT, I_ANIMAL, HT_LAND, 30, DEFAULT_ENERGY, MONUSE_NOTHING, SIZE_TINY }, @@ -214,7 +220,7 @@ 1500, 10, MONS_CENTAUR, MONS_CENTAUR, MH_NATURAL, -3, { {AT_HIT, AF_PLAIN, 10}, AT_NO_ATK, AT_NO_ATK, AT_NO_ATK }, { 4, 3, 5, 0 }, - 3, 7, MST_NO_SPELLS, CE_CLEAN, Z_BIG, S_SHOUT, I_NORMAL, + 3, 7, MST_NO_SPELLS, CE_CLEAN, Z_BIG, S_SHOUT, I_NORMAL, HT_LAND, 15, DEFAULT_ENERGY, MONUSE_WEAPONS_ARMOUR, SIZE_BIG }, diff --git a/crawl-ref/source/mon-util.cc b/crawl-ref/source/mon-util.cc index 809aa252ce..8033a83300 100644 --- a/crawl-ref/source/mon-util.cc +++ b/crawl-ref/source/mon-util.cc @@ -3007,10 +3007,12 @@ void monsters::lose_pickup_energy() void monsters::pickup_message(const item_def &item, int near) { if (need_message(near)) + { mprf("%s picks up %s.", name(DESC_CAP_THE).c_str(), item.base_type == OBJ_GOLD? "some gold" : item.name(DESC_NOCAP_A).c_str()); + } } bool monsters::pickup(item_def &item, int slot, int near, bool force_merge) @@ -3236,9 +3238,9 @@ static mon_inv_type _equip_slot_to_mslot(equipment_type eq) { switch (eq) { - case EQ_WEAPON: return MSLOT_WEAPON; + case EQ_WEAPON: return MSLOT_WEAPON; case EQ_BODY_ARMOUR: return MSLOT_ARMOUR; - case EQ_SHIELD: return MSLOT_SHIELD; + case EQ_SHIELD: return MSLOT_SHIELD; default: return (NUM_MONSTER_SLOTS); } } @@ -3250,7 +3252,30 @@ bool monsters::pickup_armour(item_def &item, int near, bool force) if (!force && !wants_armour(item)) return (false); - const equipment_type eq = get_armour_slot(item); + equipment_type eq = EQ_NONE; + + // Hack to allow nagas/centaurs to wear bardings. (jpeg) + switch(item.sub_type) + { + case ARM_NAGA_BARDING: + if (::mons_species(this->type) == MONS_NAGA) + eq = EQ_BODY_ARMOUR; + break; + case ARM_CENTAUR_BARDING: + if (::mons_species(this->type) == MONS_CENTAUR + || ::mons_species(this->type) == MONS_YAKTAUR) + { + eq = EQ_BODY_ARMOUR; + } + break; + default: + eq = get_armour_slot(item); + } + + // Bardings are only wearable by the appropriate monster. + if (eq == EQ_NONE) + return false; + // XXX: Monsters can only equip body armour and shields (as of 0.4). // They can still be forced to wear stuff - this is needed for bardings. if (!force && eq != EQ_BODY_ARMOUR && eq != EQ_SHIELD) @@ -3305,13 +3330,21 @@ bool monsters::pickup_missile(item_def &item, int near, bool force) const item_def *miss = missiles(); - // monster may not pick up trapping net - if (mons_is_caught(this) && item.sub_type == MI_THROWING_NET - && item_is_stationary(item)) + if (item.sub_type == MI_THROWING_NET) { - return (false); + // monster may not pick up trapping net + if (mons_is_caught(this) && item_is_stationary(item)) + return (false); + + // else always pick up if no other missiles + if (!miss) + return true; } + // Spellcasters should not waste time with ammunition. + if (mons_has_ranged_spell(this)) + return (false); + if (miss && items_stack(*miss, item)) return (pickup(item, MSLOT_MISSILE, near)); @@ -3324,31 +3357,43 @@ bool monsters::pickup_missile(item_def &item, int near, bool force) bool monsters::pickup_wand(item_def &item, int near) { // Only low-HD monsters bother with wands. - return hit_dice < 14 && pickup(item, MSLOT_WAND, near); + return (hit_dice < 14 && pickup(item, MSLOT_WAND, near)); } bool monsters::pickup_scroll(item_def &item, int near) { + if (item.sub_type != SCR_TELEPORTATION + && item.sub_type != SCR_BLINKING + && item.sub_type != SCR_SUMMONING) + { + return false; + } return pickup(item, MSLOT_SCROLL, near); } bool monsters::pickup_potion(item_def &item, int near) { - // only allow monsters to pick up healing potions - // if they can actually use them - if ((item.sub_type == POT_HEALING || item.sub_type == POT_HEAL_WOUNDS) - && (mons_holiness(this) == MH_UNDEAD - || mons_holiness(this) == MH_NONLIVING - || mons_holiness(this) == MH_PLANT)) - { - return false; - } - - - if (::mons_species(this->type) != MONS_VAMPIRE - && (item.sub_type == POT_BLOOD - || item.sub_type == POT_BLOOD_COAGULATED)) + // Only allow monsters to pick up potions if they can actually use them. + switch(item.sub_type) { + case POT_HEALING: + case POT_HEAL_WOUNDS: + if (mons_holiness(this) == MH_UNDEAD + || mons_holiness(this) == MH_NONLIVING + || mons_holiness(this) == MH_PLANT) + { + return false; + } + break; + case POT_BLOOD: + case POT_BLOOD_COAGULATED: + if (::mons_species(this->type) != MONS_VAMPIRE) + return false; + break; + case POT_SPEED: + case POT_INVISIBILITY: + break; + default: return false; } @@ -3394,17 +3439,55 @@ bool monsters::pickup_misc(item_def &item, int near) bool monsters::pickup_item(item_def &item, int near, bool force) { // Never pick up stuff when we're in battle. - if (!force && (behaviour != BEH_WANDER || attitude == ATT_NEUTRAL)) - return (false); +// if (!force && (behaviour != BEH_WANDER || attitude == ATT_NEUTRAL)) +// return (false); + + if (!force) + { + if (attitude == ATT_NEUTRAL) + return (false); + + bool wandering = (behaviour == BEH_WANDER); + + // Weak(ened) monsters won't stop to pick up things as long as they + // feel unsafe. + if (!wandering && (hit_points * 10 < max_hit_points || hit_points <= 10) + && mon_enemies_around(this)) + { + return false; + } + + // These are not important enough for pickup when seeking, fleeing etc. + const int itype = item.base_type; + if (!wandering + && (itype == OBJ_ARMOUR || itype == OBJ_CORPSES + || itype == OBJ_MISCELLANY || itype == OBJ_GOLD)) + { + return false; + } + } // Jellies are not handled here. switch (item.base_type) { - case OBJ_WEAPONS: - return pickup_weapon(item, near, force); + // pickup some stuff only if WANDERING case OBJ_ARMOUR: return pickup_armour(item, near, force); + case OBJ_CORPSES: + return eat_corpse(item, near); + case OBJ_MISCELLANY: + return pickup_misc(item, near); + case OBJ_GOLD: + return pickup_gold(item, near); + // other types can always be picked up + // (barring other checks depending on subtype, of course) + case OBJ_WEAPONS: + if (behaviour == BEH_FLEEING) + return false; + return pickup_weapon(item, near, force); case OBJ_MISSILES: + if (behaviour == BEH_FLEEING) + return false; return pickup_missile(item, near, force); case OBJ_WANDS: return pickup_wand(item, near); @@ -3412,12 +3495,6 @@ bool monsters::pickup_item(item_def &item, int near, bool force) return pickup_scroll(item, near); case OBJ_POTIONS: return pickup_potion(item, near); - case OBJ_CORPSES: - return eat_corpse(item, near); - case OBJ_MISCELLANY: - return pickup_misc(item, near); - case OBJ_GOLD: - return pickup_gold(item, near); default: return (false); } diff --git a/crawl-ref/source/monstuff.cc b/crawl-ref/source/monstuff.cc index af33afa77a..66e634673e 100644 --- a/crawl-ref/source/monstuff.cc +++ b/crawl-ref/source/monstuff.cc @@ -2007,10 +2007,14 @@ void behaviour_event( monsters *mon, int event, int src, // are BOTH friendly and stupid, or else fleeing anyway. // Hitting someone over the head, of course, // always triggers this code. - if ( event == ME_WHACK || - ((isFriendly != sourceFriendly || isSmart) && - (mon->behaviour != BEH_FLEE && mon->behaviour != BEH_PANIC))) + if (event == ME_WHACK + || ((isFriendly != sourceFriendly || isSmart) + && mon->behaviour != BEH_FLEE && mon->behaviour != BEH_PANIC)) { + // (plain) plants and fungi cannot flee or fight back + if (mon->type == MONS_FUNGUS || mon->type == MONS_PLANT) + return; + mon->foe = src; if (mon->behaviour != BEH_CORNERED) @@ -4018,14 +4022,6 @@ static bool _mons_announce_cast(monsters *monster, bool nearby, return (true); } -static bool _enemies_around(const monsters *monster) -{ - if (mons_friendly(monster)) - return (!mons_near(monster) || !i_feel_safe()); - else - return (mons_near(monster)); -} - //--------------------------------------------------------------- // // handle_spell @@ -4076,7 +4072,7 @@ static bool _handle_spell( monsters *monster, bolt & beem ) spell_type spell_cast = SPELL_NO_SPELL; monster_spells hspell_pass(monster->spells); - if (!_enemies_around(monster)) + if (!mon_enemies_around(monster)) { // forces the casting of dig when player not visible - this is EVIL! if (monster->has_spell(SPELL_DIG) @@ -4118,8 +4114,8 @@ static bool _handle_spell( monsters *monster, bolt & beem ) // monsters caught in a net try to get away // this is only urgent if enemies are around - if (!finalAnswer && _enemies_around(monster) && mons_is_caught(monster) - && one_chance_in(4)) + if (!finalAnswer && mon_enemies_around(monster) + && mons_is_caught(monster) && one_chance_in(4)) { for (int i = 0; i < NUM_MONSTER_SPELL_SLOTS; i++) { @@ -4166,7 +4162,7 @@ static bool _handle_spell( monsters *monster, bolt & beem ) if (!finalAnswer) { // if nothing found by now, safe friendlies will rarely cast - if (mons_friendly(monster) && !_enemies_around(monster) + if (mons_friendly(monster) && !mon_enemies_around(monster) && !one_chance_in(8)) { return (false); @@ -4805,7 +4801,6 @@ static void _handle_monster_move(int i, monsters *monster) int pfound = 0; for (int yi = -1; yi <= 1; ++yi) - { for (int xi = -1; xi <= 1; ++xi) { coord_def c = monster->pos() + coord_def(xi, yi); @@ -4816,7 +4811,6 @@ static void _handle_monster_move(int i, monsters *monster) mmov_y = yi; } } - } if (random2(2 + pfound) < 2) mmov_x = mmov_y = 0; @@ -4824,7 +4818,7 @@ static void _handle_monster_move(int i, monsters *monster) // bounds check: don't let confused monsters try to run // off the map if (monster->x + mmov_x < 0 - || monster->x + mmov_x >= GXM) + || monster->x + mmov_x >= GXM) { mmov_x = 0; } @@ -4845,8 +4839,7 @@ static void _handle_monster_move(int i, monsters *monster) && !is_sanctuary(monster->x, monster->y) && (mmov_x != 0 || mmov_y != 0)) { - monsters_fight( - i, + monsters_fight(i, mgrd[monster->x + mmov_x][monster->y + mmov_y]); brkk = true; diff --git a/crawl-ref/source/religion.cc b/crawl-ref/source/religion.cc index 6cf6e0195b..09289b8fc3 100644 --- a/crawl-ref/source/religion.cc +++ b/crawl-ref/source/religion.cc @@ -3394,7 +3394,8 @@ void divine_retribution( god_type god ) { ASSERT(god != GOD_NO_GOD); - if (!god_hates_your_god(god)) + // allow retribution during god's own penance + if (god != you.religion && !god_hates_your_god(god)) return; god_acting gdact(god, true); @@ -4802,8 +4803,8 @@ void handle_god_time() { // Nemelex penance is special: it's only "active" // when penance > 100, else it's passive. - if (you.penance[i] && (i != GOD_NEMELEX_XOBEH || - you.penance[i] > 100)) + if (you.penance[i] && (i != GOD_NEMELEX_XOBEH + || you.penance[i] > 100)) { count++; if (one_chance_in(count)) diff --git a/crawl-ref/source/view.cc b/crawl-ref/source/view.cc index ae09d2ca8e..5eff25aa60 100644 --- a/crawl-ref/source/view.cc +++ b/crawl-ref/source/view.cc @@ -3600,6 +3600,14 @@ bool mons_near(const monsters *monster, unsigned int foe) return (false); } // end mons_near() +bool mon_enemies_around(const monsters *monster) +{ + if (mons_friendly(monster)) + return (!mons_near(monster) || !i_feel_safe()); + else + return (mons_near(monster)); +} + bool see_grid( const env_show_grid &show, const coord_def &c, const coord_def &pos ) diff --git a/crawl-ref/source/view.h b/crawl-ref/source/view.h index bc7cc13f8f..39d4f613a5 100644 --- a/crawl-ref/source/view.h +++ b/crawl-ref/source/view.h @@ -79,7 +79,7 @@ void beogh_follower_convert(monsters *monster, bool orc_hit = false); * mstuff2 - spells1 - spells2 * *********************************************************************** */ bool mons_near(const monsters *monster, unsigned int foe = MHITYOU); - +bool mon_enemies_around(const monsters *monster); // last updated 12may2000 {dlb} /* *********************************************************************** |