summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordshaligram <dshaligram@c06c8d41-db1a-0410-9941-cceddc491573>2007-07-12 13:09:04 +0000
committerdshaligram <dshaligram@c06c8d41-db1a-0410-9941-cceddc491573>2007-07-12 13:09:04 +0000
commit6ff74508d47ca09bb7409b99a2d2075c3e8ca8a2 (patch)
treecef3ab6f75ece0b27e27c4d2d370681969dcfdca
parentd6c7e03e66c85a2236f38a7d0ce9ee71cab3dcbb (diff)
downloadcrawl-ref-6ff74508d47ca09bb7409b99a2d2075c3e8ca8a2.tar.gz
crawl-ref-6ff74508d47ca09bb7409b99a2d2075c3e8ca8a2.zip
[1752536] fire_order is now smarter.
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@1847 c06c8d41-db1a-0410-9941-cceddc491573
-rw-r--r--crawl-ref/docs/crawl_options.txt15
-rw-r--r--crawl-ref/init.txt2
-rw-r--r--crawl-ref/source/dat/orc.des4
-rw-r--r--crawl-ref/source/enum.h21
-rw-r--r--crawl-ref/source/externs.h6
-rw-r--r--crawl-ref/source/initfile.cc56
-rw-r--r--crawl-ref/source/item_use.cc138
7 files changed, 102 insertions, 140 deletions
diff --git a/crawl-ref/docs/crawl_options.txt b/crawl-ref/docs/crawl_options.txt
index 45229ea857..a5fdb148cf 100644
--- a/crawl-ref/docs/crawl_options.txt
+++ b/crawl-ref/docs/crawl_options.txt
@@ -920,13 +920,22 @@ item_stack_summary_minimum = 5
fire_items_start = a
Sets the first inventory item to consider. Default is a, many use c.
-fire_order = launcher, dart, stone, dagger, spear, handaxe, club
+fire_order = launcher, dart / stone / dagger, spear, handaxe, club
The list should be on one line of items, with commas between items.
+ Items that appear first get higher priority.
+
+ Items in any position may be slash-separated to indicate that these
+ are of equal priority. In the example, darts, stones and daggers are
+ at the same priority, so the first item in your inventory that is
+ one of these will be picked for firing.
+
'launcher' refers to firing the appropriate missile for the wielded
weapon (ie crossbow, bow, sling, blowgun). You'll almost certainly
want it first, as it'll be ignored when you're not wielding a ranged
- weapon. The default is
- fire_order = launcher, dart
+ weapon. The default is
+
+ fire_order = launcher, javelin / dart / stone
+
To quickly experiment with a weapon-throwing character - e.g. to
make your Berserker actually use those three spears he carries around,
try a line similar to:
diff --git a/crawl-ref/init.txt b/crawl-ref/init.txt
index e1c9a7c794..3663f7f409 100644
--- a/crawl-ref/init.txt
+++ b/crawl-ref/init.txt
@@ -198,7 +198,7 @@ message_colour = lightcyan:LOW MAGIC WARNING
##### 4-k Firing Commands #######################
#
# fire_items_start = a
-# fire_order = launcher, dart, stone, dagger, spear, handaxe, club
+# fire_order = launcher, dart / stone / javelin, dagger, spear, handaxe, club
##### 4-l Channels ##############################
#
diff --git a/crawl-ref/source/dat/orc.des b/crawl-ref/source/dat/orc.des
index d82565424c..af9d2575c4 100644
--- a/crawl-ref/source/dat/orc.des
+++ b/crawl-ref/source/dat/orc.des
@@ -401,10 +401,10 @@ TAGS: orc_entry
ORIENT: float
MONS: orc zombie/orc skeleton w:2/goblin zombie w:2/hobgoblin zombie w:2/goblin skeleton w:1/hobgoblin skeleton w:1
MONS: ogre zombie/troll zombie w:3/hill giant zombie w:1
-MONS: hungry ghost/phantom/wraith, orc sorcerer/orc priest
+MONS: hungry ghost/phantom/w:1 wraith, w:1 orc sorcerer/orc priest
SUBST: 4 = 34
SUBST: ? = x . $:1
-MAP
+DEPTH: 11
MAP
xxxxx..@..xxxxx
x21....I....12x
diff --git a/crawl-ref/source/enum.h b/crawl-ref/source/enum.h
index 9352571060..74041dab06 100644
--- a/crawl-ref/source/enum.h
+++ b/crawl-ref/source/enum.h
@@ -1307,17 +1307,16 @@ enum equipment_type
enum fire_type
{
- FIRE_NONE,
- FIRE_LAUNCHER,
- FIRE_DART,
- FIRE_STONE,
- FIRE_DAGGER,
- FIRE_JAVELIN,
- FIRE_SPEAR,
- FIRE_HAND_AXE,
- FIRE_CLUB,
- FIRE_ROCK,
- NUM_FIRE_TYPES
+ FIRE_NONE = 0x0000,
+ FIRE_LAUNCHER = 0x0001,
+ FIRE_DART = 0x0002,
+ FIRE_STONE = 0x0004,
+ FIRE_DAGGER = 0x0008,
+ FIRE_JAVELIN = 0x0010,
+ FIRE_SPEAR = 0x0020,
+ FIRE_HAND_AXE = 0x0040,
+ FIRE_CLUB = 0x0080,
+ FIRE_ROCK = 0x0100
};
enum flush_reason_type
diff --git a/crawl-ref/source/externs.h b/crawl-ref/source/externs.h
index 4ac5b302c0..90a73f833d 100644
--- a/crawl-ref/source/externs.h
+++ b/crawl-ref/source/externs.h
@@ -1633,8 +1633,8 @@ public:
bool macro_meta_entry; // Allow user to use numeric sequences when
// creating macros
- int fire_items_start; // index of first item for fire command
- FixedVector<fire_type, NUM_FIRE_TYPES> fire_order; // order for 'f' command
+ int fire_items_start; // index of first item for fire command
+ std::vector<unsigned> fire_order; // missile search order for 'f' command
bool auto_list; // automatically jump to appropriate item lists
@@ -1844,6 +1844,8 @@ private:
const std::string &interrupt_names,
bool append_interrupts,
bool remove_interrupts);
+ void set_fire_order(const std::string &full);
+ void add_fire_order_slot(const std::string &s);
void set_menu_sort(std::string field);
void new_dump_fields(const std::string &text, bool add = true);
void do_kill_map(const std::string &from, const std::string &to);
diff --git a/crawl-ref/source/initfile.cc b/crawl-ref/source/initfile.cc
index bcf373e371..cf7466b49a 100644
--- a/crawl-ref/source/initfile.cc
+++ b/crawl-ref/source/initfile.cc
@@ -255,37 +255,16 @@ static fire_type str_to_fire_types( const std::string &str )
return (FIRE_DAGGER);
else if (str == "spear")
return (FIRE_SPEAR);
- else if (str == "hand axe" || str == "handaxe")
+ else if (str == "hand axe" || str == "handaxe" || str == "axe")
return (FIRE_HAND_AXE);
else if (str == "club")
return (FIRE_CLUB);
+ else if (str == "javelin")
+ return (FIRE_JAVELIN);
return (FIRE_NONE);
}
-static void str_to_fire_order( const std::string &str,
- FixedVector< fire_type, NUM_FIRE_TYPES > &list )
-{
- int i;
- size_t pos = 0;
- std::string item = "";
-
- for (i = 0; i < NUM_FIRE_TYPES; i++)
- {
- // get next item from comma delimited list
- const size_t end = str.find( ',', pos );
- item = str.substr( pos, end - pos );
- trim_string( item );
-
- list[i] = str_to_fire_types( item );
-
- if (end == std::string::npos)
- break;
- else
- pos = end + 1;
- }
-}
-
static char str_to_race( const std::string &str )
{
int index = -1;
@@ -712,13 +691,7 @@ void game_options::reset_options()
fire_items_start = 0; // start at slot 'a'
// Clear fire_order and set up the defaults.
- for (int i = 0; i < NUM_FIRE_TYPES; i++)
- fire_order[i] = FIRE_NONE;
-
- fire_order[0] = FIRE_LAUNCHER; // fire first from bow...
- fire_order[1] = FIRE_JAVELIN;
- fire_order[2] = FIRE_DART; // then only consider darts
- fire_order[3] = FIRE_STONE; // and then chuck stones
+ set_fire_order("launcher, javelin / dart / stone");
item_stack_summary_minimum = 5;
@@ -838,6 +811,25 @@ static unsigned read_symbol(std::string s)
return (strtoul(s.c_str(), &tail, base));
}
+void game_options::set_fire_order(const std::string &s)
+{
+ fire_order.clear();
+ std::vector<std::string> slots = split_string(",", s);
+ for (int i = 0, size = slots.size(); i < size; ++i)
+ add_fire_order_slot(slots[i]);
+}
+
+void game_options::add_fire_order_slot(const std::string &s)
+{
+ unsigned flags = 0;
+ std::vector<std::string> alts = split_string("/", s);
+ for (int i = 0, size = alts.size(); i < size; ++i)
+ flags |= str_to_fire_types(alts[i]);
+
+ if (flags)
+ fire_order.push_back(flags);
+}
+
void game_options::add_feature_override(const std::string &text)
{
std::string::size_type epos = text.rfind("}");
@@ -1766,7 +1758,7 @@ void game_options::read_option_line(const std::string &str, bool runscript)
}
else if (key == "fire_order")
{
- str_to_fire_order( field, fire_order );
+ set_fire_order(field);
}
else if (key == "random_pick")
{
diff --git a/crawl-ref/source/item_use.cc b/crawl-ref/source/item_use.cc
index 17c5f8d091..43ae1f47d4 100644
--- a/crawl-ref/source/item_use.cc
+++ b/crawl-ref/source/item_use.cc
@@ -1116,59 +1116,66 @@ void throw_anything(void)
throw_it(beam, throw_slot);
} // end throw_anything()
-// Return index of first valid balanced throwing weapon or ENDOFPACK
-static int try_finding_throwing_weapon( int sub_type )
+static bool fire_item_matches(const item_def &item, unsigned fire_type)
{
- int i;
-
- for (i = Options.fire_items_start; i < ENDOFPACK; i++)
+ if (!is_valid_item(item))
+ return (false);
+
+ if (item.base_type == OBJ_MISSILES)
{
- // skip invalid objects, wielded object
- if (!is_valid_item( you.inv[i] ) || you.equip[EQ_WEAPON] == i)
- continue;
+ if ((fire_type & FIRE_DART) && item.sub_type == MI_DART)
+ return (true);
+ if ((fire_type & FIRE_STONE)
+ && (item.sub_type == MI_STONE || item.sub_type == MI_SLING_BULLET))
+ return (true);
+ if ((fire_type & FIRE_JAVELIN) && item.sub_type == MI_JAVELIN)
+ return (true);
+ if ((fire_type & FIRE_ROCK) && item.sub_type == MI_LARGE_ROCK)
+ return (true);
- // consider melee weapons that can also be thrown
- if (you.inv[i].base_type == OBJ_WEAPONS
- && you.inv[i].sub_type == sub_type)
+ if (fire_type & FIRE_LAUNCHER)
{
- break;
+ const item_def *weapon = you.weapon();
+ if (weapon && item.launched_by(*weapon))
+ return (true);
}
}
-
- return (i);
+ else if (item.base_type == OBJ_WEAPONS
+ && is_throwable(item, you.body_size()))
+ {
+ if ((fire_type & FIRE_DAGGER) && item.sub_type == WPN_DAGGER)
+ return (true);
+ if ((fire_type & FIRE_SPEAR) && item.sub_type == WPN_SPEAR)
+ return (true);
+ if ((fire_type & FIRE_HAND_AXE) && item.sub_type == WPN_HAND_AXE)
+ return (true);
+ if ((fire_type & FIRE_CLUB) && item.sub_type == WPN_CLUB)
+ return (true);
+ }
+ return (false);
}
-// Return index of first missile of sub_type or ENDOFPACK
-static int try_finding_missile( int sub_type, const item_def *launcher = NULL )
+static int find_fire_item_matching(unsigned fire_type_flags, int start = 0)
{
- int i;
-
- for (i = Options.fire_items_start; i < ENDOFPACK; i++)
+ for (int i = start; i < ENDOFPACK; ++i)
{
- // skip invalid objects
- if (!is_valid_item( you.inv[i] ))
+ if (i < Options.fire_items_start)
continue;
-
- const item_def &item = you.inv[i];
- // In theory, we should do two passes, first trying
- // to find a non-warning-inscribed item, then looping
- // through the warning-inscribed ones. Seems unlikely
- // to matter much.
-
- if (launcher && item.launched_by(*launcher))
- break;
-
- // consider melee weapons that can also be thrown
- if (item.base_type == OBJ_MISSILES
- && (item.sub_type == sub_type
- || (sub_type == MI_STONE && item.sub_type == MI_SLING_BULLET))
+ if (fire_item_matches(you.inv[i], fire_type_flags)
&& check_warning_inscriptions(you.inv[i], OPER_FIRE))
- {
- break;
- }
+ return (i);
}
- return (i);
+ for (int i = 0; i < start; ++i)
+ {
+ if (i < Options.fire_items_start)
+ continue;
+ if (fire_item_matches(you.inv[i], fire_type_flags)
+ && check_warning_inscriptions(you.inv[i], OPER_FIRE))
+ return (i);
+ }
+
+ return (ENDOFPACK);
}
// Note: This is a simple implementation, not an efficient one. -- bwr
@@ -1177,58 +1184,11 @@ static int try_finding_missile( int sub_type, const item_def *launcher = NULL )
int get_fire_item_index( void )
{
int item = ENDOFPACK;
- const int weapon = you.equip[ EQ_WEAPON ];
- for (int i = 0; i < NUM_FIRE_TYPES; i++)
+ for (unsigned i = 0; i < Options.fire_order.size(); i++)
{
- // look for next type on list... if found item is set != ENDOFPACK
- switch (Options.fire_order[i])
- {
- case FIRE_LAUNCHER:
- // check if we have ammo for a wielded launcher:
- if (weapon != -1
- && you.inv[ weapon ].base_type == OBJ_WEAPONS
- && is_range_weapon( you.inv[ weapon ] ))
- {
- item = try_finding_missile( MI_NONE, &you.inv[weapon] );
- }
- break;
-
- case FIRE_DART:
- item = try_finding_missile( MI_DART );
- break;
-
- case FIRE_STONE:
- item = try_finding_missile( MI_STONE );
- break;
-
- case FIRE_JAVELIN:
- item = try_finding_missile( MI_JAVELIN );
- break;
-
- case FIRE_DAGGER:
- item = try_finding_throwing_weapon( WPN_DAGGER );
- break;
-
- case FIRE_SPEAR:
- item = try_finding_throwing_weapon( WPN_SPEAR );
- break;
-
- case FIRE_HAND_AXE:
- item = try_finding_throwing_weapon( WPN_HAND_AXE );
- break;
-
- case FIRE_CLUB:
- item = try_finding_throwing_weapon( WPN_CLUB );
- break;
-
- case FIRE_NONE:
- default:
- break;
- }
-
- // if successful break
- if (item != ENDOFPACK)
+ const unsigned fire_flags = Options.fire_order[i];
+ if ((item = find_fire_item_matching(fire_flags)) != ENDOFPACK)
break;
}