summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source
diff options
context:
space:
mode:
authorAdam Borowski <kilobyte@angband.pl>2009-12-15 00:01:58 +0100
committerAdam Borowski <kilobyte@angband.pl>2009-12-15 00:06:49 +0100
commitf5ad2d06f0bac4de0a61d97b8887b70616006969 (patch)
tree58296a0761e58ecc58107a6ea530fbbd7ccccd84 /crawl-ref/source
parent08b32044b9fe15e1026a463da9d3d4cad19b3942 (diff)
downloadcrawl-ref-f5ad2d06f0bac4de0a61d97b8887b70616006969.tar.gz
crawl-ref-f5ad2d06f0bac4de0a61d97b8887b70616006969.zip
Make mimics hold the item they're mimicking, instead of fragile hacks with saving RNG state.
Diffstat (limited to 'crawl-ref/source')
-rw-r--r--crawl-ref/source/describe.cc10
-rw-r--r--crawl-ref/source/directn.cc16
-rw-r--r--crawl-ref/source/mon-place.cc11
-rw-r--r--crawl-ref/source/mon-stuff.cc79
-rw-r--r--crawl-ref/source/mon-stuff.h3
-rw-r--r--crawl-ref/source/monster.cc8
-rw-r--r--crawl-ref/source/show.cc15
-rw-r--r--crawl-ref/source/stash.cc9
-rw-r--r--crawl-ref/source/tilepick.cc11
-rw-r--r--crawl-ref/source/travel.cc12
10 files changed, 81 insertions, 93 deletions
diff --git a/crawl-ref/source/describe.cc b/crawl-ref/source/describe.cc
index e77ff17982..83ea1d2e2b 100644
--- a/crawl-ref/source/describe.cc
+++ b/crawl-ref/source/describe.cc
@@ -2802,9 +2802,7 @@ void get_monster_db_desc(const monsters& mons, describe_info &inf,
// For undetected mimics describe mimicked item instead.
if (!force_seen && mons_is_unknown_mimic(&mons))
{
- item_def item;
- get_mimic_item(&mons, item);
- get_item_desc(item, inf);
+ get_item_desc(get_mimic_item(&mons), inf);
return;
}
@@ -2812,12 +2810,6 @@ void get_monster_db_desc(const monsters& mons, describe_info &inf,
inf.title = mons.full_name(DESC_CAP_A, true);
std::string db_name = mons.base_name(DESC_DBNAME, force_seen);
- if (mons_is_mimic(mons.type) && mons.type != MONS_GOLD_MIMIC)
- {
- db_name = "mimic";
- if (inf.title.empty())
- inf.title = "A mimic";
- }
// This is somewhat hackish, but it's a good way of over-riding monsters'
// descriptions in Lua vaults by using MonPropsMarker. This is also the
diff --git a/crawl-ref/source/directn.cc b/crawl-ref/source/directn.cc
index 34cef9c9f9..66d3b94f96 100644
--- a/crawl-ref/source/directn.cc
+++ b/crawl-ref/source/directn.cc
@@ -521,11 +521,7 @@ void full_describe_view()
const bool unknown_mimic = (mon && mons_is_unknown_mimic(mon));
if (unknown_mimic) // It'll be on top.
- {
- item_def item;
- get_mimic_item(mon, item);
- list_items.push_back(item);
- }
+ list_items.push_back(get_mimic_item(mon));
const int oid = igrd(*ri);
if (oid == NON_ITEM)
@@ -1754,11 +1750,7 @@ std::string get_terse_square_desc(const coord_def &gc)
const monsters& mons = *monster_at(gc);
if (mons_is_mimic(mons.type) && !(mons.flags & MF_KNOWN_MIMIC))
- {
- item_def item;
- get_mimic_item(&mons, item);
- desc = item.name(DESC_PLAIN);
- }
+ desc = get_mimic_item(&mons).name(DESC_PLAIN);
else
desc = mons.full_name(DESC_PLAIN, true);
}
@@ -3361,9 +3353,7 @@ static void _describe_cell(const coord_def& where, bool in_range)
_describe_monster(mon);
else
{
- item_def item;
- get_mimic_item( mon, item );
- std::string name = get_menu_colour_prefix_tags(item,
+ std::string name = get_menu_colour_prefix_tags(get_mimic_item(mon),
DESC_NOCAP_A);
mprf(MSGCH_FLOOR_ITEMS, "You see %s here.", name.c_str());
}
diff --git a/crawl-ref/source/mon-place.cc b/crawl-ref/source/mon-place.cc
index 6629b8acf1..a4273c6a7c 100644
--- a/crawl-ref/source/mon-place.cc
+++ b/crawl-ref/source/mon-place.cc
@@ -1116,6 +1116,17 @@ static int _place_monster_aux(const mgen_data &mg,
int id = mon->mindex();
env.mgrid(fpos) = id;
+ if (mons_is_mimic(mg.cls))
+ {
+ // Mimics who mimic thin air get the axe.
+ if (!give_mimic_item(mon))
+ {
+ mon->reset();
+ mgrd(fpos) = NON_MONSTER;
+ return (-1);
+ }
+ }
+
// Generate a brand shiny new monster, or zombie.
if (mons_class_is_zombified(mg.cls))
_define_zombie(id, mg.base_type, mg.cls, mg.power, fpos);
diff --git a/crawl-ref/source/mon-stuff.cc b/crawl-ref/source/mon-stuff.cc
index 4f9fa50ac8..2288d753db 100644
--- a/crawl-ref/source/mon-stuff.cc
+++ b/crawl-ref/source/mon-stuff.cc
@@ -62,13 +62,14 @@
static bool _wounded_damaged(monster_type mon_type);
-// This function creates an artificial item to represent a mimic's
-// appearance. Eventually, mimics could be redone to be more like
-// dancing weapons: there'd only be one type and it would look like the
-// item it carries. - bwr
-void get_mimic_item( const monsters *mimic, item_def &item )
+int _make_mimic_item(monster_type type)
{
- ASSERT(mimic != NULL && mons_is_mimic( mimic->type));
+ int it = items(0, OBJ_UNASSIGNED, 0, true, 0, 0);
+
+ if (it == NON_ITEM)
+ return NON_ITEM;
+
+ item_def &item = mitm[it];
item.base_type = OBJ_UNASSIGNED;
item.sub_type = 0;
@@ -78,22 +79,16 @@ void get_mimic_item( const monsters *mimic, item_def &item )
item.quantity = 1;
item.plus = 0;
item.plus2 = 0;
- item.pos = mimic->pos();
item.link = NON_ITEM;
- int prop = 127 * mimic->pos().x + 269 * mimic->pos().y;
-
- rng_save_excursion exc;
- seed_rng( prop );
-
- switch (mimic->type)
+ int prop;
+ switch (type)
{
case MONS_WEAPON_MIMIC:
item.base_type = OBJ_WEAPONS;
- item.sub_type = (59 * mimic->pos().x + 79 * mimic->pos().y)
- % (WPN_MAX_NONBLESSED + 1);
+ item.sub_type = random2(WPN_MAX_NONBLESSED + 1);
- prop %= 100;
+ prop = random2(100);
if (prop < 20)
make_item_randart(item);
@@ -111,10 +106,9 @@ void get_mimic_item( const monsters *mimic, item_def &item )
case MONS_ARMOUR_MIMIC:
item.base_type = OBJ_ARMOUR;
- item.sub_type = (59 * mimic->pos().x + 79 * mimic->pos().y)
- % NUM_ARMOURS;
+ item.sub_type = random2(NUM_ARMOURS);
- prop %= 100;
+ prop = random2(100);
if (prop < 20)
make_item_randart(item);
@@ -134,39 +128,55 @@ void get_mimic_item( const monsters *mimic, item_def &item )
case MONS_SCROLL_MIMIC:
item.base_type = OBJ_SCROLLS;
- item.sub_type = prop % NUM_SCROLLS;
+ item.sub_type = random2(NUM_SCROLLS);
break;
case MONS_POTION_MIMIC:
item.base_type = OBJ_POTIONS;
- item.sub_type = prop % NUM_POTIONS;
+ item.sub_type = random2(NUM_POTIONS);
break;
case MONS_GOLD_MIMIC:
default:
item.base_type = OBJ_GOLD;
- item.quantity = 5 + prop % 30;
+ item.quantity = 5 + random2(1000);
break;
}
item_colour(item); // also sets special vals for scrolls/potions
+
+ return (it);
+}
+
+item_def *give_mimic_item(monsters *mimic)
+{
+ ASSERT(mimic != NULL && mons_is_mimic(mimic->type));
+
+ mimic->destroy_inventory();
+ int it = _make_mimic_item(mimic->type);
+ if (it == NON_ITEM)
+ return 0;
+ if (!mimic->pickup_misc(mitm[it], 0))
+ ASSERT("Mimic failed to pickup its item.");
+ return (&mitm[mimic->inv[MSLOT_MISCELLANY]]);
+}
+
+item_def &get_mimic_item(const monsters *mimic)
+{
+ ASSERT(mimic != NULL && mons_is_mimic(mimic->type));
+
+ ASSERT(mimic->inv[MSLOT_MISCELLANY] != NON_ITEM);
+
+ return (mitm[mimic->inv[MSLOT_MISCELLANY]]);
}
// Sets the colour of a mimic to match its description... should be called
// whenever a mimic is created or teleported. -- bwr
int get_mimic_colour( const monsters *mimic )
{
- ASSERT( mimic != NULL && mons_is_mimic( mimic->type ) );
+ ASSERT(mimic != NULL);
- if (mimic->type == MONS_SCROLL_MIMIC)
- return (LIGHTGREY);
- else if (mimic->type == MONS_GOLD_MIMIC)
- return (YELLOW);
-
- item_def item;
- get_mimic_item( mimic, item );
-
- return (item.colour);
+ return (get_mimic_item(mimic).colour);
}
// Monster curses a random player inventory item.
@@ -2126,6 +2136,8 @@ int monster_die(monsters *monster, killer_type killer,
{
_elven_twin_died(monster, in_transit);
}
+ else if (mons_is_mimic(monster->type))
+ monster->destroy_inventory();
else if (!monster->is_summoned())
{
if (mons_genus(monster->type) == MONS_MUMMY)
@@ -3733,7 +3745,10 @@ void monster_teleport(monsters *monster, bool instan, bool silent)
monster_type old_type = monster->type;
monster->type = static_cast<monster_type>(
MONS_GOLD_MIMIC + random2(5));
+ monster->destroy_inventory();
+ give_mimic_item(monster);
monster->colour = get_mimic_colour(monster);
+ was_seen = false;
// If it's changed form, you won't recognise it.
// This assumes that a non-gold mimic turning into another item of
diff --git a/crawl-ref/source/mon-stuff.h b/crawl-ref/source/mon-stuff.h
index 97acee430f..8455c89ecb 100644
--- a/crawl-ref/source/mon-stuff.h
+++ b/crawl-ref/source/mon-stuff.h
@@ -61,7 +61,8 @@ public:
// for definition of type monsters {dlb}
#include "externs.h"
-void get_mimic_item( const monsters *mimic, item_def & item );
+item_def *give_mimic_item(monsters *mimic);
+item_def &get_mimic_item(const monsters *mimic);
int get_mimic_colour( const monsters *mimic );
void alert_nearby_monsters(void);
diff --git a/crawl-ref/source/monster.cc b/crawl-ref/source/monster.cc
index 4aff1df1c1..d31935af61 100644
--- a/crawl-ref/source/monster.cc
+++ b/crawl-ref/source/monster.cc
@@ -2065,12 +2065,8 @@ static std::string _str_monam(const monsters& mon, description_level_type desc,
// Various special cases:
// non-gold mimics, dancing weapons, ghosts, Pan demons
- if (mons_is_mimic(mon.type) && mon.type != MONS_GOLD_MIMIC)
- {
- item_def item;
- get_mimic_item(&mon, item);
- return (item.name(desc));
- }
+ if (mons_is_mimic(mon.type))
+ return (get_mimic_item(&mon).name(desc));
if (mon.type == MONS_DANCING_WEAPON && mon.inv[MSLOT_WEAPON] != NON_ITEM)
{
diff --git a/crawl-ref/source/show.cc b/crawl-ref/source/show.cc
index 0d12f7f0ad..9ef5c303b9 100644
--- a/crawl-ref/source/show.cc
+++ b/crawl-ref/source/show.cc
@@ -218,19 +218,19 @@ static show_item_type _item_to_show_code(const item_def &item)
void show_def::_update_item_at(const coord_def &gp, const coord_def &ep)
{
- item_def eitem;
+ item_def *eitem;
// Check for mimics.
const monsters* m = monster_at(gp);
if (m && mons_is_unknown_mimic(m))
- get_mimic_item(m, eitem);
+ eitem = &get_mimic_item(m);
else if (igrd(gp) != NON_ITEM)
- eitem = mitm[igrd(gp)];
+ eitem = &mitm[igrd(gp)];
else
return;
unsigned short &ecol = grid(ep).colour;
- glyph g = get_item_glyph(&eitem);
+ glyph g = get_item_glyph(eitem);
const dungeon_feature_type feat = grd(gp);
if (Options.feature_item_brand && is_critical_feature(feat))
@@ -242,10 +242,13 @@ void show_def::_update_item_at(const coord_def &gp, const coord_def &ep)
const unsigned short gcol = env.grid_colours(gp);
ecol = (feat == DNGN_SHALLOW_WATER) ?
(gcol != BLACK ? gcol : CYAN) : g.col;
- if (eitem.link != NON_ITEM && !crawl_state.arena)
+ // monster(mimic)-owned items have link = NON_ITEM+1+midx
+ if (eitem->link > NON_ITEM && igrd(gp) != NON_ITEM)
+ ecol |= COLFLAG_ITEM_HEAP;
+ else if (eitem->link == NON_ITEM && !crawl_state.arena)
ecol |= COLFLAG_ITEM_HEAP;
grid(ep).cls = SH_ITEM;
- grid(ep).item = _item_to_show_code(eitem);
+ grid(ep).item = _item_to_show_code(*eitem);
}
#ifdef USE_TILE
diff --git a/crawl-ref/source/stash.cc b/crawl-ref/source/stash.cc
index 9eb534b0ff..cb3a461b61 100644
--- a/crawl-ref/source/stash.cc
+++ b/crawl-ref/source/stash.cc
@@ -380,21 +380,16 @@ void Stash::update()
// There's something on this square. Take a squint at it.
const item_def *pitem;
- item_def mimic_item;
if (_grid_has_mimic_item(p))
- {
- get_mimic_item(monster_at(p), mimic_item);
- pitem = &mimic_item;
- }
+ pitem = &get_mimic_item(monster_at(p));
else
{
pitem = &mitm[igrd(p)];
+ tutorial_first_item(*pitem);
}
const item_def& item = *pitem;
- tutorial_first_item(item);
-
if (!_grid_has_perceived_multiple_items(p))
items.clear();
diff --git a/crawl-ref/source/tilepick.cc b/crawl-ref/source/tilepick.cc
index 0e95c17d07..b8ac8a5941 100644
--- a/crawl-ref/source/tilepick.cc
+++ b/crawl-ref/source/tilepick.cc
@@ -769,12 +769,7 @@ int tileidx_monster_base(const monsters *mon, bool detected)
case MONS_ARMOUR_MIMIC:
case MONS_SCROLL_MIMIC:
case MONS_POTION_MIMIC:
- {
- // Use item tile.
- item_def item;
- get_mimic_item( mon, item );
- return tileidx_item(item);
- }
+ return tileidx_item(get_mimic_item(mon));
case MONS_DANCING_WEAPON:
{
@@ -4696,9 +4691,7 @@ void tile_place_monster(int gx, int gy, int idx, bool foreground, bool detected)
t0 |= TILE_FLAG_S_UNDER;
}
- item_def item;
- get_mimic_item( mon, item );
- if (item_needs_autopickup(item))
+ if (item_needs_autopickup(get_mimic_item(mon))
{
if (foreground)
env.tile_bg[ep.x][ep.y] |= TILE_FLAG_CURSOR3;
diff --git a/crawl-ref/source/travel.cc b/crawl-ref/source/travel.cc
index f8e4eb55cb..6da7bc6ee0 100644
--- a/crawl-ref/source/travel.cc
+++ b/crawl-ref/source/travel.cc
@@ -546,11 +546,7 @@ inline static void _check_interesting_square(int x, int y,
if (const monsters *mons = monster_at(pos))
{
if (mons_is_unknown_mimic(mons))
- {
- item_def item;
- get_mimic_item(mons, item);
- ed.found_item(pos, item);
- }
+ ed.found_item(pos, get_mimic_item(mons));
}
if (igrd(pos) != NON_ITEM)
@@ -1084,12 +1080,8 @@ static bool _is_greed_inducing_square(const LevelStashes *ls,
if (const monsters *mons = monster_at(c))
{
if (mons_is_unknown_mimic(mons) && mons_was_seen(mons))
- {
- item_def mimic_item;
- get_mimic_item(mons, mimic_item);
- if (item_needs_autopickup(mimic_item))
+ if (item_needs_autopickup(get_mimic_item(mons)))
return (true);
- }
}
return (false);
}