summaryrefslogtreecommitdiffstats
path: root/crawl-ref
diff options
context:
space:
mode:
authorj-p-e-g <j-p-e-g@c06c8d41-db1a-0410-9941-cceddc491573>2008-04-16 13:33:32 +0000
committerj-p-e-g <j-p-e-g@c06c8d41-db1a-0410-9941-cceddc491573>2008-04-16 13:33:32 +0000
commit1a6c94ae92a619e3612a0359d97d4498f2adeba8 (patch)
tree00bba720527cf6966d0d6a1cd0a4e96bb7e8cd29 /crawl-ref
parent3c8efd591ced0fbdad0da577af07011700df7562 (diff)
downloadcrawl-ref-1a6c94ae92a619e3612a0359d97d4498f2adeba8.tar.gz
crawl-ref-1a6c94ae92a619e3612a0359d97d4498f2adeba8.zip
Fix 1943303: Prevention of barding generation in monsters equipment.
And while I was at it... improved monster pickup handling. * Ranged spellcasters won't pick up missiles anymore (except throwing nets). * Allow monsters with behaviour != BEH_WANDER to pick up items again. (Restricted to scrolls, potions, wands and weapons, since these could be useful in a fight.) * Restrict monster pickup to items they may actually use (3 types of scrolls, six types of potions), though they may still pick up all types of wands, if only to annoy the player. As before, pickup only takes place if a monster happens to be on a square with items and only the top items of stashes are checked - monsters won't make a beeline for items or search stashes for goodies. Also, neutrals and friendlies still won't pick up anything at all; this might have to be changed. Unrelated: fixed an ASSERT for divine retribution during penance. git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@4255 c06c8d41-db1a-0410-9941-cceddc491573
Diffstat (limited to 'crawl-ref')
-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}
/* ***********************************************************************