Ejemplo n.º 1
0
        /**
         * Remove slays which are duplicates, i.e. they have exactly the same "monster
         * flag" and the same "resist flag". The one with highest multiplier is kept.
         *
         * \param flags is the flagset from which to remove duplicates.
         * count is the number of dups removed.
         */
        public static int dedup_slays(ref Bitflag flags)
        {
            int i, j;
            int count = 0;

            for (i = 0; i < list.Count(); i++)
            {
                Slay s_ptr = list[i];
                if (flags.has(s_ptr.object_flag.value))
                {
                    for (j = i + 1; j < list.Count(); j++)
                    {
                        Slay t_ptr = list[j];
                        if (flags.has(t_ptr.object_flag.value) &&
                            (t_ptr.monster_flag == s_ptr.monster_flag) &&
                            (t_ptr.resist_flag == s_ptr.resist_flag) &&
                            (t_ptr.mult != s_ptr.mult))
                        {
                            count++;
                            if (t_ptr.mult > s_ptr.mult)
                            {
                                flags.off(s_ptr.object_flag.value);
                            }
                            else
                            {
                                flags.off(t_ptr.object_flag.value);
                            }
                        }
                    }
                }
            }

            return(count);
        }
Ejemplo n.º 2
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;
                    }
                }
            }
        }
Ejemplo n.º 3
0
        /**
         * Match slays in flags against a chosen flag mask
         *
         * count is the number of matches
         * \param flags is the flagset to analyse for matches
         * \param mask is the flagset against which to test
         * \param desc[] is the array of descriptions of matching slays - can be null
         * \param brand[] is the array of descriptions of brands - can be null
         * \param mult[] is the array of multipliers of those slays - can be null
         * \param dedup is whether or not to remove duplicates
         *
         * desc[], brand[] and mult[] must be >= SL_MAX in size
         */
        //Bitflags were size Object_Flag.SIZE, might be an out param
        public static int list_slays(Bitflag flags, Bitflag mask, string[] desc, string[] brand, int[] mult, bool dedup)
        {
            int     i, count = 0;
            Bitflag f = new Bitflag(Object_Flag.SIZE);

            /* We are only interested in the flags specified in mask */
            f.copy(flags);
            f.inter(mask);

            /* Remove "duplicate" flags if desired */
            if (dedup)
            {
                dedup_slays(ref f);
            }

            /* Collect slays */
            for (i = 0; i < list.Count(); i++)
            {
                Slay s_ptr = list[i];
                if (f.has(s_ptr.object_flag.value))
                {
                    if (mult != null)
                    {
                        mult[count] = s_ptr.mult;
                    }
                    if (brand != null)
                    {
                        brand[count] = s_ptr.brand;
                    }
                    if (desc != null)
                    {
                        desc[count] = s_ptr.desc;
                    }
                    count++;
                }
            }

            return(count);
        }
Ejemplo n.º 4
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);
        }
Ejemplo n.º 5
0
        /**
         * Calculate the rating for a given slay combination
         */
        int slay_power(bool verbose, StreamWriter log_file, bool known)
        {
            Bitflag      s_index = new Bitflag(Object_Flag.SIZE);
            Bitflag      f = new Bitflag(Object_Flag.SIZE);
            Bitflag      f2 = new Bitflag(Object_Flag.SIZE);
            int          sv = 0;    //uint
            int          i, j;
            int          mult;
            Slay         best_s_ptr = null;
            Monster_Race r_ptr;

            Monster.Monster m_ptr;
            //monster_type monster_type_body;
            string[] desc   = new string[Slay.MAX.value];      // = { 0 }, *
            string[] brand  = new string[Slay.MAX.value];      // = { 0 };
            int[]    s_mult = new int[Slay.MAX.value];         // = { 0 };

            if (known)
            {
                object_flags(ref f);
            }
            else
            {
                object_flags_known(ref f);
            }

            /* Combine the slay bytes into an index value, return if there are none */
            s_index.copy(f);
            Object_Flag.create_mask(f2, false, Object_Flag.object_flag_type.SLAY,
                                    Object_Flag.object_flag_type.KILL, Object_Flag.object_flag_type.BRAND);

            if (!s_index.is_inter(f2))
            {
                return(Eval.tot_mon_power);
            }
            else
            {
                s_index.inter(f2);
            }

            /* Look in the cache to see if we know this one yet */
            sv = Slay.check_slay_cache(s_index);

            /* If it's cached (or there are no slays), return the value */
            if (sv != 0)
            {
                //file_putf(log_file, "Slay cache hit\n");
                return(sv);
            }

            /*
             * Otherwise we need to calculate the expected average multiplier
             * for this combination (multiplied by the total number of
             * monsters, which we'll divide out later).
             */
            for (i = 0; i < Misc.z_info.r_max; i++)
            {
                best_s_ptr = null;
                mult       = 1;
                r_ptr      = Misc.r_info[i];
                if (r_ptr == null)
                {
                    continue;
                }
                m_ptr       = new Monster.Monster();
                m_ptr.r_idx = (short)i;

                /* Find the best multiplier against this monster */
                Slay.improve_attack_modifier(this, m_ptr, ref best_s_ptr, false, !known);
                if (best_s_ptr != null)
                {
                    mult = best_s_ptr.mult;
                }

                /* Add the multiple to sv */
                sv += (int)(mult * r_ptr.scaled_power);
            }

            /*
             * To get the expected damage for this weapon, multiply the
             * average damage from base dice by sv, and divide by the
             * total number of monsters.
             */
            if (verbose)
            {
                /* Write info about the slay combination and multiplier */
                //file_putf(log_file, "Slay multiplier for: ");

                j = Slay.list_slays(s_index, s_index, desc, brand, s_mult, false);

                //for (i = 0; i < j; i++) {
                //    if (brand[i]) {
                //        file_putf(log_file, brand[i]);
                //    } else {
                //        file_putf(log_file, desc[i]);
                //    }
                //    file_putf(log_file, "x%d ", s_mult[i]);
                //}
                //file_putf(log_file, "\nsv is: %d\n", sv);
                //file_putf(log_file, " and t_m_p is: %d \n", tot_mon_power);
                //file_putf(log_file, "times 1000 is: %d\n", (1000 * sv) / tot_mon_power);
            }

            /* Add to the cache */
            if (Slay.fill_slay_cache(s_index, sv))
            {
                //file_putf(log_file, "Added to slay cache\n");
            }

            return(sv);
        }
Ejemplo n.º 6
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? */
        }
Ejemplo n.º 7
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;
                }
            }
        }