diff options
author | zelgadis <zelgadis@c06c8d41-db1a-0410-9941-cceddc491573> | 2009-01-08 06:34:25 +0000 |
---|---|---|
committer | zelgadis <zelgadis@c06c8d41-db1a-0410-9941-cceddc491573> | 2009-01-08 06:34:25 +0000 |
commit | 2af58b0346183d18125bfa5867be4339ce055ffe (patch) | |
tree | 937b1e45d0d7e8faa72b859c09f7e68b8ea8d273 /crawl-ref/source/items.cc | |
parent | 3fe0cf688e2dad0503dbb31dd43cfe3bd1fa6536 (diff) | |
download | crawl-ref-2af58b0346183d18125bfa5867be4339ce055ffe.tar.gz crawl-ref-2af58b0346183d18125bfa5867be4339ce055ffe.zip |
Make the position of monster held items (-2, -2) rather than (0, 0), so that
any valid item in mitm[] which is still at (0, 0) by the time debug_item_scan()
is called must be buggy. Also set the link fields of monster held items to
NON_ITEM + 1 + monster_index, so that it's easy to tell which monster is
holding any given item; this is used in debug_mons_scan() and
monsters::pickup() to do some sanity checking of monster inventory. I've tried
to thoroughly test this, but there might still be some bugs left.
Breaks savefile compatibility (or, rather, will lead to endless error messages
if you use an old save file).
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@8322 c06c8d41-db1a-0410-9941-cceddc491573
Diffstat (limited to 'crawl-ref/source/items.cc')
-rw-r--r-- | crawl-ref/source/items.cc | 62 |
1 files changed, 36 insertions, 26 deletions
diff --git a/crawl-ref/source/items.cc b/crawl-ref/source/items.cc index 200656794c..7dff728830 100644 --- a/crawl-ref/source/items.cc +++ b/crawl-ref/source/items.cc @@ -110,13 +110,18 @@ void link_items(void) igrd.init(NON_ITEM); // Link all items on the grid, plus shop inventory, - // but DON'T link the huge pile of monster items at (0,0). + // but DON'T link the huge pile of monster items at (-2,-2). for (int i = 0; i < MAX_ITEMS; i++) { - if (!is_valid_item(mitm[i]) || mitm[i].pos.origin()) + // Don't mess with monster held items, since the index of the holding + // monster is stored in the link field. + if (held_by_monster(mitm[i])) + continue; + + if (!is_valid_item(mitm[i])) { - // Item is not assigned, or is monster item. Ignore. + // Item is not assigned. Ignore. mitm[i].link = NON_ITEM; continue; } @@ -365,37 +370,39 @@ void unlink_item( int dest ) if (dest == NON_ITEM || !is_valid_item( mitm[dest] )) return; - if (mitm[dest].pos.origin()) + monsters* monster = holding_monster(mitm[dest]); + + if (monster != NULL) { - // (0,0) is where the monster items are (and they're unlinked by igrd), - // although it also contains items that are not linked in yet. - // - // Check if a monster has it: - for (int c = 0; c < MAX_MONSTERS; c++) + for (int i = 0; i < NUM_MONSTER_SLOTS; i++) { - monsters *monster = &menv[c]; - - if (monster->type == -1) - continue; - - for (int cy = 0; cy < NUM_MONSTER_SLOTS; cy++) + if (monster->inv[i] == dest) { - if (monster->inv[cy] == dest) - { - monster->inv[cy] = NON_ITEM; + monster->inv[i] = NON_ITEM; - mitm[dest].pos.reset(); - mitm[dest].link = NON_ITEM; - return; - } + mitm[dest].pos.reset(); + mitm[dest].link = NON_ITEM; + return; } } - - // Always return because this item might just be temporary. + mprf(MSGCH_ERROR, "Item %s claims to be held by monster %s, but " + "it isn't in the monster's inventory.", + mitm[dest].name(DESC_PLAIN, false, true).c_str(), + monster->name(DESC_PLAIN, true).c_str()); + // Don't return so the debugging code can take a look at it. + } + // Unlinking a newly created item, or a a temporary one, or an item in + // the player's inventory. + else if (mitm[dest].pos.origin() || mitm[dest].pos.equals(-1, -1)) + { + mitm[dest].pos.reset(); + mitm[dest].link = NON_ITEM; return; } else { + ASSERT(in_bounds(mitm[dest].pos)); + // Linked item on map: // // Use the items (x,y) to access the list (igrd[x][y]) where @@ -1629,8 +1636,11 @@ int move_item_to_player( int obj, int quant_got, bool quiet, } coord_def p = mitm[obj].pos; - dungeon_events.fire_position_event( - dgn_event(DET_ITEM_PICKUP, p, 0, obj, -1), p); + // If moving an item directly from a monster to the player without the + // item having been on the grid, then it really isn't a position event. + if (in_bounds(p)) + dungeon_events.fire_position_event( + dgn_event(DET_ITEM_PICKUP, p, 0, obj, -1), p); item_def &item = you.inv[freeslot]; // Copy item. |