diff options
-rw-r--r-- | crawl-ref/docs/crawl_options.txt | 15 | ||||
-rw-r--r-- | crawl-ref/init.txt | 2 | ||||
-rw-r--r-- | crawl-ref/source/dat/orc.des | 4 | ||||
-rw-r--r-- | crawl-ref/source/enum.h | 21 | ||||
-rw-r--r-- | crawl-ref/source/externs.h | 6 | ||||
-rw-r--r-- | crawl-ref/source/initfile.cc | 56 | ||||
-rw-r--r-- | crawl-ref/source/item_use.cc | 138 |
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; } |