summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source
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 /crawl-ref/source
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
Diffstat (limited to 'crawl-ref/source')
-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
5 files changed, 89 insertions, 136 deletions
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;
}