/** * Notice things about an object that would be noticed in time. */ static void object_notice_after_time() { int i; int flag; Object o_ptr; string o_name; //[80]; Bitflag f = new Bitflag(Object_Flag.SIZE); Bitflag timed_mask = new Bitflag(Object_Flag.SIZE); Object_Flag.create_mask(timed_mask, true, Object_Flag.object_flag_id.TIMED); /* Check every item the player is wearing */ for (i = Misc.INVEN_WIELD; i < Misc.ALL_INVEN_TOTAL; i++) { o_ptr = Misc.p_ptr.inventory[i]; if (o_ptr.kind == null || o_ptr.is_known()) { continue; } /* Check for timed notice flags */ o_name = o_ptr.object_desc(Detail.BASE); o_ptr.object_flags(ref f); f.inter(timed_mask); for (flag = f.next(Bitflag.FLAG_START); flag != Bitflag.FLAG_null; flag = f.next(flag + 1)) { if (!o_ptr.known_flags.has(flag)) { /* Message */ Object_Flag.flag_message(flag, o_name); /* Notice the flag */ o_ptr.notice_flag(flag); if (o_ptr.is_jewelry() && (o_ptr.effect() == null || o_ptr.effect_is_known())) { /* XXX this is a small hack, but jewelry with anything noticeable really is obvious */ /* XXX except, wait until learn activation if that is only clue */ o_ptr.flavor_aware(); o_ptr.check_for_ident(); } } else { /* Notice the flag is absent */ o_ptr.notice_flag(flag); } } /* XXX Is this necessary? */ o_ptr.check_for_ident(); } }
/** * This is a safe way to choose a random new flag to add to an object. * It takes the existing flags and an array of new flags, * and returns an entry from newf, or 0 if there are no * new flags available. */ static int get_new_attr(Bitflag flags, Bitflag newf) { int options = 0, flag = 0; for (int i = newf.next(Bitflag.FLAG_START); i != Bitflag.FLAG_null; i = newf.next(i + 1)) { /* skip this one if the flag is already present */ if (flags.has(i)) { continue; } /* each time we find a new possible option, we have a 1-in-N chance of * choosing it and an (N-1)-in-N chance of keeping a previous one */ if (Random.one_in_(++options)) { flag = i; } } return(flag); }
/** * Apply generation magic to an ego-item. */ void ego_apply_magic(int level) { int i, flag, x; Bitflag flags = new Bitflag(Object_Flag.SIZE); Bitflag newf = new Bitflag(Object_Flag.SIZE); object_flags(ref flags); /* Extra powers */ if (ego.xtra == Object_Flag.OBJECT_XTRA_TYPE_SUSTAIN) { Object_Flag.create_mask(newf, false, Object_Flag.object_flag_type.SUST); } else if (ego.xtra == Object_Flag.OBJECT_XTRA_TYPE_RESIST) { Object_Flag.create_mask(newf, false, Object_Flag.object_flag_type.HRES); } else if (ego.xtra == Object_Flag.OBJECT_XTRA_TYPE_POWER) { Object_Flag.create_mask(newf, false, Object_Flag.object_flag_type.PROT, Object_Flag.object_flag_type.MISC); } if (ego.xtra != 0) { this.flags.on(get_new_attr(flags, newf)); } /* Apply extra ego bonuses */ to_h += (short)Random.randcalc(ego.to_h, level, aspect.RANDOMISE); to_d += (short)Random.randcalc(ego.to_d, level, aspect.RANDOMISE); to_a += (short)Random.randcalc(ego.to_a, level, aspect.RANDOMISE); /* Apply pvals */ for (i = 0; i < ego.num_pvals; i++) { flags.copy(ego.pval_flags[i]); x = Random.randcalc(ego.pval[i], level, aspect.RANDOMISE); for (flag = flags.next(Bitflag.FLAG_START); flag != Bitflag.FLAG_null; flag = flags.next(flag + 1)) { add_pval(x, flag); } } /* Apply flags */ this.flags.union(ego.flags); return; }
/** * Notice things about an object that would be noticed in time. */ static void object_notice_after_time() { int i; int flag; Object o_ptr; string o_name;//[80]; Bitflag f = new Bitflag(Object_Flag.SIZE); Bitflag timed_mask = new Bitflag(Object_Flag.SIZE); Object_Flag.create_mask(timed_mask, true, Object_Flag.object_flag_id.TIMED); /* Check every item the player is wearing */ for (i = Misc.INVEN_WIELD; i < Misc.ALL_INVEN_TOTAL; i++) { o_ptr = Misc.p_ptr.inventory[i]; if (o_ptr.kind == null || o_ptr.is_known()) continue; /* Check for timed notice flags */ o_name = o_ptr.object_desc(Detail.BASE); o_ptr.object_flags(ref f); f.inter(timed_mask); for (flag = f.next(Bitflag.FLAG_START); flag != Bitflag.FLAG_null; flag = f.next(flag + 1)) { if (!o_ptr.known_flags.has(flag)) { /* Message */ Object_Flag.flag_message(flag, o_name); /* Notice the flag */ o_ptr.notice_flag(flag); if (o_ptr.is_jewelry() && (o_ptr.effect() == null || o_ptr.effect_is_known())) { /* XXX this is a small hack, but jewelry with anything noticeable really is obvious */ /* XXX except, wait until learn activation if that is only clue */ o_ptr.flavor_aware(); o_ptr.check_for_ident(); } } else { /* Notice the flag is absent */ o_ptr.notice_flag(flag); } } /* XXX Is this necessary? */ o_ptr.check_for_ident(); } }
/** * Wipe an object clean and make it a standard object of the specified kind. * Was previous "object_prep", is now a constructor for Object */ public void prep(Object_Kind k, int lev, aspect rand_aspect) { int flag, x; Bitflag flags = new Bitflag(Object_Flag.SIZE); // Assign the kind and copy across data this.kind = k; this.tval = k.tval; this.sval = k.sval; this.ac = k.ac; this.dd = k.dd; this.ds = k.ds; this.weight = k.weight; // Default number this.number = 1; for(int i = 0; i < pval_flags.Length; i++) { pval_flags[i] = new Bitflag(Object_Flag.SIZE); } // Apply pvals and then copy flags for (int i = 0; i < k.num_pvals; i++) { flags.copy(k.pval_flags[i]); flags.copy(k.pval_flags[i]); x = Random.randcalc(k.pval[i], lev, rand_aspect); for (flag = flags.next(Bitflag.FLAG_START); flag != Bitflag.FLAG_null; flag = flags.next(flag + 1)) add_pval(x, flag); } if(k.Base != null) { flags.copy(k.Base.flags); } flags.union(k.flags); // Assign charges (wands/staves only) if (tval == TVal.TV_WAND || tval == TVal.TV_STAFF) pval[Misc.DEFAULT_PVAL] = (short)Random.randcalc(k.charge, lev, rand_aspect); // Assign flagless pval for food or oil if (tval == TVal.TV_FOOD || tval == TVal.TV_POTION || tval == TVal.TV_FLASK) pval[Misc.DEFAULT_PVAL] = (short)Random.randcalc(k.pval[Misc.DEFAULT_PVAL], lev, rand_aspect); // Default fuel for lamps if (tval == TVal.TV_LIGHT) { if(sval == SVal.SV_LIGHT_TORCH) timeout = Misc.DEFAULT_TORCH; else if(sval == SVal.SV_LIGHT_LANTERN) timeout = Misc.DEFAULT_LAMP; } // Default magic to_h = (short)Random.randcalc(k.to_h, lev, rand_aspect); to_d = (short)Random.randcalc(k.to_d, lev, rand_aspect); to_a = (short)Random.randcalc(k.to_a, lev, rand_aspect); }
/* * Evaluate the object's overall power level. */ public int object_power(bool verbose, StreamWriter log_file, bool known) { int p = 0, q = 0, slay_pwr = 0, dice_pwr = 0; int i, j; int extra_stat_bonus = 0, mult = 1, num_slays = 0, k = 1; Bitflag flags = new Bitflag(Object_Flag.SIZE); Bitflag mask = new Bitflag(Object_Flag.SIZE); /* Zero the flag counts */ for (i = 0; i < sets.Length; i++) { sets[i].count = 0; } /* Extract the flags */ if (known) { // log_file.Write("Object is deemed knwon\n"); object_flags(ref flags); } else { // log_file.Write("Object may not be fully known\n"); object_flags_known(ref flags); } /* Log the flags in human-readable form */ //if (verbose) //log_flags(flags, log_file); //meh /* Get the slay power and number of slay/brand types */ Object_Flag.create_mask(mask, false, Object_Flag.object_flag_type.SLAY, Object_Flag.object_flag_type.KILL, Object_Flag.object_flag_type.BRAND); num_slays = Slay.list_slays(flags, mask, null, null, null, true); if (num_slays != 0) { slay_pwr = slay_power(verbose, log_file, known); } /* Start with any damage boost from the item itself */ p += (to_d * DAMAGE_POWER / 2); //file_putf(log_file, "Adding power from to_dam, total is %d\n", p); /* Add damage from dice for any wieldable weapon or ammo */ if (wield_slot() == Misc.INVEN_WIELD || is_ammo()) { dice_pwr = (dd * (ds + 1) * DAMAGE_POWER / 4); // file_putf(log_file, "Adding %d power for dam dice\n", dice_pwr); /* Add 2nd lot of damage power for nonweapons */ } else if (wield_slot() != Misc.INVEN_BOW) { p += (to_d * DAMAGE_POWER); // file_putf(log_file, "Adding power from nonweap to_dam, total is %d\n", p); /* Add power boost for nonweapons with combat flags */ if (num_slays != 0 || flags.has(Object_Flag.BLOWS.value) || flags.has(Object_Flag.SHOTS.value) || flags.has(Object_Flag.MIGHT.value)) { dice_pwr = (WEAP_DAMAGE * DAMAGE_POWER); // file_putf(log_file, "Adding %d power for nonweap combat flags\n", dice_pwr); } } p += dice_pwr; /* Add ammo damage for launchers, get multiplier and rescale */ if (wield_slot() == Misc.INVEN_BOW) { p += (archery[sval / 10].ammo_dam * DAMAGE_POWER / 2); // file_putf(log_file, "Adding power from ammo, total is %d\n", p); mult = bow_multiplier(sval); // file_putf(log_file, "Base mult for this weapon is %d\n", mult); } /* Add launcher bonus for ego ammo, multiply for launcher and rescale */ if (is_ammo()) { if (ego != null) { p += (archery[tval - TVal.TV_SHOT].launch_dam * DAMAGE_POWER / 2); } p = p * archery[tval - TVal.TV_SHOT].launch_mult / (2 * MAX_BLOWS); // file_putf(log_file, "After multiplying ammo and rescaling, power is %d\n", p); } /* Add power for extra blows */ if (flags.has(Object_Flag.BLOWS.value)) { j = which_pval(Object_Flag.BLOWS.value); if (known || this_pval_is_visible(j)) { if (pval[j] >= INHIBIT_BLOWS) { p += INHIBIT_POWER; // file_putf(log_file, "INHIBITING - too many extra blows - quitting\n"); return(p); } else { p = p * (MAX_BLOWS + pval[j]) / MAX_BLOWS; /* Add boost for assumed off-weapon damage */ p += (NONWEAP_DAMAGE * pval[j] * DAMAGE_POWER / 2); // file_putf(log_file, "Adding power for extra blows, total is %d\n", p); } } } /* Add power for extra shots - note that we cannot handle negative shots */ if (flags.has(Object_Flag.SHOTS.value)) { j = which_pval(Object_Flag.SHOTS.value); if (known || this_pval_is_visible(j)) { if (pval[j] >= INHIBIT_SHOTS) { p += INHIBIT_POWER; // file_putf(log_file, "INHIBITING - too many extra shots - quitting\n"); return(p); } else if (pval[j] > 0) { p = (p * (1 + pval[j])); // file_putf(log_file, "Extra shots: multiplying power by 1 + %d, total is %d\n", o_ptr.pval[j], p); } } } /* Add power for extra might */ if (flags.has(Object_Flag.MIGHT.value)) { j = which_pval(Object_Flag.MIGHT.value); if (known || this_pval_is_visible(j)) { if (pval[j] >= INHIBIT_MIGHT) { p += INHIBIT_POWER; mult = 1; /* don't overflow */ // file_putf(log_file, "INHIBITING - too much extra might - quitting\n"); return(p); } else { mult += pval[j]; } // file_putf(log_file, "Mult after extra might is %d\n", mult); } } p *= mult; //file_putf(log_file, "After multiplying power for might, total is %d\n", p); /* Apply the correct slay multiplier */ if (slay_pwr != 0) { p += (dice_pwr * (slay_pwr / 100)) / (Eval.tot_mon_power / 100); // file_putf(log_file, "Adjusted for slay power, total is %d\n", p); } /* Melee weapons assume MAX_BLOWS per turn, so we must divide by MAX_BLOWS * to get equal ratings for launchers. */ if (wield_slot() == Misc.INVEN_BOW) { p /= MAX_BLOWS; // file_putf(log_file, "Rescaling bow power, total is %d\n", p); } /* Add power for +to_hit */ p += (to_h * TO_HIT_POWER / 2); //file_putf(log_file, "Adding power for to hit, total is %d\n", p); /* Add power for base AC and adjust for weight */ if (ac != 0) { p += BASE_ARMOUR_POWER; q += (ac * BASE_AC_POWER / 2); // file_putf(log_file, "Adding %d power for base AC value\n", q); /* Add power for AC per unit weight */ if (weight > 0) { i = 750 * (ac + to_a) / weight; /* Avoid overpricing Elven Cloaks */ if (i > 450) { i = 450; } q *= i; q /= 100; /* Weightless (ethereal) armour items get fixed boost */ } else { q *= 5; } p += q; // file_putf(log_file, "Adding power for AC per unit weight, now %d\n", p); } /* Add power for +to_ac */ p += (to_a * TO_AC_POWER / 2); //file_putf(log_file, "Adding power for to_ac of %d, total is %d\n", o_ptr.to_a, p); if (to_a > HIGH_TO_AC) { p += ((to_a - (HIGH_TO_AC - 1)) * TO_AC_POWER); // file_putf(log_file, "Adding power for high to_ac value, total is %d\n", p); } if (to_a > VERYHIGH_TO_AC) { p += ((to_a - (VERYHIGH_TO_AC - 1)) * TO_AC_POWER * 2); // file_putf(log_file, "Adding power for very high to_ac value, total is %d\n", p); } if (to_a >= INHIBIT_AC) { p += INHIBIT_POWER; // file_putf(log_file, "INHIBITING: AC bonus too high\n"); } /* Add power for light sources by radius XXX Hack - rewrite calc_torch! */ if (wield_slot() == Misc.INVEN_LIGHT) { p += BASE_LIGHT_POWER; /* Artifact lights have larger radius so add more */ if (artifact != null) { p += BASE_LIGHT_POWER; } // file_putf(log_file, "Adding power for light radius, total is %d\n", p); } /* Add base power for jewelry */ if (is_jewelry()) { p += BASE_JEWELRY_POWER; // file_putf(log_file, "Adding power for jewelry, total is %d\n", p); } /* Add power for non-derived flags (derived flags have flag_power 0) */ for (i = flags.next(Bitflag.FLAG_START); i != Bitflag.FLAG_null; i = flags.next(i + 1)) { if (Object_Flag.flag_uses_pval(i)) { j = which_pval(i); if (known || this_pval_is_visible(j)) { k = pval[j]; extra_stat_bonus += (k * Object_Flag.pval_mult(i)); } } else { k = 1; } if (Object_Flag.flag_power(i) != 0) { p += (k * Object_Flag.flag_power(i) * Object_Flag.slot_mult(i, wield_slot())); //file_putf(log_file, "Adding power for %s, total is %d\n", flag_name(i), p); } /* Track combinations of flag types - note we ignore SUST_CHR */ for (j = 0; j < sets.Length; j++) { if ((sets[j].type == Object_Flag.obj_flag_type(i)) && (i != Object_Flag.SUST_CHR.value)) { sets[j].count++; } } } /* Add extra power term if there are a lot of ability bonuses */ if (extra_stat_bonus > 249) { // file_putf(log_file, "Inhibiting! (Total ability bonus of %d is too high)\n", extra_stat_bonus); p += INHIBIT_POWER; } else { p += ability_power[extra_stat_bonus / 10]; // file_putf(log_file, "Adding power for pval total of %d, total is %d\n", extra_stat_bonus, p); } /* Add extra power for multiple flags of the same type */ for (i = 0; i < sets.Length; i++) { if (sets[i].count > 1) { q = (sets[i].factor * sets[i].count * sets[i].count); /* Scale damage-dependent set bonuses by damage dice power */ if (sets[i].dam_dep) { q = q * dice_pwr / (DAMAGE_POWER * 5); } p += q; // file_putf(log_file, "Adding power for multiple %s, total is %d\n", sets[i].desc, p); } /* Add bonus if item has a full set of these flags */ if (sets[i].count == sets[i].size) { p += sets[i].bonus; // file_putf(log_file, "Adding power for full set of %s, total is %d\n", sets[i].desc, p); } } /* add power for effect */ if (known || effect_is_known()) { if (artifact != null && artifact.effect != null) { p += artifact.effect.effect_power(); // file_putf(log_file, "Adding power for artifact activation, total is %d\n", p); } else { p += kind.effect.effect_power(); // file_putf(log_file, "Adding power for item activation, total is %d\n", p); } } //file_putf(log_file, "FINAL POWER IS %d\n", p); return(p); }
/** * Apply generation magic to an ego-item. */ void ego_apply_magic(int level) { int i, flag, x; Bitflag flags = new Bitflag(Object_Flag.SIZE); Bitflag newf = new Bitflag(Object_Flag.SIZE); object_flags(ref flags); /* Extra powers */ if (ego.xtra == Object_Flag.OBJECT_XTRA_TYPE_SUSTAIN) Object_Flag.create_mask(newf, false, Object_Flag.object_flag_type.SUST); else if (ego.xtra == Object_Flag.OBJECT_XTRA_TYPE_RESIST) Object_Flag.create_mask(newf, false, Object_Flag.object_flag_type.HRES); else if (ego.xtra == Object_Flag.OBJECT_XTRA_TYPE_POWER) Object_Flag.create_mask(newf, false, Object_Flag.object_flag_type.PROT, Object_Flag.object_flag_type.MISC); if (ego.xtra != 0) this.flags.on(get_new_attr(flags, newf)); /* Apply extra ego bonuses */ to_h += (short)Random.randcalc(ego.to_h, level, aspect.RANDOMISE); to_d += (short)Random.randcalc(ego.to_d, level, aspect.RANDOMISE); to_a += (short)Random.randcalc(ego.to_a, level, aspect.RANDOMISE); /* Apply pvals */ for (i = 0; i < ego.num_pvals; i++) { flags.copy(ego.pval_flags[i]); x = Random.randcalc(ego.pval[i], level, aspect.RANDOMISE); for (flag = flags.next(Bitflag.FLAG_START); flag != Bitflag.FLAG_null; flag = flags.next(flag + 1)) add_pval(x, flag); } /* Apply flags */ this.flags.union(ego.flags); return; }
/** * This is a safe way to choose a random new flag to add to an object. * It takes the existing flags and an array of new flags, * and returns an entry from newf, or 0 if there are no * new flags available. */ static int get_new_attr(Bitflag flags, Bitflag newf) { int options = 0, flag = 0; for (int i = newf.next(Bitflag.FLAG_START); i != Bitflag.FLAG_null; i = newf.next(i + 1)) { /* skip this one if the flag is already present */ if (flags.has(i)) continue; /* each time we find a new possible option, we have a 1-in-N chance of * choosing it and an (N-1)-in-N chance of keeping a previous one */ if (Random.one_in_(++options)) flag = i; } return flag; }
/* * Evaluate the object's overall power level. */ public int object_power(bool verbose, StreamWriter log_file, bool known) { int p = 0, q = 0, slay_pwr = 0, dice_pwr = 0; int i, j; int extra_stat_bonus = 0, mult = 1, num_slays = 0, k = 1; Bitflag flags = new Bitflag(Object_Flag.SIZE); Bitflag mask = new Bitflag(Object_Flag.SIZE); /* Zero the flag counts */ for (i = 0; i < sets.Length; i++) sets[i].count = 0; /* Extract the flags */ if (known) { // log_file.Write("Object is deemed knwon\n"); object_flags(ref flags); } else { // log_file.Write("Object may not be fully known\n"); object_flags_known(ref flags); } /* Log the flags in human-readable form */ //if (verbose) //log_flags(flags, log_file); //meh /* Get the slay power and number of slay/brand types */ Object_Flag.create_mask(mask, false, Object_Flag.object_flag_type.SLAY, Object_Flag.object_flag_type.KILL, Object_Flag.object_flag_type.BRAND); num_slays = Slay.list_slays(flags, mask, null, null, null, true); if (num_slays != 0) slay_pwr = slay_power(verbose, log_file, known); /* Start with any damage boost from the item itself */ p += (to_d * DAMAGE_POWER / 2); //file_putf(log_file, "Adding power from to_dam, total is %d\n", p); /* Add damage from dice for any wieldable weapon or ammo */ if (wield_slot() == Misc.INVEN_WIELD || is_ammo()) { dice_pwr = (dd * (ds + 1) * DAMAGE_POWER / 4); // file_putf(log_file, "Adding %d power for dam dice\n", dice_pwr); /* Add 2nd lot of damage power for nonweapons */ } else if (wield_slot() != Misc.INVEN_BOW) { p += (to_d * DAMAGE_POWER); // file_putf(log_file, "Adding power from nonweap to_dam, total is %d\n", p); /* Add power boost for nonweapons with combat flags */ if (num_slays != 0 || flags.has(Object_Flag.BLOWS.value) || flags.has(Object_Flag.SHOTS.value) || flags.has(Object_Flag.MIGHT.value)) { dice_pwr = (WEAP_DAMAGE * DAMAGE_POWER); // file_putf(log_file, "Adding %d power for nonweap combat flags\n", dice_pwr); } } p += dice_pwr; /* Add ammo damage for launchers, get multiplier and rescale */ if (wield_slot() == Misc.INVEN_BOW) { p += (archery[sval / 10].ammo_dam * DAMAGE_POWER / 2); // file_putf(log_file, "Adding power from ammo, total is %d\n", p); mult = bow_multiplier(sval); // file_putf(log_file, "Base mult for this weapon is %d\n", mult); } /* Add launcher bonus for ego ammo, multiply for launcher and rescale */ if (is_ammo()) { if (ego != null) p += (archery[tval - TVal.TV_SHOT].launch_dam * DAMAGE_POWER / 2); p = p * archery[tval - TVal.TV_SHOT].launch_mult / (2 * MAX_BLOWS); // file_putf(log_file, "After multiplying ammo and rescaling, power is %d\n", p); } /* Add power for extra blows */ if (flags.has(Object_Flag.BLOWS.value)) { j = which_pval(Object_Flag.BLOWS.value); if (known || this_pval_is_visible(j)) { if (pval[j] >= INHIBIT_BLOWS) { p += INHIBIT_POWER; // file_putf(log_file, "INHIBITING - too many extra blows - quitting\n"); return p; } else { p = p * (MAX_BLOWS + pval[j]) / MAX_BLOWS; /* Add boost for assumed off-weapon damage */ p += (NONWEAP_DAMAGE * pval[j] * DAMAGE_POWER / 2); // file_putf(log_file, "Adding power for extra blows, total is %d\n", p); } } } /* Add power for extra shots - note that we cannot handle negative shots */ if (flags.has(Object_Flag.SHOTS.value)) { j = which_pval(Object_Flag.SHOTS.value); if (known || this_pval_is_visible(j)) { if (pval[j] >= INHIBIT_SHOTS) { p += INHIBIT_POWER; // file_putf(log_file, "INHIBITING - too many extra shots - quitting\n"); return p; } else if (pval[j] > 0) { p = (p * (1 + pval[j])); // file_putf(log_file, "Extra shots: multiplying power by 1 + %d, total is %d\n", o_ptr.pval[j], p); } } } /* Add power for extra might */ if (flags.has(Object_Flag.MIGHT.value)) { j = which_pval(Object_Flag.MIGHT.value); if (known || this_pval_is_visible(j)) { if (pval[j] >= INHIBIT_MIGHT) { p += INHIBIT_POWER; mult = 1; /* don't overflow */ // file_putf(log_file, "INHIBITING - too much extra might - quitting\n"); return p; } else mult += pval[j]; // file_putf(log_file, "Mult after extra might is %d\n", mult); } } p *= mult; //file_putf(log_file, "After multiplying power for might, total is %d\n", p); /* Apply the correct slay multiplier */ if (slay_pwr != 0) { p += (dice_pwr * (slay_pwr / 100)) / (Eval.tot_mon_power / 100); // file_putf(log_file, "Adjusted for slay power, total is %d\n", p); } /* Melee weapons assume MAX_BLOWS per turn, so we must divide by MAX_BLOWS * to get equal ratings for launchers. */ if (wield_slot() == Misc.INVEN_BOW) { p /= MAX_BLOWS; // file_putf(log_file, "Rescaling bow power, total is %d\n", p); } /* Add power for +to_hit */ p += (to_h * TO_HIT_POWER / 2); //file_putf(log_file, "Adding power for to hit, total is %d\n", p); /* Add power for base AC and adjust for weight */ if (ac != 0) { p += BASE_ARMOUR_POWER; q += (ac * BASE_AC_POWER / 2); // file_putf(log_file, "Adding %d power for base AC value\n", q); /* Add power for AC per unit weight */ if (weight > 0) { i = 750 * (ac + to_a) / weight; /* Avoid overpricing Elven Cloaks */ if (i > 450) i = 450; q *= i; q /= 100; /* Weightless (ethereal) armour items get fixed boost */ } else q *= 5; p += q; // file_putf(log_file, "Adding power for AC per unit weight, now %d\n", p); } /* Add power for +to_ac */ p += (to_a * TO_AC_POWER / 2); //file_putf(log_file, "Adding power for to_ac of %d, total is %d\n", o_ptr.to_a, p); if (to_a > HIGH_TO_AC) { p += ((to_a - (HIGH_TO_AC - 1)) * TO_AC_POWER); // file_putf(log_file, "Adding power for high to_ac value, total is %d\n", p); } if (to_a > VERYHIGH_TO_AC) { p += ((to_a - (VERYHIGH_TO_AC -1)) * TO_AC_POWER * 2); // file_putf(log_file, "Adding power for very high to_ac value, total is %d\n", p); } if (to_a >= INHIBIT_AC) { p += INHIBIT_POWER; // file_putf(log_file, "INHIBITING: AC bonus too high\n"); } /* Add power for light sources by radius XXX Hack - rewrite calc_torch! */ if (wield_slot() == Misc.INVEN_LIGHT) { p += BASE_LIGHT_POWER; /* Artifact lights have larger radius so add more */ if (artifact != null) p += BASE_LIGHT_POWER; // file_putf(log_file, "Adding power for light radius, total is %d\n", p); } /* Add base power for jewelry */ if (is_jewelry()) { p += BASE_JEWELRY_POWER; // file_putf(log_file, "Adding power for jewelry, total is %d\n", p); } /* Add power for non-derived flags (derived flags have flag_power 0) */ for (i = flags.next(Bitflag.FLAG_START); i != Bitflag.FLAG_null; i = flags.next(i + 1)) { if (Object_Flag.flag_uses_pval(i)) { j = which_pval(i); if (known || this_pval_is_visible(j)) { k = pval[j]; extra_stat_bonus += (k * Object_Flag.pval_mult(i)); } } else k = 1; if (Object_Flag.flag_power(i) != 0) { p += (k * Object_Flag.flag_power(i) * Object_Flag.slot_mult(i, wield_slot())); //file_putf(log_file, "Adding power for %s, total is %d\n", flag_name(i), p); } /* Track combinations of flag types - note we ignore SUST_CHR */ for (j = 0; j < sets.Length; j++) if ((sets[j].type == Object_Flag.obj_flag_type(i)) && (i != Object_Flag.SUST_CHR.value)) sets[j].count++; } /* Add extra power term if there are a lot of ability bonuses */ if (extra_stat_bonus > 249) { // file_putf(log_file, "Inhibiting! (Total ability bonus of %d is too high)\n", extra_stat_bonus); p += INHIBIT_POWER; } else { p += ability_power[extra_stat_bonus / 10]; // file_putf(log_file, "Adding power for pval total of %d, total is %d\n", extra_stat_bonus, p); } /* Add extra power for multiple flags of the same type */ for (i = 0; i < sets.Length; i++) { if (sets[i].count > 1) { q = (sets[i].factor * sets[i].count * sets[i].count); /* Scale damage-dependent set bonuses by damage dice power */ if (sets[i].dam_dep) q = q * dice_pwr / (DAMAGE_POWER * 5); p += q; // file_putf(log_file, "Adding power for multiple %s, total is %d\n", sets[i].desc, p); } /* Add bonus if item has a full set of these flags */ if (sets[i].count == sets[i].size) { p += sets[i].bonus; // file_putf(log_file, "Adding power for full set of %s, total is %d\n", sets[i].desc, p); } } /* add power for effect */ if (known || effect_is_known()) { if (artifact != null && artifact.effect != null) { p += artifact.effect.effect_power(); // file_putf(log_file, "Adding power for artifact activation, total is %d\n", p); } else { p += kind.effect.effect_power(); // file_putf(log_file, "Adding power for item activation, total is %d\n", p); } } //file_putf(log_file, "FINAL POWER IS %d\n", p); return p; }