Пример #1
0
        /**
         * Extract the multiplier from a given object hitting a given monster.
         *
         * \param o_ptr is the object being used to attack
         * \param m_ptr is the monster being attacked
         * \param best_s_ptr is the best applicable slay_table entry, or null if no
         *  slay already known
         * \param real is whether this is a real attack (where we update lore) or a
         *  simulation (where we don't)
         * \param known_only is whether we are using all the object flags, or only
         * the ones we *already* know about
         */
        //Best_s_ptr was slay**
        public static void improve_attack_modifier(Object o_ptr, Monster.Monster m_ptr,
                                                   ref Slay best_s_ptr, bool real, bool known_only)
        {
            Monster_Race r_ptr   = Misc.r_info[m_ptr.r_idx];
            Monster_Lore l_ptr   = Misc.l_list[m_ptr.r_idx];
            Bitflag      f       = new Bitflag(Object_Flag.SIZE);
            Bitflag      known_f = new Bitflag(Object_Flag.SIZE);
            Bitflag      note_f  = new Bitflag(Object_Flag.SIZE);
            int          i;

            o_ptr.object_flags(ref f);
            o_ptr.object_flags_known(ref known_f);

            for (i = 0; i < Slay.MAX.value; i++)
            {
                Slay s_ptr = list[i];
                if ((known_only && !known_f.has(s_ptr.object_flag.value)) || (!known_only && !f.has(s_ptr.object_flag.value)))
                {
                    continue;
                }

                /* In a real attack, learn about monster resistance or slay match if:
                 * EITHER the slay flag on the object is known,
                 * OR the monster is vulnerable to the slay/brand
                 */
                if (real && (known_f.has(s_ptr.object_flag.value) || (s_ptr.monster_flag != Monster_Flag.NONE &&
                                                                      r_ptr.flags.has(s_ptr.monster_flag.value)) ||
                             (s_ptr.resist_flag != Monster_Flag.NONE && !r_ptr.flags.has(s_ptr.resist_flag.value))))
                {
                    /* notice any brand or slay that would affect monster */
                    note_f.wipe();
                    note_f.on(s_ptr.object_flag.value);
                    object_notice_slays(o_ptr, note_f);

                    if (m_ptr.ml && s_ptr.monster_flag != Monster_Flag.NONE)
                    {
                        l_ptr.flags.on(s_ptr.monster_flag.value);
                    }

                    if (m_ptr.ml && s_ptr.resist_flag != Monster_Flag.NONE)
                    {
                        l_ptr.flags.on(s_ptr.resist_flag.value);
                    }
                }

                /* If the monster doesn't resist or the slay flag matches */
                if ((s_ptr.brand != null && s_ptr.brand.Length != 0 &&
                     !r_ptr.flags.has(s_ptr.resist_flag.value)) ||
                    (s_ptr.monster_flag != Monster_Flag.NONE &&
                     r_ptr.flags.has(s_ptr.monster_flag.value)))
                {
                    /* compare multipliers to determine best attack */
                    if ((best_s_ptr == null) || ((best_s_ptr).mult < s_ptr.mult))
                    {
                        best_s_ptr = s_ptr;
                    }
                }
            }
        }
Пример #2
0
        /**
         * Create a "mask" of flags of a specific type or ID threshold.
         *
         * \param f is the flag array we're filling
         * \param id is whether we're masking by ID level
         * \param ... is the list of flags or ID types we're looking for
         *
         * N.B. OFT_MAX must be the last item in the ... list
         */
        public static void create_mask(Bitflag f, bool id, params object[] vals)
        {
            f.wipe();

            /* Process each type in the va_args */
            for (int i = 0; i < vals.Length; i++)
            {
                int value = (int)vals[i];
                foreach (Object_Flag of in list)
                {
                    if ((id && of.value == value) || (!id && of.type == (object_flag_type)vals[i]))
                    {
                        f.on(of.value);
                    }
                }

                /*for (Object_Flag of_ptr = object_flag_table; of_ptr.index < OF_MAX; of_ptr++)
                 *  if ((id && of_ptr.id == i) || (!id && of_ptr.type == i))
                 *      of_on(f, of_ptr.index);*/
            }

            return;
        }
Пример #3
0
        /*
         * Remove the "bad" spells from a spell list
         */
        static void remove_bad_spells(int m_idx, Bitflag f)
        {
            Monster      m_ptr = Cave.cave_monster(Cave.cave, m_idx);
            Monster_Race r_ptr = Misc.r_info[m_ptr.r_idx];

            Bitflag f2       = new Bitflag(Monster_Spell_Flag.SIZE);
            Bitflag ai_flags = new Bitflag(Object_Flag.SIZE);

            int  i;
            uint smart = 0;

            /* Stupid monsters act randomly */
            if (r_ptr.flags.has(Monster_Flag.STUPID.value))
            {
                return;
            }

            /* Take working copy of spell flags */
            f2.copy(f);

            /* Don't heal if full */
            if (m_ptr.hp >= m_ptr.maxhp)
            {
                f2.off(Monster_Spell_Flag.HEAL.value);
            }

            /* Don't haste if hasted with time remaining */
            if (m_ptr.m_timed[(int)Misc.MON_TMD.FAST] > 10)
            {
                f2.off(Monster_Spell_Flag.HASTE.value);
            }

            /* Don't teleport to if the player is already next to us */
            if (m_ptr.cdis == 1)
            {
                f2.off(Monster_Spell_Flag.TELE_TO.value);
            }

            /* Update acquired knowledge */
            ai_flags.wipe();
            if (Option.birth_ai_learn.value)
            {
                /* Occasionally forget player status */
                if (Random.one_in_(100))
                {
                    m_ptr.known_pflags.wipe();
                }

                /* Use the memorized flags */
                smart = m_ptr.smart;
                ai_flags.copy(m_ptr.known_pflags);
            }

            /* Cheat if requested */
            if (Option.birth_ai_cheat.value)
            {
                for (i = 0; i < Object_Flag.MAX.value; i++)
                {
                    if (Misc.p_ptr.check_state(Object_Flag.list[i], Misc.p_ptr.state.flags))
                    {
                        ai_flags.on(i);
                    }
                }
                if (Misc.p_ptr.msp == 0)
                {
                    smart |= Misc.SM_IMM_MANA;
                }
            }

            /* Cancel out certain flags based on knowledge */
            if (!ai_flags.is_empty())
            {
                throw new NotImplementedException();
                //unset_spells(f2, ai_flags, r_ptr);
            }

            if ((smart & Misc.SM_IMM_MANA) != 0 && Random.randint0(100) < 50 * (r_ptr.flags.has(Monster_Flag.SMART.value) ? 2 : 1))
            {
                f2.off(Monster_Spell_Flag.DRAIN_MANA.value);
            }

            /* use working copy of spell flags */
            f.copy(f2);
        }
Пример #4
0
        /**
         * Create a "mask" of flags of a specific type or ID threshold.
         *
         * \param f is the flag array we're filling
         * \param id is whether we're masking by ID level
         * \param ... is the list of flags or ID types we're looking for
         *
         * N.B. OFT_MAX must be the last item in the ... list
         */
        public static void create_mask(Bitflag f, bool id, params object[] vals)
        {
            f.wipe();

            /* Process each type in the va_args */
            for (int i = 0; i < vals.Length; i++) {
                int value = (int)vals[i];
                foreach(Object_Flag of in list) {
                    if ((id && of.value == value) || (!id && of.type == (object_flag_type)vals[i]))
                        f.on(of.value);
                }
                /*for (Object_Flag of_ptr = object_flag_table; of_ptr.index < OF_MAX; of_ptr++)
                    if ((id && of_ptr.id == i) || (!id && of_ptr.type == i))
                        of_on(f, of_ptr.index);*/
            }

            return;
        }
Пример #5
0
        /*
         * Determine whether a weapon or missile weapon is obviously {excellent} when
         * worn.
         *
         * XXX Eddie should messages be adhoc all over the place?  perhaps the main
         * loop should check for change in inventory/wieldeds and all messages be
         * printed from one place
         */
        public void notice_on_wield()
        {
            Bitflag f = new Bitflag(Object_Flag.SIZE);
            Bitflag f2 = new Bitflag(Object_Flag.SIZE);
            Bitflag obvious_mask = new Bitflag(Object_Flag.SIZE);
            bool obvious = false;

            Object_Flag.create_mask(obvious_mask, true, Object_Flag.object_flag_id.WIELD);

            /* Save time of wield for later */
            object_last_wield = Misc.turn;

            /* Only deal with un-ID'd items */
            if (is_known()) return;

            /* Wear it */
            flavor_tried();
            if (add_ident_flags(IDENT_WORN))
                check_for_ident();

            /* CC: may wish to be more subtle about this once we have ego lights
             * with multiple pvals */
            if (is_light() && ego != null)
                notice_ego();

            if (flavor_is_aware() && easy_know())
            {
                notice_everything();
                return;
            }

            /* Automatically sense artifacts upon wield */
            sense_artifact();

            /* Note artifacts when found */
            if (artifact != null)
                History.add_artifact(artifact, is_known(), true);

            /* special case FA, needed at least for mages wielding gloves */
            if (FA_would_be_obvious())
                obvious_mask.on(Object_Flag.FREE_ACT.value);

            /* Extract the flags */
            object_flags(ref f);

            /* Find obvious things (disregarding curses) - why do we remove the curses?? */
            Object_Flag.create_mask(f2, false, Object_Flag.object_flag_type.CURSE);
            obvious_mask.diff(f2);
            if (f.is_inter(obvious_mask)) obvious = true;
            Object_Flag.create_mask(obvious_mask, true, Object_Flag.object_flag_id.WIELD);

            /* Notice any obvious brands or slays */
            Slay.object_notice_slays(this, obvious_mask);

            /* Learn about obvious flags */
            known_flags.union(obvious_mask);

            /* XXX Eddie should these next NOT call object_check_for_ident due to worries about repairing? */

            /* XXX Eddie this is a small hack, but jewelry with anything noticeable really is obvious */
            /* XXX Eddie learn =soulkeeping vs =bodykeeping when notice sustain_str */
            if (is_jewelry())
            {
                /* Learn the flavor of jewelry with obvious flags */
                if (EASY_LEARN && obvious)
                    flavor_aware();

                /* Learn all flags on any aware non-artifact jewelry */
                if (flavor_is_aware() && artifact == null)
                    know_all_flags();
            }

            check_for_ident();

            if (!obvious) return;

            /* XXX Eddie need to add stealth here, also need to assert/double-check everything is covered */
            /* CC: also need to add FA! */
            if (f.has(Object_Flag.STR.value))
                Utilities.msg("You feel %s!", pval[which_pval(
                    Object_Flag.STR.value)] > 0 ? "stronger" : "weaker");
            if (f.has(Object_Flag.INT.value))
                Utilities.msg("You feel %s!", pval[which_pval(
                    Object_Flag.INT.value)] > 0 ? "smarter" : "more stupid");
            if (f.has(Object_Flag.WIS.value))
                Utilities.msg("You feel %s!", pval[which_pval(
                    Object_Flag.WIS.value)] > 0 ? "wiser" : "more naive");
            if (f.has(Object_Flag.DEX.value))
                Utilities.msg("You feel %s!", pval[which_pval(
                    Object_Flag.DEX.value)] > 0 ? "more dextrous" : "clumsier");
            if (f.has(Object_Flag.CON.value))
                Utilities.msg("You feel %s!", pval[which_pval(
                    Object_Flag.CON.value)] > 0 ? "healthier" : "sicklier");
            if (f.has(Object_Flag.CHR.value))
                Utilities.msg("You feel %s!", pval[which_pval(
                    Object_Flag.CHR.value)] > 0 ? "cuter" : "uglier");
            if (f.has(Object_Flag.SPEED.value))
                Utilities.msg("You feel strangely %s.", pval[which_pval(
                    Object_Flag.SPEED.value)] > 0 ? "quick" : "sluggish");
            if (f.has(Object_Flag.BLOWS.value))
                Utilities.msg("Your weapon %s in your hands.",
                    pval[which_pval(Object_Flag.BLOWS.value)] > 0 ?
                        "tingles" : "aches");
            if (f.has(Object_Flag.SHOTS.value))
                Utilities.msg("Your bow %s in your hands.",
                    pval[which_pval(Object_Flag.SHOTS.value)] > 0 ?
                        "tingles" : "aches");
            if (f.has(Object_Flag.INFRA.value))
                Utilities.msg("Your eyes tingle.");
            if (f.has(Object_Flag.LIGHT.value))
                Utilities.msg("It glows!");
            if (f.has(Object_Flag.TELEPATHY.value))
                Utilities.msg("Your mind feels strangely sharper!");

            /* WARNING -- masking f by obvious mask -- this should be at the end of this function */
            /* CC: I think this can safely go, but just in case ... */
            /*flags_mask(f, OF_SIZE, OF_OBVIOUS_MASK, FLAG_END); */

            /* Remember the flags */
            notice_sensing();

            /* XXX Eddie should we check_for_ident here? */
        }
Пример #6
0
        /*
         * Given an object, return a short identifier which gives some idea of what
         * the item is.
         */
        public obj_pseudo_t pseudo()
        {
            Bitflag flags = new Bitflag(Object_Flag.SIZE);
            Bitflag f2 = new Bitflag(Object_Flag.SIZE);

            /* Get the known and obvious flags on the object,
             * not including curses or properties of the kind.
             */
            object_flags_known(ref flags);
            Object_Flag.create_mask(f2, true, Object_Flag.object_flag_id.WIELD);

            /* FA on gloves is obvious to mage casters */
            if (FA_would_be_obvious())
                f2.on(Object_Flag.FREE_ACT.value);

            /* Now we remove the non-obvious known flags */
            flags.inter(f2);

            /* Now we remove the cursed flags and the kind flags */
            Object_Flag.create_mask(f2, false, Object_Flag.object_flag_type.CURSE);
            flags.diff(f2);
            flags.diff(kind.flags);

            if ((ident & IDENT_INDESTRUCT) != 0)
                return obj_pseudo_t.INSCRIP_SPECIAL;
            if ((was_sensed() || was_worn()) && artifact != null)
                return obj_pseudo_t.INSCRIP_SPECIAL;

            /* jewelry does not pseudo */
            if (is_jewelry())
                return obj_pseudo_t.INSCRIP_null;

            /* XXX Eddie should also check for flags with pvals where the pval exceeds
             * the base pval for things like picks of digging, though for now acid brand gets those
             */
            if (!flags.is_empty())
                return obj_pseudo_t.INSCRIP_SPLENDID;

            if (!is_known() && !was_sensed())
                return obj_pseudo_t.INSCRIP_null;

            if (ego != null)
            {
                /* uncursed bad egos are not excellent */
                if (ego.flags.is_inter(f2))
                    return obj_pseudo_t.INSCRIP_STRANGE; /* XXX Eddie need something worse */
                else
                    return obj_pseudo_t.INSCRIP_EXCELLENT;
            }

            if (to_a == Random.randcalc(kind.to_a, 0, aspect.MINIMISE) &&
                to_h == Random.randcalc(kind.to_h, 0, aspect.MINIMISE) &&
                 to_d == Random.randcalc(kind.to_d, 0, aspect.MINIMISE))
                return obj_pseudo_t.INSCRIP_AVERAGE;

            if (to_a >= Random.randcalc(kind.to_a, 0, aspect.MINIMISE) &&
                to_h >= Random.randcalc(kind.to_h, 0, aspect.MINIMISE) &&
                to_d >= Random.randcalc(kind.to_d, 0, aspect.MINIMISE))
                return obj_pseudo_t.INSCRIP_MAGICAL;

            if (to_a <= Random.randcalc(kind.to_a, 0, aspect.MINIMISE) &&
                to_h <= Random.randcalc(kind.to_h, 0, aspect.MINIMISE) &&
                to_d <= Random.randcalc(kind.to_d, 0, aspect.MINIMISE))
                return obj_pseudo_t.INSCRIP_MAGICAL;

            return obj_pseudo_t.INSCRIP_STRANGE;
        }
Пример #7
0
        /*
         * Remove the "bad" spells from a spell list
         */
        static void remove_bad_spells(int m_idx, Bitflag f)
        {
            Monster m_ptr = Cave.cave_monster(Cave.cave, m_idx);
            Monster_Race r_ptr = Misc.r_info[m_ptr.r_idx];

            Bitflag f2 = new Bitflag(Monster_Spell_Flag.SIZE);
            Bitflag ai_flags = new Bitflag(Object_Flag.SIZE);

            int i;
            uint smart = 0;

            /* Stupid monsters act randomly */
            if (r_ptr.flags.has(Monster_Flag.STUPID.value)) return;

            /* Take working copy of spell flags */
            f2.copy(f);

            /* Don't heal if full */
            if (m_ptr.hp >= m_ptr.maxhp) f2.off(Monster_Spell_Flag.HEAL.value);

            /* Don't haste if hasted with time remaining */
            if (m_ptr.m_timed[(int)Misc.MON_TMD.FAST] > 10) f2.off(Monster_Spell_Flag.HASTE.value);

            /* Don't teleport to if the player is already next to us */
            if (m_ptr.cdis == 1) f2.off(Monster_Spell_Flag.TELE_TO.value);

            /* Update acquired knowledge */
            ai_flags.wipe();
            if (Option.birth_ai_learn.value)
            {
                /* Occasionally forget player status */
                if (Random.one_in_(100))
                    m_ptr.known_pflags.wipe();

                /* Use the memorized flags */
                smart = m_ptr.smart;
                ai_flags.copy(m_ptr.known_pflags);
            }

            /* Cheat if requested */
            if (Option.birth_ai_cheat.value) {
                for (i = 0; i < Object_Flag.MAX.value; i++)
                    if (Misc.p_ptr.check_state(Object_Flag.list[i], Misc.p_ptr.state.flags))
                        ai_flags.on(i);
                if (Misc.p_ptr.msp == 0) smart |= Misc.SM_IMM_MANA;
            }

            /* Cancel out certain flags based on knowledge */
            if(!ai_flags.is_empty()) {
                throw new NotImplementedException();
                //unset_spells(f2, ai_flags, r_ptr);
            }

            if ((smart & Misc.SM_IMM_MANA) != 0 && Random.randint0(100) < 50 * (r_ptr.flags.has(Monster_Flag.SMART.value) ? 2 : 1))
                f2.off(Monster_Spell_Flag.DRAIN_MANA.value);

            /* use working copy of spell flags */
            f.copy(f2);
        }
Пример #8
0
        /*
         * Determine whether a weapon or missile weapon is obviously {excellent} when
         * worn.
         *
         * XXX Eddie should messages be adhoc all over the place?  perhaps the main
         * loop should check for change in inventory/wieldeds and all messages be
         * printed from one place
         */
        public void notice_on_wield()
        {
            Bitflag f            = new Bitflag(Object_Flag.SIZE);
            Bitflag f2           = new Bitflag(Object_Flag.SIZE);
            Bitflag obvious_mask = new Bitflag(Object_Flag.SIZE);
            bool    obvious      = false;

            Object_Flag.create_mask(obvious_mask, true, Object_Flag.object_flag_id.WIELD);

            /* Save time of wield for later */
            object_last_wield = Misc.turn;

            /* Only deal with un-ID'd items */
            if (is_known())
            {
                return;
            }

            /* Wear it */
            flavor_tried();
            if (add_ident_flags(IDENT_WORN))
            {
                check_for_ident();
            }

            /* CC: may wish to be more subtle about this once we have ego lights
             * with multiple pvals */
            if (is_light() && ego != null)
            {
                notice_ego();
            }

            if (flavor_is_aware() && easy_know())
            {
                notice_everything();
                return;
            }

            /* Automatically sense artifacts upon wield */
            sense_artifact();

            /* Note artifacts when found */
            if (artifact != null)
            {
                History.add_artifact(artifact, is_known(), true);
            }

            /* special case FA, needed at least for mages wielding gloves */
            if (FA_would_be_obvious())
            {
                obvious_mask.on(Object_Flag.FREE_ACT.value);
            }

            /* Extract the flags */
            object_flags(ref f);

            /* Find obvious things (disregarding curses) - why do we remove the curses?? */
            Object_Flag.create_mask(f2, false, Object_Flag.object_flag_type.CURSE);
            obvious_mask.diff(f2);
            if (f.is_inter(obvious_mask))
            {
                obvious = true;
            }
            Object_Flag.create_mask(obvious_mask, true, Object_Flag.object_flag_id.WIELD);

            /* Notice any obvious brands or slays */
            Slay.object_notice_slays(this, obvious_mask);

            /* Learn about obvious flags */
            known_flags.union(obvious_mask);

            /* XXX Eddie should these next NOT call object_check_for_ident due to worries about repairing? */

            /* XXX Eddie this is a small hack, but jewelry with anything noticeable really is obvious */
            /* XXX Eddie learn =soulkeeping vs =bodykeeping when notice sustain_str */
            if (is_jewelry())
            {
                /* Learn the flavor of jewelry with obvious flags */
                if (EASY_LEARN && obvious)
                {
                    flavor_aware();
                }

                /* Learn all flags on any aware non-artifact jewelry */
                if (flavor_is_aware() && artifact == null)
                {
                    know_all_flags();
                }
            }

            check_for_ident();

            if (!obvious)
            {
                return;
            }

            /* XXX Eddie need to add stealth here, also need to assert/double-check everything is covered */
            /* CC: also need to add FA! */
            if (f.has(Object_Flag.STR.value))
            {
                Utilities.msg("You feel %s!", pval[which_pval(
                                                       Object_Flag.STR.value)] > 0 ? "stronger" : "weaker");
            }
            if (f.has(Object_Flag.INT.value))
            {
                Utilities.msg("You feel %s!", pval[which_pval(
                                                       Object_Flag.INT.value)] > 0 ? "smarter" : "more stupid");
            }
            if (f.has(Object_Flag.WIS.value))
            {
                Utilities.msg("You feel %s!", pval[which_pval(
                                                       Object_Flag.WIS.value)] > 0 ? "wiser" : "more naive");
            }
            if (f.has(Object_Flag.DEX.value))
            {
                Utilities.msg("You feel %s!", pval[which_pval(
                                                       Object_Flag.DEX.value)] > 0 ? "more dextrous" : "clumsier");
            }
            if (f.has(Object_Flag.CON.value))
            {
                Utilities.msg("You feel %s!", pval[which_pval(
                                                       Object_Flag.CON.value)] > 0 ? "healthier" : "sicklier");
            }
            if (f.has(Object_Flag.CHR.value))
            {
                Utilities.msg("You feel %s!", pval[which_pval(
                                                       Object_Flag.CHR.value)] > 0 ? "cuter" : "uglier");
            }
            if (f.has(Object_Flag.SPEED.value))
            {
                Utilities.msg("You feel strangely %s.", pval[which_pval(
                                                                 Object_Flag.SPEED.value)] > 0 ? "quick" : "sluggish");
            }
            if (f.has(Object_Flag.BLOWS.value))
            {
                Utilities.msg("Your weapon %s in your hands.",
                              pval[which_pval(Object_Flag.BLOWS.value)] > 0 ?
                              "tingles" : "aches");
            }
            if (f.has(Object_Flag.SHOTS.value))
            {
                Utilities.msg("Your bow %s in your hands.",
                              pval[which_pval(Object_Flag.SHOTS.value)] > 0 ?
                              "tingles" : "aches");
            }
            if (f.has(Object_Flag.INFRA.value))
            {
                Utilities.msg("Your eyes tingle.");
            }
            if (f.has(Object_Flag.LIGHT.value))
            {
                Utilities.msg("It glows!");
            }
            if (f.has(Object_Flag.TELEPATHY.value))
            {
                Utilities.msg("Your mind feels strangely sharper!");
            }

            /* WARNING -- masking f by obvious mask -- this should be at the end of this function */
            /* CC: I think this can safely go, but just in case ... */
            /*flags_mask(f, OF_SIZE, OF_OBVIOUS_MASK, FLAG_END); */

            /* Remember the flags */
            notice_sensing();

            /* XXX Eddie should we check_for_ident here? */
        }
Пример #9
0
        /**
         * Extract the multiplier from a given object hitting a given monster.
         *
         * \param o_ptr is the object being used to attack
         * \param m_ptr is the monster being attacked
         * \param best_s_ptr is the best applicable slay_table entry, or null if no
         *  slay already known
         * \param real is whether this is a real attack (where we update lore) or a
         *  simulation (where we don't)
         * \param known_only is whether we are using all the object flags, or only
         * the ones we *already* know about
         */
        //Best_s_ptr was slay**
        public static void improve_attack_modifier(Object o_ptr, Monster.Monster m_ptr, 
			ref Slay best_s_ptr, bool real, bool known_only)
        {
            Monster_Race r_ptr = Misc.r_info[m_ptr.r_idx];
            Monster_Lore l_ptr = Misc.l_list[m_ptr.r_idx];
            Bitflag f = new Bitflag(Object_Flag.SIZE);
            Bitflag known_f = new Bitflag(Object_Flag.SIZE);
            Bitflag note_f = new Bitflag(Object_Flag.SIZE);
            int i;

            o_ptr.object_flags(ref f);
            o_ptr.object_flags_known(ref known_f);

            for (i = 0; i < Slay.MAX.value; i++) {
                Slay s_ptr = list[i];
                if ((known_only && !known_f.has(s_ptr.object_flag.value)) || (!known_only && !f.has(s_ptr.object_flag.value)))
                    continue;

                /* In a real attack, learn about monster resistance or slay match if:
                 * EITHER the slay flag on the object is known,
                 * OR the monster is vulnerable to the slay/brand
                 */
                if (real && (known_f.has(s_ptr.object_flag.value) || (s_ptr.monster_flag != Monster_Flag.NONE
                        && r_ptr.flags.has(s_ptr.monster_flag.value)) ||
                        (s_ptr.resist_flag != Monster_Flag.NONE && !r_ptr.flags.has(s_ptr.resist_flag.value)))) {

                    /* notice any brand or slay that would affect monster */
                    note_f.wipe();
                    note_f.on(s_ptr.object_flag.value);
                    object_notice_slays(o_ptr, note_f);

                    if (m_ptr.ml && s_ptr.monster_flag != Monster_Flag.NONE)
                        l_ptr.flags.on(s_ptr.monster_flag.value);

                    if (m_ptr.ml && s_ptr.resist_flag != Monster_Flag.NONE)
                        l_ptr.flags.on(s_ptr.resist_flag.value);
                }

                /* If the monster doesn't resist or the slay flag matches */
                if ((s_ptr.brand != null && s_ptr.brand.Length != 0 &&
                        !r_ptr.flags.has(s_ptr.resist_flag.value)) ||
                        (s_ptr.monster_flag != Monster_Flag.NONE &&
                        r_ptr.flags.has(s_ptr.monster_flag.value))) {

                    /* compare multipliers to determine best attack */
                    if ((best_s_ptr == null) || ((best_s_ptr).mult < s_ptr.mult))
                        best_s_ptr = s_ptr;
                }
            }
        }