Be a bit more generous regarding books for Evoc and Invoc types.
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@8890 c06c8d41-db1a-0410-9941-cceddc491573
OE3TD4J5FSIFAM37J2UPEV7QQNXLSZM6GDUMPI66LC5LW2OM2J4AC RUQVAI734QP35FKCUOPWHBY7C63BDOLNMJ3P5I5BLM7N34ZSCAJQC YDWBT7CZGY33CNDPF7S4LK7YULFMDUJAKIODKMGB2IYIWHF4SJWQC CIZ6TVSDTU7YJI3DGHNSC2SHGMEGT5AXSEO5X65EUD7UW5FPGQDAC 6ZZO2QBB46RZM6OXVS7OIKC5M3SEAULSSJFXW5PJG556JDKKUHWAC K2CS6TCX2NDVL2ASEHGP4J4K4IJ6FP3ANNKTSIWVG43HPYSBX6ZQC NW6P7VRKBFBQ2FRDZBXN7APJZPYC4SYCIA3MOOE2KZGX43IXNK2AC Q3DNEB5OOJ34P5ML4CMK3L6SCP7RLW7DDOZEG24KZBX3C7BJRQDAC DTO3EUKWHZ5RJNGNCFYXSOVTIPVXPP637F2W7WFGYKJ7JK7VNKNQC 7YUGK5Q64KG5O7GJGTUBRRLHAHBCJ5YOE23YUPT6UBKUSB67CYAQC SVY2PTCLXR3KNPQAWXVXTTGCC5DR334HOAKHYO3VDDRWM2BWMALAC RPOZZWKG5GLPHVZZ7ZKMKS64ZMV2LDCQSARBJFJ6FZOTOKCQO7FAC 2YLX45THVAG2ICWFAOANL3BQQBYMPQV36EY73TYCWA336RVW7KGQC 52XHD5LKS6UVLXBYUXMPTMVMTXQ6FBUFXJ2TAW6R7CSJY7OXWVJAC 75M6AVUSS3G5EJECJJRB67V5UYDOIV26FZNB2FFCMBZ33EK7FVIQC 557IY36VX2M4ERVCP5HNI3YTHHVTHPETZ5RWDX5BKDKXXIYCFUJAC 4FQAKUKUO6PCAZ3N4HUR5XL6E4VA5UQUZ3AEDGRBLVY7W2LMWI7QC P2ZCF3BBG523ZEOD6XQA4X5YEHBTWH3IM33YVHXP2SQ5POXZIH4QC 7V4DCKFJCNBXFODMKJ6H3MCDUTSD4XVQ7D4D6XFCD4JNF4HCE4KAC 2W34FMSGJ2BZY7QQM6X6RTVRXXI2H72Z2MH75SU3SDL4FN4G74KAC LUNOTEIMYZJ7JL5P55GEHUVSDEZMYX3TWYUB2ABRHAYJEWQSSXIAC 3ZWALZFSTSIVYXY4BAY6ANGINTDACZC6RSSJTEMQSTSUIE66YOBQC VCQYSNAWZZHOZMARWQ4AJBDNFSS7T7CZBQISSPZ2YIIK5PVAWPRQC VD4KDTGHVKCN35AWREYB4TEOUMCTW7SAUPAMTMF5ABC7VBHVKP4AC FIYBXLWALQINNQTHG2KNDUUTAQAZRDDLXW2XOVSKDKBADJ3XCJ4AC RZLMIEOHITWGYNVBHDVVWS24YQ5SD5HG3T3JCMIBCD2VA5TEPHCQC SJP5BHX6MFWF3OSQPEF4WUWZWPUGMOVURTT2CUVT6H3A66LETXUAC JZ4YC57SR2WQJIEIZSO3ZECA2FNMQUB7JYFKID4SIQ3RQ5NYXIVAC 64VBM7SGUX7CVO5TMVOFU4A26BDOFQXKS6G5K7BXCSWKCCXEETOAC SDLKLUNFGVKDS55DDJZCBAVIB7NL3RRYPTACAY65SCUQKV6APFSAC VJZ4D26E4L4E22SO6UYB44DNUTLG72LA4GTAEZ2DKKEMAICHOXBQC 45CXZWWXI7SGKLHVSRP2U6KNXJBT2XADNLIIHQQJYL2E6QWNURKQC KQNIGKATHT4YSPJFPJGIGPD6VNR5B753SE2JN2LCXZZJNHCGY3DQC QG7MKYZECIRDJJZKVRFI6XTCH42GTKA55BFIWPJBQZ27CZVLUJDQC OQ4KB7QCJSK7GSW3DYBARH4DCB75HFKLUSOSOZZZ4IUFKNGFRUDQC YCL3W2PFE6ILTGBFODCSXNPDIA46KVSZP2TI7HDMYAOEJT65RIEAC CCRQESB4ADT4WA7FGLNZZXAJ6G5QMCTYCZIWORBN45P6ZPILC34AC OFH2B2UZBK43QLFQBZ54FOCFLFNE54BZVDNCEUGDTBCUGNVZULIQC P6JHIG4GFZEBV3XFKWZMZRUD6PJWQKNPG6CUNIWBYV3WHBY73ONQC SWT4O2TCOAQOVFA6WRA7MCU3KMTMJWFEMIHO64N4PWL5FNHDPADAC V53DXVC5T3N6J47H2CNG4MMPRR4PHW4AIS66QNVTKJNNYTTTQL4AC KNO4TZR76DMOYJCF24PSVQW7FUZOTMOJTL7I7J74SM4IHOGDX6TAC // last_updated 24may2000 {dlb}/* ************************************************************************ called from: acr - chardump - effects - files - player - skills -* skills2 - stuff* *********************************************************************** */
case TRAP_BLADE:return (10 + random2(30));case TRAP_DART:return (random2(4));case TRAP_ARROW:return (random2(7));case TRAP_SPEAR:return (random2(10));case TRAP_BOLT:return (random2(13));case TRAP_AXE:return (random2(15));default:return (0);
case TRAP_BLADE: return (10 + random2(30));case TRAP_DART: return (random2(4));case TRAP_ARROW: return (random2(7));case TRAP_SPEAR: return (random2(10));case TRAP_BOLT: return (random2(13));case TRAP_AXE: return (random2(15));default: return (0);
ASSERT(class_wanted != OBJ_RANDOM);
// Increasing the representation of the non-body armour// slots here to make up for the fact that there's one// one type of item for most of them. -- bwr//// NUM_ARMOURS is body armour and handled belowarmour_type result = (coinflip()) ? NUM_ARMOURS: _random_nonbody_armour_type();
int type_wanted = OBJ_RANDOM;int iteration = 0;
// Some species specific fitting problems.// FIXME: switch to the cleaner logic in can_wear_armour()switch (you.species){case SP_OGRE:case SP_TROLL:case SP_RED_DRACONIAN:case SP_WHITE_DRACONIAN:case SP_GREEN_DRACONIAN:case SP_YELLOW_DRACONIAN:case SP_GREY_DRACONIAN:case SP_BLACK_DRACONIAN:case SP_PURPLE_DRACONIAN:case SP_MOTTLED_DRACONIAN:case SP_PALE_DRACONIAN:case SP_BASE_DRACONIAN:case SP_SPRIGGAN:if (result == ARM_GLOVES|| result == ARM_BOOTS|| result == ARM_CENTAUR_BARDING|| result == ARM_NAGA_BARDING){result = ARM_ROBE; // no heavy armour}else if (result == ARM_SHIELD){if (you.species == SP_SPRIGGAN)result = ARM_BUCKLER;else if (coinflip()) // giant races: 50/50 shield/large shieldresult = ARM_LARGE_SHIELD;}else if (result == NUM_ARMOURS){result = ARM_ROBE; // no heavy armour, see below}break;
int spell_skills = 0;for (int i = SK_SPELLCASTING; i <= SK_POISON_MAGIC; i++)spell_skills += you.skills[i];for (int acqc = 0; acqc < ENDOFPACK; acqc++)
// Mutation specific problems (horns allow caps).if (result == ARM_BOOTS && !player_has_feet()|| result == ARM_GLOVES && you.has_claws(false) >= 3)
if (is_valid_item( you.inv[acqc] )&& you.inv[acqc].base_type == class_wanted){ASSERT( you.inv[acqc].sub_type < max_has_value );already_has[you.inv[acqc].sub_type] += you.inv[acqc].quantity;}
result = NUM_ARMOURS;
if (class_wanted == OBJ_FOOD)
// Do this here, before acquirement()'s call to can_wear_armour(),// so that caps will be just as common as helmets for those// that can't wear helmets.// We check for the mutation directly to avoid acquirement fiddles// with vampires.if (result == ARM_HELMET&& (!you_can_wear(EQ_HELMET) || you.mutation[MUT_HORNS]))
if (you.species == SP_GHOUL){type_wanted = one_chance_in(10) ? FOOD_ROYAL_JELLY: FOOD_CHUNK;}else if (you.species == SP_VAMPIRE){// Vampires really don't want any OBJ_FOOD but OBJ_CORPSES// but it's easier to just give them a potion of blood// class type is set elsewheretype_wanted = POT_BLOOD;quantity = 2 + random2(4);}
// Now we'll randomly pick a body armour (light only in the// case of ARM_ROBE). Unlike before, now we're only giving// out the finished products here, never the hides. -- bwrif (result == NUM_ARMOURS || result == ARM_ROBE){// start with normal base armourif (result == ARM_ROBE)result = coinflip() ? ARM_ROBE : ARM_ANIMAL_SKIN;
// Meat is better than bread (except for herbivores), and// by choosing it as the default we don't have to worry// about special cases for carnivorous races (e.g. kobolds)type_wanted = FOOD_MEAT_RATION;
result = static_cast<armour_type>(ARM_ROBE + random2(8));
// If we have some regular rations, then we're probably more// interested in faster foods (especially royal jelly)...// otherwise the regular rations should be a good enough offer.if (already_has[FOOD_MEAT_RATION]+ already_has[FOOD_BREAD_RATION] >= 2 || coinflip()){type_wanted = one_chance_in(5) ? FOOD_HONEYCOMB: FOOD_ROYAL_JELLY;}
if (one_chance_in(10))result = ARM_ANIMAL_SKIN;
quantity = 3 + random2(5);// giving more of the lower food value itemsif (type_wanted == FOOD_HONEYCOMB || type_wanted == FOOD_CHUNK)
// everyone can wear things made from hidesif (one_chance_in(20))
quantity += random2avg(10, 2);
result = static_cast<armour_type>(random_choose_weighted(20, ARM_TROLL_LEATHER_ARMOUR,20, ARM_STEAM_DRAGON_ARMOUR,15, ARM_MOTTLED_DRAGON_ARMOUR,15, ARM_SWAMP_DRAGON_ARMOUR,10, ARM_DRAGON_ARMOUR,10, ARM_ICE_DRAGON_ARMOUR,5, ARM_STORM_DRAGON_ARMOUR,5, ARM_GOLD_DRAGON_ARMOUR,0));
// Adding a small constant allows for the occasional// weapon in an untrained skill.
// Write results into arguments.void _acquirement_determine_food(int& type_wanted, int& quantity,const has_vector& already_has){// food is a little less predictable now -- bwrif (you.species == SP_GHOUL)type_wanted = one_chance_in(10) ? FOOD_ROYAL_JELLY : FOOD_CHUNK;else if (you.species == SP_VAMPIRE){// Vampires really don't want any OBJ_FOOD but OBJ_CORPSES// but it's easier to just give them a potion of blood// class type is set elsewheretype_wanted = POT_BLOOD;quantity = 2 + random2(4);}else{// Meat is better than bread (except for herbivores), and// by choosing it as the default we don't have to worry// about special cases for carnivorous races (e.g. kobolds)type_wanted = FOOD_MEAT_RATION;
if (x_chance_in_y(weight, count))skill = i;
// If we have some regular rations, then we're probably more// interested in faster foods (especially royal jelly)...// otherwise the regular rations should be a good enough offer.if (already_has[FOOD_MEAT_RATION]+ already_has[FOOD_BREAD_RATION] >= 2 || coinflip()){type_wanted = one_chance_in(5) ? FOOD_HONEYCOMB: FOOD_ROYAL_JELLY;
item_def item_considered;item_considered.base_type = OBJ_WEAPONS;for (int i = 0; i < NUM_WEAPONS; ++i){item_considered.sub_type = i;
// giving more of the lower food value itemsif (type_wanted == FOOD_HONEYCOMB || type_wanted == FOOD_CHUNK){quantity += random2avg(10, 2);}}
const int acqweight = property(item_considered, PWPN_ACQ_WEIGHT);
static int _acquirement_weapon_subtype(){// Asking for a weapon is biased towards your skills.// First pick a skill, weighting towards those you have.int count = 0;int skill = SK_FIGHTING;
int wskill = range_skill(OBJ_WEAPONS, i);if (wskill == SK_THROWING)wskill = weapon_skill(OBJ_WEAPONS, i);
// Adding a small constant allows for the occasional// weapon in an untrained skill.
if (wskill == skill && x_chance_in_y(acqweight, count += acqweight))type_wanted = i;}
const int weight = you.skills[i] + 1;count += weight;if (x_chance_in_y(weight, count))skill = i;
for (int i = SK_SLINGS; i <= SK_DARTS; i++){if (you.skills[i]){count += you.skills[i];if (x_chance_in_y(you.skills[i], count))skill = i;}}
switch (skill){case SK_SLINGS:type_wanted = MI_STONE;break;
// Now choose a subtype which uses that skill.int result = OBJ_RANDOM;count = 0;item_def item_considered;item_considered.base_type = OBJ_WEAPONS;for (int i = 0; i < NUM_WEAPONS; ++i){item_considered.sub_type = i;
case SK_CROSSBOWS:type_wanted = MI_DART;for (int i = 0; i < ENDOFPACK; i++){// Assuming that crossbow in inventory means that they// want bolts for it (not darts for a hand crossbow)...// perhaps we should check for both and compare ammo// amounts on hand?if (is_valid_item( you.inv[i] )&& you.inv[i].base_type == OBJ_WEAPONS&& you.inv[i].sub_type == WPN_CROSSBOW){type_wanted = MI_BOLT;break;}}break;
if (!acqweight)continue;
case SK_DARTS:type_wanted = MI_DART;for (int i = 0; i < ENDOFPACK; i++){if (is_valid_item( you.inv[i] )&& you.inv[i].base_type == OBJ_WEAPONS&& you.inv[i].sub_type == WPN_BLOWGUN){// Assuming that blowgun in inventory means that they// may want needles for it (but darts might also be// wanted). Maybe expand this... see above comment.if (coinflip())type_wanted = MI_NEEDLE;break;}}break;
int wskill = range_skill(OBJ_WEAPONS, i);if (wskill == SK_THROWING)wskill = weapon_skill(OBJ_WEAPONS, i);
else if (class_wanted == OBJ_ARMOUR){// Increasing the representation of the non-body armour// slots here to make up for the fact that there's one// one type of item for most of them. -- bwr//// OBJ_RANDOM is body armour and handled belowtype_wanted = (coinflip())? OBJ_RANDOM :static_cast<int>(_random_nonbody_armour_type());
return (result);}
// Some species specific fitting problems.switch (you.species)
static bool _have_item_with_types(object_class_type basetype, int subtype){for (int i = 0; i < ENDOFPACK; i++){const item_def& item = you.inv[i];if (is_valid_item(item)&& item.base_type == basetype && item.sub_type == subtype)
case SP_OGRE:case SP_TROLL:case SP_RED_DRACONIAN:case SP_WHITE_DRACONIAN:case SP_GREEN_DRACONIAN:case SP_YELLOW_DRACONIAN:case SP_GREY_DRACONIAN:case SP_BLACK_DRACONIAN:case SP_PURPLE_DRACONIAN:case SP_MOTTLED_DRACONIAN:case SP_PALE_DRACONIAN:case SP_BASE_DRACONIAN:case SP_SPRIGGAN:if (type_wanted == ARM_GLOVES || type_wanted == ARM_BOOTS|| type_wanted == ARM_CENTAUR_BARDING|| type_wanted == ARM_NAGA_BARDING){type_wanted = ARM_ROBE; // no heavy armour}else if (type_wanted == ARM_SHIELD){if (you.species == SP_SPRIGGAN)type_wanted = ARM_BUCKLER;else if (coinflip()) // giant races: 50/50 shield/large shieldtype_wanted = ARM_LARGE_SHIELD;}else if (type_wanted == OBJ_RANDOM){type_wanted = ARM_ROBE; // no heavy armour, see below}break;case SP_NAGA:if (type_wanted == ARM_BOOTS || type_wanted == ARM_CENTAUR_BARDING)type_wanted = ARM_NAGA_BARDING;break;case SP_CENTAUR:if (type_wanted == ARM_BOOTS || type_wanted == ARM_NAGA_BARDING)type_wanted = ARM_CENTAUR_BARDING;break;default:if (type_wanted == ARM_CENTAUR_BARDING|| type_wanted == ARM_NAGA_BARDING){type_wanted = ARM_BOOTS;}break;
return (true);
// Mutation specific problems (horns allow caps).if (type_wanted == ARM_BOOTS && !player_has_feet()|| type_wanted == ARM_GLOVES && you.has_claws(false) >= 3){type_wanted = OBJ_RANDOM;}
static missile_type _acquirement_missile_subtype(){int count = 0;int skill = SK_THROWING;
// Do this here, before acquirement()'s call to can_wear_armour(),// so that caps will be just as common as helmets for those// that can't wear helmets.// We check for the mutation directly to avoid acquirement fiddles// with vampires.if (type_wanted == ARM_HELMET&& (!you_can_wear(EQ_HELMET) || you.mutation[MUT_HORNS]))
for (int i = SK_SLINGS; i <= SK_DARTS; i++){if (you.skills[i])
// Now we'll randomly pick a body armour (light only in the// case of ARM_ROBE). Unlike before, now we're only giving// out the finished products here, never the hides. -- bwrif (type_wanted == OBJ_RANDOM || type_wanted == ARM_ROBE){// start with normal base armourif (type_wanted == ARM_ROBE)type_wanted = coinflip() ? ARM_ROBE : ARM_ANIMAL_SKIN;else{type_wanted = ARM_ROBE + random2(8);
missile_type result = MI_DART;
if (one_chance_in(10))type_wanted = ARM_ANIMAL_SKIN;}
case SK_CROSSBOWS:// Assuming that crossbow in inventory means that they// want bolts for it (not darts for a hand crossbow)...// perhaps we should check for both and compare ammo// amounts on hand?result = (_have_item_with_types(OBJ_WEAPONS, WPN_CROSSBOW) ? MI_BOLT: MI_DART);break;
// everyone can wear things made from hidesif (one_chance_in(20)){int rnd = random2(20);
case SK_DARTS:// Assuming that blowgun in inventory means that they// may want needles for it (but darts might also be// wanted). Maybe expand this... see above comment.result =(_have_item_with_types(OBJ_WEAPONS, WPN_BLOWGUN) && coinflip())? MI_NEEDLE : MI_DART;break;
type_wanted = (rnd < 4) ? ARM_TROLL_LEATHER_ARMOUR : // 20%(rnd < 8) ? ARM_STEAM_DRAGON_ARMOUR : // 20%(rnd < 11) ? ARM_MOTTLED_DRAGON_ARMOUR : // 15%(rnd < 14) ? ARM_SWAMP_DRAGON_ARMOUR : // 15%(rnd < 16) ? ARM_DRAGON_ARMOUR : // 10%(rnd < 18) ? ARM_ICE_DRAGON_ARMOUR : // 10%(rnd < 19) ? ARM_STORM_DRAGON_ARMOUR // 5%: ARM_GOLD_DRAGON_ARMOUR; // 5%}}
default:break;
unsigned char i;switch (class_wanted){case OBJ_JEWELLERY:// Try for a base type the player hasn't identifiedfor (i = 0; i < 10; i++){type_wanted = random2(24);
result = AMU_FIRST_AMULET+ random2(NUM_JEWELLERY - AMU_FIRST_AMULET);}else{result = random2(NUM_RINGS);}
case OBJ_BOOKS:// Remember, put rarer books higher in the list.iteration = 1;type_wanted = NUM_BOOKS;
static int _choose_first_unseen_book(int first, ...){va_list args;va_start(args, first);
switch (best_spell){default:case SK_SPELLCASTING:if (you.skills[SK_SPELLCASTING] <= 3&& !you.had_book[BOOK_CANTRIPS]){// Handful of level one spells, very useful for the// new spellcaster who's asking for a book -- bwrtype_wanted = BOOK_CANTRIPS;}else if (!you.had_book[BOOK_MINOR_MAGIC_I])type_wanted = BOOK_MINOR_MAGIC_I + random2(3);else if (!you.had_book[BOOK_WIZARDRY])type_wanted = BOOK_WIZARDRY;else if (!you.had_book[BOOK_CONTROL])type_wanted = BOOK_CONTROL;else if (!you.had_book[BOOK_POWER])type_wanted = BOOK_POWER;break;
while (nargs-- > 0){const int another = va_arg(args, int);if (another == NUM_BOOKS || !you.had_book[another]){va_end(args);return (another);}}
case SK_SUMMONINGS:if (!you.had_book[BOOK_CALLINGS])type_wanted = BOOK_CALLINGS;else if (!you.had_book[BOOK_SUMMONINGS])type_wanted = BOOK_SUMMONINGS;
skill_type best_spell_skill = SK_NONE;// Do two iterations: one with the best spell skill, one with// the second-best.for (int i = 0; i < 2; ++i){// FIXME: Assumes that SK_POISON_MAGIC is the last spell skill.best_spell_skill = best_skill(SK_SPELLCASTING, SK_POISON_MAGIC,best_spell_skill);switch (best_spell_skill){default:case SK_SPELLCASTING:if (you.skills[SK_SPELLCASTING] <= 3&& !you.had_book[BOOK_CANTRIPS]){// Handful of level one spells, very useful for the// new spellcaster who's asking for a book -- bwrresult = BOOK_CANTRIPS;}else{result = _choose_first_unseen_book(BOOK_MINOR_MAGIC_I,BOOK_WIZARDRY,BOOK_CONTROL,BOOK_POWER,NUM_BOOKS);if (result == BOOK_MINOR_MAGIC_I)result += random2(3);}break;
// So many enchantment books! I really can't feel// guilty at all for dividing out the fighting// books and forcing the player to raise a fighting// skill (or enchantments in the case of Crusaders)// to get the remaining books... enchantments are// much too good (most spells, lots of books here,// id wand charges, gives magic resistance),// something will eventually have to be done. -- bwrif (best_any >= SK_FIGHTING && best_any <= SK_STAVES){// Fighter mages get the fighting enchantment booksif (!you.had_book[BOOK_WAR_CHANTS])type_wanted = BOOK_WAR_CHANTS;else if (!you.had_book[BOOK_TUKIMA])type_wanted = BOOK_TUKIMA;}else if (!you.had_book[BOOK_CHARMS])type_wanted = BOOK_CHARMS;else if (!you.had_book[BOOK_HINDERANCE])type_wanted = BOOK_HINDERANCE;else if (!you.had_book[BOOK_ENCHANTMENTS])type_wanted = BOOK_ENCHANTMENTS;break;
case SK_AIR_MAGIC:result = _choose_first_unseen_book(BOOK_AIR, BOOK_SKY, NUM_BOOKS);break;
case SK_CONJURATIONS:if (!you.had_book[BOOK_CONJURATIONS_I])type_wanted = give_first_conjuration_book();else if (!you.had_book[BOOK_TEMPESTS])type_wanted = BOOK_TEMPESTS;
case SK_ICE_MAGIC:result = _choose_first_unseen_book(BOOK_FROST, BOOK_ICE, NUM_BOOKS);break;
// now a Vehumet special -- bwr// else if (!you.had_book[BOOK_ANNIHILATIONS])// type_wanted = BOOK_ANNIHILATIONS;break;
case SK_FIRE_MAGIC:result = _choose_first_unseen_book(BOOK_FLAMES, BOOK_FIRE,NUM_BOOKS);break;
case SK_NECROMANCY:if (!you.had_book[BOOK_NECROMANCY])type_wanted = BOOK_NECROMANCY;else if (!you.had_book[BOOK_DEATH])type_wanted = BOOK_DEATH;else if (!you.had_book[BOOK_UNLIFE])type_wanted = BOOK_UNLIFE;
case SK_SUMMONINGS:// Don't give Demonology, that's a Vehumet special.result = _choose_first_unseen_book(BOOK_CALLINGS, BOOK_SUMMONINGS,NUM_BOOKS);break;
case SK_TRANSLOCATIONS:if (!you.had_book[BOOK_SPATIAL_TRANSLOCATIONS])type_wanted = BOOK_SPATIAL_TRANSLOCATIONS;else if (!you.had_book[BOOK_WARP])type_wanted = BOOK_WARP;break;
// So many enchantment books! I really can't feel// guilty at all for dividing out the fighting// books and forcing the player to raise a fighting// skill (or enchantments in the case of Crusaders)// to get the remaining books... enchantments are// much too good (most spells, lots of books here,// id wand charges, gives magic resistance),// something will eventually have to be done. -- bwrif (best_any >= SK_FIGHTING && best_any <= SK_STAVES){// Fighter mages get the fighting enchantment booksresult = _choose_first_unseen_book(BOOK_WAR_CHANTS, BOOK_TUKIMA,NUM_BOOKS);}else{result = _choose_first_unseen_book(BOOK_CHARMS, BOOK_HINDERANCE,BOOK_ENCHANTMENTS,NUM_BOOKS);}break;}
case SK_TRANSMUTATION:if (!you.had_book[BOOK_CHANGES])type_wanted = BOOK_CHANGES;else if (!you.had_book[BOOK_TRANSFIGURATIONS])type_wanted = BOOK_TRANSFIGURATIONS;else if (!you.had_book[BOOK_MUTATIONS])type_wanted = BOOK_MUTATIONS;break;
case SK_CONJURATIONS:// Don't give Annihilations, that's a Vehumet special.result = _choose_first_unseen_book(BOOK_CONJURATIONS_I,BOOK_TEMPESTS, NUM_BOOKS);if (result == BOOK_CONJURATIONS_I)result = give_first_conjuration_book();break;
case SK_DIVINATIONS: //jmf: added 24mar2000if (!you.had_book[BOOK_SURVEYANCES])type_wanted = BOOK_SURVEYANCES;else if (!you.had_book[BOOK_DIVINATIONS])type_wanted = BOOK_DIVINATIONS;break;}/*if (type_wanted == 99 && glof == best_skill(SK_SPELLCASTING, (NUM_SKILLS - 1), 99))*/if (type_wanted == NUM_BOOKS && iteration == 1){best_spell = best_skill( SK_SPELLCASTING, NUM_SKILLS - 1,best_skill(SK_SPELLCASTING,NUM_SKILLS - 1, 99) );iteration++;goto which_book;}
case SK_NECROMANCY:// Don't give the Necromicon, that's a Kikubaaqudgha special.result = _choose_first_unseen_book(BOOK_NECROMANCY, BOOK_DEATH,BOOK_UNLIFE, NUM_BOOKS);break;
// If we don't have a book, try and get a new one.if (type_wanted > MAX_FIXED_BOOK){do{type_wanted = random2(NUM_NORMAL_BOOKS);if (one_chance_in(500))break;}while (you.had_book[type_wanted]);}
case SK_TRANSLOCATIONS:result = _choose_first_unseen_book(BOOK_SPATIAL_TRANSLOCATIONS,BOOK_WARP, NUM_BOOKS);break;
// If the book is invalid find any valid one.while (type_wanted == BOOK_HEALING)type_wanted = random2(NUM_NORMAL_BOOKS);break;
case SK_TRANSMUTATION:result = _choose_first_unseen_book(BOOK_CHARMS,BOOK_TRANSFIGURATIONS,BOOK_MUTATIONS,NUM_BOOKS);break;
// Elemental preferences -- bwrif (type_wanted == STAFF_FIRE || type_wanted == STAFF_COLD){if (you.skills[SK_FIRE_MAGIC] > you.skills[SK_ICE_MAGIC])type_wanted = STAFF_FIRE;else if (you.skills[SK_FIRE_MAGIC] != you.skills[SK_ICE_MAGIC])type_wanted = STAFF_COLD;}else if (type_wanted == STAFF_AIR || type_wanted == STAFF_EARTH){if (you.skills[SK_AIR_MAGIC] > you.skills[SK_EARTH_MAGIC])type_wanted = STAFF_AIR;else if (you.skills[SK_AIR_MAGIC] != you.skills[SK_EARTH_MAGIC])type_wanted = STAFF_EARTH;}
// If we don't have a book, try and get a new one.if (result == NUM_BOOKS){do{result = random2(NUM_NORMAL_BOOKS);if (one_chance_in(500))break;}while (you.had_book[result]);}
// If we're going to give out an enhancer staff,// we should at least bias things towards the// best spell skill. -- bwrswitch (best_spell){case SK_FIRE_MAGIC:if (!already_has[STAFF_FIRE])type_wanted = STAFF_FIRE;break;
return result;}
case SK_AIR_MAGIC:if (!already_has[STAFF_AIR])type_wanted = STAFF_AIR;break;
// Elemental preferences -- bwrif (result == STAFF_FIRE || result == STAFF_COLD){if (you.skills[SK_FIRE_MAGIC] > you.skills[SK_ICE_MAGIC])result = STAFF_FIRE;if (you.skills[SK_FIRE_MAGIC] < you.skills[SK_ICE_MAGIC])result = STAFF_COLD;}else if (result == STAFF_AIR || result == STAFF_EARTH){if (you.skills[SK_AIR_MAGIC] > you.skills[SK_EARTH_MAGIC])result = STAFF_AIR;if (you.skills[SK_AIR_MAGIC] < you.skills[SK_EARTH_MAGIC])result = STAFF_EARTH;}
case SK_POISON_MAGIC:if (!already_has[STAFF_POISON])type_wanted = STAFF_POISON;break;
#define TRY_GIVE(x) { if (!already_has[x]) result = x; }// If we're going to give out an enhancer staff,// we should at least bias things towards the// best spell skill. -- bwrswitch (best_spell_skill){case SK_FIRE_MAGIC: TRY_GIVE(STAFF_FIRE); break;case SK_ICE_MAGIC: TRY_GIVE(STAFF_COLD); break;case SK_AIR_MAGIC: TRY_GIVE(STAFF_AIR); break;case SK_EARTH_MAGIC: TRY_GIVE(STAFF_EARTH); break;case SK_POISON_MAGIC: TRY_GIVE(STAFF_POISON); break;case SK_NECROMANCY: TRY_GIVE(STAFF_DEATH); break;case SK_CONJURATIONS: TRY_GIVE(STAFF_CONJURATION); break;case SK_ENCHANTMENTS: TRY_GIVE(STAFF_ENCHANTMENT); break;case SK_SUMMONINGS: TRY_GIVE(STAFF_SUMMONING); break;#undef TRY_GIVE
case SK_CONJURATIONS:if (!already_has[STAFF_CONJURATION])type_wanted = STAFF_CONJURATION;break;
default: // Invocations and leftover spell schools.switch (random2(5)){case 0: result = STAFF_WIZARDRY; break;case 1: result = STAFF_POWER; break;case 2: result = STAFF_ENERGY; break;case 3: result = STAFF_CHANNELING; break;case 4: break; // keep the original random staff}break;}
case SK_SUMMONINGS:if (!already_has[STAFF_SUMMONING])type_wanted = STAFF_SUMMONING;break;
// Increased chance of getting a rod for new or// non-spellcasters. -- bwrif (one_chance_in(20)|| (spell_skills <= 1 // short on spells&& result < STAFF_FIRST_ROD&& !one_chance_in(4))){result = coinflip() ? STAFF_STRIKING : random_rod_subtype();}
default: // Invocations and leftover spell schools.switch (random2(5)){case 0:type_wanted = STAFF_WIZARDRY;break;
static int _acquirement_misc_subtype(){int result = NUM_MISCELLANY;do{result = random2(NUM_MISCELLANY);}while (result == MISC_HORN_OF_GERYON|| result == MISC_RUNE_OF_ZOT|| result == MISC_CRYSTAL_BALL_OF_FIXATION|| result == MISC_EMPTY_EBONY_CASKET|| result == MISC_DECK_OF_PUNISHMENT);
case 4:break;}break;}
// Write down what the player is carrying.has_vector already_has;already_has.init(0);for (int i = 0; i < ENDOFPACK; ++i){const item_def& item = you.inv[i];if (is_valid_item(item) && item.base_type == class_wanted){ASSERT(item.sub_type < max_has_value);already_has[item.sub_type] += item.quantity;}}
// Increased chance of getting a rod for new or// non-spellcasters. -- bwrif (one_chance_in(20)|| (spell_skills <= 1 // short on spells&& type_wanted < STAFF_SMITING&& !one_chance_in(4))){type_wanted = coinflip() ? STAFF_STRIKING :random_rod_subtype();}break;
bool try_again = (class_wanted == OBJ_JEWELLERY|| class_wanted == OBJ_BOOKS|| class_wanted == OBJ_STAVES|| class_wanted == OBJ_MISCELLANY);do{switch (class_wanted){case OBJ_FOOD:// set type_wanted and quantity_acquirement_determine_food(type_wanted, quantity, already_has);break;
case OBJ_MISCELLANY:do{type_wanted = random2(NUM_MISCELLANY);}while (type_wanted == MISC_HORN_OF_GERYON|| type_wanted == MISC_RUNE_OF_ZOT|| type_wanted == MISC_CRYSTAL_BALL_OF_FIXATION|| type_wanted == MISC_EMPTY_EBONY_CASKET|| type_wanted == MISC_DECK_OF_PUNISHMENT);break;default:break;}
case OBJ_WEAPONS: type_wanted = _acquirement_weapon_subtype(); break;case OBJ_MISSILES: type_wanted = _acquirement_missile_subtype(); break;case OBJ_ARMOUR: type_wanted = _acquirement_armour_subtype(); break;case OBJ_BOOKS: type_wanted = _acquirement_book_subtype(); break;case OBJ_MISCELLANY: type_wanted = _acquirement_misc_subtype(); break;case OBJ_STAVES: type_wanted = _acquirement_staff_subtype(already_has);break;case OBJ_JEWELLERY: type_wanted = _acquirement_jewellery_subtype();break;