summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorj-p-e-g <j-p-e-g@c06c8d41-db1a-0410-9941-cceddc491573>2009-04-03 17:06:22 +0000
committerj-p-e-g <j-p-e-g@c06c8d41-db1a-0410-9941-cceddc491573>2009-04-03 17:06:22 +0000
commit2d1dc73ba81562198242670c328146d3f13695c6 (patch)
tree6526769c27f00c87d81ac2dd552c9e0bd1f7b7c0
parent20e25439cad6e0c97716e197bb2dceae731a9d24 (diff)
downloadcrawl-ref-2d1dc73ba81562198242670c328146d3f13695c6.tar.gz
crawl-ref-2d1dc73ba81562198242670c328146d3f13695c6.zip
* Allow fleeing monster to push past higher ranked monsters of the same
type. * Allow quivering of wielded missiles (stones for Sandblast etc.) and wielded weapons of returning if your throwing skill is > 0. * Add stairs/gates/shops to the 'V' command, mostly for the convenience of the easy travel feature. git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@9574 c06c8d41-db1a-0410-9941-cceddc491573
-rw-r--r--crawl-ref/source/beam.cc5
-rw-r--r--crawl-ref/source/command.cc1
-rw-r--r--crawl-ref/source/dat/descript/skills.txt3
-rw-r--r--crawl-ref/source/directn.cc83
-rw-r--r--crawl-ref/source/item_use.cc2
-rw-r--r--crawl-ref/source/itemprop.cc3
-rw-r--r--crawl-ref/source/menu.cc35
-rw-r--r--crawl-ref/source/menu.h12
-rw-r--r--crawl-ref/source/mon-util.cc25
-rw-r--r--crawl-ref/source/mon-util.h3
-rw-r--r--crawl-ref/source/monstuff.cc3
-rw-r--r--crawl-ref/source/quiver.cc28
-rw-r--r--crawl-ref/source/stash.cc14
13 files changed, 170 insertions, 47 deletions
diff --git a/crawl-ref/source/beam.cc b/crawl-ref/source/beam.cc
index 605c07b749..dae307097d 100644
--- a/crawl-ref/source/beam.cc
+++ b/crawl-ref/source/beam.cc
@@ -4956,12 +4956,11 @@ mon_resist_type bolt::apply_enchantment_to_monster(monsters* mon)
return (MON_OTHER);
}
- if (mon->add_ench(ENCH_CHARM))
+ if (!mon->has_ench(ENCH_CHARM))
{
- // FIXME: Put in an exception for fungi, plants and other
- // things you won't notice becoming charmed.
if (simple_monster_message(mon, " is charmed."))
obvious_effect = true;
+ mon->add_ench(ENCH_CHARM);
}
return (MON_AFFECTED);
diff --git a/crawl-ref/source/command.cc b/crawl-ref/source/command.cc
index 6bcb35072f..6014528aae 100644
--- a/crawl-ref/source/command.cc
+++ b/crawl-ref/source/command.cc
@@ -1371,7 +1371,6 @@ static bool _do_description(std::string key, std::string type,
if (thing_created != NON_ITEM
&& (type == "item" || type == "spell"))
{
-
char name[80];
strncpy(name, key.c_str(), sizeof(name));
if (get_item_by_name(&mitm[thing_created], name, OBJ_WEAPONS))
diff --git a/crawl-ref/source/dat/descript/skills.txt b/crawl-ref/source/dat/descript/skills.txt
index d3a00884ad..44fb34a4e4 100644
--- a/crawl-ref/source/dat/descript/skills.txt
+++ b/crawl-ref/source/dat/descript/skills.txt
@@ -278,5 +278,6 @@ Evocations
Evocations is all about using magical items like wands, decks or
other uncommon objects. The higher your skill, the more likely is a
-positive outcome when evoking items.
+positive outcome when evoking items. Also, high skill may let you determine
+the amount of charges a zapped wand has left.
%%%%
diff --git a/crawl-ref/source/directn.cc b/crawl-ref/source/directn.cc
index 605192bf47..4926bffab3 100644
--- a/crawl-ref/source/directn.cc
+++ b/crawl-ref/source/directn.cc
@@ -457,10 +457,14 @@ void full_describe_view()
{
std::vector<const monsters*> list_mons;
std::vector<item_def> list_items;
+ std::vector<coord_def> list_features;
// Grab all items known (or thought) to be in the stashes in view.
for (radius_iterator ri(you.pos(), LOS_RADIUS); ri; ++ri)
{
+ if (grid_stair_direction(grd(*ri)) != CMD_NO_CMD)
+ list_features.push_back(*ri);
+
const monsters *mon = monster_at(*ri);
const bool unknown_mimic = (mon && mons_is_unknown_mimic(mon));
@@ -506,9 +510,9 @@ void full_describe_view()
for (unsigned int i = 0; i < mons.size(); i++)
list_mons.push_back(mons[i].m_mon);
- if (list_mons.empty() && list_items.empty())
+ if (list_mons.empty() && list_items.empty() && list_features.empty())
{
- mprf("Neither monsters nor items are visible.");
+ mprf("No monsters, items or features are visible.");
return;
}
@@ -518,9 +522,23 @@ void full_describe_view()
desc_menu.set_highlighter(NULL);
// FIXME: Need different title for the opposite toggle:
// "Visible Monsters/Items (select for more detail, '!' to examine):"
- desc_menu.set_title(
- new MenuEntry("Visible Monsters/Items (select for more detail, '!' to view/travel):",
- MEL_TITLE));
+ std::string title = "";
+ if (!list_mons.empty())
+ title += "Monsters";
+ if (!list_items.empty())
+ {
+ if (!title.empty())
+ title += "/";
+ title += "Items";
+ }
+ if (!list_features.empty())
+ {
+ if (!title.empty())
+ title += "/";
+ title += "Features";
+ }
+ title = "Visible " + title + " (select for more detail, '!' to view/travel):";
+ desc_menu.set_title( new MenuEntry(title, MEL_TITLE));
desc_menu.set_tag("pickup");
desc_menu.set_type(MT_PICKUP); // necessary for sorting of the item submenu
@@ -538,7 +556,6 @@ void full_describe_view()
if (!list_mons.empty())
{
desc_menu.add_entry( new MenuEntry("Monsters", MEL_SUBTITLE) );
-// desc_menu.mdisplay->set_num_columns(1);
for (unsigned int i = 0; i < list_mons.size(); ++i, ++hotkey)
{
// List monsters in the form
@@ -601,7 +618,7 @@ void full_describe_view()
}
// Build menu entries for items.
- if (list_items.size())
+ if (!list_items.empty())
{
std::vector<InvEntry*> all_items;
for (unsigned int i = 0; i < list_items.size(); ++i)
@@ -626,6 +643,40 @@ void full_describe_view()
}
}
+ if (!list_features.empty())
+ {
+ desc_menu.add_entry( new MenuEntry("Features", MEL_SUBTITLE) );
+ for (unsigned int i = 0; i < list_features.size(); ++i, ++hotkey)
+ {
+ const coord_def c = list_features[i];
+ std::string desc = "";
+#ifndef USE_TILE
+// get_screen_glyph(c)
+ const coord_def e = c - you.pos() + coord_def(9,9);
+ unsigned short col = env.show_col(e);;
+ int object = env.show(e);
+ unsigned ch;
+ get_item_symbol( object, &ch, &col );
+
+ const std::string colour_str = colour_to_str(col);
+ desc = "(<" + colour_str + ">";
+ desc += stringize_glyph(ch);
+ if (ch == '<')
+ desc += '<';
+
+ desc += "</" + colour_str +">) ";
+#endif
+ desc += feature_description(c);
+ if (is_travelable_stair(grd(c)) && !travel_cache.know_stair(c))
+ desc += " (not visited)";
+ FeatureMenuEntry *me = new FeatureMenuEntry(desc, c, hotkey);
+ me->tag = "description";
+ // Hack to make features selectable.
+ me->quantity = c.x*100 + c.y + 3;
+ desc_menu.add_entry(me);
+ }
+ }
+
// Select an item to read its full description, or a monster to read its
// e'x'amine description. Toggle with '!' to travel to an item's position
// or read a monster's database entry.
@@ -633,9 +684,10 @@ void full_describe_view()
// For ASCII, the 'x' information may include short database descriptions.
// Menu loop
+ std::vector<MenuEntry*> sel;
while (true)
{
- std::vector<MenuEntry*> sel = desc_menu.show();
+ sel = desc_menu.show();
redraw_screen();
if (sel.empty())
@@ -692,6 +744,21 @@ void full_describe_view()
break;
}
}
+ else
+ {
+ const int num = quant - 3;
+ const int y = num % 100;
+ const int x = (num - y)/100;
+ coord_def c(x,y);
+
+ if (desc_menu.menu_action == InvMenu::ACT_EXAMINE)
+ describe_feature_wide(c);
+ else // ACT_EXECUTE -> travel to feature
+ {
+ start_travel( c );
+ break;
+ }
+ }
}
#ifndef USE_TILE
diff --git a/crawl-ref/source/item_use.cc b/crawl-ref/source/item_use.cc
index b505f3aac7..e20ab461d5 100644
--- a/crawl-ref/source/item_use.cc
+++ b/crawl-ref/source/item_use.cc
@@ -3873,7 +3873,7 @@ void zap_wand(int slot)
return;
}
- // if you happen to be wielding the wand, its display might change.
+ // If you happen to be wielding the wand, its display might change.
if (you.equip[EQ_WEAPON] == item_slot)
you.wield_change = true;
diff --git a/crawl-ref/source/itemprop.cc b/crawl-ref/source/itemprop.cc
index 5603d1ac76..e0e6e5dc2b 100644
--- a/crawl-ref/source/itemprop.cc
+++ b/crawl-ref/source/itemprop.cc
@@ -513,6 +513,9 @@ void do_curse_item( item_def &item, bool quiet )
{
mprf("Your %s glows black for a moment.",
item.name(DESC_PLAIN).c_str());
+
+ // If we get the message, we know the item is cursed now.
+ item.flags |= ISFLAG_KNOW_CURSE;
}
item.flags |= ISFLAG_CURSED;
diff --git a/crawl-ref/source/menu.cc b/crawl-ref/source/menu.cc
index 67af41fd61..d39d1080c6 100644
--- a/crawl-ref/source/menu.cc
+++ b/crawl-ref/source/menu.cc
@@ -20,7 +20,11 @@ REVISION("$Rev$");
#include "mon-util.h"
#endif
#include "player.h"
-#include "tiles.h"
+#ifdef USE_TILE
+ #include "stuff.h"
+ #include "tiles.h"
+ #include "travel.h"
+#endif
#include "tutorial.h"
#include "view.h"
#include "initfile.h"
@@ -692,10 +696,17 @@ MonsterMenuEntry::MonsterMenuEntry(const std::string &str, const monsters* mon,
quantity = 1;
}
+FeatureMenuEntry::FeatureMenuEntry(const std::string &str, const coord_def p, int hotkey) :
+ MenuEntry(str, MEL_ITEM, 1, hotkey)
+{
+ pos = p;
+ quantity = 1;
+}
+
#ifdef USE_TILE
bool MenuEntry::get_tiles(std::vector<tile_def>& tileset) const
{
- return false;
+ return (false);
}
bool MonsterMenuEntry::get_tiles(std::vector<tile_def>& tileset) const
@@ -781,6 +792,19 @@ bool MonsterMenuEntry::get_tiles(std::vector<tile_def>& tileset) const
return (true);
}
+
+bool FeatureMenuEntry::get_tiles(std::vector<tile_def>& tileset) const
+{
+ if (!in_bounds(pos))
+ return (false);
+
+ tileset.push_back(tile_def(tileidx_feature(grd(pos), pos.x, pos.y),
+ TEX_DUNGEON));
+ if (is_travelable_stair(grd(pos)) && !travel_cache.know_stair(pos))
+ tileset.push_back(tile_def(TILE_NEW_STAIR, TEX_DEFAULT));
+
+ return (true);
+}
#endif
bool Menu::is_selectable(int item) const
@@ -1505,11 +1529,12 @@ formatted_scroller::formatted_scroller(int _flags, const std::string& s) :
void formatted_scroller::add_text(const std::string& s)
{
size_t eolpos = 0;
- while ( true )
+ while (true)
{
const size_t newpos = s.find( "\n", eolpos );
- add_item_formatted_string(formatted_string::parse_string(std::string(s, eolpos, newpos-eolpos)));
- if ( newpos == std::string::npos )
+ add_item_formatted_string(formatted_string::parse_string(
+ std::string(s, eolpos, newpos-eolpos)));
+ if (newpos == std::string::npos)
break;
else
eolpos = newpos + 1;
diff --git a/crawl-ref/source/menu.h b/crawl-ref/source/menu.h
index 12517ec097..d3d358e8ac 100644
--- a/crawl-ref/source/menu.h
+++ b/crawl-ref/source/menu.h
@@ -172,6 +172,18 @@ public:
#endif
};
+class FeatureMenuEntry : public MenuEntry
+{
+public:
+ coord_def pos;
+
+ FeatureMenuEntry(const std::string &str, const coord_def p, int hotkey);
+
+#ifdef USE_TILE
+ virtual bool get_tiles(std::vector<tile_def>& tileset) const;
+#endif
+};
+
class MenuHighlighter
{
public:
diff --git a/crawl-ref/source/mon-util.cc b/crawl-ref/source/mon-util.cc
index 1bd90804d2..982c671771 100644
--- a/crawl-ref/source/mon-util.cc
+++ b/crawl-ref/source/mon-util.cc
@@ -3393,7 +3393,7 @@ bool monster_shover(const monsters *m)
// Returns true if m1 and m2 are related, and m1 is higher up the totem pole
// than m2. The criteria for being related are somewhat loose, as you can see
// below.
-bool monster_senior(const monsters *m1, const monsters *m2)
+bool monster_senior(const monsters *m1, const monsters *m2, bool fleeing)
{
const monsterentry *me1 = get_monster_data(m1->type),
*me2 = get_monster_data(m2->type);
@@ -3406,12 +3406,12 @@ bool monster_senior(const monsters *m1, const monsters *m2)
// If both are demons, the smaller number is the nastier demon.
if (isdigit(mchar1) && isdigit(mchar2))
- return (mchar1 < mchar2);
+ return (fleeing || mchar1 < mchar2);
// &s are the evillest demons of all, well apart from Geryon, who really
// profits from *not* pushing past beasts.
if (mchar1 == '&' && isdigit(mchar2) && m1->type != MONS_GERYON)
- return (m1->hit_dice > m2->hit_dice);
+ return (fleeing || m1->hit_dice > m2->hit_dice);
// If they're the same holiness, monsters smart enough to use stairs can
// push past monsters too stupid to use stairs (so that e.g. non-zombified
@@ -3422,21 +3422,24 @@ bool monster_senior(const monsters *m1, const monsters *m2)
return (true);
}
- if (m1->type == MONS_QUEEN_BEE
- && (m2->type == MONS_KILLER_BEE
- || m2->type == MONS_KILLER_BEE_LARVA))
+ if (mons_genus(m1->type) == MONS_KILLER_BEE
+ && mons_genus(m2->type) == MONS_KILLER_BEE)
{
- return (true);
- }
+ if (fleeing)
+ return (true);
- if (m1->type == MONS_KILLER_BEE && m2->type == MONS_KILLER_BEE_LARVA)
- return (true);
+ if (m1->type == MONS_QUEEN_BEE && m2->type != MONS_QUEEN_BEE)
+ return (true);
+
+ if (m1->type == MONS_KILLER_BEE && m2->type == MONS_KILLER_BEE_LARVA)
+ return (true);
+ }
// Special-case gnolls, so they can't get past (hob)goblins.
if (m1->type == MONS_GNOLL && m2->type != MONS_GNOLL)
return (false);
- return (mchar1 == mchar2 && m1->hit_dice > m2->hit_dice);
+ return (mchar1 == mchar2 && (fleeing || m1->hit_dice > m2->hit_dice));
}
diff --git a/crawl-ref/source/mon-util.h b/crawl-ref/source/mon-util.h
index 92eacdaf3b..116b215a80 100644
--- a/crawl-ref/source/mon-util.h
+++ b/crawl-ref/source/mon-util.h
@@ -815,7 +815,8 @@ bool mons_is_petrifying(const monsters *m);
bool mons_cannot_act(const monsters *m);
bool mons_cannot_move(const monsters *m);
-bool monster_senior(const monsters *first, const monsters *second);
+bool monster_senior(const monsters *first, const monsters *second,
+ bool fleeing = false);
monster_type draco_subspecies( const monsters *mon );
std::string draconian_colour_name(monster_type mtype);
monster_type draconian_colour_by_name(const std::string &colour);
diff --git a/crawl-ref/source/monstuff.cc b/crawl-ref/source/monstuff.cc
index c0048a05d6..a7fe9465d8 100644
--- a/crawl-ref/source/monstuff.cc
+++ b/crawl-ref/source/monstuff.cc
@@ -7649,7 +7649,8 @@ static bool _mons_can_displace(const monsters *mpusher, const monsters *mpushee)
if (!monster_shover(mpusher))
return (false);
- if (!monster_senior(mpusher, mpushee))
+ // Fleeing monsters of the same type may push past higher ranking ones.
+ if (!monster_senior(mpusher, mpushee, mons_is_fleeing(mpusher)))
return (false);
return (true);
diff --git a/crawl-ref/source/quiver.cc b/crawl-ref/source/quiver.cc
index 12187347b1..315db5edcc 100644
--- a/crawl-ref/source/quiver.cc
+++ b/crawl-ref/source/quiver.cc
@@ -166,14 +166,19 @@ void choose_item_for_quiver()
: "hand crossbow");
return;
}
- else if (slot == you.equip[EQ_WEAPON])
+ else if (slot == you.equip[EQ_WEAPON]
+ && you.inv[slot].base_type == OBJ_WEAPONS
+ && (get_weapon_brand(you.inv[slot]) != SPWPN_RETURNING
+ || you.skills[SK_THROWING] == 0))
{
- mpr("You can't quiver wielded items.");
+ // Don't quiver a wielded weapon unless it's a weapon of returning
+ // and we've got some throwing skill.
+ mpr("You can't quiver wielded weapons.");
return;
}
else
{
- for (int i = 0; i < NUM_EQUIP; i++)
+ for (int i = EQ_CLOAK; i < NUM_EQUIP; i++)
{
if (you.equip[i] == slot)
{
@@ -320,8 +325,11 @@ void player_quiver::_maybe_fill_empty_slot()
// If we're wielding an item previously quivered, the quiver may need
// to be cleared. Else, any already quivered item is valid and we
// don't need to do anything else.
- if (m_last_used_of_type[slot].link == you.equip[EQ_WEAPON])
+ if (m_last_used_of_type[slot].link == you.equip[EQ_WEAPON]
+ && you.equip[EQ_WEAPON] == -1)
+ {
unquiver_weapon = true;
+ }
else
return;
}
@@ -332,8 +340,6 @@ void player_quiver::_maybe_fill_empty_slot()
const launch_retval desired_ret =
(weapon && is_range_weapon(*weapon)) ? LRET_LAUNCHED : LRET_THROWN;
-// const launch_retval desired_ret =
-// (slot == AMMO_THROW ? LRET_THROWN : LRET_LAUNCHED);
std::vector<int> order;
_get_fire_order(order, false, weapon);
@@ -398,9 +404,15 @@ void player_quiver::_get_fire_order( std::vector<int>& order,
if (!is_valid_item(item))
continue;
- // Don't quiver wielded weapon.
- if (you.equip[EQ_WEAPON] == i_inv)
+ // Don't quiver a wielded weapon unless it's a weapon of returning
+ // and we've got some throwing skill.
+ if (you.equip[EQ_WEAPON] == i_inv
+ && you.inv[i_inv].base_type == OBJ_WEAPONS
+ && (get_weapon_brand(you.inv[i_inv]) != SPWPN_RETURNING
+ || you.skills[SK_THROWING] == 0))
+ {
continue;
+ }
// Don't do anything if this item is not really fit for throwing.
if (is_launched(&you, you.weapon(), item) == LRET_FUMBLED)
diff --git a/crawl-ref/source/stash.cc b/crawl-ref/source/stash.cc
index caa4eed7d5..0b1002c5e3 100644
--- a/crawl-ref/source/stash.cc
+++ b/crawl-ref/source/stash.cc
@@ -908,7 +908,7 @@ void ShopInfo::describe_shop_item(const shop_item &si) const
item_def it = static_cast<item_def>(si.item);
describe_item( it );
- if ( oldflags != si.item.flags )
+ if (oldflags != si.item.flags)
const_cast<shop_item&>(si).item.flags = oldflags;
}
@@ -920,7 +920,7 @@ public:
menu_letter hotkey) : InvEntry(it.item)
{
text = item_name;
- add_hotkey(hotkey);
+ hotkeys[0] = hotkey;
}
};
@@ -930,8 +930,8 @@ bool ShopInfo::show_menu(const std::string &place,
StashMenu menu;
MenuEntry *mtitle = new MenuEntry(name + " (" + place, MEL_TITLE);
- menu.can_travel = can_travel;
- mtitle->quantity = items.size();
+ menu.can_travel = can_travel;
+ mtitle->quantity = items.size();
menu.set_title(mtitle);
menu_letter hotkey;
@@ -949,9 +949,9 @@ bool ShopInfo::show_menu(const std::string &place,
{
for (int i = 0, count = items.size(); i < count; ++i)
{
- MenuEntry *me = new ShopItemEntry(items[i],
- shop_item_name(items[i]),
- hotkey++);
+ ShopItemEntry *me = new ShopItemEntry(items[i],
+ shop_item_name(items[i]),
+ hotkey++);
menu.add_entry(me);
}
}