Esempio n. 1
0
        /**
         * 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();
            }
        }
Esempio n. 2
0
        /**
         * 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);
        }
Esempio n. 3
0
        /**
         * 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;
        }
Esempio n. 4
0
        /**
         * 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();
            }
        }
Esempio n. 5
0
        /**
         * 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);
        }
Esempio n. 6
0
        /*
         * 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);
        }
Esempio n. 7
0
        /**
         * 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;
        }
Esempio n. 8
0
        /**
         * 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;
        }
Esempio n. 9
0
        /*
         * 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;
        }