summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--crawl-ref/source/debug.cc2
-rw-r--r--crawl-ref/source/makeitem.cc2
-rw-r--r--crawl-ref/source/mon-data.h14
-rw-r--r--crawl-ref/source/mon-util.cc141
-rw-r--r--crawl-ref/source/monstuff.cc33
-rw-r--r--crawl-ref/source/religion.cc7
-rw-r--r--crawl-ref/source/view.cc8
-rw-r--r--crawl-ref/source/view.h2
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}
/* ***********************************************************************