git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@1847 c06c8d41-db1a-0410-9941-cceddc491573
4GFCF6N3MZSCHUB77Z3SQYJ3FYR5N3VBW2CGWANLJ74O5FEQH3CQC 2CKTZRWEVA5INSOXZ6H7675TAAA55TPNWYIVVUQWSCS5DYCANSFQC 5V47S4NNTHWTSAHV3YLO2VGH7JTUIYJ3GBPDN5ZM4UQALT2ZEXDQC K2CS6TCX2NDVL2ASEHGP4J4K4IJ6FP3ANNKTSIWVG43HPYSBX6ZQC IPB47Q5V3UZIUXP4CHHLYXA5UA4ETTNXJACUBD6YWVIYQDMCZNAAC RPOZZWKG5GLPHVZZ7ZKMKS64ZMV2LDCQSARBJFJ6FZOTOKCQO7FAC GT7BSR54BVJKHUCLEBTELGBMNBFFDQW52EVC4XKVEMUVG2UGZMDAC 2WNUWTZNE66IUUTQ4NW3RN7P2MFUKBXPD265M5CTZCDKC56VQONQC VNIAJEGE3PYE6F6EAMCQDWMAS52EQTKJUPAFXK7ARCITZ326WTTQC V4WGXVERZ34B7CEINV4D3ZYEKKT2TUIUYTOX5FSOX6B26U3DPVLQC SDLKLUNFGVKDS55DDJZCBAVIB7NL3RRYPTACAY65SCUQKV6APFSAC KU6YUIJWXZSNTABFB36HDEEZ6LTY7O4VKI3RNFBQE3LEYZCT3XQQC BWAQ3FHBBM6G3K3KYP75CRTR343RDQZJRYX5ZGYUEXYBAC3APDLAC H3552BCIAVBLKAYKE4DHFLBLFW5RGRMYBMRRYHYEB5IPIJRUVU5QC 2ZFV5PKZU3HDHMLJWVWPPFV43NUNUON6YSAITHB26D7L4XIVWUHQC EHSY6DVGUMI6C67WKET3GDJVLWJWGYBYQONNDK5JVT7BCTHBEZVAC RVST2QHYJ757ZHK4AUJ5NGPDZ44AD6RVFVXYPKQIBJXZBDNUCHXQC XPCGZBHHSL6MB3ORMUJI64BAERU6AZTIY6RK56BBW7SNB3IK24IAC // skip invalid objects, wielded objectif (!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);
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 ENDOFPACKstatic 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)
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 thrownif (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)
// look for next type on list... if found item is set != ENDOFPACKswitch (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] );}
const unsigned fire_flags = Options.fire_order[i];if ((item = find_fire_item_matching(fire_flags)) != ENDOFPACK)
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 breakif (item != ENDOFPACK)break;
}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 listconst 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;elsepos = end + 1;}
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 dartsfire_order[3] = FIRE_STONE; // and then chuck stones
set_fire_order("launcher, javelin / dart / stone");
}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);
int fire_items_start; // index of first item for fire commandFixedVector<fire_type, NUM_FIRE_TYPES> fire_order; // order for 'f' command
int fire_items_start; // index of first item for fire commandstd::vector<unsigned> fire_order; // missile search order for 'f' command
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
Items that appear first get higher priority.Items in any position may be slash-separated to indicate that theseare of equal priority. In the example, darts, stones and daggers areat the same priority, so the first item in your inventory that isone of these will be picked for firing.