/* File: borg4.c */ /* Purpose: Notice and Power code for the Borg -BEN- */ #include "angband.h" #ifdef ALLOW_BORG #include "borg1.h" #include "borg2.h" #include "borg3.h" #include "borg4.h" bool borg_full_damage; /* make danger = full damage. */ /* * Note that we assume that any item with quantity zero does not exist, * thus, when simulating possible worlds, we do not actually have to * "optimize" empty slots. * * XXX XXX XXX Also, we could reward equipment based on possible enchantment, * up to the maximal amount available in the home, which would induce item * switching when the item could be enchanted sufficiently. */ /* * The "notice" functions examine various aspects of the player inventory, * the player equipment, or the home contents, and extract various numerical * quantities based on those aspects, adjusting them for various "abilities", * such as the ability to cast certain spells, etc. * * The "power" functions use the numerical quantities described above, and * use them to do two different things: (1) rank the "value" of having * various abilities relative to the possible "money" reward of carrying * sellable items instead, and (2) rank the value of various abilities * relative to each other, which is used to determine what to wear/buy, * and in what order to wear/buy those items. * * These functions use some very heuristic values, by the way... * * We should probably take account of things like possible enchanting * (especially when in town), and items which may be found soon. * * We consider several things: * (1) the actual "power" of the current weapon and bow * (2) the various "flags" imparted by the equipment * (3) the various abilities imparted by the equipment * (4) the penalties induced by heavy armor or gloves or edged weapons * (5) the abilities required to enter the "max_depth" dungeon level * (6) the various abilities of some useful inventory items * * Note the use of special "item counters" for evaluating the value of * a collection of items of the given type. Basically, the first item * of the given type is always the most valuable, with subsequent items * being worth less, until the "limit" is reached, after which point any * extra items are only worth as much as they can be sold for. */ /* * Helper function -- notice the player equipment */ static void borg_notice_aux1(void) { int i, hold; int extra_blows = 0; int extra_shots = 0; int extra_might = 0; auto_item *item; /* Clear the armor class */ my_ac = 0; /* Clear the bonuses */ my_to_hit = my_to_dam = my_to_ac = 0; /* Start with a single blow per turn */ my_num_blow = 1; /* Start with a single shot per turn */ my_num_fire = 1; /* Assume normal speed */ my_speed = 110; /* Assume normal other */ my_other = 0; /* Reset the "ammo" tval */ my_ammo_tval = 0; /* Reset the "ammo" sides */ my_ammo_sides = 0; /* Reset the shooting power */ my_ammo_power = 0; /* Reset the shooting range */ my_ammo_range = 0; /* Clear all the flags */ my_see_inv = FALSE; my_teleport = FALSE; my_free_act = FALSE; my_slow_digest = FALSE; my_aggravate = FALSE; my_regenerate = FALSE; my_ffall = FALSE; my_hold_life = FALSE; my_telepathy = FALSE; my_lite = FALSE; my_slay_animal = FALSE; my_slay_evil = FALSE; my_slay_undead = FALSE; my_slay_demon = FALSE; my_slay_orc = FALSE; my_slay_troll = FALSE; my_slay_giant = FALSE; my_slay_dragon = FALSE; my_kill_dragon = FALSE; my_impact = FALSE; my_brand_acid = FALSE; my_brand_elec = FALSE; my_brand_fire = FALSE; my_brand_cold = FALSE; my_immune_acid = FALSE; my_immune_elec = FALSE; my_immune_fire = FALSE; my_immune_cold = FALSE; my_resist_acid = FALSE; my_resist_elec = FALSE; my_resist_fire = FALSE; my_resist_cold = FALSE; my_resist_pois = FALSE; my_resist_conf = FALSE; my_resist_sound = FALSE; my_resist_lite = FALSE; my_resist_dark = FALSE; my_resist_chaos = FALSE; my_resist_disen = FALSE; my_resist_shard = FALSE; my_resist_nexus = FALSE; my_resist_blind = FALSE; my_resist_neth = FALSE; my_resist_fear = FALSE; my_sustain_str = FALSE; my_sustain_int = FALSE; my_sustain_wis = FALSE; my_sustain_con = FALSE; my_sustain_dex = FALSE; my_sustain_chr = FALSE; /* Base infravision (purely racial) */ my_see_infra = rb_ptr->infra; /* Base skill -- disarming */ my_skill_dis = rb_ptr->r_dis + cb_ptr->c_dis; /* Base skill -- magic devices */ my_skill_dev = rb_ptr->r_dev + cb_ptr->c_dev; /* Base skill -- saving throw */ my_skill_sav = rb_ptr->r_sav + cb_ptr->c_sav; /* Base skill -- stealth */ my_skill_stl = rb_ptr->r_stl + cb_ptr->c_stl; /* Base skill -- searching ability */ my_skill_srh = rb_ptr->r_srh + cb_ptr->c_srh; /* Base skill -- searching frequency */ my_skill_fos = rb_ptr->r_fos + cb_ptr->c_fos; /* Base skill -- combat (normal) */ my_skill_thn = rb_ptr->r_thn + cb_ptr->c_thn; /* Base skill -- combat (shooting) */ my_skill_thb = rb_ptr->r_thb + cb_ptr->c_thb; /* Base skill -- combat (throwing) */ my_skill_tht = rb_ptr->r_thb + cb_ptr->c_thb; /* Base skill -- Digging */ my_skill_dig = 0; /* Elf */ if (auto_race == RACE_ELF) my_resist_lite = TRUE; /* Hobbit */ if (auto_race == RACE_HOBBIT) my_sustain_dex = TRUE; /* Gnome */ if (auto_race == RACE_GNOME) my_free_act = TRUE; /* Dwarf */ if (auto_race == RACE_DWARF) my_resist_blind = TRUE; /* Half-Orc */ if (auto_race == RACE_HALF_ORC) my_resist_dark = TRUE; /* Half-Troll */ if (auto_race == RACE_HALF_TROLL) my_sustain_str = TRUE; /* Dunadan */ if (auto_race == RACE_DUNADAN) my_sustain_con = TRUE; /* High Elf */ if (auto_race == RACE_HIGH_ELF) my_resist_lite = TRUE; if (auto_race == RACE_HIGH_ELF) my_see_inv = TRUE; /* Clear the stat modifiers */ for (i = 0; i < 6; i++) my_stat_add[i] = 0; /* Scan the usable inventory */ for (i = INVEN_WIELD; i < INVEN_TOTAL; i++) { item = &auto_items[i]; /* Skip empty items */ if (!item->iqty) continue; /* Affect stats */ if (item->flags1 & TR1_STR) my_stat_add[A_STR] += item->pval; if (item->flags1 & TR1_INT) my_stat_add[A_INT] += item->pval; if (item->flags1 & TR1_WIS) my_stat_add[A_WIS] += item->pval; if (item->flags1 & TR1_DEX) my_stat_add[A_DEX] += item->pval; if (item->flags1 & TR1_CON) my_stat_add[A_CON] += item->pval; if (item->flags1 & TR1_CHR) my_stat_add[A_CHR] += item->pval; /* various slays */ if (item->flags1 & TR1_SLAY_ANIMAL) my_slay_animal = TRUE; if (item->flags1 & TR1_SLAY_EVIL) my_slay_evil = TRUE; if (item->flags1 & TR1_SLAY_UNDEAD) my_slay_undead = TRUE; if (item->flags1 & TR1_SLAY_DEMON) my_slay_demon = TRUE; if (item->flags1 & TR1_SLAY_ORC) my_slay_orc = TRUE; if (item->flags1 & TR1_SLAY_TROLL) my_slay_troll = TRUE; if (item->flags1 & TR1_SLAY_GIANT) my_slay_giant = TRUE; if (item->flags1 & TR1_SLAY_DRAGON) my_slay_dragon = TRUE; if (item->flags1 & TR1_KILL_DRAGON) my_kill_dragon = TRUE; if (item->flags1 & TR1_IMPACT) my_impact = TRUE; if (item->flags1 & TR1_BRAND_ACID) my_brand_acid = TRUE; if (item->flags1 & TR1_BRAND_ELEC) my_brand_elec = TRUE; if (item->flags1 & TR1_BRAND_FIRE) my_brand_fire = TRUE; if (item->flags1 & TR1_BRAND_COLD) my_brand_cold = TRUE; /* Affect infravision */ if (item->flags1 & TR1_INFRA) my_see_infra += item->pval; /* Affect stealth */ if (item->flags1 & TR1_STEALTH) my_skill_stl += item->pval; /* Affect searching ability (factor of five) */ if (item->flags1 & TR1_SEARCH) my_skill_srh += (item->pval * 5); /* Affect searching frequency (factor of five) */ if (item->flags1 & TR1_SEARCH) my_skill_fos += (item->pval * 5); /* Affect digging (factor of 20) */ if (item->flags1 & TR1_TUNNEL) my_skill_dig += (item->pval * 20); /* Affect speed */ if (item->flags1 & TR1_SPEED) my_speed += item->pval; /* Affect blows */ if (item->flags1 & TR1_BLOWS) extra_blows += item->pval; /* Boost shots */ if (item->flags3 & TR3_XTRA_SHOTS) extra_shots++; /* Boost might */ if (item->flags3 & TR3_XTRA_MIGHT) extra_might++; /* Various flags */ if (item->flags3 & TR3_SLOW_DIGEST) my_slow_digest = TRUE; if (item->flags3 & TR3_AGGRAVATE) my_aggravate = TRUE; if (item->flags3 & TR3_TELEPORT) my_teleport = TRUE; if (item->flags3 & TR3_REGEN) my_regenerate = TRUE; if (item->flags3 & TR3_TELEPATHY) my_telepathy = TRUE; if (item->flags3 & TR3_LITE) my_lite = TRUE; if (item->flags3 & TR3_SEE_INVIS) my_see_inv = TRUE; if (item->flags3 & TR3_FEATHER) my_ffall = TRUE; if (item->flags2 & TR2_FREE_ACT) my_free_act = TRUE; if (item->flags2 & TR2_HOLD_LIFE) my_hold_life = TRUE; /* Immunity flags */ /* if you are immune you automaticly resist */ if (item->flags2 & TR2_IM_FIRE) { my_immune_fire = TRUE; my_resist_fire = TRUE; } if (item->flags2 & TR2_IM_ACID) { my_immune_acid = TRUE; my_resist_acid = TRUE; } if (item->flags2 & TR2_IM_COLD) { my_immune_cold = TRUE; my_resist_cold = TRUE; } if (item->flags2 & TR2_IM_ELEC) { my_immune_elec = TRUE; my_resist_elec = TRUE; } /* Resistance flags */ if (item->flags2 & TR2_RES_ACID) my_resist_acid = TRUE; if (item->flags2 & TR2_RES_ELEC) my_resist_elec = TRUE; if (item->flags2 & TR2_RES_FIRE) my_resist_fire = TRUE; if (item->flags2 & TR2_RES_COLD) my_resist_cold = TRUE; if (item->flags2 & TR2_RES_POIS) my_resist_pois = TRUE; if (item->flags2 & TR2_RES_CONF) my_resist_conf = TRUE; if (item->flags2 & TR2_RES_SOUND) my_resist_sound = TRUE; if (item->flags2 & TR2_RES_LITE) my_resist_lite = TRUE; if (item->flags2 & TR2_RES_DARK) my_resist_dark = TRUE; if (item->flags2 & TR2_RES_CHAOS) my_resist_chaos = TRUE; if (item->flags2 & TR2_RES_DISEN) my_resist_disen = TRUE; if (item->flags2 & TR2_RES_SHARDS) my_resist_shard = TRUE; if (item->flags2 & TR2_RES_NEXUS) my_resist_nexus = TRUE; if (item->flags2 & TR2_RES_BLIND) my_resist_blind = TRUE; if (item->flags2 & TR2_RES_NETHER) my_resist_neth = TRUE; /* Sustain flags */ if (item->flags2 & TR2_SUST_STR) my_sustain_str = TRUE; if (item->flags2 & TR2_SUST_INT) my_sustain_int = TRUE; if (item->flags2 & TR2_SUST_WIS) my_sustain_wis = TRUE; if (item->flags2 & TR2_SUST_DEX) my_sustain_dex = TRUE; if (item->flags2 & TR2_SUST_CON) my_sustain_con = TRUE; if (item->flags2 & TR2_SUST_CHR) my_sustain_chr = TRUE; /* Modify the base armor class */ my_ac += item->ac; /* Apply the bonuses to armor class */ my_to_ac += item->to_a; /* Hack -- do not apply "weapon" bonuses */ if (i == INVEN_WIELD) continue; /* Hack -- do not apply "bow" bonuses */ if (i == INVEN_BOW) continue; /* Apply the bonuses to hit/damage */ my_to_hit += item->to_h; my_to_dam += item->to_d; } /* Hack -- Chaos / Confusion */ if (my_resist_chaos) my_resist_conf = TRUE; /* Update "stats" */ for (i = 0; i < 6; i++) { int use, ind; /* Extract the new "use_stat" value for the stat */ use = modify_stat_value(my_stat_cur[i], my_stat_add[i]); /* Save the stat */ my_stat_use[i] = use; /* Values: 3, ..., 17 */ if (use <= 17) ind = (use - 3); /* Ranges: 18/00-18/09, ..., 18/210-18/219 */ else if (use <= 18+219) ind = (15 + (use - 18) / 10); /* Range: 18/220+ */ else ind = (37); /* Save the index */ my_stat_ind[i] = ind; } #if 0 /* XXX XXX XXX */ /* Extract the current weight (in tenth pounds) */ j = inven_weight; /* Extract the "weight limit" (in tenth pounds) */ i = weight_limit(); /* XXX Hack -- Apply "encumbrance" from weight */ if (j > i/2) my_speed -= ((j - (i/2)) / (i / 10)); #endif /* Bloating slows the player down (a little) */ if (do_gorged) my_speed -= 10; /* Actual Modifier Bonuses (Un-inflate stat bonuses) */ my_to_ac += ((int)(adj_dex_ta[my_stat_ind[A_DEX]]) - 128); my_to_dam += ((int)(adj_str_td[my_stat_ind[A_STR]]) - 128); my_to_hit += ((int)(adj_dex_th[my_stat_ind[A_DEX]]) - 128); my_to_hit += ((int)(adj_str_th[my_stat_ind[A_STR]]) - 128); /* Obtain the "hold" value */ hold = adj_str_hold[my_stat_ind[A_STR]]; /* Examine the "current bow" */ item = &auto_items[INVEN_BOW]; /* attacking with bare hands */ if (item->iqty == 0) { item->ds = 0; item->dd = 0; item->to_d = 0; item->to_h = 0; item->weight = 0; } /* It is hard to carholdry a heavy bow */ if (hold < item->weight / 10) { /* Hard to wield a heavy bow */ my_to_hit += 2 * (hold - item->weight / 10); } /* Compute "extra shots" if needed */ if (item->iqty && (hold >= item->weight / 10)) { /* Take note of required "tval" for missiles */ switch (item->sval) { case SV_SLING: my_ammo_tval = TV_SHOT; my_ammo_sides = 3; my_ammo_power = 2; break; case SV_SHORT_BOW: my_ammo_tval = TV_ARROW; my_ammo_sides = 4; my_ammo_power = 2; break; case SV_LONG_BOW: my_ammo_tval = TV_ARROW; my_ammo_sides = 4; my_ammo_power = 3; break; case SV_LIGHT_XBOW: my_ammo_tval = TV_BOLT; my_ammo_sides = 5; my_ammo_power = 3; break; case SV_HEAVY_XBOW: my_ammo_tval = TV_BOLT; my_ammo_sides = 5; my_ammo_power = 4; break; } /* Add in extra power */ my_ammo_power += extra_might; /* Calculate total range */ my_ammo_range = 10 + my_ammo_power * 5; /* Hack -- High Level Rangers shoot arrows quickly */ if ((auto_class == 4) && (my_ammo_tval == TV_ARROW)) { /* Extra shot at level 20 */ if (auto_max_level >= 20) my_num_fire++; /* Extra shot at level 40 */ if (auto_max_level >= 40) my_num_fire++; } /* Add in the "bonus shots" */ my_num_fire += extra_shots; /* Require at least one shot */ if (my_num_fire < 1) my_num_fire = 1; } /* Examine the "main weapon" */ item = &auto_items[INVEN_WIELD]; /* attacking with bare hands */ if (item->iqty == 0) { item->ds = 0; item->dd = 0; item->to_d = 0; item->to_h = 0; item->weight = 0; } /* It is hard to hold a heavy weapon */ if (hold < item->weight / 10) { /* Hard to wield a heavy weapon */ my_to_hit += 2 * (hold - item->weight / 10); } /* Normal weapons */ if (item->iqty && (hold >= item->weight / 10)) { int str_index, dex_index; int num = 0, wgt = 0, mul = 0, div = 0; /* Analyze the class */ switch (auto_class) { /* Warrior */ case 0: num = 6; wgt = 30; mul = 5; break; /* Mage */ case 1: num = 4; wgt = 40; mul = 2; break; /* Priest (was mul = 3.5) */ case 2: num = 5; wgt = 35; mul = 3; break; /* Rogue */ case 3: num = 5; wgt = 30; mul = 3; break; /* Ranger */ case 4: num = 5; wgt = 35; mul = 4; break; /* Paladin */ case 5: num = 5; wgt = 30; mul = 4; break; } /* Enforce a minimum "weight" */ div = ((item->weight < wgt) ? wgt : item->weight); /* Access the strength vs weight */ str_index = (adj_str_blow[my_stat_ind[A_STR]] * mul / div); /* Maximal value */ if (str_index > 11) str_index = 11; /* Index by dexterity */ dex_index = (adj_dex_blow[my_stat_ind[A_DEX]]); /* Maximal value */ if (dex_index > 11) dex_index = 11; /* Use the blows table */ my_num_blow = blows_table[str_index][dex_index]; /* Maximal value */ if (my_num_blow > num) my_num_blow = num; /* Add in the "bonus blows" */ my_num_blow += extra_blows; /* Require at least one blow */ if (my_num_blow < 1) my_num_blow = 1; /* Boost digging skill by weapon weight */ my_skill_dig += (item->weight / 10); } /* Priest weapon penalty for non-blessed edged weapons */ if ((auto_class == 2) && ((item->tval == TV_SWORD) || (item->tval == TV_POLEARM)) && (!(item->flags3 & TR3_BLESSED))) { /* Reduce the real bonuses */ my_to_hit -= 2; my_to_dam -= 2; } /* Affect Skill -- stealth (bonus one) */ my_skill_stl += 1; /* Affect Skill -- disarming (DEX and INT) */ my_skill_dis += adj_dex_dis[my_stat_ind[A_DEX]]; my_skill_dis += adj_int_dis[my_stat_ind[A_INT]]; /* Affect Skill -- magic devices (INT) */ my_skill_dev += adj_int_dev[my_stat_ind[A_INT]]; /* Affect Skill -- saving throw (WIS) */ my_skill_sav += adj_wis_sav[my_stat_ind[A_WIS]]; /* Affect Skill -- digging (STR) */ my_skill_dig += adj_str_dig[my_stat_ind[A_STR]]; /* Affect Skill -- disarming (Level, by Class) */ my_skill_dis += (cb_ptr->x_dis * auto_max_level / 10); /* Affect Skill -- magic devices (Level, by Class) */ my_skill_dev += (cb_ptr->x_dev * auto_max_level / 10); /* Affect Skill -- saving throw (Level, by Class) */ my_skill_sav += (cb_ptr->x_sav * auto_max_level / 10); /* Affect Skill -- stealth (Level, by Class) */ my_skill_stl += (cb_ptr->x_stl * auto_max_level / 10); /* Affect Skill -- search ability (Level, by Class) */ my_skill_srh += (cb_ptr->x_srh * auto_max_level / 10); /* Affect Skill -- search frequency (Level, by Class) */ my_skill_fos += (cb_ptr->x_fos * auto_max_level / 10); /* Affect Skill -- combat (normal) (Level, by Class) */ my_skill_thn += (cb_ptr->x_thn * auto_max_level / 10); /* Affect Skill -- combat (shooting) (Level, by Class) */ my_skill_thb += (cb_ptr->x_thb * auto_max_level / 10); /* Affect Skill -- combat (throwing) (Level, by Class) */ my_skill_tht += (cb_ptr->x_thb * auto_max_level / 10); /* Limit Skill -- stealth from 0 to 30 */ if (my_skill_stl > 30) my_skill_stl = 30; if (my_skill_stl < 0) my_skill_stl = 0; /* Limit Skill -- digging from 1 up */ if (my_skill_dig < 1) my_skill_dig = 1; /*** Count needed enchantment ***/ /* Assume no enchantment needed */ my_need_enchant_to_a = 0; my_need_enchant_to_h = 0; my_need_enchant_to_d = 0; /* Hack -- enchant all the equipment (weapons) */ for (i = INVEN_WIELD; i <= INVEN_BOW; i++) { item = &auto_items[i]; /* Skip empty items */ if (!item->iqty) continue; /* Skip "unknown" items */ if (!item->able) continue; /* Enchant all weapons (to hit) */ if (borg_prayer_legal(7, 3)) { if (item->to_h < 12) { my_need_enchant_to_h += (12 - item->to_h); } /* Enchant all weapons (to damage) */ if (item->to_d < 12) { my_need_enchant_to_d += (12 - item->to_d); } } else { if (item->to_h < 8) { my_need_enchant_to_h += (8 - item->to_h); } /* Enchant all weapons (to damage) */ if (item->to_d < 8) { my_need_enchant_to_d += (8 - item->to_d); } } } /* Hack -- enchant all the equipment (armor) */ for (i = INVEN_BODY; i <= INVEN_FEET; i++) { item = &auto_items[i]; /* Skip empty items */ if (!item->iqty) continue; /* Skip "unknown" items */ if (!item->able) continue; /* Note need for enchantment */ if (borg_prayer_legal(7, 4)) { if (item->to_a < 15) { my_need_enchant_to_a += (15 - item->to_a); } } else { if (item->to_a < 8) { my_need_enchant_to_a += (8 - item->to_a); } } } /* Examine the lite */ item = &auto_items[INVEN_LITE]; /* Assume normal lite radius */ my_cur_lite = 0; /* Glowing player has light */ if (my_lite) my_cur_lite = 1; /* Lite */ if (item->tval == TV_LITE) { /* Torches -- radius one */ if (item->sval == SV_LITE_TORCH) my_cur_lite = 1; /* Lanterns -- radius two */ if (item->sval == SV_LITE_LANTERN) my_cur_lite = 2; /* No fuel means no radius */ if (!item->pval) my_cur_lite = 0; /* Artifact lites -- radius three */ /* HACK assume non-torch/non lantern lite is artifact */ if ((item->sval != SV_LITE_TORCH) && (item->sval != SV_LITE_LANTERN)) { my_cur_lite = 3; /* Artifact lites -- assume glowing */ my_lite = TRUE; } } } /* * Helper function -- notice the player inventory */ static void borg_notice_aux2(void) { int i; auto_item *item; /*** Reset counters ***/ /* Reset basic */ amt_fuel = 0; amt_food = 0; amt_ident = 0; amt_star_ident = 0; amt_recall = 0; amt_phase = 0; amt_escape = 0; amt_teleport = 0; amt_teleport_staff = 0; /* Reset healing */ amt_mana = 0; amt_ez_mana = 0; amt_heal = 0; amt_ez_heal = 0; amt_cure_critical = 0; amt_cure_serious = 0; /* Reset detection */ amt_detect_trap = 0; amt_detect_door = 0; /* Reset missiles */ amt_missile = 0; /* Reset books */ amt_book[0] = 0; amt_book[1] = 0; amt_book[2] = 0; amt_book[3] = 0; amt_book[4] = 0; amt_book[5] = 0; amt_book[6] = 0; amt_book[7] = 0; amt_book[8] = 0; /* Reset various */ amt_add_stat[A_STR] = 0; amt_add_stat[A_INT] = 0; amt_add_stat[A_WIS] = 0; amt_add_stat[A_DEX] = 0; amt_add_stat[A_CON] = 0; amt_add_stat[A_CHR] = 0; amt_fix_stat[A_STR] = 0; amt_fix_stat[A_INT] = 0; amt_fix_stat[A_WIS] = 0; amt_fix_stat[A_DEX] = 0; amt_fix_stat[A_CON] = 0; amt_fix_stat[A_CHR] = 0; amt_fix_exp = 0; amt_speed = 0; /* Reset enchantment */ amt_enchant_to_a = 0; amt_enchant_to_d = 0; amt_enchant_to_h = 0; /*** Process the inventory ***/ /* Scan the inventory */ for (i = 0; i < INVEN_PACK; i++) { item = &auto_items[i]; /* Skip empty items */ if (!item->iqty) continue; /* Hack -- skip un-aware items */ if (!item->kind) continue; /* Analyze the item */ switch (item->tval) { /* Books */ case TV_MAGIC_BOOK: case TV_PRAYER_BOOK: /* Skip incorrect books */ if (item->tval != mb_ptr->spell_book) break; /* Count the books */ amt_book[item->sval] += item->iqty; break; /* Food */ case TV_FOOD: /* Analyze */ switch (item->sval) { case SV_FOOD_RATION: amt_food += item->iqty; break; } break; /* Potions */ case TV_POTION: /* Analyze */ switch (item->sval) { case SV_POTION_HEALING: amt_heal += item->iqty; break; case SV_POTION_STAR_HEALING: case SV_POTION_LIFE: amt_ez_heal += item->iqty; break; case SV_POTION_CURE_CRITICAL: amt_cure_critical += item->iqty; break; case SV_POTION_CURE_SERIOUS: amt_cure_serious += item->iqty; break; case SV_POTION_INC_STR: amt_add_stat[A_STR] += item->iqty; break; case SV_POTION_INC_INT: amt_add_stat[A_INT] += item->iqty; break; case SV_POTION_INC_WIS: amt_add_stat[A_WIS] += item->iqty; break; case SV_POTION_INC_DEX: amt_add_stat[A_DEX] += item->iqty; break; case SV_POTION_INC_CON: amt_add_stat[A_CON] += item->iqty; break; case SV_POTION_INC_CHR: amt_add_stat[A_CHR] += item->iqty; break; case SV_POTION_RES_STR: amt_fix_stat[A_STR] += item->iqty; break; case SV_POTION_RES_INT: amt_fix_stat[A_INT] += item->iqty; break; case SV_POTION_RES_WIS: amt_fix_stat[A_WIS] += item->iqty; break; case SV_POTION_RES_DEX: amt_fix_stat[A_DEX] += item->iqty; break; case SV_POTION_RES_CON: amt_fix_stat[A_CON] += item->iqty; break; case SV_POTION_RES_CHR: amt_fix_stat[A_CHR] += item->iqty; break; case SV_POTION_RESTORE_EXP: amt_fix_exp += item->iqty; break; case SV_POTION_SPEED: amt_speed += item->iqty; break; case SV_POTION_RESTORE_MANA: amt_mana += item->iqty; break; } break; /* Scrolls */ case TV_SCROLL: /* Analyze the scroll */ switch (item->sval) { case SV_SCROLL_IDENTIFY: amt_ident += item->iqty; break; case SV_SCROLL_STAR_IDENTIFY: amt_star_ident += item->iqty; break; case SV_SCROLL_PHASE_DOOR: amt_phase += item->iqty; break; case SV_SCROLL_TELEPORT: amt_escape += item->iqty; break; case SV_SCROLL_WORD_OF_RECALL: amt_recall += item->iqty; break; case SV_SCROLL_ENCHANT_ARMOR: amt_enchant_to_a += item->iqty; break; case SV_SCROLL_ENCHANT_WEAPON_TO_HIT: amt_enchant_to_h += item->iqty; break; case SV_SCROLL_ENCHANT_WEAPON_TO_DAM: amt_enchant_to_d += item->iqty; break; } break; /* Rods */ case TV_ROD: /* Analyze */ switch (item->sval) { case SV_ROD_IDENTIFY: amt_ident += item->iqty * 100; break; case SV_ROD_RECALL: amt_recall += item->iqty * 100; break; case SV_ROD_DETECT_TRAP: amt_detect_trap += item->iqty * 100; break; case SV_ROD_DETECT_DOOR: amt_detect_door += item->iqty * 100; break; case SV_ROD_DETECTION: amt_detect_trap += item->iqty * 100; amt_detect_door += item->iqty * 100; break; case SV_ROD_SPEED: amt_speed += item->iqty * 100; break; case SV_ROD_HEALING: /* only +1 per rod because of long charge time. */ amt_ez_heal += item->iqty; break; } break; /* Staffs */ case TV_STAFF: /* Analyze */ switch (item->sval) { case SV_STAFF_IDENTIFY: amt_ident += item->iqty * item->pval; break; case SV_STAFF_TELEPORTATION: amt_teleport += item->iqty * item->pval; /* do not count staffs with no changes */ if (item->pval) amt_teleport_staff += item->iqty; break; case SV_STAFF_SPEED: amt_speed += item->iqty * item->pval; break; case SV_STAFF_HEALING: amt_ez_heal += item->iqty * item->pval; break; case SV_STAFF_THE_MAGI: amt_ez_mana += item->iqty * item->pval; break; } break; /* Flasks */ case TV_FLASK: /* Use as fuel (etc) */ amt_fuel += item->iqty; /* Hack -- use as missiles until powerful */ if (auto_level < 10) amt_missile += item->iqty; break; /* Missiles */ case TV_SHOT: case TV_ARROW: case TV_BOLT: /* Hack -- ignore invalid missiles */ if (item->tval != my_ammo_tval) break; /* Hack -- ignore worthless missiles */ if (item->value <= 0) break; /* Count them */ amt_missile += item->iqty; /* if we have shit loads of cash (as we will at level 35), */ /* enchant missiles */ if (auto_level > 35) { if (borg_prayer_legal(7, 3) && item->iqty >= 10) { if (item->to_h < 10) { my_need_enchant_to_h += (10 - item->to_h); } if (item->to_d < 10) { my_need_enchant_to_d += (10 - item->to_d); } } else { if (item->to_h < 8) { my_need_enchant_to_h += (8 - item->to_h); } if (item->to_d < 8) { my_need_enchant_to_d += (8 - item->to_d); } } } break; } } /*** Process the Spells and Prayers ***/ /* Handle "satisfy hunger" -> infinite food */ if (borg_spell_legal_fail(2, 0, 20) || borg_prayer_legal_fail(1, 5, 20)) { amt_food += 1000; } /* Handle "identify" -> infinite identifies */ if (borg_spell_legal(2, 4) || borg_prayer_legal(5, 2)) { amt_ident += 1000; } /* Handle "detect traps" */ if (borg_prayer_legal(0, 5)) { amt_detect_trap += 1000; } /* Handle "detect doors" */ if (borg_prayer_legal(0, 6)) { amt_detect_door += 1000; } /* Handle "detection" */ if (borg_prayer_legal(5, 1)) { amt_detect_door += 1000; amt_detect_trap += 1000; } /* Handle "detect traps/doors" */ if (borg_spell_legal(0, 7)) { amt_detect_door += 1000; amt_detect_trap += 1000; } /* Handle "enchant weapon" */ if (borg_prayer_legal(7, 3)) { amt_enchant_to_h += 1000; amt_enchant_to_d += 1000; } /* Handle "enchant armor" */ if (borg_prayer_legal(7, 4)) { amt_enchant_to_a += 1000; } /* Handle recall */ if (borg_prayer_legal(4, 4) || borg_spell_legal(5, 4)) { amt_recall += 1000; } /* speed spells */ if ( borg_spell_legal( 3, 3 ) || borg_spell_legal( 7, 3 )) { amt_speed += 1000; } /*** Process the Needs ***/ /* No need for fuel */ if ((auto_items[INVEN_LITE].sval != SV_LITE_TORCH) && (auto_items[INVEN_LITE].sval != SV_LITE_LANTERN)) amt_fuel += 1000; /* No need to *buy* stat increase potions */ if (my_stat_cur[A_STR] >= (18+100) + 10 * p_ptr->maximize * (rp_ptr->r_adj[A_STR] + cp_ptr->c_adj[A_STR])) amt_add_stat[A_STR] += 1000; if (my_stat_cur[A_INT] >= (18+100) + 10 * p_ptr->maximize * (rp_ptr->r_adj[A_INT] + cp_ptr->c_adj[A_INT])) amt_add_stat[A_INT] += 1000; if (my_stat_cur[A_WIS] >= (18+100) + 10 * p_ptr->maximize * (rp_ptr->r_adj[A_WIS] + cp_ptr->c_adj[A_WIS])) amt_add_stat[A_WIS] += 1000; if (my_stat_cur[A_DEX] >= (18+100) + 10 * p_ptr->maximize * (rp_ptr->r_adj[A_DEX] + cp_ptr->c_adj[A_DEX])) amt_add_stat[A_DEX] += 1000; if (my_stat_cur[A_CON] >= (18+100) + 10 * p_ptr->maximize * (rp_ptr->r_adj[A_CON] + cp_ptr->c_adj[A_CON])) amt_add_stat[A_CON] += 1000; if (my_stat_cur[A_CHR] >= (18+100) + 10 * p_ptr->maximize * (rp_ptr->r_adj[A_CHR] + cp_ptr->c_adj[A_CHR])) amt_add_stat[A_CHR] += 1000; /* No need to *buy* stat repair potions XXX XXX XXX */ if (!do_fix_stat[A_STR]) amt_fix_stat[A_STR] += 1000; if (!do_fix_stat[A_INT]) amt_fix_stat[A_INT] += 1000; if (!do_fix_stat[A_WIS]) amt_fix_stat[A_WIS] += 1000; if (!do_fix_stat[A_DEX]) amt_fix_stat[A_DEX] += 1000; if (!do_fix_stat[A_CON]) amt_fix_stat[A_CON] += 1000; if (!do_fix_stat[A_CHR]) amt_fix_stat[A_CHR] += 1000; /* No need for experience repair */ if (!do_fix_exp) amt_fix_exp += 1000; } /* * Analyze the equipment and inventory */ void borg_notice(void) { /* Notice the equipment */ borg_notice_aux1(); /* Notice the inventory */ borg_notice_aux2(); } /* * Helper function -- notice the home equipment */ static void borg_notice_home_aux1(auto_item* in_item, bool no_items) { /*** Reset counters ***/ /* Reset basic */ num_food = 0; num_ident = 0; num_star_ident = 0; num_recall = 0; num_phase = 0; num_escape = 0; num_teleport = 0; num_artifact = 0; num_slow_digest = 0; num_regenerate = 0; num_telepathy = 0; num_see_inv = 0; num_ffall = 0; num_free_act = 0; num_hold_life = 0; num_immune_acid = 0; num_immune_elec = 0; num_immune_fire = 0; num_immune_cold = 0; num_resist_acid = 0; num_resist_elec = 0; num_resist_fire = 0; num_resist_cold = 0; num_resist_pois = 0; num_resist_conf = 0; num_resist_sound = 0; num_resist_lite = 0; num_resist_dark = 0; num_resist_chaos = 0; num_resist_disen = 0; num_resist_shard = 0; num_resist_nexus = 0; num_resist_blind = 0; num_resist_neth = 0; home_stat_add[A_STR] = 0; home_stat_add[A_INT] = 0; home_stat_add[A_WIS] = 0; home_stat_add[A_DEX] = 0; home_stat_add[A_CON] = 0; home_stat_add[A_CHR] = 0; num_weapons = 0; num_bow =0; num_rings = 0; num_neck = 0; num_armor = 0; num_cloaks = 0; num_shields = 0; num_hats = 0; num_gloves = 0; num_boots = 0; num_lite = 0; num_speed = 0; num_edged_weapon = 0; num_bad_gloves= 0; /* Reset healing */ num_cure_critical = 0; num_cure_serious = 0; /* Reset missiles */ num_missile = 0; /* Reset books */ num_book[0] = 0; num_book[1] = 0; num_book[2] = 0; num_book[3] = 0; num_book[4] = 0; num_book[5] = 0; num_book[6] = 0; num_book[7] = 0; num_book[8] = 0; /* Reset various */ num_fix_stat[A_STR] = 0; num_fix_stat[A_INT] = 0; num_fix_stat[A_WIS] = 0; num_fix_stat[A_DEX] = 0; num_fix_stat[A_CON] = 0; num_fix_stat[A_CHR] = 0; num_fix_exp = 0; num_mana = 0; num_heal = 0; /* Reset enchantment */ num_enchant_to_a = 0; num_enchant_to_d = 0; num_enchant_to_h = 0; home_slot_free = 0; home_damage = 0; num_duplicate_items = 0; } /* * This checks for duplicate items in the home */ static void borg_notice_home_dupe(auto_item *item, bool check_sval, int i) { /* eventually check for power overlap... armor of resistence is same as weak elvenkind.*/ /* two armors of elvenkind that resist poison is a dupe. AJG*/ int dupe_count, x; auto_item *item2; /* check for a duplicate. */ /* be carefull about extra powers (elvenkind/magi) */ switch (item->name2) { case EGO_BLESS_BLADE: case EGO_PERMANENCE: case EGO_ELVENKIND: case EGO_MAGI: case EGO_AMAN: return; break; case EGO_HA: case EGO_DF: default: break; } /* if this is a stack of items then all after the first are a */ /* duplicate */ dupe_count = item->iqty-1; /* Look for other items before this one that are the same */ for (x = 0; x < i; x++) { if (x < STORE_INVEN_MAX) item2 = &auto_shops[7].ware[x]; else /* Check what the borg has on as well.*/ item2 = &auto_items[((x-STORE_INVEN_MAX)+INVEN_WIELD)]; /* if everything matches it is a duplicate item */ /* Note that we only check sval on certain items. This */ /* is because, for example, two pairs of dragon armor */ /* are not the same unless thier subtype (color) matches */ /* but a defender is a defender even if one is a dagger and */ /* one is a mace */ if ( (item->tval == item2->tval) && (check_sval ? (item->sval == item2->sval) : TRUE) && (item->name1 == item2->name1) && (item->name2 == item2->name2) ) { dupe_count++; } } /* there can be one dupe of rings because there are two ring slots. */ if (item->tval == TV_RING && dupe_count) dupe_count--; /* Add this items count to the total duplicate count */ num_duplicate_items += dupe_count; } /* * Helper function -- notice the home inventory */ static void borg_notice_home_aux2(auto_item *in_item, bool no_items) { int i; auto_item *item; auto_shop *shop = &auto_shops[7]; /*** Process the inventory ***/ /* Scan the home */ for (i = 0; i < (STORE_INVEN_MAX+(INVEN_TOTAL-INVEN_WIELD)); i++) { if (no_items) break; if (!in_item) if (i < STORE_INVEN_MAX) item = &shop->ware[i]; else item = &auto_items[((i-STORE_INVEN_MAX)+INVEN_WIELD)]; else item = in_item; /* Skip empty items */ if (!item->iqty) { home_slot_free++; continue; } /* Hack -- skip un-aware items */ if (!item->kind) { home_slot_free++; continue; } if (item->flags3 & TR3_SLOW_DIGEST) num_slow_digest += item->iqty; if (item->flags3 & TR3_REGEN) num_regenerate += item->iqty; if (item->flags3 & TR3_TELEPATHY) num_telepathy += item->iqty; if (item->flags3 & TR3_SEE_INVIS) num_see_inv += item->iqty; if (item->flags3 & TR3_FEATHER) num_ffall += item->iqty; if (item->flags2 & TR2_FREE_ACT) num_free_act += item->iqty; if (item->flags2 & TR2_HOLD_LIFE) num_hold_life += item->iqty; if (item->flags2 & TR2_IM_FIRE) { num_immune_fire += item->iqty; num_resist_fire += item->iqty; } if (item->flags2 & TR2_IM_ACID) { num_immune_acid += item->iqty; num_resist_acid += item->iqty; } if (item->flags2 & TR2_IM_COLD) { num_immune_cold += item->iqty; num_resist_cold += item->iqty; } if (item->flags2 & TR2_IM_ELEC) { num_immune_elec += item->iqty; num_resist_elec += item->iqty; } if (item->flags2 & TR2_RES_ACID) num_resist_acid += item->iqty; if (item->flags2 & TR2_RES_ELEC) num_resist_elec += item->iqty; if (item->flags2 & TR2_RES_FIRE) num_resist_fire += item->iqty; if (item->flags2 & TR2_RES_COLD) num_resist_cold += item->iqty; if (item->flags2 & TR2_RES_POIS) num_resist_pois += item->iqty; if (item->flags2 & TR2_RES_SOUND) num_resist_sound += item->iqty; if (item->flags2 & TR2_RES_LITE) num_resist_lite += item->iqty; if (item->flags2 & TR2_RES_DARK) num_resist_dark += item->iqty; if (item->flags2 & TR2_RES_CHAOS) num_resist_chaos += item->iqty; /* chaos also does confusion */ if (item->flags2 & TR2_RES_CONF || item->flags2 & TR2_RES_CHAOS) num_resist_conf += item->iqty; if (item->flags2 & TR2_RES_DISEN) num_resist_disen += item->iqty; if (item->flags2 & TR2_RES_SHARDS) num_resist_shard += item->iqty; if (item->flags2 & TR2_RES_NEXUS) num_resist_nexus += item->iqty; if (item->flags2 & TR2_RES_BLIND) num_resist_blind += item->iqty; if (item->flags2 & TR2_RES_NETHER) num_resist_neth += item->iqty; /* count up bonus to stats */ /* HACK only collect stat rings above +3 */ if (item->flags1 & TR1_STR) { if (item->tval != TV_RING || item->pval > 3) home_stat_add[A_STR] += item->pval * item->iqty; } if (item->flags1 & TR1_INT) { if (item->tval != TV_RING || item->pval > 3) home_stat_add[A_INT] += item->pval * item->iqty; } if (item->flags1 & TR1_WIS) { if (item->tval != TV_RING || item->pval > 3) home_stat_add[A_WIS] += item->pval * item->iqty; } if (item->flags1 & TR1_DEX) { if (item->tval != TV_RING || item->pval > 3) home_stat_add[A_DEX] += item->pval * item->iqty; } if (item->flags1 & TR1_CON) { if (item->tval != TV_RING || item->pval > 3) home_stat_add[A_CON] += item->pval * item->iqty; } if (item->flags1 & TR1_CHR) { if (item->tval != TV_RING || item->pval > 3) home_stat_add[A_CHR] += item->pval * item->iqty; } /* count up bonus to speed */ if (item->flags1 & TR1_SPEED) num_speed += item->pval * item->iqty; /* count artifacts */ if (item->name1) num_artifact += item->iqty; /* Analyze the item */ switch (item->tval) { case TV_SOFT_ARMOR: case TV_HARD_ARMOR: num_armor += item->iqty; /* see if this item is duplicated */ borg_notice_home_dupe( item, FALSE, i ); break; case TV_DRAG_ARMOR: num_armor += item->iqty; /* see if this item is duplicated */ borg_notice_home_dupe( item, TRUE, i ); break; case TV_CLOAK: num_cloaks += item->iqty; /* see if this item is duplicated */ borg_notice_home_dupe( item, FALSE, i ); break; case TV_SHIELD: num_shields += item->iqty; /* see if this item is duplicated */ borg_notice_home_dupe( item, FALSE, i ); break; case TV_HELM: case TV_CROWN: num_hats += item->iqty; /* see if this item is duplicated */ borg_notice_home_dupe( item, FALSE, i ); break; case TV_GLOVES: num_gloves += item->iqty; /* most gloves hurt magic for spell-casters */ if (mb_ptr->spell_book == TV_MAGIC_BOOK) { /* Penalize non-usable gloves */ if (item->iqty && (!(item->flags2 & TR2_FREE_ACT)) && (!((item->flags1 & TR1_DEX) && (item->pval > 0)))) { num_bad_gloves += item->iqty; } } /* gloves of slaying give a damage bonus */ home_damage += item->to_d * 3; /* see if this item is duplicated */ borg_notice_home_dupe( item, FALSE, i ); break; case TV_LITE: num_lite += item->iqty; break; case TV_BOOTS: num_boots += item->iqty; /* see if this item is duplicated */ borg_notice_home_dupe( item, FALSE, i ); break; case TV_SWORD: case TV_POLEARM: case TV_HAFTED: case TV_DIGGING: { s16b num_blow; num_weapons += item->iqty; /* most edged weapons hurt magic for priests */ if (auto_class == CLASS_PRIEST) { /* Penalize non-blessed edged weapons */ if (((item->tval == TV_SWORD) || (item->tval == TV_POLEARM)) && (!(item->flags3 & TR3_BLESSED))) { num_edged_weapon += item->iqty; } } /* NOTE: This damage does not take slays into account. */ /* it is just a rough estimate to make sure the glave of pain*/ /* is kept if it is found */ /* It is hard to hold a heavy weapon */ num_blow = 1; if (adj_str_hold[my_stat_ind[A_STR]] >= item->weight / 10) { int str_index, dex_index; int num = 0, wgt = 0, mul = 0, div = 0; /* Analyze the class */ switch (auto_class) { /* Warrior */ case 0: num = 6; wgt = 30; mul = 5; break; /* Mage */ case 1: num = 4; wgt = 40; mul = 2; break; /* Priest (was mul = 3.5) */ case 2: num = 5; wgt = 35; mul = 3; break; /* Rogue */ case 3: num = 5; wgt = 30; mul = 3; break; /* Ranger */ case 4: num = 5; wgt = 35; mul = 4; break; /* Paladin */ case 5: num = 5; wgt = 30; mul = 4; break; } /* Enforce a minimum "weight" */ div = ((item->weight < wgt) ? wgt : item->weight); /* Access the strength vs weight */ str_index = (adj_str_blow[my_stat_ind[A_STR]] * mul / div); /* Maximal value */ if (str_index > 11) str_index = 11; /* Index by dexterity */ dex_index = (adj_dex_blow[my_stat_ind[A_DEX]]); /* Maximal value */ if (dex_index > 11) dex_index = 11; /* Use the blows table */ num_blow = blows_table[str_index][dex_index]; /* Maximal value */ if (num_blow > num) num_blow = num; } /* Require at least one blow */ if (num_blow < 1) num_blow = 1; if (item->flags1 & TR1_BLOWS) num_blow += item->pval; num_blow *= item->iqty; if ( item->to_d > 8 || auto_level < 15 ) { home_damage += num_blow * (item->dd * (item->ds) + (my_to_dam + item->to_d)); } else { home_damage += num_blow * (item->dd * (item->ds) + (my_to_dam + 8)); } /* see if this item is a duplicate */ borg_notice_home_dupe( item, FALSE, i ); break; } case TV_BOW: num_bow += item->iqty; /* see if this item is a duplicate */ borg_notice_home_dupe( item, FALSE, i ); break; case TV_RING: num_rings += item->iqty; /*ring of damage */ #if 0 /* these are common as dirt so i commented this out */ home_damage += item->to_d * 10; #endif /* see if this item is a duplicate */ borg_notice_home_dupe( item, TRUE, i ); break; case TV_AMULET: num_neck += item->iqty; /* see if this item is a duplicate */ borg_notice_home_dupe( item, TRUE, i ); break; /* Books */ case TV_MAGIC_BOOK: case TV_PRAYER_BOOK: /* Skip incorrect books */ if (item->tval != mb_ptr->spell_book) break; /* Count the books */ num_book[item->sval] += item->iqty; break; /* Food */ case TV_FOOD: /* Analyze */ switch (item->sval) { case SV_FOOD_RATION: num_food += item->iqty; break; } break; /* Potions */ case TV_POTION: /* Analyze */ switch (item->sval) { case SV_POTION_CURE_CRITICAL: num_cure_critical += item->iqty; break; case SV_POTION_CURE_SERIOUS: num_cure_serious += item->iqty; break; case SV_POTION_RES_STR: num_fix_stat[A_STR] += item->iqty; break; case SV_POTION_RES_INT: num_fix_stat[A_INT] += item->iqty; break; case SV_POTION_RES_WIS: num_fix_stat[A_WIS] += item->iqty; break; case SV_POTION_RES_DEX: num_fix_stat[A_DEX] += item->iqty; break; case SV_POTION_RES_CON: num_fix_stat[A_CON] += item->iqty; break; case SV_POTION_RES_CHR: num_fix_stat[A_CHR] += item->iqty; break; case SV_POTION_RESTORE_EXP: num_fix_exp += item->iqty; break; case SV_POTION_RESTORE_MANA: num_mana += item->iqty; break; case SV_POTION_HEALING: num_heal += item->iqty; break; } break; /* Scrolls */ case TV_SCROLL: /* Analyze the scroll */ switch (item->sval) { case SV_SCROLL_IDENTIFY: num_ident += item->iqty; break; case SV_SCROLL_STAR_IDENTIFY: num_star_ident += item->iqty; break; case SV_SCROLL_PHASE_DOOR: num_phase += item->iqty; break; case SV_SCROLL_TELEPORT: num_escape += item->iqty; break; case SV_SCROLL_WORD_OF_RECALL: num_recall += item->iqty; break; case SV_SCROLL_ENCHANT_ARMOR: num_enchant_to_a += item->iqty; break; case SV_SCROLL_ENCHANT_WEAPON_TO_HIT: num_enchant_to_h += item->iqty; break; case SV_SCROLL_ENCHANT_WEAPON_TO_DAM: num_enchant_to_d += item->iqty; break; } break; /* Rods */ case TV_ROD: /* Analyze */ switch (item->sval) { case SV_ROD_IDENTIFY: num_ident += item->iqty * 100; break; case SV_ROD_RECALL: num_recall += item->iqty * 100; break; } break; /* Staffs */ case TV_STAFF: /* only collect staves with more than 3 charges at high level */ if (item->pval <= 3 && auto_level > 30) break; /* Analyze */ switch (item->sval) { case SV_STAFF_IDENTIFY: num_ident += item->iqty * item->pval; break; case SV_STAFF_TELEPORTATION: num_teleport += item->iqty * item->pval; break; } break; /* Missiles */ case TV_SHOT: case TV_ARROW: case TV_BOLT: /* Hack -- ignore invalid missiles */ if (item->tval != my_ammo_tval) break; /* Hack -- ignore worthless missiles */ if (item->value <= 0) break; /* Count them */ num_missile += item->iqty; break; } /* if only doing one item, break. */ if (in_item) break; } /*** Process the Spells and Prayers ***/ /* Handle "satisfy hunger" -> infinite food */ if (borg_spell_legal(2, 0) || borg_prayer_legal(1, 5)) { num_food += 1000; } /* Handle "identify" -> infinite identifies */ if (borg_spell_legal(2, 4) || borg_prayer_legal(5, 2)) { num_ident += 1000; } /* Handle "enchant weapon" */ if (borg_prayer_legal(7, 3)) { num_enchant_to_h += 1000; num_enchant_to_d += 1000; } /* Handle "enchant armor" */ if (borg_prayer_legal(7, 4)) { num_enchant_to_a += 1000; } /* handle restore */ if (borg_prayer_legal(6, 4)) { num_fix_exp += 1000; } /* Handle recall */ if (borg_prayer_legal(4, 4) || borg_spell_legal(5, 4)) { num_recall += 1000; } /*** Process the Needs ***/ /* Hack -- No need for stat repair */ if (my_sustain_str) num_fix_stat[A_STR] += 1000; if (my_sustain_int) num_fix_stat[A_INT] += 1000; if (my_sustain_wis) num_fix_stat[A_WIS] += 1000; if (my_sustain_dex) num_fix_stat[A_DEX] += 1000; if (my_sustain_con) num_fix_stat[A_CON] += 1000; if (my_sustain_chr) num_fix_stat[A_CHR] += 1000; /* race bonuses */ if (auto_race == RACE_ELF) num_resist_lite = 1000; if (auto_race == RACE_GNOME) num_free_act = 1000; if (auto_race == RACE_DWARF) num_resist_blind = 1000; if (auto_race == RACE_HALF_ORC) num_resist_dark = 1000; if (auto_race == RACE_HIGH_ELF) num_resist_lite = 1000; if (auto_race == RACE_HIGH_ELF) num_see_inv = 1000; } /* * Extract the bonuses for items in the home. * * in_item is passed in if you want to pretent that in_item is * the only item in the home. * no_items is passed in as TRUE if you want to pretend that the * home is empty. */ void borg_notice_home(auto_item *in_item, bool no_items) { /* Notice the home equipment */ borg_notice_home_aux1(in_item, no_items); /* Notice the home inventory */ borg_notice_home_aux2(in_item, no_items); } /* * Helper function -- calculate "power" of equipment */ static s32b borg_power_aux1(void) { int hold; int damage; int i; int cur_wgt = 0; int max_wgt = 0; s32b value = 0L; auto_item *item; /* Obtain the "hold" value (weight limit for weapons) */ hold = adj_str_hold[my_stat_ind[A_STR]]; /*** Analyze weapon ***/ /* Examine current weapon */ item = &auto_items[INVEN_WIELD]; /* Calculate "average" damage per "normal" blow */ /* and assume we can enchant up to +8 if auto_level > 25 */ if ( item->to_d > 8 || auto_level < 25 ) { damage = (item->dd * (item->ds) + (my_to_dam + item->to_d)); } else { damage = (item->dd * (item->ds) + (my_to_dam + 8)); } /* Reward "damage" */ value += (my_num_blow * damage * 110L); /* Reward "bonus to hit" */ if ( item->to_h > 8 || auto_level < 25 ) value += ((my_to_hit + item->to_h) * 25L); else value += ((my_to_hit + 8) * 25L); /* assume 2x base damage for x% of creatures */ damage = (item->dd * (item->ds)) * 2 * my_num_blow * 110L; if (my_slay_animal) value += (damage * 2) / 10; if (my_slay_evil) value += (damage * 2) / 10; /* assume 3x base damage for x% of creatures */ damage = (item->dd * (item->ds)) * 3 * my_num_blow * 110L; if (my_slay_undead) value += (damage * 9) / 100; if (my_slay_demon) value += (damage * 6) / 100; if (my_slay_orc) value += (damage * 9) / 100; if (my_slay_troll) value += (damage * 9) / 100; if (my_slay_giant) value += (damage * 9) / 100; if (my_slay_dragon) value += (damage * 11) / 100; if (my_brand_acid) value += (damage * 17) / 100; if (my_brand_elec) value += (damage * 17) / 100; if (my_brand_fire) value += (damage * 14) / 100; if (my_brand_cold) value += (damage * 14) / 100; /* assume 5x base damage for x% of creatures */ damage = (item->dd * (item->ds)) * 5 * my_num_blow * 110L; if (my_kill_dragon) value += (damage * 11) / 100; /* what ever... Will never get this anyway. it is only on Grond */ if (my_impact) value += 5000L; /* Hack -- It is hard to hold a heavy weapon */ if (hold < item->weight / 10) value -= 500000L; /*** Analyze bow ***/ /* Examine current bow */ item = &auto_items[INVEN_BOW]; /* Calculate "average" damage per "normal" shot (times 2) */ if ( item->to_d > 8 || auto_level < 25 ) damage = ((my_ammo_sides) + (item->to_d)) * my_ammo_power; else damage = (my_ammo_sides + 8) * my_ammo_power; /* Reward "damage" */ value += (my_num_fire * damage * 300L); /* Reward "bonus to hit" */ if ( item->to_h > 8 || auto_level < 25 ) value += ((my_to_hit + item->to_h) * 50L); else value += ((my_to_hit + 8) * 50L); /* Analyze the class */ switch (auto_class) { /* Prefer crossbows, then bows */ case CLASS_WARRIOR: case CLASS_ROGUE: case CLASS_PRIEST: case CLASS_PALADIN: if (my_ammo_tval == TV_BOLT) value += 50000L; /* Prefer bows */ case CLASS_MAGE: case CLASS_RANGER: if (my_ammo_tval == TV_ARROW) value += 30000L; } /* Hack -- It is hard to hold a heavy weapon */ if (hold < item->weight / 10) value -= 500000L; /*** Reward various things ***/ /* Hack -- Reward light radius */ value += (my_cur_lite * 1000000L); /* HACK reward upgrading artifact lites. (for activation) */ /* do this by assuming more valueable artifact lights are better */ if (my_cur_lite == 3) value += (auto_items[INVEN_LITE].value / 1000); /* Hack -- Reward speed */ if (my_speed < 130) value += ((my_speed - 110) * 20000L); else if (my_speed < 140) value += ((my_speed - 130) * 5000L) + 400000L; else value += ((my_speed - 140) * 500L) + 450000L; /* Hack -- Reward strength bonus */ value += (my_stat_ind[A_STR] * 500L); /* Hack -- Reward intelligence bonus */ if (mb_ptr->spell_book == TV_MAGIC_BOOK) { value += (my_stat_ind[A_INT] * 500L); /* Bonus for sp. */ value += ((adj_mag_mana[my_stat_ind[A_INT]] * auto_level) / 2) * 175L; /* bonus for fail rate */ value += adj_mag_stat[my_stat_ind[A_INT]] * 3100L; /* mage should try to get min fail to 0 */ if (auto_class == CLASS_MAGE) { if (adj_mag_fail[my_stat_ind[A_INT]] < 1) value += 70000L; } } /* Hack -- Reward wisdom bonus */ if (mb_ptr->spell_book == TV_PRAYER_BOOK) { value += (my_stat_ind[A_WIS] * 500L); /* Bonus for sp. */ value += ((adj_mag_mana[my_stat_ind[A_WIS]] * auto_level) / 2) * 150L; /* bonus for fail rate */ value += adj_mag_stat[my_stat_ind[A_WIS]] * 3000L; /* priest should try to get min fail to 0 */ if (auto_class == CLASS_PRIEST) { if (adj_mag_fail[my_stat_ind[A_WIS]] < 1) value += 70000L; } } /* Bonus for hp. */ value += (((adj_con_mhp[my_stat_ind[A_CON]] -128) * auto_level) / 2) *100L; /* HACK - a small bonus for adding to stats even above max. */ /* This will allow us to swap a ring of int +6 for */ /* our ring of int +2 even though we are at max int because */ /* we are wielding a weapon that has +4 int */ /* later it might be nice to swap to a weapon that does not */ /* have an int bonus */ for (i = 0; i < 6; i++) value += my_stat_add[i]; /* Hack -- Reward charisma bonus up to level 25 */ if (auto_level < 25) value += (my_stat_ind[A_CHR] * 10L); /*** Reward current skills ***/ /* Hack -- tiny rewards */ value += (my_skill_dis * 2L); value += (my_skill_dev * 50L); value += (my_skill_sav * 50L); /* perfect saves are very nice */ if (my_skill_sav > 99) value += 10000; value += (my_skill_stl * 2L); value += (my_skill_srh * 1L); value += (my_skill_fos * 1L); value += (my_skill_thn * 10L); value += (my_skill_thb * 70L); value += (my_skill_tht * 2L); value += (my_skill_dig * 2L); /*** Reward current flags ***/ /* Various flags */ if (my_slow_digest) value += 10L; if (my_ffall) value += 10L; if (my_lite) value += 2000L; if (my_telepathy) { if (my_see_inv) value += 500L; } else if (my_see_inv) value += 5000L; if (my_free_act) value += 10000L; /* after you max out you are pretty safe from drainers.*/ if (auto_level < 50) { if (my_hold_life) value += 2000L; } else { if (my_hold_life) value += 200L; } if (my_regenerate) value += 2000L; if (my_telepathy) value += 50000L; /* Immunity flags */ if (my_immune_cold) value += 30000L; if (my_immune_elec) value += 40000L; if (my_immune_fire) value += 60000L; if (my_immune_acid) value += 80000L; /* Resistance flags */ if (my_resist_cold) value += 3000L; if (my_resist_elec) value += 4000L; if (my_resist_acid) value += 6000L; if (my_resist_fire) value += 8000L; /* extra bonus for getting all basic resist */ if (my_resist_fire && my_resist_acid && my_resist_elec && my_resist_cold) value += 17500L; if (my_resist_pois) value += 20000L; if (my_resist_sound) value += 2000L; if (my_resist_lite) value += 200L; if (my_resist_dark) value += 200L; if (my_resist_chaos) value += 2000L; if (my_resist_conf) value += 5000L; if (my_resist_disen) value += 5000L; if (my_resist_shard) value += 100L; if (my_resist_nexus) value += 100L; if (my_resist_blind) value += 5000L; if (my_resist_neth) value += 5500L; if (my_resist_fear) value += 2000L; /* Sustain flags */ if (my_sustain_str) value += 50L; if (my_sustain_int) value += 50L; if (my_sustain_wis) value += 50L; if (my_sustain_con) value += 50L; if (my_sustain_dex) value += 50L; /*** XXX XXX XXX Reward "necessary" flags ***/ /* Mega-Hack -- See invisible (level 10) */ if ((my_see_inv || my_telepathy) && (auto_max_depth+1 >= 10)) value += 100000L; /* Mega-Hack -- Free action (level 20) */ if (my_free_act && (auto_max_depth+1 >= 20)) value += 100000L; /* Mega-Hack -- resist nether (level 50) */ if (my_resist_neth && (auto_max_depth+1 >= 50)) value += 100000L; /* Mega-Hack -- resist poison (level 40) */ if (my_resist_pois && (auto_max_depth+1 >= 40)) value += 100000L; /* Mega-Hack -- resist disenchant (level 60) */ if (my_resist_disen && (auto_max_depth+1 >= 60)) value += 100000L; /*** Reward powerful armor ***/ /* Reward armor */ /* HACK first 10 points are very important */ if ((my_ac + my_to_ac) < 10) value += ((my_ac + my_to_ac) * 10000L); else value += (((my_ac + my_to_ac)-10) * 15L) + 100000L; /*** Penalize various things ***/ /* Penalize various flags */ if (my_teleport) value -= 100000L; if (my_aggravate) value -= 50000L; /*** Penalize armor weight ***/ /* Compute the total armor weight */ cur_wgt += auto_items[INVEN_BODY].weight; cur_wgt += auto_items[INVEN_HEAD].weight; cur_wgt += auto_items[INVEN_ARM].weight; cur_wgt += auto_items[INVEN_OUTER].weight; cur_wgt += auto_items[INVEN_HANDS].weight; cur_wgt += auto_items[INVEN_FEET].weight; /* Determine the weight allowance */ max_wgt = mb_ptr->spell_weight; /* Hack -- heavy armor hurts magic */ if ((mb_ptr->spell_book) && (((cur_wgt - max_wgt) / 10) > 0) && (auto_max_level < 30)) { /* Mega-Hack -- Penalize heavy armor which hurts mana */ value -= (((cur_wgt - max_wgt) / 10) * (30 - auto_max_level) * 10L); } /*** Penalize bad magic ***/ /* Hack -- most gloves hurt magic for spell-casters */ if (mb_ptr->spell_book == TV_MAGIC_BOOK) { item = &auto_items[INVEN_HANDS]; /* Penalize non-usable gloves */ if (item->iqty && (!(item->flags2 & TR2_FREE_ACT)) && (!((item->flags1 & TR1_DEX) && (item->pval > 0)))) { /* Hack -- Major penalty */ value -= 50000L; } } /* Hack -- most edged weapons hurt magic for priests */ if (auto_class == CLASS_PRIEST) { item = &auto_items[INVEN_WIELD]; /* Penalize non-blessed edged weapons */ if (((item->tval == TV_SWORD) || (item->tval == TV_POLEARM)) && (!(item->flags3 & TR3_BLESSED))) { /* Hack -- Major penalty */ value -= 50000L; } } /* HUGE MEGA MONDO HACK! prepare for the big fight */ /* go after Morgoth new priorities. */ if ((auto_max_depth+1 >= 100) && borg_collect_potions_morgoth) { /* protect from stat drain */ if (my_sustain_str) value += 30000L; if (my_sustain_int) value += 30000L; if (my_sustain_wis) value += 30000L; if (my_sustain_con) value += 30000L; if (my_sustain_dex) value += 30000L; /* Another bonus for resist nether, poison and base four */ if (my_resist_neth) value += 100000L; if (my_resist_disen) value += 100000L; /* to protect against summoned baddies */ if (my_resist_pois) value += 100000L; if (my_resist_fire && my_resist_acid && my_resist_elec && my_resist_cold) value += 100000L; /* another damage bonus! need to hit hard to kill morgoth */ item = &auto_items[INVEN_WIELD]; /* Calculate "average" damage per "normal" blow (times 2) */ if ( item->to_d > 8 || auto_level < 25 ) { damage = (item->dd * (item->ds) + (my_to_dam + item->to_d)); } else { damage = (item->dd * (item->ds) + (my_to_dam + 8)); } /* Reward "damage" */ value += (my_num_blow * damage * 110L); damage = (item->dd * (item->ds)) * 2 * my_num_blow * 110L; if (my_slay_evil) value += (damage * 2) / 10; damage = (item->dd * (item->ds)) * 3 * my_num_blow * 110L; if (my_slay_giant) value += (damage * 9) / 100; } /* Result */ return (value); } /* * Helper function -- calculate power of inventory */ static s32b borg_power_aux2(void) { int k, book; s32b value = 0L; /*** Basic abilities ***/ /* Reward fuel */ k = 0; for (; k < 5 && k < amt_fuel; k++) value += 60000L; for (; k < 10 && k < amt_fuel; k++) value += 6000L; /* Reward food */ /* if weak, do not count food spells */ if (do_weak && amt_food > 1000) amt_food -= 1000; /* if hungry, food is THE top priority */ if (do_hungry) if (amt_food) value += 100000; k = 0; for (; k < 5 && k < amt_food; k++) value += 50000L; for (; k < 10 && k < amt_food; k++) value += 5000L; /* Reward ident */ k = 0; for (; k < 20 && k < amt_ident; k++) value += 6000L; for (; k < 40 && k < amt_ident; k++) value += 600L; /* Reward *id* (only carry one!) */ if (amt_star_ident) value += 10000L; /* Reward recall */ k = 0; for (; k < 3 && k < amt_recall; k++) value += 50000L; for (; k < 5 && k < amt_recall; k++) value += 5000L; /* Reward phase */ k = 1; /* first phase door is very important */ if (amt_phase) value += 50000; for (; k < 20 && k < amt_phase; k++) value += 500L; /* Reward escape */ k = 0; for (; k < 5 && k < amt_escape; k++) value += 10000L; /* Reward teleport */ k = 0; for (; k < 5 && k < amt_teleport; k++) value += 10000L; /* Reward teleport staves */ /*(try to carry more than one if we can afford it)*/ if (auto_level > 25) { k = 0; for (; k < 2 && k < amt_teleport_staff; k++) value += 2000L; } /*** Healing ***/ if (auto_mhp > 400) { /* normally keep all the heal you can get */ int heal_to_keep = 100; /* until getting ready for Morgoth */ if (fear_depth > 98) { /* if almost at Morgoth, keep only 5 to wipe out last uniques */ heal_to_keep = 5; /* unless we are heading for Morgoth land, then only keep one */ /* this will prevent us from whiping out our supply on Morgoth */ if (fear_depth > 99) { /* if in town, don't carry any */ if (!auto_depth) heal_to_keep = 0; else heal_to_keep = 1; /* unless going after morgoth, then get all potions! */ if (borg_collect_potions_morgoth) heal_to_keep = 100; } } k = 0; for (; k < heal_to_keep && k < amt_heal; k++) value += 4000L; /* preists do not collect extra heals, */ /* they clutter inventory too much */ if (auto_class != CLASS_PRIEST) { k = 0; for (; k < 100 && k < amt_ez_heal; k++) value += 4000L; } } /* Restore Mana */ if (auto_msp > 100) { /* normally keep all the restore manas you can get */ int mana_to_keep = 100; /* getting ready for Morgoth */ if (fear_depth > 98) { /* if almost at Morgoth, keep only 5 to wipe out last uniques */ mana_to_keep = 5; /* unless we are heading for Morgoth land, then only keep one */ /* this will prevent us from whiping out our supply on Morgoth */ if (fear_depth > 99) { /* if in town, don't carry any */ if (!auto_depth) mana_to_keep = 0; else mana_to_keep = 1; /* unless going after Morgoth, then get all potions! */ if (borg_collect_potions_morgoth) mana_to_keep = 100; } } k = 0; for (; k < mana_to_keep && k < amt_mana; k++) value += 4000L; k = 0; for (; k < 100 && k < amt_ez_mana; k++) value += 4000L; } /* Reward cure critical */ k = 0; for (; k < 5 && k < amt_cure_critical; k++) value += 5000L; for (; k < 20 && k < amt_cure_critical; k++) value += 500L; /* Reward cure serious */ /* only reward serious if low on crits */ if (amt_cure_critical < 10) { k = 0; for (; k < 5 && k < amt_cure_serious; k++) value += 50L; for (; k < 10 && k < amt_cure_serious; k++) value += 5L; } /*** Detection ***/ /* Reward detect trap */ k = 0; for (; k < 1 && k < amt_detect_trap; k++) value += 4000L; /* Reward detect door */ k = 0; for (; k < 1 && k < amt_detect_door; k++) value += 2000L; /* Reward speed potions/staves */ k = 0; for (; k < 50 && k < amt_speed; k++) value += 5000L; /*** Missiles ***/ /* Reward missiles */ k = 0; for (; k < 10 && k < amt_missile; k++) value += 1000L; for (; k < 50 && k < amt_missile; k++) value += 100L; /*** Various ***/ /* Hack -- Reward add stat */ if (amt_add_stat[A_STR]) value += 50000; if (amt_add_stat[A_INT]) value += 20000; if (mb_ptr->spell_book == TV_MAGIC_BOOK) if (amt_add_stat[A_INT]) value += 50000; if (amt_add_stat[A_WIS]) value += 20000; if (mb_ptr->spell_book == TV_PRAYER_BOOK) if (amt_add_stat[A_WIS]) value += 50000; if (amt_add_stat[A_DEX]) value += 50000; if (amt_add_stat[A_CON]) value += 50000; if (amt_add_stat[A_CHR]) value += 20000; /* Hack -- Reward fix stat */ if (amt_fix_stat[A_STR]) value += 10000; if (amt_fix_stat[A_INT]) value += 10000; if (amt_fix_stat[A_WIS]) value += 10000; if (amt_fix_stat[A_DEX]) value += 10000; if (amt_fix_stat[A_CON]) value += 10000; if (amt_fix_stat[A_CHR]) value += 10000; /* Hack -- Restore experience */ if (amt_fix_exp) value += 500000; /*** Enchantment ***/ /* Reward enchant armor */ if (amt_enchant_to_a && my_need_enchant_to_a) value += 14L; /* Reward enchant weapon to hit */ if (amt_enchant_to_h && my_need_enchant_to_h) value += 24L; /* Reward enchant weapon to damage */ if (amt_enchant_to_d && my_need_enchant_to_d) value += 109L; /*** Hack -- books ***/ /* Reward books */ for (book = 0; book < 9; book++) { /* No copies */ if (!amt_book[book]) continue; /* The "hard" books */ if (book >= 4) { /* Reward the book */ k = 0; for (; k < 1 && k < amt_book[book]; k++) value += 300000L; } /* The "easy" books */ else { int what, when = 99; /* Scan the spells */ for (what = 0; what < 9; what++) { auto_magic *as = &auto_magics[book][what]; /* Track minimum level */ if (as->level < when) when = as->level; } /* Hack -- Ignore "difficult" normal books */ if ((when > 5) && (when >= auto_max_level + 2)) continue; /* Reward the book */ k = 0; for (; k < 1 && k < amt_book[book]; k++) value += 500000L; if (auto_max_depth > 5) for (; k < 2 && k < amt_book[book]; k++) value += 10000L; if (auto_max_depth > 50) for (; k < 4 && k < amt_book[book]; k++) value += 10000L; } } /* Return the value */ return (value); } /* * Calculate the "power" of the Borg */ s32b borg_power(void) { s32b value = 0L; /* Process the equipment */ value += borg_power_aux1(); /* Process the inventory */ value += borg_power_aux2(); /* Return the value */ return (value); } /* * Helper function -- calculate power of equipment in the home */ static s32b borg_power_home_aux1(void) { s32b value = 0L; /* This would be better seperated by item type (so 1 bonus for resist cold armor */ /* 1 bonus for resist cold shield... but that would take a bunch more code. */ /* !FIX These number are heavily weighted toward the mage... they should adjusted */ /* to be less mageocentric. Also I just made them up. They seem to work but */ /* should probably be based on something more real. */ /* try to collect at least 2 of each resist/power (for swapping) */ /* This can be used to get rid of extra artifacts... */ if (num_slow_digest == 1) value += 50L; else if (num_slow_digest == 2) value += 70L; else if (num_slow_digest > 2) value += 70L + (num_slow_digest - 2) * 5L; if (num_regenerate == 1) value += 75L; else if (num_regenerate == 2) value += 100L; else if (num_regenerate > 2) value += 100L + (num_regenerate - 2) * 10L; if (num_telepathy == 1) value += 1000L; else if (num_telepathy == 2) value += 1500L; else if (num_telepathy > 2) value += 1500L + (num_telepathy - 2) * 10L; if (num_see_inv == 1) value += 800L; else if (num_see_inv == 2) value += 1200L; else if (num_see_inv > 2) value += 1200L + (num_see_inv - 2) * 10L; if (num_ffall == 1) value += 10L; else if (num_ffall == 2) value += 15L; else if (num_ffall > 2) value += 15L + (num_ffall - 2) * 1L; if (num_free_act == 1) value += 1000L; else if (num_free_act == 2) value += 1500L; else if (num_free_act > 2) value += 1500L + (num_free_act - 2) * 10L; if (num_hold_life == 1) value += 1000L; else if (num_hold_life == 2) value += 1500L; else if (num_hold_life > 2) value += 1500L + (num_hold_life - 2) * 10L; if (num_resist_acid == 1) value += 1000L; else if (num_resist_acid == 2) value += 1500L; else if (num_resist_acid > 2) value += 1500L + (num_resist_acid - 2) * 1L; if (num_immune_acid == 1) value += 3000L; else if (num_immune_acid == 2) value += 5000L; else if (num_immune_acid > 2) value += 5000L + (num_immune_acid - 2) * 30L; if (num_resist_elec == 1) value += 1000L; else if (num_resist_elec == 2) value += 1500L; else if (num_resist_elec > 2) value += 1500L + (num_resist_elec - 2) * 1L; if (num_immune_elec == 1) value += 3000L; else if (num_immune_elec == 2) value += 5000L; else if (num_immune_elec > 2) value += 5000L + (num_immune_elec - 2) * 30L; if (num_resist_fire == 1) value += 1000L; else if (num_resist_fire == 2) value += 1500L; else if (num_resist_fire > 2) value += 1500L + (num_resist_fire - 2) * 1L; if (num_immune_fire == 1) value += 3000L; else if (num_immune_fire == 2) value += 5000L; else if (num_immune_fire > 2) value += 5000L + (num_immune_fire - 2) * 30L; if (num_resist_cold == 1) value += 1000L; else if (num_resist_cold == 2) value += 1500L; else if (num_resist_cold > 2) value += 1500L + (num_resist_cold - 2) * 1L; if (num_immune_cold == 1) value += 3000L; else if (num_immune_cold == 2) value += 5000L; else if (num_immune_cold > 2) value += 5000L + (num_immune_cold - 2) * 30L; if (num_resist_pois == 1) value += 5000L; else if (num_resist_pois == 2) value += 9000L; else if (num_resist_pois > 2) value += 9000L + (num_resist_pois - 2) * 40L; if (num_resist_conf == 1) value += 2000L; else if (num_resist_conf == 2) value += 3500L; else if (num_resist_conf > 2) value += 3500L + (num_resist_conf - 2) * 45L; if (num_resist_sound == 1) value += 100L; else if (num_resist_sound == 2) value += 150L; else if (num_resist_sound > 2) value += 150L + (num_resist_sound - 2) * 1L; if (num_resist_lite == 1) value += 100L; else if (num_resist_lite == 2) value += 150L; else if (num_resist_lite > 2) value += 150L + (num_resist_lite - 2) * 1L; if (num_resist_dark == 1) value += 100L; else if (num_resist_dark == 2) value += 150L; else if (num_resist_dark > 2) value += 150L + (num_resist_dark - 2) * 1L; if (num_resist_chaos == 1) value += 1000L; else if (num_resist_chaos == 2) value += 1500L; else if (num_resist_chaos > 2) value += 1500L + (num_resist_chaos - 2) * 10L; if (num_resist_disen == 1) value += 5000L; else if (num_resist_disen == 2) value += 7000L; else if (num_resist_disen > 2) value += 7000L + (num_resist_disen - 2) * 35L; if (num_resist_shard == 1) value += 100L; else if (num_resist_shard == 2) value += 150L; else if (num_resist_shard > 2) value += 150L + (num_resist_shard - 2) * 1L; if (num_resist_nexus == 1) value += 200L; else if (num_resist_nexus == 2) value += 300L; else if (num_resist_nexus > 2) value += 300L + (num_resist_nexus - 2) * 2L; if (num_resist_blind == 1) value += 500L; else if (num_resist_blind == 2) value += 700L; else if (num_resist_blind > 2) value += 700L + (num_resist_blind - 2) * 5L; if (num_resist_neth == 1) value += 5000L; else if (num_resist_neth == 2) value += 7000L; else if (num_resist_neth > 2) value += 7000L + (num_resist_neth - 2) * 45L; /* stat gain items as well...(good to carry ring of dex +6 in */ /* house even if I don't need it right now) */ if (home_stat_add[A_STR] < 9) value += home_stat_add[A_STR] * 500L; else if (home_stat_add[A_STR] < 15) value += 9 * 500L + (home_stat_add[A_STR] - 9) * 200L; else value += 9 * 500L + 6 * 200L + (home_stat_add[A_STR] - 15) * 1L; if (home_stat_add[A_DEX] < 9) value += home_stat_add[A_DEX] * 500L; else if (home_stat_add[A_DEX] < 15) value += 9 * 500L + (home_stat_add[A_DEX] - 9) * 200L; else value += 9 * 500L + 6 * 200L + (home_stat_add[A_DEX] - 15) * 1L; /* HACK extra con for thorin and other such things */ if (home_stat_add[A_CON] < 15) value += home_stat_add[A_CON] * 500L; else if (home_stat_add[A_CON] < 21) value += 15 * 500L + (home_stat_add[A_CON] - 15) * 200L; else value += 15 * 500L + 6 * 200L + (home_stat_add[A_CON] - 21) * 1L; /* int and wis are only bonused for spell casters. */ if (mb_ptr->spell_book == TV_MAGIC_BOOK) { if (home_stat_add[A_INT] < 20) value += home_stat_add[A_INT] * 600L; else if (home_stat_add[A_INT] < 26) value += 20 * 600L + (home_stat_add[A_INT] - 20) * 300L; else value += 20 * 300L + 6 * 300L + (home_stat_add[A_INT] - 26) * 5L; } if (mb_ptr->spell_book == TV_PRAYER_BOOK) { if (home_stat_add[A_WIS] < 20) value += home_stat_add[A_WIS] * 600L; else if (home_stat_add[A_WIS] < 26) value += 20 * 600L + (home_stat_add[A_WIS] - 20) * 300L; else value += 20 * 600L + 6 * 300L + (home_stat_add[A_WIS] - 26) * 3L; } /* do a minus for too many duplicates. This way we do not store */ /* useless items and spread out types of items. */ if (num_weapons > 5) value -= (num_weapons - 5) * 2000L; else if (num_weapons > 1) value -= (num_weapons - 1) * 100L; if (num_bow > 2) value -= (num_bow - 2) * 1000L; if (num_rings > 6) value -= (num_rings - 6) * 4000L; else if (num_rings > 4) value -= (num_rings - 4) * 2000L; if (num_neck > 3) value -= (num_neck - 3) * 1500L; else if (num_neck > 2) value -= (num_neck - 2) * 700L; if (num_armor > 6) value -= (num_armor - 6) * 1000L; if (num_cloaks > 3) value -= (num_cloaks - 3) * 1000L; if (num_shields > 3) value -= (num_shields - 3) * 1000L; if (num_hats > 4) value -= (num_hats - 4) * 1000L; if (num_gloves > 3) value -= (num_gloves - 3) * 1000L; if (num_boots > 2) value -= (num_boots - 2) * 1000L; /* HACK no spare lite sorces. Not needed */ if (num_lite > 1) value -= 5000L; value += home_damage * 5L; value += num_speed * 1000L; /* if edged and priest, dump it */ value -= num_edged_weapon * 3000L; /* if gloves and mage or ranger and not FA/Dex, dump it. */ value -= num_bad_gloves * 3000L; /* do not allow duplication of items. */ value -= num_duplicate_items * 50000L; /* Return the value */ return (value); } /* * Helper function -- calculate power of items in the home * * The weird calculations help spread out the purchase order */ static s32b borg_power_home_aux2(void) { int k, book; s32b value = 0L; /*** Basic abilities ***/ /* Collect food */ for (k = 0; k < 10 && k < num_food; k++) value += 8000L - k*10L; /* Collect ident */ for (k = 0; k < 50 && k < num_ident; k++) value += 2000L - k*10L; /* Collect *id*ent */ for (k = 0; k < 50 && k < num_star_ident; k++) value += 5000L - k*10L; /* Collect recall */ for (k = 0; k < 50 && k < num_recall; k++) value += 3000L - k*10L; /* Collect escape */ for (k = 0; k < 50 && k < num_escape; k++) value += 2000L - k*10L; /* Collect teleport */ for (k = 0; k < 50 && k < num_teleport; k++) value += 400L - k*8L; /* collect heal/mana */ if (auto_msp > 100) for (k = 0; k < 50 && k < num_mana; k++) value += 2000L - k*8L; if (auto_mhp > 400) for (k = 0; k < 50 && k < num_heal; k++) value += 2000L - k*8L; /* collect potions to go after Morgoth */ if (((auto_msp <= 100) || (num_mana > 14)) && (num_heal > 9)) { borg_collect_potions_morgoth = TRUE; } /*** Healing ***/ /* Collect cure critical */ if (auto_level > 35) for (k = 0; k < 90 && k < num_cure_critical; k++) value += 1500L-k*10L; else for (k = 0; k < 30 && k < num_cure_critical; k++) value += 1500L-k*10L; /*** Various ***/ if (auto_level > 35) for (k = 0; k < 70 && k < num_fix_exp; k++) value += 5000L - k*10L; else for (k = 0; k < 5 && k < num_fix_exp; k++) value += 5000L - k*10L; /*** Hack -- books ***/ /* Reward books */ for (book = 0; book < 4; book++) { if (auto_level > 35) /* Collect up to 5 copies of each normal book */ for (k = 0; k < 70 && k < num_book[book]; k++) { /* Hack -- only stockpile useful books */ if (num_book[book]) value += 5000L - k*10L; } else /* Collect up to 5 copies of each normal book */ for (k = 0; k < 5 && k < num_book[book]; k++) { /* Hack -- only stockpile useful books */ if (num_book[book]) value += 5000L - k*10L; } } /* Reward artifacts in the home */ value += num_artifact * 500L; /* Return the value */ return (value); } /* * Calculate the "power" of the home */ s32b borg_power_home(void) { s32b value = 0L; /* Process the home equipment */ value += borg_power_home_aux1(); /* Process the home inventory */ value += borg_power_home_aux2(); /* Return the value */ return (value); } /* * Calculate base danger from a monster's physical attacks * * We attempt to take account of various resistances, both in * terms of actual damage, and special effects, as appropriate. * * We reduce the danger from distant "sleeping" monsters. */ static int borg_danger_aux1(int i) { int k, n = 0; int power, chance; s16b ac = my_ac; auto_kill *kill = &auto_kills[i]; monster_race *r_ptr = &r_info[kill->r_idx]; /* goi gives +100 to ac */ if (borg_goi) ac += 100; /* shields gives +50 to ac */ if (borg_shield) ac += 50; /* Mega-Hack -- unknown monsters */ if (kill->r_idx >= MAX_R_IDX) return (1000); /* Analyze each physical attack */ for (k = 0; k < 4; k++) { int z = 0; monster_blow *b_ptr = &r_ptr->blow[k]; power = 0; /* Done */ if (!b_ptr->method) break; /* Analyze the attack */ switch (b_ptr->effect) { case RBE_HURT: z = (b_ptr->d_dice * b_ptr->d_side); z -= (z * ((ac < 150) ? ac : 150) / 250); /* if invulnurable, no damage */ if (borg_goi && !borg_attacking) z = 0; /* stun */ if ((b_ptr->d_side < 3) && (z > 19)) n += 150; power = 60; break; case RBE_POISON: z = (b_ptr->d_dice * b_ptr->d_side); power = 5; if (my_resist_pois) break; if (borg_temp_poison) break; if (!borg_full_damage) z += 10; break; case RBE_UN_BONUS: z = (b_ptr->d_dice * b_ptr->d_side); power = 20; if (borg_goi && !borg_attacking) z = 0; if (my_resist_disen) break; /* if invulnurable, no damage */ if (!borg_full_damage) z += 500; break; case RBE_UN_POWER: z = (b_ptr->d_dice * b_ptr->d_side); /* if invulnurable, no damage */ if (borg_goi && !borg_attacking) z = 0; if (!borg_full_damage) z += 20; power = 15; break; case RBE_EAT_GOLD: z = (b_ptr->d_dice * b_ptr->d_side); /* if in town and low level avoid them stupid urchins */ if (auto_level < 3) z += 50; /* if invulnurable, no damage */ power = 5; if (borg_goi && !borg_attacking) z = 0; if (100 <= adj_dex_safe[my_stat_ind[A_DEX]] + auto_level) break; if (auto_gold < 100) break; if (!borg_full_damage) z += 5; break; case RBE_EAT_ITEM: z = (b_ptr->d_dice * b_ptr->d_side); /* if invulnurable, no damage */ power = 5; if (borg_goi && !borg_attacking) z = 0; if (100 <= adj_dex_safe[my_stat_ind[A_DEX]] + auto_level) break; if (!borg_full_damage) z += 20; break; case RBE_EAT_FOOD: z = (b_ptr->d_dice * b_ptr->d_side); power = 5; /* if invulnurable, no damage */ if (borg_goi && !borg_attacking) z = 0; if (amt_food > 5) break; if (!borg_full_damage) z += 5; break; case RBE_EAT_LITE: z = (b_ptr->d_dice * b_ptr->d_side); power = 5; /* if invulnurable, no damage */ if (borg_goi && !borg_attacking) z = 0; if (amt_fuel > 5) break; if (!borg_full_damage) z += 20; break; case RBE_ACID: if (my_immune_acid) break; z = (b_ptr->d_dice * b_ptr->d_side); if (my_resist_acid) z = (z + 2) / 3; if (borg_temp_acid) z = (z + 2) / 3; /* if invulnurable, no damage */ if (borg_goi && !borg_attacking) z = 0; if (!borg_full_damage) z += 20; break; case RBE_ELEC: if (my_immune_elec) break; z = (b_ptr->d_dice * b_ptr->d_side); power = 10; /* if invulnurable, no damage */ if (borg_goi && !borg_attacking) z = 0; if (my_resist_elec) z = (z + 2) / 3; if (borg_temp_elec) z = (z + 2) / 3; if (!borg_full_damage) z += 10; break; case RBE_FIRE: if (my_immune_fire) break; z = (b_ptr->d_dice * b_ptr->d_side); power = 10; /* if invulnurable, no damage */ if (borg_goi && !borg_attacking) z = 0; if (my_resist_fire) z = (z + 2) / 3; if (borg_temp_fire) z = (z + 2) / 3; if (!borg_full_damage) z += 20; break; case RBE_COLD: if (my_immune_cold) break; z = (b_ptr->d_dice * b_ptr->d_side); power = 10; /* if invulnurable, no damage */ if (borg_goi && !borg_attacking) z = 0; if (my_resist_cold) z = (z + 2) / 3; if (borg_temp_cold) z = (z + 2) / 3; if (!borg_full_damage) z += 15; break; case RBE_BLIND: z = (b_ptr->d_dice * b_ptr->d_side); power = 2; /* if invulnurable, no damage */ if (borg_goi && !borg_attacking) z = 0; if (my_resist_blind) break; if (!borg_full_damage) z += 10; break; case RBE_CONFUSE: z = (b_ptr->d_dice * b_ptr->d_side); power = 10; /* if invulnurable, no damage */ if (borg_goi && !borg_attacking) z = 0; if (my_resist_conf) break; if (!borg_full_damage) z += 10; break; case RBE_TERRIFY: z = (b_ptr->d_dice * b_ptr->d_side); power = 10; /* if invulnurable, no damage */ if (borg_goi && !borg_attacking) z = 0; if (my_resist_fear) break; if (!borg_full_damage) z += 10; break; case RBE_PARALYZE: z = (b_ptr->d_dice * b_ptr->d_side); power = 2; /* if invulnurable, no damage */ if (borg_goi && !borg_attacking) z = 0; if (my_free_act) break; z += 200; break; case RBE_LOSE_STR: z = (b_ptr->d_dice * b_ptr->d_side); /* if invulnurable, no damage */ if (borg_goi && !borg_attacking) z = 0; if (my_sustain_str) break; if (auto_stat[A_STR] <= 3) break; if (borg_prayer_legal(6, 3)) break; if (!borg_full_damage) { z += 50; /* extra scary to have str drain below 10 */ if (auto_stat[A_STR] < 10) z += 250; } break; case RBE_LOSE_DEX: z = (b_ptr->d_dice * b_ptr->d_side); /* if invulnurable, no damage */ if (borg_goi && !borg_attacking) z = 0; if (my_sustain_dex) break; if (auto_stat[A_DEX] <= 3) break; if (borg_prayer_legal(6, 3)) break; if (!borg_full_damage) z += 50; break; case RBE_LOSE_CON: z = (b_ptr->d_dice * b_ptr->d_side); /* if invulnurable, no damage */ if (borg_goi && !borg_attacking) z = 0; if (my_sustain_con) break; if (auto_stat[A_CON] <= 3) break; if (borg_prayer_legal(6, 3)) break; if (!borg_full_damage) { z += 50; /* extra scary to have con drain below 8 */ if (auto_stat[A_STR] < 8) z += 250; } break; case RBE_LOSE_INT: z = (b_ptr->d_dice * b_ptr->d_side); /* if invulnurable, no damage */ if (borg_goi && !borg_attacking) z = 0; if (my_sustain_int) break; if (auto_stat[A_INT] <= 3) break; if (borg_prayer_legal(6, 3)) break; if (!borg_full_damage) { z += 5; /* extra scary for spell caster */ if (mb_ptr->spell_book == TV_MAGIC_BOOK) z += 100; } break; case RBE_LOSE_WIS: z = (b_ptr->d_dice * b_ptr->d_side); /* if invulnurable, no damage */ if (borg_goi && !borg_attacking) z = 0; if (my_sustain_wis) break; if (auto_stat[A_WIS] <= 3) break; if (borg_prayer_legal(6, 3)) break; if (!borg_full_damage) { z += 5; /* extra scary for pray'er */ if (mb_ptr->spell_book == TV_PRAYER_BOOK) z += 100; } break; case RBE_LOSE_CHR: z = (b_ptr->d_dice * b_ptr->d_side); /* if invulnurable, no damage */ if (borg_goi && !borg_attacking) z = 0; if (my_sustain_chr) break; if (auto_stat[A_CHR] <= 3) break; if (borg_prayer_legal(6, 3)) break; if (!borg_full_damage) z += 5; break; case RBE_LOSE_ALL: z = (b_ptr->d_dice * b_ptr->d_side); power = 2; /* if invulnurable, no damage */ if (borg_goi && !borg_attacking) z = 0; /* only morgoth. HACK to make it easier to fight him */ break; z += 50; break; case RBE_SHATTER: z = (b_ptr->d_dice * b_ptr->d_side); z -= (z * ((ac < 150) ? ac : 150) / 250); power = 60; /* if invulnurable, no damage */ if (borg_goi && !borg_attacking) z = 0; if (borg_goi && !borg_attacking) z += 150; break; case RBE_EXP_10: z = (b_ptr->d_dice * b_ptr->d_side); /* if invulnurable, no damage */ if (borg_goi && !borg_attacking) z = 0; if (my_hold_life) break; /* do not worry about drain exp after level 50 */ if (auto_level == 50) break; if (borg_prayer_legal(6, 4)) break; if (!borg_full_damage) z += 100; break; case RBE_EXP_20: z = (b_ptr->d_dice * b_ptr->d_side); /* if invulnurable, no damage */ if (borg_goi && !borg_attacking) z = 0; if (my_hold_life) break; /* do not worry about drain exp after level 50 */ if (auto_level == 50) break; if (borg_prayer_legal(6, 4)) break; if (!borg_full_damage) z += 150; break; case RBE_EXP_40: z = (b_ptr->d_dice * b_ptr->d_side); /* if invulnurable, no damage */ if (borg_goi && !borg_attacking) z = 0; if (my_hold_life) break; /* do not worry about drain exp after level 50 */ if (auto_level == 50) break; if (borg_prayer_legal(6, 4)) break; if (!borg_full_damage) z += 200; break; case RBE_EXP_80: z = (b_ptr->d_dice * b_ptr->d_side); /* if invulnurable, no damage */ if (borg_goi && !borg_attacking) z = 0; if (my_hold_life) break; /* do not worry about drain exp after level 50 */ if (auto_level == 50) break; if (borg_prayer_legal(6, 4)) break; if (!borg_full_damage) z += 250; break; } /* if we are doing partial damage reduse for % chance that it will */ /* hit you. */ if (!borg_full_damage) { /* figure out chance that monster will hit you. */ /* add a 30% bonus in to account for bad luck. */ if ((r_ptr->level + power) > 0) chance = 130 - (((ac * 300) / 4) / ((r_ptr->level + power) * 3)); else chance = -1; /* always have a 5% chance of hitting. */ if (chance < 0) z = (z * 5) / 100; if (chance < 100) z = (z * chance) / 100; } /* Add in damage */ n += z; } if (!borg_full_damage) { /* Hack -- Apply "protection from evil" */ if ((borg_prot_from_evil) && (r_ptr->flags3 & RF3_EVIL) && (auto_level >= r_ptr->level)) { n = (n * (100 - (50 + auto_level)))/100; } } /* Return danger */ return (n); } /* * Calculate base danger from a monster's spell attacks * * We attempt to take account of various resistances, both in * terms of actual damage, and special effects, as appropriate. * * We reduce the danger from distant "sleeping" monsters. */ static int borg_danger_aux2(int i) { int q, k, n = 0; int lev, hp; byte spell[96], num = 0; auto_kill *kill = &auto_kills[i]; monster_race *r_ptr = &r_info[kill->r_idx]; /* Mega-Hack -- unknown monsters */ if (kill->r_idx >= MAX_R_IDX) return (1000); /* Extract the "inate" spells */ for (k = 0; k < 32; k++) { if (r_ptr->flags4 & (1L << k)) spell[num++] = k + 32 * 3; } /* Extract the "normal" spells */ for (k = 0; k < 32; k++) { if (r_ptr->flags5 & (1L << k)) spell[num++] = k + 32 * 4; } /* Extract the "bizarre" spells */ for (k = 0; k < 32; k++) { if (r_ptr->flags6 & (1L << k)) spell[num++] = k + 32 * 5; } /* Paranoia -- Nothing to cast */ if (!num) return (0); /* Extract the level */ lev = r_ptr->level; /* Extract hit-points */ hp = kill->power; /* Analyze the spells */ for (q = 0; q < num; q++) { int p = 0; int z = 0; /* Cast the spell. */ switch (spell[q]) { case 96+0: /* RF4_SHRIEK */ /* if looking at full damage, things that are just annoying */ /* do not count.*/ if (!borg_full_damage) p += 10; break; case 96+1: /* RF4_XXX2X4 */ break; case 96+2: /* RF4_XXX3X4 */ break; case 96+3: /* RF4_XXX4X4 */ break; case 96+4: /* RF4_ARROW_1 */ z = (1 * 6); break; case 96+5: /* RF4_ARROW_2 */ z = (3 * 6); break; case 96+6: /* RF4_ARROW_3 */ z = (5 * 6); break; case 96+7: /* RF4_ARROW_4 */ z = (7 * 6); break; case 96+8: /* RF4_BR_ACID */ if (my_immune_acid) break; z = (hp / 3); /* max damage */ if (z > 1600) z = 1600; if (my_resist_acid) z = (z + 2) / 3; if (borg_temp_acid) z = (z + 2) / 3; /* if looking at full damage, things that are just annoying */ /* do not count.*/ if (!borg_full_damage) p += 40; break; case 96+9: /* RF4_BR_ELEC */ if (my_immune_elec) break; z = (hp / 3); /* max damage */ if (z > 1600) z = 1600; if (my_resist_elec) z = (z + 2) / 3; if (borg_temp_elec) z = (z + 2) / 3; /* if looking at full damage, things that are just annoying */ /* do not count.*/ if (!borg_full_damage) p += 20; break; case 96+10: /* RF4_BR_FIRE */ if (my_immune_fire) break; z = (hp / 3); /* max damage */ if (z > 1600) z = 1600; if (my_resist_fire) z = (z + 2) / 3; if (borg_temp_fire) z = (z + 2) / 3; /* if looking at full damage, things that are just annoying */ /* do not count. */ if (!borg_full_damage) p += 40; break; case 96+11: /* RF4_BR_COLD */ if (my_immune_cold) break; z = (hp / 3); /* max damage */ if (z > 1600) z = 1600; if (my_resist_cold) z = (z + 2) / 3; if (borg_temp_cold) z = (z + 2) / 3; /* if looking at full damage, things that are just annoying */ /* do not count. */ if (!borg_full_damage) p += 20; break; case 96+12: /* RF4_BR_POIS */ z = (hp / 3); /* max damage */ if (z > 800) z = 800; if (my_resist_pois) z = (z + 2) / 3; if (borg_temp_poison) z = (z + 2) / 3; if (borg_temp_poison) break; if (my_resist_pois) break; /* if looking at full damage, things that are just annoying */ /* do not count. */ if (!borg_full_damage) p += 20; break; case 96+13: /* RF4_BR_NETH */ z = (hp / 6); /* max damage */ if (z > 550) z = 550; if (my_resist_neth) z = (z*6)/8; if (my_resist_neth) break; /* if looking at full damage, things that are just annoying */ /* do not count. */ if (!borg_full_damage) p += 50; if (my_hold_life) break; /* do not worry about drain exp after level 50 */ if (auto_level == 50) break; /* if looking at full damage, things that are just annoying */ /* do not count. */ if (!borg_full_damage) p += 150; break; case 96+14: /* RF4_BR_LITE */ z = (hp / 6); /* max damage */ if (z > 400) z = 400; if (my_resist_lite) z = (z*2)/3; if (my_resist_lite) break; if (my_resist_blind) break; p += 20; break; case 96+15: /* RF4_BR_DARK */ z = (hp / 6); /* max damage */ if (z > 400) z = 400; if (my_resist_dark) z = (z*2)/ 3; if (my_resist_dark) break; if (my_resist_blind) break; p += 20; break; case 96+16: /* RF4_BR_CONF */ z = (hp / 6); /* max damage */ if (z > 400) z = 400; if (my_resist_conf) z = z / 2; if (my_resist_conf) break; /* if looking at full damage, things that are just annoying */ /* do not count. */ if (!borg_full_damage) p += 100; break; case 96+17: /* RF4_BR_SOUN */ z = (hp / 6); /* max damage */ if (z > 400) z = 400; if (my_resist_sound) z = (z*5)/8; if (my_resist_sound) break; /* if looking at full damage, things that are just annoying */ /* do not count. */ if (!borg_full_damage) p += 50; break; case 96+18: /* RF4_BR_CHAO */ z = (hp / 6); /* max damage */ if (z > 600) z = 600; if (my_resist_chaos) z = (z*6)/8; if (my_resist_chaos) break; p += 200; if (my_resist_neth) break; if (my_hold_life) break; /* do not worry about drain exp after level 50 */ if (auto_level == 50) break; /* if looking at full damage, things that are just annoying */ /* do not count. */ if (!borg_full_damage) p += 100; if (my_resist_conf) break; p += 50; break; case 96+19: /* RF4_BR_DISE */ z = (hp / 6); /* max damage */ if (z > 500) z = 500; if (my_resist_disen) z = (z*6)/8; if (my_resist_disen) break; p += 500; break; case 96+20: /* RF4_BR_NEXU */ z = (hp / 3); /* max damage */ if (z > 250) z = 250; if (my_resist_nexus) z = (z*6)/8; if (my_resist_nexus) break; /* if looking at full damage, things that are just annoying */ /* do not count. */ if (!borg_full_damage) p += 100; break; case 96+21: /* RF4_BR_TIME */ z = (hp / 3); /* max damage */ if (z > 150) z = 150; /* if looking at full damage, things that are just annoying */ /* do not count. */ if (!borg_full_damage) p += 250; break; case 96+22: /* RF4_BR_INER */ z = (hp / 6); /* max damage */ if (z > 200) z = 200; /* if looking at full damage, things that are just annoying */ /* do not count. */ if (!borg_full_damage) p += 50; break; case 96+23: /* RF4_BR_GRAV */ z = (hp / 3); /* max damage */ if (z > 200) z = 200; /* if looking at full damage, things that are just annoying */ /* do not count. */ if (!borg_full_damage) p += 50; if (my_resist_sound) break; /* if looking at full damage, things that are just annoying */ /* do not count. */ if (!borg_full_damage) p += 50; break; case 96+24: /* RF4_BR_SHAR */ z = (hp / 6); /* max damage */ if (z > 400) z = 400; if (my_resist_shard) z = (z*6)/8; if (my_resist_shard) break; /* if looking at full damage, things that are just annoying */ /* do not count. */ if (!borg_full_damage) p += 50; break; case 96+25: /* RF4_BR_PLAS */ z = (hp / 6); /* max damage */ if (z > 150) z = 150; if (my_resist_sound) break; p += 100; break; case 96+26: /* RF4_BR_WALL */ z = (hp / 6); /* max damage */ if (z > 150) z = 150; if (my_resist_sound) break; p += 50; break; case 96+27: /* RF4_BR_MANA */ /* XXX XXX XXX */ break; case 96+28: /* RF4_XXX5X4 */ break; case 96+29: /* RF4_XXX6X4 */ break; case 96+30: /* RF4_XXX7X4 */ break; case 96+31: /* RF4_XXX8X4 */ break; case 128+0: /* RF5_BA_ACID */ if (my_immune_acid) break; z = (lev * 3) + 15; if (my_resist_acid) z = (z + 2) / 3; if (borg_temp_acid) z = (z + 2) / 3; /* if looking at full damage, things that are just annoying */ /* do not count. */ if (!borg_full_damage) p += 40; break; case 128+1: /* RF5_BA_ELEC */ if (my_immune_elec) break; z = (lev * 3) / 2 + 8; if (my_resist_elec) z = (z + 2) / 3; if (borg_temp_elec) z = (z + 2) / 3; /* if looking at full damage, things that are just annoying */ /* do not count. */ if (!borg_full_damage) p += 20; break; case 128+2: /* RF5_BA_FIRE */ if (my_immune_fire) break; z = (lev * 7) / 2 + 10; if (my_resist_fire) z = (z + 2) / 3; if (borg_temp_fire) z = (z + 2) / 3; /* if looking at full damage, things that are just annoying */ /* do not count. */ if (!borg_full_damage) p += 40; break; case 128+3: /* RF5_BA_COLD */ if (my_immune_cold) break; z = (lev * 3) / 2 + 10; if (my_resist_cold) z = (z + 2) / 3; if (borg_temp_cold) z = (z + 2) / 3; /* if looking at full damage, things that are just annoying */ /* do not count. */ if (!borg_full_damage) p += 20; break; case 128+4: /* RF5_BA_POIS */ z = (12 * 2); if (my_resist_pois) z = (z + 2) / 3; if (borg_temp_poison) z = (z + 2) / 3; if (borg_temp_poison) break; if (my_resist_pois) break; /* if looking at full damage, things that are just annoying */ /* do not count. */ if (!borg_full_damage) p += 20; break; case 128+5: /* RF5_BA_NETH */ z = (50 + (10 * 10) + lev); if (my_resist_neth) z = (z*6)/8; if (my_resist_neth) break; /* if looking at full damage, things that are just annoying */ /* do not count. */ if (!borg_full_damage) p += 200; break; case 128+6: /* RF5_BA_WATE */ z = ((lev * 5) / 2) + 50; if (my_resist_sound) break; if (my_resist_conf) break; /* if looking at full damage, things that are just annoying */ /* do not count. */ if (!borg_full_damage) p += 50; break; case 128+7: /* RF5_BA_MANA */ z = ((lev * 5) + (10 * 10)); break; case 128+8: /* RF5_BA_DARK */ z = ((lev * 5) + (10 * 10)); if (my_resist_dark) z = z / 2; if (my_resist_dark) break; if (my_resist_blind) break; /* if looking at full damage, things that are just annoying */ /* do not count. */ if (!borg_full_damage) p += 20; break; case 128+9: /* RF5_DRAIN_MANA */ if (auto_msp) p += 10; break; case 128+10: /* RF5_MIND_BLAST */ if (my_skill_sav < 100) z = 20; break; case 128+11: /* RF5_BRAIN_SMASH */ z = (12 * 15); p += 200 - 2 * my_skill_sav; if (p < 0) p =0; break; case 128+12: /* RF5_CAUSE_1 */ if (my_skill_sav >= 100) break; z = (3 * 8); /* if looking at full damage, things that are just annoying */ /* do not count. */ if (!borg_full_damage) /* reduce by % chance of save (add 20% for fudge) */ z = z * (120 - my_skill_sav) / 100; break; case 128+13: /* RF5_CAUSE_2 */ if (my_skill_sav >= 100) break; z = (8 * 8); /* if looking at full damage, things that are just annoying */ /* do not count. */ if (!borg_full_damage) /* reduce by % chance of save (add 20% for fudge) */ z = z * (120 - my_skill_sav) / 100; break; case 128+14: /* RF5_CAUSE_3 */ if (my_skill_sav >= 100) break; z = (10 * 15); /* if looking at full damage, things that are just annoying */ /* do not count. */ if (!borg_full_damage) /* reduce by % chance of save (add 20% for fudge) */ z = z * (120 - my_skill_sav) / 100; break; case 128+15: /* RF5_CAUSE_4 */ if (my_skill_sav >= 100) break; z = (15 * 15); /* if looking at full damage, things that are just annoying */ /* do not count. */ if (!borg_full_damage) p += 20; /* if looking at full damage, things that are just annoying */ /* do not count. */ if (!borg_full_damage) /* reduce by % chance of save (add 40% for fudge) */ z = z * (120 - my_skill_sav) / 100; break; case 128+16: /* RF5_BO_ACID */ if (my_immune_acid) break; z = ((7 * 8) + (lev / 3)); if (my_resist_acid) z = (z + 2) / 3; if (borg_temp_acid) z = (z + 2) / 3; /* if looking at full damage, things that are just annoying */ /* do not count. */ if (!borg_full_damage) p += 40; break; case 128+17: /* RF5_BO_ELEC */ if (my_immune_elec) break; z = ((4 * 8) + (lev / 3)); if (my_resist_elec) z = (z + 2) / 3; if (borg_temp_elec) z = (z + 2) / 3; /* if looking at full damage, things that are just annoying */ /* do not count. */ if (!borg_full_damage) p += 20; break; case 128+18: /* RF5_BO_FIRE */ if (my_immune_fire) break; z = ((9 * 8) + (lev / 3)); if (my_resist_fire) z = (z + 2) / 3; if (borg_temp_fire) z = (z + 2) / 3; /* if looking at full damage, things that are just annoying */ /* do not count. */ if (!borg_full_damage) p += 40; break; case 128+19: /* RF5_BO_COLD */ if (my_immune_cold) break; z = ((6 * 8) + (lev / 3)); if (my_resist_cold) z = (z + 2) / 3; if (borg_temp_cold) z = (z + 2) / 3; /* if looking at full damage, things that are just annoying */ /* do not count. */ if (!borg_full_damage) p += 20; break; case 128+20: /* RF5_BO_POIS */ /* XXX XXX XXX */ break; case 128+21: /* RF5_BO_NETH */ z = (30 + (5 * 5) + (lev * 3) / 2); if (my_resist_neth) z = (z*6)/8; if (my_resist_neth) break; /* if looking at full damage, things that are just annoying */ /* do not count. */ if (!borg_full_damage) p += 200; break; case 128+22: /* RF5_BO_WATE */ z = ((10 * 10) + (lev)); if (my_resist_sound) break; if (my_resist_conf) break; /* if looking at full damage, things that are just annoying */ /* do not count. */ if (!borg_full_damage) p += 20; break; case 128+23: /* RF5_BO_MANA */ z = ((lev * 7) / 2) + 50; break; case 128+24: /* RF5_BO_PLAS */ z = (10 + (8 * 7) + (lev)); /* if looking at full damage, things that are just annoying */ /* do not count. */ if (!borg_full_damage) p += 20; break; case 128+25: /* RF5_BO_ICEE */ z = ((6 * 6) + (lev)); /* if looking at full damage, things that are just annoying */ /* do not count. */ if (!borg_full_damage) p += 20; break; case 128+26: /* RF5_MISSILE */ z = ((2 * 6) + (lev / 3)); break; case 128+27: /* RF5_SCARE */ if (my_skill_sav >= 100) break; /* if looking at full damage, things that are just annoying */ /* do not count. */ if (!borg_full_damage) p += 10; break; case 128+28: /* RF5_BLIND */ if (my_skill_sav >= 100) break; /* if looking at full damage, things that are just annoying */ /* do not count. */ if (!borg_full_damage) p += 10; break; case 128+29: /* RF5_CONF */ if (my_skill_sav >= 100) break; /* if looking at full damage, things that are just annoying */ /* do not count. */ if (!borg_full_damage) p += 10; break; case 128+30: /* RF5_SLOW */ if (my_free_act) break; if (my_skill_sav >= 100) break; /* if looking at full damage, things that are just annoying */ /* do not count. */ if (!borg_full_damage) p += 5; break; case 128+31: /* RF5_HOLD */ if (my_free_act) break; if (my_skill_sav >= 100) break; p += 150; break; case 160+0: /* RF6_HASTE */ /* if looking at full damage, things that are just annoying */ /* do not count. */ if (!borg_full_damage) p += 10; break; case 160+1: /* RF6_XXX1X6 */ break; case 160+2: /* RF6_HEAL */ /* if looking at full damage, things that are just annoying */ /* do not count. */ if (!borg_full_damage) p += 10; break; case 160+3: /* RF6_XXX2X6 */ break; case 160+4: /* RF6_BLINK */ break; case 160+5: /* RF6_TPORT */ break; case 160+6: /* RF6_XXX3X6 */ break; case 160+7: /* RF6_XXX4X6 */ break; case 160+8: /* RF6_TELE_TO */ /* if looking at full damage, things that are just annoying */ /* do not count. */ if (!borg_full_damage) p += 20; break; case 160+9: /* RF6_TELE_AWAY */ /* if looking at full damage, things that are just annoying */ /* do not count. */ if (!borg_full_damage) p += 10; break; case 160+10: /* RF6_TELE_LEVEL */ if (my_skill_sav >= 100) break; /* if looking at full damage, things that are just annoying */ /* do not count. */ if (!borg_full_damage) p += 50; break; case 160+11: /* RF6_XXX5 */ break; case 160+12: /* RF6_DARKNESS */ /* if looking at full damage, things that are just annoying */ /* do not count. */ if (!borg_full_damage) p += 5; break; case 160+13: /* RF6_TRAPS */ /* if looking at full damage, things that are just annoying */ /* do not count. */ if (!borg_full_damage) p += 50; break; case 160+14: /* RF6_FORGET */ if (my_skill_sav >= 100) break; /* if looking at full damage, things that are just annoying */ /* do not count. */ if (!borg_full_damage) /* if you have lots of cash (like you will at level 35) */ /* this is not very scary... just re-ID. */ if (auto_level < 35) p += 500; else p += 50; break; case 160+15: /* RF6_XXX6X6 */ break; case 160+16: /* RF6_XXX7X6 */ break; case 160+17: /* RF6_XXX8X6 */ break; /* Summoning is only as dangerious as the monster that is */ /* actually summoned but the monsters that summon are a priority */ /* to kill */ case 160+18: /* RF6_S_MONSTER */ if (borg_attacking) p += (lev) * 10; break; case 160+19: /* RF6_S_MONSTERS */ if (borg_attacking) p += (lev) * 20; break; case 160+20: /* RF6_S_ANT */ if (borg_attacking) p += (lev) * 20; break; case 160+21: /* RF6_S_SPIDER */ if (borg_attacking) p += (lev) * 20; break; case 160+22: /* RF6_S_HOUND */ if (borg_attacking) p += (lev) * 20; break; case 160+23: /* RF6_S_HYDRA */ if (borg_attacking) p += (lev) * 20; break; case 160+24: /* RF6_S_ANGEL */ if (borg_attacking) p += (lev) * 30; break; case 160+25: /* RF6_S_DEMON */ if (borg_attacking) p += (lev) * 30; break; case 160+26: /* RF6_S_UNDEAD */ if (borg_attacking) p += (lev) * 30; break; case 160+27: /* RF6_S_DRAGON */ if (borg_attacking) p += (lev) * 30; break; case 160+28: /* RF6_S_HI_UNDEAD */ if (borg_attacking) p += (lev) * 50; break; case 160+29: /* RF6_S_HI_DRAGON */ if (borg_attacking) p += (lev) * 50; break; case 160+30: /* RF6_S_WRAITH */ if (borg_attacking) p += (lev) * 50; break; case 160+31: /* RF6_S_UNIQUE */ if (borg_attacking) p += (lev) * 50; break; } /* Notice damage */ /* if invulnurable, no damage */ if (!borg_goi || borg_attacking) p += z; /* Track most dangerous spell */ if (p > n) n = p; } /* Danger */ return (n); } /* * Calculate the danger to a grid from a monster XXX XXX XXX * * Note that we are paranoid, especially about "monster speed", * since even if a monster is slower than us, it will occasionally * get one full turn to attack us. * * Note that we assume that monsters can walk through walls and * other monsters to get to the player. XXX XXX XXX * * This function ignores possibilities such as movement plus * spell attacks, physical attacks and spell attacks together, * and other similar situations. XXX XXX XXX * * Currently we assume that "sleeping" monsters are less dangerous * unless you get near them, which may wake them up. * * We attempt to take into account things like monsters which sometimes * "stumble", and monsters which only "sometimes" use powerful spells. */ int borg_danger_aux(int y, int x, int c, int i) { auto_kill *kill = &auto_kills[i]; monster_race *r_ptr = &r_info[kill->r_idx]; /* for debug. */ char * race_name = r_name + r_ptr->name; int x9 = kill->x; int y9 = kill->y; int ax, ay, d; int q, r, p, v1, v2; /* Paranoia */ if (!kill->r_idx) return (0); /* Distance components */ ax = (x9 > x) ? (x9 - x) : (x - x9); ay = (y9 > y) ? (y9 - y) : (y - y9); /* Distance */ d = MAX(ax, ay); /* Minimal distance */ if (d < 1) d = 1; /* Minimal distance */ if (d > 20) return (0); if (!borg_speed) { /* Total energy */ q = c * kill->moves; } else { /* Ugly! we recalculate the moves */ int t, e; /* Player energy per game turn */ e = extract_energy[(auto_speed + 10)]; /* Game turns per player move */ t