summaryrefslogtreecommitdiffstats
path: root/crawl-ref
diff options
context:
space:
mode:
authorzelgadis <zelgadis@c06c8d41-db1a-0410-9941-cceddc491573>2007-10-02 22:40:40 +0000
committerzelgadis <zelgadis@c06c8d41-db1a-0410-9941-cceddc491573>2007-10-02 22:40:40 +0000
commit4ba581107a1d56ce5706593f4a3917f457afb929 (patch)
treeb32318795a7f152f1fd92043e182dba09bea9bea /crawl-ref
parent6b34259b6ce235196c3f2f70e706d9235dc100cb (diff)
downloadcrawl-ref-4ba581107a1d56ce5706593f4a3917f457afb929.tar.gz
crawl-ref-4ba581107a1d56ce5706593f4a3917f457afb929.zip
Made Xom be smarter about being amused at losing/missing runes, and
made Xom also be amused at runes being destroyed. Related changes: * Keep track of which items have ever been held by the player with ISFLAG_BEEN_IN_INV. * item_was_destroyed() is called when an item is destroyed (as in dropped in lava, not destroy_item() being called), and item_was_lost() is called if the item was lost (i.e., being left behind in the Abyss). * Keeps track of the number of runes that the character has collected, and how many have been left in the Halls of Zot. git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@2300 c06c8d41-db1a-0410-9941-cceddc491573
Diffstat (limited to 'crawl-ref')
-rw-r--r--crawl-ref/source/abyss.cc43
-rw-r--r--crawl-ref/source/beam.cc4
-rw-r--r--crawl-ref/source/effects.cc2
-rw-r--r--crawl-ref/source/enum.h8
-rw-r--r--crawl-ref/source/files.cc6
-rw-r--r--crawl-ref/source/items.cc124
-rw-r--r--crawl-ref/source/items.h6
-rw-r--r--crawl-ref/source/misc.cc11
-rw-r--r--crawl-ref/source/monstuff.cc29
-rw-r--r--crawl-ref/source/newgame.cc2
-rw-r--r--crawl-ref/source/religion.cc1
-rw-r--r--crawl-ref/source/terrain.cc1
-rw-r--r--crawl-ref/source/xom.cc72
-rw-r--r--crawl-ref/source/xom.h3
14 files changed, 248 insertions, 64 deletions
diff --git a/crawl-ref/source/abyss.cc b/crawl-ref/source/abyss.cc
index f059eb2435..05f1117227 100644
--- a/crawl-ref/source/abyss.cc
+++ b/crawl-ref/source/abyss.cc
@@ -219,7 +219,7 @@ static int abyss_exit_nearness()
// HACK: Why doesn't is_terrain_known() work here?
if (grd[x][y] == DNGN_EXIT_ABYSS
- && get_screen_glyph(x, y) != '\0')
+ && get_screen_glyph(x, y) != ' ')
{
nearness = MIN(nearness,
grid_distance(you.x_pos, you.y_pos,
@@ -241,7 +241,7 @@ static int abyss_rune_nearness()
continue;
// HACK: Why doesn't is_terrain_known() work here?
- if (get_screen_glyph(x, y) != '\0')
+ if (get_screen_glyph(x, y) != ' ')
{
int i = igrd[x][y];
@@ -279,19 +279,22 @@ static void xom_check_nearness()
viewwindow(true, false);
int exit_is_near = abyss_exit_nearness();
- if ((exit_was_near < INFINITE_DISTANCE &&
- exit_is_near == INFINITE_DISTANCE)
- || (exit_was_near == INFINITE_DISTANCE &&
- exit_is_near < INFINITE_DISTANCE))
+ int rune_is_near = abyss_rune_nearness();
+
+ if ((exit_was_near < INFINITE_DISTANCE
+ && exit_is_near == INFINITE_DISTANCE)
+ || (rune_was_near < INFINITE_DISTANCE
+ && rune_is_near == INFINITE_DISTANCE
+ && you.attribute[ATTR_ABYSSAL_RUNES] == 0))
{
- xom_is_stimulated(255);
+ xom_is_stimulated(255, "Xom snickers loudly.", true);
}
- int rune_is_near = abyss_rune_nearness();
- if ((rune_was_near < INFINITE_DISTANCE &&
- rune_is_near == INFINITE_DISTANCE)
- || (rune_was_near == INFINITE_DISTANCE &&
- rune_is_near < INFINITE_DISTANCE))
+ if ((rune_was_near == INFINITE_DISTANCE
+ && rune_is_near < INFINITE_DISTANCE
+ && you.attribute[ATTR_ABYSSAL_RUNES] == 0)
+ || (exit_was_near == INFINITE_DISTANCE &&
+ exit_is_near < INFINITE_DISTANCE))
{
xom_is_stimulated(255);
}
@@ -338,7 +341,7 @@ void area_shift(void)
grd[i][j] = DNGN_UNSEEN;
// nuke items
- destroy_item_stack( i, j );
+ lose_item_stack( i, j );
if (mgrd[i][j] != NON_MONSTER)
abyss_lose_monster( menv[ mgrd[i][j] ] );
@@ -474,19 +477,7 @@ void abyss_teleport( bool new_area )
{
if (is_valid_item( mitm[k] ))
{
- if (mitm[k].base_type == OBJ_ORBS)
- {
- set_unique_item_status( OBJ_ORBS, mitm[k].sub_type,
- UNIQ_LOST_IN_ABYSS );
- }
- else if (is_fixed_artefact( mitm[k] ))
- {
- set_unique_item_status( OBJ_WEAPONS, mitm[k].special,
- UNIQ_LOST_IN_ABYSS );
- }
-
- xom_check_lost_item( mitm[k] );
-
+ item_was_lost( mitm[k] );
destroy_item( k );
}
}
diff --git a/crawl-ref/source/beam.cc b/crawl-ref/source/beam.cc
index 14e42d849a..43a5540b77 100644
--- a/crawl-ref/source/beam.cc
+++ b/crawl-ref/source/beam.cc
@@ -2406,6 +2406,8 @@ void beam_drop_object( bolt &beam, item_def *item, int x, int y )
// Too much message spam otherwise
if ( YOU_KILL(beam.thrower) && player_can_hear(x, y) )
mprf(MSGCH_SOUND, grid_item_destruction_message(grd[x][y]));
+
+ item_was_destroyed(*item, beam.beam_source);
return;
}
@@ -2932,6 +2934,8 @@ static void affect_items(bolt &beam, int x, int y)
if (objs_vulnerable != -1 &&
mitm[igrd[x][y]].base_type == objs_vulnerable)
{
+ item_was_destroyed(mitm[igrd[x][y]], beam.beam_source);
+
destroy_item( igrd[ x ][ y ] );
if (objs_vulnerable == OBJ_SCROLLS && see_grid(x,y))
diff --git a/crawl-ref/source/effects.cc b/crawl-ref/source/effects.cc
index 8b99b05d30..ff4de0f7a0 100644
--- a/crawl-ref/source/effects.cc
+++ b/crawl-ref/source/effects.cc
@@ -1330,6 +1330,8 @@ bool acquirement(object_class_type class_wanted, int agent)
if (!silenced(you.pos()))
mprf(MSGCH_SOUND,
grid_item_destruction_message(grd[you.x_pos][you.y_pos]));
+
+ item_was_destroyed(mitm[igrd[you.x_pos][you.y_pos]], NON_MONSTER);
}
else
{
diff --git a/crawl-ref/source/enum.h b/crawl-ref/source/enum.h
index ddc29fe4e9..05ae52441e 100644
--- a/crawl-ref/source/enum.h
+++ b/crawl-ref/source/enum.h
@@ -173,6 +173,10 @@ enum attribute_type
ATTR_HELD, // caught in a net
ATTR_ABYSS_ENTOURAGE, // maximum number of hostile monsters in
// sight of the player while in the Abyss.
+ ATTR_UNIQUE_RUNES,
+ ATTR_DEMONIC_RUNES,
+ ATTR_ABYSSAL_RUNES,
+ ATTR_RUNES_IN_ZOT,
NUM_ATTRIBUTES
};
@@ -1270,7 +1274,9 @@ enum item_status_flag_type // per item flags: ie. ident status, cursed status
ISFLAG_RACIAL_MASK = 0x07000000, // mask of racial equipment types
ISFLAG_NOTED_ID = 0x08000000,
- ISFLAG_NOTED_GET = 0x10000000
+ ISFLAG_NOTED_GET = 0x10000000,
+
+ ISFLAG_BEEN_IN_INV = 0x20000000 // Item has been in inventory
};
enum job_type
diff --git a/crawl-ref/source/files.cc b/crawl-ref/source/files.cc
index 53a2452cce..951cd6794a 100644
--- a/crawl-ref/source/files.cc
+++ b/crawl-ref/source/files.cc
@@ -826,7 +826,7 @@ static void grab_followers()
// Should be called afetr grab_followers(), so that items carried by
// followers won't be considered lost.
-static void _xom_check_lost_items(level_area_type old_level_type)
+static void do_lost_items(level_area_type old_level_type)
{
if (old_level_type == LEVEL_DUNGEON)
return;
@@ -842,7 +842,7 @@ static void _xom_check_lost_items(level_area_type old_level_type)
if (item.x == -1 && item.y == -1)
continue;
- xom_check_lost_item(item);
+ item_was_lost(item);
}
}
@@ -894,7 +894,7 @@ bool load( dungeon_feature_type stair_taken, int load_mode,
save_level( old_level, LEVEL_DUNGEON, where_were_you2 );
}
- _xom_check_lost_items(old_level_type);
+ do_lost_items(old_level_type);
// Try to open level savefile.
FILE *levelFile = fopen(cha_fil.c_str(), "rb");
diff --git a/crawl-ref/source/items.cc b/crawl-ref/source/items.cc
index 7d7daea1b6..92bd3fa034 100644
--- a/crawl-ref/source/items.cc
+++ b/crawl-ref/source/items.cc
@@ -289,6 +289,12 @@ bool dec_inv_item_quantity( int obj, int amount )
bool dec_mitm_item_quantity( int obj, int amount )
{
if (mitm[obj].quantity <= amount)
+ amount = mitm[obj].quantity;
+
+ if (player_in_branch(BRANCH_HALL_OF_ZOT) && is_rune(mitm[obj]))
+ you.attribute[ATTR_RUNES_IN_ZOT] -= amount;
+
+ if (mitm[obj].quantity == amount)
{
destroy_item( obj );
// If we're repeating a command, the repetitions used up the
@@ -315,6 +321,9 @@ void inc_inv_item_quantity( int obj, int amount )
void inc_mitm_item_quantity( int obj, int amount )
{
+ if (player_in_branch(BRANCH_HALL_OF_ZOT) && is_rune(mitm[obj]))
+ you.attribute[ATTR_RUNES_IN_ZOT] += amount;
+
mitm[obj].quantity += amount;
}
@@ -509,7 +518,52 @@ void destroy_item( int dest )
mitm[dest].clear();
}
-void destroy_item_stack( int x, int y )
+static void handle_gone_item(const item_def &item)
+{
+ if (item.base_type == OBJ_ORBS)
+ {
+ set_unique_item_status(OBJ_ORBS, item.sub_type,
+ UNIQ_LOST_IN_ABYSS);
+ }
+ else if (is_fixed_artefact(item))
+ {
+ set_unique_item_status(OBJ_WEAPONS, item.special,
+ UNIQ_LOST_IN_ABYSS);
+ }
+
+ if (is_rune(item))
+ {
+ if ((item.flags & ISFLAG_BEEN_IN_INV))
+ {
+ if (is_unique_rune(item))
+ you.attribute[ATTR_UNIQUE_RUNES] -= item.quantity;
+ else if (item.plus == RUNE_ABYSSAL)
+ you.attribute[ATTR_ABYSSAL_RUNES] -= item.quantity;
+ else
+ you.attribute[ATTR_DEMONIC_RUNES] -= item.quantity;
+ }
+
+ if (player_in_branch(BRANCH_HALL_OF_ZOT)
+ && item.x != -1 && item.y != -1)
+ {
+ you.attribute[ATTR_RUNES_IN_ZOT] -= item.quantity;
+ }
+ }
+}
+
+void item_was_lost(const item_def &item)
+{
+ handle_gone_item( item );
+ xom_check_lost_item( item );
+}
+
+void item_was_destroyed(const item_def &item, int cause)
+{
+ handle_gone_item( item );
+ xom_check_destroyed_item( item, cause );
+}
+
+void lose_item_stack( int x, int y )
{
int o = igrd[x][y];
@@ -521,18 +575,29 @@ void destroy_item_stack( int x, int y )
if (is_valid_item( mitm[o] ))
{
- if (mitm[o].base_type == OBJ_ORBS)
- {
- set_unique_item_status( OBJ_ORBS, mitm[o].sub_type,
- UNIQ_LOST_IN_ABYSS );
- }
- else if (is_fixed_artefact( mitm[o] ))
- {
- set_unique_item_status( OBJ_WEAPONS, mitm[o].special,
- UNIQ_LOST_IN_ABYSS );
- }
+ item_was_lost(mitm[o]);
+
+ mitm[o].base_type = OBJ_UNASSIGNED;
+ mitm[o].quantity = 0;
+ }
+
+ o = next;
+ }
+}
+
+void destroy_item_stack( int x, int y, int cause )
+{
+ int o = igrd[x][y];
- xom_check_lost_item( mitm[o] );
+ igrd[x][y] = NON_ITEM;
+
+ while (o != NON_ITEM)
+ {
+ int next = mitm[o].link;
+
+ if (is_valid_item( mitm[o] ))
+ {
+ item_was_destroyed(mitm[o], cause);
mitm[o].base_type = OBJ_UNASSIGNED;
mitm[o].quantity = 0;
@@ -1344,6 +1409,25 @@ int find_free_slot(const item_def &i)
#undef slotisfree
}
+static void got_item(item_def& item, int quant)
+{
+ if (!is_rune(item))
+ return;
+
+ // Picking up the rune for the first time.
+ if (!(item.flags & ISFLAG_BEEN_IN_INV))
+ {
+ if (is_unique_rune(item))
+ you.attribute[ATTR_UNIQUE_RUNES] += quant;
+ else if (item.plus == RUNE_ABYSSAL)
+ you.attribute[ATTR_ABYSSAL_RUNES] += quant;
+ else
+ you.attribute[ATTR_DEMONIC_RUNES] += quant;
+ }
+
+ item.flags |= ISFLAG_BEEN_IN_INV;
+}
+
// Returns quantity of items moved into player's inventory and -1 if
// the player's inventory is full.
int move_item_to_player( int obj, int quant_got, bool quiet )
@@ -1421,6 +1505,8 @@ int move_item_to_player( int obj, int quant_got, bool quiet )
dec_mitm_item_quantity( obj, quant_got );
burden_change();
+ got_item(mitm[obj], quant_got);
+
if (!quiet)
mpr( you.inv[m].name(DESC_INVENTORY).c_str() );
@@ -1491,6 +1577,8 @@ int move_item_to_player( int obj, int quant_got, bool quiet )
if (item.base_type == OBJ_ORBS && you.level_type == LEVEL_DUNGEON)
unset_branch_flags(BFLAG_HAS_ORB);
+ got_item(item, item.quantity);
+
you.turn_is_over = true;
return (retval);
@@ -1558,8 +1646,16 @@ void move_item_to_grid( int *const obj, int x, int y )
mitm[*obj].link = igrd[x][y];
igrd[x][y] = *obj;
- if (mitm[*obj].base_type == OBJ_ORBS && you.level_type == LEVEL_DUNGEON)
+ if (is_rune(mitm[*obj]))
+ {
+ if (player_in_branch(BRANCH_HALL_OF_ZOT))
+ you.attribute[ATTR_RUNES_IN_ZOT] += mitm[*obj].quantity;
+ }
+ else if (mitm[*obj].base_type == OBJ_ORBS
+ && you.level_type == LEVEL_DUNGEON)
+ {
set_branch_flags(BFLAG_HAS_ORB);
+ }
return;
}
@@ -1734,6 +1830,8 @@ bool drop_item( int item_dropped, int quant_drop, bool try_offer )
{
if( !silenced(you.pos()) )
mprf(MSGCH_SOUND, grid_item_destruction_message(my_grid));
+
+ item_was_destroyed(you.inv[item_dropped], NON_MONSTER);
}
else if (strstr(you.inv[item_dropped].inscription.c_str(), "=s") != 0)
stashes.add_stash();
diff --git a/crawl-ref/source/items.h b/crawl-ref/source/items.h
index 9d0b8eb93c..2a451f7551 100644
--- a/crawl-ref/source/items.h
+++ b/crawl-ref/source/items.h
@@ -76,7 +76,8 @@ int get_item_slot( int reserve = 50 );
* *********************************************************************** */
void unlink_item(int dest);
void destroy_item(int dest);
-void destroy_item_stack( int x, int y );
+void destroy_item_stack( int x, int y, int cause = -1 );
+void lose_item_stack( int x, int y );
// last updated: 08jun2000 {dlb}
/* ***********************************************************************
@@ -171,4 +172,7 @@ void autoinscribe();
bool item_is_equipped(const item_def &item);
+void item_was_lost(const item_def &item);
+void item_was_destroyed(const item_def &item, int cause = -1);
+
#endif
diff --git a/crawl-ref/source/misc.cc b/crawl-ref/source/misc.cc
index 96c66ab2c2..6ddf4eae07 100644
--- a/crawl-ref/source/misc.cc
+++ b/crawl-ref/source/misc.cc
@@ -684,10 +684,15 @@ void up_stairs(dungeon_feature_type force_stair,
// of dropping some runes within Zot), but need to get back in Zot
// to get the Orb? Zom finds that funny.
if (stair_find == DNGN_RETURN_FROM_ZOT
- && runes_in_pack() < NUMBER_OF_RUNES_NEEDED
- && (branches[BRANCH_HALL_OF_ZOT].branch_flags & BFLAG_HAS_ORB))
+ && branches[BRANCH_HALL_OF_ZOT].branch_flags & BFLAG_HAS_ORB)
{
- xom_is_stimulated(255, "Xom snickers loudly.", true);
+ int runes_avail = you.attribute[ATTR_UNIQUE_RUNES]
+ + you.attribute[ATTR_DEMONIC_RUNES]
+ + you.attribute[ATTR_ABYSSAL_RUNES]
+ - you.attribute[ATTR_RUNES_IN_ZOT];
+
+ if (runes_avail < NUMBER_OF_RUNES_NEEDED)
+ xom_is_stimulated(255, "Xom snickers loudly.", true);
}
if (you.skills[SK_TRANSLOCATIONS] > 0 && !allow_control_teleport( true ))
diff --git a/crawl-ref/source/monstuff.cc b/crawl-ref/source/monstuff.cc
index 2f71c94086..bcf04efba4 100644
--- a/crawl-ref/source/monstuff.cc
+++ b/crawl-ref/source/monstuff.cc
@@ -268,6 +268,8 @@ static void monster_drop_ething(monsters *monster,
hostile_grid = true;
}
+ int midx = (int) monster_index(monster);
+
for (i = MSLOT_GOLD; i >= MSLOT_WEAPON; i--)
{
int item = monster->inv[i];
@@ -276,6 +278,7 @@ static void monster_drop_ething(monsters *monster,
{
if (hostile_grid)
{
+ item_was_destroyed(mitm[item], midx);
destroyed = true;
destroy_item( item );
}
@@ -301,7 +304,6 @@ static void monster_drop_ething(monsters *monster,
static void place_monster_corpse(const monsters *monster)
{
int corpse_class = mons_species(monster->type);
-
if (corpse_class == MONS_DRACONIAN)
corpse_class = draco_subspecies(monster);
@@ -310,12 +312,8 @@ static void place_monster_corpse(const monsters *monster)
else if (monster->has_ench(ENCH_GLOWING_SHAPESHIFTER))
corpse_class = MONS_GLOWING_SHAPESHIFTER;
- if (mons_weight(corpse_class) == 0
- || grid_destroys_items(grd[monster->x][monster->y])
- || coinflip())
- {
+ if (mons_weight(corpse_class) == 0 || coinflip())
return;
- }
int o = get_item_slot();
if (o == NON_ITEM)
@@ -333,6 +331,13 @@ static void place_monster_corpse(const monsters *monster)
if (mitm[o].colour == BLACK)
mitm[o].colour = monster->colour;
+ if (grid_destroys_items(grd[monster->x][monster->y]))
+ {
+ item_was_destroyed(mitm[o]);
+ mitm[o].base_type = OBJ_UNASSIGNED;
+ return;
+ }
+
// Don't care if 'o' is changed, and it shouldn't be (corpses don't stack)
move_item_to_grid( &o, monster->x, monster->y );
if (see_grid(monster->x, monster->y))
@@ -4242,10 +4247,11 @@ static bool handle_pickup(monsters *monster)
if (mons_itemuse(monster->type) == MONUSE_EATS_ITEMS)
{
- int hps_gained = 0;
- int max_eat = roll_dice( 1, 10 );
- int eaten = 0;
- bool eaten_net = false;
+ int midx = monster_index(monster);
+ int hps_gained = 0;
+ int max_eat = roll_dice( 1, 10 );
+ int eaten = 0;
+ bool eaten_net = false;
for (item = igrd[monster->x][monster->y];
item != NON_ITEM && eaten < max_eat && hps_gained < 50;
@@ -4282,6 +4288,9 @@ static bool handle_pickup(monsters *monster)
eaten++;
}
+ if (quant >= mitm[item].quantity)
+ item_was_destroyed(mitm[item], midx);
+
dec_mitm_item_quantity( item, quant );
}
diff --git a/crawl-ref/source/newgame.cc b/crawl-ref/source/newgame.cc
index fedd19e087..5a06795884 100644
--- a/crawl-ref/source/newgame.cc
+++ b/crawl-ref/source/newgame.cc
@@ -873,6 +873,8 @@ game_start:
{
if (is_valid_item(you.inv[i]))
{
+ you.inv[i].flags |= ISFLAG_BEEN_IN_INV;
+
// identify all items in pack
set_ident_type( you.inv[i].base_type,
you.inv[i].sub_type, ID_KNOWN_TYPE );
diff --git a/crawl-ref/source/religion.cc b/crawl-ref/source/religion.cc
index 26a7c89765..9fb5f64318 100644
--- a/crawl-ref/source/religion.cc
+++ b/crawl-ref/source/religion.cc
@@ -3114,6 +3114,7 @@ void offer_items()
<< sacrifice_message(you.religion, mitm[i],
gained_piety)
<< std::endl;
+ item_was_destroyed(mitm[i]);
destroy_item(i);
i = next;
num_sacced++;
diff --git a/crawl-ref/source/terrain.cc b/crawl-ref/source/terrain.cc
index ecb1a70092..9423c44f8f 100644
--- a/crawl-ref/source/terrain.cc
+++ b/crawl-ref/source/terrain.cc
@@ -377,6 +377,7 @@ static void dgn_check_terrain_items(const coord_def &pos, bool preserve_items)
dgn_shift_item(pos, mitm[curr]);
else
{
+ item_was_destroyed(mitm[item]);
destroy_item(curr);
did_destroy = true;
}
diff --git a/crawl-ref/source/xom.cc b/crawl-ref/source/xom.cc
index 0269c0ef5e..5ffe6d2279 100644
--- a/crawl-ref/source/xom.cc
+++ b/crawl-ref/source/xom.cc
@@ -9,6 +9,7 @@
#include "AppHdr.h"
#include "beam.h"
+#include "branch.h"
#include "effects.h"
#include "it_use2.h"
#include "items.h"
@@ -927,7 +928,29 @@ void xom_acts(bool niceness, int sever)
you.piety = 200 - you.piety;
}
-void xom_check_lost_item(item_def& item)
+static void xom_check_less_runes(int runes_gones)
+{
+ if (player_in_branch(BRANCH_HALL_OF_ZOT) ||
+ !(branches[BRANCH_HALL_OF_ZOT].branch_flags & BFLAG_HAS_ORB))
+ {
+ return;
+ }
+
+ int runes_avail = you.attribute[ATTR_UNIQUE_RUNES]
+ + you.attribute[ATTR_DEMONIC_RUNES]
+ + you.attribute[ATTR_ABYSSAL_RUNES]
+ - you.attribute[ATTR_RUNES_IN_ZOT];
+ int was_avail = runes_avail + runes_gones;
+
+ // No longer enough available runes to get into Zot
+ if (was_avail >= NUMBER_OF_RUNES_NEEDED &&
+ runes_avail < NUMBER_OF_RUNES_NEEDED)
+ {
+ xom_is_stimulated(128, "Xom snickers.", true);
+ }
+}
+
+void xom_check_lost_item(const item_def& item)
{
if (item.base_type == OBJ_ORBS)
xom_is_stimulated(255, "Xom laughs nastily.", true);
@@ -935,14 +958,20 @@ void xom_check_lost_item(item_def& item)
xom_is_stimulated(128, "Xom snickers.", true);
else if (is_rune(item))
{
+ // If you'd dropped it, check if that means you'd dropped your
+ // third rune and now don't have enough to get into Zot.
+ if (item.flags & ISFLAG_BEEN_IN_INV)
+ xom_check_less_runes(item.quantity);
+
if (is_unique_rune(item))
xom_is_stimulated(255, "Xom snickers loudly.", true);
else if (you.entry_cause == EC_SELF_EXPLICIT &&
- !(item.flags & ISFLAG_DROPPED))
+ !(item.flags & ISFLAG_BEEN_IN_INV))
{
- // Player voluntarily entered Pan or the Abyss looking
- // for runes, yet never found it.
- if (item.plus == RUNE_ABYSSAL)
+ // Player voluntarily entered Pan or the Abyss looking for
+ // runes, yet never found it.
+ if (item.plus == RUNE_ABYSSAL &&
+ you.attribute[ATTR_ABYSSAL_RUNES] == 0)
{
// Ignore Abyss area shifts.
if (you.level_type != LEVEL_ABYSS)
@@ -951,8 +980,39 @@ void xom_check_lost_item(item_def& item)
// stimulation.
xom_is_stimulated(128, "Xom snickers.", true);
}
- else
+ else if (item.plus == RUNE_DEMONIC &&
+ you.attribute[ATTR_DEMONIC_RUNES] == 0)
+ {
xom_is_stimulated(64, "Xom snickers softly.", true);
+ }
}
}
}
+
+void xom_check_destroyed_item(const item_def& item, int cause)
+{
+ int amusement = 0;
+
+ if (item.base_type == OBJ_ORBS)
+ {
+ xom_is_stimulated(255, "Xom laughs nastily.", true);
+ return;
+ }
+ else if (is_fixed_artefact(item))
+ xom_is_stimulated(128, "Xom snickers.", true);
+ else if (is_rune(item))
+ {
+ xom_check_less_runes(item.quantity);
+
+ if (is_unique_rune(item) || item.plus == RUNE_ABYSSAL)
+ amusement = 255;
+ else
+ amusement = 64 * item.quantity;
+ }
+
+ xom_is_stimulated(amusement,
+ amusement > 128 ? "Xom snickers loudly." :
+ amusement > 64 ? "Xom snickers." :
+ "Xom snickers softly.",
+ true);
+}
diff --git a/crawl-ref/source/xom.h b/crawl-ref/source/xom.h
index c68bafafbc..b14b9b7d66 100644
--- a/crawl-ref/source/xom.h
+++ b/crawl-ref/source/xom.h
@@ -36,6 +36,7 @@ inline void xom_acts(int sever)
xom_acts(xom_is_nice(), sever);
}
-void xom_check_lost_item(item_def& item);
+void xom_check_lost_item(const item_def& item);
+void xom_check_destroyed_item(const item_def& item, int cause = -1);
#endif